From 9701da35558b9b5cea06b43315d813c287d88649 Mon Sep 17 00:00:00 2001
From: Ivan_Kustau <Ivan_Kustau@epam.com>
Date: Wed, 6 Sep 2023 11:53:10 +0300
Subject: [PATCH 01/25] Add caffeine cache manager

---
 build.gradle | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/build.gradle b/build.gradle
index 3dc5ddc9e5..b157bd1b9b 100644
--- a/build.gradle
+++ b/build.gradle
@@ -84,7 +84,7 @@ dependencies {
         compile 'com.epam.reportportal:plugin-api'
     } else {
         compile 'com.github.reportportal:commons-events:e337f8b7be'
-        compile 'com.github.reportportal:commons-dao:b2db29b'
+        compile 'com.github.reportportal:commons-dao:34829fb198'
         compile 'com.github.reportportal:commons-rules:5.10.0'
         compile 'com.github.reportportal:commons-model:e0a12669'
         compile 'com.github.reportportal:commons:ce2166b'

From 7024166a5c8a2e67af4df2b3a2054a656e66bfa6 Mon Sep 17 00:00:00 2001
From: hlebkanonik <hleb_kanonik@epam.com>
Date: Wed, 6 Sep 2023 12:07:26 +0200
Subject: [PATCH 02/25] added github.run_number to rc build

(cherry picked from commit 52ca2ef7089f465f6ce84be2afaec43a300f7478)
---
 .github/workflows/rc.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/rc.yaml b/.github/workflows/rc.yaml
index 6dfb1317cd..a16303a460 100644
--- a/.github/workflows/rc.yaml
+++ b/.github/workflows/rc.yaml
@@ -38,7 +38,7 @@ jobs:
       - name: Create variables
         id: vars
         run: |
-          echo "tag=$(echo ${{ github.ref_name }} | tr '/' '-')" >> $GITHUB_OUTPUT
+          echo "tag=$(echo ${{ github.ref_name }}-${{ github.run_number }} | tr '/' '-')" >> $GITHUB_OUTPUT
           echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT
           echo "version=$(echo '${{ github.ref_name }}' | sed -nE 's/.*([0-9]+\.[0-9]+\.[0-9]+).*/\1/p')" >> $GITHUB_OUTPUT
       

From 3dcf60a6aa4a28cfdc4c81ceee2a32d9a4eaf41d Mon Sep 17 00:00:00 2001
From: Ivan Kustau <86599591+IvanKustau@users.noreply.github.com>
Date: Thu, 14 Sep 2023 10:19:59 +0300
Subject: [PATCH 03/25] EPMRPP-86400 || Fix the problem with 'undefined' for
 exported filename (#1794)

---
 .../epam/ta/reportportal/ws/controller/LaunchController.java    | 2 +-
 .../epam/ta/reportportal/ws/controller/ProjectController.java   | 2 +-
 .../com/epam/ta/reportportal/ws/controller/UserController.java  | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/LaunchController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/LaunchController.java
index 705bdfbd2d..5949add2c2 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/controller/LaunchController.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/controller/LaunchController.java
@@ -351,7 +351,7 @@ public void getLaunchReport(@PathVariable String projectName, @PathVariable Long
 		response.setContentType(format.getContentType());
 
 		response.setHeader(HttpHeaders.CONTENT_DISPOSITION,
-				String.format("attachment; filename=RP_LAUNCH_%s_Report.%s", format.name(), format.getValue())
+				String.format("attachment; filename=\"RP_LAUNCH_%s_Report.%s\"", format.name(), format.getValue())
 		);
 
 		try (OutputStream outputStream = response.getOutputStream()) {
diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/ProjectController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/ProjectController.java
index ff8614e7b8..ee505599a1 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/controller/ProjectController.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/controller/ProjectController.java
@@ -343,7 +343,7 @@ public void exportProjects(
     response.setContentType(format.getContentType());
 
     response.setHeader(CONTENT_DISPOSITION,
-        String.format("attachment; filename=RP_PROJECTS_%s_Report.%s", format.name(),
+        String.format("attachment; filename=\"RP_PROJECTS_%s_Report.%s\"", format.name(),
             format.getValue())
     );
 
diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/UserController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/UserController.java
index c4071d8838..4252f9033d 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/controller/UserController.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/controller/UserController.java
@@ -282,7 +282,7 @@ public void export(@ApiParam(allowableValues = "csv")
     response.setContentType(format.getContentType());
 
     response.setHeader(com.google.common.net.HttpHeaders.CONTENT_DISPOSITION,
-        String.format("attachment; filename=RP_USERS_%s_Report.%s", format.name(),
+        String.format("attachment; filename=\"RP_USERS_%s_Report.%s\"", format.name(),
             format.getValue()
         )
     );

From 30612d724b501aa332c6ae78769b975df9709964 Mon Sep 17 00:00:00 2001
From: Hleb Kanonik <hleb_kanonik@epam.com>
Date: Fri, 29 Sep 2023 10:21:02 +0200
Subject: [PATCH 04/25] tag latest added

---
 .github/workflows/rc.yaml | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/rc.yaml b/.github/workflows/rc.yaml
index a16303a460..ac8ae32983 100644
--- a/.github/workflows/rc.yaml
+++ b/.github/workflows/rc.yaml
@@ -65,7 +65,9 @@ jobs:
             GITHUB_TOKEN=${{ secrets.GH_TOKEN }}
             RELEASE_MODE=${{ env.RELEASE_MODE }}
           platforms: ${{ env.PLATFORMS }}
-          tags: ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:${{ env.IMAGE_TAG }}
+          tags: Ё
+            ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:${{ env.IMAGE_TAG }}
+            ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:latest
       
       - name: Summarize
         env:
@@ -75,4 +77,4 @@ jobs:
           echo "## General information about the build:" >> $GITHUB_STEP_SUMMARY
           echo "" >> $GITHUB_STEP_SUMMARY
           echo "- :gift: Docker image in Amazon ECR: ecr/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_STEP_SUMMARY
-          echo "- :octocat: The commit SHA from which the build was performed: [$GITHUB_SHA](https://github.com/$GITHUB_REPOSITORY/commit/$GITHUB_SHA)" >> $GITHUB_STEP_SUMMARY
\ No newline at end of file
+          echo "- :octocat: The commit SHA from which the build was performed: [$GITHUB_SHA](https://github.com/$GITHUB_REPOSITORY/commit/$GITHUB_SHA)" >> $GITHUB_STEP_SUMMARY

From 5f92284efa63ba0ce8cd3114951cd23d1e4f3012 Mon Sep 17 00:00:00 2001
From: Hleb Kanonik <hleb_kanonik@epam.com>
Date: Fri, 29 Sep 2023 10:22:35 +0200
Subject: [PATCH 05/25] Update rc.yaml

---
 .github/workflows/rc.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/rc.yaml b/.github/workflows/rc.yaml
index ac8ae32983..98d9ca8724 100644
--- a/.github/workflows/rc.yaml
+++ b/.github/workflows/rc.yaml
@@ -65,7 +65,7 @@ jobs:
             GITHUB_TOKEN=${{ secrets.GH_TOKEN }}
             RELEASE_MODE=${{ env.RELEASE_MODE }}
           platforms: ${{ env.PLATFORMS }}
-          tags: Ё
+          tags: |
             ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:${{ env.IMAGE_TAG }}
             ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:latest
       

From f056315e6c9febeb90b5bc105cc694653b4b4867 Mon Sep 17 00:00:00 2001
From: Hleb Kanonik <hleb_kanonik@epam.com>
Date: Mon, 2 Oct 2023 13:09:52 +0200
Subject: [PATCH 06/25] Create dockerhub-release.yaml

---
 .github/workflows/dockerhub-release.yaml | 69 ++++++++++++++++++++++++
 1 file changed, 69 insertions(+)
 create mode 100644 .github/workflows/dockerhub-release.yaml

diff --git a/.github/workflows/dockerhub-release.yaml b/.github/workflows/dockerhub-release.yaml
new file mode 100644
index 0000000000..127df9b298
--- /dev/null
+++ b/.github/workflows/dockerhub-release.yaml
@@ -0,0 +1,69 @@
+name: Retag RC Docker image
+
+on:
+  pull_request_review:
+    types: [submitted]
+
+env:
+  AWS_REGION: ${{ vars.AWS_REGION }}         # set this to your preferred AWS region, e.g. us-west-1
+  ECR_REPOSITORY: ${{ vars.ECR_REPOSITORY }} # set this to your Amazon ECR repository name
+  PLATFORMS: ${{ vars.BUILD_PLATFORMS }}     # set target build platforms. By default linux/amd64
+  RELEASE_MODE: ${{ vars.RELEASE_MODE }}
+
+jobs:
+  retag-image:
+    name: Retag and push image 
+    runs-on: ubuntu-latest
+    environment: rc
+    if: github.base_ref == 'master' || github.base_ref == 'main'
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v3
+
+      - name: Configure AWS credentials
+        uses: aws-actions/configure-aws-credentials@v2
+        with:
+          # role-to-assume: arn:aws:iam::123456789012:role/my-github-actions-role
+          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
+          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
+          aws-region: ${{ env.AWS_REGION }}
+
+      - name: Login to Amazon ECR
+        id: login-ecr
+        uses: aws-actions/amazon-ecr-login@v1
+        with:
+          mask-password: 'true'
+      
+      - name: Log in to Docker Hub
+        uses: docker/login-action@v3
+        with:
+          username: ${{ secrets.DOCKERHUB_USERNAME }}
+          password: ${{ secrets.DOCKERHUB_PASSWORD }}
+      
+      - name: Create variables
+        id: vars
+        run: |
+          echo "tag=$(echo '${{ github.event.pull_request.title }}' | sed -nE 's/.*([0-9]+\.[0-9]+\.[0-9]+).*/\1/p')" >> $GITHUB_OUTPUT
+      
+      - name: Set up QEMU
+        uses: docker/setup-qemu-action@v2
+      
+      - name: Set up Docker Buildx
+        uses: docker/setup-buildx-action@v2
+
+      - name: Retag and Push Docker Image
+        env:
+          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
+          IMAGE_TAG: ${{ steps.vars.outputs.tag }}
+        run: |
+          docker buildx imagetools create $ECR_REGISTRY/$ECR_REPOSITORY:latest --tag $DOCKERHUB_REGISTRY/$DOCKERHUB_REPOSITORY:$IMAGE_TAG --tag $DOCKERHUB_REGISTRY/$DOCKERHUB_REPOSITORY:latest
+      
+      - name: Summarize
+        env:
+          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
+          IMAGE_TAG: ${{ steps.vars.outputs.tag }}
+        run: |
+          echo "## General information about the build:" >> $GITHUB_STEP_SUMMARY
+          echo "" >> $GITHUB_STEP_SUMMARY
+          echo "- :whale: Docker image: $DOCKERHUB_REGISTRY/$DOCKERHUB_REPOSITORY:$IMAGE_TAG" >> $GITHUB_STEP_SUMMARY
+          echo "- :octocat: The commit SHA from which the build was performed: [$GITHUB_SHA](https://github.com/$GITHUB_REPOSITORY/commit/$GITHUB_SHA)" >> $GITHUB_STEP_SUMMARY

From e25059f54be4aa6557cc676d8a06025ffe6fb528 Mon Sep 17 00:00:00 2001
From: hlebkanonik <hleb_kanonik@epam.com>
Date: Mon, 2 Oct 2023 13:44:01 +0200
Subject: [PATCH 07/25] github.event.pull_request.base.ref

---
 .github/workflows/dockerhub-release.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/dockerhub-release.yaml b/.github/workflows/dockerhub-release.yaml
index 127df9b298..827768c052 100644
--- a/.github/workflows/dockerhub-release.yaml
+++ b/.github/workflows/dockerhub-release.yaml
@@ -15,7 +15,7 @@ jobs:
     name: Retag and push image 
     runs-on: ubuntu-latest
     environment: rc
-    if: github.base_ref == 'master' || github.base_ref == 'main'
+    if: github.event.pull_request.base.ref == 'master' || github.event.pull_request.base.ref == 'main'
     steps:
       - name: Checkout
         uses: actions/checkout@v3

From f88d8abae9a58fe11ca761aa7dffe875a32203b5 Mon Sep 17 00:00:00 2001
From: hlebkanonik <hleb_kanonik@epam.com>
Date: Mon, 2 Oct 2023 14:21:45 +0200
Subject: [PATCH 08/25] rewrite target regestry envs

---
 .github/workflows/dockerhub-release.yaml | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/.github/workflows/dockerhub-release.yaml b/.github/workflows/dockerhub-release.yaml
index 827768c052..bebe70f7fa 100644
--- a/.github/workflows/dockerhub-release.yaml
+++ b/.github/workflows/dockerhub-release.yaml
@@ -5,9 +5,11 @@ on:
     types: [submitted]
 
 env:
-  AWS_REGION: ${{ vars.AWS_REGION }}         # set this to your preferred AWS region, e.g. us-west-1
-  ECR_REPOSITORY: ${{ vars.ECR_REPOSITORY }} # set this to your Amazon ECR repository name
-  PLATFORMS: ${{ vars.BUILD_PLATFORMS }}     # set target build platforms. By default linux/amd64
+  AWS_REGION: ${{ vars.AWS_REGION }}                  # set this to your preferred AWS region, e.g. us-west-1
+  ECR_REPOSITORY: ${{ vars.ECR_REPOSITORY }}          # set this to your Amazon ECR repository name
+  TARGET_REGISTRY: ${{ vars.TARGET_REGISTRY }}     # set to target regestry (DockerHub, GitHub & etc)
+  TARGET_REPOSITORY: ${{ vars.TARGET_REPOSITORY }} # set to target repository
+  PLATFORMS: ${{ vars.BUILD_PLATFORMS }}              # set target build platforms. By default linux/amd64
   RELEASE_MODE: ${{ vars.RELEASE_MODE }}
 
 jobs:
@@ -37,8 +39,8 @@ jobs:
       - name: Log in to Docker Hub
         uses: docker/login-action@v3
         with:
-          username: ${{ secrets.DOCKERHUB_USERNAME }}
-          password: ${{ secrets.DOCKERHUB_PASSWORD }}
+          username: ${{ secrets.REGESTRY_USERNAME }}
+          password: ${{ secrets.REGESTRY_PASSWORD }}
       
       - name: Create variables
         id: vars
@@ -56,7 +58,7 @@ jobs:
           ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
           IMAGE_TAG: ${{ steps.vars.outputs.tag }}
         run: |
-          docker buildx imagetools create $ECR_REGISTRY/$ECR_REPOSITORY:latest --tag $DOCKERHUB_REGISTRY/$DOCKERHUB_REPOSITORY:$IMAGE_TAG --tag $DOCKERHUB_REGISTRY/$DOCKERHUB_REPOSITORY:latest
+          docker buildx imagetools create $ECR_REGISTRY/$ECR_REPOSITORY:latest --tag $TARGET_REGISTRY/$TARGET_REPOSITORY:$IMAGE_TAG --tag $TARGET_REGISTRY/$TARGET_REPOSITORY:latest
       
       - name: Summarize
         env:
@@ -65,5 +67,5 @@ jobs:
         run: |
           echo "## General information about the build:" >> $GITHUB_STEP_SUMMARY
           echo "" >> $GITHUB_STEP_SUMMARY
-          echo "- :whale: Docker image: $DOCKERHUB_REGISTRY/$DOCKERHUB_REPOSITORY:$IMAGE_TAG" >> $GITHUB_STEP_SUMMARY
+          echo "- :whale: Docker image: $TARGET_REGISTRY/$TARGET_REPOSITORY:$IMAGE_TAG" >> $GITHUB_STEP_SUMMARY
           echo "- :octocat: The commit SHA from which the build was performed: [$GITHUB_SHA](https://github.com/$GITHUB_REPOSITORY/commit/$GITHUB_SHA)" >> $GITHUB_STEP_SUMMARY

From 13d6e1697792b620def74b45da35160d4525836c Mon Sep 17 00:00:00 2001
From: hlebkanonik <hleb_kanonik@epam.com>
Date: Mon, 2 Oct 2023 14:22:50 +0200
Subject: [PATCH 09/25] modified:   .github/workflows/dockerhub-release.yaml

---
 .github/workflows/dockerhub-release.yaml | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/dockerhub-release.yaml b/.github/workflows/dockerhub-release.yaml
index bebe70f7fa..f874986a45 100644
--- a/.github/workflows/dockerhub-release.yaml
+++ b/.github/workflows/dockerhub-release.yaml
@@ -5,11 +5,11 @@ on:
     types: [submitted]
 
 env:
-  AWS_REGION: ${{ vars.AWS_REGION }}                  # set this to your preferred AWS region, e.g. us-west-1
-  ECR_REPOSITORY: ${{ vars.ECR_REPOSITORY }}          # set this to your Amazon ECR repository name
+  AWS_REGION: ${{ vars.AWS_REGION }}               # set this to your preferred AWS region, e.g. us-west-1
+  ECR_REPOSITORY: ${{ vars.ECR_REPOSITORY }}       # set this to your Amazon ECR repository name
   TARGET_REGISTRY: ${{ vars.TARGET_REGISTRY }}     # set to target regestry (DockerHub, GitHub & etc)
   TARGET_REPOSITORY: ${{ vars.TARGET_REPOSITORY }} # set to target repository
-  PLATFORMS: ${{ vars.BUILD_PLATFORMS }}              # set target build platforms. By default linux/amd64
+  PLATFORMS: ${{ vars.BUILD_PLATFORMS }}           # set target build platforms. By default linux/amd64
   RELEASE_MODE: ${{ vars.RELEASE_MODE }}
 
 jobs:

From 90137488c93f2a2e0a67d4c3c8acd20d95ee1bc4 Mon Sep 17 00:00:00 2001
From: Ivan_Kustau <Ivan_Kustau@epam.com>
Date: Mon, 2 Oct 2023 15:51:38 +0300
Subject: [PATCH 10/25] Update to release version

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index d0a545f507..1dec792439 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version=develop
+version=5.10.0
 description=EPAM Report portal. Main API Service
 dockerPrepareEnvironment=
 dockerJavaOpts=-Xmx1g -XX:+UseG1GC -XX:InitiatingHeapOccupancyPercent=70 -Djava.security.egd=file:/dev/./urandom

From ef9d00bcd372fc69c0c55c165bc5a5d73f68e2a9 Mon Sep 17 00:00:00 2001
From: "reportportal.io" <support@reportportal.io>
Date: Mon, 2 Oct 2023 13:07:39 +0000
Subject: [PATCH 11/25] [Gradle Release Plugin] - new version commit: 
 '5.10.1'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 1dec792439..a58c7cedca 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version=5.10.0
+version=5.10.1
 description=EPAM Report portal. Main API Service
 dockerPrepareEnvironment=
 dockerJavaOpts=-Xmx1g -XX:+UseG1GC -XX:InitiatingHeapOccupancyPercent=70 -Djava.security.egd=file:/dev/./urandom

From f0e8cbb36956f89e53f5484b0a4668ca656c9ca1 Mon Sep 17 00:00:00 2001
From: APiankouski <109206864+APiankouski@users.noreply.github.com>
Date: Wed, 25 Oct 2023 11:03:28 +0300
Subject: [PATCH 12/25] Hotfix 5.10.1 (#1837)

* EPMRPP-87223 || Fix duplicated logs
---
 .github/workflows/release.yml                  |  2 +-
 .../ws/rabbit/AsyncReportingListener.java      | 18 ++++++++++--------
 2 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index d6d1335791..11f7c0cd29 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -11,7 +11,7 @@ on:
 
 env:
   GH_USER_NAME: github.actor
-  RELEASE_VERSION: 5.10.0
+  RELEASE_VERSION: 5.10.1
   REPOSITORY_URL: 'https://maven.pkg.github.com/'
 
 jobs:
diff --git a/src/main/java/com/epam/ta/reportportal/ws/rabbit/AsyncReportingListener.java b/src/main/java/com/epam/ta/reportportal/ws/rabbit/AsyncReportingListener.java
index bccbac8713..574610eeef 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/rabbit/AsyncReportingListener.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/rabbit/AsyncReportingListener.java
@@ -296,14 +296,16 @@ private void createItemLog(SaveLogRQ request, TestItem item, BinaryDataMetaInfo
 		Launch effectiveLaunch = testItemService.getEffectiveLaunch(item);
 		logService.saveLogMessageToElasticSearch(log, effectiveLaunch.getId());
 
-		saveAttachment(request.getFile().getName(), metaInfo,
-				log.getId(),
-				projectId,
-				effectiveLaunch.getId(),
-				item.getItemId(),
-				effectiveLaunch.getUuid(),
-				log.getUuid()
-		);
+    if (Objects.nonNull(request.getFile())) {
+      saveAttachment(request.getFile().getName(), metaInfo,
+          log.getId(),
+          projectId,
+          effectiveLaunch.getId(),
+          item.getItemId(),
+          effectiveLaunch.getUuid(),
+          log.getUuid()
+      );
+    }
 	}
 
 	private void createLaunchLog(SaveLogRQ request, Launch launch, BinaryDataMetaInfo metaInfo,

From afb083d7738f4af8371fa697fa25cf01529985bf Mon Sep 17 00:00:00 2001
From: "reportportal.io" <support@reportportal.io>
Date: Wed, 25 Oct 2023 08:09:43 +0000
Subject: [PATCH 13/25] [Gradle Release Plugin] - new version commit: 
 '5.10.2'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index a58c7cedca..e415066637 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version=5.10.1
+version=5.10.2
 description=EPAM Report portal. Main API Service
 dockerPrepareEnvironment=
 dockerJavaOpts=-Xmx1g -XX:+UseG1GC -XX:InitiatingHeapOccupancyPercent=70 -Djava.security.egd=file:/dev/./urandom

From 3c970cea6a75435e319692f5b992701ab0374740 Mon Sep 17 00:00:00 2001
From: PeeAyBee <pavel_bortnik@epam.com>
Date: Fri, 1 Mar 2024 11:07:03 +0300
Subject: [PATCH 14/25] Release 5.11.0 (#1899)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* EPMRPP-77647 || switched to develop

* EPMRPP-77647 || changed commons version

* EPMRPP-77648 || implement POST endpoint

* EPMRPP-77648 || copyrights fix

* EPMRPP-77779 || Launch and test item description limits

* EPMRPP-76804 || Add recalculation on items deletion

* EPMRPP-76804 || Fix unit tests

* EPMRPP-77779 || updated commons-dao version

* EPMRPP-77779 || updated limit on service api

* EPMRPP-77811 || Implement validation for POST endpoint

* Newjenkins (#1587)

* Update Jenkinsfile

* Update Jenkinsfile

* Update Jenkinsfile

* Update Jenkinsfile

* Update Jenkinsfile

Co-authored-by: Pavel Bortnik <pavel_bortnik@epam.com>

* EPMRPP-77779 || limited length to 2048

* EPMRPP-77779 || updated commons-model hash

* EPMRPP-77779 || id field for SenderCaseDTO

* EPMRPP-77779 || updated commons-model hash

* EPMRPP-77777 || implement PUT request

* EPMRPP-77623 || Clustering last run attribute removing

* EPMRPP-77778 || implement DELETE endpoint

* RC pipeline modified

* description changed

* tagging by gradlew updated

* String parameter BRANCH added

* Update Jenkinsfile-candidate

* spaces

* EPMRPP-77972 || Fix retries and nesteds counting

* EPMRPP-77972 || Update dao version

* EPMRPP-77972 || Update dao version

* EPMRPP-77973 || Potential fix for perf issue

* EPMRPP-77973 || Update batch size as env variable

* EPMRPP-77973 || Fix launch logs counting

* EPMRPP-78088 || List equality validation fix

* EPMRPP-78107 || Dao with updated mapping provided

* EPMRPP-77973 || Fix partition handling

* EPMRPP-78071 || Dao with updated query provided

* EPMRPP-77922 || Performance fix

* EPMRPP-77922 || Performance fix

* EPMRPP-64803 || Make async remove test items from index (#1604)

Co-authored-by: Andrei Piankouski <andrei.piankouski@ukg.com>

* EPMRPP-64803 || Make async remove test items from index (#1605)

Co-authored-by: Andrei Piankouski <andrei.piankouski@ukg.com>

* EPMRPP-78587 || Fix attribute grouping

* Update README.md

* Update README.md

* EPMRPP-78284: Move all notification endpoints to ProjectSettingsController and add tests

* EPMRPP-77947 || Move all notification endpoints to ProjectSettingsController and add tests

* promote.yml update

* Remove hardcoded publishing URL

* Remove Sealights

* Update promote.yml

* EPMRPP-78764 || Changed number of allowed custom defect types

* Epmrpp 75612 deletion from es (#1615)

* EPMRPP-75612 || Deletion logs from ES

* EPMRPP-79208 || Launch export. Empty file is exported if there is item with 'in progress' status in the launch (#1616)

Co-authored-by: Andrei Piankouski <andrei_piankouski@epam.com>

* EPMRPP-79167 || Updated commons dao version (#1620)

* EPMRPP-79329 || Update autocomplete in Notification. start from 1 symbol (#1622)

* EPMRPP-79329 || Update autocomplete in Notification. start from 1 symbol

* EPMRPP-79329 || Fix test

Co-authored-by: Andrei Piankouski <andrei_piankouski@epam.com>

* EPMRPP-78998 || Flaky test cases widget. Increase the amount of items to be displayed on widget from 20 to 50

* EPMRPP-80255 || Save the Dashboards and widgets of deleted user

* EPMRPP-79630 || Update Passing rate per Launch widget

* Delete .travis.yml

We don't use it anymore

* EPMRPP-80176 || Update Passing rate summary widget

* EPMRPP-78657 || Notification of an inexistent launch in Edit/Duplicate

* Update release.yml

* EMPRPP-80865 || Update commons-dao dependency (#1676)

* EPMRPP-80865 || Merge master to develop (#1680)

* EPMRPP-79211 || Changed Minio interface to JCloud

* EPMRPP-79211 || Updated DataStore configuration and properties

* EPMRPP-79211 || Updated docker-compose with right BinaryStore value

* EPMRPP-79211 || Update commons dao version

* Update commons dao dependency to 5.7.4

* EPMRPP-80865|| Update bom and other versions (#1663)

5.7.4 || Update bom and other versions

* [Gradle Release Plugin] - new version commit:  '5.7.5'.

---------

Co-authored-by: miracle8484 <76156909+miracle8484@users.noreply.github.com>
Co-authored-by: reportportal.io <support@reportportal.io>

* EPMRPP-80809 marked API getLogByUuid as Deprecated (#1686)

* EPMRPP-73535 || Added getting logMessage from ES + merging with PG

* Add removeScripts task to Cleanup stage in Jenkins (#1689)

* EPMRPP-76400 || Patternt analyze working with ES

* EPMRPP-82405 || Fix es deleting bug

* EPMRPP-82327 || Formatting code according to code style (#1688)

* EPMRPP-82327-google-style google-style applied

* EPMRPP-82327-google-style formatted new changes

* EPMRPP-82327-google-style fixed import in test

* EPMRPP-82614 || Fix pattern analysis for nested steps (#1693)

* EPMRPP-82614 || Fix pattern analysis for nested steps

* EPMRPP-82614 || Refactor ElasticLogService

* Epmrpp-84251 || merge to develop (#1710)

* Update spring boot version to fix CVE-2022-22965

* EPMRPP-76845 || Update spring boot

* Update Jenkinsfile

* EPMRPP-77678 || Description length increased to 2048

* EPMRPP-77678 || Redundant import fix

* EPMRPP-79737 || Fix vulnerabilities and update libraries version (#1624)

* EPMRPP-79136 || Add retrieving all logs with it's locations (#1619)

* EPMRPP-79136 || Add retrieving all logs with it's locations

* EPMRPP-79136 || Add filtering by log level and item type

* EPMRPP-79136 || Change response to save correct ordering

* EPMRPP-79136 || Fix exclude passed logs parameter

* EPMRPP-79136 || Override page size limit

* EPMRPP-79136 || Fix retrieving with passed logs exclusion

* Update Jenkinsfile-candidate

* EPMRPP-79136 || Update dao version

* EPMRPP-80383 || Notifications. AND/OR attribute option

* EPMRPP-80744 || Change email on the API page

* EPMRPP-80601 || Timeline widget. Remove empty content

* EPMRPP-80744 || Add item attribute max length validation (#1640)

EPMRPP-80744 || Add item attribute max length validation

* EPMRPP-81136 || Incorrect 'startTime' value is reported for tests via 'Import' functionality

Co-authored-by: Andrei Piankouski <andrei_piankouski@epam.com>

* EPMRPP-81046 || Impossible to report test items to project with "demo" name

* EPMRPP-81019 || Launch import. Error 'org.hibernate.exception.DataException: could not execute statement' occurs on importing launch (#1645)

* EPMRPP-81052 || Most failed test-cases table (TOP-20). Increase the amount of items to be displayed on widget from 20 to 50 or 100

* EPMRPP-80606 || Cut notification attribute to max length (#1650)

EPMRPP-80606 || Cut attributes to max length

* EPMRPP-81029 || There is no validation for the creation of dashboards exceeding the limit (#1651)

* Revert "EPMRPP-81029 || There is no validation for the creation of dashboards exceeding the limit (#1651)"

This reverts commit 13a49a644635f76b9b38dcb7ea41f7601d1fab04.

* EPMRPP-81029 || There is no validation for the creation of dashboards exceeding the limit

* EPMRPP-80606 || Update filter attribute cut logic (#1652)

* EPMRPP-78741 || Remove duplicate onboarding endpoint (#1653)

* EPMRPP-80606 || UserFilter cut attribute refactor (#1655)

* EPMRPP-81358 || Fix vulnerabilities

* EPMRPP-81193 || Wrong error code and message when creating notification rule without mandatory field

* EPMRPP-81202 || Widget 'Flaky test cases table (TOP-50). It is possible to create widget with invalid 'Launches count' value via API (#1670)

* EPMRPP-81202 || Widget 'Flaky test cases table (TOP-50). It is possible to create widget with invalid 'Launches count' value via API

* EPMRPP-81202 || Change migration brunch

* EPMRPP-81202 || Replace tab to spaces

---------

Co-authored-by: Andrei Piankouski <andrei_piankouski@epam.com>

* EPMRPP-82300 || Typo in the error message when creating 'Flaky test cases table (TOP-50)' widget with some invalid values via API (#1674)

* EPMRPP-82300-fix-typo-error uploaded commons-model dependency and fixed tests in service-api

* EPMRPP-82300-fix-typo-error fixed tests in service-api

* Epmrpp 78258 move acl (#1667)

* EPMRPP-81233 || Move ACL tasks from RP-23.3 to RP-23.1

* EPMRPP-72320 || Fix unit tests

* EPMRPP-81233 || Move ACL tasks from RP-23.3 to RP-23.1

* EPMRPP-81233 || Update bom

---------

Co-authored-by: Pavel Bortnik <pavel_bortnik@epam.com>
Co-authored-by: Andrei Piankouski <andrei_piankouski@epam.com>

* EPMRPP-81050 || Most Failed test-cases table widget. Increase the amount of items to be displayed on widget from 20 to 50

* EPMRPP-82116 || Update Notification template after launch finish (#1673)

* EPMRPP-82116 Updated template for Notifications after launch finish

* EPMRPP-82116 edited invitation templates

* Update common model

* EPMRPP-81362 || Fix security vulnerabilities (#1671)

* EPMRPP-82116 || Update Notification template after launch finish (removed attachments) (#1678)

* EPMRPP-82116-remove-attachments removed vk and fb attachments from specific email notifications

* EPMRPP-82116-remove-attachments removed vk and fb links from all templates

* EPMRPP-81154 added xml to api description and added file size check (#1677)

* EPMRPP-81970 || Autocomplete in Recipients filed on Notifications tab in Project settings should show options starting from 1 symbol (#1681)

* EPMRPP-81970 changed symbol limit from 3 to 1

* EPMRPP-81970 added code formatting

* EPMRPP-82375 || Implement notification when changing password and make some template updates (#1682)

* EPMRPP-82375 added a trigger to send a password change email

* EPMRPP-82375 updated YouTube links and footer text

* EPMRPP-82375 fixed test

* EPMRPP-82375 minor change in index template (#1683)

* EPMRPP-82545 || Update validation for Widgets (#1694)

* EPMRPP-82545 Updated validation for Widgets

* EPMRPP-82545 changed indent

* Update commons dao

* Master merge to 5.7.5 (#1695)

* EPMRPP-79211 || Changed Minio interface to JCloud

* EPMRPP-79211 || Updated DataStore configuration and properties

* EPMRPP-79211 || Updated docker-compose with right BinaryStore value

* EPMRPP-79211 || Update commons dao version

* Update commons dao dependency to 5.7.4

* EPMRPP-80865|| Update bom and other versions (#1663)

5.7.4 || Update bom and other versions

* [Gradle Release Plugin] - new version commit:  '5.7.5'.

---------

Co-authored-by: miracle8484 <76156909+miracle8484@users.noreply.github.com>
Co-authored-by: reportportal.io <support@reportportal.io>

* EPMRPP-83030 || Create RC branch

* Update version

* EPMRPP-82707 || Add single bucket configuration (#1696)

* EPMRPP-82707 || Add single bucket configuration

* EPMRPP-82707 || Refactor according to check style

* EPMRPP-82707 || Refactor according to check style

* EPMRPP-82707 || Change delete plguin from data store logic

* EPMRPP-83068 || Fix checkstyle

* EPMRPP-83068 || Update Admin permissions. Read/Write permissions without assign. (#1700)

* EPMRPP-83068 || Update Admin permissions. Read/Write permissions without assign.
---------

Co-authored-by: Andrei Piankouski <andrei_piankouski@epam.com>

* Merge master to hotfix/next (#1702)

* EPMRPP-79211 || Changed Minio interface to JCloud

* EPMRPP-79211 || Updated DataStore configuration and properties

* EPMRPP-79211 || Updated docker-compose with right BinaryStore value

* EPMRPP-79211 || Update commons dao version

* Update commons dao dependency to 5.7.4

* EPMRPP-80865|| Update bom and other versions (#1663)

5.7.4 || Update bom and other versions

* [Gradle Release Plugin] - new version commit:  '5.7.5'.

* 23.1 release  (#1698)

* Update spring boot version to fix CVE-2022-22965

* EPMRPP-76845 || Update spring boot

* Update Jenkinsfile

* EPMRPP-77678 || Description length increased to 2048

* EPMRPP-77678 || Redundant import fix

* EPMRPP-79737 || Fix vulnerabilities and update libraries version (#1624)

* EPMRPP-79136 || Add retrieving all logs with it's locations (#1619)

* EPMRPP-79136 || Add retrieving all logs with it's locations

* EPMRPP-79136 || Add filtering by log level and item type

* EPMRPP-79136 || Change response to save correct ordering

* EPMRPP-79136 || Fix exclude passed logs parameter

* EPMRPP-79136 || Override page size limit

* EPMRPP-79136 || Fix retrieving with passed logs exclusion

* Update Jenkinsfile-candidate

* EPMRPP-79136 || Update dao version

* EPMRPP-80383 || Notifications. AND/OR attribute option

* EPMRPP-80744 || Change email on the API page

* EPMRPP-80601 || Timeline widget. Remove empty content

* EPMRPP-80744 || Add item attribute max length validation (#1640)

EPMRPP-80744 || Add item attribute max length validation

* EPMRPP-81136 || Incorrect 'startTime' value is reported for tests via 'Import' functionality

Co-authored-by: Andrei Piankouski <andrei_piankouski@epam.com>

* EPMRPP-81046 || Impossible to report test items to project with "demo" name

* EPMRPP-81019 || Launch import. Error 'org.hibernate.exception.DataException: could not execute statement' occurs on importing launch (#1645)

* EPMRPP-81052 || Most failed test-cases table (TOP-20). Increase the amount of items to be displayed on widget from 20 to 50 or 100

* EPMRPP-80606 || Cut notification attribute to max length (#1650)

EPMRPP-80606 || Cut attributes to max length

* EPMRPP-81029 || There is no validation for the creation of dashboards exceeding the limit (#1651)

* Revert "EPMRPP-81029 || There is no validation for the creation of dashboards exceeding the limit (#1651)"

This reverts commit 13a49a644635f76b9b38dcb7ea41f7601d1fab04.

* EPMRPP-81029 || There is no validation for the creation of dashboards exceeding the limit

* EPMRPP-80606 || Update filter attribute cut logic (#1652)

* EPMRPP-78741 || Remove duplicate onboarding endpoint (#1653)

* EPMRPP-80606 || UserFilter cut attribute refactor (#1655)

* EPMRPP-81358 || Fix vulnerabilities

* EPMRPP-81193 || Wrong error code and message when creating notification rule without mandatory field

* EPMRPP-81202 || Widget 'Flaky test cases table (TOP-50). It is possible to create widget with invalid 'Launches count' value via API (#1670)

* EPMRPP-81202 || Widget 'Flaky test cases table (TOP-50). It is possible to create widget with invalid 'Launches count' value via API

* EPMRPP-81202 || Change migration brunch

* EPMRPP-81202 || Replace tab to spaces

---------

Co-authored-by: Andrei Piankouski <andrei_piankouski@epam.com>

* EPMRPP-82300 || Typo in the error message when creating 'Flaky test cases table (TOP-50)' widget with some invalid values via API (#1674)

* EPMRPP-82300-fix-typo-error uploaded commons-model dependency and fixed tests in service-api

* EPMRPP-82300-fix-typo-error fixed tests in service-api

* Epmrpp 78258 move acl (#1667)

* EPMRPP-81233 || Move ACL tasks from RP-23.3 to RP-23.1

* EPMRPP-72320 || Fix unit tests

* EPMRPP-81233 || Move ACL tasks from RP-23.3 to RP-23.1

* EPMRPP-81233 || Update bom

---------

Co-authored-by: Pavel Bortnik <pavel_bortnik@epam.com>
Co-authored-by: Andrei Piankouski <andrei_piankouski@epam.com>

* EPMRPP-81050 || Most Failed test-cases table widget. Increase the amount of items to be displayed on widget from 20 to 50

* EPMRPP-82116 || Update Notification template after launch finish (#1673)

* EPMRPP-82116 Updated template for Notifications after launch finish

* EPMRPP-82116 edited invitation templates

* Update common model

* EPMRPP-81362 || Fix security vulnerabilities (#1671)

* EPMRPP-82116 || Update Notification template after launch finish (removed attachments) (#1678)

* EPMRPP-82116-remove-attachments removed vk and fb attachments from specific email notifications

* EPMRPP-82116-remove-attachments removed vk and fb links from all templates

* EPMRPP-81154 added xml to api description and added file size check (#1677)

* EPMRPP-81970 || Autocomplete in Recipients filed on Notifications tab in Project settings should show options starting from 1 symbol (#1681)

* EPMRPP-81970 changed symbol limit from 3 to 1

* EPMRPP-81970 added code formatting

* EPMRPP-82375 || Implement notification when changing password and make some template updates (#1682)

* EPMRPP-82375 added a trigger to send a password change email

* EPMRPP-82375 updated YouTube links and footer text

* EPMRPP-82375 fixed test

* EPMRPP-82375 minor change in index template (#1683)

* EPMRPP-82545 || Update validation for Widgets (#1694)

* EPMRPP-82545 Updated validation for Widgets

* EPMRPP-82545 changed indent

* Update commons dao

* Master merge to 5.7.5 (#1695)

* EPMRPP-79211 || Changed Minio interface to JCloud

* EPMRPP-79211 || Updated DataStore configuration and properties

* EPMRPP-79211 || Updated docker-compose with right BinaryStore value

* EPMRPP-79211 || Update commons dao version

* Update commons dao dependency to 5.7.4

* EPMRPP-80865|| Update bom and other versions (#1663)

5.7.4 || Update bom and other versions

* [Gradle Release Plugin] - new version commit:  '5.7.5'.

---------

Co-authored-by: miracle8484 <76156909+miracle8484@users.noreply.github.com>
Co-authored-by: reportportal.io <support@reportportal.io>

* EPMRPP-83030 || Create RC branch

* Update version

* EPMRPP-83239 || Impossible to change password without Email Server integration

* EPMRPP-83239 || Impossible to change password without Email Server integration
---------

Co-authored-by: Andrei Piankouski <andrei_piankouski@epam.com>

* EPMRPP-78998 || Update dao

---------

Co-authored-by: Maksim Antonov <Maksim_Antonov@epam.com>
Co-authored-by: Ivan_Budayeu <Skileton2018>
Co-authored-by: miracle8484 <76156909+miracle8484@users.noreply.github.com>
Co-authored-by: Pavel Bortnik <pavel_bortnik@epam.com>
Co-authored-by: Ivan_Kustau <Ivan_Kustau@epam.com>
Co-authored-by: Ivan Kustau <86599591+IvanKustau@users.noreply.github.com>
Co-authored-by: Andrei Piankouski <andrei_piankouski@epam.com>
Co-authored-by: rkukharenka <125865748+rkukharenka@users.noreply.github.com>
Co-authored-by: reportportal.io <support@reportportal.io>

* Update release.yml

* [Gradle Release Plugin] - new version commit:  '5.8.1'.

---------

Co-authored-by: Ivan_Kustau <Ivan_Kustau@epam.com>
Co-authored-by: miracle8484 <76156909+miracle8484@users.noreply.github.com>
Co-authored-by: Ivan Kustau <86599591+IvanKustau@users.noreply.github.com>
Co-authored-by: reportportal.io <support@reportportal.io>
Co-authored-by: Maksim Antonov <Maksim_Antonov@epam.com>
Co-authored-by: Pavel Bortnik <pavel_bortnik@epam.com>
Co-authored-by: Andrei Piankouski <andrei_piankouski@epam.com>
Co-authored-by: rkukharenka <125865748+rkukharenka@users.noreply.github.com>

* Update commons-dao version

* Add removeScripts task to Jenkins

* Epmrpp 83130 || Update the token generation and its storage (#1706)

* Create Jenkinsfile-release

Added Jenkinsfile-release

* Epmrpp 83130 || api key trim (#1707)

* EPMRPP-83130 || Trim Api key.

* EPMRPP-83130 || Trim Api key.

---------

Co-authored-by: Andre Piankouski <andrei_piankouski@epam.com>

* EPMRPP-83098 || Update all datastore variables naming (#1709)

* EPMRPP-83536 || Reporting with new API Keys (#1708)

* EPMRPP-83536 || Reporting with new API Keys

---------

Co-authored-by: Andrei Piankouski <andrei_piankouski@epam.com>

* EPMRPP-84251 || Fix test

* EPMRPP-84251 || Fix test

* EPMRPP-84251 || Decrease branch limits

---------

Co-authored-by: Maksim Antonov <Maksim_Antonov@epam.com>
Co-authored-by: Ivan_Budayeu <Skileton2018>
Co-authored-by: miracle8484 <76156909+miracle8484@users.noreply.github.com>
Co-authored-by: Pavel Bortnik <pavel_bortnik@epam.com>
Co-authored-by: Ivan_Kustau <Ivan_Kustau@epam.com>
Co-authored-by: Ivan Kustau <86599591+IvanKustau@users.noreply.github.com>
Co-authored-by: Andrei Piankouski <andrei_piankouski@epam.com>
Co-authored-by: rkukharenka <125865748+rkukharenka@users.noreply.github.com>
Co-authored-by: reportportal.io <support@reportportal.io>
Co-authored-by: Hleb Kanonik <hleb_kanonik@epam.com>

* EPMRPP-83882 || Add normalizing project name in ProjectExtractor (#1714) (#1715)

* Fix migration scripts

* EPMRPP-84705 || Remove vk and fb from email templates (#1773)

* EPMRPP-85137 || Remove cookie auth for plugin files endpoint (#1775)

* EPMRPP-85137 || Removed cookie auth for plugin files endpoint

* EPMRPP-85137 || delete test by removed endpoint

* EPMRPP-84310 || added check for integration type (#1777)

* EPMRPP-81792 || Fix names validation

* EPMRPP-81753 || Limit test item nesting

* added github.run_number to rc build

* EPMRPP-54905 || Launch report for one project is allowed for export by the members and customers of another project

* EPMRPP-86199 || 500 Server Error when trying to delete deleted API Key (#1789)

* EPMRPP-86199 || 500 Server Error when trying to delete deleted API Key

* EPMRPP-86199 || Update rules

* EPMRPP-84794 || Add new type of event on creating invitation link

* EPMRPP-78737 || Fix luanch attribute link

* EPMRPP-84794 || Change Object Name

* EPMRPP-79633 || Remove staled notifications endpoint (#1792)

* EPMRPP-80519 || Add project attachments deletion (#1793)

* EPMRPP-80519 || Add project attachments deletion

* Update dao version

* EPMRPP-83956 || Remove null from email link after launch force finish (#1795)

* EPMRPP-83956 || Add slash in url

* EPMRPP-86221 || Fix test

* EPMRPP-86221 || Fix test

* EPMRPP-86221 || Fix test

* EPMRPP-86660 || Notification rule names are empty after the deploy in case any notification was created on the project

* EPMRPP-86660 || Notification rule names are empty after the deploy in case any notification was created on the project

* EPMRPP-86363 || updated commons-dao version

* EPMRPP-86348 || Implement immediate pattern analysis on test item fin… (#1798)

* EPMRPP-86348 || Implement immediate pattern analysis on test item finish event.

* EPMRPP-86348 || Add headers

* EPMRPP-86348 || Update dao version

* EPMRPP-85806 || added timestamps with offsets handling (#1800)

* EPMRPP-84226 || Remove access token logic from the code (#1801)

* EPMRPP-84226 || Remove access token logic from the code

* EPMRPP-84226 || Update dao

* EPMRPP-84226 || Cut attribute in notifications

* EPMRPP-86361 || Add possibility to filter items by composite system (#1804)

* EPMRPP-86348 || Implement immediate pattern analysis on test item finish event.

* EPMRPP-86348 || Add headers

* EPMRPP-86348 || Update dao version

* EPMRPP-86361 || Filter items with immediatePa system attribute on launch finish pattern analysis

* EPMRPP-86361 || Update dao

* EPMRPP-86361 || Add missed headers

* EPMRPP-86361 || Return back analyzer existence check

* EPMRPP-86400 || Fix the problem with 'undefined' for exported filename (#1794)

* EPMRPP-86208 || Update api key cache resolver

* EPMRPP-86542 || fixed loading resources for email (#1816)

* EPMRPP-85520 || Improve the filtering option 'User' on Project Monitoring page

* EPMRPP-86219 || Implement immediate AutoAnalyze on TestItemFinishing (#1818)

* EPMRPP-86775 || Add possibility to have no auth in ES

* EPMRPP-86947 || ImmediateAA works when immediateAA attribute is not marked as system

* EPMRPP-86775 || Add possibility to have no auth in ES

* EPMRPP-86945 ||Check application name into Swagger base-path (#1820)

* EPMRPP-86359 || Implement pattern analyzer handling using rabbitmq queue (#1822)

* EPMRPP-86359 || Implement pattern analyzer handling using rabbitmq queue

* EPMRPP-86361 || Add some checkstyle refactoring

* EPMRPP-86359 || Change default single item prop value

* EPMRPP-86967 || ImmediateAA works when Step finishes with immediateAA:false attribute

* EPMRPP-86742 || extended launch import response (#1821)

* EPMRPP-86742 || extended launch import response

* EPMRPP-86969 || ImmediateAA works not only for TI defect type (#1824)

* EPMRPP-86967 || Add null check

* EPMRPP-86742 || message fix (#1825)

* EPMRPP-86969 || ImmediateAA works not only for TI defect type

* EPMRPP-86742 || launch name fix (#1826)

* EPMRPP-86742 || launch name fix

* EPMRPP-86969 || ImmediateAA works not only for TI defect type

* EPMRPP-84054 || Add DeprecatedUserController and updated route for UserController (#1827)

* EPMRPP-84054 || Add DeprecatedUserController and updated route for UserController

* EPMRPP-84054 || Update DeprecatedUserController

* EPMRPP-86466 || changed activity parameters upon creating invited user (#1828)

* EPMRPP-80574 || Update dao version. Remove redundant encryptor (#1830)

* EPMRPP-87028 || Update security configuration for user endpoints (#1831)

* EPMRPP-86812 || extended actuator with "jobs" module info (#1832)

* EPMRPP-86867 || updated logos in email templates (#1833)

* EPMRPP-86867 || updated logos in email templates

* EPMRPP-80574 || Update dao version.

* EPMRPP-86248 || Auto-Analysis should skip already analyzed items on launch finish

* EPMRPP-80989 || Add attribute operator in duplicate operation check (#1835)

* EPMRPP-80989 || Add attribute operator in duplicate operation check

* EPMRPP-80989 || Fix unit tests

* EPMRPP-86109 || changed response model for GET {activeProject}/activity/item/{itemId} (#1838)

Co-authored-by: rkukharenka <ryhor_kukharenka@epam.com>

* EPMRPP-86867 || updated icons || re-organized template directory structure (#1834)

* EPMRPP-86867 || updated icons || re-organized template directory structure

* EPMRPP-86867 github icon fix (#1840)

* EPMRPP-86743 || Move all launch fields to the request body for import (#1839)

* EPMRPP-80989 || Add attribute operator in duplicate operation check

* EPMRPP-80989 || Fix unit tests

* EPMRPP-86743 || Move all launch fields to the request body for import controller

* EPMRPP-86743 || Update commons-model

* EPMRPP-86743 || Add import launch json request part

* EPMRPP-86743 || Update commons-model

* EPMRPP-86743 || Add import rq to swagger param

* EPMRPP-86361 || Add swagger docs

* EPMRPP-79482 || Add JCloud filesystem implementation (#1842)

* Update commons-dao version

* EPMRPP-87044 updated commons-dao version (#1843)

* Add GitHub actions for building dev image

* Patch Action Build develop Docker image

* EPMRPP-87394 || Add configrurable connection factory for pattern anal… (#1845)

* EPMRPP-87394 || Add configrurable connection factory for pattern analysis. Provide default parameters 'single-item:true', 'prefetchCount:0', 'consumersCount:1', 'connectionTimeout:10min'

* EPMRPP-87394 || Remvoe connection timeout

* EPMRPP-87394 || Fix tests

* EPMRPP-87394 || Provide default params

* EPMRPP-87394 || Fix tests

* Hotfix 5.10.1 (#1837)

* EPMRPP-87223 || Fix duplicated logs

(cherry picked from commit f0e8cbb36956f89e53f5484b0a4668ca656c9ca1)

* [Gradle Release Plugin] - new version commit:  '5.10.2'.

(cherry picked from commit afb083d7738f4af8371fa697fa25cf01529985bf)

* EPMRPP-87332 || Send launchNumber to analyzer

* EPMRPP-87394 || Add missed constuctor

* EPMRPP-87482 || Fix potential npe (#1847)

* EPMRPP-87394 || Add a separate queue per pattern template type (#1849)

* EPMRPP-87382 fixed user attachments double removal (#1848)

* EPMRPP-87173 updated commons-dao (#1850)

* EPMRPP-87173 updated commons-dao

* EPMRPP-87173 updated commons-dao

* EPMRPP-87173 fixed tests

* EPMRPP-87537 || Launch number not indexing (#1851)

* EPMRPP-87537 || Launch number not indexing

* EPMRPP-87537 || Update SuggestInfo

* EMPRPP-87316 || Add proper exception handling. Update versions (#1853)

* EMPRPP-87316 || Add proper exception handling. Update versions

* EMPRPP-87316 || Fix tests

* EPMRPP-87493 || Update build.gradle (#1857)

* Update build.gradle

* EPMRPP-87493 || Fix tests

* EPMRPP-87493 || Fix compile errors

* EPMRPP-87493 || Fix compile errors

* EPRMPP-82591 || Logs with attachments null pointer (#1858)

* EPMRPP-82591 || Add check for null file path

* EPMRPP-82591 || Add waiting for log to be saved before attachment creation

* EPMRPP-82591 || Update dao version

* EPMRPP-82591 || Update dao version

* EPMRPP-87271 updated commons dao (fix filtering by date) (#1855)

* EPMRPP-87271 updated commons dao (fix filtering by date)

* EPMRPP-87187 || Parent status is recalculated only when status is undefined (#1859)

* Update build-rc-image.yaml

* EPMRPP-87516 || Rename immediateAA parameter

* Platform specification for Docker build stage

* EPMRPP-87590 || Replace ElasticSearch with search engine

* Update build workflows for Docker images (#1862)

* EPMRPP-87591 || Page crashes when logging into RP

* EPMRPP-87613 || Add back compatibility with older plugins

* EPMRPP-87613 || Fix unit tests

* Replace workflow build with java-checks (#1863)

* EPMRPP-87590 || Capitalize article

* EPMRPP-87591 || Page crashes when logging into RP

* EPMRPP-86835 || Update releaseMode to use Maven instead of Github (#1870)

* EPMRPP-86835 || Update releaseMode to use Maven instead of Github

* EPMRPP-86835 || Update libs version

* EPMRPP-87593 fix CVEs (#1868)

* EPMRPP-87593 fix CVEs

* EPMRPP-87421 fixed attachments handling (#1871)

* EPMRPP-87421 fixed attachments handling

* EPMRPP-87692 set auto analyzer mode "All launches with the same name"  by default (#1872)

* EPMRPP-87692 set auto analyzer mode "All launches with the same name" by default

* EPMRPP-87813 || Send to the analyzer the id of previous launch

* EPMRPP-88291 || Fix case when child recalculates parent status when status is already defined (#1874)

* EPMRPP-88291 || Fix case when child recalculates parent status when status is already defined

* EPMRPP-88291 || Fix tests

* EPMRPP-87596 || No possibility to switch on/off AA and Unique Errors from UI

* Update build.gradle (#1878)

* EPMRPP-87433  || Update build.gradle (#1879)

* EPMRPP-81547 || Java code documentation fixes for Service API (#1880)

* EPMRPP-81547 || Java code documentation fixes for Service API

* migrate to java 21 (#1877)

EPMRPP-87047 || migrate to java 21 and gradle 8.4

* EPMRPP-88359 || Remove parent status recalculation when status changed (#1882)

* EPMRPP-88359 || Remove parent status recalculation when status changed

* EPMRPP-88359 || Make update parent status only for test item update

* EPMRPP-87547 || Fix notification rule check when only attribute value is provided (#1883)

* Update build-dev-image.yml

* Update build-feature-image.yaml

* EPMRPP-87547 || Fix case when all attributes are matched and ALL operator (#1885)

* EPMRPP-87401 || Add openmetrics text converter (#1886)

* EPMRPP-88577 || Analyzer uses information from deleted launches (#1891)

* EPMRPP-88577 || Analyzer uses information from deleted launches

* EPMRPP-88577 || Remove waiting rabbitMQ response

* EPMRPP-88638 || Add name validation for launch import endpoint (#1892)

Co-authored-by: Pavel Bortnik <pbortnik1207@gmail.com>

* EPMRPP-88636 || Change system attribute for skipped is not issue (#1893)

Co-authored-by: Pavel Bortnik <pbortnik1207@gmail.com>

* EPMRPP-88727 || Support null value for name in import (#1895)

* Add prefix and postfix for filesystem (#1896)

* EPMRPP-88726 downgrade jasperreports version (#1897)

* EPMRPP-88726 downgrade jasperreports version

* EPMRPP-88726 fix commons-dao reference

* rc/5.11.0 || Update versions

* rc/5.11.0 || Downgrade apache poi version for back compatibility with jasperreports

* rc/5.11.0 || Change to release version if not release mode

* EPMRPP-88915 || Pattern Analysis of REGEX type doesn't work (#1906)

* EPMRPP-88955 || increase thread executor pool size (#1908)

Co-authored-by: APiankouski <109206864+apiankouski@users.noreply.github.com>

* EPMRPP-82292 || Enable detailed health endpoint (#1796)

* EPMRPP-82292 || Enable detailed health endpoint

* EPMRPP-82292 || Enable detailed health endpoint

* rc/5.11.0 || Update commons version

* rc/5.11.0 || Perf. Add task executor for log creation handling

* rc/5.11.0 || Update dao version

* rc/5.11.0 || Update dao version

* rc/5.11.0 || Update dao version

---------

Co-authored-by: Chingiskhan <Chingiskhan_Kalanov@epam.com>
Co-authored-by: miracle8484 <76156909+miracle8484@users.noreply.github.com>
Co-authored-by: Hleb Kanonik <esscyh@gmail.com>
Co-authored-by: Ivan_Budayeu <Skileton2018>
Co-authored-by: Ivan <budaevqwerty@gmail.com>
Co-authored-by: Maksim Antonov <Maksim_Antonov@epam.com>
Co-authored-by: APiankouski <109206864+APiankouski@users.noreply.github.com>
Co-authored-by: Andrei Piankouski <andrei.piankouski@ukg.com>
Co-authored-by: Dmitriy Gumeniuk <dmitriy_gumeniuk@epam.com>
Co-authored-by: Ivan_Kustau <Ivan_Kustau@epam.com>
Co-authored-by: Vadzim Hushchanskou <vadzim_hushchanskou@epam.com>
Co-authored-by: Vadzim Hushchanskou <HardNorth@users.noreply.github.com>
Co-authored-by: Andrei Piankouski <andrei_piankouski@epam.com>
Co-authored-by: Ivan Kustau <86599591+IvanKustau@users.noreply.github.com>
Co-authored-by: reportportal.io <support@reportportal.io>
Co-authored-by: Ryhor <125865748+rkukharenka@users.noreply.github.com>
Co-authored-by: Hleb Kanonik <hleb_kanonik@epam.com>
Co-authored-by: siarhei_hrabko <siarhei_hrabko@epam.com>
Co-authored-by: Siarhei Hrabko <45555481+grabsefx@users.noreply.github.com>
Co-authored-by: Reingold Shekhtel <13565058+raikbitters@users.noreply.github.com>
Co-authored-by: rkukharenka <ryhor_kukharenka@epam.com>
Co-authored-by: raikbitters <raikbitters@gmail.com>
Co-authored-by: Dzmitry Kosarau <Dzmitry_Kosarau@epam.com>
Co-authored-by: Pavel Bortnik <pbortnik1207@gmail.com>
---
 .github/workflows/build-dev-image.yml         |   35 +
 .github/workflows/build-feature-image.yaml    |   37 +
 .github/workflows/build-rc-image.yaml         |   43 +
 .github/workflows/build.yml                   |   40 -
 .github/workflows/java-checks.yml             |   22 +
 .github/workflows/manually-release.yml        |    6 +-
 .github/workflows/rc.yaml                     |   80 -
 .github/workflows/release.yml                 |    6 +-
 Dockerfile                                    |   10 +-
 README.md                                     |    6 +-
 build.gradle                                  |  165 +-
 docker-compose.yml                            |    2 +-
 gradle.properties                             |    3 +-
 gradle/wrapper/gradle-wrapper.jar             |  Bin 58702 -> 0 bytes
 gradle/wrapper/gradle-wrapper.properties      |    2 +-
 gradlew                                       |  282 ++-
 gradlew.bat                                   |   38 +-
 postman/RpCollection.postman_collection.json  |  802 +++----
 postman/service-api.postman_collection.json   |   92 +-
 project-properties.gradle                     |   12 +-
 sealights.gradle                              |   29 -
 .../ta/reportportal/auth/ApiKeyUtils.java     |    3 +
 .../auth/PermissionsRegisterBean.java         |   55 +-
 .../reportportal/auth/ReportPortalClient.java |    6 +-
 .../reportportal/auth/UserRoleHierarchy.java  |  126 +-
 ...ortPortalAclAuthorizationStrategyImpl.java |   39 +-
 .../RegisteredUserAuthenticator.java          |   40 +-
 .../auth/authenticator/UserAuthenticator.java |    2 +-
 .../basic/DatabaseUserDetailsService.java     |   54 +-
 .../UiAuthenticationFailureEventHandler.java  |   90 +-
 .../UiAuthenticationSuccessEventHandler.java  |   21 +-
 .../auth/event/UiUserSignedInEvent.java       |   11 +-
 .../permissions/BaseProjectPermission.java    |   86 +-
 .../auth/permissions/LookupPermission.java    |   15 +-
 .../permissions/NotCustomerPermission.java    |   29 +-
 .../auth/permissions/Permission.java          |   22 +-
 .../PermissionEvaluatorFactoryBean.java       |   69 +-
 .../auth/permissions/ProjectAuthority.java    |   65 +-
 .../permissions/ProjectManagerPermission.java |   30 +-
 .../ReportPortalPermissionEvaluator.java      |   99 +-
 .../auth/permissions/ReporterPermission.java  |   24 +-
 .../ta/reportportal/auth/util/AuthUtils.java  |   97 +-
 .../ta/reportportal/auth/util/Encryptor.java  |   60 -
 .../core/ElementsCounterService.java          |   92 +
 .../core/activity/ActivityHandler.java        |   75 +-
 .../activity/impl/ActivityHandlerImpl.java    |    7 +-
 .../activityevent/ActivityEventHandler.java   |   11 +
 .../impl/ActivityEventHandlerImpl.java        |   21 +
 .../core/admin/ServerAdminHandler.java        |   27 +-
 .../core/admin/ServerAdminHandlerImpl.java    |   79 +-
 .../core/analyzer/auto/AnalyzerService.java   |   29 +-
 .../analyzer/auto/AnalyzerServiceAsync.java   |   33 +-
 .../core/analyzer/auto/LogIndexer.java        |  114 +-
 .../core/analyzer/auto/SearchLogService.java  |    3 +-
 .../auto/client/AnalyzerServiceClient.java    |  103 +-
 .../auto/client/IndexerServiceClient.java     |  100 +-
 .../auto/client/RabbitMqManagementClient.java |    3 +-
 .../impl/AnalyzerServiceClientImpl.java       |  249 ++-
 .../auto/client/impl/AnalyzerUtils.java       |   76 +-
 .../client/impl/IndexerServiceClientImpl.java |  264 ++-
 .../RabbitMqManagementClientTemplate.java     |   56 +-
 .../auto/client/model/IndexDefectsUpdate.java |   72 +-
 .../auto/client/model/IndexItemsRemove.java   |   72 +-
 .../auto/client/model/IndexLaunchRemove.java  |   71 +-
 .../auto/client/model/SuggestInfo.java        |  318 +--
 .../analyzer/auto/client/model/SuggestRq.java |  141 +-
 .../client/model/cluster/ClusterData.java     |   46 +-
 .../client/model/cluster/ClusterInfoRs.java   |   65 +-
 .../model/cluster/GenerateClustersRq.java     |   74 +-
 .../auto/impl/AnalyzerServiceAsyncImpl.java   |   33 +-
 .../auto/impl/AnalyzerServiceImpl.java        |  267 ++-
 .../auto/impl/AnalyzerStatusCache.java        |  168 +-
 .../analyzer/auto/impl/AnalyzerUtils.java     |  174 +-
 .../analyzer/auto/impl/LogIndexerService.java |  271 +--
 .../auto/impl/SearchLogServiceImpl.java       |  313 +--
 .../auto/impl/SuggestItemService.java         |  279 +--
 .../analyzer/auto/impl/SuggestedItem.java     |   43 +-
 .../impl/preparer/LaunchPreparerService.java  |   10 +-
 .../preparer/LaunchPreparerServiceImpl.java   |  197 +-
 .../preparer/TestItemPreparerService.java     |   19 +-
 .../preparer/TestItemPreparerServiceImpl.java |   89 +-
 .../auto/indexer/BatchLogIndexer.java         |  250 ++-
 .../auto/indexer/IndexerStatusCache.java      |   41 +-
 .../CollectingAutoAnalysisStarter.java        |   86 +-
 .../starter/LaunchAutoAnalysisStarter.java    |    2 +-
 .../decorator/AsyncAutoAnalysisStarter.java   |   23 +-
 .../decorator/AutoAnalysisEnabledStarter.java |   20 +-
 .../decorator/ExistingAnalyzerStarter.java    |   40 +-
 .../IndexingAutoAnalysisStarter.java          |   32 +-
 .../analyze/AnalyzeCollectorConfig.java       |   50 +-
 .../analyze/AnalyzeCollectorFactory.java      |   14 +-
 .../analyze/AnalyzeItemsCollector.java        |   21 +-
 .../strategy/analyze/AnalyzeItemsMode.java    |   52 +-
 .../analyze/AutoAnalyzedCollector.java        |   47 +-
 .../analyze/IgnoreImmediateCollector.java     |   59 +
 .../analyze/ManuallyAnalyzedCollector.java    |   58 +-
 .../analyze/ToInvestigateCollector.java       |   38 +-
 .../search/CurrentLaunchCollector.java        |   11 +-
 .../auto/strategy/search/FilterCollector.java |   66 +-
 .../strategy/search/LaunchNameCollector.java  |   39 +-
 .../search/SearchCollectorConfig.java         |   45 +-
 .../search/SearchCollectorFactory.java        |   14 +-
 .../search/SearchLaunchesCollector.java       |    5 +-
 .../auto/strategy/search/SearchLogsMode.java  |   26 +-
 .../core/analyzer/config/AnalyzerType.java    |   49 +-
 .../core/analyzer/config/AnalyzersConfig.java |   21 +-
 .../config/PatternAnalysisConfig.java         |   58 +-
 .../PatternAnalysisRabbitConfiguration.java   |   87 +
 .../config/StartLaunchAutoAnalysisConfig.java |   70 +-
 .../analyzer/pattern/PatternAnalyzer.java     |   43 -
 .../handler/ItemsPatternsAnalyzer.java}       |   39 +-
 .../impl/ItemsPatternAnalyzerImpl.java        |  110 +
 .../proxy/ItemsPatternAnalyzeConsumer.java    |   58 +
 .../handler/proxy/ItemsPatternAnalyzeDto.java |  103 +
 .../proxy/ItemsPatternAnalyzeProducer.java    |   80 +
 .../pattern/impl/PatternAnalyzerImpl.java     |  183 --
 .../selector/PatternAnalysisSelector.java     |   19 +-
 .../condition/PatternConditionProvider.java   |    3 +-
 .../PatternConditionProviderChain.java        |   53 +-
 .../AbstractPatternConditionProvider.java     |   34 +-
 .../AutoAnalyzedPatternConditionProvider.java |   19 +-
 ...diatePatternAnalysisConditionProvider.java |   48 +
 .../impl/ManualPatternConditionProvider.java  |   44 +-
 ...ToInvestigatePatternConditionProvider.java |   32 +-
 .../impl/AbstractPatternAnalysisSelector.java |   51 +-
 .../impl/RegexPatternAnalysisSelector.java    |   40 +-
 .../StringPartPatternAnalysisSelector.java    |   46 +-
 .../CreatePatternTemplateHandler.java         |   22 +-
 .../service/LaunchPatternAnalyzer.java        |   45 +
 .../CreatePatternTemplateHandlerImpl.java     |   46 +-
 .../CreateRegexPatternTemplateHandler.java    |   39 +-
 .../impl/LaunchPatternAnalyzerImpl.java       |  119 +
 .../AbstractLaunchAnalysisStrategy.java       |   45 +-
 .../strategy/LaunchAnalysisStrategy.java      |    3 +-
 .../strategy/LaunchAutoAnalysisStrategy.java  |  109 +-
 .../LaunchPatternAnalysisStrategy.java        |   52 +-
 .../core/annotation/Datastore.java            |    5 +-
 .../reportportal/core/annotation/Regular.java |    5 +-
 .../core/bts/handler/CreateTicketHandler.java |   23 +-
 .../handler/GetBugTrackingSystemHandler.java  |   11 +-
 .../core/bts/handler/GetTicketHandler.java    |   64 +-
 .../handler/impl/CreateTicketHandlerImpl.java |  120 +-
 .../impl/GetBugTrackingSystemHandlerImpl.java |  113 +-
 .../handler/impl/GetTicketHandlerImpl.java    |   93 +-
 .../core/configs/AspectConfig.java            |   20 +-
 .../core/configs/AttachmentSizeConfig.java    |  126 +-
 .../core/configs/BatchJobConfiguration.java   |   54 +-
 .../reportportal/core/configs/Conditions.java |   24 +-
 .../core/configs/DemoDataConfig.java          |   44 +-
 .../core/configs/EmailConfiguration.java      |   15 +-
 .../core/configs/ExecutorConfiguration.java   |  260 ++-
 .../core/configs/IntegrationConfig.java       |   38 +-
 .../ItemStatusChangingStrategyConfig.java     |   53 +-
 .../core/configs/JacksonConfiguration.java    |   26 +-
 .../core/configs/MergeStrategyConfig.java     |  111 +-
 .../core/configs/MultipartDataConfig.java     |   25 +-
 .../reportportal/core/configs/MvcConfig.java  |  361 +--
 .../core/configs/PluginConfiguration.java     |  199 +-
 .../core/configs/ProjectValidationConfig.java |   30 +-
 .../core/configs/ReportPortalApp.java         |   13 +-
 .../configs/ReportPortalClassLoadHelper.java  |   65 +-
 .../core/configs/SchedulerConfiguration.java  |  324 +--
 .../core/configs/SecurityConfiguration.java   |  289 +--
 .../core/configs/Swagger2Configuration.java   |  409 ++--
 .../core/configs/WidgetConfig.java            |  402 ++--
 .../core/configs/WidgetValidatorConfig.java   |  127 +-
 .../core/configs/XmlImportConfig.java         |    1 +
 .../auto/LaunchAutoAnalysisConfig.java        |   80 +-
 .../GenerateClusterPipelineConfig.java        |   71 +-
 .../DataProviderEvaluatorConfig.java          |   51 +-
 .../data/provider/DataProviderConfig.java     |   50 +-
 .../resolver/DataProviderResolverConfig.java  |   15 +-
 .../UniqueErrorAnalysisStarterConfig.java     |   18 +-
 .../event/listener/EventListenerConfig.java   |   34 +-
 .../event/publisher/EventPublisherConfig.java |   42 +-
 .../publisher/LoggingEventErrorHandler.java   |   10 +-
 .../subscriber/EventSubscriberConfig.java     |   73 +-
 .../rabbit/AnalyzerRabbitMqConfiguration.java |   67 +-
 .../BackgroundProcessingConfiguration.java    |   38 +-
 .../configs/rabbit/DeserializablePair.java    |   38 +-
 .../configs/rabbit/InternalConfiguration.java |  206 +-
 .../configs/rabbit/RabbitMqConfiguration.java |   90 +-
 .../rabbit/ReportingConfiguration.java        |  346 +--
 .../configs/remover/ContentRemoverConfig.java |   23 +-
 .../ResourceAttributeHandlerConfig.java       |   74 +-
 .../dashboard/CreateDashboardHandler.java     |   19 +-
 .../dashboard/DeleteDashboardHandler.java     |   19 +-
 .../core/dashboard/GetDashboardHandler.java   |    2 +
 .../dashboard/UpdateDashboardHandler.java     |   70 +-
 .../core/events/AnalysisEvent.java            |   53 +-
 .../ta/reportportal/core/events/Event.java    |    1 +
 .../reportportal/core/events/MessageBus.java  |   58 +-
 .../core/events/MessageBusImpl.java           |   20 +-
 .../core/events/ProjectIdAwareEvent.java      |    2 +-
 .../core/events/activity/AbstractEvent.java   |    4 +-
 .../core/events/activity/AroundEvent.java     |   26 +-
 .../core/events/activity/AssignUserEvent.java |   14 +-
 .../core/events/activity/BeforeEvent.java     |   26 +-
 .../activity/CreateInvitationLinkEvent.java   |   58 +
 .../events/activity/LaunchFinishedEvent.java  |   19 +-
 .../events/activity/UnassignUserEvent.java    |    3 +-
 .../events/activity/UserCreatedEvent.java     |   15 +-
 ...shedEvent.java => IssueResolvedEvent.java} |   38 +-
 .../events/activity/item/ItemRetryEvent.java  |   40 +-
 .../activity/item/TestItemFinishedEvent.java  |   43 +
 .../activity/util/ActivityDetailsUtil.java    |    1 +
 .../attachment/DeleteAttachmentEvent.java     |   55 +-
 .../AttachDefaultPhotoEventHandler.java       |   52 +-
 .../handler/ConfigurableEventHandler.java     |    2 +-
 .../handler/DefectTypeDeletedHandler.java     |   73 +-
 .../GenerateWidgetViewEventHandler.java       |   94 +-
 .../handler/StartAnalysisEventHandler.java    |   39 +-
 .../handler/TestItemRetryEventHandler.java    |   24 +-
 .../item/TestItemAutoAnalysisRunner.java      |   87 +
 .../handler/item/TestItemIndexRunner.java     |   40 +-
 .../item/TestItemPatternAnalysisRunner.java   |   55 +
 .../TestItemUniqueErrorAnalysisRunner.java    |   63 +-
 .../LaunchAnalysisFinishEventPublisher.java   |   24 +-
 .../launch/LaunchAutoAnalysisRunner.java      |   41 +-
 .../launch/LaunchNotificationRunner.java      |  393 ++--
 .../launch/LaunchPatternAnalysisRunner.java   |   45 +-
 .../LaunchUniqueErrorAnalysisRunner.java      |   47 +-
 .../listener/LaunchFinishedEventListener.java |   27 +-
 ...aunchUniqueErrorAnalysisEventListener.java |   30 +-
 .../TestItemFinishedEventListener.java        |   28 +-
 .../TestItemIssueResolvedEventListener.java   |   41 +
 ...DelegatingApplicationEventMulticaster.java |  122 +-
 .../events/subscriber/EventSubscriber.java    |    2 +-
 .../ProjectConfigDelegatingSubscriber.java    |   28 +-
 ...enerateComponentHealthCheckTableEvent.java |   56 +-
 .../widget/GenerateWidgetViewEvent.java       |   32 +-
 .../core/file/DeleteFilesHandler.java         |   68 +-
 .../core/file/GetFileHandler.java             |   52 +-
 .../core/file/impl/GetFileHandlerImpl.java    |   83 +-
 .../core/filter/DeleteUserFilterHandler.java  |   19 +-
 .../core/filter/SearchCriteriaService.java    |    2 -
 .../core/filter/UpdateUserFilterHandler.java  |   60 +-
 .../impl/DeleteUserFilterHandlerImpl.java     |    8 +-
 .../filter/impl/GetUserFilterHandlerImpl.java |   53 +-
 .../impl/UpdateUserFilterHandlerImpl.java     |   97 +-
 .../predefined/PredefinedFilterBuilder.java   |   22 +-
 .../predefined/PredefinedFilterType.java      |   29 +-
 .../filter/predefined/PredefinedFilters.java  |    5 -
 .../AbstractFinishHierarchyHandler.java       |  363 ++--
 .../hierarchy/FinishHierarchyHandler.java     |   21 +-
 .../impl/FinishLaunchHierarchyHandler.java    |   75 +-
 .../impl/FinishTestItemHierarchyHandler.java  |   79 +-
 .../core/imprt/FileExtensionConstant.java     |    6 +-
 .../core/imprt/ImportLaunchHandler.java       |    6 +-
 .../core/imprt/ImportLaunchHandlerImpl.java   |  149 +-
 .../imprt/impl/AbstractImportStrategy.java    |  122 +-
 .../core/imprt/impl/DateUtils.java            |   32 +-
 .../core/imprt/impl/ImportStrategy.java       |   26 +-
 .../imprt/impl/ImportStrategyFactory.java     |   20 +-
 .../imprt/impl/ImportStrategyFactoryImpl.java |   36 +-
 .../core/imprt/impl/ImportType.java           |    9 +-
 .../core/imprt/impl/ParseResults.java         |   53 +-
 .../core/imprt/impl/XmlImportStrategy.java    |   27 +-
 .../core/imprt/impl/ZipImportStrategy.java    |   33 +-
 .../imprt/impl/junit/XunitImportHandler.java  |   95 +-
 .../core/imprt/impl/junit/XunitParseJob.java  |    4 +-
 .../integration/CreateIntegrationHandler.java |    1 +
 .../ExecuteIntegrationHandler.java            |   61 +-
 .../integration/GetIntegrationHandler.java    |  114 +-
 .../impl/CreateIntegrationHandlerImpl.java    |   10 +-
 .../impl/ExecuteIntegrationHandlerImpl.java   |  172 +-
 .../impl/GetIntegrationHandlerImpl.java       |  408 ++--
 .../integration/plugin/GetPluginHandler.java  |   20 +-
 .../core/integration/plugin/PluginLoader.java |  148 +-
 .../plugin/binary/PluginFilesProvider.java    |   76 +
 .../plugin/impl/GetPluginHandlerImpl.java     |   39 +-
 .../util/AzureIntegrationService.java         |   35 +-
 .../util/BasicIntegrationServiceImpl.java     |  189 +-
 .../util/BtsIntegrationService.java           |  214 +-
 .../util/EmailServerIntegrationService.java   |  244 ++-
 .../integration/util/IntegrationService.java  |   11 +-
 .../util/SauceLabsIntegrationService.java     |   93 +-
 .../util/property/AuthProperties.java         |   16 +-
 .../util/property/BtsProperties.java          |   57 +-
 .../util/property/SauceLabsProperties.java    |   41 +-
 .../util/validator/IntegrationValidator.java  |   64 +-
 .../core/item/DeleteTestItemHandler.java      |   41 +-
 .../core/item/ExternalTicketHandler.java      |    9 +-
 .../core/item/FinishTestItemHandler.java      |   23 +-
 .../core/item/GetTestItemHandler.java         |  269 +--
 .../core/item/StartTestItemHandler.java       |   37 +-
 .../core/item/TestItemService.java            |   51 +-
 .../core/item/UpdateTestItemHandler.java      |   84 +-
 .../core/item/UpdateUniqueId.java             |  372 ++--
 .../history/ITestItemsHistoryService.java     |   66 +-
 .../item/history/TestItemsHistoryHandler.java |   28 +-
 .../core/item/identity/IdentityUtil.java      |   91 +-
 .../item/identity/TestCaseHashGenerator.java  |    3 +-
 .../identity/TestCaseHashGeneratorImpl.java   |   59 +-
 .../identity/TestItemUniqueIdGenerator.java   |  100 +-
 .../core/item/identity/UniqueIdGenerator.java |   32 +-
 .../item/impl/DeleteTestItemHandlerImpl.java  |  350 +--
 .../item/impl/ExternalTicketHandlerImpl.java  |  192 +-
 .../impl/FinishTestItemHandlerAsyncImpl.java  |   66 +-
 .../item/impl/FinishTestItemHandlerImpl.java  |  691 +++---
 .../core/item/impl/IssueTypeHandler.java      |   63 +-
 .../core/item/impl/LaunchAccessValidator.java |   26 +-
 .../item/impl/LaunchAccessValidatorImpl.java  |   71 +-
 .../impl/StartTestItemHandlerAsyncImpl.java   |  107 +-
 .../item/impl/StartTestItemHandlerImpl.java   |  334 +--
 .../item/impl/UpdateTestItemHandlerImpl.java  |  632 +++---
 .../impl/filter/updater/FilterUpdater.java    |    2 +-
 .../updater/IssueTypeConditionReplacer.java   |   62 +-
 .../impl/history/ItemHistoryBaselineEnum.java |   72 +-
 .../history/TestItemsHistoryHandlerImpl.java  |  253 ++-
 .../history/param/HistoryRequestParams.java   |  196 +-
 .../history/provider/HistoryProvider.java     |   26 +-
 .../provider/HistoryProviderFactory.java      |   23 +-
 .../ItemHistoryProviderConfiguration.java     |   45 +-
 .../impl/LaunchBaselineHistoryProvider.java   |   71 +-
 .../impl/TestItemBaselineHistoryProvider.java |  188 +-
 .../strategy/AbstractLaunchMergeStrategy.java |  314 +--
 .../strategy/BasicLaunchMergeStrategy.java    |   37 +-
 .../BasicStatisticsCalculationStrategy.java   |   32 +-
 .../strategy/DeepLaunchMergeStrategy.java     |   30 +-
 .../merge/strategy/LaunchMergeFactory.java    |   15 +-
 .../merge/strategy/MergeStrategyType.java     |   11 +-
 .../StatisticsCalculationFactory.java         |   16 +-
 .../impl/provider/DataProviderHandler.java    |   15 +-
 .../item/impl/provider/DataProviderType.java  |   33 +-
 .../impl/provider/ProviderTypeConfig.java     |   69 +-
 .../impl/BaselineLaunchDataProvider.java      |  130 +-
 .../CumulativeTestItemDataProviderImpl.java   |   93 +-
 .../DelegatingClusterDataProviderHandler.java |   72 +-
 .../impl/LaunchDataProviderHandlerImpl.java   |   83 +-
 .../core/item/impl/rerun/RerunSearcher.java   |    4 +-
 .../item/impl/rerun/RerunSearcherImpl.java    |   23 +-
 .../item/impl/retry/DefaultRetryHandler.java  |   98 +-
 .../core/item/impl/retry/RetryHandler.java    |    5 +-
 .../core/item/impl/retry/RetrySearcher.java   |    3 +-
 .../impl/retry/UniqueIdRetrySearcher.java     |   55 +-
 .../AbstractStatusChangingStrategy.java       |  284 +--
 .../item/impl/status/ChangeStatusHandler.java |    4 +-
 .../impl/status/ChangeStatusHandlerImpl.java  |  165 +-
 .../impl/status/StatusChangingStrategy.java   |    3 +-
 .../ToFailedStatusChangingStrategy.java       |   93 +-
 .../ToPassedStatusChangingStrategy.java       |  112 +-
 .../ToSkippedStatusChangingStrategy.java      |  163 +-
 .../core/item/merge/LaunchMergeStrategy.java  |    6 +-
 .../merge/StatisticsCalculationStrategy.java  |    3 +-
 .../utils/DefaultLaunchFilterProvider.java    |   92 +-
 .../parent/NestedStepConditionValidator.java  |   40 +-
 .../validator/parent/ParentItemValidator.java |   14 +-
 .../validator/parent/PathLengthValidator.java |   48 +
 .../parent/RetryConditionValidator.java       |   30 +-
 .../parent/StartTimeConditionValidator.java   |   32 +-
 .../state/NotNestedStepValidator.java         |   24 +-
 .../validator/state/NotRetryValidator.java    |   27 +-
 .../validator/state/TestItemValidator.java    |    2 +-
 .../core/jasper/GetJasperReportHandler.java   |   64 +-
 .../core/jasper/JasperReportRender.java       |   90 +-
 .../core/jasper/TestItemPojo.java             |  371 ++--
 .../constants/LaunchReportConstants.java      |   44 +-
 .../constants/ProjectReportConstants.java     |   18 +-
 .../jasper/constants/UserReportConstants.java |   18 +-
 .../impl/AbstractJasperReportHandler.java     |  183 +-
 .../impl/LaunchJasperReportHandler.java       |  147 +-
 .../impl/ProjectJasperReportHandler.java      |   77 +-
 .../jasper/impl/UserJasperReportHandler.java  |  131 +-
 .../core/jasper/util/ExportUtils.java         |   76 +-
 .../core/jasper/util/JasperDataProvider.java  |   33 +-
 .../core/launch/DeleteLaunchHandler.java      |   38 +-
 .../core/launch/FinishLaunchHandler.java      |   24 +-
 .../core/launch/GetLaunchHandler.java         |  273 +--
 .../core/launch/MergeLaunchHandler.java       |   19 +-
 .../core/launch/StartLaunchHandler.java       |   52 +-
 .../core/launch/StopLaunchHandler.java        |   45 +-
 .../core/launch/UpdateLaunchHandler.java      |   74 +-
 .../core/launch/cluster/ClusterGenerator.java |    2 +-
 .../launch/cluster/CreateClusterHandler.java  |    2 +-
 .../cluster/CreateClusterHandlerImpl.java     |   91 +-
 .../launch/cluster/GetClusterHandler.java     |    4 +-
 .../launch/cluster/GetClusterHandlerImpl.java |   63 +-
 .../cluster/UniqueErrorAnalysisStarter.java   |   37 +-
 .../launch/cluster/UniqueErrorGenerator.java  |   90 +-
 .../cluster/UniqueErrorGeneratorAsync.java    |   37 +-
 .../cluster/config/ClusterEntityContext.java  |   72 +-
 .../config/GenerateClustersConfig.java        |   60 +-
 .../pipeline/DeleteClustersPartProvider.java  |   41 +-
 .../pipeline/SaveClusterDataPartProvider.java |   29 +-
 .../SaveLastRunAttributePartProvider.java     |   57 +-
 .../data/AnalyzerClusterDataProvider.java     |   56 +-
 .../data/AnalyzerItemClusterDataProvider.java |   44 +-
 .../AnalyzerLaunchClusterDataProvider.java    |   22 +-
 .../pipeline/data/ClusterDataProvider.java    |    3 +-
 .../resolver/ClusterDataProviderResolver.java |   16 +-
 .../ClusterDataProviderEvaluator.java         |   26 +-
 .../launch/impl/DeleteLaunchHandlerImpl.java  |  264 ++-
 .../impl/FinishLaunchHandlerAsyncImpl.java    |   53 +-
 .../launch/impl/FinishLaunchHandlerImpl.java  |  158 +-
 .../launch/impl/GetLaunchHandlerImpl.java     |  661 +++---
 .../launch/impl/MergeLaunchHandlerImpl.java   |  223 +-
 .../core/launch/impl/MetadataUpdater.java     |   13 +-
 .../core/launch/impl/ResourceUpdater.java     |    6 +-
 .../impl/StartLaunchHandlerAsyncImpl.java     |   55 +-
 .../launch/impl/StartLaunchHandlerImpl.java   |   82 +-
 .../launch/impl/StopLaunchHandlerImpl.java    |    3 +-
 .../launch/impl/UpdateLaunchHandlerImpl.java  |  367 ++--
 .../core/launch/rerun/RerunHandler.java       |   53 +-
 .../core/launch/rerun/RerunHandlerImpl.java   |  338 +--
 .../core/launch/util/LaunchValidator.java     |  153 +-
 .../core/launch/util/LinkGenerator.java       |   47 +-
 .../core/log/CreateLogHandler.java            |   53 +-
 .../core/log/DeleteLogHandler.java            |   19 +-
 .../core/log/ElasticLogService.java           |  332 +++
 .../core/log/EmptyLogService.java             |  190 ++
 .../reportportal/core/log/GetLogHandler.java  |  107 +-
 .../ta/reportportal/core/log/LogService.java  |  196 +-
 .../core/log/LogServiceElastic.java           |   48 -
 .../core/log/LogServiceEmptyElastic.java      |   23 -
 .../log/impl/CreateLogHandlerAsyncImpl.java   |  135 +-
 .../core/log/impl/CreateLogHandlerImpl.java   |  169 +-
 .../core/log/impl/DeleteLogHandlerImpl.java   |  197 +-
 .../core/log/impl/GetLogHandlerImpl.java      |  702 +++---
 .../core/log/impl/PagedLogResource.java       |   21 +-
 .../core/log/impl/SaveLogBinaryDataTask.java  |   63 -
 .../log/impl/SaveLogBinaryDataTaskAsync.java  |   71 +-
 .../core/logging/HttpLogging.java             |    8 +-
 .../core/logging/HttpLoggingAspect.java       |  371 ++--
 .../core/logging/RabbitMessageLogging.java    |    4 +-
 .../logging/RabbitMessageLoggingAspect.java   |  165 +-
 .../core/onboarding/OnboardingService.java    |   36 +-
 .../core/plugin/Pf4jPluginBox.java            |  118 +-
 .../ta/reportportal/core/plugin/Plugin.java   |   79 +-
 .../reportportal/core/plugin/PluginBox.java   |   50 +-
 .../reportportal/core/plugin/PluginInfo.java  |  106 +-
 .../core/preference/GetPreferenceHandler.java |    3 +-
 .../preference/UpdatePreferenceHandler.java   |   39 +-
 .../impl/GetPreferenceHandlerImpl.java        |   48 +-
 .../core/project/CreateProjectHandler.java    |   18 +-
 .../core/project/DeleteProjectHandler.java    |    3 +
 .../core/project/GetProjectHandler.java       |  162 +-
 .../core/project/GetProjectInfoHandler.java   |   57 +-
 .../core/project/ProjectUserHandler.java      |    2 +-
 .../core/project/UpdateProjectHandler.java    |   98 +-
 .../project/config/ProjectConfigProvider.java |   23 +-
 .../impl/CreateProjectHandlerImpl.java        |    3 +-
 .../impl/DeleteProjectHandlerImpl.java        |   61 +-
 .../impl/ProjectInfoWidgetDataConverter.java  |  509 ++---
 .../project/impl/ProjectUserHandlerImpl.java  |    5 +-
 .../impl/UpdateProjectHandlerImpl.java        |    3 +-
 .../CreateProjectSettingsHandler.java         |   38 +-
 .../DeleteProjectSettingsHandler.java         |   37 +-
 .../settings/GetProjectSettingsHandler.java   |   14 +-
 .../UpdateProjectSettingsHandler.java         |   40 +-
 .../CreateProjectSettingsHandlerImpl.java     |  413 ++--
 .../impl/GetProjectSettingsHandlerImpl.java   |   22 +-
 .../UpdateProjectSettingsHandlerImpl.java     |  242 ++-
 .../CreateProjectNotificationHandler.java     |   32 +
 .../CreateProjectNotificationHandlerImpl.java |   88 +
 .../DeleteProjectNotificationHandler.java     |   32 +
 .../DeleteProjectNotificationHandlerImpl.java |   91 +
 .../GetProjectNotificationsHandler.java       |   29 +
 .../GetProjectNotificationsHandlerImpl.java   |   46 +
 .../notification/ProjectRecipientHandler.java |    2 +-
 .../notification/RecipientRemover.java        |   54 +-
 .../UpdateProjectNotificationHandler.java     |   34 +
 .../UpdateProjectNotificationHandlerImpl.java |   93 +
 .../attribute/DelayBoundLessRule.java         |   24 +-
 .../attribute/DelayBoundValidator.java        |   95 +-
 .../attribute/ProjectAttributeValidator.java  |  151 +-
 .../ProjectNotificationValidator.java         |  126 ++
 .../core/remover/ContentRemover.java          |    2 +-
 .../core/remover/item/ItemClusterRemover.java |   18 +-
 .../remover/launch/LaunchClusterRemover.java  |   20 +-
 .../project/ProjectClusterRemover.java        |   20 +-
 .../project/ProjectContentRemover.java        |   17 +-
 .../remover/project/ProjectWidgetRemover.java |   35 +-
 .../core/remover/user/UserContentRemover.java |   38 +
 .../core/remover/user/UserPhotoRemover.java   |   66 +
 .../core/remover/user/UserWidgetRemover.java  |   33 +-
 .../core/statistics/StatisticsHelper.java     |   78 +-
 .../core/user/CreateUserHandler.java          |  103 +-
 .../core/user/DeleteUserHandler.java          |   18 +-
 .../core/user/EditUserHandler.java            |   65 +-
 .../core/user/GetUserHandler.java             |  120 +-
 .../core/user/impl/ApiKeyHandlerImpl.java     |    5 +
 .../core/user/impl/CreateUserHandlerImpl.java |   34 +-
 .../core/user/impl/GetUserHandlerImpl.java    |  282 +--
 .../core/widget/CreateWidgetHandler.java      |   19 +-
 .../core/widget/UpdateWidgetHandler.java      |   18 +-
 .../widget/content/BuildFilterStrategy.java   |   18 +-
 .../widget/content/LoadContentStrategy.java   |    6 +-
 .../MaterializedLoadContentStrategy.java      |    5 +-
 .../MaterializedLoadContentStrategyImpl.java  |   39 +-
 .../MultilevelLoadContentStrategy.java        |   10 +-
 .../constant/ContentLoaderConstants.java      |   40 +-
 .../AbstractStatisticsFilterStrategy.java     |   55 +-
 .../filter/ActivityFilterStrategy.java        |   30 +-
 .../filter/GeneralLaunchFilterStrategy.java   |   26 +-
 .../filter/LaunchHistoryFilterStrategy.java   |   62 +-
 .../filter/ProductStatusFilterStrategy.java   |   61 +-
 .../content/filter/ProjectFilterStrategy.java |   18 +-
 .../AbstractStatisticsContentLoader.java      |  312 +--
 .../loader/BugTrendChartContentLoader.java    |   39 +-
 .../loader/CasesTrendContentLoader.java       |  152 +-
 .../ChartInvestigatedContentLoader.java       |  141 +-
 .../ComponentHealthCheckContentLoader.java    |  212 +-
 .../loader/FlakyCasesTableContentLoader.java  |   77 +-
 ...cutionAndIssueStatisticsContentLoader.java |   39 +-
 .../LaunchesComparisonContentLoader.java      |   54 +-
 .../loader/LaunchesDurationContentLoader.java |   43 +-
 .../loader/LaunchesTableContentLoader.java    |   39 +-
 .../loader/LineChartContentLoader.java        |   64 +-
 .../MostTimeConsumingContentLoader.java       |  217 +-
 .../loader/NotPassedTestsContentLoader.java   |   39 +-
 .../OverallStatisticsContentLoader.java       |   46 +-
 .../PassingRatePerLaunchContentLoader.java    |   62 +-
 .../PassingRateSummaryContentLoader.java      |   39 +-
 .../loader/ProductStatusContentLoader.java    |    1 +
 ...oductStatusFilterGroupedContentLoader.java |   48 +-
 ...oductStatusLaunchGroupedContentLoader.java |   58 +-
 .../loader/TopPatternContentLoader.java       |   66 +-
 .../loader/TopTestCasesContentLoader.java     |   93 +-
 .../loader/UniqueBugContentLoader.java        |   43 +-
 ...CumulativeTrendChartContentLoaderImpl.java |   93 +-
 .../HealthCheckTableReadyContentLoader.java   |  223 +-
 .../MaterializedWidgetContentLoader.java      |    5 +-
 .../generator/AbstractViewGenerator.java      |   63 +-
 .../CumulativeTrendChartViewGenerator.java    |   38 +-
 .../generator/FailedViewStateGenerator.java   |   56 +-
 .../generator/HealthCheckTableGenerator.java  |   70 +-
 .../materialized/generator/ViewGenerator.java |    5 +-
 ...CreatedMaterializedWidgetStateHandler.java |   41 +-
 .../EmptyMaterializedWidgetStateHandler.java  |   14 +-
 .../FailedMaterializedWidgetStateHandler.java |   32 +-
 .../MaterializedWidgetStateHandler.java       |    9 +-
 .../ReadyMaterializedWidgetStateHandler.java  |   65 +-
 .../ProductStatusContentLoaderManager.java    |   39 +-
 .../MaterializedViewNameGenerator.java        |   11 +-
 .../state/WidgetStateResolver.java            |   16 +-
 .../DelegatingStateContentRemover.java        |   52 +-
 .../remover/MaterializedViewRemover.java      |   28 +-
 .../remover/StaleMaterializedViewRemover.java |   47 +-
 .../content/remover/WidgetContentRemover.java |    2 +-
 .../ComponentHealthCheckPostProcessor.java    |   30 +-
 ...omponentHealthCheckTablePostProcessor.java |   39 +-
 .../CumulativeTrendChartPostProcessor.java    |   37 +-
 .../MaterializedWidgetStateUpdater.java       |   10 +-
 .../content/updater/WidgetPostProcessor.java  |   18 +-
 .../widget/content/updater/WidgetUpdater.java |    8 +-
 .../validator/ActivityContentValidator.java   |   44 +-
 .../BugTrendChartContentValidator.java        |   72 +-
 .../validator/CasesTrendContentValidator.java |   78 +-
 .../ChartInvestigatedContentValidator.java    |   39 +-
 .../ComponentHealthCheckContentValidator.java |   85 +-
 .../CumulativeTrendChartValidator.java        |   80 +-
 .../FlakyCasesTableContentValidator.java      |   13 +-
 ...ionAndIssueStatisticsContentValidator.java |   69 +-
 .../LaunchesComparisonContentValidator.java   |   69 +-
 .../LaunchesDurationContentValidator.java     |   39 +-
 .../LaunchesTableContentValidator.java        |   58 +-
 .../validator/LineChartContentValidator.java  |   69 +-
 .../MostTimeConsumingContentValidator.java    |   61 +-
 .../MultilevelValidatorStrategy.java          |    9 +-
 .../NotPassedTestsContentValidator.java       |   37 +-
 .../OverallStatisticsContentValidator.java    |   40 +-
 .../PassingRatePerLaunchContentValidator.java |   61 +-
 .../PassingRateSummaryContentValidator.java   |   39 +-
 .../ProductStatusContentValidator.java        |   63 +-
 .../validator/TopPatternContentValidator.java |   48 +-
 .../TopTestCasesContentValidator.java         |   36 +-
 .../validator/UniqueBugContentValidator.java  |   39 +-
 .../WidgetContentFieldsValidator.java         |   94 +-
 .../updater/validator/WidgetValidator.java    |    2 +-
 .../validator/WidgetValidatorStrategy.java    |    6 +-
 .../widget/util/ContentFieldMatcherUtil.java  |   14 +-
 .../util/ContentFieldPatternConstants.java    |  104 +-
 .../core/widget/util/WidgetFilterUtil.java    |   48 +-
 .../core/widget/util/WidgetOptionUtil.java    |  130 +-
 .../demodata/model/DemoDataRq.java            |   30 +-
 .../demodata/model/DemoDataRs.java            |   33 +-
 .../demodata/model/DemoItemMetadata.java      |  128 +-
 .../demodata/model/DemoLaunch.java            |   21 +-
 .../demodata/model/RootMetaData.java          |   52 +-
 .../ta/reportportal/demodata/model/Step.java  |   46 +-
 .../ta/reportportal/demodata/model/Suite.java |   60 +-
 .../ta/reportportal/demodata/model/Test.java  |   60 +-
 .../demodata/model/TestingModel.java          |   32 +-
 .../demodata/service/Attachment.java          |    9 +-
 .../demodata/service/Constants.java           |   18 +-
 .../demodata/service/ContentUtils.java        |  285 +--
 .../service/DefaultDemoDataFacade.java        |  142 +-
 .../demodata/service/DemoDataFacade.java      |   19 +-
 .../service/DemoDataLaunchService.java        |  126 +-
 .../demodata/service/DemoDataService.java     |   44 +-
 .../service/DemoDataTestItemService.java      |  173 +-
 .../demodata/service/DemoLogsService.java     |   77 +-
 .../generator/DefaultSuiteGenerator.java      |  292 +--
 .../service/generator/SuiteGenerator.java     |    2 +-
 .../generator/SuiteGeneratorResolver.java     |   15 +-
 .../SuiteWithNestedStepsGenerator.java        |   35 +-
 .../generator/SuiteWithRetriesGenerator.java  |   48 +-
 .../generator/model/SuiteGeneratorType.java   |    2 +-
 .../exception/DataStorageException.java       |   14 +-
 .../exception/HandlerNotDefinedException.java |    8 +-
 .../PermissionNotDefinedException.java        |    8 +-
 .../UserAccountExpiredException.java          |    8 +-
 .../health/JobsHealthIndicator.java           |   79 +
 .../info/AnalyzerInfoContributor.java         |   31 +-
 .../EnvironmentVariablesInfoContributor.java  |   26 +-
 .../info/ExtensionContributor.java            |    3 +-
 .../info/ExtensionsInfoContributor.java       |   24 +-
 .../info/InfoContributorComposite.java        |   33 +-
 .../info/JobSchedulerInfoContributor.java     |   76 +-
 .../info/JobsInfoContributor.java             |   61 +
 .../info/ServerSettingsInfoContributor.java   |   33 +-
 .../job/CleanExpiredCreationBidsJob.java      |   27 +-
 .../job/CleanOutdatedPluginsJob.java          |  216 +-
 .../ta/reportportal/job/FlushingDataJob.java  |   11 +-
 .../job/InterruptBrokenLaunchesJob.java       |  221 +-
 .../reportportal/job/JobExecutorDelegate.java |   30 +-
 .../ta/reportportal/job/LoadPluginsJob.java   |  144 +-
 .../epam/ta/reportportal/job/PageUtil.java    |  114 +-
 .../reportportal/job/SelfCancelableJob.java   |   45 +-
 .../job/service/PluginLoaderService.java      |    5 +-
 .../service/impl/PluginLoaderServiceImpl.java |  207 +-
 .../pipeline/PipelineConstructor.java         |   14 +-
 .../reportportal/pipeline/PipelinePart.java   |    2 +-
 .../pipeline/PipelinePartProvider.java        |    2 +-
 .../pipeline/TransactionalPipeline.java       |   11 +-
 .../plugin/Pf4jPluginManager.java             | 1334 ++++++------
 .../plugin/ReportPortalExtensionFactory.java  |   93 +-
 .../ApplicationContextAwareFactoryBean.java   |  142 +-
 .../util/BinaryDataResponseWriter.java        |   46 +
 .../ta/reportportal/util/ControllerUtils.java |  145 +-
 .../reportportal/util/DateTimeProvider.java   |    9 +-
 .../ta/reportportal/util/ItemInfoUtils.java   |  118 +-
 .../epam/ta/reportportal/util/Predicates.java |   70 +-
 .../util/ReportingQueueService.java           |   57 +-
 .../util/email/EmailRulesValidator.java       |   94 +-
 .../reportportal/util/email/EmailService.java |   29 +-
 .../util/email/MailServiceFactory.java        |    4 +
 .../email/constant/IssueRegexConstant.java    |   16 +-
 .../util/message/MessageProvider.java         |    2 +-
 .../ws/controller/ActivityController.java     |   17 +-
 .../controller/ActivityEventController.java   |   19 +
 .../BugTrackingSystemController.java          |  163 +-
 .../ws/controller/DashboardController.java    |   33 +-
 .../controller/DeprecatedUserController.java  |  268 +++
 .../ws/controller/FileStorageController.java  |  145 +-
 .../ws/controller/IntegrationController.java  |  425 ++--
 .../ws/controller/InternalApiController.java  |   35 +-
 .../ws/controller/LaunchAsyncController.java  |  134 +-
 .../ws/controller/LaunchController.java       |  761 ++++---
 .../ws/controller/LogAsyncController.java     |  211 +-
 .../ws/controller/LogController.java          |  439 ++--
 .../ws/controller/OnboardingController.java   |   15 +-
 .../ws/controller/PluginPublicController.java |   85 +
 .../controller/ProjectSettingsController.java |  274 ++-
 .../ws/controller/SettingsController.java     |   55 +-
 .../controller/TestItemAsyncController.java   |   99 +-
 .../ws/controller/TestItemController.java     |  824 +++----
 .../ws/controller/UserController.java         |    2 +-
 .../ws/converter/LogResourceAssembler.java    |   12 +-
 .../ws/converter/ResourceAssembler.java       |   63 +-
 .../converter/TestItemResourceAssembler.java  |   26 +-
 .../converter/builders/AttachmentBuilder.java |   72 +-
 .../builders/IntegrationBuilder.java          |   79 +-
 .../builders/IntegrationTypeBuilder.java      |   79 +-
 .../builders/IssueEntityBuilder.java          |   61 +-
 .../converter/builders/IssueTypeBuilder.java  |   79 +-
 .../ws/converter/builders/LaunchBuilder.java  |  199 +-
 .../{LogBuilder.java => LogFullBuilder.java}  |   63 +-
 .../builders/PatternTemplateBuilder.java      |   81 +-
 .../converter/builders/TestCaseIdEntry.java   |   48 +-
 .../converter/builders/TestItemBuilder.java   |  354 +--
 .../ws/converter/builders/UserBuilder.java    |   83 +-
 .../builders/UserPreferenceBuilder.java       |   59 +-
 .../converters/ActivityEventConverter.java    |    2 +
 .../converters/BaseEntityConverter.java       |   18 +-
 .../converters/ClusterConverter.java          |   35 +-
 .../converters/ExceptionConverter.java        |   19 +-
 .../converters/IntegrationConverter.java      |  108 +-
 .../IntegrationFieldsConverter.java           |   96 +-
 .../converters/IntegrationTypeConverter.java  |   32 +-
 .../converter/converters/IssueConverter.java  |   76 +-
 .../converters/IssueTypeConverter.java        |   19 +-
 .../converter/converters/LaunchConverter.java |  109 +-
 .../ws/converter/converters/LogConverter.java |  140 +-
 .../NotificationConfigConverter.java          |   17 +
 .../converters/OAuthDetailsConverters.java    |   68 +-
 .../converters/ParametersConverter.java       |   31 +-
 .../converters/PatternTemplateConverter.java  |   47 +-
 .../converters/ProjectActivityConverter.java  |   21 +-
 .../converters/ProjectSettingsConverter.java  |   87 +-
 .../RestorePasswordBidConverter.java          |   21 +-
 .../converters/ServerSettingsConverter.java   |   23 +-
 .../converters/StatisticsConverter.java       |   61 +-
 .../converters/TestItemConverter.java         |  190 +-
 .../converter/converters/TicketConverter.java |   27 +-
 .../converters/UserCreationBidConverter.java  |   25 +-
 .../converter/converters/WidgetConverter.java |  129 +-
 .../handler/attribute/ItemAttributeType.java  |    6 +-
 .../attribute/ResourceAttributeHandler.java   |    3 +-
 .../launch/LaunchResourceAttributeLogger.java |   26 +-
 .../LaunchResourceAttributeUpdater.java       |   15 +-
 .../matcher/ItemAttributeTypeMatcher.java     |    4 +-
 .../PredicateItemAttributeTypeMatcher.java    |   30 +-
 .../resolver/ItemAttributeTypeResolver.java   |    3 +-
 .../ItemAttributeTypeResolverDelegate.java    |   18 +-
 .../ws/converter/utils/ResourceUpdater.java   |    2 +-
 .../utils/ResourceUpdaterProvider.java        |    2 +-
 .../item/content/TestItemUpdaterContent.java  |   31 +-
 .../provider/PathNameUpdaterProvider.java     |   27 +-
 .../item/provider/RetriesUpdaterProvider.java |   49 +-
 .../utils/item/updater/PathNameUpdater.java   |   30 +-
 .../utils/item/updater/RetriesUpdater.java    |   32 +-
 .../reportportal/ws/handler/QueryHandler.java |    2 +-
 .../ws/handler/impl/QueryHandlerImpl.java     |   58 +-
 .../ws/rabbit/AsyncReportingListener.java     |  551 ++---
 .../ws/rabbit/ConsumerEventListener.java      |   76 +-
 .../ws/rabbit/MessageHeaders.java             |   30 +-
 .../reportportal/ws/rabbit/QueryConsumer.java |   16 +-
 .../ta/reportportal/ws/rabbit/QueryRQ.java    |   28 +-
 .../ws/rabbit/ReportingStartupService.java    |   22 +-
 .../reportportal/ws/rabbit/RequestType.java   |    2 +-
 .../reportportal/ws/resolver/ActiveRole.java  |   11 +-
 .../ActiveUserWebArgumentResolver.java        |   71 +-
 .../ws/resolver/FilterCriteriaResolver.java   |  137 +-
 .../reportportal/ws/resolver/FilterFor.java   |   22 +-
 .../ws/resolver/JacksonViewAware.java         |   44 +-
 .../ws/resolver/JacksonViewAwareModule.java   |   56 +-
 .../JacksonViewReturnValueHandler.java        |   88 +-
 .../resolver/JsonViewSupportFactoryBean.java  |   61 +-
 .../PagingHandlerMethodArgumentResolver.java  |   64 +-
 .../PredefinedFilterCriteriaResolver.java     |  111 +-
 .../ws/resolver/ResponseView.java             |    9 +-
 .../ws/resolver/SortArgumentResolver.java     |   81 +-
 .../ta/reportportal/ws/resolver/SortFor.java  |   18 +-
 .../JaskonRequiredPropertiesValidator.java    |   88 +-
 src/main/resources/application.properties     |   15 +-
 src/main/resources/application.yaml           |   20 +-
 src/main/resources/bug_template.ftl           |   80 +-
 src/main/resources/demo/attachments/css.css   |   22 +-
 src/main/resources/demo/attachments/html.html |   12 +-
 .../resources/demo/attachments/javascript.js  |  116 +-
 src/main/resources/demo/attachments/xml.xml   |   28 +-
 .../resources/demo/launch/002_launch.json     |  350 +--
 .../email/change-password-template.ftl        |  283 +--
 .../templates/email/create-user-template.ftl  |  326 +--
 .../delete-account-notification-template.ftl  |  512 ++---
 .../email/delete-account-template.ftl         |  500 ++---
 .../templates/email/email-connection.ftl      |  256 ++-
 .../email/finish-launch-template.ftl          |  518 +++--
 .../resources/templates/email/ic-github.png   |  Bin 816 -> 0 bytes
 .../resources/templates/email/ic-slack.png    |  Bin 686 -> 0 bytes
 .../resources/templates/email/ic-twitter.png  |  Bin 593 -> 0 bytes
 .../resources/templates/email/ic-youtube.png  |  Bin 297 -> 0 bytes
 .../email/{ => images}/create-user.png        |  Bin
 .../delete-account-notification.png           |  Bin
 .../email/{ => images}/deleted-account.png    |  Bin
 .../templates/email/images/ic-facebook.png    |  Bin 0 -> 896 bytes
 .../templates/email/images/ic-github.png      |  Bin 0 -> 1125 bytes
 .../templates/email/images/ic-linkedin.png    |  Bin 0 -> 1015 bytes
 .../templates/email/images/ic-slack.png       |  Bin 0 -> 1285 bytes
 .../templates/email/images/ic-twitter.png     |  Bin 0 -> 1233 bytes
 .../templates/email/images/ic-youtube.png     |  Bin 0 -> 1076 bytes
 .../email/{ => images}/illustration.png       |  Bin
 .../templates/email/{ => images}/logo.png     |  Bin
 .../email/images/new-ic-facebook.png          |  Bin 0 -> 976 bytes
 .../email/{ => images}/new-ic-github.png      |  Bin
 .../email/{ => images}/new-ic-linkedin.png    |  Bin
 .../email/{ => images}/new-ic-slack.png       |  Bin
 .../templates/email/images/new-ic-twitter.png |  Bin 0 -> 1593 bytes
 .../email/{ => images}/new-ic-youtube.png     |  Bin
 .../templates/email/{ => images}/new-logo.png |  Bin
 .../email/{ => images}/restore-password.png   |  Bin
 .../email/index-finished-template.ftl         |    2 +-
 .../templates/email/new-ic-twitter.png        |  Bin 690 -> 0 bytes
 .../templates/email/registration-template.ftl |  325 +--
 .../email/restore-password-template.ftl       |  311 +--
 .../email/self-delete-account-template.ftl    |  499 ++---
 .../resources/templates/report/projects.jrxml |  280 +--
 .../resources/templates/report/report.jrxml   | 1488 +++++++------
 .../resources/templates/report/users.jrxml    |  290 +--
 .../ta/reportportal/ReportPortalUserUtil.java |   35 +-
 .../com/epam/ta/reportportal/TestConfig.java  |   95 +-
 .../ta/reportportal/auth/OAuthHelper.java     |   99 +-
 .../auth/UserRoleHierarchyTest.java           |   38 +-
 .../basic/DatabaseUserDetailsServiceTest.java |   35 +-
 .../auto/client/impl/AnalyzerUtilsTest.java   |   74 +-
 .../impl/IndexerServiceClientImplTest.java    |  157 +-
 .../RabbitMqManagementClientTemplateTest.java |   25 +-
 .../auto/impl/AnalyzerServiceServiceTest.java |  295 +--
 .../analyzer/auto/impl/AnalyzerUtilsTest.java |  249 ++-
 .../auto/impl/LogIndexerServiceTest.java      |  249 +--
 .../auto/impl/SearchLogServiceImplTest.java   |  207 +-
 .../auto/impl/SuggestItemServiceTest.java     |  316 +--
 .../LaunchPreparerServiceImplTest.java        |   61 +-
 .../auto/indexer/BatchLogIndexerTest.java     |  202 +-
 .../CollectingAutoAnalysisStarterTest.java    |  112 +-
 .../AsyncAutoAnalysisStarterTest.java         |   45 +-
 .../AutoAnalysisEnabledStarterTest.java       |   68 +-
 .../ExistingAnalyzerStarterTest.java          |   75 +-
 .../IndexingAutoAnalysisStarterTest.java      |   53 +-
 .../analyzer/config/AnalyzerTypeTest.java     |   34 +-
 .../analyzer/pattern/PatternAnalyzerTest.java |  155 --
 .../LaunchAutoAnalysisStrategyTest.java       |   85 +-
 .../LaunchPatternAnalysisStrategyTest.java    |   76 +-
 .../ReportPortalClassLoadHelperTest.java      |   37 +-
 .../impl/CreateDashboardHandlerImplTest.java  |   47 +-
 .../core/events/MessageBusImplTest.java       |   21 +-
 .../events/activity/LaunchEventsTest.java     |    4 +-
 .../events/activity/UserCreatedEventTest.java |    2 +-
 ...onentHealthCheckTableEventHandlerTest.java |  174 +-
 .../handler/DefectTypeDeletedHandlerTest.java |  225 +-
 .../handler/item/TestItemIndexRunnerTest.java |   46 +-
 .../TestItemPatternAnalysisRunnerTest.java    |   76 +
 ...TestItemUniqueErrorAnalysisRunnerTest.java |   79 +-
 ...aunchAnalysisFinishEventPublisherTest.java |   41 +-
 .../launch/LaunchAutoAnalysisRunnerTest.java  |   40 +-
 .../launch/LaunchNotificationRunnerTest.java  |  117 +-
 .../LaunchPatternAnalysisRunnerTest.java      |   74 +-
 .../LaunchUniqueErrorAnalysisRunnerTest.java  |   79 +-
 ...hUniqueErrorAnalysisEventListenerTest.java |   55 +-
 ...> TestIssueResolvedEventListenerTest.java} |   32 +-
 ...ProjectConfigDelegatingSubscriberTest.java |    2 -
 .../LaunchFinishedMessagePublisherTest.java   |    2 -
 .../FinishLaunchHierarchyHandlerTest.java     |  375 ++--
 .../imprt/ImportLaunchHandlerImplTest.java    |   39 +-
 .../core/imprt/XmlImportStrategyTest.java     |   14 +-
 .../impl/junit/XunitImportHandlerTest.java    |   35 +-
 .../impl/ExecuteIntegrationHandlerTest.java   |  112 +
 .../impl/GetIntegrationHandlerTest.java       |  145 +-
 .../impl/util/IntegrationTestUtil.java        |  124 +-
 .../util/AzureIntegrationServiceTest.java     |  123 +-
 .../EmailServerIntegrationServiceTest.java    |  174 +-
 .../util/JiraIntegrationServiceTest.java      |  178 +-
 .../util/RallyIntegrationServiceTest.java     |  123 +-
 .../util/SauceLabsIntegrationServiceTest.java |  115 +-
 .../validator/IntegrationValidatorTest.java   |  108 +-
 .../impl/DeleteTestItemHandlerImplTest.java   |  404 ++--
 .../FinishTestItemHandlerAsyncImplTest.java   |   75 +-
 .../impl/FinishTestItemHandlerImplTest.java   |  351 +--
 .../core/item/impl/IssueTypeHandlerTest.java  |   61 +-
 .../impl/LaunchAccessValidatorImplTest.java   |  129 +-
 .../StartTestItemHandlerAsyncImplTest.java    |   56 +-
 .../impl/StartTestItemHandlerImplTest.java    |  383 ++--
 .../impl/TestCaseHashGeneratorImplTest.java   |   97 +-
 .../impl/TestItemUniqueIdGeneratorTest.java   |  137 +-
 .../impl/UpdateTestItemHandlerImplTest.java   |  494 +++--
 .../IssueTypeConditionReplacerTest.java       |   63 +-
 .../TestItemsHistoryHandlerImplTest.java      |   80 +-
 .../mock/ClusterItemDataProviderMockTest.java |  307 +--
 .../state/NotNestedStepValidatorTest.java     |   32 +-
 .../state/NotRetryValidatorTest.java          |   44 +-
 .../cluster/CreateClusterHandlerImplTest.java |  196 +-
 .../UniqueErrorAnalysisStarterTest.java       |   76 +-
 .../UniqueErrorGeneratorAsyncTest.java        |  209 +-
 .../cluster/UniqueErrorGeneratorTest.java     |  155 +-
 .../DeleteClustersPartProviderTest.java       |   67 +-
 .../SaveClusterDataPartProviderTest.java      |   79 +-
 .../SaveLastRunAttributePartProviderTest.java |   85 +-
 .../AnalyzerItemClusterDataProviderTest.java  |  184 +-
 ...AnalyzerLaunchClusterDataProviderTest.java |   89 +-
 .../ClusterDataProviderResolverTest.java      |   50 +-
 .../ClusterDataProviderEvaluatorTest.java     |   59 +-
 .../launch/cluster/utils/ConfigProvider.java  |   26 +-
 .../impl/DeleteLaunchHandlerImplTest.java     |   82 +-
 .../FinishLaunchHandlerAsyncImplTest.java     |   38 +-
 .../impl/FinishLaunchHandlerImplTest.java     |  303 +--
 .../launch/impl/GetLaunchHandlerImplTest.java |  518 ++---
 .../core/launch/impl/LaunchTestUtil.java      |   41 +-
 .../impl/StartLaunchHandlerAsyncImplTest.java |   38 +-
 .../impl/StartLaunchHandlerImplTest.java      |  108 +-
 .../impl/UpdateLaunchHandlerImplTest.java     |  235 +-
 .../launch/rerun/RerunHandlerImplTest.java    |  413 ++--
 .../core/launch/util/LaunchValidatorTest.java |   55 +-
 .../core/log/ElasticLogServiceTest.java       |   62 +
 .../impl/CreateLogHandlerAsyncImplTest.java   |   90 +-
 .../core/log/impl/DeleteLogHandlerTest.java   |  328 +--
 .../core/log/impl/GetLogHandlerImplTest.java  |  128 +-
 .../core/logging/HelperController.java        |   51 +-
 .../core/logging/HelperListener.java          |   18 +-
 .../reportportal/core/logging/HelperUtil.java |   45 +-
 .../core/logging/HttpLoggingAspectTest.java   |  176 +-
 .../RabbitMessageLoggingAspectTest.java       |  165 +-
 .../config/ProjectConfigProviderTest.java     |   51 +-
 .../impl/CreateProjectHandlerImplTest.java    |   78 +-
 .../impl/DeleteProjectHandlerImplTest.java    |    7 +-
 .../ProjectInfoWidgetDataConverterTest.java   |  348 +--
 .../CreateProjectSettingsHandlerImplTest.java |  246 ++-
 .../DeleteProjectSettingsHandlerImplTest.java |   66 +-
 .../GetProjectSettingsHandlerImplTest.java    |   39 +-
 .../UpdateProjectSettingsHandlerImplTest.java |  164 +-
 ...ateProjectNotificationHandlerImplTest.java |  166 ++
 ...eteProjectNotificationHandlerImplTest.java |   87 +
 ...etProjectNotificationsHandlerImplTest.java |   67 +
 ...ateProjectNotificationHandlerImplTest.java |  202 ++
 .../remover/user/UserContentRemoverTest.java  |   49 +
 .../remover/user/UserPhotoRemoverTest.java    |  101 +
 .../core/statistics/StatisticsHelperTest.java |  151 +-
 .../user/impl/CreateUserHandlerImplTest.java  |  527 +++--
 .../user/impl/GetUserHandlerImplTest.java     |  129 +-
 .../FailedViewStateGeneratorTest.java         |   64 +-
 ...lthCheckTableReadyContentResolverTest.java |  110 +-
 .../MaterializedViewNameGeneratorTest.java    |   49 +-
 .../DelegatingStateContentRemoverTest.java    |   59 +-
 .../remover/MaterializedViewRemoverTest.java  |   33 +-
 .../StaleMaterializedViewRemoverTest.java     |   45 +-
 .../ActivityContentValidatorTest.java         |   40 +-
 .../BugTrendChartContentValidatorTest.java    |   56 +-
 .../CasesTrendContentValidatorTest.java       |   56 +-
 ...ChartInvestigatedContentValidatorTest.java |   40 +-
 ...ponentHealthCheckContentValidatorTest.java |   97 +-
 .../CumulativeTrendChartValidatorTest.java    |    2 -
 .../FlakyCasesTableContentValidatorTest.java  |    1 -
 ...ndIssueStatisticsContentValidatorTest.java |   55 +-
 ...aunchesComparisonContentValidatorTest.java |   55 +-
 .../LaunchesDurationContentValidatorTest.java |   40 +-
 .../LaunchesTableContentValidatorTest.java    |   56 +-
 ...MostTimeConsumingContentValidatorTest.java |   67 +-
 .../NotPassedTestsContentValidatorTest.java   |   40 +-
 ...singRatePerLaunchContentValidatorTest.java |   66 +-
 ...assingRateSummaryContentValidatorTest.java |   53 +-
 .../TopPatternContentValidatorTest.java       |   57 +-
 .../UniqueBugContentValidatorTest.java        |   40 +-
 .../util/ContentFieldMatcherUtilTest.java     |  198 +-
 .../widget/util/WidgetOptionUtilTest.java     |  102 +-
 .../job/CleanOutdatedPluginsJobTest.java      |  166 +-
 .../job/InterruptBrokenLaunchesJobTest.java   |  174 +-
 .../job/JobExecutorDelegateTest.java          |   30 +-
 .../reportportal/job/LoadPluginsJobTest.java  |  111 +-
 .../job/PluginLoaderServiceTest.java          |  232 +-
 .../job/SaveLogBinaryDataTaskTest.java        |   59 -
 .../job/SelfCancalableJobTest.java            |   49 +-
 .../plugin/Pf4jPluginManagerTest.java         |  400 ++--
 .../store/service/DataStoreServiceTest.java   |  113 +-
 ...pplicationContextAwareFactoryBeanTest.java |   56 +-
 .../reportportal/util/ItemInfoUtilsTest.java  |  163 +-
 .../util/MultipartFileUtilsTest.java          |   37 +-
 .../ta/reportportal/util/PredicatesTest.java  |  137 +-
 .../util/ReportingQueueServiceTest.java       |   57 +-
 .../util/TestProjectExtractor.java            |   20 +-
 .../util/email/EmailRulesValidatorTest.java   |  303 +--
 .../util/email/EmailServiceTest.java          |   84 +-
 .../util/sample/LaunchSampleUtil.java         |   51 +
 .../epam/ta/reportportal/ws/BaseMvcTest.java  |   70 +-
 .../BugTrackingSystemControllerTest.java      |  341 +--
 .../DashboardControllerValidationTest.java    |  434 ++--
 .../controller/IntegrationControllerTest.java |  468 ++--
 .../controller/LaunchAsyncControllerTest.java |  216 +-
 .../ws/controller/LaunchControllerTest.java   |  732 ++++---
 .../LaunchControllerValidationTest.java       |  415 ++--
 .../ws/controller/LogAsyncControllerTest.java |  206 +-
 .../ws/controller/LogControllerTest.java      |  152 +-
 .../ws/controller/PluginControllerTest.java   |   21 +-
 .../PluginPublicControllerTest.java           |  115 +
 .../ws/controller/ProjectControllerTest.java  |    7 +-
 .../ProjectSettingsControllerTest.java        |  469 ++--
 .../ws/controller/SettingsControllerTest.java |   65 +-
 .../TestItemAsyncControllerTest.java          |  209 +-
 .../ws/controller/TestItemControllerTest.java | 1931 +++++++++--------
 .../TestItemControllerValidationTest.java     |  668 +++---
 .../UserFilterControllerValidationTest.java   |  466 ++--
 .../constants/ValidationTestsConstants.java   |   19 +-
 .../converter/LogResourceAssemblerTest.java   |   86 +-
 .../builders/IntegrationBuilderTest.java      |  149 +-
 .../builders/IssueEntityBuilderTest.java      |   48 +-
 .../builders/IssueTypeBuilderTest.java        |   44 +-
 .../converter/builders/LaunchBuilderTest.java |  130 +-
 ...ilderTest.java => LogFullBuilderTest.java} |   60 +-
 .../builders/PatternTemplateBuilderTest.java  |   39 +-
 .../builders/TestItemBuilderTest.java         |  339 +--
 .../converter/builders/UserBuilderTest.java   |   49 +-
 .../builders/UserPreferenceBuilderTest.java   |   31 +-
 .../converters/IntegrationConverterTest.java  |  125 +-
 .../IntegrationFieldsConverterTest.java       |  100 +-
 .../converters/IssueConverterTest.java        |   70 +-
 .../ItemAttributeConverterTest.java           |   20 +-
 .../converters/LogConverterTest.java          |   78 +-
 .../converters/ParametersConverterTest.java   |   66 +-
 .../PatternTemplateConverterTest.java         |   61 +-
 .../ProjectActivityConverterTest.java         |   54 +-
 .../RestorePasswordBidConverterTest.java      |   22 +-
 .../converters/TestItemConverterTest.java     |  301 +--
 .../converters/TicketConverterTest.java       |   38 +-
 .../UserCreationBidConverterTest.java         |   47 +-
 .../LaunchResourceAttributeUpdaterTest.java   |   54 +-
 ...hResourceMetadataAttributeUpdaterTest.java |   63 +-
 ...PredicateItemAttributeTypeMatcherTest.java |   56 +-
 .../ws/handler/impl/QueryHandlerImplTest.java |   93 +-
 .../ws/rabbit/AsyncReportingListenerTest.java |   14 +-
 .../ws/rabbit/QueryConsumerTest.java          |   38 +-
 .../ws/validation/BusinessRuleTest.java       |   34 +-
 ...JaskonRequiredPropertiesValidatorTest.java |  101 +-
 .../db/data-store/data-store-fill.sql         |   12 +-
 src/test/resources/db/launch/launch-fill.sql  |   12 +-
 .../migration/V001003__integration_type.sql   |    6 +-
 .../V0027__attachment_creation_date.up.sql    |    3 +-
 .../db/migration/V0030__log_project_id.up.sql |    3 +-
 .../project-settings-fill.sql                 |   33 +-
 .../resources/db/shareable/shareable-fill.sql |   89 +-
 .../item-change-status-from-failed.sql        |   31 +-
 .../item-change-status-from-interrupted.sql   |   27 +-
 .../item-change-status-from-passed.sql        |   60 +-
 .../item-change-status-from-skipped.sql       |   35 +-
 src/test/resources/db/user/user-customer.sql  |    6 +-
 src/test/resources/db/user/user-fill.sql      |   16 +-
 src/test/resources/db/widget/bug-trend.sql    |   52 +-
 src/test/resources/db/widget/cases-trend.sql  |   54 +-
 .../resources/db/widget/flaky-test-cases.sql  |   85 +-
 .../db/widget/investigated-trend.sql          |   41 +-
 .../resources/db/widget/launch-statistics.sql |   26 +-
 .../db/widget/launches-comparison-chart.sql   |   56 +-
 .../db/widget/launches-duration-chart.sql     |   12 +-
 .../resources/db/widget/launches-table.sql    |   34 +-
 .../db/widget/most-time-consuming.sql         |   43 +-
 src/test/resources/db/widget/not-passed.sql   |   24 +-
 .../resources/db/widget/old-line-chart.sql    |   24 +-
 .../db/widget/overall-statistics.sql          |   26 +-
 .../db/widget/passing-rate-per-launch.sql     |   58 +-
 .../db/widget/passing-rate-summary.sql        |   50 +-
 .../resources/db/widget/product-status.sql    |   42 +-
 .../resources/db/widget/top-test-cases.sql    |   74 +-
 .../resources/db/widget/unique-bug-table.sql  |   39 +-
 src/test/resources/logback-test.xml           |   24 +-
 1023 files changed, 50910 insertions(+), 42587 deletions(-)
 create mode 100644 .github/workflows/build-dev-image.yml
 create mode 100644 .github/workflows/build-feature-image.yaml
 create mode 100644 .github/workflows/build-rc-image.yaml
 delete mode 100644 .github/workflows/build.yml
 create mode 100644 .github/workflows/java-checks.yml
 delete mode 100644 .github/workflows/rc.yaml
 mode change 100755 => 100644 gradle/wrapper/gradle-wrapper.jar
 delete mode 100755 sealights.gradle
 delete mode 100644 src/main/java/com/epam/ta/reportportal/auth/util/Encryptor.java
 create mode 100644 src/main/java/com/epam/ta/reportportal/core/ElementsCounterService.java
 create mode 100644 src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/IgnoreImmediateCollector.java
 create mode 100644 src/main/java/com/epam/ta/reportportal/core/analyzer/config/PatternAnalysisRabbitConfiguration.java
 delete mode 100644 src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/PatternAnalyzer.java
 rename src/main/java/com/epam/ta/reportportal/{ws/converter/builders/Builder.java => core/analyzer/pattern/handler/ItemsPatternsAnalyzer.java} (53%)
 create mode 100644 src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/handler/impl/ItemsPatternAnalyzerImpl.java
 create mode 100644 src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/handler/proxy/ItemsPatternAnalyzeConsumer.java
 create mode 100644 src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/handler/proxy/ItemsPatternAnalyzeDto.java
 create mode 100644 src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/handler/proxy/ItemsPatternAnalyzeProducer.java
 delete mode 100644 src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/impl/PatternAnalyzerImpl.java
 create mode 100644 src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/condition/impl/IgnoreImmediatePatternAnalysisConditionProvider.java
 rename src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/{ => service}/CreatePatternTemplateHandler.java (58%)
 create mode 100644 src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/service/LaunchPatternAnalyzer.java
 rename src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/{ => service}/impl/CreatePatternTemplateHandlerImpl.java (54%)
 rename src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/{ => service}/impl/CreateRegexPatternTemplateHandler.java (61%)
 create mode 100644 src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/service/impl/LaunchPatternAnalyzerImpl.java
 create mode 100644 src/main/java/com/epam/ta/reportportal/core/events/activity/CreateInvitationLinkEvent.java
 rename src/main/java/com/epam/ta/reportportal/core/events/activity/item/{ItemFinishedEvent.java => IssueResolvedEvent.java} (61%)
 create mode 100644 src/main/java/com/epam/ta/reportportal/core/events/activity/item/TestItemFinishedEvent.java
 create mode 100644 src/main/java/com/epam/ta/reportportal/core/events/handler/item/TestItemAutoAnalysisRunner.java
 create mode 100644 src/main/java/com/epam/ta/reportportal/core/events/handler/item/TestItemPatternAnalysisRunner.java
 create mode 100644 src/main/java/com/epam/ta/reportportal/core/events/listener/TestItemIssueResolvedEventListener.java
 create mode 100644 src/main/java/com/epam/ta/reportportal/core/integration/plugin/binary/PluginFilesProvider.java
 create mode 100644 src/main/java/com/epam/ta/reportportal/core/item/validator/parent/PathLengthValidator.java
 create mode 100644 src/main/java/com/epam/ta/reportportal/core/log/ElasticLogService.java
 create mode 100644 src/main/java/com/epam/ta/reportportal/core/log/EmptyLogService.java
 delete mode 100644 src/main/java/com/epam/ta/reportportal/core/log/LogServiceElastic.java
 delete mode 100644 src/main/java/com/epam/ta/reportportal/core/log/LogServiceEmptyElastic.java
 delete mode 100644 src/main/java/com/epam/ta/reportportal/core/log/impl/SaveLogBinaryDataTask.java
 create mode 100644 src/main/java/com/epam/ta/reportportal/core/project/settings/notification/CreateProjectNotificationHandler.java
 create mode 100644 src/main/java/com/epam/ta/reportportal/core/project/settings/notification/CreateProjectNotificationHandlerImpl.java
 create mode 100644 src/main/java/com/epam/ta/reportportal/core/project/settings/notification/DeleteProjectNotificationHandler.java
 create mode 100644 src/main/java/com/epam/ta/reportportal/core/project/settings/notification/DeleteProjectNotificationHandlerImpl.java
 create mode 100644 src/main/java/com/epam/ta/reportportal/core/project/settings/notification/GetProjectNotificationsHandler.java
 create mode 100644 src/main/java/com/epam/ta/reportportal/core/project/settings/notification/GetProjectNotificationsHandlerImpl.java
 create mode 100644 src/main/java/com/epam/ta/reportportal/core/project/settings/notification/UpdateProjectNotificationHandler.java
 create mode 100644 src/main/java/com/epam/ta/reportportal/core/project/settings/notification/UpdateProjectNotificationHandlerImpl.java
 create mode 100644 src/main/java/com/epam/ta/reportportal/core/project/validator/notification/ProjectNotificationValidator.java
 create mode 100644 src/main/java/com/epam/ta/reportportal/core/remover/user/UserContentRemover.java
 create mode 100644 src/main/java/com/epam/ta/reportportal/core/remover/user/UserPhotoRemover.java
 create mode 100644 src/main/java/com/epam/ta/reportportal/health/JobsHealthIndicator.java
 create mode 100644 src/main/java/com/epam/ta/reportportal/info/JobsInfoContributor.java
 create mode 100644 src/main/java/com/epam/ta/reportportal/util/BinaryDataResponseWriter.java
 create mode 100644 src/main/java/com/epam/ta/reportportal/ws/controller/DeprecatedUserController.java
 create mode 100644 src/main/java/com/epam/ta/reportportal/ws/controller/PluginPublicController.java
 rename src/main/java/com/epam/ta/reportportal/ws/converter/builders/{LogBuilder.java => LogFullBuilder.java} (51%)
 delete mode 100644 src/main/resources/templates/email/ic-github.png
 delete mode 100644 src/main/resources/templates/email/ic-slack.png
 delete mode 100644 src/main/resources/templates/email/ic-twitter.png
 delete mode 100644 src/main/resources/templates/email/ic-youtube.png
 rename src/main/resources/templates/email/{ => images}/create-user.png (100%)
 rename src/main/resources/templates/email/{ => images}/delete-account-notification.png (100%)
 rename src/main/resources/templates/email/{ => images}/deleted-account.png (100%)
 create mode 100644 src/main/resources/templates/email/images/ic-facebook.png
 create mode 100644 src/main/resources/templates/email/images/ic-github.png
 create mode 100644 src/main/resources/templates/email/images/ic-linkedin.png
 create mode 100644 src/main/resources/templates/email/images/ic-slack.png
 create mode 100644 src/main/resources/templates/email/images/ic-twitter.png
 create mode 100644 src/main/resources/templates/email/images/ic-youtube.png
 rename src/main/resources/templates/email/{ => images}/illustration.png (100%)
 rename src/main/resources/templates/email/{ => images}/logo.png (100%)
 create mode 100644 src/main/resources/templates/email/images/new-ic-facebook.png
 rename src/main/resources/templates/email/{ => images}/new-ic-github.png (100%)
 rename src/main/resources/templates/email/{ => images}/new-ic-linkedin.png (100%)
 rename src/main/resources/templates/email/{ => images}/new-ic-slack.png (100%)
 create mode 100644 src/main/resources/templates/email/images/new-ic-twitter.png
 rename src/main/resources/templates/email/{ => images}/new-ic-youtube.png (100%)
 rename src/main/resources/templates/email/{ => images}/new-logo.png (100%)
 rename src/main/resources/templates/email/{ => images}/restore-password.png (100%)
 delete mode 100644 src/main/resources/templates/email/new-ic-twitter.png
 delete mode 100644 src/test/java/com/epam/ta/reportportal/core/analyzer/pattern/PatternAnalyzerTest.java
 create mode 100644 src/test/java/com/epam/ta/reportportal/core/events/handler/item/TestItemPatternAnalysisRunnerTest.java
 rename src/test/java/com/epam/ta/reportportal/core/events/listener/{TestItemFinishedEventListenerTest.java => TestIssueResolvedEventListenerTest.java} (52%)
 create mode 100644 src/test/java/com/epam/ta/reportportal/core/integration/impl/ExecuteIntegrationHandlerTest.java
 create mode 100644 src/test/java/com/epam/ta/reportportal/core/log/ElasticLogServiceTest.java
 create mode 100644 src/test/java/com/epam/ta/reportportal/core/project/settings/notification/CreateProjectNotificationHandlerImplTest.java
 create mode 100644 src/test/java/com/epam/ta/reportportal/core/project/settings/notification/DeleteProjectNotificationHandlerImplTest.java
 create mode 100644 src/test/java/com/epam/ta/reportportal/core/project/settings/notification/GetProjectNotificationsHandlerImplTest.java
 create mode 100644 src/test/java/com/epam/ta/reportportal/core/project/settings/notification/UpdateProjectNotificationHandlerImplTest.java
 create mode 100644 src/test/java/com/epam/ta/reportportal/core/remover/user/UserContentRemoverTest.java
 create mode 100644 src/test/java/com/epam/ta/reportportal/core/remover/user/UserPhotoRemoverTest.java
 delete mode 100644 src/test/java/com/epam/ta/reportportal/job/SaveLogBinaryDataTaskTest.java
 create mode 100644 src/test/java/com/epam/ta/reportportal/util/sample/LaunchSampleUtil.java
 create mode 100644 src/test/java/com/epam/ta/reportportal/ws/controller/PluginPublicControllerTest.java
 rename src/test/java/com/epam/ta/reportportal/ws/converter/builders/{LogBuilderTest.java => LogFullBuilderTest.java} (55%)

diff --git a/.github/workflows/build-dev-image.yml b/.github/workflows/build-dev-image.yml
new file mode 100644
index 0000000000..9dbee6bb91
--- /dev/null
+++ b/.github/workflows/build-dev-image.yml
@@ -0,0 +1,35 @@
+name: Build develop Docker image
+
+on:
+  push:
+    branches:
+      - develop
+    paths-ignore:
+      - '.github/**'
+      - README.md
+
+jobs:
+  variables-setup:
+    name: Setting variables for docker build
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v3
+
+      - name: Create variables
+        id: vars
+        run: |
+          echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT
+    outputs:
+      date: ${{ steps.vars.outputs.date }}
+
+  call-docker-build:
+    name: Call develop Docker build
+    needs: variables-setup
+    uses: reportportal/.github/.github/workflows/build-docker-image.yaml@main
+    with:
+      aws-region: ${{ vars.AWS_REGION }}
+      image-tag: 'develop-${{ github.run_number }}'
+      version: 'develop-${{ github.run_number }}'
+      date: ${{ needs.variables-setup.outputs.date }}
+    secrets: inherit
diff --git a/.github/workflows/build-feature-image.yaml b/.github/workflows/build-feature-image.yaml
new file mode 100644
index 0000000000..757cf2eb51
--- /dev/null
+++ b/.github/workflows/build-feature-image.yaml
@@ -0,0 +1,37 @@
+name: Build feature Docker image
+
+on:
+  pull_request:
+    types: [opened, synchronize, reopened]
+    branches:
+      - 'develop'
+
+jobs:
+  variables-setup:
+    name: Setting variables for docker build
+    runs-on: ubuntu-latest
+    if: (!startsWith(github.head_ref, 'rc/') || !startsWith(github.head_ref, 'hotfix/') || !startsWith(github.head_ref, 'master') || !startsWith(github.head_ref, 'main'))
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v3
+
+      - name: Create variables
+        id: vars
+        run: |
+          echo "tag=$(echo ${{ github.head_ref }}-${{ github.run_number }} | tr '/' '-')" >> $GITHUB_OUTPUT
+          echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT
+    outputs:
+      tag: ${{ steps.vars.outputs.tag }}
+      date: ${{ steps.vars.outputs.date }}
+
+  call-docker-build:
+    name: Call feature Docker build
+    needs: variables-setup
+    uses: reportportal/.github/.github/workflows/build-docker-image.yaml@main
+    with:
+      aws-region: ${{ vars.AWS_REGION }}
+      image-tag: ${{ needs.variables-setup.outputs.tag }}
+      version: ${{ needs.variables-setup.outputs.tag }}
+      branch: ${{ github.head_ref }}
+      date: ${{ needs.variables-setup.outputs.date }}
+    secrets: inherit
diff --git a/.github/workflows/build-rc-image.yaml b/.github/workflows/build-rc-image.yaml
new file mode 100644
index 0000000000..31dc2ff39e
--- /dev/null
+++ b/.github/workflows/build-rc-image.yaml
@@ -0,0 +1,43 @@
+name: Build RC Docker image
+
+on:
+  push:
+    branches:
+      - "rc/*"
+      - "hotfix/*"
+
+jobs:
+  variables-setup:
+    name: Setting variables for docker build
+    runs-on: ubuntu-latest
+    environment: rc
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v3
+
+      - name: Create variables
+        id: vars
+        run: |
+          echo "platforms=${{ vars.BUILD_PLATFORMS }}" >> $GITHUB_OUTPUT
+          echo "version=$(echo '${{ github.ref_name }}' | sed -nE 's/.*([0-9]+\.[0-9]+\.[0-9]+).*/\1/p')" >> $GITHUB_OUTPUT
+          echo "tag=$(echo ${{ github.ref_name }}-${{ github.run_number }} | tr '/' '-')" >> $GITHUB_OUTPUT
+          echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT
+    outputs:
+      platforms: ${{ steps.vars.outputs.platforms }}
+      version: ${{ steps.vars.outputs.version }}
+      tag: ${{ steps.vars.outputs.tag }}
+      date: ${{ steps.vars.outputs.date }}
+      
+  call-docker-build:
+    name: Call release candidate Docker build
+    needs: variables-setup
+    uses: reportportal/.github/.github/workflows/build-docker-image.yaml@main
+    with:
+      aws-region: ${{ vars.AWS_REGION }}
+      image-tag: ${{ needs.variables-setup.outputs.tag }}
+      release-mode: true
+      additional-tag: 'latest'
+      build-platforms: ${{ needs.variables-setup.outputs.platforms }}
+      version: ${{ needs.variables-setup.outputs.version }}
+      date: ${{ needs.variables-setup.outputs.date }}
+    secrets: inherit
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
deleted file mode 100644
index a508772bc0..0000000000
--- a/.github/workflows/build.yml
+++ /dev/null
@@ -1,40 +0,0 @@
-name: Build
-
-on:
-  pull_request:
-  push:
-    branches:
-      - master
-      - develop
-    paths-ignore:
-      - '.github/**'
-      - README.md
-      - gradle.properties
-
-jobs:
-  build:
-    runs-on: ubuntu-latest
-    steps:
-      - name: Checkout repository
-        uses: actions/checkout@v2
-
-      - name: Set up JDK 11
-        uses: actions/setup-java@v2
-        with:
-          distribution: 'adopt'
-          java-version: '11'
-
-      - name: Grant execute permission for gradlew
-        run: chmod +x gradlew
-
-      - name: Setup git credentials
-        uses: oleksiyrudenko/gha-git-credentials@v2
-        with:
-          name: 'reportportal.io'
-          email: 'support@reportportal.io'
-          token: ${{ secrets.GITHUB_TOKEN }}
-
-      - name: Build with Gradle
-        id: build
-        run: |
-          ./gradlew build
diff --git a/.github/workflows/java-checks.yml b/.github/workflows/java-checks.yml
new file mode 100644
index 0000000000..958772ddd2
--- /dev/null
+++ b/.github/workflows/java-checks.yml
@@ -0,0 +1,22 @@
+name: Java checks
+
+on:
+  pull_request:
+    types: [opened, synchronize, reopened]
+    paths-ignore:
+      - '.github/**'
+      - README.md
+      - gradle.properties
+  push:
+    branches:
+      - master
+      - develop
+    paths-ignore:
+      - '.github/**'
+      - README.md
+      - gradle.properties
+
+jobs:
+  call-java-cheks:
+    name: Call Java checks
+    uses: reportportal/.github/.github/workflows/java-checks.yaml@main
diff --git a/.github/workflows/manually-release.yml b/.github/workflows/manually-release.yml
index a4ac9994db..b40635ee11 100644
--- a/.github/workflows/manually-release.yml
+++ b/.github/workflows/manually-release.yml
@@ -19,11 +19,11 @@ jobs:
       - name: Checkout repository
         uses: actions/checkout@v2
 
-      - name: Set up JDK 11
+      - name: Set up JDK 21
         uses: actions/setup-java@v2
         with:
           distribution: 'adopt'
-          java-version: '11'
+          java-version: '21'
 
       - name: Grant execute permission for gradlew
         run: chmod +x gradlew
@@ -42,4 +42,4 @@ jobs:
           -PgithubUserName=${{env.GH_USER_NAME}} -PgithubToken=${{secrets.GITHUB_TOKEN}} \
           -PpublishRepo=${{ env.REPOSITORY_URL }}${{ github.repository }} \
           -PgpgPassphrase=${{secrets.GPG_PASSPHRASE}} -PgpgPrivateKey="${{secrets.GPG_PRIVATE_KEY}}" \
-          -Prelease.releaseVersion=${{env.RELEASE_VERSION}}
\ No newline at end of file
+          -Prelease.releaseVersion=${{env.RELEASE_VERSION}}
diff --git a/.github/workflows/rc.yaml b/.github/workflows/rc.yaml
deleted file mode 100644
index 98d9ca8724..0000000000
--- a/.github/workflows/rc.yaml
+++ /dev/null
@@ -1,80 +0,0 @@
-name: Build RC Docker image
-
-on:
-  push:
-    branches:
-      - "rc/*"
-      - "hotfix/*"
-
-env:
-  AWS_REGION: ${{ vars.AWS_REGION }}         # set this to your preferred AWS region, e.g. us-west-1
-  ECR_REPOSITORY: ${{ vars.ECR_REPOSITORY }} # set this to your Amazon ECR repository name
-  PLATFORMS: ${{ vars.BUILD_PLATFORMS }}     # set target build platforms. By default linux/amd64
-  RELEASE_MODE: ${{ vars.RELEASE_MODE }}
-
-jobs:
-  build-and-export:
-    name: Build and export to AWS ECR
-    runs-on: ubuntu-latest
-    environment: rc
-    steps:
-      - name: Checkout
-        uses: actions/checkout@v3
-
-      - name: Configure AWS credentials
-        uses: aws-actions/configure-aws-credentials@v2
-        with:
-          # role-to-assume: arn:aws:iam::123456789012:role/my-github-actions-role
-          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
-          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
-          aws-region: ${{ env.AWS_REGION }}
-
-      - name: Login to Amazon ECR
-        id: login-ecr
-        uses: aws-actions/amazon-ecr-login@v1
-        with:
-          mask-password: 'true'
-
-      - name: Create variables
-        id: vars
-        run: |
-          echo "tag=$(echo ${{ github.ref_name }}-${{ github.run_number }} | tr '/' '-')" >> $GITHUB_OUTPUT
-          echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT
-          echo "version=$(echo '${{ github.ref_name }}' | sed -nE 's/.*([0-9]+\.[0-9]+\.[0-9]+).*/\1/p')" >> $GITHUB_OUTPUT
-      
-      - name: Set up QEMU
-        uses: docker/setup-qemu-action@v2
-      
-      - name: Set up Docker Buildx
-        uses: docker/setup-buildx-action@v2
-
-      - name: Build
-        uses: docker/build-push-action@v4
-        env:
-          VERSION: ${{ steps.vars.outputs.version }}
-          DATE: ${{ steps.vars.outputs.date }}
-          IMAGE_TAG: ${{ steps.vars.outputs.tag }}
-          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
-        with:
-          context: .
-          push: true
-          build-args: |
-            APP_VERSION=${{ env.VERSION }}
-            BUILD_DATE=${{ env.DATE }}
-            GITHUB_USER=${{ secrets.GH_USER }}
-            GITHUB_TOKEN=${{ secrets.GH_TOKEN }}
-            RELEASE_MODE=${{ env.RELEASE_MODE }}
-          platforms: ${{ env.PLATFORMS }}
-          tags: |
-            ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:${{ env.IMAGE_TAG }}
-            ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:latest
-      
-      - name: Summarize
-        env:
-          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
-          IMAGE_TAG: ${{ steps.vars.outputs.tag }}
-        run: |
-          echo "## General information about the build:" >> $GITHUB_STEP_SUMMARY
-          echo "" >> $GITHUB_STEP_SUMMARY
-          echo "- :gift: Docker image in Amazon ECR: ecr/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_STEP_SUMMARY
-          echo "- :octocat: The commit SHA from which the build was performed: [$GITHUB_SHA](https://github.com/$GITHUB_REPOSITORY/commit/$GITHUB_SHA)" >> $GITHUB_STEP_SUMMARY
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 11f7c0cd29..ef232831f9 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -11,7 +11,7 @@ on:
 
 env:
   GH_USER_NAME: github.actor
-  RELEASE_VERSION: 5.10.1
+  RELEASE_VERSION: 5.11.0
   REPOSITORY_URL: 'https://maven.pkg.github.com/'
 
 jobs:
@@ -21,11 +21,11 @@ jobs:
       - name: Checkout repository
         uses: actions/checkout@v2
 
-      - name: Set up JDK 11
+      - name: Set up JDK 21
         uses: actions/setup-java@v2
         with:
           distribution: 'adopt'
-          java-version: '11'
+          java-version: '21'
 
       - name: Grant execute permission for gradlew
         run: chmod +x gradlew
diff --git a/Dockerfile b/Dockerfile
index a2543c295a..7953abb037 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,24 +1,20 @@
-FROM gradle:6.8.3-jdk11 AS build
+FROM --platform=$BUILDPLATFORM gradle:8.4.0-jdk21 AS build
 ARG RELEASE_MODE
 ARG APP_VERSION
-ARG GITHUB_USER
-ARG GITHUB_TOKEN
 WORKDIR /usr/app
 COPY . /usr/app
 RUN if [ "${RELEASE_MODE}" = true ]; then \
     gradle build --exclude-task test \
         -PreleaseMode=true \
-        -PgithubUserName=${GITHUB_USER} \
-        -PgithubToken=${GITHUB_TOKEN} \
         -Dorg.gradle.project.version=${APP_VERSION}; \
     else gradle build --exclude-task test -Dorg.gradle.project.version=${APP_VERSION}; fi
 
 # For ARM build use flag: `--platform linux/arm64`
-FROM --platform=$BUILDPLATFORM amazoncorretto:11.0.20
+FROM --platform=$BUILDPLATFORM amazoncorretto:21.0.2
 LABEL version=${APP_VERSION} description="EPAM Report portal. Main API Service" maintainer="Andrei Varabyeu <andrei_varabyeu@epam.com>, Hleb Kanonik <hleb_kanonik@epam.com>"
 ARG APP_VERSION=${APP_VERSION}
 ENV APP_DIR=/usr/app
-ENV JAVA_OPTS="-Xmx1g -XX:+UseG1GC -XX:InitiatingHeapOccupancyPercent=70 -Djava.security.egd=file:/dev/./urandom"
+ENV JAVA_OPTS="-Xmx1g -XX:+UseG1GC -XX:InitiatingHeapOccupancyPercent=70 -Djava.security.egd=file:/dev/./urandom "
 WORKDIR $APP_DIR
 COPY --from=build $APP_DIR/build/libs/service-api-*exec.jar .
 VOLUME ["/tmp"]
diff --git a/README.md b/README.md
index 791a2c1eee..742e13338d 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,6 @@
 # ReportPortal. Main API Module
+
+[![Docker Pulls](https://img.shields.io/docker/pulls/reportportal/service-api.svg?maxAge=159200)](https://hub.docker.com/r/reportportal/service-api/)
 [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
 [![stackoverflow](https://img.shields.io/badge/reportportal-stackoverflow-orange.svg?style=flat)](http://stackoverflow.com/questions/tagged/reportportal)
 [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Freportportal%2Fservice-api.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Freportportal%2Fservice-api?ref=badge_shield)
@@ -6,9 +8,9 @@
 [![Build](https://github.com/reportportal/service-api/actions/workflows/build.yml/badge.svg)](https://github.com/reportportal/service-api/actions/workflows/build.yml)
 [![Code Coverage](https://codecov.io/gh/reportportal/service-api/graphs/badge.svg)](https://codecov.io/gh/reportportal/service-api)
 [![Maven Central](https://img.shields.io/maven-central/v/com.epam.reportportal/service-api.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22com.epam.reportportal%22%20AND%20a:%22service-api%22)
-[![Docker Pulls](https://img.shields.io/docker/pulls/reportportal/service-api.svg?maxAge=159200)](https://hub.docker.com/r/reportportal/service-api/)
-
+[![Total alerts](https://img.shields.io/lgtm/alerts/g/reportportal/service-api.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/reportportal/service-api/alerts/)
 
 ## Copyright Notice
+
 Licensed under the [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0)
 license (see the LICENSE file).
diff --git a/build.gradle b/build.gradle
index b157bd1b9b..1ff5d40461 100644
--- a/build.gradle
+++ b/build.gradle
@@ -15,10 +15,10 @@
  */
 
 plugins {
-    id "io.spring.dependency-management" version "1.0.9.RELEASE"
-    id 'org.springframework.boot' version '2.5.12'
+    id "io.spring.dependency-management" version "1.1.4"
+    id 'org.springframework.boot' version '2.5.15'
     id 'java'
-    id "org.owasp.dependencycheck" version "5.3.1"
+    id "org.owasp.dependencycheck" version "8.2.1"
 }
 
 import org.owasp.dependencycheck.reporting.ReportGenerator
@@ -37,124 +37,126 @@ project.hasProperty('sealightsSession') && sealightsSession?.trim() ? apply(from
 
 repositories {
     mavenCentral { url "https://repo1.maven.org/maven2" }
-    if (releaseMode) {
-        dependencyRepos.forEach { path ->
-            maven {
-                setUrl("https://maven.pkg.github.com/reportportal/${path}")
-                credentials {
-                    username = findProperty("githubUserName")
-                    password = findProperty("githubToken")
-                }
-            }
-        }
-    } else {
+
+    if (!releaseMode) {
         maven { url 'https://jitpack.io' }
     }
-//    maven { url "http://jasperreports.sourceforge.net/maven2" }
-//    maven { url "http://jaspersoft.artifactoryonline.com/jaspersoft/third-party-ce-artifacts" }
     maven { url "https://jaspersoft.jfrog.io/artifactory/third-party-ce-artifacts" }
 }
 
 //https://nvd.nist.gov/vuln/detail/CVE-2020-10683 (dom4j 2.1.3 version dependency) AND https://nvd.nist.gov/vuln/detail/CVE-2019-14900
-ext['hibernate.version'] = '5.4.18.Final'
+ext['hibernate.version'] = '5.6.15.Final'
 //https://nvd.nist.gov/vuln/detail/CVE-2020-10693
-ext['hibernate-validator.version'] = '6.1.5.Final'
+ext['hibernate-validator.version'] = '6.2.5.Final'
 //https://nvd.nist.gov/vuln/detail/CVE-2020-13692
 //ext['postgresql.version'] = '42.2.13'
 //https://nvd.nist.gov/vuln/detail/CVE-2020-9488 and https://nvd.nist.gov/vuln/detail/CVE-2021-44228 and https://nvd.nist.gov/vuln/detail/CVE-2021-45046
-ext['log4j2.version'] = '2.17.1'
-ext['log4j-to-slf4j.version'] = '2.17.1'
+ext['log4j2.version'] = '2.21.1'
+ext['log4j-to-slf4j.version'] = '2.21.1'
 //https://nvd.nist.gov/vuln/detail/cve-2022-22965
-ext['spring-boot.version'] = '2.5.12'
+ext['spring-boot.version'] = '2.5.15'
 
 dependencyManagement {
     imports {
-        mavenBom(releaseMode ? 'com.epam.reportportal:commons-bom:' + '5.10.0' : 'com.github.reportportal:commons-bom:6aa55fc0')
+        mavenBom(releaseMode ? 'com.epam.reportportal:commons-bom:' + '5.11.6' : 'com.epam.reportportal:commons-bom:5.11.6')
         mavenBom('io.zonky.test.postgres:embedded-postgres-binaries-bom:12.9.0')
     }
 }
 
 dependencies {
     if (releaseMode) {
-        compile 'com.epam.reportportal:commons-dao'
-        compile 'com.epam.reportportal:commons-rules'
-        compile 'com.epam.reportportal:commons-model'
-        compile 'com.epam.reportportal:commons'
-        compile 'com.epam.reportportal:commons-fonts'
-        compile 'com.epam.reportportal:plugin-api'
+        implementation 'com.epam.reportportal:commons-events'
+        implementation 'com.epam.reportportal:commons-dao'
+        implementation 'com.epam.reportportal:commons-rules'
+        implementation 'com.epam.reportportal:commons-model'
+        implementation 'com.epam.reportportal:commons'
+        implementation 'com.epam.reportportal:commons-fonts'
+        implementation 'com.epam.reportportal:plugin-api'
     } else {
-        compile 'com.github.reportportal:commons-events:e337f8b7be'
-        compile 'com.github.reportportal:commons-dao:34829fb198'
-        compile 'com.github.reportportal:commons-rules:5.10.0'
-        compile 'com.github.reportportal:commons-model:e0a12669'
-        compile 'com.github.reportportal:commons:ce2166b'
-        compile 'com.github.reportportal:commons-fonts:d6e62dd'
-        compile 'com.github.reportportal:plugin-api:fb8845f'
+        implementation 'com.epam.reportportal:commons-events'
+        implementation 'com.epam.reportportal:commons-dao'
+        implementation 'com.epam.reportportal:commons-rules'
+        implementation 'com.epam.reportportal:commons-model'
+        implementation 'com.epam.reportportal:commons'
+        implementation 'com.epam.reportportal:commons-fonts'
+        implementation 'com.epam.reportportal:plugin-api'
     }
 
-    compile 'org.springframework.boot:spring-boot-starter-aop'
-    compile 'org.springframework.boot:spring-boot-starter-web'
-    compile 'org.springframework.boot:spring-boot-starter-quartz'
-    compile 'org.springframework.boot:spring-boot-starter-freemarker'
-    compile 'org.springframework.boot:spring-boot-starter-actuator'
-    compile 'org.springframework.boot:spring-boot-starter-amqp'
-    compile('org.springframework.boot:spring-boot-starter-batch')
+    implementation 'org.springframework.boot:spring-boot-starter-aop'
+    implementation 'org.springframework.boot:spring-boot-starter-web'
+    implementation 'org.springframework.boot:spring-boot-starter-quartz'
+    implementation 'org.springframework.boot:spring-boot-starter-freemarker'
+    implementation 'org.springframework.boot:spring-boot-starter-actuator'
+    implementation 'org.springframework.boot:spring-boot-starter-amqp'
+    implementation 'org.springframework.boot:spring-boot-starter-batch'
 
 
-    compile group: 'com.opencsv', name: 'opencsv', version: '5.7.1'
+    implementation 'com.opencsv:opencsv:5.8'
 
     // Fix CVE-2021-41079, CVE-2022-23181, CVE-2021-33037, CVE-2021-30640, CVE-2022-42252
-    compile 'org.apache.tomcat.embed:tomcat-embed-core:9.0.68'
-    compile 'org.apache.tomcat.embed:tomcat-embed-el:9.0.68'
-    compile 'org.apache.tomcat.embed:tomcat-embed-websocket:9.0.68'
+    implementation 'org.apache.tomcat.embed:tomcat-embed-core:9.0.82'
+    implementation 'org.apache.tomcat.embed:tomcat-embed-el:9.0.82'
+    implementation 'org.apache.tomcat.embed:tomcat-embed-websocket:9.0.82'
     //
 
     //https://nvd.nist.gov/vuln/detail/CVE-2020-5411
-    compile('org.springframework.batch:spring-batch-core:4.2.3.RELEASE')
-    compile('org.springframework.batch:spring-batch-infrastructure:4.2.3.RELEASE')
+    implementation('org.springframework.batch:spring-batch-core:4.3.9')
+    implementation('org.springframework.batch:spring-batch-infrastructure:4.3.9')
 
 
     // Optional for spring-boot-starter-amqp
-    compile "com.rabbitmq:http-client:2.1.0.RELEASE"
+    implementation "com.rabbitmq:http-client:5.2.0"
 
-    compile 'com.sun.mail:javax.mail:1.6.2'
-    compile 'net.sf.jasperreports:jasperreports:6.12.2'
-    compile 'com.lowagie:itext:2.1.7.js7'
+    implementation 'com.sun.mail:javax.mail:1.6.2'
+    // check authentication error response format for versions higher than 6.18.1
+    implementation 'net.sf.jasperreports:jasperreports:6.18.1'
+    implementation 'xerces:xercesImpl:2.12.2'
+    implementation 'com.lowagie:itext:2.1.7.js7'
     // JasperReport's export to XLS uses Apache POI
-    compile 'org.apache.poi:poi:4.1.1'
-    compile 'io.springfox:springfox-swagger2'
+    implementation 'org.apache.poi:poi:4.1.2'
+    implementation 'io.springfox:springfox-swagger2:2.9.2'
+    implementation 'com.google.code.gson:gson:2.8.9'
+
 
     ///// Security
     //https://nvd.nist.gov/vuln/detail/CVE-2020-5407 AND https://nvd.nist.gov/vuln/detail/CVE-2020-5408
-    compile 'org.springframework.security:spring-security-core:5.5.8'
-    compile 'org.springframework.security:spring-security-config:5.5.8'
-    compile 'org.springframework.security:spring-security-web:5.5.8'
+    implementation 'org.springframework.security:spring-security-core:5.8.8'
+    implementation 'org.springframework.security:spring-security-config:5.8.8'
+    implementation 'org.springframework.security:spring-security-web:5.8.8'
     //
 
     // Fix CVE-2022-22969
-    compile 'org.springframework.security.oauth:spring-security-oauth2:2.5.2.RELEASE'
-    compile 'org.springframework.security:spring-security-jwt:1.0.11.RELEASE'
-    compile 'org.springframework.security:spring-security-acl'
-    compile 'com.github.ben-manes.caffeine:caffeine:2.8.0'
+    implementation 'org.springframework.security.oauth:spring-security-oauth2:2.5.2.RELEASE'
+    implementation 'org.springframework.security:spring-security-jwt:1.1.1.RELEASE'
+    implementation 'org.springframework.security:spring-security-acl'
+    implementation 'com.github.ben-manes.caffeine:caffeine:2.9.3'
 
     // Fix CVE-2022-22965, CVE-2022-22970
-    compile 'org.springframework:spring-beans:5.3.20'
+    implementation 'org.springframework:spring-beans:5.3.31'
     // Fix CVE-2021-22060, CVE-2021-22096
-    compile 'org.springframework:spring-core:5.3.20'
+    implementation 'org.springframework:spring-core:5.3.31'
     // Fix CVE-2022-45685, CVE-2022-40150, CVE-2022-40149
-    compile 'org.codehaus.jettison:jettison:1.5.2'
+    implementation 'org.codehaus.jettison:jettison:1.5.4'
     // Fix CVE-2020-15522
-    compile 'org.bouncycastle:bcprov-jdk15on:1.69'
-    compile 'org.apache.commons:commons-compress:1.21'
-    compile 'org.yaml:snakeyaml:1.32'
-    compile 'org.hibernate:hibernate-core:5.4.24.Final'
+    implementation 'org.bouncycastle:bcprov-jdk15on:1.70'
+    implementation 'org.apache.commons:commons-compress:1.25.0'
+    implementation 'org.yaml:snakeyaml:1.33'
+    implementation 'org.hibernate:hibernate-core:5.6.15.Final'
 
     // Metrics
-    compile 'io.micrometer:micrometer-registry-prometheus:1.7.10'
+    implementation 'io.micrometer:micrometer-registry-prometheus:1.8.13'
+
+    // add lombok support
+    compileOnly "org.projectlombok:lombok:${lombokVersion}"
+    annotationProcessor "org.projectlombok:lombok:${lombokVersion}"
+    testCompileOnly "org.projectlombok:lombok:${lombokVersion}"
+    testAnnotationProcessor "org.projectlombok:lombok:${lombokVersion}"
 
     //  Tests
-    testCompile 'org.springframework.boot:spring-boot-starter-test'
-    testCompile 'org.flywaydb.flyway-test-extensions:flyway-spring-test:7.0.0'
+    testImplementation 'org.springframework.boot:spring-boot-starter-test'
+    testImplementation 'org.mockito:mockito-core:5.7.0'
+    testImplementation 'net.bytebuddy:byte-buddy:1.14.9'
+    testImplementation 'org.flywaydb.flyway-test-extensions:flyway-spring-test:9.5.0'
 }
 
 processResources {
@@ -164,7 +166,9 @@ processResources {
     }
 }
 
-tasks.withType(JavaCompile) {
+tasks.withType(JavaCompile).configureEach {
+    sourceCompatibility = JavaVersion.VERSION_21
+    targetCompatibility = JavaVersion.VERSION_21
     options.encoding = "UTF-8"
     options.compilerArgs << "-parameters"
     options.debug = true
@@ -191,25 +195,10 @@ test {
         exceptionFormat = 'short'
     }
     reports {
-        junitXml.enabled = true
+        junitXml.required = true
     }
 }
 
-jacocoTestReport {
-    doFirst {
-        classDirectories.setFrom(
-                classDirectories.files.collect {
-                    fileTree(dir: it, exclude: [
-                            'com/epam/ta/reportportal/core/events/AnalysisEvent.class',
-                            'com/epam/ta/reportportal/auth/acl/ReportPortalAclAuthorizationStrategyImpl.class',
-                            '**/Abstract*.class'
-                    ])
-                }
-        )
-    }
-
-}
-
 publish.dependsOn build
 publish.mustRunAfter build
 checkCommitNeeded.dependsOn removeScripts
diff --git a/docker-compose.yml b/docker-compose.yml
index be3ea15f13..ee9e4e2b8d 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -70,7 +70,7 @@ services:
       MINIO_SECRET_KEY: minio123
     command: server /data
     healthcheck:
-      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
+      test: [ "CMD", "curl", "-f", "http://localhost:9000/minio/health/live" ]
       interval: 30s
       timeout: 20s
       retries: 3
diff --git a/gradle.properties b/gradle.properties
index e415066637..489863e567 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version=5.10.2
+version=5.11.0
 description=EPAM Report portal. Main API Service
 dockerPrepareEnvironment=
 dockerJavaOpts=-Xmx1g -XX:+UseG1GC -XX:InitiatingHeapOccupancyPercent=70 -Djava.security.egd=file:/dev/./urandom
@@ -12,3 +12,4 @@ dockerJavaOptsDev=-DLOG_FILE=app.log \
                   -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
 dockerServerUrl=unix:///var/run/docker.sock
 org.gradle.jvmargs=-Xmx2048m
+lombokVersion=1.18.30
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
old mode 100755
new mode 100644
index cc4fdc293d0e50b0ad9b65c16e7ddd1db2f6025b..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
HcmV?d00001

literal 58702
zcma&OV~}W3vL#%;<*Hk@ZQHhO+qTVHwr$(CZQFL$+?np4n10i5zVAmKMC6WrGGd+F
zD|4@N<RpPXAOQft!2tjO`2QLJ0MP$B0suh#JxdEK@l%V-h|mH9$o-q6bsY~k-(Lsb
zzlQXGI!g1)h>Hj-D$z)bJV;MYNJ&!D%)v-fQ%q0JG$_z5GVUJTPg0MHPf1Tvic<kX
zo`)DE9~Nqmx1tgk9~M#sp%SAY6{6fZ+&KXLml^*~^1mMq<nOhugX#bERR5<B)IWVp
z9rTT?jQ^jmi2v^D>Y#6DXYBBQ4M`$iC~gA;06+%@0HFQPLj-JXogAJ1j+fRqw^4M`
zcW^RxAfl%+w9<EUj8>SiS>QwBUTAfuFAjPXc2DHf6*sr+V+jLQj^m@DQgHTPmAb@F
z8%GyCfcQkhWWlT31%4$PtV4tV*LI?J#C4orYI~WU(cSR{aEs^ycxY`1>j1po>yDMi
zh4W$pMaecV*mCsOsPLxQ#Xc!RXhpXy*p3S2Hl8t}H7x#p5<WRyv}DXB?O~G(<$s$*
zKaOKsPlhxwVsG;yzcbFHI7dn;N@!ew>V6G5va4jV;5^S^+>+x&#zzv4!R}wB;)TyU
zE_N~}nN>DTG+uZns%_eI=DL1E#<--Sccx30gvMT}^eu`2-u|{qQZ58(rA2aBYE*ZD
zm|*12zg*@J$n|tbH%Mp|d|O9W%VT~<mtdFxoyg6#?kijTREKTws{`nYl9fj8r{K~0
zMu0f8cYQ}X31$v~y4H25-D)q8#heTIRfC~{opJg3^7Ooc5b-v2z7D{(ZN1$J#;pIq
zcmMvi?bwYCS7hZ>xG})R=Ld5z<(z%DOO6=MF3Xh-aF%9Hf$?1N9%8Pkev{wun$jZ2
z^i*EhRt8Ve<7`Wyz~iMZDye+XVn}O%qbhV`wHL+%P+n)K&-UMuZw^RRfeQ)%K=k*m
zq5l7mf`4K_WkV5B73~MxajljrjGiJqpiV#>0FkyyrB)@HY!;Ln(7JJ*W(>d5#^ubU
zVAkTMs*CHzzvUa^nRu0<X(7d>*f-(ek+VZw+@P~}a;;(K=|!9Mhv(~y-ml<QTm%4-
zL1zFI0#z_Ik&f69<7WJpKZ%Y|Uqu8u#Yk(|li~Oe@<?YCJc^N4pR#=?u7HeOb+Daw
z|1Sgu27*?6Lo8NeuhnoJFCu;@efib#$O1fA8h!C$A3(g2{2*g6<8h|8Ec!-=v=sD!
z5+_Ah8OB$HF-qv~DCJ$~4dt!FhNO9dmXjvoKr;QMam!)kspTQh=u_8Z=lVD$>W);J
zb&bB=vySHG`u?j&_6dh^*se*l_B3avjlE|!!Cb0pXyEXRbLy*@WEQ4|)M<`p8<Y|5
z2%93>Q!rfDJ2RI!u1hPzNjy&)(kcY~GaD6?)7#dCbm`NF<g;7l5g5&;Mj%py#Ra;y
z1f5hxOf`Wvp;B#xff%qI8u3<?PxNalP0$dvK)<OJ=xo<{oLC}PR#F@5qU=twiZ#W7
z67lXxhom0vf~r;n1SbcUy7Uvu7@IU>h?Y_g$#!+Qrie7%<7P}<-+W@{sxi4JYI{iY
zk0(>m$DxOI=~-&eXf2bfh^&(U@o)>(iA1_wJ%B(+nFH+ceib%H<b^rOPv2E&MDz*+
zr2XQfL74H-frDv=SY0Pdq#DCW*_^D%3zICZ*|CytwcjZFf`LbQNP;uT36ha5;8j5z
zkkE-B2=@&q?8HR?nCy^Lm13`I{xIWZ1-Sv7kk=8002K(!NL~T5$eRP+<1|gK;}^wB
z*p}nK<Oun@j9xNT6dC~v8w$#xy1SB~x_g%Ag&y;aA<D=3-H_dVde~Z37)+5$(13@U
zpgVj10XKJk#h1vTR=Z&VxVMA@vy>Eck32QL=J(BNFh`f>St1%llF8chX7#cp*;z}&
zcTeXkwsXhf+e;#<mHvK))RWS2J3{sLW+lTJ7aYn7N;z>#!FS2yi=2cChcYfzm$wQJ
z9%4kAq)wLHf5wfcj!A|xDsAiAOHRzf*)Z-|daN9y5jK-*R{Q0?xaSX-3m|WeuZ`BJ
z>eTi@uQ{OGSDIJ#Iu@JPtOy!C?q)g*6SHORg)eAJGh8b-I*X_+xNqZ|OXEsQ-RWte
ze`zjjeV9PpE3ac2za+Rs=PA;%QZ>T{x(TRzwWLp_X^2yC-DOEMUy5So!npzL&-@}u
z#>uK#&`i&c%J$!bsntEJhY@rF(>6eY;6RoI5Qkn!&<80X5+1(<A$tFH9m~_-ye9aQ
z>x$T|wR-ad?4N1N^a0)nBj#&EkVvQ?I_+8t*%l#VK&I?uo$ERI1HMu4P2rLMeH%m3
zZ|HA^*O^dA$gb<A+8nWE*k|^~9YyriduFNhhxV~rFy`G?Fp=Nyxg%Hcw9t{3e=8LB
zF)zo5Es8J(TDV5xlhq!cIHF5nZif)&_hum~A2pjjr;tmkr{n=0C`K<u%<PnC^Yk2C
zzTu%X@i-=%OlQX7fplhWP?xe~(g>$`Cw;z9?G?m3@nH6TNYJ04Fd-M2wp8@(;vAvJ
ztFoni)BLwncQ3@cO*^+6u;(&D<;N;RKb)_NQ_Qu&?@h3MWvo>6FHG%%*smTwj3;dG
zQJnT7Wb?4!XmV^>N@ZkA7Jv9kAfD-gC<I~>Hu2i+!A!}y98SO><8g}t;1JOOxj>#l
zM!?y|j5fR3WY2(&_HSGjgMa?Zif<<W?VbNO!_NOT!vCCUg=}4ItZem-{<X$>M@d8W
z)4>Ptm@zj|xX=bbt$=j}@a_s|xdp6-tRlq6D|xb_;`9oJlkYF1AH%?Pzv$eIAogMi
zf(_H*5t({Arfs5XAPj46pjiudQw?dulW-=OUqBVa)OW9E;^R+NDr&LES&m_nmP>Ga
zPf)7_&Gn(3v1qu_a^qW9w4#XIEfgiHOQ(LDi=E&(-DcUSfuQE0`ULsRvS}fpS@<)3
z|CbQSi49rU{<4|XU;kiV|C7}Gld$}Yh5YXjg^W$~ovobybuZ^&YwBR^=qP3G=wxhT
z?C_5Trbu~95mOoIXUmEOY646_j4ZL)ubCM{qFkl1u*%xs%#18a4!(*b<&edy<8t2w
z_zUxWS5fypUp9ue+eswoJSyv*J&=*3;2;q9U?j>n^q?)}c8+}4Ns8oToBJgD;Ug=y
zOa0>{VFrLJutjR{PJmm(P9lPzoPi{K!I{l)pGwDy59p-uxHB9I&7zl11lkCu(}*A<
zh492AmxsgwEondBpB^{`I*L&Ut40fjM^JS8VdAWQMlwc>_RUM5|Mjes!36DGqW`xs
z4tU4`CpOk|vew8!(L}fEvv5&-3#GqZ(#1EZF4ekDQ@y*$tMDEeG?nOUiS-KXG=rAZ
zHUDlMo@X&yzo1TdE6b6!s#f{*45V-T3`e2)w5Ra3l>JWf46`v?Y6B&7*1$eS4M(3%
z9C~G@<i(!>N@RXm)8~EXL*9IObA+PwD)`%64fON_8}&pqjrg|<uecKJ--R_&hYSS;
z45Wc65)1%>2LmP{W^<0@W`9s^*i#F}V;E8~`-}(4@R4kz?t(RjA;y-r%s^=)15%C>
zbF;NZET~nybEsmUr8sH^Hgq^xc^n$ZP=GcZ!-X-Go7J4nByj8%?aQ`c{88;p15K<V
z_d~|1+?4Of*5i$x2xWRe8tvdys2dG>f>|0h+5BLkM&@KI-(flp^npO3MC~W@Uyjv*
z6Hu!4#(NtZJ0*;_{8<J7i=0az&%(<wS04-($bOqbcbe=uYc<`1Rb#j%;6L!T%ZS_V
zMbGG<3YW{=7)G%MCMRNB>^xcLrC4-zK$BVo7S5V=eg?R8P;BOpK3Xwms+Jt-8R6us
zf_rUHFYHn~lu!)U$e$#%UBz7d8YS;mq}xx$T1PIi=4={c-_cY6OVc<=){mOVn>~J$
zW*2PB%*40eE^c<dlxK9Bvqt-M7aU^3PVe-^Jdu~jOmq^mOt%KN4?i~W$Rz0zz3gTI
zO10DxC0A~Xt|6f*@>+d=PP7J@bqIX_h4u6b6#W|ir<;IlR`#s`Q*_Z8Q?*s<ipU}C
znJI(0^W}FQE#0cJ?}zrKq&LVFW@=gW@-3uOe9H}<#JHT}p&{DB{3o-4!x`}b_o6VK
zx_QKsJ{r-=Y5h-fZFj+CH)$d6Y$&chBrmxO`M#7{#wFMtQhdY~p2sMLLWhoXb?h@o
zqg!S0;-k+JS<Moesi8@EgD2<{{X!b%EaE#h7NN;r&^HdO_%wt!GRa&Fc2{T!e6b=#
zR{1MnI@pu!?=15b)mgWnY9L&^02S(JQaRCkQ;Kui#Z+B;pq{udS&lnShF4(1SIHuW
z_)%trHzwlpgrUL&*@|H!)`f}k!qoM#LZ&1o>_&emuu8D;NSiPX9mK?>$CwcbjhCuv
zO&u(0)@}8nZe=Fl*0uMri02oYDjs#g$OHCZ6oTXV2Y0TrZ}+o%{%i)OAJBj2xHC<V
zJg9%`K&ii}iRu3%^Zw04ZtncfPG-h7PUeRCPPYHdL`jNQHVFJk+zoOlEs{gZeHtJ7
znimR5MLxoT^yYLVBxdPK8L8jt{UFO$u48m!?v&9G@X}rYxZ`f7l9c8UOJ8-2jyLQl
z*_^Bo7cVb4066<)!Rl1%wRJ`Y?9s?jEp_R`8W<NIo+JHW*BWBI%ys7bID+TFxbNr0
zg8kH&^hA{M+H_jg?|E)3>|F5o+`Qmq`$`2EaL=uePwq%k<;6S2n=w%_9vj$8NO|{`
zTEg*tK8PU#DnQ#dQ2mMJaaL|HV;BCn?eQ%d0v<K_HfTbf-99?GlXN@q7NMtGV#^~A
zK1d9eZNcZH-)WwCa@$67YlGe)%B~iBRrS~FY!viVx&TJCE(I}_;Va$O+>Y@S7Pu@7
zsf5u`T=bL7NfyYO?K^PR_|jap@<F00udMd{#(px%QdVnBTcYiwhKRCg5kIbJ&~1u_
zrU;RW878B{gMOhfwk<0v`+xLRW`sq8l(<7+S~$Su=ixAq`rqIO8X$Uo3r%K*M}s0L
zq-k1;4vh%TP@XBF-yn#eDLwk36xRnKyD%`{C3|NBLAn4q+#Bbi=^EJm?vhx*>K|qQ
zmO8CK+&O3fzgEnp2|_=^K9ln~QhxjgMM>EQqY@k@@#np@FnZq|C{EyEP7^NurUm0q
zW5rKmiy%__KE>YItA<BWGcGAzq0!#vJ2KS5%v%gT395&RU@W@)Dr)Tn2kOsw{~c(u
zSvk0UumAvvH~;|n|8JoEV|}Yqhj7zUb^eYuahEM988Xy-UJYlAF%(_K;EchZ2uGZ_
zSiKipR%56?V3VCsV0tzaNpm;URQKcCLNS93ZVcuFhZpm!WkZUULZWk`r`A3dK$SR4
zpYL+YD{2IJ>TyMhE({0%ve10la=mUd<^AcB{T_$Y`2_N-x;F#3xTORXvhPZ7psm<b
zUAnad>qhXy?WxxB5w!m*4&Q;?t$4Kt?m_em-htVDxora24&6~5z$MG(RT{trtp(L(
zy&VDT{@p9_DGoq+I|abw$E!TyTO7j6dWQ<wiR)Vy(!+3D@A2&nAbX$*_zCl^0^_SH
zZS8Bjj|=oF`kCPG%W`)Gz_O?7CFhIbhw(}IP3>25dqdKV*z3E?n-p|IG42ZUnNok?
zY4K{y{27bUT@#|Zcni!tIgjE`j=-0rl(tVlWEn>5x7BJBkt0iw6j^4n1f2i^6ebo;
zt^&Yb##}W0$3xhH&Nz*nANYpO$emARR6-FWX;C?(l7+}<97Ay#!y%BI6^st=LaJ>n
zu{ORVJ9%`f*oy85MUf@Fek@T_+ML0-0b$lkEE2y8h%#P^<E#sUGr^uAAmf?6z=dV+
zT2fn#MB!P?mV-Ijg(2<QZP<B~3_RY+-a>X6+cn<CYt==OX!%7nR>)IEXa@T7CQ{fV
z-{^wJGN*+T!NsAH@VNM3tWG;%y{pV<xGCY<FKd*exDmpl{T&W#b;p$ig}qG|?>F2m
z2*0+i?o40zSKVq_S18#=0RrJIse+;5cv#a`*`wNs+B%Ln8#e0v^I>7a_33h?lHo14
zg)CbDfGMyH2cj%7C`>|Rrg;U?$&y!z(U10>(dHKQsf9*=z)&@9u@w%y+e@*CnUS|E
z*O^cQqM*!sD|e!u(yhXPi$Sl<$daf3sq@Ie<ZQHLniQg<q{eeW>xafxt3F#2R&=cK
z!gT-qto{oVdGUIxC0q`tg)B-Zy(pxGx}&svoA}7p=}jb3<Deq;uYCwnOS;Rr-^Lgh
z20WA(rh{XxcSiiGTc2H2eqX4eS>jEjQ!v6=afKI!2`&M{#tY$~3LR}#G#U2up2L{}
zMGSX>Yjg6-^vWgeX0i;Nb0=gQmYa!|r0rRUshm2+z3AlehjfTqRGnRAmGhHY3`R_@
zPh4GAF@=nkRz;xMO3TPh$)9Iq?Fs5B@~)Q<G^#^w-p1z4@tK-Tg<F4M1#K9OBJnk0
z+Ooh*FXc;ku~92E;V-A4fXBlIVb(;ppgmHu!r^G8PLCtrG%kb2we(sar!y-`MdAy{
z`=|e8**Dv6<X|mR*OrwDm@5nX385dEvX#Jf-n>IntSyeBy^10!ts?9Z@tK&L6xJd9
zNzaaz<rXw;6ED)9yFL}aX;}zw-PcebRxU3jIEY~o>6zvrtr&MPQ@UD)njFUtFupwB
zv+8%r`c@#asm}cKW^*x0%v_k3faHOnRLt7vzVFlqslue32rt(NNXnkS+fMSM&^u)8
zC`p{on>0pf=1id|vzdTnBLB;v%*ta`o_lzj21u+U-cTRXR%sxE%4k<(bU!orfsJ&v
z3FLM2UT_*)BJm1^W;Z{0<d(!lZ_}A{gA{p}>;z^_e=N&QXSO>rdB`*cp>yGnjHJt$
zcJd~52X&k1b<-`2R{bqLm*E(W{=|-)RTB*i$h4TdV12@beTkR&*iJ==ck*QlFiQ52
zBZ|o_LP06C?Sgs3VJ=oZQU0vK6#}f9gHSs)JB7TU2h~}UVe%un<qkD{F?01SaaNX7
z)^EWW&3Rg@z9Zs4r{qbscuGj<-Fl||#+VyPb-*E+wTI3OW@F;)#D4fM>JA!URBgJ#
zI~26)lGD4yk~ngKRg;(s4f@PccDZaL{Y=%6UKHl&k|M@Zc4vdx-DX4{belQ);URF?
zyxW+|Ziv}%Y<r9Dq}a^~ObiFm4~Y;n`Vy<s!I7z$$Hlk&*e$o<6C~KU;}qG?cDDWa
z>!sFdY@YO))Z|f34L(WjN*v#EfZHn6m)X@;TzQ@wIjl4B_TieZY}qY`mG}3VL{w?;
z&O>sZ8)YnW+eLuW@rhClOOCZe2YP@4YWKN?P{c~zFUj*U?OayavPUo!r{uqA1<8h!
zs0=rKKlwJYk~34F9$q6fQ&jnw_|@cTn{_kA8sUZ#2(Lb@R$NL*u>08yYGx{p6OeX~
zr7!lwGqMSury(v5=1_9%#*MORl2apGf(MQIQTMN35yE3l`^OS7r;SKS6&v-5q}Gw*
zNWI*4OKBD&2YbCr8c{ifn~-9w-v+mV49W+k)$jjU@WA+Aok01SA#X$Sspj}*r52!-
zNqOS<0%uMUZeSp+*i1TEO$KGKn7EwzW=s?(b5X^@3s5k*80ns2I2|bTHU+bWZ$x;j
z`k@<m7i|D;)p+5h2=doQb#<n7oFI?h-8r2Le0MiDcODojim!C5C7&lD!*Tb;{j^M!
zwo4_dJ|LYnc7;R>>)1G#JgT=F!8awgol?DqK^S4R*g?<j)Em0v<Rr^iEUud)JcOH(
z;j}xl%Ki+t#kp}5-1LyHCEG}dwhXenu4yedz7AtrlzTlWS~@$is%I}VLm5qXh=H9c
z=RD{ouN=1VZE5UvE5AADipriSPn0vLPSj+*b)YLV>e}2rOYRVMUKKxSudO(hOLnnL
zQqpxPNouLiQFYJs3?7!9f6!-#Pi83{q3-GgOA|{btKup4fYDu-JFOK~Q1c3KD@fdJ
z?uABYOkHA^Fc~l0gTAy4geF<-1UqdS=b=UM6Xi30mPhy1-f^aQh9H(jwFl5w*X`Mh
z=Ee5C<tYtM&3HgW2B%f^TRXT=U62{6MBC$8$4Z|{?j2f=zZggy{xnO!otRFog--_9
zp;oV#6Ml}L5D_jvr_=ldE2?RSY|XQmVlDd>?038GEqSVTd!67bn9*zQg-r8RIH3$$
zf8vWEBbOc`_0U{b)t)Toa~~<7c-K_=G%*iTW^?6mj9{#)<L8!847Sdr#z3mABv$w=
zEvStNJ~?l6I@Kk@27iwDE^HS$6ph<mYmV@yOUSNX1EEp~l?On9(o~Lc2;tl5;RQ9Y
zjkp8xA(PaCi5E)TBzXDOUUEn0z7y?nm3B)!K6veo!9no=A7=FnV&NWZ@_OCgt8Z-*
zR9P?lL2XPGWimt_QAsr$D9B_!LBI3p<p05_)1XA)RxB@nlp=pHL$;+Vb^E1Us>@|#
zku9R^IDzbzzERz~fpxFrU*it;-Iu&<j;5*?pXVX-!@&XPBzIw**a7Oi8iCxJ)wdQB
z-72`zNKM;jv``!`ozd8#?2)|0QkGUfElI&!1G)TUX6cXI*Q>m!CAtM&$)6^2rMyV4
z$+e!$(e)!UY(Sc9n6hkr^n&cvqy8}NfZz+AQc8fU9lNczlP>5D3qzWoR55YvH94^*
z-S%SVQ<IE2ZA<>96pK3|Yo`75D&85)xij9Dl8AO<OG)v-)LY{lc$!e^^sZ4&kUDTL
z^8>8{J*{_yhs-KtsLXUYqwieO(nfrkB@%|OyI>yF+1G?m7>X&djb(HBNNw3KX;M<Q
zZL^M3x-GBRRlsrxmBt?Qt3_3n8|H*!`NZzQv-X~G6~2==G@5ah39Zu^LwW_nQbk3#
z-gS{_`P|gn@Cwo@yVPf&Tulp7%VS@>a*oMV)cV0xzxmIy+5>yz>l_LLH)VyRnYYce
zw$?q!hJzX0TlE0+o5QJDM~sPrjVCN7#|32#rUkc>?-eN6Q0RqQTAl~`&isrQg)ass
z+x5XapaYh{Dj`+V096?w)w2!Cnmh?x1WmFC$jEFY4;V)XAl3*tBS)V)3TbL)g46_g
zCw9pl^!3OCTOcaEP!?==guEAw;VZ}fE6K-;@qD-Rx~td+j(N>)Wv$_mq<O4G#`)_D
zg%4ybW4PuW2>FTH_wVZNEEuDG!0T`HXLsf+_E=X3lw4`_&d5&YMl%H733ckO){vZm
znF<wT-MSz)%0zh6H-vHoxb5hdUc&M}_nclvZU{HVN=o#;5dP|r)y%ciy(qvpjJJvY
zFPLuYy}zIz(W4UF%1lwDB^|<#*Js%z1-~NS!lW9UOtvABw4uH1lE0Q}&5B+_p|MQP
zWQ5y{y$#BD9FWrQ!2?U%&A*_Vp;=C9mDx6@bF4qx0(m#y8VoU9b!eK(bZyymm!B{0
z^hKOxhD1l-sIn<bUyT5jU0GYC3{4xaCT_doFRk*bv0S(zBv-DrE4P++w-{Hs*`hrI
zUXE)^(!e)|Okq9Oq8x7%Li<C_Mh2jl2%!%z>LS`;5J#^`5~unet`V#*Y5In3yb|Ax
z|A6b^F37!_z$_{6h{7l~<{u7{Fx*A*#zw{GD)6e}n6f<|)&7`S-txiz3Jm4S5hV&8
zm|Ncc{j_~`^pQ*I#w21;(jwi8GnH4efO;R|r4<G1p%Ku<jzuUqgF5G$#u;0Y_4VKy
z(y0*MvA`MV-?s}9tXk6{f++pmOHa}y`+-3@Seh2+f1TuN!2FS)^;MgoZ6CF?HKKuQ
z+SKF!^o2&LHFUuvqQ}h6(`V&A+69=iKPfqG;f0Zs)@MJ=ChHlc?hBZ+R~fr{3zbP8
z=F^FEG2*P{{(y((i=t{)5Mc*ZZc?^gV40BhN0Asi<H-J;I!<g>$tH~i;Bcmp^sP9)
zjhJne@yzU&XvFNoc~i(wQ?nE`o6Hk~!;x(%xh7?zvigH2g`!v<HwxDXh*xMMM<3HW
z_4L_Fy~v7Oy+?S3!Iq}+)$tv#C5(_ZnW6~n9#W&J%Udh6PZE@~ho88dPWG4VLjU#d
z*ZMl+`1&p|7H1c~Cbw4~{?qNRP)w;Tz2zQOmeZpFR7|6^L9j3U>8L-vEN0DvV3?m(
zSW(TZ%2AWf`rS}GGMqUj!8yCp#|fR--Vxfj=9}YD<U6o`xy0)+sf@3V>97Gocdj=S
z0zkF-jsO>EcPTB1zRO$++k^bH%O`=UkHdHT^5?{$)ot<-K2XIE7js*4OjF)BsVjCJ
z*KN<g*T3%mQu%p*>)!FdM*sh=fB$p8*EzZmGJp?B_=a-90$FI{S$LLjBU$(lxUj;9
zIBszmA*129W+YE;Yy{J~3u<Twd*;f=9Y}3|Z{SIuZ0cY+jRWz)tb}ITlr##&NYEYC
z=%IE*Kowigv*k{XF8F|)GRMAlI-`F3SD9!P!qhNGS)Ep`PBV#qo)ZBA^+Bd^m9cs~
z$`4ZiX~slGCz}>yOr<2A(`*cu0IJN#tmUfz2jIWQi_h)_-V6o+5CjbX!1$lz6?QYU
za&|O#F%~hmGUhil{M+J|*0<3&{a1%ONp-^!Qx*LOTYY}L!r9BbTxCjHMuUR0E(uH`
z!b$*ZMdnB{b2vsb<&P6})+%O=%a8@~$fjbtfF@Z>^Q@enTOJ%V<CRnekz2@P*(BWn
zCbTbLtoL3pIvQP110{Pmu@v|7nq&9FR?p7M)w}G^*B34TR$q-1SA?lX?tyyKq=lP|
zD3b1?os1~fOzA+%;&o>T)Rdc!wX|@iq9i}HaFZAeY6g8xGZY7h-r1sy_<#YU6}I?L
zwvf0ePE5PKbK>2RiJOFO5xNhMY+kt`Qi?Oxo&@xH$<^Q;Nb(&rjPBAcv;XtmSY90z
z;oIFFl%lDq$o&kYQ;aSHZHD@W({Y1hw<-I>7f_X8wc?%hNDlo~Ig;63RlHNhw~#R3
zA*f5D_Qo`4_ajY4Gr{mLs*(Fxh(U%oua_u3r%`H!TI)@R!!iqV8IOhIOzI@=7QJ=G
zV$(9mEVL(7DvPn0j%_cOZN|vvNg8*PHma`6+oS;PDz%iOFyo0n0e%$<#A3r~$=I0T
zDL*{AREUGx&C2}?I9cVL`UcPyawTqA4j-4%Mr-4`9#8GX1jiJkKGpHVr1~Rj#zFaZ
zqmE!<|1JCi!LDG?1^Ys62xz(p;Uu!QZB7!C0#piy1_9=e?^s@-sd1gs!h$;Q`TNtf
z3N4Elsgl#={#U`~&}FNvH78MLjjavl1x*4pNVr338>%sfHu>bxo2#eZN2ee9q#*Jg
zDk_=OBR;8t6=pBN0aj)&Nj}pzqqUYW(tfk?bXTdKbNQFSUMCyN-!b0#3?Z;ijzx$M
z^Eo6Eq*NO!Y8K;84H4MHj_xwBYc|3>+D(PFj7ejhECG@5@Pk&8dG<)HwwO2~j7KV6
z0$s}=*D;ek#8$a*sxVlC_`qFkM0%BQQ@v2H&Aq@G9XCQt^^x<8w*=MbZV)@aPrrn;
z`6r*&f`x&1lp)`5>-|-4%l&W4jy~LydfN;iq?Y8Xx>Sh#2Lx@FXo|5{WKp@y-x;)7
zl;;<Qz|a;@wP~yH(!0er%z<lyLwxk~5K2ICIx(q03AW??arZ^Re4=vD+%Qa;I&F4g
zI?4Z}!kS90ccrTM|0F)(Ny9-x)u-w(Q0I(6NYylHaaesf-hgEvl07qa8t-ycTfDaU
zx7ce8&_aJAsH)F$^4CN*dou!oK5rsAM1OQNDH3*Uz(&F7NYT1oE0o5oWkLM*;uv*K
zt$dbxIX2IaJ4#gFKbn?$aS7zCp4~$VPn%r6s6ueAExSADz!%@`ZRT#}|J@axf)XB9
zJC_Y*Qlfn4E~S>_Y*-Nu3pcH-)p0(tP~3xO_u~>HpCdEfgyq7V-!ZZ{?`6v_b-vx<
zuu|gm5mG6c@D{FYMLuzvG+A2T&6&`n>XM%s`+Qtj)5XdpyFOnz3KLSCOxaCEUl()M
z3b~FYqA3FT1#SY{p36h%M^gBQpB2QzEdtM9hMBMRMu{<KhV173&yh!JiTXWL8LIaT
zOjx!yF5Y~@2QX6?DmX7nm~fkm{Z=drRxd2qWGo6EcEsMotJG@|eCqE$8T1IdA2uFI
zn)L8bboxf1{cvO<Q@CY#O@6OuFeaM}OS3a6yRyDk|7FFl&M9HVISd!A5ySJfXB33<
zH6Ltk%G1=U2^SZIu+0}{BiC(|w$#xf^zkq58$yREuJUj#$?~IEG^NJE=l2b^_JBhx
z+Y?~cTRocOh^0T{LyC78IFM+nKj{%WgVjn=P|8f&9pPIyl|H3PkJYSQp)5(^7|$-(
z2j9D3tgu@G8h9loVyBQu^A&ug*qw%WMLijkRx=5$S&Yl{7%gc(JqLz!!&uGXuunqr
zLPD-~Jf+!(a!($Jv3A~xOXDDXYyx;#rq<I96eLi(M5<|vkQdKDl#dvek6<wl%igd(
zBCtLDygreDi)2j!{2JK9BW&Tmw*z-MpB$g4!?h9izxxVj*{Wcm7cvqE!aG-k<?B!l
z_W^ErgCRVa$zc;t>|rf}(;S85&|A!|Aj}?fMKaju!y>_AS}#hRe_!&%8V=6+oPPtE
zOOJ-Rcrf>hNq<InXW^Acyh4TC67d>@lG{{@$H?6ikt@!A2OePLe{MBIWSPz7{u(I}
z$PXzD;leHG?Xl0FnWt+Wr<rd)0uIC(aO;XiGnyqUc^y$z?J9`@apilEzT621F50PL
zR^-affr-}-;(F?Jexj+E$T?v|csvv}yJ`y-1=;3z`s9u;FtRFIE9TQisLKt0+W|T|
zad(XQdi&&fvX1gimra6ziGzr)?_|StV|w^6ZSOyqK~(O4_g6yx?yvke8Y0pEC0kQ=
zG<FcPwKkTrwY7A%`=^FTaYJT<51t!}$R)~uF;Nl{NrIfHaS(KU9!fZ0kB>krk*|<T
zm_!{ku#RvfFJE^l5~Nhj`%<u{teoQ_ND>e3P~YVF@N$y<VvG03=NpJF5EN8CO5Baa
zP^%AQ9{~YUAT{w$t5R2JHh>&L929cc=#-!*k)HZKDo8!#+t|?9p0z1KSDKclB<j;<
zSnOn_nFSh*+F1`LqurW=nESvpS@FG>&M6~hN5<9~^DIltXKR$+iK<Ozh!vaHa$Q;G
z>*h9k$|@Qoy9H}PSI;b(v>w`8(k70@sfa4nRweeiwZ-syP3zPSsyK_8Te9*(FQdm+
z84ZDah4PGehH72w=Q8bx;pK5juT67rJKb|ovD#COI^l6z0eBidn$!Y?T2;5sN+vTV
z$`%Edb<%-Oq@NPZy<2Z3m;$}!9JzIuVK6;fJi>><V{U}bUe=tba9BbGLiTzA7eS}O
zEs!1TshDr>m3q!Lr!2xXRq+l0LvZIR_PNYrP57E#sCvD^4UU2GVr*Rx`QcT}yQanF
z3i~!-2Vkk4S%4Hd2baDvrM2g(&1jZaA1!vLi!I#5wX6g^&PE`0-TovM(%wuaPXAno
z`a&j{ai=TsgKpc1C3|)tY#!4>SPBbMnchi}glCBwaNE(4`gi}JY0;`|m`s{HtaP@&
zHxwCt#2&z9A7O+=v>za}LW~}G>_tWo$dsRX)f1L=+tZF5E&RBA#jUC|N9ZPa_&z5=
zekCOsIfOh`p(&S8dnkE~9#(;BAh8qzi5JYT0nP7x&Hga3v`XFdRN|$5Ry#mq*AN$J
zV)l~LSq}2d{EJ@%{TLnkRVn*sdM{_b|4!x73|Ux9{%S;FPyhfZ{xg;P2ZmMuA*cMG
zipYNeI7{u98`22!_phwRk|lyX#49r%Lq1aZAabxs6MP79J3Kxh0z1E>MzLS6Ee5u+
z@od~O#6yMa;R}eI*a|ZB$ar0BT`%X4+kyxqW4s+D3rV176EAsfS**6-swZ9OIPRZ&
zlmIH>ppe;l28`Kd0z(alw^r<%RlDpI6hv)6Gs?GIpffKApgx^)2-6jAzjZE0BtPBC
z0z8!#C5AP${zTF$-Z^v%^ie8LI*rvR+*xc=>fa;`SRUSLAio?qL;jVFV1Bw4K>D+i
zyEQ}vyG2HTx>W?Ul&MhxUXK7n;yfN)QS`foM!4>4-(PGwxW!^^UyKOz(v+1BejI*&
zQSkV|m5=JF4T0k*+|h|3dx`ZKBVX7H4{5iakAxnD#J=9igW@LS;HE_8$lZy1l|$wX
zn<8-$u=7&li+^MB(1y~Mz7lj7?oYf%1k{wT#?(Mep094qqnPv7*OYkQ#7$pkU5U24
zzPLEwAb<<WoR&Nlw`OCRo!3>VIp_uUE~+r5)jt(>>Bg48_{)twH$QJDSBrUS!j{lX
z)SK$6dfLWt)c9%Cml+sRp*OHXB?e<YL%nKD`AAfR55^ByJME|HKb?>4hbYZQo!@=6
zBPTpi&6&atD*#Cn6f@5<>79Mq7o0^E!NH)bD26g}?@qg%*AYeE6Tec@F?y9Q8i}^s
zz`)l`8>;h75!kL!`&*<Cny^?$4#8Bbz^Rj<UZuvxBLNOENOw?+Y)9a4NuYnKrPi1-
z;aFNQBSLVm(ME4w-NKhLSdhpfirJ`XcIKUEjk6$hIOg92XpA)f7NifoL_0XapO0I}
zX^FjDP!O(linG*Rj~U7sKAV?8wZu)jVnS?eAh3aj7BfEa5XRr9a?q7dp7&V}E4EJf
zjO=`cLvj#rX~~JksAh-kp58tE`Wmu<Zzb14`_rEmRdp`mkfb9wxGje@y<REs#!wtA
zx%z2uQnW~&@>_hsX1%2)(lWr|7!}@gn%MfwY8vN0=pMm3WesCRv5e*5m4z|u(zb<a
z<hzW!8Hc+~5!b;%r;imxC73kEBD`Far0GlqU&(W_5t(`OF<afCTSd%Y3K%Yo<w1(U
z=KKreIbU=DF>YCpuxO9$bY)hkL|}mRj{3dlRgNK)#PJp#vR=k<Ex81u)$5OX?%u|0
zOu&uBD^9m;wj$6`$vpi4irSYi7AFjEFC6nHIIqerB24Ul$z=YW;9^+`7`hM)@4yW5
zr@#R19VHAsm+%0*j5(Ws3B_wu$j)vHkR#XRdHfL@&dHt&>a^TZ(tKVI<>M~ekIfd2
zm3UDUNW*ZvS5L|SF334|YD>LJk(EqgPpVxtzwclUNaH70zWDVt^1+cz|F?RdF4HHn
z@4~Gs`lj!0dWi2n#>7C@B$Q<wpK@Qa@7|8Xjv?fC!Jhr6Y91c`Ad+yRc|YkmvV0zd
z@N1eZD;xjgqMOX6H0hOE|0p$ru9Ag7lE!O{qPw&bgtVSxMYdGBOX*H-97G5mQqqY{
z*f%6LYn9wGDgN@?to?*kP`;J;$YbK~a^1{wUHLzuTO%@P@|uW>f7|t{1!3mtrO1H7
zi{=I#^Oa1jJiF<s{+1D`W#Q@uEQ|^u$n>I!j>PualW+ncHJ)TelW$bv2MqUG1xK7R
z%TsQfTn)7D3}XYU+{?Hq!I&fqi4>DmryMiO?!aN!T4fnwq2vsuB^s6fPW@u*h-JwG
zNniJFR(RI*?5HV=tqO)lv}CRv_eNEBR%z}Vnftv0+<L2TR|d~&9c0$|63rt}R#`&I
z(}Mb-YqN4psHxY)BHNtvE|HaJ{&w^r-nDl7*OHiSc(6#W0xj^B<mPz^7AL`As86Z$
zdTu)l7LmpYF0UcII-t&#l<w6iiL#=825c&`kAgbp2ju-#YuT1M#4B-*ktfQ<tDw<1
ze}=5f6VQ=TR2w*oj|W|g=La1WG+NxSwo+A(kEPn{9%(v>DUH^OCODH#&;{+aw^1vR
z-c~|Mk+o?j-^Z+rR4s<fWU8E{OXgT6m@b4f&bk3mV#sq0#Hv!gtIJYN2h`5GX+ke>
z-gNA5guTuab7N`{Y@eT&)!xF8#<YnYQKehlL|Kqf9>AeetvQ6d!W4BlO;0#0TxS_(
zMm-A-u+h7-PjmOQHlh{Hxn+J$jh?uEtc8RG8tu->o<eV4;cW9B){Rg)FmgRhNN>g@
z86A%eUt+P8E3oLXIrq#K(nCF@L12>=DVT3ec6Vn=B^B;>D=O%op+0BT;T)FHZ`I93
z^5|bpJC_kB92`alM40Am>Yz5o1gxkIGRYQ)x^+R|TCK)r;Qyq6+~S9Uy9nr^nkvc-
zxw~#_9eBBJcZNK0yFZxUK4h>u$8;4k-KpNTblRgS(y&u~u&J;O!aqAMYJp+(BED*d
z^I#F7vPOEADj}Pziprs=a{%qgz#eso$j`At7p<W_8t?MLKPKsl80)I%mY2++&U!GU
zrt?3swTZ-+h~N9mFFKg!wsEP^yexxyN25#GR-^SrnGl!$(V&k=GfGS9yMzwlubwo2
z{`EB>N~bDw%&ba-+4pI}T*?w-z^_~DfD~Z3Tg+#M#u{s&uRF^dr5RFZh7<|WNEG;P
z-_SzXTbHc^yD$r;WJqqJkA7^(zN`nzQ5V16nG~Zobuy)a)(T@<ha)S<cs(qVX&ObN
z2UVTBWWV+20tc%<OXgDKjf+FdRfQms@H1TiA|=cT&G>Ik>V!qOf<yFMm{;2;Q41`F
z5eqDf$B&;Z(fL<ROep%u!{R=O48j%AQzT)Z9T7G=5J}J5^QZ{BL?!t=1BV0BUiUEH
z03C*CZ6eQPeDZPJFt&p9ke_v_;IHIaFY`qyR7jL0zX#_<dWj_3?#kY#wZ?LT&*Zir
z8WiG{n9jp;hfg4ZRrauCsvRoPJ?P{ITj5;tT82Q)(7JN8YEC#C71)@XIjYS9r>w;e
z)?AZXjzDJg%BkIEY&bm&BczLuWY~k}3Zyx#)jxg1A9R`sz!_dCb!|13b*3PiA@(E6
z9HmG2R>-YrW93UMQO}XE4loI(*er9J*wDUd1se!pzdp<L$3aT<v1RADvUBMM+QQeJ
z<z{5S)X%p^dzb8X%ro~YV>oB_v6^lQl}+!6e5MS`+bU#_b*a5Pkt;o+lOV4loyn2P
z$3;z-cX>$R{6M4q%b}aMBF}6N+0RCE70bB;XwHV~JLO&!EB)Cgo9ta_>>Os1HNfaY
z4PNu7BGhw`6}cm>glh6i^)Ja{rpLHi&#5x?C?u;(e&GI{?!E7$9hd*5c^iL?;6Kwn
z@qbBE|3UMF|F$Ok>7YY?CeMzMes@CZJQ?&|R8v5M@XvW}jjxhjl`gzl;rvy6Nn9$K
z;1TKGpUgZs`vR!t-sD~2<GqGgCoXc~OBH8i>ar{58-;2k`H(MIWr_cujtSCpjue(R
z(a7R{q`G+;8qD8D1e?1zWv+pPFtk=k#>f`yqZo)3KwCBgABgQbq%hu4q}h+Bdyh?*
z#Rlr*$38^Ru%m9FUTQL2Xy^j|f%*4H*{zWFRsMbs6@u{JM{48fq;F;QFV%6Dn!6X0
zEAr2G{RmY8;Jlmws#%7Hl_TvQMbLnN0KGK=9)1u=Vb&#V27UwM#U+)$hn#hlXxBxO
zM~<3s(W;fe-0%mVWtZ)oN|h-01@5z=u(z!V>)I9-IepH|_q6NR_DA>2hxGK<NnR*m
zWk2t+J}{L{{ATAL%!~{q)|e=iLSn4A-~C}h1q?=o?ha9+Eupsr*SeFGw0p-zn^-5u
zu;>t-QX;H6(^FXwcBndi1s%qn2sH-rsuON7*ARP6Qt$2XIy3d#cn8sLh&7#USTFn3
zQm-o6-Bnofon2V;oq-v1@Ye@NuH$Z~+th}Cs>F7=H#=4PKLp%-!EwR&0`a}XL=br<
zF>&?HNr}9ahB-EA7a({^_6`taBwmB~hJG)p>8r^vq0J_+o`sOq<{s2~2t}W&1f5`l
zj;E0nmt?YRp{ONhti9{4&rvt5uoS0CO@%+Yv>+}ROQAGP3VLu^S4fe{ZRoGviEXMF
zhM=I=Eg2~^5PIwEq{~Wt?inz13!axZU3knx_)Ey9<)z<=!TnCPHvs1l^spF`@INYQ
zY|J1RWri-^D9mVY5Z<j$Ujv8AlCwzWydcK4C|+vv1pTa1iR$dG6=ZFyb~2D_cqt9U
z3LS@qozPiYcF)#+d>{u+bXg#}3rUwSXX>&@PN+017W@!L5H8CvZf0wZxQ=UrHJ{Um
z$Z;~3t<fSfV_$nKB$9GL7$e7eGk`|rFBnpk*l@Ms#aN18Lz{qD!dbS8_3AD&uT#ok
zHo!>6ARGql*O1^YY(h4awy!h_brE6&k9B&5l;ya>jDyW5?o$q~=1iV!t7#8&QOx6P
zhQIm55sij*Ef-G_?k^$AjK2j?=QQ?^=r{MDaGZ7`Y<Ik^MKRub@OW%3<1o)yw9XR$
zV+vp_%4EHfekP<b7G7B$#O)B9)Lf8$QmAE>o*Kp1uoZ=&5|O)D#xAHL)n9_l6-E!b
zVV@8ny;`XU#X2((4cTmv5unmYzUmJ>Hm+Kvht&a+j3nr!sljTHUZn^0w@L|WKw2TO
zRO>T!>jutIzNI5U_KL}vd00oi6$aJqPeJwq)lIr(2Gt#52i@sqCFaWC)pS$pYoRCK
z<Am&vynz5ok1xL>d*$)r6FCClYp+n>gCqVF>x)ghAbl+h${~Mc_sQGk@+sR@b(88l
zcx?*Usr}v|kV!RPfS%HK>Bn{7tdEV$CB5Z@=uy4>^(o(%@R|_7dq69s1(X_8szPZ!
zSS~$LCX>-}F=io=YcY~9!vqo3&dh9_Mosio<F(tfcLSN-U)Vcue&bvsEh=lKD6ppL
z6qI#&c+@~lX-+#F)tl51AhP=|DK)1x+fWoa?xN2jH<zYk=E_8&m7MhuZz-RhlB}ae
zp2uQgS$=R_-5V00)NB-;DWBuTtVMJ(!fcu{Uh;g;m+zjEJ{!?s_s*iXMv@daoQ`1Z
zI;?<lJc#B%Wh=hBo~~fr)9RCQQPzw#tL0c`1NxL`dLmHoc%e7WFdx$_=^QdjZ^2Yv
zbegXruBz-cttz)ie=L{QV3DD2Jz!-4#s0>`zO6i|$&p;-9%+~sdYNrVE?Q8rS+eHx
z4O$l|b3FUT#2jb(WU<`oKAjGQUsoCgE1(c>3byBNPhKeJ7f4S-hBRqRyePY)im;>H
z)hyFuFTDqx*ZgXo$hn+u>TGs~=Bjqr3bhPmXG)v8){EU;N*58NKU5;EIZ<q#-eG>l
z9%|JomX+b6M#jS2`B%~!+`EStMD{|y^P=`xPbD$o6;|!((h!+y%7Y{DuC!NCKDIN1
zER-J?vZ$2el4y~!<J6G}$XW{+?MSbe>-0vWjNRoC|ARB`IX@M&;?ZpULcAIu`zlH9
z&JK#H);Ij~fqoT{59}OI#ViA%!lPYyd@kHg*hyI;iMdCtw2&eLHOd1*N%2Y!BG*H_
zu@E?VbtZlI{7B{C>A^b3njh=KdF!=rQ!)oIjwkP{t^I{2q&<K(evUD+TLJYkvRec7
zYZ$&1>emQ-C1&U&fPC_viACTbT;(A3qRJeGINz^!0N26vQ~o|#pmjp-Zq46%+{X9n
zLGKqhLh4`-(*oDHqHU~-45_+pe(BICF$*0jD&FW?ED=vn=t?p9X(%AH9+;6NcJ8JF
zASkf}LfT7Z3u*#i$ml`gKIS>3jrTla--x##EDM{w{>Iu9qV!x95ECU*W_O`q>hcCa
zswU!;H3R{}(A6aQ(B)lImTF$BzF;$V_?It*+8ZeiZa|b8n_DN4jUfI0jIA<yNEz-<
zUAZU5rNnB5g&~PSflg90>6Q6*c0f(uq~DxrNm!$~G=Uz=qP*)?qc(}|7MQZT&B=Um
zr{Lj_R7QJAlwD=CoYpjQsUyu1)C9p5CE)%3nb<t{qTHZCa3>)~WtP;@6(qGG`*qDT
zS(zM>&R<;Z23V|80%3s!`0<bQH?H)~tkw2Eq4I%CK{w1nB~7P!a39`Gm_(f;5IclH
z_Xj~YoDf^25IZFhTd@e;xP+73;-x+qR|XI^C>QpTt0Ay;*xLJeE|DP5@x?a!1)`g=
z-1}G_LxiiO(*?R*{(yH#&yl|Seyx6*+ETayQtv7Htk3WPvI;U!@h-e$)gw9>pyKmB
zk8#$3BF-ou%=`9_3)Q`0ttk$cymvULFS`Khmjes=2(-QY@eVjJ)rSD)z)1No&o+dz
zrGItPZ$QuD;Nqt~U{J?9VlM0g{kx!4$?!?=o?um>#7tjMzrLfv<@pI&cp*5H>XPPZ
zu8Xh<Y%l^G*aDwQBur}de;dit5r?efr|696x8R2CT@&l&Cx|39HUn<!vQ|CwedGQ+
zD*>&6y7v0pGDiQqd-~tBjK%-SO8$8kG&44|{09|FO5BoNkV6~JX>g{b#NHJW?gmM#
zhbcS|M9fDc44(seG%$hK#va#4YL98mddGDi2qr;@CeiWO!!`DrF<%=_^*3JgoZiSj
zdEv30G5`7ex`XP4#6cG;AQ}(|>CcCTGiom^pc*j-Mz1_oGp4iP*>N125YeWCw#L4H
z*>u2Ih8jVRJ?rOj-7KbU7KXpYs2UZf)Vf}(lsM(oiB>tgqX2tILJit<W`zs#E>w_x
z&7gq;`b}qrL{lEA3DaXDOi~HQ!^?xxjjVW|#Z+Ek&GKA2dYgO@zB2V*eY<n7t=eX>
zx>@D06X)(FUz3xz99V3v*k7x|wxiFxv>=N$1Chfp>CErJq)gnf=P!u-QKrYnulzdQ
zP56u!AH2^QVnuxTJjcQtlflq>PSm4C!$^fv4V_XsIO2d=O8|J`4bUDtjBchJ!14~3
z#mgUPYF*Z?k;Y)Igdx3yQg8L)M=c%}p3!P-0KOuXI+{*LXJ&w)$gzxeTyr`)h-Nc!
z`$xa<>T2pbuU0VR?#FPEM44XDRw+cM6U1R2aLQpGHX40=4Er=lp&2aN#P1IA3|r+L
z?5jaRyCgN)b(KuS+(x9rPLLjY&4^YY{0T2Ai%`f0p}sG*R!}{DSf7GdPJ=C2MT1ND
zUJ@#y06`CNc9n?13R2KY1K*SYeV87wG%bjcIbn+AR8*FS<{?wWomTT5@`}~z3bFAJ
zLR-wmE$iwwJ-Tn<Q5K*6H7Xi<7gjmiO=VIt?rKq7b!GrN6Ul@)bkLRFm0!xF9aqiP
z9_Pg)EI}1<$M(ui^AkIKVo;qp+t%8pBvqRv=D97`;5VVg%UOaj{Ceqs=^8hD!q*o5
z{b2y#Uku~@H)X^>VEhl{{?+??DJ?DWk~VaX-L3-RLtprT2%z-GfD{UVBR~T}zymA0
z6VZ;1Qr%5q#+Oz#3)`D(%WVWWS4BW6%ZvAtt!u25FO@e{X`)_LH>p&pFzx(wvNEO-
z!2$Z}`iynmY<d2b`M>2j&UCmRNB)9Cn3MXRls&PFVHzkzr;)B^BCMY~6lYY>0rsKT
zm4}RV`Q7tbn)Aseay%@-I6ZT~PBsO?D|>kG*%(PGo=|gZ#0zsmE})xxtAvaCe&$1?
z(7GyH&^jm!cguuMo@CPA&-lrdE&Aq8GIOuUK9jt{K0ldcvJJp7I`ZMx-EYj$)hl~)
zFM!U~HxgO+lb$1cIK-nvz<5OPs(@d4tB6DUa3?-bJ98|dv-kIdtMS;9BuLc{a~_wW
zO$u`rNyms<O+qXSuTB+_W%5p)Jq_HP^8*g_)!h=}PWkkjk27Z;>AeMH9zh(|w=<*V
z&&B{&O0Am`<$iBa)>pNZ6cO`d^3B5%=gmsH(HYZw6!U(c@}#)19F}`BT+yOfamJY$
zYOmy2m^k+ADH2klhAJMLq;6>t3)NREUgk*cjJHg{NBkVhDORNK;v5362&NN=y*Ef-
z$vxYTG5Ga{SI&C93^Gsu9G-osqbC9PbsC&@xxGlF?o{!rs9|YpEE?P8ix#yS`7JUy
z%ez(_Q%I^RwPrW%rFF(+mE}rp#Wtg@^>O7T(@LFA7j{LNrL=XGDyB-|3<*mqLL_UA
zUZz?ulF$5O59-WWZ!d@hRxC@4d6?okW%`1$#<5w9eh>4Cyr#xe5%VPG@TBe#HA^O}
z1&q{T_TMTr($f<()ah%TXapiGp}`MAC7>0I=Cx*t+bXy+gMyk*#(A~ft=&4YBdQki
zQ}I=c;etc@sD4?l`eYaksPtJnx5OUaZ6u;7p64DUuI`omrWjht5$8+cqb6Hw75WNX
z@D(fl7tDl2H)H%QYyX3>cL0*DZPv8+ZgaP7+t_W}wr$(CZQHhO+qUig`^@>y%s1~j
z6Y)pXii(P=SQS<4iS=aOnR(rqe#b*BR~GN+bMNQSnhcMHxh<oN+p_*@?ZNyQ{F31O
z4E(hxex*(G{Iznmp)Gk__F1N9vOiHL^vV{PrPRnf8^HwQh!M`><eZ~9Id5FLsN8(T
zWClYsF`O<sI`U$&kp#I1Sy1`gABIV;yhM^m^}tM|Raesy5y-{-dNa!|yaoL08X}v#
z=8?LVzU@GDTGec@{th$%Y08sH!!r4Ymb6D^;y=69@L3iOE5?Gb@cNc_En3;Md`9l4
zVmfd<8t7(o`$ZKNh{eZ6&m|E}gc3K4jbKJ-MmJVcjLZ-V^~}_~4VG5H&rI_AV?#wv
zKoSJ+qKyM;L{U|Ajc-&GjmVJ35Z=<e<A`nPrUOcwU`$QMY1WdIAS#&~!iQhz?0!Vx
zbE2uC;P1zV_`0Ro)qnY@n*2AR@c_qQYG3uaG}MslD)yRHX`%&nhT%H%3p<IB=z6&z
zQJ#?9X8{6fu4Ng}+LKglZ!a?ZzQV9%Z37zNYdyhWOdgH+Ak|q$qlV#yI;{lze|1(0
zR{wnjF&{!{`VFq=KczFKut~7<`*bI=QxwS!B7GqsEiWyVw&wML;O5L2I)|_-9m&!s
zj|@bk5+hcIgZf7J*V7@0U_DS8!TdgR-a`;m+mep)T+1q~c#7$ZnmSE58r&o!6@W8p
zDvXC3GeNj9s(m9|d`1T$9K?EtO~zc!7Z82^b6Aw(X^dvfQ+Hz?eHc}w0Axg#DE$nG
zoGT^#Y#x{}k^mh6S^$Lh@A#m-#$3`V+LJT#l(yeygL{i<zi8TdVb0^sp+Vn$WI{<Q
z>Vf6<CY86L9HFp!u$yM-M1NgDbONG~<QWI&+`0_2j6e7YN2dw7uYo7|);1uLRqz=R
z7WV?4CgAnP>D7_zYs}@<K!DfX(WfX1Ai!~EE^8*KT!Co*K{>oo$eK9sZig1_lH0|C
z&<1W;8dh6lutS+|02t0VqRfh9R+%!~9YsQ>cw-uGi!YMSo?19?Sty(u{GRqmTx8Zv
zLz|nph}CNn+4a~dDzMog(j+NForDvDjLwub!b;p@dLHSBO0kjaI0CPZ)8B2(HNL&A
zdr8Pw@u(POF1J*groJ~!1|E(Gm<U0SF<{bvqbm<z{6eP~UDu5*>nR3L6`P*3C;v?R
zDw-pBC=u%}<}P_);mn-_cE}am&b1_WlqnWVzFS;*NhwoOb%+#0nI|H*Bw6_0R(=Kj
z;7@eEqYkW2OvWkoz|yY1gZAJw8=>KShthS*ANzYdDT61^AK)>0H%LV4q3}hw?bkA$
zF$tz;<5T59v0Zd$)unmJ{vu_7eGDP6+pe(H&n^3E)g^rB?pn?GT<XDnE%*A{E#7oq
zG^wO_f)9^{h?|RO1$KVF*JJ`JPlc&bhOtC&o!4l`CQ_6>9l1gztAUpR*+Kvt=FE~M
zq5rZM&9v>ww1mzrK)vx*0;;?tnqA@Q;FBC@$2~=gy#jW$bAJUNIl_YpT)``*9nnkV
zF!&XBK8(PeQfnScH*JaYqy{1bN4MwF=&g2)`!Kuo165*d^1Sc_d{I4>6V=>74c%g4
zXE_M`b@syq%jQx9VRp@ba!rY|MRhr!S3bN!1RT}^I(2gXE`KT57Y;maGA&dHM#`4*
zy%<P60u?#!lJ{hm+I{teQZ&zA%?=v`TI>@6YB0A6Z^?fg!$4Gq0auM47(jE$Y4osH
zhydBwQ-S~vMS7)hg;AC=MRf~AHZu|Ue*bk=ff`!Ol1%=|W-a+~l)QH04q^oeMZHj~
z8$8jQn(n1#O!_7sg1hi;{v%?nd&gK7<l$g#FetZCyif6!)lL5J_%)fl8&{g9&-fuI
zz}MTJG%Z3cbXI$Jg<E5E0dl6)`j@n)Jz)^~Fq8EZW}-Hqi|_b2d3Rs8(yL<c3)rz-
z6xoiA!n!^AcaS$lgcr%Ad1r!HvKx8#RJ#mI2slyAmPqU)^{RrG{K$}}>tfN3I{A0j
zcg`ISk^Ir4G=(SvV$v}DE(nE+%rgFkT%cu5VR0Qa^H4-xPC*7Y*+<jZ^$o*_eeFvF
zsTfD%_k_3XOEvj-<agB__e*w)d1E<m;`ZUQ!WT++G{8dbm+UF$SMwN72+DUqPSM1A
zwTS#HfvDp*5>E8#xvyepS#xYE+FyIIi0|5$J%mKAB58%MgleT%Zx42e^L`TdA~Ips
z=NvgHNpYZju?*J>oNcmd^(nFUc+-bu4*+9)qIwU^g?1_4-&-`uZm&f7F^1?@3I<Pc
zR+jZ}=8fI>vJc{gnlh?no$<XHR=hHI%%?`ym%)e<m+sK?buh9+gMBvu!{q@xu@_Sg
zL$w<39);`)8C-hm**vC?Zqy1NIpW&I7Vl$$s@COLjdoK=`O4y62~<uW9d$E)1V}mq
z&1tG?e|CYuI;ov5(0@bx@$pLnnRPQ^>E9jFIfJ8i+33;o-!b2hD@}}{o}J4{l{44v
z3Cd{3Lj%9^E43SBXmIvwsA2_8sXgRu=4=H{j9R(fYcCzOXriTZ51l+HcXr@)^?rK*
zmc89=w8MW+txdobBh`X4rMvY#vuv0GIEO67sgL}mIw$pNW6s8Fd<Bov!}@g2V8>=t
z@58{pFs^Oz&g}CPr8EL~QyUjk&}1qyO4;-6m0MRd4J9T2r5_j+YdeKP%Q+jnWNdV|
zUJLU&d%m|g&3B83R^8K^WM{0at+=9UdVAzTnL+CqdcT#($38|-fQ|BJbHY4vk=ANj
zvX?ek_oYp6t8bQz-T){|-5OGrv`IGd?>X*h(s{MvQ{j>fZbx<^-)&(j8(N+z^sftB
z;V$0+Wd0oUR^&)Q+2bHfLt#V~jZT$UPU<McT?X43`{{xPGdu)fXen%p1BR%`j);!s
zcQ>bkd#vD#zZJ&huG+-;T%sU~ONA?a`Va|T%I0yd%0*Xr3>p#slVg7Y<6o&Bx856S
zg;7Q>mCFF?xq_m}VG5`(0fIX(V=yvQ;xjpwNhrLFMui8xdBw2aFOvI3t6-NG3%+d=
z>1un%A{1+tFrn2nu2%`-hiqYhXDga3%{ZVkC@ROtTcA;g*E@K4i_G1&^P#Pl_9*m&
zwBVKqZhrf4<CZn2jxKjiiI5NgAJti7cg9jZZMx)u3Vl*fh%q=`I#Rf>bhw@M)78cm
zBMB!;A)H{6<Kn{rpK!2cr*s82Q@$}Dj(7rR*&p2Xoi)!3DtXgs`gx(6&=g+hePVA-
zfr9>h6AjEv&|DGxYRmY|e_ARf_dMIvm*-i4h<r_8tvkwv-mtv3OW%+`67Gbr1Y*j9
z1&T&I%Q7}RZ_tLx5Xdau=2t~nmnA^llqFC`c`kZjr|ST!83-3^#QiGD+g(!P4^l0_
zP|$Ys8$BR6*YL`x-QRAEV-A|)Ue80PXI-%W90G95r?{o0Al{DMWFSAm*&2tnm~WWR
zhB~N%h%v2*_wF<)WBhV+&W<{-{1jc}Aoumb^X+%biz)LbtdgCsCEjHL4sZSJ%spEh
zwgQ4F)TR#!&1T4=RYeE5`3<M_dH=EAM06^oozPWr&lokjqVj@hez~UoCV%h@e;2)U
z75g~|x;*@i!%Rx+mB#bq<~0f^N0kOCtCREd`XCl#6_i?3^?89#>R#IU_#<!!sCCgP
ze<}OU<m2Sqkyn~b64uC7PUsbeDGv`CeW!m^IW#FfW2sYmw6ilejtm>A_QYP@L|sHs
zo@Ky_Bx6e2??_k;7vjibD#pM*T7`h9V&s(moOn_x^N|9{gkOtFY~gDqSo+7meUjBR
zK2jiOsA%PwD|1*KC^m(-WZ5j2AWi;81kCi5t)KouHKt|R6m{m!!n|4YN3yyBo0mSZ
zN^yj9>I9Y6dI&$!T7&$%3Ccxua0-&DoNJFbCV%1;h^-U&1Q+@47qrKld+QNGOrh{a
z27PfD|L06XuL1+ZMc{_7rB7bd&WD%*lbypj>|K|<#2#t+qPX<E^hRp}5ifDWr}U>H
zTm`5QC)ktLW5+G&4lhvX8DgOK)|mvQ_b^HuJ&=wP%Z6%;E+Bx|#|Q}vOoGR(jK}sD
zk9x4A-V%Hs#G>J5XldT-W&|Kv(!mEi;J38jdK>L|Q7~<_no&|~Fdc~yhC~%VqQc2e
z2|pva(YaxgaE`xa5=u=WkhtI|f`XRHhA6|>1`)hDgYzt9kByS$l*OQ2O-a#Iq%SLz
zV^&-mn{^KrM6&BueyiV}>&)9rr)de2+DkV8##PSmko(<`nqPVr^n_V~UoIi`_yVdB
zzcj4`b5QijKNrR%0AYi<`{NDb!y1^#Pv|K2N8<&wlO7-JDa5Yp?eM)pf>PbMq@)Wr
zvki0Y1yLr2WfDb`RBPgq^VC(KH;ofR#9^i$TaMi9J6p5TP5F8<&ofnvL|`*(;urRO
z?0k?7WiOd&^v);ux~R9Hznc3moOxE+O$lYV0Ku|hENFV~?Lt!QZlMNp1%d#^Rv!pC
zfq`*V)n<`Io8N2XGBOjLYB}#{g#>o-?Hmb6$VyvSN@nI?3{y-pdNvcYe%&%CIeh?s
zWfdM@$o~R)P|M>ElHW0BAMI=ozdH-Fle#Dvq-bpmPg-!rDY|1*o|1dvDh9{`{gt%n
zFemDyrWMrywXJ+rV5r%UR~0T*75`i&rM4=%7}ulJyHu{rZw;C$r+nn@cLyLgh0d-A
z(3SS5tW>ZK0in8bOH$vW>HIcipgUXYGUq49#>Ixff27cCfWz$0vR4Dmq}CBw<~4Sh
zDe9adM$vVItE_)3FJT5Bgk}V=1g+Qvf5+<KeZeKg27tmTqE9gb&&x%=tpSf&2MEao
zUC{VNpb0ds0kEy%dt82E>hpxwh78gHe$<|r1^Nh?B&_~xSq+nVdY+~dc4GJ?e5EpV
zXs-H~6poV`Kh5kok2qSUMD<MdZn`+nJNYMw{&G)!^_(?T4R_K|kG_&kKB*w~M<(!-
zhQZMCoK7`vb~VQPn;h4Wbt|7ZqMK$e62u$?R-P>?0&WXKs7T0?Z-J8zti^WD-*_fo
zhAqM(p+l2*(|b>aZC+?aK~^_VCZkP0>}TxdEC-KcmAx*YS?wTK?cW>PjS+NxM==Wg
zg}e_*NcH%2(J=+WVL+;P)kz0c@48^4ZuemowCO=rriJFSD|#7D2oO{}$kCbL0#0%2
zQe&D2wwJ3%d|+L`bE=&9k_~(BOe$ZFap$YMGL$&$D0=mJ9n%He#RRlC3f=|WyrI0L
zA_qS=<Vgd!^sQRNl;o#=j*2#}(jFc=Pbq)IH^}HuM2WfsZQ)UbZ$S&{*oOS@w8ILR
zRS_=vsZ=Vvsel_;qaI4VVF?G4!%(}yJ9vLLtOY+Am(uVlK1?*n&LcLmEm7jIY#;R?
z_}|tfmWe55o05Q+CuY#3(HB=;YRs1LyxEV4H=K1SVp&1_TRsjTe;iIff4w?AtlNHB
zNMqEX>kzzw8f_QiJ<uGSKkH_|=yZI~fIr~fJr3_YkhypY(dCTuY)5@*ykUN{nPNZ=
zTeU%bCW`RsT`<**6S5_K{prH4z?S|7a;AA{o^xN}hu@BBsCCv6e(zZ4{chs%Cfc%K
z;|90`6xnOi$c?>Yg_b?xA6UgBS0tT_Y$!9>(J-Q|m=O+8+wIPlb5i=-aU~kBf=4dD
zd6Q8*EoKqRCcMNO5q%nez-osz1XT6PZ+r7r7A_{!vpDIfE$$yCUU66H>HOUO>u7aE
zs*>|KS24COy<^3O^xXssCI`2iF%;A&<Kxv-{GflzSv6^-_`6rn?k>7{j1UDk9dvv<
zsUbj2HMoFr%{j!bRrmyt%jM|4U<OHrC`kz-+@|l{4Z^UxanM9OAV-o<n@~_@M{FGp
zB3{v>Kza#}%V<gr#D>f*_fEvi$*6J-h}oRdsdinr_W1<aeI;E(BS}I<tGvKo%aVl9
zT8*N*66uB1#vc&pIZOW_e)6jzRk@!n4%w5IflFM&9gB4pN3@HP1cznSFcKzGbLr(5
z%;-ZZvhr^v5@#b;>-)p24zB*p9tfDdUa27+<E>yi5W`#8+~eE_NyvNZgCP48jF8P;
zgYS#IP!@sLe^SeCy4jwre}sC*A4Vk3|EzFISR4QEai+j{bL%-B#Nlt4WJN3eh+Uo)
zVtaBF&A%PtbaaH`A~$h0I(5#|WARn>4Hbxy+Jn-$LdJWL+&({?oGdxCC?@gw`D44O
zZ)fV$Yi@4u-zGU|!cfh6Eq?2C3Nn%TL2ZoA1+5g5O#q6$QGS|1C!;H{)PU?dDlSGU
zLGKxOa;zm!C-Zghet4U7l(%LaEQnKF+>ECNt@`F07q-JO?%%X~*k}Yndc#f*iq0<E
zh-aX|Fu{GY>`hgW#iOvymYI0Ur<nK88ceN)<(kWMl$~V0V>}T;8qZ+%f1paM#v7e!
zUS~+CMQqEbYZ%Ix+4iKAGa>>DLya7d_5zQo_zm&bP6F_75Qk^L7A%?p74r#_+3V6R
z@m)%h$SZlQi)PpLLYyya^FulLkrPuM%+!YnWBCX|f#M*ph-`6S5IH3F;Os;ZZ&cDq
z<~WF?be7SQre3OHq63A%t27ee4>e--Q*N)lFkAI_P@Yoq?Bd0s)IIqLY)xtXU`k>x
zfQK0;b2n0v{oPhQju4$`uD>)Syw=X_l}YEfVF8)awhULL-sJNdq;z8~(wyAEW&sDx
zxqHk8ufaTXHNnIUP~eE&k>D!g#IVt<k6q){kZ+Xa5{E*O4m>73wHY+ugJwtuy74u*
z1qC32jRV4EWbz*0B5d5qGm7FB;V0Z>C63g4n6hW?!BfHU=<o!#m$<U^6GCf6@zfb2
zCK6(EF~y7{8irNw(TEqZa;=^EL_~#5FA*W{6Ch;E3Y4Bn8%0+V;vUKD8l#|Tf+?%!
z$v>hqZbuGx&ccdij#|lWok<JeWHyPdKD0NJ{;sEc|6?4_+6oP>>4#{m^Fy>{`JdOS
zjIM(Tuf4sYrJltP%2vW!U)Mt5hd5_vs^{onYW=T{?nF6taSUF>uPLMY@>8Y#vd&fU
zJg$MqI>EOkIj}Gpu%?+k{%zvX7zqvMeuMm%YD6eLoHxL?e6eW>J~|~Z&lHB^r_Ag0
z{*SlMeG(r}i;4UY6e1TDhAnY@tyh=*e7>7?vlwq>&py6<k}1K8x)%|myUzlL62{)~
zcC(t-q?)Y}2a+q3St$dLT)}P{#}C1S%{Lv~>9o*=h<mOQg+m<h$F++m)45ZV^MD;}
z14~gAixLHFnCUb*Zv-g9fXE7>IE389P!iE)Fe1v;HN5fVGS&&jBzQk*Q}Rb%{FF5H
zt;vL@*J)TU^_AGy%>+&9)+R@9XQHe9%Cr#w>Q$NM0~WAiktZl>9`I-Ypc0UjVU1rn
z_FPNg@88w2iz;NHBJ8)vM$%1oe7QzSs;NxSieG5h->Cq6`M#YqU;tx=1hYym@h%fi
zzWLOcEgsbZ>jW|mkR)qpxv-Z}J6iTzy?L3sZiv!nbZ3a;A~Hu3j6-^%FcrouBW^*9
zwOO;eD$2J8edza=ZDF&}5X#=B9O(;A4zyM&5yTvxuoqjP+FZY!ZYI`_D=;czTJF-e
z1-$=(BE%9~*+c%p5UT&+n27&>tc8D77L`o(F_e)w^~KRuv4^AdNE-D~2I(p(SCPRP
zc{V^gm}JdYd(~~{max<jT;W{{qJ%=B4as7XJjrB86YBU^HBAa+06(X!_1K+_C|9c_
z)?wVPyNchhSe;#;C%M1xhq!-b3~m!(+EIn*a{?eN6C_xT#3bwT2NJCVt0F3LVDSR6
zuGR{Y2kwq&MDYwtu67ai7ll=VMeQQMdB}Z*@2ApoA@vsDrh++mC>0nhdPp5j3){eJ
z$LuzR9V>9)451K&?27Aps3vsd_bU(1EDOA~g;@vOO2Ty`4MFO9u=`!_wEKPQp>9L&
zzuUbCBGHhsuxYBy-^Uw`)=n<g=_6ADtF6^Rx#L$SiwTMLhKAeg$Ir`Cgx|~CQzRQP
z$Wz=y+MlL|L*&gbKc>5pSF5)!a6qfH$^u&=0GA(}B-Ixjj|ce?Bp(~$q^7BqWU|H8
zKU!?5P@+8*_63=^7)|h<=`vW)2%PZF(`Q0Lr0x5QLjWKIQZB9)OOB_ISy!Mx`E{lJ
z1=1d&Ic*{{_h#6sNH^Hz)~vB7gCTbuUkVrOm(pCye57-0<dsb45#E2#1+L^YW_jPQ
zg|{|1r?W0<UY^icT@rM5xUrN4-Ga9XU0u_nfIv?(1uMbrC`*n&(*!`9nyVmbS_=f&
ztm#Z7_qI6{SDwi8TYXWlf2RJhh;ePSIHox*bQFuoCD~m5Rk*v`1f8!iXFpVs${-fy
z$0c2AP?2akzba<<^d<SZbCyJ~xa#1j;me29{-lz*roj;A<-tdU;s<sg)#XHxkMhZ9
z+8i0#C#i2XPgfC#@#J$TB(Cd_z^H$s?1$3twT&=tBNuLe%Fl<ptJ!ehn76f9bc;XE
zGYEqyVB(x1YL77I?c#HWf{)93)ceY}s>NUsKiFMeA#@NBB+F5<+s{(H7mQAPQx`OR
z8xRz&uf&f&-?8paW&Q%EHCq$Lv~}lCIW%s>Wxj&$Majn9D~*<r5R^S?hRD5q0~zZT
zs*IT7`7B7o>{Yn8jBZ3b9-fuz!82Hn?&ZI2_JZYAy$kb_?<bYK2x3_{G^w#>7m*?J
z7Ec<Xr+(5=w4>rbL2*)gJ(Wl`yg~c)vC1w>dR$LezB90-T0%EZo|KuQOirNpKJAd)
zr+w2F#9m@j64vevMEx_$M}ESx!oajKsI7|Q#c-fWRsS7nAgMlxf$l`eoBx6_u1LP`
z5wVEEAYNPN*iXKJza7=aP+z_r$z;5})S<oi+}-~^-hbQc5A1fqvyb6yUd6CgGXp~&
z{!K_DqomY(!`}Af6)K8g57Ew*!8H?)fvR?Q1-qUyJge=3IfU+X{+Zbg*SGbTXB`6_
znB-fU;%-e~&GT+)<Zxm)3ukS-Zw|J@2{{Btj2|*FTy-<IRp;ZZg%-llvq6UA^3q{&
z9-1NEWMTQ79rE01H;IvFc~*(*jxd{v*|<7%6lCMnTfDTRZCx;Wcs|m$@c3O(heLDe
zz7X)KqYewJqpsVoSuCn{7x=bLQ>QGWl0SrU7qL5T>MpzjZPVq~an6pv29s{gIn1Rh
z$*Vp>0p=05JN|HRiyOCbpgpZ@;9Xj|o3DNV!%Xn6t3hE>(=2$dFuEx{osGXYv`m73
z@j>86*-gsSS^3m<oE3c-)n~5N*se_9lLX+^`1AncyC%QkMGrmLV=Ho6!+4146a;OE
z=`t$t9k^-$9aX;|lxOSwN9>R)HB6Bj1fy+E{@9e{bcRLU_iAqDzdQUqG)+sqNE`h1
z$3w4loJ+!{F4NdK!E7Vu6L}j5d=VnffP!j5b(b5(u}{;?o9PB`YLsrEsOeE8IUM8F
zj!}~kYF^$l^i7CS$AnS+a4#EnWySE!?hNnzWe>=ETyc4WCXpNzZ9R&vLWR9n2)aFS
zeT`FE>ZzLpjPr*qdk%A3<`U8cpr3K~?abpqM})l-j}Hz+9tJcw;_-BzCtzpYoNVk^
zd4xI@9~_|+Y_6S*Kx+?A$c)OqC718Wiat0Sl%qFMhix0?j{gw1XO9$zQhjjoeDj|S
z8hS*$R7Ol=9=Sd-9s*OgZAC1sMC*(iexn}3CMYJdNZu8^S5)5@Bxo7ayS4fG2D@ns
z(Y9t<TvhILu3uTgNy#qP3#T@k<{6-VswRt1u&eW*57dPh$?Zc_!H*7qqO83%5^W=J
zUDb1tF}tG{zti)_rTId70^zJ-pFwgc_I^4(>_4DB(20CAx~=eL=RM?RRc4|4V{?Qe
z=>g3K7H^2nxwHm|*N+zhk9ET-=0ak5wZAxM<)DFY7|^q+@a_=>AXMj@vZG11mH%nQ
zn9XfRt<p14uRBgwWE`}!Ge7riPu`nI2MyttnjsO{6D=|e6fC%I-Hd12iyv8n7o-+$
zd+FXqK4mJ>7)!V&u0~v+`DaED;5~WX_cQ6~@iQ$)`#<lj@~%G+U&|lF!;kNPgQ=mt
zh_2O-X~DlpnvqKX$@JBXtHGnBngM{GLk_3fWvC2OkgG`o3B4oYC4J1N)=j4j*lbx%
z*i-)Wx`^MG@VuGqMH^0ii~B>bKdk&+uvYtZMGQ??&<Ml&ykYNkykYNsyp{g>zRmpw
zbc5donS&q;jPQE_7rh5{ONJKBM;cxKH>r!f)K=VDf}bfc1B4Nv3C}__D{B|kU<cyu
zF9k}G7xqV$0Xa_Uy)eXayVw@La<2}I9(Nb*FqncC;#r&}eZ(|BB;TVKI}bcIPfIH=
zrzm_jxOTq%g)}FA$YLf2v?%r_U19<N=>4Q04E((6!W^q+&Xb=m`c#S!$wEEp4py_0
zDJO?v%A16hzF;#-Lt+DUyec?VXUS?%21=wBiJ<}TTQMa&n$+5wnHr4sni_Hb`tFO;
z((K<Oi*SVDnfmxN(dJ3`C_=~LISLzk1=8i3J_I4P=m*3i)?tz0;zp?bkDyV@leHk8
z8Ym0~2G-&oe2JQxq&RM7jLy^<hA7?C2iK)XD&n~d11tW&nRZb|%1aLc{0q4frPQfe
zL3eXNXW=1KO2n&WluR+J&Gk#3SDjeG1^E&4l@t0}!D9$oEGr}aNp!0lE%`)CXuC(U
zF)}q}K4Xr)Z7s2kOeDq(-Vdi5-1lz2Es6CAZoUOkBn}=jL1iw#i-FUgmQok$$f^qQ
zLlb&t%@DyGICCfIGjsKz&&lWLZ)3?nkxjPC-MEa|hJw1LSCv`|#aRhD%hmxjW!IZ7
zrX~}toQkL{6T7B5gPgRCsq)F0b;NW_M|KEQV=D0>g?Xh0p)JZ<LKDKMJSb=0FP{C4
zDb(+v$X^5oi(e!Lk6Q}&AU#U=C_F0nFgz$`R9u~00mjhDa;`{j=p?NM_{N%;!=2q}
zNRLjMj#Mb~mq@X_xS*6*TgM0pa3DpadTKeBztTzJx&+q7#*~GwRtcSch}eXWn6yaj
zaHTycG$->nUc=-mE(Ls`z5)+Qr8;F0R92sj9yEJx1kK&wQ8S2S`)h+Qk?^jShBw0n
z^g^Pht7xCZvs&|5W95{bypf4acXhX`O_>*QyEk183j48^Ws>JcasVrhs5G9;&2dyi
z%>jCf;J1W^x5i(=Cvt|^PAWSdNG}XTJ@;UD+R!_#xn5!VD8@`C$I>Ipes@q*x>0`l
z)z8=i*VF~+bxTYjaCr)lzaDau^|9V&q!IlGwQu0TKbn4oBljDL$D`d(xUR1D_M2H5
z_D)E{)YMOgPe9j&Ta=X`w!K8L8Fz1tOon!uWan9)huounS4Mh4dF)BRXPW~rZ){=b
z8GKrX8h<5U_7;gkNu2?Vha=mHR?g_-tDJ7e(~<p`5So+xCj_-OKdxm*zb&kc2OZP*
zS*dMJml5H=AgV98Q*HXN{iwX0%>;kBqw^DncZb0-heR1$Eu84i7(X`&aR*AQIwovW
z>fz)N@L0uBeI%!;>fF*(y?a<c_!g>B?LspSl*h;#V3|hH@lSBCC>z%=##r4vBD?~%
zIcaMD#Ep&MMR|QloYSVm4m`6&D~o=K)KUR!2dn`<yN`auN<s+X&^0ReqACJ&1&%`i
zS9AJ&$N9ZQ1((R%+~P=Z=oBq)CTZ&h*($ex{G*kzjI$J`=0_pn{>e7}AFYi4ni=M|
zwlXp`cKoTc{O?pVGTu@effshzIQL;~Uran3$O8b$6lS*o0s<dgL{S2X9~gc+hAQJw
zq&2R+oY;$8l90IT2Jj^}g25Rw!7x3An4zBGKKt|X>T!BoyZd(zz&P7axA%@Nz)_qI
zkD$LWxQoOtM=CJA^aux0eMxT|$TTV{XcUf%R6YWWWpb~~Wr+7tk~!$o(-O!M!{#H?
z)jCw2taNz0WO)=*Gud<JaW9@fpL3bl$WP$^I7J6|S#A$6nMZmSNyA=+P(gb_ljw{(
zpw$3VlU2o9^;u=VQPT<2F$?i*b$!3|=NVHi+<=nB!2{$_ZQWc=G8(7B;yip<TFPR2
zE%GD0>3!7Hi9?DqB;9JQ_pLDASj_PC!c^M|om%q>Zz+S3oK5Y^V&l+!?6vHO@6@c?
z%)vqVE`pRD|ItbFC1kt4ApdNC)&9im8NW=RUr><p>@up^y4&I8N>~wvL%f(S2W%NN
zf&x46sN${5Gh+I9cd>g-O|x3@x#@hdvU54zx*WtnC#5%quWk43w{;_G!4&;N;wy-O
z?urjbDnKfp2u4gknf&*wBJS`YfdzBa#pf^Lo9ei}Z)MCk6MP}h0OYrd8`j<XJ`}!e
z0HI@HcE57X35JKili58J7T;t86BZwc4YX1Lws-ENID+Z{zZ+abbPM)lpp3$4gSdHe
zY+yBlF;38gng@uH-O8X-xOu*vxG1TCQ1*Q7Z!J+#_K+^F@~!OO5Fa2BIVYrYj-*&}
zQ5{3U5obGRh7eY4kqC+XCCGWN`Z$q9BtXdWhc15e!SG{9lk+m783=*fX+!6Y;@X##
zKKvSmh#?~y$$_G;1|lov1u={fT%dgXH3}Y62TzFS&!Oy>VipqsRTq}lh>h#|o4yiA
zbPQLKXatZ+L=I$?XEGfd7x*_lf|=3xKLi)yj}jQ9pD+OPrv;Mqe+~uywe$sD4D}uV
z4@_J6*&E>)?K_L=^<ZCx9>f9)ZpbIb0tyI>qF^OuZ;8LrA_T9JRowWUXNjyBVFxj7
zcFv)I!ZI!9%3&ro1=#}qZ!W@`!*%Do@xlC)>lS-KJPYY3@3mXj^ZUgyXXo8DiZ)0M
z@ORv8NQ5xIiv%yy7Wuv<gda;WPv83Mfi2oK*ls5MR^blRR%H&dG-*n(J^fa`4&Kxv
z{IR>M3l7ZnaX8M-u4s`LZ2-*e2V%BIin4U@4b=3ps|#~L^v#DXv3G<r4$LkBhj(1C
zbl?r<boS9M13ec;-?54><iwXNu=74-#U6_5BaxOTYe03)+cZNzBz=*qSJtTXNK1(h
zd)L@OHJQjhyuX$bt-mU;^35ZxR>Dk8H#;lK%qAV<%I5Z8dd3-sIMfqq2WY52;$Y7|
zC@8Z_G%EJ3tOhCq_Ad3l4=IN9=Ee$7k#R%^@JPd7SnqL~*a3EWdfPj^Ft)B}bgnkr
zBT1I)!g2ha@JU#wQW1op@1SkuaGVJcEJVhstebVvoHV+n`EI?;^p~M~tfk#K1CBi-
zF<+3FQvDXkoVE)E6Bj9T)Vlo9rjgCj>S}EH&DnJgn49L@7ZaI&#X6=<x<;pRn<=KT
z8T)QyTh=O!X-f$Km9us?>v&F?OY*>NLOQ-u43cR-0P{LGZCyKsW{^hNC8iDiqJ{~)
zNqU!S?7Gb=jXSc_T>xTosLbq!#)VKVs^hKlReb|!_v(O0B(=A8tA0Fic+K)>Lc!(J
zge-eb*cuWjJCE_q)D}kLQ`X73XAD=didg`EDAk|<!CB}ip9-sH7-$E3o;#ynu|z(_
zJW@g6JNly$0rBNIfH}-MdIvmxv(o?)Dn6kkc-3X%aHp8r%~g$Frzq#~m!ODbgAR!+
zoMp>uw*rjJ1Yj*bj<;`v&<aSHn4f_YVQXq??gA_7CW)csCEYaU)8a!nrY7-vi%oc2
z2$LliRrO;6{{&i05pc<71XA765|}Tlu|8!ah?st-nGC}8<Jk8N9U04t@U4ms5N=P!
zX1(G!MxoVR`)jG#xwjOhk&P1#_G_@y5E_M%IUGuv+~QKwC=swM0}(W3vTD*=$?+?u
zJ6Aob)p9~XWcJ3Ef;@cYIxz6b?{=pV2<uw05TzUTb!O-G+J!3xsJ(Q;wd%IiCo1e9
z1rLnv+#$_6*PNKfNYPFeGk7)4Onjo75mYh+)o$i)t~h4Xbf(J?ue35_f<#I1a_<E8
z#IWl<cgjn2rfl{KY^3V`b4AP^b45&nW{5~fPQQHes{MCD!b`HnKUCG_FTb^9V~0hN
zxD7-NF~KLZWNrzLUg!|cI|mK|glJ^zXiN7<{tTHSaT_u};t?blke);ZWYaw!8v=p8
zph&zBA)I-%5xLgPQyR?miErfL7kglurN;N=Vywz{%h^U)elh`mgLEt2vTJ=}3zy0k
zj;EOfAra$b2YM2yZbXSz7yotU@QfDx;2p%dB|-8&l0Y4nMe~-uRsN71+E)Ak{7$H;
zo{k6+h|ZwD2ps|U91C^fDlU$o<ChkWsHi6UYv&)Q8>pOnps=(g<^CaeJRd*q!NQ`O
zTAcA*KCphxtD>M<0l)OpWo@|W=Vs)XFpM7C;96VQR+W3~AXoqC9@yN@7J9kuboR-H
zHL8|U?V*D#Jg&`hR95a1#ByH}mfw|kcIP#b2%C}r_nxhIoWdo%k*DB;N)%#~P458H
zR&1-?mh?}HxGi(-dh@nkK_H45IB{y)%qwup^p85vZeUpqh|G;9wr%q$_*4*|PS(bw
z3$<2M;y;*(WAtHSM--PRyA1<)1Xe^(yuRRaZX9nR0oP5%Wg)P(ak|_q$^7Cd)NP#f
zFt*;;hP)je2EkvO_Juc*@6Fd}(xbH@+`c?h1(9yjJzcLY^!{hs3;2?q^IfrF`+D{7
zeAjrrb~tUbxms|met4=I%jCVN6O3DEeY8_%NiNb1EvTu>AI1J!n@36jd$2##c}B>0
z4L;|^v$`6=K#^tk;MTA+ji{smQT)gaODj-((|WI%X2JbpJ46#0RZ&FMJeh+Z<&>04
z)cI;7Dm)CZ1Q9H0Ge@zDXKAsB9dZbg4?1joh3}_)K2k;c^(s6)kl-$}hLll_T0$(y
z-4SgpruNv<L+aH!q8IS8MzY-gg?eaOL-SBc(|NiekyEP>#}%R(l@3!%tj5l<!T1a+
zmzd1#!RA2v;r2~Stm-6FOWHj8**5(k!_c-){Ogo@$~19ba2$cgu#Q+WzJiQa_~uJ9
z--DAXeBY@UCoqOU>!d~Np>{BXo}gF5QWAP7*n?JW-N~>|I~-Sokci&_Ho87f;<jMH
zf#SudKQ=r{7b2n+Ec|5w;>meu+(2@Yz45X{^W92m`3_^%9FadE5^cGO72ffn`$&G}
zGOIPIF?FsLh^0eater8)<@~LjNIyP(W<U$h2l%YS9YU1AkliE19yN#0-#D!bNwB$c
zlcdqBzq8al#RLPM6(ys9dr<g5yEjE>7F~ackhd7ase+Gfo@-RBG6$Q+CeDbE-eiO!
z66k;0^Ze3P9kEj(yiZ!_vx)K5>+Jrl2af_iKMbiG*Z6y})9{?`w@LyvBpEEC99HEm
z94J&4%248p>c%Nb+Y?Mm9%w8P;5(?F8nINf&_*-><^LeQ6{hj_UPeUhLmtxd+Vmgt
zX+WF*G|x;d1!gF0D5?$*b6|tDV#m<_?(f{b+Jd?J92?)y8t>gZ+-KQ+Bj*PJW__xR
zdf03Su)GBsi{L~F7m?zTiiu`Wk!YO=QO{H#)PP2?loJ6bfRs0oKxO3+aYm9`#}5V$
z`x646$<?I+_|&qB9yVC`3(2AonpGM(C=8yTG=zFgghaCdFhJoFxA6^cH4AquVxU~U
zp$tBySaago1O>5C08JvW-c>mV&jy+a+V^zH9IQ#Inj?BmB?I0~jhx7qLD!cSQ9{<)
zCB(xvh>|7z&?P1A6fTeZ=vH4`HaRJenyQMrBMl$uNuOX#!uWTr0YsU$pvq9H4wY>t
zl^X-E=|ppy073iT6Xv?zU&~*SO<KFj!<^Vw<Y#jSXZX8Re&4&_0RQ)Z)Pi9+<bTv#
zv3`#KaEtm+8zriL*(g!{FAGMSpJLX}1pI%gEEJ?;(_)g;WKEJZViKdGi;`2L2jt|F
z6r&T8jfVjLsE_=d@_+kJlKuDd+vxuEXBqz3JyKcyJlp@<xBSyO^WRSd^Yh~0JfHL}
zO#hqf<l+W*6~|AuB>z)S{s$uTKR(W@_aA<f`VRcomX<%Fk%Xz0;ZN4&^dlqvmwc3{
zplSUdMl67k;pc1kO^sgs+zHWg<kCg3@N*`Nc$IK-1H-zi%a%IHQ2hDcecO37jI#qc
zJJIx8STQn54G+4<TdeNat@cM-o7~>sUm!9<t2_YgY);SuHTpcm_dV`#E~;3pSgu&W
zK`x7r8mjssM)t)}Yq8t4Xi6AW#yBwUmg)^I?cyS3yXqb8V}TeKBss*~?SMgg{U}nS
za2@lF;!4X@i|c@7Ekw~DTG8&AJ{Kd;Q<iv^vbrlR6OWDG+0`Bhd1mE`rEuw1k#Ir%
z7W)y|_j1YZQm0sfKoyB-7X_Y1>UD9D`~`uK!3`Buc{%2B4{J%ioRlMx&#kB{e!Avb
zJrlj#<)~p=4r6CfO9_3Cn1xhg=x7nk+LY}yn%fvBEBY;q4p`CSxj7W<Dru1=c41fi
zjgF{FvXK1BA>fX^CU5+@tJWJi(W&KcO*jj5x;xDLZ*AxFvIAYA@P8yW`o)9#pos(U
zSgS*I-N9vd=^11lccI*yNQxzMgJ!_I?64MNHZL9-U_DIfm>8g{k^fj)WeFHM8I_z&
zZ3l@3<|n0jQSo~R0*Qcqvf~?+vNohOl*bzy=)XeN;2a3p1~0V$$gAWoVuI=*iPkyO
z;E~luur&+0{@(mshrT+g9pcf!^T48w$vch$Nigsv6ylw&q=E-ICa#nDgi$8vmBC($
z=yLuLM0U-^2^S`{_ZwTz$|kB|ZzUr`AM@J;{X1nZJEj`$4skl+fss?6#-GZt`JdU#
zvVUW}%8!tF0rBe>`+r}#|FsnVkBs^MUX+ze>dHSpWnWVCqdl~T@Zci3NHq%q1q0&Z
zjiRz*rIA75MSd&j>=Hq=uts|mK)cc}S884FYT9`Ym2Gbq-?zNU&7M-!u<)j1^s21K
z7oJaB$L#M;cjw#E-oI~{yJTr2o((;6binRCTJm*%J0nr<VUutll)ppFy@>P<k38sr
zk8`FBLf|O1--H6-a9#2>f%?1jgigQI5bI~2dsFN451~NyCYYvfVfu5!YwE`!Uv%`&
zB-2spw{|p}vcNP<;@k3}sV|3_r|H|Z4JC9~&KtI*)@JhM?U=mg#m<Bq>3PjRVoE+M
zVYM5uWSO==K5b<g9k#9ludk65?GmDaKnQ7`*c2Y5HVx9Eh8j6Fcv8tORPf=Svlc1h
z&c-6owg(lb3KC4yE*VWPV$~bfsyA0s)yp`6-6<R}t{}`PF%1)GY{2!#sW3=%sbm#g
zuE`pUD#yk)R48lq*c1at(x!6fCRVWJU!)EW#3_jhNzWp-#!2$(m_p1|*|roRjSubd
zj?!r;^FTD-7ij=rH1TeP`S6l4;g81eGy3Ho9k5U?A{+?So0K7mQ5Z)-X^pt0b%~?*
zMMVSy>E81EEz2?F$jdRB^ec45FWK&Dz+e}E=Op=h#{z^;qey2Dx+2Q2qzwA-MpAB%
z6U&685w0+}tjouEmcVXOF$U)7w=8u*B7piVzASTr-X|xfrQR1uvc@IZr$CD4MUVF|
zMre!R*v|cBT}rB>9#r~c4@(}lBCp$9)X`O$7f_9s)8|{>$Da!Go<Jm-tOz&ASh&&Z
z2DkZ2v>_qr=;4rtnr7TgXUpffMV9akHEvEw*Z&g!2Env6(!b;)$Zkq!j9UGy>Zopi
zUQ<$5Ex<;<A+9Dl>BxM?&1+E#8>B$er2c?TqH!q^=LX)1lV=@=!xtMbm`$gt70@|}
z8AM$V_n1o@=*E15EncO@{D<SVX-=L()z8Fh8{LsQU1^I&WmONXx!p1C`IWx38^d(*
zswUB)-7ssxAUa>Fc)hEBSA@Nbk=GkNsF#}_mBtmF20k$-)eOP+G`q*EAP^>>5d@ea
zg6^gb37{ol+=uYC3->5=jbqd}&J|19Oh}yYviQ}E@&>94`r85c>mo=XKA{q~2C*8q
z1(8IqD#!fuWdW8DT^RfX)ssdyOzHq^sC=mmY``qcE8^g-<WoQ-{q~4g?&D$m<N<fG
z6_vZ$?+PM;;DMG>o852h1`FBL)_0fHqqzW%Y(brO+X5H!1sl*7|2>*^XZQ^Um1qp-
zj{+=uY~SxwTj1)2rmt7luK=kSptJD<xtPC2BM1x!fzBf^_W{=aF`W1sA0W%%^FQsf
zk@IF@C*}h8>qqF#W3sech+R{=RBs5U1mcd@_EU~~8?dsmUjsf7tKBg%yZYVwFEDFu
zWWQwnb~$%v)IaYXT;h~afPZz{<k4e=a}VnP?~?q0c1nHOnoi4AC3l-rj=%olW9C^o
z<tqHs-y;6AfBp}9=fB;ac<qcGEq@%$e(2MNHvdO$OpKir1EfO?lzwB#Z){Stq&Vxl
zYET5-P=dgR=-cT_x|%ml5i)`wohYe3EZgY=y~!OQq*81EGqR0$x4U+h9(f-=$M9ib
z6erag53odWM1cl4&VbB%0y_)-;`A)g5)eFjlphpa;Y5c=q&`f6Q}Co-u|$qeL7$N=
zNKB&vM29ZjBhC&Fbm&9yL(ndpfkeU*o`A%^(i~$c(zC!tA)nAAo-050;VjSyqxQw9
zC(O+){IcVn(b~IAr%xe$H8@i5AM`N_C0<Ncf=zg%m;c><G-Q2FqhI{9jl)HOBl%5n
zYYEo8GksGdkVUWV!BZVP(xfB;(jhoFI4;e*N?l8}GXT5RK2xwIRje%}va2i>4^@br
zn<wq%L^w{;R*Yph<{KY8UNx}~%O804Jvq#G1!7H%A=5hlVJIeNt{9YD*L(;1zazE!
z?Y%d&pQ~d0b5;H$lKMvg^lw+?ACXL?tfY8953J|>($GS68Obz0BZLqKb0MyvEEp-F
z%XZOu9nt29ll<E{#|z+x>>hI<yaa@%iqp|#*K<&6_I9=PuV)tL8Als2n>Y!o7Ulpi
znv6Q&d-<Y(Z@m_y{RB{=3rCK_Q1A|NffEjDgfCNrqN6`kU{-{Idc?~aHp(O%q`I-Q
za-lk?1GYP>;x1Q#smNV37IAjmqJ`f>4;j)zs}@5Ggb8NHQ&r9}YcFk1=s0qSmfDIT
zL}IzQfY+Hb7z3YWw>3^;vPtIw+@lL;+6f0j=R`K1?Rs$3&Ft1)@NM5zV1L&`Vbl&7
zswRx&Edg?U7fqYMBpWQ6jO&vI*KI5odc0(9&B?LUS$lNhs$&T-QLab-p|8suK`a9N
zU;>Q)dneC-M2!FT|4RScQqNRUcScY|-Hb2FWK7ixX)w*zIKVgM!)R>CsoYSb9@Lsy
zLJk9)H;@1=N~KM;fxCA80PT1w>bSwB_El6JKa7XzdPVs_qfTy_HegHLC>RgUxX-lj
zs_$O^k~(_!_WA<u8Gj*;uw)_G_dxxfVJ?W1q-Oiu8uBy`bt`lSmRj%zf;yZxu@;jT
z9Stol!nxmsW^)X}R8YhXOt~+kIxG;buZ(3hv=@<IYom)8L|lkBh>Dl_zRBtc0-mj?
zs$_XlVRk8UA;TzI%p`NZo^_F0EiGU(u~@&bF!!jgly!a1es#9LBez7Usio}j;#J*M
zYwchj{qF*wFL`?T^AP-=5n(>kT+$T_0iGHp4PM3Z+@Rs&k(ghDz;|7e>IBW%Q&>Q*
z*|!8m`k0#8(2SfZzjS1JdAS)iL*a3Q>Tt-uHB0^>6;<V$nh@W3O4j^kKfIo8_N%CR
z{emGs#-(-)EaqQ^G!Z0Sqp<SvG$xv<fPN!2CS(P16m#eLL5F_uH3~L{j`LM1#iQYR
zs@(RuU-RearN`#}XAP69W^ZQ=Y0gz+q+>1Ac&)lXvA#A+^~TF&^<-Px{Arzw?$8;b
z6(xcC)ary#!{#M(-LV!}WvwJ94Y}p+dl+)^9$xeZPD9+g#b-y4E)=6{dZvMSy(4bs
zQqd@m1o^6YxMp0{hxGGmxj9Cv;|d+QcXE|*vQbI!0Pil2SOuAXlwDZl!rN-01kujv
z`f06S5M~gsjn6G_ql(Z9v;Hz>hvm)t+G*Reo}Oz2DoZC~IJYFxV3=*1bcDI#V-ehb
z`yS4?O;M_uUKUWRm9-0*%jA%+L}L(ouJ)NW*6>k4H0cLNq(fNgHv4Jnoecj0zTR!}
zd#20Z0rVivt#5;(=aRdj<I<fS%aM2UZ3tz;_4Dg=;q4{lQj8JEIPH+}>Zc}W37m&`
zO8hf+O$5W$AK*8A8`$z*=vRHy=*QmoFlAg=(s#RhNTHVYC1}1K@hC|GVLZ=F6-*0x
z{+sO$vPen^=y*Dt6A!PzJ!}(6LIqT()R5jys9m(YH-ka(Nn?~~Rtl-H*pP{zU-MQ?
zlXus*&2qLymA^@KO>Y@ZjhbR)e1(|kVQ~2STn}<nr}~EMrrv&o5vmQJl(b{lz1B=?
z`G(`WrTO+e2Uxb3yoO5yxCIAx;BLwNg#ZCF_3#K2DdT<$;e#miQ|jt+_}8+(#-}ea
z5Noz5M^J)`U(f5XiCc)yo-iY~fViu$R23efuG=@d8qvm}5`->zH$Hv*3wW<D6X|ct
zE%&!$z&zmCy%tEksP)#cTtLo~A*HuY!2E|(!a`BA4w1;r2i+eco4|K^0L=$7Ism3A
z`=6O@-7$#cxhb$h|Acl}m$8^MgNIQT!uxPAZ@3D?n{oy8!4wRmFbdmF)t5K_{204B
za^`0?t%RF&&2^%f<rZgDVU3u-ETAmop#>t5KBjg$eN#@{G$fcMS8-`5K^IA7m_aM6
z`$)$n`bVh3x<&!)d?X1WLQ9uG9!?;qPGiS*BaH;RE}RifZm9eNEHWtim<ZHESjbbe
zo_<btIr?F(=O55waud-trgV4(CJ(K{D;FV}vsPiF!Xb(B^?^Y>)l0DD^SyZww8iac
z7r6e^#bzT+IQYWSF&Kq!LAalh*r_;Wzi*>jtu~LuXq%d^sr49_?y34lr!u2w+EXxL
ztvGKYoa^y*IC%Ypz%YnJV8{reNW^fpBHc9m`O*l>0iqm+au0Ze=X^~VrnQF?&PU+5
zvDnPzI3)KOpigkw6k+Ys(1~ggta{l}hmoJQoMZf-VJ+IOf#vtk(!25;+d@FGwm{aR
zAx2bT?D_&PU}I*Rt}$?_UtrnE;npz+3Wm#cQDminaPZX-ZsD&rZgNMlOP>~lPs)5-
z1VY9g@uu8tU)@>Vy33Lo9Nkp)j+fdu6g^!Frwn87+^Rz~KEqI<wPRV2ZBv|i8Izgm
ze)kDGLS{?i5iivw>ZNvGPU)wR*jLB$B}I$TO*f~!7t4654oLO6t8V2r?1+T_Q&0K0
z4682u*_{u6j(?P@{;`Y5=-T~Y%Kr<77Z}0&gZ+aQ{5EN9gm5}+3o-ZC$|VI0^CJnl
zlu@4piaXoYaQOv8RMg_I3w0k1bN&6lEJ=n~1W@$^LZ*+5?6;J{!0RU%BNqm{<~-t-
zYBiVcsKMtWrxI-wsbMy>B;oLhCnBi?O$~EZ4$9!UcL&30S4}6G<>y$P0t(I%#Lna}
zX_$_w@IIB}3veH9GP|^0P;_>@eR7vav@g)kd<ftEA?>8j3{^_~v_K#JRObGNy!PKV
z%zyn<UZWp%Mab07-a+0`?_Y2KXFu$q(zz6ZEbNz*I*XxtjskB7fl@%z3?x2o2y#L=
zA_TAK&30XdW9~)VC4QIR^e&`M9xoBy7sIWr2Z(+~y?Ty{4kX^~G^@SQk%#?i>gxUd
z^s@D@xs>D?9|0^XQSe9+5fMBr9-1rL2ipylxZmKI{+KW<K}0~b_`H1tQNx&ML2BoX
zN)d!;YxO~?(g%{Rg*n6teo3edOUs6yMCGSv85YQj_8|?yOq%sVsKjiWi{Fbis}zQA
z{F>oVU3B__h9-y+tCNq0iyqW8C?N<_=wTWv36hc-;u6_5$-8<-iG^wVX{rs#%*o<0
zP`zZD%9FKz8kA)Pi`QrR2c(!`3^|x4*s*D2BB*E3p1pCB6wSJ(K~r=?GY2zKWbkSM
zk97>~<lV6dz^c<E$dvN)_xy<&)XvisHKU-_7Ds}6<ToedXiZ$KipXkJ1MH{k>}>cv
zb$Jz&BN$J`J1%`SPSlD!*ydwZh|}u@Dsp<F3<71X!?;wa=|y=_=6N1!<PL5EReoUm
ze6V<owj9uUm<X8hyb`-;{ORgus34kHuDR8xLrGo&oDJ9{5PRfR;KN2GF`Cd4IDp%B
z89D7^0QL|eYULlK8)-=5QMuO=oJx`sQG*lzA7$?tooUx)jaJ3BS+Q+bY};1Fwv#)y
zZQHhO+cqow(*5)}<Mi8ozVV*_*S~A+z2}-(E6K7f*pO2uhSzIe?y_BVHdJ_rTt0I&
zEDtR_){j`(+y*sr_ORi!s1OxtK{>A<j-e#;zHD$to|nOXyu8fda+Ai?Zen(W6J@PE
z-(-@b!SL@)X_H%Vd78&!-Uny@4o7RBtO8wR&sSpGi@DsaNcX#lJ5G(97z}e>$4$sz
zuve=&^SCLUwSd_bGS|G?7q|}mlM8;PN?3s*Qn`LoL_I|_0v+g4G5lm(&>D&~sR6?l
znI)Ws=bL^}57Jk}tm&J<?wp~3>ypgNPrn=57ljDoPx5vC%_rIdlHBI-9tCQd3ccs7
z8t-*ywH72aUrR7)OSDPqV2JeQ%}`Fj)8^<7+S({A|0d~}AU_#mFK*xIuPXctHbR_6
z0>4#tdv;L;zy3>@ngEyuC~{UEld$Xby%R!P6GeG0aQ`p@>*JR7p_5+YHPKN^V4fk3
zP=|o0bY4goP@xf7HieU5*Pudrp}QZK@B~{n6cMl7DMdWz@t^;~@D^eU<>!6(45Z(_
zk$+hp^uOOo|9MRR!MG0pHBKn;ANR<Y2Ti9vO+(2qUR4l3DqG($!Xcp>0%BC@7!g<f
zx&~8@&a2eR+!w@m+O8NOlGy?HonXc(ooV~IIAFuHi>ZmJPZJXt>$m&mX8a!}cI&=T
z^1$X1PVvlD`DVXD#eo%T9Hq`v^hcCB+%v=fj3To3%Z<jfl#{wGHdcn6tI4)nt}GUM
zWrG41a7EcawE?lUuFtoOg7%~3NZiFRRO^q@n!NkzwCXYm9Z)XgTAUK_k>Wn%=JZC_
zoex%j4<fH!1xm*SR_sR)BLUK7PW1M~CNY6HQCGzk_fDVQ^E!{M59uO+&)PYv&m>J+
zbQX)n<fsyw2pf9hmWtAYH8f0jZbbf*6yp<%vB{E#6Gd2T+!0)ZLG;-nmE-H6zoy)^
zd!c-bMxSGPwTf1^w|TLST83)8eYnGhrvAJ$&P9vAwb?uqXkdoQnrWz>1VtYQf2U6;
zl+lO7)ctA65@v(JWy3f!Jhj+syx9tcQ)P2qi3?*W-Zw#Ork|#Fs{k`fVV_!Mn!xL3
zIk}JIQwGd7Ve?#cLD_l3;B&IP`k1Ad;eT4RS=pW5A1<B+;OgEnx-?%3>i9B3J!lo3
z!WN4Denb)1o>9t<EeviDEih*`m1+W?r1s`FNLGUFWPT##=gQ6xuk6>u9*MQeIgR3$
z0rD%TiSRC-!526-Q_<1bGYn58#9j%95VT-muFHVK2w+EN#G8i;i`sA@UJgGpB~}7x
zXT$xV`dKsMX!X;9Ku-Kvd`_&(SCYV;p<-2TVNbPS!mBJ-Wd&_+BDCO7!-z<HhH8*5
zoZItvE?zcukf&x77_&;4QL2%h0tR%rsDKIsju8veS*I`^NUDu2bBOnjQ}BMZ;Psiw
zF80VD=wSW<+{^%I$mYMd$_2y2J3qe}*L3I~Ke+#|t@3}pOajIxHum4Ev;Oy|Nnu?C
z<#P$Gf+&2TB_*(_0FLFSXYWRwUOF*onx>tt23Z4X=cs@kswD@}xU^1g^h~pu=^6pW
ze8CszeDle6mmn7p6^EWdfD|dyNB$<y+i8XkUnUQy&*$4Y^bZHuUxpCjWGAt)h`ofO
zGJrr5Om!`|J*X;sPhzxj94ervS{Te__9}4Ofc>Hf%@?7eA4}|ajD2dy<hC37C(YeV
zShbjdTF=e00;;4o<;8i8MX~B73zo%=G3+95(MGJcM52c{eXJ)`0CxP=%`#$?TRCiU
z`kG#h%DE<IKZU-U&C*z#lPZnsDALq2OJiHE20*R(d%@l~g8D4}0?kL8KFftc{l?vB
z&IY6OrbcC1BtWJ{ST?S<D(a+w-wJ<CIAf}w9%f-OuTsN#H`Z!FI%*mNY_k<RoYm^C
zkt5Zo#Jjqvyi8pj-D;eks#Rt@f$b4)d!V;k1C>BKnD5ou30#)271<>qDF}GnvD)t$
z2fj&M*=&%VGF>YIAwtb!y?Ie|YWR?x(Xu<S<BqqlBHp8mjA@U73eN$iR%gpFCj7Ce
zP<|>T5a+5#3i=W?qc_A~KjWxnJccu=Xz$PiiuHzL7#&Jt#VEx6v~-8J%V@+^q|MYi
z{c+eNd4k(vCCT3b1G%D0UknFNZ?%lsqRm{_Bk#15n|;|H)9O&HOroVE-FG(hc4&ZE
z(2P$V`Y^c7#KE)tx3Id<0tT%cp7~`AFs#cqf_JH!mS_Fm3^W1T!JXma96S=IrQy{}
zb0%%7OB-G)J8g)5WpUWTd10Kg^gMRt${vh%)nB};`vmNAbL>TCRA6}wIE<1qWykbg
zPcCUTMV-!d>owCDM3^BD{hCpJcQE*pH$gV#ErC;Wx|Pm9SnipSi4GEzX%cltZ8sf0
z4GJEGTyuxoh}YL_<o$SGkk|NqUnJId>^g{rSCj(Mn9xB&ZpEqiyz-a5H?)=3b8E8s
zNV4xhy4<lFeqUr7Z#Q^6vSB=|(Y#H*zuJADM_Hvj0*A@}0+{muNU{Rp?Ya&h=|E;g
z^Shu+6U6FpA1a4^0N0qW@zcFtFSvdc%!D6)>dT&cqJb_1$w&<_Ly*<nn}fe8JQZGH
zizPmlZZQS8Fg#nsZN)ocv0`-yw%yKfBxZP^WgMA=Si<F#`Y|*G;<QDgv<r{y26MZ2
zkk<374T0i?G$)G8jsy|XLx{wAMa8pFib|cNxxgPkz6T8tAYwrI31wK}Hvd)&6}dVY
zetJAdk6O(@X1@}60&@71Aj{>)afAyxX!#R8gU)gG)(#SXrbXZnoP4uq5;X(XFv+a6
zX>3lBn@9^3=&!a@<q#c?@b$p(nU~UoepO~~n$dq1a~deiHKe~^)9df+MdaVPS_JhS
zjK4=q8e2P<JASX{Q~b^VTAO}@-~UiP{~x1Tp`!M;Jrjk;<*in(Sz$alj4(vmj33RF
zp(wCKS}JWJx*+g57x!$(IeEf5)MxOkC!8+jMbGmIAM<v9>Iy7C*kVuccxvO@qV6GM
z%IEWSgV;mL3SA>lp*KOzvB5IVgDpwgX_;?gI5<Q}&|T<>YK6==zNjtGgy=}3pI7Ml
z*K=k&-d*&<ErX)jKkCLgNaZMlw0@Qf73m0@FhQCx!MlXeiFiF$#k(5u0X_&#J_k}}
z{<+ZFl@NyHd)XRj+woJwiTm88>zJ{n?u+*PW8qBhLLy><lmBL@Eceiy{rPVk$Yo^j
zY3Z29U8%-VmR|h=AfNsdOrQ*Ho4UHHwQVwlWt8>UlMZiEIK|oHw$2r<n9LI1j8ays
zjp$yYLhFUd`=xXzfkWMyz}u#?zl2yAx0*g_CI}SMABQVTH9J;ClnnuXS0lw^V(FNF
znoYuRP;5tgv9!R?Z6OP{OL3$O#=zcQPkg>s9WFwD^(_d8L4@aT5=s?a8<Ckkz5kY+
z&!+e4O=qApdWVr#!w{afUU?6)L-lb`R~sVZ<?yuUKpNJ%<f(A!sFgclv59*CO?JB`
z{vnk!5gQR?UTfl*Wawu62$Fi)+B`Ceo9^|LQlFYqYKicG>c%PT*VUVg&tO4QDy2SY
zjm2bF%vg0dwTFqL)$eqaDox6HxHo5b<wJD&<$KMD6W*98J5qUf4f1!tJA|C{QbG^>
zNFgp5r*h$E+lpT*h%KuH+&3V2#-tv2SyzkL$JGiwZeF>fbV(hQ2BwSr_!rt3?1T{#
z<Qw|+BL4Wn^Y0X_q_vHU^*`|MpVv{*QQy({A0W7?_U3}Ji2Jo+6u)W-2H^*Sj3Oc}
zR_BIv<7cpz;t#?K&5D6_+grnB4aUl3XTl2EwXR`x{wDwDhaXzPA9GL(B!wL1=*G%m
zpZw#82icR|lI`n>3+p)Tl>z*Z!>MQQ>u0C#>Grq9WuFghUm2<38IZ<^qz{5X#CQaF
zf*+9#(YJ9s#v$mL$-q)RasrGY`j8?J&3!QZLlA<|;QEREfPSG;1T6Zobq2^_0kt5q
z09VRDG;Z8JCf6j{ENFc;@3BBW=)L0zw=Nv`9rTWlU%SG*pCtHSWjNhK_eeShOUWc1
zguBW=S8?nd=TBUyH^szUGwHcZ_085TFwz#|m8>-DLDz_i63t}Q{&1Hz4#&BBM00Rg
zVBLmTo3$&AFIBXyzJFV$-LXKdTj9!w1s4u$sTtwJ%L#eIW7Q-qMV*+xeM-%y0(?Xu
zYf$T);aSqS%JCFk#=-}_oMlbLI6SL(vsS@VW3P{axttW?Aj^|nTNjt{WwB<@*PDZT
z83dbE=PjR;JkTlb_0}gc$vw%DL8IuHL48?t7bk-p_2$2S%@_`iYL2H6r(tbXtG6$H
zi1#UpOr)gY$kAjz^D_2qA(d?Drx*fE7c<PPDJ_3{tK3<QFt=3-{ZV7W@$<lT=wEDD
zQGzVPbW3dA14%;AztGF(+}pOM7#3*EC}F*dp#Z{-3}0$x&gEEF;_`^!8!7_d97jAB
zQ!u1UY@v`!)Z-LPYn-R!aT|a&bx)7i<CuM_7wAhz+KRhr>iOz|S65GQ?@VtM-pB2z
zI4+D&hV8ICIAo>$0u9M+c}S<ADzaMS_*~>*w#r~(Y`X!*Ot*s<>_$|Jy`<huD#Y7+
z>Jtq%-UyXuOq-?62R=8(;>I?z9KdCKML;#{YLY$;T>XZm?=UMn_|2rJTDP1Hb8<Fp
z<aUbnsQr#8qC6!OWw`~&osnw>tg|jxd^v+7b=!NmtTqBeh&ZS#8&>3NHz5w>{Y4R_
zO^gPq`R-cbRMDwPNbP_#R>)zaj_`d(XF|e#kUT~iLdsnipk{POw`}Y61ZAD0nZ%DK
z`9$<-)~~Drk;!X=k_bh1nq3~u>-~rbzMYZ?_?z4aK6~P}R|Rp=V)u!VrbLFxIW+2b
z>QCbRY0tN4TkELh&c0Z?EZk3qPr_Z~pM`RmqbUOkJ-FMoK2VOdHC4y-G}8eV+DZWk
zX6jN-&=s0$n)ykYm32Cz^-9AHW)kRCfBXP_Rx{TG3mN7#g=+BS3*~Hwshl1}_t0Tr
z@>%){i8cncHw7ld83d}Tbd$lY)kp&6w=djR4OnT|iOe!>@!}5DO!8*$5^bG9=g)2C
zhntFe*FYJuTv6y}J@zbU^Oo(_A470wLp;z+iI}Hu+#FvD9GC*|JoXx#vUsEWFMWzs
zrZu`29dr4^OWAsvC}BUpF4b3865d`bCI=`twM+)7OHA!s+~FKJo5g*Z3)bGBekB6l
z{^OH$w2KE<?zf&8@k_6yRIJr}hcudOqE1~y0Eq*_fPs1cky+8)Sv7i7LpNB?Om!yx
zM;fItNi@4ZrQ2AmE|%j}vPtG!AqRwCI|OatCMqg7xAqiaR-xma;2N$7gT8N)?LBc=
zp8?k3Za4&tOui9P;ck++*zS@zNI#38ctVf`1UBcj#6^)4Eb(s~ezA@KN;{OsJ&dI=
z7kRp<eD#c;PN8~45^8*&6`&S`b?pNIOSf9++RLBl2IrC^ZIvz4&9}tn`mbiLP=}&5
zuY?D^V<dj#YMg2~pCAffpw#IigWKuFHQZiWsUA|c=JzlvDEjb_8g5a<Xzk4<#_%DE
zF$3mxpI#NnrZXhGzpGznI{6!mc^m@Bn{tya*JW&f2wN;8bO0l6uXzO`KU9)=^-?HF
z=Kxryb2RjTBxwy6f3^PwI5<SAjYT2gBQA1~?-{DrUO?WV+PIhp35dCmysUAajtlYY
zuCGd2N?^){)%p8({py_ti`FeU(0qDBeYym}GD$t-s3WZ=8h7>i*_gGoh!}k-;;t>d
zONzdN&YtPqo8~CDbOb*JqmAK3!_<<xsDfx4-c#JdvbMn))W)>^zKpEMCm1_Aw;5Ap
z5mLu5wB~x0{)K=s#@QHe4QB^QHDEk8EK5<Ay(@pqF*Jbwp!5Y!I*`mx`WYm-xBVjE
z8RQd2Rn^^h5Z_Dz?INEMZWqe!(w$wZ>WS~XtNf1f;f+>NG|?7@i{z{;oEixJ8NF5>
zqrFoEMY^>gJf2r0h7)7!AZa0;Q)Gm-_udiHd6-r+nLkdP8Idjb7YZHg0a|P*pi7<c
z=@pcCpP<<n!yO~K<?yqlTpxc;D>*?SHZmWTU_)ek9rzu5jNMxZ1-PQ*8;dpg0KMZ+
zvg<$xcKwT1PCU?+SNM$wAHJ2tf2-A$Hg|CNMu7i3u;2Rm|Lb+l{H9sv<-UiSxL|KC
zp<+^oL`w;+0@uOD5|ltr1!It<>CyM9qAyLPU7^`<<=sZwJj}lcAO#Jed;j1|xZP-)
z_$diC9(R?o{+&~-z0B_J_6ANFjEe%X=ZqU66Q?A1(h!AWTU?EZ3$shuPcfd!pqaK8
z!fD0;=)T-Z(rPPKxo<FGMidLA)ctW-X3++;rV(Ke0uG$ksjb&kYR{O{wH7Rr=z+UO
ziDF2??3a;}T(WcHF2Q3o4MUVOIS-i%U{p0GVHLafuvs%RsyNa&boS>I++8v5w=@#2
zMjXbSXl5Z|#_JGO8fUn|tFn|N+D7@TQwqfCT14gR8eKfo(XD8)29;&w))lNX3C4^C
z4_yvO`*Vokel4~CYWw|m?mdP`6}1AN$VtBqzG;7rd!*;vK*TA97s|PqHCZ{xFnm)~
z9s2x4@urFRS56_BvH!qM3*$k#n1pR|IB6|zmWY+93=<3xqmsN1=9s}qAI$)aN{!JH
zA_;b-#~mdM`1_d@qW?<#VVuI_28>DS-W;HRhS3j+m07d#0Xp|#ZnIhhr8t)5s_EE`
zT3JNF4UnQUH9EOWEO^G^5&wflY#veqIXg;kE-My3<3l<9gfNQkP1q**CvbxQNd9i4
z?}rC`rg%nf{cI18sklEK1$F*5M?}!fAVS$8bbE-G#XWNyeA8y{>>3X2v0d-+Oj2Nm
zDM~hDkKQMEUONW4)V08yH^lSkurW|St2O-qg*X|7z@2eK@Q#PRzc^?S&VF!iHkZ9r
zQ|_p96s8ueJgP3de8T?u*X4X7*PB1c+u43Z4}DJ|zhVoT0A8Fiv)KyX%2cjV8ZN3c
ztL2<cM_koDKzBCbI<+v(4|2eaodkp75tK?F<m^qk4|R?V<yYnl_<v_wlt3hT%f8Eh
z;Jf_)Ep+)`b?>5YZ~Q;dWu@}E_5AmW*7O3qy%ypGR;@9T0t)F($+h1UowgLH!l=2w
zK!qu7u!lkB2db9ff@F80U3Y&HLxo6uuR{t-k=~4><flcY+saI>KaMap`91+%-=X4x
zPIjb`(iwV6mt`gQh|&>5t)M7K(0ED|DJt@k5JMGy`CcbL;4X9eMpYv9y3t4yjy&B0
zXf?}(|7;DEY^&|$+8O=?lHh`ed24Gb-U*!6TTaZ0@pw}Q7YzJ;?~UHyTPQ)J#Zvh?
z@zWJEmhvLkp>o(em;{^vHcBnExu;CTR9eB;(I!)lr!hG6E{)ZFyun7Nb=JW@0qs@d
zEkQlh4xOnd+KSSjO@HD@I=o=|<+>iix{rdun$Lsk$f(=9m_IWJCWN&~H&6?b*q;D~
z_z1*N#2($~+O|WY^B2XDwT~$_Z>S36GLjfaX(W-3%cth0B?O@ffccd9nP^2UYXi03
z4uGbbTuq5S<T#9jUus3ija01(<T6!rnRkkQO|oX$rb!AX-m!OQiJwL>1&7(wk?e{h
zVAQ9y(!U+Xu-73g-D=uy!XCaY0}{*g46Aw(uj3Y^`bK2@ecVX7t+Z{Sba#VZYI$;U
za)t(vXQ(p)x&2Z1>e|kteyh;gzRHrGHZFI%Py~Mt0qoEdxHKWd^)3)GmjLTWKW3do
zAjEvy9GP>k;}a@@mp%Hf?5FySdRRTR601M)xPFMIdDtwb#x(F{<^lxbF(}O2M7WWp
zl2Z1I|46W47x`fC9WM8*U=}&;9?~EtEz$n{MNV}j<ykf&X&JA^Dx1(YK_|Geq6VWt
z>hKm(Yw$~vO&R{W4Hb*>XipJ>;XH2Jpx|a+wMXI;lt6wo3Z)Ljs`DHXyJ)$LIq``b
zD^gxc6cys%uUQ7+5cWzYV*7mU@Rfg|8&gPjCfdIbLD}~qVEcDktbY!{zmfonO8<HN
zdtWWh%5&mWLv{JWY(fPv{zeFcpq-^w?=b=lL>n{L7g&g|Bl-aN0_nVe5{2&8e+`xB
zMjki8%CJ(<YEO@QO*vfg96xw}JpP6D6;2>Aq9@AD?tZ1GGLZ5Aq1*=~L5L<yEiUH3
z6-h>@!tSX&ponNexP<A>Dz*N=h8YKH9L-P81rF9<S!RySRe994+co=4a|ff6*=But
zS~Yq(Lh*7f6;06YagZLR?VKjsR{j<>{!7(z-F7_b$_<PlsVr(;4!g=*5A)9^qjDds
z)0=OxTV;FJu8i*C490-Fo_wC_H`MAAqruBn3Ymv|K<ZcW>>=@tomyjdThM!y<6Bae
zY{vdG=_1{p8)N}8ioS;C@(dr@R_)}T5C%c>V|b~c;5LhRi;iAu8)R}ulL@=&s@Zk6
z>}ySWoQ>vDwvcTPx>kHaVbZ+SX}@rki*GH~J4<nV#NhW3SXO9Gsz#^&a=$>+^t9PC
z=u|fHt=14)lle{6cYvOX)mZ&GBJ2{g$@KN8b~e?65RAYOh7N;tzih~EAExjN@1q+I
z%{fZHMf2P&Y=78aW10S)9?~lu7_`s|<`1A++aoC^NWXxm+jurhppAHvH?dRhvT4g}
zhq=&!vD%Yows`SWp3<?__@pggGK}{3Pe@*SBiOjYI3r?3CQ~s_ViG?B_h(zOH-P@!
zA%ZXB2EnLnc-{`YP!eG)qes{QM_}^>OsVWit8a_qg>5DDv6w@<i?tMckfVKSCB8V}
zXB5E`u-g;UNE;5LsCuh2`m=v##SX7IH)Ak(O3n&5u4NoELA!Lj2gap!qDlyQYU(QV
z1L~;{)Zc?NB9lHN_0I#sIF`8365a|AFA>3>Lm9=CAtDXgJv-m&d;~GjW^oz$Nk(#o
z1@_a2@uE@10q#}vxN(esT?KbwBA8PA?NrPEpYyT)cg5-dgKbER+m`sAk2Ta?uU_9)
zg!RR|*tAsgGaqGH!bakI{!w92PLLRFM>=soXI*OIYUm4;7fv+@-Rlppk~yYy-;f~Y
zcJ%Gk`t85CQyCv0$GhmhL<<5aHHdw~BEFM9lm%|p%#Hbwp&mQodTollzGque(8vY{
zR52gtrQ4dcCO!$xA&Ru#v!AX@CL$(HRaHtn!s|1duc@egD!o=UGEWK_r5cS7tNhs`
zXU)qVDM>CVNreLwc-GFA*S^Fo;8zo42_DKC(|j8o_}K(;FZ+tK^h}zcEzqyTWWgS@
zh9q-VNo7ZrCv?L8M>F4XBPFc`LGn%7C|ap&BD@1pRflYD?8kcG=Bv?7FhDcF#Y3#*
zBRajkVLtbCw0g{{;BLZUXNXE4Z14wHVE*azZ*o4JS@ma$C)d8`c`ZbJk2~_fGvavN
z!>{FFkFc8!sb3(TVQQgHCSQ14xZrpu4#;GuWJm0@kuVUqKsRotYGY2ARIOEe##N}v
zbX>=47@whw*!`#5H)A98{>QVNI>*K~_FtOT@KY!+UcqjB1B4c-kBRlkrvGYy$QybV
zF8{s^o4$h=|CZeN&(Hsd7yXB2N>uui`3|dpKDi%`*(GRz2+1RcH;9hQ4`lzsvXF{^
zASDO;(yU6hckQ&eg3FKILw=zn1_~wR^}Q~zbJj$#j2DQXx|*2syq}!7`gpznAoJzm
zJ{9JZ${c8jVh$6aDWuQe$D)R<=VV3+B8O&3?z7tEs@|;vc)&p7En(D+ufG#Db6+i2
zG_pH>tN{ti&V+3C6i?=zx8Hu>Rb89an+j^Ca#Z|_`WR}?UZ%#yU8jLIFGa^8Qht-2
zPIzqsHkga9<B=E<%BeMwf@jd%E`4Fc`6IcC790>3Dl`Ym)3uh<jg<VIQy*nww`sw#
z$VW0mia$@&kog?)0mFRNH=Kv9DRhpM4L&qSPr<4k1gB;#(=lNIN3{TO7`kaC7Z-2i
zRqVt03It<<BMf`fP{Wh`rb{9DDsDc>-Nbi}_SsrnFPardtK(KG0R0Alo=5;j>-W%a
zv;YBaW_n*32D(HTYQ0$f1D}mzt}0b00pREwqaDs63=9t4-W0$vOrgWA$;f-Z?&gN`
z#Y@8Jh((?U{Aty(@Y^H#kv>kR!#)il7cQQrqnK(M8+N!FX;TKysz_yWVeZyih+bxz
zPFhwq*I9wiJQ<ayh=sx`ASYa64a^);1AIb|c;eKn#KaEYQWgL=N{_1d;GW{Ilk_{S
z6od55l?jHZ1!g2utp7lUSiwwo-mEaR0FF9sJI5p*{N%5HE&dEETrAQbx>ZaX@R@Fd
zhm)M^g<jf0GU8%9zd`2FezUzMSFOTsFyp&Q5qwh8E8%co;c{E4G;n(7=yD4}OtP3b
z>4J!ocM&Sr#Je(})eKrZfmJTtsBOj#%QhS~p?;xq0xat>K!`S6yqJ+fOHe7RiPEXH
z=n0VtGLi<r&KQu$p(hH~Bd(Ue3{$Qy=_C4oN5iK4c6ABgweR{}`~N@C@c*s}WGYSn
zhbHi8;=CSY42_ygsqwpFM!|^US6~8y7;+q`veX~32i62>buH)7tE89ep3(GVosQpm
zp|j;a@eEz7Rpe-uw=-^hN9oU9&rT-Yo*rL_J%lQb4~8PawCJ#I-}SFFF?tvaaBG!b
zTBym%9f;9t*5>+-4c`T6gEj75YQhMztT$#gMLkh}wXQgjGilvp^{t|I(d@IA0>GVn
zVpcietfni2yDnL&wq|Q@girp$h%7qMbnk`ys)1-$xqmNOeHiRAOobh0h4dia@LIh{
zy#XGd*48bZ$YIF~Nt-&b2;LJ)iLy;M0aw48LMd|`3NK3}exvO<d?E}*z;X2!V}H66
z{k^KhgA%DKJ7C9snK;Dd5v)Q)?P3b03>%Kva$Hkbmypq|qc`#aotE2e&8Cg`t<RqO
z7|cUi4Zl-txj$cED@jy)&~)ott=l(9skXbhjrjT{_>oXsxK7lp#v2NQs4T)#v(*T`
z4V-l$BJ&{B?HBmT8)3|K-<zm?OhY>ss)<qqV$T;0QqDePXGrX*n=$c(rUBM#M%7Ge
zIWENk`o21)P_#jXW-)~E)I{kioj-g;;f4_^#ZwQU<_@rNe^~1UQpev71oH{za@Qzx
z2j_M96?FxbSx$UlRhFzOp5&ilB6Vc)#9vV${dogkK)(PACCrVtqRbPD96qi8nbq@4
zmT;U!>Yn$YH3|v82T4{qFo{drP++b-XdQ8sW`iIaxs@bhmv(W2Fxcau^uSMsEK>Rj
z73{pi-93B=GkRE^q(gv}Me`lRD$4u##NtahUMW~WV<_G(mZgpxEkT>ktO&T}AiKv)
zYPQQC9FaFTI5u-gy3R1+TJ&fCfwY)wTXYdcPDt(be=m1EX>Vna?{aVX*1{P79o+jr
zI=)23ZJRl{?>rL)3bcdo`T_?kA{z$wVkc$<DU!6*h>8Dd{}$~`4ejC5hO@{QnXc#T
z0QlFBFY^6Xn)J<I{AmrxqTTnI*BR@dpZE9ZzQ7GuM)LKsf;7>?tY@wU`ojVNF&?|(
zbnfCK%xS|Q_1F<weSfCouXg_$?UcbA>^Kz7K?C~u(8lI(naxFtb;QU!&?z02`H&FF
z!mkS)m6y@=PwvK@>EsMeD+WefGIOsvHuV@0?F+bwogS6kg5}ae=zx=nP;tE?I({Q9
zVRtg!inDjc7#8DG$VPEZA`5Im)BVEC9nv_2iK;;wK}ioH&CPgGb<CbHXDq(lvora2
z!V<&;`*k3^xo>exUQ@(Sj9_!r)kv<GQy;l4&5BxidP|gi!Kdjx2RN`eZo9uOu$j<X
z@kk@0-GP+fQd(X$YocigU*uZqXV)}OSaPp*U*f<{ZRiWJt9f4ruI=qsF-u1Io2G=A
zxt4Wroe_f7k9DiSz1HcSp!(Vd5CzlJPF{Wb-bUgAv+_A`ij$zM(2@RVD)$|gkc$eX
zv_y`BQ^ibcQy%pU{`-hEsUcM#`x_~3r9FrR0l8{lM#>XCJ%encU1>SYu&bJCU4kM%
zu&#jOS{6FHo~6ie5+zx|y)N0k&eb>APMu|luTQ!uedH$Hsv?C|)pDP8od%Zf@L%DB
z?d11_^zWLo_?E2r{+*gqwzl}c2v(iS;|kx#LLQem@jm+B5D2$HA>`r^fywY7wJ~#Z
zlu(rd>NV}eigu2Sg3_d8bT4$Y1!1Cz(0o0K*t*bc)*B~uYR<An0)cV_v>T4w>&?@r
zUBxz}*FN1|;CfKaECVr%Gk{uFjmY}Z+SHu@@koWD{1&W1mY<Cm;?p5}fZuOKr%A9b
ziNHXw!0W6VB$7$vBI<gct9Ie7c~sCzvE!O1)}s`O1=?z?R{3GrRRPnGfd!f<V$^)`
zbVgHg&J4|Gtwq`e`A_dZRrF5i>!%e<_Q}MIwi={u_<O`~jV)znH11DX{BGhDbB@~B
zjSCgl=r@M#`x#$EWOOtv=2+bDLHf58<Au(A4EUNezsGw^Pdi?8A8_+S5Br_IW(xPW
z(~XB)*D5etMlVPgE>m2rB<#9V4J9>?*vl5oRZfXJTmY|e!7f;(GLTw$3dyXdC-ur&
zs_ZQKr0CpVi2L-7ErFzqvnpB^fdXWKiYzKQQQ2%ZnB1O5i8%H>MR9pfj2#q3(f2sp
zVrO!56^9YP@>1p*qBZ4b(z8B}iwWo#QPzJfZ2n5J5;l5WWJQ<IBX*k8hhg;q0m7}5
zYiU1hwU^dFU3+G6FNZCON*MU%1-gDBi7DU@E>I2<J@U*<a)(IH%`1nxmS~1fx}A*p
zCdZiH4q;r^4q-avoNGPr=TE#!tn}M6kdl`lIeV6*D@WCHkb-ku334Wy$+vsYzfadr
zd{Ebpi6AU%ur<dqiQAN7ce#-hF)GA{w_1k>))jQh@YnAnpn|kj!GlSHn`h1%4Pf10
z#$`L|cVl)t_`K}u(j}W>gTh}T{@E_S>wj}-5oWCtG&&=!2_|H?_mnV%zl1v9mRA+J
zCMJ^31?>7-WTFszA&y6w3_lSx!8<+n4o@pN{Lvn?<(T0BQ29+UM7(g`QwA~LQZnP4
zU<-r)B?xOkj>kLd9>>fmqNQU{&&ZyHsS0l7`|r20kw*Fg+V}Ep%kOXy>A!Ju{=wRr
z>gIY{gR!3yX{l`P-^*cF>v;4mcY)877@BGh6?uPPO0p)^#==jixyOm%O^2i+HnD$i
ze?W{vh|)s_^3w|j@ozPP_FI*1=|dX1LRy)u(_anX@r5O@{4qT2{jrrkJ8^;;`Yz`p
z>!R$W?6kPNC|ix|@r2;3ey4=Td0YGEQ<bHAxfU(k>?Ht>j(7H!;<Lozl?nE%cvtrC
z3oP$)?mjfG+lxZK{&yVW*b}FB*7IVRVG(CJ5Jffog+z21V{~yK->}2=V^6W0W$^`7
zI4ep!?~O!v5~B<=*F@yi7{w_Ts5@e*KyKL4voF&)g4EC{VF$Szr8e2F46~Y@w1hMV
zB%|OUt0FB_LN@$5!IPUVer2bGG~Q`Jtd_L+EQLyuIkjw*8Ta0}ElPt!T7GJ#Kxo*&
zonOLfp)?We+vTM-Y)^7ym3oj2<t|LQD3PdJwn)pQ?9fJAe*nXhRymsCS&@X*ol!cf
z#gb9nRPi|OS@;apO|8_8ZeFJ*$^<%&gmWl%<_a=aVS-sbs?bfX=uER*tE^HotM1LA
z>2{2xeP&!pdpt(j%`AtU70i5Ar?K>M$lchY5>M(Uj~|*+YrLz+Z9N3Kui`=?Fe|1=
zh!)mB7k+gDHRK;^CKd1GKRWJjSI>*YMszDj=op$RO-x?XI{$YHU5cHrjt6NIvle|B
z#L$juDFK31N_xp**g>|YiJyMW_!Wp>UXUE`c<JencEzSf9*vU~B$LVX5Q{llM5D<R
z)Zkud(UsMLg(&@;#81h|CbNl&v}Gg1v7b&{0Srur+tU8;5uuYC^qZRg4CTue<+__K
zjkQ(!gG($<=S!7p>*Np>XD~WQ6<0EWeTxkBn;XiVq$xQnv48#L<uz9edBidE=Sr~s
zwF^cqpc+N}L$5Gsv|?M^dOk7XMApi!e%`AJ8(uD6*6LZTR9Hg>m*K9f1Q8ZhUc3t@
zaByP4iMp@`I;U1fwS$bkGAwxxx!D;{Fr(r!oG;(WaktP|&V_b?=8BQmip6Luj5$0|
zhc~53_*^ZlbQ-2(Y8FF)29@X0^xnMcQ5Se~#b*hLhQt+n2DLTSmsT`OMuM0oSz=k*
zm^XohSF%XMksLI`ycclL8ia^bIX9+^&a4uqXvT>sPv0wq!P{{4E3DjB=sm@V$Y7%!
zC+sm1RYq9hN$~{yN{e7VltX_cA)c|!n;*q?dYXczgf!fg(noPLrn<H#v<5pv%a3<b
z7EDhz|Bm(ho}5a61*H#b3uuAfKtNfnPNCGOv9!w7{8_o^=NuRXrVt3R1tQl$#}rF3
zCkX&)4XU<=)R=s?z_x~I55?S!%N*6s<dtbE&hv*theJY~2FW00;s-D>nxesgD==To
z8kL8^Xe6-n;aMKLfz8PlRF#MSv?4>??F%vaeY|2;u^2((FqEY{<}^6LdJYlC1ZqB3
z2{oA5)w({3mp4GtYs<#=m=-G}^`WExESws{F`1^KHG35pCaemZYTNP4S&coDVz1)h
z8*Z79OCNUVzXp0;MeWe`E?DxliQF|%2gv+p-JXPDdv`g^VtVM@?JFJ?P6J_C73sK&
z0ASccOU!}Lgai6b!cl)%Gh6~G=;U>AUOIwkc2>p<plqp!-!7yYUH3ADrk5)8H&?b-
zO5;ui@?+C9sw_BLo%v69_<@7ak}GDZUs%U#;1tR0auq73mV#?)Ot^ZkWu!8J&PxJB
z{1kL%IoeI&Y^RhnOksi@<kVwP7-U0l=zgVprJqaBUa3J_5Cx6wgNc_Z*u!juX~Jyy
zV#97!h-~*>3YGZLOhFEDwM3HA02;!~cRX5T<+xEU;Np547z(7<S_2$Q0L@yHG0Tw_
zPQ@);EUVUHYR(u)u_XlB_6&$5Z#OWZkp1+<b#pO+j?k3B8w{N{O4!;0E0q-+j=Oy{
zhk%QO7J~MI;TXw7MnT$SDhOPX@clx#!M-v^!7c(-$~+q^`$R2i*M_CVI*mcAmLTN_
zCe_x$vIx6uFs;!uOJQoXNKE@k1^4%z28bX{<spd6HkB%-15Nu*0yc8d4RTcs`*_dw
znDoOxg4Vs4fDOuK%sX5X%C`-$!8(HGaTj&9)}Df}NOZ<2C+!Jlw<`bnV0AQDZn6Z6
zYq`lxzy^s6S)^kPQ{ASe6Hv4|ht%$BG=^Xo*|SlK0(v;82MQw-F=ZHRM}QB#QL`4E
zFM-E_j$jwvvzdLiAKM`~U?Y1l3&=tcPj2@p6)ziaG=vlTC+y!`Ez6OBJA~&{Yuwpr
z4B^{7gF(HKe#*h2R>REiT>>AxDj?=02(=YF7$%UbodGTeWgW)mhUq%ohVGsscH}xZ
zFvAmi7P59!*J~lG8ifrnwf6T!fOnxnfy+8QVkBu4a81qdeDe<eJCQgh8dhm;#0Ziw
z7XT9OAQPpj66On9)$&0xfSWSf{EjIRPQJHDUxGSHq>pEiW>$<4BTR0#DoQW#Xh48w
zkOr5#77d`5aa;OS*H+0?*2SoI*}r^XC-_7qOqyh=<N5cfYW%D(!DFy!p~U_?sZK#K
zD~9ZJfxs}7<T;KY6yV7_jjb>csx#Lg>hkQ;q_?!}lL-SJD0?H4&BRTO`(T7`&1=fH
z0g9@7?8b;wGwu11oSm{o@(2a)+v}dEcFaqdFJr`Tp%QNrqmIDFSa17nefwd?;NaEU
z(#gt`FJTu}HP<`XFin|1%8^^}AmpUB1EQQ$c0SzBm)=_Eg<(8417DwupI)rljtaNr
zZ!AN8cyEV!L^3VFlg#OVE8?Kq_gdBKK8{@L9YI6kM5O`k4C2vLnrurQ>zRO>*pd){
zz3B0|ccsUkB^<*IiL?N3Kcj2iHMHJbD41!e)8V1H5xSTc=e~^O90+yHjLh1Wa+A!h
zsoiZ6;mE2e)6``%fiuL#d5-M={fwoxF9fU!#-A<PEw!f?Y3>*n=IWKM&w6fl-e<0p
zdsn$Tzxt~Hkl3`0vvVNwF?<Nq+~1R0%6RKGrE0P;<#d}Za%)O$$Iw}cE<@p{q)vU`
z%?cQ>#PRg}gj1OfgXZX(wfV=*t!t0bR$4n!F}W{m&0LlNF>A&2Jm-taK&Yln0GU5z
zg!R9P+|Jc4c&$~?;e0^r=y@EmV%*K6r^IyM+Jo+v?U}Zaph@_=ol40*wb0{(PeHbw
z>xTsnVu8b9`43^L!`Rw3ZM>{%%-%P=J3nCihI4UopHu_=f*oEV;eU>t>SB?$kzD<z
zc3bb;yp1{-j6LMu^6iI_K3?U%wm410tgqS`Mqa9{qqi1S&{)j6<>v;~WH^`S`elYG
z*-6@0jA_om<Y`pTwjy<}P0U7o7%357^tsAEV#czco3fhb&Ql6<edNE?chZp6ts6T}
zn|*Ib$ytl$i%wQrmYk3CC<53awRpGsylu6Nv{Clz1$nI7zeX(B#ZJ3)`D=k_&#`B}
z`qOpnb=Qjb$2QZ5Ti;$sK;;x(3NZZ9o=g->I-bj}^^@vts~0>)LPgL8s+ErVUw*UB
zn`>FfTXiWa>Yw|TgrdG!mqU0}+vBytAJ2b>*|<^jXExZ(40s1!Ut^ay;5%C{%nu$2
zbZvhO{fsa>86G*RgW~X&k394u-+}H!zIo7Z&};6f5()C}?n}|IG45FpuWdi9^=+;x
zLEm@I&%xhMM?DW5^0LP-2JU1xXOkf`?vdP!_h6`9Lce+3LqXD#@fSzqSMJfQsX>po
z@MJYcqzFT;M4JJ6KWrV@<4Ke<jW-V)bSx7-zvV1I!M=G_aE#9$Sl}Tid}LO*=J)0+
zx+j<M@S`R!d!(ob?&6&o$!#B^Q0FxjmE`I;9I0BQmYB@#D67LKK~d6BTMD-q*4he(
zT9mDL1b^==*@*1(<uj*M?v?)2RyL~{ubNP-rSkFXXpZtz!5MY=ES1nnv>*#febLn_
z>w@cZkC(cLHm<6wz6*Xncuo@WbSZYya>K>a#F$Q|dc{UKB&?WBzW0e+N)Jg&82PLQ
zj>?XA{Sm?dxM?5gAqP{{fM{M1+0cp!ZwQS$68d&|B}{jputRd}xdt{nA9Q$@l1OjN
zwPBRPEZM+OjDqt}$}*WW&=}cSj4W?1h_)37eOx+ZRA=B&{?i+b>yYDNWV}UbYk=)Q
zP>aH+hvg2lDxPoOodbaFV4spi`Gh}cc6QhgZ_BsdPLKH=`oZCekYCCWnS}93Y+G@}
za!L0GzeR8iHDvG>isJs$IH~dIu+43%6sAgXN?`AKa`S4wTD&sOfq!<Oez8ANUPqDY
zg>yL+ooa`CK*a5zP0v<5_Vz--GC62C>eyW3Jv6(Yq3-K%NWL6Xy!!|CEm|)Mz%W>E
z8o}p}6cv@1RSD1*Et%D)=A1BlM=CzT0YvvVP&fOXK}KZ{D8k`P?nVeeRZiT)*pEM%
z=FU_qeKs+p%;7KvQdJQe#e{H?@5!Jesxq)<)e46sH(6w?SKJ)^FkwkxQ^6~{Jy>!L
z?-0%cPaPB9Qg7@EGm^=Q4d9)a>IGPIM!an+Kj=s0)XsqsL{vM{mxvH33e!z(xV#6{
z`Ke{~DFS`$k{wC!l};Mz_P4M{A9wg2cg30(J!DExlI6~DOy0jNOTs*m^C+sdVS>|8
zKQbY|-cZxXWaaYAPh&a(6n8nM<Q~jV7H%>C$E#4Ax1dG1^7U`<hJ>kbyP)eNt<$z#
zeKqf8_zvmg@OpT5%}K7@-KjUNJ3r7^Rf>FD;loeDy{U_?lNQ`5X<QbN-f@Dz4^)(>
zXHyC%i3!D^8iGWLS`tcKhJXqJ60@d+&adg%I-N)y%VpG8B@euw1mA7gj8|K<pv(RP
zzr(!V@!@B%_aIaJ0gjCz$_1)gI->2kPH>G~2^m))x1XKx$48W}sSyxP{S^wVRF|HV
zSk#xKrLp;$DhJ9vDqaY%EILEM2Ie>ubBPA(l^rv|ENJbGe@9V+j@`0`*N(IrXNb+t
z205{qs|n4g|1uYbn6-A<23RGq1$3<Li#1?IZ%?py?1U=8=!}ghoFojpLekGmVv^L?
z;9I0*^B<W8o;Jo~+Os(vcn@t746WK=>V8EW-~7xP9?syH(BlAPhezomNa`j4br9Fz
z)=~FT)xlItaCuX3-KK2-mJdlf2&(s_-7;NWiW66eC_FeWNyhAkMMLJM8Npo?+Ozl3
zBevk_Vd?ByzGrXwCsVhv6s(Tp+}Ppw3y4LwYlS3-2BbkP8R^(QNOla#O~s?%vbkoe
zBg7QnQr#UJByEJVsd2iM+}^v!s~<Pki5#X^j#ewCz0)vEZtY&Pn~tBzj=p%fD;h7u
zVz}Wn$~box>Q^P|b?a;Rxpn}(?tsFwEWKETpFp4?3BvCi5gy4)HQYE#UD<JtrVm2l
z7*86KP&2s%1`Qu*dto@Bteu@9*C}Rs4Q&m38}p@MGGb$MhmYy{Rofnx)$v+NRHxH#
zmZtydEWY5^0qr-x2S7QY+sNl{2){*j_rJ8-{^&15VW08l+uF;rQJi&wpzA)Q`H&r`
zcL_D^?nl~clDwsB`1(M}Qm(;z7oBrU)G6><7N|{(C=aHd(2(eQrshhDxlelF8qM>`
z?!0>eag8!)0GMz9P1*xxHa$t6>2EWBNqBCD`#9Y24Ad)Tu`6xK*_p{(M;4Dbj0LQy
z%O9jFpEv&AJWr7I^R~32?HCc~v6<%wf!D(hX9T6A8GT&3cqG%Ov}t_I^NJRnkCk?)
z40aie{3tP3S-krhh($@gBH7JJs$BGY!0`02RLo%7Lxm;5!mS%1%yUC9v`4f>ieE4H
z#l!OqX^|s43*g(cuhNd>V;JW(jq>3?_#5Zu!R`cQIIF)&sZ$kIb0@Y*8LZGeMsTds
znrK>jN8=W3HoVhJ8%0!N;w!@&QL5YHfg-HJ%tTy__Huju0)K2$Wl{|%)5`w*z1p=m
zqk(I6-12zJ=u`GR8QMYSslPAtZ@0EflK#cS$XoUTvUzAD5C{~PM{Op$pD8|ftE~PX
z{g+?P+@KCOnx(#?cP%8e!)k;X?=ysdA>^SgL=k26OVx%=wa~L|(d(mYv!{8dcze6j
z_h|LI<1^Y<o?RX9oc9=~qD_4`-l$f50?vt6bw@wbFRJejZW_4kU{9-!eQ-}zkSTO-
z4?q5eS;7iG<Q@IyV}E?JOaBYA^q;K0(SPN+|6`Kgf2p{t<}TQ#sNN#$BX<MgXC%(?
zO45d!NrxD5KW-J8qtav8n-uqkhA3#HDncuimdNvCk((1}<;+%dEzMWifFWa0;`Hp*
zx_WoHwqJ&_b22hgj=fBYC6`(lM2{yno~OLBpSO-_nO=uG`93jwe!kQCJEu_IA-?D>
z5rl?QRzUbq<^7^<3Nrw4iZW@%LvB%uj&Gr+rJ~GIy%hkFrYABRAUnS$q%D0>;?e0F
z*YC*NTZCx#;`B%J6dANYbnJuKuiyJ@rPo1!W(yoV9-N|E*bi?ZPSQpCp{sJ6NZ*CU
zkKUycUA-@@e-CT-x2UC~bWalsYqBGg!6Ar<im54aw6HX_BZuxBSePpwH)Za=AL`76
z@ifC4okp;C^sJa@in0874j8WIrog-qd@d<#3=0@~b)qM}O_^R{|7b2QOH$gzeu%<t
z?}j`U`z}eI-o7cHQVE~eaD~~eKx5x72c+)18DAAk^uvl6Zz_ydKixyREj26aNu59e
zdFYZZqp1-jO4S;|Q=Y-Arf1j3PV%O;fO(#xgosF|5OkfsDGHZ7hB>FWmEw1t)0(NT
zZ%ah9P*p#+ogxb4pG<{n=s1{w6yf)5Pnc7k->i4J$D=#<?M$I?U0K?hS7DJ{XmYL1
z$*JUANc5!G=*N2^dUlbO>oy!(LeDbH6emaBR=LFm?bmTzLCYIaUSX9i+(Np3Ech~*
zZHTPZ`qMW7@!C0m)ySk|8>=iz9uk3a={c)1BmX_(iy>YbGwBzbB70ITRD;4)n5Re3
zv3feudeh@Wv$Z^3LRkfij>W8`O&Xe0Gm<P9kBEPZ6?L=1+A3nTS%Do>Itv={wt<V`
zl9VjgxJc7Rs@2vI6jBy^6GX@Mo7DBpv^8NF%I4Es8Hd%1D4TSGS*bgvsf0_UefSUO
zlhOpCjKz9kL+Dras$Sz`H{46fK)!Q*kFUEgzP`l_I}Oh2auXo8ocZOEi0?dqgdyha
zlNHO&ThKff+&&cK=C9Kh9W|qHi<9BcG;o~1SX<G+Sa7?({@|=xQR+!ugb+(NKRxC8
zHC;9PU2b_`w};_T2Cj}792$9encork6mAWh`b?IT--Y^RZ<#>BH*eWd&MAov7wPat
zRX+eoZInHV$FwzpEE#?ASl&^}UDi!0=un=cDFEG_WE^xJtRnhKeVAkBcPLe5t$F(B
zdMxkAZQBM_DexyTjp?KgPItFnTep?d7nJi;%7+2_B3wz#V@$6<-6N=m@0Eb_ma<*2
ztl1m5s--y1ew_AvXWGOBMlS{P^oSw+WJ3-`l?LTUxly?Y@u^I6d#dM}QeckO61;u5
z*oLSY({aV(R;c;E4J-16B^vd3ZXp@#!TXInjaahq0>{!8;$%ZPqW!!dTfeZcQFyZ1
z>`NnKReAcFyh{VoCo(Ecg&r#L7$AT&J50!dWuZCSI$7O<R^@nZTC(dU*s~-ejq6b|
z=7#&<8Lf_k9e&8qp3BkqB*I_sr_t!>;2*rs6tQS_bbKP5x$#Btj|uuR!tp8n*%I3T
z#I*o#zgxZ75dLNmV{k-117H-Xi89zDKYCfrph%G{*9i8aW)#fi>{Od&bOn&EF~ftt
z+7Pq>z)@g8x%{iNrNriHjL8#Tcz|$oqk6D3K2kKbzn0Hlx!8<i`tSJshb+icE8n|p
z@)xG2Z!=;3@_!<)1YuqPB6(a<;dfaEZaBrUcB2H};q~)>MjN0IXyEo3x@M3g3*q)7
zf=$>mM3McVz#U|myVoDXx{f+xFGNmwCa95_dZ&z|Bvtyn?%{DPH&dD&SoE3s&_z0x
z;~M43AnS-z%h+87s-#;(dqrM5{(uxI-x``q{p*WxUWkEWpcdlud)Nt*NWi7ZdDIrC
z_*E;|%V30~wZFY1*p<%<Jk#jCx3s4uJ~7vKN9oQ>OpJEBchiO-F5;>!XwzZz1kddp
zLZ#w8zx>=scB@Ztd0c#j?z|9PpBNz*-EK)g4%Ib=AD#i#u%c_fz|}vELP1yJH;%_G
zBIz&kcdB@=G(LXklqV+FuusvJHyD%Dgh&vGat^kil{edhO2WkgZP$cFd57ALEfGEm
zA{ooH`(!1zw_6z}?LjLUIq8nv7yXTl)rjW5#`YLa&C~01FLasqF-bD~i?@MUFJQU&
zSK^=jJ}|QE;-6WsfAZ7xKB+J(n3l$B6d_yYh*tf=XlZKuwE1eZmsuk&H(f!fH*$*-
z=8VRBrHYD*9hKoEhI<&FNX$4HtbcL+-fc8Vrj^C=axFkI+|CN6am>_(t&OL%n-LR|
zXL0(#i=SzkCh-Z&b)93uyM`NMyhTR&m(~3<4n_DN8BWx=fa0lu|1Wo@HZ_;#WnRA`
zFqhUtg=`xdz#g5)lATxmS6KhH?*TGIn9kY;$7<LVWZR956j=3fth1qe-()4}Zw$qa
z;8yJPxinL7tqQSn6=zjLjQqO@7}}N)4z@~<GPN|c!IXsknq<)jo0s)p6bSoeBe6}?
z)8gz9hYn98@<n3eF!cD9>BRg7*A5X&9B*MBPkOrMH%aA`I`Ybng+8#5_=~W4X{{&s
zp|@|-*oP4uBv0IA7toH!!d(J7dy@Ny_DjwVaC~P;D|)N5{HHp?{K9H-kn(a+Nk${B
z{~CaG+Xi)9`xa=0zdbJ0|5IlAA7J1gd)GgZAo4rry6_u?XS4cB)X(^@9Ed(@ps{>e
z$;(f|5Hm3q2K9j6W_=e0u=dNMOQhZ68_T_L_>>Y5@dZ<#gj*R+J$2&S-1*dXk7=Ic
zjqk;++de;1`r?`E$jeg1i2Mzpa9gs94gq1K#1G6!EvdaUQY3boUDqWoRNM3Rt;Ks?
z|EIDufroPI<M>d>lu~1>khSb`Z}t=!`zW%eR6~<(n0XDNNTWf@b}bdxZX%T;np@o~
z(jpSKP@+_Hy(&v?mP+^bo{8~rj4|)&GoP_^zP~ePd(Lw_=l4G;fL^t`kw|tiVN}*L
z&USsIm7Jk{c%)>R9*x(!@`lVOub%65yrN#sRP#t;S$u}Rid7@pCX|9Mh#q$0D>wVy
z`ks^`e)vp6hryw}6~U=;H&Wd3y($#i=Gfb3f0I37m4Co6CP43!Z(x-N`X5osp1tms
ze%c3}6kDxdVi;xvDg5Kk=TLkvqlYWfL@LvboWsVW+U`h~6rz383{`x@j1I34O>A9u
z(OF!w(7xw%ab7W5$HpM}K%Mf9$YGm+jk=D;r>mTjH9CcgYjXwbLtab1OI>AUy5g{C
zP<EL+S(2fy?AM3gen;uP$g=DpcOBb+jj3wGpPx*i$IF%EQIA~w2Yb~!ACk({bG)90
zbX7~HUIl^sVnHyzi+Njd8+yOE-5J5Yd}~r<Q<7xd(#%k4`zY~gjhI6I<L_&Sl+)5j
zZTHHq=-iPMGZ?QL!aH=@=iHkHdo|sC(Rpc?5}(w#@rxc!y>+qH{X$!n|DOCvC7Z1h
zLb#ijLmCEVe<tV+)Can0+8tPK-@)^|drMlkteoG(iKAxy6}b_=IDgp}rQ+e(VqvKM
zpiXgQ;`5^Gk{$yz*Oq&v6GH_9!g1HKZYI5L?iRnhJXtP(T`l>mlBALG`lx+>j-CJM
z{h@xv#Js&KqkRhBOy1ko*g1^9E1Qrp(!v^?%anZ^SMoN$#p>Wa#eciXlWFTD1ES($
zH&V4-ltR*P33%k}#G;=mJh;o#As5=>+aU21_EK|k|9@jb19hYPwg}y<lI{MK?5sg9
zbib|9+HP_6bxZlku^ud@Zcl2fp4{^=!JQxD;=e<Og7$>m-xdxYfL#h6fHhz<MgmE`
z1kWID41cpzY<AQdi$pi`Eyjj#wYyW$U$Zz<BDhE1K3=szL1Nt0@U)hH?6O6I->qHN
zYkcGRSE)zjf>t}WM{V$3mj0`ekRsBM<`vXf`EFyewPD2G@^lO3*a69qCC@P{(GljB
zE`En-IER~AWiM9AR!j4{Uk=#yOt;C+#-Op<(;EA!y|FJxLO9WFXBeaS><3EcaP&*(
zzo~{Dmbt3xpYxQDABzsC^mB-j_Y4fixsHDJ@(yo#wk?L1;9ELcW8OHntM9o~DYh@8
zuPLcd@fq&(3&k|dQ~tzN!->&}k}9$L;?Dn7wRQCA2?Hg$*v-@qnn$E{Tf&&2xYXs+
z_LD(>AN;Ua#b*3^n-u!hwIU%`r>>7{oU5eb3t#wbl-7!T;3rgjJ92pfS?_rEApy7Y
zS9*>cy#}|gS#39hFKYTV!#^#)X~5`sPNONB&!GZCky=_LR?Jg)3KK5)P-{=pn-RD7
z|KV4UFm2h_XU&_LWA-qv&zCnd!%S81{Fg%;N=8@A{_{GzS<i^srr*Har$4t%;ZSrl
zZigT{&g_(j)_06WVw&48`d?!_^=&hIp}h@bcQ;x*SxkJVrro=vnbIx4C}7sNZ0oXi
ziCVg@CU(^ZAK?;{ySuV}{?z>aQPzz=BLBF>Q^P|%BeNnwjwq79i}r|@D4J&`6WOqN
zeY4<!j<3najE8lWc^zKTUAUJkPaZJ{Oxrm`Ib~p~;<{=3-Ah?z$7<|zmv&b2Nf~;(
zE&o{nFY~wx^TI-QHNX4d&DOORr$TP%I>?>G@M^Cmc%VrU_17)(9zUH(3Np8iJ<QNg
zjtXO3WgK-qqNGeA<M!(kG|Cp+II9VLc61G`FE}|`opun*=a`2w<E2~VN#3=qa}lBT
z@L2m__C9*G^!~a{`X&Rup{3UzmkE`&Q0{n-H41sPW)uVn>wT-!F6ng7(=exsw5C*3
z$^`UBU)w+AjcY3CzPctu1(Qyh&@|3*@)ERG>GdpMP7qb49B)w7x`l3AJg7h}x;0XH
zOs6_OLo-O7?~z)8VTm_**C=p9U)bW;@Ae%!8vjrG)&fz`lo;@0df-oa--Bn=Is4xK
z#g*H=;%p+BqtiVPugD@`558mx$YcUuh-p4BSDQ-0sDU59vNdxwQMcM|u4!j8JDY#`
z79(TupPA21fk;WyiB1KNgrKIg*_v#(GB<N@)UY*&3Ct{@fB#6}p}wia6#f-_&2*gQ
zlmoc!%*atam1DA2Ic8)wz+_@dy$4^;Ft?owMKA}DuGms^0}RO3V3O5j<p=L{sucJs
z8^AUaDTo4G|H-y^p8#;|lIiu&vfqP0mJg5G#dTnXqW~I(8ElP}=u~+i$0dAn(F3Es
z?f;D^0K6yQCC}o5cRDozv_2a&7Wgp`N%#Zvl~q~MQ%4W9Ry)|Dne020R63OmIu9ox
zmT(XsOblWPfD4jWAb~=`fk@?q09GIbxctr6&|AboC&2;9O|!}`0Gx9<$pL<7m`QMu
zH*k#h@kHEDV1*sox$ABN7DgI{lAWbM7UrnHzQV((xPp9uX#g*#oi!_g`T?V!LxH)g
z4_W>2B@A%#i?(d?zypHcFT)lO%(98W6yOD8?n5M)czS{wx5WqGz2>X%<bIl37^v_V
zP~o%tqSpqt0v3UI5C+u=xJz1+{0TS`$uF49zG^Z&b##kCClL}up;TA}2k&&MD)^R7
z)l8zNf~_&f5qs{}Zi(ItfYS+Ha<jN=K$l^|wPN)__B?%}NVhW>9Wh`BayD<VHhW$G
zB?wO>&NpQEt}Go42UWTnwA<_|%>>Wwvn$^e4><WSxu)I(Pe1lWt@tKfMhCO6G2qI~
z`sjFLPH6VDkJScaBv8;zU@iikbvn_hrcP{WIFi@A9f=gMdL@Ggh1w6MFuiFMv$cm@
z*uv~U;1?4Lh2ZZ2qUtK(NS=5i7R(KSJ|4k{**iRXrL5b##lTdw8;oG)ZZRv-sS~>v
zR$*TaG$<A@!gRv3Wx~s`S&@O^62p--5jx=@Tl!T02Maqm&L)h8BNrm*{XU$~v*Q@T
zR5)l4Lj65(dKtqhgbxg40zfbOk(g@*R-#kaQsw~XU&(O7GGq2kCgwH%0Km=|X3S%O
zaAr7y4=X#JnmRW#D~QVc%WfDCM`c0q(jjxo#=>)R%LWU<(G(D&=EHM@W|V)P*a|Qn
z4hw+b3E`aZ&|L|Ph28KG?7aw1*qPfsFcbDhMwm-!oR~lMl;&Nk!8XJQb&MP8{HDZk
z@nIuXL@4_N7sa1zs|pLiwv~uL@+mF^IG9+%O0bI^qVyq&3ni{R?O;vVhz!xpO5sA2
zlPwu61)H)UQWF_mNO7=eft6tY3q<K_78gpBqs4@+8wM-|y9^*w-*dT^0`m)V`kpo(
zghk+^+la`DLas$7$LkDZ8(0NCBaEmlJIA%k<f%#a>jn5ACL*xp{QoJiP>sQd;1H>C
zumXmzaWkg(sYz|Yx`GcxA$*%sF8G{}N5KsPpCLiSqRSQ*W8W6=(*p?eRqY(+kLsBF
zECF0j_>T|>v%g_sCZ}r@ymgC^g`4J*x!=fzKLNa*i0Hg+o}&Y=W@mJx1uo<878fG(
z+vDkl-FzEfaG9BzS*t|m?iMT2se)iLW5(_odEUJ)I~zW5%Y{PefPe47&D?g75rz66
D613UA

diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index da9702f9e7..e411586a54 100755
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
index 2fe81a7d95..1aa94a4269 100755
--- a/gradlew
+++ b/gradlew
@@ -1,7 +1,7 @@
-#!/usr/bin/env sh
+#!/bin/sh
 
 #
-# Copyright 2015 the original author or authors.
+# Copyright © 2015-2021 the original authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -17,78 +17,111 @@
 #
 
 ##############################################################################
-##
-##  Gradle start up script for UN*X
-##
+#
+#   Gradle start up script for POSIX generated by Gradle.
+#
+#   Important for running:
+#
+#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+#       noncompliant, but you have some other compliant shell such as ksh or
+#       bash, then to run this script, type that shell name before the whole
+#       command line, like:
+#
+#           ksh Gradle
+#
+#       Busybox and similar reduced shells will NOT work, because this script
+#       requires all of these POSIX shell features:
+#         * functions;
+#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+#         * compound commands having a testable exit status, especially «case»;
+#         * various built-in commands including «command», «set», and «ulimit».
+#
+#   Important for patching:
+#
+#   (2) This script targets any POSIX shell, so it avoids extensions provided
+#       by Bash, Ksh, etc; in particular arrays are avoided.
+#
+#       The "traditional" practice of packing multiple parameters into a
+#       space-separated string is a well documented source of bugs and security
+#       problems, so this is (mostly) avoided, by progressively accumulating
+#       options in "$@", and eventually passing that to Java.
+#
+#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+#       see the in-line comments for details.
+#
+#       There are tweaks for specific operating systems such as AIX, CygWin,
+#       Darwin, MinGW, and NonStop.
+#
+#   (3) This script is generated from the Groovy template
+#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+#       within the Gradle project.
+#
+#       You can find Gradle at https://github.com/gradle/gradle/.
+#
 ##############################################################################
 
 # Attempt to set APP_HOME
+
 # Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
-    ls=`ls -ld "$PRG"`
-    link=`expr "$ls" : '.*-> \(.*\)$'`
-    if expr "$link" : '/.*' > /dev/null; then
-        PRG="$link"
-    else
-        PRG=`dirname "$PRG"`"/$link"
-    fi
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+    APP_HOME=${app_path%"${app_path##*/}"}  # leaves a trailing /; empty if no leading path
+    [ -h "$app_path" ]
+do
+    ls=$( ls -ld "$app_path" )
+    link=${ls#*' -> '}
+    case $link in             #(
+      /*)   app_path=$link ;; #(
+      *)    app_path=$APP_HOME$link ;;
+    esac
 done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >/dev/null
-APP_HOME="`pwd -P`"
-cd "$SAVED" >/dev/null
 
-APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=${0##*/}
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
 
 # Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
+MAX_FD=maximum
 
 warn () {
     echo "$*"
-}
+} >&2
 
 die () {
     echo
     echo "$*"
     echo
     exit 1
-}
+} >&2
 
 # OS specific support (must be 'true' or 'false').
 cygwin=false
 msys=false
 darwin=false
 nonstop=false
-case "`uname`" in
-  CYGWIN* )
-    cygwin=true
-    ;;
-  Darwin* )
-    darwin=true
-    ;;
-  MINGW* )
-    msys=true
-    ;;
-  NONSTOP* )
-    nonstop=true
-    ;;
+case "$( uname )" in                #(
+  CYGWIN* )         cygwin=true  ;; #(
+  Darwin* )         darwin=true  ;; #(
+  MSYS* | MINGW* )  msys=true    ;; #(
+  NONSTOP* )        nonstop=true ;;
 esac
 
 CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
 
+
 # Determine the Java command to use to start the JVM.
 if [ -n "$JAVA_HOME" ] ; then
     if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
         # IBM's JDK on AIX uses strange locations for the executables
-        JAVACMD="$JAVA_HOME/jre/sh/java"
+        JAVACMD=$JAVA_HOME/jre/sh/java
     else
-        JAVACMD="$JAVA_HOME/bin/java"
+        JAVACMD=$JAVA_HOME/bin/java
     fi
     if [ ! -x "$JAVACMD" ] ; then
         die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -97,87 +130,120 @@ Please set the JAVA_HOME variable in your environment to match the
 location of your Java installation."
     fi
 else
-    JAVACMD="java"
-    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+    JAVACMD=java
+    if ! command -v java >/dev/null 2>&1
+    then
+        die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
 
 Please set the JAVA_HOME variable in your environment to match the
 location of your Java installation."
+    fi
 fi
 
 # Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
-    MAX_FD_LIMIT=`ulimit -H -n`
-    if [ $? -eq 0 ] ; then
-        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
-            MAX_FD="$MAX_FD_LIMIT"
-        fi
-        ulimit -n $MAX_FD
-        if [ $? -ne 0 ] ; then
-            warn "Could not set maximum file descriptor limit: $MAX_FD"
-        fi
-    else
-        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
-    fi
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+    case $MAX_FD in #(
+      max*)
+        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+        # shellcheck disable=SC2039,SC3045
+        MAX_FD=$( ulimit -H -n ) ||
+            warn "Could not query maximum file descriptor limit"
+    esac
+    case $MAX_FD in  #(
+      '' | soft) :;; #(
+      *)
+        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+        # shellcheck disable=SC2039,SC3045
+        ulimit -n "$MAX_FD" ||
+            warn "Could not set maximum file descriptor limit to $MAX_FD"
+    esac
 fi
 
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
-    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
+# Collect all arguments for the java command, stacking in reverse order:
+#   * args from the command line
+#   * the main class name
+#   * -classpath
+#   * -D...appname settings
+#   * --module-path (only if needed)
+#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
 
 # For Cygwin or MSYS, switch paths to Windows format before running java
-if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
-    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
-    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
-    JAVACMD=`cygpath --unix "$JAVACMD"`
-
-    # We build the pattern for arguments to be converted via cygpath
-    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
-    SEP=""
-    for dir in $ROOTDIRSRAW ; do
-        ROOTDIRS="$ROOTDIRS$SEP$dir"
-        SEP="|"
-    done
-    OURCYGPATTERN="(^($ROOTDIRS))"
-    # Add a user-defined pattern to the cygpath arguments
-    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
-        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
-    fi
+if "$cygwin" || "$msys" ; then
+    APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+    CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+    JAVACMD=$( cygpath --unix "$JAVACMD" )
+
     # Now convert the arguments - kludge to limit ourselves to /bin/sh
-    i=0
-    for arg in "$@" ; do
-        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
-        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
-
-        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
-            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
-        else
-            eval `echo args$i`="\"$arg\""
+    for arg do
+        if
+            case $arg in                                #(
+              -*)   false ;;                            # don't mess with options #(
+              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath
+                    [ -e "$t" ] ;;                      #(
+              *)    false ;;
+            esac
+        then
+            arg=$( cygpath --path --ignore --mixed "$arg" )
         fi
-        i=`expr $i + 1`
+        # Roll the args list around exactly as many times as the number of
+        # args, so each arg winds up back in the position where it started, but
+        # possibly modified.
+        #
+        # NB: a `for` loop captures its iteration list before it begins, so
+        # changing the positional parameters here affects neither the number of
+        # iterations, nor the values presented in `arg`.
+        shift                   # remove old arg
+        set -- "$@" "$arg"      # push replacement arg
     done
-    case $i in
-        0) set -- ;;
-        1) set -- "$args0" ;;
-        2) set -- "$args0" "$args1" ;;
-        3) set -- "$args0" "$args1" "$args2" ;;
-        4) set -- "$args0" "$args1" "$args2" "$args3" ;;
-        5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
-        6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
-        7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
-        8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
-        9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
-    esac
 fi
 
-# Escape application args
-save () {
-    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
-    echo " "
-}
-APP_ARGS=`save "$@"`
 
-# Collect all arguments for the java command, following the shell quoting and substitution rules
-eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command:
+#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+#     and any embedded shellness will be escaped.
+#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+#     treated as '${Hostname}' itself on the command line.
+
+set -- \
+        "-Dorg.gradle.appname=$APP_BASE_NAME" \
+        -classpath "$CLASSPATH" \
+        org.gradle.wrapper.GradleWrapperMain \
+        "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+    die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+#   readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+#   set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+        printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+        xargs -n1 |
+        sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+        tr '\n' ' '
+    )" '"$@"'
 
 exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
index 24467a141f..6689b85bee 100755
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -14,7 +14,7 @@
 @rem limitations under the License.
 @rem
 
-@if "%DEBUG%" == "" @echo off
+@if "%DEBUG%"=="" @echo off
 @rem ##########################################################################
 @rem
 @rem  Gradle startup script for Windows
@@ -25,10 +25,14 @@
 if "%OS%"=="Windows_NT" setlocal
 
 set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
+if "%DIRNAME%"=="" set DIRNAME=.
+@rem This is normally unused
 set APP_BASE_NAME=%~n0
 set APP_HOME=%DIRNAME%
 
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
 @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
 set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
 
@@ -37,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
 
 set JAVA_EXE=java.exe
 %JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
+if %ERRORLEVEL% equ 0 goto execute
 
 echo.
 echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -51,7 +55,7 @@ goto fail
 set JAVA_HOME=%JAVA_HOME:"=%
 set JAVA_EXE=%JAVA_HOME%/bin/java.exe
 
-if exist "%JAVA_EXE%" goto init
+if exist "%JAVA_EXE%" goto execute
 
 echo.
 echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -61,38 +65,26 @@ echo location of your Java installation.
 
 goto fail
 
-:init
-@rem Get command-line arguments, handling Windows variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-
 :execute
 @rem Setup the command line
 
 set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
 
+
 @rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
 
 :end
 @rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
+if %ERRORLEVEL% equ 0 goto mainEnd
 
 :fail
 rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
 rem the _cmd.exe /c_ return code!
-if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
 
 :mainEnd
 if "%OS%"=="Windows_NT" endlocal
diff --git a/postman/RpCollection.postman_collection.json b/postman/RpCollection.postman_collection.json
index 5023bf3054..6c93e416ec 100644
--- a/postman/RpCollection.postman_collection.json
+++ b/postman/RpCollection.postman_collection.json
@@ -1,403 +1,403 @@
 {
-	"info": {
-		"_postman_id": "318614d6-a5b9-4a7a-b040-e35f253ba572",
-		"name": "RpCollection",
-		"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
-	},
-	"item": [
-		{
-			"name": "API Info",
-			"event": [
-				{
-					"listen": "test",
-					"script": {
-						"id": "2464c641-2864-4fb4-a92b-4744f3b77617",
-						"exec": [
-							"pm.test(\"Validate Status\", function (){",
-							"    pm.response.to.have.status(200);",
-							"});",
-							"",
-							"pm.test(\"Validate Build Version\", function(){",
-							"    var jsonData = pm.response.json();",
-							"    pm.expect(jsonData.build.version).to.eql(pm.environment.get(\"build\"))",
-							"});",
-							"",
-							"pm.test(\"Validate Metadate Activity Action\", function(){",
-							"    var jsonData = pm.response.json();",
-							"    var activityActions = [\"createDashboard\",",
-							"            \"updateDashboard\",",
-							"            \"deleteDashboard\",",
-							"            \"createWidget\",",
-							"            \"updateWidget\",",
-							"            \"deleteWidget\",",
-							"            \"createFilter\",",
-							"            \"updateFilter\",",
-							"            \"deleteFilter\",",
-							"            \"analyzeItem\",",
-							"            \"createDefect\",",
-							"            \"updateDefect\",",
-							"            \"deleteDefect\",",
-							"            \"createIntegration\",",
-							"            \"updateIntegration\",",
-							"            \"deleteIntegration\",",
-							"            \"startLaunch\",",
-							"            \"finishLaunch\",",
-							"            \"deleteLaunch\",",
-							"            \"updateProject\",",
-							"            \"updateAnalyzer\",",
-							"            \"postIssue\",",
-							"            \"linkIssue\",",
-							"            \"linkIssueAa\",",
-							"            \"unlinkIssue\",",
-							"            \"updateItem\",",
-							"            \"createUser\",",
-							"            \"deleteIndex\",",
-							"            \"generateIndex\",",
-							"            \"startImport\",",
-							"            \"finishImport\",",
-							"            \"createPattern\",",
-							"            \"updatePattern\",",
-							"            \"deletePattern\",",
-							"            \"patternMatched\"];",
-							"    pm.expect(jsonData.metadata.activityAction.length).to.eql(activityActions.length);",
-							"",
-							"});",
-							"",
-							"pm.test(\"Validate Activity Entity Type\", function(){",
-							"    var jsonData = pm.response.json();",
-							"     var activityActions = [\"launch\",",
-							"            \"item\",",
-							"            \"dashboard\",",
-							"            \"defectType\",",
-							"            \"emailConfig\",",
-							"            \"filter\",",
-							"            \"import\",",
-							"            \"integration\",",
-							"            \"itemIssue\",",
-							"            \"project\",",
-							"            \"sharing\",",
-							"            \"ticket\",",
-							"            \"user\",",
-							"            \"widget\",",
-							"            \"pattern\"];",
-							"    pm.expect(jsonData.metadata.activityEntityType.length).to.eql(activityActions.length);",
-							"",
-							"});"
-						],
-						"type": "text/javascript"
-					}
-				}
-			],
-			"request": {
-				"method": "GET",
-				"header": [
-					{
-						"key": "Authorization",
-						"value": "bearer 78afb592-b4e3-401c-8097-f45d7489898f",
-						"type": "text",
-						"disabled": true
-					},
-					{
-						"key": "Accept",
-						"value": "application/json",
-						"type": "text",
-						"disabled": true
-					}
-				],
-				"url": {
-					"raw": "{{host}}/api/info",
-					"host": [
-						"{{host}}"
-					],
-					"path": [
-						"api",
-						"info"
-					]
-				}
-			},
-			"response": []
-		},
-		{
-			"name": "API Health",
-			"event": [
-				{
-					"listen": "test",
-					"script": {
-						"id": "fe96f91f-1539-45a0-8e08-c11dc784ad65",
-						"exec": [
-							"pm.test(\"Validate Status\", function (){",
-							"    pm.response.to.have.status(200);",
-							"});",
-							"",
-							"pm.test(\"Validate Health\", function(){",
-							"    var jsonData = pm.response.json();",
-							"    pm.expect(jsonData.status).to.eql(\"UP\")",
-							"});"
-						],
-						"type": "text/javascript"
-					}
-				}
-			],
-			"request": {
-				"method": "GET",
-				"header": [],
-				"url": {
-					"raw": "{{host}}/api/health",
-					"host": [
-						"{{host}}"
-					],
-					"path": [
-						"api",
-						"health"
-					]
-				}
-			},
-			"response": []
-		},
-		{
-			"name": "UAT Info",
-			"event": [
-				{
-					"listen": "test",
-					"script": {
-						"id": "b1730e92-c7c7-4e73-8fe4-b3fbc92b2f9c",
-						"exec": [
-							"pm.test(\"Validate Status\", function (){",
-							"    pm.response.to.have.status(200);",
-							"});",
-							"",
-							"pm.test(\"Validate Build Version\", function(){",
-							"    var jsonData = pm.response.json();",
-							"    pm.expect(jsonData.build.version).to.eql(\"5.0\")",
-							"});",
-							"",
-							"pm.test(\"Validate Project Roles\", function(){",
-							"    var jsonData = pm.response.json();",
-							"    var prRoles = [\"OPERATOR\", \"CUSTOMER\", \"MEMBER\", \"PROJECT_MANAGER\"];",
-							"    pm.expect(jsonData.metadata.project_roles.length).to.eql(prRoles.length);",
-							"});"
-						],
-						"type": "text/javascript"
-					}
-				}
-			],
-			"request": {
-				"method": "GET",
-				"header": [],
-				"url": {
-					"raw": "{{host}}/uat/info",
-					"host": [
-						"{{host}}"
-					],
-					"path": [
-						"uat",
-						"info"
-					]
-				}
-			},
-			"response": []
-		},
-		{
-			"name": "UAT Health",
-			"event": [
-				{
-					"listen": "test",
-					"script": {
-						"id": "d6803e52-8276-423b-941f-e0334b6364c8",
-						"exec": [
-							"pm.test(\"Validate Status\", function (){",
-							"    pm.response.to.have.status(200);",
-							"});",
-							"",
-							"pm.test(\"Validate Health\", function(){",
-							"    var jsonData = pm.response.json();",
-							"    pm.expect(jsonData.status).to.eql(\"UP\")",
-							"});"
-						],
-						"type": "text/javascript"
-					}
-				}
-			],
-			"request": {
-				"method": "GET",
-				"header": [],
-				"url": {
-					"raw": "{{host}}/uat/health",
-					"host": [
-						"{{host}}"
-					],
-					"path": [
-						"uat",
-						"health"
-					]
-				}
-			},
-			"response": []
-		},
-		{
-			"name": "{{host}}/uat/sso/oauth/token",
-			"event": [
-				{
-					"listen": "test",
-					"script": {
-						"id": "d338cddf-0851-4d2b-b414-9147a109cf31",
-						"exec": [
-							"pm.test(\"Validate Status\", function (){",
-							"    pm.response.to.have.status(200);",
-							"});",
-							"",
-							"pm.test(\"Validate Access Token Value\", function(){",
-							"    var jsonData = pm.response.json();",
-							"    pm.expect(jsonData.access_token).not.eql(\"\")",
-							"});",
-							"",
-							"pm.test(\"Validate Token Type\", function(){",
-							"    var jsonData = pm.response.json();",
-							"    pm.expect(jsonData.token_type).to.eql(\"bearer\")",
-							"});",
-							"",
-							"pm.test(\"Validate Refresh Token Value\", function(){",
-							"    var jsonData = pm.response.json();",
-							"    pm.expect(jsonData.refresh_token).not.eql(\"\")",
-							"});",
-							"",
-							"pm.test(\"Validate Refresh Token Value\", function(){",
-							"    var jsonData = pm.response.json();",
-							"    pm.expect(jsonData.refresh_token).not.eql(\"\")",
-							"});"
-						],
-						"type": "text/javascript"
-					}
-				}
-			],
-			"request": {
-				"auth": {
-					"type": "noauth"
-				},
-				"method": "POST",
-				"header": [
-					{
-						"key": "Authorization",
-						"value": "{{Authorization}}",
-						"type": "text"
-					}
-				],
-				"body": {
-					"mode": "formdata",
-					"formdata": [
-						{
-							"key": "grant_type",
-							"value": "{{grant_type}}",
-							"type": "text"
-						},
-						{
-							"key": "username",
-							"value": "{{username}}",
-							"type": "text"
-						},
-						{
-							"key": "password",
-							"value": "{{password}}",
-							"type": "text"
-						}
-					]
-				},
-				"url": {
-					"raw": "{{host}}/uat/sso/oauth/token",
-					"host": [
-						"{{host}}"
-					],
-					"path": [
-						"uat",
-						"sso",
-						"oauth",
-						"token"
-					]
-				}
-			},
-			"response": []
-		},
-		{
-			"name": "{{host}}/user/default",
-			"event": [
-				{
-					"listen": "prerequest",
-					"script": {
-						"id": "a1315561-d45a-4879-b0a2-6cc2f07bb86a",
-						"exec": [
-							"pm.sendRequest({\r",
-							"    url: pm.environment.get(\"host\") + '/uat/sso/oauth/token',\r",
-							"    method: 'POST',\r",
-							"    header: {\r",
-							"        'Authorization':  pm.environment.get(\"Authorization\"),\r",
-							"        'Content-Type': 'multpart/form-data'\r",
-							"     },\r",
-							"    body: {\r",
-							"          mode: 'formdata',\r",
-							"          formdata: [\r",
-							"            {key: \"grant_type\", value:pm.environment.get(\"grant_type\")},\r",
-							"            {key: \"username\", value:pm.environment.get(\"username\")},\r",
-							"            {key: \"password\", value:pm.environment.get(\"password\")}\r",
-							"        ]\r",
-							"    }\r",
-							"},\r",
-							"function (err, res) {\r",
-							"    pm.environment.set(\"token\", res.json().access_token);\r",
-							"});"
-						],
-						"type": "text/javascript"
-					}
-				},
-				{
-					"listen": "test",
-					"script": {
-						"id": "f2a5311a-87cb-4b81-bb35-379713824833",
-						"exec": [
-							"pm.test(\"Validate Status\", function (){",
-							"    pm.response.to.have.status(200);",
-							"});",
-							"",
-							"pm.test(\"Validate UserId\", function(){",
-							"    var jsonData = pm.response.json();",
-							"    pm.expect(jsonData.userId).to.eql(\"default\")",
-							"});",
-							"",
-							"pm.test(\"Validate Assigned Project: default_personal\", function(){",
-							"    var jsonData = pm.response.json();",
-							"    pm.expect(jsonData.assignedProjects.default_personal).not.eql(\"\")",
-							"});"
-						],
-						"type": "text/javascript"
-					}
-				}
-			],
-			"request": {
-				"auth": {
-					"type": "bearer",
-					"bearer": [
-						{
-							"key": "token",
-							"value": "{{token}}",
-							"type": "string"
-						}
-					]
-				},
-				"method": "GET",
-				"header": [],
-				"url": {
-					"raw": "{{host}}/api/v1/user/default",
-					"host": [
-						"{{host}}"
-					],
-					"path": [
-						"api",
-						"v1",
-						"user",
-						"default"
-					]
-				}
-			},
-			"response": []
-		}
-	]
+  "info": {
+    "_postman_id": "318614d6-a5b9-4a7a-b040-e35f253ba572",
+    "name": "RpCollection",
+    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
+  },
+  "item": [
+    {
+      "name": "API Info",
+      "event": [
+        {
+          "listen": "test",
+          "script": {
+            "id": "2464c641-2864-4fb4-a92b-4744f3b77617",
+            "exec": [
+              "pm.test(\"Validate Status\", function (){",
+              "    pm.response.to.have.status(200);",
+              "});",
+              "",
+              "pm.test(\"Validate Build Version\", function(){",
+              "    var jsonData = pm.response.json();",
+              "    pm.expect(jsonData.build.version).to.eql(pm.environment.get(\"build\"))",
+              "});",
+              "",
+              "pm.test(\"Validate Metadate Activity Action\", function(){",
+              "    var jsonData = pm.response.json();",
+              "    var activityActions = [\"createDashboard\",",
+              "            \"updateDashboard\",",
+              "            \"deleteDashboard\",",
+              "            \"createWidget\",",
+              "            \"updateWidget\",",
+              "            \"deleteWidget\",",
+              "            \"createFilter\",",
+              "            \"updateFilter\",",
+              "            \"deleteFilter\",",
+              "            \"analyzeItem\",",
+              "            \"createDefect\",",
+              "            \"updateDefect\",",
+              "            \"deleteDefect\",",
+              "            \"createIntegration\",",
+              "            \"updateIntegration\",",
+              "            \"deleteIntegration\",",
+              "            \"startLaunch\",",
+              "            \"finishLaunch\",",
+              "            \"deleteLaunch\",",
+              "            \"updateProject\",",
+              "            \"updateAnalyzer\",",
+              "            \"postIssue\",",
+              "            \"linkIssue\",",
+              "            \"linkIssueAa\",",
+              "            \"unlinkIssue\",",
+              "            \"updateItem\",",
+              "            \"createUser\",",
+              "            \"deleteIndex\",",
+              "            \"generateIndex\",",
+              "            \"startImport\",",
+              "            \"finishImport\",",
+              "            \"createPattern\",",
+              "            \"updatePattern\",",
+              "            \"deletePattern\",",
+              "            \"patternMatched\"];",
+              "    pm.expect(jsonData.metadata.activityAction.length).to.eql(activityActions.length);",
+              "",
+              "});",
+              "",
+              "pm.test(\"Validate Activity Entity Type\", function(){",
+              "    var jsonData = pm.response.json();",
+              "     var activityActions = [\"launch\",",
+              "            \"item\",",
+              "            \"dashboard\",",
+              "            \"defectType\",",
+              "            \"emailConfig\",",
+              "            \"filter\",",
+              "            \"import\",",
+              "            \"integration\",",
+              "            \"itemIssue\",",
+              "            \"project\",",
+              "            \"sharing\",",
+              "            \"ticket\",",
+              "            \"user\",",
+              "            \"widget\",",
+              "            \"pattern\"];",
+              "    pm.expect(jsonData.metadata.activityEntityType.length).to.eql(activityActions.length);",
+              "",
+              "});"
+            ],
+            "type": "text/javascript"
+          }
+        }
+      ],
+      "request": {
+        "method": "GET",
+        "header": [
+          {
+            "key": "Authorization",
+            "value": "bearer 78afb592-b4e3-401c-8097-f45d7489898f",
+            "type": "text",
+            "disabled": true
+          },
+          {
+            "key": "Accept",
+            "value": "application/json",
+            "type": "text",
+            "disabled": true
+          }
+        ],
+        "url": {
+          "raw": "{{host}}/api/info",
+          "host": [
+            "{{host}}"
+          ],
+          "path": [
+            "api",
+            "info"
+          ]
+        }
+      },
+      "response": []
+    },
+    {
+      "name": "API Health",
+      "event": [
+        {
+          "listen": "test",
+          "script": {
+            "id": "fe96f91f-1539-45a0-8e08-c11dc784ad65",
+            "exec": [
+              "pm.test(\"Validate Status\", function (){",
+              "    pm.response.to.have.status(200);",
+              "});",
+              "",
+              "pm.test(\"Validate Health\", function(){",
+              "    var jsonData = pm.response.json();",
+              "    pm.expect(jsonData.status).to.eql(\"UP\")",
+              "});"
+            ],
+            "type": "text/javascript"
+          }
+        }
+      ],
+      "request": {
+        "method": "GET",
+        "header": [],
+        "url": {
+          "raw": "{{host}}/api/health",
+          "host": [
+            "{{host}}"
+          ],
+          "path": [
+            "api",
+            "health"
+          ]
+        }
+      },
+      "response": []
+    },
+    {
+      "name": "UAT Info",
+      "event": [
+        {
+          "listen": "test",
+          "script": {
+            "id": "b1730e92-c7c7-4e73-8fe4-b3fbc92b2f9c",
+            "exec": [
+              "pm.test(\"Validate Status\", function (){",
+              "    pm.response.to.have.status(200);",
+              "});",
+              "",
+              "pm.test(\"Validate Build Version\", function(){",
+              "    var jsonData = pm.response.json();",
+              "    pm.expect(jsonData.build.version).to.eql(\"5.0\")",
+              "});",
+              "",
+              "pm.test(\"Validate Project Roles\", function(){",
+              "    var jsonData = pm.response.json();",
+              "    var prRoles = [\"OPERATOR\", \"CUSTOMER\", \"MEMBER\", \"PROJECT_MANAGER\"];",
+              "    pm.expect(jsonData.metadata.project_roles.length).to.eql(prRoles.length);",
+              "});"
+            ],
+            "type": "text/javascript"
+          }
+        }
+      ],
+      "request": {
+        "method": "GET",
+        "header": [],
+        "url": {
+          "raw": "{{host}}/uat/info",
+          "host": [
+            "{{host}}"
+          ],
+          "path": [
+            "uat",
+            "info"
+          ]
+        }
+      },
+      "response": []
+    },
+    {
+      "name": "UAT Health",
+      "event": [
+        {
+          "listen": "test",
+          "script": {
+            "id": "d6803e52-8276-423b-941f-e0334b6364c8",
+            "exec": [
+              "pm.test(\"Validate Status\", function (){",
+              "    pm.response.to.have.status(200);",
+              "});",
+              "",
+              "pm.test(\"Validate Health\", function(){",
+              "    var jsonData = pm.response.json();",
+              "    pm.expect(jsonData.status).to.eql(\"UP\")",
+              "});"
+            ],
+            "type": "text/javascript"
+          }
+        }
+      ],
+      "request": {
+        "method": "GET",
+        "header": [],
+        "url": {
+          "raw": "{{host}}/uat/health",
+          "host": [
+            "{{host}}"
+          ],
+          "path": [
+            "uat",
+            "health"
+          ]
+        }
+      },
+      "response": []
+    },
+    {
+      "name": "{{host}}/uat/sso/oauth/token",
+      "event": [
+        {
+          "listen": "test",
+          "script": {
+            "id": "d338cddf-0851-4d2b-b414-9147a109cf31",
+            "exec": [
+              "pm.test(\"Validate Status\", function (){",
+              "    pm.response.to.have.status(200);",
+              "});",
+              "",
+              "pm.test(\"Validate Access Token Value\", function(){",
+              "    var jsonData = pm.response.json();",
+              "    pm.expect(jsonData.access_token).not.eql(\"\")",
+              "});",
+              "",
+              "pm.test(\"Validate Token Type\", function(){",
+              "    var jsonData = pm.response.json();",
+              "    pm.expect(jsonData.token_type).to.eql(\"bearer\")",
+              "});",
+              "",
+              "pm.test(\"Validate Refresh Token Value\", function(){",
+              "    var jsonData = pm.response.json();",
+              "    pm.expect(jsonData.refresh_token).not.eql(\"\")",
+              "});",
+              "",
+              "pm.test(\"Validate Refresh Token Value\", function(){",
+              "    var jsonData = pm.response.json();",
+              "    pm.expect(jsonData.refresh_token).not.eql(\"\")",
+              "});"
+            ],
+            "type": "text/javascript"
+          }
+        }
+      ],
+      "request": {
+        "auth": {
+          "type": "noauth"
+        },
+        "method": "POST",
+        "header": [
+          {
+            "key": "Authorization",
+            "value": "{{Authorization}}",
+            "type": "text"
+          }
+        ],
+        "body": {
+          "mode": "formdata",
+          "formdata": [
+            {
+              "key": "grant_type",
+              "value": "{{grant_type}}",
+              "type": "text"
+            },
+            {
+              "key": "username",
+              "value": "{{username}}",
+              "type": "text"
+            },
+            {
+              "key": "password",
+              "value": "{{password}}",
+              "type": "text"
+            }
+          ]
+        },
+        "url": {
+          "raw": "{{host}}/uat/sso/oauth/token",
+          "host": [
+            "{{host}}"
+          ],
+          "path": [
+            "uat",
+            "sso",
+            "oauth",
+            "token"
+          ]
+        }
+      },
+      "response": []
+    },
+    {
+      "name": "{{host}}/user/default",
+      "event": [
+        {
+          "listen": "prerequest",
+          "script": {
+            "id": "a1315561-d45a-4879-b0a2-6cc2f07bb86a",
+            "exec": [
+              "pm.sendRequest({\r",
+              "    url: pm.environment.get(\"host\") + '/uat/sso/oauth/token',\r",
+              "    method: 'POST',\r",
+              "    header: {\r",
+              "        'Authorization':  pm.environment.get(\"Authorization\"),\r",
+              "        'Content-Type': 'multpart/form-data'\r",
+              "     },\r",
+              "    body: {\r",
+              "          mode: 'formdata',\r",
+              "          formdata: [\r",
+              "            {key: \"grant_type\", value:pm.environment.get(\"grant_type\")},\r",
+              "            {key: \"username\", value:pm.environment.get(\"username\")},\r",
+              "            {key: \"password\", value:pm.environment.get(\"password\")}\r",
+              "        ]\r",
+              "    }\r",
+              "},\r",
+              "function (err, res) {\r",
+              "    pm.environment.set(\"token\", res.json().access_token);\r",
+              "});"
+            ],
+            "type": "text/javascript"
+          }
+        },
+        {
+          "listen": "test",
+          "script": {
+            "id": "f2a5311a-87cb-4b81-bb35-379713824833",
+            "exec": [
+              "pm.test(\"Validate Status\", function (){",
+              "    pm.response.to.have.status(200);",
+              "});",
+              "",
+              "pm.test(\"Validate UserId\", function(){",
+              "    var jsonData = pm.response.json();",
+              "    pm.expect(jsonData.userId).to.eql(\"default\")",
+              "});",
+              "",
+              "pm.test(\"Validate Assigned Project: default_personal\", function(){",
+              "    var jsonData = pm.response.json();",
+              "    pm.expect(jsonData.assignedProjects.default_personal).not.eql(\"\")",
+              "});"
+            ],
+            "type": "text/javascript"
+          }
+        }
+      ],
+      "request": {
+        "auth": {
+          "type": "bearer",
+          "bearer": [
+            {
+              "key": "token",
+              "value": "{{token}}",
+              "type": "string"
+            }
+          ]
+        },
+        "method": "GET",
+        "header": [],
+        "url": {
+          "raw": "{{host}}/api/v1/user/default",
+          "host": [
+            "{{host}}"
+          ],
+          "path": [
+            "api",
+            "v1",
+            "user",
+            "default"
+          ]
+        }
+      },
+      "response": []
+    }
+  ]
 }
\ No newline at end of file
diff --git a/postman/service-api.postman_collection.json b/postman/service-api.postman_collection.json
index cc37003226..4ab47860a8 100644
--- a/postman/service-api.postman_collection.json
+++ b/postman/service-api.postman_collection.json
@@ -1,48 +1,48 @@
 {
-	"info": {
-		"_postman_id": "1c81a0f3-8beb-4317-8749-0d506c95eac8",
-		"name": "service-api",
-		"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
-	},
-	"item": [
-		{
-			"name": "GET Info",
-			"event": [
-				{
-					"listen": "test",
-					"script": {
-						"id": "3e2613e1-567b-46da-a520-f54f5a7936f7",
-						"exec": [
-							"pm.test(\"Status code is 200\", function () {",
-							"    pm.response.to.have.status(200);",
-							"});",
-							"",
-							"pm.test(\"Build Version is Present\", function () {",
-							"    var jsonData = pm.response.json();",
-							"    pm.expect(jsonData.build.version).to.not.eq(undefined);",
-							"});",
-							"",
-							""
-						],
-						"type": "text/javascript"
-					}
-				}
-			],
-			"request": {
-				"method": "GET",
-				"header": [],
-				"url": {
-					"raw": "{{rp_url}}/api/info",
-					"host": [
-						"{{rp_url}}"
-					],
-					"path": [
-						"api",
-						"info"
-					]
-				}
-			},
-			"response": []
-		}
-	]
+  "info": {
+    "_postman_id": "1c81a0f3-8beb-4317-8749-0d506c95eac8",
+    "name": "service-api",
+    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
+  },
+  "item": [
+    {
+      "name": "GET Info",
+      "event": [
+        {
+          "listen": "test",
+          "script": {
+            "id": "3e2613e1-567b-46da-a520-f54f5a7936f7",
+            "exec": [
+              "pm.test(\"Status code is 200\", function () {",
+              "    pm.response.to.have.status(200);",
+              "});",
+              "",
+              "pm.test(\"Build Version is Present\", function () {",
+              "    var jsonData = pm.response.json();",
+              "    pm.expect(jsonData.build.version).to.not.eq(undefined);",
+              "});",
+              "",
+              ""
+            ],
+            "type": "text/javascript"
+          }
+        }
+      ],
+      "request": {
+        "method": "GET",
+        "header": [],
+        "url": {
+          "raw": "{{rp_url}}/api/info",
+          "host": [
+            "{{rp_url}}"
+          ],
+          "path": [
+            "api",
+            "info"
+          ]
+        }
+      },
+      "response": []
+    }
+  ]
 }
\ No newline at end of file
diff --git a/project-properties.gradle b/project-properties.gradle
index 78d8cc2981..5aa0e51a56 100755
--- a/project-properties.gradle
+++ b/project-properties.gradle
@@ -1,5 +1,3 @@
-sourceCompatibility = JavaVersion.VERSION_11
-targetCompatibility = JavaVersion.VERSION_11
 
 def commonScriptsUrl = 'https://raw.githubusercontent.com/reportportal/gradle-scripts/'
 def migrationsScriptsUrl = 'https://raw.githubusercontent.com/reportportal/migrations/'
@@ -17,8 +15,8 @@ project.ext {
     ]
     isDebugMode = System.getProperty("DEBUG", "false") == "true"
     releaseMode = project.hasProperty("releaseMode")
-    scriptsUrl = commonScriptsUrl + (releaseMode ? '5.10.0' : 'develop')
-    migrationsUrl = migrationsScriptsUrl + (releaseMode ? '5.10.0' : 'develop')
+    scriptsUrl = commonScriptsUrl + (releaseMode ? '5.11.0' : 'develop')
+    migrationsUrl = migrationsScriptsUrl + (releaseMode ? '5.11.0' : 'feature/settings')
     //TODO refactor with archive download
     testScriptsSrc = [
             (migrationsUrl + '/migrations/0_extensions.up.sql')                        : 'V001__extensions.sql',
@@ -65,6 +63,10 @@ project.ext {
             (migrationsUrl + '/migrations/69_replace_activity_table.up.sql')           : 'V069__replace_activity_table.sql',
             (migrationsUrl + '/migrations/71_user_bid_inviting_user_id.up.sql')        : 'V071__user_bid_inviting_user_id.sql',
             (migrationsUrl + '/migrations/72_add_attachment_name.up.sql')              : 'V072__add_attachment_name.sql',
+            (migrationsUrl + '/migrations/73_sender_case_rule_name.up.sql')            : 'V073__sender_case_rule_name.sql',
+            (migrationsUrl + '/migrations/76_user_bid_extension.up.sql')               : 'V076__user_bid_extension.sql',
+            (migrationsUrl + '/migrations/77_email_server_documentation_link.up.sql')  : 'V077__email_server_documentation_link.sql',
+            (migrationsUrl + '/migrations/78_drop_redundant_index.up.sql')             : 'V078__drop_redundant_index.sql',
     ]
     excludeTests = ['**/entity/**',
                     '**/aop/**',
@@ -80,5 +82,5 @@ project.ext {
 }
 
 wrapper {
-    gradleVersion = '6.8'
+    gradleVersion = '8.4'
 }
diff --git a/sealights.gradle b/sealights.gradle
deleted file mode 100755
index f196ae9ea4..0000000000
--- a/sealights.gradle
+++ /dev/null
@@ -1,29 +0,0 @@
-buildscript {
-    repositories {
-        mavenCentral()
-    }
-    dependencies {
-        classpath 'io.sealights.on-premise.agents.plugin:sealights-gradle-plugin:latest.release'
-    }
-}
-
-apply plugin: io.sealights.onpremise.agents.plugin.SealightsPlugin
-
-sealights {
-    buildSessionId = project.properties['sealightsSession']
-    token = project.properties['sealightsToken']
-    createBuildSessionId = false
-
-    filesStorage = "/tmp"
-
-    logEnabled = false
-    logLevel = "off"
-    logToFile = false
-    logToConsole = true
-
-    includeResources = true
-
-    runTestOnly = false
-    testTasks = ["test", "junitPlatformTest", "integrationTest"]
-    sealightsJvmParams = ["sl.junitVersion": "5"]
-}
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/auth/ApiKeyUtils.java b/src/main/java/com/epam/ta/reportportal/auth/ApiKeyUtils.java
index 225f42f7a4..e1b7a73918 100644
--- a/src/main/java/com/epam/ta/reportportal/auth/ApiKeyUtils.java
+++ b/src/main/java/com/epam/ta/reportportal/auth/ApiKeyUtils.java
@@ -34,6 +34,9 @@ private ApiKeyUtils() {
 
   /**
    * Validate token sign
+   *
+   * @param apiKey   User's Api token
+   * @return true if apiKey valid
    */
   public static boolean validateToken(String apiKey) {
     if (isUUID(apiKey) || (apiKey.length() == 27 && Base64.getUrlDecoder().decode(apiKey.getBytes(
diff --git a/src/main/java/com/epam/ta/reportportal/auth/PermissionsRegisterBean.java b/src/main/java/com/epam/ta/reportportal/auth/PermissionsRegisterBean.java
index 731970dd0f..1792d1f368 100644
--- a/src/main/java/com/epam/ta/reportportal/auth/PermissionsRegisterBean.java
+++ b/src/main/java/com/epam/ta/reportportal/auth/PermissionsRegisterBean.java
@@ -18,39 +18,42 @@
 
 import com.epam.ta.reportportal.auth.permissions.LookupPermission;
 import com.epam.ta.reportportal.auth.permissions.Permission;
+import java.util.Arrays;
+import java.util.Map;
 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
 import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
 import org.springframework.beans.factory.support.BeanDefinitionRegistry;
 import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
 
-import java.util.Arrays;
-import java.util.Map;
-
 public class PermissionsRegisterBean implements BeanDefinitionRegistryPostProcessor {
 
-	@SuppressWarnings("unchecked")
-	@Override
-	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
-		Map<String, Permission> permissionsMap = beanFactory.getBean("permissionsMap", Map.class);
-		beanFactory.getBeansOfType(Permission.class).entrySet().forEach(permission -> {
-			/*
-			 * There will be no NPE since we asked bean factory to get beans
-			 * with this annotation
-			 */
-			Arrays.stream(permission.getValue().getClass().getAnnotation(LookupPermission.class).value()).forEach(permissionName -> {
-				/*
-				 * TODO add check for type before doing this
-				 */
-				Permission permissionBean = permission.getValue();
-				beanFactory.autowireBeanProperties(permissionBean, AutowireCapableBeanFactory.AUTOWIRE_NO, true);
-				permissionsMap.put(permissionName, permissionBean);
-			});
-		});
-	}
+  @SuppressWarnings("unchecked")
+  @Override
+  public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
+      throws BeansException {
+    Map<String, Permission> permissionsMap = beanFactory.getBean("permissionsMap", Map.class);
+    beanFactory.getBeansOfType(Permission.class).entrySet().forEach(permission -> {
+      /*
+       * There will be no NPE since we asked bean factory to get beans
+       * with this annotation
+       */
+      Arrays.stream(permission.getValue().getClass().getAnnotation(LookupPermission.class).value())
+          .forEach(permissionName -> {
+            /*
+             * TODO add check for type before doing this
+             */
+            Permission permissionBean = permission.getValue();
+            beanFactory.autowireBeanProperties(permissionBean,
+                AutowireCapableBeanFactory.AUTOWIRE_NO, true);
+            permissionsMap.put(permissionName, permissionBean);
+          });
+    });
+  }
 
-	@Override
-	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
-		//nothing to do
-	}
+  @Override
+  public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
+      throws BeansException {
+    //nothing to do
+  }
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/auth/ReportPortalClient.java b/src/main/java/com/epam/ta/reportportal/auth/ReportPortalClient.java
index f29eb8640c..e87f65b3c0 100644
--- a/src/main/java/com/epam/ta/reportportal/auth/ReportPortalClient.java
+++ b/src/main/java/com/epam/ta/reportportal/auth/ReportPortalClient.java
@@ -21,7 +21,7 @@
  * @author <a href="mailto:andrei_varabyeu@epam.com">Andrei Varabyeu</a>
  */
 public enum ReportPortalClient {
-	ui,
-	api,
-	internal
+  ui,
+  api,
+  internal
 }
diff --git a/src/main/java/com/epam/ta/reportportal/auth/UserRoleHierarchy.java b/src/main/java/com/epam/ta/reportportal/auth/UserRoleHierarchy.java
index 003dfa81dc..7b3b3f0aa2 100644
--- a/src/main/java/com/epam/ta/reportportal/auth/UserRoleHierarchy.java
+++ b/src/main/java/com/epam/ta/reportportal/auth/UserRoleHierarchy.java
@@ -18,6 +18,13 @@
 
 import com.epam.ta.reportportal.entity.user.UserRole;
 import com.google.common.collect.ImmutableSet;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
@@ -25,71 +32,70 @@
 import org.springframework.security.core.authority.AuthorityUtils;
 import org.springframework.security.core.authority.SimpleGrantedAuthority;
 
-import java.util.*;
-import java.util.stream.Collectors;
-
 /**
- * UserRoleHierarchy processor. Actually, hierarchy is pretty simple: role in
- * {@link UserRole} has more
- * rights than the following one. So, Administrator is more privileged than
- * User.
+ * UserRoleHierarchy processor. Actually, hierarchy is pretty simple: role in {@link UserRole} has
+ * more rights than the following one. So, Administrator is more privileged than User.
  *
  * @author Andrei Varabyeu
  */
 public class UserRoleHierarchy implements RoleHierarchy {
 
-	public static final String ROLE_REGISTERED = "ROLE_REGISTERED";
-
-	/**
-	 * Special additional role for other microservices
-	 */
-	public static final String ROLE_COMPONENT = "ROLE_COMPONENT";
-
-	private static final Logger logger = LoggerFactory.getLogger(UserRoleHierarchy.class);
-
-	private Map<GrantedAuthority, Set<GrantedAuthority>> authoritiesMap;
-
-	public UserRoleHierarchy() {
-		authoritiesMap = Arrays.stream(UserRole.values()).collect(Collectors.toMap(this::asAuthority, this::findReachableRoles));
-		/*
-		 * Specify authorities explicitly. It additionally has USER role to allow other services to pass login check
-		 */
-		GrantedAuthority component = new SimpleGrantedAuthority(ROLE_COMPONENT);
-		authoritiesMap.put(component, ImmutableSet.<GrantedAuthority>builder().add(component).build());
-	}
-
-	@Override
-	public Collection<? extends GrantedAuthority> getReachableGrantedAuthorities(Collection<? extends GrantedAuthority> authorities) {
-
-		if ((authorities == null) || (authorities.isEmpty())) {
-			return AuthorityUtils.NO_AUTHORITIES;
-		}
-
-		List<GrantedAuthority> reachableRoles = authorities.stream()
-				.filter(authority -> authoritiesMap.containsKey(authority))
-				.flatMap(authority -> authoritiesMap.get(authority).stream())
-				.collect(Collectors.toList());
-
-		if (logger.isDebugEnabled()) {
-			logger.debug("getReachableGrantedAuthorities() - From the roles " + authorities + " one can reach " + reachableRoles
-					+ " in zero or more steps.");
-		}
-
-		return reachableRoles;
-	}
-
-	private Set<GrantedAuthority> findReachableRoles(UserRole authority) {
-		Set<GrantedAuthority> reachableRoles = new HashSet<>();
-		UserRole[] roles = UserRole.values();
-		int startIndex = Arrays.binarySearch(UserRole.values(), authority);
-		for (int i = 0; i <= startIndex; i++) {
-			reachableRoles.add(asAuthority(roles[i]));
-		}
-		return reachableRoles;
-	}
-
-	private GrantedAuthority asAuthority(UserRole userRole) {
-		return new SimpleGrantedAuthority(userRole.getAuthority());
-	}
+  public static final String ROLE_REGISTERED = "ROLE_REGISTERED";
+
+  /**
+   * Special additional role for other microservices
+   */
+  public static final String ROLE_COMPONENT = "ROLE_COMPONENT";
+
+  private static final Logger logger = LoggerFactory.getLogger(UserRoleHierarchy.class);
+
+  private Map<GrantedAuthority, Set<GrantedAuthority>> authoritiesMap;
+
+  public UserRoleHierarchy() {
+    authoritiesMap = Arrays.stream(UserRole.values())
+        .collect(Collectors.toMap(this::asAuthority, this::findReachableRoles));
+    /*
+     * Specify authorities explicitly. It additionally has USER role to allow other services to pass login check
+     */
+    GrantedAuthority component = new SimpleGrantedAuthority(ROLE_COMPONENT);
+    authoritiesMap.put(component, ImmutableSet.<GrantedAuthority>builder().add(component).build());
+  }
+
+  @Override
+  public Collection<? extends GrantedAuthority> getReachableGrantedAuthorities(
+      Collection<? extends GrantedAuthority> authorities) {
+
+    if ((authorities == null) || (authorities.isEmpty())) {
+      return AuthorityUtils.NO_AUTHORITIES;
+    }
+
+    List<GrantedAuthority> reachableRoles = authorities.stream()
+        .filter(authority -> authoritiesMap.containsKey(authority))
+        .flatMap(authority -> authoritiesMap.get(authority).stream())
+        .collect(Collectors.toList());
+
+    if (logger.isDebugEnabled()) {
+      logger.debug(
+          "getReachableGrantedAuthorities() - From the roles " + authorities + " one can reach "
+              + reachableRoles
+              + " in zero or more steps.");
+    }
+
+    return reachableRoles;
+  }
+
+  private Set<GrantedAuthority> findReachableRoles(UserRole authority) {
+    Set<GrantedAuthority> reachableRoles = new HashSet<>();
+    UserRole[] roles = UserRole.values();
+    int startIndex = Arrays.binarySearch(UserRole.values(), authority);
+    for (int i = 0; i <= startIndex; i++) {
+      reachableRoles.add(asAuthority(roles[i]));
+    }
+    return reachableRoles;
+  }
+
+  private GrantedAuthority asAuthority(UserRole userRole) {
+    return new SimpleGrantedAuthority(userRole.getAuthority());
+  }
 
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/auth/acl/ReportPortalAclAuthorizationStrategyImpl.java b/src/main/java/com/epam/ta/reportportal/auth/acl/ReportPortalAclAuthorizationStrategyImpl.java
index ffa21bfd4c..81cdec8fe5 100644
--- a/src/main/java/com/epam/ta/reportportal/auth/acl/ReportPortalAclAuthorizationStrategyImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/auth/acl/ReportPortalAclAuthorizationStrategyImpl.java
@@ -16,6 +16,8 @@
 
 package com.epam.ta.reportportal.auth.acl;
 
+import static com.epam.ta.reportportal.auth.UserRoleHierarchy.ROLE_REGISTERED;
+
 import org.springframework.security.access.AccessDeniedException;
 import org.springframework.security.acls.domain.AclAuthorizationStrategyImpl;
 import org.springframework.security.acls.model.Acl;
@@ -23,32 +25,33 @@
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.context.SecurityContextHolder;
 
-import static com.epam.ta.reportportal.auth.UserRoleHierarchy.ROLE_REGISTERED;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public class ReportPortalAclAuthorizationStrategyImpl extends AclAuthorizationStrategyImpl {
 
-	public ReportPortalAclAuthorizationStrategyImpl(GrantedAuthority... auths) {
-		super(auths);
-	}
+  public ReportPortalAclAuthorizationStrategyImpl(GrantedAuthority... auths) {
+    super(auths);
+  }
 
-	@Override
-	public void securityCheck(Acl acl, int changeType) {
+  @Override
+  public void securityCheck(Acl acl, int changeType) {
 
-		if ((SecurityContextHolder.getContext() == null) || (SecurityContextHolder.getContext().getAuthentication() == null) || !SecurityContextHolder.getContext().getAuthentication().isAuthenticated()) {
-			throw new AccessDeniedException("Authenticated principal required to operate with ACLs");
-		}
+    if ((SecurityContextHolder.getContext() == null) || (
+        SecurityContextHolder.getContext().getAuthentication() == null)
+        || !SecurityContextHolder.getContext().getAuthentication().isAuthenticated()) {
+      throw new AccessDeniedException("Authenticated principal required to operate with ACLs");
+    }
 
-		Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
 
-		if (!authentication.isAuthenticated() || !isJustRegistered(authentication)) {
-			super.securityCheck(acl, changeType);
-		}
-	}
+    if (!authentication.isAuthenticated() || !isJustRegistered(authentication)) {
+      super.securityCheck(acl, changeType);
+    }
+  }
 
-	private boolean isJustRegistered(Authentication authentication) {
-		return authentication.getAuthorities().stream().anyMatch(authority -> ROLE_REGISTERED.equals(authority.getAuthority()));
-	}
+  private boolean isJustRegistered(Authentication authentication) {
+    return authentication.getAuthorities().stream()
+        .anyMatch(authority -> ROLE_REGISTERED.equals(authority.getAuthority()));
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/auth/authenticator/RegisteredUserAuthenticator.java b/src/main/java/com/epam/ta/reportportal/auth/authenticator/RegisteredUserAuthenticator.java
index 5b79021bbe..d15f7c7bac 100644
--- a/src/main/java/com/epam/ta/reportportal/auth/authenticator/RegisteredUserAuthenticator.java
+++ b/src/main/java/com/epam/ta/reportportal/auth/authenticator/RegisteredUserAuthenticator.java
@@ -1,5 +1,7 @@
 package com.epam.ta.reportportal.auth.authenticator;
 
+import static com.epam.ta.reportportal.auth.UserRoleHierarchy.ROLE_REGISTERED;
+
 import com.epam.ta.reportportal.entity.user.User;
 import com.google.common.collect.Sets;
 import org.springframework.security.acls.model.Acl;
@@ -9,25 +11,27 @@
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.stereotype.Service;
 
-import static com.epam.ta.reportportal.auth.UserRoleHierarchy.ROLE_REGISTERED;
-
 @Service
 public class RegisteredUserAuthenticator implements UserAuthenticator {
 
-	/**
-	 * Required for {@link org.springframework.security.acls.domain.AclAuthorizationStrategy#securityCheck(Acl, int)} with custom implementation
-	 * {@link com.epam.ta.reportportal.auth.acl.ReportPortalAclAuthorizationStrategyImpl} to permit shared objects to the newly created user
-	 *
-	 * @param user {@link User}
-	 * @return {@link Authentication} with authenticated user with the role {@link com.epam.ta.reportportal.auth.UserRoleHierarchy#ROLE_REGISTERED}
-	 */
-	@Override
-	public Authentication authenticate(User user) {
-		final Authentication authentication = new UsernamePasswordAuthenticationToken(user.getLogin(),
-				user.getPassword(),
-				Sets.newHashSet(new SimpleGrantedAuthority(ROLE_REGISTERED))
-		);
-		SecurityContextHolder.getContext().setAuthentication(authentication);
-		return authentication;
-	}
+  /**
+   * Required for
+   * {@link org.springframework.security.acls.domain.AclAuthorizationStrategy#securityCheck(Acl,
+   * int)} with custom implementation
+   * {@link com.epam.ta.reportportal.auth.acl.ReportPortalAclAuthorizationStrategyImpl} to permit
+   * shared objects to the newly created user
+   *
+   * @param user {@link User}
+   * @return {@link Authentication} with authenticated user with the role
+   * {@link com.epam.ta.reportportal.auth.UserRoleHierarchy#ROLE_REGISTERED}
+   */
+  @Override
+  public Authentication authenticate(User user) {
+    final Authentication authentication = new UsernamePasswordAuthenticationToken(user.getLogin(),
+        user.getPassword(),
+        Sets.newHashSet(new SimpleGrantedAuthority(ROLE_REGISTERED))
+    );
+    SecurityContextHolder.getContext().setAuthentication(authentication);
+    return authentication;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/auth/authenticator/UserAuthenticator.java b/src/main/java/com/epam/ta/reportportal/auth/authenticator/UserAuthenticator.java
index cd85ebe1cd..b59d4cb17e 100644
--- a/src/main/java/com/epam/ta/reportportal/auth/authenticator/UserAuthenticator.java
+++ b/src/main/java/com/epam/ta/reportportal/auth/authenticator/UserAuthenticator.java
@@ -5,5 +5,5 @@
 
 public interface UserAuthenticator {
 
-	Authentication authenticate(User user);
+  Authentication authenticate(User user);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/auth/basic/DatabaseUserDetailsService.java b/src/main/java/com/epam/ta/reportportal/auth/basic/DatabaseUserDetailsService.java
index 1d9c319a34..1eab301d76 100644
--- a/src/main/java/com/epam/ta/reportportal/auth/basic/DatabaseUserDetailsService.java
+++ b/src/main/java/com/epam/ta/reportportal/auth/basic/DatabaseUserDetailsService.java
@@ -15,6 +15,8 @@
  */
 package com.epam.ta.reportportal.auth.basic;
 
+import static com.epam.ta.reportportal.commons.EntityUtils.normalizeId;
+
 import com.epam.ta.reportportal.auth.util.AuthUtils;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.dao.UserRepository;
@@ -27,43 +29,41 @@
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import static com.epam.ta.reportportal.commons.EntityUtils.normalizeId;
-
 /**
- * Spring's {@link UserDetailsService} implementation. Uses {@link User} entity
- * from ReportPortal database
+ * Spring's {@link UserDetailsService} implementation. Uses {@link User} entity from ReportPortal
+ * database
  *
  * @author <a href="mailto:andrei_varabyeu@epam.com">Andrei Varabyeu</a>
  */
 @Service
 public class DatabaseUserDetailsService implements UserDetailsService {
 
-	private UserRepository userRepository;
+  private UserRepository userRepository;
 
-	@Autowired
-	public void setUserRepository(UserRepository userRepository) {
-		this.userRepository = userRepository;
-	}
+  @Autowired
+  public void setUserRepository(UserRepository userRepository) {
+    this.userRepository = userRepository;
+  }
 
-	@Override
-	@Transactional(readOnly = true)
-	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
-		ReportPortalUser user = userRepository.findReportPortalUser(normalizeId(username))
-				.orElseThrow(() -> new UsernameNotFoundException("User not found"));
+  @Override
+  @Transactional(readOnly = true)
+  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
+    ReportPortalUser user = userRepository.findReportPortalUser(normalizeId(username))
+        .orElseThrow(() -> new UsernameNotFoundException("User not found"));
 
-		UserDetails userDetails = User.builder()
-				.username(user.getUsername())
-				.password(user.getPassword() == null ? "" : user.getPassword())
-				.authorities(AuthUtils.AS_AUTHORITIES.apply(user.getUserRole()))
-				.build();
+    UserDetails userDetails = User.builder()
+        .username(user.getUsername())
+        .password(user.getPassword() == null ? "" : user.getPassword())
+        .authorities(AuthUtils.AS_AUTHORITIES.apply(user.getUserRole()))
+        .build();
 
-		return ReportPortalUser.userBuilder()
-				.withUserDetails(userDetails)
-				.withUserId(user.getUserId())
-				.withUserRole(user.getUserRole())
-				.withProjectDetails(Maps.newHashMapWithExpectedSize(1))
-				.withEmail(user.getEmail())
-				.build();
-	}
+    return ReportPortalUser.userBuilder()
+        .withUserDetails(userDetails)
+        .withUserId(user.getUserId())
+        .withUserRole(user.getUserRole())
+        .withProjectDetails(Maps.newHashMapWithExpectedSize(1))
+        .withEmail(user.getEmail())
+        .build();
+  }
 
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/auth/event/UiAuthenticationFailureEventHandler.java b/src/main/java/com/epam/ta/reportportal/auth/event/UiAuthenticationFailureEventHandler.java
index e2015660f3..073f1e3fa3 100644
--- a/src/main/java/com/epam/ta/reportportal/auth/event/UiAuthenticationFailureEventHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/auth/event/UiAuthenticationFailureEventHandler.java
@@ -19,68 +19,70 @@
 import com.google.common.cache.CacheLoader;
 import com.google.common.cache.LoadingCache;
 import com.google.common.net.HttpHeaders;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import javax.inject.Inject;
+import javax.inject.Provider;
+import javax.servlet.http.HttpServletRequest;
 import org.springframework.context.ApplicationListener;
 import org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent;
 import org.springframework.security.web.util.matcher.RequestHeaderRequestMatcher;
 import org.springframework.stereotype.Component;
 
-import javax.inject.Inject;
-import javax.inject.Provider;
-import javax.servlet.http.HttpServletRequest;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
 /**
  * Initial implementation of authentication failures handler
  *
  * @author Andrei_Ramanchuk
  */
 @Component
-public class UiAuthenticationFailureEventHandler implements ApplicationListener<AuthenticationFailureBadCredentialsEvent> {
+public class UiAuthenticationFailureEventHandler implements
+    ApplicationListener<AuthenticationFailureBadCredentialsEvent> {
 
-	private static final long MAXIMUM_SIZE = 5000;
-	private static final long EXPIRATION_SECONDS = 30;
-	private static final int MAX_ATTEMPTS = 3;
-	private static final RequestHeaderRequestMatcher AJAX_REQUEST_MATCHER = new RequestHeaderRequestMatcher(HttpHeaders.X_REQUESTED_WITH,
-			"XMLHttpRequest");
+  private static final long MAXIMUM_SIZE = 5000;
+  private static final long EXPIRATION_SECONDS = 30;
+  private static final int MAX_ATTEMPTS = 3;
+  private static final RequestHeaderRequestMatcher AJAX_REQUEST_MATCHER = new RequestHeaderRequestMatcher(
+      HttpHeaders.X_REQUESTED_WITH,
+      "XMLHttpRequest");
 
-	@Inject
-	private Provider<HttpServletRequest> request;
+  @Inject
+  private Provider<HttpServletRequest> request;
 
-	private LoadingCache<String, AtomicInteger> failures;
+  private LoadingCache<String, AtomicInteger> failures;
 
-	public UiAuthenticationFailureEventHandler() {
-		super();
-		failures = CacheBuilder.newBuilder().maximumSize(MAXIMUM_SIZE).expireAfterWrite(EXPIRATION_SECONDS, TimeUnit.SECONDS)
-				.build(new CacheLoader<String, AtomicInteger>() {
-					@Override
-					public AtomicInteger load(String key) {
-						return new AtomicInteger(0);
-					}
-				});
-	}
+  public UiAuthenticationFailureEventHandler() {
+    super();
+    failures = CacheBuilder.newBuilder().maximumSize(MAXIMUM_SIZE)
+        .expireAfterWrite(EXPIRATION_SECONDS, TimeUnit.SECONDS)
+        .build(new CacheLoader<String, AtomicInteger>() {
+          @Override
+          public AtomicInteger load(String key) {
+            return new AtomicInteger(0);
+          }
+        });
+  }
 
-	public boolean isBlocked(HttpServletRequest request) {
-		AtomicInteger attempts = failures.getIfPresent(getClientIP(request));
-		return null != attempts && attempts.get() > MAX_ATTEMPTS;
-	}
+  public boolean isBlocked(HttpServletRequest request) {
+    AtomicInteger attempts = failures.getIfPresent(getClientIP(request));
+    return null != attempts && attempts.get() > MAX_ATTEMPTS;
+  }
 
-	private void onAjaxFailure(HttpServletRequest request) {
-		String clientIP = getClientIP(request);
-		failures.getUnchecked(clientIP).incrementAndGet();
+  private void onAjaxFailure(HttpServletRequest request) {
+    String clientIP = getClientIP(request);
+    failures.getUnchecked(clientIP).incrementAndGet();
 
-	}
+  }
 
-	private String getClientIP(HttpServletRequest request) {
-		String xfHeader = request.getHeader(HttpHeaders.X_FORWARDED_FOR);
-		if (xfHeader == null) {
-			return request.getRemoteAddr();
-		}
-		return xfHeader.split(",")[0];
-	}
+  private String getClientIP(HttpServletRequest request) {
+    String xfHeader = request.getHeader(HttpHeaders.X_FORWARDED_FOR);
+    if (xfHeader == null) {
+      return request.getRemoteAddr();
+    }
+    return xfHeader.split(",")[0];
+  }
 
-	@Override
-	public void onApplicationEvent(AuthenticationFailureBadCredentialsEvent event) {
-		onAjaxFailure(request.get());
-	}
+  @Override
+  public void onApplicationEvent(AuthenticationFailureBadCredentialsEvent event) {
+    onAjaxFailure(request.get());
+  }
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/auth/event/UiAuthenticationSuccessEventHandler.java b/src/main/java/com/epam/ta/reportportal/auth/event/UiAuthenticationSuccessEventHandler.java
index 1b8bd39e57..d2c4ebe3d5 100644
--- a/src/main/java/com/epam/ta/reportportal/auth/event/UiAuthenticationSuccessEventHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/auth/event/UiAuthenticationSuccessEventHandler.java
@@ -24,16 +24,17 @@
  * @author Andrei Varabyeu
  */
 @Component
-public class UiAuthenticationSuccessEventHandler implements ApplicationListener<UiUserSignedInEvent> {
+public class UiAuthenticationSuccessEventHandler implements
+    ApplicationListener<UiUserSignedInEvent> {
 
-	//    @Autowired
-	//    private UserRepository userRepository;
-	//	@Autowired
-	//	private DSLContext dsl;
+  //    @Autowired
+  //    private UserRepository userRepository;
+  //	@Autowired
+  //	private DSLContext dsl;
 
-	@Override
-	public void onApplicationEvent(UiUserSignedInEvent event) {
-		//		dsl.update(Users.USERS).set(Users.USERS.)
-		//        userRepository.updateLastLoginDate(event.getAuthentication().getName(), new Date(event.getTimestamp()));
-	}
+  @Override
+  public void onApplicationEvent(UiUserSignedInEvent event) {
+    //		dsl.update(Users.USERS).set(Users.USERS.)
+    //        userRepository.updateLastLoginDate(event.getAuthentication().getName(), new Date(event.getTimestamp()));
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/auth/event/UiUserSignedInEvent.java b/src/main/java/com/epam/ta/reportportal/auth/event/UiUserSignedInEvent.java
index 21add2235e..ed8b65ffe0 100644
--- a/src/main/java/com/epam/ta/reportportal/auth/event/UiUserSignedInEvent.java
+++ b/src/main/java/com/epam/ta/reportportal/auth/event/UiUserSignedInEvent.java
@@ -20,16 +20,15 @@
 
 /**
  * UI user has signed in
- * 
+ *
  * @author Andrei Varabyeu
- * 
  */
 public class UiUserSignedInEvent extends AuthenticationSuccessEvent {
 
-	private static final long serialVersionUID = -6746135168882975399L;
+  private static final long serialVersionUID = -6746135168882975399L;
 
-	public UiUserSignedInEvent(Authentication authentication) {
-		super(authentication);
-	}
+  public UiUserSignedInEvent(Authentication authentication) {
+    super(authentication);
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/auth/permissions/BaseProjectPermission.java b/src/main/java/com/epam/ta/reportportal/auth/permissions/BaseProjectPermission.java
index 1a5d329ec3..372b7be071 100644
--- a/src/main/java/com/epam/ta/reportportal/auth/permissions/BaseProjectPermission.java
+++ b/src/main/java/com/epam/ta/reportportal/auth/permissions/BaseProjectPermission.java
@@ -23,62 +23,64 @@
 import com.epam.ta.reportportal.util.ProjectExtractor;
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.google.common.collect.Maps;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.oauth2.provider.OAuth2Authentication;
-
 import java.util.Map;
 import java.util.Objects;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.oauth2.provider.OAuth2Authentication;
 
 /**
- * Base logic for project-related permissions. Validates project exists and
- * there is provided in {@link Authentication} user assigned to this project
+ * Base logic for project-related permissions. Validates project exists and there is provided in
+ * {@link Authentication} user assigned to this project
  *
  * @author Andrei Varabyeu
  */
 abstract class BaseProjectPermission implements Permission {
 
-	private final ProjectExtractor projectExtractor;
+  private final ProjectExtractor projectExtractor;
 
-	protected BaseProjectPermission(ProjectExtractor projectExtractor) {
-		this.projectExtractor = projectExtractor;
-	}
+  protected BaseProjectPermission(ProjectExtractor projectExtractor) {
+    this.projectExtractor = projectExtractor;
+  }
 
-	/**
-	 * Validates project exists and user assigned to project. After that
-	 * delegates permission check to subclass
-	 */
-	@Override
-	public boolean isAllowed(Authentication authentication, Object projectName) {
-		if (!authentication.isAuthenticated()) {
-			return false;
-		}
+  /**
+   * Validates project exists and user assigned to project. After that delegates permission check to
+   * subclass
+   */
+  @Override
+  public boolean isAllowed(Authentication authentication, Object projectName) {
+    if (!authentication.isAuthenticated()) {
+      return false;
+    }
 
-		OAuth2Authentication oauth = (OAuth2Authentication) authentication;
-		ReportPortalUser rpUser = (ReportPortalUser) oauth.getUserAuthentication().getPrincipal();
-		BusinessRule.expect(rpUser, Objects::nonNull).verify(ErrorType.ACCESS_DENIED);
+    OAuth2Authentication oauth = (OAuth2Authentication) authentication;
+    ReportPortalUser rpUser = (ReportPortalUser) oauth.getUserAuthentication().getPrincipal();
+    BusinessRule.expect(rpUser, Objects::nonNull).verify(ErrorType.ACCESS_DENIED);
 
-		final String resolvedProjectName = String.valueOf(projectName);
-		final ReportPortalUser.ProjectDetails projectDetails = projectExtractor.findProjectDetails(rpUser, resolvedProjectName)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.ACCESS_DENIED));
-		fillProjectDetails(rpUser, resolvedProjectName, projectDetails);
+    final String resolvedProjectName = String.valueOf(projectName);
+    final ReportPortalUser.ProjectDetails projectDetails = projectExtractor.findProjectDetails(
+            rpUser, resolvedProjectName)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.ACCESS_DENIED));
+    fillProjectDetails(rpUser, resolvedProjectName, projectDetails);
 
-		ProjectRole role = projectDetails.getProjectRole();
-		return checkAllowed(rpUser, projectName.toString(), role);
-	}
+    ProjectRole role = projectDetails.getProjectRole();
+    return checkAllowed(rpUser, projectName.toString(), role);
+  }
 
-	private void fillProjectDetails(ReportPortalUser rpUser, String resolvedProjectName, ReportPortalUser.ProjectDetails projectDetails) {
-		final Map<String, ReportPortalUser.ProjectDetails> projectDetailsMapping = Maps.newHashMapWithExpectedSize(1);
-		projectDetailsMapping.put(resolvedProjectName, projectDetails);
-		rpUser.setProjectDetails(projectDetailsMapping);
-	}
+  private void fillProjectDetails(ReportPortalUser rpUser, String resolvedProjectName,
+      ReportPortalUser.ProjectDetails projectDetails) {
+    final Map<String, ReportPortalUser.ProjectDetails> projectDetailsMapping = Maps.newHashMapWithExpectedSize(
+        1);
+    projectDetailsMapping.put(resolvedProjectName, projectDetails);
+    rpUser.setProjectDetails(projectDetailsMapping);
+  }
 
-	/**
-	 * Validates permission
-	 *
-	 * @param user    ReportPortal user object
-	 * @param project ReportPortal's Project name
-	 * @param role    User role
-	 * @return TRUE if access allowed
-	 */
-	abstract protected boolean checkAllowed(ReportPortalUser user, String project, ProjectRole role);
+  /**
+   * Validates permission
+   *
+   * @param user    ReportPortal user object
+   * @param project ReportPortal's Project name
+   * @param role    User role
+   * @return TRUE if access allowed
+   */
+  abstract protected boolean checkAllowed(ReportPortalUser user, String project, ProjectRole role);
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/auth/permissions/LookupPermission.java b/src/main/java/com/epam/ta/reportportal/auth/permissions/LookupPermission.java
index 21512ac856..5aaa0f3cf0 100644
--- a/src/main/java/com/epam/ta/reportportal/auth/permissions/LookupPermission.java
+++ b/src/main/java/com/epam/ta/reportportal/auth/permissions/LookupPermission.java
@@ -16,20 +16,20 @@
 
 package com.epam.ta.reportportal.auth.permissions;
 
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
 import java.lang.annotation.Documented;
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
 /**
  * * Specifies list of permission names to be assigned to some
  * {@link com.epam.ta.reportportal.auth.permissions.Permission} implementation<br>
  * <b>BE AWARE</b> that each permissions should be marked with
- * {@link com.epam.ta.reportportal.auth.permissions.LookupPermission} annotation
- * to be assigned to some permission name. Without this permission will be
- * ignored by {@link org.springframework.security.access.PermissionEvaluator}
+ * {@link com.epam.ta.reportportal.auth.permissions.LookupPermission} annotation to be assigned to
+ * some permission name. Without this permission will be ignored by
+ * {@link org.springframework.security.access.PermissionEvaluator}
  *
  * @author Andrei Varabyeu
  */
@@ -37,5 +37,6 @@
 @Retention(RUNTIME)
 @Documented
 public @interface LookupPermission {
-	String[] value();
+
+  String[] value();
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/auth/permissions/NotCustomerPermission.java b/src/main/java/com/epam/ta/reportportal/auth/permissions/NotCustomerPermission.java
index e2e60cc68b..5f63552beb 100644
--- a/src/main/java/com/epam/ta/reportportal/auth/permissions/NotCustomerPermission.java
+++ b/src/main/java/com/epam/ta/reportportal/auth/permissions/NotCustomerPermission.java
@@ -23,27 +23,26 @@
 import org.springframework.stereotype.Component;
 
 /**
- * Validates this is {@link ProjectRole#MEMBER} or higher authority in the
- * authentication context
+ * Validates this is {@link ProjectRole#MEMBER} or higher authority in the authentication context
  *
  * @author Andrei Varabyeu
  */
 @Component
-@LookupPermission({ "notCustomerPermission" })
+@LookupPermission({"notCustomerPermission"})
 public class NotCustomerPermission extends BaseProjectPermission {
 
-	@Autowired
-	public NotCustomerPermission(ProjectExtractor projectExtractor) {
-		super(projectExtractor);
-	}
+  @Autowired
+  public NotCustomerPermission(ProjectExtractor projectExtractor) {
+    super(projectExtractor);
+  }
 
-	/**
-	 * Validates this is not a {@link ProjectRole#CUSTOMER} or higher authority in the
-	 * authentication context
-	 */
-	@Override
-	protected boolean checkAllowed(ReportPortalUser user, String project, ProjectRole role) {
-		return (null != role) && role.compareTo(ProjectRole.CUSTOMER) != 0;
-	}
+  /**
+   * Validates this is not a {@link ProjectRole#CUSTOMER} or higher authority in the authentication
+   * context
+   */
+  @Override
+  protected boolean checkAllowed(ReportPortalUser user, String project, ProjectRole role) {
+    return (null != role) && role.compareTo(ProjectRole.CUSTOMER) != 0;
+  }
 
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/auth/permissions/Permission.java b/src/main/java/com/epam/ta/reportportal/auth/permissions/Permission.java
index 5ca4f014e2..e16f0a866e 100644
--- a/src/main/java/com/epam/ta/reportportal/auth/permissions/Permission.java
+++ b/src/main/java/com/epam/ta/reportportal/auth/permissions/Permission.java
@@ -21,20 +21,20 @@
 /**
  * Report Portal Permission representation<br>
  * <b>BE AWARE</b> that each permissions should be marked with
- * {@link com.epam.ta.reportportal.auth.permissions.LookupPermission} annotation
- * to be assigned to some permission name. Without this permission will be
- * ignored by {@link org.springframework.security.access.PermissionEvaluator}
+ * {@link com.epam.ta.reportportal.auth.permissions.LookupPermission} annotation to be assigned to
+ * some permission name. Without this permission will be ignored by
+ * {@link org.springframework.security.access.PermissionEvaluator}
  *
  * @author Andrei Varabyeu
  */
 public interface Permission {
 
-	/**
-	 * Is action allowed for user with {@link Authentication} for target object
-	 *
-	 * @param authentication
-	 * @param targetDomainObject
-	 * @return
-	 */
-	boolean isAllowed(Authentication authentication, Object targetDomainObject);
+  /**
+   * Is action allowed for user with {@link Authentication} for target object
+   *
+   * @param authentication     {@link Authentication}
+   * @param targetDomainObject target domain object
+   * @return true if access is allowed
+   */
+  boolean isAllowed(Authentication authentication, Object targetDomainObject);
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/auth/permissions/PermissionEvaluatorFactoryBean.java b/src/main/java/com/epam/ta/reportportal/auth/permissions/PermissionEvaluatorFactoryBean.java
index 54f71340d9..aeb9ee767f 100644
--- a/src/main/java/com/epam/ta/reportportal/auth/permissions/PermissionEvaluatorFactoryBean.java
+++ b/src/main/java/com/epam/ta/reportportal/auth/permissions/PermissionEvaluatorFactoryBean.java
@@ -17,50 +17,51 @@
 package com.epam.ta.reportportal.auth.permissions;
 
 import com.epam.ta.reportportal.util.ApplicationContextAwareFactoryBean;
-import org.springframework.security.access.PermissionEvaluator;
-
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Map.Entry;
+import org.springframework.security.access.PermissionEvaluator;
 
 /**
- * Factory bean for providing permissions marked with {@link LookupPermission}
- * annotation
+ * Factory bean for providing permissions marked with {@link LookupPermission} annotation
  *
  * @author Andrei Varabyeu
  */
-public class PermissionEvaluatorFactoryBean extends ApplicationContextAwareFactoryBean<PermissionEvaluator> {
+public class PermissionEvaluatorFactoryBean extends
+    ApplicationContextAwareFactoryBean<PermissionEvaluator> {
 
-	@Override
-	public Class<?> getObjectType() {
-		return PermissionEvaluator.class;
-	}
+  @Override
+  public Class<?> getObjectType() {
+    return PermissionEvaluator.class;
+  }
 
-	@Override
-	protected PermissionEvaluator createInstance() {
+  @Override
+  protected PermissionEvaluator createInstance() {
 
-		/*
-		 * Find all beans in context marked with
-		 * com.epam.ta.reportportal.auth.permissions.LookupPermission annotation
-		 */
-		Map<String, Object> permissionBeans = getApplicationContext().getBeansWithAnnotation(LookupPermission.class);
-		Map<String, Permission> permissionsMap = new HashMap<>();
-		for (Entry<String, Object> permission : permissionBeans.entrySet()) {
-			/*
-			 * There will be no NPE since we asked bean factory to get beans
-			 * with this annotation
-			 */
-			for (String permissionName : permission.getValue().getClass().getAnnotation(LookupPermission.class).value()) {
-				if (Permission.class.isAssignableFrom(permission.getValue().getClass())) {
-					/*
-					 * Assign permission name from LookupPermission annotation
-					 * to it's value
-					 */
-					permissionsMap.put(permissionName, (Permission) permission.getValue());
-				}
-			}
-		}
+    /*
+     * Find all beans in context marked with
+     * com.epam.ta.reportportal.auth.permissions.LookupPermission annotation
+     */
+    Map<String, Object> permissionBeans = getApplicationContext().getBeansWithAnnotation(
+        LookupPermission.class);
+    Map<String, Permission> permissionsMap = new HashMap<>();
+    for (Entry<String, Object> permission : permissionBeans.entrySet()) {
+      /*
+       * There will be no NPE since we asked bean factory to get beans
+       * with this annotation
+       */
+      for (String permissionName : permission.getValue().getClass()
+          .getAnnotation(LookupPermission.class).value()) {
+        if (Permission.class.isAssignableFrom(permission.getValue().getClass())) {
+          /*
+           * Assign permission name from LookupPermission annotation
+           * to it's value
+           */
+          permissionsMap.put(permissionName, (Permission) permission.getValue());
+        }
+      }
+    }
 
-		return new ReportPortalPermissionEvaluator(permissionsMap);
-	}
+    return new ReportPortalPermissionEvaluator(permissionsMap);
+  }
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/auth/permissions/ProjectAuthority.java b/src/main/java/com/epam/ta/reportportal/auth/permissions/ProjectAuthority.java
index 7a66191913..da8f39c0cc 100644
--- a/src/main/java/com/epam/ta/reportportal/auth/permissions/ProjectAuthority.java
+++ b/src/main/java/com/epam/ta/reportportal/auth/permissions/ProjectAuthority.java
@@ -15,9 +15,8 @@
  */
 package com.epam.ta.reportportal.auth.permissions;
 
-import org.springframework.security.core.GrantedAuthority;
-
 import java.util.Objects;
+import org.springframework.security.core.GrantedAuthority;
 
 /**
  * Project authority
@@ -26,41 +25,41 @@
  */
 public class ProjectAuthority implements GrantedAuthority {
 
-	private final String project;
-	private final String projectRole;
+  private final String project;
+  private final String projectRole;
 
-	public ProjectAuthority(String project, String projectRole) {
-		this.project = project;
-		this.projectRole = projectRole;
-	}
+  public ProjectAuthority(String project, String projectRole) {
+    this.project = project;
+    this.projectRole = projectRole;
+  }
 
-	public String getProject() {
-		return project;
-	}
+  public String getProject() {
+    return project;
+  }
 
-	public String getProjectRole() {
-		return projectRole;
-	}
+  public String getProjectRole() {
+    return projectRole;
+  }
 
-	@Override
-	public String getAuthority() {
-		return "PROJECT_" + project + "_" + projectRole;
-	}
+  @Override
+  public String getAuthority() {
+    return "PROJECT_" + project + "_" + projectRole;
+  }
 
-	@Override
-	public boolean equals(Object o) {
-		if (this == o) {
-			return true;
-		}
-		if (o == null || getClass() != o.getClass()) {
-			return false;
-		}
-		ProjectAuthority that = (ProjectAuthority) o;
-		return Objects.equals(project, that.project) && Objects.equals(projectRole, that.projectRole);
-	}
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    ProjectAuthority that = (ProjectAuthority) o;
+    return Objects.equals(project, that.project) && Objects.equals(projectRole, that.projectRole);
+  }
 
-	@Override
-	public int hashCode() {
-		return Objects.hash(project, projectRole);
-	}
+  @Override
+  public int hashCode() {
+    return Objects.hash(project, projectRole);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/auth/permissions/ProjectManagerPermission.java b/src/main/java/com/epam/ta/reportportal/auth/permissions/ProjectManagerPermission.java
index 054ff48d81..af3e5a1669 100644
--- a/src/main/java/com/epam/ta/reportportal/auth/permissions/ProjectManagerPermission.java
+++ b/src/main/java/com/epam/ta/reportportal/auth/permissions/ProjectManagerPermission.java
@@ -23,26 +23,26 @@
 import org.springframework.stereotype.Component;
 
 /**
- * Validates this is {@link ProjectRole#PROJECT_MANAGER} or higher authority in the
- * authentication context
+ * Validates this is {@link ProjectRole#PROJECT_MANAGER} or higher authority in the authentication
+ * context
  *
  * @author Andrei Varabyeu
  */
 @Component
-@LookupPermission({ "projectManagerPermission" })
+@LookupPermission({"projectManagerPermission"})
 public class ProjectManagerPermission extends BaseProjectPermission {
 
-	@Autowired
-	public ProjectManagerPermission(ProjectExtractor projectExtractor) {
-		super(projectExtractor);
-	}
+  @Autowired
+  public ProjectManagerPermission(ProjectExtractor projectExtractor) {
+    super(projectExtractor);
+  }
 
-	/**
-	 * Validates this is {@link ProjectRole#PROJECT_MANAGER} or higher authority in the
-	 * authentication context
-	 */
-	@Override
-	protected boolean checkAllowed(ReportPortalUser user, String project, ProjectRole role) {
-		return role.sameOrHigherThan(ProjectRole.PROJECT_MANAGER);
-	}
+  /**
+   * Validates this is {@link ProjectRole#PROJECT_MANAGER} or higher authority in the authentication
+   * context
+   */
+  @Override
+  protected boolean checkAllowed(ReportPortalUser user, String project, ProjectRole role) {
+    return role.sameOrHigherThan(ProjectRole.PROJECT_MANAGER);
+  }
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/auth/permissions/ReportPortalPermissionEvaluator.java b/src/main/java/com/epam/ta/reportportal/auth/permissions/ReportPortalPermissionEvaluator.java
index fe1a429caa..daaa26b327 100644
--- a/src/main/java/com/epam/ta/reportportal/auth/permissions/ReportPortalPermissionEvaluator.java
+++ b/src/main/java/com/epam/ta/reportportal/auth/permissions/ReportPortalPermissionEvaluator.java
@@ -19,14 +19,13 @@
 import com.epam.ta.reportportal.entity.user.UserRole;
 import com.epam.ta.reportportal.exception.PermissionNotDefinedException;
 import com.google.common.base.Preconditions;
+import java.io.Serializable;
+import java.util.Map;
 import org.springframework.security.access.PermissionEvaluator;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.authority.SimpleGrantedAuthority;
 
-import java.io.Serializable;
-import java.util.Map;
-
 /**
  * ReportPortal permission evaluator
  *
@@ -35,56 +34,66 @@
 // TODO add custom exception handling
 class ReportPortalPermissionEvaluator implements PermissionEvaluator {
 
-	private static final GrantedAuthority ADMIN_AUTHORITY = new SimpleGrantedAuthority(UserRole.ADMINISTRATOR.getAuthority());
+  private static final GrantedAuthority ADMIN_AUTHORITY = new SimpleGrantedAuthority(
+      UserRole.ADMINISTRATOR.getAuthority());
 
-	/**
-	 * Mapping between permission names and permissions
-	 */
-	private Map<String, Permission> permissionNameToPermissionMap;
+  /**
+   * Mapping between permission names and permissions
+   */
+  private Map<String, Permission> permissionNameToPermissionMap;
 
-	private boolean allowAllToAdmin;
+  private boolean allowAllToAdmin;
 
-	public ReportPortalPermissionEvaluator(Map<String, Permission> permissionNameToPermissionMap) {
-		this(permissionNameToPermissionMap, true);
+  public ReportPortalPermissionEvaluator(Map<String, Permission> permissionNameToPermissionMap) {
+    this(permissionNameToPermissionMap, true);
 
-	}
+  }
 
-	public ReportPortalPermissionEvaluator(Map<String, Permission> permissionNameToPermissionMap, boolean allowAllToAdmin) {
-		this.permissionNameToPermissionMap = Preconditions.checkNotNull(permissionNameToPermissionMap);
-		this.allowAllToAdmin = allowAllToAdmin;
-	}
+  public ReportPortalPermissionEvaluator(Map<String, Permission> permissionNameToPermissionMap,
+      boolean allowAllToAdmin) {
+    this.permissionNameToPermissionMap = Preconditions.checkNotNull(permissionNameToPermissionMap);
+    this.allowAllToAdmin = allowAllToAdmin;
+  }
 
-	@Override
-	public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
-		boolean hasPermission = false;
-		if (canHandle(authentication, targetDomainObject, permission)) {
-			hasPermission = checkPermission(authentication, targetDomainObject, (String) permission);
-		}
-		return hasPermission;
-	}
+  @Override
+  public boolean hasPermission(Authentication authentication, Object targetDomainObject,
+      Object permission) {
+    boolean hasPermission = false;
+    if (canHandle(authentication, targetDomainObject, permission)) {
+      hasPermission = checkPermission(authentication, targetDomainObject, (String) permission);
+    }
+    return hasPermission;
+  }
 
-	private boolean canHandle(Authentication authentication, Object targetDomainObject, Object permission) {
-		return targetDomainObject != null && authentication != null && String.class.equals(permission.getClass());
-	}
+  private boolean canHandle(Authentication authentication, Object targetDomainObject,
+      Object permission) {
+    return targetDomainObject != null && authentication != null && String.class.equals(
+        permission.getClass());
+  }
 
-	private boolean checkPermission(Authentication authentication, Object targetDomainObject, String permissionKey) {
-		verifyPermissionIsDefined(permissionKey);
-		if (allowAllToAdmin && authentication.isAuthenticated() && authentication.getAuthorities().contains(ADMIN_AUTHORITY)) {
-			return true;
-		}
-		Permission permission = permissionNameToPermissionMap.get(permissionKey);
-		return permission.isAllowed(authentication, targetDomainObject);
-	}
+  private boolean checkPermission(Authentication authentication, Object targetDomainObject,
+      String permissionKey) {
+    verifyPermissionIsDefined(permissionKey);
+    if (allowAllToAdmin && authentication.isAuthenticated() && authentication.getAuthorities()
+        .contains(ADMIN_AUTHORITY)) {
+      return true;
+    }
+    Permission permission = permissionNameToPermissionMap.get(permissionKey);
+    return permission.isAllowed(authentication, targetDomainObject);
+  }
 
-	private void verifyPermissionIsDefined(String permissionKey) {
-		if (!permissionNameToPermissionMap.containsKey(permissionKey)) {
-			throw new PermissionNotDefinedException(
-					"No permission with key " + permissionKey + " is defined in " + this.getClass().toString());
-		}
-	}
+  private void verifyPermissionIsDefined(String permissionKey) {
+    if (!permissionNameToPermissionMap.containsKey(permissionKey)) {
+      throw new PermissionNotDefinedException(
+          "No permission with key " + permissionKey + " is defined in " + this.getClass()
+              .toString());
+    }
+  }
 
-	@Override
-	public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
-		throw new PermissionNotDefinedException("Id and Class permissions are not supperted by " + this.getClass().toString());
-	}
+  @Override
+  public boolean hasPermission(Authentication authentication, Serializable targetId,
+      String targetType, Object permission) {
+    throw new PermissionNotDefinedException(
+        "Id and Class permissions are not supperted by " + this.getClass().toString());
+  }
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/auth/permissions/ReporterPermission.java b/src/main/java/com/epam/ta/reportportal/auth/permissions/ReporterPermission.java
index 8a20c19836..fd7a98efc0 100644
--- a/src/main/java/com/epam/ta/reportportal/auth/permissions/ReporterPermission.java
+++ b/src/main/java/com/epam/ta/reportportal/auth/permissions/ReporterPermission.java
@@ -28,19 +28,19 @@
  * @author Andrei Varabyeu
  */
 @Component
-@LookupPermission({ "reporterPermission" })
+@LookupPermission({"reporterPermission"})
 public class ReporterPermission extends BaseProjectPermission {
 
-	@Autowired
-	public ReporterPermission(ProjectExtractor projectExtractor) {
-		super(projectExtractor);
-	}
+  @Autowired
+  public ReporterPermission(ProjectExtractor projectExtractor) {
+    super(projectExtractor);
+  }
 
-	/**
-	 * Validates that user is allowed to report (start/finish, launch, start/finish item, log)
-	 */
-	@Override
-	protected boolean checkAllowed(ReportPortalUser user, String project, ProjectRole role) {
-		return role.sameOrHigherThan(ProjectRole.CUSTOMER);
-	}
+  /**
+   * Validates that user is allowed to report (start/finish, launch, start/finish item, log)
+   */
+  @Override
+  protected boolean checkAllowed(ReportPortalUser user, String project, ProjectRole role) {
+    return role.sameOrHigherThan(ProjectRole.CUSTOMER);
+  }
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/auth/util/AuthUtils.java b/src/main/java/com/epam/ta/reportportal/auth/util/AuthUtils.java
index bf93c89df4..6e7dc8a246 100644
--- a/src/main/java/com/epam/ta/reportportal/auth/util/AuthUtils.java
+++ b/src/main/java/com/epam/ta/reportportal/auth/util/AuthUtils.java
@@ -16,19 +16,23 @@
 package com.epam.ta.reportportal.auth.util;
 
 import com.epam.ta.reportportal.entity.user.UserRole;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InvalidClassException;
+import java.io.ObjectInputStream;
+import java.io.ObjectStreamClass;
+import java.util.Collections;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import javax.annotation.Nullable;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.authority.SimpleGrantedAuthority;
 import org.springframework.security.oauth2.common.util.SerializationUtils;
 
-import javax.annotation.Nullable;
-import java.io.*;
-import java.util.Collections;
-import java.util.List;
-import java.util.function.Consumer;
-import java.util.function.Function;
-
 /**
  * Authentication utils
  *
@@ -36,79 +40,12 @@
  */
 public final class AuthUtils {
 
-	private AuthUtils() {
-		//statics only
-	}
-
-	public static final Function<UserRole, List<GrantedAuthority>> AS_AUTHORITIES = userRole -> Collections.singletonList(new SimpleGrantedAuthority(
-			userRole.getAuthority()));
-
-	/**
-	 * Dirty hack to fix <a href="https://github.com/spring-projects/spring-security-oauth/issues/665">Spring Security Issue</a>
-	 * If there is serialUid mismatch, replaces Uuid and tries de-serialize object again
-	 * Introduces mismatchCallback function to handle successful recovery of Uuid mismatch
-	 *
-	 * @param data             Data to de-serialize
-	 * @param mismatchCallback Mismatch callback. Executed in case of successful recovery
-	 * @param <T>              Type of Object
-	 * @return De-serialized object
-	 */
-	@SuppressWarnings("unchecked")
-	public static <T> T deserializeSafely(byte[] data, @Nullable Consumer<T> mismatchCallback) {
-		try {
-			return SerializationUtils.deserialize(data);
-		} catch (IllegalArgumentException e) {
-			boolean serialUidMismatch = java.io.InvalidClassException.class.equals(e.getCause().getClass());
-			if (!serialUidMismatch) {
-				throw e;
-			}
-
-			try {
-				//TODO investigate stream closing requirement
-				ObjectInputStream is = new SerialUidReplacingInputStream(new ByteArrayInputStream(data));
-				T t = (T) is.readObject();
-				if (null != mismatchCallback) {
-					mismatchCallback.accept(t);
-				}
-				return t;
-			} catch (IOException | ClassNotFoundException e1) {
-				throw new IllegalArgumentException("Unable to serialize object", e1);
-			}
-		}
-	}
-
-	public static class SerialUidReplacingInputStream extends ObjectInputStream {
-
-		private static Logger logger = LoggerFactory.getLogger(SerialUidReplacingInputStream.class);
-
-		public SerialUidReplacingInputStream(InputStream in) throws IOException {
-			super(in);
-		}
+  private AuthUtils() {
+    //statics only
+  }
 
-		protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException {
-			ObjectStreamClass resultClassDescriptor = super.readClassDescriptor(); // initially streams descriptor
-			Class localClass; // the class in the local JVM that this descriptor represents.
-			try {
-				localClass = Class.forName(resultClassDescriptor.getName());
-			} catch (ClassNotFoundException e) {
-				logger.error("No local class for " + resultClassDescriptor.getName(), e);
-				return resultClassDescriptor;
-			}
-			ObjectStreamClass localClassDescriptor = ObjectStreamClass.lookup(localClass);
-			if (localClassDescriptor != null) { // only if class implements serializable
-				final long localSUID = localClassDescriptor.getSerialVersionUID();
-				final long streamSUID = resultClassDescriptor.getSerialVersionUID();
-				if (streamSUID != localSUID) { // check for serialVersionUID mismatch.
-					final StringBuffer s = new StringBuffer("Overriding serialized class version mismatch: ");
-					s.append("local serialVersionUID = ").append(localSUID);
-					s.append(" stream serialVersionUID = ").append(streamSUID);
-					Exception e = new InvalidClassException(s.toString());
-					logger.error("Potentially Fatal Deserialization Operation.", e);
-					resultClassDescriptor = localClassDescriptor; // Use local class descriptor for deserialization
-				}
-			}
-			return resultClassDescriptor;
-		}
-	}
+  public static final Function<UserRole, List<GrantedAuthority>> AS_AUTHORITIES = userRole -> Collections.singletonList(
+      new SimpleGrantedAuthority(
+          userRole.getAuthority()));
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/auth/util/Encryptor.java b/src/main/java/com/epam/ta/reportportal/auth/util/Encryptor.java
deleted file mode 100644
index 028a21cd7c..0000000000
--- a/src/main/java/com/epam/ta/reportportal/auth/util/Encryptor.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2019 EPAM Systems
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.epam.ta.reportportal.auth.util;
-
-import org.jasypt.util.text.BasicTextEncryptor;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-
-/**
- * @author Andrei Varabyeu
- */
-@Component
-public class Encryptor implements InitializingBean {
-
-	@Value("${rp.auth.encryptor.password:reportportal}")
-	private String password;
-
-	private BasicTextEncryptor textEncryptor;
-
-	/**
-	 * Encrypts string
-	 *
-	 * @param str String to be encrypted
-	 * @return Encrypted string
-	 */
-	public String encrypt(String str) {
-		return this.textEncryptor.encrypt(str);
-	}
-
-	/**
-	 * Decrypts string
-	 *
-	 * @param str String to be decrypted
-	 * @return Decrypted string
-	 */
-	public String decrypt(String str) {
-		return this.textEncryptor.decrypt(str);
-	}
-
-	@Override
-	public void afterPropertiesSet() throws Exception {
-		textEncryptor = new BasicTextEncryptor();
-		textEncryptor.setPassword(password);
-	}
-}
diff --git a/src/main/java/com/epam/ta/reportportal/core/ElementsCounterService.java b/src/main/java/com/epam/ta/reportportal/core/ElementsCounterService.java
new file mode 100644
index 0000000000..0868ec7572
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/core/ElementsCounterService.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2022 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.epam.ta.reportportal.core;
+
+import com.epam.ta.reportportal.dao.LogRepository;
+import com.epam.ta.reportportal.dao.TestItemRepository;
+import com.epam.ta.reportportal.entity.item.TestItem;
+import com.google.common.collect.Lists;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicLong;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+/**
+ * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
+ */
+@Service
+public class ElementsCounterService {
+
+  private final Integer batchSize;
+
+  private final TestItemRepository testItemRepository;
+
+  private final LogRepository logRepository;
+
+  @Autowired
+  public ElementsCounterService(
+      @Value("${rp.environment.variable.elements-counter.batch-size}") Integer batchSize,
+      TestItemRepository testItemRepository, LogRepository logRepository) {
+    this.batchSize = batchSize;
+    this.testItemRepository = testItemRepository;
+    this.logRepository = logRepository;
+  }
+
+  public Long countNumberOfLaunchElements(Long launchId) {
+    final AtomicLong resultedNumber = new AtomicLong(1L);
+    final List<Long> testItemIdsByLaunchId = testItemRepository.findIdsByLaunchId(launchId);
+    resultedNumber.addAndGet(testItemIdsByLaunchId.size());
+    resultedNumber.addAndGet(logRepository.countLogsByLaunchId(launchId));
+    Lists.partition(testItemIdsByLaunchId, batchSize)
+        .forEach(
+            batch -> resultedNumber.addAndGet(logRepository.countLogsByTestItemItemIdIn(batch)));
+    return resultedNumber.longValue();
+  }
+
+  public Long countNumberOfItemElements(TestItem item) {
+    if (item != null) {
+      final AtomicLong resultedNumber;
+      final List<Long> itemIds = testItemRepository.selectAllDescendantsIds(item.getPath());
+      resultedNumber = new AtomicLong(itemIds.size());
+      resultedNumber.addAndGet(logRepository.countLogsByTestItemItemIdIn(itemIds));
+
+      if (item.isHasRetries()) {
+        final List<Long> retryIds = testItemRepository.findIdsByRetryOf(item.getItemId());
+        final List<String> nestedPaths = testItemRepository.findPathsByParentIds(
+            retryIds.toArray(new Long[0]));
+        nestedPaths.forEach(path -> {
+          final List<Long> nestedChild = testItemRepository.selectAllDescendantsIds(path);
+          resultedNumber.addAndGet(nestedChild.size());
+          resultedNumber.addAndGet(logRepository.countLogsByTestItemItemIdIn(nestedChild));
+        });
+      }
+      return resultedNumber.longValue();
+    }
+    return 0L;
+  }
+
+  public Long countNumberOfItemElements(List<TestItem> items) {
+    if (!CollectionUtils.isEmpty(items)) {
+      final AtomicLong resultedNumber = new AtomicLong(0L);
+      items.forEach(item -> resultedNumber.addAndGet(countNumberOfItemElements(item)));
+      return resultedNumber.get();
+    }
+    return 0L;
+  }
+
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/activity/ActivityHandler.java b/src/main/java/com/epam/ta/reportportal/core/activity/ActivityHandler.java
index eece781574..e795b03a7b 100644
--- a/src/main/java/com/epam/ta/reportportal/core/activity/ActivityHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/activity/ActivityHandler.java
@@ -19,6 +19,7 @@
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.querygen.Queryable;
+import com.epam.ta.reportportal.ws.model.ActivityEventResource;
 import com.epam.ta.reportportal.ws.model.ActivityResource;
 import org.springframework.data.domain.Pageable;
 
@@ -27,51 +28,55 @@
  */
 public interface ActivityHandler {
 
-	/**
-	 * Load list of {@link com.epam.ta.reportportal.ws.model.ActivityResource}
-	 * for specified
-	 * {@link com.epam.ta.reportportal.entity.item.TestItem}
-	 *
-	 * @param projectDetails Details of project {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
-	 * @param filter         Filter
-	 * @param pageable       Page Details
-	 * @return Found activities
-	 */
-	Iterable<ActivityResource> getActivitiesHistory(ReportPortalUser.ProjectDetails projectDetails, Filter filter,
-			Queryable predefinedFilter, Pageable pageable);
+  /**
+   * Load list of {@link com.epam.ta.reportportal.ws.model.ActivityResource} for specified
+   * {@link com.epam.ta.reportportal.entity.item.TestItem}
+   *
+   * @param projectDetails     Details of project
+   *                           {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
+   * @param filter             Filter
+   * @param pageable           Page Details
+   * @param predefinedFilter   Additional filter
+   * @return Found activities
+   */
+  Iterable<ActivityResource> getActivitiesHistory(ReportPortalUser.ProjectDetails projectDetails,
+      Filter filter,
+      Queryable predefinedFilter, Pageable pageable);
 
-	/**
-	 * Load {@link com.epam.ta.reportportal.ws.model.ActivityResource}
-	 *
-	 * @param projectDetails Details of project {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
-	 * @param activityId     ID of activity
-	 * @return Found Activity or NOT FOUND exception
-	 */
-	ActivityResource getActivity(ReportPortalUser.ProjectDetails projectDetails, Long activityId);
+  /**
+   * Load {@link com.epam.ta.reportportal.ws.model.ActivityResource}
+   *
+   * @param projectDetails Details of project
+   *                       {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
+   * @param activityId     ID of activity
+   * @return Found Activity or NOT FOUND exception
+   */
+  ActivityResource getActivity(ReportPortalUser.ProjectDetails projectDetails, Long activityId);
 
 	/**
-	 * Load list of {@link com.epam.ta.reportportal.ws.model.ActivityResource}
-	 * for specified
+	 * Load list of {@link com.epam.ta.reportportal.ws.model.ActivityEventResource} for specified
 	 * {@link com.epam.ta.reportportal.entity.item.TestItem}
 	 *
-	 * @param projectDetails Details of project {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
+	 * @param projectDetails Details of project
+	 *                       {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
 	 * @param itemId         ID of test item
 	 * @param filter         Filter
 	 * @param pageable       Page Details
 	 * @return Found activities
 	 */
-	Iterable<ActivityResource> getItemActivities(ReportPortalUser.ProjectDetails projectDetails, Long itemId, Filter filter,
+	Iterable<ActivityEventResource> getItemActivities(ReportPortalUser.ProjectDetails projectDetails,
+			Long itemId, Filter filter,
 			Pageable pageable);
 
-	/**
-	 * Load list of {@link com.epam.ta.reportportal.ws.model.ActivityResource}
-	 * for specified
-	 * {@link com.epam.ta.reportportal.entity.project.Project}
-	 *
-	 * @param projectDetails Details of project {@link ReportPortalUser.ProjectDetails}
-	 * @param filter         Filter
-	 * @param pageable       Page Details
-	 * @return Found activities
-	 */
-	Iterable<ActivityResource> getItemActivities(ReportPortalUser.ProjectDetails projectDetails, Filter filter, Pageable pageable);
+  /**
+   * Load list of {@link com.epam.ta.reportportal.ws.model.ActivityResource} for specified
+   * {@link com.epam.ta.reportportal.entity.project.Project}
+   *
+   * @param projectDetails Details of project {@link ReportPortalUser.ProjectDetails}
+   * @param filter         Filter
+   * @param pageable       Page Details
+   * @return Found activities
+   */
+  Iterable<ActivityResource> getItemActivities(ReportPortalUser.ProjectDetails projectDetails,
+      Filter filter, Pageable pageable);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/activity/impl/ActivityHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/activity/impl/ActivityHandlerImpl.java
index 5343695c19..a14b93f9d9 100644
--- a/src/main/java/com/epam/ta/reportportal/core/activity/impl/ActivityHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/activity/impl/ActivityHandlerImpl.java
@@ -48,6 +48,8 @@
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.converter.PagedResourcesAssembler;
 import com.epam.ta.reportportal.ws.converter.converters.ActivityConverter;
+import com.epam.ta.reportportal.ws.converter.converters.ActivityEventConverter;
+import com.epam.ta.reportportal.ws.model.ActivityEventResource;
 import com.epam.ta.reportportal.ws.model.ActivityResource;
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import java.util.function.Predicate;
@@ -111,7 +113,8 @@ public ActivityResource getActivity(ReportPortalUser.ProjectDetails projectDetai
 	}
 
 	@Override
-	public Iterable<ActivityResource> getItemActivities(ReportPortalUser.ProjectDetails projectDetails, Long itemId, Filter filter,
+	public Iterable<ActivityEventResource> getItemActivities(
+			ReportPortalUser.ProjectDetails projectDetails, Long itemId, Filter filter,
 			Pageable pageable) {
 		TestItem testItem = testItemRepository.findById(itemId).orElseThrow(() -> new ReportPortalException(TEST_ITEM_NOT_FOUND, itemId));
 		Launch launch = launchRepository.findById(testItem.getLaunchId())
@@ -141,7 +144,7 @@ public Iterable<ActivityResource> getItemActivities(ReportPortalUser.ProjectDeta
         new CompositeFilter(Operator.OR, filter, patternActivityFilter),
         PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), sortByCreationDateDesc)
     );
-    return PagedResourcesAssembler.pageConverter(ActivityConverter.TO_RESOURCE).apply(page);
+		return PagedResourcesAssembler.pageConverter(ActivityEventConverter.TO_RESOURCE).apply(page);
   }
 
   @Override
diff --git a/src/main/java/com/epam/ta/reportportal/core/activityevent/ActivityEventHandler.java b/src/main/java/com/epam/ta/reportportal/core/activityevent/ActivityEventHandler.java
index f3d79611cd..398e503048 100644
--- a/src/main/java/com/epam/ta/reportportal/core/activityevent/ActivityEventHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/activityevent/ActivityEventHandler.java
@@ -16,9 +16,11 @@
 
 package com.epam.ta.reportportal.core.activityevent;
 
+import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.querygen.Queryable;
 import com.epam.ta.reportportal.ws.model.ActivityEventResource;
 import com.epam.ta.reportportal.ws.model.PagedResponse;
+import java.util.List;
 import org.springframework.data.domain.Pageable;
 
 
@@ -39,4 +41,13 @@ public interface ActivityEventHandler {
   PagedResponse<ActivityEventResource> getActivityEventsHistory(Queryable filter,
       Pageable pageable);
 
+  /**
+   * Get list of specified subjectName in project activities.
+   *
+   * @param projectDetails Project name
+   * @param value          Filter value
+   * @return List of found user logins
+   */
+  List<String> getSubjectNames(ReportPortalUser.ProjectDetails projectDetails, String value);
+
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/activityevent/impl/ActivityEventHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/activityevent/impl/ActivityEventHandlerImpl.java
index 11b40b91d7..bb1db79398 100644
--- a/src/main/java/com/epam/ta/reportportal/core/activityevent/impl/ActivityEventHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/activityevent/impl/ActivityEventHandlerImpl.java
@@ -16,14 +16,20 @@
 
 package com.epam.ta.reportportal.core.activityevent.impl;
 
+import com.epam.ta.reportportal.commons.Predicates;
+import com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails;
 import com.epam.ta.reportportal.commons.querygen.Queryable;
+import com.epam.ta.reportportal.commons.validation.BusinessRule;
+import com.epam.ta.reportportal.commons.validation.Suppliers;
 import com.epam.ta.reportportal.core.activityevent.ActivityEventHandler;
 import com.epam.ta.reportportal.dao.ActivityRepository;
 import com.epam.ta.reportportal.entity.activity.Activity;
 import com.epam.ta.reportportal.ws.converter.PagedResourcesAssembler;
 import com.epam.ta.reportportal.ws.converter.converters.ActivityEventConverter;
 import com.epam.ta.reportportal.ws.model.ActivityEventResource;
+import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.epam.ta.reportportal.ws.model.PagedResponse;
+import java.util.List;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
@@ -36,6 +42,9 @@
 @Service
 public class ActivityEventHandlerImpl implements ActivityEventHandler {
 
+  private static final String LENGTH_LESS_THAN_1_SYMBOL_MSG = "Length of the filtering string "
+      + "'{}' is less than 1 symbol";
+
   private final ActivityRepository activityRepository;
 
   public ActivityEventHandlerImpl(ActivityRepository activityRepository) {
@@ -51,4 +60,16 @@ public PagedResponse<ActivityEventResource> getActivityEventsHistory(Queryable f
         .apply(activityPage);
   }
 
+  @Override
+  public List<String> getSubjectNames(ProjectDetails projectDetails, String value) {
+    checkBusinessRuleLessThan1Symbol(value);
+    return activityRepository.findSubjectNameByProjectIdAndSubjectName(
+        projectDetails.getProjectId(), value.toLowerCase());
+  }
+
+  private void checkBusinessRuleLessThan1Symbol(String value) {
+    BusinessRule.expect(value.length() >= 1, Predicates.equalTo(true))
+        .verify(ErrorType.INCORRECT_FILTER_PARAMETERS,
+            Suppliers.formattedSupplier(LENGTH_LESS_THAN_1_SYMBOL_MSG, value));
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/admin/ServerAdminHandler.java b/src/main/java/com/epam/ta/reportportal/core/admin/ServerAdminHandler.java
index 47d74f76cb..591afac049 100644
--- a/src/main/java/com/epam/ta/reportportal/core/admin/ServerAdminHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/admin/ServerAdminHandler.java
@@ -19,7 +19,6 @@
 import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
 import com.epam.ta.reportportal.ws.model.settings.AnalyticsResource;
 import com.epam.ta.reportportal.ws.model.settings.ServerSettingsResource;
-
 import java.util.Map;
 
 /**
@@ -29,18 +28,18 @@
  */
 public interface ServerAdminHandler {
 
-	/**
-	 * Get all server settings
-	 *
-	 * @return {@link ServerSettingsResource}
-	 */
-	Map<String, String> getServerSettings();
+  /**
+   * Get all server settings
+   *
+   * @return {@link ServerSettingsResource}
+   */
+  Map<String, String> getServerSettings();
 
-	/**
-	 * Update analytics settings
-	 *
-	 * @param analyticsResource {@link AnalyticsResource}
-	 * @return Operation results
-	 */
-	OperationCompletionRS saveAnalyticsSettings(AnalyticsResource analyticsResource);
+  /**
+   * Update analytics settings
+   *
+   * @param analyticsResource {@link AnalyticsResource}
+   * @return Operation results
+   */
+  OperationCompletionRS saveAnalyticsSettings(AnalyticsResource analyticsResource);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/admin/ServerAdminHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/admin/ServerAdminHandlerImpl.java
index 255d32bce0..feb792b1d6 100644
--- a/src/main/java/com/epam/ta/reportportal/core/admin/ServerAdminHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/admin/ServerAdminHandlerImpl.java
@@ -16,65 +16,66 @@
 
 package com.epam.ta.reportportal.core.admin;
 
+import static com.epam.ta.reportportal.entity.ServerSettingsConstants.ANALYTICS_CONFIG_PREFIX;
+import static java.util.Optional.ofNullable;
+import static java.util.stream.Collectors.toMap;
+
 import com.epam.ta.reportportal.dao.ServerSettingsRepository;
 import com.epam.ta.reportportal.entity.ServerSettings;
 import com.epam.ta.reportportal.ws.converter.converters.ServerSettingsConverter;
 import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
 import com.epam.ta.reportportal.ws.model.settings.AnalyticsResource;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
 import java.util.Map;
 import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.entity.ServerSettingsConstants.ANALYTICS_CONFIG_PREFIX;
-import static java.util.Optional.ofNullable;
-import static java.util.stream.Collectors.toMap;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
- * Basic implementation of server administration interface
- * {@link ServerAdminHandler}
+ * Basic implementation of server administration interface {@link ServerAdminHandler}
  *
  * @author Andrei_Ramanchuk
  */
 @Service
 public class ServerAdminHandlerImpl implements ServerAdminHandler {
 
-	private final ServerSettingsRepository serverSettingsRepository;
+  private final ServerSettingsRepository serverSettingsRepository;
 
-	@Autowired
-	public ServerAdminHandlerImpl(ServerSettingsRepository serverSettingsRepository) {
-		this.serverSettingsRepository = serverSettingsRepository;
-	}
+  @Autowired
+  public ServerAdminHandlerImpl(ServerSettingsRepository serverSettingsRepository) {
+    this.serverSettingsRepository = serverSettingsRepository;
+  }
 
-	@Override
-	public Map<String, String> getServerSettings() {
-		return ServerSettingsConverter.TO_RESOURCE.apply(serverSettingsRepository.selectServerSettings());
-	}
+  @Override
+  public Map<String, String> getServerSettings() {
+    return ServerSettingsConverter.TO_RESOURCE.apply(
+        serverSettingsRepository.selectServerSettings());
+  }
 
-	@Override
-	public OperationCompletionRS saveAnalyticsSettings(AnalyticsResource analyticsResource) {
-		String analyticsType = analyticsResource.getType();
-		Map<String, ServerSettings> serverAnalyticsDetails = findServerSettings().entrySet()
-				.stream()
-				.filter(entry -> entry.getKey().startsWith(ANALYTICS_CONFIG_PREFIX))
-				.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
+  @Override
+  public OperationCompletionRS saveAnalyticsSettings(AnalyticsResource analyticsResource) {
+    String analyticsType = analyticsResource.getType();
+    Map<String, ServerSettings> serverAnalyticsDetails = findServerSettings().entrySet()
+        .stream()
+        .filter(entry -> entry.getKey().startsWith(ANALYTICS_CONFIG_PREFIX))
+        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
 
-		String formattedAnalyticsType = analyticsType.startsWith(ANALYTICS_CONFIG_PREFIX) ?
-				analyticsType :
-				ANALYTICS_CONFIG_PREFIX + analyticsType;
+    String formattedAnalyticsType = analyticsType.startsWith(ANALYTICS_CONFIG_PREFIX) ?
+        analyticsType :
+        ANALYTICS_CONFIG_PREFIX + analyticsType;
 
-		ServerSettings analyticsDetails = ofNullable(serverAnalyticsDetails.get(formattedAnalyticsType)).orElseGet(ServerSettings::new);
-		analyticsDetails.setKey(formattedAnalyticsType);
-		analyticsDetails.setValue(String.valueOf((ofNullable(analyticsResource.getEnabled()).orElse(false))));
+    ServerSettings analyticsDetails = ofNullable(
+        serverAnalyticsDetails.get(formattedAnalyticsType)).orElseGet(ServerSettings::new);
+    analyticsDetails.setKey(formattedAnalyticsType);
+    analyticsDetails.setValue(
+        String.valueOf((ofNullable(analyticsResource.getEnabled()).orElse(false))));
 
-		serverSettingsRepository.save(analyticsDetails);
-		return new OperationCompletionRS("Server Settings were successfully updated.");
-	}
+    serverSettingsRepository.save(analyticsDetails);
+    return new OperationCompletionRS("Server Settings were successfully updated.");
+  }
 
-	private Map<String, ServerSettings> findServerSettings() {
-		return serverSettingsRepository.selectServerSettings()
-				.stream()
-				.collect(toMap(ServerSettings::getKey, s -> s, (prev, curr) -> prev));
-	}
+  private Map<String, ServerSettings> findServerSettings() {
+    return serverSettingsRepository.selectServerSettings()
+        .stream()
+        .collect(toMap(ServerSettings::getKey, s -> s, (prev, curr) -> prev));
+  }
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/AnalyzerService.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/AnalyzerService.java
index 1cd5f8080f..e951489e27 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/AnalyzerService.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/AnalyzerService.java
@@ -18,7 +18,6 @@
 
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
-
 import java.util.List;
 
 /**
@@ -29,19 +28,19 @@
  */
 public interface AnalyzerService {
 
-	/**
-	 * Run analyzers for provided launch with concrete config
-	 *
-	 * @param launch         Launch
-	 * @param testItemIds    Ids of items to be analyzed
-	 * @param analyzerConfig Analyzer Configuration
-	 */
-	void runAnalyzers(Launch launch, List<Long> testItemIds, AnalyzerConfig analyzerConfig);
+  /**
+   * Run analyzers for provided launch with concrete config
+   *
+   * @param launch         Launch
+   * @param testItemIds    Ids of items to be analyzed
+   * @param analyzerConfig Analyzer Configuration
+   */
+  void runAnalyzers(Launch launch, List<Long> testItemIds, AnalyzerConfig analyzerConfig);
 
-	/**
-	 * Checks if any analyzer is available
-	 *
-	 * @return <code>true</code> if some exists
-	 */
-	boolean hasAnalyzers();
+  /**
+   * Checks if any analyzer is available
+   *
+   * @return <code>true</code> if some exists
+   */
+  boolean hasAnalyzers();
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/AnalyzerServiceAsync.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/AnalyzerServiceAsync.java
index af4e631c89..41252d8f4c 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/AnalyzerServiceAsync.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/AnalyzerServiceAsync.java
@@ -18,7 +18,6 @@
 
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
-
 import java.util.List;
 import java.util.concurrent.CompletableFuture;
 
@@ -27,21 +26,23 @@
  */
 public interface AnalyzerServiceAsync {
 
-	/**
-	 * Analyze history to find similar issues and updates items if some were found
-	 * Indexes investigated issues as well.
-	 *
-	 * @param launch         - Initial launch for history
-	 * @param testItemIds    - Prepared ids of test item for analyzing
-	 * @param analyzerConfig - Analyze mode
-	 */
-	CompletableFuture<Void> analyze(Launch launch, List<Long> testItemIds, AnalyzerConfig analyzerConfig);
+  /**
+   * Analyze history to find similar issues and updates items if some were found Indexes
+   * investigated issues as well.
+   *
+   * @param launch         - Initial launch for history
+   * @param testItemIds    - Prepared ids of test item for analyzing
+   * @param analyzerConfig - Analyze mode
+   * @return {@link CompletableFuture}
+   */
+  CompletableFuture<Void> analyze(Launch launch, List<Long> testItemIds,
+      AnalyzerConfig analyzerConfig);
 
-	/**
-	 * Checks if any analyzer is available
-	 *
-	 * @return <code>true</code> if some exists
-	 */
-	boolean hasAnalyzers();
+  /**
+   * Checks if any analyzer is available
+   *
+   * @return <code>true</code> if some exists
+   */
+  boolean hasAnalyzers();
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/LogIndexer.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/LogIndexer.java
index f95404d982..5efbd2efdf 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/LogIndexer.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/LogIndexer.java
@@ -19,7 +19,6 @@
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
-
 import java.util.Collection;
 import java.util.List;
 import java.util.concurrent.CompletableFuture;
@@ -31,69 +30,70 @@
  */
 public interface LogIndexer {
 
-	/**
-	 * Index logs with it's level greater than
-	 * {@link com.epam.ta.reportportal.entity.enums.LogLevel#ERROR}
-	 * for all given test items within launch
-	 *
-	 * @param projectId      - project id
-	 * @param analyzerConfig - anlayzer config
-	 * @return The count of indexed test items
-	 */
-	CompletableFuture<Long> index(Long projectId, AnalyzerConfig analyzerConfig);
+  /**
+   * Index logs with it's level greater than
+   * {@link com.epam.ta.reportportal.entity.enums.LogLevel#ERROR} for all given test items within
+   * launch
+   *
+   * @param projectId      - project id
+   * @param analyzerConfig - anlayzer config
+   * @return The count of indexed test items
+   */
+  CompletableFuture<Long> index(Long projectId, AnalyzerConfig analyzerConfig);
 
-	Long indexLaunchLogs(Launch launch, AnalyzerConfig analyzerConfig);
+  Long indexLaunchLogs(Launch launch, AnalyzerConfig analyzerConfig);
 
-	Long indexItemsLogs(Long projectId, Long launchId, List<Long> itemIds, AnalyzerConfig analyzerConfig);
+  Long indexItemsLogs(Long projectId, Long launchId, List<Long> itemIds,
+      AnalyzerConfig analyzerConfig);
 
-	/**
-	 * Delete index of specified project
-	 *
-	 * @param project Project/index
-	 */
-	void deleteIndex(Long project);
+  /**
+   * Delete index of specified project
+   *
+   * @param project Project/index
+   */
+  void deleteIndex(Long project);
 
-	/**
-	 * Remove documents with specified ids from index
-	 *
-	 * @param index Index to to be cleaned
-	 * @param ids   The {@link List} of the {@link com.epam.ta.reportportal.entity.log.Log#id}
-	 * @return Amount of deleted logs
-	 */
-	CompletableFuture<Long> cleanIndex(Long index, List<Long> ids);
+  /**
+   * Remove documents with specified ids from index
+   *
+   * @param index Index to to be cleaned
+   * @param ids   The {@link List} of the {@link com.epam.ta.reportportal.entity.log.Log#id}
+   * @return Amount of deleted logs
+   */
+  CompletableFuture<Long> cleanIndex(Long index, List<Long> ids);
 
-	/**
-	 * Async handle of updated items for indexing.
-	 *
-	 * @param projectId      Project id
-	 * @param analyzerConfig Analyzer config for indexing
-	 * @param testItems      Test items must be updated
-	 */
-	void indexDefectsUpdate(Long projectId, AnalyzerConfig analyzerConfig, List<TestItem> testItems);
+  /**
+   * Async handle of updated items for indexing.
+   *
+   * @param projectId      Project id
+   * @param analyzerConfig Analyzer config for indexing
+   * @param testItems      Test items must be updated
+   */
+  void indexDefectsUpdate(Long projectId, AnalyzerConfig analyzerConfig, List<TestItem> testItems);
 
-	/**
-	 * Handle of items that should be removed from index.
-	 *
-	 * @param projectId           Project id
-	 * @param itemsForIndexRemove Ids of items
-	 * @return number of removed items
-	 */
-	int indexItemsRemove(Long projectId, Collection<Long> itemsForIndexRemove);
+  /**
+   * Handle of items that should be removed from index.
+   *
+   * @param projectId           Project id
+   * @param itemsForIndexRemove Ids of items
+   * @return number of removed items
+   */
+  int indexItemsRemove(Long projectId, Collection<Long> itemsForIndexRemove);
 
-	/**
-	 * Async handle of items that should be removed from index.
-	 *
-	 * @param projectId           Project id
-	 * @param itemsForIndexRemove Ids of items
-	 */
-	void indexItemsRemoveAsync(Long projectId, Collection<Long> itemsForIndexRemove);
+  /**
+   * Async handle of items that should be removed from index.
+   *
+   * @param projectId           Project id
+   * @param itemsForIndexRemove Ids of items
+   */
+  void indexItemsRemoveAsync(Long projectId, Collection<Long> itemsForIndexRemove);
 
-	/**
-	 * Async handle of launches that should be removed from index.
-	 *
-	 * @param projectId              Project id
-	 * @param launchesForIndexRemove Ids of  launches
-	 */
-	void indexLaunchesRemove(Long projectId, Collection<Long> launchesForIndexRemove);
+  /**
+   * Async handle of launches that should be removed from index.
+   *
+   * @param projectId              Project id
+   * @param launchesForIndexRemove Ids of  launches
+   */
+  void indexLaunchesRemove(Long projectId, Collection<Long> launchesForIndexRemove);
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/SearchLogService.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/SearchLogService.java
index 259dbe5cea..e6913b8035 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/SearchLogService.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/SearchLogService.java
@@ -25,5 +25,6 @@
  */
 public interface SearchLogService {
 
-	Iterable<SearchLogRs> search(Long itemId, SearchLogRq request, ReportPortalUser.ProjectDetails projectDetails);
+  Iterable<SearchLogRs> search(Long itemId, SearchLogRq request,
+      ReportPortalUser.ProjectDetails projectDetails);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/AnalyzerServiceClient.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/AnalyzerServiceClient.java
index 4beb8d69cd..f6fdd5b19e 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/AnalyzerServiceClient.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/AnalyzerServiceClient.java
@@ -17,82 +17,79 @@
 package com.epam.ta.reportportal.core.analyzer.auto.client;
 
 import com.epam.ta.reportportal.core.analyzer.auto.client.impl.AnalyzerUtils;
+import com.epam.ta.reportportal.core.analyzer.auto.client.model.SuggestInfo;
+import com.epam.ta.reportportal.core.analyzer.auto.client.model.SuggestRq;
 import com.epam.ta.reportportal.core.analyzer.auto.client.model.cluster.ClusterData;
 import com.epam.ta.reportportal.core.analyzer.auto.client.model.cluster.GenerateClustersRq;
-import com.epam.ta.reportportal.core.analyzer.auto.client.model.SuggestRq;
-import com.epam.ta.reportportal.core.analyzer.auto.client.model.SuggestInfo;
 import com.epam.ta.reportportal.ws.model.analyzer.AnalyzedItemRs;
 import com.epam.ta.reportportal.ws.model.analyzer.IndexLaunch;
 import com.epam.ta.reportportal.ws.model.analyzer.SearchRq;
 import com.epam.ta.reportportal.ws.model.analyzer.SearchRs;
-
 import java.util.List;
 import java.util.Map;
 
 /**
- * Rabbit client for all log indexing/analysis services. Such services are those that have
- * tag {@link AnalyzerUtils#ANALYZER_KEY}
- * in service's metadata.
+ * Rabbit client for all log indexing/analysis services. Such services are those that have tag
+ * {@link AnalyzerUtils#ANALYZER_KEY} in service's metadata.
  * <p>
  * To define that service indexes/collecting data it should be indicated by tag
- * {@link AnalyzerUtils#ANALYZER_INDEX}
- * with <code>true</code> in metadata. If tag is not provided it is <code>false</code> by default
+ * {@link AnalyzerUtils#ANALYZER_INDEX} with <code>true</code> in metadata. If tag is not provided
+ * it is <code>false</code> by default
  * <p>
- * Items are analyzed in order of priority specified in tag
- * * {@link AnalyzerUtils#ANALYZER_PRIORITY} in metadata.
- * If priority is not provided service gets the lowest one. If several analyzers provided different
- * issues for one item, it would be overwritten with results of more priority
- * service.
+ * Items are analyzed in order of priority specified in tag *
+ * {@link AnalyzerUtils#ANALYZER_PRIORITY} in metadata. If priority is not provided service gets the
+ * lowest one. If several analyzers provided different issues for one item, it would be overwritten
+ * with results of more priority service.
  *
  * @author Ivan Sharamet
  * @author Pavel Bortnik
  */
 public interface AnalyzerServiceClient {
 
-	/**
-	 * Checks if any client is available
-	 *
-	 * @return <code>true</code> if some exists
-	 */
-	boolean hasClients();
+  /**
+   * Checks if any client is available
+   *
+   * @return <code>true</code> if some exists
+   */
+  boolean hasClients();
 
-	/**
-	 * Analyze launch
-	 *
-	 * @param rq Launch
-	 * @return Analyzed Launch
-	 */
-	Map<String, List<AnalyzedItemRs>> analyze(IndexLaunch rq);
+  /**
+   * Analyze launch
+   *
+   * @param rq Launch
+   * @return Analyzed Launch
+   */
+  Map<String, List<AnalyzedItemRs>> analyze(IndexLaunch rq);
 
-	/**
-	 * Searches logs with similar log message
-	 *
-	 * @param rq {@link SearchRq} request
-	 * @return {@link List<SearchRs>} of log ids
-	 */
-	List<SearchRs> searchLogs(SearchRq rq);
+  /**
+   * Searches logs with similar log message
+   *
+   * @param rq {@link SearchRq} request
+   * @return {@link List} of {@link SearchRs} of log ids
+   */
+  List<SearchRs> searchLogs(SearchRq rq);
 
-	/**
-	 * Removes suggest index
-	 *
-	 * @param projectId Project/index id
-	 */
-	void removeSuggest(Long projectId);
+  /**
+   * Removes suggest index
+   *
+   * @param projectId Project/index id
+   */
+  void removeSuggest(Long projectId);
 
-	/**
-	 * Searches suggests in analyzer for provided item
-	 *
-	 * @param rq {@link SuggestRq} request
-	 * @return {@link List<SuggestInfo>} list of founded suggests
-	 */
-	List<SuggestInfo> searchSuggests(SuggestRq rq);
+  /**
+   * Searches suggests in analyzer for provided item
+   *
+   * @param rq {@link SuggestRq} request
+   * @return {@link List} of {@link SuggestInfo} - list of founded suggests
+   */
+  List<SuggestInfo> searchSuggests(SuggestRq rq);
 
-	/**
-	 * Sends to analyzer info about user choice from suggests
-	 *
-	 * @param suggestInfos Info about user suggests
-	 */
-	void handleSuggestChoice(List<SuggestInfo> suggestInfos);
+  /**
+   * Sends to analyzer info about user choice from suggests
+   *
+   * @param suggestInfos Info about user suggests
+   */
+  void handleSuggestChoice(List<SuggestInfo> suggestInfos);
 
-	ClusterData generateClusters(GenerateClustersRq generateClustersRq);
+  ClusterData generateClusters(GenerateClustersRq generateClustersRq);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/IndexerServiceClient.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/IndexerServiceClient.java
index f79f938fc3..5a31fdde23 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/IndexerServiceClient.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/IndexerServiceClient.java
@@ -17,7 +17,6 @@
 package com.epam.ta.reportportal.core.analyzer.auto.client;
 
 import com.epam.ta.reportportal.ws.model.analyzer.IndexLaunch;
-
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
@@ -27,59 +26,62 @@
  */
 public interface IndexerServiceClient {
 
-	/**
-	 * Remove documents with specified ids from index
-	 *
-	 * @param index Index to to be cleaned
-	 * @param ids   Document ids to be deleted from index
-	 * @return Amount of deleted logs
-	 */
-	Long cleanIndex(Long index, List<Long> ids);
+  /**
+   * Remove documents with specified ids from index
+   *
+   * @param index Index to to be cleaned
+   * @param ids   Document ids to be deleted from index
+   * @return Amount of deleted logs
+   */
+  Long cleanIndex(Long index, List<Long> ids);
 
-	/**
-	 * Delete index
-	 *
-	 * @param index Index to be deleted
-	 */
-	void deleteIndex(Long index);
+  /**
+   * Delete index
+   *
+   * @param index Index to be deleted
+   */
+  void deleteIndex(Long index);
 
-	/**
-	 * Index list of launches
-	 *
-	 * @param rq Launches
-	 * @return Count of indexed test items
-	 */
-	Long index(List<IndexLaunch> rq);
+  /**
+   * Index list of launches
+   *
+   * @param rq Launches
+   */
+  void index(List<IndexLaunch> rq);
 
-	/**
-	 * Sends a message to the queue with a map of items which must be updated with a new issue type
-	 *
-	 * @param itemsForIndexUpdate Pair of itemId - issue type
-	 * @return List of missed items in analyzer
-	 */
-	List<Long> indexDefectsUpdate(Long projectId, Map<Long, String> itemsForIndexUpdate);
+  /**
+   * Sends a message to the queue with a map of items which must be updated with a new issue type
+   *
+   * @param projectId Project id
+   * @param itemsForIndexUpdate Pair of itemId - issue type
+   * @return List of missed items in analyzer
+   */
+  List<Long> indexDefectsUpdate(Long projectId, Map<Long, String> itemsForIndexUpdate);
 
-	/**
-	 * Sends a message to the queue with a list of items which must be removed from index
-	 * and receive number of removed objects as a response.
-	 *
-	 * @param itemsForIndexRemove List of item ids
-	 * @return number of removed objects
-	 */
-	Integer indexItemsRemove(Long projectId, Collection<Long> itemsForIndexRemove);
+  /**
+   * Sends a message to the queue with a list of items which must be removed from index and receive
+   * number of removed objects as a response.
+   *
+   * @param projectId Project id
+   * @param itemsForIndexRemove List of item ids
+   * @return number of removed objects
+   */
+  Integer indexItemsRemove(Long projectId, Collection<Long> itemsForIndexRemove);
 
-	/**
-	 * Sends a message to the queue with a list of items which must be removed from index
-	 *
-	 * @param itemsForIndexRemove List of item ids
-	 */
-	void indexItemsRemoveAsync(Long projectId, Collection<Long> itemsForIndexRemove);
+  /**
+   * Sends a message to the queue with a list of items which must be removed from index
+   *
+   * @param projectId Project id
+   * @param itemsForIndexRemove List of item ids
+   */
+  void indexItemsRemoveAsync(Long projectId, Collection<Long> itemsForIndexRemove);
 
-	/**
-	 * Sends a message to the queue with a list of launches which must be removed from index
-	 *
-	 * @param launchesForIndexRemove List of launhces ids
-	 */
-	void indexLaunchesRemove(Long projectId, Collection<Long> launchesForIndexRemove);
+  /**
+   * Sends a message to the queue with a list of launches which must be removed from index
+   *
+   * @param projectId Project id
+   * @param launchesForIndexRemove List of launhces ids
+   */
+  void indexLaunchesRemove(Long projectId, Collection<Long> launchesForIndexRemove);
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/RabbitMqManagementClient.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/RabbitMqManagementClient.java
index db429a7c3c..81e02ec7c7 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/RabbitMqManagementClient.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/RabbitMqManagementClient.java
@@ -17,7 +17,6 @@
 package com.epam.ta.reportportal.core.analyzer.auto.client;
 
 import com.rabbitmq.http.client.domain.ExchangeInfo;
-
 import java.util.List;
 
 /**
@@ -25,6 +24,6 @@
  */
 public interface RabbitMqManagementClient {
 
-	List<ExchangeInfo> getAnalyzerExchangesInfo();
+  List<ExchangeInfo> getAnalyzerExchangesInfo();
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/impl/AnalyzerServiceClientImpl.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/impl/AnalyzerServiceClientImpl.java
index c44afe47e4..69de662e08 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/impl/AnalyzerServiceClientImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/impl/AnalyzerServiceClientImpl.java
@@ -16,12 +16,18 @@
 
 package com.epam.ta.reportportal.core.analyzer.auto.client.impl;
 
+import static com.epam.ta.reportportal.core.analyzer.auto.client.impl.AnalyzerUtils.DOES_SUPPORT_CLUSTER;
+import static com.epam.ta.reportportal.core.analyzer.auto.client.impl.AnalyzerUtils.DOES_SUPPORT_SEARCH;
+import static com.epam.ta.reportportal.core.analyzer.auto.client.impl.AnalyzerUtils.DOES_SUPPORT_SUGGEST;
+import static com.epam.ta.reportportal.core.analyzer.auto.client.impl.AnalyzerUtils.EXCHANGE_PRIORITY;
+import static java.util.stream.Collectors.toList;
+
 import com.epam.ta.reportportal.core.analyzer.auto.client.AnalyzerServiceClient;
 import com.epam.ta.reportportal.core.analyzer.auto.client.RabbitMqManagementClient;
-import com.epam.ta.reportportal.core.analyzer.auto.client.model.cluster.ClusterData;
-import com.epam.ta.reportportal.core.analyzer.auto.client.model.cluster.GenerateClustersRq;
 import com.epam.ta.reportportal.core.analyzer.auto.client.model.SuggestInfo;
 import com.epam.ta.reportportal.core.analyzer.auto.client.model.SuggestRq;
+import com.epam.ta.reportportal.core.analyzer.auto.client.model.cluster.ClusterData;
+import com.epam.ta.reportportal.core.analyzer.auto.client.model.cluster.GenerateClustersRq;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.epam.ta.reportportal.ws.model.analyzer.AnalyzedItemRs;
@@ -29,6 +35,13 @@
 import com.epam.ta.reportportal.ws.model.analyzer.SearchRq;
 import com.epam.ta.reportportal.ws.model.analyzer.SearchRs;
 import com.rabbitmq.http.client.domain.ExchangeInfo;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Predicate;
 import org.springframework.amqp.rabbit.core.RabbitTemplate;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
@@ -37,122 +50,126 @@
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
-import java.util.*;
-import java.util.function.Predicate;
-
-import static com.epam.ta.reportportal.core.analyzer.auto.client.impl.AnalyzerUtils.*;
-import static java.util.stream.Collectors.toList;
-
 @Service
 public class AnalyzerServiceClientImpl implements AnalyzerServiceClient {
 
-	private static final String ANALYZE_ROUTE = "analyze";
-	private static final String SEARCH_ROUTE = "search";
-	private static final String SUGGEST_ROUTE = "suggest";
-	private static final String SUGGEST_INFO_ROUTE = "index_suggest_info";
-	private static final String REMOVE_SUGGEST_ROUTE = "remove_suggest_info";
-	private static final String CLUSTER_ROUTE = "cluster";
-
-	private final RabbitMqManagementClient rabbitMqManagementClient;
-
-	private final RabbitTemplate rabbitTemplate;
-
-	private String virtualHost;
-
-	@Autowired
-	public AnalyzerServiceClientImpl(RabbitMqManagementClient rabbitMqManagementClient,
-			@Qualifier("analyzerRabbitTemplate") RabbitTemplate rabbitTemplate, @Value("${rp.amqp.analyzer-vhost}") String virtualHost) {
-		this.rabbitMqManagementClient = rabbitMqManagementClient;
-		this.rabbitTemplate = rabbitTemplate;
-		this.virtualHost = virtualHost;
-	}
-
-	@Override
-	public boolean hasClients() {
-		return rabbitMqManagementClient.getAnalyzerExchangesInfo().size() != 0;
-	}
-
-	@Override
-	public Map<String, List<AnalyzedItemRs>> analyze(IndexLaunch rq) {
-		List<ExchangeInfo> analyzerExchanges = rabbitMqManagementClient.getAnalyzerExchangesInfo();
-		Map<String, List<AnalyzedItemRs>> resultMap = new HashMap<>(analyzerExchanges.size());
-		analyzerExchanges.forEach(exchange -> analyze(rq, resultMap, exchange));
-		return resultMap;
-	}
-
-	@Override
-	public List<SearchRs> searchLogs(SearchRq rq) {
-		String exchangeName = resolveExchangeName(DOES_SUPPORT_SEARCH)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
-						"There are no analyzer services with search logs support deployed."
-				));
-		return rabbitTemplate.convertSendAndReceiveAsType(exchangeName, SEARCH_ROUTE, rq, new ParameterizedTypeReference<>() {
-		});
-	}
-
-	@Override
-	public void removeSuggest(Long projectId) {
-		resolveExchangeName(DOES_SUPPORT_SUGGEST)
-				.ifPresent(suggestExchange -> rabbitTemplate.convertAndSend(suggestExchange, REMOVE_SUGGEST_ROUTE, projectId));
-	}
-
-	@Override
-	public List<SuggestInfo> searchSuggests(SuggestRq rq) {
-		return rabbitTemplate.convertSendAndReceiveAsType(getSuggestExchangeName(), SUGGEST_ROUTE, rq, new ParameterizedTypeReference<>() {
-		});
-	}
-
-	@Override
-	public void handleSuggestChoice(List<SuggestInfo> suggestInfos) {
-		rabbitTemplate.convertAndSend(getSuggestExchangeName(), SUGGEST_INFO_ROUTE, suggestInfos);
-	}
-
-	@Override
-	public ClusterData generateClusters(GenerateClustersRq generateClustersRq) {
-		final String exchangeName = resolveExchangeName(DOES_SUPPORT_CLUSTER).orElseThrow(() -> new ReportPortalException(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
-				"There are no analyzer services with clusters creation support deployed."
-		));
-		return rabbitTemplate.convertSendAndReceiveAsType(exchangeName, CLUSTER_ROUTE, generateClustersRq, new ParameterizedTypeReference<>() {
-		});
-	}
-
-	private Optional<String> resolveExchangeName(Predicate<ExchangeInfo> supportCondition) {
-		return rabbitMqManagementClient.getAnalyzerExchangesInfo()
-				.stream()
-				.filter(supportCondition)
-				.min(Comparator.comparingInt(EXCHANGE_PRIORITY))
-				.map(ExchangeInfo::getName);
-	}
-
-	private String getSuggestExchangeName() {
-		return resolveExchangeName(DOES_SUPPORT_SUGGEST)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
-						"There are no analyzer services with suggest items support deployed."
-				));
-	}
-
-	private void analyze(IndexLaunch rq, Map<String, List<AnalyzedItemRs>> resultMap, ExchangeInfo exchangeInfo) {
-		List<AnalyzedItemRs> result = rabbitTemplate.convertSendAndReceiveAsType(exchangeInfo.getName(),
-				ANALYZE_ROUTE,
-				Collections.singletonList(rq),
-				new ParameterizedTypeReference<>() {
-				}
-		);
-		if (!CollectionUtils.isEmpty(result)) {
-			resultMap.put((String) exchangeInfo.getArguments().getOrDefault(virtualHost, exchangeInfo.getName()), result);
-			removeAnalyzedFromRq(rq, result);
-		}
-	}
-
-	/**
-	 * Removes form rq analyzed items to make rq for the next analyzer.
-	 *
-	 * @param rq       Request
-	 * @param analyzed List of analyzer items
-	 */
-	private void removeAnalyzedFromRq(IndexLaunch rq, List<AnalyzedItemRs> analyzed) {
-		List<Long> analyzedItemIds = analyzed.stream().map(AnalyzedItemRs::getItemId).collect(toList());
-		rq.getTestItems().removeIf(it -> analyzedItemIds.contains(it.getTestItemId()));
-	}
+  private static final String ANALYZE_ROUTE = "analyze";
+  private static final String SEARCH_ROUTE = "search";
+  private static final String SUGGEST_ROUTE = "suggest";
+  private static final String SUGGEST_INFO_ROUTE = "index_suggest_info";
+  private static final String REMOVE_SUGGEST_ROUTE = "remove_suggest_info";
+  private static final String CLUSTER_ROUTE = "cluster";
+
+  private final RabbitMqManagementClient rabbitMqManagementClient;
+
+  private final RabbitTemplate rabbitTemplate;
+
+  private String virtualHost;
+
+  @Autowired
+  public AnalyzerServiceClientImpl(RabbitMqManagementClient rabbitMqManagementClient,
+      @Qualifier("analyzerRabbitTemplate") RabbitTemplate rabbitTemplate,
+      @Value("${rp.amqp.analyzer-vhost}") String virtualHost) {
+    this.rabbitMqManagementClient = rabbitMqManagementClient;
+    this.rabbitTemplate = rabbitTemplate;
+    this.virtualHost = virtualHost;
+  }
+
+  @Override
+  public boolean hasClients() {
+    return rabbitMqManagementClient.getAnalyzerExchangesInfo().size() != 0;
+  }
+
+  @Override
+  public Map<String, List<AnalyzedItemRs>> analyze(IndexLaunch rq) {
+    List<ExchangeInfo> analyzerExchanges = rabbitMqManagementClient.getAnalyzerExchangesInfo();
+    Map<String, List<AnalyzedItemRs>> resultMap = new HashMap<>(analyzerExchanges.size());
+    analyzerExchanges.forEach(exchange -> analyze(rq, resultMap, exchange));
+    return resultMap;
+  }
+
+  @Override
+  public List<SearchRs> searchLogs(SearchRq rq) {
+    String exchangeName = resolveExchangeName(DOES_SUPPORT_SEARCH)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
+            "There are no analyzer services with search logs support deployed."
+        ));
+    return rabbitTemplate.convertSendAndReceiveAsType(exchangeName, SEARCH_ROUTE, rq,
+        new ParameterizedTypeReference<>() {
+        });
+  }
+
+  @Override
+  public void removeSuggest(Long projectId) {
+    resolveExchangeName(DOES_SUPPORT_SUGGEST)
+        .ifPresent(
+            suggestExchange -> rabbitTemplate.convertAndSend(suggestExchange, REMOVE_SUGGEST_ROUTE,
+                projectId));
+  }
+
+  @Override
+  public List<SuggestInfo> searchSuggests(SuggestRq rq) {
+    return rabbitTemplate.convertSendAndReceiveAsType(getSuggestExchangeName(), SUGGEST_ROUTE, rq,
+        new ParameterizedTypeReference<>() {
+        });
+  }
+
+  @Override
+  public void handleSuggestChoice(List<SuggestInfo> suggestInfos) {
+    rabbitTemplate.convertAndSend(getSuggestExchangeName(), SUGGEST_INFO_ROUTE, suggestInfos);
+  }
+
+  @Override
+  public ClusterData generateClusters(GenerateClustersRq generateClustersRq) {
+    final String exchangeName = resolveExchangeName(DOES_SUPPORT_CLUSTER).orElseThrow(
+        () -> new ReportPortalException(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
+            "There are no analyzer services with clusters creation support deployed."
+        ));
+    return rabbitTemplate.convertSendAndReceiveAsType(exchangeName, CLUSTER_ROUTE,
+        generateClustersRq, new ParameterizedTypeReference<>() {
+        });
+  }
+
+  private Optional<String> resolveExchangeName(Predicate<ExchangeInfo> supportCondition) {
+    return rabbitMqManagementClient.getAnalyzerExchangesInfo()
+        .stream()
+        .filter(supportCondition)
+        .min(Comparator.comparingInt(EXCHANGE_PRIORITY))
+        .map(ExchangeInfo::getName);
+  }
+
+  private String getSuggestExchangeName() {
+    return resolveExchangeName(DOES_SUPPORT_SUGGEST)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
+            "There are no analyzer services with suggest items support deployed."
+        ));
+  }
+
+  private void analyze(IndexLaunch rq, Map<String, List<AnalyzedItemRs>> resultMap,
+      ExchangeInfo exchangeInfo) {
+    List<AnalyzedItemRs> result = rabbitTemplate.convertSendAndReceiveAsType(exchangeInfo.getName(),
+        ANALYZE_ROUTE,
+        Collections.singletonList(rq),
+        new ParameterizedTypeReference<>() {
+        }
+    );
+    if (!CollectionUtils.isEmpty(result)) {
+      resultMap.put(
+          (String) exchangeInfo.getArguments().getOrDefault(virtualHost, exchangeInfo.getName()),
+          result);
+      removeAnalyzedFromRq(rq, result);
+    }
+  }
+
+  /**
+   * Removes form rq analyzed items to make rq for the next analyzer.
+   *
+   * @param rq       Request
+   * @param analyzed List of analyzer items
+   */
+  private void removeAnalyzedFromRq(IndexLaunch rq, List<AnalyzedItemRs> analyzed) {
+    List<Long> analyzedItemIds = analyzed.stream().map(AnalyzedItemRs::getItemId).collect(toList());
+    rq.getTestItems().removeIf(it -> analyzedItemIds.contains(it.getTestItemId()));
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/impl/AnalyzerUtils.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/impl/AnalyzerUtils.java
index 98ace65552..744e235deb 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/impl/AnalyzerUtils.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/impl/AnalyzerUtils.java
@@ -16,59 +16,55 @@
 
 package com.epam.ta.reportportal.core.analyzer.auto.client.impl;
 
-import com.rabbitmq.http.client.domain.ExchangeInfo;
-import org.apache.commons.lang3.BooleanUtils;
-import org.apache.commons.lang3.math.NumberUtils;
+import static java.util.Optional.ofNullable;
 
+import com.rabbitmq.http.client.domain.ExchangeInfo;
 import java.util.function.Predicate;
 import java.util.function.ToIntFunction;
-
-import static java.util.Optional.ofNullable;
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.commons.lang3.math.NumberUtils;
 
 /**
  * @author Pavel Bortnik
  */
 public final class AnalyzerUtils {
 
-	static final String ANALYZER_KEY = "analyzer";
-	static final String ANALYZER_PRIORITY = "analyzer_priority";
-	static final String ANALYZER_INDEX = "analyzer_index";
-	static final String ANALYZER_LOG_SEARCH = "analyzer_log_search";
-	static final String ANALYZER_SUGGEST = "analyzer_suggest";
-	static final String ANALYZER_CLUSTER = "analyzer_cluster";
+  static final String ANALYZER_KEY = "analyzer";
+  static final String ANALYZER_PRIORITY = "analyzer_priority";
+  static final String ANALYZER_INDEX = "analyzer_index";
+  static final String ANALYZER_LOG_SEARCH = "analyzer_log_search";
+  static final String ANALYZER_SUGGEST = "analyzer_suggest";
+  static final String ANALYZER_CLUSTER = "analyzer_cluster";
 
-	/**
-	 * Comparing by client service priority
-	 */
-	static final ToIntFunction<ExchangeInfo> EXCHANGE_PRIORITY = it -> ofNullable(it.getArguments()
-			.get(ANALYZER_PRIORITY)).map(val -> NumberUtils.toInt(val.toString(), Integer.MAX_VALUE)).orElse(Integer.MAX_VALUE);
+  /**
+   * Comparing by client service priority
+   */
+  static final ToIntFunction<ExchangeInfo> EXCHANGE_PRIORITY = it -> ofNullable(it.getArguments()
+      .get(ANALYZER_PRIORITY)).map(val -> NumberUtils.toInt(val.toString(), Integer.MAX_VALUE))
+      .orElse(Integer.MAX_VALUE);
 
-	/**
-	 * Checks if service support items indexing. <code>false</code>
-	 * by default
-	 */
-	static final Predicate<ExchangeInfo> DOES_SUPPORT_INDEX = it -> ofNullable(it.getArguments()
-			.get(ANALYZER_INDEX)).map(val -> BooleanUtils.toBoolean(val.toString())).orElse(false);
+  /**
+   * Checks if service support items indexing. <code>false</code> by default
+   */
+  static final Predicate<ExchangeInfo> DOES_SUPPORT_INDEX = it -> ofNullable(it.getArguments()
+      .get(ANALYZER_INDEX)).map(val -> BooleanUtils.toBoolean(val.toString())).orElse(false);
 
-	/**
-	 * Checks if service support logs searching. <code>false</code>
-	 * by default
-	 */
-	static final Predicate<ExchangeInfo> DOES_SUPPORT_SEARCH = it -> ofNullable(it.getArguments()
-			.get(ANALYZER_LOG_SEARCH)).map(val -> BooleanUtils.toBoolean(val.toString())).orElse(false);
+  /**
+   * Checks if service support logs searching. <code>false</code> by default
+   */
+  static final Predicate<ExchangeInfo> DOES_SUPPORT_SEARCH = it -> ofNullable(it.getArguments()
+      .get(ANALYZER_LOG_SEARCH)).map(val -> BooleanUtils.toBoolean(val.toString())).orElse(false);
 
-	/**
-	 * Checks if service support logs searching. <code>false</code>
-	 * by default
-	 */
-	static final Predicate<ExchangeInfo> DOES_SUPPORT_SUGGEST = it -> ofNullable(it.getArguments()
-			.get(ANALYZER_SUGGEST)).map(val -> BooleanUtils.toBoolean(val.toString())).orElse(false);
+  /**
+   * Checks if service support logs searching. <code>false</code> by default
+   */
+  static final Predicate<ExchangeInfo> DOES_SUPPORT_SUGGEST = it -> ofNullable(it.getArguments()
+      .get(ANALYZER_SUGGEST)).map(val -> BooleanUtils.toBoolean(val.toString())).orElse(false);
 
-	/**
-	 * Checks if service support logs cluster creation. <code>false</code>
-	 * by default
-	 */
-	static final Predicate<ExchangeInfo> DOES_SUPPORT_CLUSTER = it -> ofNullable(it.getArguments()
-			.get(ANALYZER_CLUSTER)).map(val -> BooleanUtils.toBoolean(val.toString())).orElse(false);
+  /**
+   * Checks if service support logs cluster creation. <code>false</code> by default
+   */
+  static final Predicate<ExchangeInfo> DOES_SUPPORT_CLUSTER = it -> ofNullable(it.getArguments()
+      .get(ANALYZER_CLUSTER)).map(val -> BooleanUtils.toBoolean(val.toString())).orElse(false);
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/impl/IndexerServiceClientImpl.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/impl/IndexerServiceClientImpl.java
index ccc3501e40..6f5450f6e2 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/impl/IndexerServiceClientImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/impl/IndexerServiceClientImpl.java
@@ -16,6 +16,11 @@
 
 package com.epam.ta.reportportal.core.analyzer.auto.client.impl;
 
+import static com.epam.ta.reportportal.core.analyzer.auto.client.impl.AnalyzerUtils.DOES_SUPPORT_INDEX;
+import static com.epam.ta.reportportal.core.analyzer.auto.client.impl.AnalyzerUtils.EXCHANGE_PRIORITY;
+import static java.util.Optional.ofNullable;
+import static java.util.stream.Collectors.toList;
+
 import com.epam.ta.reportportal.core.analyzer.auto.client.IndexerServiceClient;
 import com.epam.ta.reportportal.core.analyzer.auto.client.RabbitMqManagementClient;
 import com.epam.ta.reportportal.core.analyzer.auto.client.model.IndexDefectsUpdate;
@@ -24,6 +29,13 @@
 import com.epam.ta.reportportal.ws.model.analyzer.CleanIndexRq;
 import com.epam.ta.reportportal.ws.model.analyzer.IndexLaunch;
 import com.epam.ta.reportportal.ws.model.analyzer.IndexRs;
+import java.util.AbstractMap;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.amqp.rabbit.core.RabbitTemplate;
@@ -31,144 +43,128 @@
 import org.springframework.core.ParameterizedTypeReference;
 import org.springframework.stereotype.Service;
 
-import java.util.*;
-import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.core.analyzer.auto.client.impl.AnalyzerUtils.DOES_SUPPORT_INDEX;
-import static com.epam.ta.reportportal.core.analyzer.auto.client.impl.AnalyzerUtils.EXCHANGE_PRIORITY;
-import static java.util.Optional.ofNullable;
-import static java.util.stream.Collectors.toList;
-
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
  */
 @Service
 public class IndexerServiceClientImpl implements IndexerServiceClient {
 
-	private static final Logger LOGGER = LoggerFactory.getLogger(IndexerServiceClient.class);
-	private static final String INDEX_ROUTE = "index";
-	static final String DEFECT_UPDATE_ROUTE = "defect_update";
-	static final String ITEM_REMOVE_ROUTE = "item_remove";
-	static final String LAUNCH_REMOVE_ROUTE = "launch_remove";
-	private static final String NAMESPACE_FINDER_ROUTE = "namespace_finder";
-	static final String DELETE_ROUTE = "delete";
-	private static final String CLEAN_ROUTE = "clean";
-	private static final Integer DELETE_INDEX_SUCCESS_CODE = 1;
-
-	private final RabbitMqManagementClient rabbitMqManagementClient;
-
-	private final RabbitTemplate rabbitTemplate;
-
-	public IndexerServiceClientImpl(RabbitMqManagementClient rabbitMqManagementClient,
-			@Qualifier("analyzerRabbitTemplate") RabbitTemplate rabbitTemplate) {
-		this.rabbitMqManagementClient = rabbitMqManagementClient;
-		this.rabbitTemplate = rabbitTemplate;
-	}
-
-	@Override
-	public Long index(List<IndexLaunch> rq) {
-		return rabbitMqManagementClient.getAnalyzerExchangesInfo().stream().filter(DOES_SUPPORT_INDEX).map(exchange -> {
-			rabbitTemplate.convertAndSend(exchange.getName(), NAMESPACE_FINDER_ROUTE, rq);
-			return rabbitTemplate.convertSendAndReceiveAsType(exchange.getName(),
-					INDEX_ROUTE,
-					rq,
-					new ParameterizedTypeReference<IndexRs>() {
-					}
-			);
-		}).mapToLong(it -> {
-			if (Objects.nonNull(it)) {
-				return it.getTook();
-			}
-			return 0;
-		}).sum();
-	}
-
-	@Override
-	public List<Long> indexDefectsUpdate(Long projectId, Map<Long, String> itemsForIndexUpdate) {
-		return rabbitMqManagementClient.getAnalyzerExchangesInfo()
-				.stream()
-				.filter(DOES_SUPPORT_INDEX)
-				.flatMap(exchange -> ofNullable(rabbitTemplate.convertSendAndReceiveAsType(exchange.getName(),
-						DEFECT_UPDATE_ROUTE,
-						new IndexDefectsUpdate(projectId, itemsForIndexUpdate),
-						new ParameterizedTypeReference<List<Long>>() {
-						}
-				)).orElse(Collections.emptyList()).stream())
-				.collect(toList());
-	}
-
-	@Override
-	public Integer indexItemsRemove(Long projectId, Collection<Long> itemsForIndexRemove) {
-		return rabbitMqManagementClient.getAnalyzerExchangesInfo()
-				.stream()
-				.filter(DOES_SUPPORT_INDEX)
-				.map(exchange -> ofNullable(rabbitTemplate.convertSendAndReceiveAsType(exchange.getName(),
-						ITEM_REMOVE_ROUTE,
-						new IndexItemsRemove(projectId, itemsForIndexRemove),
-						new ParameterizedTypeReference<Integer>() {
-						}
-				)).orElse(0))
-				.mapToInt(Integer::intValue)
-				.sum();
-	}
-
-	@Override
-	public void indexItemsRemoveAsync(Long projectId, Collection<Long> itemsForIndexRemove) {
-		rabbitMqManagementClient.getAnalyzerExchangesInfo()
-				.stream()
-				.filter(DOES_SUPPORT_INDEX)
-				.forEach(exchange -> rabbitTemplate.convertAndSend(exchange.getName(),
-						ITEM_REMOVE_ROUTE,
-						new IndexItemsRemove(projectId, itemsForIndexRemove)
-				));
-	}
-
-	@Override
-	public void indexLaunchesRemove(Long projectId, Collection<Long> launchesForIndexRemove) {
-		rabbitMqManagementClient.getAnalyzerExchangesInfo()
-				.stream()
-				.filter(DOES_SUPPORT_INDEX)
-				.forEach(exchange -> rabbitTemplate.convertAndSend(exchange.getName(),
-						LAUNCH_REMOVE_ROUTE,
-						new IndexLaunchRemove(projectId, launchesForIndexRemove)
-				));
-	}
-
-	@Override
-	public Long cleanIndex(Long index, List<Long> ids) {
-		Map<Integer, Long> priorityToCleanedLogsCountMapping = rabbitMqManagementClient.getAnalyzerExchangesInfo()
-				.stream()
-				.collect(Collectors.toMap(EXCHANGE_PRIORITY::applyAsInt,
-						exchange -> rabbitTemplate.convertSendAndReceiveAsType(exchange.getName(),
-								CLEAN_ROUTE,
-								new CleanIndexRq(index, ids),
-								new ParameterizedTypeReference<>() {
-								}
-						)
-				));
-		return priorityToCleanedLogsCountMapping.entrySet()
-				.stream()
-				.min(Map.Entry.comparingByKey())
-				.orElseGet(() -> new AbstractMap.SimpleEntry<>(0, 0L))
-				.getValue();
-	}
-
-	@Override
-	public void deleteIndex(Long index) {
-		rabbitMqManagementClient.getAnalyzerExchangesInfo()
-				.stream()
-				.map(exchange -> rabbitTemplate.convertSendAndReceiveAsType(exchange.getName(),
-						DELETE_ROUTE,
-						index,
-						new ParameterizedTypeReference<Integer>() {
-						}
-				))
-				.forEach(it -> {
-					if (DELETE_INDEX_SUCCESS_CODE.equals(it)) {
-						LOGGER.info("Successfully deleted index '{}'", index);
-					} else {
-						LOGGER.error("Error deleting index '{}'", index);
-					}
-				});
-	}
+  private static final Logger LOGGER = LoggerFactory.getLogger(IndexerServiceClient.class);
+  private static final String INDEX_ROUTE = "index";
+  static final String DEFECT_UPDATE_ROUTE = "defect_update";
+  static final String ITEM_REMOVE_ROUTE = "item_remove";
+  static final String LAUNCH_REMOVE_ROUTE = "launch_remove";
+  private static final String NAMESPACE_FINDER_ROUTE = "namespace_finder";
+  static final String DELETE_ROUTE = "delete";
+  private static final String CLEAN_ROUTE = "clean";
+  private static final Integer DELETE_INDEX_SUCCESS_CODE = 1;
+
+  private final RabbitMqManagementClient rabbitMqManagementClient;
+
+  private final RabbitTemplate rabbitTemplate;
+
+  public IndexerServiceClientImpl(RabbitMqManagementClient rabbitMqManagementClient,
+      @Qualifier("analyzerRabbitTemplate") RabbitTemplate rabbitTemplate) {
+    this.rabbitMqManagementClient = rabbitMqManagementClient;
+    this.rabbitTemplate = rabbitTemplate;
+  }
+
+  @Override
+  public void index(List<IndexLaunch> rq) {
+    rabbitMqManagementClient.getAnalyzerExchangesInfo().stream().filter(DOES_SUPPORT_INDEX)
+        .forEach(exchange -> {
+          rabbitTemplate.convertAndSend(exchange.getName(), NAMESPACE_FINDER_ROUTE, rq);
+          rabbitTemplate.convertAndSend(exchange.getName(), INDEX_ROUTE, rq);
+        });
+  }
+
+  @Override
+  public List<Long> indexDefectsUpdate(Long projectId, Map<Long, String> itemsForIndexUpdate) {
+    return rabbitMqManagementClient.getAnalyzerExchangesInfo()
+        .stream()
+        .filter(DOES_SUPPORT_INDEX)
+        .flatMap(
+            exchange -> ofNullable(rabbitTemplate.convertSendAndReceiveAsType(exchange.getName(),
+                DEFECT_UPDATE_ROUTE,
+                new IndexDefectsUpdate(projectId, itemsForIndexUpdate),
+                new ParameterizedTypeReference<List<Long>>() {
+                }
+            )).orElse(Collections.emptyList()).stream())
+        .collect(toList());
+  }
+
+  @Override
+  public Integer indexItemsRemove(Long projectId, Collection<Long> itemsForIndexRemove) {
+    return rabbitMqManagementClient.getAnalyzerExchangesInfo()
+        .stream()
+        .filter(DOES_SUPPORT_INDEX)
+        .map(exchange -> ofNullable(rabbitTemplate.convertSendAndReceiveAsType(exchange.getName(),
+            ITEM_REMOVE_ROUTE,
+            new IndexItemsRemove(projectId, itemsForIndexRemove),
+            new ParameterizedTypeReference<Integer>() {
+            }
+        )).orElse(0))
+        .mapToInt(Integer::intValue)
+        .sum();
+  }
+
+  @Override
+  public void indexItemsRemoveAsync(Long projectId, Collection<Long> itemsForIndexRemove) {
+    rabbitMqManagementClient.getAnalyzerExchangesInfo()
+        .stream()
+        .filter(DOES_SUPPORT_INDEX)
+        .forEach(exchange -> rabbitTemplate.convertAndSend(exchange.getName(),
+            ITEM_REMOVE_ROUTE,
+            new IndexItemsRemove(projectId, itemsForIndexRemove)
+        ));
+  }
+
+  @Override
+  public void indexLaunchesRemove(Long projectId, Collection<Long> launchesForIndexRemove) {
+    rabbitMqManagementClient.getAnalyzerExchangesInfo()
+        .stream()
+        .filter(DOES_SUPPORT_INDEX)
+        .forEach(exchange -> rabbitTemplate.convertAndSend(exchange.getName(),
+            LAUNCH_REMOVE_ROUTE,
+            new IndexLaunchRemove(projectId, launchesForIndexRemove)
+        ));
+  }
+
+  @Override
+  public Long cleanIndex(Long index, List<Long> ids) {
+    Map<Integer, Long> priorityToCleanedLogsCountMapping = rabbitMqManagementClient.getAnalyzerExchangesInfo()
+        .stream()
+        .collect(Collectors.toMap(EXCHANGE_PRIORITY::applyAsInt,
+            exchange -> rabbitTemplate.convertSendAndReceiveAsType(exchange.getName(),
+                CLEAN_ROUTE,
+                new CleanIndexRq(index, ids),
+                new ParameterizedTypeReference<>() {
+                }
+            )
+        ));
+    return priorityToCleanedLogsCountMapping.entrySet()
+        .stream()
+        .min(Map.Entry.comparingByKey())
+        .orElseGet(() -> new AbstractMap.SimpleEntry<>(0, 0L))
+        .getValue();
+  }
+
+  @Override
+  public void deleteIndex(Long index) {
+    rabbitMqManagementClient.getAnalyzerExchangesInfo()
+        .stream()
+        .map(exchange -> rabbitTemplate.convertSendAndReceiveAsType(exchange.getName(),
+            DELETE_ROUTE,
+            index,
+            new ParameterizedTypeReference<Integer>() {
+            }
+        ))
+        .forEach(it -> {
+          if (DELETE_INDEX_SUCCESS_CODE.equals(it)) {
+            LOGGER.info("Successfully deleted index '{}'", index);
+          } else {
+            LOGGER.error("Error deleting index '{}'", index);
+          }
+        });
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/impl/RabbitMqManagementClientTemplate.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/impl/RabbitMqManagementClientTemplate.java
index e74dc83f00..4ff216f06c 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/impl/RabbitMqManagementClientTemplate.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/impl/RabbitMqManagementClientTemplate.java
@@ -16,47 +16,47 @@
 
 package com.epam.ta.reportportal.core.analyzer.auto.client.impl;
 
+import static com.epam.ta.reportportal.core.analyzer.auto.client.impl.AnalyzerUtils.ANALYZER_KEY;
+import static com.epam.ta.reportportal.core.analyzer.auto.client.impl.AnalyzerUtils.EXCHANGE_PRIORITY;
+import static java.util.Comparator.comparingInt;
+
 import com.epam.ta.reportportal.core.analyzer.auto.client.RabbitMqManagementClient;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.rabbitmq.http.client.Client;
 import com.rabbitmq.http.client.domain.ExchangeInfo;
-
 import java.util.List;
 import java.util.stream.Collectors;
 
-import static com.epam.ta.reportportal.core.analyzer.auto.client.impl.AnalyzerUtils.ANALYZER_KEY;
-import static com.epam.ta.reportportal.core.analyzer.auto.client.impl.AnalyzerUtils.EXCHANGE_PRIORITY;
-import static java.util.Comparator.comparingInt;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 public class RabbitMqManagementClientTemplate implements RabbitMqManagementClient {
 
-	private final Client rabbitClient;
-
-	private final String virtualHost;
-
-	public RabbitMqManagementClientTemplate(Client rabbitClient, String virtualHost) {
-		this.rabbitClient = rabbitClient;
-		this.virtualHost = virtualHost;
-		try {
-			rabbitClient.createVhost(virtualHost);
-		} catch (JsonProcessingException e) {
-			throw new ReportPortalException(ErrorType.UNCLASSIFIED_REPORT_PORTAL_ERROR, "Unable to create RabbitMq virtual host");
-		}
-	}
-
-    public List<ExchangeInfo> getAnalyzerExchangesInfo() {
-        List<ExchangeInfo> client = rabbitClient.getExchanges(virtualHost);
-        if (client == null) {
-            throw new ReportPortalException(ErrorType.ANALYZER_NOT_FOUND, virtualHost);
-        }
-        return client.stream()
-                .filter(it -> it.getArguments().get(ANALYZER_KEY) != null)
-                .sorted(comparingInt(EXCHANGE_PRIORITY))
-                .collect(Collectors.toList());
+  private final Client rabbitClient;
+
+  private final String virtualHost;
+
+  public RabbitMqManagementClientTemplate(Client rabbitClient, String virtualHost) {
+    this.rabbitClient = rabbitClient;
+    this.virtualHost = virtualHost;
+    try {
+      rabbitClient.createVhost(virtualHost);
+    } catch (Exception e) {
+      throw new ReportPortalException(ErrorType.UNCLASSIFIED_REPORT_PORTAL_ERROR,
+          "Unable to create RabbitMq virtual host");
+    }
+  }
+
+  public List<ExchangeInfo> getAnalyzerExchangesInfo() {
+    List<ExchangeInfo> client = rabbitClient.getExchanges(virtualHost);
+    if (client == null) {
+      throw new ReportPortalException(ErrorType.ANALYZER_NOT_FOUND, virtualHost);
     }
+    return client.stream()
+        .filter(it -> it.getArguments().get(ANALYZER_KEY) != null)
+        .sorted(comparingInt(EXCHANGE_PRIORITY))
+        .collect(Collectors.toList());
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/IndexDefectsUpdate.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/IndexDefectsUpdate.java
index 33898c85b9..9107ee7cd6 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/IndexDefectsUpdate.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/IndexDefectsUpdate.java
@@ -16,7 +16,6 @@
 package com.epam.ta.reportportal.core.analyzer.auto.client.model;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
-
 import java.util.Map;
 import java.util.Objects;
 
@@ -25,47 +24,48 @@
  */
 public class IndexDefectsUpdate {
 
-	@JsonProperty("project")
-	private Long projectId;
+  @JsonProperty("project")
+  private Long projectId;
 
-	@JsonProperty("itemsToUpdate")
-	private Map<Long, String> itemsToUpdate;
+  @JsonProperty("itemsToUpdate")
+  private Map<Long, String> itemsToUpdate;
 
-	public IndexDefectsUpdate(Long projectId, Map<Long, String> itemsToUpdate) {
-		this.projectId = projectId;
-		this.itemsToUpdate = itemsToUpdate;
-	}
+  public IndexDefectsUpdate(Long projectId, Map<Long, String> itemsToUpdate) {
+    this.projectId = projectId;
+    this.itemsToUpdate = itemsToUpdate;
+  }
 
-	public Long getProjectId() {
-		return projectId;
-	}
+  public Long getProjectId() {
+    return projectId;
+  }
 
-	public void setProjectId(Long projectId) {
-		this.projectId = projectId;
-	}
+  public void setProjectId(Long projectId) {
+    this.projectId = projectId;
+  }
 
-	public Map<Long, String> getItemsToUpdate() {
-		return itemsToUpdate;
-	}
+  public Map<Long, String> getItemsToUpdate() {
+    return itemsToUpdate;
+  }
 
-	public void setItemsToUpdate(Map<Long, String> itemsToUpdate) {
-		this.itemsToUpdate = itemsToUpdate;
-	}
+  public void setItemsToUpdate(Map<Long, String> itemsToUpdate) {
+    this.itemsToUpdate = itemsToUpdate;
+  }
 
-	@Override
-	public boolean equals(Object o) {
-		if (this == o) {
-			return true;
-		}
-		if (o == null || getClass() != o.getClass()) {
-			return false;
-		}
-		IndexDefectsUpdate that = (IndexDefectsUpdate) o;
-		return Objects.equals(projectId, that.projectId) && Objects.equals(itemsToUpdate, that.itemsToUpdate);
-	}
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    IndexDefectsUpdate that = (IndexDefectsUpdate) o;
+    return Objects.equals(projectId, that.projectId) && Objects.equals(itemsToUpdate,
+        that.itemsToUpdate);
+  }
 
-	@Override
-	public int hashCode() {
-		return Objects.hash(projectId, itemsToUpdate);
-	}
+  @Override
+  public int hashCode() {
+    return Objects.hash(projectId, itemsToUpdate);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/IndexItemsRemove.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/IndexItemsRemove.java
index 10ab6a0460..2b8aed48b6 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/IndexItemsRemove.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/IndexItemsRemove.java
@@ -16,7 +16,6 @@
 package com.epam.ta.reportportal.core.analyzer.auto.client.model;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
-
 import java.util.Collection;
 import java.util.Objects;
 
@@ -25,47 +24,48 @@
  */
 public class IndexItemsRemove {
 
-	@JsonProperty("project")
-	private Long projectId;
+  @JsonProperty("project")
+  private Long projectId;
 
-	@JsonProperty("itemsToDelete")
-	private Collection<Long> itemsToDelete;
+  @JsonProperty("itemsToDelete")
+  private Collection<Long> itemsToDelete;
 
-	public IndexItemsRemove(Long projectId, Collection<Long> itemsToDelete) {
-		this.projectId = projectId;
-		this.itemsToDelete = itemsToDelete;
-	}
+  public IndexItemsRemove(Long projectId, Collection<Long> itemsToDelete) {
+    this.projectId = projectId;
+    this.itemsToDelete = itemsToDelete;
+  }
 
-	public Long getProjectId() {
-		return projectId;
-	}
+  public Long getProjectId() {
+    return projectId;
+  }
 
-	public void setProjectId(Long projectId) {
-		this.projectId = projectId;
-	}
+  public void setProjectId(Long projectId) {
+    this.projectId = projectId;
+  }
 
-	public Collection<Long> getItemsToDelete() {
-		return itemsToDelete;
-	}
+  public Collection<Long> getItemsToDelete() {
+    return itemsToDelete;
+  }
 
-	public void setItemsToDelete(Collection<Long> itemsToDelete) {
-		this.itemsToDelete = itemsToDelete;
-	}
+  public void setItemsToDelete(Collection<Long> itemsToDelete) {
+    this.itemsToDelete = itemsToDelete;
+  }
 
-	@Override
-	public boolean equals(Object o) {
-		if (this == o) {
-			return true;
-		}
-		if (o == null || getClass() != o.getClass()) {
-			return false;
-		}
-		IndexItemsRemove that = (IndexItemsRemove) o;
-		return Objects.equals(projectId, that.projectId) && Objects.equals(itemsToDelete, that.itemsToDelete);
-	}
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    IndexItemsRemove that = (IndexItemsRemove) o;
+    return Objects.equals(projectId, that.projectId) && Objects.equals(itemsToDelete,
+        that.itemsToDelete);
+  }
 
-	@Override
-	public int hashCode() {
-		return Objects.hash(projectId, itemsToDelete);
-	}
+  @Override
+  public int hashCode() {
+    return Objects.hash(projectId, itemsToDelete);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/IndexLaunchRemove.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/IndexLaunchRemove.java
index 24f2048605..e098714326 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/IndexLaunchRemove.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/IndexLaunchRemove.java
@@ -16,7 +16,6 @@
 package com.epam.ta.reportportal.core.analyzer.auto.client.model;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
-
 import java.util.Collection;
 import java.util.Objects;
 
@@ -25,47 +24,47 @@
  */
 public class IndexLaunchRemove {
 
-	@JsonProperty("project")
-	private Long projectId;
+  @JsonProperty("project")
+  private Long projectId;
 
-	@JsonProperty("launch_ids")
-	private Collection<Long> launchIds;
+  @JsonProperty("launch_ids")
+  private Collection<Long> launchIds;
 
-	public IndexLaunchRemove(Long projectId, Collection<Long> launchIds) {
-		this.projectId = projectId;
-		this.launchIds = launchIds;
-	}
+  public IndexLaunchRemove(Long projectId, Collection<Long> launchIds) {
+    this.projectId = projectId;
+    this.launchIds = launchIds;
+  }
 
-	public Long getProjectId() {
-		return projectId;
-	}
+  public Long getProjectId() {
+    return projectId;
+  }
 
-	public void setProjectId(Long projectId) {
-		this.projectId = projectId;
-	}
+  public void setProjectId(Long projectId) {
+    this.projectId = projectId;
+  }
 
-	public Collection<Long> getLaunchIds() {
-		return launchIds;
-	}
+  public Collection<Long> getLaunchIds() {
+    return launchIds;
+  }
 
-	public void setLaunchIds(Collection<Long> launchIds) {
-		this.launchIds = launchIds;
-	}
+  public void setLaunchIds(Collection<Long> launchIds) {
+    this.launchIds = launchIds;
+  }
 
-	@Override
-	public boolean equals(Object o) {
-		if (this == o) {
-			return true;
-		}
-		if (o == null || getClass() != o.getClass()) {
-			return false;
-		}
-		IndexLaunchRemove that = (IndexLaunchRemove) o;
-		return Objects.equals(projectId, that.projectId) && Objects.equals(launchIds, that.launchIds);
-	}
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    IndexLaunchRemove that = (IndexLaunchRemove) o;
+    return Objects.equals(projectId, that.projectId) && Objects.equals(launchIds, that.launchIds);
+  }
 
-	@Override
-	public int hashCode() {
-		return Objects.hash(projectId, launchIds);
-	}
+  @Override
+  public int hashCode() {
+    return Objects.hash(projectId, launchIds);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/SuggestInfo.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/SuggestInfo.java
index 1a73313741..355b491798 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/SuggestInfo.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/SuggestInfo.java
@@ -23,223 +23,233 @@
 @JsonInclude(JsonInclude.Include.NON_NULL)
 public class SuggestInfo {
 
-	private Long project;
+  private Long project;
 
-	private Long testItem;
+  private Long testItem;
 
-	private Long testItemLogId;
+  private Long testItemLogId;
 
-	private Long launchId;
+  private Long launchId;
 
-	private String launchName;
+  private String launchName;
 
-	private String issueType;
+  private Long launchNumber;
 
-	private Long relevantItem;
+  private String issueType;
 
-	private Long relevantLogId;
+  private Long relevantItem;
 
-	private boolean isMergedLog;
+  private Long relevantLogId;
 
-	private float matchScore;
+  private boolean isMergedLog;
 
-	private int resultPosition;
+  private float matchScore;
 
-	private float esScore;
+  private int resultPosition;
 
-	private int esPosition;
+  private float esScore;
 
-	private String modelFeatureNames;
+  private int esPosition;
 
-	private String modelFeatureValues;
+  private String modelFeatureNames;
 
-	private String modelInfo;
+  private String modelFeatureValues;
 
-	private int usedLogLines;
+  private String modelInfo;
 
-	private int minShouldMatch;
+  private int usedLogLines;
 
-	private float processedTime;
+  private int minShouldMatch;
 
-	private int userChoice;
+  private float processedTime;
 
-	private String methodName;
+  private int userChoice;
 
-	private Long clusterId;
+  private String methodName;
 
-	public Long getProject() {
-		return project;
-	}
+  private Long clusterId;
 
-	public void setProject(Long project) {
-		this.project = project;
-	}
+  public Long getProject() {
+    return project;
+  }
 
-	public Long getTestItem() {
-		return testItem;
-	}
+  public void setProject(Long project) {
+    this.project = project;
+  }
 
-	public void setTestItem(Long testItem) {
-		this.testItem = testItem;
-	}
+  public Long getTestItem() {
+    return testItem;
+  }
 
-	public Long getTestItemLogId() {
-		return testItemLogId;
-	}
+  public void setTestItem(Long testItem) {
+    this.testItem = testItem;
+  }
 
-	public void setTestItemLogId(Long testItemLogId) {
-		this.testItemLogId = testItemLogId;
-	}
+  public Long getTestItemLogId() {
+    return testItemLogId;
+  }
 
-	public Long getLaunchId() {
-		return launchId;
-	}
+  public void setTestItemLogId(Long testItemLogId) {
+    this.testItemLogId = testItemLogId;
+  }
 
-	public void setLaunchId(Long launchId) {
-		this.launchId = launchId;
-	}
+  public Long getLaunchId() {
+    return launchId;
+  }
 
-	public String getLaunchName() {
-		return launchName;
-	}
+  public void setLaunchId(Long launchId) {
+    this.launchId = launchId;
+  }
 
-	public void setLaunchName(String launchName) {
-		this.launchName = launchName;
-	}
+  public String getLaunchName() {
+    return launchName;
+  }
 
-	public String getIssueType() {
-		return issueType;
-	}
+  public void setLaunchName(String launchName) {
+    this.launchName = launchName;
+  }
 
-	public void setIssueType(String issueType) {
-		this.issueType = issueType;
-	}
+  public String getIssueType() {
+    return issueType;
+  }
 
-	public Long getRelevantItem() {
-		return relevantItem;
-	}
+  public void setIssueType(String issueType) {
+    this.issueType = issueType;
+  }
 
-	public void setRelevantItem(Long relevantItem) {
-		this.relevantItem = relevantItem;
-	}
+  public Long getRelevantItem() {
+    return relevantItem;
+  }
 
-	public Long getRelevantLogId() {
-		return relevantLogId;
-	}
+  public void setRelevantItem(Long relevantItem) {
+    this.relevantItem = relevantItem;
+  }
 
-	public void setRelevantLogId(Long relevantLogId) {
-		this.relevantLogId = relevantLogId;
-	}
+  public Long getRelevantLogId() {
+    return relevantLogId;
+  }
 
-	public boolean getIsMergedLog() {
-		return isMergedLog;
-	}
+  public void setRelevantLogId(Long relevantLogId) {
+    this.relevantLogId = relevantLogId;
+  }
 
-	public void setIsMergedLog(boolean isMergedLog) {
-		this.isMergedLog = isMergedLog;
-	}
+  public boolean getIsMergedLog() {
+    return isMergedLog;
+  }
 
-	public float getMatchScore() {
-		return matchScore;
-	}
+  public void setIsMergedLog(boolean isMergedLog) {
+    this.isMergedLog = isMergedLog;
+  }
 
-	public void setMatchScore(float matchScore) {
-		this.matchScore = matchScore;
-	}
+  public float getMatchScore() {
+    return matchScore;
+  }
 
-	public int getResultPosition() {
-		return resultPosition;
-	}
+  public void setMatchScore(float matchScore) {
+    this.matchScore = matchScore;
+  }
 
-	public void setResultPosition(int resultPosition) {
-		this.resultPosition = resultPosition;
-	}
+  public int getResultPosition() {
+    return resultPosition;
+  }
 
-	public float getEsScore() {
-		return esScore;
-	}
+  public void setResultPosition(int resultPosition) {
+    this.resultPosition = resultPosition;
+  }
 
-	public void setEsScore(float esScore) {
-		this.esScore = esScore;
-	}
+  public float getEsScore() {
+    return esScore;
+  }
 
-	public int getEsPosition() {
-		return esPosition;
-	}
+  public void setEsScore(float esScore) {
+    this.esScore = esScore;
+  }
 
-	public void setEsPosition(int esPosition) {
-		this.esPosition = esPosition;
-	}
+  public int getEsPosition() {
+    return esPosition;
+  }
 
-	public String getModelFeatureNames() {
-		return modelFeatureNames;
-	}
+  public void setEsPosition(int esPosition) {
+    this.esPosition = esPosition;
+  }
 
-	public void setModelFeatureNames(String modelFeatureNames) {
-		this.modelFeatureNames = modelFeatureNames;
-	}
+  public String getModelFeatureNames() {
+    return modelFeatureNames;
+  }
 
-	public String getModelFeatureValues() {
-		return modelFeatureValues;
-	}
+  public void setModelFeatureNames(String modelFeatureNames) {
+    this.modelFeatureNames = modelFeatureNames;
+  }
 
-	public void setModelFeatureValues(String modelFeatureValues) {
-		this.modelFeatureValues = modelFeatureValues;
-	}
+  public String getModelFeatureValues() {
+    return modelFeatureValues;
+  }
 
-	public String getModelInfo() {
-		return modelInfo;
-	}
+  public void setModelFeatureValues(String modelFeatureValues) {
+    this.modelFeatureValues = modelFeatureValues;
+  }
 
-	public void setModelInfo(String modelInfo) {
-		this.modelInfo = modelInfo;
-	}
+  public String getModelInfo() {
+    return modelInfo;
+  }
 
-	public int getUsedLogLines() {
-		return usedLogLines;
-	}
+  public void setModelInfo(String modelInfo) {
+    this.modelInfo = modelInfo;
+  }
 
-	public void setUsedLogLines(int usedLogLines) {
-		this.usedLogLines = usedLogLines;
-	}
+  public int getUsedLogLines() {
+    return usedLogLines;
+  }
 
-	public int getMinShouldMatch() {
-		return minShouldMatch;
-	}
+  public void setUsedLogLines(int usedLogLines) {
+    this.usedLogLines = usedLogLines;
+  }
 
-	public void setMinShouldMatch(int minShouldMatch) {
-		this.minShouldMatch = minShouldMatch;
-	}
+  public int getMinShouldMatch() {
+    return minShouldMatch;
+  }
 
-	public float getProcessedTime() {
-		return processedTime;
-	}
+  public void setMinShouldMatch(int minShouldMatch) {
+    this.minShouldMatch = minShouldMatch;
+  }
 
-	public void setProcessedTime(float processedTime) {
-		this.processedTime = processedTime;
-	}
+  public float getProcessedTime() {
+    return processedTime;
+  }
 
-	public int getUserChoice() {
-		return userChoice;
-	}
+  public void setProcessedTime(float processedTime) {
+    this.processedTime = processedTime;
+  }
 
-	public void setUserChoice(int userChoice) {
-		this.userChoice = userChoice;
-	}
+  public int getUserChoice() {
+    return userChoice;
+  }
 
-	public String getMethodName() {
-		return methodName;
-	}
+  public void setUserChoice(int userChoice) {
+    this.userChoice = userChoice;
+  }
 
-	public void setMethodName(String methodName) {
-		this.methodName = methodName;
-	}
+  public String getMethodName() {
+    return methodName;
+  }
 
-	public Long getClusterId() {
-		return clusterId;
-	}
+  public void setMethodName(String methodName) {
+    this.methodName = methodName;
+  }
 
-	public void setClusterId(Long clusterId) {
-		this.clusterId = clusterId;
-	}
+  public Long getClusterId() {
+    return clusterId;
+  }
+
+  public void setClusterId(Long clusterId) {
+    this.clusterId = clusterId;
+  }
+
+  public Long getLaunchNumber() {
+    return launchNumber;
+  }
+
+  public void setLaunchNumber(Long launchNumber) {
+    this.launchNumber = launchNumber;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/SuggestRq.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/SuggestRq.java
index 693da7f4ed..c8576dc275 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/SuggestRq.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/SuggestRq.java
@@ -18,7 +18,6 @@
 import com.epam.ta.reportportal.ws.model.analyzer.IndexLog;
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
 import com.fasterxml.jackson.annotation.JsonInclude;
-
 import java.util.Set;
 
 /**
@@ -27,96 +26,106 @@
 @JsonInclude(JsonInclude.Include.NON_NULL)
 public class SuggestRq {
 
-	private Long testItemId;
+  private Long testItemId;
+
+  private String uniqueId;
+
+  private Integer testCaseHash;
+
+  private Long clusterId;
 
-	private String uniqueId;
+  private Long launchId;
 
-	private Integer testCaseHash;
+  private String launchName;
 
-	private Long clusterId;
+  private Long launchNumber;
 
-	private Long launchId;
+  private Long project;
 
-	private String launchName;
+  private AnalyzerConfig analyzerConfig;
 
-	private Long project;
+  private Set<IndexLog> logs;
 
-	private AnalyzerConfig analyzerConfig;
+  public SuggestRq() {
+  }
 
-	private Set<IndexLog> logs;
+  public Long getTestItemId() {
+    return testItemId;
+  }
 
-	public SuggestRq() {
-	}
+  public void setTestItemId(Long testItemId) {
+    this.testItemId = testItemId;
+  }
 
-	public Long getTestItemId() {
-		return testItemId;
-	}
+  public String getUniqueId() {
+    return uniqueId;
+  }
 
-	public void setTestItemId(Long testItemId) {
-		this.testItemId = testItemId;
-	}
+  public void setUniqueId(String uniqueId) {
+    this.uniqueId = uniqueId;
+  }
 
-	public String getUniqueId() {
-		return uniqueId;
-	}
+  public Integer getTestCaseHash() {
+    return testCaseHash;
+  }
 
-	public void setUniqueId(String uniqueId) {
-		this.uniqueId = uniqueId;
-	}
+  public void setTestCaseHash(Integer testCaseHash) {
+    this.testCaseHash = testCaseHash;
+  }
 
-	public Integer getTestCaseHash() {
-		return testCaseHash;
-	}
+  public Long getClusterId() {
+    return clusterId;
+  }
 
-	public void setTestCaseHash(Integer testCaseHash) {
-		this.testCaseHash = testCaseHash;
-	}
+  public void setClusterId(Long clusterId) {
+    this.clusterId = clusterId;
+  }
 
-	public Long getClusterId() {
-		return clusterId;
-	}
+  public Long getLaunchId() {
+    return launchId;
+  }
 
-	public void setClusterId(Long clusterId) {
-		this.clusterId = clusterId;
-	}
+  public void setLaunchId(Long launchId) {
+    this.launchId = launchId;
+  }
 
-	public Long getLaunchId() {
-		return launchId;
-	}
+  public String getLaunchName() {
+    return launchName;
+  }
 
-	public void setLaunchId(Long launchId) {
-		this.launchId = launchId;
-	}
+  public void setLaunchName(String launchName) {
+    this.launchName = launchName;
+  }
 
-	public String getLaunchName() {
-		return launchName;
-	}
+  public Long getProject() {
+    return project;
+  }
 
-	public void setLaunchName(String launchName) {
-		this.launchName = launchName;
-	}
+  public void setProject(Long project) {
+    this.project = project;
+  }
 
-	public Long getProject() {
-		return project;
-	}
+  public AnalyzerConfig getAnalyzerConfig() {
+    return analyzerConfig;
+  }
 
-	public void setProject(Long project) {
-		this.project = project;
-	}
+  public void setAnalyzerConfig(AnalyzerConfig analyzerConfig) {
+    this.analyzerConfig = analyzerConfig;
+  }
 
-	public AnalyzerConfig getAnalyzerConfig() {
-		return analyzerConfig;
-	}
+  public Set<IndexLog> getLogs() {
+    return logs;
+  }
 
-	public void setAnalyzerConfig(AnalyzerConfig analyzerConfig) {
-		this.analyzerConfig = analyzerConfig;
-	}
+  public void setLogs(Set<IndexLog> logs) {
+    this.logs = logs;
+  }
 
-	public Set<IndexLog> getLogs() {
-		return logs;
-	}
+  public Long getLaunchNumber() {
+    return launchNumber;
+  }
 
-	public void setLogs(Set<IndexLog> logs) {
-		this.logs = logs;
-	}
+  public void setLaunchNumber(Long launchNumber) {
+    this.launchNumber = launchNumber;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/cluster/ClusterData.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/cluster/ClusterData.java
index f0ecdad316..0f76548529 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/cluster/ClusterData.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/cluster/ClusterData.java
@@ -23,34 +23,34 @@
  */
 public class ClusterData {
 
-	private Long project;
-	private Long launchId;
-	private List<ClusterInfoRs> clusters;
+  private Long project;
+  private Long launchId;
+  private List<ClusterInfoRs> clusters;
 
-	public ClusterData() {
-	}
+  public ClusterData() {
+  }
 
-	public Long getProject() {
-		return project;
-	}
+  public Long getProject() {
+    return project;
+  }
 
-	public void setProject(Long project) {
-		this.project = project;
-	}
+  public void setProject(Long project) {
+    this.project = project;
+  }
 
-	public Long getLaunchId() {
-		return launchId;
-	}
+  public Long getLaunchId() {
+    return launchId;
+  }
 
-	public void setLaunchId(Long launchId) {
-		this.launchId = launchId;
-	}
+  public void setLaunchId(Long launchId) {
+    this.launchId = launchId;
+  }
 
-	public List<ClusterInfoRs> getClusters() {
-		return clusters;
-	}
+  public List<ClusterInfoRs> getClusters() {
+    return clusters;
+  }
 
-	public void setClusters(List<ClusterInfoRs> clusters) {
-		this.clusters = clusters;
-	}
+  public void setClusters(List<ClusterInfoRs> clusters) {
+    this.clusters = clusters;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/cluster/ClusterInfoRs.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/cluster/ClusterInfoRs.java
index e0a3f1d23b..49f60938aa 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/cluster/ClusterInfoRs.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/cluster/ClusterInfoRs.java
@@ -17,7 +17,6 @@
 package com.epam.ta.reportportal.core.analyzer.auto.client.model.cluster;
 
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-
 import java.util.LinkedHashSet;
 import java.util.Set;
 
@@ -26,47 +25,47 @@
  */
 public class ClusterInfoRs {
 
-	private Long clusterId;
-	private String clusterMessage;
+  private Long clusterId;
+  private String clusterMessage;
 
-	@JsonDeserialize(as = LinkedHashSet.class)
-	private Set<Long> itemIds;
+  @JsonDeserialize(as = LinkedHashSet.class)
+  private Set<Long> itemIds;
 
-	@JsonDeserialize(as = LinkedHashSet.class)
-	private Set<Long> logIds;
+  @JsonDeserialize(as = LinkedHashSet.class)
+  private Set<Long> logIds;
 
-	public ClusterInfoRs() {
-	}
+  public ClusterInfoRs() {
+  }
 
-	public Long getClusterId() {
-		return clusterId;
-	}
+  public Long getClusterId() {
+    return clusterId;
+  }
 
-	public void setClusterId(Long clusterId) {
-		this.clusterId = clusterId;
-	}
+  public void setClusterId(Long clusterId) {
+    this.clusterId = clusterId;
+  }
 
-	public String getClusterMessage() {
-		return clusterMessage;
-	}
+  public String getClusterMessage() {
+    return clusterMessage;
+  }
 
-	public void setClusterMessage(String clusterMessage) {
-		this.clusterMessage = clusterMessage;
-	}
+  public void setClusterMessage(String clusterMessage) {
+    this.clusterMessage = clusterMessage;
+  }
 
-	public Set<Long> getItemIds() {
-		return itemIds;
-	}
+  public Set<Long> getItemIds() {
+    return itemIds;
+  }
 
-	public void setItemIds(Set<Long> itemIds) {
-		this.itemIds = itemIds;
-	}
+  public void setItemIds(Set<Long> itemIds) {
+    this.itemIds = itemIds;
+  }
 
-	public Set<Long> getLogIds() {
-		return logIds;
-	}
+  public Set<Long> getLogIds() {
+    return logIds;
+  }
 
-	public void setLogIds(Set<Long> logIds) {
-		this.logIds = logIds;
-	}
+  public void setLogIds(Set<Long> logIds) {
+    this.logIds = logIds;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/cluster/GenerateClustersRq.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/cluster/GenerateClustersRq.java
index 328e44fea1..f76557a178 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/cluster/GenerateClustersRq.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/client/model/cluster/GenerateClustersRq.java
@@ -23,55 +23,55 @@
  */
 public class GenerateClustersRq {
 
-	private IndexLaunch launch;
+  private IndexLaunch launch;
 
-	private Long project;
+  private Long project;
 
-	private int numberOfLogLines;
+  private int numberOfLogLines;
 
-	private boolean forUpdate;
-	private boolean cleanNumbers;
+  private boolean forUpdate;
+  private boolean cleanNumbers;
 
-	public GenerateClustersRq() {
-	}
+  public GenerateClustersRq() {
+  }
 
-	public IndexLaunch getLaunch() {
-		return launch;
-	}
+  public IndexLaunch getLaunch() {
+    return launch;
+  }
 
-	public void setLaunch(IndexLaunch launch) {
-		this.launch = launch;
-	}
+  public void setLaunch(IndexLaunch launch) {
+    this.launch = launch;
+  }
 
-	public Long getProject() {
-		return project;
-	}
+  public Long getProject() {
+    return project;
+  }
 
-	public void setProject(Long project) {
-		this.project = project;
-	}
+  public void setProject(Long project) {
+    this.project = project;
+  }
 
-	public int getNumberOfLogLines() {
-		return numberOfLogLines;
-	}
+  public int getNumberOfLogLines() {
+    return numberOfLogLines;
+  }
 
-	public void setNumberOfLogLines(int numberOfLogLines) {
-		this.numberOfLogLines = numberOfLogLines;
-	}
+  public void setNumberOfLogLines(int numberOfLogLines) {
+    this.numberOfLogLines = numberOfLogLines;
+  }
 
-	public boolean isForUpdate() {
-		return forUpdate;
-	}
+  public boolean isForUpdate() {
+    return forUpdate;
+  }
 
-	public void setForUpdate(boolean forUpdate) {
-		this.forUpdate = forUpdate;
-	}
+  public void setForUpdate(boolean forUpdate) {
+    this.forUpdate = forUpdate;
+  }
 
-	public boolean isCleanNumbers() {
-		return cleanNumbers;
-	}
+  public boolean isCleanNumbers() {
+    return cleanNumbers;
+  }
 
-	public void setCleanNumbers(boolean cleanNumbers) {
-		this.cleanNumbers = cleanNumbers;
-	}
+  public void setCleanNumbers(boolean cleanNumbers) {
+    this.cleanNumbers = cleanNumbers;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/AnalyzerServiceAsyncImpl.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/AnalyzerServiceAsyncImpl.java
index aa3aa3363c..4473a46b19 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/AnalyzerServiceAsyncImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/AnalyzerServiceAsyncImpl.java
@@ -20,11 +20,10 @@
 import com.epam.ta.reportportal.core.analyzer.auto.AnalyzerServiceAsync;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
 import java.util.List;
 import java.util.concurrent.CompletableFuture;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
@@ -32,21 +31,23 @@
 @Service
 public class AnalyzerServiceAsyncImpl implements AnalyzerServiceAsync {
 
-	private final AnalyzerService analyzerService;
+  private final AnalyzerService analyzerService;
 
-	@Autowired
-	public AnalyzerServiceAsyncImpl(AnalyzerService analyzerService) {
-		this.analyzerService = analyzerService;
-	}
+  @Autowired
+  public AnalyzerServiceAsyncImpl(AnalyzerService analyzerService) {
+    this.analyzerService = analyzerService;
+  }
 
-	@Override
-	public CompletableFuture<Void> analyze(Launch launch, List<Long> itemIds, AnalyzerConfig analyzerConfig) {
-		return CompletableFuture.runAsync(() -> analyzerService.runAnalyzers(launch, itemIds, analyzerConfig));
-	}
+  @Override
+  public CompletableFuture<Void> analyze(Launch launch, List<Long> itemIds,
+      AnalyzerConfig analyzerConfig) {
+    return CompletableFuture.runAsync(
+        () -> analyzerService.runAnalyzers(launch, itemIds, analyzerConfig));
+  }
 
-	@Override
-	public boolean hasAnalyzers() {
-		return analyzerService.hasAnalyzers();
-	}
+  @Override
+  public boolean hasAnalyzers() {
+    return analyzerService.hasAnalyzers();
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/AnalyzerServiceImpl.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/AnalyzerServiceImpl.java
index 3a0b4de2c7..48e3aa4577 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/AnalyzerServiceImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/AnalyzerServiceImpl.java
@@ -28,7 +28,9 @@
 import com.epam.ta.reportportal.core.events.activity.ItemIssueTypeDefinedEvent;
 import com.epam.ta.reportportal.core.events.activity.LinkTicketEvent;
 import com.epam.ta.reportportal.core.item.impl.IssueTypeHandler;
+import com.epam.ta.reportportal.dao.LaunchRepository;
 import com.epam.ta.reportportal.dao.TestItemRepository;
+import com.epam.ta.reportportal.entity.AnalyzeMode;
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.item.issue.IssueEntity;
 import com.epam.ta.reportportal.entity.item.issue.IssueType;
@@ -63,80 +65,93 @@
 @Transactional
 public class AnalyzerServiceImpl implements AnalyzerService {
 
-	private static final Logger LOGGER = LogManager.getLogger(AnalyzerServiceImpl.class.getName());
-
-	private final AnalyzerStatusCache analyzerStatusCache;
-
-	private final LaunchPreparerService launchPreparerService;
-
-	private final AnalyzerServiceClient analyzerServicesClient;
-
-	private final IssueTypeHandler issueTypeHandler;
-
-	private final TestItemRepository testItemRepository;
-
-	private final MessageBus messageBus;
-
-	private final Integer itemsBatchSize;
-
-	@Autowired
-	public AnalyzerServiceImpl(@Value("${rp.environment.variable.item-analyze.batch-size}") Integer itemsBatchSize,
-			AnalyzerStatusCache analyzerStatusCache, LaunchPreparerService launchPreparerService,
-			AnalyzerServiceClient analyzerServicesClient, IssueTypeHandler issueTypeHandler, TestItemRepository testItemRepository,
-			MessageBus messageBus) {
-		this.itemsBatchSize = itemsBatchSize;
-		this.analyzerStatusCache = analyzerStatusCache;
-		this.launchPreparerService = launchPreparerService;
-		this.analyzerServicesClient = analyzerServicesClient;
-		this.issueTypeHandler = issueTypeHandler;
-		this.testItemRepository = testItemRepository;
-		this.messageBus = messageBus;
-	}
-
-	@Override
-	public boolean hasAnalyzers() {
-		return analyzerServicesClient.hasClients();
-	}
-
-	@Override
-	public void runAnalyzers(Launch launch, List<Long> testItemIds, AnalyzerConfig analyzerConfig) {
-		try {
-			analyzerStatusCache.analyzeStarted(AUTO_ANALYZER_KEY, launch.getId(), launch.getProjectId());
-			Iterables.partition(testItemIds, itemsBatchSize).forEach(partition -> analyzeItemsPartition(launch, partition, analyzerConfig));
-		} catch (Exception e) {
-			LOGGER.error(e.getMessage(), e);
-		} finally {
-			analyzerStatusCache.analyzeFinished(AUTO_ANALYZER_KEY, launch.getId());
-		}
-	}
-
-	/**
-	 * Prepare and analyze the number of provided test item ids.
-	 *
-	 * @param launch         Launch
-	 * @param testItemIds    Item ids for analyzing
-	 * @param analyzerConfig Analyzer config
-	 */
-	private void analyzeItemsPartition(Launch launch, List<Long> testItemIds, AnalyzerConfig analyzerConfig) {
-		LOGGER.info("Start analysis of '{}' items for launch with id '{}'", testItemIds.size(), launch.getId());
-		List<TestItem> toAnalyze = testItemRepository.findAllById(testItemIds);
-		Optional<IndexLaunch> rqLaunch = launchPreparerService.prepare(launch, toAnalyze, analyzerConfig);
-		rqLaunch.ifPresent(rq -> {
-			Map<String, List<AnalyzedItemRs>> analyzedMap = analyzerServicesClient.analyze(rq);
-			if (!MapUtils.isEmpty(analyzedMap)) {
-				analyzedMap.forEach((key, value) -> updateTestItems(key, value, toAnalyze, launch.getProjectId()));
-			}
-		});
-	}
-
-	/**
-	 * Update issue types for analyzed items and posted events for updated
-	 *
-	 * @param rs        Results of analyzing
-	 * @param testItems items to be updated
-	 * @return List of updated items
-	 */
-	private List<TestItem> updateTestItems(String analyzerInstance, List<AnalyzedItemRs> rs, List<TestItem> testItems, Long projectId) {
+  private static final Logger LOGGER = LogManager.getLogger(AnalyzerServiceImpl.class.getName());
+
+  private final AnalyzerStatusCache analyzerStatusCache;
+
+  private final LaunchPreparerService launchPreparerService;
+
+  private final AnalyzerServiceClient analyzerServicesClient;
+
+  private final IssueTypeHandler issueTypeHandler;
+
+  private final TestItemRepository testItemRepository;
+
+  private final LaunchRepository launchRepository;
+
+  private final MessageBus messageBus;
+
+  private final Integer itemsBatchSize;
+
+  @Autowired
+  public AnalyzerServiceImpl(
+      @Value("${rp.environment.variable.item-analyze.batch-size}") Integer itemsBatchSize,
+      AnalyzerStatusCache analyzerStatusCache, LaunchPreparerService launchPreparerService,
+      AnalyzerServiceClient analyzerServicesClient, IssueTypeHandler issueTypeHandler,
+      TestItemRepository testItemRepository,
+      MessageBus messageBus, LaunchRepository launchRepository) {
+    this.itemsBatchSize = itemsBatchSize;
+    this.analyzerStatusCache = analyzerStatusCache;
+    this.launchPreparerService = launchPreparerService;
+    this.analyzerServicesClient = analyzerServicesClient;
+    this.issueTypeHandler = issueTypeHandler;
+    this.testItemRepository = testItemRepository;
+    this.messageBus = messageBus;
+    this.launchRepository = launchRepository;
+  }
+
+  @Override
+  public boolean hasAnalyzers() {
+    return analyzerServicesClient.hasClients();
+  }
+
+  @Override
+  public void runAnalyzers(Launch launch, List<Long> testItemIds, AnalyzerConfig analyzerConfig) {
+    try {
+      analyzerStatusCache.analyzeStarted(AUTO_ANALYZER_KEY, launch.getId(), launch.getProjectId());
+      Optional<Long> previousLaunchId = findPreviousLaunchId(launch, analyzerConfig);
+      Iterables.partition(testItemIds, itemsBatchSize)
+          .forEach(partition -> analyzeItemsPartition(launch, partition, analyzerConfig, previousLaunchId));
+    } catch (Exception e) {
+      LOGGER.error(e.getMessage(), e);
+    } finally {
+      analyzerStatusCache.analyzeFinished(AUTO_ANALYZER_KEY, launch.getId());
+    }
+  }
+
+  /**
+   * Prepare and analyze the number of provided test item ids.
+   *
+   * @param launch         Launch
+   * @param testItemIds    Item ids for analyzing
+   * @param analyzerConfig Analyzer config
+   */
+  private void analyzeItemsPartition(Launch launch, List<Long> testItemIds,
+      AnalyzerConfig analyzerConfig, Optional<Long> previousLaunchId) {
+    LOGGER.info("Start analysis of '{}' items for launch with id '{}'", testItemIds.size(),
+        launch.getId());
+    List<TestItem> toAnalyze = testItemRepository.findAllById(testItemIds);
+    Optional<IndexLaunch> rqLaunch = launchPreparerService.prepare(launch, toAnalyze,
+        analyzerConfig);
+    rqLaunch.ifPresent(rq -> {
+      previousLaunchId.ifPresent(rq::setPreviousLaunchId);
+      Map<String, List<AnalyzedItemRs>> analyzedMap = analyzerServicesClient.analyze(rq);
+      if (!MapUtils.isEmpty(analyzedMap)) {
+        analyzedMap.forEach(
+            (key, value) -> updateTestItems(key, value, toAnalyze, launch.getProjectId()));
+      }
+    });
+  }
+
+  /**
+   * Update issue types for analyzed items and posted events for updated
+   *
+   * @param rs        Results of analyzing
+   * @param testItems items to be updated
+   * @return List of updated items
+   */
+  private List<TestItem> updateTestItems(String analyzerInstance, List<AnalyzedItemRs> rs,
+      List<TestItem> testItems, Long projectId) {
     return rs.stream().map(analyzed -> {
       Optional<TestItem> toUpdate = testItems.stream()
           .filter(item -> item.getItemId().equals(analyzed.getItemId())).findAny();
@@ -164,50 +179,64 @@ private List<TestItem> updateTestItems(String analyzerInstance, List<AnalyzedIte
     }).filter(Optional::isPresent).map(Optional::get).collect(toList());
   }
 
-	/**
-	 * Updates issue for a specified test item
-	 *
-	 * @param projectId - Project id
-	 * @param rs        - Response from an analyzer
-	 * @param testItem  - Test item to be updated
-	 * @return Updated issue entity
-	 */
-	private RelevantItemInfo updateTestItemIssue(Long projectId, AnalyzedItemRs rs, TestItem testItem) {
-		IssueType issueType = issueTypeHandler.defineIssueType(projectId, rs.getLocator());
-		IssueEntity issueEntity = new IssueEntityBuilder(testItem.getItemResults().getIssue()).addIssueType(issueType)
-				.addIgnoreFlag(testItem.getItemResults().getIssue().getIgnoreAnalyzer())
-				.addAutoAnalyzedFlag(true)
-				.get();
-		issueEntity.setIssueId(testItem.getItemId());
-		issueEntity.setTestItemResults(testItem.getItemResults());
-		testItem.getItemResults().setIssue(issueEntity);
-
-		RelevantItemInfo relevantItemInfo = null;
-		if (rs.getRelevantItemId() != null) {
-			Optional<TestItem> relevantItemOptional = testItemRepository.findById(rs.getRelevantItemId());
-			if (relevantItemOptional.isPresent()) {
-				relevantItemInfo = updateIssueFromRelevantItem(issueEntity, relevantItemOptional.get());
-			} else {
-				LOGGER.error(ErrorType.TEST_ITEM_NOT_FOUND.getDescription(), rs.getRelevantItemId());
-			}
-		}
-
-		return relevantItemInfo;
-	}
-
-	/**
-	 * Updates issue with values are taken from most relevant item
-	 *
-	 * @param issue        Issue to update
-	 * @param relevantItem Relevant item
-	 */
-	private RelevantItemInfo updateIssueFromRelevantItem(IssueEntity issue, TestItem relevantItem) {
-		ofNullable(relevantItem.getItemResults().getIssue()).ifPresent(relevantIssue -> {
-			issue.setIssueDescription(relevantIssue.getIssueDescription());
-			issue.setTickets(Sets.newHashSet(relevantIssue.getTickets()));
-		});
-
-		return AnalyzerUtils.TO_RELEVANT_ITEM_INFO.apply(relevantItem);
-	}
+  /**
+   * Updates issue for a specified test item
+   *
+   * @param projectId - Project id
+   * @param rs        - Response from an analyzer
+   * @param testItem  - Test item to be updated
+   * @return Updated issue entity
+   */
+  private RelevantItemInfo updateTestItemIssue(Long projectId, AnalyzedItemRs rs,
+      TestItem testItem) {
+    IssueType issueType = issueTypeHandler.defineIssueType(projectId, rs.getLocator());
+    IssueEntity issueEntity = new IssueEntityBuilder(
+        testItem.getItemResults().getIssue()).addIssueType(issueType)
+        .addIgnoreFlag(testItem.getItemResults().getIssue().getIgnoreAnalyzer())
+        .addAutoAnalyzedFlag(true)
+        .get();
+    issueEntity.setIssueId(testItem.getItemId());
+    issueEntity.setTestItemResults(testItem.getItemResults());
+    testItem.getItemResults().setIssue(issueEntity);
+
+    RelevantItemInfo relevantItemInfo = null;
+    if (rs.getRelevantItemId() != null) {
+      Optional<TestItem> relevantItemOptional = testItemRepository.findById(rs.getRelevantItemId());
+      if (relevantItemOptional.isPresent()) {
+        relevantItemInfo = updateIssueFromRelevantItem(issueEntity, relevantItemOptional.get());
+      } else {
+        LOGGER.error(ErrorType.TEST_ITEM_NOT_FOUND.getDescription(), rs.getRelevantItemId());
+      }
+    }
+
+    return relevantItemInfo;
+  }
 
+  /**
+   * Updates issue with values are taken from most relevant item
+   *
+   * @param issue        Issue to update
+   * @param relevantItem Relevant item
+   */
+  private RelevantItemInfo updateIssueFromRelevantItem(IssueEntity issue, TestItem relevantItem) {
+    ofNullable(relevantItem.getItemResults().getIssue()).ifPresent(relevantIssue -> {
+      issue.setIssueDescription(relevantIssue.getIssueDescription());
+      issue.setTickets(Sets.newHashSet(relevantIssue.getTickets()));
+    });
+
+    return AnalyzerUtils.TO_RELEVANT_ITEM_INFO.apply(relevantItem);
+  }
+
+  /**
+   *
+   * @param launch Analyzed launch
+   * @param analyzerConfig Current analyzer config
+   * @return Id of previous launch. Required only for PREVIOUS_LAUNCH option.
+   */
+  private Optional<Long> findPreviousLaunchId(Launch launch, AnalyzerConfig analyzerConfig) {
+    if (analyzerConfig.getAnalyzerMode().equals(AnalyzeMode.PREVIOUS_LAUNCH.getValue())) {
+      return launchRepository.findPreviousLaunchId(launch);
+    }
+    return Optional.empty();
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/AnalyzerStatusCache.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/AnalyzerStatusCache.java
index 3d79905e3a..a54ac48809 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/AnalyzerStatusCache.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/AnalyzerStatusCache.java
@@ -16,104 +16,106 @@
 
 package com.epam.ta.reportportal.core.analyzer.auto.impl;
 
+import static java.util.Optional.ofNullable;
+
 import com.google.common.cache.Cache;
 import com.google.common.cache.CacheBuilder;
 import com.google.common.collect.ImmutableMap;
-import org.springframework.stereotype.Service;
-
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
-
-import static java.util.Optional.ofNullable;
+import org.springframework.stereotype.Service;
 
 /**
  * Contains caches for analyzing and indexing status
  *
  * @author Pavel Bortnik
  */
+@Deprecated(since = "This cache is not representable since api scaling")
 @Service
 public class AnalyzerStatusCache {
 
-	public static final String AUTO_ANALYZER_KEY = "autoAnalyzer";
-	public static final String PATTERN_ANALYZER_KEY = "patternAnalyzer";
-	public static final String CLUSTER_KEY = "cluster";
-
-	private static final int CACHE_ITEM_LIVE = 10;
-	private static final int MAXIMUM_SIZE = 50000;
-
-	private static final int CLUSTER_ITEM_LIVE = 20;
-
-	/**
-	 * Contains cache of analyze running for concrete launch
-	 * launchId - projectId
-	 */
-	private Map<String, Cache<Long, Long>> analyzeStatus;
-
-	public AnalyzerStatusCache() {
-		Cache<Long, Long> autoAnalysisStatusCache = CacheBuilder.newBuilder()
-				.maximumSize(MAXIMUM_SIZE)
-				.expireAfterWrite(CACHE_ITEM_LIVE, TimeUnit.MINUTES)
-				.build();
-		Cache<Long, Long> patternAnalysisCache = CacheBuilder.newBuilder()
-				.maximumSize(MAXIMUM_SIZE)
-				.expireAfterWrite(CACHE_ITEM_LIVE, TimeUnit.MINUTES)
-				.build();
-		Cache<Long, Long> clusterCache = CacheBuilder.newBuilder()
-				.maximumSize(MAXIMUM_SIZE)
-				.expireAfterWrite(CLUSTER_ITEM_LIVE, TimeUnit.MINUTES)
-				.build();
-		analyzeStatus = ImmutableMap.<String, Cache<Long, Long>>builder().put(AUTO_ANALYZER_KEY, autoAnalysisStatusCache)
-				.put(PATTERN_ANALYZER_KEY, patternAnalysisCache)
-				.put(CLUSTER_KEY, clusterCache)
-				.build();
-	}
-
-	public AnalyzerStatusCache(Map<String, Cache<Long, Long>> analyzeStatus) {
-		this.analyzeStatus = analyzeStatus;
-	}
-
-	public boolean analyzeStarted(String analyzerKey, Long launchId, Long projectId) {
-		Cache<Long, Long> analysisCache = analyzeStatus.get(analyzerKey);
-		if (analysisCache == null) {
-			return false;
-		}
-		analysisCache.put(launchId, projectId);
-		return true;
-	}
-
-	public boolean analyzeFinished(String analyzerKey, Long launchId) {
-		Cache<Long, Long> analysisCache = analyzeStatus.get(analyzerKey);
-		if (analysisCache == null) {
-			return false;
-		}
-		analysisCache.invalidate(launchId);
-		return true;
-	}
-
-	public Optional<Cache<Long, Long>> getAnalyzeStatus(String analyzerKey) {
-		return ofNullable(analyzeStatus.get(analyzerKey));
-	}
-
-	public boolean containsLaunchId(String analyzerKey, Long launchId) {
-		return ofNullable(analyzeStatus.get(analyzerKey)).map(cache -> cache.asMap().containsKey(launchId)).orElse(Boolean.FALSE);
-	}
-
-	public boolean containsProjectId(String analyzerKey, Long projectId) {
-		return ofNullable(analyzeStatus.get(analyzerKey)).map(cache -> cache.asMap().containsValue(projectId)).orElse(Boolean.FALSE);
-	}
-
-	public Set<String> getStartedAnalyzers(Long launchId) {
-		return analyzeStatus.entrySet()
-				.stream()
-				.filter(entry -> entry.getValue().asMap().containsKey(launchId))
-				.map(Map.Entry::getKey)
-				.collect(Collectors.toSet());
-	}
-
-	public Set<String> getAnalyzers() {
-		return analyzeStatus.keySet();
-	}
+  public static final String AUTO_ANALYZER_KEY = "autoAnalyzer";
+  public static final String PATTERN_ANALYZER_KEY = "patternAnalyzer";
+  public static final String CLUSTER_KEY = "cluster";
+
+  private static final int CACHE_ITEM_LIVE = 10;
+  private static final int MAXIMUM_SIZE = 50000;
+
+  private static final int CLUSTER_ITEM_LIVE = 20;
+
+  /**
+   * Contains cache of analyze running for concrete launch launchId - projectId
+   */
+  private Map<String, Cache<Long, Long>> analyzeStatus;
+
+  public AnalyzerStatusCache() {
+    Cache<Long, Long> autoAnalysisStatusCache = CacheBuilder.newBuilder()
+        .maximumSize(MAXIMUM_SIZE)
+        .expireAfterWrite(CACHE_ITEM_LIVE, TimeUnit.MINUTES)
+        .build();
+    Cache<Long, Long> patternAnalysisCache = CacheBuilder.newBuilder()
+        .maximumSize(MAXIMUM_SIZE)
+        .expireAfterWrite(CACHE_ITEM_LIVE, TimeUnit.MINUTES)
+        .build();
+    Cache<Long, Long> clusterCache = CacheBuilder.newBuilder()
+        .maximumSize(MAXIMUM_SIZE)
+        .expireAfterWrite(CLUSTER_ITEM_LIVE, TimeUnit.MINUTES)
+        .build();
+    analyzeStatus = ImmutableMap.<String, Cache<Long, Long>>builder()
+        .put(AUTO_ANALYZER_KEY, autoAnalysisStatusCache)
+        .put(PATTERN_ANALYZER_KEY, patternAnalysisCache)
+        .put(CLUSTER_KEY, clusterCache)
+        .build();
+  }
+
+  public AnalyzerStatusCache(Map<String, Cache<Long, Long>> analyzeStatus) {
+    this.analyzeStatus = analyzeStatus;
+  }
+
+  public boolean analyzeStarted(String analyzerKey, Long launchId, Long projectId) {
+    Cache<Long, Long> analysisCache = analyzeStatus.get(analyzerKey);
+    if (analysisCache == null) {
+      return false;
+    }
+    analysisCache.put(launchId, projectId);
+    return true;
+  }
+
+  public boolean analyzeFinished(String analyzerKey, Long launchId) {
+    Cache<Long, Long> analysisCache = analyzeStatus.get(analyzerKey);
+    if (analysisCache == null) {
+      return false;
+    }
+    analysisCache.invalidate(launchId);
+    return true;
+  }
+
+  public Optional<Cache<Long, Long>> getAnalyzeStatus(String analyzerKey) {
+    return ofNullable(analyzeStatus.get(analyzerKey));
+  }
+
+  public boolean containsLaunchId(String analyzerKey, Long launchId) {
+    return ofNullable(analyzeStatus.get(analyzerKey)).map(
+        cache -> cache.asMap().containsKey(launchId)).orElse(Boolean.FALSE);
+  }
+
+  public boolean containsProjectId(String analyzerKey, Long projectId) {
+    return ofNullable(analyzeStatus.get(analyzerKey)).map(
+        cache -> cache.asMap().containsValue(projectId)).orElse(Boolean.FALSE);
+  }
+
+  public Set<String> getStartedAnalyzers(Long launchId) {
+    return analyzeStatus.entrySet()
+        .stream()
+        .filter(entry -> entry.getValue().asMap().containsKey(launchId))
+        .map(Map.Entry::getKey)
+        .collect(Collectors.toSet());
+  }
+
+  public Set<String> getAnalyzers() {
+    return analyzeStatus.keySet();
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/AnalyzerUtils.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/AnalyzerUtils.java
index ae37a9f8c7..a3d048e25b 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/AnalyzerUtils.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/AnalyzerUtils.java
@@ -16,8 +16,19 @@
 
 package com.epam.ta.reportportal.core.analyzer.auto.impl;
 
+import static com.epam.ta.reportportal.entity.enums.ProjectAttributeEnum.ALL_MESSAGES_SHOULD_MATCH;
+import static com.epam.ta.reportportal.entity.enums.ProjectAttributeEnum.AUTO_ANALYZER_ENABLED;
+import static com.epam.ta.reportportal.entity.enums.ProjectAttributeEnum.AUTO_ANALYZER_MODE;
+import static com.epam.ta.reportportal.entity.enums.ProjectAttributeEnum.AUTO_UNIQUE_ERROR_ANALYZER_ENABLED;
+import static com.epam.ta.reportportal.entity.enums.ProjectAttributeEnum.INDEXING_RUNNING;
+import static com.epam.ta.reportportal.entity.enums.ProjectAttributeEnum.MIN_SHOULD_MATCH;
+import static com.epam.ta.reportportal.entity.enums.ProjectAttributeEnum.NUMBER_OF_LOG_LINES;
+import static com.epam.ta.reportportal.entity.enums.ProjectAttributeEnum.SEARCH_LOGS_MIN_SHOULD_MATCH;
+import static com.epam.ta.reportportal.entity.enums.ProjectAttributeEnum.UNIQUE_ERROR_ANALYZER_REMOVE_NUMBERS;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.entity.item.TestItem;
-import com.epam.ta.reportportal.entity.log.Log;
+import com.epam.ta.reportportal.entity.log.LogFull;
 import com.epam.ta.reportportal.entity.project.Project;
 import com.epam.ta.reportportal.entity.project.ProjectUtils;
 import com.epam.ta.reportportal.ws.model.analyzer.IndexLog;
@@ -25,17 +36,13 @@
 import com.epam.ta.reportportal.ws.model.analyzer.RelevantItemInfo;
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
 import com.epam.ta.reportportal.ws.model.project.UniqueErrorConfig;
-import org.apache.commons.lang3.BooleanUtils;
-import org.apache.commons.lang3.StringUtils;
-
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.function.Function;
 import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.entity.enums.ProjectAttributeEnum.*;
-import static java.util.Optional.ofNullable;
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.commons.lang3.StringUtils;
 
 /**
  * Useful utils methods for basic analyzer
@@ -44,83 +51,92 @@
  */
 public class AnalyzerUtils {
 
-	private AnalyzerUtils() {
-		//static only
-	}
+  private AnalyzerUtils() {
+    //static only
+  }
 
-	/**
-	 * Creates {@link IndexLog} model for log for further
-	 * sending that into analyzer
-	 */
-	private final static Function<Log, IndexLog> TO_INDEX_LOG = log -> {
-		IndexLog indexLog = new IndexLog();
-		indexLog.setLogId(log.getId());
-		if (log.getLogLevel() != null) {
-			indexLog.setLogLevel(log.getLogLevel());
-		}
-		indexLog.setMessage(log.getLogMessage());
-		indexLog.setClusterId(log.getClusterId());
-		return indexLog;
-	};
+  /**
+   * Creates {@link IndexLog} model for log for further sending that into analyzer
+   */
+  private final static Function<LogFull, IndexLog> TO_INDEX_LOG = log -> {
+    IndexLog indexLog = new IndexLog();
+    indexLog.setLogId(log.getId());
+    if (log.getLogLevel() != null) {
+      indexLog.setLogLevel(log.getLogLevel());
+    }
+    indexLog.setMessage(log.getLogMessage());
+    indexLog.setClusterId(log.getClusterId());
+    return indexLog;
+  };
 
-	/**
-	 * Creates {@link IndexTestItem} model for test item and it's logs
-	 * for further sending that into analyzer.
-	 *
-	 * @param testItem Test item to be created from
-	 * @param logs     Test item's logs
-	 * @return {@link IndexTestItem} object
-	 */
-	public static IndexTestItem fromTestItem(TestItem testItem) {
-		IndexTestItem indexTestItem = new IndexTestItem();
-		indexTestItem.setTestItemId(testItem.getItemId());
-		indexTestItem.setTestItemName(testItem.getName());
-		indexTestItem.setUniqueId(testItem.getUniqueId());
-		indexTestItem.setStartTime(testItem.getStartTime());
-		indexTestItem.setTestCaseHash(testItem.getTestCaseHash());
-		if (testItem.getItemResults().getIssue() != null) {
-			indexTestItem.setIssueTypeLocator(testItem.getItemResults().getIssue().getIssueType().getLocator());
-			indexTestItem.setAutoAnalyzed(testItem.getItemResults().getIssue().getAutoAnalyzed());
-		}
-		return indexTestItem;
-	}
+  /**
+   * Creates {@link IndexTestItem} model for test item and it's logs for further sending that into
+   * analyzer.
+   *
+   * @param testItem Test item to be created from
+   * @return {@link IndexTestItem} object
+   */
+  public static IndexTestItem fromTestItem(TestItem testItem) {
+    IndexTestItem indexTestItem = new IndexTestItem();
+    indexTestItem.setTestItemId(testItem.getItemId());
+    indexTestItem.setTestItemName(testItem.getName());
+    indexTestItem.setUniqueId(testItem.getUniqueId());
+    indexTestItem.setStartTime(testItem.getStartTime());
+    indexTestItem.setTestCaseHash(testItem.getTestCaseHash());
+    if (testItem.getItemResults().getIssue() != null) {
+      indexTestItem.setIssueTypeLocator(
+          testItem.getItemResults().getIssue().getIssueType().getLocator());
+      indexTestItem.setAutoAnalyzed(testItem.getItemResults().getIssue().getAutoAnalyzed());
+    }
+    return indexTestItem;
+  }
 
-	public static Set<IndexLog> fromLogs(List<Log> logs) {
-		return logs.stream().filter(it -> StringUtils.isNotEmpty(it.getLogMessage())).map(TO_INDEX_LOG).collect(Collectors.toSet());
-	}
+  public static Set<IndexLog> fromLogs(List<LogFull> logs) {
+    return logs.stream().filter(it -> StringUtils.isNotEmpty(it.getLogMessage())).map(TO_INDEX_LOG)
+        .collect(Collectors.toSet());
+  }
 
-	public static AnalyzerConfig getAnalyzerConfig(Project project) {
-		Map<String, String> configParameters = ProjectUtils.getConfigParameters(project.getProjectAttributes());
-		return getAnalyzerConfig(configParameters);
-	}
+  public static AnalyzerConfig getAnalyzerConfig(Project project) {
+    Map<String, String> configParameters = ProjectUtils.getConfigParameters(
+        project.getProjectAttributes());
+    return getAnalyzerConfig(configParameters);
+  }
 
-	public static AnalyzerConfig getAnalyzerConfig(Map<String, String> configParameters) {
-		AnalyzerConfig analyzerConfig = new AnalyzerConfig();
-		analyzerConfig.setIsAutoAnalyzerEnabled(BooleanUtils.toBoolean(configParameters.get(AUTO_ANALYZER_ENABLED.getAttribute())));
-		analyzerConfig.setMinShouldMatch(Integer.valueOf(ofNullable(configParameters.get(MIN_SHOULD_MATCH.getAttribute())).orElse(
-				MIN_SHOULD_MATCH.getDefaultValue())));
-		analyzerConfig.setSearchLogsMinShouldMatch(Integer.valueOf(ofNullable(configParameters.get(SEARCH_LOGS_MIN_SHOULD_MATCH.getAttribute())).orElse(
-				SEARCH_LOGS_MIN_SHOULD_MATCH.getDefaultValue())));
-		analyzerConfig.setNumberOfLogLines(Integer.valueOf(ofNullable(configParameters.get(NUMBER_OF_LOG_LINES.getAttribute())).orElse(
-				NUMBER_OF_LOG_LINES.getDefaultValue())));
-		analyzerConfig.setIndexingRunning(BooleanUtils.toBoolean(configParameters.get(INDEXING_RUNNING.getAttribute())));
-		analyzerConfig.setAnalyzerMode(configParameters.get(AUTO_ANALYZER_MODE.getAttribute()));
-		analyzerConfig.setAllMessagesShouldMatch(BooleanUtils.toBoolean(configParameters.get(ALL_MESSAGES_SHOULD_MATCH.getAttribute())));
-		return analyzerConfig;
-	}
+  public static AnalyzerConfig getAnalyzerConfig(Map<String, String> configParameters) {
+    AnalyzerConfig analyzerConfig = new AnalyzerConfig();
+    analyzerConfig.setIsAutoAnalyzerEnabled(
+        BooleanUtils.toBoolean(configParameters.get(AUTO_ANALYZER_ENABLED.getAttribute())));
+    analyzerConfig.setMinShouldMatch(
+        Integer.valueOf(ofNullable(configParameters.get(MIN_SHOULD_MATCH.getAttribute())).orElse(
+            MIN_SHOULD_MATCH.getDefaultValue())));
+    analyzerConfig.setSearchLogsMinShouldMatch(Integer.valueOf(
+        ofNullable(configParameters.get(SEARCH_LOGS_MIN_SHOULD_MATCH.getAttribute())).orElse(
+            SEARCH_LOGS_MIN_SHOULD_MATCH.getDefaultValue())));
+    analyzerConfig.setNumberOfLogLines(
+        Integer.valueOf(ofNullable(configParameters.get(NUMBER_OF_LOG_LINES.getAttribute())).orElse(
+            NUMBER_OF_LOG_LINES.getDefaultValue())));
+    analyzerConfig.setIndexingRunning(
+        BooleanUtils.toBoolean(configParameters.get(INDEXING_RUNNING.getAttribute())));
+    analyzerConfig.setAnalyzerMode(configParameters.get(AUTO_ANALYZER_MODE.getAttribute()));
+    analyzerConfig.setAllMessagesShouldMatch(
+        BooleanUtils.toBoolean(configParameters.get(ALL_MESSAGES_SHOULD_MATCH.getAttribute())));
+    return analyzerConfig;
+  }
 
-	public static UniqueErrorConfig getUniqueErrorConfig(Map<String, String> configParameters) {
-		final UniqueErrorConfig uniqueErrorConfig = new UniqueErrorConfig();
-		uniqueErrorConfig.setEnabled(BooleanUtils.toBoolean(configParameters.get(AUTO_UNIQUE_ERROR_ANALYZER_ENABLED.getAttribute())));
-		uniqueErrorConfig.setRemoveNumbers(BooleanUtils.toBoolean(configParameters.get(UNIQUE_ERROR_ANALYZER_REMOVE_NUMBERS.getAttribute())));
-		return uniqueErrorConfig;
-	}
+  public static UniqueErrorConfig getUniqueErrorConfig(Map<String, String> configParameters) {
+    final UniqueErrorConfig uniqueErrorConfig = new UniqueErrorConfig();
+    uniqueErrorConfig.setEnabled(BooleanUtils.toBoolean(
+        configParameters.get(AUTO_UNIQUE_ERROR_ANALYZER_ENABLED.getAttribute())));
+    uniqueErrorConfig.setRemoveNumbers(BooleanUtils.toBoolean(
+        configParameters.get(UNIQUE_ERROR_ANALYZER_REMOVE_NUMBERS.getAttribute())));
+    return uniqueErrorConfig;
+  }
 
-	public static final Function<TestItem, RelevantItemInfo> TO_RELEVANT_ITEM_INFO = item -> {
-		RelevantItemInfo relevantItemInfo = new RelevantItemInfo();
-		relevantItemInfo.setItemId(String.valueOf(item.getItemId()));
-		relevantItemInfo.setPath(item.getPath());
-		relevantItemInfo.setLaunchId(String.valueOf(item.getLaunchId()));
-		return relevantItemInfo;
-	};
+  public static final Function<TestItem, RelevantItemInfo> TO_RELEVANT_ITEM_INFO = item -> {
+    RelevantItemInfo relevantItemInfo = new RelevantItemInfo();
+    relevantItemInfo.setItemId(String.valueOf(item.getItemId()));
+    relevantItemInfo.setPath(item.getPath());
+    relevantItemInfo.setLaunchId(String.valueOf(item.getLaunchId()));
+    return relevantItemInfo;
+  };
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/LogIndexerService.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/LogIndexerService.java
index d873b65edf..429225b290 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/LogIndexerService.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/LogIndexerService.java
@@ -29,6 +29,12 @@
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.epam.ta.reportportal.ws.model.analyzer.IndexLaunch;
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
+import org.apache.commons.collections4.CollectionUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -37,142 +43,145 @@
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-import org.springframework.util.CollectionUtils;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-import java.util.stream.Collectors;
 
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @Service
 public class LogIndexerService implements LogIndexer {
-	private static Logger LOGGER = LoggerFactory.getLogger(LogIndexerService.class);
-
-	private final BatchLogIndexer batchLogIndexer;
-
-	private final TaskExecutor taskExecutor;
-
-	private final LaunchRepository launchRepository;
-
-	private final TestItemRepository testItemRepository;
-
-	private final IndexerServiceClient indexerServiceClient;
-
-	private final LaunchPreparerService launchPreparerService;
-
-	private final IndexerStatusCache indexerStatusCache;
-
-	@Autowired
-	public LogIndexerService(BatchLogIndexer batchLogIndexer, @Qualifier("logIndexTaskExecutor") TaskExecutor taskExecutor,
-			LaunchRepository launchRepository, TestItemRepository testItemRepository, IndexerServiceClient indexerServiceClient,
-			LaunchPreparerService launchPreparerService, IndexerStatusCache indexerStatusCache) {
-		this.batchLogIndexer = batchLogIndexer;
-		this.taskExecutor = taskExecutor;
-		this.launchRepository = launchRepository;
-		this.testItemRepository = testItemRepository;
-		this.indexerServiceClient = indexerServiceClient;
-		this.launchPreparerService = launchPreparerService;
-		this.indexerStatusCache = indexerStatusCache;
-	}
-
-	@Override
-	public CompletableFuture<Long> index(Long projectId, AnalyzerConfig analyzerConfig) {
-		return CompletableFuture.supplyAsync(() -> {
-			try {
-				LOGGER.info("Start indexing for project: {}", projectId);
-				indexerStatusCache.indexingStarted(projectId);
-				final Long indexed = batchLogIndexer.index(projectId, analyzerConfig);
-				LOGGER.info("Indexing finished for project: {}. Logs indexed: {}", projectId, indexed);
-				return indexed;
-			} catch (Exception e) {
-				LOGGER.error(e.getMessage(), e);
-				throw new ReportPortalException(e.getMessage());
-			} finally {
-				indexerStatusCache.indexingFinished(projectId);
-			}
-		}, taskExecutor);
-	}
-
-	@Override
-	@Transactional(readOnly = true)
-	public Long indexLaunchLogs(Launch launch, AnalyzerConfig analyzerConfig) {
-		try {
-			indexerStatusCache.indexingStarted(launch.getProjectId());
-			final List<Long> itemIds = testItemRepository.selectIdsWithIssueByLaunch(launch.getId());
-			return batchLogIndexer.index(analyzerConfig, launch, itemIds);
-		} catch (Exception e) {
-			LOGGER.error(e.getMessage(), e);
-			throw new ReportPortalException(e.getMessage());
-		} finally {
-			indexerStatusCache.indexingFinished(launch.getProjectId());
-		}
-	}
-
-	@Override
-	@Transactional(readOnly = true)
-	public Long indexItemsLogs(Long projectId, Long launchId, List<Long> itemIds, AnalyzerConfig analyzerConfig) {
-		try {
-			indexerStatusCache.indexingStarted(projectId);
-			Launch launch = launchRepository.findById(launchId)
-					.orElseThrow(() -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND, launchId));
-			return batchLogIndexer.index(analyzerConfig, launch, itemIds);
-		} catch (Exception e) {
-			LOGGER.error(e.getMessage(), e);
-			throw new ReportPortalException(e.getMessage());
-		} finally {
-			indexerStatusCache.indexingFinished(projectId);
-		}
-	}
-
-	@Override
-	public void deleteIndex(Long project) {
-		indexerServiceClient.deleteIndex(project);
-	}
-
-	@Override
-	public CompletableFuture<Long> cleanIndex(Long index, List<Long> ids) {
-		return CollectionUtils.isEmpty(ids) ?
-				CompletableFuture.completedFuture(0L) :
-				CompletableFuture.supplyAsync(() -> indexerServiceClient.cleanIndex(index, ids));
-	}
-
-	@Async
-	@Override
-	public void indexDefectsUpdate(Long projectId, AnalyzerConfig analyzerConfig, List<TestItem> testItems) {
-		if (CollectionUtils.isEmpty(testItems)) {
-			return;
-		}
-
-		Map<Long, String> itemsForIndexUpdate = testItems.stream()
-				.collect(Collectors.toMap(TestItem::getItemId, it -> it.getItemResults().getIssue().getIssueType().getLocator()));
-
-		List<Long> missedItemIds = indexerServiceClient.indexDefectsUpdate(projectId, itemsForIndexUpdate);
-		List<TestItem> missedItems = testItems.stream().filter(it -> missedItemIds.contains(it.getItemId())).collect(Collectors.toList());
-
-		List<IndexLaunch> indexLaunchList = launchPreparerService.prepare(analyzerConfig, missedItems);
-
-		indexerServiceClient.index(indexLaunchList);
-	}
-
-	@Override
-	public int indexItemsRemove(Long projectId, Collection<Long> itemsForIndexRemove) {
-		return indexerServiceClient.indexItemsRemove(projectId, itemsForIndexRemove);
-	}
-
-	@Async
-	@Override
-	public void indexItemsRemoveAsync(Long projectId, Collection<Long> itemsForIndexRemove) {
-		indexerServiceClient.indexItemsRemoveAsync(projectId, itemsForIndexRemove);
-	}
-
-	@Async
-	@Override
-	public void indexLaunchesRemove(Long projectId, Collection<Long> launchesForIndexRemove) {
-		indexerServiceClient.indexLaunchesRemove(projectId, launchesForIndexRemove);
-	}
+
+  private static Logger LOGGER = LoggerFactory.getLogger(LogIndexerService.class);
+
+  private final BatchLogIndexer batchLogIndexer;
+
+  private final TaskExecutor taskExecutor;
+
+  private final LaunchRepository launchRepository;
+
+  private final TestItemRepository testItemRepository;
+
+  private final IndexerServiceClient indexerServiceClient;
+
+  private final LaunchPreparerService launchPreparerService;
+
+  private final IndexerStatusCache indexerStatusCache;
+
+  @Autowired
+  public LogIndexerService(BatchLogIndexer batchLogIndexer,
+      @Qualifier("logIndexTaskExecutor") TaskExecutor taskExecutor,
+      LaunchRepository launchRepository, TestItemRepository testItemRepository,
+      IndexerServiceClient indexerServiceClient,
+      LaunchPreparerService launchPreparerService, IndexerStatusCache indexerStatusCache) {
+    this.batchLogIndexer = batchLogIndexer;
+    this.taskExecutor = taskExecutor;
+    this.launchRepository = launchRepository;
+    this.testItemRepository = testItemRepository;
+    this.indexerServiceClient = indexerServiceClient;
+    this.launchPreparerService = launchPreparerService;
+    this.indexerStatusCache = indexerStatusCache;
+  }
+
+  @Override
+  public CompletableFuture<Long> index(Long projectId, AnalyzerConfig analyzerConfig) {
+    return CompletableFuture.supplyAsync(() -> {
+      try {
+        LOGGER.info("Start indexing for project: {}", projectId);
+        indexerStatusCache.indexingStarted(projectId);
+        final Long indexed = batchLogIndexer.index(projectId, analyzerConfig);
+        LOGGER.info("Indexing finished for project: {}. Logs indexed: {}", projectId, indexed);
+        return indexed;
+      } catch (Exception e) {
+        LOGGER.error(e.getMessage(), e);
+        throw new ReportPortalException(e.getMessage());
+      } finally {
+        indexerStatusCache.indexingFinished(projectId);
+      }
+    }, taskExecutor);
+  }
+
+  @Override
+  @Transactional(readOnly = true)
+  public Long indexLaunchLogs(Launch launch, AnalyzerConfig analyzerConfig) {
+    try {
+      indexerStatusCache.indexingStarted(launch.getProjectId());
+      final List<Long> itemIds = testItemRepository.selectIdsWithIssueByLaunch(launch.getId());
+      return batchLogIndexer.index(analyzerConfig, launch, itemIds);
+    } catch (Exception e) {
+      LOGGER.error(e.getMessage(), e);
+      throw new ReportPortalException(e.getMessage());
+    } finally {
+      indexerStatusCache.indexingFinished(launch.getProjectId());
+    }
+  }
+
+  @Override
+  @Transactional(readOnly = true)
+  public Long indexItemsLogs(Long projectId, Long launchId, List<Long> itemIds,
+      AnalyzerConfig analyzerConfig) {
+    try {
+      indexerStatusCache.indexingStarted(projectId);
+      Launch launch = launchRepository.findById(launchId)
+          .orElseThrow(() -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND, launchId));
+      return batchLogIndexer.index(analyzerConfig, launch, itemIds);
+    } catch (Exception e) {
+      LOGGER.error(e.getMessage(), e);
+      throw new ReportPortalException(e.getMessage());
+    } finally {
+      indexerStatusCache.indexingFinished(projectId);
+    }
+  }
+
+  @Override
+  public void deleteIndex(Long project) {
+    indexerServiceClient.deleteIndex(project);
+  }
+
+  @Override
+  public CompletableFuture<Long> cleanIndex(Long index, List<Long> ids) {
+    return CollectionUtils.isEmpty(ids) ?
+        CompletableFuture.completedFuture(0L) :
+        CompletableFuture.supplyAsync(() -> indexerServiceClient.cleanIndex(index, ids));
+  }
+
+  @Async
+  @Override
+  public void indexDefectsUpdate(Long projectId, AnalyzerConfig analyzerConfig,
+      List<TestItem> testItems) {
+    if (CollectionUtils.isEmpty(testItems)) {
+      return;
+    }
+
+    Map<Long, String> itemsForIndexUpdate = testItems.stream()
+        .collect(Collectors.toMap(TestItem::getItemId,
+            it -> it.getItemResults().getIssue().getIssueType().getLocator()));
+
+    List<Long> missedItemIds = indexerServiceClient.indexDefectsUpdate(projectId,
+        itemsForIndexUpdate);
+    List<TestItem> missedItems = testItems.stream()
+        .filter(it -> missedItemIds.contains(it.getItemId())).collect(Collectors.toList());
+
+    if (CollectionUtils.isNotEmpty(missedItems)) {
+      List<IndexLaunch> indexLaunchList = launchPreparerService.prepare(analyzerConfig,
+          missedItems);
+      indexerServiceClient.index(indexLaunchList);
+    }
+  }
+
+  @Override
+  public int indexItemsRemove(Long projectId, Collection<Long> itemsForIndexRemove) {
+    return indexerServiceClient.indexItemsRemove(projectId, itemsForIndexRemove);
+  }
+
+  @Async
+  @Override
+  public void indexItemsRemoveAsync(Long projectId, Collection<Long> itemsForIndexRemove) {
+    indexerServiceClient.indexItemsRemoveAsync(projectId, itemsForIndexRemove);
+  }
+
+  @Async
+  @Override
+  public void indexLaunchesRemove(Long projectId, Collection<Long> launchesForIndexRemove) {
+    indexerServiceClient.indexLaunchesRemove(projectId, launchesForIndexRemove);
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/SearchLogServiceImpl.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/SearchLogServiceImpl.java
index 481c0a37dc..997f3f709c 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/SearchLogServiceImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/SearchLogServiceImpl.java
@@ -16,13 +16,22 @@
 
 package com.epam.ta.reportportal.core.analyzer.auto.impl;
 
+import static com.epam.ta.reportportal.commons.Preconditions.statusIn;
+import static com.epam.ta.reportportal.commons.Predicates.not;
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.ws.converter.converters.LogConverter.TO_LOG_ENTRY;
+import static java.util.Collections.singletonList;
+import static java.util.Optional.ofNullable;
+import static java.util.stream.Collectors.toMap;
+import static java.util.stream.Collectors.toSet;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.analyzer.auto.SearchLogService;
 import com.epam.ta.reportportal.core.analyzer.auto.client.AnalyzerServiceClient;
 import com.epam.ta.reportportal.core.analyzer.auto.strategy.search.SearchCollectorFactory;
 import com.epam.ta.reportportal.core.analyzer.auto.strategy.search.SearchLogsMode;
+import com.epam.ta.reportportal.core.log.LogService;
 import com.epam.ta.reportportal.dao.LaunchRepository;
-import com.epam.ta.reportportal.dao.LogRepository;
 import com.epam.ta.reportportal.dao.ProjectRepository;
 import com.epam.ta.reportportal.dao.TestItemRepository;
 import com.epam.ta.reportportal.entity.enums.LogLevel;
@@ -30,7 +39,7 @@
 import com.epam.ta.reportportal.entity.item.PathName;
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.launch.Launch;
-import com.epam.ta.reportportal.entity.log.Log;
+import com.epam.ta.reportportal.entity.log.LogFull;
 import com.epam.ta.reportportal.entity.project.Project;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.converter.converters.IssueConverter;
@@ -43,23 +52,18 @@
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
+import java.time.temporal.ChronoUnit;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
 import org.apache.commons.collections.CollectionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.time.temporal.ChronoUnit;
-import java.util.*;
-
-import static com.epam.ta.reportportal.commons.Preconditions.statusIn;
-import static com.epam.ta.reportportal.commons.Predicates.not;
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.ws.converter.converters.LogConverter.TO_LOG_ENTRY;
-import static java.util.Collections.singletonList;
-import static java.util.Optional.ofNullable;
-import static java.util.stream.Collectors.toMap;
-import static java.util.stream.Collectors.toSet;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
@@ -67,135 +71,154 @@
 @Transactional
 public class SearchLogServiceImpl implements SearchLogService {
 
-	private final ProjectRepository projectRepository;
-
-	private final LaunchRepository launchRepository;
-
-	private final TestItemRepository testItemRepository;
-
-	private final LogRepository logRepository;
-
-	private final AnalyzerServiceClient analyzerServiceClient;
-
-	private final SearchCollectorFactory searchCollectorFactory;
-
-	@Autowired
-	public SearchLogServiceImpl(ProjectRepository projectRepository, LaunchRepository launchRepository,
-			TestItemRepository testItemRepository, LogRepository logRepository, AnalyzerServiceClient analyzerServiceClient,
-			SearchCollectorFactory searchCollectorFactory) {
-		this.projectRepository = projectRepository;
-		this.launchRepository = launchRepository;
-		this.testItemRepository = testItemRepository;
-		this.logRepository = logRepository;
-		this.analyzerServiceClient = analyzerServiceClient;
-		this.searchCollectorFactory = searchCollectorFactory;
-	}
-
-	@Override
-	public Iterable<SearchLogRs> search(Long itemId, SearchLogRq request, ReportPortalUser.ProjectDetails projectDetails) {
-		Project project = projectRepository.findById(projectDetails.getProjectId())
-				.orElseThrow(() -> new ReportPortalException(ErrorType.PROJECT_NOT_FOUND, projectDetails.getProjectId()));
-
-		TestItem item = testItemRepository.findById(itemId)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, itemId));
-
-		Launch launch = launchRepository.findById(item.getLaunchId())
-				.orElseThrow(() -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND, item.getLaunchId()));
-
-		expect(item.getItemResults().getStatus(), not(statusIn(StatusEnum.IN_PROGRESS))).verify(ErrorType.TEST_ITEM_IS_NOT_FINISHED);
-
-		return composeRequest(request, project, item, launch).map(searchRq -> processRequest(project.getId(), searchRq))
-				.orElse(Collections.emptyList());
-	}
-
-	private Optional<SearchRq> composeRequest(SearchLogRq request, Project project, TestItem item, Launch launch) {
-		SearchLogsMode searchMode = SearchLogsMode.fromString(request.getSearchMode())
-				.orElseThrow(() -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR, request.getSearchMode()));
-
-		SearchRq searchRq = new SearchRq();
-
-		searchRq.setFilteredLaunchIds(searchCollectorFactory.getCollector(searchMode).collect(request.getFilterId(), launch));
-
-		//TODO fix query - select messages from `Nested Step` descendants too
-		List<String> logMessages = logRepository.findMessagesByLaunchIdAndItemIdAndPathAndLevelGte(launch.getId(),
-				item.getItemId(),
-				item.getPath(),
-				LogLevel.ERROR_INT
-		);
-		if (CollectionUtils.isEmpty(logMessages)) {
-			return Optional.empty();
-		}
-		searchRq.setLogMessages(logMessages);
-
-		final AnalyzerConfig analyzerConfig = AnalyzerUtils.getAnalyzerConfig(project);
-		searchRq.setAnalyzerConfig(analyzerConfig);
-		searchRq.setLogLines(analyzerConfig.getNumberOfLogLines());
-		searchRq.setItemId(item.getItemId());
-		searchRq.setLaunchId(launch.getId());
-		searchRq.setLaunchName(launch.getName());
-		searchRq.setProjectId(project.getId());
-		return Optional.of(searchRq);
-	}
-
-	private Collection<SearchLogRs> processRequest(Long projectId, SearchRq request) {
-		List<SearchRs> searchRs = analyzerServiceClient.searchLogs(request);
-		Map<Long, Long> logIdMapping = searchRs.stream()
-				.collect(HashMap::new, (m, rs) -> m.put(rs.getLogId(), rs.getTestItemId()), Map::putAll);
-		Map<Long, TestItem> testItemMapping = testItemRepository.findAllById(logIdMapping.values())
-				.stream()
-				.collect(toMap(TestItem::getItemId, item -> item));
-		List<Log> foundLogs = logRepository.findAllById(logIdMapping.keySet());
-		Map<Long, SearchLogRs> foundLogsMap = Maps.newHashMap();
-
-		foundLogs.forEach(log -> ofNullable(logIdMapping.get(log.getId())).ifPresent(itemId -> {
-			foundLogsMap.computeIfPresent(itemId, (key, value) -> {
-				value.getLogs().add(TO_LOG_ENTRY.apply(log));
-				return value;
-			});
-			foundLogsMap.computeIfAbsent(itemId, key -> composeResponse(testItemMapping, projectId, itemId, log));
-		}));
-		return foundLogsMap.values();
-	}
-
-	private SearchLogRs composeResponse(Map<Long, TestItem> testItemMapping, Long projectId, Long itemId, Log log) {
-		TestItem testItem = ofNullable(testItemMapping.get(itemId)).orElseThrow(() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND,
-				itemId
-		));
-		Long launchId = ofNullable(testItem.getLaunchId()).orElseThrow(() -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND,
-				testItem.getLaunchId()
-		));
-		Launch launch = launchRepository.findById(launchId)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND, launchId));
-
-		Map<Long, PathName> pathNameMapping = testItemRepository.selectPathNames(singletonList(testItem));
-
-		SearchLogRs response = new SearchLogRs();
-		response.setLaunchId(launch.getId());
-		ofNullable(pathNameMapping.get(testItem.getItemId())).ifPresent(pathName -> {
-			response.setPathNames(TestItemConverter.PATH_NAME_TO_RESOURCE.apply(pathName));
-		});
-		response.setItemId(testItem.getItemId());
-		response.setItemName(testItem.getName());
-		response.setPath(testItem.getPath());
-		response.setPatternTemplates(testItem.getPatternTemplateTestItems()
-				.stream()
-				.map(patternTemplateTestItem -> patternTemplateTestItem.getPatternTemplate().getName())
-				.collect(toSet()));
-		response.setDuration(ofNullable(testItem.getItemResults().getDuration()).orElseGet(() -> getDuration(testItem)));
-		response.setStatus(testItem.getItemResults().getStatus().name());
-		TestItem itemWithStats = testItem;
-		while (!itemWithStats.isHasStats()) {
-			final Long parentId = itemWithStats.getParentId();
-			itemWithStats = testItemRepository.findById(parentId)
-					.orElseThrow(() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, parentId));
-		}
-
-		response.setIssue(IssueConverter.TO_MODEL.apply(itemWithStats.getItemResults().getIssue()));
-		response.setLogs(Lists.newArrayList(TO_LOG_ENTRY.apply(log)));
-		return response;
-	}
-
-	private double getDuration(TestItem testItem) {
-		return ChronoUnit.MILLIS.between(testItem.getStartTime(), testItem.getItemResults().getEndTime()) / 1000d;
-	}
+  private final ProjectRepository projectRepository;
+
+  private final LaunchRepository launchRepository;
+
+  private final TestItemRepository testItemRepository;
+
+  private final LogService logService;
+
+  private final AnalyzerServiceClient analyzerServiceClient;
+
+  private final SearchCollectorFactory searchCollectorFactory;
+
+  @Autowired
+  public SearchLogServiceImpl(ProjectRepository projectRepository,
+      LaunchRepository launchRepository,
+      TestItemRepository testItemRepository, LogService logService,
+      AnalyzerServiceClient analyzerServiceClient,
+      SearchCollectorFactory searchCollectorFactory) {
+    this.projectRepository = projectRepository;
+    this.launchRepository = launchRepository;
+    this.testItemRepository = testItemRepository;
+    this.logService = logService;
+    this.analyzerServiceClient = analyzerServiceClient;
+    this.searchCollectorFactory = searchCollectorFactory;
+  }
+
+  @Override
+  public Iterable<SearchLogRs> search(Long itemId, SearchLogRq request,
+      ReportPortalUser.ProjectDetails projectDetails) {
+    Project project = projectRepository.findById(projectDetails.getProjectId())
+        .orElseThrow(() -> new ReportPortalException(ErrorType.PROJECT_NOT_FOUND,
+            projectDetails.getProjectId()));
+
+    TestItem item = testItemRepository.findById(itemId)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, itemId));
+
+    Launch launch = launchRepository.findById(item.getLaunchId())
+        .orElseThrow(
+            () -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND, item.getLaunchId()));
+
+    expect(item.getItemResults().getStatus(), not(statusIn(StatusEnum.IN_PROGRESS))).verify(
+        ErrorType.TEST_ITEM_IS_NOT_FINISHED);
+
+    return composeRequest(request, project, item, launch).map(
+            searchRq -> processRequest(project.getId(), searchRq))
+        .orElse(Collections.emptyList());
+  }
+
+  private Optional<SearchRq> composeRequest(SearchLogRq request, Project project, TestItem item,
+      Launch launch) {
+    SearchLogsMode searchMode = SearchLogsMode.fromString(request.getSearchMode())
+        .orElseThrow(
+            () -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR, request.getSearchMode()));
+
+    SearchRq searchRq = new SearchRq();
+
+    searchRq.setFilteredLaunchIds(
+        searchCollectorFactory.getCollector(searchMode).collect(request.getFilterId(), launch));
+
+    //TODO fix query - select messages from `Nested Step` descendants too
+    List<String> logMessages = logService.findMessagesByLaunchIdAndItemIdAndPathAndLevelGte(
+        launch.getId(),
+        item.getItemId(),
+        item.getPath(),
+        LogLevel.ERROR_INT
+    );
+    if (CollectionUtils.isEmpty(logMessages)) {
+      return Optional.empty();
+    }
+    searchRq.setLogMessages(logMessages);
+
+    final AnalyzerConfig analyzerConfig = AnalyzerUtils.getAnalyzerConfig(project);
+    searchRq.setAnalyzerConfig(analyzerConfig);
+    searchRq.setLogLines(analyzerConfig.getNumberOfLogLines());
+    searchRq.setItemId(item.getItemId());
+    searchRq.setLaunchId(launch.getId());
+    searchRq.setLaunchName(launch.getName());
+    searchRq.setProjectId(project.getId());
+    return Optional.of(searchRq);
+  }
+
+  private Collection<SearchLogRs> processRequest(Long projectId, SearchRq request) {
+    List<SearchRs> searchRs = analyzerServiceClient.searchLogs(request);
+    Map<Long, Long> logIdMapping = searchRs.stream()
+        .collect(HashMap::new, (m, rs) -> m.put(rs.getLogId(), rs.getTestItemId()), Map::putAll);
+    Map<Long, TestItem> testItemMapping = testItemRepository.findAllById(logIdMapping.values())
+        .stream()
+        .collect(toMap(TestItem::getItemId, item -> item));
+    List<LogFull> foundLogs = logService.findAllById(logIdMapping.keySet());
+    Map<Long, SearchLogRs> foundLogsMap = Maps.newHashMap();
+
+    foundLogs.forEach(log -> ofNullable(logIdMapping.get(log.getId())).ifPresent(itemId -> {
+      foundLogsMap.computeIfPresent(itemId, (key, value) -> {
+        value.getLogs().add(TO_LOG_ENTRY.apply(log));
+        return value;
+      });
+      foundLogsMap.computeIfAbsent(itemId,
+          key -> composeResponse(testItemMapping, projectId, itemId, log));
+    }));
+    return foundLogsMap.values();
+  }
+
+  private SearchLogRs composeResponse(Map<Long, TestItem> testItemMapping, Long projectId,
+      Long itemId, LogFull log) {
+    TestItem testItem = ofNullable(testItemMapping.get(itemId)).orElseThrow(
+        () -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND,
+            itemId
+        ));
+    Long launchId = ofNullable(testItem.getLaunchId()).orElseThrow(
+        () -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND,
+            testItem.getLaunchId()
+        ));
+    Launch launch = launchRepository.findById(launchId)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND, launchId));
+
+    Map<Long, PathName> pathNameMapping = testItemRepository.selectPathNames(
+        singletonList(testItem));
+
+    SearchLogRs response = new SearchLogRs();
+    response.setLaunchId(launch.getId());
+    ofNullable(pathNameMapping.get(testItem.getItemId())).ifPresent(pathName -> {
+      response.setPathNames(TestItemConverter.PATH_NAME_TO_RESOURCE.apply(pathName));
+    });
+    response.setItemId(testItem.getItemId());
+    response.setItemName(testItem.getName());
+    response.setPath(testItem.getPath());
+    response.setPatternTemplates(testItem.getPatternTemplateTestItems()
+        .stream()
+        .map(patternTemplateTestItem -> patternTemplateTestItem.getPatternTemplate().getName())
+        .collect(toSet()));
+    response.setDuration(
+        ofNullable(testItem.getItemResults().getDuration()).orElseGet(() -> getDuration(testItem)));
+    response.setStatus(testItem.getItemResults().getStatus().name());
+    TestItem itemWithStats = testItem;
+    while (!itemWithStats.isHasStats()) {
+      final Long parentId = itemWithStats.getParentId();
+      itemWithStats = testItemRepository.findById(parentId)
+          .orElseThrow(() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, parentId));
+    }
+
+    response.setIssue(IssueConverter.TO_MODEL.apply(itemWithStats.getItemResults().getIssue()));
+    response.setLogs(Lists.newArrayList(TO_LOG_ENTRY.apply(log)));
+    return response;
+  }
+
+  private double getDuration(TestItem testItem) {
+    return
+        ChronoUnit.MILLIS.between(testItem.getStartTime(), testItem.getItemResults().getEndTime())
+            / 1000d;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/SuggestItemService.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/SuggestItemService.java
index 47a0e95c57..5547e2e220 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/SuggestItemService.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/SuggestItemService.java
@@ -15,6 +15,10 @@
  */
 package com.epam.ta.reportportal.core.analyzer.auto.impl;
 
+import static com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerUtils.getAnalyzerConfig;
+import static com.epam.ta.reportportal.entity.enums.LogLevel.ERROR_INT;
+import static com.epam.ta.reportportal.ws.model.ErrorType.BAD_REQUEST_ERROR;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.analyzer.auto.client.AnalyzerServiceClient;
 import com.epam.ta.reportportal.core.analyzer.auto.client.model.SuggestInfo;
@@ -23,8 +27,8 @@
 import com.epam.ta.reportportal.core.item.validator.state.TestItemValidator;
 import com.epam.ta.reportportal.core.launch.GetLaunchHandler;
 import com.epam.ta.reportportal.core.launch.cluster.GetClusterHandler;
+import com.epam.ta.reportportal.core.log.LogService;
 import com.epam.ta.reportportal.core.project.GetProjectHandler;
-import com.epam.ta.reportportal.dao.LogRepository;
 import com.epam.ta.reportportal.dao.TestItemRepository;
 import com.epam.ta.reportportal.entity.cluster.Cluster;
 import com.epam.ta.reportportal.entity.item.TestItem;
@@ -35,18 +39,13 @@
 import com.epam.ta.reportportal.ws.converter.converters.TestItemConverter;
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
 import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
 import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerUtils.getAnalyzerConfig;
-import static com.epam.ta.reportportal.entity.enums.LogLevel.ERROR_INT;
-import static com.epam.ta.reportportal.ws.model.ErrorType.BAD_REQUEST_ERROR;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
@@ -54,127 +53,143 @@
 @Service
 public class SuggestItemService {
 
-	private static final int SUGGESTED_ITEMS_LOGS_LIMIT = 5;
-
-	private final AnalyzerServiceClient analyzerServiceClient;
-
-	private final GetProjectHandler getProjectHandler;
-	private final GetLaunchHandler getLaunchHandler;
-	private final GetClusterHandler getClusterHandler;
-
-	private final LaunchAccessValidator launchAccessValidator;
-
-	private final TestItemRepository testItemRepository;
-	private final LogRepository logRepository;
-
-	private final List<TestItemValidator> testItemValidators;
-
-	@Autowired
-	public SuggestItemService(AnalyzerServiceClient analyzerServiceClient, GetProjectHandler getProjectHandler,
-			GetLaunchHandler getLaunchHandler, GetClusterHandler getClusterHandler, LaunchAccessValidator launchAccessValidator,
-			TestItemRepository testItemRepository, LogRepository logRepository, List<TestItemValidator> testItemValidators) {
-		this.analyzerServiceClient = analyzerServiceClient;
-		this.getProjectHandler = getProjectHandler;
-		this.getLaunchHandler = getLaunchHandler;
-		this.getClusterHandler = getClusterHandler;
-		this.launchAccessValidator = launchAccessValidator;
-		this.testItemRepository = testItemRepository;
-		this.logRepository = logRepository;
-		this.testItemValidators = testItemValidators;
-	}
-
-	@Transactional(readOnly = true)
-	public List<SuggestedItem> suggestItems(Long testItemId, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user) {
-
-		TestItem testItem = testItemRepository.findById(testItemId)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, testItemId));
-
-		validateTestItem(testItem);
-
-		Launch launch = getLaunch(testItem.getLaunchId(), projectDetails, user);
-		Project project = getProjectHandler.get(projectDetails);
-
-		SuggestRq suggestRq = prepareSuggestRq(testItem, launch, project);
-		return getSuggestedItems(suggestRq);
-	}
-
-	private void validateTestItem(TestItem testItem) {
-		testItemValidators.forEach(v -> {
-			if (!v.validate(testItem)) {
-				throw new ReportPortalException(BAD_REQUEST_ERROR, v.provide(testItem));
-			}
-		});
-	}
-
-	@Transactional(readOnly = true)
-	public List<SuggestedItem> suggestClusterItems(Long clusterId, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user) {
-		final Cluster cluster = getClusterHandler.getById(clusterId);
-		final Launch launch = getLaunch(cluster.getLaunchId(), projectDetails, user);
-		final Project project = getProjectHandler.get(projectDetails);
-		final SuggestRq suggestRq = prepareSuggestRq(cluster, launch, project);
-		return getSuggestedItems(suggestRq);
-	}
-
-	private Launch getLaunch(Long launchId, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user) {
-		Launch launch = getLaunchHandler.get(launchId);
-		launchAccessValidator.validate(launch, projectDetails, user);
-		return launch;
-	}
-
-	private SuggestRq prepareSuggestRq(TestItem testItem, Launch launch, Project project) {
-		SuggestRq suggestRq = prepareSuggestRq(launch, project);
-		suggestRq.setTestItemId(testItem.getItemId());
-		suggestRq.setUniqueId(testItem.getUniqueId());
-		suggestRq.setTestCaseHash(testItem.getTestCaseHash());
-		suggestRq.setLogs(AnalyzerUtils.fromLogs(logRepository.findAllUnderTestItemByLaunchIdAndTestItemIdsAndLogLevelGte(launch.getId(),
-				Collections.singletonList(testItem.getItemId()),
-				ERROR_INT
-		)));
-		return suggestRq;
-	}
-
-	private SuggestRq prepareSuggestRq(Cluster cluster, Launch launch, Project project) {
-		SuggestRq suggestRq = prepareSuggestRq(launch, project);
-		suggestRq.setClusterId(cluster.getIndexId());
-		return suggestRq;
-	}
-
-	private SuggestRq prepareSuggestRq(Launch launch, Project project) {
-		SuggestRq suggestRq = new SuggestRq();
-		suggestRq.setLaunchId(launch.getId());
-		suggestRq.setLaunchName(launch.getName());
-		suggestRq.setProject(project.getId());
-		suggestRq.setAnalyzerConfig(getAnalyzerConfig(project));
-		return suggestRq;
-	}
-
-	private List<SuggestedItem> getSuggestedItems(SuggestRq suggestRq) {
-		return analyzerServiceClient.searchSuggests(suggestRq)
-				.stream()
-				.map(this::prepareSuggestedItem)
-				.filter(Objects::nonNull)
-				.collect(Collectors.toList());
-	}
-
-	private SuggestedItem prepareSuggestedItem(SuggestInfo suggestInfo) {
-		TestItem relevantTestItem = testItemRepository.findById(suggestInfo.getRelevantItem()).orElse(null);
-		//TODO: EPMRPP-61038 temp fix for the case when item was removed from db but still exists in elastic
-		if (relevantTestItem == null) {
-			return null;
-		}
-		SuggestedItem suggestedItem = new SuggestedItem();
-		suggestedItem.setSuggestRs(suggestInfo);
-		suggestedItem.setTestItemResource(TestItemConverter.TO_RESOURCE.apply(relevantTestItem));
-		suggestedItem.setLogs(logRepository.findLatestUnderTestItemByLaunchIdAndTestItemIdsAndLogLevelGte(relevantTestItem.getLaunchId(),
-				relevantTestItem.getItemId(),
-				ERROR_INT,
-				SUGGESTED_ITEMS_LOGS_LIMIT
-		).stream().map(LogConverter.TO_RESOURCE).collect(Collectors.toSet()));
-		return suggestedItem;
-	}
-
-	public OperationCompletionRS handleSuggestChoice(List<SuggestInfo> suggestInfos) {
-		analyzerServiceClient.handleSuggestChoice(suggestInfos);
-		return new OperationCompletionRS("User choice of suggested item was sent for handling to ML");
-	}
+  private static final int SUGGESTED_ITEMS_LOGS_LIMIT = 5;
+
+  private final AnalyzerServiceClient analyzerServiceClient;
+
+  private final GetProjectHandler getProjectHandler;
+  private final GetLaunchHandler getLaunchHandler;
+  private final GetClusterHandler getClusterHandler;
+
+  private final LaunchAccessValidator launchAccessValidator;
+
+  private final TestItemRepository testItemRepository;
+  private final LogService logService;
+
+  private final List<TestItemValidator> testItemValidators;
+
+  @Autowired
+  public SuggestItemService(AnalyzerServiceClient analyzerServiceClient,
+      GetProjectHandler getProjectHandler,
+      GetLaunchHandler getLaunchHandler, GetClusterHandler getClusterHandler,
+      LaunchAccessValidator launchAccessValidator,
+      TestItemRepository testItemRepository, LogService logService,
+      List<TestItemValidator> testItemValidators) {
+    this.analyzerServiceClient = analyzerServiceClient;
+    this.getProjectHandler = getProjectHandler;
+    this.getLaunchHandler = getLaunchHandler;
+    this.getClusterHandler = getClusterHandler;
+    this.launchAccessValidator = launchAccessValidator;
+    this.testItemRepository = testItemRepository;
+    this.logService = logService;
+    this.testItemValidators = testItemValidators;
+  }
+
+  @Transactional(readOnly = true)
+  public List<SuggestedItem> suggestItems(Long testItemId,
+      ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user) {
+
+    TestItem testItem = testItemRepository.findById(testItemId)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, testItemId));
+
+    validateTestItem(testItem);
+
+    Launch launch = getLaunch(testItem.getLaunchId(), projectDetails, user);
+    Project project = getProjectHandler.get(projectDetails);
+
+    SuggestRq suggestRq = prepareSuggestRq(testItem, launch, project);
+    return getSuggestedItems(suggestRq);
+  }
+
+  private void validateTestItem(TestItem testItem) {
+    testItemValidators.forEach(v -> {
+      if (!v.validate(testItem)) {
+        throw new ReportPortalException(BAD_REQUEST_ERROR, v.provide(testItem));
+      }
+    });
+  }
+
+  @Transactional(readOnly = true)
+  public List<SuggestedItem> suggestClusterItems(Long clusterId,
+      ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user) {
+    final Cluster cluster = getClusterHandler.getById(clusterId);
+    final Launch launch = getLaunch(cluster.getLaunchId(), projectDetails, user);
+    final Project project = getProjectHandler.get(projectDetails);
+    final SuggestRq suggestRq = prepareSuggestRq(cluster, launch, project);
+    return getSuggestedItems(suggestRq);
+  }
+
+  private Launch getLaunch(Long launchId, ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user) {
+    Launch launch = getLaunchHandler.get(launchId);
+    launchAccessValidator.validate(launch, projectDetails, user);
+    return launch;
+  }
+
+  private SuggestRq prepareSuggestRq(TestItem testItem, Launch launch, Project project) {
+    SuggestRq suggestRq = prepareSuggestRq(launch, project);
+    suggestRq.setTestItemId(testItem.getItemId());
+    suggestRq.setUniqueId(testItem.getUniqueId());
+    suggestRq.setTestCaseHash(testItem.getTestCaseHash());
+    suggestRq.setLogs(AnalyzerUtils.fromLogs(
+        logService.findAllUnderTestItemByLaunchIdAndTestItemIdsAndLogLevelGte(launch.getId(),
+            Collections.singletonList(testItem.getItemId()),
+            ERROR_INT
+        )));
+    return suggestRq;
+  }
+
+  private SuggestRq prepareSuggestRq(Cluster cluster, Launch launch, Project project) {
+    SuggestRq suggestRq = prepareSuggestRq(launch, project);
+    suggestRq.setClusterId(cluster.getIndexId());
+    return suggestRq;
+  }
+
+  private SuggestRq prepareSuggestRq(Launch launch, Project project) {
+    SuggestRq suggestRq = new SuggestRq();
+    suggestRq.setLaunchId(launch.getId());
+    suggestRq.setLaunchName(launch.getName());
+    suggestRq.setProject(project.getId());
+    suggestRq.setAnalyzerConfig(getAnalyzerConfig(project));
+    suggestRq.setLaunchNumber(launch.getNumber());
+    return suggestRq;
+  }
+
+  private List<SuggestedItem> getSuggestedItems(SuggestRq suggestRq) {
+    return analyzerServiceClient.searchSuggests(suggestRq)
+        .stream()
+        .map(this::prepareSuggestedItem)
+        .filter(Objects::nonNull)
+        .collect(Collectors.toList());
+  }
+
+  private SuggestedItem prepareSuggestedItem(SuggestInfo suggestInfo) {
+    TestItem relevantTestItem = testItemRepository.findById(suggestInfo.getRelevantItem())
+        .orElse(null);
+    //TODO: EPMRPP-61038 temp fix for the case when item was removed from db but still exists in elastic
+    if (relevantTestItem == null) {
+      return null;
+    }
+    SuggestedItem suggestedItem = new SuggestedItem();
+    roundSuggestInfoMatchScore(suggestInfo);
+    suggestedItem.setSuggestRs(suggestInfo);
+    suggestedItem.setTestItemResource(TestItemConverter.TO_RESOURCE.apply(relevantTestItem));
+    suggestedItem.setLogs(logService.findLatestUnderTestItemByLaunchIdAndTestItemIdsAndLogLevelGte(
+        relevantTestItem.getLaunchId(),
+        relevantTestItem.getItemId(),
+        ERROR_INT,
+        SUGGESTED_ITEMS_LOGS_LIMIT
+    ).stream().map(LogConverter.TO_RESOURCE).collect(Collectors.toSet()));
+    return suggestedItem;
+  }
+
+  private void roundSuggestInfoMatchScore(SuggestInfo info) {
+    float roundedMatchScore = Math.round(info.getMatchScore());
+    info.setMatchScore(roundedMatchScore);
+  }
+
+  public OperationCompletionRS handleSuggestChoice(List<SuggestInfo> suggestInfos) {
+    analyzerServiceClient.handleSuggestChoice(suggestInfos);
+    return new OperationCompletionRS("User choice of suggested item was sent for handling to ML");
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/SuggestedItem.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/SuggestedItem.java
index 743fbac480..5d956d6055 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/SuggestedItem.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/SuggestedItem.java
@@ -19,7 +19,6 @@
 import com.epam.ta.reportportal.ws.model.TestItemResource;
 import com.epam.ta.reportportal.ws.model.log.LogResource;
 import com.fasterxml.jackson.annotation.JsonInclude;
-
 import java.util.Set;
 
 /**
@@ -28,33 +27,33 @@
 @JsonInclude(JsonInclude.Include.NON_NULL)
 public class SuggestedItem {
 
-	private TestItemResource testItemResource;
+  private TestItemResource testItemResource;
 
-	private Set<LogResource> logs;
+  private Set<LogResource> logs;
 
-	private SuggestInfo suggestInfo;
+  private SuggestInfo suggestInfo;
 
-	public Set<LogResource> getLogs() {
-		return logs;
-	}
+  public Set<LogResource> getLogs() {
+    return logs;
+  }
 
-	public void setLogs(Set<LogResource> logs) {
-		this.logs = logs;
-	}
+  public void setLogs(Set<LogResource> logs) {
+    this.logs = logs;
+  }
 
-	public TestItemResource getTestItemResource() {
-		return testItemResource;
-	}
+  public TestItemResource getTestItemResource() {
+    return testItemResource;
+  }
 
-	public void setTestItemResource(TestItemResource testItemResource) {
-		this.testItemResource = testItemResource;
-	}
+  public void setTestItemResource(TestItemResource testItemResource) {
+    this.testItemResource = testItemResource;
+  }
 
-	public SuggestInfo getSuggestRs() {
-		return suggestInfo;
-	}
+  public SuggestInfo getSuggestRs() {
+    return suggestInfo;
+  }
 
-	public void setSuggestRs(SuggestInfo suggestInfo) {
-		this.suggestInfo = suggestInfo;
-	}
+  public void setSuggestRs(SuggestInfo suggestInfo) {
+    this.suggestInfo = suggestInfo;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/preparer/LaunchPreparerService.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/preparer/LaunchPreparerService.java
index 3327a35e0a..3a10aae3b2 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/preparer/LaunchPreparerService.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/preparer/LaunchPreparerService.java
@@ -20,7 +20,6 @@
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.ws.model.analyzer.IndexLaunch;
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
-
 import java.util.List;
 import java.util.Optional;
 
@@ -29,12 +28,13 @@
  */
 public interface LaunchPreparerService {
 
-	Optional<IndexLaunch> prepare(Launch launch, List<TestItem> testItems, AnalyzerConfig analyzerConfig);
+  Optional<IndexLaunch> prepare(Launch launch, List<TestItem> testItems,
+      AnalyzerConfig analyzerConfig);
 
-	Optional<IndexLaunch> prepare(Long id, AnalyzerConfig analyzerConfig);
+  Optional<IndexLaunch> prepare(Long id, AnalyzerConfig analyzerConfig);
 
-	List<IndexLaunch> prepare(List<Long> ids, AnalyzerConfig analyzerConfig);
+  List<IndexLaunch> prepare(List<Long> ids, AnalyzerConfig analyzerConfig);
 
-	List<IndexLaunch> prepare(AnalyzerConfig analyzerConfig, List<TestItem> testItems);
+  List<IndexLaunch> prepare(AnalyzerConfig analyzerConfig, List<TestItem> testItems);
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/preparer/LaunchPreparerServiceImpl.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/preparer/LaunchPreparerServiceImpl.java
index e8f2680795..665aa65692 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/preparer/LaunchPreparerServiceImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/preparer/LaunchPreparerServiceImpl.java
@@ -16,6 +16,8 @@
 
 package com.epam.ta.reportportal.core.analyzer.auto.impl.preparer;
 
+import static com.epam.ta.reportportal.util.Predicates.LAUNCH_CAN_BE_INDEXED;
+
 import com.epam.ta.reportportal.dao.ClusterRepository;
 import com.epam.ta.reportportal.dao.LaunchRepository;
 import com.epam.ta.reportportal.entity.cluster.Cluster;
@@ -26,17 +28,14 @@
 import com.epam.ta.reportportal.ws.model.analyzer.IndexLaunch;
 import com.epam.ta.reportportal.ws.model.analyzer.IndexTestItem;
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
-import org.apache.commons.collections.CollectionUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
 import java.time.LocalDateTime;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.util.Predicates.LAUNCH_CAN_BE_INDEXED;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
@@ -44,93 +43,103 @@
 @Service
 public class LaunchPreparerServiceImpl implements LaunchPreparerService {
 
-	private final LaunchRepository launchRepository;
-	private final ClusterRepository clusterRepository;
-
-	private final TestItemPreparerService testItemPreparerService;
-
-	@Autowired
-	public LaunchPreparerServiceImpl(LaunchRepository launchRepository, ClusterRepository clusterRepository,
-			TestItemPreparerService testItemPreparerService) {
-		this.launchRepository = launchRepository;
-		this.clusterRepository = clusterRepository;
-		this.testItemPreparerService = testItemPreparerService;
-	}
-
-	@Override
-	public Optional<IndexLaunch> prepare(Launch launch, List<TestItem> testItems, AnalyzerConfig analyzerConfig) {
-		if (LAUNCH_CAN_BE_INDEXED.test(launch)) {
-			final List<IndexTestItem> preparedItems = testItemPreparerService.prepare(launch.getId(), testItems);
-			if (CollectionUtils.isNotEmpty(preparedItems)) {
-				return Optional.of(createIndexLaunch(launch.getProjectId(),
-						launch.getId(),
-						launch.getName(),
-						launch.getStartTime(),
-						analyzerConfig,
-						preparedItems
-				));
-			}
-		}
-		return Optional.empty();
-	}
-
-	private IndexLaunch createIndexLaunch(Long projectId, Long launchId, String name, LocalDateTime startLaunchTime, AnalyzerConfig analyzerConfig,
-			List<IndexTestItem> rqTestItems) {
-		IndexLaunch rqLaunch = new IndexLaunch();
-		rqLaunch.setLaunchId(launchId);
-		rqLaunch.setLaunchName(name);
-		rqLaunch.setLaunchStartTime(startLaunchTime);
-		rqLaunch.setProjectId(projectId);
-		rqLaunch.setAnalyzerConfig(analyzerConfig);
-		rqLaunch.setTestItems(rqTestItems);
-		setClusters(rqLaunch);
-		return rqLaunch;
-	}
-
-	@Override
-	public Optional<IndexLaunch> prepare(Long id, AnalyzerConfig analyzerConfig) {
-		return prepare(List.of(id), analyzerConfig).stream().findFirst();
-	}
-
-	@Override
-	public List<IndexLaunch> prepare(List<Long> ids, AnalyzerConfig analyzerConfig) {
-		return launchRepository.findIndexLaunchByIds(ids)
-				.stream()
-				.peek(this::fill)
-				.filter(l -> CollectionUtils.isNotEmpty(l.getTestItems()))
-				.peek(l -> l.setAnalyzerConfig(analyzerConfig))
-				.collect(Collectors.toList());
-	}
-
-	/**
-	 * Update prepared launch with items for indexing
-	 *
-	 * @param indexLaunch - Launch to be updated
-	 */
-	private void fill(IndexLaunch indexLaunch) {
-		final List<IndexTestItem> preparedItems = testItemPreparerService.prepare(indexLaunch.getLaunchId());
-		if (!preparedItems.isEmpty()) {
-			indexLaunch.setTestItems(preparedItems);
-			setClusters(indexLaunch);
-		}
-	}
-
-	@Override
-	public List<IndexLaunch> prepare(AnalyzerConfig analyzerConfig, List<TestItem> testItems) {
-		return testItems.stream().collect(Collectors.groupingBy(TestItem::getLaunchId)).entrySet().stream().flatMap(entry -> {
-			Launch launch = launchRepository.findById(entry.getKey())
-					.orElseThrow(() -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND, entry.getKey()));
-			return prepare(launch, entry.getValue(), analyzerConfig).stream();
-		}).collect(Collectors.toList());
-	}
-
-	private void setClusters(IndexLaunch indexLaunch) {
-		final Map<Long, String> clusters = clusterRepository.findAllByLaunchId(indexLaunch.getLaunchId())
-				.stream()
-				.collect(Collectors.toMap(Cluster::getIndexId, Cluster::getMessage));
-		if (!clusters.isEmpty()) {
-			indexLaunch.setClusters(clusters);
-		}
-	}
+  private final LaunchRepository launchRepository;
+  private final ClusterRepository clusterRepository;
+
+  private final TestItemPreparerService testItemPreparerService;
+
+  @Autowired
+  public LaunchPreparerServiceImpl(LaunchRepository launchRepository,
+      ClusterRepository clusterRepository,
+      TestItemPreparerService testItemPreparerService) {
+    this.launchRepository = launchRepository;
+    this.clusterRepository = clusterRepository;
+    this.testItemPreparerService = testItemPreparerService;
+  }
+
+  @Override
+  public Optional<IndexLaunch> prepare(Launch launch, List<TestItem> testItems,
+      AnalyzerConfig analyzerConfig) {
+    if (LAUNCH_CAN_BE_INDEXED.test(launch)) {
+      final List<IndexTestItem> preparedItems = testItemPreparerService.prepare(launch.getId(),
+          testItems);
+      if (CollectionUtils.isNotEmpty(preparedItems)) {
+        return Optional.of(createIndexLaunch(launch.getProjectId(),
+            launch.getId(),
+            launch.getName(),
+            launch.getStartTime(),
+            analyzerConfig,
+            preparedItems,
+            launch.getNumber()
+        ));
+      }
+    }
+    return Optional.empty();
+  }
+
+  private IndexLaunch createIndexLaunch(Long projectId, Long launchId, String name,
+      LocalDateTime startLaunchTime, AnalyzerConfig analyzerConfig,
+      List<IndexTestItem> rqTestItems, Long launchNumber) {
+    IndexLaunch rqLaunch = new IndexLaunch();
+    rqLaunch.setLaunchId(launchId);
+    rqLaunch.setLaunchName(name);
+    rqLaunch.setLaunchStartTime(startLaunchTime);
+    rqLaunch.setProjectId(projectId);
+    rqLaunch.setAnalyzerConfig(analyzerConfig);
+    rqLaunch.setTestItems(rqTestItems);
+    rqLaunch.setLaunchNumber(launchNumber);
+    setClusters(rqLaunch);
+    return rqLaunch;
+  }
+
+  @Override
+  public Optional<IndexLaunch> prepare(Long id, AnalyzerConfig analyzerConfig) {
+    return prepare(List.of(id), analyzerConfig).stream().findFirst();
+  }
+
+  @Override
+  public List<IndexLaunch> prepare(List<Long> ids, AnalyzerConfig analyzerConfig) {
+    return launchRepository.findIndexLaunchByIds(ids)
+        .stream()
+        .peek(this::fill)
+        .filter(l -> CollectionUtils.isNotEmpty(l.getTestItems()))
+        .peek(l -> l.setAnalyzerConfig(analyzerConfig))
+        .collect(Collectors.toList());
+  }
+
+  /**
+   * Update prepared launch with items for indexing
+   *
+   * @param indexLaunch - Launch to be updated
+   */
+  private void fill(IndexLaunch indexLaunch) {
+    final List<IndexTestItem> preparedItems = testItemPreparerService.prepare(
+        indexLaunch.getLaunchId());
+    if (!preparedItems.isEmpty()) {
+      indexLaunch.setTestItems(preparedItems);
+      setClusters(indexLaunch);
+    }
+  }
+
+  @Override
+  public List<IndexLaunch> prepare(AnalyzerConfig analyzerConfig, List<TestItem> testItems) {
+    return testItems.stream().collect(Collectors.groupingBy(TestItem::getLaunchId)).entrySet()
+        .stream().flatMap(entry -> {
+          Launch launch = launchRepository.findById(entry.getKey())
+              .orElseThrow(
+                  () -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND, entry.getKey()));
+          return prepare(launch, entry.getValue(), analyzerConfig).stream();
+        }).collect(Collectors.toList());
+  }
+
+  private void setClusters(IndexLaunch indexLaunch) {
+    final Map<Long, String> clusters = clusterRepository.findAllByLaunchId(
+            indexLaunch.getLaunchId())
+        .stream()
+        .collect(Collectors.toMap(Cluster::getIndexId, Cluster::getMessage));
+    if (!clusters.isEmpty()) {
+      indexLaunch.setClusters(clusters);
+    }
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/preparer/TestItemPreparerService.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/preparer/TestItemPreparerService.java
index 5e11d3f7fd..4a2e09bc72 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/preparer/TestItemPreparerService.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/preparer/TestItemPreparerService.java
@@ -18,7 +18,6 @@
 
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.ws.model.analyzer.IndexTestItem;
-
 import java.util.Collection;
 import java.util.List;
 
@@ -27,15 +26,15 @@
  */
 public interface TestItemPreparerService {
 
-	/**
-	 * Creates {@link IndexTestItem} from {@link TestItem}
-	 *
-	 * @param launchId  {@link TestItem#getLaunchId()}
-	 * @param testItems Test item for preparing
-	 * @return Prepared list of {@link IndexTestItem} for indexing
-	 */
-	List<IndexTestItem> prepare(Long launchId, Collection<TestItem> testItems);
+  /**
+   * Creates {@link IndexTestItem} from {@link TestItem}
+   *
+   * @param launchId  {@link TestItem#getLaunchId()}
+   * @param testItems Test item for preparing
+   * @return Prepared list of {@link IndexTestItem} for indexing
+   */
+  List<IndexTestItem> prepare(Long launchId, Collection<TestItem> testItems);
 
-	List<IndexTestItem> prepare(Long launchId);
+  List<IndexTestItem> prepare(Long launchId);
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/preparer/TestItemPreparerServiceImpl.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/preparer/TestItemPreparerServiceImpl.java
index 2bc532d1c9..a64e47597e 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/preparer/TestItemPreparerServiceImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/impl/preparer/TestItemPreparerServiceImpl.java
@@ -16,7 +16,12 @@
 
 package com.epam.ta.reportportal.core.analyzer.auto.impl.preparer;
 
+import static com.epam.ta.reportportal.util.Predicates.ITEM_CAN_BE_INDEXED;
+import static java.util.Optional.ofNullable;
+import static java.util.stream.Collectors.toList;
+
 import com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerUtils;
+import com.epam.ta.reportportal.core.log.LogService;
 import com.epam.ta.reportportal.dao.LogRepository;
 import com.epam.ta.reportportal.dao.TestItemRepository;
 import com.epam.ta.reportportal.entity.enums.LogLevel;
@@ -24,17 +29,12 @@
 import com.epam.ta.reportportal.jooq.enums.JTestItemTypeEnum;
 import com.epam.ta.reportportal.ws.model.analyzer.IndexLog;
 import com.epam.ta.reportportal.ws.model.analyzer.IndexTestItem;
-import org.apache.commons.collections.CollectionUtils;
-import org.springframework.stereotype.Service;
-
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
-
-import static com.epam.ta.reportportal.util.Predicates.ITEM_CAN_BE_INDEXED;
-import static java.util.Optional.ofNullable;
-import static java.util.stream.Collectors.toList;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -42,46 +42,51 @@
 @Service
 public class TestItemPreparerServiceImpl implements TestItemPreparerService {
 
-	private final TestItemRepository testItemRepository;
-	private final LogRepository logRepository;
+  private final TestItemRepository testItemRepository;
+  private final LogService logService;
 
-	public TestItemPreparerServiceImpl(TestItemRepository testItemRepository, LogRepository logRepository) {
-		this.testItemRepository = testItemRepository;
-		this.logRepository = logRepository;
-	}
+  public TestItemPreparerServiceImpl(TestItemRepository testItemRepository, LogService logService,
+      LogRepository logRepository) {
+    this.testItemRepository = testItemRepository;
+    this.logService = logService;
+  }
 
-	@Override
-	public List<IndexTestItem> prepare(Long launchId, Collection<TestItem> testItems) {
-		final List<IndexTestItem> itemsForIndexing = testItems.stream()
-				.filter(ITEM_CAN_BE_INDEXED)
-				.map(AnalyzerUtils::fromTestItem)
-				.collect(toList());
-		return prepare(launchId, itemsForIndexing);
-	}
+  @Override
+  public List<IndexTestItem> prepare(Long launchId, Collection<TestItem> testItems) {
+    final List<IndexTestItem> itemsForIndexing = testItems.stream()
+        .filter(ITEM_CAN_BE_INDEXED)
+        .map(AnalyzerUtils::fromTestItem)
+        .collect(toList());
+    return prepare(launchId, itemsForIndexing);
+  }
 
-	@Override
-	public List<IndexTestItem> prepare(Long launchId) {
-		final List<IndexTestItem> indexTestItems = testItemRepository.findIndexTestItemByLaunchId(launchId,
-				List.of(JTestItemTypeEnum.STEP, JTestItemTypeEnum.BEFORE_METHOD, JTestItemTypeEnum.AFTER_METHOD)
-		);
-		return prepare(launchId, indexTestItems);
-	}
+  @Override
+  public List<IndexTestItem> prepare(Long launchId) {
+    final List<IndexTestItem> indexTestItems = testItemRepository.findIndexTestItemByLaunchId(
+        launchId,
+        List.of(JTestItemTypeEnum.STEP, JTestItemTypeEnum.BEFORE_METHOD,
+            JTestItemTypeEnum.AFTER_METHOD)
+    );
+    return prepare(launchId, indexTestItems);
+  }
 
-	private List<IndexTestItem> prepare(Long launchId, List<IndexTestItem> indexTestItemList) {
-		final Map<Long, List<IndexLog>> logsMapping = getLogsMapping(launchId,
-				indexTestItemList.stream().map(IndexTestItem::getTestItemId).collect(toList())
-		);
+  private List<IndexTestItem> prepare(Long launchId, List<IndexTestItem> indexTestItemList) {
+    final Map<Long, List<IndexLog>> logsMapping = getLogsMapping(launchId,
+        indexTestItemList.stream().map(IndexTestItem::getTestItemId).collect(toList())
+    );
 
-		return indexTestItemList.stream()
-				.peek(indexTestItem -> ofNullable(logsMapping.get(indexTestItem.getTestItemId())).filter(CollectionUtils::isNotEmpty)
-						.map(HashSet::new)
-						.ifPresent(indexTestItem::setLogs))
-				.filter(it -> CollectionUtils.isNotEmpty(it.getLogs()))
-				.collect(toList());
-	}
+    return indexTestItemList.stream()
+        .peek(indexTestItem -> ofNullable(logsMapping.get(indexTestItem.getTestItemId())).filter(
+                CollectionUtils::isNotEmpty)
+            .map(HashSet::new)
+            .ifPresent(indexTestItem::setLogs))
+        .filter(it -> CollectionUtils.isNotEmpty(it.getLogs()))
+        .collect(toList());
+  }
 
-	private Map<Long, List<IndexLog>> getLogsMapping(Long launchId, List<Long> itemIds) {
-		return logRepository.findAllIndexUnderTestItemByLaunchIdAndTestItemIdsAndLogLevelGte(launchId, itemIds, LogLevel.ERROR.toInt());
-	}
+  private Map<Long, List<IndexLog>> getLogsMapping(Long launchId, List<Long> itemIds) {
+    return logService.findAllIndexUnderTestItemByLaunchIdAndTestItemIdsAndLogLevelGte(launchId,
+        itemIds, LogLevel.ERROR.toInt());
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/indexer/BatchLogIndexer.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/indexer/BatchLogIndexer.java
index 9138bb4a86..7a98614b1d 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/indexer/BatchLogIndexer.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/indexer/BatchLogIndexer.java
@@ -3,8 +3,8 @@
 import com.epam.ta.reportportal.core.analyzer.auto.client.IndexerServiceClient;
 import com.epam.ta.reportportal.core.analyzer.auto.impl.preparer.LaunchPreparerService;
 import com.epam.ta.reportportal.dao.LaunchRepository;
-import com.epam.ta.reportportal.entity.enums.LogLevel;
 import com.epam.ta.reportportal.dao.TestItemRepository;
+import com.epam.ta.reportportal.entity.enums.LogLevel;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.jooq.enums.JLaunchModeEnum;
 import com.epam.ta.reportportal.jooq.enums.JStatusEnum;
@@ -14,6 +14,11 @@
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -21,124 +26,141 @@
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.List;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.stream.Collectors;
-import java.util.stream.StreamSupport;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class BatchLogIndexer {
 
-	private static final Logger LOGGER = LoggerFactory.getLogger(BatchLogIndexer.class);
-
-	private final Integer launchBatchSize;
-	private final Integer itemsBatchSize;
-	private final LaunchRepository launchRepository;
-	private final TestItemRepository testItemRepository;
-	private final LaunchPreparerService launchPreparerService;
-	private final IndexerServiceClient indexerServiceClient;
-
-	@Autowired
-	public BatchLogIndexer(@Value("${rp.environment.variable.log-index.batch-size}") Integer launchBatchSize,
-			@Value("${rp.environment.variable.item-analyze.batch-size}") Integer itemsBatchSize, LaunchRepository launchRepository,
-			TestItemRepository testItemRepository, LaunchPreparerService launchPreparerService, IndexerServiceClient indexerServiceClient) {
-		this.launchBatchSize = launchBatchSize;
-		this.itemsBatchSize = itemsBatchSize;
-		this.launchRepository = launchRepository;
-		this.testItemRepository = testItemRepository;
-		this.launchPreparerService = launchPreparerService;
-		this.indexerServiceClient = indexerServiceClient;
-	}
-
-	@Transactional(readOnly = true)
-	public Long index(Long projectId, AnalyzerConfig analyzerConfig) {
-		final AtomicLong totalIndexed = new AtomicLong(0L);
-
-		List<Long> ids = getLaunchIds(projectId);
-		index(projectId, analyzerConfig, ids, totalIndexed);
-
-		while (launchBatchSize == ids.size()) {
-			final Long lastLaunchId = Iterables.getLast(ids);
-			ids = getLaunchIds(projectId, lastLaunchId);
-			index(projectId, analyzerConfig, ids, totalIndexed);
-		}
-
-		return totalIndexed.get();
-	}
-
-	@Transactional(readOnly = true)
-	public Long index(AnalyzerConfig analyzerConfig, Launch launch, List<Long> itemIds) {
-		AtomicLong indexedCount = new AtomicLong(0);
-		Iterables.partition(itemIds, itemsBatchSize)
-				.forEach(partition -> indexedCount.addAndGet(indexPartition(partition, analyzerConfig, launch)));
-		return indexedCount.get();
-	}
-
-	private Long indexPartition(List<Long> itemIds, AnalyzerConfig analyzerConfig, Launch launch) {
-		LOGGER.info("Indexing started for {} items.", itemIds.size());
-		final Long indexedLogs = launchPreparerService.prepare(launch, testItemRepository.findAllById(itemIds), analyzerConfig)
-				.map(it -> indexerServiceClient.index(Lists.newArrayList(it)))
-				.orElse(0L);
-		LOGGER.info("Indexing of {} logs is finished for {} items.", indexedLogs, itemIds.size());
-		return indexedLogs;
-	}
-
-	private void index(Long projectId, AnalyzerConfig analyzerConfig, List<Long> launchIds, AtomicLong totalIndexed) {
-		if (launchIds.isEmpty()) {
-			return;
-		}
-		LOGGER.debug("Project {}. Found {} ids", projectId, launchIds.size());
-		final List<Long> filteredIds = filterIds(launchIds);
-		if (filteredIds.isEmpty()) {
-			return;
-		}
-		LOGGER.debug("Project {}. Found {} filtered ids", projectId, filteredIds.size());
-		final List<IndexLaunch> preparedLaunches = launchPreparerService.prepare(launchIds, analyzerConfig);
-		if (preparedLaunches.isEmpty()) {
-			return;
-		}
-
-		LOGGER.debug("Project {}. Start indexing for {} launches", projectId, preparedLaunches.size());
-		final long indexed = indexByPartition(preparedLaunches);
-		LOGGER.debug("Project {}. Indexed {} logs", projectId, indexed);
-		totalIndexed.addAndGet(indexed);
-	}
-
-	private long indexByPartition(List<IndexLaunch> preparedLaunches) {
-		return preparedLaunches.stream().map(indexLaunch -> {
-			final Iterable<List<IndexTestItem>> lists = Iterables.partition(indexLaunch.getTestItems(), itemsBatchSize);
-			return StreamSupport.stream(lists.spliterator(), false).map(partition -> {
-				indexLaunch.setTestItems(partition);
-				final Long indexed = indexerServiceClient.index(Lists.newArrayList(indexLaunch));
-				return indexed;
-			}).mapToLong(Long::longValue).sum();
-		}).mapToLong(Long::longValue).sum();
-	}
-
-	private List<Long> filterIds(List<Long> launchIds) {
-		return launchIds.stream()
-				.filter(id -> launchRepository.hasItemsWithLogsWithLogLevel(id, List.of(JTestItemTypeEnum.STEP), LogLevel.ERROR_INT))
-				.collect(Collectors.toList());
-	}
-
-	private List<Long> getLaunchIds(Long projectId) {
-		return launchRepository.findIdsByProjectIdAndModeAndStatusNotEq(projectId,
-				JLaunchModeEnum.DEFAULT,
-				JStatusEnum.PASSED,
-				launchBatchSize
-		);
-	}
-
-	private List<Long> getLaunchIds(Long projectId, Long launchId) {
-		return launchRepository.findIdsByProjectIdAndModeAndStatusNotEqAfterId(projectId,
-				JLaunchModeEnum.DEFAULT,
-				JStatusEnum.PASSED,
-				launchId,
-				launchBatchSize
-		);
-	}
+  private static final Logger LOGGER = LoggerFactory.getLogger(BatchLogIndexer.class);
+
+  private final Integer launchBatchSize;
+  private final Integer itemsBatchSize;
+  private final LaunchRepository launchRepository;
+  private final TestItemRepository testItemRepository;
+  private final LaunchPreparerService launchPreparerService;
+  private final IndexerServiceClient indexerServiceClient;
+
+  @Autowired
+  public BatchLogIndexer(
+      @Value("${rp.environment.variable.log-index.batch-size}") Integer launchBatchSize,
+      @Value("${rp.environment.variable.item-analyze.batch-size}") Integer itemsBatchSize,
+      LaunchRepository launchRepository,
+      TestItemRepository testItemRepository, LaunchPreparerService launchPreparerService,
+      IndexerServiceClient indexerServiceClient) {
+    this.launchBatchSize = launchBatchSize;
+    this.itemsBatchSize = itemsBatchSize;
+    this.launchRepository = launchRepository;
+    this.testItemRepository = testItemRepository;
+    this.launchPreparerService = launchPreparerService;
+    this.indexerServiceClient = indexerServiceClient;
+  }
+
+  @Transactional(readOnly = true)
+  public Long index(Long projectId, AnalyzerConfig analyzerConfig) {
+    final AtomicLong totalIndexed = new AtomicLong(0L);
+
+    List<Long> ids = getLaunchIds(projectId);
+    index(projectId, analyzerConfig, ids, totalIndexed);
+
+    while (launchBatchSize == ids.size()) {
+      final Long lastLaunchId = Iterables.getLast(ids);
+      ids = getLaunchIds(projectId, lastLaunchId);
+      index(projectId, analyzerConfig, ids, totalIndexed);
+    }
+
+    return totalIndexed.get();
+  }
+
+  @Transactional(readOnly = true)
+  public Long index(AnalyzerConfig analyzerConfig, Launch launch, List<Long> itemIds) {
+    AtomicLong indexedCount = new AtomicLong(0);
+    Iterables.partition(itemIds, itemsBatchSize)
+        .forEach(
+            partition -> indexedCount.addAndGet(indexPartition(partition, analyzerConfig, launch)));
+    return indexedCount.get();
+  }
+
+  private Long indexPartition(List<Long> itemIds, AnalyzerConfig analyzerConfig, Launch launch) {
+    LOGGER.info("Indexing started for {} items.", itemIds.size());
+    Optional<IndexLaunch> prepared = launchPreparerService.prepare(launch,
+        testItemRepository.findAllById(itemIds), analyzerConfig);
+    prepared.ifPresent(it -> indexerServiceClient.index(Lists.newArrayList(it)));
+
+    Long indexedLogs = 0L;
+    if (prepared.isPresent()) {
+      indexedLogs = countLogs(Lists.newArrayList(prepared.get()));
+    }
+
+    LOGGER.info("Indexing of {} logs is finished for {} items.", indexedLogs, itemIds.size());
+    return indexedLogs;
+  }
+
+  private Long countLogs(List<IndexLaunch> indexLaunch) {
+    return indexLaunch.stream()
+        .flatMap(launch -> launch.getTestItems().stream())
+        .mapToLong(item -> item.getLogs().size())
+        .sum();
+  }
+
+  private void index(Long projectId, AnalyzerConfig analyzerConfig, List<Long> launchIds,
+      AtomicLong totalIndexed) {
+    if (launchIds.isEmpty()) {
+      return;
+    }
+    LOGGER.debug("Project {}. Found {} ids", projectId, launchIds.size());
+    final List<Long> filteredIds = filterIds(launchIds);
+    if (filteredIds.isEmpty()) {
+      return;
+    }
+    LOGGER.debug("Project {}. Found {} filtered ids", projectId, filteredIds.size());
+    final List<IndexLaunch> preparedLaunches = launchPreparerService.prepare(launchIds,
+        analyzerConfig);
+    if (preparedLaunches.isEmpty()) {
+      return;
+    }
+
+    LOGGER.debug("Project {}. Start indexing for {} launches", projectId, preparedLaunches.size());
+    indexByPartition(preparedLaunches);
+    final long indexed = countLogs(preparedLaunches);
+    LOGGER.debug("Project {}. Indexed {} logs", projectId, indexed);
+    totalIndexed.addAndGet(indexed);
+  }
+
+  private void indexByPartition(List<IndexLaunch> preparedLaunches) {
+    preparedLaunches.forEach(indexLaunch -> {
+      final Iterable<List<IndexTestItem>> lists = Iterables.partition(indexLaunch.getTestItems(),
+          itemsBatchSize);
+      StreamSupport.stream(lists.spliterator(), false).forEach(partition -> {
+        indexLaunch.setTestItems(partition);
+        indexerServiceClient.index(Lists.newArrayList(indexLaunch));
+      });
+    });
+  }
+
+  private List<Long> filterIds(List<Long> launchIds) {
+    return launchIds.stream()
+        .filter(
+            id -> launchRepository.hasItemsWithLogsWithLogLevel(id, List.of(JTestItemTypeEnum.STEP),
+                LogLevel.ERROR_INT))
+        .collect(Collectors.toList());
+  }
+
+  private List<Long> getLaunchIds(Long projectId) {
+    return launchRepository.findIdsByProjectIdAndModeAndStatusNotEq(projectId,
+        JLaunchModeEnum.DEFAULT,
+        JStatusEnum.IN_PROGRESS,
+        launchBatchSize
+    );
+  }
+
+  private List<Long> getLaunchIds(Long projectId, Long launchId) {
+    return launchRepository.findIdsByProjectIdAndModeAndStatusNotEqAfterId(projectId,
+        JLaunchModeEnum.DEFAULT,
+        JStatusEnum.IN_PROGRESS,
+        launchId,
+        launchBatchSize
+    );
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/indexer/IndexerStatusCache.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/indexer/IndexerStatusCache.java
index 8531ada0c2..6048bcd8ef 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/indexer/IndexerStatusCache.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/indexer/IndexerStatusCache.java
@@ -18,9 +18,8 @@
 
 import com.google.common.cache.Cache;
 import com.google.common.cache.CacheBuilder;
-import org.springframework.stereotype.Service;
-
 import java.util.concurrent.TimeUnit;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -28,28 +27,28 @@
 @Service
 public class IndexerStatusCache {
 
-	private static final int CACHE_ITEM_LIVE = 10;
-	private static final int MAXIMUM_SIZE = 50000;
+  private static final int CACHE_ITEM_LIVE = 10;
+  private static final int MAXIMUM_SIZE = 50000;
 
-	/**
-	 * Contains cache of indexing running for concrete project
-	 * launchId - projectId
-	 */
-	private Cache<Long, Boolean> indexingStatus;
+  /**
+   * Contains cache of indexing running for concrete project launchId - projectId
+   */
+  private Cache<Long, Boolean> indexingStatus;
 
-	public IndexerStatusCache() {
-		indexingStatus = CacheBuilder.newBuilder().maximumSize(MAXIMUM_SIZE).expireAfterWrite(CACHE_ITEM_LIVE, TimeUnit.MINUTES).build();
-	}
+  public IndexerStatusCache() {
+    indexingStatus = CacheBuilder.newBuilder().maximumSize(MAXIMUM_SIZE)
+        .expireAfterWrite(CACHE_ITEM_LIVE, TimeUnit.MINUTES).build();
+  }
 
-	public void indexingStarted(Long projectId) {
-		indexingStatus.put(projectId, true);
-	}
+  public void indexingStarted(Long projectId) {
+    indexingStatus.put(projectId, true);
+  }
 
-	public void indexingFinished(Long projectId) {
-		indexingStatus.invalidate(projectId);
-	}
+  public void indexingFinished(Long projectId) {
+    indexingStatus.invalidate(projectId);
+  }
 
-	public Cache<Long, Boolean> getIndexingStatus() {
-		return indexingStatus;
-	}
+  public Cache<Long, Boolean> getIndexingStatus() {
+    return indexingStatus;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/starter/CollectingAutoAnalysisStarter.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/starter/CollectingAutoAnalysisStarter.java
index 34e96ddd7a..71142b9da6 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/starter/CollectingAutoAnalysisStarter.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/starter/CollectingAutoAnalysisStarter.java
@@ -16,69 +16,73 @@
 
 package com.epam.ta.reportportal.core.analyzer.auto.starter;
 
+import static java.util.stream.Collectors.toList;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.analyzer.auto.AnalyzerService;
 import com.epam.ta.reportportal.core.analyzer.auto.LogIndexer;
-import com.epam.ta.reportportal.core.analyzer.config.StartLaunchAutoAnalysisConfig;
 import com.epam.ta.reportportal.core.analyzer.auto.strategy.analyze.AnalyzeCollectorFactory;
 import com.epam.ta.reportportal.core.analyzer.auto.strategy.analyze.AnalyzeItemsCollector;
 import com.epam.ta.reportportal.core.analyzer.auto.strategy.analyze.AnalyzeItemsMode;
+import com.epam.ta.reportportal.core.analyzer.config.StartLaunchAutoAnalysisConfig;
 import com.epam.ta.reportportal.core.launch.GetLaunchHandler;
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.launch.Launch;
+import java.util.List;
+import java.util.Set;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.List;
-import java.util.Set;
-
-import static java.util.stream.Collectors.toList;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public class CollectingAutoAnalysisStarter implements LaunchAutoAnalysisStarter {
 
-	private static final Logger LOGGER = LoggerFactory.getLogger(CollectingAutoAnalysisStarter.class);
+  private static final Logger LOGGER = LoggerFactory.getLogger(CollectingAutoAnalysisStarter.class);
 
-	private final GetLaunchHandler getLaunchHandler;
-	private final AnalyzeCollectorFactory analyzeCollectorFactory;
-	private final AnalyzerService analyzerService;
-	private final LogIndexer logIndexer;
+  private final GetLaunchHandler getLaunchHandler;
+  private final AnalyzeCollectorFactory analyzeCollectorFactory;
+  private final AnalyzerService analyzerService;
+  private final LogIndexer logIndexer;
 
-	public CollectingAutoAnalysisStarter(GetLaunchHandler getLaunchHandler, AnalyzeCollectorFactory analyzeCollectorFactory,
-			AnalyzerService analyzerService, LogIndexer logIndexer) {
-		this.getLaunchHandler = getLaunchHandler;
-		this.analyzeCollectorFactory = analyzeCollectorFactory;
-		this.analyzerService = analyzerService;
-		this.logIndexer = logIndexer;
-	}
+  public CollectingAutoAnalysisStarter(GetLaunchHandler getLaunchHandler,
+      AnalyzeCollectorFactory analyzeCollectorFactory,
+      AnalyzerService analyzerService, LogIndexer logIndexer) {
+    this.getLaunchHandler = getLaunchHandler;
+    this.analyzeCollectorFactory = analyzeCollectorFactory;
+    this.analyzerService = analyzerService;
+    this.logIndexer = logIndexer;
+  }
 
-	@Override
-	@Transactional
-	public void start(StartLaunchAutoAnalysisConfig config) {
-		final Launch launch = getLaunchHandler.get(config.getLaunchId());
+  @Override
+  @Transactional
+  public void start(StartLaunchAutoAnalysisConfig config) {
+    final Launch launch = getLaunchHandler.get(config.getLaunchId());
 
-		final List<Long> itemIds = collectItemsByModes(launch, config.getAnalyzeItemsModes(), config.getUser());
+    final List<Long> itemIds = collectItemsByModes(launch, config.getAnalyzeItemsModes(),
+        config.getUser());
 
-		analyzerService.runAnalyzers(launch, itemIds, config.getAnalyzerConfig());
-		logIndexer.indexItemsLogs(launch.getProjectId(), launch.getId(), itemIds, config.getAnalyzerConfig());
-	}
+    analyzerService.runAnalyzers(launch, itemIds, config.getAnalyzerConfig());
+    logIndexer.indexItemsLogs(launch.getProjectId(), launch.getId(), itemIds,
+        config.getAnalyzerConfig());
+  }
 
-	/**
-	 * Collect item ids for analyzer according to provided analyzer configuration.
-	 *
-	 * @return List of {@link TestItem#getItemId()} to analyze
-	 * @see AnalyzeItemsMode
-	 * @see AnalyzeCollectorFactory
-	 * @see AnalyzeItemsCollector
-	 */
-	private List<Long> collectItemsByModes(Launch launch, Set<AnalyzeItemsMode> analyzeItemsModes, ReportPortalUser user) {
-		return analyzeItemsModes.stream().flatMap(it -> {
-			List<Long> itemIds = analyzeCollectorFactory.getCollector(it).collectItems(launch.getProjectId(), launch.getId(), user);
-			LOGGER.debug("Item itemIds collected by '{}' mode: {}", it, itemIds);
-			return itemIds.stream();
-		}).collect(toList());
-	}
+  /**
+   * Collect item ids for analyzer according to provided analyzer configuration.
+   *
+   * @return List of {@link TestItem#getItemId()} to analyze
+   * @see AnalyzeItemsMode
+   * @see AnalyzeCollectorFactory
+   * @see AnalyzeItemsCollector
+   */
+  private List<Long> collectItemsByModes(Launch launch, Set<AnalyzeItemsMode> analyzeItemsModes,
+      ReportPortalUser user) {
+    return analyzeItemsModes.stream().flatMap(it -> {
+      List<Long> itemIds = analyzeCollectorFactory.getCollector(it)
+          .collectItems(launch.getProjectId(), launch.getId(), user);
+      LOGGER.debug("Item itemIds collected by '{}' mode: {}", it, itemIds);
+      return itemIds.stream();
+    }).distinct().collect(toList());
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/starter/LaunchAutoAnalysisStarter.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/starter/LaunchAutoAnalysisStarter.java
index 70a6324d0d..6ba28449cb 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/starter/LaunchAutoAnalysisStarter.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/starter/LaunchAutoAnalysisStarter.java
@@ -23,6 +23,6 @@
  */
 public interface LaunchAutoAnalysisStarter {
 
-	void start(StartLaunchAutoAnalysisConfig config);
+  void start(StartLaunchAutoAnalysisConfig config);
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/AsyncAutoAnalysisStarter.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/AsyncAutoAnalysisStarter.java
index 7a91584f7f..3ca452f784 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/AsyncAutoAnalysisStarter.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/AsyncAutoAnalysisStarter.java
@@ -16,8 +16,8 @@
 
 package com.epam.ta.reportportal.core.analyzer.auto.starter.decorator;
 
-import com.epam.ta.reportportal.core.analyzer.config.StartLaunchAutoAnalysisConfig;
 import com.epam.ta.reportportal.core.analyzer.auto.starter.LaunchAutoAnalysisStarter;
+import com.epam.ta.reportportal.core.analyzer.config.StartLaunchAutoAnalysisConfig;
 import org.springframework.core.task.TaskExecutor;
 
 /**
@@ -25,16 +25,17 @@
  */
 public class AsyncAutoAnalysisStarter implements LaunchAutoAnalysisStarter {
 
-	private final TaskExecutor executor;
-	private final LaunchAutoAnalysisStarter launchAutoAnalysisStarter;
+  private final TaskExecutor executor;
+  private final LaunchAutoAnalysisStarter launchAutoAnalysisStarter;
 
-	public AsyncAutoAnalysisStarter(TaskExecutor executor, LaunchAutoAnalysisStarter launchAutoAnalysisStarter) {
-		this.executor = executor;
-		this.launchAutoAnalysisStarter = launchAutoAnalysisStarter;
-	}
+  public AsyncAutoAnalysisStarter(TaskExecutor executor,
+      LaunchAutoAnalysisStarter launchAutoAnalysisStarter) {
+    this.executor = executor;
+    this.launchAutoAnalysisStarter = launchAutoAnalysisStarter;
+  }
 
-	@Override
-	public void start(StartLaunchAutoAnalysisConfig config) {
-		executor.execute(() -> launchAutoAnalysisStarter.start(config));
-	}
+  @Override
+  public void start(StartLaunchAutoAnalysisConfig config) {
+    executor.execute(() -> launchAutoAnalysisStarter.start(config));
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/AutoAnalysisEnabledStarter.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/AutoAnalysisEnabledStarter.java
index 58875ce9b9..1aa674dfa8 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/AutoAnalysisEnabledStarter.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/AutoAnalysisEnabledStarter.java
@@ -24,16 +24,16 @@
  */
 public class AutoAnalysisEnabledStarter implements LaunchAutoAnalysisStarter {
 
-	private final LaunchAutoAnalysisStarter launchAutoAnalysisStarter;
+  private final LaunchAutoAnalysisStarter launchAutoAnalysisStarter;
 
-	public AutoAnalysisEnabledStarter(LaunchAutoAnalysisStarter launchAutoAnalysisStarter) {
-		this.launchAutoAnalysisStarter = launchAutoAnalysisStarter;
-	}
+  public AutoAnalysisEnabledStarter(LaunchAutoAnalysisStarter launchAutoAnalysisStarter) {
+    this.launchAutoAnalysisStarter = launchAutoAnalysisStarter;
+  }
 
-	@Override
-	public void start(StartLaunchAutoAnalysisConfig config) {
-		if (config.getAnalyzerConfig().getIsAutoAnalyzerEnabled()) {
-			launchAutoAnalysisStarter.start(config);
-		}
-	}
+  @Override
+  public void start(StartLaunchAutoAnalysisConfig config) {
+    if (config.getAnalyzerConfig().getIsAutoAnalyzerEnabled()) {
+      launchAutoAnalysisStarter.start(config);
+    }
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/ExistingAnalyzerStarter.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/ExistingAnalyzerStarter.java
index ff29cac1cb..0e9cdd30ee 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/ExistingAnalyzerStarter.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/ExistingAnalyzerStarter.java
@@ -16,33 +16,33 @@
 
 package com.epam.ta.reportportal.core.analyzer.auto.starter.decorator;
 
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+
 import com.epam.ta.reportportal.core.analyzer.auto.AnalyzerService;
-import com.epam.ta.reportportal.core.analyzer.config.StartLaunchAutoAnalysisConfig;
 import com.epam.ta.reportportal.core.analyzer.auto.starter.LaunchAutoAnalysisStarter;
+import com.epam.ta.reportportal.core.analyzer.config.StartLaunchAutoAnalysisConfig;
 import com.epam.ta.reportportal.ws.model.ErrorType;
-
 import java.util.function.Predicate;
 
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public class ExistingAnalyzerStarter implements LaunchAutoAnalysisStarter {
-
-	private final AnalyzerService analyzerService;
-	private final LaunchAutoAnalysisStarter launchAutoAnalysisStarter;
-
-	public ExistingAnalyzerStarter(AnalyzerService analyzerService, LaunchAutoAnalysisStarter launchAutoAnalysisStarter) {
-		this.analyzerService = analyzerService;
-		this.launchAutoAnalysisStarter = launchAutoAnalysisStarter;
-	}
-
-	@Override
-	public void start(StartLaunchAutoAnalysisConfig config) {
-		expect(analyzerService.hasAnalyzers(), Predicate.isEqual(true)).verify(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
-				"There are no analyzer services are deployed."
-		);
-		launchAutoAnalysisStarter.start(config);
-	}
+  private final AnalyzerService analyzerService;
+  private final LaunchAutoAnalysisStarter launchAutoAnalysisStarter;
+
+  public ExistingAnalyzerStarter(AnalyzerService analyzerService,
+      LaunchAutoAnalysisStarter launchAutoAnalysisStarter) {
+    this.analyzerService = analyzerService;
+    this.launchAutoAnalysisStarter = launchAutoAnalysisStarter;
+  }
+
+  @Override
+  public void start(StartLaunchAutoAnalysisConfig config) {
+    expect(analyzerService.hasAnalyzers(), Predicate.isEqual(true)).verify(
+        ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
+        "There are no analyzer services are deployed."
+    );
+    launchAutoAnalysisStarter.start(config);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/IndexingAutoAnalysisStarter.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/IndexingAutoAnalysisStarter.java
index 71d2d2e6dc..4cfda33aaa 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/IndexingAutoAnalysisStarter.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/IndexingAutoAnalysisStarter.java
@@ -28,22 +28,22 @@
  */
 public class IndexingAutoAnalysisStarter implements LaunchAutoAnalysisStarter {
 
-	private final GetLaunchHandler getLaunchHandler;
-	private final LogIndexer logIndexer;
-	private final LaunchAutoAnalysisStarter launchAutoAnalysisStarter;
+  private final GetLaunchHandler getLaunchHandler;
+  private final LogIndexer logIndexer;
+  private final LaunchAutoAnalysisStarter launchAutoAnalysisStarter;
 
-	public IndexingAutoAnalysisStarter(GetLaunchHandler getLaunchHandler, LogIndexer logIndexer,
-			LaunchAutoAnalysisStarter launchAutoAnalysisStarter) {
-		this.getLaunchHandler = getLaunchHandler;
-		this.logIndexer = logIndexer;
-		this.launchAutoAnalysisStarter = launchAutoAnalysisStarter;
-	}
+  public IndexingAutoAnalysisStarter(GetLaunchHandler getLaunchHandler, LogIndexer logIndexer,
+      LaunchAutoAnalysisStarter launchAutoAnalysisStarter) {
+    this.getLaunchHandler = getLaunchHandler;
+    this.logIndexer = logIndexer;
+    this.launchAutoAnalysisStarter = launchAutoAnalysisStarter;
+  }
 
-	@Override
-	@Transactional
-	public void start(StartLaunchAutoAnalysisConfig config) {
-		final Launch launch = getLaunchHandler.get(config.getLaunchId());
-		logIndexer.indexLaunchLogs(launch, config.getAnalyzerConfig());
-		launchAutoAnalysisStarter.start(config);
-	}
+  @Override
+  @Transactional
+  public void start(StartLaunchAutoAnalysisConfig config) {
+    final Launch launch = getLaunchHandler.get(config.getLaunchId());
+    logIndexer.indexLaunchLogs(launch, config.getAnalyzerConfig());
+    launchAutoAnalysisStarter.start(config);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/AnalyzeCollectorConfig.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/AnalyzeCollectorConfig.java
index 93d3cfa467..223091585b 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/AnalyzeCollectorConfig.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/AnalyzeCollectorConfig.java
@@ -16,6 +16,8 @@
 
 package com.epam.ta.reportportal.core.analyzer.auto.strategy.analyze;
 
+import java.util.HashMap;
+import java.util.Map;
 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationContext;
@@ -23,33 +25,35 @@
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
-import java.util.HashMap;
-import java.util.Map;
-
 /**
  * @author Pavel Bortnik
  */
 @Configuration
 public class AnalyzeCollectorConfig implements ApplicationContextAware {
 
-	private ApplicationContext applicationContext;
-
-	@Autowired
-	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
-		this.applicationContext = applicationContext;
-	}
-
-	@Bean(name = "analyzerModeMapping")
-	public Map<AnalyzeItemsMode, AnalyzeItemsCollector> getAnalyzerModeMapping() {
-		Map<AnalyzeItemsMode, AnalyzeItemsCollector> mapping = new HashMap<>();
-		mapping.put(AnalyzeItemsMode.TO_INVESTIGATE, applicationContext.getBean(ToInvestigateCollector.class));
-		mapping.put(AnalyzeItemsMode.AUTO_ANALYZED, applicationContext.getBean(AutoAnalyzedCollector.class));
-		mapping.put(AnalyzeItemsMode.MANUALLY_ANALYZED, applicationContext.getBean(ManuallyAnalyzedCollector.class));
-		return mapping;
-	}
-
-	@Bean
-	public AnalyzeCollectorFactory analyzeCollectorFactory() {
-		return new AnalyzeCollectorFactory(getAnalyzerModeMapping());
-	}
+  private ApplicationContext applicationContext;
+
+  @Autowired
+  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+    this.applicationContext = applicationContext;
+  }
+
+  @Bean(name = "analyzerModeMapping")
+  public Map<AnalyzeItemsMode, AnalyzeItemsCollector> getAnalyzerModeMapping() {
+    Map<AnalyzeItemsMode, AnalyzeItemsCollector> mapping = new HashMap<>();
+    mapping.put(AnalyzeItemsMode.TO_INVESTIGATE,
+        applicationContext.getBean(ToInvestigateCollector.class));
+    mapping.put(AnalyzeItemsMode.AUTO_ANALYZED,
+        applicationContext.getBean(AutoAnalyzedCollector.class));
+    mapping.put(AnalyzeItemsMode.MANUALLY_ANALYZED,
+        applicationContext.getBean(ManuallyAnalyzedCollector.class));
+    mapping.put(AnalyzeItemsMode.IGNORE_IMMEDIATE,
+        applicationContext.getBean(IgnoreImmediateCollector.class));
+    return mapping;
+  }
+
+  @Bean
+  public AnalyzeCollectorFactory analyzeCollectorFactory() {
+    return new AnalyzeCollectorFactory(getAnalyzerModeMapping());
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/AnalyzeCollectorFactory.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/AnalyzeCollectorFactory.java
index f06a6523e0..75890c04d9 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/AnalyzeCollectorFactory.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/AnalyzeCollectorFactory.java
@@ -25,13 +25,13 @@
  */
 public class AnalyzeCollectorFactory {
 
-	private Map<AnalyzeItemsMode, AnalyzeItemsCollector> mapping;
+  private Map<AnalyzeItemsMode, AnalyzeItemsCollector> mapping;
 
-	public AnalyzeCollectorFactory(Map<AnalyzeItemsMode, AnalyzeItemsCollector> mapping) {
-		this.mapping = mapping;
-	}
+  public AnalyzeCollectorFactory(Map<AnalyzeItemsMode, AnalyzeItemsCollector> mapping) {
+    this.mapping = mapping;
+  }
 
-	public AnalyzeItemsCollector getCollector(AnalyzeItemsMode type) {
-		return this.mapping.get(type);
-	}
+  public AnalyzeItemsCollector getCollector(AnalyzeItemsMode type) {
+    return this.mapping.get(type);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/AnalyzeItemsCollector.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/AnalyzeItemsCollector.java
index 89ac60a170..e49c0ecd95 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/AnalyzeItemsCollector.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/AnalyzeItemsCollector.java
@@ -17,7 +17,6 @@
 package com.epam.ta.reportportal.core.analyzer.auto.strategy.analyze;
 
 import com.epam.ta.reportportal.commons.ReportPortalUser;
-
 import java.util.List;
 
 /**
@@ -28,15 +27,15 @@
 @FunctionalInterface
 public interface AnalyzeItemsCollector {
 
-	/**
-	 * Collects items for concrete project of concrete launch for following analyzing
-	 * according to concrete {@link com.epam.ta.reportportal.entity.AnalyzeMode}
-	 *
-	 * @param projectId Project id
-	 * @param launchId  Launch id
-	 * @param user      User started analysis
-	 * @return List of item ids
-	 */
-	List<Long> collectItems(Long projectId, Long launchId, ReportPortalUser user);
+  /**
+   * Collects items for concrete project of concrete launch for following analyzing according to
+   * concrete {@link com.epam.ta.reportportal.entity.AnalyzeMode}
+   *
+   * @param projectId Project id
+   * @param launchId  Launch id
+   * @param user      User started analysis
+   * @return List of item ids
+   */
+  List<Long> collectItems(Long projectId, Long launchId, ReportPortalUser user);
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/AnalyzeItemsMode.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/AnalyzeItemsMode.java
index 6f3b1ff644..5f4897cdf1 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/AnalyzeItemsMode.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/AnalyzeItemsMode.java
@@ -18,7 +18,6 @@
 
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
-
 import java.util.Arrays;
 import java.util.stream.Collectors;
 
@@ -27,30 +26,31 @@
  */
 public enum AnalyzeItemsMode {
 
-	TO_INVESTIGATE("TO_INVESTIGATE"),
-	AUTO_ANALYZED("AUTO_ANALYZED"),
-	MANUALLY_ANALYZED("MANUALLY_ANALYZED");
-
-	private String value;
-
-	AnalyzeItemsMode(String value) {
-		this.value = value;
-	}
-
-	public static AnalyzeItemsMode fromString(String mode) {
-		return Arrays.stream(AnalyzeItemsMode.values())
-				.filter(it -> it.getValue().equalsIgnoreCase(mode))
-				.findFirst()
-				.orElseThrow(() -> new ReportPortalException(
-						ErrorType.INCORRECT_REQUEST,
-						"Incorrect analyze items mode. Allowed are: " + Arrays.stream(AnalyzeItemsMode.values())
-								.map(AnalyzeItemsMode::getValue)
-								.collect(Collectors.toList())
-				));
-	}
-
-	public String getValue() {
-		return value;
-	}
+  TO_INVESTIGATE("TO_INVESTIGATE"),
+  AUTO_ANALYZED("AUTO_ANALYZED"),
+  MANUALLY_ANALYZED("MANUALLY_ANALYZED"),
+  IGNORE_IMMEDIATE("IGNORE_IMMEDIATE");
+
+  private String value;
+
+  AnalyzeItemsMode(String value) {
+    this.value = value;
+  }
+
+  public static AnalyzeItemsMode fromString(String mode) {
+    return Arrays.stream(AnalyzeItemsMode.values())
+        .filter(it -> it.getValue().equalsIgnoreCase(mode))
+        .findFirst()
+        .orElseThrow(() -> new ReportPortalException(
+            ErrorType.INCORRECT_REQUEST,
+            "Incorrect analyze items mode. Allowed are: " + Arrays.stream(AnalyzeItemsMode.values())
+                .map(AnalyzeItemsMode::getValue)
+                .collect(Collectors.toList())
+        ));
+  }
+
+  public String getValue() {
+    return value;
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/AutoAnalyzedCollector.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/AutoAnalyzedCollector.java
index 0a23507d01..8fc81e0483 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/AutoAnalyzedCollector.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/AutoAnalyzedCollector.java
@@ -21,41 +21,46 @@
 import com.epam.ta.reportportal.core.item.UpdateTestItemHandler;
 import com.epam.ta.reportportal.dao.TestItemRepository;
 import com.epam.ta.reportportal.entity.enums.LogLevel;
+import java.util.Collections;
+import java.util.List;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
-import java.util.List;
-
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
  */
 @Component
 public class AutoAnalyzedCollector implements AnalyzeItemsCollector {
 
-	private static final Logger LOGGER = LoggerFactory.getLogger(AutoAnalyzedCollector.class);
+  private static final Logger LOGGER = LoggerFactory.getLogger(AutoAnalyzedCollector.class);
 
-	private final TestItemRepository testItemRepository;
+  private final TestItemRepository testItemRepository;
 
-	private final LogIndexer logIndexer;
+  private final LogIndexer logIndexer;
 
-	private final UpdateTestItemHandler updateTestItemHandler;
+  private final UpdateTestItemHandler updateTestItemHandler;
 
-	@Autowired
-	public AutoAnalyzedCollector(TestItemRepository testItemRepository, LogIndexer logIndexer,
-			UpdateTestItemHandler updateTestItemHandler) {
-		this.testItemRepository = testItemRepository;
-		this.logIndexer = logIndexer;
-		this.updateTestItemHandler = updateTestItemHandler;
-	}
+  @Autowired
+  public AutoAnalyzedCollector(TestItemRepository testItemRepository, LogIndexer logIndexer,
+      UpdateTestItemHandler updateTestItemHandler) {
+    this.testItemRepository = testItemRepository;
+    this.logIndexer = logIndexer;
+    this.updateTestItemHandler = updateTestItemHandler;
+  }
 
-	@Override
-	public List<Long> collectItems(Long projectId, Long launchId, ReportPortalUser user) {
-		List<Long> itemIds = testItemRepository.selectIdsByAnalyzedWithLevelGte(true, false, launchId, LogLevel.ERROR.toInt());
-		int deletedLogsCount = logIndexer.indexItemsRemove(projectId, itemIds);
-		LOGGER.debug("{} logs deleted from analyzer", deletedLogsCount);
-		updateTestItemHandler.resetItemsIssue(itemIds, projectId, user);
-		return itemIds;
-	}
+  @Override
+  public List<Long> collectItems(Long projectId, Long launchId, ReportPortalUser user) {
+    List<Long> itemIds = testItemRepository.selectIdsByAnalyzedWithLevelGteExcludingIssueTypes(true,
+        false,
+        launchId,
+        LogLevel.ERROR.toInt(),
+        Collections.emptyList()
+    );
+    int deletedLogsCount = logIndexer.indexItemsRemove(projectId, itemIds);
+    LOGGER.debug("{} logs deleted from analyzer", deletedLogsCount);
+    updateTestItemHandler.resetItemsIssue(itemIds, projectId, user);
+    return itemIds;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/IgnoreImmediateCollector.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/IgnoreImmediateCollector.java
new file mode 100644
index 0000000000..6ab6fa5148
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/IgnoreImmediateCollector.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2023 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.epam.ta.reportportal.core.analyzer.auto.strategy.analyze;
+
+import static java.util.stream.Collectors.toList;
+
+import com.epam.ta.reportportal.commons.ReportPortalUser;
+import com.epam.ta.reportportal.dao.TestItemRepository;
+import com.epam.ta.reportportal.entity.enums.TestItemIssueGroup;
+import com.epam.ta.reportportal.entity.item.TestItem;
+import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author <a href="mailto:andrei_piankouski@epam.com">Andrei Piankouski</a>
+ */
+@Service
+public class IgnoreImmediateCollector implements AnalyzeItemsCollector {
+
+  protected static final String IMMEDIATE_AUTO_ANALYSIS = "immediateAutoAnalysis";
+
+  private TestItemRepository testItemRepository;
+
+  @Autowired
+  public IgnoreImmediateCollector(TestItemRepository testItemRepository) {
+    this.testItemRepository = testItemRepository;
+  }
+
+  @Override
+  public List<Long> collectItems(Long projectId, Long launchId, ReportPortalUser user) {
+    return testItemRepository.findItemsForAnalyze(launchId)
+        .stream()
+        .filter(ti -> !ti.getItemResults().getIssue().getIgnoreAnalyzer())
+        .filter(this::skipImmediateAA)
+        .map(TestItem::getItemId)
+        .collect(toList());
+  }
+
+  private boolean skipImmediateAA(TestItem item) {
+    return item.getAttributes().stream()
+        .filter(at -> !at.getTestItem().getItemResults().getIssue().getIgnoreAnalyzer())
+        .noneMatch(at -> IMMEDIATE_AUTO_ANALYSIS.equals(at.getKey()) && Boolean.parseBoolean(
+            at.getValue()) && at.isSystem());
+  }
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/ManuallyAnalyzedCollector.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/ManuallyAnalyzedCollector.java
index d02f8f74d6..c9f21ef029 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/ManuallyAnalyzedCollector.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/ManuallyAnalyzedCollector.java
@@ -19,44 +19,60 @@
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.analyzer.auto.LogIndexer;
 import com.epam.ta.reportportal.core.item.UpdateTestItemHandler;
+import com.epam.ta.reportportal.dao.IssueTypeRepository;
 import com.epam.ta.reportportal.dao.TestItemRepository;
 import com.epam.ta.reportportal.entity.enums.LogLevel;
+import com.epam.ta.reportportal.entity.enums.TestItemIssueGroup;
+import com.epam.ta.reportportal.entity.item.issue.IssueType;
+import java.util.Collections;
+import java.util.List;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
-import java.util.List;
-
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
  */
 @Component
 public class ManuallyAnalyzedCollector implements AnalyzeItemsCollector {
 
-	private static final Logger LOGGER = LoggerFactory.getLogger(AnalyzeItemsCollector.class);
+  private static final Logger LOGGER = LoggerFactory.getLogger(AnalyzeItemsCollector.class);
 
-	private final TestItemRepository testItemRepository;
+  private final TestItemRepository testItemRepository;
+  private final IssueTypeRepository issueTypeRepository;
 
-	private final LogIndexer logIndexer;
+  private final LogIndexer logIndexer;
 
-	private final UpdateTestItemHandler updateTestItemHandler;
+  private final UpdateTestItemHandler updateTestItemHandler;
 
-	@Autowired
-	public ManuallyAnalyzedCollector(TestItemRepository testItemRepository, LogIndexer logIndexer,
-			UpdateTestItemHandler updateTestItemHandler) {
-		this.testItemRepository = testItemRepository;
-		this.logIndexer = logIndexer;
-		this.updateTestItemHandler = updateTestItemHandler;
-	}
+  @Autowired
+  public ManuallyAnalyzedCollector(TestItemRepository testItemRepository,
+      IssueTypeRepository issueTypeRepository, LogIndexer logIndexer,
+      UpdateTestItemHandler updateTestItemHandler) {
+    this.testItemRepository = testItemRepository;
+    this.issueTypeRepository = issueTypeRepository;
+    this.logIndexer = logIndexer;
+    this.updateTestItemHandler = updateTestItemHandler;
+  }
 
-	@Override
-	public List<Long> collectItems(Long projectId, Long launchId, ReportPortalUser user) {
-		List<Long> itemIds = testItemRepository.selectIdsByAnalyzedWithLevelGte(false, false, launchId, LogLevel.ERROR.toInt());
-		int deletedLogsCount = logIndexer.indexItemsRemove(projectId, itemIds);
-		LOGGER.debug("{} logs deleted from analyzer", deletedLogsCount);
-		updateTestItemHandler.resetItemsIssue(itemIds, projectId, user);
-		return itemIds;
-	}
+  @Override
+  public List<Long> collectItems(Long projectId, Long launchId, ReportPortalUser user) {
+    final List<IssueType> excludedTypes = issueTypeRepository.findByLocator(
+            TestItemIssueGroup.TO_INVESTIGATE.getLocator())
+        .map(List::of)
+        .orElseGet(Collections::emptyList);
+    List<Long> itemIds = testItemRepository.selectIdsByAnalyzedWithLevelGteExcludingIssueTypes(
+        false,
+        false,
+        launchId,
+        LogLevel.ERROR.toInt(),
+        excludedTypes
+    );
+    int deletedLogsCount = logIndexer.indexItemsRemove(projectId, itemIds);
+    LOGGER.debug("{} logs deleted from analyzer", deletedLogsCount);
+    updateTestItemHandler.resetItemsIssue(itemIds, projectId, user);
+    return itemIds;
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/ToInvestigateCollector.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/ToInvestigateCollector.java
index 27286e301f..c3521f92ff 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/ToInvestigateCollector.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/analyze/ToInvestigateCollector.java
@@ -16,36 +16,36 @@
 
 package com.epam.ta.reportportal.core.analyzer.auto.strategy.analyze;
 
+import static java.util.stream.Collectors.toList;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.dao.TestItemRepository;
 import com.epam.ta.reportportal.entity.enums.TestItemIssueGroup;
 import com.epam.ta.reportportal.entity.item.TestItem;
+import java.util.List;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-
-import static java.util.stream.Collectors.toList;
-
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
  */
 @Service
 public class ToInvestigateCollector implements AnalyzeItemsCollector {
 
-	private TestItemRepository testItemRepository;
-
-	@Autowired
-	public ToInvestigateCollector(TestItemRepository testItemRepository) {
-		this.testItemRepository = testItemRepository;
-	}
-
-	@Override
-	public List<Long> collectItems(Long projectId, Long launchId, ReportPortalUser user) {
-		return testItemRepository.findAllInIssueGroupByLaunch(launchId, TestItemIssueGroup.TO_INVESTIGATE)
-				.stream()
-				.filter(it -> !it.getItemResults().getIssue().getIgnoreAnalyzer())
-				.map(TestItem::getItemId)
-				.collect(toList());
-	}
+  private TestItemRepository testItemRepository;
+
+  @Autowired
+  public ToInvestigateCollector(TestItemRepository testItemRepository) {
+    this.testItemRepository = testItemRepository;
+  }
+
+  @Override
+  public List<Long> collectItems(Long projectId, Long launchId, ReportPortalUser user) {
+    return testItemRepository.findAllInIssueGroupByLaunch(launchId,
+            TestItemIssueGroup.TO_INVESTIGATE)
+        .stream()
+        .filter(it -> !it.getItemResults().getIssue().getIgnoreAnalyzer())
+        .map(TestItem::getItemId)
+        .collect(toList());
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/search/CurrentLaunchCollector.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/search/CurrentLaunchCollector.java
index e265b2faa7..c33391e830 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/search/CurrentLaunchCollector.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/search/CurrentLaunchCollector.java
@@ -17,10 +17,9 @@
 package com.epam.ta.reportportal.core.analyzer.auto.strategy.search;
 
 import com.epam.ta.reportportal.entity.launch.Launch;
-import org.springframework.stereotype.Component;
-
 import java.util.Collections;
 import java.util.List;
+import org.springframework.stereotype.Component;
 
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
@@ -28,8 +27,8 @@
 @Component
 public class CurrentLaunchCollector implements SearchLaunchesCollector {
 
-	@Override
-	public List<Long> collect(Long filerId, Launch launch) {
-		return Collections.singletonList(launch.getId());
-	}
+  @Override
+  public List<Long> collect(Long filerId, Launch launch) {
+    return Collections.singletonList(launch.getId());
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/search/FilterCollector.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/search/FilterCollector.java
index 2b1262b3ee..f4dee7b67a 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/search/FilterCollector.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/search/FilterCollector.java
@@ -16,6 +16,12 @@
 
 package com.epam.ta.reportportal.core.analyzer.auto.strategy.search;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_START_TIME;
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
+import static org.springframework.data.domain.Sort.Direction.DESC;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.querygen.ProjectFilter;
 import com.epam.ta.reportportal.dao.LaunchRepository;
@@ -26,49 +32,49 @@
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.google.common.collect.Lists;
+import java.util.List;
+import java.util.stream.Collectors;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Component;
 
-import java.util.List;
-import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_START_TIME;
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
-import static org.springframework.data.domain.Sort.Direction.DESC;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @Component
 public class FilterCollector implements SearchLaunchesCollector {
 
-	private LaunchRepository launchRepository;
+  private LaunchRepository launchRepository;
 
-	private UserFilterRepository userFilterRepository;
+  private UserFilterRepository userFilterRepository;
 
-	@Autowired
-	public FilterCollector(LaunchRepository launchRepository, UserFilterRepository userFilterRepository) {
-		this.launchRepository = launchRepository;
-		this.userFilterRepository = userFilterRepository;
-	}
+  @Autowired
+  public FilterCollector(LaunchRepository launchRepository,
+      UserFilterRepository userFilterRepository) {
+    this.launchRepository = launchRepository;
+    this.userFilterRepository = userFilterRepository;
+  }
 
-	@Override
-	public List<Long> collect(Long filerId, Launch launch) {
-		UserFilter userFilter = userFilterRepository.findByIdAndProjectId(filerId, launch.getProjectId())
-				.orElseThrow(() -> new ReportPortalException(ErrorType.USER_FILTER_NOT_FOUND_IN_PROJECT, filerId, launch.getProjectId()));
-		ObjectType targetClass = userFilter.getTargetClass();
-		expect(targetClass, equalTo(ObjectType.Launch)).verify(ErrorType.INCORRECT_FILTER_PARAMETERS,
-				formattedSupplier("Filter type '{}' is not supported", targetClass)
-		);
+  @Override
+  public List<Long> collect(Long filerId, Launch launch) {
+    UserFilter userFilter = userFilterRepository.findByIdAndProjectId(filerId,
+            launch.getProjectId())
+        .orElseThrow(
+            () -> new ReportPortalException(ErrorType.USER_FILTER_NOT_FOUND_IN_PROJECT, filerId,
+                launch.getProjectId()));
+    ObjectType targetClass = userFilter.getTargetClass();
+    expect(targetClass, equalTo(ObjectType.Launch)).verify(ErrorType.INCORRECT_FILTER_PARAMETERS,
+        formattedSupplier("Filter type '{}' is not supported", targetClass)
+    );
 
-		Filter filter = ProjectFilter.of(
-				new Filter(targetClass.getClassObject(), Lists.newArrayList(userFilter.getFilterCondition())),
-				launch.getProjectId());
-		PageRequest pageable = PageRequest.of(0, LAUNCHES_FILTER_LIMIT, Sort.by(DESC, CRITERIA_START_TIME));
-		return launchRepository.findByFilter(filter, pageable).stream().map(Launch::getId).collect(Collectors.toList());
-	}
+    Filter filter = ProjectFilter.of(
+        new Filter(targetClass.getClassObject(),
+            Lists.newArrayList(userFilter.getFilterCondition())),
+        launch.getProjectId());
+    PageRequest pageable = PageRequest.of(0, LAUNCHES_FILTER_LIMIT,
+        Sort.by(DESC, CRITERIA_START_TIME));
+    return launchRepository.findByFilter(filter, pageable).stream().map(Launch::getId)
+        .collect(Collectors.toList());
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/search/LaunchNameCollector.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/search/LaunchNameCollector.java
index 5a9a5bc6ba..cd5d0900a8 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/search/LaunchNameCollector.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/search/LaunchNameCollector.java
@@ -16,41 +16,42 @@
 
 package com.epam.ta.reportportal.core.analyzer.auto.strategy.search;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_NAME;
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_START_TIME;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.querygen.FilterCondition;
 import com.epam.ta.reportportal.commons.querygen.ProjectFilter;
 import com.epam.ta.reportportal.dao.LaunchRepository;
 import com.epam.ta.reportportal.entity.launch.Launch;
+import java.util.List;
+import java.util.stream.Collectors;
 import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Component;
 
-import java.util.List;
-import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_NAME;
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_START_TIME;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @Component
 public class LaunchNameCollector implements SearchLaunchesCollector {
 
-	private final LaunchRepository launchRepository;
+  private final LaunchRepository launchRepository;
 
-	public LaunchNameCollector(LaunchRepository launchRepository) {
-		this.launchRepository = launchRepository;
-	}
+  public LaunchNameCollector(LaunchRepository launchRepository) {
+    this.launchRepository = launchRepository;
+  }
 
-	@Override
-	public List<Long> collect(Long filerId, Launch launch) {
-		Filter filter = ProjectFilter.of(Filter.builder()
-				.withTarget(Launch.class)
-				.withCondition(FilterCondition.builder().eq(CRITERIA_NAME, launch.getName()).build())
-				.build(), launch.getProjectId());
-		PageRequest pageRequest = PageRequest.of(0, LAUNCHES_FILTER_LIMIT, Sort.by(Sort.Direction.DESC, CRITERIA_START_TIME));
+  @Override
+  public List<Long> collect(Long filerId, Launch launch) {
+    Filter filter = ProjectFilter.of(Filter.builder()
+        .withTarget(Launch.class)
+        .withCondition(FilterCondition.builder().eq(CRITERIA_NAME, launch.getName()).build())
+        .build(), launch.getProjectId());
+    PageRequest pageRequest = PageRequest.of(0, LAUNCHES_FILTER_LIMIT,
+        Sort.by(Sort.Direction.DESC, CRITERIA_START_TIME));
 
-		return launchRepository.findByFilter(filter, pageRequest).stream().map(Launch::getId).collect(Collectors.toList());
-	}
+    return launchRepository.findByFilter(filter, pageRequest).stream().map(Launch::getId)
+        .collect(Collectors.toList());
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/search/SearchCollectorConfig.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/search/SearchCollectorConfig.java
index 667cb138ff..2c0da13d92 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/search/SearchCollectorConfig.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/search/SearchCollectorConfig.java
@@ -17,36 +17,37 @@
 package com.epam.ta.reportportal.core.analyzer.auto.strategy.search;
 
 import com.google.common.collect.ImmutableMap;
+import java.util.Map;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
-import java.util.Map;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @Configuration
 public class SearchCollectorConfig {
 
-	private ApplicationContext applicationContext;
-
-	public SearchCollectorConfig(ApplicationContext applicationContext) {
-		this.applicationContext = applicationContext;
-	}
-
-	@Bean("searchModeMapping")
-	public Map<SearchLogsMode, SearchLaunchesCollector> getSearchModeMapping() {
-		return ImmutableMap.<SearchLogsMode, SearchLaunchesCollector>builder().put(SearchLogsMode.BY_LAUNCH_NAME,
-				applicationContext.getBean(LaunchNameCollector.class)
-		)
-				.put(SearchLogsMode.CURRENT_LAUNCH, applicationContext.getBean(CurrentLaunchCollector.class))
-				.put(SearchLogsMode.FILTER, applicationContext.getBean(FilterCollector.class))
-				.build();
-	}
-
-	@Bean
-	public SearchCollectorFactory searchCollectorFactory() {
-		return new SearchCollectorFactory(getSearchModeMapping());
-	}
+  private ApplicationContext applicationContext;
+
+  public SearchCollectorConfig(ApplicationContext applicationContext) {
+    this.applicationContext = applicationContext;
+  }
+
+  @Bean("searchModeMapping")
+  public Map<SearchLogsMode, SearchLaunchesCollector> getSearchModeMapping() {
+    return ImmutableMap.<SearchLogsMode, SearchLaunchesCollector>builder()
+        .put(SearchLogsMode.BY_LAUNCH_NAME,
+            applicationContext.getBean(LaunchNameCollector.class)
+        )
+        .put(SearchLogsMode.CURRENT_LAUNCH,
+            applicationContext.getBean(CurrentLaunchCollector.class))
+        .put(SearchLogsMode.FILTER, applicationContext.getBean(FilterCollector.class))
+        .build();
+  }
+
+  @Bean
+  public SearchCollectorFactory searchCollectorFactory() {
+    return new SearchCollectorFactory(getSearchModeMapping());
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/search/SearchCollectorFactory.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/search/SearchCollectorFactory.java
index 01a09b7610..d3d82ab81e 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/search/SearchCollectorFactory.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/search/SearchCollectorFactory.java
@@ -23,13 +23,13 @@
  */
 public class SearchCollectorFactory {
 
-	private Map<SearchLogsMode, SearchLaunchesCollector> mapping;
+  private Map<SearchLogsMode, SearchLaunchesCollector> mapping;
 
-	public SearchCollectorFactory(Map<SearchLogsMode, SearchLaunchesCollector> mapping) {
-		this.mapping = mapping;
-	}
+  public SearchCollectorFactory(Map<SearchLogsMode, SearchLaunchesCollector> mapping) {
+    this.mapping = mapping;
+  }
 
-	public SearchLaunchesCollector getCollector(SearchLogsMode mode) {
-		return mapping.get(mode);
-	}
+  public SearchLaunchesCollector getCollector(SearchLogsMode mode) {
+    return mapping.get(mode);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/search/SearchLaunchesCollector.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/search/SearchLaunchesCollector.java
index b9fadf0a0d..dcd71d5194 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/search/SearchLaunchesCollector.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/search/SearchLaunchesCollector.java
@@ -17,7 +17,6 @@
 package com.epam.ta.reportportal.core.analyzer.auto.strategy.search;
 
 import com.epam.ta.reportportal.entity.launch.Launch;
-
 import java.util.List;
 
 /**
@@ -25,7 +24,7 @@
  */
 public interface SearchLaunchesCollector {
 
-	int LAUNCHES_FILTER_LIMIT = 10;
+  int LAUNCHES_FILTER_LIMIT = 10;
 
-	List<Long> collect(Long filerId, Launch launch);
+  List<Long> collect(Long filerId, Launch launch);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/search/SearchLogsMode.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/search/SearchLogsMode.java
index 3eb67fcb15..21860a39ff 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/search/SearchLogsMode.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/strategy/search/SearchLogsMode.java
@@ -24,21 +24,21 @@
  */
 public enum SearchLogsMode {
 
-	BY_LAUNCH_NAME("launchName"),
-	CURRENT_LAUNCH("currentLaunch"),
-	FILTER("filter");
+  BY_LAUNCH_NAME("launchName"),
+  CURRENT_LAUNCH("currentLaunch"),
+  FILTER("filter");
 
-	private String value;
+  private String value;
 
-	SearchLogsMode(String value) {
-		this.value = value;
-	}
+  SearchLogsMode(String value) {
+    this.value = value;
+  }
 
-	public String getValue() {
-		return value;
-	}
+  public String getValue() {
+    return value;
+  }
 
-	public static Optional<SearchLogsMode> fromString(String mode) {
-		return Arrays.stream(values()).filter(it -> it.getValue().equalsIgnoreCase(mode)).findFirst();
-	}
+  public static Optional<SearchLogsMode> fromString(String mode) {
+    return Arrays.stream(values()).filter(it -> it.getValue().equalsIgnoreCase(mode)).findFirst();
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/config/AnalyzerType.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/config/AnalyzerType.java
index 2c139a0a06..a1894293c7 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/config/AnalyzerType.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/config/AnalyzerType.java
@@ -18,7 +18,6 @@
 
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
-
 import java.util.Arrays;
 import java.util.stream.Collectors;
 
@@ -27,28 +26,28 @@
  */
 public enum AnalyzerType {
 
-	AUTO_ANALYZER("autoAnalyzer"),
-	PATTERN_ANALYZER("patternAnalyzer");
-
-	private final String name;
-
-	AnalyzerType(String name) {
-		this.name = name;
-	}
-
-	public static AnalyzerType fromString(String type) {
-		return Arrays.stream(AnalyzerType.values())
-				.filter(it -> it.getName().equalsIgnoreCase(type))
-				.findFirst()
-				.orElseThrow(() -> new ReportPortalException(
-						ErrorType.INCORRECT_REQUEST,
-						"Incorrect analyzer type. Allowed are: " + Arrays.stream(AnalyzerType.values())
-								.map(AnalyzerType::getName)
-								.collect(Collectors.toList())
-				));
-	}
-
-	public String getName() {
-		return name;
-	}
+  AUTO_ANALYZER("autoAnalyzer"),
+  PATTERN_ANALYZER("patternAnalyzer");
+
+  private final String name;
+
+  AnalyzerType(String name) {
+    this.name = name;
+  }
+
+  public static AnalyzerType fromString(String type) {
+    return Arrays.stream(AnalyzerType.values())
+        .filter(it -> it.getName().equalsIgnoreCase(type))
+        .findFirst()
+        .orElseThrow(() -> new ReportPortalException(
+            ErrorType.INCORRECT_REQUEST,
+            "Incorrect analyzer type. Allowed are: " + Arrays.stream(AnalyzerType.values())
+                .map(AnalyzerType::getName)
+                .collect(Collectors.toList())
+        ));
+  }
+
+  public String getName() {
+    return name;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/config/AnalyzersConfig.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/config/AnalyzersConfig.java
index cad826a04b..a7230759bb 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/config/AnalyzersConfig.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/config/AnalyzersConfig.java
@@ -20,26 +20,27 @@
 import com.epam.ta.reportportal.core.analyzer.strategy.LaunchAutoAnalysisStrategy;
 import com.epam.ta.reportportal.core.analyzer.strategy.LaunchPatternAnalysisStrategy;
 import com.google.common.collect.ImmutableMap;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
-import java.util.Map;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Configuration
 public class AnalyzersConfig {
 
-	@Autowired
-	private ApplicationContext applicationContext;
+  @Autowired
+  private ApplicationContext applicationContext;
 
-	@Bean
-	public Map<AnalyzerType, LaunchAnalysisStrategy> launchAnalysisStrategyMapping() {
-		return ImmutableMap.<AnalyzerType, LaunchAnalysisStrategy>builder().put(AnalyzerType.AUTO_ANALYZER,
-				applicationContext.getBean(LaunchAutoAnalysisStrategy.class)
-		).put(AnalyzerType.PATTERN_ANALYZER, applicationContext.getBean(LaunchPatternAnalysisStrategy.class)).build();
-	}
+  @Bean
+  public Map<AnalyzerType, LaunchAnalysisStrategy> launchAnalysisStrategyMapping() {
+    return ImmutableMap.<AnalyzerType, LaunchAnalysisStrategy>builder()
+        .put(AnalyzerType.AUTO_ANALYZER,
+            applicationContext.getBean(LaunchAutoAnalysisStrategy.class)
+        ).put(AnalyzerType.PATTERN_ANALYZER,
+            applicationContext.getBean(LaunchPatternAnalysisStrategy.class)).build();
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/config/PatternAnalysisConfig.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/config/PatternAnalysisConfig.java
index dc3e797aed..382d1562c4 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/config/PatternAnalysisConfig.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/config/PatternAnalysisConfig.java
@@ -16,49 +16,59 @@
 
 package com.epam.ta.reportportal.core.analyzer.config;
 
-import com.epam.ta.reportportal.core.analyzer.pattern.CreatePatternTemplateHandler;
-import com.epam.ta.reportportal.core.analyzer.pattern.impl.CreatePatternTemplateHandlerImpl;
-import com.epam.ta.reportportal.core.analyzer.pattern.impl.CreateRegexPatternTemplateHandler;
 import com.epam.ta.reportportal.core.analyzer.pattern.selector.PatternAnalysisSelector;
 import com.epam.ta.reportportal.core.analyzer.pattern.selector.impl.RegexPatternAnalysisSelector;
 import com.epam.ta.reportportal.core.analyzer.pattern.selector.impl.StringPartPatternAnalysisSelector;
+import com.epam.ta.reportportal.core.analyzer.pattern.service.CreatePatternTemplateHandler;
+import com.epam.ta.reportportal.core.analyzer.pattern.service.impl.CreatePatternTemplateHandlerImpl;
+import com.epam.ta.reportportal.core.analyzer.pattern.service.impl.CreateRegexPatternTemplateHandler;
 import com.epam.ta.reportportal.entity.pattern.PatternTemplateType;
 import com.google.common.collect.ImmutableMap;
+import java.util.Map;
+import org.springframework.amqp.core.Queue;
+import org.springframework.amqp.core.QueueBuilder;
+import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
+import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
+import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory;
+import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContextAware;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
-import java.util.Map;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Configuration
 public class PatternAnalysisConfig implements ApplicationContextAware {
+  private ApplicationContext applicationContext;
 
-	private ApplicationContext applicationContext;
-
-	@Autowired
-	@Override
-	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
-		this.applicationContext = applicationContext;
-	}
+  @Autowired
+  @Override
+  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+    this.applicationContext = applicationContext;
+  }
 
-	@Bean("createPatternTemplateMapping")
-	public Map<PatternTemplateType, CreatePatternTemplateHandler> createPatternTemplateHandlerMapping() {
-		return ImmutableMap.<PatternTemplateType, CreatePatternTemplateHandler>builder().put(PatternTemplateType.STRING,
-				applicationContext.getBean(CreatePatternTemplateHandlerImpl.class)
-		).put(PatternTemplateType.REGEX, applicationContext.getBean(CreateRegexPatternTemplateHandler.class)).build();
-	}
+  @Bean("createPatternTemplateMapping")
+  public Map<PatternTemplateType, CreatePatternTemplateHandler> createPatternTemplateHandlerMapping() {
+    return ImmutableMap.<PatternTemplateType, CreatePatternTemplateHandler>builder()
+        .put(PatternTemplateType.STRING,
+            applicationContext.getBean(CreatePatternTemplateHandlerImpl.class)
+        ).put(PatternTemplateType.REGEX,
+            applicationContext.getBean(CreateRegexPatternTemplateHandler.class)).build();
+  }
 
-	@Bean("patternAnalysisSelectorMapping")
-	public Map<PatternTemplateType, PatternAnalysisSelector> patternAnalysisSelectorMapping() {
-		return ImmutableMap.<PatternTemplateType, PatternAnalysisSelector>builder().put(PatternTemplateType.STRING,
-				applicationContext.getBean(StringPartPatternAnalysisSelector.class)
-		).put(PatternTemplateType.REGEX, applicationContext.getBean(RegexPatternAnalysisSelector.class)).build();
-	}
+  @Bean("patternAnalysisSelectorMapping")
+  public Map<PatternTemplateType, PatternAnalysisSelector> patternAnalysisSelectorMapping() {
+    return ImmutableMap.<PatternTemplateType, PatternAnalysisSelector>builder()
+        .put(PatternTemplateType.STRING,
+            applicationContext.getBean(StringPartPatternAnalysisSelector.class)
+        ).put(PatternTemplateType.REGEX,
+            applicationContext.getBean(RegexPatternAnalysisSelector.class)).build();
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/config/PatternAnalysisRabbitConfiguration.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/config/PatternAnalysisRabbitConfiguration.java
new file mode 100644
index 0000000000..d4dbc28ca5
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/config/PatternAnalysisRabbitConfiguration.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2023 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.core.analyzer.config;
+
+import com.epam.ta.reportportal.entity.pattern.PatternTemplateType;
+import org.springframework.amqp.core.Binding;
+import org.springframework.amqp.core.BindingBuilder;
+import org.springframework.amqp.core.DirectExchange;
+import org.springframework.amqp.core.Exchange;
+import org.springframework.amqp.core.Queue;
+import org.springframework.amqp.core.QueueBuilder;
+import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
+import org.springframework.amqp.rabbit.connection.ConnectionFactory;
+import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory;
+import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
+ */
+@Configuration
+public class PatternAnalysisRabbitConfiguration {
+
+  public static final String PATTERN_ANALYSIS = "pattern.analysis";
+  public static final String PATTERN_ANALYSIS_STRING = "analysis.pattern.string";
+  public static final String PATTERN_ANALYSIS_REGEX = "analysis.pattern.regex";
+
+  @Bean
+  public Exchange patternAnalysisExchange() {
+    return new DirectExchange(PATTERN_ANALYSIS);
+  }
+
+  @Bean
+  public Queue patternAnalysisStringQueue() {
+    return QueueBuilder.durable(PATTERN_ANALYSIS_STRING).build();
+  }
+
+  @Bean
+  public Queue patternAnalysisRegexQueue() {
+    return QueueBuilder.durable(PATTERN_ANALYSIS_REGEX).build();
+  }
+
+  @Bean
+  public Binding stringQueueBinding() {
+    return BindingBuilder.bind(patternAnalysisStringQueue()).to(patternAnalysisExchange()).with(
+        PatternTemplateType.STRING.toString()).noargs();
+  }
+
+  @Bean
+  public Binding regexQueueBinding() {
+    return BindingBuilder.bind(patternAnalysisRegexQueue()).to(patternAnalysisExchange()).with(
+        PatternTemplateType.REGEX.toString()).noargs();
+  }
+
+  @Bean
+  public RabbitListenerContainerFactory<SimpleMessageListenerContainer> patternAnalysisContainerFactory(
+      ConnectionFactory connectionFactory,
+      SimpleRabbitListenerContainerFactoryConfigurer configurer,
+      @Value("${rp.environment.variable.pattern-analysis.consumers-count:1}") int consumersCount,
+      @Value("${rp.environment.variable.pattern-analysis.prefetch-count:0}") int prefetchCount) {
+    SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
+    factory.setConcurrentConsumers(consumersCount);
+    factory.setPrefetchCount(prefetchCount);
+    factory.setDefaultRequeueRejected(false);
+    configurer.configure(factory, connectionFactory);
+    return factory;
+  }
+
+
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/config/StartLaunchAutoAnalysisConfig.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/config/StartLaunchAutoAnalysisConfig.java
index c1dba2da57..5e423855ca 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/config/StartLaunchAutoAnalysisConfig.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/config/StartLaunchAutoAnalysisConfig.java
@@ -19,44 +19,46 @@
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.analyzer.auto.strategy.analyze.AnalyzeItemsMode;
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
-
 import java.util.Set;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public class StartLaunchAutoAnalysisConfig {
-	private final Long launchId;
-	private final AnalyzerConfig analyzerConfig;
-	private final Set<AnalyzeItemsMode> analyzeItemsModes;
-	private final ReportPortalUser user;
-
-	private StartLaunchAutoAnalysisConfig(Long launchId, AnalyzerConfig analyzerConfig, Set<AnalyzeItemsMode> analyzeItemsModes,
-			ReportPortalUser user) {
-		this.launchId = launchId;
-		this.analyzerConfig = analyzerConfig;
-		this.analyzeItemsModes = analyzeItemsModes;
-		this.user = user;
-	}
-
-	public static StartLaunchAutoAnalysisConfig of(Long launchId, AnalyzerConfig analyzerConfig, Set<AnalyzeItemsMode> analyzeItemsModes,
-			ReportPortalUser user) {
-		return new StartLaunchAutoAnalysisConfig(launchId, analyzerConfig, analyzeItemsModes, user);
-	}
-
-	public Long getLaunchId() {
-		return launchId;
-	}
-
-	public AnalyzerConfig getAnalyzerConfig() {
-		return analyzerConfig;
-	}
-
-	public Set<AnalyzeItemsMode> getAnalyzeItemsModes() {
-		return analyzeItemsModes;
-	}
-
-	public ReportPortalUser getUser() {
-		return user;
-	}
+
+  private final Long launchId;
+  private final AnalyzerConfig analyzerConfig;
+  private final Set<AnalyzeItemsMode> analyzeItemsModes;
+  private final ReportPortalUser user;
+
+  private StartLaunchAutoAnalysisConfig(Long launchId, AnalyzerConfig analyzerConfig,
+      Set<AnalyzeItemsMode> analyzeItemsModes,
+      ReportPortalUser user) {
+    this.launchId = launchId;
+    this.analyzerConfig = analyzerConfig;
+    this.analyzeItemsModes = analyzeItemsModes;
+    this.user = user;
+  }
+
+  public static StartLaunchAutoAnalysisConfig of(Long launchId, AnalyzerConfig analyzerConfig,
+      Set<AnalyzeItemsMode> analyzeItemsModes,
+      ReportPortalUser user) {
+    return new StartLaunchAutoAnalysisConfig(launchId, analyzerConfig, analyzeItemsModes, user);
+  }
+
+  public Long getLaunchId() {
+    return launchId;
+  }
+
+  public AnalyzerConfig getAnalyzerConfig() {
+    return analyzerConfig;
+  }
+
+  public Set<AnalyzeItemsMode> getAnalyzeItemsModes() {
+    return analyzeItemsModes;
+  }
+
+  public ReportPortalUser getUser() {
+    return user;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/PatternAnalyzer.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/PatternAnalyzer.java
deleted file mode 100644
index 06caee84f7..0000000000
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/PatternAnalyzer.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2019 EPAM Systems
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.epam.ta.reportportal.core.analyzer.pattern;
-
-import com.epam.ta.reportportal.core.analyzer.auto.strategy.analyze.AnalyzeItemsMode;
-import com.epam.ta.reportportal.entity.enums.TestItemIssueGroup;
-import com.epam.ta.reportportal.entity.launch.Launch;
-
-import java.util.Set;
-
-/**
- * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
- */
-public interface PatternAnalyzer {
-
-	/**
-	 * Analyze by {@link com.epam.ta.reportportal.entity.pattern.PatternTemplate#value}
-	 * all {@link com.epam.ta.reportportal.entity.log.Log#logMessage} of {@link com.epam.ta.reportportal.entity.item.TestItem}
-	 * with {@link TestItemIssueGroup#TO_INVESTIGATE} for {@link com.epam.ta.reportportal.entity.launch.Launch} with provided ID.
-	 * Every matched {@link com.epam.ta.reportportal.entity.pattern.PatternTemplate} will be attached
-	 * to the {@link com.epam.ta.reportportal.entity.item.TestItem}
-	 * using {@link com.epam.ta.reportportal.entity.pattern.PatternTemplateTestItem} relation
-	 *
-	 * @param launch       {@link com.epam.ta.reportportal.entity.launch.Launch}, which {@link com.epam.ta.reportportal.entity.item.TestItem}
-	 *                     should be analyzed
-	 * @param analyzeModes {@link AnalyzeItemsMode} to modify {@link com.epam.ta.reportportal.entity.item.TestItem} query conditions
-	 */
-	void analyzeTestItems(Launch launch, Set<AnalyzeItemsMode> analyzeModes);
-}
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/Builder.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/handler/ItemsPatternsAnalyzer.java
similarity index 53%
rename from src/main/java/com/epam/ta/reportportal/ws/converter/builders/Builder.java
rename to src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/handler/ItemsPatternsAnalyzer.java
index f2a4f39f31..ca0139a41d 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/Builder.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/handler/ItemsPatternsAnalyzer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2019 EPAM Systems
+ * Copyright 2023 EPAM Systems
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,37 +14,16 @@
  * limitations under the License.
  */
 
-package com.epam.ta.reportportal.ws.converter.builders;
+package com.epam.ta.reportportal.core.analyzer.pattern.handler;
+
+import java.util.List;
 
 /**
- * Generic builder holder
- *
- * @param <T>
- * @author Andrei Varabyeu
+ * Analyse list of items by project patterns
+ * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
  */
-@Deprecated
-public abstract class Builder<T> {
-
-	private T object;
-
-	public Builder() {
-		object = initObject();
-	}
-
-	/**
-	 * Builds object
-	 *
-	 * @return Built object
-	 */
-	public T build() {
-		T toReturn = object;
-		object = initObject();
-		return toReturn;
-	}
+public interface ItemsPatternsAnalyzer {
 
-	protected abstract T initObject();
+  void analyze(long projectId, long launchId, List<Long> itemIds);
 
-	protected T getObject() {
-		return object;
-	}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/handler/impl/ItemsPatternAnalyzerImpl.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/handler/impl/ItemsPatternAnalyzerImpl.java
new file mode 100644
index 0000000000..7f8b78d5ef
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/handler/impl/ItemsPatternAnalyzerImpl.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2023 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.core.analyzer.pattern.handler.impl;
+
+import com.epam.ta.reportportal.core.analyzer.pattern.selector.PatternAnalysisSelector;
+import com.epam.ta.reportportal.core.events.MessageBus;
+import com.epam.ta.reportportal.core.events.activity.PatternMatchedEvent;
+import com.epam.ta.reportportal.dao.PatternTemplateRepository;
+import com.epam.ta.reportportal.dao.TestItemRepository;
+import com.epam.ta.reportportal.entity.pattern.PatternTemplate;
+import com.epam.ta.reportportal.entity.pattern.PatternTemplateTestItemPojo;
+import com.epam.ta.reportportal.entity.pattern.PatternTemplateType;
+import com.epam.ta.reportportal.ws.converter.converters.PatternTemplateConverter;
+import com.epam.ta.reportportal.ws.model.activity.PatternTemplateActivityResource;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+/**
+ * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
+ */
+@Service
+public class ItemsPatternAnalyzerImpl {
+
+  private final PatternTemplateRepository patternTemplateRepository;
+
+  private final Map<PatternTemplateType, PatternAnalysisSelector> patternAnalysisSelectorMapping;
+
+  private final TestItemRepository testItemRepository;
+
+  private final MessageBus messageBus;
+
+  public ItemsPatternAnalyzerImpl(PatternTemplateRepository patternTemplateRepository,
+      Map<PatternTemplateType, PatternAnalysisSelector> patternAnalysisSelectorMapping,
+      TestItemRepository testItemRepository, MessageBus messageBus) {
+    this.patternTemplateRepository = patternTemplateRepository;
+    this.patternAnalysisSelectorMapping = patternAnalysisSelectorMapping;
+    this.testItemRepository = testItemRepository;
+    this.messageBus = messageBus;
+  }
+
+  public void analyzeByPattern(PatternTemplate pattern, Long launchId, List<Long> itemIds) {
+    List<Long> filtered = filterAlreadyMatched(pattern, itemIds);
+    PatternAnalysisSelector patternAnalysisSelector = patternAnalysisSelectorMapping.get(
+        pattern.getTemplateType());
+    List<Long> matchedIds = patternAnalysisSelector.selectItemsByPattern(launchId, filtered,
+        pattern.getValue());
+    if (!CollectionUtils.isEmpty(matchedIds)) {
+      List<PatternTemplateTestItemPojo> patternTemplateTestItems = saveMatches(pattern, matchedIds);
+      publishEvents(pattern, patternTemplateTestItems);
+    }
+  }
+
+  private List<Long> filterAlreadyMatched(PatternTemplate pattern, List<Long> itemIds) {
+    List<Long> alreadyMatched = patternTemplateRepository.findMatchedItemIdsIn(pattern.getId(),
+        itemIds);
+    return itemIds.stream().filter(id -> !alreadyMatched.contains(id))
+        .collect(Collectors.toList());
+  }
+
+  private List<PatternTemplateTestItemPojo> saveMatches(PatternTemplate pattern,
+      List<Long> matchedIds) {
+    List<PatternTemplateTestItemPojo> patternTemplateTestItemPojos = convertToPojo(pattern,
+        matchedIds);
+    patternTemplateRepository.saveInBatch(patternTemplateTestItemPojos);
+    return patternTemplateTestItemPojos;
+  }
+
+  private List<PatternTemplateTestItemPojo> convertToPojo(PatternTemplate patternTemplate,
+      List<Long> itemIds) {
+    return itemIds.stream()
+        .map(itemId -> new PatternTemplateTestItemPojo(patternTemplate.getId(), itemId))
+        .collect(Collectors.toList());
+  }
+
+  private void publishEvents(PatternTemplate patternTemplate,
+      List<PatternTemplateTestItemPojo> patternTemplateTestItems) {
+    final PatternTemplateActivityResource patternTemplateActivityResource = PatternTemplateConverter.TO_ACTIVITY_RESOURCE.apply(
+        patternTemplate);
+    patternTemplateTestItems.forEach(patternItem -> {
+      Long testItemId = patternItem.getTestItemId();
+      Optional<String> itemNameByItemId = testItemRepository.findItemNameByItemId(testItemId);
+      PatternMatchedEvent patternMatchedEvent = new PatternMatchedEvent(
+          itemNameByItemId.orElse(StringUtils.EMPTY),
+          testItemId,
+          patternTemplateActivityResource
+      );
+      messageBus.publishActivity(patternMatchedEvent);
+    });
+  }
+
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/handler/proxy/ItemsPatternAnalyzeConsumer.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/handler/proxy/ItemsPatternAnalyzeConsumer.java
new file mode 100644
index 0000000000..4bfd5990d4
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/handler/proxy/ItemsPatternAnalyzeConsumer.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2023 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.core.analyzer.pattern.handler.proxy;
+
+import static com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerStatusCache.PATTERN_ANALYZER_KEY;
+import static com.epam.ta.reportportal.core.analyzer.config.PatternAnalysisRabbitConfiguration.PATTERN_ANALYSIS_REGEX;
+import static com.epam.ta.reportportal.core.analyzer.config.PatternAnalysisRabbitConfiguration.PATTERN_ANALYSIS_STRING;
+
+import com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerStatusCache;
+import com.epam.ta.reportportal.core.analyzer.pattern.handler.impl.ItemsPatternAnalyzerImpl;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.stereotype.Component;
+
+/**
+ * Consumes items for pattern analysis from the queue
+ *
+ * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
+ */
+@Component
+public class ItemsPatternAnalyzeConsumer {
+
+  private final ItemsPatternAnalyzerImpl itemsPatternsAnalyzer;
+
+  private final AnalyzerStatusCache analyzerStatusCache;
+
+  public ItemsPatternAnalyzeConsumer(ItemsPatternAnalyzerImpl itemsPatternsAnalyzer,
+      AnalyzerStatusCache analyzerStatusCache) {
+    this.itemsPatternsAnalyzer = itemsPatternsAnalyzer;
+    this.analyzerStatusCache = analyzerStatusCache;
+  }
+
+  @RabbitListener(queues = {PATTERN_ANALYSIS_REGEX,
+      PATTERN_ANALYSIS_STRING}, containerFactory = "patternAnalysisContainerFactory")
+  public void handleEvent(ItemsPatternAnalyzeDto event) {
+    if (event.isLastItem()) {
+      analyzerStatusCache.analyzeFinished(PATTERN_ANALYZER_KEY, event.getLaunchId());
+    } else {
+      itemsPatternsAnalyzer.analyzeByPattern(event.getPatternTemplate(), event.getLaunchId(),
+          event.getItemIds());
+    }
+  }
+
+
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/handler/proxy/ItemsPatternAnalyzeDto.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/handler/proxy/ItemsPatternAnalyzeDto.java
new file mode 100644
index 0000000000..c960eb009e
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/handler/proxy/ItemsPatternAnalyzeDto.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2023 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.core.analyzer.pattern.handler.proxy;
+
+import com.epam.ta.reportportal.entity.pattern.PatternTemplate;
+import java.util.List;
+
+/**
+ * Dto of item analysis event
+ *
+ * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
+ */
+public class ItemsPatternAnalyzeDto {
+
+  private PatternTemplate patternTemplate;
+  private long projectId;
+  private long launchId;
+  private List<Long> itemIds;
+  private boolean isLastItem;
+
+  public ItemsPatternAnalyzeDto() {
+  }
+
+  public ItemsPatternAnalyzeDto(long projectId, long launchId, List<Long> itemIds,
+      PatternTemplate patternTemplate) {
+    this.projectId = projectId;
+    this.launchId = launchId;
+    this.itemIds = itemIds;
+    this.patternTemplate = patternTemplate;
+  }
+
+  public ItemsPatternAnalyzeDto(long projectId, long launchId, List<Long> itemIds,
+      boolean isLastItem) {
+    this.projectId = projectId;
+    this.launchId = launchId;
+    this.itemIds = itemIds;
+    this.isLastItem = isLastItem;
+  }
+
+  public PatternTemplate getPatternTemplate() {
+    return patternTemplate;
+  }
+
+  public void setPatternTemplate(PatternTemplate patternTemplate) {
+    this.patternTemplate = patternTemplate;
+  }
+
+  public long getProjectId() {
+    return projectId;
+  }
+
+  public long getLaunchId() {
+    return launchId;
+  }
+
+  public List<Long> getItemIds() {
+    return itemIds;
+  }
+
+  public void setProjectId(long projectId) {
+    this.projectId = projectId;
+  }
+
+  public void setLaunchId(long launchId) {
+    this.launchId = launchId;
+  }
+
+  public void setItemIds(List<Long> itemIds) {
+    this.itemIds = itemIds;
+  }
+
+  public boolean isLastItem() {
+    return isLastItem;
+  }
+
+  public void setLastItem(boolean lastItem) {
+    isLastItem = lastItem;
+  }
+
+  @Override
+  public String toString() {
+    return "ItemsPatternMessage{" +
+        "projectId=" + projectId +
+        ", launchId=" + launchId +
+        ", itemIds=" + itemIds +
+        ", isLastItem=" + isLastItem +
+        '}';
+  }
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/handler/proxy/ItemsPatternAnalyzeProducer.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/handler/proxy/ItemsPatternAnalyzeProducer.java
new file mode 100644
index 0000000000..c65c4f0a81
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/handler/proxy/ItemsPatternAnalyzeProducer.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2023 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.core.analyzer.pattern.handler.proxy;
+
+
+import static com.epam.ta.reportportal.core.analyzer.config.PatternAnalysisRabbitConfiguration.PATTERN_ANALYSIS;
+
+import com.epam.ta.reportportal.core.analyzer.pattern.handler.ItemsPatternsAnalyzer;
+import com.epam.ta.reportportal.core.events.MessageBus;
+import com.epam.ta.reportportal.dao.PatternTemplateRepository;
+import com.epam.ta.reportportal.entity.pattern.PatternTemplate;
+import com.epam.ta.reportportal.entity.pattern.PatternTemplateType;
+import java.util.Collections;
+import java.util.List;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+/**
+ * Sends items for pattern analysis queue
+ *
+ * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
+ */
+@Primary
+@Component
+public class ItemsPatternAnalyzeProducer implements ItemsPatternsAnalyzer {
+
+  private final PatternTemplateRepository patternTemplateRepository;
+  private final boolean isSingleItem;
+  private final MessageBus messageBus;
+
+  public ItemsPatternAnalyzeProducer(
+      @Value("${rp.environment.variable.pattern-analysis.single-item:true}") boolean isSingleItem,
+      MessageBus messageBus, PatternTemplateRepository patternTemplateRepository) {
+    this.isSingleItem = isSingleItem;
+    this.messageBus = messageBus;
+    this.patternTemplateRepository = patternTemplateRepository;
+  }
+
+  @Override
+  public void analyze(long projectId, long launchId, List<Long> itemIds) {
+    List<PatternTemplate> patternTemplates = patternTemplateRepository.findAllByProjectIdAndEnabled(
+        projectId, true);
+    patternTemplates.forEach(pattern -> publishMessage(pattern, projectId, launchId, itemIds));
+    if (CollectionUtils.isEmpty(itemIds)) {
+      sendFinishedEvent(projectId, launchId);
+    }
+  }
+
+  private void publishMessage(PatternTemplate pattern, long projectId, long launchId,
+      List<Long> itemIds) {
+    if (isSingleItem) {
+      itemIds.forEach(id -> messageBus.publish(PATTERN_ANALYSIS, pattern.getTemplateType().name(),
+          new ItemsPatternAnalyzeDto(projectId, launchId, Collections.singletonList(id), pattern)));
+    } else {
+      messageBus.publish(PATTERN_ANALYSIS, pattern.getTemplateType().name(),
+          new ItemsPatternAnalyzeDto(projectId, launchId, itemIds, pattern));
+    }
+  }
+
+  public void sendFinishedEvent(long projectId, long launchId) {
+    messageBus.publish(PATTERN_ANALYSIS, PatternTemplateType.REGEX.name(),
+        new ItemsPatternAnalyzeDto(projectId, launchId, Collections.emptyList(), true));
+  }
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/impl/PatternAnalyzerImpl.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/impl/PatternAnalyzerImpl.java
deleted file mode 100644
index 537b2c6900..0000000000
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/impl/PatternAnalyzerImpl.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright 2019 EPAM Systems
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.epam.ta.reportportal.core.analyzer.pattern.impl;
-
-import static com.epam.ta.reportportal.commons.Predicates.not;
-import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_PATTERN_TEMPLATE_NAME;
-import static com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerStatusCache.PATTERN_ANALYZER_KEY;
-
-import com.epam.ta.reportportal.commons.querygen.Condition;
-import com.epam.ta.reportportal.commons.querygen.ConvertibleCondition;
-import com.epam.ta.reportportal.commons.querygen.Filter;
-import com.epam.ta.reportportal.commons.querygen.FilterCondition;
-import com.epam.ta.reportportal.commons.validation.BusinessRule;
-import com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerStatusCache;
-import com.epam.ta.reportportal.core.analyzer.auto.strategy.analyze.AnalyzeItemsMode;
-import com.epam.ta.reportportal.core.analyzer.pattern.PatternAnalyzer;
-import com.epam.ta.reportportal.core.analyzer.pattern.selector.PatternAnalysisSelector;
-import com.epam.ta.reportportal.core.analyzer.pattern.selector.condition.PatternConditionProviderChain;
-import com.epam.ta.reportportal.core.events.MessageBus;
-import com.epam.ta.reportportal.core.events.activity.PatternMatchedEvent;
-import com.epam.ta.reportportal.dao.PatternTemplateRepository;
-import com.epam.ta.reportportal.dao.TestItemRepository;
-import com.epam.ta.reportportal.entity.item.TestItem;
-import com.epam.ta.reportportal.entity.launch.Launch;
-import com.epam.ta.reportportal.entity.pattern.PatternTemplate;
-import com.epam.ta.reportportal.entity.pattern.PatternTemplateTestItemPojo;
-import com.epam.ta.reportportal.entity.pattern.PatternTemplateType;
-import com.epam.ta.reportportal.exception.ReportPortalException;
-import com.epam.ta.reportportal.ws.converter.converters.PatternTemplateConverter;
-import com.epam.ta.reportportal.ws.model.ErrorType;
-import com.epam.ta.reportportal.ws.model.activity.PatternTemplateActivityResource;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.core.task.TaskExecutor;
-import org.springframework.stereotype.Service;
-
-/**
- * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
- */
-@Service
-public class PatternAnalyzerImpl implements PatternAnalyzer {
-
-	public static final Logger LOGGER = LoggerFactory.getLogger(PatternAnalyzerImpl.class);
-
-	private final Integer batchSize;
-
-	private final TestItemRepository testItemRepository;
-	private final PatternTemplateRepository patternTemplateRepository;
-	private final PatternConditionProviderChain patternConditionProviderChain;
-
-	private final Map<PatternTemplateType, PatternAnalysisSelector> patternAnalysisSelectorMapping;
-
-	private final TaskExecutor patternAnalysisTaskExecutor;
-
-	private final AnalyzerStatusCache analyzerStatusCache;
-
-	private final MessageBus messageBus;
-
-	@Autowired
-	public PatternAnalyzerImpl(@Value("${rp.environment.variable.pattern-analysis.batch-size}") Integer batchSize,
-			TestItemRepository testItemRepository, PatternTemplateRepository patternTemplateRepository,
-			@Qualifier("patternAnalysisSelectorMapping") Map<PatternTemplateType, PatternAnalysisSelector> patternAnalysisSelectorMapping,
-			TaskExecutor patternAnalysisTaskExecutor, PatternConditionProviderChain patternConditionProviderChain,
-			AnalyzerStatusCache analyzerStatusCache, MessageBus messageBus) {
-		this.batchSize = batchSize;
-		this.testItemRepository = testItemRepository;
-		this.patternTemplateRepository = patternTemplateRepository;
-		this.patternAnalysisSelectorMapping = patternAnalysisSelectorMapping;
-		this.patternAnalysisTaskExecutor = patternAnalysisTaskExecutor;
-		this.patternConditionProviderChain = patternConditionProviderChain;
-		this.analyzerStatusCache = analyzerStatusCache;
-		this.messageBus = messageBus;
-	}
-
-	@Override
-	public void analyzeTestItems(Launch launch, Set<AnalyzeItemsMode> analyzeModes) {
-		BusinessRule.expect(analyzerStatusCache.getStartedAnalyzers(launch.getId()), not(started -> started.contains(PATTERN_ANALYZER_KEY)))
-				.verify(ErrorType.PATTERN_ANALYSIS_ERROR, "Pattern analysis is still in progress.");
-
-		analyzerStatusCache.analyzeStarted(PATTERN_ANALYZER_KEY, launch.getId(), launch.getProjectId());
-		patternAnalysisTaskExecutor.execute(() -> {
-			try {
-				final ConvertibleCondition itemCondition = getItemCondition(analyzeModes);
-				patternTemplateRepository.findAllByProjectIdAndEnabled(launch.getProjectId(), true)
-						.forEach(patternTemplate -> analyze(launch, itemCondition, patternTemplate));
-			} catch (Exception e) {
-				LOGGER.error(e.getMessage(), e);
-			} finally {
-				analyzerStatusCache.analyzeFinished(PATTERN_ANALYZER_KEY, launch.getId());
-			}
-		});
-
-	}
-
-	private ConvertibleCondition getItemCondition(Set<AnalyzeItemsMode> analyzeModes) {
-		return patternConditionProviderChain.provideCondition(analyzeModes)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.PATTERN_ANALYSIS_ERROR, "Unable to resolve item search condition"));
-	}
-
-	private void analyze(Launch launch, ConvertibleCondition itemCondition, PatternTemplate patternTemplate) {
-		final Filter filter = createItemFilter(itemCondition, patternTemplate.getName());
-		int offset = 0;
-		List<Long> itemIds = testItemRepository.selectIdsByFilter(launch.getId(), filter, batchSize, offset);
-		while (CollectionUtils.isNotEmpty(itemIds)) {
-			final List<Long> matchedIds = attachToPatternTemplate(launch, patternTemplate, itemIds);
-			offset += itemIds.size() - matchedIds.size();
-			itemIds = testItemRepository.selectIdsByFilter(launch.getId(), filter, batchSize, offset);
-		}
-
-	}
-
-	private List<Long> attachToPatternTemplate(Launch launch, PatternTemplate patternTemplate, List<Long> itemIds) {
-		final List<Long> matchedIds = filterItems(launch, patternTemplate, itemIds);
-		final List<PatternTemplateTestItemPojo> patternTemplateTestItems = convertToPojo(patternTemplate, matchedIds);
-		patternTemplateRepository.saveInBatch(patternTemplateTestItems);
-		publishEvents(patternTemplate, patternTemplateTestItems);
-		return matchedIds;
-	}
-
-	private List<Long> filterItems(Launch launch, PatternTemplate patternTemplate, List<Long> itemIds) {
-		final PatternAnalysisSelector patternAnalysisSelector = patternAnalysisSelectorMapping.get(patternTemplate.getTemplateType());
-		return patternAnalysisSelector.selectItemsByPattern(launch.getId(), itemIds, patternTemplate.getValue());
-	}
-
-	private Filter createItemFilter(ConvertibleCondition commonItemCondition, String patternTemplateName) {
-		return Filter.builder()
-				.withTarget(TestItem.class)
-				.withCondition(commonItemCondition)
-				.withCondition(FilterCondition.builder()
-						.withCondition(Condition.ANY)
-						.withNegative(true)
-						.withSearchCriteria(CRITERIA_PATTERN_TEMPLATE_NAME)
-						.withValue(patternTemplateName)
-						.build())
-				.build();
-	}
-
-	private List<PatternTemplateTestItemPojo> convertToPojo(PatternTemplate patternTemplate, List<Long> itemIds) {
-		return itemIds.stream()
-				.map(itemId -> new PatternTemplateTestItemPojo(patternTemplate.getId(), itemId))
-				.collect(Collectors.toList());
-	}
-
-	private void publishEvents(PatternTemplate patternTemplate, List<PatternTemplateTestItemPojo> patternTemplateTestItems) {
-		final PatternTemplateActivityResource patternTemplateActivityResource = PatternTemplateConverter.TO_ACTIVITY_RESOURCE.apply(
-				patternTemplate);
-		patternTemplateTestItems.forEach(patternItem -> {
-      Long testItemId = patternItem.getTestItemId();
-      Optional<String> itemNameByItemId = testItemRepository.findItemNameByItemId(testItemId);
-      PatternMatchedEvent patternMatchedEvent = new PatternMatchedEvent(
-          itemNameByItemId.orElse(StringUtils.EMPTY),
-          testItemId,
-          patternTemplateActivityResource
-      );
-      messageBus.publishActivity(patternMatchedEvent);
-    });
-	}
-
-}
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/PatternAnalysisSelector.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/PatternAnalysisSelector.java
index 27b0686e4d..3f1dbab7c0 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/PatternAnalysisSelector.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/PatternAnalysisSelector.java
@@ -19,7 +19,6 @@
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.entity.pattern.PatternTemplate;
-
 import java.util.Collection;
 import java.util.List;
 
@@ -28,13 +27,13 @@
  */
 public interface PatternAnalysisSelector {
 
-	/**
-	 * Select {@link TestItem#getItemId()} with logs matched by pattern value
-	 *
-	 * @param launchId {@link Launch#getId()}
-	 * @param itemIds  {@link Collection} with {@link TestItem#getItemId()}
-	 * @param pattern  {@link PatternTemplate#getValue()}
-	 * @return {@link List} of {@link TestItem#getItemId()}
-	 */
-	List<Long> selectItemsByPattern(Long launchId, Collection<Long> itemIds, String pattern);
+  /**
+   * Select {@link TestItem#getItemId()} with logs matched by pattern value
+   *
+   * @param launchId {@link Launch#getId()}
+   * @param itemIds  {@link Collection} with {@link TestItem#getItemId()}
+   * @param pattern  {@link PatternTemplate#getValue()}
+   * @return {@link List} of {@link TestItem#getItemId()}
+   */
+  List<Long> selectItemsByPattern(Long launchId, Collection<Long> itemIds, String pattern);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/condition/PatternConditionProvider.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/condition/PatternConditionProvider.java
index ceefbde798..4022989675 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/condition/PatternConditionProvider.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/condition/PatternConditionProvider.java
@@ -18,7 +18,6 @@
 
 import com.epam.ta.reportportal.commons.querygen.ConvertibleCondition;
 import com.epam.ta.reportportal.core.analyzer.auto.strategy.analyze.AnalyzeItemsMode;
-
 import java.util.Optional;
 import java.util.Set;
 
@@ -28,5 +27,5 @@
 //TODO should be updated according to the nested steps' logs retrieving logic
 public interface PatternConditionProvider {
 
-	Optional<ConvertibleCondition> provideCondition(Set<AnalyzeItemsMode> analyzeItemsModes);
+  Optional<ConvertibleCondition> provideCondition(Set<AnalyzeItemsMode> analyzeItemsModes);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/condition/PatternConditionProviderChain.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/condition/PatternConditionProviderChain.java
index 79e4bf4811..798b7b980d 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/condition/PatternConditionProviderChain.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/condition/PatternConditionProviderChain.java
@@ -20,21 +20,21 @@
 import com.epam.ta.reportportal.commons.querygen.ConvertibleCondition;
 import com.epam.ta.reportportal.core.analyzer.auto.strategy.analyze.AnalyzeItemsMode;
 import com.epam.ta.reportportal.core.analyzer.pattern.selector.condition.impl.AutoAnalyzedPatternConditionProvider;
+import com.epam.ta.reportportal.core.analyzer.pattern.selector.condition.impl.IgnoreImmediatePatternAnalysisConditionProvider;
 import com.epam.ta.reportportal.core.analyzer.pattern.selector.condition.impl.ManualPatternConditionProvider;
 import com.epam.ta.reportportal.core.analyzer.pattern.selector.condition.impl.ToInvestigatePatternConditionProvider;
 import com.epam.ta.reportportal.dao.IssueGroupRepository;
 import com.epam.ta.reportportal.entity.enums.TestItemIssueGroup;
 import com.epam.ta.reportportal.entity.item.issue.IssueGroup;
 import com.google.common.collect.Sets;
-import org.jooq.Operator;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
 import java.util.List;
 import java.util.Optional;
 import java.util.Set;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
+import org.jooq.Operator;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -42,28 +42,31 @@
 @Component
 public class PatternConditionProviderChain {
 
-	private final Set<PatternConditionProvider> patternConditionProviders;
+  private final Set<PatternConditionProvider> patternConditionProviders;
 
-	@Autowired
-	public PatternConditionProviderChain(IssueGroupRepository issueGroupRepository) {
-		Supplier<IssueGroup> issueGroupSupplier = () -> issueGroupRepository.findByTestItemIssueGroup(TestItemIssueGroup.TO_INVESTIGATE);
-		this.patternConditionProviders = Sets.newHashSet(new AutoAnalyzedPatternConditionProvider(AnalyzeItemsMode.AUTO_ANALYZED),
-				new ManualPatternConditionProvider(AnalyzeItemsMode.MANUALLY_ANALYZED, issueGroupSupplier),
-				new ToInvestigatePatternConditionProvider(AnalyzeItemsMode.TO_INVESTIGATE,
-						issueGroupSupplier
-				)
-		);
-	}
+  @Autowired
+  public PatternConditionProviderChain(IssueGroupRepository issueGroupRepository) {
+    Supplier<IssueGroup> issueGroupSupplier = () -> issueGroupRepository.findByTestItemIssueGroup(
+        TestItemIssueGroup.TO_INVESTIGATE);
+    this.patternConditionProviders = Sets.newHashSet(
+        new AutoAnalyzedPatternConditionProvider(AnalyzeItemsMode.AUTO_ANALYZED),
+        new ManualPatternConditionProvider(AnalyzeItemsMode.MANUALLY_ANALYZED, issueGroupSupplier),
+        new ToInvestigatePatternConditionProvider(AnalyzeItemsMode.TO_INVESTIGATE,
+            issueGroupSupplier
+        ),
+        new IgnoreImmediatePatternAnalysisConditionProvider(AnalyzeItemsMode.IGNORE_IMMEDIATE)
+    );
+  }
 
-	public Optional<ConvertibleCondition> provideCondition(Set<AnalyzeItemsMode> analyzeItemsModes) {
-		List<ConvertibleCondition> convertibleConditions = patternConditionProviders.stream()
-				.map(provider -> provider.provideCondition(analyzeItemsModes))
-				.filter(Optional::isPresent)
-				.map(Optional::get)
-				.collect(Collectors.toList());
+  public Optional<ConvertibleCondition> provideCondition(Set<AnalyzeItemsMode> analyzeItemsModes) {
+    List<ConvertibleCondition> convertibleConditions = patternConditionProviders.stream()
+        .map(provider -> provider.provideCondition(analyzeItemsModes))
+        .filter(Optional::isPresent)
+        .map(Optional::get)
+        .collect(Collectors.toList());
 
-		return convertibleConditions.isEmpty() ?
-				Optional.empty() :
-				Optional.of(new CompositeFilterCondition(convertibleConditions, Operator.AND));
-	}
+    return convertibleConditions.isEmpty() ?
+        Optional.empty() :
+        Optional.of(new CompositeFilterCondition(convertibleConditions, Operator.AND));
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/condition/impl/AbstractPatternConditionProvider.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/condition/impl/AbstractPatternConditionProvider.java
index 3019f97266..a1de62a364 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/condition/impl/AbstractPatternConditionProvider.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/condition/impl/AbstractPatternConditionProvider.java
@@ -19,33 +19,33 @@
 import com.epam.ta.reportportal.commons.querygen.ConvertibleCondition;
 import com.epam.ta.reportportal.core.analyzer.auto.strategy.analyze.AnalyzeItemsMode;
 import com.epam.ta.reportportal.core.analyzer.pattern.selector.condition.PatternConditionProvider;
-import org.apache.commons.collections4.CollectionUtils;
-
 import java.util.Optional;
 import java.util.Set;
+import org.apache.commons.collections4.CollectionUtils;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public abstract class AbstractPatternConditionProvider implements PatternConditionProvider {
 
-	private final AnalyzeItemsMode analyzeItemsMode;
+  private final AnalyzeItemsMode analyzeItemsMode;
 
-	public AbstractPatternConditionProvider(AnalyzeItemsMode analyzeItemsMode) {
-		this.analyzeItemsMode = analyzeItemsMode;
-	}
+  public AbstractPatternConditionProvider(AnalyzeItemsMode analyzeItemsMode) {
+    this.analyzeItemsMode = analyzeItemsMode;
+  }
 
-	@Override
-	public Optional<ConvertibleCondition> provideCondition(Set<AnalyzeItemsMode> analyzeItemsModes) {
-		if (isModificationRequired(analyzeItemsModes)) {
-			return Optional.of(provideCondition());
-		}
-		return Optional.empty();
-	}
+  @Override
+  public Optional<ConvertibleCondition> provideCondition(Set<AnalyzeItemsMode> analyzeItemsModes) {
+    if (isModificationRequired(analyzeItemsModes)) {
+      return Optional.of(provideCondition());
+    }
+    return Optional.empty();
+  }
 
-	protected boolean isModificationRequired(Set<AnalyzeItemsMode> analyzeItemsModes) {
-		return CollectionUtils.isNotEmpty(analyzeItemsModes) && analyzeItemsModes.contains(analyzeItemsMode);
-	}
+  protected boolean isModificationRequired(Set<AnalyzeItemsMode> analyzeItemsModes) {
+    return CollectionUtils.isNotEmpty(analyzeItemsModes) && analyzeItemsModes.contains(
+        analyzeItemsMode);
+  }
 
-	protected abstract ConvertibleCondition provideCondition();
+  protected abstract ConvertibleCondition provideCondition();
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/condition/impl/AutoAnalyzedPatternConditionProvider.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/condition/impl/AutoAnalyzedPatternConditionProvider.java
index 2a55ac4221..b977dc9c3d 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/condition/impl/AutoAnalyzedPatternConditionProvider.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/condition/impl/AutoAnalyzedPatternConditionProvider.java
@@ -16,25 +16,26 @@
 
 package com.epam.ta.reportportal.core.analyzer.pattern.selector.condition.impl;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.IssueCriteriaConstant.CRITERIA_ISSUE_AUTO_ANALYZED;
+
 import com.epam.ta.reportportal.commons.querygen.ConvertibleCondition;
 import com.epam.ta.reportportal.commons.querygen.FilterCondition;
 import com.epam.ta.reportportal.core.analyzer.auto.strategy.analyze.AnalyzeItemsMode;
 import org.jooq.Operator;
 
-import static com.epam.ta.reportportal.commons.querygen.constant.IssueCriteriaConstant.CRITERIA_ISSUE_AUTO_ANALYZED;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public class AutoAnalyzedPatternConditionProvider extends AbstractPatternConditionProvider {
 
-	public AutoAnalyzedPatternConditionProvider(AnalyzeItemsMode analyzeItemsMode) {
-		super(analyzeItemsMode);
-	}
+  public AutoAnalyzedPatternConditionProvider(AnalyzeItemsMode analyzeItemsMode) {
+    super(analyzeItemsMode);
+  }
 
-	@Override
-	protected ConvertibleCondition provideCondition() {
-		return FilterCondition.builder().eq(CRITERIA_ISSUE_AUTO_ANALYZED, Boolean.TRUE.toString()).withOperator(Operator.OR).build();
-	}
+  @Override
+  protected ConvertibleCondition provideCondition() {
+    return FilterCondition.builder().eq(CRITERIA_ISSUE_AUTO_ANALYZED, Boolean.TRUE.toString())
+        .withOperator(Operator.OR).build();
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/condition/impl/IgnoreImmediatePatternAnalysisConditionProvider.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/condition/impl/IgnoreImmediatePatternAnalysisConditionProvider.java
new file mode 100644
index 0000000000..a4be042d64
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/condition/impl/IgnoreImmediatePatternAnalysisConditionProvider.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2023 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.core.analyzer.pattern.selector.condition.impl;
+
+import static com.epam.ta.reportportal.commons.querygen.constant.ItemAttributeConstant.CRITERIA_COMPOSITE_SYSTEM_ATTRIBUTE;
+import static com.epam.ta.reportportal.commons.querygen.constant.ItemAttributeConstant.KEY_VALUE_SEPARATOR;
+
+import com.epam.ta.reportportal.commons.querygen.Condition;
+import com.epam.ta.reportportal.commons.querygen.ConvertibleCondition;
+import com.epam.ta.reportportal.commons.querygen.FilterCondition;
+import com.epam.ta.reportportal.core.analyzer.auto.strategy.analyze.AnalyzeItemsMode;
+
+/**
+ * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
+ */
+public class IgnoreImmediatePatternAnalysisConditionProvider extends
+    AbstractPatternConditionProvider {
+
+  private static final String IMMEDIATE_PATTERN_ANALYSIS = "immediatePatternAnalysis";
+
+  public IgnoreImmediatePatternAnalysisConditionProvider(AnalyzeItemsMode analyzeItemsMode) {
+    super(analyzeItemsMode);
+  }
+
+  @Override
+  protected ConvertibleCondition provideCondition() {
+    return FilterCondition.builder()
+        .withCondition(Condition.HAS)
+        .withNegative(true)
+        .withSearchCriteria(CRITERIA_COMPOSITE_SYSTEM_ATTRIBUTE)
+        .withValue(IMMEDIATE_PATTERN_ANALYSIS + KEY_VALUE_SEPARATOR + Boolean.TRUE)
+        .build();
+  }
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/condition/impl/ManualPatternConditionProvider.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/condition/impl/ManualPatternConditionProvider.java
index 2a30426a1c..f6e41bc039 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/condition/impl/ManualPatternConditionProvider.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/condition/impl/ManualPatternConditionProvider.java
@@ -16,6 +16,9 @@
 
 package com.epam.ta.reportportal.core.analyzer.pattern.selector.condition.impl;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.IssueCriteriaConstant.CRITERIA_ISSUE_AUTO_ANALYZED;
+import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_ISSUE_GROUP_ID;
+
 import com.epam.ta.reportportal.commons.querygen.CompositeFilterCondition;
 import com.epam.ta.reportportal.commons.querygen.Condition;
 import com.epam.ta.reportportal.commons.querygen.ConvertibleCondition;
@@ -23,33 +26,32 @@
 import com.epam.ta.reportportal.core.analyzer.auto.strategy.analyze.AnalyzeItemsMode;
 import com.epam.ta.reportportal.entity.item.issue.IssueGroup;
 import com.google.common.collect.Lists;
-import org.jooq.Operator;
-
 import java.util.function.Supplier;
-
-import static com.epam.ta.reportportal.commons.querygen.constant.IssueCriteriaConstant.CRITERIA_ISSUE_AUTO_ANALYZED;
-import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_ISSUE_GROUP_ID;
+import org.jooq.Operator;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public class ManualPatternConditionProvider extends AbstractPatternConditionProvider {
 
-	private final Supplier<IssueGroup> issueGroupSupplier;
-
-	public ManualPatternConditionProvider(AnalyzeItemsMode analyzeItemsMode, Supplier<IssueGroup> issueGroupSupplier) {
-		super(analyzeItemsMode);
-		this.issueGroupSupplier = issueGroupSupplier;
-	}
-
-	@Override
-	protected ConvertibleCondition provideCondition() {
-
-		return new CompositeFilterCondition(Lists.newArrayList(FilterCondition.builder()
-				.withCondition(Condition.NOT_EQUALS)
-				.withSearchCriteria(CRITERIA_ISSUE_GROUP_ID)
-				.withValue(String.valueOf(issueGroupSupplier.get().getId()))
-				.build(), FilterCondition.builder().eq(CRITERIA_ISSUE_AUTO_ANALYZED, Boolean.FALSE.toString()).build()), Operator.OR);
-	}
+  private final Supplier<IssueGroup> issueGroupSupplier;
+
+  public ManualPatternConditionProvider(AnalyzeItemsMode analyzeItemsMode,
+      Supplier<IssueGroup> issueGroupSupplier) {
+    super(analyzeItemsMode);
+    this.issueGroupSupplier = issueGroupSupplier;
+  }
+
+  @Override
+  protected ConvertibleCondition provideCondition() {
+
+    return new CompositeFilterCondition(Lists.newArrayList(FilterCondition.builder()
+            .withCondition(Condition.NOT_EQUALS)
+            .withSearchCriteria(CRITERIA_ISSUE_GROUP_ID)
+            .withValue(String.valueOf(issueGroupSupplier.get().getId()))
+            .build(),
+        FilterCondition.builder().eq(CRITERIA_ISSUE_AUTO_ANALYZED, Boolean.FALSE.toString())
+            .build()), Operator.OR);
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/condition/impl/ToInvestigatePatternConditionProvider.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/condition/impl/ToInvestigatePatternConditionProvider.java
index 338932859e..a01a5222b1 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/condition/impl/ToInvestigatePatternConditionProvider.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/condition/impl/ToInvestigatePatternConditionProvider.java
@@ -16,37 +16,37 @@
 
 package com.epam.ta.reportportal.core.analyzer.pattern.selector.condition.impl;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_ISSUE_GROUP_ID;
+
 import com.epam.ta.reportportal.commons.querygen.CompositeFilterCondition;
 import com.epam.ta.reportportal.commons.querygen.ConvertibleCondition;
 import com.epam.ta.reportportal.commons.querygen.FilterCondition;
 import com.epam.ta.reportportal.core.analyzer.auto.strategy.analyze.AnalyzeItemsMode;
 import com.epam.ta.reportportal.entity.item.issue.IssueGroup;
 import com.google.common.collect.Lists;
-import org.jooq.Operator;
-
 import java.util.function.Supplier;
-
-import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_ISSUE_GROUP_ID;
+import org.jooq.Operator;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public class ToInvestigatePatternConditionProvider extends AbstractPatternConditionProvider {
 
-	//TODO ADD OPTIONAL<ISSUEGROUP>
-	private final Supplier<IssueGroup> issueGroupSupplier;
+  //TODO ADD OPTIONAL<ISSUEGROUP>
+  private final Supplier<IssueGroup> issueGroupSupplier;
 
-	public ToInvestigatePatternConditionProvider(AnalyzeItemsMode analyzeItemsMode, Supplier<IssueGroup> issueGroupSupplier) {
-		super(analyzeItemsMode);
-		this.issueGroupSupplier = issueGroupSupplier;
-	}
+  public ToInvestigatePatternConditionProvider(AnalyzeItemsMode analyzeItemsMode,
+      Supplier<IssueGroup> issueGroupSupplier) {
+    super(analyzeItemsMode);
+    this.issueGroupSupplier = issueGroupSupplier;
+  }
 
-	@Override
-	protected ConvertibleCondition provideCondition() {
-		return new CompositeFilterCondition(Lists.newArrayList(FilterCondition.builder()
-				.eq(CRITERIA_ISSUE_GROUP_ID, String.valueOf(issueGroupSupplier.get().getId()))
-				.build()), Operator.OR);
+  @Override
+  protected ConvertibleCondition provideCondition() {
+    return new CompositeFilterCondition(Lists.newArrayList(FilterCondition.builder()
+        .eq(CRITERIA_ISSUE_GROUP_ID, String.valueOf(issueGroupSupplier.get().getId()))
+        .build()), Operator.OR);
 
-	}
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/impl/AbstractPatternAnalysisSelector.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/impl/AbstractPatternAnalysisSelector.java
index 941c153794..3bedcb1756 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/impl/AbstractPatternAnalysisSelector.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/impl/AbstractPatternAnalysisSelector.java
@@ -1,43 +1,50 @@
 package com.epam.ta.reportportal.core.analyzer.pattern.selector.impl;
 
 import com.epam.ta.reportportal.core.analyzer.pattern.selector.PatternAnalysisSelector;
+import com.epam.ta.reportportal.core.log.LogService;
 import com.epam.ta.reportportal.dao.TestItemRepository;
 import com.google.common.collect.Sets;
-import org.apache.commons.collections4.CollectionUtils;
-
 import java.util.Collection;
 import java.util.List;
 import java.util.Set;
+import org.apache.commons.collections4.CollectionUtils;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public abstract class AbstractPatternAnalysisSelector implements PatternAnalysisSelector {
 
-	protected final TestItemRepository testItemRepository;
+  protected final TestItemRepository testItemRepository;
+  protected final LogService logService;
+
+  public AbstractPatternAnalysisSelector(TestItemRepository testItemRepository,
+      LogService logService) {
+    this.testItemRepository = testItemRepository;
+    this.logService = logService;
+  }
 
-	public AbstractPatternAnalysisSelector(TestItemRepository testItemRepository) {
-		this.testItemRepository = testItemRepository;
-	}
+  protected abstract List<Long> getItemsWithMatches(String pattern, Set<Long> itemIds);
 
-	protected abstract List<Long> getItemsWithMatches(String pattern, Set<Long> itemIds);
-	protected abstract List<Long> getItemsWithNestedStepsMatches(Long launchId, String pattern, List<Long> itemsWithNestedSteps);
+  protected abstract List<Long> getItemsWithNestedStepsMatches(Long launchId, String pattern,
+      List<Long> itemsWithNestedSteps);
 
-	@Override
-	public List<Long> selectItemsByPattern(Long launchId, Collection<Long> itemIds, String pattern) {
-		final Set<Long> sourceIds = Sets.newHashSet(itemIds);
-		final List<Long> itemsWithMatchedLogs = getItemsWithMatches(pattern, sourceIds);
+  @Override
+  public List<Long> selectItemsByPattern(Long launchId, Collection<Long> itemIds, String pattern) {
+    final Set<Long> sourceIds = Sets.newHashSet(itemIds);
+    final List<Long> itemsWithMatchedLogs = getItemsWithMatches(pattern, sourceIds);
 
-		sourceIds.removeAll(itemsWithMatchedLogs);
+    itemsWithMatchedLogs.forEach(sourceIds::remove);
 
-		if (CollectionUtils.isNotEmpty(sourceIds)) {
-			final List<Long> itemsWithNestedSteps = testItemRepository.selectIdsByHasDescendants(sourceIds);
-			if (CollectionUtils.isNotEmpty(itemsWithNestedSteps)) {
-				final List<Long> nestedStepsMatches = getItemsWithNestedStepsMatches(launchId, pattern, itemsWithNestedSteps);
-				itemsWithMatchedLogs.addAll(nestedStepsMatches);
-			}
-		}
+    if (CollectionUtils.isNotEmpty(sourceIds)) {
+      final List<Long> itemsWithNestedSteps = testItemRepository.selectIdsByHasDescendants(
+          sourceIds);
+      if (CollectionUtils.isNotEmpty(itemsWithNestedSteps)) {
+        final List<Long> nestedStepsMatches = getItemsWithNestedStepsMatches(launchId, pattern,
+            itemsWithNestedSteps);
+        itemsWithMatchedLogs.addAll(nestedStepsMatches);
+      }
+    }
 
-		return itemsWithMatchedLogs;
-	}
+    return itemsWithMatchedLogs;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/impl/RegexPatternAnalysisSelector.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/impl/RegexPatternAnalysisSelector.java
index de2d1e0ef8..e8df7b1e5e 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/impl/RegexPatternAnalysisSelector.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/impl/RegexPatternAnalysisSelector.java
@@ -16,13 +16,13 @@
 
 package com.epam.ta.reportportal.core.analyzer.pattern.selector.impl;
 
+import com.epam.ta.reportportal.core.log.LogService;
 import com.epam.ta.reportportal.dao.TestItemRepository;
 import com.epam.ta.reportportal.entity.enums.LogLevel;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
 import java.util.List;
 import java.util.Set;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -30,22 +30,24 @@
 @Service
 public class RegexPatternAnalysisSelector extends AbstractPatternAnalysisSelector {
 
-	@Autowired
-	public RegexPatternAnalysisSelector(TestItemRepository testItemRepository) {
-		super(testItemRepository);
-	}
+  @Autowired
+  public RegexPatternAnalysisSelector(TestItemRepository testItemRepository,
+      LogService logService) {
+    super(testItemRepository, logService);
+  }
 
-	@Override
-	protected List<Long> getItemsWithMatches(String pattern, Set<Long> itemIds) {
-		return testItemRepository.selectIdsByRegexLogMessage(itemIds, LogLevel.ERROR_INT, pattern);
-	}
+  @Override
+  protected List<Long> getItemsWithMatches(String pattern, Set<Long> itemIds) {
+    return logService.selectTestItemIdsByRegexLogMessage(itemIds, LogLevel.ERROR_INT, pattern);
+  }
 
-	@Override
-	protected List<Long> getItemsWithNestedStepsMatches(Long launchId, String pattern, List<Long> itemsWithNestedSteps) {
-		return testItemRepository.selectIdsUnderByRegexLogMessage(launchId,
-				itemsWithNestedSteps,
-				LogLevel.ERROR_INT,
-				pattern
-		);
-	}
+  @Override
+  protected List<Long> getItemsWithNestedStepsMatches(Long launchId, String pattern,
+      List<Long> itemsWithNestedSteps) {
+    return logService.selectTestItemIdsUnderByRegexLogMessage(launchId,
+        itemsWithNestedSteps,
+        LogLevel.ERROR_INT,
+        pattern
+    );
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/impl/StringPartPatternAnalysisSelector.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/impl/StringPartPatternAnalysisSelector.java
index 89cee55275..88067b6c1e 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/impl/StringPartPatternAnalysisSelector.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/selector/impl/StringPartPatternAnalysisSelector.java
@@ -16,13 +16,13 @@
 
 package com.epam.ta.reportportal.core.analyzer.pattern.selector.impl;
 
+import com.epam.ta.reportportal.core.log.LogService;
 import com.epam.ta.reportportal.dao.TestItemRepository;
 import com.epam.ta.reportportal.entity.enums.LogLevel;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
 import java.util.List;
 import java.util.Set;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -30,25 +30,27 @@
 @Service
 public class StringPartPatternAnalysisSelector extends AbstractPatternAnalysisSelector {
 
-	@Autowired
-	public StringPartPatternAnalysisSelector(TestItemRepository testItemRepository) {
-		super(testItemRepository);
-	}
+  @Autowired
+  public StringPartPatternAnalysisSelector(TestItemRepository testItemRepository,
+      LogService logService) {
+    super(testItemRepository, logService);
+  }
 
-	@Override
-	protected List<Long> getItemsWithMatches(String pattern, Set<Long> itemIds) {
-		return testItemRepository.selectIdsByStringLogMessage(itemIds,
-				LogLevel.ERROR_INT,
-				pattern
-		);
-	}
+  @Override
+  protected List<Long> getItemsWithMatches(String pattern, Set<Long> itemIds) {
+    return logService.selectTestItemIdsByStringLogMessage(itemIds,
+        LogLevel.ERROR_INT,
+        pattern
+    );
+  }
 
-	@Override
-	protected List<Long> getItemsWithNestedStepsMatches(Long launchId, String pattern, List<Long> itemsWithNestedSteps) {
-		return testItemRepository.selectIdsUnderByStringLogMessage(launchId,
-				itemsWithNestedSteps,
-				LogLevel.ERROR_INT,
-				pattern
-		);
-	}
+  @Override
+  protected List<Long> getItemsWithNestedStepsMatches(Long launchId, String pattern,
+      List<Long> itemsWithNestedSteps) {
+    return logService.selectTestItemIdsUnderByStringLogMessage(launchId,
+        itemsWithNestedSteps,
+        LogLevel.ERROR_INT,
+        pattern
+    );
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/CreatePatternTemplateHandler.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/service/CreatePatternTemplateHandler.java
similarity index 58%
rename from src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/CreatePatternTemplateHandler.java
rename to src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/service/CreatePatternTemplateHandler.java
index 488e273e89..340e80c187 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/CreatePatternTemplateHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/service/CreatePatternTemplateHandler.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2019 EPAM Systems
+ * Copyright 2023 EPAM Systems
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.epam.ta.reportportal.core.analyzer.pattern;
+package com.epam.ta.reportportal.core.analyzer.pattern.service;
 
 import com.epam.ta.reportportal.entity.pattern.PatternTemplate;
 import com.epam.ta.reportportal.ws.model.project.config.pattern.CreatePatternTemplateRQ;
@@ -24,12 +24,14 @@
  */
 public interface CreatePatternTemplateHandler {
 
-	/**
-	 * Create {@link com.epam.ta.reportportal.entity.pattern.PatternTemplate} entity for specified {@link com.epam.ta.reportportal.entity.project.Project}
-	 *
-	 * @param projectId               {@link com.epam.ta.reportportal.entity.pattern.PatternTemplate#projectId}
-	 * @param createPatternTemplateRQ {@link CreatePatternTemplateRQ}
-	 * @return {@link java.util.regex.Pattern}
-	 */
-	PatternTemplate createPatternTemplate(Long projectId, CreatePatternTemplateRQ createPatternTemplateRQ);
+  /**
+   * Create {@link com.epam.ta.reportportal.entity.pattern.PatternTemplate} entity for specified
+   * {@link com.epam.ta.reportportal.entity.project.Project}
+   *
+   * @param projectId               {@link com.epam.ta.reportportal.entity.pattern.PatternTemplate}
+   * @param createPatternTemplateRQ {@link CreatePatternTemplateRQ}
+   * @return {@link java.util.regex.Pattern}
+   */
+  PatternTemplate createPatternTemplate(Long projectId,
+      CreatePatternTemplateRQ createPatternTemplateRQ);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/service/LaunchPatternAnalyzer.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/service/LaunchPatternAnalyzer.java
new file mode 100644
index 0000000000..a0751a0d8d
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/service/LaunchPatternAnalyzer.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2023 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.core.analyzer.pattern.service;
+
+import com.epam.ta.reportportal.core.analyzer.auto.strategy.analyze.AnalyzeItemsMode;
+import com.epam.ta.reportportal.entity.enums.TestItemIssueGroup;
+import com.epam.ta.reportportal.entity.launch.Launch;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
+ */
+public interface LaunchPatternAnalyzer {
+
+  /**
+   * Analyze by {@link com.epam.ta.reportportal.entity.pattern.PatternTemplate} all
+   * {@link com.epam.ta.reportportal.entity.log.Log} of
+   * {@link com.epam.ta.reportportal.entity.item.TestItem} with
+   * {@link TestItemIssueGroup#TO_INVESTIGATE} for
+   * {@link com.epam.ta.reportportal.entity.launch.Launch} with provided ID. Every matched
+   * {@link com.epam.ta.reportportal.entity.pattern.PatternTemplate} will be attached to the
+   * {@link com.epam.ta.reportportal.entity.item.TestItem} using
+   * {@link com.epam.ta.reportportal.entity.pattern.PatternTemplateTestItem} relation
+   *
+   * @param launch       {@link com.epam.ta.reportportal.entity.launch.Launch}, which
+   *                     {@link com.epam.ta.reportportal.entity.item.TestItem} should be analyzed
+   * @param analyzeModes {@link AnalyzeItemsMode} to modify
+   *                     {@link com.epam.ta.reportportal.entity.item.TestItem} query conditions
+   */
+  void analyzeLaunch(Launch launch, Set<AnalyzeItemsMode> analyzeModes);
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/impl/CreatePatternTemplateHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/service/impl/CreatePatternTemplateHandlerImpl.java
similarity index 54%
rename from src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/impl/CreatePatternTemplateHandlerImpl.java
rename to src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/service/impl/CreatePatternTemplateHandlerImpl.java
index e95f0dc070..ccac8df33b 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/impl/CreatePatternTemplateHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/service/impl/CreatePatternTemplateHandlerImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2019 EPAM Systems
+ * Copyright 2023 EPAM Systems
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,10 +13,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.epam.ta.reportportal.core.analyzer.pattern.impl;
+package com.epam.ta.reportportal.core.analyzer.pattern.service.impl;
+
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
 
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
-import com.epam.ta.reportportal.core.analyzer.pattern.CreatePatternTemplateHandler;
+import com.epam.ta.reportportal.core.analyzer.pattern.service.CreatePatternTemplateHandler;
 import com.epam.ta.reportportal.dao.PatternTemplateRepository;
 import com.epam.ta.reportportal.entity.pattern.PatternTemplate;
 import com.epam.ta.reportportal.ws.converter.builders.PatternTemplateBuilder;
@@ -25,29 +27,31 @@
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
  */
 public class CreatePatternTemplateHandlerImpl implements CreatePatternTemplateHandler {
 
-	protected final PatternTemplateRepository patternTemplateRepository;
+  protected final PatternTemplateRepository patternTemplateRepository;
 
-	@Autowired
-	public CreatePatternTemplateHandlerImpl(PatternTemplateRepository patternTemplateRepository) {
-		this.patternTemplateRepository = patternTemplateRepository;
-	}
+  @Autowired
+  public CreatePatternTemplateHandlerImpl(PatternTemplateRepository patternTemplateRepository) {
+    this.patternTemplateRepository = patternTemplateRepository;
+  }
 
-	@Override
-	public PatternTemplate createPatternTemplate(Long projectId, CreatePatternTemplateRQ createPatternTemplateRQ) {
-		final String name = StringUtils.trim(createPatternTemplateRQ.getName());
-		BusinessRule.expect(patternTemplateRepository.existsByProjectIdAndNameIgnoreCase(projectId, name), equalTo(false))
-				.verify(ErrorType.RESOURCE_ALREADY_EXISTS, name);
-		PatternTemplate patternTemplate = new PatternTemplateBuilder().withCreateRequest(createPatternTemplateRQ)
-				.withName(name)
-				.withProjectId(projectId)
-				.get();
-		return patternTemplateRepository.save(patternTemplate);
-	}
+  @Override
+  public PatternTemplate createPatternTemplate(Long projectId,
+      CreatePatternTemplateRQ createPatternTemplateRQ) {
+    final String name = StringUtils.trim(createPatternTemplateRQ.getName());
+    BusinessRule.expect(
+            patternTemplateRepository.existsByProjectIdAndNameIgnoreCase(projectId, name),
+            equalTo(false))
+        .verify(ErrorType.RESOURCE_ALREADY_EXISTS, name);
+    PatternTemplate patternTemplate = new PatternTemplateBuilder().withCreateRequest(
+            createPatternTemplateRQ)
+        .withName(name)
+        .withProjectId(projectId)
+        .get();
+    return patternTemplateRepository.save(patternTemplate);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/impl/CreateRegexPatternTemplateHandler.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/service/impl/CreateRegexPatternTemplateHandler.java
similarity index 61%
rename from src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/impl/CreateRegexPatternTemplateHandler.java
rename to src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/service/impl/CreateRegexPatternTemplateHandler.java
index 938bf3a3f8..6474044932 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/impl/CreateRegexPatternTemplateHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/service/impl/CreateRegexPatternTemplateHandler.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2019 EPAM Systems
+ * Copyright 2023 EPAM Systems
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.epam.ta.reportportal.core.analyzer.pattern.impl;
+package com.epam.ta.reportportal.core.analyzer.pattern.service.impl;
 
 import com.epam.ta.reportportal.commons.validation.Suppliers;
 import com.epam.ta.reportportal.dao.PatternTemplateRepository;
@@ -22,31 +22,32 @@
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.epam.ta.reportportal.ws.model.project.config.pattern.CreatePatternTemplateRQ;
+import javax.persistence.PersistenceException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import javax.persistence.PersistenceException;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class CreateRegexPatternTemplateHandler extends CreatePatternTemplateHandlerImpl {
 
-	@Autowired
-	public CreateRegexPatternTemplateHandler(PatternTemplateRepository patternTemplateRepository) {
-		super(patternTemplateRepository);
-	}
+  @Autowired
+  public CreateRegexPatternTemplateHandler(PatternTemplateRepository patternTemplateRepository) {
+    super(patternTemplateRepository);
+  }
 
-	@Override
-	public PatternTemplate createPatternTemplate(Long projectId, CreatePatternTemplateRQ createPatternTemplateRQ) {
-		try {
-			patternTemplateRepository.validateRegex(createPatternTemplateRQ.getValue());
-		} catch (PersistenceException ex) {
-			throw new ReportPortalException(ErrorType.BAD_REQUEST_ERROR,
-					Suppliers.formattedSupplier("Provided regex pattern - '{}' is invalid", createPatternTemplateRQ.getValue()).get()
-			);
-		}
-		return super.createPatternTemplate(projectId, createPatternTemplateRQ);
-	}
+  @Override
+  public PatternTemplate createPatternTemplate(Long projectId,
+      CreatePatternTemplateRQ createPatternTemplateRQ) {
+    try {
+      patternTemplateRepository.validateRegex(createPatternTemplateRQ.getValue());
+    } catch (PersistenceException ex) {
+      throw new ReportPortalException(ErrorType.BAD_REQUEST_ERROR,
+          Suppliers.formattedSupplier("Provided regex pattern - '{}' is invalid",
+              createPatternTemplateRQ.getValue()).get()
+      );
+    }
+    return super.createPatternTemplate(projectId, createPatternTemplateRQ);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/service/impl/LaunchPatternAnalyzerImpl.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/service/impl/LaunchPatternAnalyzerImpl.java
new file mode 100644
index 0000000000..c4bb9a1643
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/service/impl/LaunchPatternAnalyzerImpl.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2023 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.core.analyzer.pattern.service.impl;
+
+import static com.epam.ta.reportportal.commons.Predicates.not;
+import static com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerStatusCache.PATTERN_ANALYZER_KEY;
+
+import com.epam.ta.reportportal.commons.querygen.ConvertibleCondition;
+import com.epam.ta.reportportal.commons.querygen.Filter;
+import com.epam.ta.reportportal.commons.validation.BusinessRule;
+import com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerStatusCache;
+import com.epam.ta.reportportal.core.analyzer.auto.strategy.analyze.AnalyzeItemsMode;
+import com.epam.ta.reportportal.core.analyzer.pattern.handler.ItemsPatternsAnalyzer;
+import com.epam.ta.reportportal.core.analyzer.pattern.selector.condition.PatternConditionProviderChain;
+import com.epam.ta.reportportal.core.analyzer.pattern.service.LaunchPatternAnalyzer;
+import com.epam.ta.reportportal.dao.TestItemRepository;
+import com.epam.ta.reportportal.entity.item.TestItem;
+import com.epam.ta.reportportal.entity.launch.Launch;
+import com.epam.ta.reportportal.exception.ReportPortalException;
+import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import org.apache.commons.collections4.CollectionUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
+ */
+@Service
+public class LaunchPatternAnalyzerImpl implements LaunchPatternAnalyzer {
+
+  public static final Logger LOGGER = LoggerFactory.getLogger(LaunchPatternAnalyzerImpl.class);
+
+  private final Integer batchSize;
+
+  private final TestItemRepository testItemRepository;
+  private final PatternConditionProviderChain patternConditionProviderChain;
+
+  private final AnalyzerStatusCache analyzerStatusCache;
+
+  private final ItemsPatternsAnalyzer itemsPatternsAnalyzer;
+
+  @Autowired
+  public LaunchPatternAnalyzerImpl(
+      @Value("${rp.environment.variable.pattern-analysis.batch-size}") Integer batchSize,
+      TestItemRepository testItemRepository,
+      PatternConditionProviderChain patternConditionProviderChain,
+      AnalyzerStatusCache analyzerStatusCache, ItemsPatternsAnalyzer itemsPatternsAnalyzer) {
+    this.batchSize = batchSize;
+    this.testItemRepository = testItemRepository;
+    this.patternConditionProviderChain = patternConditionProviderChain;
+    this.analyzerStatusCache = analyzerStatusCache;
+    this.itemsPatternsAnalyzer = itemsPatternsAnalyzer;
+  }
+
+  @Override
+  public void analyzeLaunch(Launch launch, Set<AnalyzeItemsMode> analyzeModes) {
+    BusinessRule.expect(analyzerStatusCache.getStartedAnalyzers(launch.getId()),
+            not(started -> started.contains(PATTERN_ANALYZER_KEY)))
+        .verify(ErrorType.PATTERN_ANALYSIS_ERROR, "Pattern analysis is still in progress.");
+    analyzerStatusCache.analyzeStarted(PATTERN_ANALYZER_KEY, launch.getId(), launch.getProjectId());
+    try {
+      analyze(launch, buildItemsCondition(analyzeModes));
+    } catch (Exception e) {
+      LOGGER.error(e.getMessage(), e);
+    } finally {
+      analyzerStatusCache.analyzeFinished(PATTERN_ANALYZER_KEY, launch.getId());
+    }
+  }
+
+  private void analyze(Launch launch, ConvertibleCondition itemCondition) {
+    final Filter filter = createItemFilter(itemCondition);
+    int offset = 0;
+    List<Long> itemIds = testItemRepository.selectIdsByFilter(launch.getId(), filter, batchSize,
+        offset);
+    while (CollectionUtils.isNotEmpty(itemIds)) {
+      itemsPatternsAnalyzer.analyze(launch.getProjectId(), launch.getId(), itemIds);
+      offset += itemIds.size();
+      itemIds = testItemRepository.selectIdsByFilter(launch.getId(), filter, batchSize, offset);
+    }
+    notifyAnalysisFinished(launch.getProjectId(), launch.getId());
+  }
+
+  private void notifyAnalysisFinished(long projectId, long launchId) {
+    itemsPatternsAnalyzer.analyze(projectId, launchId, Collections.emptyList());
+  }
+
+  private ConvertibleCondition buildItemsCondition(Set<AnalyzeItemsMode> analyzeModes) {
+    return patternConditionProviderChain.provideCondition(analyzeModes)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.PATTERN_ANALYSIS_ERROR,
+            "Unable to resolve item search condition"));
+  }
+
+  private Filter createItemFilter(ConvertibleCondition commonItemCondition) {
+    return Filter.builder()
+        .withTarget(TestItem.class)
+        .withCondition(commonItemCondition)
+        .build();
+  }
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/strategy/AbstractLaunchAnalysisStrategy.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/strategy/AbstractLaunchAnalysisStrategy.java
index d7ea28bfc6..4a58a81262 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/strategy/AbstractLaunchAnalysisStrategy.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/strategy/AbstractLaunchAnalysisStrategy.java
@@ -16,6 +16,11 @@
 
 package com.epam.ta.reportportal.core.analyzer.strategy;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.ws.model.ErrorType.FORBIDDEN_OPERATION;
+import static com.epam.ta.reportportal.ws.model.ErrorType.INCORRECT_REQUEST;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.validation.Suppliers;
 import com.epam.ta.reportportal.dao.LaunchRepository;
@@ -23,35 +28,33 @@
 import com.epam.ta.reportportal.entity.enums.LaunchModeEnum;
 import com.epam.ta.reportportal.entity.launch.Launch;
 
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.ws.model.ErrorType.FORBIDDEN_OPERATION;
-import static com.epam.ta.reportportal.ws.model.ErrorType.INCORRECT_REQUEST;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public abstract class AbstractLaunchAnalysisStrategy implements LaunchAnalysisStrategy {
 
-	protected final ProjectRepository projectRepository;
-	protected final LaunchRepository launchRepository;
+  protected final ProjectRepository projectRepository;
+  protected final LaunchRepository launchRepository;
 
-	protected AbstractLaunchAnalysisStrategy(ProjectRepository projectRepository, LaunchRepository launchRepository) {
-		this.projectRepository = projectRepository;
-		this.launchRepository = launchRepository;
-	}
+  protected AbstractLaunchAnalysisStrategy(ProjectRepository projectRepository,
+      LaunchRepository launchRepository) {
+    this.projectRepository = projectRepository;
+    this.launchRepository = launchRepository;
+  }
 
-	protected void validateLaunch(Launch launch, ReportPortalUser.ProjectDetails projectDetails) {
+  protected void validateLaunch(Launch launch, ReportPortalUser.ProjectDetails projectDetails) {
 
-		expect(launch.getProjectId(), equalTo(projectDetails.getProjectId())).verify(FORBIDDEN_OPERATION,
-				Suppliers.formattedSupplier("Launch with ID '{}' is not under '{}' project.",
-						launch.getId(),
-						projectDetails.getProjectName()
-				)
-		);
+    expect(launch.getProjectId(), equalTo(projectDetails.getProjectId())).verify(
+        FORBIDDEN_OPERATION,
+        Suppliers.formattedSupplier("Launch with ID '{}' is not under '{}' project.",
+            launch.getId(),
+            projectDetails.getProjectName()
+        )
+    );
 
-		/* Do not process debug launches */
-		expect(launch.getMode(), equalTo(LaunchModeEnum.DEFAULT)).verify(INCORRECT_REQUEST, "Cannot analyze launches in debug mode.");
+    /* Do not process debug launches */
+    expect(launch.getMode(), equalTo(LaunchModeEnum.DEFAULT)).verify(INCORRECT_REQUEST,
+        "Cannot analyze launches in debug mode.");
 
-	}
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/strategy/LaunchAnalysisStrategy.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/strategy/LaunchAnalysisStrategy.java
index 4a2b54ce4a..38dec9a63a 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/strategy/LaunchAnalysisStrategy.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/strategy/LaunchAnalysisStrategy.java
@@ -24,5 +24,6 @@
  */
 public interface LaunchAnalysisStrategy {
 
-	void analyze(AnalyzeLaunchRQ analyzeLaunchRequest, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user);
+  void analyze(AnalyzeLaunchRQ analyzeLaunchRequest, ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/strategy/LaunchAutoAnalysisStrategy.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/strategy/LaunchAutoAnalysisStrategy.java
index 87bce46178..55213d6bbc 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/strategy/LaunchAutoAnalysisStrategy.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/strategy/LaunchAutoAnalysisStrategy.java
@@ -16,10 +16,15 @@
 
 package com.epam.ta.reportportal.core.analyzer.strategy;
 
+import static com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerUtils.getAnalyzerConfig;
+import static com.epam.ta.reportportal.ws.model.ErrorType.BAD_REQUEST_ERROR;
+import static com.epam.ta.reportportal.ws.model.ErrorType.LAUNCH_NOT_FOUND;
+import static com.epam.ta.reportportal.ws.model.ErrorType.PROJECT_NOT_FOUND;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
-import com.epam.ta.reportportal.core.analyzer.config.StartLaunchAutoAnalysisConfig;
 import com.epam.ta.reportportal.core.analyzer.auto.starter.LaunchAutoAnalysisStarter;
 import com.epam.ta.reportportal.core.analyzer.auto.strategy.analyze.AnalyzeItemsMode;
+import com.epam.ta.reportportal.core.analyzer.config.StartLaunchAutoAnalysisConfig;
 import com.epam.ta.reportportal.dao.LaunchRepository;
 import com.epam.ta.reportportal.dao.ProjectRepository;
 import com.epam.ta.reportportal.entity.AnalyzeMode;
@@ -28,15 +33,11 @@
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.launch.AnalyzeLaunchRQ;
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
 import java.util.LinkedHashSet;
 import java.util.Set;
 import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerUtils.getAnalyzerConfig;
-import static com.epam.ta.reportportal.ws.model.ErrorType.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -44,50 +45,54 @@
 @Service
 public class LaunchAutoAnalysisStrategy extends AbstractLaunchAnalysisStrategy {
 
-	private final LaunchAutoAnalysisStarter manualAnalysisStarter;
-
-	@Autowired
-	public LaunchAutoAnalysisStrategy(ProjectRepository projectRepository, LaunchRepository launchRepository,
-			LaunchAutoAnalysisStarter manualAnalysisStarter) {
-		super(projectRepository, launchRepository);
-		this.manualAnalysisStarter = manualAnalysisStarter;
-	}
-
-	public void analyze(AnalyzeLaunchRQ analyzeRQ, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user) {
-
-		final AnalyzeMode analyzeMode = AnalyzeMode.fromString(analyzeRQ.getAnalyzerHistoryMode())
-				.orElseThrow(() -> new ReportPortalException(BAD_REQUEST_ERROR, analyzeRQ.getAnalyzerHistoryMode()));
-		final Set<AnalyzeItemsMode> analyzeItemsModes = getAnalyzeItemsModes(analyzeRQ);
-
-		if (analyzeItemsModes.isEmpty()) {
-			return;
-		}
-
-		Launch launch = launchRepository.findById(analyzeRQ.getLaunchId())
-				.orElseThrow(() -> new ReportPortalException(LAUNCH_NOT_FOUND, analyzeRQ.getLaunchId()));
-		validateLaunch(launch, projectDetails);
-
-		Project project = projectRepository.findById(projectDetails.getProjectId())
-				.orElseThrow(() -> new ReportPortalException(PROJECT_NOT_FOUND, projectDetails.getProjectId()));
-
-		AnalyzerConfig analyzerConfig = getAnalyzerConfig(project);
-		analyzerConfig.setAnalyzerMode(analyzeMode.getValue());
-
-		final StartLaunchAutoAnalysisConfig autoAnalysisConfig = StartLaunchAutoAnalysisConfig.of(
-				launch.getId(),
-				analyzerConfig,
-				analyzeItemsModes,
-				user
-		);
-
-		manualAnalysisStarter.start(autoAnalysisConfig);
-	}
-
-	private LinkedHashSet<AnalyzeItemsMode> getAnalyzeItemsModes(AnalyzeLaunchRQ analyzeRQ) {
-		return analyzeRQ.getAnalyzeItemsModes()
-				.stream()
-				.map(AnalyzeItemsMode::fromString)
-				.collect(Collectors.toCollection(LinkedHashSet::new));
-	}
+  private final LaunchAutoAnalysisStarter manualAnalysisStarter;
+
+  @Autowired
+  public LaunchAutoAnalysisStrategy(ProjectRepository projectRepository,
+      LaunchRepository launchRepository,
+      LaunchAutoAnalysisStarter manualAnalysisStarter) {
+    super(projectRepository, launchRepository);
+    this.manualAnalysisStarter = manualAnalysisStarter;
+  }
+
+  public void analyze(AnalyzeLaunchRQ analyzeRQ, ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user) {
+
+    final AnalyzeMode analyzeMode = AnalyzeMode.fromString(analyzeRQ.getAnalyzerHistoryMode())
+        .orElseThrow(
+            () -> new ReportPortalException(BAD_REQUEST_ERROR, analyzeRQ.getAnalyzerHistoryMode()));
+    final Set<AnalyzeItemsMode> analyzeItemsModes = getAnalyzeItemsModes(analyzeRQ);
+
+    if (analyzeItemsModes.isEmpty()) {
+      return;
+    }
+
+    Launch launch = launchRepository.findById(analyzeRQ.getLaunchId())
+        .orElseThrow(() -> new ReportPortalException(LAUNCH_NOT_FOUND, analyzeRQ.getLaunchId()));
+    validateLaunch(launch, projectDetails);
+
+    Project project = projectRepository.findById(projectDetails.getProjectId())
+        .orElseThrow(
+            () -> new ReportPortalException(PROJECT_NOT_FOUND, projectDetails.getProjectId()));
+
+    AnalyzerConfig analyzerConfig = getAnalyzerConfig(project);
+    analyzerConfig.setAnalyzerMode(analyzeMode.getValue());
+
+    final StartLaunchAutoAnalysisConfig autoAnalysisConfig = StartLaunchAutoAnalysisConfig.of(
+        launch.getId(),
+        analyzerConfig,
+        analyzeItemsModes,
+        user
+    );
+
+    manualAnalysisStarter.start(autoAnalysisConfig);
+  }
+
+  private LinkedHashSet<AnalyzeItemsMode> getAnalyzeItemsModes(AnalyzeLaunchRQ analyzeRQ) {
+    return analyzeRQ.getAnalyzeItemsModes()
+        .stream()
+        .map(AnalyzeItemsMode::fromString)
+        .collect(Collectors.toCollection(LinkedHashSet::new));
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/strategy/LaunchPatternAnalysisStrategy.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/strategy/LaunchPatternAnalysisStrategy.java
index e65263b392..91ecb49023 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/strategy/LaunchPatternAnalysisStrategy.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/strategy/LaunchPatternAnalysisStrategy.java
@@ -16,54 +16,56 @@
 
 package com.epam.ta.reportportal.core.analyzer.strategy;
 
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.ws.model.ErrorType.LAUNCH_NOT_FOUND;
+import static java.util.stream.Collectors.toSet;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.analyzer.auto.strategy.analyze.AnalyzeItemsMode;
-import com.epam.ta.reportportal.core.analyzer.pattern.PatternAnalyzer;
+import com.epam.ta.reportportal.core.analyzer.pattern.service.LaunchPatternAnalyzer;
 import com.epam.ta.reportportal.dao.LaunchRepository;
 import com.epam.ta.reportportal.dao.ProjectRepository;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.epam.ta.reportportal.ws.model.launch.AnalyzeLaunchRQ;
+import java.util.Set;
 import org.apache.commons.collections.CollectionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.Set;
-
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.ws.model.ErrorType.LAUNCH_NOT_FOUND;
-import static java.util.stream.Collectors.toSet;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class LaunchPatternAnalysisStrategy extends AbstractLaunchAnalysisStrategy {
 
-	private final PatternAnalyzer patternAnalyzer;
+  private final LaunchPatternAnalyzer launchPatternAnalyzer;
 
-	@Autowired
-	public LaunchPatternAnalysisStrategy(ProjectRepository projectRepository, LaunchRepository launchRepository,
-			PatternAnalyzer patternAnalyzer) {
-		super(projectRepository, launchRepository);
-		this.patternAnalyzer = patternAnalyzer;
-	}
+  @Autowired
+  public LaunchPatternAnalysisStrategy(ProjectRepository projectRepository,
+      LaunchRepository launchRepository,
+      LaunchPatternAnalyzer launchPatternAnalyzer) {
+    super(projectRepository, launchRepository);
+    this.launchPatternAnalyzer = launchPatternAnalyzer;
+  }
 
-	public void analyze(AnalyzeLaunchRQ analyzeRQ, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user) {
+  public void analyze(AnalyzeLaunchRQ analyzeRQ, ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user) {
 
-		Set<AnalyzeItemsMode> analyzeItemsModes = analyzeRQ.getAnalyzeItemsModes()
-				.stream()
-				.map(AnalyzeItemsMode::fromString)
-				.collect(toSet());
+    Set<AnalyzeItemsMode> analyzeItemsModes = analyzeRQ.getAnalyzeItemsModes()
+        .stream()
+        .map(AnalyzeItemsMode::fromString)
+        .collect(toSet());
 
-		expect(analyzeItemsModes, CollectionUtils::isNotEmpty).verify(ErrorType.PATTERN_ANALYSIS_ERROR, "No analyze item mode specified.");
+    expect(analyzeItemsModes, CollectionUtils::isNotEmpty).verify(ErrorType.PATTERN_ANALYSIS_ERROR,
+        "No analyze item mode specified.");
 
-		Launch launch = launchRepository.findById(analyzeRQ.getLaunchId())
-				.orElseThrow(() -> new ReportPortalException(LAUNCH_NOT_FOUND, analyzeRQ.getLaunchId()));
-		validateLaunch(launch, projectDetails);
+    Launch launch = launchRepository.findById(analyzeRQ.getLaunchId())
+        .orElseThrow(() -> new ReportPortalException(LAUNCH_NOT_FOUND, analyzeRQ.getLaunchId()));
+    validateLaunch(launch, projectDetails);
 
-		patternAnalyzer.analyzeTestItems(launch, analyzeItemsModes);
+    launchPatternAnalyzer.analyzeLaunch(launch, analyzeItemsModes);
 
-	}
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/annotation/Datastore.java b/src/main/java/com/epam/ta/reportportal/core/annotation/Datastore.java
index 6805bcae9a..f51801cfb3 100644
--- a/src/main/java/com/epam/ta/reportportal/core/annotation/Datastore.java
+++ b/src/main/java/com/epam/ta/reportportal/core/annotation/Datastore.java
@@ -16,15 +16,16 @@
 
 package com.epam.ta.reportportal.core.annotation;
 
-import javax.inject.Qualifier;
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
+import javax.inject.Qualifier;
 
 @Target({ElementType.FIELD, ElementType.METHOD,
-		ElementType.TYPE, ElementType.PARAMETER})
+    ElementType.TYPE, ElementType.PARAMETER})
 @Retention(RetentionPolicy.RUNTIME)
 @Qualifier
 public @interface Datastore {
+
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/annotation/Regular.java b/src/main/java/com/epam/ta/reportportal/core/annotation/Regular.java
index cbeb7e3810..c67a5fda38 100644
--- a/src/main/java/com/epam/ta/reportportal/core/annotation/Regular.java
+++ b/src/main/java/com/epam/ta/reportportal/core/annotation/Regular.java
@@ -16,15 +16,16 @@
 
 package com.epam.ta.reportportal.core.annotation;
 
-import javax.inject.Qualifier;
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
+import javax.inject.Qualifier;
 
 @Target({ElementType.FIELD, ElementType.METHOD,
-		ElementType.TYPE, ElementType.PARAMETER})
+    ElementType.TYPE, ElementType.PARAMETER})
 @Retention(RetentionPolicy.RUNTIME)
 @Qualifier
 public @interface Regular {
+
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/bts/handler/CreateTicketHandler.java b/src/main/java/com/epam/ta/reportportal/core/bts/handler/CreateTicketHandler.java
index e41470bb4d..04aae849fb 100644
--- a/src/main/java/com/epam/ta/reportportal/core/bts/handler/CreateTicketHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/bts/handler/CreateTicketHandler.java
@@ -28,15 +28,16 @@
 
 public interface CreateTicketHandler {
 
-	/**
-	 * Post ticket to external system.
-	 *
-	 * @param postTicketRQ   Request Data
-	 * @param integrationId  Integration id
-	 * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
-	 * @param user           User
-	 * @return Found Ticket
-	 */
-	Ticket createIssue(PostTicketRQ postTicketRQ, Long integrationId, ReportPortalUser.ProjectDetails projectDetails,
-			ReportPortalUser user);
+  /**
+   * Post ticket to external system.
+   *
+   * @param postTicketRQ   Request Data
+   * @param integrationId  Integration id
+   * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
+   * @param user           User
+   * @return Found Ticket
+   */
+  Ticket createIssue(PostTicketRQ postTicketRQ, Long integrationId,
+      ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user);
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/bts/handler/GetBugTrackingSystemHandler.java b/src/main/java/com/epam/ta/reportportal/core/bts/handler/GetBugTrackingSystemHandler.java
index edd11ced22..3221010040 100644
--- a/src/main/java/com/epam/ta/reportportal/core/bts/handler/GetBugTrackingSystemHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/bts/handler/GetBugTrackingSystemHandler.java
@@ -18,7 +18,6 @@
 
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.entity.integration.Integration;
-
 import java.util.Optional;
 
 /**
@@ -26,11 +25,13 @@
  */
 public interface GetBugTrackingSystemHandler {
 
-	Optional<Integration> getEnabledProjectIntegration(ReportPortalUser.ProjectDetails projectDetails, String url, String btsProject);
+  Optional<Integration> getEnabledProjectIntegration(ReportPortalUser.ProjectDetails projectDetails,
+      String url, String btsProject);
 
-	Optional<Integration> getEnabledProjectIntegration(ReportPortalUser.ProjectDetails projectDetails, Long integrationId);
+  Optional<Integration> getEnabledProjectIntegration(ReportPortalUser.ProjectDetails projectDetails,
+      Long integrationId);
 
-	Optional<Integration> getEnabledGlobalIntegration(String url, String btsProject);
+  Optional<Integration> getEnabledGlobalIntegration(String url, String btsProject);
 
-	Optional<Integration> getEnabledGlobalIntegration(Long integrationId);
+  Optional<Integration> getEnabledGlobalIntegration(Long integrationId);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/bts/handler/GetTicketHandler.java b/src/main/java/com/epam/ta/reportportal/core/bts/handler/GetTicketHandler.java
index 3c21fe5f2d..bec0596295 100644
--- a/src/main/java/com/epam/ta/reportportal/core/bts/handler/GetTicketHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/bts/handler/GetTicketHandler.java
@@ -19,7 +19,6 @@
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.ws.model.externalsystem.PostFormField;
 import com.epam.ta.reportportal.ws.model.externalsystem.Ticket;
-
 import java.util.List;
 
 /**
@@ -29,38 +28,41 @@
  */
 public interface GetTicketHandler {
 
-	/**
-	 * Get ticket from specified external system by id.<br>
-	 * <b>Note: resulting object returned from cache.</b>
-	 *
-	 * @param ticketId       Ticket ID
-	 * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
-	 * @param btsUrl         URL of the bug tracking system to get ticket from
-	 * @param btsProject     Project in the bug tracking system to get ticket from
-	 * @return Ticket
-	 */
-	Ticket getTicket(String ticketId, String btsUrl, String btsProject, ReportPortalUser.ProjectDetails projectDetails);
+  /**
+   * Get ticket from specified external system by id.<br>
+   * <b>Note: resulting object returned from cache.</b>
+   *
+   * @param ticketId       Ticket ID
+   * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
+   * @param btsUrl         URL of the bug tracking system to get ticket from
+   * @param btsProject     Project in the bug tracking system to get ticket from
+   * @return Ticket
+   */
+  Ticket getTicket(String ticketId, String btsUrl, String btsProject,
+      ReportPortalUser.ProjectDetails projectDetails);
 
-	/**
-	 * Get set of fields of external system to submit a ticket
-	 *
-	 * @param ticketType     Ticket Type
-	 * @param integrationId  Integration id
-	 * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
-	 * @return Found fields
-	 */
-	List<PostFormField> getSubmitTicketFields(String ticketType, Long integrationId, ReportPortalUser.ProjectDetails projectDetails);
+  /**
+   * Get set of fields of external system to submit a ticket
+   *
+   * @param ticketType     Ticket Type
+   * @param integrationId  Integration id
+   * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
+   * @return Found fields
+   */
+  List<PostFormField> getSubmitTicketFields(String ticketType, Long integrationId,
+      ReportPortalUser.ProjectDetails projectDetails);
 
-	List<PostFormField> getSubmitTicketFields(String issueType, Long integrationId);
+  List<PostFormField> getSubmitTicketFields(String issueType, Long integrationId);
 
-	/**
-	 * Get allowable issue types
-	 *
-	 * @param integrationId  Integration id
-	 * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
-	 * @return Fields
-	 */
-	List<String> getAllowableIssueTypes(Long integrationId, ReportPortalUser.ProjectDetails projectDetails);
+  /**
+   * Get allowable issue types
+   *
+   * @param integrationId  Integration id
+   * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
+   * @return Fields
+   */
+  List<String> getAllowableIssueTypes(Long integrationId,
+      ReportPortalUser.ProjectDetails projectDetails);
 
-	List<String> getAllowableIssueTypes(Long integrationId);
+  List<String> getAllowableIssueTypes(Long integrationId);
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/bts/handler/impl/CreateTicketHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/bts/handler/impl/CreateTicketHandlerImpl.java
index f8e9b8bb7e..ac925d43f3 100644
--- a/src/main/java/com/epam/ta/reportportal/core/bts/handler/impl/CreateTicketHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/bts/handler/impl/CreateTicketHandlerImpl.java
@@ -16,6 +16,13 @@
 
 package com.epam.ta.reportportal.core.bts.handler.impl;
 
+import static com.epam.ta.reportportal.commons.Predicates.notNull;
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.ws.converter.converters.TestItemConverter.TO_ACTIVITY_RESOURCE;
+import static com.epam.ta.reportportal.ws.model.ErrorType.BAD_REQUEST_ERROR;
+import static com.epam.ta.reportportal.ws.model.ErrorType.UNABLE_POST_TICKET;
+import static java.util.Optional.ofNullable;
+
 import com.epam.reportportal.extension.bugtracking.BtsConstants;
 import com.epam.reportportal.extension.bugtracking.BtsExtension;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
@@ -32,19 +39,11 @@
 import com.epam.ta.reportportal.ws.model.activity.TestItemActivityResource;
 import com.epam.ta.reportportal.ws.model.externalsystem.PostTicketRQ;
 import com.epam.ta.reportportal.ws.model.externalsystem.Ticket;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
 import java.util.Collections;
 import java.util.List;
 import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.commons.Predicates.notNull;
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.ws.converter.converters.TestItemConverter.TO_ACTIVITY_RESOURCE;
-import static com.epam.ta.reportportal.ws.model.ErrorType.BAD_REQUEST_ERROR;
-import static com.epam.ta.reportportal.ws.model.ErrorType.UNABLE_POST_TICKET;
-import static java.util.Optional.ofNullable;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
  * Default implementation of {@link CreateTicketHandler}
@@ -55,60 +54,67 @@
 @Service
 public class CreateTicketHandlerImpl implements CreateTicketHandler {
 
-	private final TestItemRepository testItemRepository;
-	private final MessageBus messageBus;
-	private final PluginBox pluginBox;
-	private final GetIntegrationHandler getIntegrationHandler;
+  private final TestItemRepository testItemRepository;
+  private final MessageBus messageBus;
+  private final PluginBox pluginBox;
+  private final GetIntegrationHandler getIntegrationHandler;
 
-	@Autowired
-	public CreateTicketHandlerImpl(TestItemRepository testItemRepository, PluginBox pluginBox, MessageBus messageBus,
-			GetIntegrationHandler getIntegrationHandler) {
-		this.testItemRepository = testItemRepository;
-		this.pluginBox = pluginBox;
-		this.messageBus = messageBus;
-		this.getIntegrationHandler = getIntegrationHandler;
-	}
+  @Autowired
+  public CreateTicketHandlerImpl(TestItemRepository testItemRepository, PluginBox pluginBox,
+      MessageBus messageBus,
+      GetIntegrationHandler getIntegrationHandler) {
+    this.testItemRepository = testItemRepository;
+    this.pluginBox = pluginBox;
+    this.messageBus = messageBus;
+    this.getIntegrationHandler = getIntegrationHandler;
+  }
 
-	@Override
-	public Ticket createIssue(PostTicketRQ postTicketRQ, Long integrationId, ReportPortalUser.ProjectDetails projectDetails,
-			ReportPortalUser user) {
-		validatePostTicketRQ(postTicketRQ);
+  @Override
+  public Ticket createIssue(PostTicketRQ postTicketRQ, Long integrationId,
+      ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user) {
+    validatePostTicketRQ(postTicketRQ);
 
-		List<TestItem> testItems = ofNullable(postTicketRQ.getBackLinks()).map(links -> testItemRepository.findAllById(links.keySet()))
-				.orElseGet(Collections::emptyList);
-		List<TestItemActivityResource> before = testItems.stream()
-				.map(it -> TO_ACTIVITY_RESOURCE.apply(it, projectDetails.getProjectId()))
-				.collect(Collectors.toList());
+    List<TestItem> testItems = ofNullable(postTicketRQ.getBackLinks()).map(
+            links -> testItemRepository.findAllById(links.keySet()))
+        .orElseGet(Collections::emptyList);
+    List<TestItemActivityResource> before = testItems.stream()
+        .map(it -> TO_ACTIVITY_RESOURCE.apply(it, projectDetails.getProjectId()))
+        .collect(Collectors.toList());
 
-		Integration integration = getIntegrationHandler.getEnabledBtsIntegration(projectDetails, integrationId);
+    Integration integration = getIntegrationHandler.getEnabledBtsIntegration(projectDetails,
+        integrationId);
 
-		expect(BtsConstants.DEFECT_FORM_FIELDS.getParam(integration.getParams()), notNull()).verify(BAD_REQUEST_ERROR,
-				"There aren't any submitted BTS fields!"
-		);
+    expect(BtsConstants.DEFECT_FORM_FIELDS.getParam(integration.getParams()), notNull()).verify(
+        BAD_REQUEST_ERROR,
+        "There aren't any submitted BTS fields!"
+    );
 
-		BtsExtension btsExtension = pluginBox.getInstance(integration.getType().getName(), BtsExtension.class)
-				.orElseThrow(() -> new ReportPortalException(BAD_REQUEST_ERROR,
-						Suppliers.formattedSupplier("BugTracking plugin for {} isn't installed",
-								BtsConstants.PROJECT.getParam(integration.getParams())
-						).get()
-				));
+    BtsExtension btsExtension = pluginBox.getInstance(integration.getType().getName(),
+            BtsExtension.class)
+        .orElseThrow(() -> new ReportPortalException(BAD_REQUEST_ERROR,
+            Suppliers.formattedSupplier("BugTracking plugin for {} isn't installed",
+                BtsConstants.PROJECT.getParam(integration.getParams())
+            ).get()
+        ));
 
-		Ticket ticket = btsExtension.submitTicket(postTicketRQ, integration);
+    Ticket ticket = btsExtension.submitTicket(postTicketRQ, integration);
 
-		before.forEach(it -> messageBus.publishActivity(new TicketPostedEvent(ticket, user.getUserId(), user.getUsername(), it)));
-		return ticket;
-	}
+    before.forEach(it -> messageBus.publishActivity(
+        new TicketPostedEvent(ticket, user.getUserId(), user.getUsername(), it)));
+    return ticket;
+  }
 
-	/**
-	 * Additional validations to {@link PostTicketRQ}.
-	 *
-	 * @param postTicketRQ
-	 */
-	private void validatePostTicketRQ(PostTicketRQ postTicketRQ) {
-		if (postTicketRQ.getIsIncludeLogs() || postTicketRQ.getIsIncludeScreenshots()) {
-			expect(postTicketRQ.getBackLinks(), notNull()).verify(UNABLE_POST_TICKET,
-					"Test item id should be specified, when logs required in ticket description."
-			);
-		}
-	}
+  /**
+   * Additional validations to {@link PostTicketRQ}.
+   *
+   * @param postTicketRQ
+   */
+  private void validatePostTicketRQ(PostTicketRQ postTicketRQ) {
+    if (postTicketRQ.getIsIncludeLogs() || postTicketRQ.getIsIncludeScreenshots()) {
+      expect(postTicketRQ.getBackLinks(), notNull()).verify(UNABLE_POST_TICKET,
+          "Test item id should be specified, when logs required in ticket description."
+      );
+    }
+  }
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/bts/handler/impl/GetBugTrackingSystemHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/bts/handler/impl/GetBugTrackingSystemHandlerImpl.java
index 8ca31f18fd..8557f75b7f 100644
--- a/src/main/java/com/epam/ta/reportportal/core/bts/handler/impl/GetBugTrackingSystemHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/bts/handler/impl/GetBugTrackingSystemHandlerImpl.java
@@ -24,67 +24,72 @@
 import com.epam.ta.reportportal.entity.enums.IntegrationGroupEnum;
 import com.epam.ta.reportportal.entity.integration.Integration;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.Optional;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.Optional;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class GetBugTrackingSystemHandlerImpl implements GetBugTrackingSystemHandler {
 
-	private final IntegrationRepository integrationRepository;
-
-	@Autowired
-	public GetBugTrackingSystemHandlerImpl(IntegrationRepository integrationRepository) {
-		this.integrationRepository = integrationRepository;
-	}
-
-	@Override
-	public Optional<Integration> getEnabledProjectIntegration(ReportPortalUser.ProjectDetails projectDetails, String url,
-			String btsProject) {
-
-		Optional<Integration> integration = integrationRepository.findProjectBtsByUrlAndLinkedProject(url,
-				btsProject,
-				projectDetails.getProjectId()
-		);
-		integration.ifPresent(this::validateBtsIntegration);
-		return integration;
-	}
-
-	@Override
-	public Optional<Integration> getEnabledProjectIntegration(ReportPortalUser.ProjectDetails projectDetails, Long integrationId) {
-
-		Optional<Integration> integration = integrationRepository.findByIdAndProjectId(integrationId, projectDetails.getProjectId());
-		integration.ifPresent(this::validateBtsIntegration);
-		return integration;
-	}
-
-	@Override
-	public Optional<Integration> getEnabledGlobalIntegration(String url, String btsProject) {
-
-		Optional<Integration> integration = integrationRepository.findGlobalBtsByUrlAndLinkedProject(url, btsProject);
-		integration.ifPresent(this::validateBtsIntegration);
-		return integration;
-	}
-
-	@Override
-	public Optional<Integration> getEnabledGlobalIntegration(Long integrationId) {
-
-		Optional<Integration> integration = integrationRepository.findGlobalById(integrationId);
-		integration.ifPresent(this::validateBtsIntegration);
-		return integration;
-	}
-
-	private void validateBtsIntegration(Integration integration) {
-
-		BusinessRule.expect(integration, it -> IntegrationGroupEnum.BTS == it.getType().getIntegrationGroup())
-				.verify(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION, Suppliers.formattedSupplier(
-						"Unable to test connection to the integration with type - '{}', Allowed type(es): '{}'",
-						integration.getType().getIntegrationGroup(),
-						IntegrationGroupEnum.BTS
-				));
-	}
+  private final IntegrationRepository integrationRepository;
+
+  @Autowired
+  public GetBugTrackingSystemHandlerImpl(IntegrationRepository integrationRepository) {
+    this.integrationRepository = integrationRepository;
+  }
+
+  @Override
+  public Optional<Integration> getEnabledProjectIntegration(
+      ReportPortalUser.ProjectDetails projectDetails, String url,
+      String btsProject) {
+
+    Optional<Integration> integration = integrationRepository.findProjectBtsByUrlAndLinkedProject(
+        url,
+        btsProject,
+        projectDetails.getProjectId()
+    );
+    integration.ifPresent(this::validateBtsIntegration);
+    return integration;
+  }
+
+  @Override
+  public Optional<Integration> getEnabledProjectIntegration(
+      ReportPortalUser.ProjectDetails projectDetails, Long integrationId) {
+
+    Optional<Integration> integration = integrationRepository.findByIdAndProjectId(integrationId,
+        projectDetails.getProjectId());
+    integration.ifPresent(this::validateBtsIntegration);
+    return integration;
+  }
+
+  @Override
+  public Optional<Integration> getEnabledGlobalIntegration(String url, String btsProject) {
+
+    Optional<Integration> integration = integrationRepository.findGlobalBtsByUrlAndLinkedProject(
+        url, btsProject);
+    integration.ifPresent(this::validateBtsIntegration);
+    return integration;
+  }
+
+  @Override
+  public Optional<Integration> getEnabledGlobalIntegration(Long integrationId) {
+
+    Optional<Integration> integration = integrationRepository.findGlobalById(integrationId);
+    integration.ifPresent(this::validateBtsIntegration);
+    return integration;
+  }
+
+  private void validateBtsIntegration(Integration integration) {
+
+    BusinessRule.expect(integration,
+            it -> IntegrationGroupEnum.BTS == it.getType().getIntegrationGroup())
+        .verify(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION, Suppliers.formattedSupplier(
+            "Unable to test connection to the integration with type - '{}', Allowed type(es): '{}'",
+            integration.getType().getIntegrationGroup(),
+            IntegrationGroupEnum.BTS
+        ));
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/bts/handler/impl/GetTicketHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/bts/handler/impl/GetTicketHandlerImpl.java
index 2f38119c94..fa6ea54a0b 100644
--- a/src/main/java/com/epam/ta/reportportal/core/bts/handler/impl/GetTicketHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/bts/handler/impl/GetTicketHandlerImpl.java
@@ -16,6 +16,8 @@
 
 package com.epam.ta.reportportal.core.bts.handler.impl;
 
+import static com.epam.ta.reportportal.ws.model.ErrorType.BAD_REQUEST_ERROR;
+
 import com.epam.reportportal.extension.bugtracking.BtsExtension;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.validation.Suppliers;
@@ -27,13 +29,10 @@
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.epam.ta.reportportal.ws.model.externalsystem.PostFormField;
 import com.epam.ta.reportportal.ws.model.externalsystem.Ticket;
+import java.util.List;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-
-import static com.epam.ta.reportportal.ws.model.ErrorType.BAD_REQUEST_ERROR;
-
 /**
  * Default implementation of {@link GetTicketHandler}
  *
@@ -43,52 +42,58 @@
 @Service
 public class GetTicketHandlerImpl implements GetTicketHandler {
 
-	private final PluginBox pluginBox;
-	private final GetIntegrationHandler getIntegrationHandler;
+  private final PluginBox pluginBox;
+  private final GetIntegrationHandler getIntegrationHandler;
 
-	@Autowired
-	public GetTicketHandlerImpl(PluginBox pluginBox, GetIntegrationHandler getIntegrationHandler) {
-		this.pluginBox = pluginBox;
-		this.getIntegrationHandler = getIntegrationHandler;
-	}
+  @Autowired
+  public GetTicketHandlerImpl(PluginBox pluginBox, GetIntegrationHandler getIntegrationHandler) {
+    this.pluginBox = pluginBox;
+    this.getIntegrationHandler = getIntegrationHandler;
+  }
 
-	@Override
-	public Ticket getTicket(String ticketId, String url, String btsProject, ReportPortalUser.ProjectDetails projectDetails) {
-		Integration integration = getIntegrationHandler.getEnabledBtsIntegration(projectDetails, url, btsProject);
-		return getBtsExtension(integration).getTicket(ticketId, integration)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.TICKET_NOT_FOUND, ticketId));
-	}
+  @Override
+  public Ticket getTicket(String ticketId, String url, String btsProject,
+      ReportPortalUser.ProjectDetails projectDetails) {
+    Integration integration = getIntegrationHandler.getEnabledBtsIntegration(projectDetails, url,
+        btsProject);
+    return getBtsExtension(integration).getTicket(ticketId, integration)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.TICKET_NOT_FOUND, ticketId));
+  }
 
-	@Override
-	public List<PostFormField> getSubmitTicketFields(String ticketType, Long integrationId,
-			ReportPortalUser.ProjectDetails projectDetails) {
-		Integration integration = getIntegrationHandler.getEnabledBtsIntegration(projectDetails, integrationId);
-		return getBtsExtension(integration).getTicketFields(ticketType, integration);
-	}
+  @Override
+  public List<PostFormField> getSubmitTicketFields(String ticketType, Long integrationId,
+      ReportPortalUser.ProjectDetails projectDetails) {
+    Integration integration = getIntegrationHandler.getEnabledBtsIntegration(projectDetails,
+        integrationId);
+    return getBtsExtension(integration).getTicketFields(ticketType, integration);
+  }
 
-	@Override
-	public List<PostFormField> getSubmitTicketFields(String ticketType, Long integrationId) {
-		Integration integration = getIntegrationHandler.getEnabledBtsIntegration(integrationId);
-		return getBtsExtension(integration).getTicketFields(ticketType, integration);
-	}
+  @Override
+  public List<PostFormField> getSubmitTicketFields(String ticketType, Long integrationId) {
+    Integration integration = getIntegrationHandler.getEnabledBtsIntegration(integrationId);
+    return getBtsExtension(integration).getTicketFields(ticketType, integration);
+  }
 
-	@Override
-	public List<String> getAllowableIssueTypes(Long integrationId, ReportPortalUser.ProjectDetails projectDetails) {
-		Integration integration = getIntegrationHandler.getEnabledBtsIntegration(projectDetails, integrationId);
-		return getBtsExtension(integration).getIssueTypes(integration);
-	}
+  @Override
+  public List<String> getAllowableIssueTypes(Long integrationId,
+      ReportPortalUser.ProjectDetails projectDetails) {
+    Integration integration = getIntegrationHandler.getEnabledBtsIntegration(projectDetails,
+        integrationId);
+    return getBtsExtension(integration).getIssueTypes(integration);
+  }
 
-	@Override
-	public List<String> getAllowableIssueTypes(Long integrationId) {
-		Integration integration = getIntegrationHandler.getEnabledBtsIntegration(integrationId);
-		return getBtsExtension(integration).getIssueTypes(integration);
-	}
+  @Override
+  public List<String> getAllowableIssueTypes(Long integrationId) {
+    Integration integration = getIntegrationHandler.getEnabledBtsIntegration(integrationId);
+    return getBtsExtension(integration).getIssueTypes(integration);
+  }
 
-	private BtsExtension getBtsExtension(Integration integration) {
-		return pluginBox.getInstance(integration.getType().getName(), BtsExtension.class)
-				.orElseThrow(() -> new ReportPortalException(BAD_REQUEST_ERROR,
-						Suppliers.formattedSupplier("BugTracking plugin for {} isn't installed", integration.getType().getName()).get()
-				));
-	}
+  private BtsExtension getBtsExtension(Integration integration) {
+    return pluginBox.getInstance(integration.getType().getName(), BtsExtension.class)
+        .orElseThrow(() -> new ReportPortalException(BAD_REQUEST_ERROR,
+            Suppliers.formattedSupplier("BugTracking plugin for {} isn't installed",
+                integration.getType().getName()).get()
+        ));
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/AspectConfig.java b/src/main/java/com/epam/ta/reportportal/core/configs/AspectConfig.java
index a3e46a4c2a..96d39b693c 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/AspectConfig.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/AspectConfig.java
@@ -28,15 +28,15 @@
 @Configuration
 public class AspectConfig {
 
-    @Bean
-    @ConditionalOnProperty(name = "rp.requestLogging", havingValue = "true")
-    HttpLoggingAspect httpLoggingAspect() {
-        return new HttpLoggingAspect();
-    }
+  @Bean
+  @ConditionalOnProperty(name = "rp.requestLogging", havingValue = "true")
+  HttpLoggingAspect httpLoggingAspect() {
+    return new HttpLoggingAspect();
+  }
 
-    @Bean
-    @ConditionalOnProperty(name = "rp.requestLogging", havingValue = "true")
-    RabbitMessageLoggingAspect rabbitMessageLoggingAspect() {
-        return new RabbitMessageLoggingAspect();
-    }
+  @Bean
+  @ConditionalOnProperty(name = "rp.requestLogging", havingValue = "true")
+  RabbitMessageLoggingAspect rabbitMessageLoggingAspect() {
+    return new RabbitMessageLoggingAspect();
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/AttachmentSizeConfig.java b/src/main/java/com/epam/ta/reportportal/core/configs/AttachmentSizeConfig.java
index 91a11e44c5..5d62eb685a 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/AttachmentSizeConfig.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/AttachmentSizeConfig.java
@@ -20,6 +20,9 @@
 import com.epam.ta.reportportal.commons.validation.Suppliers;
 import com.epam.ta.reportportal.entity.attachment.Attachment;
 import com.epam.ta.reportportal.exception.ReportPortalException;
+import java.io.InputStream;
+import java.util.Optional;
+import javax.sql.DataSource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.batch.core.Step;
@@ -35,10 +38,6 @@
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.util.StreamUtils;
 
-import javax.sql.DataSource;
-import java.io.InputStream;
-import java.util.Optional;
-
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
  */
@@ -46,72 +45,75 @@
 @ConditionalOnProperty(name = "rp.attachments.recalculate", havingValue = "true")
 public class AttachmentSizeConfig {
 
-	private static final Logger LOGGER = LoggerFactory.getLogger(AttachmentSizeConfig.class);
+  private static final Logger LOGGER = LoggerFactory.getLogger(AttachmentSizeConfig.class);
 
-	private static final int CHUNK_SIZE = 10;
+  private static final int CHUNK_SIZE = 10;
 
-	@Autowired
-	private StepBuilderFactory stepBuilderFactory;
+  @Autowired
+  private StepBuilderFactory stepBuilderFactory;
 
-	@Autowired
-	private DataSource dataSource;
+  @Autowired
+  private DataSource dataSource;
 
-	@Autowired
-	@Qualifier("attachmentDataStoreService")
-	private DataStoreService dataStoreService;
+  @Autowired
+  @Qualifier("attachmentDataStoreService")
+  private DataStoreService dataStoreService;
 
-	@Autowired
-	private JdbcTemplate jdbcTemplate;
+  @Autowired
+  private JdbcTemplate jdbcTemplate;
 
-	@Bean
-	public JdbcCursorItemReader<Attachment> reader() throws Exception {
-		String query = "SELECT * from attachment order by id";
-		JdbcCursorItemReader<Attachment> reader = new JdbcCursorItemReader<>();
-		reader.setSql(query);
-		reader.setDataSource(dataSource);
-		reader.setRowMapper((rs, rowNum) -> {
-			Attachment attachment = new Attachment();
-			attachment.setId(rs.getLong("id"));
-			attachment.setFileId(rs.getString("file_id"));
-			return attachment;
-		});
-		reader.afterPropertiesSet();
-		return reader;
-	}
+  @Bean
+  public JdbcCursorItemReader<Attachment> reader() throws Exception {
+    String query = "SELECT * from attachment order by id";
+    JdbcCursorItemReader<Attachment> reader = new JdbcCursorItemReader<>();
+    reader.setSql(query);
+    reader.setDataSource(dataSource);
+    reader.setRowMapper((rs, rowNum) -> {
+      Attachment attachment = new Attachment();
+      attachment.setId(rs.getLong("id"));
+      attachment.setFileId(rs.getString("file_id"));
+      return attachment;
+    });
+    reader.afterPropertiesSet();
+    return reader;
+  }
 
-	@Bean
-	public ItemProcessor<Attachment, Attachment> processor() {
-		return item -> {
-			try {
-				Optional<InputStream> file = dataStoreService.load(item.getFileId());
-				try (final InputStream inputStream = file.get()) {
-					item.setFileSize(StreamUtils.copyToByteArray(inputStream).length);
-					return item;
-				}
-			} catch (ReportPortalException e) {
-				LOGGER.debug(Suppliers.formattedSupplier("File with id {} is not presented at the file system. Removing from the database.",
-						item.getId()
-				).get());
-				jdbcTemplate.update("DELETE FROM attachment WHERE id = ?", item.getId());
-				return null;
-			}
-		};
-	}
+  @Bean
+  public ItemProcessor<Attachment, Attachment> processor() {
+    return item -> {
+      try {
+        Optional<InputStream> file = dataStoreService.load(item.getFileId());
+        try (final InputStream inputStream = file.get()) {
+          item.setFileSize(StreamUtils.copyToByteArray(inputStream).length);
+          return item;
+        }
+      } catch (ReportPortalException e) {
+        LOGGER.debug(Suppliers.formattedSupplier(
+            "File with id {} is not presented at the file system. Removing from the database.",
+            item.getId()
+        ).get());
+        jdbcTemplate.update("DELETE FROM attachment WHERE id = ?", item.getId());
+        return null;
+      }
+    };
+  }
 
-	@Bean
-	public ItemWriter<Attachment> writer() {
-		return items -> items.forEach(item -> {
-			jdbcTemplate.update("UPDATE attachment SET file_size = ? WHERE id = ?", item.getFileSize(), item.getId());
-		});
-	}
+  @Bean
+  public ItemWriter<Attachment> writer() {
+    return items -> items.forEach(item -> {
+      jdbcTemplate.update("UPDATE attachment SET file_size = ? WHERE id = ?", item.getFileSize(),
+          item.getId());
+    });
+  }
 
-	@Bean
-	public Step attachmentSizeStep() throws Exception {
-		return stepBuilderFactory.get("attachment").<Attachment, Attachment>chunk(CHUNK_SIZE).reader(reader())
-				.processor(processor())
-				.writer(writer())
-				.allowStartIfComplete(true)
-				.build();
-	}
+  @Bean
+  public Step attachmentSizeStep() throws Exception {
+    return stepBuilderFactory.get("attachment").<Attachment, Attachment>chunk(CHUNK_SIZE)
+        .reader(reader())
+        .processor(processor())
+        .writer(writer())
+        .allowStartIfComplete(true)
+        .build();
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/BatchJobConfiguration.java b/src/main/java/com/epam/ta/reportportal/core/configs/BatchJobConfiguration.java
index 9396f0d904..9b861329fc 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/BatchJobConfiguration.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/BatchJobConfiguration.java
@@ -38,37 +38,37 @@
 @ConditionalOnBean(name = "attachmentSizeConfig")
 public class BatchJobConfiguration {
 
-	@Autowired
-	private JobBuilderFactory jobBuilderFactory;
+  @Autowired
+  private JobBuilderFactory jobBuilderFactory;
 
-	@Autowired
-	private Step attachmentSizeStep;
+  @Autowired
+  private Step attachmentSizeStep;
 
-	@Autowired
-	private JdbcTemplate jdbcTemplate;
+  @Autowired
+  private JdbcTemplate jdbcTemplate;
 
-	@Bean
-	public JobExecutionListener jobExecutionListener() {
-		return new JobExecutionListener() {
-			@Override
-			public void beforeJob(JobExecution jobExecution) {
+  @Bean
+  public JobExecutionListener jobExecutionListener() {
+    return new JobExecutionListener() {
+      @Override
+      public void beforeJob(JobExecution jobExecution) {
 
-			}
+      }
 
-			@Override
-			public void afterJob(JobExecution jobExecution) {
-				jdbcTemplate.update(
-						"UPDATE project AS prj SET allocated_storage = (SELECT coalesce(sum(attachment.file_size), 0) FROM attachment WHERE project_id = prj.id)");
-			}
-		};
-	}
+      @Override
+      public void afterJob(JobExecution jobExecution) {
+        jdbcTemplate.update(
+            "UPDATE project AS prj SET allocated_storage = (SELECT coalesce(sum(attachment.file_size), 0) FROM attachment WHERE project_id = prj.id)");
+      }
+    };
+  }
 
-	@Bean
-	public Job job() {
-		SimpleJobBuilder job = jobBuilderFactory.get("attachmentSize")
-				.incrementer(new RunIdIncrementer())
-				.listener(jobExecutionListener())
-				.start(attachmentSizeStep);
-		return job.build();
-	}
+  @Bean
+  public Job job() {
+    SimpleJobBuilder job = jobBuilderFactory.get("attachmentSize")
+        .incrementer(new RunIdIncrementer())
+        .listener(jobExecutionListener())
+        .start(attachmentSizeStep);
+    return job.build();
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/Conditions.java b/src/main/java/com/epam/ta/reportportal/core/configs/Conditions.java
index 516dcac044..7cf34b2b78 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/Conditions.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/Conditions.java
@@ -15,12 +15,11 @@
  */
 package com.epam.ta.reportportal.core.configs;
 
+import java.util.Arrays;
 import org.springframework.context.annotation.ConditionContext;
 import org.springframework.context.annotation.ConfigurationCondition;
 import org.springframework.core.type.AnnotatedTypeMetadata;
 
-import java.util.Arrays;
-
 /**
  * Configuration conditions
  *
@@ -28,17 +27,18 @@
  */
 public class Conditions {
 
-	public static class NotTestCondition implements ConfigurationCondition {
+  public static class NotTestCondition implements ConfigurationCondition {
 
-		@Override
-		public ConfigurationCondition.ConfigurationPhase getConfigurationPhase() {
-			return ConfigurationCondition.ConfigurationPhase.PARSE_CONFIGURATION;
-		}
+    @Override
+    public ConfigurationCondition.ConfigurationPhase getConfigurationPhase() {
+      return ConfigurationCondition.ConfigurationPhase.PARSE_CONFIGURATION;
+    }
 
-		@Override
-		public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
-			return Arrays.stream(context.getEnvironment().getActiveProfiles()).noneMatch(profile -> profile.equals("unittest"));
-		}
-	}
+    @Override
+    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
+      return Arrays.stream(context.getEnvironment().getActiveProfiles())
+          .noneMatch(profile -> profile.equals("unittest"));
+    }
+  }
 
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/DemoDataConfig.java b/src/main/java/com/epam/ta/reportportal/core/configs/DemoDataConfig.java
index 92b7dab06e..eb51f16f11 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/DemoDataConfig.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/DemoDataConfig.java
@@ -5,35 +5,35 @@
 import com.epam.ta.reportportal.demodata.service.generator.SuiteWithNestedStepsGenerator;
 import com.epam.ta.reportportal.demodata.service.generator.SuiteWithRetriesGenerator;
 import com.epam.ta.reportportal.demodata.service.generator.model.SuiteGeneratorType;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
-import java.util.Map;
-
 @Configuration
 public class DemoDataConfig {
 
-	private final DefaultSuiteGenerator defaultSuiteGenerator;
-	private final SuiteWithRetriesGenerator suiteWithRetriesGenerator;
-	private final SuiteWithNestedStepsGenerator suiteWithNestedStepsGenerator;
+  private final DefaultSuiteGenerator defaultSuiteGenerator;
+  private final SuiteWithRetriesGenerator suiteWithRetriesGenerator;
+  private final SuiteWithNestedStepsGenerator suiteWithNestedStepsGenerator;
 
-	@Autowired
-	public DemoDataConfig(DefaultSuiteGenerator defaultSuiteGenerator, SuiteWithRetriesGenerator suiteWithRetriesGenerator,
-			SuiteWithNestedStepsGenerator suiteWithNestedStepsGenerator) {
-		this.defaultSuiteGenerator = defaultSuiteGenerator;
-		this.suiteWithRetriesGenerator = suiteWithRetriesGenerator;
-		this.suiteWithNestedStepsGenerator = suiteWithNestedStepsGenerator;
-	}
+  @Autowired
+  public DemoDataConfig(DefaultSuiteGenerator defaultSuiteGenerator,
+      SuiteWithRetriesGenerator suiteWithRetriesGenerator,
+      SuiteWithNestedStepsGenerator suiteWithNestedStepsGenerator) {
+    this.defaultSuiteGenerator = defaultSuiteGenerator;
+    this.suiteWithRetriesGenerator = suiteWithRetriesGenerator;
+    this.suiteWithNestedStepsGenerator = suiteWithNestedStepsGenerator;
+  }
 
-	@Bean
-	public SuiteGeneratorResolver suiteGeneratorResolver() {
-		return new SuiteGeneratorResolver(Map.of(SuiteGeneratorType.DEFAULT,
-				defaultSuiteGenerator,
-				SuiteGeneratorType.RETRY,
-				suiteWithRetriesGenerator,
-				SuiteGeneratorType.NESTED,
-				suiteWithNestedStepsGenerator
-		));
-	}
+  @Bean
+  public SuiteGeneratorResolver suiteGeneratorResolver() {
+    return new SuiteGeneratorResolver(Map.of(SuiteGeneratorType.DEFAULT,
+        defaultSuiteGenerator,
+        SuiteGeneratorType.RETRY,
+        suiteWithRetriesGenerator,
+        SuiteGeneratorType.NESTED,
+        suiteWithNestedStepsGenerator
+    ));
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/EmailConfiguration.java b/src/main/java/com/epam/ta/reportportal/core/configs/EmailConfiguration.java
index 3e969afd82..5a9d443795 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/EmailConfiguration.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/EmailConfiguration.java
@@ -18,7 +18,6 @@
 
 import com.epam.reportportal.commons.template.TemplateEngine;
 import com.epam.reportportal.commons.template.TemplateEngineProvider;
-import com.epam.ta.reportportal.core.analyzer.strategy.LaunchAnalysisStrategy;
 import com.epam.ta.reportportal.util.email.strategy.EmailNotificationStrategy;
 import com.epam.ta.reportportal.util.email.strategy.EmailTemplate;
 import com.epam.ta.reportportal.util.email.strategy.UserDeletionNotificationStrategy;
@@ -27,6 +26,7 @@
 import com.google.common.collect.ImmutableMap;
 import java.util.Map;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -34,7 +34,7 @@
 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 
 /**
- * Global Email Configuration<br> Probably will be replaces by configuration per project.
+ * Global Email Configuration<br> Probably will be replaced by configuration per project.
  *
  * @author Andrei_Ramanchuk
  */
@@ -45,11 +45,14 @@ public class EmailConfiguration {
   private ApplicationContext applicationContext;
 
   @Bean
-  public ThreadPoolTaskExecutor emailExecutorService() {
+  public ThreadPoolTaskExecutor emailExecutorService(
+      @Value("${rp.environment.variable.executor.pool.user-email.core}") Integer corePoolSize,
+      @Value("${rp.environment.variable.executor.pool.user-email.max}") Integer maxPoolSize,
+      @Value("${rp.environment.variable.executor.pool.user-email.queue}") Integer queueCapacity) {
     ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
-    threadPoolTaskExecutor.setCorePoolSize(5);
-    threadPoolTaskExecutor.setMaxPoolSize(20);
-    threadPoolTaskExecutor.setQueueCapacity(50);
+    threadPoolTaskExecutor.setCorePoolSize(corePoolSize);
+    threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize);
+    threadPoolTaskExecutor.setQueueCapacity(queueCapacity);
     threadPoolTaskExecutor.setAllowCoreThreadTimeOut(true);
     threadPoolTaskExecutor.setAwaitTerminationSeconds(20);
     threadPoolTaskExecutor.setThreadNamePrefix("email-sending-exec");
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/ExecutorConfiguration.java b/src/main/java/com/epam/ta/reportportal/core/configs/ExecutorConfiguration.java
index 79719e0a63..5145ac242c 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/ExecutorConfiguration.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/ExecutorConfiguration.java
@@ -16,7 +16,6 @@
 
 package com.epam.ta.reportportal.core.configs;
 
-import com.epam.ta.reportportal.core.log.impl.SaveLogBinaryDataTask;
 import com.epam.ta.reportportal.core.log.impl.SaveLogBinaryDataTaskAsync;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.beans.factory.config.ConfigurableBeanFactory;
@@ -31,8 +30,6 @@
 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
 
-import java.util.concurrent.ThreadPoolExecutor;
-
 /**
  * Configs for beans related to job execution
  *
@@ -42,138 +39,129 @@
 @EnableAsync
 public class ExecutorConfiguration {
 
-	@Bean
-	@Primary
-	public TaskScheduler taskScheduler() {
-		ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
-		scheduler.setPoolSize(5);
-		scheduler.setThreadNamePrefix("default-task-sched");
-		scheduler.setWaitForTasksToCompleteOnShutdown(true);
-		return scheduler;
-	}
-
-	@Bean(name = "saveLogsTaskExecutor")
-	public TaskExecutor saveLogsTaskExecutor(@Value("${rp.environment.variable.executor.pool.save-logs.core}") Integer corePoolSize,
-			@Value("${rp.environment.variable.executor.pool.save-logs.max}") Integer maxPoolSize,
-			@Value("${rp.environment.variable.executor.pool.save-logs.queue}") Integer queueCapacity) {
-		ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
-		executor.setCorePoolSize(corePoolSize);
-		executor.setMaxPoolSize(maxPoolSize);
-		executor.setQueueCapacity(queueCapacity);
-		executor.setAllowCoreThreadTimeOut(true);
-		executor.setThreadNamePrefix("logs-task-exec");
-		executor.setRejectedExecutionHandler(new java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy());
-		return executor;
-	}
-
-	@Bean
-	@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
-	public SaveLogBinaryDataTask saveLogBinaryDataTask() {
-		return new SaveLogBinaryDataTask();
-	}
-
-	@Bean
-	@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
-	public SaveLogBinaryDataTaskAsync saveLogBinaryDataTaskAsync() {
-		return new SaveLogBinaryDataTaskAsync();
-	}
-
-	@EnableScheduling
-	public static class SchedulingConfiguration {
-	}
-
-	@Bean(name = "logIndexTaskExecutor")
-	public TaskExecutor logIndexTaskExecutor(@Value("${rp.environment.variable.executor.pool.log-index.core}") Integer corePoolSize,
-			@Value("${rp.environment.variable.executor.pool.log-index.max}") Integer maxPoolSize,
-			@Value("${rp.environment.variable.executor.pool.log-index.queue}") Integer queueCapacity) {
-		final ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
-		threadPoolTaskExecutor.setCorePoolSize(corePoolSize);
-		threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize);
-		threadPoolTaskExecutor.setQueueCapacity(queueCapacity);
-		threadPoolTaskExecutor.setAllowCoreThreadTimeOut(true);
-		threadPoolTaskExecutor.setThreadNamePrefix("log-index-exec");
-		return threadPoolTaskExecutor;
-	}
-
-	@Bean(name = "autoAnalyzeTaskExecutor")
-	public TaskExecutor autoAnalyzeTaskExecutor(@Value("${rp.environment.variable.executor.pool.auto-analyze.core}") Integer corePoolSize,
-			@Value("${rp.environment.variable.executor.pool.auto-analyze.max}") Integer maxPoolSize,
-			@Value("${rp.environment.variable.executor.pool.auto-analyze.queue}") Integer queueCapacity) {
-		final ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
-		threadPoolTaskExecutor.setCorePoolSize(corePoolSize);
-		threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize);
-		threadPoolTaskExecutor.setQueueCapacity(queueCapacity);
-		threadPoolTaskExecutor.setAllowCoreThreadTimeOut(true);
-		threadPoolTaskExecutor.setThreadNamePrefix("auto-analyze-exec");
-		return threadPoolTaskExecutor;
-	}
-
-	@Bean("patternAnalysisTaskExecutor")
-	public TaskExecutor patternAnalysisTaskExecutor(@Value("${rp.environment.variable.executor.pool.pattern-analyze.core}") Integer corePoolSize,
-			@Value("${rp.environment.variable.executor.pool.pattern-analyze.max}") Integer maxPoolSize,
-			@Value("${rp.environment.variable.executor.pool.pattern-analyze.queue}") Integer queueCapacity) {
-		ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
-		taskExecutor.setCorePoolSize(corePoolSize);
-		taskExecutor.setMaxPoolSize(maxPoolSize);
-		taskExecutor.setQueueCapacity(queueCapacity);
-		taskExecutor.setThreadNamePrefix("pattern-analysis-task-exec");
-		taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
-		return taskExecutor;
-	}
-
-	@Bean(name = "demoDataTaskExecutor")
-	public TaskExecutor demoDataTaskExecutor(@Value("${rp.environment.variable.executor.pool.demo-data.core}") Integer corePoolSize,
-			@Value("${rp.environment.variable.executor.pool.demo-data.max}") Integer maxPoolSize,
-			@Value("${rp.environment.variable.executor.pool.demo-data.queue}") Integer queueCapacity) {
-		ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
-		threadPoolTaskExecutor.setCorePoolSize(corePoolSize);
-		threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize);
-		threadPoolTaskExecutor.setQueueCapacity(queueCapacity);
-		threadPoolTaskExecutor.setAllowCoreThreadTimeOut(true);
-		threadPoolTaskExecutor.setAwaitTerminationSeconds(60);
-		threadPoolTaskExecutor.setThreadNamePrefix("demo-data-exec");
-		return threadPoolTaskExecutor;
-	}
-
-	@Bean(name = "widgetViewExecutor")
-	public TaskExecutor healthCheckTableExecutor(
-			@Value("${rp.environment.variable.executor.pool.widget-view.core}") Integer corePoolSize,
-			@Value("${rp.environment.variable.executor.pool.widget-view.max}") Integer maxPoolSize,
-			@Value("${rp.environment.variable.executor.pool.widget-view.queue}") Integer queueCapacity) {
-		ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
-		executor.setCorePoolSize(corePoolSize);
-		executor.setMaxPoolSize(maxPoolSize);
-		executor.setQueueCapacity(queueCapacity);
-		executor.setAllowCoreThreadTimeOut(true);
-		executor.setThreadNamePrefix("generate-widget-view-task");
-		executor.setRejectedExecutionHandler(new java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy());
-		return executor;
-	}
-
-	@Bean(name = "logClusterExecutor")
-	public TaskExecutor logClusterExecutor(@Value("${rp.environment.variable.executor.pool.log-cluster.core}") Integer corePoolSize,
-			@Value("${rp.environment.variable.executor.pool.log-cluster.max}") Integer maxPoolSize,
-			@Value("${rp.environment.variable.executor.pool.log-cluster.queue}") Integer queueCapacity) {
-		final ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
-		threadPoolTaskExecutor.setCorePoolSize(corePoolSize);
-		threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize);
-		threadPoolTaskExecutor.setQueueCapacity(queueCapacity);
-		threadPoolTaskExecutor.setAllowCoreThreadTimeOut(true);
-		threadPoolTaskExecutor.setThreadNamePrefix("log-cluster-exec");
-		return threadPoolTaskExecutor;
-	}
-
-	@Bean(name = "eventListenerExecutor")
-	public TaskExecutor eventListenerExecutor(@Value("${rp.environment.variable.executor.pool.event-listener.core}") Integer corePoolSize,
-			@Value("${rp.environment.variable.executor.pool.event-listener.max}") Integer maxPoolSize,
-			@Value("${rp.environment.variable.executor.pool.event-listener.queue}") Integer queueCapacity) {
-		final ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
-		threadPoolTaskExecutor.setCorePoolSize(corePoolSize);
-		threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize);
-		threadPoolTaskExecutor.setQueueCapacity(queueCapacity);
-		threadPoolTaskExecutor.setAllowCoreThreadTimeOut(true);
-		threadPoolTaskExecutor.setThreadNamePrefix("event-listener-exec");
-		return threadPoolTaskExecutor;
-	}
+  @Bean
+  @Primary
+  public TaskScheduler taskScheduler() {
+    ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
+    scheduler.setPoolSize(5);
+    scheduler.setThreadNamePrefix("default-task-sched");
+    scheduler.setWaitForTasksToCompleteOnShutdown(true);
+    return scheduler;
+  }
+
+  @Bean(name = "saveLogsTaskExecutor")
+  public TaskExecutor saveLogsTaskExecutor(
+      @Value("${rp.environment.variable.executor.pool.save-logs.core}") Integer corePoolSize,
+      @Value("${rp.environment.variable.executor.pool.save-logs.max}") Integer maxPoolSize,
+      @Value("${rp.environment.variable.executor.pool.save-logs.queue}") Integer queueCapacity) {
+    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+    executor.setCorePoolSize(corePoolSize);
+    executor.setMaxPoolSize(maxPoolSize);
+    executor.setQueueCapacity(queueCapacity);
+    executor.setAllowCoreThreadTimeOut(true);
+    executor.setThreadNamePrefix("logs-task-exec");
+    executor.setRejectedExecutionHandler(
+        new java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy());
+    return executor;
+  }
+
+  @Bean
+  @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
+  public SaveLogBinaryDataTaskAsync saveLogBinaryDataTaskAsync() {
+    return new SaveLogBinaryDataTaskAsync();
+  }
+
+  @EnableScheduling
+  public static class SchedulingConfiguration {
+
+  }
+
+  @Bean(name = "logIndexTaskExecutor")
+  public TaskExecutor logIndexTaskExecutor(
+      @Value("${rp.environment.variable.executor.pool.log-index.core}") Integer corePoolSize,
+      @Value("${rp.environment.variable.executor.pool.log-index.max}") Integer maxPoolSize,
+      @Value("${rp.environment.variable.executor.pool.log-index.queue}") Integer queueCapacity) {
+    final ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
+    threadPoolTaskExecutor.setCorePoolSize(corePoolSize);
+    threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize);
+    threadPoolTaskExecutor.setQueueCapacity(queueCapacity);
+    threadPoolTaskExecutor.setAllowCoreThreadTimeOut(true);
+    threadPoolTaskExecutor.setThreadNamePrefix("log-index-exec");
+    return threadPoolTaskExecutor;
+  }
+
+  @Bean(name = "autoAnalyzeTaskExecutor")
+  public TaskExecutor autoAnalyzeTaskExecutor(
+      @Value("${rp.environment.variable.executor.pool.auto-analyze.core}") Integer corePoolSize,
+      @Value("${rp.environment.variable.executor.pool.auto-analyze.max}") Integer maxPoolSize,
+      @Value("${rp.environment.variable.executor.pool.auto-analyze.queue}") Integer queueCapacity) {
+    final ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
+    threadPoolTaskExecutor.setCorePoolSize(corePoolSize);
+    threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize);
+    threadPoolTaskExecutor.setQueueCapacity(queueCapacity);
+    threadPoolTaskExecutor.setAllowCoreThreadTimeOut(true);
+    threadPoolTaskExecutor.setThreadNamePrefix("auto-analyze-exec");
+    return threadPoolTaskExecutor;
+  }
+
+  @Bean(name = "demoDataTaskExecutor")
+  public TaskExecutor demoDataTaskExecutor(
+      @Value("${rp.environment.variable.executor.pool.demo-data.core}") Integer corePoolSize,
+      @Value("${rp.environment.variable.executor.pool.demo-data.max}") Integer maxPoolSize,
+      @Value("${rp.environment.variable.executor.pool.demo-data.queue}") Integer queueCapacity) {
+    ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
+    threadPoolTaskExecutor.setCorePoolSize(corePoolSize);
+    threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize);
+    threadPoolTaskExecutor.setQueueCapacity(queueCapacity);
+    threadPoolTaskExecutor.setAllowCoreThreadTimeOut(true);
+    threadPoolTaskExecutor.setAwaitTerminationSeconds(60);
+    threadPoolTaskExecutor.setThreadNamePrefix("demo-data-exec");
+    return threadPoolTaskExecutor;
+  }
+
+  @Bean(name = "widgetViewExecutor")
+  public TaskExecutor healthCheckTableExecutor(
+      @Value("${rp.environment.variable.executor.pool.widget-view.core}") Integer corePoolSize,
+      @Value("${rp.environment.variable.executor.pool.widget-view.max}") Integer maxPoolSize,
+      @Value("${rp.environment.variable.executor.pool.widget-view.queue}") Integer queueCapacity) {
+    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+    executor.setCorePoolSize(corePoolSize);
+    executor.setMaxPoolSize(maxPoolSize);
+    executor.setQueueCapacity(queueCapacity);
+    executor.setAllowCoreThreadTimeOut(true);
+    executor.setThreadNamePrefix("generate-widget-view-task");
+    executor.setRejectedExecutionHandler(
+        new java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy());
+    return executor;
+  }
+
+  @Bean(name = "logClusterExecutor")
+  public TaskExecutor logClusterExecutor(
+      @Value("${rp.environment.variable.executor.pool.log-cluster.core}") Integer corePoolSize,
+      @Value("${rp.environment.variable.executor.pool.log-cluster.max}") Integer maxPoolSize,
+      @Value("${rp.environment.variable.executor.pool.log-cluster.queue}") Integer queueCapacity) {
+    final ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
+    threadPoolTaskExecutor.setCorePoolSize(corePoolSize);
+    threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize);
+    threadPoolTaskExecutor.setQueueCapacity(queueCapacity);
+    threadPoolTaskExecutor.setAllowCoreThreadTimeOut(true);
+    threadPoolTaskExecutor.setThreadNamePrefix("log-cluster-exec");
+    return threadPoolTaskExecutor;
+  }
+
+  @Bean(name = "eventListenerExecutor")
+  public TaskExecutor eventListenerExecutor(
+      @Value("${rp.environment.variable.executor.pool.event-listener.core}") Integer corePoolSize,
+      @Value("${rp.environment.variable.executor.pool.event-listener.max}") Integer maxPoolSize,
+      @Value("${rp.environment.variable.executor.pool.event-listener.queue}")
+      Integer queueCapacity) {
+    final ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
+    threadPoolTaskExecutor.setCorePoolSize(corePoolSize);
+    threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize);
+    threadPoolTaskExecutor.setQueueCapacity(queueCapacity);
+    threadPoolTaskExecutor.setAllowCoreThreadTimeOut(true);
+    threadPoolTaskExecutor.setThreadNamePrefix("event-listener-exec");
+    return threadPoolTaskExecutor;
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/IntegrationConfig.java b/src/main/java/com/epam/ta/reportportal/core/configs/IntegrationConfig.java
index 10ede48abe..b8bbe50fb9 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/IntegrationConfig.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/IntegrationConfig.java
@@ -16,37 +16,41 @@
 
 package com.epam.ta.reportportal.core.configs;
 
-import com.epam.ta.reportportal.core.integration.util.*;
+import com.epam.ta.reportportal.core.integration.util.AzureIntegrationService;
+import com.epam.ta.reportportal.core.integration.util.BtsIntegrationService;
+import com.epam.ta.reportportal.core.integration.util.EmailServerIntegrationService;
+import com.epam.ta.reportportal.core.integration.util.IntegrationService;
+import com.epam.ta.reportportal.core.integration.util.SauceLabsIntegrationService;
 import com.google.common.collect.ImmutableMap;
+import java.util.Map;
 import org.springframework.beans.BeansException;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContextAware;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
-import java.util.Map;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Configuration
 public class IntegrationConfig implements ApplicationContextAware {
 
-	private ApplicationContext applicationContext;
+  private ApplicationContext applicationContext;
 
-	@Override
-	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
-		this.applicationContext = applicationContext;
-	}
+  @Override
+  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+    this.applicationContext = applicationContext;
+  }
 
-	@Bean
-	public Map<String, IntegrationService> integrationServiceMapping() {
-		return ImmutableMap.<String, IntegrationService>builder().put("jira", applicationContext.getBean(BtsIntegrationService.class))
-				.put("rally", applicationContext.getBean(BtsIntegrationService.class))
-				.put("Azure DevOps", applicationContext.getBean(AzureIntegrationService.class))
-				.put("email", applicationContext.getBean(EmailServerIntegrationService.class))
-				.put("saucelabs", applicationContext.getBean(SauceLabsIntegrationService.class))
-				.build();
+  @Bean
+  public Map<String, IntegrationService> integrationServiceMapping() {
+    return ImmutableMap.<String, IntegrationService>builder()
+        .put("jira", applicationContext.getBean(BtsIntegrationService.class))
+        .put("rally", applicationContext.getBean(BtsIntegrationService.class))
+        .put("Azure DevOps", applicationContext.getBean(AzureIntegrationService.class))
+        .put("email", applicationContext.getBean(EmailServerIntegrationService.class))
+        .put("saucelabs", applicationContext.getBean(SauceLabsIntegrationService.class))
+        .build();
 
-	}
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/ItemStatusChangingStrategyConfig.java b/src/main/java/com/epam/ta/reportportal/core/configs/ItemStatusChangingStrategyConfig.java
index 3b53225357..2970c4339d 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/ItemStatusChangingStrategyConfig.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/ItemStatusChangingStrategyConfig.java
@@ -22,40 +22,41 @@
 import com.epam.ta.reportportal.core.item.impl.status.ToSkippedStatusChangingStrategy;
 import com.epam.ta.reportportal.entity.enums.StatusEnum;
 import com.google.common.collect.ImmutableMap;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
-import java.util.Map;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @Configuration
 public class ItemStatusChangingStrategyConfig {
 
-	private final ToFailedStatusChangingStrategy toFailedStatusChangingStrategy;
-
-	private final ToPassedStatusChangingStrategy toPassedStatusChangingStrategy;
-
-	private final ToSkippedStatusChangingStrategy toSkippedStatusChangingStrategy;
-
-	@Autowired
-	public ItemStatusChangingStrategyConfig(ToFailedStatusChangingStrategy toFailedStatusChangingStrategy,
-			ToPassedStatusChangingStrategy toPassedStatusChangingStrategy,
-			ToSkippedStatusChangingStrategy toSkippedStatusChangingStrategy) {
-		this.toFailedStatusChangingStrategy = toFailedStatusChangingStrategy;
-		this.toPassedStatusChangingStrategy = toPassedStatusChangingStrategy;
-		this.toSkippedStatusChangingStrategy = toSkippedStatusChangingStrategy;
-	}
-
-	@Bean
-	public Map<StatusEnum, StatusChangingStrategy> statusChangingStrategyMapping() {
-		return ImmutableMap.<StatusEnum, StatusChangingStrategy>builder().put(StatusEnum.PASSED, toPassedStatusChangingStrategy)
-				.put(StatusEnum.INFO, toPassedStatusChangingStrategy)
-				.put(StatusEnum.WARN, toPassedStatusChangingStrategy)
-				.put(StatusEnum.FAILED, toFailedStatusChangingStrategy)
-				.put(StatusEnum.SKIPPED, toSkippedStatusChangingStrategy)
-				.build();
-	}
+  private final ToFailedStatusChangingStrategy toFailedStatusChangingStrategy;
+
+  private final ToPassedStatusChangingStrategy toPassedStatusChangingStrategy;
+
+  private final ToSkippedStatusChangingStrategy toSkippedStatusChangingStrategy;
+
+  @Autowired
+  public ItemStatusChangingStrategyConfig(
+      ToFailedStatusChangingStrategy toFailedStatusChangingStrategy,
+      ToPassedStatusChangingStrategy toPassedStatusChangingStrategy,
+      ToSkippedStatusChangingStrategy toSkippedStatusChangingStrategy) {
+    this.toFailedStatusChangingStrategy = toFailedStatusChangingStrategy;
+    this.toPassedStatusChangingStrategy = toPassedStatusChangingStrategy;
+    this.toSkippedStatusChangingStrategy = toSkippedStatusChangingStrategy;
+  }
+
+  @Bean
+  public Map<StatusEnum, StatusChangingStrategy> statusChangingStrategyMapping() {
+    return ImmutableMap.<StatusEnum, StatusChangingStrategy>builder()
+        .put(StatusEnum.PASSED, toPassedStatusChangingStrategy)
+        .put(StatusEnum.INFO, toPassedStatusChangingStrategy)
+        .put(StatusEnum.WARN, toPassedStatusChangingStrategy)
+        .put(StatusEnum.FAILED, toFailedStatusChangingStrategy)
+        .put(StatusEnum.SKIPPED, toSkippedStatusChangingStrategy)
+        .build();
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/JacksonConfiguration.java b/src/main/java/com/epam/ta/reportportal/core/configs/JacksonConfiguration.java
index 13d74f7a7b..a7aabe0d82 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/JacksonConfiguration.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/JacksonConfiguration.java
@@ -31,17 +31,17 @@
 @Configuration
 public class JacksonConfiguration {
 
-	/**
-	 * @return Configured object mapper
-	 */
-	@Bean(name = "objectMapper")
-	public ObjectMapper objectMapper() {
-		ObjectMapper om = new ObjectMapper();
-		om.setAnnotationIntrospector(new JacksonAnnotationIntrospector());
-		om.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, true);
-		om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
-		om.registerModule(new JacksonViewAwareModule(om));
-		om.registerModule(new JavaTimeModule());
-		return om;
-	}
+  /**
+   * @return Configured object mapper
+   */
+  @Bean(name = "objectMapper")
+  public ObjectMapper objectMapper() {
+    ObjectMapper om = new ObjectMapper();
+    om.setAnnotationIntrospector(new JacksonAnnotationIntrospector());
+    om.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, true);
+    om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+    om.registerModule(new JacksonViewAwareModule(om));
+    om.registerModule(new JavaTimeModule());
+    return om;
+  }
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/MergeStrategyConfig.java b/src/main/java/com/epam/ta/reportportal/core/configs/MergeStrategyConfig.java
index 39c9cead53..39aaed35ae 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/MergeStrategyConfig.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/MergeStrategyConfig.java
@@ -16,8 +16,15 @@
 
 package com.epam.ta.reportportal.core.configs;
 
+import static java.util.Collections.singletonMap;
+
 import com.epam.ta.reportportal.core.item.identity.TestItemUniqueIdGenerator;
-import com.epam.ta.reportportal.core.item.impl.merge.strategy.*;
+import com.epam.ta.reportportal.core.item.impl.merge.strategy.BasicLaunchMergeStrategy;
+import com.epam.ta.reportportal.core.item.impl.merge.strategy.BasicStatisticsCalculationStrategy;
+import com.epam.ta.reportportal.core.item.impl.merge.strategy.DeepLaunchMergeStrategy;
+import com.epam.ta.reportportal.core.item.impl.merge.strategy.LaunchMergeFactory;
+import com.epam.ta.reportportal.core.item.impl.merge.strategy.MergeStrategyType;
+import com.epam.ta.reportportal.core.item.impl.merge.strategy.StatisticsCalculationFactory;
 import com.epam.ta.reportportal.core.item.merge.LaunchMergeStrategy;
 import com.epam.ta.reportportal.core.item.merge.StatisticsCalculationStrategy;
 import com.epam.ta.reportportal.dao.AttachmentRepository;
@@ -25,74 +32,74 @@
 import com.epam.ta.reportportal.dao.LogRepository;
 import com.epam.ta.reportportal.dao.TestItemRepository;
 import com.google.common.collect.ImmutableMap;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
-import java.util.Map;
-
-import static java.util.Collections.singletonMap;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Configuration
 public class MergeStrategyConfig {
 
-	private final TestItemRepository testItemRepository;
+  private final TestItemRepository testItemRepository;
 
-	private final LaunchRepository launchRepository;
+  private final LaunchRepository launchRepository;
 
-	private final TestItemUniqueIdGenerator testItemUniqueIdGenerator;
+  private final TestItemUniqueIdGenerator testItemUniqueIdGenerator;
 
-	private final LogRepository logRepository;
+  private final LogRepository logRepository;
 
-	private final AttachmentRepository attachmentRepository;
+  private final AttachmentRepository attachmentRepository;
 
-	@Autowired
-	public MergeStrategyConfig(TestItemRepository testItemRepository, LaunchRepository launchRepository,
-			TestItemUniqueIdGenerator testItemUniqueIdGenerator, LogRepository logRepository, AttachmentRepository attachmentRepository) {
-		this.testItemRepository = testItemRepository;
-		this.launchRepository = launchRepository;
-		this.testItemUniqueIdGenerator = testItemUniqueIdGenerator;
-		this.logRepository = logRepository;
-		this.attachmentRepository = attachmentRepository;
-	}
+  @Autowired
+  public MergeStrategyConfig(TestItemRepository testItemRepository,
+      LaunchRepository launchRepository,
+      TestItemUniqueIdGenerator testItemUniqueIdGenerator, LogRepository logRepository,
+      AttachmentRepository attachmentRepository) {
+    this.testItemRepository = testItemRepository;
+    this.launchRepository = launchRepository;
+    this.testItemUniqueIdGenerator = testItemUniqueIdGenerator;
+    this.logRepository = logRepository;
+    this.attachmentRepository = attachmentRepository;
+  }
 
-	@Bean
-	public Map<MergeStrategyType, StatisticsCalculationStrategy> statisticsCalculationStrategyMaping() {
-		return singletonMap(MergeStrategyType.BASIC, new BasicStatisticsCalculationStrategy());
-	}
+  @Bean
+  public Map<MergeStrategyType, StatisticsCalculationStrategy> statisticsCalculationStrategyMaping() {
+    return singletonMap(MergeStrategyType.BASIC, new BasicStatisticsCalculationStrategy());
+  }
 
-	@Bean
-	public StatisticsCalculationFactory statisticsCalculationFactory() {
-		return new StatisticsCalculationFactory(statisticsCalculationStrategyMaping());
-	}
+  @Bean
+  public StatisticsCalculationFactory statisticsCalculationFactory() {
+    return new StatisticsCalculationFactory(statisticsCalculationStrategyMaping());
+  }
 
-	@Bean
-	public Map<MergeStrategyType, LaunchMergeStrategy> launchMergeStrategyMapping() {
-		return ImmutableMap.<MergeStrategyType, LaunchMergeStrategy>builder().put(MergeStrategyType.BASIC,
-				new BasicLaunchMergeStrategy(launchRepository,
-						testItemRepository,
-						logRepository,
-						attachmentRepository,
-						testItemUniqueIdGenerator,
-						statisticsCalculationFactory()
-				)
-		)
-				.put(MergeStrategyType.DEEP,
-						new DeepLaunchMergeStrategy(launchRepository,
-								testItemRepository,
-								logRepository,
-								attachmentRepository,
-								testItemUniqueIdGenerator
-						)
-				)
-				.build();
-	}
+  @Bean
+  public Map<MergeStrategyType, LaunchMergeStrategy> launchMergeStrategyMapping() {
+    return ImmutableMap.<MergeStrategyType, LaunchMergeStrategy>builder()
+        .put(MergeStrategyType.BASIC,
+            new BasicLaunchMergeStrategy(launchRepository,
+                testItemRepository,
+                logRepository,
+                attachmentRepository,
+                testItemUniqueIdGenerator,
+                statisticsCalculationFactory()
+            )
+        )
+        .put(MergeStrategyType.DEEP,
+            new DeepLaunchMergeStrategy(launchRepository,
+                testItemRepository,
+                logRepository,
+                attachmentRepository,
+                testItemUniqueIdGenerator
+            )
+        )
+        .build();
+  }
 
-	@Bean
-	public LaunchMergeFactory launchMergeFactory() {
-		return new LaunchMergeFactory(launchMergeStrategyMapping());
-	}
+  @Bean
+  public LaunchMergeFactory launchMergeFactory() {
+    return new LaunchMergeFactory(launchMergeStrategyMapping());
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/MultipartDataConfig.java b/src/main/java/com/epam/ta/reportportal/core/configs/MultipartDataConfig.java
index ce2da3b199..dfc5000a0c 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/MultipartDataConfig.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/MultipartDataConfig.java
@@ -1,24 +1,29 @@
 package com.epam.ta.reportportal.core.configs;
 
+import com.epam.ta.reportportal.util.BinaryDataResponseWriter;
+import javax.activation.MimetypesFileTypeMap;
 import org.apache.tika.parser.AutoDetectParser;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
-import javax.activation.MimetypesFileTypeMap;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Configuration
 public class MultipartDataConfig {
 
-	@Bean
-	public MimetypesFileTypeMap mimetypesFileTypeMap() {
-		return new MimetypesFileTypeMap();
-	}
+  @Bean
+  public MimetypesFileTypeMap mimetypesFileTypeMap() {
+    return new MimetypesFileTypeMap();
+  }
+
+  @Bean
+  public AutoDetectParser autoDetectParser() {
+    return new AutoDetectParser();
+  }
 
-	@Bean
-	public AutoDetectParser autoDetectParser() {
-		return new AutoDetectParser();
-	}
+  @Bean
+  public BinaryDataResponseWriter binaryDataResponseWriter() {
+    return new BinaryDataResponseWriter();
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/MvcConfig.java b/src/main/java/com/epam/ta/reportportal/core/configs/MvcConfig.java
index f4248e49e6..2d084bd336 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/MvcConfig.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/MvcConfig.java
@@ -13,16 +13,27 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package com.epam.ta.reportportal.core.configs;
 
+import static com.google.common.base.Strings.isNullOrEmpty;
+
 import com.epam.ta.reportportal.commons.ExceptionMappings;
 import com.epam.ta.reportportal.commons.exception.forwarding.ClientResponseForwardingExceptionHandler;
 import com.epam.ta.reportportal.commons.exception.rest.DefaultErrorResolver;
 import com.epam.ta.reportportal.commons.exception.rest.ReportPortalExceptionResolver;
 import com.epam.ta.reportportal.commons.exception.rest.RestExceptionHandler;
-import com.epam.ta.reportportal.ws.resolver.*;
+import com.epam.ta.reportportal.ws.resolver.ActiveUserWebArgumentResolver;
+import com.epam.ta.reportportal.ws.resolver.FilterCriteriaResolver;
+import com.epam.ta.reportportal.ws.resolver.JsonViewSupportFactoryBean;
+import com.epam.ta.reportportal.ws.resolver.PagingHandlerMethodArgumentResolver;
+import com.epam.ta.reportportal.ws.resolver.PredefinedFilterCriteriaResolver;
+import com.epam.ta.reportportal.ws.resolver.SortArgumentResolver;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.base.Preconditions;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.List;
 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
@@ -49,11 +60,6 @@
 import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
-import java.util.Collections;
-import java.util.List;
-
-import static com.google.common.base.Strings.isNullOrEmpty;
-
 /**
  * Class-based Spring MVC Configuration
  *
@@ -63,169 +69,184 @@
 @EnableConfigurationProperties(MvcConfig.MultipartConfig.class)
 public class MvcConfig implements WebMvcConfigurer {
 
-	@Autowired
-	private ObjectMapper objectMapper;
-
-	@Autowired
-	private List<HttpMessageConverter<?>> converters;
-
-	private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/public/", "classpath:/META-INF/resources/",
-			"classpath:/resources/" };
-
-	@Override
-	public void addResourceHandlers(ResourceHandlerRegistry registry) {
-		if (!registry.hasMappingForPattern("/**")) {
-			registry.addResourceHandler("/**").addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS);
-		}
-		if (!registry.hasMappingForPattern("/webjars/**")) {
-			registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
-		}
-	}
-
-	@Bean
-	public SortArgumentResolver sortArgumentResolver() {
-		SortArgumentResolver argumentResolver = new SortArgumentResolver();
-		argumentResolver.setSortParameter("page.sort");
-		argumentResolver.setQualifierDelimiter("+");
-		return argumentResolver;
-	}
-
-	@Bean
-	public JsonViewSupportFactoryBean jsonViewSupportFactoryBean() {
-		return new JsonViewSupportFactoryBean();
-	}
-
-	@Override
-	public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
-		argumentResolvers.clear();
-		PagingHandlerMethodArgumentResolver pageableResolver = new PagingHandlerMethodArgumentResolver(sortArgumentResolver());
-		pageableResolver.setPrefix("page.");
-		pageableResolver.setOneIndexedParameters(true);
-
-		argumentResolvers.add(pageableResolver);
-
-		argumentResolvers.add(new ActiveUserWebArgumentResolver());
-		argumentResolvers.add(new FilterCriteriaResolver());
-		argumentResolvers.add(new PredefinedFilterCriteriaResolver());
-	}
-
-	@Override
-	public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
-		converters.clear();
-		converters.add(jsonConverter());
-		converters.add(stringConverter());
-	}
-
-	@Override
-	public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
-		/* to propagate exceptions from downstream services */
-		ClientResponseForwardingExceptionHandler forwardingExceptionHandler = new ClientResponseForwardingExceptionHandler();
-		forwardingExceptionHandler.setOrder(Ordered.HIGHEST_PRECEDENCE);
-		exceptionResolvers.add(forwardingExceptionHandler);
-
-		RestExceptionHandler handler = new RestExceptionHandler();
-		handler.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
-
-		DefaultErrorResolver defaultErrorResolver = new DefaultErrorResolver(ExceptionMappings.DEFAULT_MAPPING);
-		handler.setErrorResolver(new ReportPortalExceptionResolver(defaultErrorResolver));
-		handler.setMessageConverters(Collections.singletonList(jsonConverter()));
-		exceptionResolvers.add(handler);
-	}
-
-	@Override
-	public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
-		configurer.favorPathExtension(false);
-	}
-
-	@Override
-	public void configurePathMatch(PathMatchConfigurer configurer) {
-		configurer.setUseSuffixPatternMatch(false);
-	}
-
-	@Bean
-	public BeanValidationPostProcessor beanValidationPostProcessor() {
-		return new BeanValidationPostProcessor();
-	}
-
-	@Bean
-	public MappingJackson2HttpMessageConverter jsonConverter() {
-		return new MappingJackson2HttpMessageConverter(objectMapper);
-	}
-
-	@Bean
-	public StringHttpMessageConverter stringConverter() {
-		StringHttpMessageConverter converter = new StringHttpMessageConverter();
-		converter.setSupportedMediaTypes(Collections.singletonList(MediaType.TEXT_PLAIN));
-		return converter;
-	}
-
-	@Bean
-	HttpMessageConverters httpMessageConverters() {
-		return new HttpMessageConverters(converters);
-	}
-
-	@Profile("!unittest")
-	@Bean
-	@Order(0)
-	public MultipartFilter multipartFilter() {
-		MultipartFilter multipartFilter = new MultipartFilter();
-		multipartFilter.setMultipartResolverBeanName(DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME);
-		return multipartFilter;
-	}
-
-	@Profile("!unittest")
-	@Bean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME)
-	public CommonsMultipartResolver multipartResolver(MultipartConfig multipartConfig) {
-		CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver() {
-			@Override
-			protected DiskFileItemFactory newFileItemFactory() {
-				DiskFileItemFactory diskFileItemFactory = super.newFileItemFactory();
-				diskFileItemFactory.setFileCleaningTracker(null);
-				return diskFileItemFactory;
-			}
-
-			@Override
-			public void cleanupMultipart(MultipartHttpServletRequest request) {
-				//
-			}
-		};
-
-		//Lazy resolving gives a way to process file limits inside a controller
-		//level and handle exceptions in proper way. Fixes reportportal/reportportal#19
-		commonsMultipartResolver.setResolveLazily(true);
-
-		commonsMultipartResolver.setMaxUploadSize(multipartConfig.maxUploadSize);
-		commonsMultipartResolver.setMaxUploadSizePerFile(multipartConfig.maxFileSize);
-		return commonsMultipartResolver;
-	}
-
-	@ConfigurationProperties("rp.upload")
-	public static class MultipartConfig {
-		long maxUploadSize = 128L * 1024L * 1024L;
-		long maxFileSize = 128L * 1024L * 1024L;
-
-		public void setMaxUploadSize(String maxUploadSize) {
-			this.maxUploadSize = parseSize(maxUploadSize);
-		}
-
-		public void setMaxFileSize(String maxFileSize) {
-			this.maxFileSize = parseSize(maxFileSize);
-		}
-
-		private long parseSize(String size) {
-			Preconditions.checkArgument(!isNullOrEmpty(size), "Size must not be empty");
-			size = size.toUpperCase();
-			if (size.endsWith("KB")) {
-				return Long.parseLong(size.substring(0, size.length() - 2)) * 1024;
-			}
-			if (size.endsWith("MB")) {
-				return Long.parseLong(size.substring(0, size.length() - 2)) * 1024 * 1024;
-			}
-			if (size.endsWith("GB")) {
-				return Long.parseLong(size.substring(0, size.length() - 2)) * 1024 * 1024 * 1024;
-			}
-			return Long.parseLong(size);
-		}
-	}
+  @Autowired
+  private ObjectMapper objectMapper;
+
+  @Autowired
+  private List<HttpMessageConverter<?>> converters;
+
+  private static final String[] CLASSPATH_RESOURCE_LOCATIONS =
+      { "classpath:/public/", "classpath:/META-INF/resources/", "classpath:/resources/" };
+
+  @Override
+  public void addResourceHandlers(ResourceHandlerRegistry registry) {
+    if (!registry.hasMappingForPattern("/**")) {
+      registry.addResourceHandler("/**").addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS);
+    }
+    if (!registry.hasMappingForPattern("/webjars/**")) {
+      registry.addResourceHandler("/webjars/**")
+          .addResourceLocations("classpath:/META-INF/resources/webjars/");
+    }
+  }
+
+  @Bean
+  public SortArgumentResolver sortArgumentResolver() {
+    SortArgumentResolver argumentResolver = new SortArgumentResolver();
+    argumentResolver.setSortParameter("page.sort");
+    argumentResolver.setQualifierDelimiter("+");
+    return argumentResolver;
+  }
+
+  @Bean
+  public JsonViewSupportFactoryBean jsonViewSupportFactoryBean() {
+    return new JsonViewSupportFactoryBean();
+  }
+
+  @Override
+  public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
+    argumentResolvers.clear();
+    PagingHandlerMethodArgumentResolver pageableResolver =
+        new PagingHandlerMethodArgumentResolver(sortArgumentResolver());
+    pageableResolver.setPrefix("page.");
+    pageableResolver.setOneIndexedParameters(true);
+
+    argumentResolvers.add(pageableResolver);
+
+    argumentResolvers.add(new ActiveUserWebArgumentResolver());
+    argumentResolvers.add(new FilterCriteriaResolver());
+    argumentResolvers.add(new PredefinedFilterCriteriaResolver());
+  }
+
+  @Override
+  public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
+    converters.clear();
+    converters.add(jsonConverter());
+    converters.add(openMetricsTextStringConverter());
+    converters.add(stringConverter());
+  }
+
+  @Override
+  public void configureHandlerExceptionResolvers(
+      List<HandlerExceptionResolver> exceptionResolvers) {
+    /* to propagate exceptions from downstream services */
+    ClientResponseForwardingExceptionHandler forwardingExceptionHandler =
+        new ClientResponseForwardingExceptionHandler();
+    forwardingExceptionHandler.setOrder(Ordered.HIGHEST_PRECEDENCE);
+    exceptionResolvers.add(forwardingExceptionHandler);
+
+    RestExceptionHandler handler = new RestExceptionHandler();
+    handler.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
+
+    DefaultErrorResolver defaultErrorResolver =
+        new DefaultErrorResolver(ExceptionMappings.DEFAULT_MAPPING);
+    handler.setErrorResolver(new ReportPortalExceptionResolver(defaultErrorResolver));
+    handler.setMessageConverters(Collections.singletonList(jsonConverter()));
+    exceptionResolvers.add(handler);
+  }
+
+  @Override
+  public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
+    configurer.favorPathExtension(false);
+  }
+
+  @Override
+  public void configurePathMatch(PathMatchConfigurer configurer) {
+    configurer.setUseSuffixPatternMatch(false);
+  }
+
+  @Bean
+  public BeanValidationPostProcessor beanValidationPostProcessor() {
+    return new BeanValidationPostProcessor();
+  }
+
+  @Bean
+  public MappingJackson2HttpMessageConverter jsonConverter() {
+    return new MappingJackson2HttpMessageConverter(objectMapper);
+  }
+
+  @Bean
+  public StringHttpMessageConverter stringConverter() {
+    StringHttpMessageConverter converter = new StringHttpMessageConverter();
+    converter.setSupportedMediaTypes(Collections.singletonList(MediaType.TEXT_PLAIN));
+    return converter;
+  }
+
+  @Bean
+  public StringHttpMessageConverter openMetricsTextStringConverter() {
+    StringHttpMessageConverter converter = new StringHttpMessageConverter();
+    converter.setSupportedMediaTypes(Collections.singletonList(
+        new MediaType("application", "openmetrics-text", StandardCharsets.UTF_8)));
+    return converter;
+  }
+
+  @Bean
+  HttpMessageConverters httpMessageConverters() {
+    return new HttpMessageConverters(converters);
+  }
+
+  @Profile("!unittest")
+  @Bean
+  @Order(0)
+  public MultipartFilter multipartFilter() {
+    MultipartFilter multipartFilter = new MultipartFilter();
+    multipartFilter.setMultipartResolverBeanName(DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME);
+    return multipartFilter;
+  }
+
+  @Profile("!unittest")
+  @Bean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME)
+  public CommonsMultipartResolver multipartResolver(MultipartConfig multipartConfig) {
+    CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver() {
+      @Override
+      protected DiskFileItemFactory newFileItemFactory() {
+        DiskFileItemFactory diskFileItemFactory = super.newFileItemFactory();
+        diskFileItemFactory.setFileCleaningTracker(null);
+        return diskFileItemFactory;
+      }
+
+      @Override
+      public void cleanupMultipart(MultipartHttpServletRequest request) {
+        //
+      }
+    };
+
+    //Lazy resolving gives a way to process file limits inside a controller
+    //level and handle exceptions in proper way. Fixes reportportal/reportportal#19
+    commonsMultipartResolver.setResolveLazily(true);
+
+    commonsMultipartResolver.setMaxUploadSize(multipartConfig.maxUploadSize);
+    commonsMultipartResolver.setMaxUploadSizePerFile(multipartConfig.maxFileSize);
+    return commonsMultipartResolver;
+  }
+
+  @ConfigurationProperties("rp.upload")
+  public static class MultipartConfig {
+
+    long maxUploadSize = 128L * 1024L * 1024L;
+    long maxFileSize = 128L * 1024L * 1024L;
+
+    public void setMaxUploadSize(String maxUploadSize) {
+      this.maxUploadSize = parseSize(maxUploadSize);
+    }
+
+    public void setMaxFileSize(String maxFileSize) {
+      this.maxFileSize = parseSize(maxFileSize);
+    }
+
+    private long parseSize(String size) {
+      Preconditions.checkArgument(!isNullOrEmpty(size), "Size must not be empty");
+      size = size.toUpperCase();
+      if (size.endsWith("KB")) {
+        return Long.parseLong(size.substring(0, size.length() - 2)) * 1024;
+      }
+      if (size.endsWith("MB")) {
+        return Long.parseLong(size.substring(0, size.length() - 2)) * 1024 * 1024;
+      }
+      if (size.endsWith("GB")) {
+        return Long.parseLong(size.substring(0, size.length() - 2)) * 1024 * 1024 * 1024;
+      }
+      return Long.parseLong(size);
+    }
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/PluginConfiguration.java b/src/main/java/com/epam/ta/reportportal/core/configs/PluginConfiguration.java
index 933df708cb..08d97e97db 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/PluginConfiguration.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/PluginConfiguration.java
@@ -16,105 +16,134 @@
 
 package com.epam.ta.reportportal.core.configs;
 
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.core.integration.plugin.PluginLoader;
+import com.epam.ta.reportportal.core.integration.plugin.binary.PluginFilesProvider;
 import com.epam.ta.reportportal.core.plugin.Pf4jPluginBox;
 import com.epam.ta.reportportal.dao.IntegrationTypeRepository;
 import com.epam.ta.reportportal.plugin.Pf4jPluginManager;
 import com.epam.ta.reportportal.plugin.ReportPortalExtensionFactory;
-import org.pf4j.*;
+import java.io.IOException;
+import java.nio.file.Paths;
+import java.util.Collections;
+import java.util.Set;
+import javax.activation.FileTypeMap;
+import org.pf4j.DefaultExtensionFinder;
+import org.pf4j.DefaultPluginManager;
+import org.pf4j.ExtensionFactory;
+import org.pf4j.ExtensionFinder;
+import org.pf4j.LegacyExtensionFinder;
+import org.pf4j.ManifestPluginDescriptorFinder;
+import org.pf4j.PluginDescriptorFinder;
+import org.pf4j.PluginManager;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
 import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
-
-import java.io.IOException;
-import java.nio.file.Paths;
-import java.util.Collections;
-import java.util.Set;
-
-import static java.util.Optional.ofNullable;
+import org.springframework.mail.javamail.ConfigurableMimeFileTypeMap;
 
 @Configuration
 public class PluginConfiguration {
 
-	@Autowired
-	private AutowireCapableBeanFactory context;
-
-	@Autowired
-	private PluginLoader pluginLoader;
-
-	@Autowired
-	private IntegrationTypeRepository integrationTypeRepository;
-
-	@Autowired
-	private ApplicationEventPublisher applicationEventPublisher;
-
-	@Value("${rp.plugins.path}")
-	private String pluginsPath;
-
-	@Value("${rp.plugins.temp.path}")
-	private String pluginsTempPath;
-
-	@Value("${rp.plugins.resources.path}")
-	private String pluginsResourcesPath;
-
-	@Bean
-	public Pf4jPluginBox pf4jPluginBox() throws IOException {
-		Pf4jPluginManager pluginManager = new Pf4jPluginManager(pluginsPath,
-				pluginsTempPath,
-				pluginsResourcesPath,
-				pluginLoader,
-				integrationTypeRepository,
-				pluginManager(),
-				context,
-				applicationEventPublisher
-		);
-		pluginManager.startUp();
-		return pluginManager;
-	}
-
-	@Bean
-	public PluginManager pluginManager() {
-
-		return new DefaultPluginManager(Paths.get(pluginsPath)) {
-			@Override
-			protected PluginDescriptorFinder createPluginDescriptorFinder() {
-				return pluginDescriptorFinder();
-			}
-
-			@Override
-			protected ExtensionFactory createExtensionFactory() {
-				return new ReportPortalExtensionFactory(pluginsResourcesPath, this, context);
-			}
-
-			@Override
-			protected ExtensionFinder createExtensionFinder() {
-				RpExtensionFinder extensionFinder = new RpExtensionFinder(this);
-				addPluginStateListener(extensionFinder);
-				return extensionFinder;
-			}
-
-			class RpExtensionFinder extends DefaultExtensionFinder {
-
-				private RpExtensionFinder(PluginManager pluginManager) {
-					super(pluginManager);
-					finders.clear();
-					finders.add(new LegacyExtensionFinder(pluginManager) {
-						@Override
-						public Set<String> findClassNames(String pluginId) {
-							return ofNullable(super.findClassNames(pluginId)).orElseGet(Collections::emptySet);
-						}
-					});
-				}
-			}
-		};
-	}
-
-	@Bean
-	public PluginDescriptorFinder pluginDescriptorFinder() {
-		return new ManifestPluginDescriptorFinder();
-	}
+  @Autowired
+  private AutowireCapableBeanFactory context;
+
+  @Autowired
+  private PluginLoader pluginLoader;
+
+  @Autowired
+  private IntegrationTypeRepository integrationTypeRepository;
+
+  @Autowired
+  private ApplicationEventPublisher applicationEventPublisher;
+
+  @Value("${rp.plugins.path}")
+  private String pluginsPath;
+
+  @Value("${rp.plugins.temp.path}")
+  private String pluginsTempPath;
+
+  @Value("${rp.plugins.resources.path}")
+  private String pluginsResourcesPath;
+
+  @Value("${rp.plugins.resources.public}")
+  private String publicFolderQualifier;
+
+  @Bean
+  public Pf4jPluginBox pf4jPluginBox() throws IOException {
+    Pf4jPluginManager pluginManager = new Pf4jPluginManager(pluginsPath,
+        pluginsTempPath,
+        pluginsResourcesPath,
+        pluginLoader,
+        integrationTypeRepository,
+        pluginManager(),
+        context,
+        applicationEventPublisher
+    );
+    pluginManager.startUp();
+    return pluginManager;
+  }
+
+  @Bean
+  public PluginManager pluginManager() {
+
+    return new DefaultPluginManager(Paths.get(pluginsPath)) {
+      @Override
+      protected PluginDescriptorFinder createPluginDescriptorFinder() {
+        return pluginDescriptorFinder();
+      }
+
+      @Override
+      protected ExtensionFactory createExtensionFactory() {
+        return new ReportPortalExtensionFactory(pluginsResourcesPath, this, context);
+      }
+
+      @Override
+      protected ExtensionFinder createExtensionFinder() {
+        RpExtensionFinder extensionFinder = new RpExtensionFinder(this);
+        addPluginStateListener(extensionFinder);
+        return extensionFinder;
+      }
+
+      class RpExtensionFinder extends DefaultExtensionFinder {
+
+        private RpExtensionFinder(PluginManager pluginManager) {
+          super(pluginManager);
+          finders.clear();
+          finders.add(new LegacyExtensionFinder(pluginManager) {
+            @Override
+            public Set<String> findClassNames(String pluginId) {
+              return ofNullable(super.findClassNames(pluginId)).orElseGet(Collections::emptySet);
+            }
+          });
+        }
+      }
+    };
+  }
+
+  @Bean
+  public PluginDescriptorFinder pluginDescriptorFinder() {
+    return new ManifestPluginDescriptorFinder();
+  }
+
+  @Bean
+  public FileTypeMap fileTypeMap() {
+    return new ConfigurableMimeFileTypeMap();
+  }
+
+  @Bean
+  public PluginFilesProvider pluginPublicFilesProvider() {
+    return new PluginFilesProvider(pluginsResourcesPath, publicFolderQualifier, fileTypeMap(),
+        integrationTypeRepository);
+  }
+
+  @Bean
+  public PluginFilesProvider pluginFilesProvider() {
+    return new PluginFilesProvider(pluginsResourcesPath, "", fileTypeMap(),
+        integrationTypeRepository);
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/ProjectValidationConfig.java b/src/main/java/com/epam/ta/reportportal/core/configs/ProjectValidationConfig.java
index bedc74316f..d21e156d2b 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/ProjectValidationConfig.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/ProjectValidationConfig.java
@@ -4,27 +4,27 @@
 import com.epam.ta.reportportal.core.project.validator.attribute.DelayBoundValidator;
 import com.epam.ta.reportportal.core.project.validator.attribute.ProjectAttributeValidator;
 import com.epam.ta.reportportal.entity.enums.ProjectAttributeEnum;
+import java.util.List;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
-import java.util.List;
-
 @Configuration
 public class ProjectValidationConfig {
 
-	@Bean
-	public DelayBoundValidator delayBoundValidator() {
-		return new DelayBoundValidator(getDelayBoundRules());
-	}
+  @Bean
+  public DelayBoundValidator delayBoundValidator() {
+    return new DelayBoundValidator(getDelayBoundRules());
+  }
 
-	private List<DelayBoundLessRule> getDelayBoundRules() {
-		return List.of(new DelayBoundLessRule(ProjectAttributeEnum.KEEP_SCREENSHOTS, ProjectAttributeEnum.KEEP_LOGS),
-				new DelayBoundLessRule(ProjectAttributeEnum.KEEP_LOGS, ProjectAttributeEnum.KEEP_LAUNCHES)
-		);
-	}
+  private List<DelayBoundLessRule> getDelayBoundRules() {
+    return List.of(new DelayBoundLessRule(ProjectAttributeEnum.KEEP_SCREENSHOTS,
+            ProjectAttributeEnum.KEEP_LOGS),
+        new DelayBoundLessRule(ProjectAttributeEnum.KEEP_LOGS, ProjectAttributeEnum.KEEP_LAUNCHES)
+    );
+  }
 
-	@Bean
-	public ProjectAttributeValidator projectAttributeValidator() {
-		return new ProjectAttributeValidator(delayBoundValidator());
-	}
+  @Bean
+  public ProjectAttributeValidator projectAttributeValidator() {
+    return new ProjectAttributeValidator(delayBoundValidator());
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/ReportPortalApp.java b/src/main/java/com/epam/ta/reportportal/core/configs/ReportPortalApp.java
index 979929cda3..26ba489a01 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/ReportPortalApp.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/ReportPortalApp.java
@@ -27,14 +27,15 @@
  *
  * @author Andrei Varabyeu
  */
-@SpringBootApplication(scanBasePackages = { "com.epam.ta.reportportal", "com.epam.reportportal" }, exclude = {
-		MultipartAutoConfiguration.class, FlywayAutoConfiguration.class })
+@SpringBootApplication(scanBasePackages = {"com.epam.ta.reportportal",
+    "com.epam.reportportal"}, exclude = {
+    MultipartAutoConfiguration.class, FlywayAutoConfiguration.class})
 @Configuration
-@Import({ com.epam.ta.reportportal.config.DatabaseConfiguration.class })
+@Import({com.epam.ta.reportportal.config.DatabaseConfiguration.class})
 public class ReportPortalApp {
 
-	public static void main(String[] args) {
-		SpringApplication.run(ReportPortalApp.class, args);
-	}
+  public static void main(String[] args) {
+    SpringApplication.run(ReportPortalApp.class, args);
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/ReportPortalClassLoadHelper.java b/src/main/java/com/epam/ta/reportportal/core/configs/ReportPortalClassLoadHelper.java
index 907fc7bd1c..460b0eab5c 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/ReportPortalClassLoadHelper.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/ReportPortalClassLoadHelper.java
@@ -12,36 +12,37 @@
  */
 public class ReportPortalClassLoadHelper extends ResourceLoaderClassLoadHelper {
 
-	@Nullable
-	private ResourceLoader resourceLoader;
-
-	public ReportPortalClassLoadHelper() {
-	}
-
-	public ReportPortalClassLoadHelper(@Nullable ResourceLoader resourceLoader) {
-		this.resourceLoader = resourceLoader;
-	}
-
-	@Override
-	public void initialize() {
-		super.initialize();
-		if (this.resourceLoader == null) {
-			this.resourceLoader = SchedulerFactoryBean.getConfigTimeResourceLoader();
-			if (this.resourceLoader == null) {
-				this.resourceLoader = new DefaultResourceLoader();
-			}
-		}
-	}
-
-	@Override
-	public Class<?> loadClass(String name) throws ClassNotFoundException {
-		Assert.state(this.resourceLoader != null, "ResourceLoaderClassLoadHelper not initialized");
-		return this.resourceLoader.getClassLoader().loadClass(name);
-	}
-
-	@SuppressWarnings("unchecked")
-	@Override
-	public <T> Class<? extends T> loadClass(String name, Class<T> clazz) throws ClassNotFoundException {
-		return (Class<? extends T>) loadClass(name);
-	}
+  @Nullable
+  private ResourceLoader resourceLoader;
+
+  public ReportPortalClassLoadHelper() {
+  }
+
+  public ReportPortalClassLoadHelper(@Nullable ResourceLoader resourceLoader) {
+    this.resourceLoader = resourceLoader;
+  }
+
+  @Override
+  public void initialize() {
+    super.initialize();
+    if (this.resourceLoader == null) {
+      this.resourceLoader = SchedulerFactoryBean.getConfigTimeResourceLoader();
+      if (this.resourceLoader == null) {
+        this.resourceLoader = new DefaultResourceLoader();
+      }
+    }
+  }
+
+  @Override
+  public Class<?> loadClass(String name) throws ClassNotFoundException {
+    Assert.state(this.resourceLoader != null, "ResourceLoaderClassLoadHelper not initialized");
+    return this.resourceLoader.getClassLoader().loadClass(name);
+  }
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public <T> Class<? extends T> loadClass(String name, Class<T> clazz)
+      throws ClassNotFoundException {
+    return (Class<? extends T>) loadClass(name);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/SchedulerConfiguration.java b/src/main/java/com/epam/ta/reportportal/core/configs/SchedulerConfiguration.java
index 9f621912db..a994945398 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/SchedulerConfiguration.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/SchedulerConfiguration.java
@@ -16,7 +16,14 @@
 package com.epam.ta.reportportal.core.configs;
 
 import com.epam.reportportal.extension.classloader.ReportPortalResourceLoader;
-import com.epam.ta.reportportal.job.*;
+import com.epam.ta.reportportal.job.CleanExpiredCreationBidsJob;
+import com.epam.ta.reportportal.job.FlushingDataJob;
+import com.epam.ta.reportportal.job.InterruptBrokenLaunchesJob;
+import java.time.Duration;
+import java.util.List;
+import java.util.Properties;
+import javax.inject.Named;
+import javax.sql.DataSource;
 import org.quartz.Job;
 import org.quartz.JobDetail;
 import org.quartz.SimpleTrigger;
@@ -27,166 +34,173 @@
 import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.context.annotation.*;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Conditional;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.context.annotation.Profile;
 import org.springframework.core.io.ResourceLoader;
-import org.springframework.scheduling.quartz.*;
+import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
+import org.springframework.scheduling.quartz.JobDetailFactoryBean;
+import org.springframework.scheduling.quartz.SchedulerFactoryBean;
+import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;
+import org.springframework.scheduling.quartz.SpringBeanJobFactory;
 import org.springframework.transaction.PlatformTransactionManager;
 
-import javax.inject.Named;
-import javax.sql.DataSource;
-import java.time.Duration;
-import java.util.List;
-import java.util.Properties;
-
 @Configuration
 @Conditional(Conditions.NotTestCondition.class)
-@EnableConfigurationProperties({ SchedulerConfiguration.QuartzProperties.class })
+@EnableConfigurationProperties({SchedulerConfiguration.QuartzProperties.class})
 public class SchedulerConfiguration {
 
-	@Autowired
-	List<Trigger> listOfTrigger;
-
-	@Autowired
-	private QuartzProperties quartzProperties;
-
-	@Autowired
-	private AutowireCapableBeanFactory context;
-
-	@Autowired
-	private DataSource dataSource;
-
-	@Autowired
-	private PlatformTransactionManager transactionManager;
-
-	@Autowired
-	private ReportPortalResourceLoader resourceLoader;
-
-	@Bean
-	@Primary
-	public SchedulerFactoryBean schedulerFactoryBean() {
-		SchedulerFactoryBean scheduler = new SchedulerFactoryBean() {
-			@Override
-			public void setResourceLoader(ResourceLoader resourceLoader) {
-				if (this.resourceLoader == null) {
-					super.setResourceLoader(resourceLoader);
-				}
-			}
-		};
-		scheduler.setApplicationContextSchedulerContextKey("applicationContext");
-
-		scheduler.setOverwriteExistingJobs(true);
-		scheduler.setResourceLoader(resourceLoader);
-		scheduler.setQuartzProperties(quartzProperties.getQuartz());
-		scheduler.setDataSource(dataSource);
-		scheduler.setTransactionManager(transactionManager);
-		scheduler.setAutoStartup(true);  // to not automatically start after startup
-		scheduler.setWaitForJobsToCompleteOnShutdown(true);
-		scheduler.setJobFactory(beanJobFactory());
-
-		// Here we will set all the trigger beans we have defined.
-		if (null != listOfTrigger && !listOfTrigger.isEmpty()) {
-			scheduler.setTriggers(listOfTrigger.toArray(new Trigger[listOfTrigger.size()]));
-		}
-
-		return scheduler;
-	}
-
-	@Bean
-	public SpringBeanJobFactory beanJobFactory() {
-		return new SpringBeanJobFactory() {
-			@Override
-			protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
-				final Object jobInstance = super.createJobInstance(bundle);
-				context.autowireBean(jobInstance);
-				return jobInstance;
-			}
-		};
-	}
-
-	@Bean
-	public SimpleTriggerFactoryBean interruptLaunchesTrigger(@Named("interruptLaunchesJobBean") JobDetail jobDetail,
-			@Value("${com.ta.reportportal.job.interrupt.broken.launches.cron}") String interruptLaunchesCron) {
-		return createTriggerDelayed(jobDetail, Duration.parse(interruptLaunchesCron).toMillis());
-	}
-
-	@Bean
-	public SimpleTriggerFactoryBean cleanExpiredCreationBidsTrigger(@Named("cleanExpiredCreationBidsJobBean") JobDetail jobDetail,
-			@Value("${com.ta.reportportal.job.clean.bids.cron}") String cleanBidsCron) {
-		return createTrigger(jobDetail, Duration.parse(cleanBidsCron).toMillis());
-	}
-
-	@Bean
-	@Profile("demo")
-	public SimpleTriggerFactoryBean flushingDataTrigger(@Named("flushingDataJob") JobDetail jobDetail,
-			@Value("${com.ta.reportportal.rp.flushing.time.cron}") String flushingCron) {
-		return createTrigger(jobDetail, Duration.parse(flushingCron).toMillis());
-	}
-
-	@Bean("interruptLaunchesJobBean")
-	public JobDetailFactoryBean interruptLaunchesJob() {
-		return createJobDetail(InterruptBrokenLaunchesJob.class);
-	}
-
-	@Bean("cleanExpiredCreationBidsJobBean")
-	public JobDetailFactoryBean cleanExpiredCreationBidsJob() {
-		return createJobDetail(CleanExpiredCreationBidsJob.class);
-	}
-
-	@Bean
-	@Profile("demo")
-	@Named("flushingDataJob")
-	public JobDetailFactoryBean flushingDataJob() {
-		return createJobDetail(FlushingDataJob.class);
-	}
-
-	public SimpleTriggerFactoryBean createTrigger(JobDetail jobDetail, long pollFrequencyMs) {
-		SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
-		factoryBean.setJobDetail(jobDetail);
-		factoryBean.setStartDelay(0L);
-		factoryBean.setRepeatInterval(pollFrequencyMs);
-		factoryBean.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
-		// in case of misfire, ignore all missed triggers and continue :
-		factoryBean.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT);
-		return factoryBean;
-	}
-
-	public SimpleTriggerFactoryBean createTriggerDelayed(JobDetail jobDetail, long pollFrequencyMs) {
-		SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
-		factoryBean.setJobDetail(jobDetail);
-		factoryBean.setStartDelay(pollFrequencyMs);
-		factoryBean.setRepeatInterval(pollFrequencyMs);
-		factoryBean.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
-		// in case of misfire, ignore all missed triggers and continue :
-		factoryBean.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT);
-		return factoryBean;
-	}
-
-	// Use this method for creating cron triggers instead of simple triggers:
-	public static CronTriggerFactoryBean createCronTrigger(JobDetail jobDetail, String cronExpression) {
-		CronTriggerFactoryBean factoryBean = new CronTriggerFactoryBean();
-		factoryBean.setJobDetail(jobDetail);
-		factoryBean.setCronExpression(cronExpression);
-		factoryBean.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_FIRE_NOW);
-		return factoryBean;
-	}
-
-	public static JobDetailFactoryBean createJobDetail(Class<? extends Job> jobClass) {
-		JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();
-		factoryBean.setJobClass(jobClass);
-		// job has to be durable to be stored in DB:
-		factoryBean.setDurability(true);
-		return factoryBean;
-	}
-
-	@ConfigurationProperties("spring.application")
-	public static class QuartzProperties {
-
-		private final Properties quartz = new Properties();
-
-		public Properties getQuartz() {
-			return quartz;
-		}
-
-	}
+  @Autowired
+  List<Trigger> listOfTrigger;
+
+  @Autowired
+  private QuartzProperties quartzProperties;
+
+  @Autowired
+  private AutowireCapableBeanFactory context;
+
+  @Autowired
+  private DataSource dataSource;
+
+  @Autowired
+  private PlatformTransactionManager transactionManager;
+
+  @Autowired
+  private ReportPortalResourceLoader resourceLoader;
+
+  @Bean
+  @Primary
+  public SchedulerFactoryBean schedulerFactoryBean() {
+    SchedulerFactoryBean scheduler = new SchedulerFactoryBean() {
+      @Override
+      public void setResourceLoader(ResourceLoader resourceLoader) {
+        if (this.resourceLoader == null) {
+          super.setResourceLoader(resourceLoader);
+        }
+      }
+    };
+    scheduler.setApplicationContextSchedulerContextKey("applicationContext");
+
+    scheduler.setOverwriteExistingJobs(true);
+    scheduler.setResourceLoader(resourceLoader);
+    scheduler.setQuartzProperties(quartzProperties.getQuartz());
+    scheduler.setDataSource(dataSource);
+    scheduler.setTransactionManager(transactionManager);
+    scheduler.setAutoStartup(true);  // to not automatically start after startup
+    scheduler.setWaitForJobsToCompleteOnShutdown(true);
+    scheduler.setJobFactory(beanJobFactory());
+
+    // Here we will set all the trigger beans we have defined.
+    if (null != listOfTrigger && !listOfTrigger.isEmpty()) {
+      scheduler.setTriggers(listOfTrigger.toArray(new Trigger[listOfTrigger.size()]));
+    }
+
+    return scheduler;
+  }
+
+  @Bean
+  public SpringBeanJobFactory beanJobFactory() {
+    return new SpringBeanJobFactory() {
+      @Override
+      protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
+        final Object jobInstance = super.createJobInstance(bundle);
+        context.autowireBean(jobInstance);
+        return jobInstance;
+      }
+    };
+  }
+
+  @Bean
+  public SimpleTriggerFactoryBean interruptLaunchesTrigger(
+      @Named("interruptLaunchesJobBean") JobDetail jobDetail,
+      @Value("${com.ta.reportportal.job.interrupt.broken.launches.cron}") String interruptLaunchesCron) {
+    return createTriggerDelayed(jobDetail, Duration.parse(interruptLaunchesCron).toMillis());
+  }
+
+  @Bean
+  public SimpleTriggerFactoryBean cleanExpiredCreationBidsTrigger(
+      @Named("cleanExpiredCreationBidsJobBean") JobDetail jobDetail,
+      @Value("${com.ta.reportportal.job.clean.bids.cron}") String cleanBidsCron) {
+    return createTrigger(jobDetail, Duration.parse(cleanBidsCron).toMillis());
+  }
+
+  @Bean
+  @Profile("demo")
+  public SimpleTriggerFactoryBean flushingDataTrigger(@Named("flushingDataJob") JobDetail jobDetail,
+      @Value("${com.ta.reportportal.rp.flushing.time.cron}") String flushingCron) {
+    return createTrigger(jobDetail, Duration.parse(flushingCron).toMillis());
+  }
+
+  @Bean("interruptLaunchesJobBean")
+  public JobDetailFactoryBean interruptLaunchesJob() {
+    return createJobDetail(InterruptBrokenLaunchesJob.class);
+  }
+
+  @Bean("cleanExpiredCreationBidsJobBean")
+  public JobDetailFactoryBean cleanExpiredCreationBidsJob() {
+    return createJobDetail(CleanExpiredCreationBidsJob.class);
+  }
+
+  @Bean
+  @Profile("demo")
+  @Named("flushingDataJob")
+  public JobDetailFactoryBean flushingDataJob() {
+    return createJobDetail(FlushingDataJob.class);
+  }
+
+  public SimpleTriggerFactoryBean createTrigger(JobDetail jobDetail, long pollFrequencyMs) {
+    SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
+    factoryBean.setJobDetail(jobDetail);
+    factoryBean.setStartDelay(0L);
+    factoryBean.setRepeatInterval(pollFrequencyMs);
+    factoryBean.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
+    // in case of misfire, ignore all missed triggers and continue :
+    factoryBean.setMisfireInstruction(
+        SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT);
+    return factoryBean;
+  }
+
+  public SimpleTriggerFactoryBean createTriggerDelayed(JobDetail jobDetail, long pollFrequencyMs) {
+    SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
+    factoryBean.setJobDetail(jobDetail);
+    factoryBean.setStartDelay(pollFrequencyMs);
+    factoryBean.setRepeatInterval(pollFrequencyMs);
+    factoryBean.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
+    // in case of misfire, ignore all missed triggers and continue :
+    factoryBean.setMisfireInstruction(
+        SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT);
+    return factoryBean;
+  }
+
+  // Use this method for creating cron triggers instead of simple triggers:
+  public static CronTriggerFactoryBean createCronTrigger(JobDetail jobDetail,
+      String cronExpression) {
+    CronTriggerFactoryBean factoryBean = new CronTriggerFactoryBean();
+    factoryBean.setJobDetail(jobDetail);
+    factoryBean.setCronExpression(cronExpression);
+    factoryBean.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_FIRE_NOW);
+    return factoryBean;
+  }
+
+  public static JobDetailFactoryBean createJobDetail(Class<? extends Job> jobClass) {
+    JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();
+    factoryBean.setJobClass(jobClass);
+    // job has to be durable to be stored in DB:
+    factoryBean.setDurability(true);
+    return factoryBean;
+  }
+
+  @ConfigurationProperties("spring.application")
+  public static class QuartzProperties {
+
+    private final Properties quartz = new Properties();
+
+    public Properties getQuartz() {
+      return quartz;
+    }
+
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/SecurityConfiguration.java b/src/main/java/com/epam/ta/reportportal/core/configs/SecurityConfiguration.java
index 4e17b0a5ce..a118981afe 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/SecurityConfiguration.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/SecurityConfiguration.java
@@ -22,6 +22,8 @@
 import com.epam.ta.reportportal.dao.ServerSettingsRepository;
 import com.epam.ta.reportportal.entity.ServerSettings;
 import com.google.common.collect.Lists;
+import java.util.List;
+import java.util.Optional;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Bean;
@@ -53,9 +55,6 @@
 import org.springframework.security.web.access.expression.WebExpressionVoter;
 import org.springframework.util.StringUtils;
 
-import java.util.List;
-import java.util.Optional;
-
 /**
  * Spring's Security Configuration
  *
@@ -64,147 +63,149 @@
 @Configuration
 class SecurityConfiguration {
 
-	@Bean
-	public PermissionEvaluatorFactoryBean permissionEvaluator() {
-		return new PermissionEvaluatorFactoryBean();
-	}
-
-	@Bean
-	public PasswordEncoder passwordEncoder() {
-		return new BCryptPasswordEncoder();
-	}
-
-	@Configuration
-	@EnableGlobalMethodSecurity(proxyTargetClass = true, prePostEnabled = true)
-	public static class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
-
-		@Autowired
-		private RoleHierarchy roleHierarchy;
-
-		@Autowired
-		private PermissionEvaluator permissionEvaluator;
-
-		@Override
-		protected MethodSecurityExpressionHandler createExpressionHandler() {
-			DefaultMethodSecurityExpressionHandler handler = new DefaultMethodSecurityExpressionHandler();
-			handler.setRoleHierarchy(roleHierarchy);
-			handler.setPermissionEvaluator(permissionEvaluator);
-			return handler;
-		}
-
-	}
-
-	@Configuration
-	@EnableResourceServer
-	public static class SecurityServerConfiguration extends ResourceServerConfigurerAdapter {
-
-		private static final String SECRET_KEY = "secret.key";
-
-		@Value("${rp.jwt.signing-key}")
-		private String signingKey;
-
-		@Autowired
-		private PermissionEvaluator permissionEvaluator;
-
-		@Autowired
-		private DatabaseUserDetailsService userDetailsService;
-
-		@Autowired
-		private ServerSettingsRepository serverSettingsRepository;
-
-		@Bean
-		public static PermissionEvaluatorFactoryBean permissionEvaluatorFactoryBean() {
-			return new PermissionEvaluatorFactoryBean();
-		}
-
-		@Bean
-		public static RoleHierarchy userRoleHierarchy() {
-			return new UserRoleHierarchy();
-		}
-
-		@Bean
-		public TokenStore tokenStore() {
-			return new CombinedTokenStore(accessTokenConverter());
-		}
-
-		@Bean
-		@Profile("!unittest")
-		public JwtAccessTokenConverter accessTokenConverter() {
-			JwtAccessTokenConverter jwtConverter = new JwtAccessTokenConverter();
-			jwtConverter.setSigningKey(getSecret());
-
-			DefaultAccessTokenConverter accessTokenConverter = new DefaultAccessTokenConverter();
-			DefaultUserAuthenticationConverter defaultUserAuthenticationConverter = new DefaultUserAuthenticationConverter();
-			defaultUserAuthenticationConverter.setUserDetailsService(userDetailsService);
-			accessTokenConverter.setUserTokenConverter(defaultUserAuthenticationConverter);
-
-			jwtConverter.setAccessTokenConverter(accessTokenConverter);
-
-			return jwtConverter;
-		}
-
-		private String getSecret() {
-			if (!StringUtils.isEmpty(signingKey)) {
-				return signingKey;
-			}
-			Optional<ServerSettings> secretKey = serverSettingsRepository.findByKey(SECRET_KEY);
-			return secretKey.isPresent() ? secretKey.get().getValue() : serverSettingsRepository.generateSecret();
-		}
-
-		@Bean
-		@Primary
-		public DefaultTokenServices tokenServices() {
-			DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
-			defaultTokenServices.setTokenStore(tokenStore());
-			defaultTokenServices.setSupportRefreshToken(true);
-			defaultTokenServices.setTokenEnhancer(accessTokenConverter());
-			return defaultTokenServices;
-		}
-
-		private DefaultWebSecurityExpressionHandler webSecurityExpressionHandler() {
-			OAuth2WebSecurityExpressionHandler handler = new OAuth2WebSecurityExpressionHandler();
-			handler.setRoleHierarchy(userRoleHierarchy());
-			handler.setPermissionEvaluator(permissionEvaluator);
-			return handler;
-		}
-
-		private AccessDecisionManager webAccessDecisionManager() {
-			List<AccessDecisionVoter<?>> accessDecisionVoters = Lists.newArrayList();
-			accessDecisionVoters.add(new AuthenticatedVoter());
-			WebExpressionVoter webVoter = new WebExpressionVoter();
-			webVoter.setExpressionHandler(webSecurityExpressionHandler());
-			accessDecisionVoters.add(webVoter);
-
-			return new AffirmativeBased(accessDecisionVoters);
-		}
-
-		@Override
-		public void configure(HttpSecurity http) throws Exception {
-			http.authorizeRequests()
-					.accessDecisionManager(webAccessDecisionManager())
-					.antMatchers("/**/user/registration/info*",
-							"/**/user/registration**",
-							"/**/user/password/reset/*",
-							"/**/user/password/reset**",
-							"/**/user/password/restore**",
-							"/documentation.html",
-							"/health",
-							"/info"
-					)
-					.permitAll()
-					/* set of special endpoints for another microservices from RP ecosystem */
-					.antMatchers("/api-internal/**")
-					.hasRole("COMPONENT")
-					.antMatchers("/v2/**", "/swagger-resources", "/certificate/**", "/api/**", "/**")
-					.hasRole("USER")
-					.anyRequest()
-					.authenticated()
-					.and()
-					.csrf()
-					.disable();
-		}
-
-	}
+  @Bean
+  public PermissionEvaluatorFactoryBean permissionEvaluator() {
+    return new PermissionEvaluatorFactoryBean();
+  }
+
+  @Bean
+  public PasswordEncoder passwordEncoder() {
+    return new BCryptPasswordEncoder();
+  }
+
+  @Configuration
+  @EnableGlobalMethodSecurity(proxyTargetClass = true, prePostEnabled = true)
+  public static class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
+
+    @Autowired
+    private RoleHierarchy roleHierarchy;
+
+    @Autowired
+    private PermissionEvaluator permissionEvaluator;
+
+    @Override
+    protected MethodSecurityExpressionHandler createExpressionHandler() {
+      DefaultMethodSecurityExpressionHandler handler = new DefaultMethodSecurityExpressionHandler();
+      handler.setRoleHierarchy(roleHierarchy);
+      handler.setPermissionEvaluator(permissionEvaluator);
+      return handler;
+    }
+
+  }
+
+  @Configuration
+  @EnableResourceServer
+  public static class SecurityServerConfiguration extends ResourceServerConfigurerAdapter {
+
+    private static final String SECRET_KEY = "secret.key";
+
+    @Value("${rp.jwt.signing-key}")
+    private String signingKey;
+
+    @Autowired
+    private PermissionEvaluator permissionEvaluator;
+
+    @Autowired
+    private DatabaseUserDetailsService userDetailsService;
+
+    @Autowired
+    private ServerSettingsRepository serverSettingsRepository;
+
+    @Bean
+    public static PermissionEvaluatorFactoryBean permissionEvaluatorFactoryBean() {
+      return new PermissionEvaluatorFactoryBean();
+    }
+
+    @Bean
+    public static RoleHierarchy userRoleHierarchy() {
+      return new UserRoleHierarchy();
+    }
+
+    @Bean
+    public TokenStore tokenStore() {
+      return new CombinedTokenStore(accessTokenConverter());
+    }
+
+    @Bean
+    @Profile("!unittest")
+    public JwtAccessTokenConverter accessTokenConverter() {
+      JwtAccessTokenConverter jwtConverter = new JwtAccessTokenConverter();
+      jwtConverter.setSigningKey(getSecret());
+
+      DefaultAccessTokenConverter accessTokenConverter = new DefaultAccessTokenConverter();
+      DefaultUserAuthenticationConverter defaultUserAuthenticationConverter = new DefaultUserAuthenticationConverter();
+      defaultUserAuthenticationConverter.setUserDetailsService(userDetailsService);
+      accessTokenConverter.setUserTokenConverter(defaultUserAuthenticationConverter);
+
+      jwtConverter.setAccessTokenConverter(accessTokenConverter);
+
+      return jwtConverter;
+    }
+
+    private String getSecret() {
+      if (!StringUtils.isEmpty(signingKey)) {
+        return signingKey;
+      }
+      Optional<ServerSettings> secretKey = serverSettingsRepository.findByKey(SECRET_KEY);
+      return secretKey.isPresent() ? secretKey.get().getValue()
+          : serverSettingsRepository.generateSecret();
+    }
+
+    @Bean
+    @Primary
+    public DefaultTokenServices tokenServices() {
+      DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
+      defaultTokenServices.setTokenStore(tokenStore());
+      defaultTokenServices.setSupportRefreshToken(true);
+      defaultTokenServices.setTokenEnhancer(accessTokenConverter());
+      return defaultTokenServices;
+    }
+
+    private DefaultWebSecurityExpressionHandler webSecurityExpressionHandler() {
+      OAuth2WebSecurityExpressionHandler handler = new OAuth2WebSecurityExpressionHandler();
+      handler.setRoleHierarchy(userRoleHierarchy());
+      handler.setPermissionEvaluator(permissionEvaluator);
+      return handler;
+    }
+
+    private AccessDecisionManager webAccessDecisionManager() {
+      List<AccessDecisionVoter<?>> accessDecisionVoters = Lists.newArrayList();
+      accessDecisionVoters.add(new AuthenticatedVoter());
+      WebExpressionVoter webVoter = new WebExpressionVoter();
+      webVoter.setExpressionHandler(webSecurityExpressionHandler());
+      accessDecisionVoters.add(webVoter);
+
+      return new AffirmativeBased(accessDecisionVoters);
+    }
+
+    @Override
+    public void configure(HttpSecurity http) throws Exception {
+      http.authorizeRequests()
+          .accessDecisionManager(webAccessDecisionManager())
+          .antMatchers("/**/user**/registration/info*",
+              "/**/user**/registration**",
+              "/**/user**/password/reset/*",
+              "/**/user**/password/reset**",
+              "/**/user**/password/restore**",
+              "/**/plugin/public/**",
+              "/documentation.html",
+              "/health",
+              "/info"
+          )
+          .permitAll()
+          /* set of special endpoints for another microservices from RP ecosystem */
+          .antMatchers("/api-internal/**")
+          .hasRole("COMPONENT")
+          .antMatchers("/v2/**", "/swagger-resources", "/certificate/**", "/api/**", "/**")
+          .hasRole("USER")
+          .anyRequest()
+          .authenticated()
+          .and()
+          .csrf()
+          .disable();
+    }
+
+  }
 }
 
 
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/Swagger2Configuration.java b/src/main/java/com/epam/ta/reportportal/core/configs/Swagger2Configuration.java
index c9dcea28ef..82271717dc 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/Swagger2Configuration.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/Swagger2Configuration.java
@@ -16,6 +16,13 @@
 
 package com.epam.ta.reportportal.core.configs;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.ProjectCriteriaConstant.CRITERIA_PROJECT_ATTRIBUTE_NAME;
+import static com.google.common.base.Predicates.not;
+import static com.google.common.base.Predicates.or;
+import static com.google.common.collect.Lists.newArrayList;
+import static springfox.documentation.builders.RequestHandlerSelectors.basePackage;
+import static springfox.documentation.spi.schema.contexts.ModelContext.inputParam;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.querygen.CriteriaHolder;
 import com.epam.ta.reportportal.commons.querygen.Filter;
@@ -30,6 +37,14 @@
 import com.fasterxml.classmate.TypeResolver;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
+import java.sql.Timestamp;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import javax.servlet.ServletContext;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Bean;
@@ -58,22 +73,6 @@
 import springfox.documentation.swagger.web.UiConfigurationBuilder;
 import springfox.documentation.swagger2.annotations.EnableSwagger2;
 
-import javax.servlet.ServletContext;
-import java.sql.Timestamp;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.Set;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.commons.querygen.constant.ProjectCriteriaConstant.CRITERIA_PROJECT_ATTRIBUTE_NAME;
-import static com.google.common.base.Predicates.not;
-import static com.google.common.base.Predicates.or;
-import static com.google.common.collect.Lists.newArrayList;
-import static springfox.documentation.builders.RequestHandlerSelectors.basePackage;
-import static springfox.documentation.spi.schema.contexts.ModelContext.inputParam;
-
 /**
  * SWAGGER 2.0 UI page configuration for Report Portal application
  *
@@ -87,16 +86,17 @@
 @ComponentScan(basePackages = "com.epam.ta.reportportal.ws.controller")
 public class Swagger2Configuration {
 
-	private static final Set<String> hiddenParams = ImmutableSet.<String>builder().add(CRITERIA_PROJECT_ATTRIBUTE_NAME).build();
+  private static final Set<String> hiddenParams = ImmutableSet.<String>builder()
+      .add(CRITERIA_PROJECT_ATTRIBUTE_NAME).build();
 
-	@Autowired
-	private ServletContext servletContext;
+  @Autowired
+  private ServletContext servletContext;
 
-	@Value("${spring.application.name}")
-	private String applicationName;
+  @Value("${spring.application.name}")
+  private String applicationName;
 
-	@Value("${info.build.version}")
-	private String buildVersion;
+  @Value("${info.build.version}")
+  private String buildVersion;
 
 	@Bean
 	public Docket docket() {
@@ -112,178 +112,193 @@ public Docket docket() {
 				Collections.emptyList()
 		);
 
-		// @formatter:off
-        Docket rpDocket = new Docket(DocumentationType.SWAGGER_2)
-                .ignoredParameterTypes(ReportPortalUser.class, Filter.class, Queryable.class, Pageable.class, UserRole.class)
-                .pathProvider(rpPathProvider())
-                .useDefaultResponseMessages(false)
-                /* remove default endpoints from listing */
-                .select().apis(not(or(
-                        basePackage("org.springframework.boot"),
-                        basePackage("org.springframework.cloud"))))
-                .build();
-        //@formatter:on
-
-		rpDocket.apiInfo(rpInfo);
-		return rpDocket;
-	}
-
-	@Bean
-	public PathProvider rpPathProvider() {
-		return new RelativePathProvider(servletContext) {
-			@Override
-			public String getApplicationBasePath() {
-				return "/" + applicationName + super.getApplicationBasePath();
-			}
-		};
-	}
-
-	@Bean
-	OperationPageableParameterReader pageableParameterBuilderPlugin(TypeNameExtractor nameExtractor, TypeResolver resolver) {
-		return new OperationPageableParameterReader(nameExtractor, resolver);
-	}
-
-	@Bean
-	public UiConfiguration uiConfig() {
-		return UiConfigurationBuilder.builder().build();
-	}
-
-	@Component
-	public class OperationPageableParameterReader implements OperationBuilderPlugin {
-		private final TypeNameExtractor nameExtractor;
-		private final TypeResolver resolver;
-
-		private final ResolvedType pageableType;
-		private final ResolvedType filterType;
-
-		@Autowired
-		public OperationPageableParameterReader(TypeNameExtractor nameExtractor, TypeResolver resolver) {
-			this.nameExtractor = nameExtractor;
-			this.resolver = resolver;
-			this.pageableType = resolver.resolve(Pageable.class);
-			this.filterType = resolver.resolve(Filter.class);
-		}
-
-		@Override
-		public void apply(OperationContext context) {
-			List<ResolvedMethodParameter> methodParameters = context.getParameters();
-			List<Parameter> parameters = newArrayList();
-
-			for (ResolvedMethodParameter methodParameter : methodParameters) {
-				ResolvedType resolvedType = methodParameter.getParameterType();
-				ParameterContext parameterContext = new ParameterContext(
-						methodParameter,
-						new ParameterBuilder(),
-						context.getDocumentationContext(),
-						context.getGenericsNamingStrategy(),
-						context
-				);
-				Function<ResolvedType, ? extends ModelReference> factory = createModelRefFactory(parameterContext);
-				ModelReference stringModel = factory.apply(resolver.resolve(List.class, String.class));
-
-				if (pageableType.equals(resolvedType)) {
-
-					ModelReference intModel = factory.apply(resolver.resolve(Integer.TYPE));
-
-					parameters.add(new ParameterBuilder().parameterType("query")
-							.name("page.page")
-							.modelRef(intModel)
-							.description("Results page you want to retrieve (0..N)")
-							.build());
-					parameters.add(new ParameterBuilder().parameterType("query")
-							.name("page.size")
-							.modelRef(intModel)
-							.description("Number of records per page")
-							.build());
-					parameters.add(new ParameterBuilder().parameterType("query")
-							.name("page.sort")
-							.modelRef(stringModel)
-							.allowMultiple(true)
-							.description("Sorting criteria in the format: property, (asc|desc). " + "Default sort order is ascending. "
-									+ "Multiple sort criteria are supported.")
-							.build());
-					context.operationBuilder().parameters(parameters);
-
-				} else if (filterType.equals(resolvedType)) {
-					FilterFor filterClass = methodParameter.findAnnotation(FilterFor.class).get();
-
-					List<Parameter> defaultParams = Lists.newArrayList();
-					if (filterClass.value() == TestItem.class || filterClass.value() == Launch.class) {
-						defaultParams = StatisticsHelper.defaultStatisticsFields()
-								.map(it -> buildParameters(parameterContext, factory, it))
-								.collect(Collectors.toList());
-					}
-
-					List<CriteriaHolder> criteriaList = FilterTarget.findByClass(filterClass.value()).getCriteriaHolders();
-					List<Parameter> params = criteriaList.stream()
-							.filter(ch -> !hiddenParams.contains(ch.getFilterCriteria()))
-							.map(it -> buildParameters(parameterContext, factory, it))
-							/* if type is not a collection and first letter is not capital (all known to swagger types start from lower case) */
-							.filter(p -> !(null == p.getModelRef().getItemType() && Character.isUpperCase(p.getModelRef()
-									.getType()
-									.toCharArray()[0])))
-							.collect(Collectors.toList());
-
-					params.addAll(defaultParams);
-					context.operationBuilder().parameters(params);
-				}
-			}
-		}
-
-		private Parameter buildParameters(ParameterContext parameterContext, Function<ResolvedType, ? extends ModelReference> factory,
-				CriteriaHolder criteriaHolder) {
-			return parameterContext.parameterBuilder()
-					.parameterType("query")
-					.name("filter.eq." + criteriaHolder.getFilterCriteria())
-					.allowMultiple(true)
-					.modelRef(factory.apply(resolver.resolve(
-							criteriaHolder.getDataType() == Timestamp.class ? Date.class : criteriaHolder.getDataType())))
-					.description("Filters by '" + criteriaHolder.getFilterCriteria() + "'")
-					.build();
-		}
-
-		private Parameter buildParameters(ParameterContext parameterContext, Function<ResolvedType, ? extends ModelReference> factory,
-				String parameter) {
-			return parameterContext.parameterBuilder()
-					.parameterType("query")
-					.name("filter.eq." + parameter)
-					.allowMultiple(true)
-					.modelRef(factory.apply(resolver.resolve(Long.class)))
-					.description("Filters by '" + parameter + "'")
-					.build();
-		}
-
-		@Override
-		public boolean supports(DocumentationType delimiter) {
-			return true;
-		}
-
-		private Function<ResolvedType, ? extends ModelReference> createModelRefFactory(ParameterContext context) {
-			ModelContext modelContext = inputParam(
-					Docket.DEFAULT_GROUP_NAME,
-					context.resolvedMethodParameter().getParameterType().getErasedType(),
-					context.getDocumentationType(),
-					context.getAlternateTypeProvider(),
-					context.getGenericNamingStrategy(),
-					context.getIgnorableParameterTypes()
-			);
-			return ResolvedTypes.modelRefFactory(modelContext, nameExtractor);
-		}
-	}
-
-	@SuppressWarnings("unused")
-	private static class RPPathProvider extends RelativePathProvider {
-
-		private String gatewayPath;
-
-		RPPathProvider(ServletContext servletContext, String gatewayPath) {
-			super(servletContext);
-			this.gatewayPath = gatewayPath;
-		}
-
-		@Override
-		protected String applicationPath() {
-			return "/" + gatewayPath + super.applicationPath();
-		}
-	}
+    // @formatter:off
+    Docket rpDocket = new Docket(DocumentationType.SWAGGER_2)
+        .ignoredParameterTypes(ReportPortalUser.class, Filter.class, Queryable.class,
+            Pageable.class, UserRole.class)
+        .pathProvider(rpPathProvider())
+        .useDefaultResponseMessages(false)
+        /* remove default endpoints from listing */
+        .select().apis(not(or(
+            basePackage("org.springframework.boot"),
+            basePackage("org.springframework.cloud"))))
+        .build();
+    //@formatter:on
+
+    rpDocket.apiInfo(rpInfo);
+    return rpDocket;
+  }
+
+  @Bean
+  public PathProvider rpPathProvider() {
+    return new RelativePathProvider(servletContext) {
+      @Override
+      public String getApplicationBasePath() {
+        if (super.getApplicationBasePath().contains(applicationName)) {
+          return super.getApplicationBasePath();
+        }
+        return "/" + applicationName + super.getApplicationBasePath();
+      }
+    };
+  }
+
+  @Bean
+  OperationPageableParameterReader pageableParameterBuilderPlugin(TypeNameExtractor nameExtractor,
+      TypeResolver resolver) {
+    return new OperationPageableParameterReader(nameExtractor, resolver);
+  }
+
+  @Bean
+  public UiConfiguration uiConfig() {
+    return UiConfigurationBuilder.builder().build();
+  }
+
+  @Component
+  public class OperationPageableParameterReader implements OperationBuilderPlugin {
+
+    private final TypeNameExtractor nameExtractor;
+    private final TypeResolver resolver;
+
+    private final ResolvedType pageableType;
+    private final ResolvedType filterType;
+
+    @Autowired
+    public OperationPageableParameterReader(TypeNameExtractor nameExtractor,
+        TypeResolver resolver) {
+      this.nameExtractor = nameExtractor;
+      this.resolver = resolver;
+      this.pageableType = resolver.resolve(Pageable.class);
+      this.filterType = resolver.resolve(Filter.class);
+    }
+
+    @Override
+    public void apply(OperationContext context) {
+      List<ResolvedMethodParameter> methodParameters = context.getParameters();
+      List<Parameter> parameters = newArrayList();
+
+      for (ResolvedMethodParameter methodParameter : methodParameters) {
+        ResolvedType resolvedType = methodParameter.getParameterType();
+        ParameterContext parameterContext = new ParameterContext(
+            methodParameter,
+            new ParameterBuilder(),
+            context.getDocumentationContext(),
+            context.getGenericsNamingStrategy(),
+            context
+        );
+        Function<ResolvedType, ? extends ModelReference> factory = createModelRefFactory(
+            parameterContext);
+        ModelReference stringModel = factory.apply(resolver.resolve(List.class, String.class));
+
+        if (pageableType.equals(resolvedType)) {
+
+          ModelReference intModel = factory.apply(resolver.resolve(Integer.TYPE));
+
+          parameters.add(new ParameterBuilder().parameterType("query")
+              .name("page.page")
+              .modelRef(intModel)
+              .description("Results page you want to retrieve (0..N)")
+              .build());
+          parameters.add(new ParameterBuilder().parameterType("query")
+              .name("page.size")
+              .modelRef(intModel)
+              .description("Number of records per page")
+              .build());
+          parameters.add(new ParameterBuilder().parameterType("query")
+              .name("page.sort")
+              .modelRef(stringModel)
+              .allowMultiple(true)
+              .description("Sorting criteria in the format: property, (asc|desc). "
+                  + "Default sort order is ascending. "
+                  + "Multiple sort criteria are supported.")
+              .build());
+          context.operationBuilder().parameters(parameters);
+
+        } else if (filterType.equals(resolvedType)) {
+          FilterFor filterClass = methodParameter.findAnnotation(FilterFor.class).get();
+
+          List<Parameter> defaultParams = Lists.newArrayList();
+          if (filterClass.value() == TestItem.class || filterClass.value() == Launch.class) {
+            defaultParams = StatisticsHelper.defaultStatisticsFields()
+                .map(it -> buildParameters(parameterContext, factory, it))
+                .collect(Collectors.toList());
+          }
+
+          List<CriteriaHolder> criteriaList = FilterTarget.findByClass(filterClass.value())
+              .getCriteriaHolders();
+          List<Parameter> params = criteriaList.stream()
+              .filter(ch -> !hiddenParams.contains(ch.getFilterCriteria()))
+              .map(it -> buildParameters(parameterContext, factory, it))
+              /* if type is not a collection and first letter is not capital (all known to swagger types start from lower case) */
+              .filter(p -> !(null == p.getModelRef().getItemType() && Character.isUpperCase(
+                  p.getModelRef()
+                      .getType()
+                      .toCharArray()[0])))
+              .collect(Collectors.toList());
+
+          params.addAll(defaultParams);
+          context.operationBuilder().parameters(params);
+        }
+      }
+    }
+
+    private Parameter buildParameters(ParameterContext parameterContext,
+        Function<ResolvedType, ? extends ModelReference> factory,
+        CriteriaHolder criteriaHolder) {
+      return parameterContext.parameterBuilder()
+          .parameterType("query")
+          .name("filter.eq." + criteriaHolder.getFilterCriteria())
+          .allowMultiple(true)
+          .modelRef(factory.apply(resolver.resolve(
+              criteriaHolder.getDataType() == Timestamp.class ? Date.class
+                  : criteriaHolder.getDataType())))
+          .description("Filters by '" + criteriaHolder.getFilterCriteria() + "'")
+          .build();
+    }
+
+    private Parameter buildParameters(ParameterContext parameterContext,
+        Function<ResolvedType, ? extends ModelReference> factory,
+        String parameter) {
+      return parameterContext.parameterBuilder()
+          .parameterType("query")
+          .name("filter.eq." + parameter)
+          .allowMultiple(true)
+          .modelRef(factory.apply(resolver.resolve(Long.class)))
+          .description("Filters by '" + parameter + "'")
+          .build();
+    }
+
+    @Override
+    public boolean supports(DocumentationType delimiter) {
+      return true;
+    }
+
+    private Function<ResolvedType, ? extends ModelReference> createModelRefFactory(
+        ParameterContext context) {
+      ModelContext modelContext = inputParam(
+          Docket.DEFAULT_GROUP_NAME,
+          context.resolvedMethodParameter().getParameterType().getErasedType(),
+          context.getDocumentationType(),
+          context.getAlternateTypeProvider(),
+          context.getGenericNamingStrategy(),
+          context.getIgnorableParameterTypes()
+      );
+      return ResolvedTypes.modelRefFactory(modelContext, nameExtractor);
+    }
+  }
+
+  @SuppressWarnings("unused")
+  private static class RPPathProvider extends RelativePathProvider {
+
+    private String gatewayPath;
+
+    RPPathProvider(ServletContext servletContext, String gatewayPath) {
+      super(servletContext);
+      this.gatewayPath = gatewayPath;
+    }
+
+    @Override
+    protected String applicationPath() {
+      return "/" + gatewayPath + super.applicationPath();
+    }
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/WidgetConfig.java b/src/main/java/com/epam/ta/reportportal/core/configs/WidgetConfig.java
index cf6ba4dd2b..8e617143b3 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/WidgetConfig.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/WidgetConfig.java
@@ -19,8 +19,32 @@
 import com.epam.ta.reportportal.core.widget.content.BuildFilterStrategy;
 import com.epam.ta.reportportal.core.widget.content.LoadContentStrategy;
 import com.epam.ta.reportportal.core.widget.content.MultilevelLoadContentStrategy;
-import com.epam.ta.reportportal.core.widget.content.filter.*;
-import com.epam.ta.reportportal.core.widget.content.loader.*;
+import com.epam.ta.reportportal.core.widget.content.filter.ActivityFilterStrategy;
+import com.epam.ta.reportportal.core.widget.content.filter.GeneralLaunchFilterStrategy;
+import com.epam.ta.reportportal.core.widget.content.filter.LaunchHistoryFilterStrategy;
+import com.epam.ta.reportportal.core.widget.content.filter.ProductStatusFilterStrategy;
+import com.epam.ta.reportportal.core.widget.content.loader.ActivityContentLoader;
+import com.epam.ta.reportportal.core.widget.content.loader.BugTrendChartContentLoader;
+import com.epam.ta.reportportal.core.widget.content.loader.CasesTrendContentLoader;
+import com.epam.ta.reportportal.core.widget.content.loader.ChartInvestigatedContentLoader;
+import com.epam.ta.reportportal.core.widget.content.loader.ComponentHealthCheckContentLoader;
+import com.epam.ta.reportportal.core.widget.content.loader.FlakyCasesTableContentLoader;
+import com.epam.ta.reportportal.core.widget.content.loader.LaunchExecutionAndIssueStatisticsContentLoader;
+import com.epam.ta.reportportal.core.widget.content.loader.LaunchesComparisonContentLoader;
+import com.epam.ta.reportportal.core.widget.content.loader.LaunchesDurationContentLoader;
+import com.epam.ta.reportportal.core.widget.content.loader.LaunchesTableContentLoader;
+import com.epam.ta.reportportal.core.widget.content.loader.LineChartContentLoader;
+import com.epam.ta.reportportal.core.widget.content.loader.MostTimeConsumingContentLoader;
+import com.epam.ta.reportportal.core.widget.content.loader.NotPassedTestsContentLoader;
+import com.epam.ta.reportportal.core.widget.content.loader.OverallStatisticsContentLoader;
+import com.epam.ta.reportportal.core.widget.content.loader.PassingRatePerLaunchContentLoader;
+import com.epam.ta.reportportal.core.widget.content.loader.PassingRateSummaryContentLoader;
+import com.epam.ta.reportportal.core.widget.content.loader.ProductStatusContentLoader;
+import com.epam.ta.reportportal.core.widget.content.loader.ProductStatusFilterGroupedContentLoader;
+import com.epam.ta.reportportal.core.widget.content.loader.ProductStatusLaunchGroupedContentLoader;
+import com.epam.ta.reportportal.core.widget.content.loader.TopPatternContentLoader;
+import com.epam.ta.reportportal.core.widget.content.loader.TopTestCasesContentLoader;
+import com.epam.ta.reportportal.core.widget.content.loader.UniqueBugContentLoader;
 import com.epam.ta.reportportal.core.widget.content.loader.materialized.CumulativeTrendChartContentLoaderImpl;
 import com.epam.ta.reportportal.core.widget.content.loader.materialized.HealthCheckTableReadyContentLoader;
 import com.epam.ta.reportportal.core.widget.content.loader.materialized.MaterializedWidgetContentLoader;
@@ -28,7 +52,11 @@
 import com.epam.ta.reportportal.core.widget.content.loader.materialized.generator.FailedViewStateGenerator;
 import com.epam.ta.reportportal.core.widget.content.loader.materialized.generator.HealthCheckTableGenerator;
 import com.epam.ta.reportportal.core.widget.content.loader.materialized.generator.ViewGenerator;
-import com.epam.ta.reportportal.core.widget.content.loader.materialized.handler.*;
+import com.epam.ta.reportportal.core.widget.content.loader.materialized.handler.CreatedMaterializedWidgetStateHandler;
+import com.epam.ta.reportportal.core.widget.content.loader.materialized.handler.EmptyMaterializedWidgetStateHandler;
+import com.epam.ta.reportportal.core.widget.content.loader.materialized.handler.FailedMaterializedWidgetStateHandler;
+import com.epam.ta.reportportal.core.widget.content.loader.materialized.handler.MaterializedWidgetStateHandler;
+import com.epam.ta.reportportal.core.widget.content.loader.materialized.handler.ReadyMaterializedWidgetStateHandler;
 import com.epam.ta.reportportal.core.widget.content.loader.util.ProductStatusContentLoaderManager;
 import com.epam.ta.reportportal.core.widget.content.remover.MaterializedViewRemover;
 import com.epam.ta.reportportal.core.widget.content.remover.StaleMaterializedViewRemover;
@@ -39,6 +67,8 @@
 import com.epam.ta.reportportal.entity.widget.WidgetType;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
+import java.util.Map;
+import java.util.Set;
 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationContext;
@@ -46,9 +76,6 @@
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
-import java.util.Map;
-import java.util.Set;
-
 /**
  * Configuration related to widgets.
  *
@@ -58,169 +85,204 @@
 @Configuration
 public class WidgetConfig implements ApplicationContextAware {
 
-	private ApplicationContext applicationContext;
-
-	@Autowired
-	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
-		this.applicationContext = applicationContext;
-	}
-
-	@Bean("contentLoader")
-	public Map<WidgetType, LoadContentStrategy> contentLoader() {
-		return ImmutableMap.<WidgetType, LoadContentStrategy>builder().put(WidgetType.FLAKY_TEST_CASES,
-				applicationContext.getBean(FlakyCasesTableContentLoader.class)
-		)
-				.put(WidgetType.OVERALL_STATISTICS, applicationContext.getBean(OverallStatisticsContentLoader.class))
-				.put(WidgetType.PASSING_RATE_SUMMARY, applicationContext.getBean(PassingRateSummaryContentLoader.class))
-				.put(WidgetType.OLD_LINE_CHART, applicationContext.getBean(LineChartContentLoader.class))
-				.put(WidgetType.INVESTIGATED_TREND, applicationContext.getBean(ChartInvestigatedContentLoader.class))
-				.put(WidgetType.STATISTIC_TREND, applicationContext.getBean(LineChartContentLoader.class))
-				.put(WidgetType.LAUNCH_STATISTICS, applicationContext.getBean(LaunchExecutionAndIssueStatisticsContentLoader.class))
-				.put(WidgetType.CASES_TREND, applicationContext.getBean(CasesTrendContentLoader.class))
-				.put(WidgetType.NOT_PASSED, applicationContext.getBean(NotPassedTestsContentLoader.class))
-				.put(WidgetType.UNIQUE_BUG_TABLE, applicationContext.getBean(UniqueBugContentLoader.class))
-				.put(WidgetType.BUG_TREND, applicationContext.getBean(BugTrendChartContentLoader.class))
-				.put(WidgetType.ACTIVITY, applicationContext.getBean(ActivityContentLoader.class))
-				.put(WidgetType.LAUNCHES_COMPARISON_CHART, applicationContext.getBean(LaunchesComparisonContentLoader.class))
-				.put(WidgetType.LAUNCHES_DURATION_CHART, applicationContext.getBean(LaunchesDurationContentLoader.class))
-				.put(WidgetType.LAUNCHES_TABLE, applicationContext.getBean(LaunchesTableContentLoader.class))
-				.put(WidgetType.TOP_TEST_CASES, applicationContext.getBean(TopTestCasesContentLoader.class))
-				.put(WidgetType.PASSING_RATE_PER_LAUNCH, applicationContext.getBean(PassingRatePerLaunchContentLoader.class))
-				.put(WidgetType.PRODUCT_STATUS, applicationContext.getBean(ProductStatusContentLoaderManager.class))
-				.put(WidgetType.MOST_TIME_CONSUMING, applicationContext.getBean(MostTimeConsumingContentLoader.class))
-				.build();
-	}
-
-	@Bean("multilevelContentLoader")
-	public Map<WidgetType, MultilevelLoadContentStrategy> multilevelContentLoader() {
-		return ImmutableMap.<WidgetType, MultilevelLoadContentStrategy>builder().put(WidgetType.TOP_PATTERN_TEMPLATES,
-				applicationContext.getBean(TopPatternContentLoader.class)
-		)
-				.put(WidgetType.COMPONENT_HEALTH_CHECK, applicationContext.getBean(ComponentHealthCheckContentLoader.class))
-				.build();
-	}
-
-	@Bean("buildFilterStrategy")
-	public Map<WidgetType, BuildFilterStrategy> buildFilterStrategy() {
-		return ImmutableMap.<WidgetType, BuildFilterStrategy>builder().put(WidgetType.OLD_LINE_CHART,
-				(GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy")
-		)
-				.put(WidgetType.INVESTIGATED_TREND, (GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy"))
-				.put(WidgetType.STATISTIC_TREND, (GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy"))
-				.put(WidgetType.LAUNCH_STATISTICS, (GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy"))
-				.put(WidgetType.OVERALL_STATISTICS, (GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy"))
-				.put(WidgetType.CASES_TREND, (GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy"))
-				.put(WidgetType.NOT_PASSED, (GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy"))
-				.put(WidgetType.BUG_TREND, (GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy"))
-				.put(WidgetType.LAUNCHES_TABLE, (GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy"))
-				.put(WidgetType.PASSING_RATE_SUMMARY,
-						(GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy")
-				)
-				.put(WidgetType.CUMULATIVE, (GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy"))
-				.put(WidgetType.PRODUCT_STATUS, (ProductStatusFilterStrategy) applicationContext.getBean("productStatusFilterStrategy"))
-				.put(WidgetType.UNIQUE_BUG_TABLE, (GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy"))
-				.put(WidgetType.ACTIVITY, (ActivityFilterStrategy) applicationContext.getBean("activityFilterStrategy"))
-				.put(WidgetType.LAUNCHES_COMPARISON_CHART,
-						(GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy")
-				)
-				.put(WidgetType.LAUNCHES_DURATION_CHART,
-						(GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy")
-				)
-				.put(WidgetType.TOP_TEST_CASES, (LaunchHistoryFilterStrategy) applicationContext.getBean("launchHistoryFilterStrategy"))
-				.put(WidgetType.PASSING_RATE_PER_LAUNCH,
-						(GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy")
-				)
-				.put(WidgetType.FLAKY_TEST_CASES, (GeneralLaunchFilterStrategy) applicationContext.getBean("launchHistoryFilterStrategy"))
-				.put(WidgetType.MOST_TIME_CONSUMING, (GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy"))
-				.put(WidgetType.TOP_PATTERN_TEMPLATES,
-						(GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy")
-				)
-				.put(WidgetType.COMPONENT_HEALTH_CHECK,
-						(GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy")
-				)
-				.put(WidgetType.COMPONENT_HEALTH_CHECK_TABLE,
-						(GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy")
-				)
-				.build();
-	}
-
-	@Bean("productStatusContentLoader")
-	public Map<String, ProductStatusContentLoader> productStatusContentLoader() {
-		return ImmutableMap.<String, ProductStatusContentLoader>builder().put("launch",
-				applicationContext.getBean(ProductStatusLaunchGroupedContentLoader.class)
-		)
-				.put("filter", applicationContext.getBean(ProductStatusFilterGroupedContentLoader.class))
-				.build();
-	}
-
-	@Bean("groupingStrategy")
-	public Map<InfoInterval, ProjectInfoWidgetDataConverter.ProjectInfoGroup> group() {
-		return ImmutableMap.<InfoInterval, ProjectInfoWidgetDataConverter.ProjectInfoGroup>builder().put(InfoInterval.ONE_MONTH,
-				ProjectInfoWidgetDataConverter.ProjectInfoGroup.BY_DAY
-		)
-				.put(InfoInterval.THREE_MONTHS, ProjectInfoWidgetDataConverter.ProjectInfoGroup.BY_WEEK)
-				.put(InfoInterval.SIX_MONTHS, ProjectInfoWidgetDataConverter.ProjectInfoGroup.BY_WEEK)
-				.build();
-	}
-
-	@Bean("unfilteredWidgetTypes")
-	public Set<WidgetType> unfilteredWidgetTypes() {
-		return ImmutableSet.<WidgetType>builder().add(WidgetType.ACTIVITY)
-				.add(WidgetType.TOP_TEST_CASES)
-				.add(WidgetType.PASSING_RATE_PER_LAUNCH)
-				.add(WidgetType.MOST_TIME_CONSUMING)
-				.add(WidgetType.FLAKY_TEST_CASES)
-				.build();
-	}
-
-	@Bean("widgetStateHandlerMapping")
-	public Map<WidgetState, MaterializedWidgetStateHandler> widgetStateHandlerMapping() {
-		return ImmutableMap.<WidgetState, MaterializedWidgetStateHandler>builder().put(WidgetState.CREATED,
-				applicationContext.getBean(CreatedMaterializedWidgetStateHandler.class)
-		)
-				.put(WidgetState.READY, applicationContext.getBean(ReadyMaterializedWidgetStateHandler.class))
-				.put(WidgetState.RENDERING, applicationContext.getBean(EmptyMaterializedWidgetStateHandler.class))
-				.put(WidgetState.FAILED, applicationContext.getBean(FailedMaterializedWidgetStateHandler.class))
-				.build();
-	}
-
-	@Bean("materializedWidgetContentLoaderMapping")
-	public Map<WidgetType, MaterializedWidgetContentLoader> materializedWidgetContentLoaderMapping() {
-		return ImmutableMap.<WidgetType, MaterializedWidgetContentLoader>builder().put(WidgetType.COMPONENT_HEALTH_CHECK_TABLE,
-				applicationContext.getBean(HealthCheckTableReadyContentLoader.class)
-		)
-				.put(WidgetType.CUMULATIVE, applicationContext.getBean(CumulativeTrendChartContentLoaderImpl.class))
-				.build();
-	}
-
-	@Bean("cumulativeFailedViewStateGenerator")
-	public FailedViewStateGenerator cumulativeFailedViewStateGenerator() {
-		return new FailedViewStateGenerator(applicationContext.getBean(CumulativeTrendChartViewGenerator.class),
-				applicationContext.getBean(WidgetRepository.class)
-		);
-	}
-
-	@Bean("healthCheckTableFailedViewStateGenerator")
-	public FailedViewStateGenerator healthCheckTableFailedViewStateGenerator() {
-		return new FailedViewStateGenerator(applicationContext.getBean(HealthCheckTableGenerator.class),
-				applicationContext.getBean(WidgetRepository.class)
-		);
-	}
-
-	@Bean("viewGeneratorMapping")
-	public Map<WidgetType, ViewGenerator> viewGeneratorMapping() {
-		return ImmutableMap.<WidgetType, ViewGenerator>builder()
-				.put(WidgetType.COMPONENT_HEALTH_CHECK_TABLE, healthCheckTableFailedViewStateGenerator())
-				.put(WidgetType.CUMULATIVE, cumulativeFailedViewStateGenerator())
-				.build();
-	}
-
-	@Bean("widgetContentRemoverMapping")
-	public Map<WidgetState, WidgetContentRemover> widgetContentRemoverMapping() {
-		return ImmutableMap.<WidgetState, WidgetContentRemover>builder()
-				.put(WidgetState.READY, applicationContext.getBean(MaterializedViewRemover.class))
-				.put(WidgetState.RENDERING, applicationContext.getBean(StaleMaterializedViewRemover.class))
-				.build();
-	}
+  private ApplicationContext applicationContext;
+
+  @Autowired
+  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+    this.applicationContext = applicationContext;
+  }
+
+  @Bean("contentLoader")
+  public Map<WidgetType, LoadContentStrategy> contentLoader() {
+    return ImmutableMap.<WidgetType, LoadContentStrategy>builder().put(WidgetType.FLAKY_TEST_CASES,
+            applicationContext.getBean(FlakyCasesTableContentLoader.class)
+        )
+        .put(WidgetType.OVERALL_STATISTICS,
+            applicationContext.getBean(OverallStatisticsContentLoader.class))
+        .put(WidgetType.PASSING_RATE_SUMMARY,
+            applicationContext.getBean(PassingRateSummaryContentLoader.class))
+        .put(WidgetType.OLD_LINE_CHART, applicationContext.getBean(LineChartContentLoader.class))
+        .put(WidgetType.INVESTIGATED_TREND,
+            applicationContext.getBean(ChartInvestigatedContentLoader.class))
+        .put(WidgetType.STATISTIC_TREND, applicationContext.getBean(LineChartContentLoader.class))
+        .put(WidgetType.LAUNCH_STATISTICS,
+            applicationContext.getBean(LaunchExecutionAndIssueStatisticsContentLoader.class))
+        .put(WidgetType.CASES_TREND, applicationContext.getBean(CasesTrendContentLoader.class))
+        .put(WidgetType.NOT_PASSED, applicationContext.getBean(NotPassedTestsContentLoader.class))
+        .put(WidgetType.UNIQUE_BUG_TABLE, applicationContext.getBean(UniqueBugContentLoader.class))
+        .put(WidgetType.BUG_TREND, applicationContext.getBean(BugTrendChartContentLoader.class))
+        .put(WidgetType.ACTIVITY, applicationContext.getBean(ActivityContentLoader.class))
+        .put(WidgetType.LAUNCHES_COMPARISON_CHART,
+            applicationContext.getBean(LaunchesComparisonContentLoader.class))
+        .put(WidgetType.LAUNCHES_DURATION_CHART,
+            applicationContext.getBean(LaunchesDurationContentLoader.class))
+        .put(WidgetType.LAUNCHES_TABLE,
+            applicationContext.getBean(LaunchesTableContentLoader.class))
+        .put(WidgetType.TOP_TEST_CASES, applicationContext.getBean(TopTestCasesContentLoader.class))
+        .put(WidgetType.PASSING_RATE_PER_LAUNCH,
+            applicationContext.getBean(PassingRatePerLaunchContentLoader.class))
+        .put(WidgetType.PRODUCT_STATUS,
+            applicationContext.getBean(ProductStatusContentLoaderManager.class))
+        .put(WidgetType.MOST_TIME_CONSUMING,
+            applicationContext.getBean(MostTimeConsumingContentLoader.class))
+        .build();
+  }
+
+  @Bean("multilevelContentLoader")
+  public Map<WidgetType, MultilevelLoadContentStrategy> multilevelContentLoader() {
+    return ImmutableMap.<WidgetType, MultilevelLoadContentStrategy>builder()
+        .put(WidgetType.TOP_PATTERN_TEMPLATES,
+            applicationContext.getBean(TopPatternContentLoader.class)
+        )
+        .put(WidgetType.COMPONENT_HEALTH_CHECK,
+            applicationContext.getBean(ComponentHealthCheckContentLoader.class))
+        .build();
+  }
+
+  @Bean("buildFilterStrategy")
+  public Map<WidgetType, BuildFilterStrategy> buildFilterStrategy() {
+    return ImmutableMap.<WidgetType, BuildFilterStrategy>builder().put(WidgetType.OLD_LINE_CHART,
+            (GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy")
+        )
+        .put(WidgetType.INVESTIGATED_TREND,
+            (GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy"))
+        .put(WidgetType.STATISTIC_TREND,
+            (GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy"))
+        .put(WidgetType.LAUNCH_STATISTICS,
+            (GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy"))
+        .put(WidgetType.OVERALL_STATISTICS,
+            (GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy"))
+        .put(WidgetType.CASES_TREND,
+            (GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy"))
+        .put(WidgetType.NOT_PASSED,
+            (GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy"))
+        .put(WidgetType.BUG_TREND,
+            (GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy"))
+        .put(WidgetType.LAUNCHES_TABLE,
+            (GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy"))
+        .put(WidgetType.PASSING_RATE_SUMMARY,
+            (GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy")
+        )
+        .put(WidgetType.CUMULATIVE,
+            (GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy"))
+        .put(WidgetType.PRODUCT_STATUS,
+            (ProductStatusFilterStrategy) applicationContext.getBean("productStatusFilterStrategy"))
+        .put(WidgetType.UNIQUE_BUG_TABLE,
+            (GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy"))
+        .put(WidgetType.ACTIVITY,
+            (ActivityFilterStrategy) applicationContext.getBean("activityFilterStrategy"))
+        .put(WidgetType.LAUNCHES_COMPARISON_CHART,
+            (GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy")
+        )
+        .put(WidgetType.LAUNCHES_DURATION_CHART,
+            (GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy")
+        )
+        .put(WidgetType.TOP_TEST_CASES,
+            (LaunchHistoryFilterStrategy) applicationContext.getBean("launchHistoryFilterStrategy"))
+        .put(WidgetType.PASSING_RATE_PER_LAUNCH,
+            (GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy")
+        )
+        .put(WidgetType.FLAKY_TEST_CASES,
+            (GeneralLaunchFilterStrategy) applicationContext.getBean("launchHistoryFilterStrategy"))
+        .put(WidgetType.MOST_TIME_CONSUMING,
+            (GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy"))
+        .put(WidgetType.TOP_PATTERN_TEMPLATES,
+            (GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy")
+        )
+        .put(WidgetType.COMPONENT_HEALTH_CHECK,
+            (GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy")
+        )
+        .put(WidgetType.COMPONENT_HEALTH_CHECK_TABLE,
+            (GeneralLaunchFilterStrategy) applicationContext.getBean("generalLaunchFilterStrategy")
+        )
+        .build();
+  }
+
+  @Bean("productStatusContentLoader")
+  public Map<String, ProductStatusContentLoader> productStatusContentLoader() {
+    return ImmutableMap.<String, ProductStatusContentLoader>builder().put("launch",
+            applicationContext.getBean(ProductStatusLaunchGroupedContentLoader.class)
+        )
+        .put("filter", applicationContext.getBean(ProductStatusFilterGroupedContentLoader.class))
+        .build();
+  }
+
+  @Bean("groupingStrategy")
+  public Map<InfoInterval, ProjectInfoWidgetDataConverter.ProjectInfoGroup> group() {
+    return ImmutableMap.<InfoInterval, ProjectInfoWidgetDataConverter.ProjectInfoGroup>builder()
+        .put(InfoInterval.ONE_MONTH,
+            ProjectInfoWidgetDataConverter.ProjectInfoGroup.BY_DAY
+        )
+        .put(InfoInterval.THREE_MONTHS, ProjectInfoWidgetDataConverter.ProjectInfoGroup.BY_WEEK)
+        .put(InfoInterval.SIX_MONTHS, ProjectInfoWidgetDataConverter.ProjectInfoGroup.BY_WEEK)
+        .build();
+  }
+
+  @Bean("unfilteredWidgetTypes")
+  public Set<WidgetType> unfilteredWidgetTypes() {
+    return ImmutableSet.<WidgetType>builder().add(WidgetType.ACTIVITY)
+        .add(WidgetType.TOP_TEST_CASES)
+        .add(WidgetType.PASSING_RATE_PER_LAUNCH)
+        .add(WidgetType.MOST_TIME_CONSUMING)
+        .add(WidgetType.FLAKY_TEST_CASES)
+        .build();
+  }
+
+  @Bean("widgetStateHandlerMapping")
+  public Map<WidgetState, MaterializedWidgetStateHandler> widgetStateHandlerMapping() {
+    return ImmutableMap.<WidgetState, MaterializedWidgetStateHandler>builder()
+        .put(WidgetState.CREATED,
+            applicationContext.getBean(CreatedMaterializedWidgetStateHandler.class)
+        )
+        .put(WidgetState.READY,
+            applicationContext.getBean(ReadyMaterializedWidgetStateHandler.class))
+        .put(WidgetState.RENDERING,
+            applicationContext.getBean(EmptyMaterializedWidgetStateHandler.class))
+        .put(WidgetState.FAILED,
+            applicationContext.getBean(FailedMaterializedWidgetStateHandler.class))
+        .build();
+  }
+
+  @Bean("materializedWidgetContentLoaderMapping")
+  public Map<WidgetType, MaterializedWidgetContentLoader> materializedWidgetContentLoaderMapping() {
+    return ImmutableMap.<WidgetType, MaterializedWidgetContentLoader>builder()
+        .put(WidgetType.COMPONENT_HEALTH_CHECK_TABLE,
+            applicationContext.getBean(HealthCheckTableReadyContentLoader.class)
+        )
+        .put(WidgetType.CUMULATIVE,
+            applicationContext.getBean(CumulativeTrendChartContentLoaderImpl.class))
+        .build();
+  }
+
+  @Bean("cumulativeFailedViewStateGenerator")
+  public FailedViewStateGenerator cumulativeFailedViewStateGenerator() {
+    return new FailedViewStateGenerator(
+        applicationContext.getBean(CumulativeTrendChartViewGenerator.class),
+        applicationContext.getBean(WidgetRepository.class)
+    );
+  }
+
+  @Bean("healthCheckTableFailedViewStateGenerator")
+  public FailedViewStateGenerator healthCheckTableFailedViewStateGenerator() {
+    return new FailedViewStateGenerator(applicationContext.getBean(HealthCheckTableGenerator.class),
+        applicationContext.getBean(WidgetRepository.class)
+    );
+  }
+
+  @Bean("viewGeneratorMapping")
+  public Map<WidgetType, ViewGenerator> viewGeneratorMapping() {
+    return ImmutableMap.<WidgetType, ViewGenerator>builder()
+        .put(WidgetType.COMPONENT_HEALTH_CHECK_TABLE, healthCheckTableFailedViewStateGenerator())
+        .put(WidgetType.CUMULATIVE, cumulativeFailedViewStateGenerator())
+        .build();
+  }
+
+  @Bean("widgetContentRemoverMapping")
+  public Map<WidgetState, WidgetContentRemover> widgetContentRemoverMapping() {
+    return ImmutableMap.<WidgetState, WidgetContentRemover>builder()
+        .put(WidgetState.READY, applicationContext.getBean(MaterializedViewRemover.class))
+        .put(WidgetState.RENDERING, applicationContext.getBean(StaleMaterializedViewRemover.class))
+        .build();
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/WidgetValidatorConfig.java b/src/main/java/com/epam/ta/reportportal/core/configs/WidgetValidatorConfig.java
index f1441d33a9..cb22a167bf 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/WidgetValidatorConfig.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/WidgetValidatorConfig.java
@@ -1,59 +1,100 @@
 package com.epam.ta.reportportal.core.configs;
 
-import com.epam.ta.reportportal.core.widget.content.updater.validator.*;
+import com.epam.ta.reportportal.core.widget.content.updater.validator.ActivityContentValidator;
+import com.epam.ta.reportportal.core.widget.content.updater.validator.BugTrendChartContentValidator;
+import com.epam.ta.reportportal.core.widget.content.updater.validator.CasesTrendContentValidator;
+import com.epam.ta.reportportal.core.widget.content.updater.validator.ChartInvestigatedContentValidator;
+import com.epam.ta.reportportal.core.widget.content.updater.validator.ComponentHealthCheckContentValidator;
+import com.epam.ta.reportportal.core.widget.content.updater.validator.CumulativeTrendChartValidator;
+import com.epam.ta.reportportal.core.widget.content.updater.validator.FlakyCasesTableContentValidator;
+import com.epam.ta.reportportal.core.widget.content.updater.validator.LaunchExecutionAndIssueStatisticsContentValidator;
+import com.epam.ta.reportportal.core.widget.content.updater.validator.LaunchesComparisonContentValidator;
+import com.epam.ta.reportportal.core.widget.content.updater.validator.LaunchesDurationContentValidator;
+import com.epam.ta.reportportal.core.widget.content.updater.validator.LaunchesTableContentValidator;
+import com.epam.ta.reportportal.core.widget.content.updater.validator.LineChartContentValidator;
+import com.epam.ta.reportportal.core.widget.content.updater.validator.MostTimeConsumingContentValidator;
+import com.epam.ta.reportportal.core.widget.content.updater.validator.MultilevelValidatorStrategy;
+import com.epam.ta.reportportal.core.widget.content.updater.validator.NotPassedTestsContentValidator;
+import com.epam.ta.reportportal.core.widget.content.updater.validator.OverallStatisticsContentValidator;
+import com.epam.ta.reportportal.core.widget.content.updater.validator.PassingRatePerLaunchContentValidator;
+import com.epam.ta.reportportal.core.widget.content.updater.validator.PassingRateSummaryContentValidator;
+import com.epam.ta.reportportal.core.widget.content.updater.validator.ProductStatusContentValidator;
+import com.epam.ta.reportportal.core.widget.content.updater.validator.TopPatternContentValidator;
+import com.epam.ta.reportportal.core.widget.content.updater.validator.TopTestCasesContentValidator;
+import com.epam.ta.reportportal.core.widget.content.updater.validator.UniqueBugContentValidator;
+import com.epam.ta.reportportal.core.widget.content.updater.validator.WidgetValidatorStrategy;
 import com.epam.ta.reportportal.entity.widget.WidgetType;
 import com.google.common.collect.ImmutableMap;
+import java.util.Map;
 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
-import java.util.Map;
-
 @Configuration
 public class WidgetValidatorConfig {
-	private ApplicationContext applicationContext;
 
-	@Autowired
-	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
-		this.applicationContext = applicationContext;
-	}
+  private ApplicationContext applicationContext;
+
+  @Autowired
+  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+    this.applicationContext = applicationContext;
+  }
 
-	@Bean("widgetValidatorLoader")
-	public Map<WidgetType, WidgetValidatorStrategy> widgetValidatorLoader() {
-		return ImmutableMap.<WidgetType, WidgetValidatorStrategy>builder().put(WidgetType.FLAKY_TEST_CASES,
-				applicationContext.getBean(FlakyCasesTableContentValidator.class)
-		)
-				.put(WidgetType.OVERALL_STATISTICS, applicationContext.getBean(OverallStatisticsContentValidator.class))
-				.put(WidgetType.PASSING_RATE_SUMMARY, applicationContext.getBean(PassingRateSummaryContentValidator.class))
-				.put(WidgetType.OLD_LINE_CHART, applicationContext.getBean(LineChartContentValidator.class))
-				.put(WidgetType.INVESTIGATED_TREND, applicationContext.getBean(ChartInvestigatedContentValidator.class))
-				.put(WidgetType.STATISTIC_TREND, applicationContext.getBean(LineChartContentValidator.class))
-				.put(WidgetType.LAUNCH_STATISTICS, applicationContext.getBean(LaunchExecutionAndIssueStatisticsContentValidator.class))
-				.put(WidgetType.CASES_TREND, applicationContext.getBean(CasesTrendContentValidator.class))
-				.put(WidgetType.NOT_PASSED, applicationContext.getBean(NotPassedTestsContentValidator.class))
-				.put(WidgetType.UNIQUE_BUG_TABLE, applicationContext.getBean(UniqueBugContentValidator.class))
-				.put(WidgetType.BUG_TREND, applicationContext.getBean(BugTrendChartContentValidator.class))
-				.put(WidgetType.ACTIVITY, applicationContext.getBean(ActivityContentValidator.class))
-				.put(WidgetType.LAUNCHES_COMPARISON_CHART, applicationContext.getBean(LaunchesComparisonContentValidator.class))
-				.put(WidgetType.LAUNCHES_DURATION_CHART, applicationContext.getBean(LaunchesDurationContentValidator.class))
-				.put(WidgetType.LAUNCHES_TABLE, applicationContext.getBean(LaunchesTableContentValidator.class))
-				.put(WidgetType.TOP_TEST_CASES, applicationContext.getBean(TopTestCasesContentValidator.class))
-				.put(WidgetType.PASSING_RATE_PER_LAUNCH, applicationContext.getBean(PassingRatePerLaunchContentValidator.class))
-				.put(WidgetType.MOST_TIME_CONSUMING, applicationContext.getBean(MostTimeConsumingContentValidator.class))
-				.put(WidgetType.PRODUCT_STATUS, applicationContext.getBean(ProductStatusContentValidator.class))
-				.build();
-	}
+  @Bean("widgetValidatorLoader")
+  public Map<WidgetType, WidgetValidatorStrategy> widgetValidatorLoader() {
+    return ImmutableMap.<WidgetType, WidgetValidatorStrategy>builder()
+        .put(WidgetType.FLAKY_TEST_CASES,
+            applicationContext.getBean(FlakyCasesTableContentValidator.class)
+        )
+        .put(WidgetType.OVERALL_STATISTICS,
+            applicationContext.getBean(OverallStatisticsContentValidator.class))
+        .put(WidgetType.PASSING_RATE_SUMMARY,
+            applicationContext.getBean(PassingRateSummaryContentValidator.class))
+        .put(WidgetType.OLD_LINE_CHART, applicationContext.getBean(LineChartContentValidator.class))
+        .put(WidgetType.INVESTIGATED_TREND,
+            applicationContext.getBean(ChartInvestigatedContentValidator.class))
+        .put(WidgetType.STATISTIC_TREND,
+            applicationContext.getBean(LineChartContentValidator.class))
+        .put(WidgetType.LAUNCH_STATISTICS,
+            applicationContext.getBean(LaunchExecutionAndIssueStatisticsContentValidator.class))
+        .put(WidgetType.CASES_TREND, applicationContext.getBean(CasesTrendContentValidator.class))
+        .put(WidgetType.NOT_PASSED,
+            applicationContext.getBean(NotPassedTestsContentValidator.class))
+        .put(WidgetType.UNIQUE_BUG_TABLE,
+            applicationContext.getBean(UniqueBugContentValidator.class))
+        .put(WidgetType.BUG_TREND, applicationContext.getBean(BugTrendChartContentValidator.class))
+        .put(WidgetType.ACTIVITY, applicationContext.getBean(ActivityContentValidator.class))
+        .put(WidgetType.LAUNCHES_COMPARISON_CHART,
+            applicationContext.getBean(LaunchesComparisonContentValidator.class))
+        .put(WidgetType.LAUNCHES_DURATION_CHART,
+            applicationContext.getBean(LaunchesDurationContentValidator.class))
+        .put(WidgetType.LAUNCHES_TABLE,
+            applicationContext.getBean(LaunchesTableContentValidator.class))
+        .put(WidgetType.TOP_TEST_CASES,
+            applicationContext.getBean(TopTestCasesContentValidator.class))
+        .put(WidgetType.PASSING_RATE_PER_LAUNCH,
+            applicationContext.getBean(PassingRatePerLaunchContentValidator.class))
+        .put(WidgetType.MOST_TIME_CONSUMING,
+            applicationContext.getBean(MostTimeConsumingContentValidator.class))
+        .put(WidgetType.PRODUCT_STATUS,
+            applicationContext.getBean(ProductStatusContentValidator.class))
+        .build();
+  }
 
-	@Bean("multilevelValidatorLoader")
-	public Map<WidgetType, MultilevelValidatorStrategy> multilevelValidatorLoader() {
-		return ImmutableMap.<WidgetType, MultilevelValidatorStrategy>builder().put(WidgetType.CUMULATIVE,
-				applicationContext.getBean(CumulativeTrendChartValidator.class)
-		)
-				.put(WidgetType.TOP_PATTERN_TEMPLATES, applicationContext.getBean(TopPatternContentValidator.class))
-				.put(WidgetType.COMPONENT_HEALTH_CHECK, applicationContext.getBean(ComponentHealthCheckContentValidator.class))
-				.put(WidgetType.COMPONENT_HEALTH_CHECK_TABLE, applicationContext.getBean(ComponentHealthCheckContentValidator.class))
-				.build();
-	}
+  @Bean("multilevelValidatorLoader")
+  public Map<WidgetType, MultilevelValidatorStrategy> multilevelValidatorLoader() {
+    return ImmutableMap.<WidgetType, MultilevelValidatorStrategy>builder()
+        .put(WidgetType.CUMULATIVE,
+            applicationContext.getBean(CumulativeTrendChartValidator.class)
+        )
+        .put(WidgetType.TOP_PATTERN_TEMPLATES,
+            applicationContext.getBean(TopPatternContentValidator.class))
+        .put(WidgetType.COMPONENT_HEALTH_CHECK,
+            applicationContext.getBean(ComponentHealthCheckContentValidator.class))
+        .put(WidgetType.COMPONENT_HEALTH_CHECK_TABLE,
+            applicationContext.getBean(ComponentHealthCheckContentValidator.class))
+        .build();
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/XmlImportConfig.java b/src/main/java/com/epam/ta/reportportal/core/configs/XmlImportConfig.java
index a070d630b0..fe41c4a6d2 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/XmlImportConfig.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/XmlImportConfig.java
@@ -26,4 +26,5 @@
 @Configuration
 @Conditional(Conditions.NotTestCondition.class)
 public class XmlImportConfig {
+
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/analyzer/auto/LaunchAutoAnalysisConfig.java b/src/main/java/com/epam/ta/reportportal/core/configs/analyzer/auto/LaunchAutoAnalysisConfig.java
index ce36e19ac5..9cce40db47 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/analyzer/auto/LaunchAutoAnalysisConfig.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/analyzer/auto/LaunchAutoAnalysisConfig.java
@@ -37,53 +37,57 @@
 @Configuration
 public class LaunchAutoAnalysisConfig {
 
-	private final GetLaunchHandler getLaunchHandler;
+  private final GetLaunchHandler getLaunchHandler;
 
-	private final AnalyzeCollectorFactory analyzeCollectorFactory;
-	private final AnalyzerService analyzerService;
+  private final AnalyzeCollectorFactory analyzeCollectorFactory;
+  private final AnalyzerService analyzerService;
 
-	private final LogIndexer logIndexer;
+  private final LogIndexer logIndexer;
 
-	private final TaskExecutor autoAnalyzeTaskExecutor;
+  private final TaskExecutor autoAnalyzeTaskExecutor;
 
-	@Autowired
-	public LaunchAutoAnalysisConfig(GetLaunchHandler getLaunchHandler, AnalyzeCollectorFactory analyzeCollectorFactory,
-			AnalyzerService analyzerService, LogIndexer logIndexer, TaskExecutor autoAnalyzeTaskExecutor) {
-		this.getLaunchHandler = getLaunchHandler;
-		this.analyzeCollectorFactory = analyzeCollectorFactory;
-		this.analyzerService = analyzerService;
-		this.logIndexer = logIndexer;
-		this.autoAnalyzeTaskExecutor = autoAnalyzeTaskExecutor;
-	}
+  @Autowired
+  public LaunchAutoAnalysisConfig(GetLaunchHandler getLaunchHandler,
+      AnalyzeCollectorFactory analyzeCollectorFactory,
+      AnalyzerService analyzerService, LogIndexer logIndexer,
+      TaskExecutor autoAnalyzeTaskExecutor) {
+    this.getLaunchHandler = getLaunchHandler;
+    this.analyzeCollectorFactory = analyzeCollectorFactory;
+    this.analyzerService = analyzerService;
+    this.logIndexer = logIndexer;
+    this.autoAnalyzeTaskExecutor = autoAnalyzeTaskExecutor;
+  }
 
-	@Bean
-	public LaunchAutoAnalysisStarter manualAnalysisStarter() {
-		return new ExistingAnalyzerStarter(analyzerService, asyncAutoAnalysisStarter());
-	}
+  @Bean
+  public LaunchAutoAnalysisStarter manualAnalysisStarter() {
+    return new ExistingAnalyzerStarter(analyzerService, asyncAutoAnalysisStarter());
+  }
 
-	@Bean
-	public LaunchAutoAnalysisStarter autoAnalysisStarter() {
-		return new ExistingAnalyzerStarter(analyzerService, indexingAutoAnalysisStarter());
-	}
+  @Bean
+  public LaunchAutoAnalysisStarter autoAnalysisStarter() {
+    return new ExistingAnalyzerStarter(analyzerService, indexingAutoAnalysisStarter());
+  }
 
-	@Bean
-	public CollectingAutoAnalysisStarter collectingAutoAnalysisStarter() {
-		return new CollectingAutoAnalysisStarter(getLaunchHandler, analyzeCollectorFactory, analyzerService, logIndexer);
-	}
+  @Bean
+  public CollectingAutoAnalysisStarter collectingAutoAnalysisStarter() {
+    return new CollectingAutoAnalysisStarter(getLaunchHandler, analyzeCollectorFactory,
+        analyzerService, logIndexer);
+  }
 
-	@Bean
-	public AsyncAutoAnalysisStarter asyncAutoAnalysisStarter() {
-		return new AsyncAutoAnalysisStarter(autoAnalyzeTaskExecutor, collectingAutoAnalysisStarter());
-	}
+  @Bean
+  public AsyncAutoAnalysisStarter asyncAutoAnalysisStarter() {
+    return new AsyncAutoAnalysisStarter(autoAnalyzeTaskExecutor, collectingAutoAnalysisStarter());
+  }
 
-	@Bean
-	public AutoAnalysisEnabledStarter autoAnalysisEnabledStarter() {
-		return new AutoAnalysisEnabledStarter(collectingAutoAnalysisStarter());
-	}
+  @Bean
+  public AutoAnalysisEnabledStarter autoAnalysisEnabledStarter() {
+    return new AutoAnalysisEnabledStarter(collectingAutoAnalysisStarter());
+  }
 
-	@Bean
-	public IndexingAutoAnalysisStarter indexingAutoAnalysisStarter() {
-		return new IndexingAutoAnalysisStarter(getLaunchHandler, logIndexer, autoAnalysisEnabledStarter());
-	}
+  @Bean
+  public IndexingAutoAnalysisStarter indexingAutoAnalysisStarter() {
+    return new IndexingAutoAnalysisStarter(getLaunchHandler, logIndexer,
+        autoAnalysisEnabledStarter());
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/cluster/GenerateClusterPipelineConfig.java b/src/main/java/com/epam/ta/reportportal/core/configs/cluster/GenerateClusterPipelineConfig.java
index 500efbed75..5df770f458 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/cluster/GenerateClusterPipelineConfig.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/cluster/GenerateClusterPipelineConfig.java
@@ -26,56 +26,57 @@
 import com.epam.ta.reportportal.dao.ItemAttributeRepository;
 import com.epam.ta.reportportal.dao.LogRepository;
 import com.epam.ta.reportportal.pipeline.PipelineConstructor;
+import java.util.List;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
-import java.util.List;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Configuration
 public class GenerateClusterPipelineConfig {
 
-	private final CreateClusterHandler createClusterHandler;
+  private final CreateClusterHandler createClusterHandler;
 
-	private final ClusterDataProviderResolver clusterDataProviderResolver;
+  private final ClusterDataProviderResolver clusterDataProviderResolver;
 
-	private final ClusterRepository clusterRepository;
-	private final LogRepository logRepository;
-	private final ItemAttributeRepository itemAttributeRepository;
+  private final ClusterRepository clusterRepository;
+  private final LogRepository logRepository;
+  private final ItemAttributeRepository itemAttributeRepository;
 
-	@Autowired
-	public GenerateClusterPipelineConfig(CreateClusterHandler createClusterHandler, ClusterDataProviderResolver clusterDataProviderResolver,
-			ClusterRepository clusterRepository, LogRepository logRepository, ItemAttributeRepository itemAttributeRepository) {
-		this.createClusterHandler = createClusterHandler;
-		this.clusterDataProviderResolver = clusterDataProviderResolver;
-		this.clusterRepository = clusterRepository;
-		this.logRepository = logRepository;
-		this.itemAttributeRepository = itemAttributeRepository;
-	}
+  @Autowired
+  public GenerateClusterPipelineConfig(CreateClusterHandler createClusterHandler,
+      ClusterDataProviderResolver clusterDataProviderResolver,
+      ClusterRepository clusterRepository, LogRepository logRepository,
+      ItemAttributeRepository itemAttributeRepository) {
+    this.createClusterHandler = createClusterHandler;
+    this.clusterDataProviderResolver = clusterDataProviderResolver;
+    this.clusterRepository = clusterRepository;
+    this.logRepository = logRepository;
+    this.itemAttributeRepository = itemAttributeRepository;
+  }
 
-	@Bean
-	public PipelineConstructor<GenerateClustersConfig> generateClustersPipelineConstructor() {
-		return new PipelineConstructor<>(List.of(deleteClustersPartProvider(),
-				saveClusterDataPartProvider(),
-				saveLastRunAttributePartProvider()
-		));
-	}
+  @Bean
+  public PipelineConstructor<GenerateClustersConfig> generateClustersPipelineConstructor() {
+    return new PipelineConstructor<>(List.of(deleteClustersPartProvider(),
+        saveClusterDataPartProvider(),
+        saveLastRunAttributePartProvider()
+    ));
+  }
 
-	@Bean
-	public DeleteClustersPartProvider deleteClustersPartProvider() {
-		return new DeleteClustersPartProvider(clusterRepository, logRepository);
-	}
+  @Bean
+  public DeleteClustersPartProvider deleteClustersPartProvider() {
+    return new DeleteClustersPartProvider(clusterRepository, logRepository);
+  }
 
-	@Bean
-	public SaveClusterDataPartProvider saveClusterDataPartProvider() {
-		return new SaveClusterDataPartProvider(clusterDataProviderResolver, createClusterHandler);
-	}
+  @Bean
+  public SaveClusterDataPartProvider saveClusterDataPartProvider() {
+    return new SaveClusterDataPartProvider(clusterDataProviderResolver, createClusterHandler);
+  }
 
-	@Bean
-	public SaveLastRunAttributePartProvider saveLastRunAttributePartProvider() {
-		return new SaveLastRunAttributePartProvider(itemAttributeRepository);
-	}
+  @Bean
+  public SaveLastRunAttributePartProvider saveLastRunAttributePartProvider() {
+    return new SaveLastRunAttributePartProvider(itemAttributeRepository);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/cluster/data/evaluator/DataProviderEvaluatorConfig.java b/src/main/java/com/epam/ta/reportportal/core/configs/cluster/data/evaluator/DataProviderEvaluatorConfig.java
index 21cadb51bc..e53c41958a 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/cluster/data/evaluator/DataProviderEvaluatorConfig.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/cluster/data/evaluator/DataProviderEvaluatorConfig.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2021 EPAM Systems
- *  
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- *  
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- *  
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -20,35 +20,38 @@
 import com.epam.ta.reportportal.core.launch.cluster.pipeline.data.AnalyzerItemClusterDataProvider;
 import com.epam.ta.reportportal.core.launch.cluster.pipeline.data.AnalyzerLaunchClusterDataProvider;
 import com.epam.ta.reportportal.core.launch.cluster.pipeline.data.resolver.evaluator.ClusterDataProviderEvaluator;
+import java.util.function.Predicate;
 import org.apache.commons.collections4.CollectionUtils;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
-import java.util.function.Predicate;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Configuration
 public class DataProviderEvaluatorConfig {
 
-	@Bean
-	public ClusterDataProviderEvaluator launchClusterDataProviderEvaluator(AnalyzerLaunchClusterDataProvider launchClusterDataProvider) {
-		return new ClusterDataProviderEvaluator(launchClusterDataProviderPredicate(), launchClusterDataProvider);
-	}
-
-	@Bean
-	public ClusterDataProviderEvaluator itemClusterDataProviderEvaluator(AnalyzerItemClusterDataProvider itemClusterDataProvider) {
-		return new ClusterDataProviderEvaluator(itemClusterDataProviderPredicate(), itemClusterDataProvider);
-	}
-
-	@Bean
-	public Predicate<GenerateClustersConfig> launchClusterDataProviderPredicate() {
-		return config -> CollectionUtils.isEmpty(config.getEntityContext().getItemIds());
-	}
-
-	@Bean
-	public Predicate<GenerateClustersConfig> itemClusterDataProviderPredicate() {
-		return config -> CollectionUtils.isNotEmpty(config.getEntityContext().getItemIds());
-	}
+  @Bean
+  public ClusterDataProviderEvaluator launchClusterDataProviderEvaluator(
+      AnalyzerLaunchClusterDataProvider launchClusterDataProvider) {
+    return new ClusterDataProviderEvaluator(launchClusterDataProviderPredicate(),
+        launchClusterDataProvider);
+  }
+
+  @Bean
+  public ClusterDataProviderEvaluator itemClusterDataProviderEvaluator(
+      AnalyzerItemClusterDataProvider itemClusterDataProvider) {
+    return new ClusterDataProviderEvaluator(itemClusterDataProviderPredicate(),
+        itemClusterDataProvider);
+  }
+
+  @Bean
+  public Predicate<GenerateClustersConfig> launchClusterDataProviderPredicate() {
+    return config -> CollectionUtils.isEmpty(config.getEntityContext().getItemIds());
+  }
+
+  @Bean
+  public Predicate<GenerateClustersConfig> itemClusterDataProviderPredicate() {
+    return config -> CollectionUtils.isNotEmpty(config.getEntityContext().getItemIds());
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/cluster/data/provider/DataProviderConfig.java b/src/main/java/com/epam/ta/reportportal/core/configs/cluster/data/provider/DataProviderConfig.java
index 6e8b2b0a67..d24e0088c8 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/cluster/data/provider/DataProviderConfig.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/cluster/data/provider/DataProviderConfig.java
@@ -31,28 +31,30 @@
 @Configuration
 public class DataProviderConfig {
 
-	private final GetLaunchHandler getLaunchHandler;
-
-	private final LaunchPreparerService launchPreparerService;
-	private final AnalyzerServiceClient analyzerServiceClient;
-
-	private final TestItemRepository testItemRepository;
-
-	public DataProviderConfig(GetLaunchHandler getLaunchHandler, LaunchPreparerService launchPreparerService,
-			AnalyzerServiceClient analyzerServiceClient, TestItemRepository testItemRepository) {
-		this.getLaunchHandler = getLaunchHandler;
-		this.launchPreparerService = launchPreparerService;
-		this.analyzerServiceClient = analyzerServiceClient;
-		this.testItemRepository = testItemRepository;
-	}
-
-	@Bean
-	public AnalyzerLaunchClusterDataProvider analyzerLaunchClusterDataProvider() {
-		return new AnalyzerLaunchClusterDataProvider(analyzerServiceClient, launchPreparerService);
-	}
-
-	@Bean
-	public AnalyzerItemClusterDataProvider analyzerItemClusterDataProvider() {
-		return new AnalyzerItemClusterDataProvider(analyzerServiceClient, getLaunchHandler, testItemRepository, launchPreparerService);
-	}
+  private final GetLaunchHandler getLaunchHandler;
+
+  private final LaunchPreparerService launchPreparerService;
+  private final AnalyzerServiceClient analyzerServiceClient;
+
+  private final TestItemRepository testItemRepository;
+
+  public DataProviderConfig(GetLaunchHandler getLaunchHandler,
+      LaunchPreparerService launchPreparerService,
+      AnalyzerServiceClient analyzerServiceClient, TestItemRepository testItemRepository) {
+    this.getLaunchHandler = getLaunchHandler;
+    this.launchPreparerService = launchPreparerService;
+    this.analyzerServiceClient = analyzerServiceClient;
+    this.testItemRepository = testItemRepository;
+  }
+
+  @Bean
+  public AnalyzerLaunchClusterDataProvider analyzerLaunchClusterDataProvider() {
+    return new AnalyzerLaunchClusterDataProvider(analyzerServiceClient, launchPreparerService);
+  }
+
+  @Bean
+  public AnalyzerItemClusterDataProvider analyzerItemClusterDataProvider() {
+    return new AnalyzerItemClusterDataProvider(analyzerServiceClient, getLaunchHandler,
+        testItemRepository, launchPreparerService);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/cluster/data/resolver/DataProviderResolverConfig.java b/src/main/java/com/epam/ta/reportportal/core/configs/cluster/data/resolver/DataProviderResolverConfig.java
index f2b4efcb57..58a353d4c2 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/cluster/data/resolver/DataProviderResolverConfig.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/cluster/data/resolver/DataProviderResolverConfig.java
@@ -18,21 +18,22 @@
 
 import com.epam.ta.reportportal.core.launch.cluster.pipeline.data.resolver.ClusterDataProviderResolver;
 import com.epam.ta.reportportal.core.launch.cluster.pipeline.data.resolver.evaluator.ClusterDataProviderEvaluator;
+import java.util.List;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
-import java.util.List;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Configuration
 public class DataProviderResolverConfig {
 
-	@Bean
-	public ClusterDataProviderResolver clusterDataProviderResolver(ClusterDataProviderEvaluator launchClusterDataProviderEvaluator,
-			ClusterDataProviderEvaluator itemClusterDataProviderEvaluator) {
-		return new ClusterDataProviderResolver(List.of(launchClusterDataProviderEvaluator, itemClusterDataProviderEvaluator));
-	}
+  @Bean
+  public ClusterDataProviderResolver clusterDataProviderResolver(
+      ClusterDataProviderEvaluator launchClusterDataProviderEvaluator,
+      ClusterDataProviderEvaluator itemClusterDataProviderEvaluator) {
+    return new ClusterDataProviderResolver(
+        List.of(launchClusterDataProviderEvaluator, itemClusterDataProviderEvaluator));
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/cluster/starter/UniqueErrorAnalysisStarterConfig.java b/src/main/java/com/epam/ta/reportportal/core/configs/cluster/starter/UniqueErrorAnalysisStarterConfig.java
index f1e0352c89..fedf39c943 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/cluster/starter/UniqueErrorAnalysisStarterConfig.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/cluster/starter/UniqueErrorAnalysisStarterConfig.java
@@ -29,13 +29,15 @@
 @Configuration
 public class UniqueErrorAnalysisStarterConfig {
 
-	@Bean
-	public UniqueErrorAnalysisStarter uniqueErrorAnalysisStarter(@Autowired UniqueErrorGenerator uniqueErrorGenerator) {
-		return new UniqueErrorAnalysisStarter(uniqueErrorGenerator);
-	}
+  @Bean
+  public UniqueErrorAnalysisStarter uniqueErrorAnalysisStarter(
+      @Autowired UniqueErrorGenerator uniqueErrorGenerator) {
+    return new UniqueErrorAnalysisStarter(uniqueErrorGenerator);
+  }
 
-	@Bean
-	public UniqueErrorAnalysisStarter uniqueErrorAnalysisStarterAsync(@Autowired UniqueErrorGeneratorAsync uniqueErrorGeneratorAsync) {
-		return new UniqueErrorAnalysisStarter(uniqueErrorGeneratorAsync);
-	}
+  @Bean
+  public UniqueErrorAnalysisStarter uniqueErrorAnalysisStarterAsync(
+      @Autowired UniqueErrorGeneratorAsync uniqueErrorGeneratorAsync) {
+    return new UniqueErrorAnalysisStarter(uniqueErrorGeneratorAsync);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/event/listener/EventListenerConfig.java b/src/main/java/com/epam/ta/reportportal/core/configs/event/listener/EventListenerConfig.java
index be84788721..1ea9ef6dc7 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/event/listener/EventListenerConfig.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/event/listener/EventListenerConfig.java
@@ -17,31 +17,37 @@
 package com.epam.ta.reportportal.core.configs.event.listener;
 
 import com.epam.ta.reportportal.core.events.activity.LaunchFinishedEvent;
-import com.epam.ta.reportportal.core.events.activity.item.ItemFinishedEvent;
+import com.epam.ta.reportportal.core.events.activity.item.IssueResolvedEvent;
+import com.epam.ta.reportportal.core.events.activity.item.TestItemFinishedEvent;
 import com.epam.ta.reportportal.core.events.listener.LaunchFinishedEventListener;
 import com.epam.ta.reportportal.core.events.listener.TestItemFinishedEventListener;
+import com.epam.ta.reportportal.core.events.listener.TestItemIssueResolvedEventListener;
 import com.epam.ta.reportportal.core.events.subscriber.impl.delegate.ProjectConfigDelegatingSubscriber;
+import java.util.List;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
-import java.util.List;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Configuration
 public class EventListenerConfig {
 
-	@Bean
-	public LaunchFinishedEventListener launchFinishedEventListener(
-			ProjectConfigDelegatingSubscriber<LaunchFinishedEvent> launchFinishedDelegatingSubscriber) {
-		return new LaunchFinishedEventListener(List.of(launchFinishedDelegatingSubscriber));
-	}
+  @Bean
+  public LaunchFinishedEventListener launchFinishedEventListener(
+      ProjectConfigDelegatingSubscriber<LaunchFinishedEvent> launchFinishedDelegatingSubscriber) {
+    return new LaunchFinishedEventListener(List.of(launchFinishedDelegatingSubscriber));
+  }
 
-	@Bean
-	public TestItemFinishedEventListener testItemFinishedEventListener(
-			ProjectConfigDelegatingSubscriber<ItemFinishedEvent> itemFinishedDelegatingSubscriber) {
-		return new TestItemFinishedEventListener(List.of(itemFinishedDelegatingSubscriber));
-	}
+  @Bean
+  public TestItemIssueResolvedEventListener testItemIssueResolvedEventListener(
+      ProjectConfigDelegatingSubscriber<IssueResolvedEvent> itemIssueResolvedDelegatingSubscriber) {
+    return new TestItemIssueResolvedEventListener(List.of(itemIssueResolvedDelegatingSubscriber));
+  }
 
-}
+  @Bean
+  public TestItemFinishedEventListener testItemFinishedEventListener(
+      ProjectConfigDelegatingSubscriber<TestItemFinishedEvent> testItemFinishedDelegatingSubscriber) {
+    return new TestItemFinishedEventListener(List.of(testItemFinishedDelegatingSubscriber));
+  }
+}
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/event/publisher/EventPublisherConfig.java b/src/main/java/com/epam/ta/reportportal/core/configs/event/publisher/EventPublisherConfig.java
index 6dba24825c..c46e938513 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/event/publisher/EventPublisherConfig.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/event/publisher/EventPublisherConfig.java
@@ -16,42 +16,42 @@
 
 package com.epam.ta.reportportal.core.configs.event.publisher;
 
+import static org.springframework.context.support.AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME;
+
 import com.epam.reportportal.extension.event.LaunchAutoAnalysisFinishEvent;
 import com.epam.reportportal.extension.event.LaunchStartUniqueErrorAnalysisEvent;
 import com.epam.reportportal.extension.event.LaunchUniqueErrorAnalysisFinishEvent;
 import com.epam.ta.reportportal.core.events.multicaster.DelegatingApplicationEventMulticaster;
+import java.util.Set;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.event.ApplicationEventMulticaster;
 import org.springframework.util.ErrorHandler;
 
-import java.util.Set;
-
-import static org.springframework.context.support.AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Configuration
 public class EventPublisherConfig {
 
-	private final ErrorHandler loggingEventErrorHandler;
-
-	@Autowired
-	public EventPublisherConfig(ErrorHandler loggingEventErrorHandler) {
-		this.loggingEventErrorHandler = loggingEventErrorHandler;
-	}
-
-	@Bean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)
-	public ApplicationEventMulticaster applicationEventMulticaster() {
-		final DelegatingApplicationEventMulticaster eventMulticaster = new DelegatingApplicationEventMulticaster(Set.of(
-				LaunchAutoAnalysisFinishEvent.class,
-				LaunchUniqueErrorAnalysisFinishEvent.class,
-				LaunchStartUniqueErrorAnalysisEvent.class
-		));
-		eventMulticaster.setErrorHandler(loggingEventErrorHandler);
-		return eventMulticaster;
-	}
+  private final ErrorHandler loggingEventErrorHandler;
+
+  @Autowired
+  public EventPublisherConfig(ErrorHandler loggingEventErrorHandler) {
+    this.loggingEventErrorHandler = loggingEventErrorHandler;
+  }
+
+  @Bean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)
+  public ApplicationEventMulticaster applicationEventMulticaster() {
+    final DelegatingApplicationEventMulticaster eventMulticaster = new DelegatingApplicationEventMulticaster(
+        Set.of(
+            LaunchAutoAnalysisFinishEvent.class,
+            LaunchUniqueErrorAnalysisFinishEvent.class,
+            LaunchStartUniqueErrorAnalysisEvent.class
+        ));
+    eventMulticaster.setErrorHandler(loggingEventErrorHandler);
+    return eventMulticaster;
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/event/publisher/LoggingEventErrorHandler.java b/src/main/java/com/epam/ta/reportportal/core/configs/event/publisher/LoggingEventErrorHandler.java
index edd66b1506..62274dd77b 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/event/publisher/LoggingEventErrorHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/event/publisher/LoggingEventErrorHandler.java
@@ -27,10 +27,10 @@
 @Service
 public class LoggingEventErrorHandler implements ErrorHandler {
 
-	private static final Logger LOGGER = LoggerFactory.getLogger(LoggingEventErrorHandler.class);
+  private static final Logger LOGGER = LoggerFactory.getLogger(LoggingEventErrorHandler.class);
 
-	@Override
-	public void handleError(Throwable throwable) {
-		LOGGER.error("Error during event publishing", throwable);
-	}
+  @Override
+  public void handleError(Throwable throwable) {
+    LOGGER.error("Error during event publishing", throwable);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/event/subscriber/EventSubscriberConfig.java b/src/main/java/com/epam/ta/reportportal/core/configs/event/subscriber/EventSubscriberConfig.java
index f53fd11b54..d7a5776e08 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/event/subscriber/EventSubscriberConfig.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/event/subscriber/EventSubscriberConfig.java
@@ -17,45 +17,64 @@
 package com.epam.ta.reportportal.core.configs.event.subscriber;
 
 import com.epam.ta.reportportal.core.events.activity.LaunchFinishedEvent;
-import com.epam.ta.reportportal.core.events.activity.item.ItemFinishedEvent;
+import com.epam.ta.reportportal.core.events.activity.item.IssueResolvedEvent;
+import com.epam.ta.reportportal.core.events.activity.item.TestItemFinishedEvent;
+import com.epam.ta.reportportal.core.events.handler.item.TestItemAutoAnalysisRunner;
+import com.epam.ta.reportportal.core.events.handler.item.TestItemPatternAnalysisRunner;
 import com.epam.ta.reportportal.core.events.handler.item.TestItemIndexRunner;
 import com.epam.ta.reportportal.core.events.handler.item.TestItemUniqueErrorAnalysisRunner;
-import com.epam.ta.reportportal.core.events.handler.launch.*;
+import com.epam.ta.reportportal.core.events.handler.launch.LaunchAnalysisFinishEventPublisher;
+import com.epam.ta.reportportal.core.events.handler.launch.LaunchAutoAnalysisRunner;
+import com.epam.ta.reportportal.core.events.handler.launch.LaunchNotificationRunner;
+import com.epam.ta.reportportal.core.events.handler.launch.LaunchPatternAnalysisRunner;
+import com.epam.ta.reportportal.core.events.handler.launch.LaunchUniqueErrorAnalysisRunner;
 import com.epam.ta.reportportal.core.events.subscriber.impl.delegate.ProjectConfigDelegatingSubscriber;
 import com.epam.ta.reportportal.core.project.config.ProjectConfigProvider;
+import java.util.List;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
-import java.util.List;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Configuration
 public class EventSubscriberConfig {
 
-	@Bean
-	public ProjectConfigDelegatingSubscriber<LaunchFinishedEvent> launchFinishedDelegatingSubscriber(
-			ProjectConfigProvider projectConfigProvider, LaunchAutoAnalysisRunner autoAnalysisEventHandler,
-			LaunchUniqueErrorAnalysisRunner uniqueErrorAnalysisEventHandler,
-			LaunchAnalysisFinishEventPublisher launchAnalysisFinishEventPublisher, LaunchPatternAnalysisRunner patternAnalysisEventHandler,
-			LaunchNotificationRunner notificationEventHandler) {
-		return new ProjectConfigDelegatingSubscriber<>(projectConfigProvider,
-				List.of(autoAnalysisEventHandler,
-						uniqueErrorAnalysisEventHandler,
-						launchAnalysisFinishEventPublisher,
-						patternAnalysisEventHandler,
-						notificationEventHandler
-				)
-		);
-	}
+  @Bean
+  public ProjectConfigDelegatingSubscriber<LaunchFinishedEvent> launchFinishedDelegatingSubscriber(
+      ProjectConfigProvider projectConfigProvider,
+      LaunchAutoAnalysisRunner autoAnalysisEventHandler,
+      LaunchUniqueErrorAnalysisRunner uniqueErrorAnalysisEventHandler,
+      LaunchAnalysisFinishEventPublisher launchAnalysisFinishEventPublisher,
+      LaunchPatternAnalysisRunner patternAnalysisEventHandler,
+      LaunchNotificationRunner notificationEventHandler) {
+    return new ProjectConfigDelegatingSubscriber<>(projectConfigProvider,
+        List.of(autoAnalysisEventHandler,
+            uniqueErrorAnalysisEventHandler,
+            launchAnalysisFinishEventPublisher,
+            patternAnalysisEventHandler,
+            notificationEventHandler
+        )
+    );
+  }
+
+  @Bean
+  public ProjectConfigDelegatingSubscriber<IssueResolvedEvent> itemIssueResolvedDelegatingSubscriber(
+      ProjectConfigProvider projectConfigProvider, TestItemIndexRunner testItemIndexRunner,
+      TestItemUniqueErrorAnalysisRunner testItemUniqueErrorAnalysisRunner) {
+    return new ProjectConfigDelegatingSubscriber<>(projectConfigProvider,
+        List.of(testItemIndexRunner, testItemUniqueErrorAnalysisRunner)
+    );
+  }
+
+  @Bean
+  public ProjectConfigDelegatingSubscriber<TestItemFinishedEvent> testItemFinishedDelegatingSubscriber(
+      ProjectConfigProvider projectConfigProvider,
+      TestItemPatternAnalysisRunner testItemPatternAnalysisRunner,
+      TestItemAutoAnalysisRunner testItemAutoAnalysisRunner) {
+    return new ProjectConfigDelegatingSubscriber<>(projectConfigProvider,
+        List.of(testItemPatternAnalysisRunner, testItemAutoAnalysisRunner)
+    );
+  }
 
-	@Bean
-	public ProjectConfigDelegatingSubscriber<ItemFinishedEvent> itemFinishedDelegatingSubscriber(
-			ProjectConfigProvider projectConfigProvider, TestItemIndexRunner testItemIndexRunner,
-			TestItemUniqueErrorAnalysisRunner testItemUniqueErrorAnalysisRunner) {
-		return new ProjectConfigDelegatingSubscriber<>(projectConfigProvider,
-				List.of(testItemIndexRunner, testItemUniqueErrorAnalysisRunner)
-		);
-	}
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/rabbit/AnalyzerRabbitMqConfiguration.java b/src/main/java/com/epam/ta/reportportal/core/configs/rabbit/AnalyzerRabbitMqConfiguration.java
index d585d996c1..89ba9e755e 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/rabbit/AnalyzerRabbitMqConfiguration.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/rabbit/AnalyzerRabbitMqConfiguration.java
@@ -22,6 +22,7 @@
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.rabbitmq.http.client.Client;
+import java.net.URI;
 import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
 import org.springframework.amqp.rabbit.connection.ConnectionFactory;
 import org.springframework.amqp.rabbit.core.RabbitTemplate;
@@ -33,8 +34,6 @@
 import org.springframework.context.annotation.Conditional;
 import org.springframework.context.annotation.Configuration;
 
-import java.net.URI;
-
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
  */
@@ -42,39 +41,41 @@
 @Conditional(Conditions.NotTestCondition.class)
 public class AnalyzerRabbitMqConfiguration {
 
-	@Autowired
-	private MessageConverter messageConverter;
+  @Autowired
+  private MessageConverter messageConverter;
 
-	@Bean
-	public RabbitMqManagementClient managementTemplate(@Value("${rp.amqp.api-address}") String address,
-			@Value("${rp.amqp.analyzer-vhost}") String virtualHost) {
-		Client rabbitClient;
-		try {
-			rabbitClient = new Client(address);
-		} catch (Exception e) {
-			throw new ReportPortalException(
-					ErrorType.UNCLASSIFIED_REPORT_PORTAL_ERROR,
-					"Cannot create a HTTP rabbit client instance. Incorrect api address " + address
-			);
-		}
-		return new RabbitMqManagementClientTemplate(rabbitClient, virtualHost);
-	}
+  @Bean
+  public RabbitMqManagementClient managementTemplate(
+      @Value("${rp.amqp.api-address}") String address,
+      @Value("${rp.amqp.analyzer-vhost}") String virtualHost) {
+    Client rabbitClient;
+    try {
+      rabbitClient = new Client(address);
+    } catch (Exception e) {
+      throw new ReportPortalException(
+          ErrorType.UNCLASSIFIED_REPORT_PORTAL_ERROR,
+          "Cannot create a HTTP rabbit client instance. Incorrect api address " + address
+      );
+    }
+    return new RabbitMqManagementClientTemplate(rabbitClient, virtualHost);
+  }
 
-	@Bean(name = "analyzerConnectionFactory")
-	public ConnectionFactory analyzerConnectionFactory(@Value("${rp.amqp.addresses}") URI addresses,
-			@Value("${rp.amqp.analyzer-vhost}") String virtualHost) {
-		CachingConnectionFactory factory = new CachingConnectionFactory(addresses);
-		factory.setVirtualHost(virtualHost);
-		return factory;
-	}
+  @Bean(name = "analyzerConnectionFactory")
+  public ConnectionFactory analyzerConnectionFactory(@Value("${rp.amqp.addresses}") URI addresses,
+      @Value("${rp.amqp.analyzer-vhost}") String virtualHost) {
+    CachingConnectionFactory factory = new CachingConnectionFactory(addresses);
+    factory.setVirtualHost(virtualHost);
+    return factory;
+  }
 
-	@Bean(name = "analyzerRabbitTemplate")
-	public RabbitTemplate analyzerRabbitTemplate(@Autowired @Qualifier("analyzerConnectionFactory") ConnectionFactory connectionFactory,
-			@Value("${rp.amqp.reply-timeout}") long replyTimeout) {
-		RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
-		rabbitTemplate.setMessageConverter(messageConverter);
-		rabbitTemplate.setReplyTimeout(replyTimeout);
-		return rabbitTemplate;
-	}
+  @Bean(name = "analyzerRabbitTemplate")
+  public RabbitTemplate analyzerRabbitTemplate(
+      @Autowired @Qualifier("analyzerConnectionFactory") ConnectionFactory connectionFactory,
+      @Value("${rp.amqp.reply-timeout}") long replyTimeout) {
+    RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
+    rabbitTemplate.setMessageConverter(messageConverter);
+    rabbitTemplate.setReplyTimeout(replyTimeout);
+    return rabbitTemplate;
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/rabbit/BackgroundProcessingConfiguration.java b/src/main/java/com/epam/ta/reportportal/core/configs/rabbit/BackgroundProcessingConfiguration.java
index 7b62dd2d41..895f250f8b 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/rabbit/BackgroundProcessingConfiguration.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/rabbit/BackgroundProcessingConfiguration.java
@@ -1,7 +1,10 @@
 package com.epam.ta.reportportal.core.configs.rabbit;
 
 import com.epam.ta.reportportal.core.configs.Conditions;
-import org.springframework.amqp.core.*;
+import org.springframework.amqp.core.Binding;
+import org.springframework.amqp.core.BindingBuilder;
+import org.springframework.amqp.core.DirectExchange;
+import org.springframework.amqp.core.Queue;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Conditional;
@@ -10,23 +13,24 @@
 @Configuration
 @Conditional(Conditions.NotTestCondition.class)
 public class BackgroundProcessingConfiguration {
-    public static final String LOG_MESSAGE_SAVING_QUEUE_NAME = "log_message_saving";
-    public static final String LOG_MESSAGE_SAVING_ROUTING_KEY = "log_message_saving";
-    public static final String PROCESSING_EXCHANGE_NAME = "processing";
 
-    @Bean
-    Queue logMessageSavingQueue() {
-        return new Queue(LOG_MESSAGE_SAVING_QUEUE_NAME);
-    }
+  public static final String LOG_MESSAGE_SAVING_QUEUE_NAME = "log_message_saving";
+  public static final String LOG_MESSAGE_SAVING_ROUTING_KEY = "log_message_saving";
+  public static final String PROCESSING_EXCHANGE_NAME = "processing";
 
-    @Bean
-    DirectExchange exchangeProcessing() {
-        return new DirectExchange(PROCESSING_EXCHANGE_NAME);
-    }
+  @Bean
+  Queue logMessageSavingQueue() {
+    return new Queue(LOG_MESSAGE_SAVING_QUEUE_NAME);
+  }
 
-    @Bean
-    Binding bindingSavingLogs(@Qualifier("logMessageSavingQueue") Queue queue,
-                              @Qualifier("exchangeProcessing") DirectExchange exchange) {
-        return BindingBuilder.bind(queue).to(exchange).with(LOG_MESSAGE_SAVING_ROUTING_KEY);
-    }
+  @Bean
+  DirectExchange exchangeProcessing() {
+    return new DirectExchange(PROCESSING_EXCHANGE_NAME);
+  }
+
+  @Bean
+  Binding bindingSavingLogs(@Qualifier("logMessageSavingQueue") Queue queue,
+      @Qualifier("exchangeProcessing") DirectExchange exchange) {
+    return BindingBuilder.bind(queue).to(exchange).with(LOG_MESSAGE_SAVING_ROUTING_KEY);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/rabbit/DeserializablePair.java b/src/main/java/com/epam/ta/reportportal/core/configs/rabbit/DeserializablePair.java
index 6bb0751168..703bc0c1f2 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/rabbit/DeserializablePair.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/rabbit/DeserializablePair.java
@@ -17,32 +17,34 @@
 package com.epam.ta.reportportal.core.configs.rabbit;
 
 /**
- * Jackson's crazy to deserialize class w/o default constructor
- * To avoid mixins, we will create our own pair container
+ * Jackson's crazy to deserialize class w/o default constructor To avoid mixins, we will create our
+ * own pair container
  *
  * @author Konstantin Antipin
  */
 public class DeserializablePair<L, R> {
-	private L left;
 
-	private R right;
+  private L left;
 
-	public DeserializablePair() {}
+  private R right;
 
-	private DeserializablePair(L left, R right) {
-		this.left = left;
-		this.right = right;
-	}
+  public DeserializablePair() {
+  }
 
-	public L getLeft() {
-		return left;
-	}
+  private DeserializablePair(L left, R right) {
+    this.left = left;
+    this.right = right;
+  }
 
-	public R getRight() {
-		return right;
-	}
+  public L getLeft() {
+    return left;
+  }
 
-	public static <L, R> DeserializablePair<L, R> of(L left, R right) {
-		return new DeserializablePair(left, right);
-	}
+  public R getRight() {
+    return right;
+  }
+
+  public static <L, R> DeserializablePair<L, R> of(L left, R right) {
+    return new DeserializablePair(left, right);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/rabbit/InternalConfiguration.java b/src/main/java/com/epam/ta/reportportal/core/configs/rabbit/InternalConfiguration.java
index d546804a45..bbc8fcd843 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/rabbit/InternalConfiguration.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/rabbit/InternalConfiguration.java
@@ -19,7 +19,15 @@
 import com.epam.ta.reportportal.core.configs.Conditions;
 import com.epam.ta.reportportal.core.events.MessageBus;
 import com.epam.ta.reportportal.core.events.MessageBusImpl;
-import org.springframework.amqp.core.*;
+import org.springframework.amqp.core.AmqpTemplate;
+import org.springframework.amqp.core.AnonymousQueue;
+import org.springframework.amqp.core.Base64UrlNamingStrategy;
+import org.springframework.amqp.core.Binding;
+import org.springframework.amqp.core.BindingBuilder;
+import org.springframework.amqp.core.DirectExchange;
+import org.springframework.amqp.core.FanoutExchange;
+import org.springframework.amqp.core.Queue;
+import org.springframework.amqp.core.TopicExchange;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.context.annotation.Bean;
@@ -33,104 +41,100 @@
 @Conditional(Conditions.NotTestCondition.class)
 public class InternalConfiguration {
 
-	/**
-	 * Exchanges
-	 */
-	public static final String EXCHANGE_EVENTS = "broadcast.events";
-	public static final String EXCHANGE_ACTIVITY = "activity";
-	public static final String EXCHANGE_ATTACHMENT = "attachment";
-	public static final String EXCHANGE_NOTIFICATION = "notification";
-
-	/**
-	 * Queues
-	 */
-	public static final String KEY_EVENTS = "broadcast.events";
-	public static final String QUEUE_ACTIVITY = "activity";
-	public static final String QUEUE_ACTIVITY_KEY = "activity.#";
-	public static final String QUEUE_ATTACHMENT_DELETE = "attachment.delete";
-	public static final String QUEUE_EMAIL = "notification.email";
-
-	public static final String QUEUE_QUERY_RQ = "query-rq";
-
-	@Bean
-	public MessageBus messageBus(@Autowired @Qualifier(value = "rabbitTemplate") AmqpTemplate amqpTemplate) {
-		return new MessageBusImpl(amqpTemplate);
-	}
-
-	/**
-	 * Exchanges definition
-	 */
-
-	@Bean
-	public FanoutExchange eventsExchange() {
-		return new FanoutExchange(EXCHANGE_EVENTS, false, false);
-	}
-
-	@Bean
-	public TopicExchange activityExchange() {
-		return new TopicExchange(EXCHANGE_ACTIVITY, true, false);
-	}
-
-	@Bean
-	public DirectExchange attachmentExchange() {
-		return new DirectExchange(EXCHANGE_ATTACHMENT, true, false);
-	}
-
-	@Bean
-	public DirectExchange notificationExchange() {
-		return new DirectExchange(EXCHANGE_NOTIFICATION, true, false);
-	}
-
-	/**
-	 * Queues definition
-	 */
-
-	@Bean
-	public Queue eventsQueue() {
-		return new AnonymousQueue(new Base64UrlNamingStrategy(KEY_EVENTS + "."));
-	}
-
-	@Bean
-	public Queue activityQueue() {
-		return new Queue(QUEUE_ACTIVITY);
-	}
-
-	@Bean
-	public Queue deleteAttachmentQueue() {
-		return new Queue(QUEUE_ATTACHMENT_DELETE);
-	}
-
-	@Bean
-	public Queue queryQueue() {
-		return new Queue(QUEUE_QUERY_RQ);
-	}
-
-	@Bean
-	public Queue emailNotificationQueue() {
-		return new Queue(QUEUE_EMAIL);
-	}
-
-	/**
-	 * Bindings
-	 */
-
-	@Bean
-	public Binding eventsQueueBinding() {
-		return BindingBuilder.bind(eventsQueue()).to(eventsExchange());
-	}
-
-	@Bean
-	public Binding eventsActivityBinding() {
-		return BindingBuilder.bind(activityQueue()).to(activityExchange()).with(QUEUE_ACTIVITY_KEY);
-	}
-
-	@Bean
-	public Binding attachmentDeleteBinding() {
-		return BindingBuilder.bind(deleteAttachmentQueue()).to(attachmentExchange()).with(QUEUE_ATTACHMENT_DELETE);
-	}
-
-	@Bean
-	public Binding emailNotificationBinding() {
-		return BindingBuilder.bind(emailNotificationQueue()).to(notificationExchange()).with(QUEUE_EMAIL);
-	}
+  /**
+   * Exchanges
+   */
+  public static final String EXCHANGE_EVENTS = "broadcast.events";
+  public static final String EXCHANGE_ACTIVITY = "activity";
+  public static final String EXCHANGE_ATTACHMENT = "attachment";
+  public static final String EXCHANGE_NOTIFICATION = "notification";
+
+  /**
+   * Queues
+   */
+  public static final String KEY_EVENTS = "broadcast.events";
+  public static final String QUEUE_ACTIVITY = "activity";
+  public static final String QUEUE_ACTIVITY_KEY = "activity.#";
+  public static final String QUEUE_ATTACHMENT_DELETE = "attachment.delete";
+  public static final String QUEUE_EMAIL = "notification.email";
+
+  public static final String QUEUE_QUERY_RQ = "query-rq";
+
+  @Bean
+  public MessageBus messageBus(
+      @Autowired @Qualifier(value = "rabbitTemplate") AmqpTemplate amqpTemplate) {
+    return new MessageBusImpl(amqpTemplate);
+  }
+
+  //  Exchanges definition
+
+  @Bean
+  public FanoutExchange eventsExchange() {
+    return new FanoutExchange(EXCHANGE_EVENTS, false, false);
+  }
+
+  @Bean
+  public TopicExchange activityExchange() {
+    return new TopicExchange(EXCHANGE_ACTIVITY, true, false);
+  }
+
+  @Bean
+  public DirectExchange attachmentExchange() {
+    return new DirectExchange(EXCHANGE_ATTACHMENT, true, false);
+  }
+
+  @Bean
+  public DirectExchange notificationExchange() {
+    return new DirectExchange(EXCHANGE_NOTIFICATION, true, false);
+  }
+
+  //  Queues definition
+
+  @Bean
+  public Queue eventsQueue() {
+    return new AnonymousQueue(new Base64UrlNamingStrategy(KEY_EVENTS + "."));
+  }
+
+  @Bean
+  public Queue activityQueue() {
+    return new Queue(QUEUE_ACTIVITY);
+  }
+
+  @Bean
+  public Queue deleteAttachmentQueue() {
+    return new Queue(QUEUE_ATTACHMENT_DELETE);
+  }
+
+  @Bean
+  public Queue queryQueue() {
+    return new Queue(QUEUE_QUERY_RQ);
+  }
+
+  @Bean
+  public Queue emailNotificationQueue() {
+    return new Queue(QUEUE_EMAIL);
+  }
+
+  //  Bindings
+
+  @Bean
+  public Binding eventsQueueBinding() {
+    return BindingBuilder.bind(eventsQueue()).to(eventsExchange());
+  }
+
+  @Bean
+  public Binding eventsActivityBinding() {
+    return BindingBuilder.bind(activityQueue()).to(activityExchange()).with(QUEUE_ACTIVITY_KEY);
+  }
+
+  @Bean
+  public Binding attachmentDeleteBinding() {
+    return BindingBuilder.bind(deleteAttachmentQueue()).to(attachmentExchange())
+        .with(QUEUE_ATTACHMENT_DELETE);
+  }
+
+  @Bean
+  public Binding emailNotificationBinding() {
+    return BindingBuilder.bind(emailNotificationQueue()).to(notificationExchange()).with(QUEUE_EMAIL);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/rabbit/RabbitMqConfiguration.java b/src/main/java/com/epam/ta/reportportal/core/configs/rabbit/RabbitMqConfiguration.java
index c4c15571cf..c82aeb9509 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/rabbit/RabbitMqConfiguration.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/rabbit/RabbitMqConfiguration.java
@@ -21,6 +21,7 @@
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.rabbitmq.http.client.Client;
+import java.net.URI;
 import org.springframework.amqp.core.AmqpAdmin;
 import org.springframework.amqp.rabbit.annotation.EnableRabbit;
 import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
@@ -38,8 +39,6 @@
 import org.springframework.context.annotation.Conditional;
 import org.springframework.context.annotation.Configuration;
 
-import java.net.URI;
-
 /**
  * @author Pavel Bortnik
  */
@@ -48,52 +47,55 @@
 @Conditional(Conditions.NotTestCondition.class)
 public class RabbitMqConfiguration {
 
-	@Autowired
-	private ObjectMapper objectMapper;
+  @Autowired
+  private ObjectMapper objectMapper;
 
-	@Bean
-	public MessageConverter jsonMessageConverter() {
-		return new Jackson2JsonMessageConverter(objectMapper);
-	}
+  @Bean
+  public MessageConverter jsonMessageConverter() {
+    return new Jackson2JsonMessageConverter(objectMapper);
+  }
 
-	@Bean
-	public ConnectionFactory connectionFactory(@Value("${rp.amqp.api-address}") String apiAddress,
-			@Value("${rp.amqp.addresses}") URI addresses, @Value("${rp.amqp.base-vhost}") String virtualHost) {
-		try {
-			Client client = new Client(apiAddress);
-			client.createVhost(virtualHost);
-		} catch (Exception e) {
-			throw new ReportPortalException(ErrorType.UNCLASSIFIED_REPORT_PORTAL_ERROR,
-					"Unable to create RabbitMq virtual host: " + e.getMessage()
-			);
-		}
-		final CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory(addresses);
-		cachingConnectionFactory.setVirtualHost(virtualHost);
-		return cachingConnectionFactory;
-	}
+  @Bean
+  public ConnectionFactory connectionFactory(@Value("${rp.amqp.api-address}") String apiAddress,
+      @Value("${rp.amqp.addresses}") URI addresses,
+      @Value("${rp.amqp.base-vhost}") String virtualHost) {
+    try {
+      Client client = new Client(apiAddress);
+      client.createVhost(virtualHost);
+    } catch (Exception e) {
+      throw new ReportPortalException(ErrorType.UNCLASSIFIED_REPORT_PORTAL_ERROR,
+          "Unable to create RabbitMq virtual host: " + e.getMessage()
+      );
+    }
+    final CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory(
+        addresses);
+    cachingConnectionFactory.setVirtualHost(virtualHost);
+    return cachingConnectionFactory;
+  }
 
-	@Bean
-	public AmqpAdmin amqpAdmin(@Autowired ConnectionFactory connectionFactory) {
-		return new RabbitAdmin(connectionFactory);
-	}
+  @Bean
+  public AmqpAdmin amqpAdmin(@Autowired ConnectionFactory connectionFactory) {
+    return new RabbitAdmin(connectionFactory);
+  }
 
-	@Bean(name = "rabbitTemplate")
-	public RabbitTemplate rabbitTemplate(@Autowired @Qualifier("connectionFactory") ConnectionFactory connectionFactory) {
-		RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
-		rabbitTemplate.setMessageConverter(jsonMessageConverter());
-		return rabbitTemplate;
-	}
+  @Bean(name = "rabbitTemplate")
+  public RabbitTemplate rabbitTemplate(
+      @Autowired @Qualifier("connectionFactory") ConnectionFactory connectionFactory) {
+    RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
+    rabbitTemplate.setMessageConverter(jsonMessageConverter());
+    return rabbitTemplate;
+  }
 
-	@Bean
-	public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(
-			@Autowired @Qualifier("connectionFactory") ConnectionFactory connectionFactory) {
-		SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
-		factory.setConnectionFactory(connectionFactory);
-		factory.setDefaultRequeueRejected(false);
-		factory.setErrorHandler(new ConditionalRejectingErrorHandler());
-		factory.setAutoStartup(true);
-		factory.setMessageConverter(jsonMessageConverter());
-		return factory;
-	}
+  @Bean
+  public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(
+      @Autowired @Qualifier("connectionFactory") ConnectionFactory connectionFactory) {
+    SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
+    factory.setConnectionFactory(connectionFactory);
+    factory.setDefaultRequeueRejected(false);
+    factory.setErrorHandler(new ConditionalRejectingErrorHandler());
+    factory.setAutoStartup(true);
+    factory.setMessageConverter(jsonMessageConverter());
+    return factory;
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/rabbit/ReportingConfiguration.java b/src/main/java/com/epam/ta/reportportal/core/configs/rabbit/ReportingConfiguration.java
index 405aaf14d8..6b7cfc6100 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/rabbit/ReportingConfiguration.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/rabbit/ReportingConfiguration.java
@@ -18,9 +18,18 @@
 
 import com.epam.ta.reportportal.core.configs.Conditions;
 import com.epam.ta.reportportal.ws.rabbit.AsyncReportingListener;
+import java.util.ArrayList;
+import java.util.List;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.amqp.core.*;
+import org.springframework.amqp.core.AmqpAdmin;
+import org.springframework.amqp.core.Binding;
+import org.springframework.amqp.core.BindingBuilder;
+import org.springframework.amqp.core.Exchange;
+import org.springframework.amqp.core.ExchangeBuilder;
+import org.springframework.amqp.core.MessageListener;
+import org.springframework.amqp.core.Queue;
+import org.springframework.amqp.core.QueueBuilder;
 import org.springframework.amqp.rabbit.connection.ConnectionFactory;
 import org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer;
 import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
@@ -34,9 +43,6 @@
 import org.springframework.context.annotation.Conditional;
 import org.springframework.context.annotation.Configuration;
 
-import java.util.ArrayList;
-import java.util.List;
-
 /**
  * @author Konstantin Antipin
  */
@@ -44,167 +50,175 @@
 @Conditional(Conditions.NotTestCondition.class)
 public class ReportingConfiguration {
 
-	private static final Logger logger = LoggerFactory.getLogger(ReportingConfiguration.class);
-
-	public static final long DEAD_LETTER_DELAY_MILLIS = 60_000L;
-	public static final long DEAD_LETTER_MAX_RETRY = 10L;
-
-	/**
-	 * Exchanges
-	 */
-	public static final String EXCHANGE_REPORTING = "reporting";
-	public static final String EXCHANGE_REPORTING_RETRY = "reporting.retry";
-
-	/**
-	 * Queue definitions
-	 */
-	public static final String QUEUE_PREFIX = "reporting";
-	public static final String QUEUE_RETRY_PREFIX = "reporting.retry";
-	public static final String QUEUE_DLQ = "reporting.dlq";
-
-	@Value("${rp.amqp.queues}")
-	public int queueAmount;
-
-	/**
-	 * Cluster configuration parameter.
-	 * Number of queues to be processed by this service-api pod (default effectively infinite)
-	 * Note: should correlate with number QUEUE_AMOUNT & number of service-api pods being started in cluster
-	 */
-	@Value("${rp.amqp.queuesPerPod:1000000}")
-	private int queuesPerPod;
-
-	@Autowired
-	private ApplicationContext applicationContext;
-
-	@Autowired
-	private ConfigurableListableBeanFactory configurableBeanFactory;
-
-	@Bean
-	public Exchange reportingExchange(AmqpAdmin amqpAdmin) {
-		Exchange exchange = ExchangeBuilder.directExchange(EXCHANGE_REPORTING).durable(true).build();
-		amqpAdmin.declareExchange(exchange);
-		return exchange;
-	}
-
-	@Bean
-	public Exchange reportingRetryExchange(AmqpAdmin amqpAdmin) {
-		Exchange exchange = ExchangeBuilder.directExchange(EXCHANGE_REPORTING_RETRY).durable(true).build();
-		amqpAdmin.declareExchange(exchange);
-		return exchange;
-	}
-
-	@Bean
-	public List<Queue> queues(AmqpAdmin amqpAdmin) {
-		List<Queue> queues = new ArrayList();
-		for (int i = 0; i < queueAmount; i++) {
-			String index = String.valueOf(i);
-			String queueName = QUEUE_PREFIX + "." + index;
-			Queue queue = QueueBuilder.durable(queueName)
-					.withArgument("x-dead-letter-exchange", EXCHANGE_REPORTING_RETRY)
-					.withArgument("x-dead-letter-routing-key", index)
-					.build();
-			queue.setShouldDeclare(true);
-			queue.setAdminsThatShouldDeclare(amqpAdmin);
-			registerSingleton(queueName, queue);
-			amqpAdmin.declareQueue(queue);
-			queues.add(queue);
-		}
-		return queues;
-	}
-
-	@Bean
-	public List<Queue> retryQueues(AmqpAdmin amqpAdmin) {
-		List<Queue> queues = new ArrayList();
-		for (int i = 0; i < queueAmount; i++) {
-			String index = String.valueOf(i);
-			String queueName = QUEUE_RETRY_PREFIX + "." + index;
-			Queue retryQueue = QueueBuilder.durable(queueName)
-					.withArgument("x-dead-letter-exchange", EXCHANGE_REPORTING)
-					.withArgument("x-dead-letter-routing-key", index)
-					.withArgument("x-message-ttl", DEAD_LETTER_DELAY_MILLIS)
-					.build();
-			retryQueue.setShouldDeclare(true);
-			retryQueue.setAdminsThatShouldDeclare(amqpAdmin);
-			registerSingleton(queueName, retryQueue);
-			amqpAdmin.declareQueue(retryQueue);
-			queues.add(retryQueue);
-		}
-		return queues;
-	}
-
-	@Bean
-	public Queue queueDlq(AmqpAdmin amqpAdmin) {
-		Queue queue = QueueBuilder.durable(QUEUE_DLQ).build();
-		queue.setShouldDeclare(true);
-		queue.setAdminsThatShouldDeclare(amqpAdmin);
-		amqpAdmin.declareQueue(queue);
-		return queue;
-	}
-
-	@Bean
-	public List<Binding> bindings(AmqpAdmin amqpAdmin, @Qualifier("reportingExchange") Exchange reportingExchange,
-			@Qualifier("reportingRetryExchange") Exchange reportingRetryExchange, @Qualifier("queues") List<Queue> queues,
-			@Qualifier("queueDlq") Queue queueDlq, @Qualifier("retryQueues") List<Queue> retryQueues) {
-		List<Binding> bindings = new ArrayList<>();
-		int i = 0;
-		for (Queue queue : queues) {
-			String index = String.valueOf(i);
-			Binding queueBinding = BindingBuilder.bind(queue).to(reportingExchange).with(index).noargs();
-			bindings.add(queueBinding);
-			queueBinding.setShouldDeclare(true);
-			queueBinding.setAdminsThatShouldDeclare(amqpAdmin);
-			amqpAdmin.declareBinding(queueBinding);
-			registerSingleton("queueBinding." + queue.getName(), queueBinding);
-			i++;
-		}
-		i = 0;
-		for (Queue retryQueue : retryQueues) {
-			String index = String.valueOf(i);
-			Binding queueBinding = BindingBuilder.bind(retryQueue).to(reportingRetryExchange).with(index).noargs();
-			bindings.add(queueBinding);
-			queueBinding.setShouldDeclare(true);
-			queueBinding.setAdminsThatShouldDeclare(amqpAdmin);
-			amqpAdmin.declareBinding(queueBinding);
-			registerSingleton("queueBinding." + retryQueue.getName(), queueBinding);
-			i++;
-		}
-		Binding queueBinding = BindingBuilder.bind(queueDlq).to(reportingRetryExchange).with(QUEUE_DLQ).noargs();
-		amqpAdmin.declareBinding(queueBinding);
-
-		return bindings;
-	}
-
-	@Bean
-	@Qualifier("reportingListenerContainers")
-	public List<AbstractMessageListenerContainer> listenerContainers(ConnectionFactory connectionFactory,
-			ApplicationEventPublisher applicationEventPublisher, @Qualifier("queues") List<Queue> queues) {
-		List<AbstractMessageListenerContainer> containers = new ArrayList<>();
-		int consumersCount = 0;
-		while (consumersCount < queuesPerPod) {
-			SimpleMessageListenerContainer listenerContainer = new SimpleMessageListenerContainer(connectionFactory);
-			containers.add(listenerContainer);
-			listenerContainer.setConnectionFactory(connectionFactory);
-			listenerContainer.addQueueNames(queues.get(consumersCount).getName());
-			listenerContainer.setExclusive(true);
-			listenerContainer.setMissingQueuesFatal(false);
-			listenerContainer.setApplicationEventPublisher(applicationEventPublisher);
-			listenerContainer.setupMessageListener(reportingListener());
-			listenerContainer.afterPropertiesSet();
-			consumersCount++;
-			logger.info("Consumer is created, current consumers count is {}", consumersCount);
-		}
-		return containers;
-	}
-
-	@Bean
-	public MessageListener reportingListener() {
-		return new AsyncReportingListener();
-	}
-
-	private void registerSingleton(String name, Object bean) {
-		configurableBeanFactory.registerSingleton(name.trim(), bean);
-		applicationContext.getAutowireCapableBeanFactory().autowireBean(bean);
-		applicationContext.getAutowireCapableBeanFactory().initializeBean(bean, name);
-	}
+  private static final Logger logger = LoggerFactory.getLogger(ReportingConfiguration.class);
+
+  public static final long DEAD_LETTER_DELAY_MILLIS = 60_000L;
+  public static final long DEAD_LETTER_MAX_RETRY = 10L;
+
+  /**
+   * Exchanges
+   */
+  public static final String EXCHANGE_REPORTING = "reporting";
+  public static final String EXCHANGE_REPORTING_RETRY = "reporting.retry";
+
+  /**
+   * Queue definitions
+   */
+  public static final String QUEUE_PREFIX = "reporting";
+  public static final String QUEUE_RETRY_PREFIX = "reporting.retry";
+  public static final String QUEUE_DLQ = "reporting.dlq";
+
+  @Value("${rp.amqp.queues}")
+  public int queueAmount;
+
+  /**
+   * Cluster configuration parameter. Number of queues to be processed by this service-api pod
+   * (default effectively infinite) Note: should correlate with number QUEUE_AMOUNT & number of
+   * service-api pods being started in cluster
+   */
+  @Value("${rp.amqp.queuesPerPod:1000000}")
+  private int queuesPerPod;
+
+  @Autowired
+  private ApplicationContext applicationContext;
+
+  @Autowired
+  private ConfigurableListableBeanFactory configurableBeanFactory;
+
+  @Bean
+  public Exchange reportingExchange(AmqpAdmin amqpAdmin) {
+    Exchange exchange = ExchangeBuilder.directExchange(EXCHANGE_REPORTING).durable(true).build();
+    amqpAdmin.declareExchange(exchange);
+    return exchange;
+  }
+
+  @Bean
+  public Exchange reportingRetryExchange(AmqpAdmin amqpAdmin) {
+    Exchange exchange = ExchangeBuilder.directExchange(EXCHANGE_REPORTING_RETRY).durable(true)
+        .build();
+    amqpAdmin.declareExchange(exchange);
+    return exchange;
+  }
+
+  @Bean
+  public List<Queue> queues(AmqpAdmin amqpAdmin) {
+    List<Queue> queues = new ArrayList();
+    for (int i = 0; i < queueAmount; i++) {
+      String index = String.valueOf(i);
+      String queueName = QUEUE_PREFIX + "." + index;
+      Queue queue = QueueBuilder.durable(queueName)
+          .withArgument("x-dead-letter-exchange", EXCHANGE_REPORTING_RETRY)
+          .withArgument("x-dead-letter-routing-key", index)
+          .build();
+      queue.setShouldDeclare(true);
+      queue.setAdminsThatShouldDeclare(amqpAdmin);
+      registerSingleton(queueName, queue);
+      amqpAdmin.declareQueue(queue);
+      queues.add(queue);
+    }
+    return queues;
+  }
+
+  @Bean
+  public List<Queue> retryQueues(AmqpAdmin amqpAdmin) {
+    List<Queue> queues = new ArrayList();
+    for (int i = 0; i < queueAmount; i++) {
+      String index = String.valueOf(i);
+      String queueName = QUEUE_RETRY_PREFIX + "." + index;
+      Queue retryQueue = QueueBuilder.durable(queueName)
+          .withArgument("x-dead-letter-exchange", EXCHANGE_REPORTING)
+          .withArgument("x-dead-letter-routing-key", index)
+          .withArgument("x-message-ttl", DEAD_LETTER_DELAY_MILLIS)
+          .build();
+      retryQueue.setShouldDeclare(true);
+      retryQueue.setAdminsThatShouldDeclare(amqpAdmin);
+      registerSingleton(queueName, retryQueue);
+      amqpAdmin.declareQueue(retryQueue);
+      queues.add(retryQueue);
+    }
+    return queues;
+  }
+
+  @Bean
+  public Queue queueDlq(AmqpAdmin amqpAdmin) {
+    Queue queue = QueueBuilder.durable(QUEUE_DLQ).build();
+    queue.setShouldDeclare(true);
+    queue.setAdminsThatShouldDeclare(amqpAdmin);
+    amqpAdmin.declareQueue(queue);
+    return queue;
+  }
+
+  @Bean
+  public List<Binding> bindings(AmqpAdmin amqpAdmin,
+      @Qualifier("reportingExchange") Exchange reportingExchange,
+      @Qualifier("reportingRetryExchange") Exchange reportingRetryExchange,
+      @Qualifier("queues") List<Queue> queues,
+      @Qualifier("queueDlq") Queue queueDlq, @Qualifier("retryQueues") List<Queue> retryQueues) {
+    List<Binding> bindings = new ArrayList<>();
+    int i = 0;
+    for (Queue queue : queues) {
+      String index = String.valueOf(i);
+      Binding queueBinding = BindingBuilder.bind(queue).to(reportingExchange).with(index).noargs();
+      bindings.add(queueBinding);
+      queueBinding.setShouldDeclare(true);
+      queueBinding.setAdminsThatShouldDeclare(amqpAdmin);
+      amqpAdmin.declareBinding(queueBinding);
+      registerSingleton("queueBinding." + queue.getName(), queueBinding);
+      i++;
+    }
+    i = 0;
+    for (Queue retryQueue : retryQueues) {
+      String index = String.valueOf(i);
+      Binding queueBinding = BindingBuilder.bind(retryQueue).to(reportingRetryExchange).with(index)
+          .noargs();
+      bindings.add(queueBinding);
+      queueBinding.setShouldDeclare(true);
+      queueBinding.setAdminsThatShouldDeclare(amqpAdmin);
+      amqpAdmin.declareBinding(queueBinding);
+      registerSingleton("queueBinding." + retryQueue.getName(), queueBinding);
+      i++;
+    }
+    Binding queueBinding = BindingBuilder.bind(queueDlq).to(reportingRetryExchange).with(QUEUE_DLQ)
+        .noargs();
+    amqpAdmin.declareBinding(queueBinding);
+
+    return bindings;
+  }
+
+  @Bean
+  @Qualifier("reportingListenerContainers")
+  public List<AbstractMessageListenerContainer> listenerContainers(
+      ConnectionFactory connectionFactory,
+      ApplicationEventPublisher applicationEventPublisher,
+      @Qualifier("queues") List<Queue> queues) {
+    List<AbstractMessageListenerContainer> containers = new ArrayList<>();
+    int consumersCount = 0;
+    while (consumersCount < queuesPerPod) {
+      SimpleMessageListenerContainer listenerContainer = new SimpleMessageListenerContainer(
+          connectionFactory);
+      containers.add(listenerContainer);
+      listenerContainer.setConnectionFactory(connectionFactory);
+      listenerContainer.addQueueNames(queues.get(consumersCount).getName());
+      listenerContainer.setExclusive(true);
+      listenerContainer.setMissingQueuesFatal(false);
+      listenerContainer.setApplicationEventPublisher(applicationEventPublisher);
+      listenerContainer.setupMessageListener(reportingListener());
+      listenerContainer.afterPropertiesSet();
+      consumersCount++;
+      logger.info("Consumer is created, current consumers count is {}", consumersCount);
+    }
+    return containers;
+  }
+
+  @Bean
+  public MessageListener reportingListener() {
+    return new AsyncReportingListener();
+  }
+
+  private void registerSingleton(String name, Object bean) {
+    configurableBeanFactory.registerSingleton(name.trim(), bean);
+    applicationContext.getAutowireCapableBeanFactory().autowireBean(bean);
+    applicationContext.getAutowireCapableBeanFactory().initializeBean(bean, name);
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/remover/ContentRemoverConfig.java b/src/main/java/com/epam/ta/reportportal/core/configs/remover/ContentRemoverConfig.java
index de4a49f17b..714cf82a88 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/remover/ContentRemoverConfig.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/remover/ContentRemoverConfig.java
@@ -19,22 +19,31 @@
 import com.epam.ta.reportportal.core.remover.project.ProjectClusterRemover;
 import com.epam.ta.reportportal.core.remover.project.ProjectContentRemover;
 import com.epam.ta.reportportal.core.remover.project.ProjectWidgetRemover;
+import com.epam.ta.reportportal.core.remover.user.UserContentRemover;
+import com.epam.ta.reportportal.core.remover.user.UserPhotoRemover;
+import com.epam.ta.reportportal.core.remover.user.UserWidgetRemover;
+import java.util.List;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
-import java.util.List;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Configuration
 public class ContentRemoverConfig {
 
-	@Bean
-	public ProjectContentRemover projectContentRemover(@Autowired ProjectClusterRemover projectClusterRemover,
-			@Autowired ProjectWidgetRemover projectWidgetRemover) {
-		return new ProjectContentRemover(List.of(projectClusterRemover, projectWidgetRemover));
-	}
+  @Bean
+  public ProjectContentRemover projectContentRemover(
+      @Autowired ProjectClusterRemover projectClusterRemover,
+      @Autowired ProjectWidgetRemover projectWidgetRemover) {
+    return new ProjectContentRemover(List.of(projectClusterRemover, projectWidgetRemover));
+  }
+
+  @Bean
+  public UserContentRemover userContentRemover(@Autowired UserWidgetRemover userWidgetRemover,
+      @Autowired UserPhotoRemover userPhotoRemover) {
+    return new UserContentRemover(List.of(userWidgetRemover, userPhotoRemover));
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/resource/ResourceAttributeHandlerConfig.java b/src/main/java/com/epam/ta/reportportal/core/configs/resource/ResourceAttributeHandlerConfig.java
index 42342c7be8..7361307741 100644
--- a/src/main/java/com/epam/ta/reportportal/core/configs/resource/ResourceAttributeHandlerConfig.java
+++ b/src/main/java/com/epam/ta/reportportal/core/configs/resource/ResourceAttributeHandlerConfig.java
@@ -16,6 +16,8 @@
 
 package com.epam.ta.reportportal.core.configs.resource;
 
+import static com.epam.ta.reportportal.core.launch.cluster.pipeline.SaveLastRunAttributePartProvider.RP_CLUSTER_LAST_RUN_KEY;
+
 import com.epam.ta.reportportal.entity.ItemAttribute;
 import com.epam.ta.reportportal.ws.converter.resource.handler.attribute.ItemAttributeType;
 import com.epam.ta.reportportal.ws.converter.resource.handler.attribute.ResourceAttributeHandler;
@@ -28,14 +30,11 @@
 import com.epam.ta.reportportal.ws.converter.resource.handler.attribute.resolver.ItemAttributeTypeResolverDelegate;
 import com.epam.ta.reportportal.ws.model.launch.LaunchResource;
 import com.google.common.collect.ImmutableMap;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-
-import static com.epam.ta.reportportal.core.launch.cluster.pipeline.SaveLastRunAttributePartProvider.RP_CLUSTER_LAST_RUN_KEY;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -43,42 +42,43 @@
 @Configuration
 public class ResourceAttributeHandlerConfig {
 
-	@Bean
-	public ResourceAttributeHandler<LaunchResource> launchResourceAttributeUpdater() {
-		return new LaunchResourceAttributeUpdater();
-	}
+  @Bean
+  public ResourceAttributeHandler<LaunchResource> launchResourceAttributeUpdater() {
+    return new LaunchResourceAttributeUpdater();
+  }
 
-	@Bean
-	public ResourceAttributeHandler<LaunchResource> launchResourceMetadataAttributeUpdater() {
-		return new LaunchResourceMetadataAttributeUpdater(Set.of(RP_CLUSTER_LAST_RUN_KEY));
-	}
+  @Bean
+  public ResourceAttributeHandler<LaunchResource> launchResourceMetadataAttributeUpdater() {
+    return new LaunchResourceMetadataAttributeUpdater(Set.of(RP_CLUSTER_LAST_RUN_KEY));
+  }
 
-	@Bean
-	public ResourceAttributeHandler<LaunchResource> unresolvedAttributesLaunchLogger() {
-		return new LaunchResourceAttributeLogger("Attributes with unresolved type: ");
-	}
+  @Bean
+  public ResourceAttributeHandler<LaunchResource> unresolvedAttributesLaunchLogger() {
+    return new LaunchResourceAttributeLogger("Attributes with unresolved type: ");
+  }
 
-	@Bean
-	public ItemAttributeTypeMatcher systemAttributeTypePredicateMatcher() {
-		return new PredicateItemAttributeTypeMatcher(ItemAttribute::isSystem, ItemAttributeType.SYSTEM);
-	}
+  @Bean
+  public ItemAttributeTypeMatcher systemAttributeTypePredicateMatcher() {
+    return new PredicateItemAttributeTypeMatcher(ItemAttribute::isSystem, ItemAttributeType.SYSTEM);
+  }
 
-	@Bean
-	public ItemAttributeTypeMatcher publicAttributeTypePredicateMatcher() {
-		return new PredicateItemAttributeTypeMatcher(it -> !it.isSystem(), ItemAttributeType.PUBLIC);
-	}
+  @Bean
+  public ItemAttributeTypeMatcher publicAttributeTypePredicateMatcher() {
+    return new PredicateItemAttributeTypeMatcher(it -> !it.isSystem(), ItemAttributeType.PUBLIC);
+  }
 
-	@Bean
-	public ItemAttributeTypeResolver itemAttributeTypeResolver() {
-		return new ItemAttributeTypeResolverDelegate(List.of(publicAttributeTypePredicateMatcher(), systemAttributeTypePredicateMatcher()));
-	}
+  @Bean
+  public ItemAttributeTypeResolver itemAttributeTypeResolver() {
+    return new ItemAttributeTypeResolverDelegate(
+        List.of(publicAttributeTypePredicateMatcher(), systemAttributeTypePredicateMatcher()));
+  }
 
-	@Bean
-	public Map<ItemAttributeType, ResourceAttributeHandler<LaunchResource>> attributeUpdaterMapping() {
-		return ImmutableMap.<ItemAttributeType, ResourceAttributeHandler<LaunchResource>>builder()
-				.put(ItemAttributeType.PUBLIC, launchResourceAttributeUpdater())
-				.put(ItemAttributeType.SYSTEM, launchResourceMetadataAttributeUpdater())
-				.put(ItemAttributeType.UNRESOLVED, unresolvedAttributesLaunchLogger())
-				.build();
-	}
+  @Bean
+  public Map<ItemAttributeType, ResourceAttributeHandler<LaunchResource>> attributeUpdaterMapping() {
+    return ImmutableMap.<ItemAttributeType, ResourceAttributeHandler<LaunchResource>>builder()
+        .put(ItemAttributeType.PUBLIC, launchResourceAttributeUpdater())
+        .put(ItemAttributeType.SYSTEM, launchResourceMetadataAttributeUpdater())
+        .put(ItemAttributeType.UNRESOLVED, unresolvedAttributesLaunchLogger())
+        .build();
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/dashboard/CreateDashboardHandler.java b/src/main/java/com/epam/ta/reportportal/core/dashboard/CreateDashboardHandler.java
index fe51a96911..994d2ed7cf 100644
--- a/src/main/java/com/epam/ta/reportportal/core/dashboard/CreateDashboardHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/dashboard/CreateDashboardHandler.java
@@ -25,14 +25,15 @@
  */
 public interface CreateDashboardHandler {
 
-	/**
-	 * Creates a new dashboard.
-	 *
-	 * @param projectDetails Project details
-	 * @param rq             Dashboard details
-	 * @param user           User
-	 * @return EntryCreatedRS
-	 */
-	EntryCreatedRS createDashboard(ReportPortalUser.ProjectDetails projectDetails, CreateDashboardRQ rq, ReportPortalUser user);
+  /**
+   * Creates a new dashboard.
+   *
+   * @param projectDetails Project details
+   * @param rq             Dashboard details
+   * @param user           User
+   * @return EntryCreatedRS
+   */
+  EntryCreatedRS createDashboard(ReportPortalUser.ProjectDetails projectDetails,
+      CreateDashboardRQ rq, ReportPortalUser user);
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/dashboard/DeleteDashboardHandler.java b/src/main/java/com/epam/ta/reportportal/core/dashboard/DeleteDashboardHandler.java
index dec61a3805..44a2ac46ed 100644
--- a/src/main/java/com/epam/ta/reportportal/core/dashboard/DeleteDashboardHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/dashboard/DeleteDashboardHandler.java
@@ -24,14 +24,15 @@
  */
 public interface DeleteDashboardHandler {
 
-	/**
-	 * Delete {@link com.epam.ta.reportportal.entity.dashboard.Dashboard} instance with specified id
-	 *
-	 * @param dashboardId    Dashboard id
-	 * @param projectDetails Project details
-	 * @param user           User
-	 * @return {@link OperationCompletionRS}
-	 */
-	OperationCompletionRS deleteDashboard(Long dashboardId, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user);
+  /**
+   * Delete {@link com.epam.ta.reportportal.entity.dashboard.Dashboard} instance with specified id
+   *
+   * @param dashboardId    Dashboard id
+   * @param projectDetails Project details
+   * @param user           User
+   * @return {@link OperationCompletionRS}
+   */
+  OperationCompletionRS deleteDashboard(Long dashboardId,
+      ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user);
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/dashboard/GetDashboardHandler.java b/src/main/java/com/epam/ta/reportportal/core/dashboard/GetDashboardHandler.java
index d45b36a2ef..2b9f95f44d 100644
--- a/src/main/java/com/epam/ta/reportportal/core/dashboard/GetDashboardHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/dashboard/GetDashboardHandler.java
@@ -42,6 +42,8 @@ public interface GetDashboardHandler {
 	 *
 	 * @param projectDetails Project details
 	 * @param user           User
+	 * @param pageable       Page Details
+	 * @param filter         {@link Filter}
 	 * @return Page of permitted dashboard resources
 	 */
 	Iterable<DashboardResource> getDashboards(ReportPortalUser.ProjectDetails projectDetails, Pageable pageable, Filter filter,
diff --git a/src/main/java/com/epam/ta/reportportal/core/dashboard/UpdateDashboardHandler.java b/src/main/java/com/epam/ta/reportportal/core/dashboard/UpdateDashboardHandler.java
index d07eccc001..9fa2d7fcb8 100644
--- a/src/main/java/com/epam/ta/reportportal/core/dashboard/UpdateDashboardHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/dashboard/UpdateDashboardHandler.java
@@ -17,6 +17,7 @@
 package com.epam.ta.reportportal.core.dashboard;
 
 import com.epam.ta.reportportal.commons.ReportPortalUser;
+import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
 import com.epam.ta.reportportal.ws.model.dashboard.AddWidgetRq;
 import com.epam.ta.reportportal.ws.model.dashboard.UpdateDashboardRQ;
@@ -26,40 +27,43 @@
  */
 public interface UpdateDashboardHandler {
 
-	/**
-	 * Update dashboard with specified id
-	 *
-	 * @param projectDetails Project details
-	 * @param rq             Update details
-	 * @param dashboardId    Dashboard id to be updated
-	 * @param user           User
-	 * @return OperationCompletionRS
-	 */
-	OperationCompletionRS updateDashboard(ReportPortalUser.ProjectDetails projectDetails, UpdateDashboardRQ rq, Long dashboardId,
-			ReportPortalUser user);
+  /**
+   * Update dashboard with specified id
+   *
+   * @param projectDetails Project details
+   * @param rq             Update details
+   * @param dashboardId    Dashboard id to be updated
+   * @param user           User
+   * @return OperationCompletionRS
+   */
+  OperationCompletionRS updateDashboard(ReportPortalUser.ProjectDetails projectDetails,
+      UpdateDashboardRQ rq, Long dashboardId,
+      ReportPortalUser user);
 
-	/**
-	 * Add a new widget to the specified dashboard
-	 *
-	 * @param dashboardId    Dashboard id
-	 * @param projectDetails Project details
-	 * @param rq             Widget details
-	 * @param user           User
-	 * @return OperationCompletionRS
-	 */
-	OperationCompletionRS addWidget(Long dashboardId, ReportPortalUser.ProjectDetails projectDetails, AddWidgetRq rq,
-			ReportPortalUser user);
+  /**
+   * Add a new widget to the specified dashboard
+   *
+   * @param dashboardId    Dashboard id
+   * @param projectDetails Project details
+   * @param rq             Widget details
+   * @param user           User
+   * @return OperationCompletionRS
+   */
+  OperationCompletionRS addWidget(Long dashboardId, ReportPortalUser.ProjectDetails projectDetails,
+      AddWidgetRq rq,
+      ReportPortalUser user);
 
-	/**
-	 * Removes a specified widget from the specified dashboard
-	 *
-	 * @param widgetId       Widget id
-	 * @param dashboardId    Dashboard id
-	 * @param projectDetails Project details
-	 * @param user
-	 * @return OperationCompletionRS
-	 */
-	OperationCompletionRS removeWidget(Long widgetId, Long dashboardId, ReportPortalUser.ProjectDetails projectDetails,
-			ReportPortalUser user);
+  /**
+   * Removes a specified widget from the specified dashboard
+   *
+   * @param widgetId       Widget id
+   * @param dashboardId    Dashboard id
+   * @param projectDetails Project details
+   * @param user           {@link ReportPortalUser}
+   * @return OperationCompletionRS
+   */
+  OperationCompletionRS removeWidget(Long widgetId, Long dashboardId,
+      ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user);
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/AnalysisEvent.java b/src/main/java/com/epam/ta/reportportal/core/events/AnalysisEvent.java
index 1f5b9fe689..49a04c171b 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/AnalysisEvent.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/AnalysisEvent.java
@@ -18,7 +18,6 @@
 
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
-
 import java.util.List;
 
 /**
@@ -26,39 +25,39 @@
  */
 public class AnalysisEvent {
 
-	private Launch launch;
+  private Launch launch;
 
-	private List<Long> itemIds;
+  private List<Long> itemIds;
 
-	private AnalyzerConfig analyzerConfig;
+  private AnalyzerConfig analyzerConfig;
 
-	public AnalysisEvent(Launch launch, List<Long> itemIds, AnalyzerConfig analyzerConfig) {
-		this.launch = launch;
-		this.itemIds = itemIds;
-		this.analyzerConfig = analyzerConfig;
-	}
+  public AnalysisEvent(Launch launch, List<Long> itemIds, AnalyzerConfig analyzerConfig) {
+    this.launch = launch;
+    this.itemIds = itemIds;
+    this.analyzerConfig = analyzerConfig;
+  }
 
-	public List<Long> getItemIds() {
-		return itemIds;
-	}
+  public List<Long> getItemIds() {
+    return itemIds;
+  }
 
-	public void setItemIds(List<Long> itemIds) {
-		this.itemIds = itemIds;
-	}
+  public void setItemIds(List<Long> itemIds) {
+    this.itemIds = itemIds;
+  }
 
-	public AnalyzerConfig getAnalyzerConfig() {
-		return analyzerConfig;
-	}
+  public AnalyzerConfig getAnalyzerConfig() {
+    return analyzerConfig;
+  }
 
-	public void setAnalyzerConfig(AnalyzerConfig analyzerConfig) {
-		this.analyzerConfig = analyzerConfig;
-	}
+  public void setAnalyzerConfig(AnalyzerConfig analyzerConfig) {
+    this.analyzerConfig = analyzerConfig;
+  }
 
-	public Launch getLaunch() {
-		return launch;
-	}
+  public Launch getLaunch() {
+    return launch;
+  }
 
-	public void setLaunch(Launch launch) {
-		this.launch = launch;
-	}
+  public void setLaunch(Launch launch) {
+    this.launch = launch;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/Event.java b/src/main/java/com/epam/ta/reportportal/core/events/Event.java
index 674c2f79ac..c45bf6ccf0 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/Event.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/Event.java
@@ -20,4 +20,5 @@
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public interface Event {
+
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/MessageBus.java b/src/main/java/com/epam/ta/reportportal/core/events/MessageBus.java
index dac882ecf6..adb78f1cf2 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/MessageBus.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/MessageBus.java
@@ -16,10 +16,6 @@
 
 package com.epam.ta.reportportal.core.events;
 
-import com.epam.ta.reportportal.core.events.attachment.DeleteAttachmentEvent;
-
-import java.util.concurrent.ExecutionException;
-
 /**
  * MessageBus is an abstraction for dealing with events over external event-streaming system
  *
@@ -27,36 +23,28 @@
  */
 public interface MessageBus {
 
-	void publish(String exchange, String route, Object o) throws ExecutionException, InterruptedException;
-
-	/**
-	 * Sends event by the given route
-	 *
-	 * @param route Route
-	 * @param o     Payload
-	 */
-	void publish(String route, Object o);
-
-	/**
-	 * Sends event to special broadcasting exchange
-	 *
-	 * @param o Payload
-	 */
-	void broadcastEvent(Object o);
-
-	/**
-	 * Sends activity
-	 *
-	 * @param o Payload
-	 */
-	void publishActivity(ActivityEvent o);
-
-	/**
-	 * Publish event to remove {@link com.epam.ta.reportportal.entity.attachment.Attachment}
-	 * from the database and {@link com.epam.ta.reportportal.filesystem.DataStore}
-	 *
-	 * @param event {@link DeleteAttachmentEvent}
-	 */
-	void publishDeleteAttachmentEvent(DeleteAttachmentEvent event);
+  /**
+   * Sends event by the given route and exchange
+   *
+   * @param exchange Exchange name
+   * @param route    Route
+   * @param o        Payload
+   */
+  void publish(String exchange, String route, Object o);
+
+  /**
+   * Sends event by the given route
+   *
+   * @param route Route
+   * @param o     Payload
+   */
+  void publish(String route, Object o);
+
+  /**
+   * Sends activity
+   *
+   * @param o Payload
+   */
+  void publishActivity(ActivityEvent o);
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/MessageBusImpl.java b/src/main/java/com/epam/ta/reportportal/core/events/MessageBusImpl.java
index 3f168fbe26..6e05016da0 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/MessageBusImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/MessageBusImpl.java
@@ -17,11 +17,7 @@
 package com.epam.ta.reportportal.core.events;
 
 import static com.epam.ta.reportportal.core.configs.rabbit.InternalConfiguration.EXCHANGE_ACTIVITY;
-import static com.epam.ta.reportportal.core.configs.rabbit.InternalConfiguration.EXCHANGE_ATTACHMENT;
-import static com.epam.ta.reportportal.core.configs.rabbit.InternalConfiguration.EXCHANGE_EVENTS;
-import static com.epam.ta.reportportal.core.configs.rabbit.InternalConfiguration.QUEUE_ATTACHMENT_DELETE;
 
-import com.epam.ta.reportportal.core.events.attachment.DeleteAttachmentEvent;
 import com.epam.ta.reportportal.entity.activity.Activity;
 import java.util.Objects;
 import org.springframework.amqp.core.AmqpTemplate;
@@ -36,17 +32,12 @@ public MessageBusImpl(AmqpTemplate amqpTemplate) {
 
   @Override
   public void publish(String exchange, String route, Object o) {
-    this.amqpTemplate.convertAndSend(exchange, route, o);
+    amqpTemplate.convertAndSend(exchange, route, o);
   }
 
   @Override
   public void publish(String route, Object o) {
-    this.amqpTemplate.convertSendAndReceive(route, o);
-  }
-
-  @Override
-  public void broadcastEvent(Object o) {
-    this.amqpTemplate.convertAndSend(EXCHANGE_EVENTS, "", o);
+    amqpTemplate.convertAndSend(route, o);
   }
 
   /**
@@ -69,11 +60,4 @@ private String generateKey(Activity activity) {
         activity.getObjectType(),
         activity.getEventName());
   }
-
-  @Override
-  public void publishDeleteAttachmentEvent(DeleteAttachmentEvent event) {
-
-    amqpTemplate.convertAndSend(EXCHANGE_ATTACHMENT, QUEUE_ATTACHMENT_DELETE, event);
-
-  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/ProjectIdAwareEvent.java b/src/main/java/com/epam/ta/reportportal/core/events/ProjectIdAwareEvent.java
index 116d188702..075594851f 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/ProjectIdAwareEvent.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/ProjectIdAwareEvent.java
@@ -21,5 +21,5 @@
  */
 public interface ProjectIdAwareEvent extends Event {
 
-	Long getProjectId();
+  Long getProjectId();
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/activity/AbstractEvent.java b/src/main/java/com/epam/ta/reportportal/core/events/activity/AbstractEvent.java
index 804320174d..dbf440cbe4 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/activity/AbstractEvent.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/activity/AbstractEvent.java
@@ -21,8 +21,8 @@
  */
 public abstract class AbstractEvent {
 
-  private Long userId;
-  private String userLogin;
+  protected Long userId;
+  protected String userLogin;
 
   protected AbstractEvent() {
   }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/activity/AroundEvent.java b/src/main/java/com/epam/ta/reportportal/core/events/activity/AroundEvent.java
index f1616f4bbe..cba2a11862 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/activity/AroundEvent.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/activity/AroundEvent.java
@@ -22,21 +22,21 @@
  */
 public class AroundEvent<T> extends BeforeEvent<T> {
 
-	private T after;
+  private T after;
 
-	public AroundEvent() {
-	}
+  public AroundEvent() {
+  }
 
-	public AroundEvent(Long userId, String userLogin, T before, T after) {
-		super(userId, userLogin, before);
-		this.after = Preconditions.checkNotNull(after);
-	}
+  public AroundEvent(Long userId, String userLogin, T before, T after) {
+    super(userId, userLogin, before);
+    this.after = Preconditions.checkNotNull(after);
+  }
 
-	public T getAfter() {
-		return after;
-	}
+  public T getAfter() {
+    return after;
+  }
 
-	public void setAfter(T after) {
-		this.after = after;
-	}
+  public void setAfter(T after) {
+    this.after = after;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/activity/AssignUserEvent.java b/src/main/java/com/epam/ta/reportportal/core/events/activity/AssignUserEvent.java
index 404eb2d37a..c262f722d0 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/activity/AssignUserEvent.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/activity/AssignUserEvent.java
@@ -16,6 +16,7 @@
 
 package com.epam.ta.reportportal.core.events.activity;
 
+import static com.epam.ta.reportportal.core.events.activity.util.ActivityDetailsUtil.RP_SUBJECT_NAME;
 import static com.epam.ta.reportportal.entity.activity.ActivityAction.ASSIGN_USER;
 
 import com.epam.ta.reportportal.builder.ActivityBuilder;
@@ -31,12 +32,13 @@ public class AssignUserEvent extends AbstractEvent implements ActivityEvent {
 
   private UserActivityResource userActivityResource;
 
-  public AssignUserEvent() {
-  }
+  private final boolean isSystemEvent;
 
-  public AssignUserEvent(UserActivityResource userActivityResource, Long userId, String userLogin) {
+  public AssignUserEvent(UserActivityResource userActivityResource, Long userId, String userLogin,
+      boolean isSystemEvent) {
     super(userId, userLogin);
     this.userActivityResource = userActivityResource;
+    this.isSystemEvent = isSystemEvent;
   }
 
   public UserActivityResource getUserActivityResource() {
@@ -58,9 +60,9 @@ public Activity toActivity() {
         .addObjectName(userActivityResource.getFullName())
         .addObjectType(EventObject.USER)
         .addProjectId(userActivityResource.getDefaultProjectId())
-        .addSubjectId(getUserId())
-        .addSubjectName(getUserLogin())
-        .addSubjectType(EventSubject.USER)
+        .addSubjectId(isSystemEvent ? null : getUserId())
+        .addSubjectName(isSystemEvent ? RP_SUBJECT_NAME : getUserLogin())
+        .addSubjectType(isSystemEvent ? EventSubject.APPLICATION : EventSubject.USER)
         .get();
   }
 
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/activity/BeforeEvent.java b/src/main/java/com/epam/ta/reportportal/core/events/activity/BeforeEvent.java
index f166147eef..7a680f07ec 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/activity/BeforeEvent.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/activity/BeforeEvent.java
@@ -24,21 +24,21 @@
  */
 public class BeforeEvent<T> extends AbstractEvent {
 
-	private T before;
+  private T before;
 
-	public BeforeEvent() {
-	}
+  public BeforeEvent() {
+  }
 
-	public BeforeEvent(Long userId, String userLogin, T before) {
-		super(userId, userLogin);
-		this.before = Preconditions.checkNotNull(before);
-	}
+  public BeforeEvent(Long userId, String userLogin, T before) {
+    super(userId, userLogin);
+    this.before = Preconditions.checkNotNull(before);
+  }
 
-	public T getBefore() {
-		return before;
-	}
+  public T getBefore() {
+    return before;
+  }
 
-	public void setBefore(T before) {
-		this.before = before;
-	}
+  public void setBefore(T before) {
+    this.before = before;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/activity/CreateInvitationLinkEvent.java b/src/main/java/com/epam/ta/reportportal/core/events/activity/CreateInvitationLinkEvent.java
new file mode 100644
index 0000000000..88cc5b8cea
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/core/events/activity/CreateInvitationLinkEvent.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2023 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.core.events.activity;
+
+import com.epam.ta.reportportal.builder.ActivityBuilder;
+import com.epam.ta.reportportal.core.events.ActivityEvent;
+import com.epam.ta.reportportal.entity.activity.Activity;
+import com.epam.ta.reportportal.entity.activity.EventAction;
+import com.epam.ta.reportportal.entity.activity.EventObject;
+import com.epam.ta.reportportal.entity.activity.EventPriority;
+import com.epam.ta.reportportal.entity.activity.EventSubject;
+
+/**
+ * Event on creation invite link.
+ *
+ * @author Andrei Piankouski
+ */
+public class CreateInvitationLinkEvent extends AbstractEvent implements ActivityEvent {
+
+  private static final String EVENT_NAME = "createInvitationLink";
+
+  private final Long projectId;
+
+  public CreateInvitationLinkEvent(Long userId, String userLogin, Long projectId) {
+    super(userId, userLogin);
+    this.projectId = projectId;
+  }
+
+  @Override
+  public Activity toActivity() {
+    return new ActivityBuilder()
+        .addCreatedNow()
+        .addAction(EventAction.CREATE)
+        .addEventName(EVENT_NAME)
+        .addPriority(EventPriority.HIGH)
+        .addObjectName(EventObject.INVITATION_LINK.getValue())
+        .addObjectType(EventObject.INVITATION_LINK)
+        .addSubjectId(getUserId())
+        .addSubjectName(getUserLogin())
+        .addSubjectType(EventSubject.USER)
+        .addProjectId(projectId)
+        .get();
+  }
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/activity/LaunchFinishedEvent.java b/src/main/java/com/epam/ta/reportportal/core/events/activity/LaunchFinishedEvent.java
index e8d660e0f4..2fa5a95429 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/activity/LaunchFinishedEvent.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/activity/LaunchFinishedEvent.java
@@ -13,8 +13,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package com.epam.ta.reportportal.core.events.activity;
 
+import static com.epam.ta.reportportal.core.events.activity.util.ActivityDetailsUtil.RP_SUBJECT_NAME;
+
 import com.epam.ta.reportportal.builder.ActivityBuilder;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.events.ActivityEvent;
@@ -46,28 +49,32 @@ public class LaunchFinishedEvent extends AbstractEvent implements ActivityEvent,
 
   private String baseUrl;
 
+  private final boolean isSystemEvent;
+
   public LaunchFinishedEvent(Launch launch) {
+    this(launch, null, null, true);
     this.id = launch.getId();
     this.name = launch.getName();
     this.mode = launch.getMode();
     this.projectId = launch.getProjectId();
   }
 
-  public LaunchFinishedEvent(Launch launch, Long userId, String userLogin) {
+  public LaunchFinishedEvent(Launch launch, Long userId, String userLogin, boolean isSystemEvent) {
     super(userId, userLogin);
     this.id = launch.getId();
     this.name = launch.getName();
     this.mode = launch.getMode();
     this.projectId = launch.getProjectId();
+    this.isSystemEvent = isSystemEvent;
   }
 
   public LaunchFinishedEvent(Launch launch, Long userId, String userLogin, String baseUrl) {
-    this(launch, userId, userLogin);
+    this(launch, userId, userLogin, false);
     this.baseUrl = baseUrl;
   }
 
   public LaunchFinishedEvent(Launch launch, ReportPortalUser user, String baseUrl) {
-    this(launch, user.getUserId(), user.getUsername());
+    this(launch, user.getUserId(), user.getUsername(), false);
     this.user = user;
     this.baseUrl = baseUrl;
   }
@@ -132,9 +139,9 @@ public Activity toActivity() {
         .addObjectName(name)
         .addObjectType(EventObject.LAUNCH)
         .addProjectId(projectId)
-        .addSubjectId(getUserId())
-        .addSubjectName(getUserLogin())
-        .addSubjectType(EventSubject.USER)
+        .addSubjectId(isSystemEvent ? null : getUserId())
+        .addSubjectName(isSystemEvent ? RP_SUBJECT_NAME : getUserLogin())
+        .addSubjectType(isSystemEvent ? EventSubject.APPLICATION : EventSubject.USER)
         .get();
   }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/activity/UnassignUserEvent.java b/src/main/java/com/epam/ta/reportportal/core/events/activity/UnassignUserEvent.java
index 86554fb310..b323e36465 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/activity/UnassignUserEvent.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/activity/UnassignUserEvent.java
@@ -16,6 +16,7 @@
 
 package com.epam.ta.reportportal.core.events.activity;
 
+import static com.epam.ta.reportportal.core.events.activity.util.ActivityDetailsUtil.RP_SUBJECT_NAME;
 import static com.epam.ta.reportportal.entity.activity.ActivityAction.UNASSIGN_USER;
 
 import com.epam.ta.reportportal.builder.ActivityBuilder;
@@ -79,7 +80,7 @@ public Activity toActivity() {
         .addObjectType(EventObject.USER)
         .addProjectId(userActivityResource.getDefaultProjectId())
         .addSubjectId(isSystemEvent ? null : getUserId())
-        .addSubjectName(isSystemEvent ? "ReportPortal" : getUserLogin())
+        .addSubjectName(isSystemEvent ? RP_SUBJECT_NAME : getUserLogin())
         .addSubjectType(isSystemEvent ? EventSubject.APPLICATION : EventSubject.USER)
         .get();
   }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/activity/UserCreatedEvent.java b/src/main/java/com/epam/ta/reportportal/core/events/activity/UserCreatedEvent.java
index f7b6fc8b23..7576388859 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/activity/UserCreatedEvent.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/activity/UserCreatedEvent.java
@@ -15,6 +15,8 @@
  */
 package com.epam.ta.reportportal.core.events.activity;
 
+import static com.epam.ta.reportportal.core.events.activity.util.ActivityDetailsUtil.RP_SUBJECT_NAME;
+
 import com.epam.ta.reportportal.builder.ActivityBuilder;
 import com.epam.ta.reportportal.core.events.ActivityEvent;
 import com.epam.ta.reportportal.entity.activity.Activity;
@@ -31,14 +33,13 @@
 public class UserCreatedEvent extends AbstractEvent implements ActivityEvent {
 
   private UserActivityResource userActivityResource;
-
-  public UserCreatedEvent() {
-  }
+  private final boolean isSystemEvent;
 
   public UserCreatedEvent(UserActivityResource userActivityResource, Long userId,
-      String userLogin) {
+      String userLogin, boolean isSystemEvent) {
     super(userId, userLogin);
     this.userActivityResource = userActivityResource;
+    this.isSystemEvent = isSystemEvent;
   }
 
   public UserActivityResource getUserActivityResource() {
@@ -59,9 +60,9 @@ public Activity toActivity() {
         .addObjectId(userActivityResource.getId())
         .addObjectName(userActivityResource.getFullName())
         .addObjectType(EventObject.USER)
-        .addSubjectId(getUserId())
-        .addSubjectName(getUserLogin())
-        .addSubjectType(EventSubject.USER)
+        .addSubjectId(isSystemEvent ? null : getUserId())
+        .addSubjectName(isSystemEvent ? RP_SUBJECT_NAME : getUserLogin())
+        .addSubjectType(isSystemEvent ? EventSubject.APPLICATION : EventSubject.USER)
         .get();
   }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/activity/item/ItemFinishedEvent.java b/src/main/java/com/epam/ta/reportportal/core/events/activity/item/IssueResolvedEvent.java
similarity index 61%
rename from src/main/java/com/epam/ta/reportportal/core/events/activity/item/ItemFinishedEvent.java
rename to src/main/java/com/epam/ta/reportportal/core/events/activity/item/IssueResolvedEvent.java
index 83d3e3983a..279e5319ac 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/activity/item/ItemFinishedEvent.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/activity/item/IssueResolvedEvent.java
@@ -21,30 +21,30 @@
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
-public class ItemFinishedEvent implements ProjectIdAwareEvent {
+public class IssueResolvedEvent implements ProjectIdAwareEvent {
 
-	private final Long itemId;
+  private final Long itemId;
 
-	private final Long launchId;
+  private final Long launchId;
 
-	private final Long projectId;
+  private final Long projectId;
 
-	public ItemFinishedEvent(Long itemId, Long launchId, Long projectId) {
-		this.itemId = itemId;
-		this.launchId = launchId;
-		this.projectId = projectId;
-	}
+  public IssueResolvedEvent(Long itemId, Long launchId, Long projectId) {
+    this.itemId = itemId;
+    this.launchId = launchId;
+    this.projectId = projectId;
+  }
 
-	public Long getItemId() {
-		return itemId;
-	}
+  public Long getItemId() {
+    return itemId;
+  }
 
-	public Long getLaunchId() {
-		return launchId;
-	}
+  public Long getLaunchId() {
+    return launchId;
+  }
 
-	@Override
-	public Long getProjectId() {
-		return projectId;
-	}
+  @Override
+  public Long getProjectId() {
+    return projectId;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/activity/item/ItemRetryEvent.java b/src/main/java/com/epam/ta/reportportal/core/events/activity/item/ItemRetryEvent.java
index 46da848b9c..f6e3569f3d 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/activity/item/ItemRetryEvent.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/activity/item/ItemRetryEvent.java
@@ -23,32 +23,32 @@
  */
 public class ItemRetryEvent implements Event {
 
-	private final Long projectId;
+  private final Long projectId;
 
-	private final Long launchId;
+  private final Long launchId;
 
-	private final Long itemId;
+  private final Long itemId;
 
-	private ItemRetryEvent(Long projectId, Long launchId, Long itemId) {
-		this.projectId = projectId;
-		this.launchId = launchId;
-		this.itemId = itemId;
-	}
+  private ItemRetryEvent(Long projectId, Long launchId, Long itemId) {
+    this.projectId = projectId;
+    this.launchId = launchId;
+    this.itemId = itemId;
+  }
 
-	public Long getProjectId() {
-		return projectId;
-	}
+  public Long getProjectId() {
+    return projectId;
+  }
 
-	public Long getLaunchId() {
-		return launchId;
-	}
+  public Long getLaunchId() {
+    return launchId;
+  }
 
-	public Long getItemId() {
-		return itemId;
-	}
+  public Long getItemId() {
+    return itemId;
+  }
 
-	public static ItemRetryEvent of(Long projectId, Long launchId, Long itemId) {
-		return new ItemRetryEvent(projectId, launchId, itemId);
-	}
+  public static ItemRetryEvent of(Long projectId, Long launchId, Long itemId) {
+    return new ItemRetryEvent(projectId, launchId, itemId);
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/activity/item/TestItemFinishedEvent.java b/src/main/java/com/epam/ta/reportportal/core/events/activity/item/TestItemFinishedEvent.java
new file mode 100644
index 0000000000..767fcb9795
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/core/events/activity/item/TestItemFinishedEvent.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2023 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.epam.ta.reportportal.core.events.activity.item;
+
+import com.epam.ta.reportportal.core.events.ProjectIdAwareEvent;
+import com.epam.ta.reportportal.entity.item.TestItem;
+
+/**
+ * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
+ */
+public class TestItemFinishedEvent implements ProjectIdAwareEvent {
+
+  private final TestItem testItem;
+
+  private final Long projectId;
+
+  public TestItemFinishedEvent(TestItem testItem, Long projectId) {
+    this.testItem = testItem;
+    this.projectId = projectId;
+  }
+
+  public TestItem getTestItem() {
+    return testItem;
+  }
+
+  @Override
+  public Long getProjectId() {
+    return projectId;
+  }
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/activity/util/ActivityDetailsUtil.java b/src/main/java/com/epam/ta/reportportal/core/events/activity/util/ActivityDetailsUtil.java
index e270e6f3ac..dfbae1a2ce 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/activity/util/ActivityDetailsUtil.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/activity/util/ActivityDetailsUtil.java
@@ -52,6 +52,7 @@ private ActivityDetailsUtil() {
 	public static final String ITEM_IDS = "itemIds";
 	public static final String LAUNCH_ID = "launchId";
   public static final String PATTERN_NAME = "patternName";
+  public static final String RP_SUBJECT_NAME = "ReportPortal";
 
 	public static Optional<HistoryField> processName(String oldName, String newName) {
 		if (!Strings.isNullOrEmpty(newName) && !oldName.equals(newName)) {
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/attachment/DeleteAttachmentEvent.java b/src/main/java/com/epam/ta/reportportal/core/events/attachment/DeleteAttachmentEvent.java
index b803a8049f..cb96331789 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/attachment/DeleteAttachmentEvent.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/attachment/DeleteAttachmentEvent.java
@@ -18,7 +18,6 @@
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.google.common.collect.Lists;
-
 import java.util.List;
 
 /**
@@ -26,39 +25,39 @@
  */
 public class DeleteAttachmentEvent {
 
-	@JsonProperty(value = "ids")
-	private List<Long> ids;
+  @JsonProperty(value = "ids")
+  private List<Long> ids;
 
-	@JsonProperty(value = "paths")
-	private List<String> paths;
+  @JsonProperty(value = "paths")
+  private List<String> paths;
 
-	public DeleteAttachmentEvent() {
-		ids = Lists.newArrayList();
-		paths = Lists.newArrayList();
-	}
+  public DeleteAttachmentEvent() {
+    ids = Lists.newArrayList();
+    paths = Lists.newArrayList();
+  }
 
-	public DeleteAttachmentEvent(List<Long> ids) {
-		this.ids = ids;
-	}
+  public DeleteAttachmentEvent(List<Long> ids) {
+    this.ids = ids;
+  }
 
-	public DeleteAttachmentEvent(List<Long> ids, List<String> paths) {
-		this.ids = ids;
-		this.paths = paths;
-	}
+  public DeleteAttachmentEvent(List<Long> ids, List<String> paths) {
+    this.ids = ids;
+    this.paths = paths;
+  }
 
-	public List<Long> getIds() {
-		return ids;
-	}
+  public List<Long> getIds() {
+    return ids;
+  }
 
-	public void setIds(List<Long> ids) {
-		this.ids = ids;
-	}
+  public void setIds(List<Long> ids) {
+    this.ids = ids;
+  }
 
-	public List<String> getPaths() {
-		return paths;
-	}
+  public List<String> getPaths() {
+    return paths;
+  }
 
-	public void setPaths(List<String> paths) {
-		this.paths = paths;
-	}
+  public void setPaths(List<String> paths) {
+    this.paths = paths;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/handler/AttachDefaultPhotoEventHandler.java b/src/main/java/com/epam/ta/reportportal/core/events/handler/AttachDefaultPhotoEventHandler.java
index 60c801b216..d771363a12 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/handler/AttachDefaultPhotoEventHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/handler/AttachDefaultPhotoEventHandler.java
@@ -16,6 +16,8 @@
 
 package com.epam.ta.reportportal.core.events.handler;
 
+import static com.epam.ta.reportportal.util.MultipartFileUtils.getMultipartFile;
+
 import com.epam.ta.reportportal.binary.UserBinaryDataService;
 import com.epam.ta.reportportal.commons.validation.Suppliers;
 import com.epam.ta.reportportal.core.events.activity.UserCreatedEvent;
@@ -31,8 +33,6 @@
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-import static com.epam.ta.reportportal.util.MultipartFileUtils.getMultipartFile;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
@@ -41,31 +41,35 @@
 @Transactional
 public class AttachDefaultPhotoEventHandler {
 
-	private static final Logger LOGGER = LoggerFactory.getLogger(UserCreatedEvent.class);
+  private static final Logger LOGGER = LoggerFactory.getLogger(UserCreatedEvent.class);
 
-	private final UserRepository userRepository;
+  private final UserRepository userRepository;
 
-	private final UserBinaryDataService userBinaryDataService;
+  private final UserBinaryDataService userBinaryDataService;
 
-	@Autowired
-	public AttachDefaultPhotoEventHandler(UserRepository userRepository, UserBinaryDataService userBinaryDataService) {
-		this.userRepository = userRepository;
-		this.userBinaryDataService = userBinaryDataService;
-	}
+  @Autowired
+  public AttachDefaultPhotoEventHandler(UserRepository userRepository,
+      UserBinaryDataService userBinaryDataService) {
+    this.userRepository = userRepository;
+    this.userBinaryDataService = userBinaryDataService;
+  }
 
-	@EventListener
-	public void handleContextRefresh(ContextRefreshedEvent event) {
-		userRepository.findByLogin("superadmin").ifPresent(it -> attachPhoto(it, "image/superAdminPhoto.jpg"));
-		userRepository.findByLogin("default").ifPresent(it -> attachPhoto(it, "image/defaultUserPhoto.jpg"));
-	}
+  @EventListener
+  public void handleContextRefresh(ContextRefreshedEvent event) {
+    userRepository.findByLogin("superadmin")
+        .ifPresent(it -> attachPhoto(it, "image/superAdminPhoto.jpg"));
+    userRepository.findByLogin("default")
+        .ifPresent(it -> attachPhoto(it, "image/defaultUserPhoto.jpg"));
+  }
 
-	private void attachPhoto(User user, String photoPath) {
-		if (StringUtils.isEmpty(user.getAttachment())) {
-			try {
-				userBinaryDataService.saveUserPhoto(user, getMultipartFile(photoPath));
-			} catch (Exception exception) {
-				LOGGER.error(Suppliers.formattedSupplier("Cannot attach default photo to user '{}'.", user.getLogin()).get(), exception);
-			}
-		}
-	}
+  private void attachPhoto(User user, String photoPath) {
+    if (StringUtils.isEmpty(user.getAttachment())) {
+      try {
+        userBinaryDataService.saveUserPhoto(user, getMultipartFile(photoPath));
+      } catch (Exception exception) {
+        LOGGER.error(Suppliers.formattedSupplier("Cannot attach default photo to user '{}'.",
+            user.getLogin()).get(), exception);
+      }
+    }
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/handler/ConfigurableEventHandler.java b/src/main/java/com/epam/ta/reportportal/core/events/handler/ConfigurableEventHandler.java
index f20e048f27..51b46a3a01 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/handler/ConfigurableEventHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/handler/ConfigurableEventHandler.java
@@ -23,5 +23,5 @@
  */
 public interface ConfigurableEventHandler<T extends Event, C> {
 
-	void handle(T event, C config);
+  void handle(T event, C config);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/handler/DefectTypeDeletedHandler.java b/src/main/java/com/epam/ta/reportportal/core/events/handler/DefectTypeDeletedHandler.java
index 5cb030f52c..190f6abe39 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/handler/DefectTypeDeletedHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/handler/DefectTypeDeletedHandler.java
@@ -16,6 +16,11 @@
 
 package com.epam.ta.reportportal.core.events.handler;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerStatusCache.AUTO_ANALYZER_KEY;
+import static com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerUtils.getAnalyzerConfig;
+
 import com.epam.ta.reportportal.core.analyzer.auto.LogIndexer;
 import com.epam.ta.reportportal.core.analyzer.auto.client.AnalyzerServiceClient;
 import com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerStatusCache;
@@ -33,11 +38,6 @@
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.event.TransactionalEventListener;
 
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerStatusCache.AUTO_ANALYZER_KEY;
-import static com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerUtils.getAnalyzerConfig;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
@@ -45,42 +45,47 @@
 @Transactional
 public class DefectTypeDeletedHandler {
 
-	private final AnalyzerStatusCache analyzerStatusCache;
+  private final AnalyzerStatusCache analyzerStatusCache;
 
-	private final AnalyzerServiceClient analyzerServiceClient;
+  private final AnalyzerServiceClient analyzerServiceClient;
 
-	private final LaunchRepository launchRepository;
+  private final LaunchRepository launchRepository;
 
-	private final LogIndexer logIndexer;
+  private final LogIndexer logIndexer;
 
-	private final ProjectRepository projectRepository;
+  private final ProjectRepository projectRepository;
 
-	@Autowired
-	public DefectTypeDeletedHandler(AnalyzerStatusCache analyzerStatusCache, AnalyzerServiceClient analyzerServiceClient,
-			LaunchRepository launchRepository, LogIndexer logIndexer, ProjectRepository projectRepository) {
-		this.analyzerStatusCache = analyzerStatusCache;
-		this.analyzerServiceClient = analyzerServiceClient;
-		this.launchRepository = launchRepository;
-		this.logIndexer = logIndexer;
-		this.projectRepository = projectRepository;
-	}
+  @Autowired
+  public DefectTypeDeletedHandler(AnalyzerStatusCache analyzerStatusCache,
+      AnalyzerServiceClient analyzerServiceClient,
+      LaunchRepository launchRepository, LogIndexer logIndexer,
+      ProjectRepository projectRepository) {
+    this.analyzerStatusCache = analyzerStatusCache;
+    this.analyzerServiceClient = analyzerServiceClient;
+    this.launchRepository = launchRepository;
+    this.logIndexer = logIndexer;
+    this.projectRepository = projectRepository;
+  }
 
-	@Transactional
-	@Retryable(value = ReportPortalException.class, maxAttempts = 5, backoff = @Backoff(value = 5000L))
-	@TransactionalEventListener
-	public void handleDefectTypeDeleted(DefectTypeDeletedEvent event) {
-		Project project = projectRepository.findById(event.getProjectId())
-				.orElseThrow(() -> new ReportPortalException(ErrorType.PROJECT_NOT_FOUND, event.getProjectId()));
+  @Transactional
+  @Retryable(value = ReportPortalException.class, maxAttempts = 5, backoff = @Backoff(value = 5000L))
+  @TransactionalEventListener
+  public void handleDefectTypeDeleted(DefectTypeDeletedEvent event) {
+    Project project = projectRepository.findById(event.getProjectId())
+        .orElseThrow(
+            () -> new ReportPortalException(ErrorType.PROJECT_NOT_FOUND, event.getProjectId()));
 
-		if (analyzerServiceClient.hasClients()) {
-			Cache<Long, Long> analyzeStatus = analyzerStatusCache.getAnalyzeStatus(AUTO_ANALYZER_KEY)
-					.orElseThrow(() -> new ReportPortalException(ErrorType.ANALYZER_NOT_FOUND, AUTO_ANALYZER_KEY));
-			expect(analyzeStatus.asMap().containsValue(event.getProjectId()), equalTo(false)).verify(ErrorType.FORBIDDEN_OPERATION,
-					"Index can not be removed until auto-analysis proceeds."
-			);
+    if (analyzerServiceClient.hasClients()) {
+      Cache<Long, Long> analyzeStatus = analyzerStatusCache.getAnalyzeStatus(AUTO_ANALYZER_KEY)
+          .orElseThrow(
+              () -> new ReportPortalException(ErrorType.ANALYZER_NOT_FOUND, AUTO_ANALYZER_KEY));
+      expect(analyzeStatus.asMap().containsValue(event.getProjectId()), equalTo(false)).verify(
+          ErrorType.FORBIDDEN_OPERATION,
+          "Index can not be removed until auto-analysis proceeds."
+      );
 
-			logIndexer.index(event.getProjectId(), getAnalyzerConfig(project));
-		}
-	}
+      logIndexer.index(event.getProjectId(), getAnalyzerConfig(project));
+    }
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/handler/GenerateWidgetViewEventHandler.java b/src/main/java/com/epam/ta/reportportal/core/events/handler/GenerateWidgetViewEventHandler.java
index 4846d413b7..cfa1d63959 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/handler/GenerateWidgetViewEventHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/handler/GenerateWidgetViewEventHandler.java
@@ -1,5 +1,11 @@
 package com.epam.ta.reportportal.core.events.handler;
 
+import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
+import static com.epam.ta.reportportal.core.widget.content.loader.materialized.handler.MaterializedWidgetStateHandler.REFRESH;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_SORTS;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.core.events.widget.GenerateWidgetViewEvent;
 import com.epam.ta.reportportal.core.widget.content.BuildFilterStrategy;
@@ -9,6 +15,7 @@
 import com.epam.ta.reportportal.entity.widget.WidgetType;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.Map;
 import org.apache.commons.lang3.BooleanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
@@ -20,62 +27,57 @@
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.event.TransactionalEventListener;
 
-import java.util.Map;
-
-import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
-import static com.epam.ta.reportportal.core.widget.content.loader.materialized.handler.MaterializedWidgetStateHandler.REFRESH;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_SORTS;
-import static java.util.Optional.ofNullable;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class GenerateWidgetViewEventHandler {
 
-	private final WidgetRepository widgetRepository;
-	private final Map<WidgetType, BuildFilterStrategy> buildFilterStrategyMapping;
-	private final MaterializedViewNameGenerator materializedViewNameGenerator;
-	private final TaskExecutor widgetViewExecutor;
-	private final Map<WidgetType, ViewGenerator> viewGeneratorMapping;
+  private final WidgetRepository widgetRepository;
+  private final Map<WidgetType, BuildFilterStrategy> buildFilterStrategyMapping;
+  private final MaterializedViewNameGenerator materializedViewNameGenerator;
+  private final TaskExecutor widgetViewExecutor;
+  private final Map<WidgetType, ViewGenerator> viewGeneratorMapping;
 
-	@Autowired
-	public GenerateWidgetViewEventHandler(WidgetRepository widgetRepository,
-			@Qualifier("buildFilterStrategy") Map<WidgetType, BuildFilterStrategy> buildFilterStrategyMapping,
-			MaterializedViewNameGenerator materializedViewNameGenerator, @Qualifier("widgetViewExecutor") TaskExecutor widgetViewExecutor,
-			@Qualifier("viewGeneratorMapping") Map<WidgetType, ViewGenerator> viewGeneratorMapping) {
-		this.widgetRepository = widgetRepository;
-		this.buildFilterStrategyMapping = buildFilterStrategyMapping;
-		this.materializedViewNameGenerator = materializedViewNameGenerator;
-		this.widgetViewExecutor = widgetViewExecutor;
-		this.viewGeneratorMapping = viewGeneratorMapping;
-	}
+  @Autowired
+  public GenerateWidgetViewEventHandler(WidgetRepository widgetRepository,
+      @Qualifier("buildFilterStrategy") Map<WidgetType, BuildFilterStrategy> buildFilterStrategyMapping,
+      MaterializedViewNameGenerator materializedViewNameGenerator,
+      @Qualifier("widgetViewExecutor") TaskExecutor widgetViewExecutor,
+      @Qualifier("viewGeneratorMapping") Map<WidgetType, ViewGenerator> viewGeneratorMapping) {
+    this.widgetRepository = widgetRepository;
+    this.buildFilterStrategyMapping = buildFilterStrategyMapping;
+    this.materializedViewNameGenerator = materializedViewNameGenerator;
+    this.widgetViewExecutor = widgetViewExecutor;
+    this.viewGeneratorMapping = viewGeneratorMapping;
+  }
 
-	@Async
-	@Transactional(propagation = Propagation.REQUIRES_NEW)
-	@TransactionalEventListener
-	public void onApplicationEvent(GenerateWidgetViewEvent event) {
-		widgetRepository.findById(event.getWidgetId()).ifPresent(widget -> {
-			WidgetType widgetType = WidgetType.findByName(widget.getWidgetType())
-					.orElseThrow(() -> new ReportPortalException(ErrorType.UNABLE_TO_CREATE_WIDGET,
-							formattedSupplier("Unsupported widget type '{}'", widget.getWidgetType())
-					));
+  @Async
+  @Transactional(propagation = Propagation.REQUIRES_NEW)
+  @TransactionalEventListener
+  public void onApplicationEvent(GenerateWidgetViewEvent event) {
+    widgetRepository.findById(event.getWidgetId()).ifPresent(widget -> {
+      WidgetType widgetType = WidgetType.findByName(widget.getWidgetType())
+          .orElseThrow(() -> new ReportPortalException(ErrorType.UNABLE_TO_CREATE_WIDGET,
+              formattedSupplier("Unsupported widget type '{}'", widget.getWidgetType())
+          ));
 
-			Map<Filter, Sort> filterSortMapping = buildFilterStrategyMapping.get(widgetType).buildFilter(widget);
-			Filter launchesFilter = GROUP_FILTERS.apply(filterSortMapping.keySet());
-			Sort launchesSort = GROUP_SORTS.apply(filterSortMapping.values());
+      Map<Filter, Sort> filterSortMapping = buildFilterStrategyMapping.get(widgetType)
+          .buildFilter(widget);
+      Filter launchesFilter = GROUP_FILTERS.apply(filterSortMapping.keySet());
+      Sort launchesSort = GROUP_SORTS.apply(filterSortMapping.values());
 
-			ofNullable(viewGeneratorMapping.get(widgetType)).ifPresent(viewGenerator -> widgetViewExecutor.execute(() -> viewGenerator.generate(
-					BooleanUtils.toBoolean(event.getParams().getFirst(REFRESH)),
-					materializedViewNameGenerator.generate(widget),
-					widget,
-					launchesFilter,
-					launchesSort,
-					event.getParams()
-			)));
+      ofNullable(viewGeneratorMapping.get(widgetType)).ifPresent(
+          viewGenerator -> widgetViewExecutor.execute(() -> viewGenerator.generate(
+              BooleanUtils.toBoolean(event.getParams().getFirst(REFRESH)),
+              materializedViewNameGenerator.generate(widget),
+              widget,
+              launchesFilter,
+              launchesSort,
+              event.getParams()
+          )));
 
-		});
-	}
+    });
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/handler/StartAnalysisEventHandler.java b/src/main/java/com/epam/ta/reportportal/core/events/handler/StartAnalysisEventHandler.java
index 4aeb7f34ca..70e683570a 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/handler/StartAnalysisEventHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/handler/StartAnalysisEventHandler.java
@@ -29,24 +29,25 @@
 @Component
 public class StartAnalysisEventHandler {
 
-	private final AnalyzerServiceAsync analyzerServiceAsync;
-
-	private final LogIndexer logIndexer;
-
-	@Autowired
-	public StartAnalysisEventHandler(AnalyzerServiceAsync analyzerServiceAsync, LogIndexer logIndexer) {
-		this.analyzerServiceAsync = analyzerServiceAsync;
-		this.logIndexer = logIndexer;
-	}
-
-	@TransactionalEventListener
-	public void handleEvent(AnalysisEvent event) {
-		analyzerServiceAsync.analyze(event.getLaunch(), event.getItemIds(), event.getAnalyzerConfig())
-				.thenApply(it -> logIndexer.indexItemsLogs(event.getLaunch().getProjectId(),
-						event.getLaunch().getId(),
-						event.getItemIds(),
-						event.getAnalyzerConfig()
-				));
-	}
+  private final AnalyzerServiceAsync analyzerServiceAsync;
+
+  private final LogIndexer logIndexer;
+
+  @Autowired
+  public StartAnalysisEventHandler(AnalyzerServiceAsync analyzerServiceAsync,
+      LogIndexer logIndexer) {
+    this.analyzerServiceAsync = analyzerServiceAsync;
+    this.logIndexer = logIndexer;
+  }
+
+  @TransactionalEventListener
+  public void handleEvent(AnalysisEvent event) {
+    analyzerServiceAsync.analyze(event.getLaunch(), event.getItemIds(), event.getAnalyzerConfig())
+        .thenApply(it -> logIndexer.indexItemsLogs(event.getLaunch().getProjectId(),
+            event.getLaunch().getId(),
+            event.getItemIds(),
+            event.getAnalyzerConfig()
+        ));
+  }
 
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/handler/TestItemRetryEventHandler.java b/src/main/java/com/epam/ta/reportportal/core/events/handler/TestItemRetryEventHandler.java
index 91a466b433..080969d972 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/handler/TestItemRetryEventHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/handler/TestItemRetryEventHandler.java
@@ -18,29 +18,29 @@
 
 import com.epam.ta.reportportal.core.analyzer.auto.LogIndexer;
 import com.epam.ta.reportportal.core.events.activity.item.ItemRetryEvent;
+import java.util.Collections;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.event.TransactionalEventListener;
 
-import java.util.Collections;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @Component
 public class TestItemRetryEventHandler {
 
-	private final LogIndexer logIndexer;
+  private final LogIndexer logIndexer;
 
-	@Autowired
-	public TestItemRetryEventHandler(LogIndexer logIndexer) {
-		this.logIndexer = logIndexer;
-	}
+  @Autowired
+  public TestItemRetryEventHandler(LogIndexer logIndexer) {
+    this.logIndexer = logIndexer;
+  }
 
-	@Async
-	@TransactionalEventListener
-	public void onItemRetry(ItemRetryEvent event) {
-		logIndexer.indexItemsRemoveAsync(event.getProjectId(), Collections.singletonList(event.getItemId()));
-	}
+  @Async
+  @TransactionalEventListener
+  public void onItemRetry(ItemRetryEvent event) {
+    logIndexer.indexItemsRemoveAsync(event.getProjectId(),
+        Collections.singletonList(event.getItemId()));
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/handler/item/TestItemAutoAnalysisRunner.java b/src/main/java/com/epam/ta/reportportal/core/events/handler/item/TestItemAutoAnalysisRunner.java
new file mode 100644
index 0000000000..49faf257c4
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/core/events/handler/item/TestItemAutoAnalysisRunner.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2023 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.core.events.handler.item;
+
+import com.epam.ta.reportportal.core.analyzer.auto.AnalyzerService;
+import com.epam.ta.reportportal.core.analyzer.auto.LogIndexer;
+import com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerUtils;
+import com.epam.ta.reportportal.core.events.activity.item.TestItemFinishedEvent;
+import com.epam.ta.reportportal.core.events.handler.ConfigurableEventHandler;
+import com.epam.ta.reportportal.core.launch.GetLaunchHandler;
+import com.epam.ta.reportportal.entity.enums.TestItemIssueGroup;
+import com.epam.ta.reportportal.entity.item.TestItem;
+import com.epam.ta.reportportal.entity.launch.Launch;
+import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import org.springframework.stereotype.Component;
+
+/**
+ * Run auto analyzer for finished test item with immediateAutoAnalysis attribute.
+ *
+ * @author <a href="mailto:andrei_piankouski@epam.com">Andrei Piankouski</a>
+ */
+@Component
+public class TestItemAutoAnalysisRunner implements
+    ConfigurableEventHandler<TestItemFinishedEvent, Map<String, String>> {
+
+  protected static final String IMMEDIATE_AUTO_ANALYSIS = "immediateAutoAnalysis";
+
+  private final AnalyzerService analyzerService;
+
+  private final LogIndexer logIndexer;
+
+  private final GetLaunchHandler getLaunchHandler;
+
+  public TestItemAutoAnalysisRunner(AnalyzerService analyzerService, LogIndexer logIndexer,
+      GetLaunchHandler getLaunchHandler) {
+    this.analyzerService = analyzerService;
+    this.logIndexer = logIndexer;
+    this.getLaunchHandler = getLaunchHandler;
+  }
+
+  @Override
+  public void handle(TestItemFinishedEvent testItemFinishedEvent,
+      Map<String, String> projectConfig) {
+    if (analyzerService.hasAnalyzers() && isNeedToRunAA(testItemFinishedEvent.getTestItem())) {
+      final AnalyzerConfig analyzerConfig = AnalyzerUtils.getAnalyzerConfig(projectConfig);
+      TestItem testItem = testItemFinishedEvent.getTestItem();
+      logIndex(testItem, testItemFinishedEvent.getProjectId(), analyzerConfig);
+      Launch launch = getLaunchHandler.get(testItem.getLaunchId());
+      analyzerService.runAnalyzers(launch, List.of(testItem.getItemId()), analyzerConfig);
+      logIndex(testItem, testItemFinishedEvent.getProjectId(), analyzerConfig);
+    }
+  }
+
+  private void logIndex(TestItem testItem, Long projectId, AnalyzerConfig config) {
+    logIndexer.indexItemsLogs(projectId, testItem.getLaunchId(), List.of(testItem.getItemId()),
+        config);
+  }
+
+  private boolean isNeedToRunAA(TestItem testItem) {
+    if (Objects.nonNull(testItem.getItemResults().getIssue()) && testItem.getItemResults()
+        .getIssue().getIssueType().getIssueGroup().getTestItemIssueGroup()
+        .equals(TestItemIssueGroup.TO_INVESTIGATE)) {
+      return testItem.getAttributes().stream()
+          .filter(at -> !at.getTestItem().getItemResults().getIssue().getIgnoreAnalyzer())
+          .anyMatch(at -> IMMEDIATE_AUTO_ANALYSIS.equals(at.getKey()) && Boolean.parseBoolean(
+              at.getValue()) && at.isSystem());
+    }
+    return false;
+  }
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/handler/item/TestItemIndexRunner.java b/src/main/java/com/epam/ta/reportportal/core/events/handler/item/TestItemIndexRunner.java
index 253b4543f2..dde65e4bda 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/handler/item/TestItemIndexRunner.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/handler/item/TestItemIndexRunner.java
@@ -18,40 +18,40 @@
 
 import com.epam.ta.reportportal.core.analyzer.auto.LogIndexer;
 import com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerUtils;
+import com.epam.ta.reportportal.core.events.activity.item.IssueResolvedEvent;
 import com.epam.ta.reportportal.core.events.handler.ConfigurableEventHandler;
-import com.epam.ta.reportportal.core.events.activity.item.ItemFinishedEvent;
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
 import com.google.common.collect.Lists;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.Map;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
-public class TestItemIndexRunner implements ConfigurableEventHandler<ItemFinishedEvent, Map<String, String>> {
+public class TestItemIndexRunner implements
+    ConfigurableEventHandler<IssueResolvedEvent, Map<String, String>> {
 
-	private final LogIndexer logIndexer;
+  private final LogIndexer logIndexer;
 
-	@Autowired
-	public TestItemIndexRunner(LogIndexer logIndexer) {
-		this.logIndexer = logIndexer;
-	}
+  @Autowired
+  public TestItemIndexRunner(LogIndexer logIndexer) {
+    this.logIndexer = logIndexer;
+  }
 
-	@Override
-	@Transactional(readOnly = true)
-	public void handle(ItemFinishedEvent event, Map<String, String> projectConfig) {
+  @Override
+  @Transactional(readOnly = true)
+  public void handle(IssueResolvedEvent event, Map<String, String> projectConfig) {
 
-		final AnalyzerConfig analyzerConfig = AnalyzerUtils.getAnalyzerConfig(projectConfig);
+    final AnalyzerConfig analyzerConfig = AnalyzerUtils.getAnalyzerConfig(projectConfig);
 
-		logIndexer.indexItemsLogs(
-				event.getProjectId(),
-				event.getLaunchId(),
-				Lists.newArrayList(event.getItemId()),
-				analyzerConfig
-		);
-	}
+    logIndexer.indexItemsLogs(
+        event.getProjectId(),
+        event.getLaunchId(),
+        Lists.newArrayList(event.getItemId()),
+        analyzerConfig
+    );
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/handler/item/TestItemPatternAnalysisRunner.java b/src/main/java/com/epam/ta/reportportal/core/events/handler/item/TestItemPatternAnalysisRunner.java
new file mode 100644
index 0000000000..f6fa77945d
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/core/events/handler/item/TestItemPatternAnalysisRunner.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2023 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.epam.ta.reportportal.core.events.handler.item;
+
+import com.epam.ta.reportportal.core.analyzer.pattern.handler.ItemsPatternsAnalyzer;
+import com.epam.ta.reportportal.core.events.activity.item.TestItemFinishedEvent;
+import com.epam.ta.reportportal.core.events.handler.ConfigurableEventHandler;
+import com.epam.ta.reportportal.entity.ItemAttribute;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Optional;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
+ */
+@Service
+public class TestItemPatternAnalysisRunner implements
+    ConfigurableEventHandler<TestItemFinishedEvent, Map<String, String>> {
+
+  protected static final String IMMEDIATE_PATTERN_ANALYSIS = "immediatePatternAnalysis";
+
+  private final ItemsPatternsAnalyzer patternsAnalyzer;
+
+  public TestItemPatternAnalysisRunner(ItemsPatternsAnalyzer patternsAnalyzer) {
+    this.patternsAnalyzer = patternsAnalyzer;
+  }
+
+  @Override
+  public void handle(TestItemFinishedEvent event, Map<String, String> config) {
+    if (isImmediatePaProvided(event)) {
+      patternsAnalyzer.analyze(event.getProjectId(), event.getTestItem().getLaunchId(),
+          Collections.singletonList(event.getTestItem().getItemId()));
+    }
+  }
+
+  private static boolean isImmediatePaProvided(TestItemFinishedEvent event) {
+    Optional<ItemAttribute> immediatePa = event.getTestItem().getAttributes().stream()
+        .filter(it -> IMMEDIATE_PATTERN_ANALYSIS.equals(it.getKey())).findAny();
+    return immediatePa.isPresent() && Boolean.parseBoolean(immediatePa.get().getValue());
+  }
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/handler/item/TestItemUniqueErrorAnalysisRunner.java b/src/main/java/com/epam/ta/reportportal/core/events/handler/item/TestItemUniqueErrorAnalysisRunner.java
index f17b52ace2..f281499da6 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/handler/item/TestItemUniqueErrorAnalysisRunner.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/handler/item/TestItemUniqueErrorAnalysisRunner.java
@@ -16,57 +16,54 @@
 
 package com.epam.ta.reportportal.core.events.handler.item;
 
+import static com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerUtils.getAnalyzerConfig;
+import static com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerUtils.getUniqueErrorConfig;
+
+import com.epam.ta.reportportal.core.events.activity.item.IssueResolvedEvent;
 import com.epam.ta.reportportal.core.events.handler.ConfigurableEventHandler;
-import com.epam.ta.reportportal.core.events.activity.item.ItemFinishedEvent;
 import com.epam.ta.reportportal.core.launch.cluster.ClusterGenerator;
 import com.epam.ta.reportportal.core.launch.cluster.config.ClusterEntityContext;
 import com.epam.ta.reportportal.core.launch.cluster.config.GenerateClustersConfig;
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
 import com.epam.ta.reportportal.ws.model.project.UniqueErrorConfig;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.context.ApplicationEventPublisher;
-import org.springframework.stereotype.Service;
-
 import java.util.List;
 import java.util.Map;
-
-import static com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerUtils.getAnalyzerConfig;
-import static com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerUtils.getUniqueErrorConfig;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
-public class TestItemUniqueErrorAnalysisRunner implements ConfigurableEventHandler<ItemFinishedEvent, Map<String, String>> {
+public class TestItemUniqueErrorAnalysisRunner implements
+    ConfigurableEventHandler<IssueResolvedEvent, Map<String, String>> {
 
-	private final ClusterGenerator clusterGenerator;
-	private final ApplicationEventPublisher eventPublisher;
+  private final ClusterGenerator clusterGenerator;
 
-	public TestItemUniqueErrorAnalysisRunner(@Qualifier("uniqueErrorGenerator") ClusterGenerator clusterGenerator,
-			ApplicationEventPublisher eventPublisher) {
-		this.clusterGenerator = clusterGenerator;
-		this.eventPublisher = eventPublisher;
-	}
+  public TestItemUniqueErrorAnalysisRunner(
+      @Qualifier("uniqueErrorGenerator") ClusterGenerator clusterGenerator) {
+    this.clusterGenerator = clusterGenerator;
+  }
 
-	@Override
-	public void handle(ItemFinishedEvent event, Map<String, String> projectConfig) {
-		final UniqueErrorConfig uniqueErrorConfig = getUniqueErrorConfig(projectConfig);
+  @Override
+  public void handle(IssueResolvedEvent event, Map<String, String> projectConfig) {
+    final UniqueErrorConfig uniqueErrorConfig = getUniqueErrorConfig(projectConfig);
 
-		if (uniqueErrorConfig.isEnabled()) {
-			final GenerateClustersConfig clustersConfig = new GenerateClustersConfig();
-			clustersConfig.setForUpdate(true);
-			clustersConfig.setCleanNumbers(uniqueErrorConfig.isRemoveNumbers());
+    if (uniqueErrorConfig.isEnabled()) {
+      final GenerateClustersConfig clustersConfig = new GenerateClustersConfig();
+      clustersConfig.setForUpdate(true);
+      clustersConfig.setCleanNumbers(uniqueErrorConfig.isRemoveNumbers());
 
-			final AnalyzerConfig analyzerConfig = getAnalyzerConfig(projectConfig);
-			clustersConfig.setAnalyzerConfig(analyzerConfig);
+      final AnalyzerConfig analyzerConfig = getAnalyzerConfig(projectConfig);
+      clustersConfig.setAnalyzerConfig(analyzerConfig);
 
-			final ClusterEntityContext entityContext = ClusterEntityContext.of(event.getLaunchId(),
-					event.getProjectId(),
-					List.of(event.getItemId())
-			);
-			clustersConfig.setEntityContext(entityContext);
+      final ClusterEntityContext entityContext = ClusterEntityContext.of(event.getLaunchId(),
+          event.getProjectId(),
+          List.of(event.getItemId())
+      );
+      clustersConfig.setEntityContext(entityContext);
 
-			clusterGenerator.generate(clustersConfig);
-		}
-	}
+      clusterGenerator.generate(clustersConfig);
+    }
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchAnalysisFinishEventPublisher.java b/src/main/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchAnalysisFinishEventPublisher.java
index 9f50d52560..1b2ea25c93 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchAnalysisFinishEventPublisher.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchAnalysisFinishEventPublisher.java
@@ -19,27 +19,27 @@
 import com.epam.reportportal.extension.event.LaunchAnalysisFinishEvent;
 import com.epam.ta.reportportal.core.events.activity.LaunchFinishedEvent;
 import com.epam.ta.reportportal.core.events.handler.ConfigurableEventHandler;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.stereotype.Service;
 
-import java.util.Map;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
-public class LaunchAnalysisFinishEventPublisher implements ConfigurableEventHandler<LaunchFinishedEvent, Map<String, String>> {
+public class LaunchAnalysisFinishEventPublisher implements
+    ConfigurableEventHandler<LaunchFinishedEvent, Map<String, String>> {
 
-	private final ApplicationEventPublisher eventPublisher;
+  private final ApplicationEventPublisher eventPublisher;
 
-	@Autowired
-	public LaunchAnalysisFinishEventPublisher(ApplicationEventPublisher eventPublisher) {
-		this.eventPublisher = eventPublisher;
-	}
+  @Autowired
+  public LaunchAnalysisFinishEventPublisher(ApplicationEventPublisher eventPublisher) {
+    this.eventPublisher = eventPublisher;
+  }
 
-	@Override
-	public void handle(LaunchFinishedEvent event, Map<String, String> config) {
-		eventPublisher.publishEvent(new LaunchAnalysisFinishEvent(event.getId(), config));
-	}
+  @Override
+  public void handle(LaunchFinishedEvent event, Map<String, String> config) {
+    eventPublisher.publishEvent(new LaunchAnalysisFinishEvent(event.getId(), config));
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchAutoAnalysisRunner.java b/src/main/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchAutoAnalysisRunner.java
index bc9b70c016..5f2fa63d8b 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchAutoAnalysisRunner.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchAutoAnalysisRunner.java
@@ -23,32 +23,33 @@
 import com.epam.ta.reportportal.core.events.activity.LaunchFinishedEvent;
 import com.epam.ta.reportportal.core.events.handler.ConfigurableEventHandler;
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
-import org.springframework.stereotype.Service;
-
 import java.util.Map;
 import java.util.Set;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
-public class LaunchAutoAnalysisRunner implements ConfigurableEventHandler<LaunchFinishedEvent, Map<String, String>> {
-
-	private final LaunchAutoAnalysisStarter autoAnalysisStarter;
-
-	public LaunchAutoAnalysisRunner(LaunchAutoAnalysisStarter autoAnalysisStarter) {
-		this.autoAnalysisStarter = autoAnalysisStarter;
-	}
-
-	@Override
-	public void handle(LaunchFinishedEvent launchFinishedEvent, Map<String, String> projectConfig) {
-		final AnalyzerConfig analyzerConfig = AnalyzerUtils.getAnalyzerConfig(projectConfig);
-		final StartLaunchAutoAnalysisConfig config = StartLaunchAutoAnalysisConfig.of(launchFinishedEvent.getId(),
-				analyzerConfig,
-				Set.of(AnalyzeItemsMode.TO_INVESTIGATE),
-				launchFinishedEvent.getUser()
-		);
-		autoAnalysisStarter.start(config);
-	}
+public class LaunchAutoAnalysisRunner implements
+    ConfigurableEventHandler<LaunchFinishedEvent, Map<String, String>> {
+
+  private final LaunchAutoAnalysisStarter autoAnalysisStarter;
+
+  public LaunchAutoAnalysisRunner(LaunchAutoAnalysisStarter autoAnalysisStarter) {
+    this.autoAnalysisStarter = autoAnalysisStarter;
+  }
+
+  @Override
+  public void handle(LaunchFinishedEvent launchFinishedEvent, Map<String, String> projectConfig) {
+    final AnalyzerConfig analyzerConfig = AnalyzerUtils.getAnalyzerConfig(projectConfig);
+    final StartLaunchAutoAnalysisConfig config = StartLaunchAutoAnalysisConfig.of(
+        launchFinishedEvent.getId(),
+        analyzerConfig,
+        Set.of(AnalyzeItemsMode.IGNORE_IMMEDIATE),
+        launchFinishedEvent.getUser()
+    );
+    autoAnalysisStarter.start(config);
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchNotificationRunner.java b/src/main/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchNotificationRunner.java
index e610c7418d..21f6530d54 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchNotificationRunner.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchNotificationRunner.java
@@ -16,6 +16,13 @@
 
 package com.epam.ta.reportportal.core.events.handler.launch;
 
+import static com.epam.ta.reportportal.core.statistics.StatisticsHelper.extractStatisticsCount;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DEFECTS_AUTOMATION_BUG_TOTAL;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DEFECTS_PRODUCT_BUG_TOTAL;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DEFECTS_SYSTEM_ISSUE_TOTAL;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DEFECTS_TO_INVESTIGATE_TOTAL;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.EXECUTIONS_TOTAL;
+
 import com.epam.ta.reportportal.core.events.activity.LaunchFinishedEvent;
 import com.epam.ta.reportportal.core.events.handler.ConfigurableEventHandler;
 import com.epam.ta.reportportal.core.integration.GetIntegrationHandler;
@@ -39,6 +46,11 @@
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.epam.ta.reportportal.ws.model.attribute.ItemAttributeResource;
 import com.google.common.annotations.VisibleForTesting;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.BooleanUtils;
 import org.slf4j.Logger;
@@ -47,187 +59,212 @@
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.core.statistics.StatisticsHelper.extractStatisticsCount;
-import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.*;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
-public class LaunchNotificationRunner implements ConfigurableEventHandler<LaunchFinishedEvent, Map<String, String>> {
-
-	public static final Logger LOGGER = LoggerFactory.getLogger(LaunchNotificationRunner.class);
-
-	private final GetProjectHandler getProjectHandler;
-	private final GetLaunchHandler getLaunchHandler;
-	private final GetIntegrationHandler getIntegrationHandler;
-	private final MailServiceFactory mailServiceFactory;
-	private final UserRepository userRepository;
-
-	@Autowired
-	public LaunchNotificationRunner(GetProjectHandler getProjectHandler, GetLaunchHandler getLaunchHandler,
-			GetIntegrationHandler getIntegrationHandler, MailServiceFactory mailServiceFactory, UserRepository userRepository) {
-		this.getProjectHandler = getProjectHandler;
-		this.getLaunchHandler = getLaunchHandler;
-		this.getIntegrationHandler = getIntegrationHandler;
-		this.mailServiceFactory = mailServiceFactory;
-		this.userRepository = userRepository;
-	}
-
-	@Override
-	@Transactional(readOnly = true)
-	public void handle(LaunchFinishedEvent launchFinishedEvent, Map<String, String> projectConfig) {
-
-		boolean isNotificationsEnabled = BooleanUtils.toBoolean(projectConfig.get(ProjectAttributeEnum.NOTIFICATIONS_ENABLED.getAttribute()));
-
-		if (isNotificationsEnabled) {
-			getIntegrationHandler.getEnabledByProjectIdOrGlobalAndIntegrationGroup(launchFinishedEvent.getProjectId(),
-							IntegrationGroupEnum.NOTIFICATION
-					)
-					.flatMap(mailServiceFactory::getDefaultEmailService)
-					.ifPresentOrElse(emailService -> sendEmail(launchFinishedEvent, emailService),
-							() -> LOGGER.warn("Unable to find {} integration for project {}",
-									IntegrationGroupEnum.NOTIFICATION,
-									launchFinishedEvent.getProjectId()
-							)
-					);
-
-		}
-
-	}
-
-	/**
-	 * Try to send email when it is needed
-	 *
-	 * @param launch       Launch to be used
-	 * @param project      Project
-	 * @param emailService Mail Service
-	 */
-	private void sendEmail(LaunchFinishedEvent launchFinishedEvent, EmailService emailService) {
-
-		final Launch launch = getLaunchHandler.get(launchFinishedEvent.getId());
-		final Project project = getProjectHandler.get(launch.getProjectId());
-
-		project.getSenderCases().stream().filter(SenderCase::isEnabled).forEach(ec -> {
-			SendCase sendCase = ec.getSendCase();
-			boolean successRate = isSuccessRateEnough(launch, sendCase);
-			boolean matchedNames = isLaunchNameMatched(launch, ec);
-			boolean matchedTags = isAttributesMatched(launch, ec.getLaunchAttributeRules(), ec.getAttributesOperator());
-
-			Set<String> recipients = ec.getRecipients();
-			if (successRate && matchedNames && matchedTags) {
-				String[] recipientsArray = findRecipients(userRepository.findLoginById(launch.getUserId())
-						.orElseThrow(() -> new ReportPortalException(ErrorType.USER_NOT_FOUND, launch.getUserId())), recipients);
-				try {
-					emailService.sendLaunchFinishNotification(recipientsArray,
-							String.format("%s/ui/#%s", launchFinishedEvent.getBaseUrl(), project.getName()),
-							project,
-							launch
-					);
-				} catch (Exception e) {
-					LOGGER.error("Unable to send email.", e);
-				}
-			}
-		});
-
-	}
-
-	private String[] findRecipients(String owner, Set<String> recipients) {
-		return recipients.stream().map(recipient -> {
-			if (recipient.contains("@")) {
-				return recipient;
-			} else {
-				String toFind = recipient.equals(ProjectUtils.getOwner()) ? owner : recipient;
-				Optional<User> user = userRepository.findByLogin(toFind);
-				return user.map(User::getEmail).orElse(null);
-			}
-		}).filter(Objects::nonNull).distinct().toArray(String[]::new);
-	}
-
-	/**
-	 * @param launch launch to be evaluated
-	 * @return success rate of provided launch in %
-	 */
-	private static double getSuccessRate(Launch launch) {
-		double ti = extractStatisticsCount(DEFECTS_TO_INVESTIGATE_TOTAL, launch.getStatistics()).doubleValue();
-		double pb = extractStatisticsCount(DEFECTS_PRODUCT_BUG_TOTAL, launch.getStatistics()).doubleValue();
-		double si = extractStatisticsCount(DEFECTS_SYSTEM_ISSUE_TOTAL, launch.getStatistics()).doubleValue();
-		double ab = extractStatisticsCount(DEFECTS_AUTOMATION_BUG_TOTAL, launch.getStatistics()).doubleValue();
-		double total = extractStatisticsCount(EXECUTIONS_TOTAL, launch.getStatistics()).doubleValue();
-		return total == 0 ? total : (ti + pb + si + ab) / total;
-	}
-
-	/**
-	 * @param launch Launch to be evaluated
-	 * @param option SendCase option
-	 * @return TRUE of success rate is enough for notification
-	 */
-	private boolean isSuccessRateEnough(Launch launch, SendCase option) {
-		switch (option) {
-			case ALWAYS:
-				return true;
-			case FAILED:
-				return getLaunchHandler.hasItemsWithIssues(launch);
-			case TO_INVESTIGATE:
-				return extractStatisticsCount(DEFECTS_TO_INVESTIGATE_TOTAL, launch.getStatistics()) > 0;
-			case MORE_10:
-				return getSuccessRate(launch) > 0.1;
-			case MORE_20:
-				return getSuccessRate(launch) > 0.2;
-			case MORE_50:
-				return getSuccessRate(launch) > 0.5;
-			default:
-				return false;
-		}
-	}
-
-	/**
-	 * Validate matching of finished launch name and project settings for emailing
-	 *
-	 * @param launch  Launch to be evaluated
-	 * @param oneCase Mail case
-	 * @return TRUE if launch name matched
-	 */
-	private static boolean isLaunchNameMatched(Launch launch, SenderCase oneCase) {
-		Set<String> configuredNames = oneCase.getLaunchNames();
-		return (null == configuredNames) || (configuredNames.isEmpty()) || configuredNames.contains(launch.getName());
-	}
-
-	/**
-	 * Validate matching of finished launch tags and project settings for emailing
-	 *
-	 * @param launch Launch to be evaluated
-	 * @return TRUE if tags matched
-	 */
-	@VisibleForTesting
-	private static boolean isAttributesMatched(Launch launch, Set<LaunchAttributeRule> launchAttributeRules, LogicalOperator logicalOperator) {
-
-		if (CollectionUtils.isEmpty(launchAttributeRules)) {
-			return true;
-		}
-
-		Set<ItemAttributeResource> itemAttributesResource = launchAttributeRules.stream()
-				.map(NotificationConfigConverter.TO_ATTRIBUTE_RULE_RESOURCE)
-				.collect(Collectors.toSet());
-
-		Set<ItemAttributeResource> itemAttributes = launch.getAttributes().stream().filter(attribute -> !attribute.isSystem()).map(attribute -> {
-			ItemAttributeResource attributeResource = new ItemAttributeResource();
-			attributeResource.setKey(attribute.getKey());
-			attributeResource.setValue(attribute.getValue());
-			return attributeResource;
-		}).collect(Collectors.toSet());
-
-		if (LogicalOperator.AND.equals(logicalOperator)) {
-			return itemAttributes.containsAll(itemAttributesResource);
-		}
-
-		return CollectionUtils.containsAny(itemAttributes, itemAttributesResource);
-	}
+public class LaunchNotificationRunner
+    implements ConfigurableEventHandler<LaunchFinishedEvent, Map<String, String>> {
+
+  public static final Logger LOGGER = LoggerFactory.getLogger(LaunchNotificationRunner.class);
+
+  private final GetProjectHandler getProjectHandler;
+  private final GetLaunchHandler getLaunchHandler;
+  private final GetIntegrationHandler getIntegrationHandler;
+  private final MailServiceFactory mailServiceFactory;
+  private final UserRepository userRepository;
+
+  @Autowired
+  public LaunchNotificationRunner(GetProjectHandler getProjectHandler,
+      GetLaunchHandler getLaunchHandler, GetIntegrationHandler getIntegrationHandler,
+      MailServiceFactory mailServiceFactory, UserRepository userRepository) {
+    this.getProjectHandler = getProjectHandler;
+    this.getLaunchHandler = getLaunchHandler;
+    this.getIntegrationHandler = getIntegrationHandler;
+    this.mailServiceFactory = mailServiceFactory;
+    this.userRepository = userRepository;
+  }
+
+  @Override
+  @Transactional(readOnly = true)
+  public void handle(LaunchFinishedEvent launchFinishedEvent, Map<String, String> projectConfig) {
+
+    boolean isNotificationsEnabled = BooleanUtils.toBoolean(
+        projectConfig.get(ProjectAttributeEnum.NOTIFICATIONS_ENABLED.getAttribute()));
+
+    if (isNotificationsEnabled) {
+      getIntegrationHandler.getEnabledByProjectIdOrGlobalAndIntegrationGroup(
+              launchFinishedEvent.getProjectId(), IntegrationGroupEnum.NOTIFICATION)
+          .flatMap(mailServiceFactory::getDefaultEmailService)
+          .ifPresentOrElse(emailService -> sendEmail(launchFinishedEvent, emailService),
+              () -> LOGGER.warn("Unable to find {} integration for project {}",
+                  IntegrationGroupEnum.NOTIFICATION, launchFinishedEvent.getProjectId()
+              )
+          );
+
+    }
+
+  }
+
+  /**
+   * Try to send email when it is needed
+   *
+   * @param launch       Launch to be used
+   * @param project      Project
+   * @param emailService Mail Service
+   */
+  private void sendEmail(LaunchFinishedEvent launchFinishedEvent, EmailService emailService) {
+
+    final Launch launch = getLaunchHandler.get(launchFinishedEvent.getId());
+    final Project project = getProjectHandler.get(launch.getProjectId());
+
+    project.getSenderCases().stream().filter(SenderCase::isEnabled).forEach(ec -> {
+      SendCase sendCase = ec.getSendCase();
+      boolean successRate = isSuccessRateEnough(launch, sendCase);
+      boolean matchedNames = isLaunchNameMatched(launch, ec);
+      boolean matchedTags =
+          isAttributesMatched(launch, ec.getLaunchAttributeRules(), ec.getAttributesOperator());
+
+      Set<String> recipients = ec.getRecipients();
+      if (successRate && matchedNames && matchedTags) {
+        String[] recipientsArray = findRecipients(
+            userRepository.findLoginById(launch.getUserId()).orElseThrow(
+                () -> new ReportPortalException(ErrorType.USER_NOT_FOUND, launch.getUserId())),
+            recipients
+        );
+        try {
+          if (launchFinishedEvent.getBaseUrl() != null) {
+            emailService.sendLaunchFinishNotification(recipientsArray,
+                String.format("%s/ui/#%s", launchFinishedEvent.getBaseUrl(), project.getName()),
+                project, launch
+            );
+          } else {
+            emailService.sendLaunchFinishNotification(
+                recipientsArray, String.format("/ui/#%s", project.getName()), project, launch);
+          }
+        } catch (Exception e) {
+          LOGGER.error("Unable to send email.", e);
+        }
+      }
+    });
+
+  }
+
+  private String[] findRecipients(String owner, Set<String> recipients) {
+    return recipients.stream().map(recipient -> {
+      if (recipient.contains("@")) {
+        return recipient;
+      } else {
+        String toFind = recipient.equals(ProjectUtils.getOwner()) ? owner : recipient;
+        Optional<User> user = userRepository.findByLogin(toFind);
+        return user.map(User::getEmail).orElse(null);
+      }
+    }).filter(Objects::nonNull).distinct().toArray(String[]::new);
+  }
+
+  /**
+   * @param launch launch to be evaluated
+   * @return success rate of provided launch in %
+   */
+  private static double getSuccessRate(Launch launch) {
+    double ti =
+        extractStatisticsCount(DEFECTS_TO_INVESTIGATE_TOTAL, launch.getStatistics()).doubleValue();
+    double pb =
+        extractStatisticsCount(DEFECTS_PRODUCT_BUG_TOTAL, launch.getStatistics()).doubleValue();
+    double si =
+        extractStatisticsCount(DEFECTS_SYSTEM_ISSUE_TOTAL, launch.getStatistics()).doubleValue();
+    double ab =
+        extractStatisticsCount(DEFECTS_AUTOMATION_BUG_TOTAL, launch.getStatistics()).doubleValue();
+    double total = extractStatisticsCount(EXECUTIONS_TOTAL, launch.getStatistics()).doubleValue();
+    return total == 0 ? total : (ti + pb + si + ab) / total;
+  }
+
+  /**
+   * @param launch Launch to be evaluated
+   * @param option SendCase option
+   * @return TRUE of success rate is enough for notification
+   */
+  private boolean isSuccessRateEnough(Launch launch, SendCase option) {
+    switch (option) {
+      case ALWAYS:
+        return true;
+      case FAILED:
+        return getLaunchHandler.hasItemsWithIssues(launch);
+      case TO_INVESTIGATE:
+        return extractStatisticsCount(DEFECTS_TO_INVESTIGATE_TOTAL, launch.getStatistics()) > 0;
+      case MORE_10:
+        return getSuccessRate(launch) > 0.1;
+      case MORE_20:
+        return getSuccessRate(launch) > 0.2;
+      case MORE_50:
+        return getSuccessRate(launch) > 0.5;
+      default:
+        return false;
+    }
+  }
+
+  /**
+   * Validate matching of finished launch name and project settings for emailing
+   *
+   * @param launch  Launch to be evaluated
+   * @param oneCase Mail case
+   * @return TRUE if launch name matched
+   */
+  private static boolean isLaunchNameMatched(Launch launch, SenderCase oneCase) {
+    Set<String> configuredNames = oneCase.getLaunchNames();
+    return (null == configuredNames) || (configuredNames.isEmpty()) || configuredNames.contains(
+        launch.getName());
+  }
+
+  /**
+   * Validate matching of finished launch tags and project settings for emailing
+   *
+   * @param launch Launch to be evaluated
+   * @return TRUE if tags matched
+   */
+  @VisibleForTesting
+  private static boolean isAttributesMatched(Launch launch,
+      Set<LaunchAttributeRule> launchAttributeRules, LogicalOperator logicalOperator) {
+
+    if (CollectionUtils.isEmpty(launchAttributeRules)) {
+      return true;
+    }
+
+    Set<ItemAttributeResource> itemAttributesResource =
+        launchAttributeRules.stream().map(NotificationConfigConverter.TO_ATTRIBUTE_RULE_RESOURCE)
+            .collect(Collectors.toSet());
+
+    Set<ItemAttributeResource> itemAttributes =
+        launch.getAttributes().stream().filter(attribute -> !attribute.isSystem())
+            .map(attribute -> {
+              ItemAttributeResource attributeResource = new ItemAttributeResource();
+              attributeResource.setKey(attribute.getKey());
+              attributeResource.setValue(attribute.getValue());
+              return attributeResource;
+            }).collect(Collectors.toSet());
+
+    if (LogicalOperator.AND.equals(logicalOperator)) {
+      return itemAttributesResource.stream().allMatch(resourceAttr -> itemAttributes.stream()
+          .anyMatch(attr -> areAttributesMatched(attr, resourceAttr)));
+    }
+
+    return itemAttributes.stream().anyMatch(attr -> itemAttributesResource.stream()
+        .anyMatch(resourceAttr -> areAttributesMatched(attr, resourceAttr)));
+  }
+
+  private static boolean areAttributesMatched(ItemAttributeResource itemAttribute,
+      ItemAttributeResource itemAttributeResource) {
+    // Case 1: Key and Value are the same
+    boolean isEqual =
+        Objects.equals(itemAttribute.getKey(), itemAttributeResource.getKey()) && Objects.equals(
+            itemAttribute.getValue(), itemAttributeResource.getValue());
+
+    // Case 2: Key is null in itemAttributesResource and the Value is the same
+    boolean isValueEqualWithKeyNull =
+        itemAttributeResource.getKey() == null && Objects.equals(itemAttribute.getValue(),
+            itemAttributeResource.getValue()
+        );
 
+    return isEqual || isValueEqualWithKeyNull;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchPatternAnalysisRunner.java b/src/main/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchPatternAnalysisRunner.java
index 825d6df0cc..1ce570340e 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchPatternAnalysisRunner.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchPatternAnalysisRunner.java
@@ -17,45 +17,48 @@
 package com.epam.ta.reportportal.core.events.handler.launch;
 
 import com.epam.ta.reportportal.core.analyzer.auto.strategy.analyze.AnalyzeItemsMode;
-import com.epam.ta.reportportal.core.analyzer.pattern.PatternAnalyzer;
+import com.epam.ta.reportportal.core.analyzer.pattern.service.LaunchPatternAnalyzer;
 import com.epam.ta.reportportal.core.events.activity.LaunchFinishedEvent;
 import com.epam.ta.reportportal.core.events.handler.ConfigurableEventHandler;
 import com.epam.ta.reportportal.core.launch.GetLaunchHandler;
 import com.epam.ta.reportportal.entity.enums.ProjectAttributeEnum;
 import com.epam.ta.reportportal.entity.launch.Launch;
+import com.google.common.collect.Sets;
+import java.util.Map;
 import org.apache.commons.lang3.BooleanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.Collections;
-import java.util.Map;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
-public class LaunchPatternAnalysisRunner implements ConfigurableEventHandler<LaunchFinishedEvent, Map<String, String>> {
+public class LaunchPatternAnalysisRunner implements
+    ConfigurableEventHandler<LaunchFinishedEvent, Map<String, String>> {
 
-	private final GetLaunchHandler getLaunchHandler;
-	private final PatternAnalyzer patternAnalyzer;
+  private final GetLaunchHandler getLaunchHandler;
+  private final LaunchPatternAnalyzer launchPatternAnalyzer;
 
-	@Autowired
-	public LaunchPatternAnalysisRunner(GetLaunchHandler getLaunchHandler, PatternAnalyzer patternAnalyzer) {
-		this.getLaunchHandler = getLaunchHandler;
-		this.patternAnalyzer = patternAnalyzer;
-	}
+  @Autowired
+  public LaunchPatternAnalysisRunner(GetLaunchHandler getLaunchHandler,
+      LaunchPatternAnalyzer launchPatternAnalyzer) {
+    this.getLaunchHandler = getLaunchHandler;
+    this.launchPatternAnalyzer = launchPatternAnalyzer;
+  }
 
-	@Override
-	@Transactional
-	public void handle(LaunchFinishedEvent launchFinishedEvent, Map<String, String> projectConfig) {
+  @Override
+  @Transactional
+  public void handle(LaunchFinishedEvent launchFinishedEvent, Map<String, String> projectConfig) {
 
-		boolean isPatternAnalysisEnabled = BooleanUtils.toBoolean(projectConfig.get(ProjectAttributeEnum.AUTO_PATTERN_ANALYZER_ENABLED.getAttribute()));
+    boolean isPatternAnalysisEnabled = BooleanUtils.toBoolean(
+        projectConfig.get(ProjectAttributeEnum.AUTO_PATTERN_ANALYZER_ENABLED.getAttribute()));
 
-		if (isPatternAnalysisEnabled) {
-			final Launch launch = getLaunchHandler.get(launchFinishedEvent.getId());
-			patternAnalyzer.analyzeTestItems(launch, Collections.singleton(AnalyzeItemsMode.TO_INVESTIGATE));
-		}
-	}
+    if (isPatternAnalysisEnabled) {
+      final Launch launch = getLaunchHandler.get(launchFinishedEvent.getId());
+      launchPatternAnalyzer.analyzeLaunch(launch,
+          Sets.newHashSet(AnalyzeItemsMode.TO_INVESTIGATE, AnalyzeItemsMode.IGNORE_IMMEDIATE));
+    }
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchUniqueErrorAnalysisRunner.java b/src/main/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchUniqueErrorAnalysisRunner.java
index 279c1fb2f7..4194d712e1 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchUniqueErrorAnalysisRunner.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchUniqueErrorAnalysisRunner.java
@@ -16,40 +16,43 @@
 
 package com.epam.ta.reportportal.core.events.handler.launch;
 
+import static com.epam.ta.reportportal.entity.enums.ProjectAttributeEnum.AUTO_UNIQUE_ERROR_ANALYZER_ENABLED;
+
 import com.epam.ta.reportportal.core.events.activity.LaunchFinishedEvent;
 import com.epam.ta.reportportal.core.events.handler.ConfigurableEventHandler;
 import com.epam.ta.reportportal.core.launch.cluster.UniqueErrorAnalysisStarter;
 import com.epam.ta.reportportal.core.launch.cluster.config.ClusterEntityContext;
+import java.util.Map;
 import org.apache.commons.lang3.BooleanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 
-import java.util.Map;
-
-import static com.epam.ta.reportportal.entity.enums.ProjectAttributeEnum.AUTO_UNIQUE_ERROR_ANALYZER_ENABLED;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
-public class LaunchUniqueErrorAnalysisRunner implements ConfigurableEventHandler<LaunchFinishedEvent, Map<String, String>> {
-
-	private final UniqueErrorAnalysisStarter uniqueErrorAnalysisStarter;
-
-	@Autowired
-	public LaunchUniqueErrorAnalysisRunner(@Qualifier("uniqueErrorAnalysisStarter") UniqueErrorAnalysisStarter uniqueErrorAnalysisStarter) {
-		this.uniqueErrorAnalysisStarter = uniqueErrorAnalysisStarter;
-	}
-
-	@Override
-	public void handle(LaunchFinishedEvent launchFinishedEvent, Map<String, String> projectConfig) {
-		final boolean enabled = BooleanUtils.toBoolean(projectConfig.get(AUTO_UNIQUE_ERROR_ANALYZER_ENABLED.getAttribute()));
-		if (enabled) {
-			uniqueErrorAnalysisStarter.start(ClusterEntityContext.of(launchFinishedEvent.getId(), launchFinishedEvent.getProjectId()),
-					projectConfig
-			);
-		}
-	}
+public class LaunchUniqueErrorAnalysisRunner implements
+    ConfigurableEventHandler<LaunchFinishedEvent, Map<String, String>> {
+
+  private final UniqueErrorAnalysisStarter uniqueErrorAnalysisStarter;
+
+  @Autowired
+  public LaunchUniqueErrorAnalysisRunner(
+      @Qualifier("uniqueErrorAnalysisStarter") UniqueErrorAnalysisStarter uniqueErrorAnalysisStarter) {
+    this.uniqueErrorAnalysisStarter = uniqueErrorAnalysisStarter;
+  }
+
+  @Override
+  public void handle(LaunchFinishedEvent launchFinishedEvent, Map<String, String> projectConfig) {
+    final boolean enabled = BooleanUtils.toBoolean(
+        projectConfig.get(AUTO_UNIQUE_ERROR_ANALYZER_ENABLED.getAttribute()));
+    if (enabled) {
+      uniqueErrorAnalysisStarter.start(
+          ClusterEntityContext.of(launchFinishedEvent.getId(), launchFinishedEvent.getProjectId()),
+          projectConfig
+      );
+    }
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/listener/LaunchFinishedEventListener.java b/src/main/java/com/epam/ta/reportportal/core/events/listener/LaunchFinishedEventListener.java
index 65acb7fa89..8bd764b721 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/listener/LaunchFinishedEventListener.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/listener/LaunchFinishedEventListener.java
@@ -19,31 +19,30 @@
 import com.epam.ta.reportportal.core.events.activity.LaunchFinishedEvent;
 import com.epam.ta.reportportal.core.events.subscriber.EventSubscriber;
 import com.epam.ta.reportportal.entity.enums.LaunchModeEnum;
+import java.util.List;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.transaction.event.TransactionalEventListener;
 
-import java.util.List;
-
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
  */
 public class LaunchFinishedEventListener {
 
-	private final List<EventSubscriber<LaunchFinishedEvent>> subscribers;
+  private final List<EventSubscriber<LaunchFinishedEvent>> subscribers;
 
-	public LaunchFinishedEventListener(List<EventSubscriber<LaunchFinishedEvent>> subscribers) {
-		this.subscribers = subscribers;
-	}
+  public LaunchFinishedEventListener(List<EventSubscriber<LaunchFinishedEvent>> subscribers) {
+    this.subscribers = subscribers;
+  }
 
-	@Async(value = "eventListenerExecutor")
-	@TransactionalEventListener
-	public void onApplicationEvent(LaunchFinishedEvent event) {
-		if (LaunchModeEnum.DEBUG == event.getMode()) {
-			return;
-		}
+  @Async(value = "eventListenerExecutor")
+  @TransactionalEventListener
+  public void onApplicationEvent(LaunchFinishedEvent event) {
+    if (LaunchModeEnum.DEBUG == event.getMode()) {
+      return;
+    }
 
-		subscribers.forEach(s -> s.handleEvent(event));
+    subscribers.forEach(s -> s.handleEvent(event));
 
-	}
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/listener/StartLaunchUniqueErrorAnalysisEventListener.java b/src/main/java/com/epam/ta/reportportal/core/events/listener/StartLaunchUniqueErrorAnalysisEventListener.java
index 609e17aa82..ab41e66666 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/listener/StartLaunchUniqueErrorAnalysisEventListener.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/listener/StartLaunchUniqueErrorAnalysisEventListener.java
@@ -20,32 +20,32 @@
 import com.epam.ta.reportportal.core.launch.cluster.UniqueErrorAnalysisStarter;
 import com.epam.ta.reportportal.core.launch.cluster.config.ClusterEntityContext;
 import com.epam.ta.reportportal.core.project.config.ProjectConfigProvider;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.context.event.EventListener;
 import org.springframework.stereotype.Service;
 
-import java.util.Map;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class StartLaunchUniqueErrorAnalysisEventListener {
 
-	private final ProjectConfigProvider projectConfigProvider;
-	private final UniqueErrorAnalysisStarter uniqueErrorAnalysisStarter;
+  private final ProjectConfigProvider projectConfigProvider;
+  private final UniqueErrorAnalysisStarter uniqueErrorAnalysisStarter;
 
-	@Autowired
-	public StartLaunchUniqueErrorAnalysisEventListener(ProjectConfigProvider projectConfigProvider,
-			@Qualifier("uniqueErrorAnalysisStarter") UniqueErrorAnalysisStarter uniqueErrorAnalysisStarter) {
-		this.projectConfigProvider = projectConfigProvider;
-		this.uniqueErrorAnalysisStarter = uniqueErrorAnalysisStarter;
-	}
+  @Autowired
+  public StartLaunchUniqueErrorAnalysisEventListener(ProjectConfigProvider projectConfigProvider,
+      @Qualifier("uniqueErrorAnalysisStarter") UniqueErrorAnalysisStarter uniqueErrorAnalysisStarter) {
+    this.projectConfigProvider = projectConfigProvider;
+    this.uniqueErrorAnalysisStarter = uniqueErrorAnalysisStarter;
+  }
 
-	@EventListener
-	public void onApplicationEvent(LaunchStartUniqueErrorAnalysisEvent event) {
-		final Map<String, String> projectConfig = projectConfigProvider.provide(event.getProjectId());
-		uniqueErrorAnalysisStarter.start(ClusterEntityContext.of(event.getSource(), event.getProjectId()), projectConfig);
-	}
+  @EventListener
+  public void onApplicationEvent(LaunchStartUniqueErrorAnalysisEvent event) {
+    final Map<String, String> projectConfig = projectConfigProvider.provide(event.getProjectId());
+    uniqueErrorAnalysisStarter.start(
+        ClusterEntityContext.of(event.getSource(), event.getProjectId()), projectConfig);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/listener/TestItemFinishedEventListener.java b/src/main/java/com/epam/ta/reportportal/core/events/listener/TestItemFinishedEventListener.java
index a7cb65ecc2..dec6fe874b 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/listener/TestItemFinishedEventListener.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/listener/TestItemFinishedEventListener.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2021 EPAM Systems
+ * Copyright 2023 EPAM Systems
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,30 +13,28 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package com.epam.ta.reportportal.core.events.listener;
 
-import com.epam.ta.reportportal.core.events.activity.item.ItemFinishedEvent;
+import com.epam.ta.reportportal.core.events.activity.item.TestItemFinishedEvent;
 import com.epam.ta.reportportal.core.events.subscriber.EventSubscriber;
+import java.util.List;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.transaction.event.TransactionalEventListener;
 
-import java.util.List;
-
 /**
- * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
+ * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
  */
 public class TestItemFinishedEventListener {
 
-	private final List<EventSubscriber<ItemFinishedEvent>> subscribers;
+  private final List<EventSubscriber<TestItemFinishedEvent>> subscribers;
 
-	public TestItemFinishedEventListener(List<EventSubscriber<ItemFinishedEvent>> subscribers) {
-		this.subscribers = subscribers;
-	}
+  public TestItemFinishedEventListener(List<EventSubscriber<TestItemFinishedEvent>> subscribers) {
+    this.subscribers = subscribers;
+  }
 
-	@Async(value = "eventListenerExecutor")
-	@TransactionalEventListener
-	public void onApplicationEvent(ItemFinishedEvent event) {
-		subscribers.forEach(s -> s.handleEvent(event));
-	}
+  @Async(value = "eventListenerExecutor")
+  @TransactionalEventListener
+  public void onApplicationEvent(TestItemFinishedEvent event) {
+    subscribers.forEach(s -> s.handleEvent(event));
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/listener/TestItemIssueResolvedEventListener.java b/src/main/java/com/epam/ta/reportportal/core/events/listener/TestItemIssueResolvedEventListener.java
new file mode 100644
index 0000000000..7a89b37e0c
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/core/events/listener/TestItemIssueResolvedEventListener.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.core.events.listener;
+
+import com.epam.ta.reportportal.core.events.activity.item.IssueResolvedEvent;
+import com.epam.ta.reportportal.core.events.subscriber.EventSubscriber;
+import java.util.List;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.transaction.event.TransactionalEventListener;
+
+/**
+ * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
+ */
+public class TestItemIssueResolvedEventListener {
+
+  private final List<EventSubscriber<IssueResolvedEvent>> subscribers;
+
+  public TestItemIssueResolvedEventListener(List<EventSubscriber<IssueResolvedEvent>> subscribers) {
+    this.subscribers = subscribers;
+  }
+
+  @Async(value = "eventListenerExecutor")
+  @TransactionalEventListener
+  public void onApplicationEvent(IssueResolvedEvent event) {
+    subscribers.forEach(s -> s.handleEvent(event));
+  }
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/multicaster/DelegatingApplicationEventMulticaster.java b/src/main/java/com/epam/ta/reportportal/core/events/multicaster/DelegatingApplicationEventMulticaster.java
index 29b0a2b681..9f9c6fd8fc 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/multicaster/DelegatingApplicationEventMulticaster.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/multicaster/DelegatingApplicationEventMulticaster.java
@@ -16,80 +16,82 @@
 
 package com.epam.ta.reportportal.core.events.multicaster;
 
+import static java.util.Optional.ofNullable;
+
+import java.util.Set;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.springframework.context.ApplicationEvent;
 import org.springframework.context.ApplicationListener;
 import org.springframework.context.event.SimpleApplicationEventMulticaster;
 
-import java.util.Set;
-
-import static java.util.Optional.ofNullable;
-
 /**
- * Extension for {@link SimpleApplicationEventMulticaster} to allow error handling only for provided set of events
+ * Extension for {@link SimpleApplicationEventMulticaster} to allow error handling only for provided
+ * set of events
  *
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public class DelegatingApplicationEventMulticaster extends SimpleApplicationEventMulticaster {
 
-	private final Set<Class<?>> errorHandlingEventTypes;
+  private final Set<Class<?>> errorHandlingEventTypes;
 
-	public DelegatingApplicationEventMulticaster(Set<Class<?>> errorHandlingEventTypes) {
-		this.errorHandlingEventTypes = errorHandlingEventTypes;
-	}
+  public DelegatingApplicationEventMulticaster(Set<Class<?>> errorHandlingEventTypes) {
+    this.errorHandlingEventTypes = errorHandlingEventTypes;
+  }
 
-	@Override
-	protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
-		ofNullable(getErrorHandler()).filter(h -> errorHandlingEventTypes.contains(event.getClass())).ifPresentOrElse(h -> {
-			try {
-				doInvokeListener(listener, event);
-			} catch (Throwable err) {
-				h.handleError(err);
-			}
-		}, () -> doInvokeListener(listener, event));
-	}
+  @Override
+  protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
+    ofNullable(getErrorHandler()).filter(h -> errorHandlingEventTypes.contains(event.getClass()))
+        .ifPresentOrElse(h -> {
+          try {
+            doInvokeListener(listener, event);
+          } catch (Throwable err) {
+            h.handleError(err);
+          }
+        }, () -> doInvokeListener(listener, event));
+  }
 
-	/**
-	 * @see SimpleApplicationEventMulticaster
-	 */
-	@SuppressWarnings({ "rawtypes", "unchecked" })
-	private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
-		try {
-			listener.onApplicationEvent(event);
-		} catch (ClassCastException ex) {
-			String msg = ex.getMessage();
-			if (msg == null || matchesClassCastMessage(msg, event.getClass())) {
-				// Possibly a lambda-defined listener which we could not resolve the generic event type for
-				// -> let's suppress the exception and just log a debug message.
-				Log logger = LogFactory.getLog(getClass());
-				if (logger.isTraceEnabled()) {
-					logger.trace("Non-matching event type for listener: " + listener, ex);
-				}
-			} else {
-				throw ex;
-			}
-		}
-	}
+  /**
+   * @see SimpleApplicationEventMulticaster
+   */
+  @SuppressWarnings({"rawtypes", "unchecked"})
+  private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
+    try {
+      listener.onApplicationEvent(event);
+    } catch (ClassCastException ex) {
+      String msg = ex.getMessage();
+      if (msg == null || matchesClassCastMessage(msg, event.getClass())) {
+        // Possibly a lambda-defined listener which we could not resolve the generic event type for
+        // -> let's suppress the exception and just log a debug message.
+        Log logger = LogFactory.getLog(getClass());
+        if (logger.isTraceEnabled()) {
+          logger.trace("Non-matching event type for listener: " + listener, ex);
+        }
+      } else {
+        throw ex;
+      }
+    }
+  }
 
-	/**
-	 * @see SimpleApplicationEventMulticaster
-	 */
-	private boolean matchesClassCastMessage(String classCastMessage, Class<?> eventClass) {
-		// On Java 8, the message starts with the class name: "java.lang.String cannot be cast..."
-		if (classCastMessage.startsWith(eventClass.getName())) {
-			return true;
-		}
-		// On Java 11, the message starts with "class ..." a.k.a. Class.toString()
-		if (classCastMessage.startsWith(eventClass.toString())) {
-			return true;
-		}
-		// On Java 9, the message used to contain the module name: "java.base/java.lang.String cannot be cast..."
-		int moduleSeparatorIndex = classCastMessage.indexOf('/');
-		if (moduleSeparatorIndex != -1 && classCastMessage.startsWith(eventClass.getName(), moduleSeparatorIndex + 1)) {
-			return true;
-		}
-		// Assuming an unrelated class cast failure...
-		return false;
-	}
+  /**
+   * @see SimpleApplicationEventMulticaster
+   */
+  private boolean matchesClassCastMessage(String classCastMessage, Class<?> eventClass) {
+    // On Java 8, the message starts with the class name: "java.lang.String cannot be cast..."
+    if (classCastMessage.startsWith(eventClass.getName())) {
+      return true;
+    }
+    // On Java 11, the message starts with "class ..." a.k.a. Class.toString()
+    if (classCastMessage.startsWith(eventClass.toString())) {
+      return true;
+    }
+    // On Java 9, the message used to contain the module name: "java.base/java.lang.String cannot be cast..."
+    int moduleSeparatorIndex = classCastMessage.indexOf('/');
+    if (moduleSeparatorIndex != -1 && classCastMessage.startsWith(eventClass.getName(),
+        moduleSeparatorIndex + 1)) {
+      return true;
+    }
+    // Assuming an unrelated class cast failure...
+    return false;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/subscriber/EventSubscriber.java b/src/main/java/com/epam/ta/reportportal/core/events/subscriber/EventSubscriber.java
index 3cebb0847e..0a45f490e5 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/subscriber/EventSubscriber.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/subscriber/EventSubscriber.java
@@ -23,5 +23,5 @@
  */
 public interface EventSubscriber<T extends Event> {
 
-	void handleEvent(T event);
+  void handleEvent(T event);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/subscriber/impl/delegate/ProjectConfigDelegatingSubscriber.java b/src/main/java/com/epam/ta/reportportal/core/events/subscriber/impl/delegate/ProjectConfigDelegatingSubscriber.java
index 39e46604bf..ef9d5044eb 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/subscriber/impl/delegate/ProjectConfigDelegatingSubscriber.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/subscriber/impl/delegate/ProjectConfigDelegatingSubscriber.java
@@ -20,27 +20,27 @@
 import com.epam.ta.reportportal.core.events.handler.ConfigurableEventHandler;
 import com.epam.ta.reportportal.core.events.subscriber.EventSubscriber;
 import com.epam.ta.reportportal.core.project.config.ProjectConfigProvider;
-
 import java.util.List;
 import java.util.Map;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
-public class ProjectConfigDelegatingSubscriber<T extends ProjectIdAwareEvent> implements EventSubscriber<T> {
+public class ProjectConfigDelegatingSubscriber<T extends ProjectIdAwareEvent> implements
+    EventSubscriber<T> {
 
-	private final ProjectConfigProvider projectConfigProvider;
-	private final List<ConfigurableEventHandler<T, Map<String, String>>> eventHandlers;
+  private final ProjectConfigProvider projectConfigProvider;
+  private final List<ConfigurableEventHandler<T, Map<String, String>>> eventHandlers;
 
-	public ProjectConfigDelegatingSubscriber(ProjectConfigProvider projectConfigProvider,
-			List<ConfigurableEventHandler<T, Map<String, String>>> eventHandlers) {
-		this.projectConfigProvider = projectConfigProvider;
-		this.eventHandlers = eventHandlers;
-	}
+  public ProjectConfigDelegatingSubscriber(ProjectConfigProvider projectConfigProvider,
+      List<ConfigurableEventHandler<T, Map<String, String>>> eventHandlers) {
+    this.projectConfigProvider = projectConfigProvider;
+    this.eventHandlers = eventHandlers;
+  }
 
-	@Override
-	public void handleEvent(T event) {
-		final Map<String, String> projectConfig = projectConfigProvider.provide(event.getProjectId());
-		eventHandlers.forEach(h -> h.handle(event, projectConfig));
-	}
+  @Override
+  public void handleEvent(T event) {
+    final Map<String, String> projectConfig = projectConfigProvider.provide(event.getProjectId());
+    eventHandlers.forEach(h -> h.handle(event, projectConfig));
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/widget/GenerateComponentHealthCheckTableEvent.java b/src/main/java/com/epam/ta/reportportal/core/events/widget/GenerateComponentHealthCheckTableEvent.java
index aacd822d1d..c55573f419 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/widget/GenerateComponentHealthCheckTableEvent.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/widget/GenerateComponentHealthCheckTableEvent.java
@@ -1,7 +1,6 @@
 package com.epam.ta.reportportal.core.events.widget;
 
 import com.google.common.collect.Lists;
-
 import java.util.List;
 
 /**
@@ -9,31 +8,32 @@
  */
 public class GenerateComponentHealthCheckTableEvent {
 
-	private final Long widgetId;
-	private final boolean refresh;
-	private final List<String> attributeKeys;
-
-	public GenerateComponentHealthCheckTableEvent(Long widgetId, boolean refresh) {
-		this.widgetId = widgetId;
-		this.refresh = refresh;
-		this.attributeKeys = Lists.newArrayList();
-	}
-
-	public GenerateComponentHealthCheckTableEvent(Long widgetId, boolean refresh, List<String> attributeKeys) {
-		this.widgetId = widgetId;
-		this.refresh = refresh;
-		this.attributeKeys = attributeKeys;
-	}
-
-	public Long getWidgetId() {
-		return widgetId;
-	}
-
-	public boolean isRefresh() {
-		return refresh;
-	}
-
-	public List<String> getAttributeKeys() {
-		return attributeKeys;
-	}
+  private final Long widgetId;
+  private final boolean refresh;
+  private final List<String> attributeKeys;
+
+  public GenerateComponentHealthCheckTableEvent(Long widgetId, boolean refresh) {
+    this.widgetId = widgetId;
+    this.refresh = refresh;
+    this.attributeKeys = Lists.newArrayList();
+  }
+
+  public GenerateComponentHealthCheckTableEvent(Long widgetId, boolean refresh,
+      List<String> attributeKeys) {
+    this.widgetId = widgetId;
+    this.refresh = refresh;
+    this.attributeKeys = attributeKeys;
+  }
+
+  public Long getWidgetId() {
+    return widgetId;
+  }
+
+  public boolean isRefresh() {
+    return refresh;
+  }
+
+  public List<String> getAttributeKeys() {
+    return attributeKeys;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/events/widget/GenerateWidgetViewEvent.java b/src/main/java/com/epam/ta/reportportal/core/events/widget/GenerateWidgetViewEvent.java
index f0430dfcd8..cf73138a93 100644
--- a/src/main/java/com/epam/ta/reportportal/core/events/widget/GenerateWidgetViewEvent.java
+++ b/src/main/java/com/epam/ta/reportportal/core/events/widget/GenerateWidgetViewEvent.java
@@ -8,24 +8,24 @@
  */
 public class GenerateWidgetViewEvent {
 
-	private final Long widgetId;
-	private final MultiValueMap<String, String> params;
+  private final Long widgetId;
+  private final MultiValueMap<String, String> params;
 
-	public GenerateWidgetViewEvent(Long widgetId, MultiValueMap<String, String> params) {
-		this.widgetId = widgetId;
-		this.params = params;
-	}
+  public GenerateWidgetViewEvent(Long widgetId, MultiValueMap<String, String> params) {
+    this.widgetId = widgetId;
+    this.params = params;
+  }
 
-	public GenerateWidgetViewEvent(Long widgetId) {
-		this.widgetId = widgetId;
-		this.params = new LinkedMultiValueMap<>();
-	}
+  public GenerateWidgetViewEvent(Long widgetId) {
+    this.widgetId = widgetId;
+    this.params = new LinkedMultiValueMap<>();
+  }
 
-	public Long getWidgetId() {
-		return widgetId;
-	}
+  public Long getWidgetId() {
+    return widgetId;
+  }
 
-	public MultiValueMap<String, String> getParams() {
-		return params;
-	}
+  public MultiValueMap<String, String> getParams() {
+    return params;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/file/DeleteFilesHandler.java b/src/main/java/com/epam/ta/reportportal/core/file/DeleteFilesHandler.java
index 11ef8832ee..49161f40a1 100644
--- a/src/main/java/com/epam/ta/reportportal/core/file/DeleteFilesHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/file/DeleteFilesHandler.java
@@ -1,5 +1,8 @@
 package com.epam.ta.reportportal.core.file;
 
+import static com.epam.ta.reportportal.core.configs.rabbit.InternalConfiguration.EXCHANGE_ATTACHMENT;
+import static com.epam.ta.reportportal.core.configs.rabbit.InternalConfiguration.QUEUE_ATTACHMENT_DELETE;
+
 import com.epam.ta.reportportal.core.events.MessageBus;
 import com.epam.ta.reportportal.core.events.attachment.DeleteAttachmentEvent;
 import com.epam.ta.reportportal.exception.ReportPortalException;
@@ -10,48 +13,49 @@
 import com.opencsv.CSVParserBuilder;
 import com.opencsv.CSVReader;
 import com.opencsv.CSVReaderBuilder;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
 import org.apache.commons.collections4.ListUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
 
-import java.io.InputStreamReader;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-
 @Service
 public class DeleteFilesHandler {
 
-	private static final int FILE_ID = 1;
-	private static final int CSV_SKIP_LINES = 1;
-	private static final int THUMBNAIL_ID = 2;
-	private static final int BATCH = 250;
+  private static final int FILE_ID = 1;
+  private static final int CSV_SKIP_LINES = 1;
+  private static final int THUMBNAIL_ID = 2;
+  private static final int BATCH = 250;
 
-	@Autowired
-	private MessageBus messageBus;
+  @Autowired
+  private MessageBus messageBus;
 
-	public OperationCompletionRS removeFilesByCsv(MultipartFile file) {
-		CSVParser parser = new CSVParserBuilder().withSeparator(',').withIgnoreQuotations(true).build();
-		try (CSVReader csvReader = new CSVReaderBuilder(new InputStreamReader(file.getInputStream(), StandardCharsets.UTF_8)).withSkipLines(
-				CSV_SKIP_LINES).withCSVParser(parser).build()) {
-			List<String[]> attachments = csvReader.readAll();
-			List<String> pathsForDelete = Lists.newArrayListWithCapacity(attachments.size());
-			attachments.forEach(attachmentLine -> {
-				pathsForDelete.add(attachmentLine[FILE_ID]);
-				if (!StringUtils.isEmpty(attachmentLine[THUMBNAIL_ID])) {
-					pathsForDelete.add(attachmentLine[THUMBNAIL_ID]);
-				}
-			});
-			ListUtils.partition(pathsForDelete, BATCH).forEach(partition -> {
-				DeleteAttachmentEvent deleteAttachmentEvent = new DeleteAttachmentEvent();
-				deleteAttachmentEvent.setPaths(partition);
-				messageBus.publishDeleteAttachmentEvent(deleteAttachmentEvent);
-			});
-			return new OperationCompletionRS("Csv file " + file.getName() + " is accepted for delete process");
-		} catch (Exception e) {
-			throw new ReportPortalException(ErrorType.BAD_REQUEST_ERROR, e.getMessage());
-		}
-	}
+  public OperationCompletionRS removeFilesByCsv(MultipartFile file) {
+    CSVParser parser = new CSVParserBuilder().withSeparator(',').withIgnoreQuotations(true).build();
+    try (CSVReader csvReader = new CSVReaderBuilder(
+        new InputStreamReader(file.getInputStream(), StandardCharsets.UTF_8)).withSkipLines(
+        CSV_SKIP_LINES).withCSVParser(parser).build()) {
+      List<String[]> attachments = csvReader.readAll();
+      List<String> pathsForDelete = Lists.newArrayListWithCapacity(attachments.size());
+      attachments.forEach(attachmentLine -> {
+        pathsForDelete.add(attachmentLine[FILE_ID]);
+        if (!StringUtils.isEmpty(attachmentLine[THUMBNAIL_ID])) {
+          pathsForDelete.add(attachmentLine[THUMBNAIL_ID]);
+        }
+      });
+      ListUtils.partition(pathsForDelete, BATCH).forEach(partition -> {
+        DeleteAttachmentEvent deleteAttachmentEvent = new DeleteAttachmentEvent();
+        deleteAttachmentEvent.setPaths(partition);
+        messageBus.publish(EXCHANGE_ATTACHMENT, QUEUE_ATTACHMENT_DELETE, deleteAttachmentEvent);
+      });
+      return new OperationCompletionRS(
+          "Csv file " + file.getName() + " is accepted for delete process");
+    } catch (Exception e) {
+      throw new ReportPortalException(ErrorType.BAD_REQUEST_ERROR, e.getMessage());
+    }
+  }
 
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/file/GetFileHandler.java b/src/main/java/com/epam/ta/reportportal/core/file/GetFileHandler.java
index 52b376d42f..119a4fdf07 100644
--- a/src/main/java/com/epam/ta/reportportal/core/file/GetFileHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/file/GetFileHandler.java
@@ -17,7 +17,6 @@
 
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.entity.attachment.BinaryData;
-
 import java.io.InputStream;
 
 /**
@@ -25,29 +24,34 @@
  */
 public interface GetFileHandler {
 
-	/**
-	 * Returns {@link InputStream} for current logged-in user photo
-	 *
-	 * @param loggedInUser Logged-in {@link ReportPortalUser}
-	 * @return {@link InputStream}
-	 */
-	BinaryData getUserPhoto(ReportPortalUser loggedInUser, boolean loadThumbnail);
+  /**
+   * Returns {@link InputStream} for current logged-in user photo
+   *
+   * @param loggedInUser  Logged-in {@link ReportPortalUser}
+   * @param loadThumbnail true if need to load thumbnail
+   * @return {@link InputStream}
+   */
+  BinaryData getUserPhoto(ReportPortalUser loggedInUser, boolean loadThumbnail);
 
-	/**
-	 * Returns {@link InputStream} for photo of the {@link com.epam.ta.reportportal.entity.user.User} with specified username
-	 *
-	 * @param username     Username of user which photo to get
-	 * @param loggedInUser Logged-in {@link ReportPortalUser}
-	 * @return {@link InputStream}
-	 */
-	BinaryData getUserPhoto(String username, ReportPortalUser loggedInUser, String projectName,
-			boolean loadThumbnail);
+  /**
+   * Returns {@link InputStream} for photo of the {@link com.epam.ta.reportportal.entity.user.User}
+   * with specified username
+   *
+   * @param username       Username of user which photo to get
+   * @param loggedInUser   Logged-in {@link ReportPortalUser}
+   * @param projectName    Project name
+   * @param loadThumbnail  true if need to load thumbnail
+   * @return {@link InputStream}
+   */
+  BinaryData getUserPhoto(String username, ReportPortalUser loggedInUser, String projectName,
+      boolean loadThumbnail);
 
-	/**
-	 * Returns {@link InputStream} for the file with the specified id
-	 *
-	 * @param fileId Id of the file to get
-	 * @return {@link InputStream}
-	 */
-	BinaryData loadFileById(Long fileId, ReportPortalUser.ProjectDetails projectDetails);
+  /**
+   * Returns {@link BinaryData} for the file with the specified id
+   *
+   * @param fileId Id of the file to get
+   * @param projectDetails {@link ReportPortalUser.ProjectDetails}
+   * @return {@link BinaryData} file data
+   */
+  BinaryData loadFileById(Long fileId, ReportPortalUser.ProjectDetails projectDetails);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/file/impl/GetFileHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/file/impl/GetFileHandlerImpl.java
index 9cd1d92d66..3bc74f859e 100644
--- a/src/main/java/com/epam/ta/reportportal/core/file/impl/GetFileHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/file/impl/GetFileHandlerImpl.java
@@ -15,6 +15,9 @@
  */
 package com.epam.ta.reportportal.core.file.impl;
 
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
+
 import com.epam.ta.reportportal.binary.AttachmentBinaryDataService;
 import com.epam.ta.reportportal.binary.UserBinaryDataService;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
@@ -27,59 +30,61 @@
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.util.ProjectExtractor;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.function.Predicate;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.function.Predicate;
-
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class GetFileHandlerImpl implements GetFileHandler {
 
-	private final UserRepository userRepository;
+  private final UserRepository userRepository;
 
-	private final UserBinaryDataService userDataStoreService;
+  private final UserBinaryDataService userDataStoreService;
 
-	private final AttachmentBinaryDataService attachmentBinaryDataService;
+  private final AttachmentBinaryDataService attachmentBinaryDataService;
 
-	private final ProjectExtractor projectExtractor;
+  private final ProjectExtractor projectExtractor;
 
-	@Autowired
-	public GetFileHandlerImpl(UserRepository userRepository, UserBinaryDataService userDataStoreService,
-			AttachmentBinaryDataService attachmentBinaryDataService, ProjectExtractor projectExtractor) {
-		this.userRepository = userRepository;
-		this.userDataStoreService = userDataStoreService;
-		this.attachmentBinaryDataService = attachmentBinaryDataService;
-		this.projectExtractor = projectExtractor;
-	}
+  @Autowired
+  public GetFileHandlerImpl(UserRepository userRepository,
+      UserBinaryDataService userDataStoreService,
+      AttachmentBinaryDataService attachmentBinaryDataService, ProjectExtractor projectExtractor) {
+    this.userRepository = userRepository;
+    this.userDataStoreService = userDataStoreService;
+    this.attachmentBinaryDataService = attachmentBinaryDataService;
+    this.projectExtractor = projectExtractor;
+  }
 
-	@Override
-	public BinaryData getUserPhoto(ReportPortalUser loggedInUser, boolean loadThumbnail) {
-		User user = userRepository.findByLogin(loggedInUser.getUsername())
-				.orElseThrow(() -> new ReportPortalException(ErrorType.USER_NOT_FOUND, loggedInUser.getUsername()));
-		return userDataStoreService.loadUserPhoto(user, loadThumbnail);
-	}
+  @Override
+  public BinaryData getUserPhoto(ReportPortalUser loggedInUser, boolean loadThumbnail) {
+    User user = userRepository.findByLogin(loggedInUser.getUsername())
+        .orElseThrow(
+            () -> new ReportPortalException(ErrorType.USER_NOT_FOUND, loggedInUser.getUsername()));
+    return userDataStoreService.loadUserPhoto(user, loadThumbnail);
+  }
 
-	@Override
-	public BinaryData getUserPhoto(String username, ReportPortalUser loggedInUser, String projectName, boolean loadThumbnail) {
-		User user = userRepository.findByLogin(username).orElseThrow(() -> new ReportPortalException(ErrorType.USER_NOT_FOUND, username));
-		ReportPortalUser.ProjectDetails projectDetails = projectExtractor.extractProjectDetailsAdmin(loggedInUser, projectName);
-		if (loggedInUser.getUserRole() != UserRole.ADMINISTRATOR) {
-			expect(
-					ProjectUtils.isAssignedToProject(user, projectDetails.getProjectId()),
-					Predicate.isEqual(true)
-			).verify(ErrorType.ACCESS_DENIED, formattedSupplier("You are not assigned to project '{}'", projectDetails.getProjectName()));
-		}
-		return userDataStoreService.loadUserPhoto(user, loadThumbnail);
-	}
+  @Override
+  public BinaryData getUserPhoto(String username, ReportPortalUser loggedInUser, String projectName,
+      boolean loadThumbnail) {
+    User user = userRepository.findByLogin(username)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.USER_NOT_FOUND, username));
+    ReportPortalUser.ProjectDetails projectDetails = projectExtractor.extractProjectDetailsAdmin(
+        loggedInUser, projectName);
+    if (loggedInUser.getUserRole() != UserRole.ADMINISTRATOR) {
+      expect(
+          ProjectUtils.isAssignedToProject(user, projectDetails.getProjectId()),
+          Predicate.isEqual(true)
+      ).verify(ErrorType.ACCESS_DENIED, formattedSupplier("You are not assigned to project '{}'",
+          projectDetails.getProjectName()));
+    }
+    return userDataStoreService.loadUserPhoto(user, loadThumbnail);
+  }
 
-	@Override
-	public BinaryData loadFileById(Long fileId, ReportPortalUser.ProjectDetails projectDetails) {
-		return attachmentBinaryDataService.load(fileId, projectDetails);
-	}
+  @Override
+  public BinaryData loadFileById(Long fileId, ReportPortalUser.ProjectDetails projectDetails) {
+    return attachmentBinaryDataService.load(fileId, projectDetails);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/filter/DeleteUserFilterHandler.java b/src/main/java/com/epam/ta/reportportal/core/filter/DeleteUserFilterHandler.java
index 32ee4b9f12..81bbd11ada 100644
--- a/src/main/java/com/epam/ta/reportportal/core/filter/DeleteUserFilterHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/filter/DeleteUserFilterHandler.java
@@ -26,14 +26,15 @@
  */
 public interface DeleteUserFilterHandler {
 
-	/**
-	 * Delete complex filter by id
-	 *
-	 * @param id             Filter id
-	 * @param projectDetails Project details
-	 * @param user           User
-	 * @return {@link OperationCompletionRS}
-	 */
-	OperationCompletionRS deleteFilter(Long id, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user);
+  /**
+   * Delete complex filter by id
+   *
+   * @param id             Filter id
+   * @param projectDetails Project details
+   * @param user           User
+   * @return {@link OperationCompletionRS}
+   */
+  OperationCompletionRS deleteFilter(Long id, ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user);
 
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/filter/SearchCriteriaService.java b/src/main/java/com/epam/ta/reportportal/core/filter/SearchCriteriaService.java
index 3256564739..cfb5c93d17 100644
--- a/src/main/java/com/epam/ta/reportportal/core/filter/SearchCriteriaService.java
+++ b/src/main/java/com/epam/ta/reportportal/core/filter/SearchCriteriaService.java
@@ -18,9 +18,7 @@
 
 import com.epam.ta.reportportal.commons.querygen.Queryable;
 import com.epam.ta.reportportal.core.filter.predefined.PredefinedFilterType;
-import com.epam.ta.reportportal.ws.model.SearchCriteria;
 import com.epam.ta.reportportal.ws.model.SearchCriteriaRQ;
-import java.util.Set;
 
 /**
  * Service for converting SearchCriteria to Filter.
diff --git a/src/main/java/com/epam/ta/reportportal/core/filter/UpdateUserFilterHandler.java b/src/main/java/com/epam/ta/reportportal/core/filter/UpdateUserFilterHandler.java
index 187bcdfaf1..2374c0eb67 100644
--- a/src/main/java/com/epam/ta/reportportal/core/filter/UpdateUserFilterHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/filter/UpdateUserFilterHandler.java
@@ -34,37 +34,37 @@
  */
 public interface UpdateUserFilterHandler {
 
-	/**
-	 * Creates new filter
-	 *
-	 * @param createFilterRQ
-	 * @param projectName
-	 * @param user
-	 * @return EntryCreatedRS
-	 */
-	EntryCreatedRS createFilter(UpdateUserFilterRQ createFilterRQ, String projectName, ReportPortalUser user);
+  /**
+   * Creates new filter for a specific project and user.
+   *
+   * @param createFilterRQ The request containing the filter creation data
+   * @param projectName    The name of the project where the filter will be created
+   * @param user           The {@link ReportPortalUser} who is creating the filter
+   * @return An {@link EntryCreatedRS} instance containing the created filter's ID
+   */
+  EntryCreatedRS createFilter(UpdateUserFilterRQ createFilterRQ, String projectName, ReportPortalUser user);
 
-	/**
-	 * Update user filter with specified id
-	 *
-	 * @param userFilterId   User filter id
-	 * @param updateRQ       Update filter details
-	 * @param projectDetails Project details
-	 * @param user           User
-	 * @return {@link OperationCompletionRS}
-	 */
-	OperationCompletionRS updateUserFilter(Long userFilterId, UpdateUserFilterRQ updateRQ, ReportPortalUser.ProjectDetails projectDetails,
-			ReportPortalUser user);
+  /**
+   * Update user filter with specified id
+   *
+   * @param userFilterId   User filter id
+   * @param updateRQ       Update filter details
+   * @param projectDetails Project details
+   * @param user           User
+   * @return {@link OperationCompletionRS}
+   */
+  OperationCompletionRS updateUserFilter(Long userFilterId, UpdateUserFilterRQ updateRQ, ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user);
 
-	/**
-	 * Update user filter
-	 *
-	 * @param updateRQ
-	 * @param projectDetails
-	 * @param user
-	 * @return List of {@link OperationCompletionRS}
-	 */
-	List<OperationCompletionRS> updateUserFilter(CollectionsRQ<BulkUpdateFilterRQ> updateRQ, ReportPortalUser.ProjectDetails projectDetails,
-			ReportPortalUser user);
+  /**
+   * Update user filter
+   *
+   * @param updateRQ        Request for filter update
+   * @param projectDetails  {@link ReportPortalUser.ProjectDetails}
+   * @param user            {@link ReportPortalUser} filter's owner
+   * @return List of {@link OperationCompletionRS}
+   */
+  List<OperationCompletionRS> updateUserFilter(CollectionsRQ<BulkUpdateFilterRQ> updateRQ, ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user);
 
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/filter/impl/DeleteUserFilterHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/filter/impl/DeleteUserFilterHandlerImpl.java
index 13984cb1d3..bb1a88f3a3 100644
--- a/src/main/java/com/epam/ta/reportportal/core/filter/impl/DeleteUserFilterHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/filter/impl/DeleteUserFilterHandlerImpl.java
@@ -37,13 +37,13 @@
 @Service
 public class DeleteUserFilterHandlerImpl implements DeleteUserFilterHandler {
 
-	private final UserFilterRepository userFilterRepository;
-	private final MessageBus messageBus;
+  private final UserFilterRepository userFilterRepository;
+  private final MessageBus messageBus;
 
 	@Autowired
 	public DeleteUserFilterHandlerImpl(UserFilterRepository userFilterRepository, MessageBus messageBus) {
-		this.userFilterRepository = userFilterRepository;
-		this.messageBus = messageBus;
+    this.userFilterRepository = userFilterRepository;
+    this.messageBus = messageBus;
 	}
 
 	@Override
diff --git a/src/main/java/com/epam/ta/reportportal/core/filter/impl/GetUserFilterHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/filter/impl/GetUserFilterHandlerImpl.java
index a1f80caafb..d106551e61 100644
--- a/src/main/java/com/epam/ta/reportportal/core/filter/impl/GetUserFilterHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/filter/impl/GetUserFilterHandlerImpl.java
@@ -30,6 +30,7 @@
 import com.epam.ta.reportportal.ws.model.OwnedEntityResource;
 import com.epam.ta.reportportal.ws.model.filter.UserFilterResource;
 import com.google.common.collect.Lists;
+import java.util.List;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
@@ -45,18 +46,18 @@
 @Transactional(readOnly = true)
 public class GetUserFilterHandlerImpl implements GetUserFilterHandler {
 
-	private UserFilterRepository filterRepository;
-	private final ProjectExtractor projectExtractor;
+  private UserFilterRepository filterRepository;
+  private final ProjectExtractor projectExtractor;
 
-	@Autowired
-	public GetUserFilterHandlerImpl(ProjectExtractor projectExtractor) {
-		this.projectExtractor = projectExtractor;
-	}
+  @Autowired
+  public GetUserFilterHandlerImpl(ProjectExtractor projectExtractor) {
+    this.projectExtractor = projectExtractor;
+  }
 
-	@Autowired
-	public void setFilterRepository(UserFilterRepository filterRepository) {
-		this.filterRepository = filterRepository;
-	}
+  @Autowired
+  public void setFilterRepository(UserFilterRepository filterRepository) {
+    this.filterRepository = filterRepository;
+  }
 
 	@Override
 	public UserFilterResource getUserFilter(Long id, ReportPortalUser.ProjectDetails projectDetails) {
@@ -68,24 +69,28 @@ public UserFilterResource getUserFilter(Long id, ReportPortalUser.ProjectDetails
 		return UserFilterConverter.TO_FILTER_RESOURCE.apply(userFilter);
 	}
 
-	@Override
-	public Iterable<UserFilterResource> getUserFilters(String projectName, Pageable pageable, Filter filter, ReportPortalUser user) {
-		ReportPortalUser.ProjectDetails projectDetails = projectExtractor.extractProjectDetails(user, projectName);
-		Page<UserFilter> userFilters = filterRepository.findByFilter(ProjectFilter.of(filter, projectDetails.getProjectId()), pageable);
+  @Override
+  public Iterable<UserFilterResource> getUserFilters(String projectName, Pageable pageable, Filter filter,
+      ReportPortalUser user) {
+    ReportPortalUser.ProjectDetails projectDetails = projectExtractor.extractProjectDetails(user,
+        projectName);
+    Page<UserFilter> userFilters = filterRepository.findByFilter(ProjectFilter.of(filter, projectDetails.getProjectId()), pageable);
 		return PagedResourcesAssembler.pageConverter(UserFilterConverter.TO_FILTER_RESOURCE).apply(userFilters);
-	}
+  }
 
-	@Override
-	public Iterable<OwnedEntityResource> getFiltersNames(ReportPortalUser.ProjectDetails projectDetails, Pageable pageable, Filter filter,
+  @Override
+  public Iterable<OwnedEntityResource> getFiltersNames(ReportPortalUser.ProjectDetails projectDetails, Pageable pageable, Filter filter,
 			ReportPortalUser user) {
-		final Page<UserFilter> userFilters = filterRepository.findByFilter(ProjectFilter.of(filter, projectDetails.getProjectId()),
-				pageable
-		);
-		return PagedResourcesAssembler.pageConverter(UserFilterConverter.TO_OWNED_ENTITY_RESOURCE).apply(userFilters);
-	}
+    final Page<UserFilter> userFilters = filterRepository.findByFilter(
+        ProjectFilter.of(filter, projectDetails.getProjectId()),
+        pageable
+    );
+    return PagedResourcesAssembler.pageConverter(UserFilterConverter.TO_OWNED_ENTITY_RESOURCE)
+        .apply(userFilters);
+  }
 
-	@Override
-	public List<UserFilter> getFiltersById(Long[] ids, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user) {
+  @Override
+  public List<UserFilter> getFiltersById(Long[] ids, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user) {
 		return filterRepository.findAllByIdInAndProjectId(Lists.newArrayList(ids), projectDetails.getProjectId());
 	}
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/filter/impl/UpdateUserFilterHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/filter/impl/UpdateUserFilterHandlerImpl.java
index 18600e4fbe..83911724ef 100644
--- a/src/main/java/com/epam/ta/reportportal/core/filter/impl/UpdateUserFilterHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/filter/impl/UpdateUserFilterHandlerImpl.java
@@ -16,6 +16,11 @@
 
 package com.epam.ta.reportportal.core.filter.impl;
 
+import static com.epam.ta.reportportal.commons.Preconditions.NOT_EMPTY_COLLECTION;
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.ws.converter.converters.UserFilterConverter.TO_ACTIVITY_RESOURCE;
+import static com.epam.ta.reportportal.ws.model.ErrorType.USER_FILTER_NOT_FOUND;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.querygen.Condition;
 import com.epam.ta.reportportal.commons.querygen.CriteriaHolder;
@@ -32,7 +37,11 @@
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.util.ProjectExtractor;
 import com.epam.ta.reportportal.ws.converter.builders.UserFilterBuilder;
-import com.epam.ta.reportportal.ws.model.*;
+import com.epam.ta.reportportal.ws.model.CollectionsRQ;
+import com.epam.ta.reportportal.ws.model.EntryCreatedRS;
+import com.epam.ta.reportportal.ws.model.ErrorType;
+import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
+import com.epam.ta.reportportal.ws.model.ValidationConstraints;
 import com.epam.ta.reportportal.ws.model.activity.UserFilterActivityResource;
 import com.epam.ta.reportportal.ws.model.filter.BulkUpdateFilterRQ;
 import com.epam.ta.reportportal.ws.model.filter.UpdateUserFilterRQ;
@@ -43,11 +52,9 @@
 import java.util.List;
 import java.util.Optional;
 import java.util.function.Predicate;
-
-import static com.epam.ta.reportportal.commons.Preconditions.NOT_EMPTY_COLLECTION;
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.ws.converter.converters.UserFilterConverter.TO_ACTIVITY_RESOURCE;
-import static com.epam.ta.reportportal.ws.model.ErrorType.USER_FILTER_NOT_FOUND;
+import org.apache.commons.lang3.BooleanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 @Service
 public class UpdateUserFilterHandlerImpl implements UpdateUserFilterHandler {
@@ -68,11 +75,13 @@ public UpdateUserFilterHandlerImpl(ProjectExtractor projectExtractor, UserFilter
 		this.messageBus = messageBus;
 	}
 
-	@Override
-	public EntryCreatedRS createFilter(UpdateUserFilterRQ createFilterRQ, String projectName, ReportPortalUser user) {
-		ReportPortalUser.ProjectDetails projectDetails = projectExtractor.extractProjectDetails(user, projectName);
+  @Override
+  public EntryCreatedRS createFilter(UpdateUserFilterRQ createFilterRQ, String projectName,
+      ReportPortalUser user) {
+    ReportPortalUser.ProjectDetails projectDetails = projectExtractor.extractProjectDetails(user,
+        projectName);
 
-		validateFilterRq(createFilterRQ);
+    validateFilterRq(createFilterRQ);
 
 		BusinessRule.expect(userFilterRepository.existsByNameAndOwnerAndProjectId(createFilterRQ.getName(),
 						user.getUsername(),
@@ -80,10 +89,10 @@ public EntryCreatedRS createFilter(UpdateUserFilterRQ createFilterRQ, String pro
 				), BooleanUtils::isFalse)
 				.verify(ErrorType.USER_FILTER_ALREADY_EXISTS, createFilterRQ.getName(), user.getUsername(), projectName);
 
-		UserFilter filter = new UserFilterBuilder().addFilterRq(createFilterRQ)
-				.addProject(projectDetails.getProjectId())
-				.addOwner(user.getUsername())
-				.get();
+    UserFilter filter = new UserFilterBuilder().addFilterRq(createFilterRQ)
+        .addProject(projectDetails.getProjectId())
+        .addOwner(user.getUsername())
+        .get();
 
 		userFilterRepository.save(filter);
 		messageBus.publishActivity(new FilterCreatedEvent(TO_ACTIVITY_RESOURCE.apply(filter), user.getUserId(), user.getUsername()));
@@ -105,7 +114,7 @@ public OperationCompletionRS updateUserFilter(Long userFilterId, UpdateUserFilte
 				user.getUserId()
 		);
 
-		if (!userFilter.getName().equals(updateRQ.getName())) {
+    if (!userFilter.getName().equals(updateRQ.getName())) {
 
 			BusinessRule.expect(userFilterRepository.existsByNameAndOwnerAndProjectId(updateRQ.getName(),
 							userFilter.getOwner(),
@@ -118,8 +127,8 @@ public OperationCompletionRS updateUserFilter(Long userFilterId, UpdateUserFilte
 					);
 		}
 
-		UserFilterActivityResource before = TO_ACTIVITY_RESOURCE.apply(userFilter);
-		UserFilter updated = new UserFilterBuilder(userFilter).addFilterRq(updateRQ).get();
+    UserFilterActivityResource before = TO_ACTIVITY_RESOURCE.apply(userFilter);
+    UserFilter updated = new UserFilterBuilder(userFilter).addFilterRq(updateRQ).get();
 
 		messageBus.publishActivity(new FilterUpdatedEvent(before,
 				TO_ACTIVITY_RESOURCE.apply(updated),
@@ -129,34 +138,36 @@ public OperationCompletionRS updateUserFilter(Long userFilterId, UpdateUserFilte
 		return new OperationCompletionRS("User filter with ID = '" + updated.getId() + "' successfully updated.");
 	}
 
-	@Override
-	public List<OperationCompletionRS> updateUserFilter(CollectionsRQ<BulkUpdateFilterRQ> updateRQ,
-			ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user) {
-		throw new UnsupportedOperationException("Not implemented");
-	}
+  @Override
+  public List<OperationCompletionRS> updateUserFilter(CollectionsRQ<BulkUpdateFilterRQ> updateRQ,
+      ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user) {
+    throw new UnsupportedOperationException("Not implemented");
+  }
 
-	/**
+  /**
 	 * Validation of update filter rq
 	 *
 	 * @param updateFilerRq Request
 	 */
 	private void validateFilterRq(UpdateUserFilterRQ updateFilerRq) {
 
-		FilterTarget filterTarget = FilterTarget.findByClass(ObjectType.getObjectTypeByName(updateFilerRq.getObjectType())
-				.getClassObject());
+    FilterTarget filterTarget = FilterTarget.findByClass(
+        ObjectType.getObjectTypeByName(updateFilerRq.getObjectType())
+            .getClassObject());
 
-		BusinessRule.expect(updateFilerRq.getConditions(), NOT_EMPTY_COLLECTION)
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Filter conditions should not be empty");
+    BusinessRule.expect(updateFilerRq.getConditions(), NOT_EMPTY_COLLECTION)
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Filter conditions should not be empty");
 
-		BusinessRule.expect(updateFilerRq.getOrders(), NOT_EMPTY_COLLECTION)
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Sort conditions should not be empty");
+    BusinessRule.expect(updateFilerRq.getOrders(), NOT_EMPTY_COLLECTION)
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Sort conditions should not be empty");
 
-		//filter conditions validation
-		updateFilerRq.getConditions().forEach(it -> {
-			CriteriaHolder criteriaHolder = filterTarget.getCriteriaByFilter(it.getFilteringField())
-					.orElseThrow(() -> new ReportPortalException(ErrorType.INCORRECT_FILTER_PARAMETERS,
-							Suppliers.formattedSupplier("Filter parameter '{}' is not defined", it.getFilteringField()).get()
-					));
+    //filter conditions validation
+    updateFilerRq.getConditions().forEach(it -> {
+      CriteriaHolder criteriaHolder = filterTarget.getCriteriaByFilter(it.getFilteringField())
+          .orElseThrow(() -> new ReportPortalException(ErrorType.INCORRECT_FILTER_PARAMETERS,
+              Suppliers.formattedSupplier("Filter parameter '{}' is not defined",
+                  it.getFilteringField()).get()
+          ));
 
 			Condition condition = Condition.findByMarker(it.getCondition())
 					.orElseThrow(() -> new ReportPortalException(ErrorType.INCORRECT_FILTER_PARAMETERS, it.getCondition()));
@@ -168,13 +179,14 @@ private void validateFilterRq(UpdateUserFilterRQ updateFilerRq) {
 			it.setValue(value);
 		});
 
-		//order conditions validation
-		updateFilerRq.getOrders()
-				.forEach(order -> BusinessRule.expect(filterTarget.getCriteriaByFilter(order.getSortingColumnName()), Optional::isPresent)
-						.verify(ErrorType.INCORRECT_SORTING_PARAMETERS,
-								"Unable to find sort parameter '" + order.getSortingColumnName() + "'"
-						));
-	}
+    //order conditions validation
+    updateFilerRq.getOrders()
+        .forEach(order -> BusinessRule.expect(
+                filterTarget.getCriteriaByFilter(order.getSortingColumnName()), Optional::isPresent)
+            .verify(ErrorType.INCORRECT_SORTING_PARAMETERS,
+                "Unable to find sort parameter '" + order.getSortingColumnName() + "'"
+            ));
+  }
 
 	private String cutAttributesToMaxLength(String keyAndValue) {
 		if (keyAndValue == null || keyAndValue.isEmpty()) {
@@ -215,6 +227,7 @@ private String cutAttributeToLength(String attribute, int length){
 		}
 		return attribute;
 	}
+
 	private String cutStringToLength(String string, int length) {
 		if (string.length() > length) {
 			string = string.substring(0, length);
diff --git a/src/main/java/com/epam/ta/reportportal/core/filter/predefined/PredefinedFilterBuilder.java b/src/main/java/com/epam/ta/reportportal/core/filter/predefined/PredefinedFilterBuilder.java
index fa03d81821..60404bfa17 100644
--- a/src/main/java/com/epam/ta/reportportal/core/filter/predefined/PredefinedFilterBuilder.java
+++ b/src/main/java/com/epam/ta/reportportal/core/filter/predefined/PredefinedFilterBuilder.java
@@ -25,19 +25,19 @@
  */
 public abstract class PredefinedFilterBuilder {
 
-	public Queryable buildFilter(String[] params) {
-		checkParams(params);
-		return build(params);
-	}
+  public Queryable buildFilter(String[] params) {
+    checkParams(params);
+    return build(params);
+  }
 
-	abstract protected Queryable build(String[] params);
+  abstract protected Queryable build(String[] params);
 
-	protected void checkParams(String[] params) {
-		//empty by default
-	}
+  protected void checkParams(String[] params) {
+    //empty by default
+  }
 
-	protected Exception incorrectParamsException(String message) {
-		throw new ReportPortalException(ErrorType.INCORRECT_REQUEST, message);
-	}
+  protected Exception incorrectParamsException(String message) {
+    throw new ReportPortalException(ErrorType.INCORRECT_REQUEST, message);
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/filter/predefined/PredefinedFilterType.java b/src/main/java/com/epam/ta/reportportal/core/filter/predefined/PredefinedFilterType.java
index 64a06823c4..4f8b8898bc 100644
--- a/src/main/java/com/epam/ta/reportportal/core/filter/predefined/PredefinedFilterType.java
+++ b/src/main/java/com/epam/ta/reportportal/core/filter/predefined/PredefinedFilterType.java
@@ -24,22 +24,23 @@
  */
 public enum PredefinedFilterType {
 
-	COLLAPSED("collapsed"),
-	USERS("users"),
-	PROJECTS("projects"),
-	ACTIVITIES("activities");
+  COLLAPSED("collapsed"),
+  USERS("users"),
+  PROJECTS("projects"),
+  ACTIVITIES("activities");
 
-	private String type;
+  private String type;
 
-	PredefinedFilterType(String type) {
-		this.type = type;
-	}
+  PredefinedFilterType(String type) {
+    this.type = type;
+  }
 
-	public static Optional<PredefinedFilterType> fromString(String value) {
-		return Arrays.stream(PredefinedFilterType.values()).filter(it -> it.getType().equalsIgnoreCase(value)).findFirst();
-	}
+  public static Optional<PredefinedFilterType> fromString(String value) {
+    return Arrays.stream(PredefinedFilterType.values())
+        .filter(it -> it.getType().equalsIgnoreCase(value)).findFirst();
+  }
 
-	public String getType() {
-		return type;
-	}
+  public String getType() {
+    return type;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/filter/predefined/PredefinedFilters.java b/src/main/java/com/epam/ta/reportportal/core/filter/predefined/PredefinedFilters.java
index 6dde00bab2..9e5d2467c2 100644
--- a/src/main/java/com/epam/ta/reportportal/core/filter/predefined/PredefinedFilters.java
+++ b/src/main/java/com/epam/ta/reportportal/core/filter/predefined/PredefinedFilters.java
@@ -61,11 +61,6 @@ private PredefinedFilters() {
     //no instance required
   }
 
-  /**
-   * Костыль requested by UI team. Back-end team doesn't really understand what such a strange query
-   * is supposed to be used for.
-   * TODO Incompatible with free structure tree and BDD-like structure
-   */
   public static final Collection<TestItemTypeEnum> HAS_METHOD_OR_CLASS = Arrays.stream(
       TestItemTypeEnum.values()).filter(it -> {
     String name = it.name();
diff --git a/src/main/java/com/epam/ta/reportportal/core/hierarchy/AbstractFinishHierarchyHandler.java b/src/main/java/com/epam/ta/reportportal/core/hierarchy/AbstractFinishHierarchyHandler.java
index 9f24cd56b3..716405f69f 100644
--- a/src/main/java/com/epam/ta/reportportal/core/hierarchy/AbstractFinishHierarchyHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/hierarchy/AbstractFinishHierarchyHandler.java
@@ -16,6 +16,18 @@
 
 package com.epam.ta.reportportal.core.hierarchy;
 
+import static com.epam.ta.reportportal.commons.EntityUtils.TO_LOCAL_DATE_TIME;
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.core.item.impl.status.ToSkippedStatusChangingStrategy.SKIPPED_ISSUE_KEY;
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.FAILED;
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.IN_PROGRESS;
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.PASSED;
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.SKIPPED;
+import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.TO_INVESTIGATE;
+import static com.epam.ta.reportportal.entity.enums.TestItemTypeEnum.SUITE;
+import static com.epam.ta.reportportal.ws.model.ErrorType.INCORRECT_REQUEST;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.item.impl.IssueTypeHandler;
 import com.epam.ta.reportportal.core.item.impl.retry.RetryHandler;
@@ -31,187 +43,194 @@
 import com.epam.ta.reportportal.entity.item.issue.IssueType;
 import com.epam.ta.reportportal.job.PageUtil;
 import com.epam.ta.reportportal.jooq.enums.JStatusEnum;
-import org.apache.commons.lang3.BooleanUtils;
-import org.springframework.data.domain.Pageable;
-
 import java.time.LocalDateTime;
-import java.util.*;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.commons.EntityUtils.TO_LOCAL_DATE_TIME;
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.core.item.impl.status.ToSkippedStatusChangingStrategy.SKIPPED_ISSUE_KEY;
-import static com.epam.ta.reportportal.entity.enums.StatusEnum.*;
-import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.TO_INVESTIGATE;
-import static com.epam.ta.reportportal.entity.enums.TestItemTypeEnum.SUITE;
-import static com.epam.ta.reportportal.ws.model.ErrorType.INCORRECT_REQUEST;
-import static java.util.Optional.ofNullable;
+import org.apache.commons.lang3.BooleanUtils;
+import org.springframework.data.domain.Pageable;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public abstract class AbstractFinishHierarchyHandler<T> implements FinishHierarchyHandler<T> {
 
-	public static final int ITEM_PAGE_SIZE = 50;
-
-	public static final String ATTRIBUTE_KEY_STATUS = "status";
-	public static final String ATTRIBUTE_VALUE_INTERRUPTED = "interrupted";
-
-	protected final LaunchRepository launchRepository;
-	protected final TestItemRepository testItemRepository;
-	protected final ItemAttributeRepository itemAttributeRepository;
-	protected final IssueEntityRepository issueEntityRepository;
-	private final RetryHandler retryHandler;
-	private final IssueTypeHandler issueTypeHandler;
-	private final ChangeStatusHandler changeStatusHandler;
-
-	public AbstractFinishHierarchyHandler(LaunchRepository launchRepository, TestItemRepository testItemRepository,
-			ItemAttributeRepository itemAttributeRepository, IssueEntityRepository issueEntityRepository, RetryHandler retryHandler,
-			IssueTypeHandler issueTypeHandler,
-			ChangeStatusHandler changeStatusHandler) {
-		this.launchRepository = launchRepository;
-		this.testItemRepository = testItemRepository;
-		this.itemAttributeRepository = itemAttributeRepository;
-		this.issueEntityRepository = issueEntityRepository;
-		this.retryHandler = retryHandler;
-		this.issueTypeHandler = issueTypeHandler;
-		this.changeStatusHandler = changeStatusHandler;
-	}
-
-	protected abstract boolean isIssueRequired(StatusEnum status, T entity);
-
-	protected abstract Function<Pageable, List<Long>> getItemIdsFunction(boolean hasChildren, T entity, StatusEnum status);
-
-	protected boolean evaluateSkippedAttributeValue(StatusEnum status, Long launchId) {
-		if (SKIPPED.equals(status)) {
-			return itemAttributeRepository.findByLaunchIdAndKeyAndSystem(launchId, SKIPPED_ISSUE_KEY, true)
-					.map(attribute -> BooleanUtils.toBoolean(attribute.getValue()))
-					.orElse(false);
-		} else {
-			return false;
-		}
-	}
-
-	protected Optional<IssueType> getIssueType(boolean isIssueRequired, Long projectId, String locator) {
-		if (isIssueRequired) {
-			return Optional.of(issueTypeHandler.defineIssueType(projectId, locator));
-		}
-		return Optional.empty();
-	}
-
-	@Override
-	public int finishDescendants(T parentEntity, StatusEnum status, Date endDate, ReportPortalUser user,
-			ReportPortalUser.ProjectDetails projectDetails) {
-
-		expect(status, s -> s != IN_PROGRESS).verify(INCORRECT_REQUEST, "Unable to update current status to - " + IN_PROGRESS);
-
-		LocalDateTime endTime = TO_LOCAL_DATE_TIME.apply(endDate);
-
-		final int withoutChildren = updateDescendantsWithoutChildren(parentEntity, projectDetails.getProjectId(), status, endTime, user);
-		final int withChildren = updateDescendantsWithChildren(parentEntity, endTime);
-		return withoutChildren + withChildren;
-	}
-
-	private int updateDescendantsWithoutChildren(T entity, Long projectId, StatusEnum status, LocalDateTime endTime, ReportPortalUser user) {
-		AtomicInteger updatedCount = new AtomicInteger(0);
-		getIssueType(isIssueRequired(status, entity),
-				projectId,
-				TO_INVESTIGATE.getLocator()
-		).ifPresentOrElse(issueType -> PageUtil.iterateOverContent(ITEM_PAGE_SIZE,
-				getItemIdsFunction(false, entity, IN_PROGRESS),
-				itemIdsWithoutChildrenHandler(issueType, status, endTime, projectId, user, updatedCount)
-				),
-				() -> PageUtil.iterateOverContent(ITEM_PAGE_SIZE,
-						getItemIdsFunction(false, entity, IN_PROGRESS),
-						itemIdsWithoutChildrenHandler(status, endTime, projectId, user, updatedCount)
-				)
-		);
-		return updatedCount.get();
-	}
-
-	private Consumer<List<Long>> itemIdsWithoutChildrenHandler(IssueType issueType, StatusEnum status, LocalDateTime endTime,
-			Long projectId, ReportPortalUser user, AtomicInteger updatedCount) {
-		return itemIds -> {
-			Map<Long, TestItem> itemMapping = getItemMapping(itemIds);
-			itemIds.forEach(itemId -> ofNullable(itemMapping.get(itemId)).ifPresent(testItem -> {
-				finishItem(testItem, status, endTime);
-				attachIssue(testItem, issueType);
-				changeStatusHandler.changeParentStatus(testItem, projectId, user);
-			}));
-			updatedCount.addAndGet(itemIds.size());
-		};
-	}
-
-	private Consumer<List<Long>> itemIdsWithoutChildrenHandler(StatusEnum status, LocalDateTime endTime, Long projectId,
-			ReportPortalUser user, AtomicInteger updatedCount) {
-		return itemIds -> {
-			Map<Long, TestItem> itemMapping = getItemMapping(itemIds);
-			itemIds.forEach(itemId -> ofNullable(itemMapping.get(itemId)).ifPresent(testItem -> {
-				finishItem(testItem, status, endTime);
-				changeStatusHandler.changeParentStatus(testItem, projectId, user);
-			}));
-			updatedCount.addAndGet(itemIds.size());
-		};
-	}
-
-	/**
-	 * Attach default issue to the item only if it wasn't already created
-	 *
-	 * @param testItem  {@link TestItem}
-	 * @param issueType {@link IssueType}
-	 */
-	private void attachIssue(TestItem testItem, IssueType issueType) {
-		if (!SUITE.sameLevel(testItem.getType()) && testItem.isHasStats()) {
-			issueEntityRepository.findById(testItem.getItemId()).ifPresentOrElse(issue -> {
-			}, () -> {
-				IssueEntity issueEntity = new IssueEntity();
-				issueEntity.setIssueType(issueType);
-				issueEntity.setTestItemResults(testItem.getItemResults());
-				issueEntityRepository.save(issueEntity);
-				testItem.getItemResults().setIssue(issueEntity);
-			});
-		}
-	}
-
-	private int updateDescendantsWithChildren(T entity, LocalDateTime endTime) {
-		AtomicInteger updatedCount = new AtomicInteger(0);
-		PageUtil.iterateOverContent(ITEM_PAGE_SIZE,
-				getItemIdsFunction(true, entity, IN_PROGRESS),
-				itemIdsWithChildrenHandler(endTime, updatedCount)
-		);
-		return updatedCount.get();
-	}
-
-	private Consumer<List<Long>> itemIdsWithChildrenHandler(LocalDateTime endTime, AtomicInteger updatedCount) {
-		return itemIds -> {
-			Map<Long, TestItem> itemMapping = getItemMapping(itemIds);
-			itemIds.forEach(itemId -> ofNullable(itemMapping.get(itemId)).ifPresent(testItem -> {
-				boolean isFailed = testItemRepository.hasDescendantsNotInStatus(testItem.getItemId(),
-						StatusEnum.PASSED.name(),
-						StatusEnum.INFO.name(),
-						StatusEnum.WARN.name()
-				);
-				finishItem(testItem, isFailed ? FAILED : PASSED, endTime);
-			}));
-			updatedCount.addAndGet(itemIds.size());
-		};
-	}
-
-	private Map<Long, TestItem> getItemMapping(List<Long> itemIds) {
-		return testItemRepository.findAllById(itemIds).stream().collect(Collectors.toMap(TestItem::getItemId, i -> i));
-	}
-
-	private void finishItem(TestItem testItem, StatusEnum status, LocalDateTime endTime) {
-		testItem.getItemResults().setStatus(status);
-		testItem.getItemResults().setEndTime(endTime);
-		ItemAttribute interruptedAttribute = new ItemAttribute(ATTRIBUTE_KEY_STATUS, ATTRIBUTE_VALUE_INTERRUPTED, false);
-		interruptedAttribute.setTestItem(testItem);
-		testItem.getAttributes().add(interruptedAttribute);
-		if (testItem.isHasRetries()) {
-			retryHandler.finishRetries(testItem.getItemId(), JStatusEnum.valueOf(status.name()), endTime);
-		}
-	}
+  public static final int ITEM_PAGE_SIZE = 50;
+
+  public static final String ATTRIBUTE_KEY_STATUS = "status";
+  public static final String ATTRIBUTE_VALUE_INTERRUPTED = "interrupted";
+
+  protected final LaunchRepository launchRepository;
+  protected final TestItemRepository testItemRepository;
+  protected final ItemAttributeRepository itemAttributeRepository;
+  protected final IssueEntityRepository issueEntityRepository;
+  private final RetryHandler retryHandler;
+  private final IssueTypeHandler issueTypeHandler;
+  private final ChangeStatusHandler changeStatusHandler;
+
+  public AbstractFinishHierarchyHandler(LaunchRepository launchRepository,
+      TestItemRepository testItemRepository,
+      ItemAttributeRepository itemAttributeRepository, IssueEntityRepository issueEntityRepository,
+      RetryHandler retryHandler,
+      IssueTypeHandler issueTypeHandler,
+      ChangeStatusHandler changeStatusHandler) {
+    this.launchRepository = launchRepository;
+    this.testItemRepository = testItemRepository;
+    this.itemAttributeRepository = itemAttributeRepository;
+    this.issueEntityRepository = issueEntityRepository;
+    this.retryHandler = retryHandler;
+    this.issueTypeHandler = issueTypeHandler;
+    this.changeStatusHandler = changeStatusHandler;
+  }
+
+  protected abstract boolean isIssueRequired(StatusEnum status, T entity);
+
+  protected abstract Function<Pageable, List<Long>> getItemIdsFunction(boolean hasChildren,
+      T entity, StatusEnum status);
+
+  protected boolean evaluateSkippedAttributeValue(StatusEnum status, Long launchId) {
+    if (SKIPPED.equals(status)) {
+      return itemAttributeRepository.findByLaunchIdAndKeyAndSystem(launchId, SKIPPED_ISSUE_KEY,
+              true)
+          .map(attribute -> BooleanUtils.toBoolean(attribute.getValue()))
+          .orElse(false);
+    } else {
+      return false;
+    }
+  }
+
+  protected Optional<IssueType> getIssueType(boolean isIssueRequired, Long projectId,
+      String locator) {
+    if (isIssueRequired) {
+      return Optional.of(issueTypeHandler.defineIssueType(projectId, locator));
+    }
+    return Optional.empty();
+  }
+
+  @Override
+  public int finishDescendants(T parentEntity, StatusEnum status, Date endDate,
+      ReportPortalUser user,
+      ReportPortalUser.ProjectDetails projectDetails) {
+
+    expect(status, s -> s != IN_PROGRESS).verify(INCORRECT_REQUEST,
+        "Unable to update current status to - " + IN_PROGRESS);
+
+    LocalDateTime endTime = TO_LOCAL_DATE_TIME.apply(endDate);
+
+    final int withoutChildren = updateDescendantsWithoutChildren(parentEntity,
+        projectDetails.getProjectId(), status, endTime, user);
+    final int withChildren = updateDescendantsWithChildren(parentEntity, endTime);
+    return withoutChildren + withChildren;
+  }
+
+  private int updateDescendantsWithoutChildren(T entity, Long projectId, StatusEnum status,
+      LocalDateTime endTime, ReportPortalUser user) {
+    AtomicInteger updatedCount = new AtomicInteger(0);
+    getIssueType(isIssueRequired(status, entity),
+        projectId,
+        TO_INVESTIGATE.getLocator()
+    ).ifPresentOrElse(issueType -> PageUtil.iterateOverContent(ITEM_PAGE_SIZE,
+            getItemIdsFunction(false, entity, IN_PROGRESS),
+            itemIdsWithoutChildrenHandler(issueType, status, endTime, projectId, user, updatedCount)
+        ),
+        () -> PageUtil.iterateOverContent(ITEM_PAGE_SIZE,
+            getItemIdsFunction(false, entity, IN_PROGRESS),
+            itemIdsWithoutChildrenHandler(status, endTime, projectId, user, updatedCount)
+        )
+    );
+    return updatedCount.get();
+  }
+
+  private Consumer<List<Long>> itemIdsWithoutChildrenHandler(IssueType issueType, StatusEnum status,
+      LocalDateTime endTime,
+      Long projectId, ReportPortalUser user, AtomicInteger updatedCount) {
+    return itemIds -> {
+      Map<Long, TestItem> itemMapping = getItemMapping(itemIds);
+      itemIds.forEach(itemId -> ofNullable(itemMapping.get(itemId)).ifPresent(testItem -> {
+        finishItem(testItem, status, endTime);
+        attachIssue(testItem, issueType);
+        changeStatusHandler.changeParentStatus(testItem, projectId, user);
+      }));
+      updatedCount.addAndGet(itemIds.size());
+    };
+  }
+
+  private Consumer<List<Long>> itemIdsWithoutChildrenHandler(StatusEnum status,
+      LocalDateTime endTime, Long projectId,
+      ReportPortalUser user, AtomicInteger updatedCount) {
+    return itemIds -> {
+      Map<Long, TestItem> itemMapping = getItemMapping(itemIds);
+      itemIds.forEach(itemId -> ofNullable(itemMapping.get(itemId)).ifPresent(testItem -> {
+        finishItem(testItem, status, endTime);
+        changeStatusHandler.changeParentStatus(testItem, projectId, user);
+      }));
+      updatedCount.addAndGet(itemIds.size());
+    };
+  }
+
+  /**
+   * Attach default issue to the item only if it wasn't already created
+   *
+   * @param testItem  {@link TestItem}
+   * @param issueType {@link IssueType}
+   */
+  private void attachIssue(TestItem testItem, IssueType issueType) {
+    if (!SUITE.sameLevel(testItem.getType()) && testItem.isHasStats()) {
+      issueEntityRepository.findById(testItem.getItemId()).ifPresentOrElse(issue -> {
+      }, () -> {
+        IssueEntity issueEntity = new IssueEntity();
+        issueEntity.setIssueType(issueType);
+        issueEntity.setTestItemResults(testItem.getItemResults());
+        issueEntityRepository.save(issueEntity);
+        testItem.getItemResults().setIssue(issueEntity);
+      });
+    }
+  }
+
+  private int updateDescendantsWithChildren(T entity, LocalDateTime endTime) {
+    AtomicInteger updatedCount = new AtomicInteger(0);
+    PageUtil.iterateOverContent(ITEM_PAGE_SIZE,
+        getItemIdsFunction(true, entity, IN_PROGRESS),
+        itemIdsWithChildrenHandler(endTime, updatedCount)
+    );
+    return updatedCount.get();
+  }
+
+  private Consumer<List<Long>> itemIdsWithChildrenHandler(LocalDateTime endTime,
+      AtomicInteger updatedCount) {
+    return itemIds -> {
+      Map<Long, TestItem> itemMapping = getItemMapping(itemIds);
+      itemIds.forEach(itemId -> ofNullable(itemMapping.get(itemId)).ifPresent(testItem -> {
+        boolean isFailed = testItemRepository.hasDescendantsNotInStatus(testItem.getItemId(),
+            StatusEnum.PASSED.name(),
+            StatusEnum.INFO.name(),
+            StatusEnum.WARN.name()
+        );
+        finishItem(testItem, isFailed ? FAILED : PASSED, endTime);
+      }));
+      updatedCount.addAndGet(itemIds.size());
+    };
+  }
+
+  private Map<Long, TestItem> getItemMapping(List<Long> itemIds) {
+    return testItemRepository.findAllById(itemIds).stream()
+        .collect(Collectors.toMap(TestItem::getItemId, i -> i));
+  }
+
+  private void finishItem(TestItem testItem, StatusEnum status, LocalDateTime endTime) {
+    testItem.getItemResults().setStatus(status);
+    testItem.getItemResults().setEndTime(endTime);
+    ItemAttribute interruptedAttribute = new ItemAttribute(ATTRIBUTE_KEY_STATUS,
+        ATTRIBUTE_VALUE_INTERRUPTED, false);
+    interruptedAttribute.setTestItem(testItem);
+    testItem.getAttributes().add(interruptedAttribute);
+    if (testItem.isHasRetries()) {
+      retryHandler.finishRetries(testItem.getItemId(), JStatusEnum.valueOf(status.name()), endTime);
+    }
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/hierarchy/FinishHierarchyHandler.java b/src/main/java/com/epam/ta/reportportal/core/hierarchy/FinishHierarchyHandler.java
index 2ebd4d159a..d6daf274bf 100644
--- a/src/main/java/com/epam/ta/reportportal/core/hierarchy/FinishHierarchyHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/hierarchy/FinishHierarchyHandler.java
@@ -18,7 +18,6 @@
 
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.entity.enums.StatusEnum;
-
 import java.util.Date;
 
 /**
@@ -26,14 +25,14 @@
  */
 public interface FinishHierarchyHandler<T> {
 
-	/**
-	 * @param parentEntity   Parent entity which descendants should be finished
-	 * @param status         {@link StatusEnum} that should be assigned to descendants
-	 * @param endDate        {@link java.time.LocalDateTime} finish date for descendants
-	 * @param user           {@link ReportPortalUser}
-	 * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
-	 * @return finished descendants count
-	 */
-	int finishDescendants(T parentEntity, StatusEnum status, Date endDate, ReportPortalUser user,
-			ReportPortalUser.ProjectDetails projectDetails);
+  /**
+   * @param parentEntity   Parent entity which descendants should be finished
+   * @param status         {@link StatusEnum} that should be assigned to descendants
+   * @param endDate        {@link java.time.LocalDateTime} finish date for descendants
+   * @param user           {@link ReportPortalUser}
+   * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
+   * @return finished descendants count
+   */
+  int finishDescendants(T parentEntity, StatusEnum status, Date endDate, ReportPortalUser user,
+      ReportPortalUser.ProjectDetails projectDetails);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/hierarchy/impl/FinishLaunchHierarchyHandler.java b/src/main/java/com/epam/ta/reportportal/core/hierarchy/impl/FinishLaunchHierarchyHandler.java
index 64c1fa71d0..0a99f4731a 100644
--- a/src/main/java/com/epam/ta/reportportal/core/hierarchy/impl/FinishLaunchHierarchyHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/hierarchy/impl/FinishLaunchHierarchyHandler.java
@@ -16,6 +16,8 @@
 
 package com.epam.ta.reportportal.core.hierarchy.impl;
 
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.FAILED;
+
 import com.epam.ta.reportportal.core.hierarchy.AbstractFinishHierarchyHandler;
 import com.epam.ta.reportportal.core.item.impl.IssueTypeHandler;
 import com.epam.ta.reportportal.core.item.impl.retry.RetryHandler;
@@ -26,53 +28,54 @@
 import com.epam.ta.reportportal.dao.TestItemRepository;
 import com.epam.ta.reportportal.entity.enums.StatusEnum;
 import com.epam.ta.reportportal.entity.launch.Launch;
+import java.util.List;
+import java.util.function.Function;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.function.Function;
-
-import static com.epam.ta.reportportal.entity.enums.StatusEnum.FAILED;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service("finishLaunchHierarchyHandler")
 public class FinishLaunchHierarchyHandler extends AbstractFinishHierarchyHandler<Launch> {
 
-	@Autowired
-	public FinishLaunchHierarchyHandler(LaunchRepository launchRepository, TestItemRepository testItemRepository,
-			ItemAttributeRepository itemAttributeRepository, RetryHandler retryHandler, IssueTypeHandler issueTypeHandler,
-			IssueEntityRepository issueEntityRepository, ChangeStatusHandler changeStatusHandler) {
-		super(launchRepository,
-				testItemRepository,
-				itemAttributeRepository,
-				issueEntityRepository,
-				retryHandler,
-				issueTypeHandler,
-				changeStatusHandler
-		);
-	}
+  @Autowired
+  public FinishLaunchHierarchyHandler(LaunchRepository launchRepository,
+      TestItemRepository testItemRepository,
+      ItemAttributeRepository itemAttributeRepository, RetryHandler retryHandler,
+      IssueTypeHandler issueTypeHandler,
+      IssueEntityRepository issueEntityRepository, ChangeStatusHandler changeStatusHandler) {
+    super(launchRepository,
+        testItemRepository,
+        itemAttributeRepository,
+        issueEntityRepository,
+        retryHandler,
+        issueTypeHandler,
+        changeStatusHandler
+    );
+  }
 
-	@Override
-	protected boolean isIssueRequired(StatusEnum status, Launch launch) {
-		return FAILED.equals(status) || evaluateSkippedAttributeValue(status, launch.getId());
-	}
+  @Override
+  protected boolean isIssueRequired(StatusEnum status, Launch launch) {
+    return FAILED.equals(status) || evaluateSkippedAttributeValue(status, launch.getId());
+  }
 
-	@Override
-	protected Function<Pageable, List<Long>> getItemIdsFunction(boolean hasChildren, Launch launch, StatusEnum status) {
-		return hasChildren ?
-				pageable -> testItemRepository.findIdsByHasChildrenAndLaunchIdAndStatusOrderedByPathLevel(launch.getId(),
-						status,
-						pageable.getPageSize(),
-						pageable.getOffset()
-				) :
-				pageable -> testItemRepository.findIdsByNotHasChildrenAndLaunchIdAndStatus(launch.getId(),
-						status,
-						pageable.getPageSize(),
-						pageable.getOffset()
-				);
-	}
+  @Override
+  protected Function<Pageable, List<Long>> getItemIdsFunction(boolean hasChildren, Launch launch,
+      StatusEnum status) {
+    return hasChildren ?
+        pageable -> testItemRepository.findIdsByHasChildrenAndLaunchIdAndStatusOrderedByPathLevel(
+            launch.getId(),
+            status,
+            pageable.getPageSize(),
+            pageable.getOffset()
+        ) :
+        pageable -> testItemRepository.findIdsByNotHasChildrenAndLaunchIdAndStatus(launch.getId(),
+            status,
+            pageable.getPageSize(),
+            pageable.getOffset()
+        );
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/hierarchy/impl/FinishTestItemHierarchyHandler.java b/src/main/java/com/epam/ta/reportportal/core/hierarchy/impl/FinishTestItemHierarchyHandler.java
index d244dbb3bf..2f83ccea88 100644
--- a/src/main/java/com/epam/ta/reportportal/core/hierarchy/impl/FinishTestItemHierarchyHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/hierarchy/impl/FinishTestItemHierarchyHandler.java
@@ -16,6 +16,9 @@
 
 package com.epam.ta.reportportal.core.hierarchy.impl;
 
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.FAILED;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.core.hierarchy.AbstractFinishHierarchyHandler;
 import com.epam.ta.reportportal.core.item.impl.IssueTypeHandler;
 import com.epam.ta.reportportal.core.item.impl.retry.RetryHandler;
@@ -26,14 +29,10 @@
 import com.epam.ta.reportportal.dao.TestItemRepository;
 import com.epam.ta.reportportal.entity.enums.StatusEnum;
 import com.epam.ta.reportportal.entity.item.TestItem;
-import org.springframework.data.domain.Pageable;
-import org.springframework.stereotype.Service;
-
 import java.util.List;
 import java.util.function.Function;
-
-import static com.epam.ta.reportportal.entity.enums.StatusEnum.FAILED;
-import static java.util.Optional.ofNullable;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -41,38 +40,44 @@
 @Service("finishTestItemHierarchyHandler")
 public class FinishTestItemHierarchyHandler extends AbstractFinishHierarchyHandler<TestItem> {
 
-	public FinishTestItemHierarchyHandler(LaunchRepository launchRepository, TestItemRepository testItemRepository,
-			ItemAttributeRepository itemAttributeRepository, IssueEntityRepository issueEntityRepository, RetryHandler retryHandler,
-			IssueTypeHandler issueTypeHandler, ChangeStatusHandler changeStatusHandler) {
-		super(launchRepository,
-				testItemRepository,
-				itemAttributeRepository,
-				issueEntityRepository,
-				retryHandler,
-				issueTypeHandler,
-				changeStatusHandler
-		);
-	}
+  public FinishTestItemHierarchyHandler(LaunchRepository launchRepository,
+      TestItemRepository testItemRepository,
+      ItemAttributeRepository itemAttributeRepository, IssueEntityRepository issueEntityRepository,
+      RetryHandler retryHandler,
+      IssueTypeHandler issueTypeHandler, ChangeStatusHandler changeStatusHandler) {
+    super(launchRepository,
+        testItemRepository,
+        itemAttributeRepository,
+        issueEntityRepository,
+        retryHandler,
+        issueTypeHandler,
+        changeStatusHandler
+    );
+  }
 
-	@Override
-	protected boolean isIssueRequired(StatusEnum status, TestItem testItem) {
-		return FAILED.equals(status) || ofNullable(testItem.getLaunchId()).map(launchId -> evaluateSkippedAttributeValue(status, launchId))
-				.orElse(false);
-	}
+  @Override
+  protected boolean isIssueRequired(StatusEnum status, TestItem testItem) {
+    return FAILED.equals(status) || ofNullable(testItem.getLaunchId()).map(
+            launchId -> evaluateSkippedAttributeValue(status, launchId))
+        .orElse(false);
+  }
 
-	@Override
-	protected Function<Pageable, List<Long>> getItemIdsFunction(boolean hasChildren, TestItem testItem, StatusEnum status) {
-		return hasChildren ?
-				pageable -> testItemRepository.findIdsByHasChildrenAndParentPathAndStatusOrderedByPathLevel(testItem.getPath(),
-						StatusEnum.IN_PROGRESS,
-						pageable.getPageSize(),
-						pageable.getOffset()
-				) :
-				pageable -> testItemRepository.findIdsByNotHasChildrenAndParentPathAndStatus(testItem.getPath(),
-						status,
-						pageable.getPageSize(),
-						pageable.getOffset()
-				);
-	}
+  @Override
+  protected Function<Pageable, List<Long>> getItemIdsFunction(boolean hasChildren,
+      TestItem testItem, StatusEnum status) {
+    return hasChildren ?
+        pageable -> testItemRepository.findIdsByHasChildrenAndParentPathAndStatusOrderedByPathLevel(
+            testItem.getPath(),
+            StatusEnum.IN_PROGRESS,
+            pageable.getPageSize(),
+            pageable.getOffset()
+        ) :
+        pageable -> testItemRepository.findIdsByNotHasChildrenAndParentPathAndStatus(
+            testItem.getPath(),
+            status,
+            pageable.getPageSize(),
+            pageable.getOffset()
+        );
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/imprt/FileExtensionConstant.java b/src/main/java/com/epam/ta/reportportal/core/imprt/FileExtensionConstant.java
index 91bef321a6..0f8bd22f78 100644
--- a/src/main/java/com/epam/ta/reportportal/core/imprt/FileExtensionConstant.java
+++ b/src/main/java/com/epam/ta/reportportal/core/imprt/FileExtensionConstant.java
@@ -20,7 +20,7 @@
  */
 public class FileExtensionConstant {
 
-	//TODO return '.zip' and '.xml' 
-	public static final String ZIP_EXTENSION = "zip";
-	public static final String XML_EXTENSION = "xml";
+  //TODO return '.zip' and '.xml'
+  public static final String ZIP_EXTENSION = "zip";
+  public static final String XML_EXTENSION = "xml";
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/imprt/ImportLaunchHandler.java b/src/main/java/com/epam/ta/reportportal/core/imprt/ImportLaunchHandler.java
index 21b969be47..9ff51786e5 100644
--- a/src/main/java/com/epam/ta/reportportal/core/imprt/ImportLaunchHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/imprt/ImportLaunchHandler.java
@@ -17,7 +17,7 @@
 
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
-import java.util.Map;
+import com.epam.ta.reportportal.ws.model.launch.LaunchImportRQ;
 import org.springframework.web.multipart.MultipartFile;
 
 /**
@@ -32,9 +32,11 @@ public interface ImportLaunchHandler {
    * @param user           user
    * @param format         report format
    * @param file           file with report
+   * @param baseUrl        Application base url
+   * @param rq             Launch import request
    * @return OperationCompletionRS
    */
   OperationCompletionRS importLaunch(ReportPortalUser.ProjectDetails projectDetails,
       ReportPortalUser user, String format, MultipartFile file, String baseUrl,
-      Map<String, String> params);
+      LaunchImportRQ rq);
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/imprt/ImportLaunchHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/imprt/ImportLaunchHandlerImpl.java
index 5c9cfdb579..e92d83e3fd 100644
--- a/src/main/java/com/epam/ta/reportportal/core/imprt/ImportLaunchHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/imprt/ImportLaunchHandlerImpl.java
@@ -13,82 +13,121 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package com.epam.ta.reportportal.core.imprt;
 
+import static com.epam.ta.reportportal.commons.Predicates.notNull;
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.core.imprt.FileExtensionConstant.XML_EXTENSION;
+import static com.epam.ta.reportportal.core.imprt.FileExtensionConstant.ZIP_EXTENSION;
+import static com.epam.ta.reportportal.ws.model.ErrorType.INCORRECT_REQUEST;
+import static org.apache.commons.io.FileUtils.ONE_MB;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.events.MessageBus;
 import com.epam.ta.reportportal.core.events.activity.ImportFinishedEvent;
 import com.epam.ta.reportportal.core.imprt.impl.ImportStrategy;
 import com.epam.ta.reportportal.core.imprt.impl.ImportStrategyFactory;
 import com.epam.ta.reportportal.core.imprt.impl.ImportType;
+import com.epam.ta.reportportal.dao.LaunchRepository;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import com.epam.ta.reportportal.ws.model.LaunchImportCompletionRS;
+import com.epam.ta.reportportal.ws.model.LaunchImportData;
 import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
-import java.util.Map;
+import com.epam.ta.reportportal.ws.model.launch.LaunchImportRQ;
+import java.io.File;
+import java.io.IOException;
+import java.util.Optional;
 import org.apache.commons.io.FilenameUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
 
-import java.io.File;
-import java.io.IOException;
-
-import static com.epam.ta.reportportal.commons.Predicates.notNull;
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.core.imprt.FileExtensionConstant.XML_EXTENSION;
-import static com.epam.ta.reportportal.core.imprt.FileExtensionConstant.ZIP_EXTENSION;
-import static com.epam.ta.reportportal.ws.model.ErrorType.INCORRECT_REQUEST;
-
 @Service
 public class ImportLaunchHandlerImpl implements ImportLaunchHandler {
-	private static final int MAX_FILE_SIZE = 32 * 1024 * 1024;
 
-	private ImportStrategyFactory importStrategyFactory;
-	private MessageBus messageBus;
+  private static final long MAX_FILE_SIZE = 32 * ONE_MB;
+
+  private final ImportStrategyFactory importStrategyFactory;
+  private final MessageBus messageBus;
+  private final LaunchRepository launchRepository;
+
 
-	@Autowired
-	public ImportLaunchHandlerImpl(ImportStrategyFactory importStrategyFactory, MessageBus messageBus) {
-		this.importStrategyFactory = importStrategyFactory;
-		this.messageBus = messageBus;
-	}
+  @Autowired
+  public ImportLaunchHandlerImpl(ImportStrategyFactory importStrategyFactory, MessageBus messageBus,
+      LaunchRepository launchRepository) {
+    this.importStrategyFactory = importStrategyFactory;
+    this.messageBus = messageBus;
+    this.launchRepository = launchRepository;
+  }
 
-	@Override
+  @Override
   public OperationCompletionRS importLaunch(ReportPortalUser.ProjectDetails projectDetails,
       ReportPortalUser user, String format,
-      MultipartFile file, String baseUrl, Map<String, String> params) {
-
-		validate(file);
-
-		ImportType type = ImportType.fromValue(format)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR, "Unknown import type - " + format));
-
-		File tempFile = transferToTempFile(file);
-		ImportStrategy strategy = importStrategyFactory.getImportStrategy(type, file.getOriginalFilename());
-    String launchId = strategy.importLaunch(projectDetails, user, tempFile, baseUrl, params);
-		messageBus.publishActivity(new ImportFinishedEvent(user.getUserId(),
-				user.getUsername(),
-				projectDetails.getProjectId(),
-				file.getOriginalFilename()
-		));
-		return new OperationCompletionRS("Launch with id = " + launchId + " is successfully imported.");
-	}
-
-	private void validate(MultipartFile file) {
-		expect(file.getOriginalFilename(), notNull()).verify(ErrorType.INCORRECT_REQUEST, "File name should be not empty.");
-
-		expect(file.getOriginalFilename(), it -> it.endsWith(ZIP_EXTENSION) || it.endsWith(XML_EXTENSION)).verify(INCORRECT_REQUEST,
-				"Should be a zip archive or an xml file " + file.getOriginalFilename()
-		);
-		expect(file.getSize(), size -> size <= MAX_FILE_SIZE).verify(INCORRECT_REQUEST, "File size is more than 32 Mb.");
-	}
-
-	private File transferToTempFile(MultipartFile file) {
-		try {
-			File tmp = File.createTempFile(file.getOriginalFilename(), "." + FilenameUtils.getExtension(file.getOriginalFilename()));
-			file.transferTo(tmp);
-			return tmp;
-		} catch (IOException e) {
-			throw new ReportPortalException("Error during transferring multipart file.", e);
-		}
-	}
+      MultipartFile file, String baseUrl, LaunchImportRQ rq) {
+
+    validate(file);
+    rq = getBackCompatibleRq(rq);
+
+    ImportType type = ImportType.fromValue(format)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR,
+            "Unknown import type - " + format));
+
+    File tempFile = transferToTempFile(file);
+    ImportStrategy strategy = importStrategyFactory.getImportStrategy(type,
+        file.getOriginalFilename());
+    String launchId = strategy.importLaunch(projectDetails, user, tempFile, baseUrl, rq);
+    messageBus.publishActivity(new ImportFinishedEvent(user.getUserId(),
+        user.getUsername(),
+        projectDetails.getProjectId(),
+        file.getOriginalFilename()
+    ));
+    return prepareLaunchImportResponse(launchId);
+  }
+
+  //back compatibility with ui
+  private LaunchImportRQ getBackCompatibleRq(LaunchImportRQ rq) {
+    return Optional.ofNullable(rq).orElse(new LaunchImportRQ());
+  }
+
+  private void validate(MultipartFile file) {
+    expect(file.getOriginalFilename(), notNull()).verify(ErrorType.INCORRECT_REQUEST,
+        "File name should be not empty.");
+
+    expect(file.getOriginalFilename(),
+        it -> it.endsWith(ZIP_EXTENSION) || it.endsWith(XML_EXTENSION)).verify(INCORRECT_REQUEST,
+        "Should be a zip archive or an xml file " + file.getOriginalFilename()
+    );
+    expect(file.getSize(), size -> size <= MAX_FILE_SIZE).verify(INCORRECT_REQUEST,
+        "File size is more than 32 Mb.");
+  }
+
+  private File transferToTempFile(MultipartFile file) {
+    try {
+      File tmp = File.createTempFile(file.getOriginalFilename(),
+          "." + FilenameUtils.getExtension(file.getOriginalFilename()));
+      file.transferTo(tmp);
+      return tmp;
+    } catch (IOException e) {
+      throw new ReportPortalException("Error during transferring multipart file.", e);
+    }
+  }
+
+  private OperationCompletionRS prepareLaunchImportResponse(String launchId) {
+
+    var launch = launchRepository.findByUuid(launchId)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND));
+
+    var data = new LaunchImportData();
+    data.setId(launchId);
+    data.setName(launch.getName());
+    data.setNumber(launch.getNumber());
+
+    var response = new LaunchImportCompletionRS();
+    response.setResultMessage("Launch with id = " + launchId + " is successfully imported.");
+    response.setData(data);
+
+    return response;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/imprt/impl/AbstractImportStrategy.java b/src/main/java/com/epam/ta/reportportal/core/imprt/impl/AbstractImportStrategy.java
index 2f1ebba0aa..9cc95fde08 100644
--- a/src/main/java/com/epam/ta/reportportal/core/imprt/impl/AbstractImportStrategy.java
+++ b/src/main/java/com/epam/ta/reportportal/core/imprt/impl/AbstractImportStrategy.java
@@ -15,7 +15,7 @@
  */
 package com.epam.ta.reportportal.core.imprt.impl;
 
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static java.util.Optional.ofNullable;
 
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.launch.FinishLaunchHandler;
@@ -27,23 +27,22 @@
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.epam.ta.reportportal.ws.model.FinishExecutionRQ;
 import com.epam.ta.reportportal.ws.model.attribute.ItemAttributesRQ;
+import com.epam.ta.reportportal.ws.model.launch.LaunchImportRQ;
 import com.epam.ta.reportportal.ws.model.launch.Mode;
 import com.epam.ta.reportportal.ws.model.launch.StartLaunchRQ;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.function.Predicate;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
+import com.google.common.collect.Sets;
 import java.time.LocalDateTime;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Date;
+import java.util.Set;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -51,30 +50,10 @@
 @Component
 public abstract class AbstractImportStrategy implements ImportStrategy {
 
-  public static final String LAUNCH_NAME = "launchName";
-  public static final String LAUNCH_DESCRIPTION = "description";
-  public static final String ATTRIBUTE_KEY = "attributeKey";
-  public static final String ATTRIBUTE_VALUE = "attributeValue";
   public static final String SKIPPED_IS_NOT_ISSUE = "skippedIsNotIssue";
-  public static final String SKIPPED_ISSUE = "skippedIssue";
   protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractImportStrategy.class);
   private static final Date initialStartTime = new Date(0);
   protected static final ExecutorService service = Executors.newFixedThreadPool(5);
-  public static final String LAUNCH_NAME_RESTRICTION_MSG =
-      "User can't import launch with the invalid number of symbols for Name.";
-  public static final String LAUNCH_DESCRIPTION_RESTRICTION_MSG =
-      "User can't import launch with the invalid number of symbols for Description.";
-  public static final String ATTRIBUTE_KEY_RESTRICTION_MSG =
-      "User can't import launch with the invalid number of symbols for Attribute Key.";
-  public static final String ATTRIBUTE_KEY_WITHOUT_VALUE_MSG =
-      "User can't import launch with only Attribute Key without Attribute Value.";
-  public static final String ATTRIBUTE_VALUE_RESTRICTION_MSG =
-      "User can't import launch with the invalid number of symbols for Attribute Value.";
-  public static final String INCORRECT_NOT_ISSUE_PARAMETER_MSG =
-      "User can't import launch with invalid value for parameter skippedIsNotIssue.";
-  public static final int MAX_ATTRIBUTE_LENGTH = 512;
-  public static final int MAX_DESCRIPTION_LENGTH = 2048;
-  public static final int MAX_NAME_LENGTH = 256;
 
   private StartLaunchHandler startLaunchHandler;
 
@@ -107,30 +86,17 @@ protected ParseResults processResults(CompletableFuture... futures) {
   }
 
   protected String startLaunch(ReportPortalUser.ProjectDetails projectDetails,
-      ReportPortalUser user, String launchName, Map<String, String> params) {
+      ReportPortalUser user, String launchName, LaunchImportRQ rq) {
     StartLaunchRQ startLaunchRQ = new StartLaunchRQ();
-    startLaunchRQ.setStartTime(initialStartTime);
-    startLaunchRQ.setName(params.get(LAUNCH_NAME) != null ? params.get(LAUNCH_NAME) : launchName);
-    startLaunchRQ.setDescription(params.get(LAUNCH_DESCRIPTION));
-    startLaunchRQ.setMode(Mode.DEFAULT);
-    Set<ItemAttributesRQ> itemAttributes = getItemAttributes(params);
-    startLaunchRQ.setAttributes(itemAttributes);
+    startLaunchRQ.setStartTime(ofNullable(rq.getStartTime()).orElse(initialStartTime));
+    startLaunchRQ.setName(ofNullable(rq.getName()).orElse(launchName));
+    ofNullable(rq.getDescription())
+        .ifPresent(startLaunchRQ::setDescription);
+    startLaunchRQ.setMode(ofNullable(rq.getMode()).orElse(Mode.DEFAULT));
+    startLaunchRQ.setAttributes(ofNullable(rq.getAttributes()).orElse(Sets.newHashSet()));
     return startLaunchHandler.startLaunch(user, projectDetails, startLaunchRQ).getId();
   }
 
-  private Set<ItemAttributesRQ> getItemAttributes(Map<String, String> params) {
-    Set<ItemAttributesRQ> itemAttributes = new HashSet<>();
-    if (params.get(ATTRIBUTE_VALUE) != null) {
-      itemAttributes.add(
-          new ItemAttributesRQ(params.get(ATTRIBUTE_KEY), params.get(ATTRIBUTE_VALUE)));
-    }
-    if (params.get(SKIPPED_IS_NOT_ISSUE) != null && Boolean.parseBoolean(params.get(
-        SKIPPED_IS_NOT_ISSUE))) {
-      itemAttributes.add(new ItemAttributesRQ(SKIPPED_ISSUE, "true", true));
-    }
-    return itemAttributes;
-  }
-
   protected void finishLaunch(String launchId, ReportPortalUser.ProjectDetails projectDetails,
       ReportPortalUser user,
       ParseResults results, String baseUrl) {
@@ -143,6 +109,14 @@ protected void finishLaunch(String launchId, ReportPortalUser.ProjectDetails pro
     launchRepository.save(launch);
   }
 
+  protected Boolean isSkippedNotIssue(Set<ItemAttributesRQ> attributes) {
+    return ofNullable(attributes).orElse(Collections.emptySet()).stream()
+        .filter(
+            attribute -> SKIPPED_IS_NOT_ISSUE.equals(attribute.getKey()) && attribute.isSystem())
+        .findAny()
+        .filter(itemAttributesRQ -> Boolean.parseBoolean(itemAttributesRQ.getValue())).isPresent();
+  }
+
   /**
    * Got a cause exception message if it has any.
    *
@@ -170,52 +144,4 @@ protected void updateBrokenLaunch(String savedLaunchId) {
       launchRepository.save(launch);
     }
   }
-
-  protected void validateOverrideParameters(Map<String, String> params) {
-    validateLaunchName(params);
-    validateLaunchDescription(params);
-    validateAttributeKey(params);
-    validateAttributeKeyWithValue(params);
-    validateAttributeValue(params);
-    validateSkippedParameter(params);
-  }
-
-  private void validateLaunchName(Map<String, String> params) {
-    String launchName = params.get(LAUNCH_NAME);
-    boolean isValid = launchName == null || (1 < launchName.length() && launchName.length() <= MAX_NAME_LENGTH);
-    expect(isValid, Predicate.isEqual(true)).verify(ErrorType.BAD_REQUEST_ERROR, LAUNCH_NAME_RESTRICTION_MSG);
-  }
-
-  private void validateLaunchDescription(Map<String, String> params) {
-    String launchDescription = params.get(LAUNCH_DESCRIPTION);
-    boolean isValid = launchDescription == null || (launchDescription.length() <= MAX_DESCRIPTION_LENGTH);
-    expect(isValid, Predicate.isEqual(true)).verify(ErrorType.BAD_REQUEST_ERROR, LAUNCH_DESCRIPTION_RESTRICTION_MSG);
-  }
-
-  private void validateAttributeKey(Map<String, String> params) {
-    String attributeKey = params.get(ATTRIBUTE_KEY);
-    boolean isValid = attributeKey == null || (attributeKey.length() <= MAX_ATTRIBUTE_LENGTH);
-    expect(isValid, Predicate.isEqual(true)).verify(ErrorType.BAD_REQUEST_ERROR, ATTRIBUTE_KEY_RESTRICTION_MSG);
-  }
-
-  private void validateAttributeKeyWithValue(Map<String, String> params) {
-    String attributeKey = params.get(ATTRIBUTE_KEY);
-    String attributeValue = params.get(ATTRIBUTE_VALUE);
-    boolean isValid = attributeKey == null || attributeValue != null;
-    expect(isValid, Predicate.isEqual(true)).verify(ErrorType.BAD_REQUEST_ERROR, ATTRIBUTE_KEY_WITHOUT_VALUE_MSG);
-  }
-
-  private void validateAttributeValue(Map<String, String> params) {
-    String attributeValue = params.get(ATTRIBUTE_VALUE);
-    boolean isValid = attributeValue == null || (attributeValue.length() <= MAX_ATTRIBUTE_LENGTH);
-    expect(isValid, Predicate.isEqual(true)).verify(ErrorType.BAD_REQUEST_ERROR, ATTRIBUTE_VALUE_RESTRICTION_MSG);
-  }
-
-  private void validateSkippedParameter(Map<String, String> params) {
-    String notIssue = params.get(SKIPPED_IS_NOT_ISSUE);
-    boolean isValid =
-        notIssue == null || "true".equalsIgnoreCase(notIssue) || "false".equalsIgnoreCase(notIssue);
-    expect(isValid, Predicate.isEqual(true)).verify(ErrorType.BAD_REQUEST_ERROR,
-        INCORRECT_NOT_ISSUE_PARAMETER_MSG);
-  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/imprt/impl/DateUtils.java b/src/main/java/com/epam/ta/reportportal/core/imprt/impl/DateUtils.java
index 7d3f1f37bf..138e2d42b3 100644
--- a/src/main/java/com/epam/ta/reportportal/core/imprt/impl/DateUtils.java
+++ b/src/main/java/com/epam/ta/reportportal/core/imprt/impl/DateUtils.java
@@ -20,22 +20,22 @@
  */
 public final class DateUtils {
 
-	private DateUtils() {
-		//static only
-	}
+  private DateUtils() {
+    //static only
+  }
 
-	/**
-	 * Converts string representation of seconds to millis
-	 *
-	 * @param duration String seconds
-	 * @return long millis
-	 */
-	public static long toMillis(String duration) {
-		if (null != duration) {
-			Double value = Double.valueOf(duration) * 1000;
-			return value.longValue();
-		}
-		return 0;
-	}
+  /**
+   * Converts string representation of seconds to millis
+   *
+   * @param duration String seconds
+   * @return long millis
+   */
+  public static long toMillis(String duration) {
+    if (null != duration) {
+      Double value = Double.valueOf(duration) * 1000;
+      return value.longValue();
+    }
+    return 0;
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/imprt/impl/ImportStrategy.java b/src/main/java/com/epam/ta/reportportal/core/imprt/impl/ImportStrategy.java
index 7038eef804..20c7e1911c 100644
--- a/src/main/java/com/epam/ta/reportportal/core/imprt/impl/ImportStrategy.java
+++ b/src/main/java/com/epam/ta/reportportal/core/imprt/impl/ImportStrategy.java
@@ -16,9 +16,8 @@
 package com.epam.ta.reportportal.core.imprt.impl;
 
 import com.epam.ta.reportportal.commons.ReportPortalUser;
-
+import com.epam.ta.reportportal.ws.model.launch.LaunchImportRQ;
 import java.io.File;
-import java.util.Map;
 
 /**
  * Handler for processing launch importing.
@@ -26,14 +25,17 @@
  * @author Pavel_Bortnik
  */
 public interface ImportStrategy {
-	/**
-	 * Processing launch importing.
-	 *
-	 * @param projectDetails project
-	 * @param user           user
-	 * @param file           zip file that contains xml test reports
-	 * @return launch uuid
-	 */
-	String importLaunch(ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user,
-			File file, String baseUrl, Map<String, String> params);
+
+  /**
+   * Processing launch importing.
+   *
+   * @param projectDetails project
+   * @param user           user
+   * @param file           zip file that contains xml test reports
+   * @param baseUrl        application base url
+   * @param rq             {@link LaunchImportRQ} launch import request
+   * @return launch uuid
+   */
+  String importLaunch(ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user,
+      File file, String baseUrl, LaunchImportRQ rq);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/imprt/impl/ImportStrategyFactory.java b/src/main/java/com/epam/ta/reportportal/core/imprt/impl/ImportStrategyFactory.java
index 5159f50ab2..d2c4f488c4 100644
--- a/src/main/java/com/epam/ta/reportportal/core/imprt/impl/ImportStrategyFactory.java
+++ b/src/main/java/com/epam/ta/reportportal/core/imprt/impl/ImportStrategyFactory.java
@@ -16,19 +16,19 @@
 package com.epam.ta.reportportal.core.imprt.impl;
 
 /**
- * Factory for launch import handlers.
- * Could be implemented other imports in future versions.
+ * Factory for launch import handlers. Could be implemented other imports in future versions.
  *
  * @author Pavel_Bortnik
  */
 
 public interface ImportStrategyFactory {
-	/**
-	 * Return import handler for specified type of import.
-	 *
-	 * @param type     import type
-	 * @param fileName file name with extension
-	 * @return handler
-	 */
-	ImportStrategy getImportStrategy(ImportType type, String fileName);
+
+  /**
+   * Return import handler for specified type of import.
+   *
+   * @param type     import type
+   * @param fileName file name with extension
+   * @return handler
+   */
+  ImportStrategy getImportStrategy(ImportType type, String fileName);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/imprt/impl/ImportStrategyFactoryImpl.java b/src/main/java/com/epam/ta/reportportal/core/imprt/impl/ImportStrategyFactoryImpl.java
index b2a3cc921e..1bdb0d4529 100644
--- a/src/main/java/com/epam/ta/reportportal/core/imprt/impl/ImportStrategyFactoryImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/imprt/impl/ImportStrategyFactoryImpl.java
@@ -15,33 +15,35 @@
  */
 package com.epam.ta.reportportal.core.imprt.impl;
 
+import static com.epam.ta.reportportal.core.imprt.FileExtensionConstant.XML_EXTENSION;
+import static com.epam.ta.reportportal.core.imprt.FileExtensionConstant.ZIP_EXTENSION;
+
 import com.google.common.collect.ImmutableMap;
+import java.util.Map;
 import org.apache.commons.io.FilenameUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.stereotype.Service;
 
-import java.util.Map;
-
-import static com.epam.ta.reportportal.core.imprt.FileExtensionConstant.XML_EXTENSION;
-import static com.epam.ta.reportportal.core.imprt.FileExtensionConstant.ZIP_EXTENSION;
-
 @Service
 @Configuration
 public class ImportStrategyFactoryImpl implements ImportStrategyFactory {
 
-	private final Map<ImportType, Map<String, ImportStrategy>> MAPPING;
+  private final Map<ImportType, Map<String, ImportStrategy>> MAPPING;
 
-	@Autowired
-	public ImportStrategyFactoryImpl(ImportStrategy zipImportStrategy, ImportStrategy xmlImportStrategy) {
-		Map<String, ImportStrategy> xunitStrategyMap = ImmutableMap.<String, ImportStrategy>builder().put(ZIP_EXTENSION, zipImportStrategy)
-				.put(XML_EXTENSION, xmlImportStrategy)
-				.build();
-		MAPPING = ImmutableMap.<ImportType, Map<String, ImportStrategy>>builder().put(ImportType.XUNIT, xunitStrategyMap).build();
-	}
+  @Autowired
+  public ImportStrategyFactoryImpl(ImportStrategy zipImportStrategy,
+      ImportStrategy xmlImportStrategy) {
+    Map<String, ImportStrategy> xunitStrategyMap = ImmutableMap.<String, ImportStrategy>builder()
+        .put(ZIP_EXTENSION, zipImportStrategy)
+        .put(XML_EXTENSION, xmlImportStrategy)
+        .build();
+    MAPPING = ImmutableMap.<ImportType, Map<String, ImportStrategy>>builder()
+        .put(ImportType.XUNIT, xunitStrategyMap).build();
+  }
 
-	@Override
-	public ImportStrategy getImportStrategy(ImportType type, String filename) {
-		return MAPPING.get(type).get(FilenameUtils.getExtension(filename));
-	}
+  @Override
+  public ImportStrategy getImportStrategy(ImportType type, String filename) {
+    return MAPPING.get(type).get(FilenameUtils.getExtension(filename));
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/imprt/impl/ImportType.java b/src/main/java/com/epam/ta/reportportal/core/imprt/impl/ImportType.java
index 654abe263a..5714e1edc6 100644
--- a/src/main/java/com/epam/ta/reportportal/core/imprt/impl/ImportType.java
+++ b/src/main/java/com/epam/ta/reportportal/core/imprt/impl/ImportType.java
@@ -19,9 +19,10 @@
 import java.util.Optional;
 
 public enum ImportType {
-	XUNIT;
+  XUNIT;
 
-	public static Optional<ImportType> fromValue(String value) {
-		return Arrays.stream(ImportType.values()).filter(type -> type.name().equalsIgnoreCase(value)).findFirst();
-	}
+  public static Optional<ImportType> fromValue(String value) {
+    return Arrays.stream(ImportType.values()).filter(type -> type.name().equalsIgnoreCase(value))
+        .findFirst();
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/imprt/impl/ParseResults.java b/src/main/java/com/epam/ta/reportportal/core/imprt/impl/ParseResults.java
index ec9e5185b6..eac18a8839 100644
--- a/src/main/java/com/epam/ta/reportportal/core/imprt/impl/ParseResults.java
+++ b/src/main/java/com/epam/ta/reportportal/core/imprt/impl/ParseResults.java
@@ -16,45 +16,44 @@
 package com.epam.ta.reportportal.core.imprt.impl;
 
 import com.epam.ta.reportportal.commons.EntityUtils;
-
 import java.time.LocalDateTime;
 import java.time.temporal.ChronoUnit;
 import java.util.Date;
 
 public class ParseResults {
 
-	private LocalDateTime startTime;
+  private LocalDateTime startTime;
 
-	private long duration;
+  private long duration;
 
-	ParseResults() {
-		startTime = LocalDateTime.now();
-	}
+  ParseResults() {
+    startTime = LocalDateTime.now();
+  }
 
-	public ParseResults(LocalDateTime startTime, long duration) {
-		this.startTime = startTime;
-		this.duration = duration;
-	}
+  public ParseResults(LocalDateTime startTime, long duration) {
+    this.startTime = startTime;
+    this.duration = duration;
+  }
 
-	public LocalDateTime getStartTime() {
-		return startTime;
-	}
+  public LocalDateTime getStartTime() {
+    return startTime;
+  }
 
-	public long getDuration() {
-		return duration;
-	}
+  public long getDuration() {
+    return duration;
+  }
 
-	void checkAndSetStartLaunchTime(LocalDateTime startSuiteTime) {
-		if (this.startTime.isAfter(startSuiteTime)) {
-			this.startTime = startSuiteTime;
-		}
-	}
+  void checkAndSetStartLaunchTime(LocalDateTime startSuiteTime) {
+    if (this.startTime.isAfter(startSuiteTime)) {
+      this.startTime = startSuiteTime;
+    }
+  }
 
-	void increaseDuration(long duration) {
-		this.duration += duration;
-	}
+  void increaseDuration(long duration) {
+    this.duration += duration;
+  }
 
-	public Date getEndTime() {
-		return EntityUtils.TO_DATE.apply(startTime.plus(duration, ChronoUnit.MILLIS));
-	}
+  public Date getEndTime() {
+    return EntityUtils.TO_DATE.apply(startTime.plus(duration, ChronoUnit.MILLIS));
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/imprt/impl/XmlImportStrategy.java b/src/main/java/com/epam/ta/reportportal/core/imprt/impl/XmlImportStrategy.java
index 2ce5219297..c1bd76a038 100644
--- a/src/main/java/com/epam/ta/reportportal/core/imprt/impl/XmlImportStrategy.java
+++ b/src/main/java/com/epam/ta/reportportal/core/imprt/impl/XmlImportStrategy.java
@@ -15,21 +15,20 @@
  */
 package com.epam.ta.reportportal.core.imprt.impl;
 
+import static com.epam.ta.reportportal.core.imprt.FileExtensionConstant.XML_EXTENSION;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.imprt.impl.junit.XunitParseJob;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
-import java.util.Map;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
-import javax.inject.Provider;
+import com.epam.ta.reportportal.ws.model.launch.LaunchImportRQ;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStream;
-
-import static com.epam.ta.reportportal.core.imprt.FileExtensionConstant.XML_EXTENSION;
-import static java.util.Optional.ofNullable;
+import javax.inject.Provider;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -42,10 +41,9 @@ public class XmlImportStrategy extends AbstractImportStrategy {
 
   @Override
   public String importLaunch(ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user,
-      File file, String baseUrl, Map<String, String> params) {
-    validateOverrideParameters(params);
+      File file, String baseUrl, LaunchImportRQ rq) {
     try {
-      return processXmlFile(file, projectDetails, user, baseUrl, params);
+      return processXmlFile(file, projectDetails, user, baseUrl, rq);
     } finally {
       try {
         ofNullable(file).ifPresent(File::delete);
@@ -56,17 +54,16 @@ public String importLaunch(ReportPortalUser.ProjectDetails projectDetails, Repor
   }
 
   private String processXmlFile(File xml, ReportPortalUser.ProjectDetails projectDetails,
-      ReportPortalUser user, String baseUrl, Map<String, String> params) {
+      ReportPortalUser user, String baseUrl, LaunchImportRQ rq) {
     //copy of the launch's id to use it in catch block if something goes wrong
     String savedLaunchId = null;
     try (InputStream xmlStream = new FileInputStream(xml)) {
       String launchId = startLaunch(projectDetails, user,
-          xml.getName().substring(0, xml.getName().indexOf("." + XML_EXTENSION)), params);
+          xml.getName().substring(0, xml.getName().indexOf("." + XML_EXTENSION)), rq);
       savedLaunchId = launchId;
       XunitParseJob job = xmlParseJobProvider.get()
           .withParameters(projectDetails, launchId, user, xmlStream,
-              params.get(SKIPPED_IS_NOT_ISSUE) != null && Boolean.parseBoolean(params.get(
-                  SKIPPED_IS_NOT_ISSUE)));
+              isSkippedNotIssue(rq.getAttributes()));
       ParseResults parseResults = job.call();
       finishLaunch(launchId, projectDetails, user, parseResults, baseUrl);
       return launchId;
diff --git a/src/main/java/com/epam/ta/reportportal/core/imprt/impl/ZipImportStrategy.java b/src/main/java/com/epam/ta/reportportal/core/imprt/impl/ZipImportStrategy.java
index d9cbbb04fe..b6b83ac8b4 100644
--- a/src/main/java/com/epam/ta/reportportal/core/imprt/impl/ZipImportStrategy.java
+++ b/src/main/java/com/epam/ta/reportportal/core/imprt/impl/ZipImportStrategy.java
@@ -15,15 +15,15 @@
  */
 package com.epam.ta.reportportal.core.imprt.impl;
 
+import static com.epam.ta.reportportal.core.imprt.FileExtensionConstant.XML_EXTENSION;
+import static com.epam.ta.reportportal.core.imprt.FileExtensionConstant.ZIP_EXTENSION;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.imprt.impl.junit.XunitParseJob;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
-import java.util.Map;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
-import javax.inject.Provider;
+import com.epam.ta.reportportal.ws.model.launch.LaunchImportRQ;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
@@ -31,28 +31,28 @@
 import java.util.function.Predicate;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
-
-import static com.epam.ta.reportportal.core.imprt.FileExtensionConstant.XML_EXTENSION;
-import static com.epam.ta.reportportal.core.imprt.FileExtensionConstant.ZIP_EXTENSION;
-import static java.util.Optional.ofNullable;
+import javax.inject.Provider;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class ZipImportStrategy extends AbstractImportStrategy {
+
   private static final Predicate<ZipEntry> isFile = zipEntry -> !zipEntry.isDirectory();
-  private static final Predicate<ZipEntry> isXml = zipEntry -> zipEntry.getName().endsWith(XML_EXTENSION);
+  private static final Predicate<ZipEntry> isXml = zipEntry -> zipEntry.getName()
+      .endsWith(XML_EXTENSION);
 
   @Autowired
   private Provider<XunitParseJob> xmlParseJobProvider;
 
   @Override
   public String importLaunch(ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user,
-      File file, String baseUrl, Map<String, String> params) {
-    validateOverrideParameters(params);
+      File file, String baseUrl, LaunchImportRQ rq) {
     try {
-      return processZipFile(file, projectDetails, user, baseUrl, params);
+      return processZipFile(file, projectDetails, user, baseUrl, rq);
     } finally {
       try {
         ofNullable(file).ifPresent(File::delete);
@@ -63,18 +63,17 @@ public String importLaunch(ReportPortalUser.ProjectDetails projectDetails, Repor
   }
 
   private String processZipFile(File zip, ReportPortalUser.ProjectDetails projectDetails,
-      ReportPortalUser user, String baseUrl, Map<String, String> params) {
+      ReportPortalUser user, String baseUrl, LaunchImportRQ rq) {
     //copy of the launch's id to use it in catch block if something goes wrong
     String savedLaunchId = null;
     try (ZipFile zipFile = new ZipFile(zip)) {
       String launchId = startLaunch(projectDetails, user,
-          zip.getName().substring(0, zip.getName().indexOf("." + ZIP_EXTENSION)), params);
+          zip.getName().substring(0, zip.getName().indexOf("." + ZIP_EXTENSION)), rq);
       savedLaunchId = launchId;
       CompletableFuture[] futures = zipFile.stream().filter(isFile.and(isXml)).map(zipEntry -> {
         XunitParseJob job = xmlParseJobProvider.get()
             .withParameters(projectDetails, launchId, user, getEntryStream(zipFile, zipEntry),
-                params.get(SKIPPED_IS_NOT_ISSUE) != null && Boolean.parseBoolean(params.get(
-                    SKIPPED_IS_NOT_ISSUE)));
+                isSkippedNotIssue(rq.getAttributes()));
         return CompletableFuture.supplyAsync(job::call, service);
       }).toArray(CompletableFuture[]::new);
       ParseResults parseResults = processResults(futures);
diff --git a/src/main/java/com/epam/ta/reportportal/core/imprt/impl/junit/XunitImportHandler.java b/src/main/java/com/epam/ta/reportportal/core/imprt/impl/junit/XunitImportHandler.java
index 99b16f7566..935263f9bd 100644
--- a/src/main/java/com/epam/ta/reportportal/core/imprt/impl/junit/XunitImportHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/imprt/impl/junit/XunitImportHandler.java
@@ -15,6 +15,9 @@
  */
 package com.epam.ta.reportportal.core.imprt.impl.junit;
 
+import static com.epam.ta.reportportal.core.imprt.impl.DateUtils.toMillis;
+import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.NOT_ISSUE_FLAG;
+
 import com.epam.ta.reportportal.commons.EntityUtils;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.item.FinishTestItemHandler;
@@ -28,6 +31,18 @@
 import com.epam.ta.reportportal.ws.model.issue.Issue;
 import com.epam.ta.reportportal.ws.model.log.SaveLogRQ;
 import com.google.common.base.Strings;
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.temporal.ChronoUnit;
+import java.time.temporal.TemporalAccessor;
+import java.time.temporal.TemporalQueries;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.Optional;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -38,19 +53,6 @@
 import org.xml.sax.Attributes;
 import org.xml.sax.helpers.DefaultHandler;
 
-import java.time.Instant;
-import java.time.LocalDateTime;
-import java.time.ZoneId;
-import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeFormatterBuilder;
-import java.time.temporal.ChronoUnit;
-import java.util.ArrayDeque;
-import java.util.Deque;
-import java.util.Optional;
-
-import static com.epam.ta.reportportal.core.imprt.impl.DateUtils.toMillis;
-import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.NOT_ISSUE_FLAG;
-
 @Component
 @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
 public class XunitImportHandler extends DefaultHandler {
@@ -77,7 +79,7 @@ public XunitImportHandler(StartTestItemHandler startTestItemHandler, FinishTestI
 	private ReportPortalUser.ProjectDetails projectDetails;
 	private ReportPortalUser user;
 	private String launchUuid;
-	private boolean skippedIsNotIssue = false;
+	private boolean isSkippedNotIssue = false;
 
 	//need to know item's id to attach System.out/System.err logs
 	private String currentItemUuid;
@@ -193,29 +195,37 @@ private void startRootItem(String name, String timestamp) {
 		itemUuids.push(id);
 	}
 
-	private LocalDateTime parseTimeStamp(String timestamp) {
-		LocalDateTime localDateTime = null;
-		try {
-			localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(Long.parseLong(timestamp)), ZoneId.systemDefault());
-		} catch (NumberFormatException ignored) {
-			//ignored
-		}
-		if (null == localDateTime) {
-			DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendOptional(DateTimeFormatter.RFC_1123_DATE_TIME)
-					.appendOptional(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
-					.optionalStart()
-					.appendZoneId()
-					.optionalEnd()
-					.optionalStart()
-					.appendLiteral(' ')
-					.parseCaseSensitive()
-					.appendZoneId()
-					.optionalEnd()
-					.toFormatter();
-			localDateTime = LocalDateTime.parse(timestamp, formatter);
-		}
-		return localDateTime;
-	}
+  private LocalDateTime parseTimeStamp(String timestamp) {
+    // try to parse datetime as Long, otherwise parse as timestamp
+    try {
+      return LocalDateTime.ofInstant(Instant.ofEpochMilli(Long.parseLong(timestamp)), ZoneOffset.UTC);
+    } catch (NumberFormatException ignored) {
+      DateTimeFormatter formatter = new DateTimeFormatterBuilder()
+          .appendOptional(DateTimeFormatter.RFC_1123_DATE_TIME)
+          .appendOptional(DateTimeFormatter.ISO_OFFSET_DATE_TIME)
+          .appendOptional(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
+          .optionalStart()
+            .appendOffsetId()
+            .appendZoneId()
+          .optionalEnd()
+          .optionalStart()
+            .appendLiteral(' ')
+            .parseCaseSensitive()
+            .appendZoneId()
+          .optionalEnd()
+          .toFormatter();
+
+      TemporalAccessor temporalAccessor = formatter.parse(timestamp);
+      if (isParsedTimeStampHasOffset(temporalAccessor)) {
+        return ZonedDateTime.from(temporalAccessor)
+            .withZoneSameInstant(ZoneOffset.UTC)
+            .toLocalDateTime();
+      } else {
+        return LocalDateTime.from(temporalAccessor);
+      }
+    }
+
+  }
 
 	private void startTestItem(String name) {
 		StartTestItemRQ rq = buildStartTestRq(name);
@@ -256,7 +266,7 @@ private void finishTestItem() {
 	}
 
 	private void markAsNotIssue(FinishTestItemRQ rq) {
-		if (StatusEnum.SKIPPED.equals(status) && skippedIsNotIssue) {
+		if (StatusEnum.SKIPPED.equals(status) && isSkippedNotIssue) {
 			Issue issue = new Issue();
 			issue.setIssueType(NOT_ISSUE_FLAG.getValue());
 			rq.setIssue(issue);
@@ -275,11 +285,11 @@ private void attachLog(LogLevel logLevel) {
 	}
 
 	XunitImportHandler withParameters(ReportPortalUser.ProjectDetails projectDetails, String launchId,
-			ReportPortalUser user, boolean skipped) {
+			ReportPortalUser user, boolean isSkippedNotIssue) {
 		this.projectDetails = projectDetails;
 		this.launchUuid = launchId;
 		this.user = user;
-		this.skippedIsNotIssue = skipped;
+		this.isSkippedNotIssue = isSkippedNotIssue;
 		return this;
 	}
 
@@ -299,4 +309,9 @@ LocalDateTime getStartSuiteTime() {
 	long getCommonDuration() {
 		return commonDuration;
 	}
+
+  private boolean isParsedTimeStampHasOffset(TemporalAccessor temporalAccessor) {
+    return temporalAccessor.query(TemporalQueries.offset()) != null;
+  }
+
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/imprt/impl/junit/XunitParseJob.java b/src/main/java/com/epam/ta/reportportal/core/imprt/impl/junit/XunitParseJob.java
index 82f1e94c18..60880a5c9b 100644
--- a/src/main/java/com/epam/ta/reportportal/core/imprt/impl/junit/XunitParseJob.java
+++ b/src/main/java/com/epam/ta/reportportal/core/imprt/impl/junit/XunitParseJob.java
@@ -73,9 +73,9 @@ public ParseResults call() {
 	}
 
 	public XunitParseJob withParameters(ReportPortalUser.ProjectDetails projectDetails, String launchId, ReportPortalUser user,
-			InputStream xmlInputStream, boolean skipped) {
+			InputStream xmlInputStream, boolean isSkippedNotIssue) {
 		this.xmlInputStream = xmlInputStream;
-		this.handler = handler.withParameters(projectDetails, launchId, user, skipped);
+		this.handler = handler.withParameters(projectDetails, launchId, user, isSkippedNotIssue);
 		return this;
 	}
 
diff --git a/src/main/java/com/epam/ta/reportportal/core/integration/CreateIntegrationHandler.java b/src/main/java/com/epam/ta/reportportal/core/integration/CreateIntegrationHandler.java
index 3280968a84..707984f395 100644
--- a/src/main/java/com/epam/ta/reportportal/core/integration/CreateIntegrationHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/integration/CreateIntegrationHandler.java
@@ -32,6 +32,7 @@ public interface CreateIntegrationHandler {
    *
    * @param pluginName    Plugin name
    * @param createRequest {@link IntegrationRQ}
+   * @param user          {@link ReportPortalUser}
    * @return {@link EntryCreatedRS}
    */
   EntryCreatedRS createGlobalIntegration(IntegrationRQ createRequest, String pluginName,
diff --git a/src/main/java/com/epam/ta/reportportal/core/integration/ExecuteIntegrationHandler.java b/src/main/java/com/epam/ta/reportportal/core/integration/ExecuteIntegrationHandler.java
index 3691d95487..4d1ac67cbf 100644
--- a/src/main/java/com/epam/ta/reportportal/core/integration/ExecuteIntegrationHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/integration/ExecuteIntegrationHandler.java
@@ -17,39 +17,50 @@
 package com.epam.ta.reportportal.core.integration;
 
 import com.epam.ta.reportportal.commons.ReportPortalUser;
-
 import java.util.Map;
 
 /**
- * Executes one of provided commands for configured integration with id
- * at existed plugin.
+ * Executes one of provided commands for configured integration with id at existed plugin.
  *
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
  */
 public interface ExecuteIntegrationHandler {
 
-	/**
-	 * Executes provided common plugin command
-	 *
-	 * @param projectDetails  Project details
-	 * @param pluginName      Command name
-	 * @param command         Command to be executed
-	 * @param executionParams Parameters for execute
-	 * @return Result of the command execution
-	 */
-	Object executeCommand(ReportPortalUser.ProjectDetails projectDetails, String pluginName, String command,
-			Map<String, Object> executionParams);
+  /**
+   * Executes provided common plugin command
+   *
+   * @param projectDetails  Project details
+   * @param pluginName      Command name
+   * @param command         Command to be executed
+   * @param executionParams Parameters for execute
+   * @return Result of the command execution
+   */
+  Object executeCommand(ReportPortalUser.ProjectDetails projectDetails, String pluginName,
+      String command,
+      Map<String, Object> executionParams);
+
+  /**
+   * Executes provided plugin public command
+   *
+   * @param pluginName      Command name
+   * @param command         Command to be executed
+   * @param executionParams Parameters for execute
+   * @return Result of the command execution
+   */
+  Object executePublicCommand(String pluginName, String command,
+      Map<String, Object> executionParams);
 
-	/**
-	 * Executes provided plugin command for existed integration
-	 *
-	 * @param projectDetails  Project details
-	 * @param integrationId   Integration id
-	 * @param command         Command to be executed
-	 * @param executionParams Parameters for execute
-	 * @return Result of the command execution
-	 */
-	Object executeCommand(ReportPortalUser.ProjectDetails projectDetails, Long integrationId, String command,
-			Map<String, Object> executionParams);
+  /**
+   * Executes provided plugin command for existed integration
+   *
+   * @param projectDetails  Project details
+   * @param integrationId   Integration id
+   * @param command         Command to be executed
+   * @param executionParams Parameters for execute
+   * @return Result of the command execution
+   */
+  Object executeCommand(ReportPortalUser.ProjectDetails projectDetails, Long integrationId,
+      String command,
+      Map<String, Object> executionParams);
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/integration/GetIntegrationHandler.java b/src/main/java/com/epam/ta/reportportal/core/integration/GetIntegrationHandler.java
index 9bb75bc8db..e58315f011 100644
--- a/src/main/java/com/epam/ta/reportportal/core/integration/GetIntegrationHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/integration/GetIntegrationHandler.java
@@ -20,7 +20,6 @@
 import com.epam.ta.reportportal.entity.enums.IntegrationGroupEnum;
 import com.epam.ta.reportportal.entity.integration.Integration;
 import com.epam.ta.reportportal.ws.model.integration.IntegrationResource;
-
 import java.util.List;
 import java.util.Optional;
 
@@ -29,59 +28,62 @@
  */
 public interface GetIntegrationHandler {
 
-	/**
-	 * @param integrationId Integration id
-	 * @param projectName   Project name
-	 * @return {@link IntegrationResource}
-	 */
-	IntegrationResource getProjectIntegrationById(Long integrationId, String projectName);
-
-	IntegrationResource getGlobalIntegrationById(Long integrationId);
-
-	Optional<Integration> getEnabledByProjectIdOrGlobalAndIntegrationGroup(Long projectId, IntegrationGroupEnum integrationGroup);
-
-	Integration getEnabledBtsIntegration(ReportPortalUser.ProjectDetails projectDetails, String url, String btsProject);
-
-	Integration getEnabledBtsIntegration(ReportPortalUser.ProjectDetails projectDetails, Long integrationId);
-
-	Integration getEnabledBtsIntegration(Long integrationId);
-
-	List<IntegrationResource> getGlobalIntegrations();
-
-	List<IntegrationResource> getGlobalIntegrations(String pluginName);
-
-	/**
-	 * Get project integrations
-	 *
-	 * @param projectName Project nam
-	 * @return List of integrations
-	 */
-	List<IntegrationResource> getProjectIntegrations(String projectName);
-
-	/**
-	 * Get project integrations with plugin
-	 *
-	 * @param pluginName  Plugin name
-	 * @param projectName Project nam
-	 * @return List of integrations
-	 */
-	List<IntegrationResource> getProjectIntegrations(String pluginName, String projectName);
-
-	/**
-	 * Test integration connection. Firstly tries to find a project integration.
-	 * If doesn't exist it tries to find Global integration
-	 *
-	 * @param integrationId Integration id
-	 * @param projectName   Project name
-	 * @return True if a connection is established
-	 */
-	boolean testConnection(Long integrationId, String projectName);
-
-	/**
-	 * Test integration connection. Connection attempt to the global integration
-	 *
-	 * @param integrationId Integration id
-	 * @return True if a connection is established
-	 */
-	boolean testConnection(Long integrationId);
+  /**
+   * @param integrationId Integration id
+   * @param projectName   Project name
+   * @return {@link IntegrationResource}
+   */
+  IntegrationResource getProjectIntegrationById(Long integrationId, String projectName);
+
+  IntegrationResource getGlobalIntegrationById(Long integrationId);
+
+  Optional<Integration> getEnabledByProjectIdOrGlobalAndIntegrationGroup(Long projectId,
+      IntegrationGroupEnum integrationGroup);
+
+  Integration getEnabledBtsIntegration(ReportPortalUser.ProjectDetails projectDetails, String url,
+      String btsProject);
+
+  Integration getEnabledBtsIntegration(ReportPortalUser.ProjectDetails projectDetails,
+      Long integrationId);
+
+  Integration getEnabledBtsIntegration(Long integrationId);
+
+  List<IntegrationResource> getGlobalIntegrations();
+
+  List<IntegrationResource> getGlobalIntegrations(String pluginName);
+
+  /**
+   * Get project integrations
+   *
+   * @param projectName Project nam
+   * @return List of integrations
+   */
+  List<IntegrationResource> getProjectIntegrations(String projectName);
+
+  /**
+   * Get project integrations with plugin
+   *
+   * @param pluginName  Plugin name
+   * @param projectName Project nam
+   * @return List of integrations
+   */
+  List<IntegrationResource> getProjectIntegrations(String pluginName, String projectName);
+
+  /**
+   * Test integration connection. Firstly tries to find a project integration. If doesn't exist it
+   * tries to find Global integration
+   *
+   * @param integrationId Integration id
+   * @param projectName   Project name
+   * @return True if a connection is established
+   */
+  boolean testConnection(Long integrationId, String projectName);
+
+  /**
+   * Test integration connection. Connection attempt to the global integration
+   *
+   * @param integrationId Integration id
+   * @return True if a connection is established
+   */
+  boolean testConnection(Long integrationId);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/integration/impl/CreateIntegrationHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/integration/impl/CreateIntegrationHandlerImpl.java
index 01089c8e4f..7bca6c9f23 100644
--- a/src/main/java/com/epam/ta/reportportal/core/integration/impl/CreateIntegrationHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/integration/impl/CreateIntegrationHandlerImpl.java
@@ -16,6 +16,9 @@
 
 package com.epam.ta.reportportal.core.integration.impl;
 
+import static com.epam.ta.reportportal.ws.converter.converters.IntegrationConverter.TO_ACTIVITY_RESOURCE;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.commons.validation.Suppliers;
@@ -35,6 +38,7 @@
 import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
 import com.epam.ta.reportportal.ws.model.activity.IntegrationActivityResource;
 import com.epam.ta.reportportal.ws.model.integration.IntegrationRQ;
+import java.util.Map;
 import org.apache.commons.lang3.BooleanUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -42,11 +46,6 @@
 import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.stereotype.Service;
 
-import java.util.Map;
-
-import static com.epam.ta.reportportal.ws.converter.converters.IntegrationConverter.TO_ACTIVITY_RESOURCE;
-import static java.util.Optional.ofNullable;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
@@ -102,7 +101,6 @@ public EntryCreatedRS createGlobalIntegration(IntegrationRQ createRequest, Strin
     integration.setCreator(user.getUsername());
     integrationService.checkConnection(integration);
     integrationRepository.save(integration);
-
     publishCreationActivity(integration, user);
 
     return new EntryCreatedRS(integration.getId());
diff --git a/src/main/java/com/epam/ta/reportportal/core/integration/impl/ExecuteIntegrationHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/integration/impl/ExecuteIntegrationHandlerImpl.java
index ddac984b76..315d1692e6 100644
--- a/src/main/java/com/epam/ta/reportportal/core/integration/impl/ExecuteIntegrationHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/integration/impl/ExecuteIntegrationHandlerImpl.java
@@ -16,24 +16,25 @@
 
 package com.epam.ta.reportportal.core.integration.impl;
 
+import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
+import static com.epam.ta.reportportal.ws.model.ErrorType.ACCESS_DENIED;
+import static com.epam.ta.reportportal.ws.model.ErrorType.BAD_REQUEST_ERROR;
+import static com.epam.ta.reportportal.ws.model.ErrorType.INTEGRATION_NOT_FOUND;
+import static java.util.Optional.ofNullable;
+
 import com.epam.reportportal.extension.ReportPortalExtensionPoint;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
+import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.core.integration.ExecuteIntegrationHandler;
 import com.epam.ta.reportportal.core.plugin.PluginBox;
 import com.epam.ta.reportportal.dao.IntegrationRepository;
 import com.epam.ta.reportportal.entity.integration.Integration;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
-import org.springframework.scheduling.annotation.Async;
-import org.springframework.stereotype.Service;
-
 import java.util.Map;
 import java.util.function.Supplier;
-
-import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
-import static com.epam.ta.reportportal.ws.model.ErrorType.BAD_REQUEST_ERROR;
-import static com.epam.ta.reportportal.ws.model.ErrorType.INTEGRATION_NOT_FOUND;
-import static java.util.Optional.ofNullable;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
@@ -41,67 +42,96 @@
 @Service
 public class ExecuteIntegrationHandlerImpl implements ExecuteIntegrationHandler {
 
-	private static final String ASYNC_MODE = "async";
-
-	//Required field for user authorization in plugin
-	private static final String PROJECT_ID = "projectId";
-
-	private final IntegrationRepository integrationRepository;
-
-	private final PluginBox pluginBox;
-
-	public ExecuteIntegrationHandlerImpl(IntegrationRepository integrationRepository, PluginBox pluginBox) {
-		this.integrationRepository = integrationRepository;
-		this.pluginBox = pluginBox;
-	}
-
-	@Override
-	public Object executeCommand(ReportPortalUser.ProjectDetails projectDetails, String pluginName, String command,
-			Map<String, Object> executionParams) {
-		ReportPortalExtensionPoint pluginInstance = pluginBox.getInstance(pluginName, ReportPortalExtensionPoint.class)
-				.orElseThrow(() -> new ReportPortalException(BAD_REQUEST_ERROR,
-						formattedSupplier("Plugin for '{}' isn't installed", pluginName).get()
-				));
-		executionParams.put(PROJECT_ID, projectDetails.getProjectId());
-		return ofNullable(pluginInstance.getCommonCommand(command)).map(it -> it.executeCommand(executionParams))
-				.orElseThrow(() -> new ReportPortalException(BAD_REQUEST_ERROR,
-						formattedSupplier("Command '{}' is not found in plugin {}.", command, pluginName).get()
-				));
-	}
-
-	@Override
-	public Object executeCommand(ReportPortalUser.ProjectDetails projectDetails, Long integrationId, String command,
-			Map<String, Object> executionParams) {
-		Integration integration = integrationRepository.findByIdAndProjectId(integrationId, projectDetails.getProjectId())
-				.orElseGet(() -> integrationRepository.findGlobalById(integrationId)
-						.orElseThrow(() -> new ReportPortalException(INTEGRATION_NOT_FOUND, integrationId)));
-
-		ReportPortalExtensionPoint pluginInstance = pluginBox.getInstance(integration.getType().getName(), ReportPortalExtensionPoint.class)
-				.orElseThrow(() -> new ReportPortalException(BAD_REQUEST_ERROR,
-						formattedSupplier("Plugin for '{}' isn't installed", integration.getType().getName()).get()
-				));
-
-		Boolean asyncMode = ofNullable((Boolean) executionParams.get(ASYNC_MODE)).orElse(false);
-
-		executionParams.put(PROJECT_ID, projectDetails.getProjectId());
-
-		return ofNullable(pluginInstance.getIntegrationCommand(command)).map(it -> {
-			if (asyncMode) {
-				supplyAsync(() -> it.executeCommand(integration, executionParams));
-				return new OperationCompletionRS(formattedSupplier("Command '{}' accepted for processing in plugin",
-						command,
-						integration.getType().getName()
-				).get());
-			}
-			return it.executeCommand(integration, executionParams);
-		}).orElseThrow(() -> new ReportPortalException(BAD_REQUEST_ERROR,
-				formattedSupplier("Command '{}' is not found in plugin {}.", command, integration.getType().getName()).get()
-		));
-	}
-
-	@Async
-	//need for security context sharing into plugin
-	public <U> void supplyAsync(Supplier<U> supplier) {
-		supplier.get();
-	}
+  private static final String ASYNC_MODE = "async";
+
+  //Required field for user authorization in plugin
+  private static final String PROJECT_ID = "projectId";
+  private static final String PUBLIC_COMMAND_PREFIX = "public_";
+
+  private final IntegrationRepository integrationRepository;
+
+  private final PluginBox pluginBox;
+
+  public ExecuteIntegrationHandlerImpl(IntegrationRepository integrationRepository,
+      PluginBox pluginBox) {
+    this.integrationRepository = integrationRepository;
+    this.pluginBox = pluginBox;
+  }
+
+  @Override
+  public Object executeCommand(ReportPortalUser.ProjectDetails projectDetails, String pluginName,
+      String command,
+      Map<String, Object> executionParams) {
+    ReportPortalExtensionPoint pluginInstance = pluginBox.getInstance(pluginName,
+            ReportPortalExtensionPoint.class)
+        .orElseThrow(() -> new ReportPortalException(BAD_REQUEST_ERROR,
+            formattedSupplier("Plugin for '{}' isn't installed", pluginName).get()
+        ));
+    executionParams.put(PROJECT_ID, projectDetails.getProjectId());
+    return ofNullable(pluginInstance.getCommonCommand(command)).map(
+            it -> it.executeCommand(executionParams))
+        .orElseThrow(() -> new ReportPortalException(BAD_REQUEST_ERROR,
+            formattedSupplier("Command '{}' is not found in plugin {}.", command, pluginName).get()
+        ));
+  }
+
+  @Override
+  public Object executePublicCommand(String pluginName, String command,
+      Map<String, Object> executionParams) {
+    BusinessRule.expect(command, c -> c.startsWith(PUBLIC_COMMAND_PREFIX))
+        .verify(ACCESS_DENIED, formattedSupplier("Command '{}' is not public.", command).get());
+    ReportPortalExtensionPoint pluginInstance = pluginBox.getInstance(pluginName,
+            ReportPortalExtensionPoint.class)
+        .orElseThrow(() -> new ReportPortalException(BAD_REQUEST_ERROR,
+            formattedSupplier("Plugin for '{}' isn't installed", pluginName).get()
+        ));
+    return ofNullable(pluginInstance.getCommonCommand(command)).map(
+            it -> it.executeCommand(executionParams))
+        .orElseThrow(() -> new ReportPortalException(BAD_REQUEST_ERROR,
+            formattedSupplier("Public command '{}' is not found in plugin {}.", command,
+                pluginName).get()
+        ));
+  }
+
+  @Override
+  public Object executeCommand(ReportPortalUser.ProjectDetails projectDetails, Long integrationId,
+      String command,
+      Map<String, Object> executionParams) {
+    Integration integration = integrationRepository.findByIdAndProjectId(integrationId,
+            projectDetails.getProjectId())
+        .orElseGet(() -> integrationRepository.findGlobalById(integrationId)
+            .orElseThrow(() -> new ReportPortalException(INTEGRATION_NOT_FOUND, integrationId)));
+
+    ReportPortalExtensionPoint pluginInstance = pluginBox.getInstance(
+            integration.getType().getName(), ReportPortalExtensionPoint.class)
+        .orElseThrow(() -> new ReportPortalException(BAD_REQUEST_ERROR,
+            formattedSupplier("Plugin for '{}' isn't installed",
+                integration.getType().getName()).get()
+        ));
+
+    Boolean asyncMode = ofNullable((Boolean) executionParams.get(ASYNC_MODE)).orElse(false);
+
+    executionParams.put(PROJECT_ID, projectDetails.getProjectId());
+
+    return ofNullable(pluginInstance.getIntegrationCommand(command)).map(it -> {
+      if (asyncMode) {
+        supplyAsync(() -> it.executeCommand(integration, executionParams));
+        return new OperationCompletionRS(
+            formattedSupplier("Command '{}' accepted for processing in plugin",
+                command,
+                integration.getType().getName()
+            ).get());
+      }
+      return it.executeCommand(integration, executionParams);
+    }).orElseThrow(() -> new ReportPortalException(BAD_REQUEST_ERROR,
+        formattedSupplier("Command '{}' is not found in plugin {}.", command,
+            integration.getType().getName()).get()
+    ));
+  }
+
+  @Async
+  //need for security context sharing into plugin
+  public <U> void supplyAsync(Supplier<U> supplier) {
+    supplier.get();
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/integration/impl/GetIntegrationHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/integration/impl/GetIntegrationHandlerImpl.java
index 1b3de9faa2..d3c2e00305 100644
--- a/src/main/java/com/epam/ta/reportportal/core/integration/impl/GetIntegrationHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/integration/impl/GetIntegrationHandlerImpl.java
@@ -16,6 +16,8 @@
 
 package com.epam.ta.reportportal.core.integration.impl;
 
+import static com.epam.ta.reportportal.ws.converter.converters.IntegrationConverter.TO_INTEGRATION_RESOURCE;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.commons.validation.Suppliers;
@@ -33,17 +35,14 @@
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.epam.ta.reportportal.ws.model.integration.IntegrationResource;
-import org.apache.commons.collections.CollectionUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.stereotype.Service;
-
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.ws.converter.converters.IntegrationConverter.TO_INTEGRATION_RESOURCE;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:andrei_varabyeu@epam.com">Andrei Varabyeu</a>
@@ -51,185 +50,218 @@
 @Service
 public class GetIntegrationHandlerImpl implements GetIntegrationHandler {
 
-	private final Map<String, IntegrationService> integrationServiceMapping;
-	private final IntegrationService basicIntegrationService;
-	private final IntegrationRepository integrationRepository;
-	private final IntegrationTypeRepository integrationTypeRepository;
-	private final ProjectRepository projectRepository;
-	private final GetBugTrackingSystemHandler getBugTrackingSystemHandler;
-
-	@Autowired
-	public GetIntegrationHandlerImpl(@Qualifier("integrationServiceMapping") Map<String, IntegrationService> integrationServiceMapping,
-			@Qualifier("basicIntegrationServiceImpl") IntegrationService integrationService, IntegrationRepository integrationRepository,
-			IntegrationTypeRepository integrationTypeRepository, ProjectRepository projectRepository,
-			GetBugTrackingSystemHandler getBugTrackingSystemHandler) {
-		this.integrationServiceMapping = integrationServiceMapping;
-		this.basicIntegrationService = integrationService;
-		this.integrationRepository = integrationRepository;
-		this.integrationTypeRepository = integrationTypeRepository;
-		this.projectRepository = projectRepository;
-		this.getBugTrackingSystemHandler = getBugTrackingSystemHandler;
-	}
-
-	@Override
-	public IntegrationResource getProjectIntegrationById(Long integrationId, String projectName) {
-		Project project = projectRepository.findByName(projectName)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.PROJECT_NOT_FOUND, projectName));
-		Integration integration = integrationRepository.findByIdAndProjectId(integrationId, project.getId())
-				.orElseThrow(() -> new ReportPortalException(ErrorType.INTEGRATION_NOT_FOUND, integrationId));
-		return TO_INTEGRATION_RESOURCE.apply(integration);
-	}
-
-	@Override
-	public IntegrationResource getGlobalIntegrationById(Long integrationId) {
-		Integration integration = integrationRepository.findGlobalById(integrationId)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.INTEGRATION_NOT_FOUND, integrationId));
-		return TO_INTEGRATION_RESOURCE.apply(integration);
-	}
-
-	@Override
-	public Optional<Integration> getEnabledByProjectIdOrGlobalAndIntegrationGroup(Long projectId, IntegrationGroupEnum integrationGroup) {
-
-		List<Long> integrationTypeIds = integrationTypeRepository.findAllByIntegrationGroup(integrationGroup)
-				.stream()
-				.map(IntegrationType::getId)
-				.collect(Collectors.toList());
-
-		List<Integration> integrations = integrationRepository.findAllByProjectIdAndInIntegrationTypeIds(projectId, integrationTypeIds);
-
-		if (!CollectionUtils.isEmpty(integrations)) {
-
-			return integrations.stream().filter(integration -> integration.getType().isEnabled() && integration.isEnabled()).findFirst();
-
-		} else {
-
-			return getGlobalIntegrationByIntegrationTypeIds(integrationTypeIds);
-		}
-
-	}
-
-	@Override
-	public Integration getEnabledBtsIntegration(ReportPortalUser.ProjectDetails projectDetails, String url, String btsProject) {
-
-		Project project = projectRepository.findById(projectDetails.getProjectId())
-				.orElseThrow(() -> new ReportPortalException(ErrorType.PROJECT_NOT_FOUND, projectDetails.getProjectName()));
-
-		Integration integration = getBugTrackingSystemHandler.getEnabledProjectIntegration(projectDetails, url, btsProject)
-				.orElseGet(() -> {
-					Integration globalIntegration = getBugTrackingSystemHandler.getEnabledGlobalIntegration(url, btsProject)
-							.orElseThrow(() -> new ReportPortalException(ErrorType.INTEGRATION_NOT_FOUND, url));
-
-					IntegrationValidator.validateProjectLevelIntegrationConstraints(project, globalIntegration);
-
-					return globalIntegration;
-				});
-		validateIntegration(integration);
-		return integration;
-	}
-
-	@Override
-	public Integration getEnabledBtsIntegration(ReportPortalUser.ProjectDetails projectDetails, Long integrationId) {
-
-		Project project = projectRepository.findById(projectDetails.getProjectId())
-				.orElseThrow(() -> new ReportPortalException(ErrorType.PROJECT_NOT_FOUND, projectDetails.getProjectName()));
-
-		Integration integration = getBugTrackingSystemHandler.getEnabledProjectIntegration(projectDetails, integrationId).orElseGet(() -> {
-			Integration globalIntegration = getBugTrackingSystemHandler.getEnabledGlobalIntegration(integrationId)
-					.orElseThrow(() -> new ReportPortalException(ErrorType.INTEGRATION_NOT_FOUND, integrationId));
-
-			IntegrationValidator.validateProjectLevelIntegrationConstraints(project, globalIntegration);
-
-			return globalIntegration;
-		});
-		validateIntegration(integration);
-		return integration;
-	}
-
-	@Override
-	public Integration getEnabledBtsIntegration(Long integrationId) {
-
-		Integration globalIntegration = getBugTrackingSystemHandler.getEnabledGlobalIntegration(integrationId)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.INTEGRATION_NOT_FOUND, integrationId));
-
-		return globalIntegration;
-	}
-
-	@Override
-	public List<IntegrationResource> getGlobalIntegrations() {
-		return integrationRepository.findAllGlobal().stream().map(TO_INTEGRATION_RESOURCE).collect(Collectors.toList());
-	}
-
-	@Override
-	public List<IntegrationResource> getGlobalIntegrations(String pluginName) {
-		IntegrationType integrationType = integrationTypeRepository.findByName(pluginName)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.INTEGRATION_NOT_FOUND, pluginName));
-		return integrationRepository.findAllGlobalByType(integrationType)
-				.stream()
-				.map(TO_INTEGRATION_RESOURCE)
-				.collect(Collectors.toList());
-	}
-
-	@Override
-	public List<IntegrationResource> getProjectIntegrations(String projectName) {
-		Project project = projectRepository.findByName(projectName)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.PROJECT_NOT_FOUND, projectName));
-		return integrationRepository.findAllByProjectIdOrderByCreationDateDesc(project.getId()).stream().map(TO_INTEGRATION_RESOURCE).collect(Collectors.toList());
-	}
-
-	@Override
-	public List<IntegrationResource> getProjectIntegrations(String pluginName, String projectName) {
-		Project project = projectRepository.findByName(projectName)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.PROJECT_NOT_FOUND, projectName));
-		IntegrationType integrationType = integrationTypeRepository.findByName(pluginName)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.INTEGRATION_NOT_FOUND, pluginName));
-		return integrationRepository.findAllByProjectIdAndTypeOrderByCreationDateDesc(project.getId(), integrationType)
-				.stream()
-				.map(TO_INTEGRATION_RESOURCE)
-				.collect(Collectors.toList());
-	}
-
-	@Override
-	public boolean testConnection(Long integrationId, String projectName) {
-		Project project = projectRepository.findByName(projectName)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.PROJECT_NOT_FOUND, projectName));
-
-		Integration integration = integrationRepository.findByIdAndProjectId(integrationId, project.getId())
-				.orElseGet(() -> integrationRepository.findGlobalById(integrationId)
-						.orElseThrow(() -> new ReportPortalException(ErrorType.INTEGRATION_NOT_FOUND, integrationId)));
-
-		IntegrationService integrationService = integrationServiceMapping.getOrDefault(integration.getType().getName(),
-				this.basicIntegrationService
-		);
-		return integrationService.checkConnection(integration);
-	}
-
-	@Override
-	public boolean testConnection(Long integrationId) {
-		Integration integration = integrationRepository.findGlobalById(integrationId)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.INTEGRATION_NOT_FOUND, integrationId));
-
-		IntegrationService integrationService = integrationServiceMapping.getOrDefault(integration.getType().getName(),
-				this.basicIntegrationService
-		);
-		return integrationService.checkConnection(integration);
-	}
-
-	private Optional<Integration> getGlobalIntegrationByIntegrationTypeIds(List<Long> integrationTypeIds) {
-		return integrationRepository.findAllGlobalInIntegrationTypeIds(integrationTypeIds)
-				.stream()
-				.filter(integration -> integration.getType().isEnabled() && integration.isEnabled())
-				.findFirst();
-	}
-
-	private void validateIntegration(Integration integration) {
-		BusinessRule.expect(integration, i -> integration.getType().isEnabled())
-				.verify(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
-						Suppliers.formattedSupplier("'{}' type integrations are disabled by Administrator", integration.getType().getName())
-								.get()
-				);
-		BusinessRule.expect(integration, Integration::isEnabled)
-				.verify(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
-						Suppliers.formattedSupplier("Integration with ID = '{}' is disabled", integration.getId()).get()
-				);
-	}
+  private final Map<String, IntegrationService> integrationServiceMapping;
+  private final IntegrationService basicIntegrationService;
+  private final IntegrationRepository integrationRepository;
+  private final IntegrationTypeRepository integrationTypeRepository;
+  private final ProjectRepository projectRepository;
+  private final GetBugTrackingSystemHandler getBugTrackingSystemHandler;
+
+  @Autowired
+  public GetIntegrationHandlerImpl(
+      @Qualifier("integrationServiceMapping") Map<String, IntegrationService> integrationServiceMapping,
+      @Qualifier("basicIntegrationServiceImpl") IntegrationService integrationService,
+      IntegrationRepository integrationRepository,
+      IntegrationTypeRepository integrationTypeRepository, ProjectRepository projectRepository,
+      GetBugTrackingSystemHandler getBugTrackingSystemHandler) {
+    this.integrationServiceMapping = integrationServiceMapping;
+    this.basicIntegrationService = integrationService;
+    this.integrationRepository = integrationRepository;
+    this.integrationTypeRepository = integrationTypeRepository;
+    this.projectRepository = projectRepository;
+    this.getBugTrackingSystemHandler = getBugTrackingSystemHandler;
+  }
+
+  @Override
+  public IntegrationResource getProjectIntegrationById(Long integrationId, String projectName) {
+    Project project = projectRepository.findByName(projectName)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.PROJECT_NOT_FOUND, projectName));
+    Integration integration = integrationRepository.findByIdAndProjectId(integrationId,
+            project.getId())
+        .orElseThrow(
+            () -> new ReportPortalException(ErrorType.INTEGRATION_NOT_FOUND, integrationId));
+    return TO_INTEGRATION_RESOURCE.apply(integration);
+  }
+
+  @Override
+  public IntegrationResource getGlobalIntegrationById(Long integrationId) {
+    Integration integration = integrationRepository.findGlobalById(integrationId)
+        .orElseThrow(
+            () -> new ReportPortalException(ErrorType.INTEGRATION_NOT_FOUND, integrationId));
+    return TO_INTEGRATION_RESOURCE.apply(integration);
+  }
+
+  @Override
+  public Optional<Integration> getEnabledByProjectIdOrGlobalAndIntegrationGroup(Long projectId,
+      IntegrationGroupEnum integrationGroup) {
+
+    List<Long> integrationTypeIds = integrationTypeRepository.findAllByIntegrationGroup(
+            integrationGroup)
+        .stream()
+        .map(IntegrationType::getId)
+        .collect(Collectors.toList());
+
+    List<Integration> integrations = integrationRepository.findAllByProjectIdAndInIntegrationTypeIds(
+        projectId, integrationTypeIds);
+
+    if (!CollectionUtils.isEmpty(integrations)) {
+
+      return integrations.stream()
+          .filter(integration -> integration.getType().isEnabled() && integration.isEnabled())
+          .findFirst();
+
+    } else {
+
+      return getGlobalIntegrationByIntegrationTypeIds(integrationTypeIds);
+    }
+
+  }
+
+  @Override
+  public Integration getEnabledBtsIntegration(ReportPortalUser.ProjectDetails projectDetails,
+      String url, String btsProject) {
+
+    Project project = projectRepository.findById(projectDetails.getProjectId())
+        .orElseThrow(() -> new ReportPortalException(ErrorType.PROJECT_NOT_FOUND,
+            projectDetails.getProjectName()));
+
+    Integration integration = getBugTrackingSystemHandler.getEnabledProjectIntegration(
+            projectDetails, url, btsProject)
+        .orElseGet(() -> {
+          Integration globalIntegration = getBugTrackingSystemHandler.getEnabledGlobalIntegration(
+                  url, btsProject)
+              .orElseThrow(() -> new ReportPortalException(ErrorType.INTEGRATION_NOT_FOUND, url));
+
+          IntegrationValidator.validateProjectLevelIntegrationConstraints(project,
+              globalIntegration);
+
+          return globalIntegration;
+        });
+    validateIntegration(integration);
+    return integration;
+  }
+
+  @Override
+  public Integration getEnabledBtsIntegration(ReportPortalUser.ProjectDetails projectDetails,
+      Long integrationId) {
+
+    Project project = projectRepository.findById(projectDetails.getProjectId())
+        .orElseThrow(() -> new ReportPortalException(ErrorType.PROJECT_NOT_FOUND,
+            projectDetails.getProjectName()));
+
+    Integration integration = getBugTrackingSystemHandler.getEnabledProjectIntegration(
+        projectDetails, integrationId).orElseGet(() -> {
+      Integration globalIntegration = getBugTrackingSystemHandler.getEnabledGlobalIntegration(
+              integrationId)
+          .orElseThrow(
+              () -> new ReportPortalException(ErrorType.INTEGRATION_NOT_FOUND, integrationId));
+
+      IntegrationValidator.validateProjectLevelIntegrationConstraints(project, globalIntegration);
+
+      return globalIntegration;
+    });
+    validateIntegration(integration);
+    return integration;
+  }
+
+  @Override
+  public Integration getEnabledBtsIntegration(Long integrationId) {
+
+    Integration globalIntegration = getBugTrackingSystemHandler.getEnabledGlobalIntegration(
+            integrationId)
+        .orElseThrow(
+            () -> new ReportPortalException(ErrorType.INTEGRATION_NOT_FOUND, integrationId));
+
+    return globalIntegration;
+  }
+
+  @Override
+  public List<IntegrationResource> getGlobalIntegrations() {
+    return integrationRepository.findAllGlobal().stream().map(TO_INTEGRATION_RESOURCE)
+        .collect(Collectors.toList());
+  }
+
+  @Override
+  public List<IntegrationResource> getGlobalIntegrations(String pluginName) {
+    IntegrationType integrationType = integrationTypeRepository.findByName(pluginName)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.INTEGRATION_NOT_FOUND, pluginName));
+    return integrationRepository.findAllGlobalByType(integrationType)
+        .stream()
+        .map(TO_INTEGRATION_RESOURCE)
+        .collect(Collectors.toList());
+  }
+
+  @Override
+  public List<IntegrationResource> getProjectIntegrations(String projectName) {
+    Project project = projectRepository.findByName(projectName)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.PROJECT_NOT_FOUND, projectName));
+    return integrationRepository.findAllByProjectIdOrderByCreationDateDesc(project.getId()).stream()
+        .map(TO_INTEGRATION_RESOURCE).collect(Collectors.toList());
+  }
+
+  @Override
+  public List<IntegrationResource> getProjectIntegrations(String pluginName, String projectName) {
+    Project project = projectRepository.findByName(projectName)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.PROJECT_NOT_FOUND, projectName));
+    IntegrationType integrationType = integrationTypeRepository.findByName(pluginName)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.INTEGRATION_NOT_FOUND, pluginName));
+    return integrationRepository.findAllByProjectIdAndTypeOrderByCreationDateDesc(project.getId(),
+            integrationType)
+        .stream()
+        .map(TO_INTEGRATION_RESOURCE)
+        .collect(Collectors.toList());
+  }
+
+  @Override
+  public boolean testConnection(Long integrationId, String projectName) {
+    Project project = projectRepository.findByName(projectName)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.PROJECT_NOT_FOUND, projectName));
+
+    Integration integration = integrationRepository.findByIdAndProjectId(integrationId,
+            project.getId())
+        .orElseGet(() -> integrationRepository.findGlobalById(integrationId)
+            .orElseThrow(
+                () -> new ReportPortalException(ErrorType.INTEGRATION_NOT_FOUND, integrationId)));
+
+    IntegrationService integrationService = integrationServiceMapping.getOrDefault(
+        integration.getType().getName(),
+        this.basicIntegrationService
+    );
+    return integrationService.checkConnection(integration);
+  }
+
+  @Override
+  public boolean testConnection(Long integrationId) {
+    Integration integration = integrationRepository.findGlobalById(integrationId)
+        .orElseThrow(
+            () -> new ReportPortalException(ErrorType.INTEGRATION_NOT_FOUND, integrationId));
+
+    IntegrationService integrationService = integrationServiceMapping.getOrDefault(
+        integration.getType().getName(),
+        this.basicIntegrationService
+    );
+    return integrationService.checkConnection(integration);
+  }
+
+  private Optional<Integration> getGlobalIntegrationByIntegrationTypeIds(
+      List<Long> integrationTypeIds) {
+    return integrationRepository.findAllGlobalInIntegrationTypeIds(integrationTypeIds)
+        .stream()
+        .filter(integration -> integration.getType().isEnabled() && integration.isEnabled())
+        .findFirst();
+  }
+
+  private void validateIntegration(Integration integration) {
+    BusinessRule.expect(integration, i -> integration.getType().isEnabled())
+        .verify(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
+            Suppliers.formattedSupplier("'{}' type integrations are disabled by Administrator",
+                    integration.getType().getName())
+                .get()
+        );
+    BusinessRule.expect(integration, Integration::isEnabled)
+        .verify(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
+            Suppliers.formattedSupplier("Integration with ID = '{}' is disabled",
+                integration.getId()).get()
+        );
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/integration/plugin/GetPluginHandler.java b/src/main/java/com/epam/ta/reportportal/core/integration/plugin/GetPluginHandler.java
index d7b69ce4cd..0e3eaece79 100644
--- a/src/main/java/com/epam/ta/reportportal/core/integration/plugin/GetPluginHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/integration/plugin/GetPluginHandler.java
@@ -17,7 +17,6 @@
 package com.epam.ta.reportportal.core.integration.plugin;
 
 import com.epam.ta.reportportal.ws.model.integration.IntegrationTypeResource;
-
 import java.util.List;
 
 /**
@@ -25,11 +24,18 @@
  */
 public interface GetPluginHandler {
 
-	/**
-	 * Get a list of all existing plugins
-	 *
-	 * @return {@link List} of the {@link IntegrationTypeResource}
-	 */
-	List<IntegrationTypeResource> getPlugins();
+  /**
+   * Get a list of all existing plugins
+   *
+   * @return {@link List} of the {@link IntegrationTypeResource}
+   */
+  List<IntegrationTypeResource> getPlugins();
+
+  /**
+   * Get a list of all existing public plugins
+   *
+   * @return {@link List} of the {@link IntegrationTypeResource}
+   */
+  List<IntegrationTypeResource> getPublicPlugins();
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/integration/plugin/PluginLoader.java b/src/main/java/com/epam/ta/reportportal/core/integration/plugin/PluginLoader.java
index b170d4f8d3..602a523b32 100644
--- a/src/main/java/com/epam/ta/reportportal/core/integration/plugin/PluginLoader.java
+++ b/src/main/java/com/epam/ta/reportportal/core/integration/plugin/PluginLoader.java
@@ -19,91 +19,99 @@
 import com.epam.ta.reportportal.core.plugin.PluginInfo;
 import com.epam.ta.reportportal.entity.integration.IntegrationTypeDetails;
 import com.epam.ta.reportportal.exception.ReportPortalException;
-import org.pf4j.PluginException;
-import org.pf4j.PluginWrapper;
-
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.file.Path;
+import org.pf4j.PluginException;
+import org.pf4j.PluginWrapper;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public interface PluginLoader {
 
-	/**
-	 * Extract info about the plugin from the provided path
-	 *
-	 * @param pluginPath Plugin's path
-	 * @return {@link PluginInfo} with {@link PluginInfo#getId()} and {@link PluginInfo#getVersion()}
-	 */
-	PluginInfo extractPluginInfo(Path pluginPath) throws PluginException;
+  /**
+   * Extract info about the plugin from the provided path
+   *
+   * @param pluginPath Plugin's path
+   * @return {@link PluginInfo} with {@link PluginInfo#getId()} and {@link PluginInfo#getVersion()}
+   * @throws PluginException if there is an issue in loading the plugin or the plugin is not found in the specified path
+   */
+  PluginInfo extractPluginInfo(Path pluginPath) throws PluginException;
 
-	/**
-	 * Creates the {@link IntegrationTypeDetails} object based on the params of the plugin
-	 *
-	 * @param pluginInfo {@link PluginInfo} with {@link PluginInfo#getId()} and {@link PluginInfo#getVersion()}
-	 * @return {@link IntegrationTypeDetails}
-	 */
-	IntegrationTypeDetails resolvePluginDetails(PluginInfo pluginInfo);
+  /**
+   * Creates the {@link IntegrationTypeDetails} object based on the params of the plugin
+   *
+   * @param pluginInfo {@link PluginInfo} with {@link PluginInfo#getId()} and
+   *                   {@link PluginInfo#getVersion()}
+   * @return {@link IntegrationTypeDetails}
+   */
+  IntegrationTypeDetails resolvePluginDetails(PluginInfo pluginInfo);
 
-	/**
-	 * Validate the plugin with {@link com.epam.reportportal.extension.common.ExtensionPoint}
-	 * on the presence of the mandatory extension class/classes
-	 *
-	 * @param plugin {@link PluginWrapper}
-	 * @return true if the plugin has mandatory extension class/classes, else false
-	 */
-	boolean validatePluginExtensionClasses(PluginWrapper plugin);
+  /**
+   * Validate the plugin with {@link com.epam.reportportal.extension.common.ExtensionPoint} on the
+   * presence of the mandatory extension class/classes
+   *
+   * @param plugin {@link PluginWrapper}
+   * @return true if the plugin has mandatory extension class/classes, else false
+   */
+  boolean validatePluginExtensionClasses(PluginWrapper plugin);
 
-	/**
-	 * Save plugin in the {@link com.epam.ta.reportportal.filesystem.DataStore}
-	 *
-	 * @param fileName   New plugin file name
-	 * @param fileStream {@link InputStream} of the new plugin file
-	 * @return File id of the saved file in the file system
-	 * @throws ReportPortalException
-	 */
-	String saveToDataStore(String fileName, InputStream fileStream) throws ReportPortalException;
+  /**
+   * Save plugin in the {@link com.epam.ta.reportportal.filesystem.DataStore}
+   *
+   * @param fileName   New plugin file name
+   * @param fileStream {@link InputStream} of the new plugin file
+   * @return File id of the saved file in the file system
+   * @throws ReportPortalException if can't save data
+   */
+  String saveToDataStore(String fileName, InputStream fileStream) throws ReportPortalException;
 
-	/**
-	 * Upload plugin file to the directory.
-	 *
-	 * @param pluginPath Path to save plugin file
-	 * @param fileStream {@link InputStream} of the plugin file
-	 */
-	void savePlugin(Path pluginPath, InputStream fileStream) throws IOException;
+  /**
+   * Upload plugin file to the directory.
+   *
+   * @param pluginPath Path to save plugin file
+   * @param fileStream {@link InputStream} of the plugin file
+   * @throws IOException if can't save plugin
+   */
+  void savePlugin(Path pluginPath, InputStream fileStream) throws IOException;
 
-	/**
-	 * Copy plugin with resources from the {@link com.epam.ta.reportportal.filesystem.DataStore} to the provided path
-	 *
-	 * @param fileId              {@link com.epam.ta.reportportal.core.integration.util.property.IntegrationDetailsProperties#FILE_ID} value
-	 * @param pluginPath          Path where to copy plugin file
-	 * @param pluginResourcesPath Path were to copy plugin resources
-	 */
-	void copyFromDataStore(String fileId, Path pluginPath, Path pluginResourcesPath) throws IOException;
+  /**
+   * Copy plugin with resources from the {@link com.epam.ta.reportportal.filesystem.DataStore} to
+   * the provided path
+   *
+   * @param fileId              value
+   * @param pluginPath          Path where to copy plugin file
+   * @param pluginResourcesPath Path were to copy plugin resources
+   * @throws IOException in case errors due coping
+   */
+  void copyFromDataStore(String fileId, Path pluginPath, Path pluginResourcesPath)
+      throws IOException;
 
-	/**
-	 * Delete plugin file from the {@link com.epam.ta.reportportal.filesystem.DataStore}
-	 *
-	 * @param fileId {@link com.epam.ta.reportportal.core.integration.util.property.IntegrationDetailsProperties#FILE_ID} value
-	 */
-	void deleteFromDataStore(String fileId);
+  /**
+   * Delete plugin file from the {@link com.epam.ta.reportportal.filesystem.DataStore}
+   *
+   * @param fileId fileId of plugin
+   */
+  void deleteFromDataStore(String fileId);
 
-	/**
-	 * Copy plugin resources to the target path
-	 *
-	 * @param pluginPath          Plugin path in the filesystem
-	 * @param resourcesTargetPath Path to copy plugin resources
-	 * @throws IOException
-	 */
-	void copyPluginResource(Path pluginPath, Path resourcesTargetPath) throws IOException, ReportPortalException;
+  /**
+   * Copy plugin resources to the target path
+   *
+   * @param pluginPath          Plugin path in the filesystem
+   * @param resourcesTargetPath Path to copy plugin resources
+   * @throws IOException in case of errors due coping plugin
+   */
+  void copyPluginResource(Path pluginPath, Path resourcesTargetPath)
+      throws IOException, ReportPortalException;
 
-	/**
-	 * Remove the plugin file from the temporary directory and file name from the {@link com.epam.ta.reportportal.plugin.Pf4jPluginManager#uploadingPlugins}
-	 *
-	 * @param pluginFileDirectory Path to the temporary directory with the plugin file
-	 * @param pluginFileName      Name of the plugin file
-	 */
-	void deleteTempPlugin(String pluginFileDirectory, String pluginFileName) throws IOException;
+  /**
+   * Remove the plugin file from the temporary directory and file name from the
+   * {@link com.epam.ta.reportportal.plugin.Pf4jPluginManager#uploadingPlugins}
+   *
+   * @param pluginFileDirectory Path to the temporary directory with the plugin file
+   * @param pluginFileName      Name of the plugin file
+   * @throws IOException in case errors due deleting
+   */
+  void deleteTempPlugin(String pluginFileDirectory, String pluginFileName) throws IOException;
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/integration/plugin/binary/PluginFilesProvider.java b/src/main/java/com/epam/ta/reportportal/core/integration/plugin/binary/PluginFilesProvider.java
new file mode 100644
index 0000000000..20439cb983
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/core/integration/plugin/binary/PluginFilesProvider.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2022 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.core.integration.plugin.binary;
+
+import com.epam.ta.reportportal.dao.IntegrationTypeRepository;
+import com.epam.ta.reportportal.entity.attachment.BinaryData;
+import com.epam.ta.reportportal.entity.integration.IntegrationType;
+import com.epam.ta.reportportal.exception.ReportPortalException;
+import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Paths;
+import javax.activation.FileTypeMap;
+import org.apache.commons.io.FileUtils;
+
+/**
+ * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
+ */
+public class PluginFilesProvider {
+
+  private final String baseDirectory;
+  private final String folderQualifier;
+
+  private final FileTypeMap fileTypeResolver;
+
+  private final IntegrationTypeRepository integrationTypeRepository;
+
+  public PluginFilesProvider(String baseDirectory, String folderQualifier,
+      FileTypeMap fileTypeResolver,
+      IntegrationTypeRepository integrationTypeRepository) {
+    this.baseDirectory = baseDirectory;
+    this.folderQualifier = folderQualifier;
+    this.fileTypeResolver = fileTypeResolver;
+    this.integrationTypeRepository = integrationTypeRepository;
+  }
+
+  public BinaryData load(String pluginName, String fileName) {
+    final IntegrationType integrationType = integrationTypeRepository.findByName(pluginName)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.INTEGRATION_NOT_FOUND, pluginName));
+
+    final File file = Paths.get(baseDirectory, integrationType.getName(), folderQualifier, fileName)
+        .toFile();
+
+    if (!file.exists() || file.isDirectory()) {
+      throw new ReportPortalException(ErrorType.UNABLE_TO_LOAD_BINARY_DATA, fileName);
+    }
+
+    return getBinaryData(file);
+
+  }
+
+  private BinaryData getBinaryData(File file) {
+    try {
+      final InputStream fileStream = FileUtils.openInputStream(file);
+      final String contentType = fileTypeResolver.getContentType(file.getName());
+      return new BinaryData(contentType, (long) fileStream.available(), fileStream);
+    } catch (IOException e) {
+      throw new ReportPortalException(ErrorType.UNABLE_TO_LOAD_BINARY_DATA, e.getMessage());
+    }
+  }
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/integration/plugin/impl/GetPluginHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/integration/plugin/impl/GetPluginHandlerImpl.java
index 051b1eec57..1a0080020f 100644
--- a/src/main/java/com/epam/ta/reportportal/core/integration/plugin/impl/GetPluginHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/integration/plugin/impl/GetPluginHandlerImpl.java
@@ -20,11 +20,10 @@
 import com.epam.ta.reportportal.dao.IntegrationTypeRepository;
 import com.epam.ta.reportportal.ws.converter.converters.IntegrationTypeConverter;
 import com.epam.ta.reportportal.ws.model.integration.IntegrationTypeResource;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
 import java.util.List;
 import java.util.stream.Collectors;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -32,18 +31,28 @@
 @Service
 public class GetPluginHandlerImpl implements GetPluginHandler {
 
-	private final IntegrationTypeRepository integrationTypeRepository;
+  private static final String ACCESS_TYPE_PUBLIC_NAME = "public";
+
+  private final IntegrationTypeRepository integrationTypeRepository;
+
+  @Autowired
+  public GetPluginHandlerImpl(IntegrationTypeRepository integrationTypeRepository) {
+    this.integrationTypeRepository = integrationTypeRepository;
+  }
 
-	@Autowired
-	public GetPluginHandlerImpl(IntegrationTypeRepository integrationTypeRepository) {
-		this.integrationTypeRepository = integrationTypeRepository;
-	}
+  @Override
+  public List<IntegrationTypeResource> getPlugins() {
+    return integrationTypeRepository.findAllByOrderByCreationDate()
+        .stream()
+        .map(IntegrationTypeConverter.TO_RESOURCE)
+        .collect(Collectors.toList());
+  }
 
-	@Override
-	public List<IntegrationTypeResource> getPlugins() {
-		return integrationTypeRepository.findAllByOrderByCreationDate()
-				.stream()
-				.map(IntegrationTypeConverter.TO_RESOURCE)
-				.collect(Collectors.toList());
-	}
+  @Override
+  public List<IntegrationTypeResource> getPublicPlugins() {
+    return integrationTypeRepository.findAllByAccessType(ACCESS_TYPE_PUBLIC_NAME)
+        .stream()
+        .map(IntegrationTypeConverter.TO_RESOURCE)
+        .collect(Collectors.toList());
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/integration/util/AzureIntegrationService.java b/src/main/java/com/epam/ta/reportportal/core/integration/util/AzureIntegrationService.java
index f9c27c6ee8..ab43693205 100644
--- a/src/main/java/com/epam/ta/reportportal/core/integration/util/AzureIntegrationService.java
+++ b/src/main/java/com/epam/ta/reportportal/core/integration/util/AzureIntegrationService.java
@@ -17,33 +17,34 @@
 
 import com.epam.ta.reportportal.core.plugin.PluginBox;
 import com.epam.ta.reportportal.dao.IntegrationRepository;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.Map;
-
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
  */
 @Service
 public class AzureIntegrationService extends BasicIntegrationServiceImpl {
 
-	private BtsIntegrationService btsIntegrationService;
+  private BtsIntegrationService btsIntegrationService;
 
-	@Autowired
-	public AzureIntegrationService(IntegrationRepository integrationRepository, PluginBox pluginBox,
-			BtsIntegrationService btsIntegrationService) {
-		super(integrationRepository, pluginBox);
-		this.btsIntegrationService = btsIntegrationService;
-	}
+  @Autowired
+  public AzureIntegrationService(IntegrationRepository integrationRepository, PluginBox pluginBox,
+      BtsIntegrationService btsIntegrationService) {
+    super(integrationRepository, pluginBox);
+    this.btsIntegrationService = btsIntegrationService;
+  }
 
-	@Override
-	public Map<String, Object> retrieveCreateParams(String integrationType, Map<String, Object> integrationParams) {
-		return btsIntegrationService.retrieveCreateParams(integrationType, integrationParams);
-	}
+  @Override
+  public Map<String, Object> retrieveCreateParams(String integrationType,
+      Map<String, Object> integrationParams) {
+    return btsIntegrationService.retrieveCreateParams(integrationType, integrationParams);
+  }
 
-	@Override
-	public Map<String, Object> retrieveUpdatedParams(String integrationType, Map<String, Object> integrationParams) {
-		return btsIntegrationService.retrieveUpdatedParams(integrationType, integrationParams);
-	}
+  @Override
+  public Map<String, Object> retrieveUpdatedParams(String integrationType,
+      Map<String, Object> integrationParams) {
+    return btsIntegrationService.retrieveUpdatedParams(integrationType, integrationParams);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/integration/util/BasicIntegrationServiceImpl.java b/src/main/java/com/epam/ta/reportportal/core/integration/util/BasicIntegrationServiceImpl.java
index 8e35ac35c4..fb79c653f6 100644
--- a/src/main/java/com/epam/ta/reportportal/core/integration/util/BasicIntegrationServiceImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/integration/util/BasicIntegrationServiceImpl.java
@@ -16,6 +16,9 @@
 
 package com.epam.ta.reportportal.core.integration.util;
 
+import static com.epam.ta.reportportal.ws.model.ErrorType.BAD_REQUEST_ERROR;
+import static java.util.Optional.ofNullable;
+
 import com.epam.reportportal.extension.CommonPluginCommand;
 import com.epam.reportportal.extension.PluginCommand;
 import com.epam.reportportal.extension.ReportPortalExtensionPoint;
@@ -27,15 +30,11 @@
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.converter.builders.IntegrationBuilder;
 import com.epam.ta.reportportal.ws.model.integration.IntegrationRQ;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
 import java.time.LocalDateTime;
 import java.util.Map;
 import java.util.Optional;
-
-import static com.epam.ta.reportportal.ws.model.ErrorType.BAD_REQUEST_ERROR;
-import static java.util.Optional.ofNullable;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
@@ -43,84 +42,102 @@
 @Service
 public class BasicIntegrationServiceImpl implements IntegrationService {
 
-	private static final String TEST_CONNECTION_COMMAND = "testConnection";
-	private static final String RETRIEVE_CREATE_PARAMS = "retrieveCreate";
-	private static final String RETRIEVE_UPDATED_PARAMS = "retrieveUpdated";
-
-	protected IntegrationRepository integrationRepository;
-
-	protected PluginBox pluginBox;
-
-	@Autowired
-	public BasicIntegrationServiceImpl(IntegrationRepository integrationRepository, PluginBox pluginBox) {
-		this.integrationRepository = integrationRepository;
-		this.pluginBox = pluginBox;
-	}
-
-	@Override
-	public Integration createIntegration(IntegrationRQ integrationRq, IntegrationType integrationType) {
-		return new IntegrationBuilder().withCreationDate(LocalDateTime.now())
-				.withType(integrationType)
-				.withEnabled(integrationRq.getEnabled())
-				.withName(integrationRq.getName())
-				.withParams(new IntegrationParams(retrieveCreateParams(integrationType.getName(), integrationRq.getIntegrationParams())))
-				.get();
-	}
-
-	@Override
-	public Integration updateIntegration(Integration integration, IntegrationRQ integrationRQ) {
-		Map<String, Object> validParams = retrieveUpdatedParams(integration.getType().getName(), integrationRQ.getIntegrationParams());
-		IntegrationParams combinedParams = getCombinedParams(integration, validParams);
-		integration.setParams(combinedParams);
-		ofNullable(integrationRQ.getEnabled()).ifPresent(integration::setEnabled);
-		ofNullable(integrationRQ.getName()).ifPresent(integration::setName);
-		return integration;
-	}
-
-	@Override
-	public Map<String, Object> retrieveCreateParams(String integrationType, Map<String, Object> integrationParams) {
-		final Optional<CommonPluginCommand<?>> pluginCommand = getCommonCommand(integrationType, RETRIEVE_CREATE_PARAMS);
-		if (pluginCommand.isPresent()) {
-			return (Map<String, Object>) pluginCommand.get().executeCommand(integrationParams);
-		}
-		return integrationParams;
-	}
-
-	@Override
-	public Map<String, Object> retrieveUpdatedParams(String integrationType, Map<String, Object> integrationParams) {
-		final Optional<CommonPluginCommand<?>> pluginCommand = getCommonCommand(integrationType, RETRIEVE_UPDATED_PARAMS);
-		if (pluginCommand.isPresent()) {
-			return (Map<String, Object>) pluginCommand.get().executeCommand(integrationParams);
-		}
-		return integrationParams;
-	}
-
-	@Override
-	public boolean checkConnection(Integration integration) {
-		final Optional<PluginCommand<?>> pluginCommand = getIntegrationCommand(integration.getType().getName(), TEST_CONNECTION_COMMAND);
-		if (pluginCommand.isPresent()) {
-			return (Boolean) pluginCommand.get().executeCommand(integration, integration.getParams().getParams());
-		}
-		return true;
-	}
-
-	private Optional<PluginCommand<?>> getIntegrationCommand(String integration, String commandName) {
-		ReportPortalExtensionPoint pluginInstance = pluginBox.getInstance(integration, ReportPortalExtensionPoint.class)
-				.orElseThrow(() -> new ReportPortalException(BAD_REQUEST_ERROR, "Plugin for {} isn't installed", integration));
-		return ofNullable(pluginInstance.getIntegrationCommand(commandName));
-	}
-
-	private Optional<CommonPluginCommand<?>> getCommonCommand(String integration, String commandName) {
-		ReportPortalExtensionPoint pluginInstance = pluginBox.getInstance(integration, ReportPortalExtensionPoint.class)
-				.orElseThrow(() -> new ReportPortalException(BAD_REQUEST_ERROR, "Plugin for {} isn't installed", integration));
-		return ofNullable(pluginInstance.getCommonCommand(commandName));
-	}
-
-	private IntegrationParams getCombinedParams(Integration integration, Map<String, Object> retrievedParams) {
-		if (integration.getParams() != null && integration.getParams().getParams() != null) {
-			integration.getParams().getParams().putAll(retrievedParams);
-			return integration.getParams();
-		}
-		return new IntegrationParams(retrievedParams);
-	}
+  private static final String TEST_CONNECTION_COMMAND = "testConnection";
+  private static final String RETRIEVE_CREATE_PARAMS = "retrieveCreate";
+  private static final String RETRIEVE_UPDATED_PARAMS = "retrieveUpdated";
+
+  protected IntegrationRepository integrationRepository;
+
+  protected PluginBox pluginBox;
+
+  @Autowired
+  public BasicIntegrationServiceImpl(IntegrationRepository integrationRepository,
+      PluginBox pluginBox) {
+    this.integrationRepository = integrationRepository;
+    this.pluginBox = pluginBox;
+  }
+
+  @Override
+  public Integration createIntegration(IntegrationRQ integrationRq,
+      IntegrationType integrationType) {
+    return new IntegrationBuilder().withCreationDate(LocalDateTime.now())
+        .withType(integrationType)
+        .withEnabled(integrationRq.getEnabled())
+        .withName(integrationRq.getName())
+        .withParams(new IntegrationParams(
+            retrieveCreateParams(integrationType.getName(), integrationRq.getIntegrationParams())))
+        .get();
+  }
+
+  @Override
+  public Integration updateIntegration(Integration integration, IntegrationRQ integrationRQ) {
+    Map<String, Object> validParams = retrieveUpdatedParams(integration.getType().getName(),
+        integrationRQ.getIntegrationParams());
+    IntegrationParams combinedParams = getCombinedParams(integration, validParams);
+    integration.setParams(combinedParams);
+    ofNullable(integrationRQ.getEnabled()).ifPresent(integration::setEnabled);
+    ofNullable(integrationRQ.getName()).ifPresent(integration::setName);
+    return integration;
+  }
+
+  @Override
+  public Map<String, Object> retrieveCreateParams(String integrationType,
+      Map<String, Object> integrationParams) {
+    final Optional<CommonPluginCommand<?>> pluginCommand = getCommonCommand(integrationType,
+        RETRIEVE_CREATE_PARAMS);
+    if (pluginCommand.isPresent()) {
+      return (Map<String, Object>) pluginCommand.get().executeCommand(integrationParams);
+    }
+    return integrationParams;
+  }
+
+  @Override
+  public Map<String, Object> retrieveUpdatedParams(String integrationType,
+      Map<String, Object> integrationParams) {
+    final Optional<CommonPluginCommand<?>> pluginCommand = getCommonCommand(integrationType,
+        RETRIEVE_UPDATED_PARAMS);
+    if (pluginCommand.isPresent()) {
+      return (Map<String, Object>) pluginCommand.get().executeCommand(integrationParams);
+    }
+    return integrationParams;
+  }
+
+  @Override
+  public boolean checkConnection(Integration integration) {
+    final Optional<PluginCommand<?>> pluginCommand = getIntegrationCommand(
+        integration.getType().getName(), TEST_CONNECTION_COMMAND);
+    if (pluginCommand.isPresent()) {
+      return (Boolean) pluginCommand.get()
+          .executeCommand(integration, integration.getParams().getParams());
+    }
+    return true;
+  }
+
+  private Optional<PluginCommand<?>> getIntegrationCommand(String integration, String commandName) {
+    ReportPortalExtensionPoint pluginInstance = pluginBox.getInstance(integration,
+            ReportPortalExtensionPoint.class)
+        .orElseThrow(
+            () -> new ReportPortalException(BAD_REQUEST_ERROR, "Plugin for {} isn't installed",
+                integration));
+    return ofNullable(pluginInstance.getIntegrationCommand(commandName));
+  }
+
+  private Optional<CommonPluginCommand<?>> getCommonCommand(String integration,
+      String commandName) {
+    ReportPortalExtensionPoint pluginInstance = pluginBox.getInstance(integration,
+            ReportPortalExtensionPoint.class)
+        .orElseThrow(
+            () -> new ReportPortalException(BAD_REQUEST_ERROR, "Plugin for {} isn't installed",
+                integration));
+    return ofNullable(pluginInstance.getCommonCommand(commandName));
+  }
+
+  private IntegrationParams getCombinedParams(Integration integration,
+      Map<String, Object> retrievedParams) {
+    if (integration.getParams() != null && integration.getParams().getParams() != null) {
+      integration.getParams().getParams().putAll(retrievedParams);
+      return integration.getParams();
+    }
+    return new IntegrationParams(retrievedParams);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/integration/util/BtsIntegrationService.java b/src/main/java/com/epam/ta/reportportal/core/integration/util/BtsIntegrationService.java
index 89952eb814..db252edcc9 100644
--- a/src/main/java/com/epam/ta/reportportal/core/integration/util/BtsIntegrationService.java
+++ b/src/main/java/com/epam/ta/reportportal/core/integration/util/BtsIntegrationService.java
@@ -15,6 +15,9 @@
  */
 package com.epam.ta.reportportal.core.integration.util;
 
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.ws.model.ErrorType.UNABLE_INTERACT_WITH_INTEGRATION;
+
 import com.epam.reportportal.extension.bugtracking.BtsExtension;
 import com.epam.ta.reportportal.commons.validation.Suppliers;
 import com.epam.ta.reportportal.core.integration.util.property.BtsProperties;
@@ -25,116 +28,129 @@
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.google.common.collect.Maps;
+import java.util.Map;
+import java.util.Optional;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang3.BooleanUtils;
 import org.jasypt.util.text.BasicTextEncryptor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.Map;
-import java.util.Optional;
-
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.ws.model.ErrorType.UNABLE_INTERACT_WITH_INTEGRATION;
-
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
  */
 @Service
 public class BtsIntegrationService extends BasicIntegrationServiceImpl {
 
-	private final BasicTextEncryptor basicTextEncryptor;
-
-	@Autowired
-	public BtsIntegrationService(IntegrationRepository integrationRepository, PluginBox pluginBox, BasicTextEncryptor basicTextEncryptor) {
-		super(integrationRepository, pluginBox);
-		this.basicTextEncryptor = basicTextEncryptor;
-	}
-
-	@Override
-	public Map<String, Object> retrieveCreateParams(String integrationType, Map<String, Object> integrationParams) {
-		expect(integrationParams, MapUtils::isNotEmpty).verify(ErrorType.BAD_REQUEST_ERROR, "No integration params provided");
-
-		Map<String, Object> resultParams = Maps.newHashMapWithExpectedSize(BtsProperties.values().length);
-
-		resultParams.put(BtsProperties.PROJECT.getName(),
-				BtsProperties.PROJECT.getParam(integrationParams)
-						.orElseThrow(() -> new ReportPortalException(UNABLE_INTERACT_WITH_INTEGRATION, "BTS project is not specified."))
-		);
-		resultParams.put(BtsProperties.URL.getName(),
-				BtsProperties.URL.getParam(integrationParams)
-						.orElseThrow(() -> new ReportPortalException(UNABLE_INTERACT_WITH_INTEGRATION, "BTS url is not specified."))
-		);
-
-		final String authName = BtsProperties.AUTH_TYPE.getParam(integrationParams)
-				.orElseThrow(() -> new ReportPortalException(UNABLE_INTERACT_WITH_INTEGRATION, "Auth type is not specified."));
-		retrieveAuthParams(integrationParams, resultParams, authName);
-		resultParams.put(BtsProperties.AUTH_TYPE.getName(), authName);
-
-		return resultParams;
-	}
-
-	@Override
-	public Map<String, Object> retrieveUpdatedParams(String integrationType, Map<String, Object> integrationParams) {
-		Map<String, Object> resultParams = Maps.newHashMapWithExpectedSize(integrationParams.size());
-
-		BtsProperties.URL.getParam(integrationParams)
-				.ifPresent(url -> resultParams.put(BtsProperties.URL.getName(), url));
-
-		BtsProperties.PROJECT.getParam(integrationParams)
-				.ifPresent(url -> resultParams.put(BtsProperties.PROJECT.getName(), url));
-
-		BtsProperties.AUTH_TYPE.getParam(integrationParams).ifPresent(authName -> {
-			retrieveAuthParams(integrationParams, resultParams, authName);
-			resultParams.put(BtsProperties.AUTH_TYPE.getName(), authName);
-		});
-
-		Optional.ofNullable(integrationParams.get("defectFormFields"))
-				.ifPresent(defectFormFields -> resultParams.put("defectFormFields", defectFormFields));
-
-		return resultParams;
-	}
-
-	@Override
-	public boolean checkConnection(Integration integration) {
-		BtsExtension extension = pluginBox.getInstance(integration.getType().getName(), BtsExtension.class)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
-						Suppliers.formattedSupplier("Could not find plugin with name '{}'.", integration.getType().getName()).get()
-				));
-		expect(extension.testConnection(integration), BooleanUtils::isTrue).verify(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
-				"Connection refused."
-		);
-		return true;
-	}
-
-	/**
-	 * Retrieves auth params based on auth type
-	 */
-	private Map<String, Object> retrieveAuthParams(Map<String, Object> integrationParams, Map<String, Object> resultParams,
-			String authName) {
-		AuthType authType = AuthType.findByName(authName)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.INCORRECT_AUTHENTICATION_TYPE, authName));
-		if (AuthType.BASIC.equals(authType)) {
-			resultParams.put(BtsProperties.USER_NAME.getName(),
-					BtsProperties.USER_NAME.getParam(integrationParams)
-							.orElseThrow(() -> new ReportPortalException(UNABLE_INTERACT_WITH_INTEGRATION,
-									"Username value is not specified"
-							))
-			);
-
-			String encryptedPassword = basicTextEncryptor.encrypt(BtsProperties.PASSWORD.getParam(integrationParams)
-					.orElseThrow(() -> new ReportPortalException(UNABLE_INTERACT_WITH_INTEGRATION, "Password value is not specified")));
-			resultParams.put(BtsProperties.PASSWORD.getName(), encryptedPassword);
-		} else if (AuthType.OAUTH.equals(authType)) {
-			final String encryptedAccessKey = basicTextEncryptor.encrypt(BtsProperties.OAUTH_ACCESS_KEY.getParam(integrationParams)
-					.orElseThrow(() -> new ReportPortalException(UNABLE_INTERACT_WITH_INTEGRATION, "AccessKey value is not specified")));
-			resultParams.put(BtsProperties.OAUTH_ACCESS_KEY.getName(), encryptedAccessKey);
-		} else {
-			throw new ReportPortalException(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
-					"Unsupported auth type for integration - " + authType.name()
-			);
-		}
-		return resultParams;
-	}
+  private final BasicTextEncryptor basicTextEncryptor;
+
+  @Autowired
+  public BtsIntegrationService(IntegrationRepository integrationRepository, PluginBox pluginBox,
+      BasicTextEncryptor basicTextEncryptor) {
+    super(integrationRepository, pluginBox);
+    this.basicTextEncryptor = basicTextEncryptor;
+  }
+
+  @Override
+  public Map<String, Object> retrieveCreateParams(String integrationType,
+      Map<String, Object> integrationParams) {
+    expect(integrationParams, MapUtils::isNotEmpty).verify(ErrorType.BAD_REQUEST_ERROR,
+        "No integration params provided");
+
+    Map<String, Object> resultParams = Maps.newHashMapWithExpectedSize(
+        BtsProperties.values().length);
+
+    resultParams.put(BtsProperties.PROJECT.getName(),
+        BtsProperties.PROJECT.getParam(integrationParams)
+            .orElseThrow(() -> new ReportPortalException(UNABLE_INTERACT_WITH_INTEGRATION,
+                "BTS project is not specified."))
+    );
+    resultParams.put(BtsProperties.URL.getName(),
+        BtsProperties.URL.getParam(integrationParams)
+            .orElseThrow(() -> new ReportPortalException(UNABLE_INTERACT_WITH_INTEGRATION,
+                "BTS url is not specified."))
+    );
+
+    final String authName = BtsProperties.AUTH_TYPE.getParam(integrationParams)
+        .orElseThrow(() -> new ReportPortalException(UNABLE_INTERACT_WITH_INTEGRATION,
+            "Auth type is not specified."));
+    retrieveAuthParams(integrationParams, resultParams, authName);
+    resultParams.put(BtsProperties.AUTH_TYPE.getName(), authName);
+
+    return resultParams;
+  }
+
+  @Override
+  public Map<String, Object> retrieveUpdatedParams(String integrationType,
+      Map<String, Object> integrationParams) {
+    Map<String, Object> resultParams = Maps.newHashMapWithExpectedSize(integrationParams.size());
+
+    BtsProperties.URL.getParam(integrationParams)
+        .ifPresent(url -> resultParams.put(BtsProperties.URL.getName(), url));
+
+    BtsProperties.PROJECT.getParam(integrationParams)
+        .ifPresent(url -> resultParams.put(BtsProperties.PROJECT.getName(), url));
+
+    BtsProperties.AUTH_TYPE.getParam(integrationParams).ifPresent(authName -> {
+      retrieveAuthParams(integrationParams, resultParams, authName);
+      resultParams.put(BtsProperties.AUTH_TYPE.getName(), authName);
+    });
+
+    Optional.ofNullable(integrationParams.get("defectFormFields"))
+        .ifPresent(defectFormFields -> resultParams.put("defectFormFields", defectFormFields));
+
+    return resultParams;
+  }
+
+  @Override
+  public boolean checkConnection(Integration integration) {
+    BtsExtension extension = pluginBox.getInstance(integration.getType().getName(),
+            BtsExtension.class)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
+            Suppliers.formattedSupplier("Could not find plugin with name '{}'.",
+                integration.getType().getName()).get()
+        ));
+    expect(extension.testConnection(integration), BooleanUtils::isTrue).verify(
+        ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
+        "Connection refused."
+    );
+    return true;
+  }
+
+  /**
+   * Retrieves auth params based on auth type
+   */
+  private Map<String, Object> retrieveAuthParams(Map<String, Object> integrationParams,
+      Map<String, Object> resultParams,
+      String authName) {
+    AuthType authType = AuthType.findByName(authName)
+        .orElseThrow(
+            () -> new ReportPortalException(ErrorType.INCORRECT_AUTHENTICATION_TYPE, authName));
+    if (AuthType.BASIC.equals(authType)) {
+      resultParams.put(BtsProperties.USER_NAME.getName(),
+          BtsProperties.USER_NAME.getParam(integrationParams)
+              .orElseThrow(() -> new ReportPortalException(UNABLE_INTERACT_WITH_INTEGRATION,
+                  "Username value is not specified"
+              ))
+      );
+
+      String encryptedPassword = basicTextEncryptor.encrypt(
+          BtsProperties.PASSWORD.getParam(integrationParams)
+              .orElseThrow(() -> new ReportPortalException(UNABLE_INTERACT_WITH_INTEGRATION,
+                  "Password value is not specified")));
+      resultParams.put(BtsProperties.PASSWORD.getName(), encryptedPassword);
+    } else if (AuthType.OAUTH.equals(authType)) {
+      final String encryptedAccessKey = basicTextEncryptor.encrypt(
+          BtsProperties.OAUTH_ACCESS_KEY.getParam(integrationParams)
+              .orElseThrow(() -> new ReportPortalException(UNABLE_INTERACT_WITH_INTEGRATION,
+                  "AccessKey value is not specified")));
+      resultParams.put(BtsProperties.OAUTH_ACCESS_KEY.getName(), encryptedAccessKey);
+    } else {
+      throw new ReportPortalException(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
+          "Unsupported auth type for integration - " + authType.name()
+      );
+    }
+    return resultParams;
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/integration/util/EmailServerIntegrationService.java b/src/main/java/com/epam/ta/reportportal/core/integration/util/EmailServerIntegrationService.java
index 5d17c6c42c..595012e21e 100644
--- a/src/main/java/com/epam/ta/reportportal/core/integration/util/EmailServerIntegrationService.java
+++ b/src/main/java/com/epam/ta/reportportal/core/integration/util/EmailServerIntegrationService.java
@@ -16,6 +16,12 @@
 
 package com.epam.ta.reportportal.core.integration.util;
 
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.fail;
+import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
+import static com.epam.ta.reportportal.ws.model.ErrorType.EMAIL_CONFIGURATION_IS_INCORRECT;
+import static com.epam.ta.reportportal.ws.model.ErrorType.FORBIDDEN_OPERATION;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.core.admin.ServerAdminHandlerImpl;
 import com.epam.ta.reportportal.core.plugin.PluginBox;
@@ -28,6 +34,9 @@
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.google.common.collect.Maps;
 import com.mchange.lang.IntegerUtils;
+import java.util.Map;
+import java.util.Optional;
+import javax.mail.MessagingException;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang3.BooleanUtils;
 import org.apache.commons.validator.routines.UrlValidator;
@@ -36,128 +45,131 @@
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
 
-import javax.mail.MessagingException;
-import java.util.Map;
-import java.util.Optional;
-
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.fail;
-import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
-import static com.epam.ta.reportportal.ws.model.ErrorType.EMAIL_CONFIGURATION_IS_INCORRECT;
-import static com.epam.ta.reportportal.ws.model.ErrorType.FORBIDDEN_OPERATION;
-import static java.util.Optional.ofNullable;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class EmailServerIntegrationService extends BasicIntegrationServiceImpl {
 
-	private static final Logger LOGGER = LoggerFactory.getLogger(ServerAdminHandlerImpl.class);
-
-	private final BasicTextEncryptor basicTextEncryptor;
-
-	private final MailServiceFactory emailServiceFactory;
-
-	public EmailServerIntegrationService(IntegrationRepository integrationRepository, PluginBox pluginBox,
-			BasicTextEncryptor basicTextEncryptor, MailServiceFactory emailServiceFactory) {
-		super(integrationRepository, pluginBox);
-		this.basicTextEncryptor = basicTextEncryptor;
-		this.emailServiceFactory = emailServiceFactory;
-	}
-
-	@Override
-	public Map<String, Object> retrieveCreateParams(String integrationType, Map<String, Object> integrationParams) {
-		BusinessRule.expect(integrationParams, MapUtils::isNotEmpty).verify(ErrorType.BAD_REQUEST_ERROR, "No integration params provided");
-
-		Map<String, Object> resultParams = Maps.newHashMapWithExpectedSize(EmailSettingsEnum.values().length);
-
-		Optional<String> fromAttribute = EmailSettingsEnum.FROM.getAttribute(integrationParams);
-
-		fromAttribute.ifPresent(from -> resultParams.put(EmailSettingsEnum.FROM.getAttribute(), from));
-
-		ofNullable(integrationParams.get(EmailSettingsEnum.PORT.getAttribute())).ifPresent(p -> {
-			int port = IntegerUtils.parseInt(String.valueOf(p), -1);
-			if ((port <= 0) || (port > 65535)) {
-				BusinessRule.fail().withError(ErrorType.INCORRECT_REQUEST, "Incorrect 'Port' value. Allowed value is [1..65535]");
-			}
-			resultParams.put(EmailSettingsEnum.PORT.getAttribute(), p);
-		});
-
-		EmailSettingsEnum.PROTOCOL.getAttribute(integrationParams)
-				.ifPresent(protocol -> resultParams.put(EmailSettingsEnum.PROTOCOL.getAttribute(), protocol));
-
-		ofNullable(integrationParams.get(EmailSettingsEnum.AUTH_ENABLED.getAttribute())).ifPresent(authEnabledAttribute -> {
-			boolean isAuthEnabled = BooleanUtils.toBoolean(String.valueOf(authEnabledAttribute));
-			if (isAuthEnabled) {
-				EmailSettingsEnum.USERNAME.getAttribute(integrationParams)
-						.ifPresent(username -> resultParams.put(EmailSettingsEnum.USERNAME.getAttribute(), username));
-				EmailSettingsEnum.PASSWORD.getAttribute(integrationParams)
-						.ifPresent(password -> resultParams.put(EmailSettingsEnum.PASSWORD.getAttribute(),
-								basicTextEncryptor.encrypt(password)
-						));
-			} else {
-				/* Auto-drop values on switched-off authentication */
-				resultParams.put(EmailSettingsEnum.USERNAME.getAttribute(), null);
-				resultParams.put(EmailSettingsEnum.PASSWORD.getAttribute(), null);
-			}
-			resultParams.put(EmailSettingsEnum.AUTH_ENABLED.getAttribute(), isAuthEnabled);
-		});
-
-		EmailSettingsEnum.STAR_TLS_ENABLED.getAttribute(integrationParams)
-				.ifPresent(attr -> resultParams.put(EmailSettingsEnum.STAR_TLS_ENABLED.getAttribute(), BooleanUtils.toBoolean(attr)));
-		EmailSettingsEnum.SSL_ENABLED.getAttribute(integrationParams)
-				.ifPresent(attr -> resultParams.put(EmailSettingsEnum.SSL_ENABLED.getAttribute(), BooleanUtils.toBoolean(attr)));
-		EmailSettingsEnum.HOST.getAttribute(integrationParams)
-				.ifPresent(attr -> resultParams.put(EmailSettingsEnum.HOST.getAttribute(), attr));
-		EmailSettingsEnum.RP_HOST.getAttribute(integrationParams)
-				.filter(UrlValidator.getInstance()::isValid)
-				.ifPresent(attr -> resultParams.put(EmailSettingsEnum.RP_HOST.getAttribute(), attr));
-
-		return resultParams;
-	}
-
-	@Override
-	public Map<String, Object> retrieveUpdatedParams(String integrationType, Map<String, Object> integrationParams) {
-		return retrieveCreateParams(integrationType, integrationParams);
-	}
-
-	@Override
-	public boolean checkConnection(Integration integration) {
-		Optional<EmailService> emailService = emailServiceFactory.getEmailService(integration);
-		if (emailService.isPresent()) {
-			try {
-				emailService.get().testConnection();
-			} catch (MessagingException ex) {
-				LOGGER.error("Cannot send email to user", ex);
-				fail().withError(FORBIDDEN_OPERATION,
-						"Email configuration is incorrect. Please, check your configuration. " + ex.getMessage()
-				);
-			}
-
-			// if an email integration is new and not saved at db yet - try to send a creation integration message
-			if (integration.getId() == null) {
-				try {
-					EmailSettingsEnum.AUTH_ENABLED.getAttribute(integration.getParams().getParams()).ifPresent(authEnabled -> {
-						if (BooleanUtils.toBoolean(authEnabled)) {
-							String sendTo = EmailSettingsEnum.USERNAME.getAttribute(integration.getParams().getParams())
-									.orElseThrow(() -> new ReportPortalException(EMAIL_CONFIGURATION_IS_INCORRECT,
-											"Email server username is not specified."
-									));
-							emailService.get().sendConnectionTestEmail(sendTo);
-						}
-					});
-				} catch (Exception ex) {
-					fail().withError(EMAIL_CONFIGURATION_IS_INCORRECT,
-							formattedSupplier("Unable to send connection test email. " + ex.getMessage())
-					);
-				}
-			}
-
-		} else {
-			return false;
-		}
-		return true;
-	}
+  private static final Logger LOGGER = LoggerFactory.getLogger(ServerAdminHandlerImpl.class);
+
+  private final BasicTextEncryptor basicTextEncryptor;
+
+  private final MailServiceFactory emailServiceFactory;
+
+  public EmailServerIntegrationService(IntegrationRepository integrationRepository,
+      PluginBox pluginBox,
+      BasicTextEncryptor basicTextEncryptor, MailServiceFactory emailServiceFactory) {
+    super(integrationRepository, pluginBox);
+    this.basicTextEncryptor = basicTextEncryptor;
+    this.emailServiceFactory = emailServiceFactory;
+  }
+
+  @Override
+  public Map<String, Object> retrieveCreateParams(String integrationType,
+      Map<String, Object> integrationParams) {
+    BusinessRule.expect(integrationParams, MapUtils::isNotEmpty)
+        .verify(ErrorType.BAD_REQUEST_ERROR, "No integration params provided");
+
+    Map<String, Object> resultParams = Maps.newHashMapWithExpectedSize(
+        EmailSettingsEnum.values().length);
+
+    Optional<String> fromAttribute = EmailSettingsEnum.FROM.getAttribute(integrationParams);
+
+    fromAttribute.ifPresent(from -> resultParams.put(EmailSettingsEnum.FROM.getAttribute(), from));
+
+    ofNullable(integrationParams.get(EmailSettingsEnum.PORT.getAttribute())).ifPresent(p -> {
+      int port = IntegerUtils.parseInt(String.valueOf(p), -1);
+      if ((port <= 0) || (port > 65535)) {
+        BusinessRule.fail().withError(ErrorType.INCORRECT_REQUEST,
+            "Incorrect 'Port' value. Allowed value is [1..65535]");
+      }
+      resultParams.put(EmailSettingsEnum.PORT.getAttribute(), p);
+    });
+
+    EmailSettingsEnum.PROTOCOL.getAttribute(integrationParams)
+        .ifPresent(
+            protocol -> resultParams.put(EmailSettingsEnum.PROTOCOL.getAttribute(), protocol));
+
+    EmailSettingsEnum.USERNAME.getAttribute(integrationParams)
+        .ifPresent(
+            username -> resultParams.put(EmailSettingsEnum.USERNAME.getAttribute(), username));
+
+    ofNullable(integrationParams.get(EmailSettingsEnum.AUTH_ENABLED.getAttribute())).ifPresent(
+        authEnabledAttribute -> {
+          boolean isAuthEnabled = BooleanUtils.toBoolean(String.valueOf(authEnabledAttribute));
+          if (isAuthEnabled) {
+            EmailSettingsEnum.PASSWORD.getAttribute(integrationParams)
+                .ifPresent(password -> resultParams.put(EmailSettingsEnum.PASSWORD.getAttribute(),
+                    basicTextEncryptor.encrypt(password)
+                ));
+          } else {
+            /* Auto-drop values on switched-off authentication */
+            resultParams.put(EmailSettingsEnum.PASSWORD.getAttribute(), null);
+          }
+          resultParams.put(EmailSettingsEnum.AUTH_ENABLED.getAttribute(), isAuthEnabled);
+        });
+
+    EmailSettingsEnum.STAR_TLS_ENABLED.getAttribute(integrationParams)
+        .ifPresent(attr -> resultParams.put(EmailSettingsEnum.STAR_TLS_ENABLED.getAttribute(),
+            BooleanUtils.toBoolean(attr)));
+    EmailSettingsEnum.SSL_ENABLED.getAttribute(integrationParams)
+        .ifPresent(attr -> resultParams.put(EmailSettingsEnum.SSL_ENABLED.getAttribute(),
+            BooleanUtils.toBoolean(attr)));
+    EmailSettingsEnum.HOST.getAttribute(integrationParams)
+        .ifPresent(attr -> resultParams.put(EmailSettingsEnum.HOST.getAttribute(), attr));
+    EmailSettingsEnum.RP_HOST.getAttribute(integrationParams)
+        .filter(UrlValidator.getInstance()::isValid)
+        .ifPresent(attr -> resultParams.put(EmailSettingsEnum.RP_HOST.getAttribute(), attr));
+
+    return resultParams;
+  }
+
+  @Override
+  public Map<String, Object> retrieveUpdatedParams(String integrationType,
+      Map<String, Object> integrationParams) {
+    return retrieveCreateParams(integrationType, integrationParams);
+  }
+
+  @Override
+  public boolean checkConnection(Integration integration) {
+    Optional<EmailService> emailService = emailServiceFactory.getEmailService(integration);
+    if (emailService.isPresent()) {
+      try {
+        emailService.get().testConnection();
+      } catch (MessagingException ex) {
+        LOGGER.error("Cannot send email to user", ex);
+        fail().withError(FORBIDDEN_OPERATION,
+            "Email configuration is incorrect. Please, check your configuration. " + ex.getMessage()
+        );
+      }
+
+      // if an email integration is new and not saved at db yet - try to send a creation integration message
+      if (integration.getId() == null) {
+        try {
+          EmailSettingsEnum.AUTH_ENABLED.getAttribute(integration.getParams().getParams())
+              .ifPresent(authEnabled -> {
+                if (BooleanUtils.toBoolean(authEnabled)) {
+                  String sendTo = EmailSettingsEnum.USERNAME.getAttribute(
+                          integration.getParams().getParams())
+                      .orElseThrow(() -> new ReportPortalException(EMAIL_CONFIGURATION_IS_INCORRECT,
+                          "Email server username is not specified."
+                      ));
+                  emailService.get().sendConnectionTestEmail(sendTo);
+                }
+              });
+        } catch (Exception ex) {
+          fail().withError(EMAIL_CONFIGURATION_IS_INCORRECT,
+              formattedSupplier("Unable to send connection test email. " + ex.getMessage())
+          );
+        }
+      }
+
+    } else {
+      return false;
+    }
+    return true;
+  }
 
 }
 
diff --git a/src/main/java/com/epam/ta/reportportal/core/integration/util/IntegrationService.java b/src/main/java/com/epam/ta/reportportal/core/integration/util/IntegrationService.java
index 0c37f653fd..8aa41b60e7 100644
--- a/src/main/java/com/epam/ta/reportportal/core/integration/util/IntegrationService.java
+++ b/src/main/java/com/epam/ta/reportportal/core/integration/util/IntegrationService.java
@@ -19,7 +19,6 @@
 import com.epam.ta.reportportal.entity.integration.Integration;
 import com.epam.ta.reportportal.entity.integration.IntegrationType;
 import com.epam.ta.reportportal.ws.model.integration.IntegrationRQ;
-
 import java.util.Map;
 
 /**
@@ -27,14 +26,14 @@
  */
 public interface IntegrationService {
 
-	Integration createIntegration(IntegrationRQ integrationRq, IntegrationType integrationType);
+  Integration createIntegration(IntegrationRQ integrationRq, IntegrationType integrationType);
 
-	Integration updateIntegration(Integration integration, IntegrationRQ integrationRQ);
+  Integration updateIntegration(Integration integration, IntegrationRQ integrationRQ);
 
-	Map<String, Object> retrieveCreateParams(String integrationType, Map<String, Object> params);
+  Map<String, Object> retrieveCreateParams(String integrationType, Map<String, Object> params);
 
-	Map<String, Object> retrieveUpdatedParams(String integrationType, Map<String, Object> params);
+  Map<String, Object> retrieveUpdatedParams(String integrationType, Map<String, Object> params);
 
-	boolean checkConnection(Integration integration);
+  boolean checkConnection(Integration integration);
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/integration/util/SauceLabsIntegrationService.java b/src/main/java/com/epam/ta/reportportal/core/integration/util/SauceLabsIntegrationService.java
index 07516c2a7b..5e48b9d2b5 100644
--- a/src/main/java/com/epam/ta/reportportal/core/integration/util/SauceLabsIntegrationService.java
+++ b/src/main/java/com/epam/ta/reportportal/core/integration/util/SauceLabsIntegrationService.java
@@ -16,69 +16,76 @@
 
 package com.epam.ta.reportportal.core.integration.util;
 
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.core.integration.util.property.SauceLabsProperties.ACCESS_TOKEN;
+import static com.epam.ta.reportportal.core.integration.util.property.SauceLabsProperties.USERNAME;
+import static com.epam.ta.reportportal.ws.model.ErrorType.BAD_REQUEST_ERROR;
+
 import com.epam.ta.reportportal.core.plugin.PluginBox;
 import com.epam.ta.reportportal.dao.IntegrationRepository;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.google.common.collect.Maps;
+import java.util.HashMap;
+import java.util.Map;
 import org.apache.commons.collections4.MapUtils;
 import org.jasypt.util.text.BasicTextEncryptor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.HashMap;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.core.integration.util.property.SauceLabsProperties.ACCESS_TOKEN;
-import static com.epam.ta.reportportal.core.integration.util.property.SauceLabsProperties.USERNAME;
-import static com.epam.ta.reportportal.ws.model.ErrorType.BAD_REQUEST_ERROR;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @Service
 public class SauceLabsIntegrationService extends BasicIntegrationServiceImpl {
 
-	private final BasicTextEncryptor encryptor;
+  private final BasicTextEncryptor encryptor;
 
-	@Autowired
-	public SauceLabsIntegrationService(IntegrationRepository integrationRepository, PluginBox pluginBox, BasicTextEncryptor encryptor) {
-		super(integrationRepository, pluginBox);
-		this.encryptor = encryptor;
-	}
+  @Autowired
+  public SauceLabsIntegrationService(IntegrationRepository integrationRepository,
+      PluginBox pluginBox, BasicTextEncryptor encryptor) {
+    super(integrationRepository, pluginBox);
+    this.encryptor = encryptor;
+  }
 
-	@Override
-	public Map<String, Object> retrieveCreateParams(String integrationType, Map<String, Object> integrationParams) {
-		expect(integrationParams, MapUtils::isNotEmpty).verify(BAD_REQUEST_ERROR, "No integration params provided");
+  @Override
+  public Map<String, Object> retrieveCreateParams(String integrationType,
+      Map<String, Object> integrationParams) {
+    expect(integrationParams, MapUtils::isNotEmpty).verify(BAD_REQUEST_ERROR,
+        "No integration params provided");
 
-		final String encryptedToken = encryptor.encrypt(ACCESS_TOKEN.getParameter(integrationParams)
-				.orElseThrow(() -> new ReportPortalException(BAD_REQUEST_ERROR, "Access token value is not specified")));
-		final String username = USERNAME.getParameter(integrationParams)
-				.orElseThrow(() -> new ReportPortalException(BAD_REQUEST_ERROR, "Username value is not specified"));
+    final String encryptedToken = encryptor.encrypt(ACCESS_TOKEN.getParameter(integrationParams)
+        .orElseThrow(() -> new ReportPortalException(BAD_REQUEST_ERROR,
+            "Access token value is not specified")));
+    final String username = USERNAME.getParameter(integrationParams)
+        .orElseThrow(
+            () -> new ReportPortalException(BAD_REQUEST_ERROR, "Username value is not specified"));
 
-		HashMap<String, Object> result = Maps.newHashMapWithExpectedSize(integrationParams.size());
-		result.put(ACCESS_TOKEN.getName(), encryptedToken);
-		result.put(USERNAME.getName(), username);
+    HashMap<String, Object> result = Maps.newHashMapWithExpectedSize(integrationParams.size());
+    result.put(ACCESS_TOKEN.getName(), encryptedToken);
+    result.put(USERNAME.getName(), username);
 
-		integrationParams.entrySet()
-				.stream()
-				.filter(it -> !it.getKey().equals(ACCESS_TOKEN.getName()) && !it.getKey().equals(USERNAME.getName()))
-				.forEach(it -> result.put(it.getKey(), it.getValue()));
+    integrationParams.entrySet()
+        .stream()
+        .filter(it -> !it.getKey().equals(ACCESS_TOKEN.getName()) && !it.getKey()
+            .equals(USERNAME.getName()))
+        .forEach(it -> result.put(it.getKey(), it.getValue()));
 
-		return result;
-	}
+    return result;
+  }
 
-	@Override
-	public Map<String, Object> retrieveUpdatedParams(String integrationType, Map<String, Object> integrationParams) {
-		HashMap<String, Object> result = Maps.newHashMapWithExpectedSize(integrationParams.size());
-		ACCESS_TOKEN.getParameter(integrationParams)
-				.ifPresent(token -> result.put(ACCESS_TOKEN.getName(), encryptor.encrypt(token)));
-		USERNAME.getParameter(integrationParams)
-				.ifPresent(username -> result.put(USERNAME.getName(), username));
-		integrationParams.entrySet()
-				.stream()
-				.filter(it -> !it.getKey().equals(ACCESS_TOKEN.getName()) && !it.getKey().equals(USERNAME.getName()))
-				.forEach(it -> result.put(it.getKey(), it.getValue()));
-		return result;
-	}
+  @Override
+  public Map<String, Object> retrieveUpdatedParams(String integrationType,
+      Map<String, Object> integrationParams) {
+    HashMap<String, Object> result = Maps.newHashMapWithExpectedSize(integrationParams.size());
+    ACCESS_TOKEN.getParameter(integrationParams)
+        .ifPresent(token -> result.put(ACCESS_TOKEN.getName(), encryptor.encrypt(token)));
+    USERNAME.getParameter(integrationParams)
+        .ifPresent(username -> result.put(USERNAME.getName(), username));
+    integrationParams.entrySet()
+        .stream()
+        .filter(it -> !it.getKey().equals(ACCESS_TOKEN.getName()) && !it.getKey()
+            .equals(USERNAME.getName()))
+        .forEach(it -> result.put(it.getKey(), it.getValue()));
+    return result;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/integration/util/property/AuthProperties.java b/src/main/java/com/epam/ta/reportportal/core/integration/util/property/AuthProperties.java
index 5213a6f36c..aea36dc671 100644
--- a/src/main/java/com/epam/ta/reportportal/core/integration/util/property/AuthProperties.java
+++ b/src/main/java/com/epam/ta/reportportal/core/integration/util/property/AuthProperties.java
@@ -21,15 +21,15 @@
  */
 public enum AuthProperties {
 
-	MANAGER_PASSWORD("managerPassword");
+  MANAGER_PASSWORD("managerPassword");
 
-	private String name;
+  private String name;
 
-	AuthProperties(String name) {
-		this.name = name;
-	}
+  AuthProperties(String name) {
+    this.name = name;
+  }
 
-	public String getName() {
-		return name;
-	}
+  public String getName() {
+    return name;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/integration/util/property/BtsProperties.java b/src/main/java/com/epam/ta/reportportal/core/integration/util/property/BtsProperties.java
index 8a6e75233a..08f086e201 100644
--- a/src/main/java/com/epam/ta/reportportal/core/integration/util/property/BtsProperties.java
+++ b/src/main/java/com/epam/ta/reportportal/core/integration/util/property/BtsProperties.java
@@ -17,39 +17,38 @@
 package com.epam.ta.reportportal.core.integration.util.property;
 
 import com.epam.ta.reportportal.entity.integration.IntegrationParams;
-
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Optional;
 
 public enum BtsProperties {
 
-	USER_NAME("username"),
-	PASSWORD("password"),
-	API_TOKEN("apiToken"),
-	PROJECT("project"),
-	AUTH_TYPE("authType"),
-	OAUTH_ACCESS_KEY("oauthAccessKey"),
-	URL("url");
-
-	private final String name;
-
-	BtsProperties(String name) {
-		this.name = name;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public Optional<String> getParam(Map<String, Object> params) {
-		return Optional.ofNullable(params.get(this.name)).map(String::valueOf);
-	}
-
-	public void setParam(IntegrationParams params, String value) {
-		if (null == params.getParams()) {
-			params.setParams(new HashMap<>());
-		}
-		params.getParams().put(this.name, value);
-	}
+  USER_NAME("username"),
+  PASSWORD("password"),
+  API_TOKEN("apiToken"),
+  PROJECT("project"),
+  AUTH_TYPE("authType"),
+  OAUTH_ACCESS_KEY("oauthAccessKey"),
+  URL("url");
+
+  private final String name;
+
+  BtsProperties(String name) {
+    this.name = name;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public Optional<String> getParam(Map<String, Object> params) {
+    return Optional.ofNullable(params.get(this.name)).map(String::valueOf);
+  }
+
+  public void setParam(IntegrationParams params, String value) {
+    if (null == params.getParams()) {
+      params.setParams(new HashMap<>());
+    }
+    params.getParams().put(this.name, value);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/integration/util/property/SauceLabsProperties.java b/src/main/java/com/epam/ta/reportportal/core/integration/util/property/SauceLabsProperties.java
index c4fbe59e5c..b818237244 100644
--- a/src/main/java/com/epam/ta/reportportal/core/integration/util/property/SauceLabsProperties.java
+++ b/src/main/java/com/epam/ta/reportportal/core/integration/util/property/SauceLabsProperties.java
@@ -16,39 +16,38 @@
 
 package com.epam.ta.reportportal.core.integration.util.property;
 
-import com.epam.ta.reportportal.entity.integration.IntegrationParams;
+import static java.util.Optional.ofNullable;
 
+import com.epam.ta.reportportal.entity.integration.IntegrationParams;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Optional;
 
-import static java.util.Optional.ofNullable;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 public enum SauceLabsProperties {
-	USERNAME("username"),
-	ACCESS_TOKEN("accessToken");
+  USERNAME("username"),
+  ACCESS_TOKEN("accessToken");
 
-	private String name;
+  private String name;
 
-	SauceLabsProperties(String name) {
-		this.name = name;
-	}
+  SauceLabsProperties(String name) {
+    this.name = name;
+  }
 
-	public String getName() {
-		return name;
-	}
+  public String getName() {
+    return name;
+  }
 
-	public Optional<String> getParameter(Map<String, Object> parameters) {
-		return ofNullable(parameters.get(this.name)).map(String::valueOf);
-	}
+  public Optional<String> getParameter(Map<String, Object> parameters) {
+    return ofNullable(parameters.get(this.name)).map(String::valueOf);
+  }
 
-	public void setParameter(IntegrationParams params, String value) {
-		if (null == params.getParams()) {
-			params.setParams(new HashMap<>());
-		}
-		params.getParams().put(this.name, value);
-	}
+  public void setParameter(IntegrationParams params, String value) {
+    if (null == params.getParams()) {
+      params.setParams(new HashMap<>());
+    }
+    params.getParams().put(this.name, value);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/integration/util/validator/IntegrationValidator.java b/src/main/java/com/epam/ta/reportportal/core/integration/util/validator/IntegrationValidator.java
index dcc40e6e31..9ad4eea6b3 100644
--- a/src/main/java/com/epam/ta/reportportal/core/integration/util/validator/IntegrationValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/integration/util/validator/IntegrationValidator.java
@@ -16,50 +16,54 @@
 
 package com.epam.ta.reportportal.core.integration.util.validator;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.commons.validation.Suppliers;
 import com.epam.ta.reportportal.entity.integration.Integration;
 import com.epam.ta.reportportal.entity.integration.IntegrationType;
 import com.epam.ta.reportportal.entity.project.Project;
 import com.epam.ta.reportportal.ws.model.ErrorType;
-import org.apache.commons.lang3.StringUtils;
-
 import java.util.Objects;
-
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import org.apache.commons.lang3.StringUtils;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public final class IntegrationValidator {
 
-	private IntegrationValidator() {
-		//static only
-	}
+  private IntegrationValidator() {
+    //static only
+  }
 
-	/**
-	 * Validation fails if a project has at least one integration with the same type as the provided global integration has
-	 *
-	 * @param project     {@link Project}
-	 * @param integration {@link Integration} with {@link Integration#project == NULL}
-	 */
-	public static void validateProjectLevelIntegrationConstraints(Project project, Integration integration) {
+  /**
+   * Validation fails if a project has at least one integration with the same type as the provided
+   * global integration has
+   *
+   * @param project     {@link Project}
+   * @param integration {@link Integration} with {@link Integration#project == NULL}
+   */
+  public static void validateProjectLevelIntegrationConstraints(Project project,
+      Integration integration) {
 
-		BusinessRule.expect(integration.getProject(), Objects::isNull)
-				.verify(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
-						Suppliers.formattedSupplier("Integration with ID = '{}' is not global.", integration.getId())
-				);
+    BusinessRule.expect(integration.getProject(), Objects::isNull)
+        .verify(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
+            Suppliers.formattedSupplier("Integration with ID = '{}' is not global.",
+                integration.getId())
+        );
 
-		BusinessRule.expect(project.getIntegrations().stream().map(Integration::getType).noneMatch(it -> {
-			IntegrationType integrationType = integration.getType();
-			return it.getIntegrationGroup() == integrationType.getIntegrationGroup() && StringUtils.equalsIgnoreCase(it.getName(),
-					integrationType.getName());
-		}), equalTo(true))
-				.verify(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
-						Suppliers.formattedSupplier(
-								"Global integration with ID = '{}' has been found, but you cannot use it, because you have project-level integration(s) of that type",
-								integration.getId()
-						).get()
-				);
-	}
+    BusinessRule.expect(
+            project.getIntegrations().stream().map(Integration::getType).noneMatch(it -> {
+              IntegrationType integrationType = integration.getType();
+              return it.getIntegrationGroup() == integrationType.getIntegrationGroup()
+                  && StringUtils.equalsIgnoreCase(it.getName(),
+                  integrationType.getName());
+            }), equalTo(true))
+        .verify(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
+            Suppliers.formattedSupplier(
+                "Global integration with ID = '{}' has been found, but you cannot use it, because you have project-level integration(s) of that type",
+                integration.getId()
+            ).get()
+        );
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/DeleteTestItemHandler.java b/src/main/java/com/epam/ta/reportportal/core/item/DeleteTestItemHandler.java
index 6967fe3205..af63784c47 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/DeleteTestItemHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/DeleteTestItemHandler.java
@@ -18,7 +18,6 @@
 
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
-
 import java.util.Collection;
 import java.util.List;
 
@@ -30,24 +29,26 @@
  */
 public interface DeleteTestItemHandler {
 
-	/**
-	 * Delete test item by id.
-	 *
-	 * @param itemId         Item id
-	 * @param projectDetails Project Details
-	 * @param user           User
-	 * @return {@link OperationCompletionRS}
-	 */
-	OperationCompletionRS deleteTestItem(Long itemId, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user);
+  /**
+   * Delete test item by id.
+   *
+   * @param itemId         Item id
+   * @param projectDetails Project Details
+   * @param user           User
+   * @return {@link OperationCompletionRS}
+   */
+  OperationCompletionRS deleteTestItem(Long itemId, ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user);
 
-	/**
-	 * Delete list of items by ids.
-	 *
-	 * @param ids            Test item ids
-	 * @param projectDetails Project Details
-	 * @param user           User
-	 * @return {@link OperationCompletionRS}
-	 */
-	List<OperationCompletionRS> deleteTestItems(Collection<Long> ids, ReportPortalUser.ProjectDetails projectDetails,
-			ReportPortalUser user);
+  /**
+   * Delete list of items by ids.
+   *
+   * @param ids            Test item ids
+   * @param projectDetails Project Details
+   * @param user           User
+   * @return {@link OperationCompletionRS}
+   */
+  List<OperationCompletionRS> deleteTestItems(Collection<Long> ids,
+      ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user);
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/ExternalTicketHandler.java b/src/main/java/com/epam/ta/reportportal/core/item/ExternalTicketHandler.java
index 04a31fac88..98d67d87ad 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/ExternalTicketHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/ExternalTicketHandler.java
@@ -20,7 +20,6 @@
 import com.epam.ta.reportportal.entity.item.issue.IssueEntity;
 import com.epam.ta.reportportal.ws.model.issue.Issue;
 import com.epam.ta.reportportal.ws.model.item.UnlinkExternalIssueRQ;
-
 import java.util.List;
 import java.util.Set;
 
@@ -29,10 +28,12 @@
  */
 public interface ExternalTicketHandler {
 
-	void linkExternalTickets(String submitter, List<IssueEntity> issueEntities, List<Issue.ExternalSystemIssue> tickets);
+  void linkExternalTickets(String submitter, List<IssueEntity> issueEntities,
+      List<Issue.ExternalSystemIssue> tickets);
 
-	void unlinkExternalTickets(List<TestItem> items, UnlinkExternalIssueRQ request);
+  void unlinkExternalTickets(List<TestItem> items, UnlinkExternalIssueRQ request);
 
-	void updateLinking(String submitter, IssueEntity newEntity, Set<Issue.ExternalSystemIssue> externalTickets);
+  void updateLinking(String submitter, IssueEntity newEntity,
+      Set<Issue.ExternalSystemIssue> externalTickets);
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/FinishTestItemHandler.java b/src/main/java/com/epam/ta/reportportal/core/item/FinishTestItemHandler.java
index affd7e71f8..52a1671278 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/FinishTestItemHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/FinishTestItemHandler.java
@@ -28,15 +28,16 @@
  */
 public interface FinishTestItemHandler {
 
-	/**
-	 * Updates {@link com.epam.ta.reportportal.entity.item.TestItem} instance
-	 *
-	 * @param user              RQ principal
-	 * @param projectDetails    Project Details
-	 * @param testItemId        Test item ID
-	 * @param finishExecutionRQ Request with finish Test Item data
-	 * @return OperationCompletionRS
-	 */
-	OperationCompletionRS finishTestItem(ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails, String testItemId,
-			FinishTestItemRQ finishExecutionRQ);
+  /**
+   * Updates {@link com.epam.ta.reportportal.entity.item.TestItem} instance
+   *
+   * @param user              RQ principal
+   * @param projectDetails    Project Details
+   * @param testItemId        Test item ID
+   * @param finishExecutionRQ Request with finish Test Item data
+   * @return OperationCompletionRS
+   */
+  OperationCompletionRS finishTestItem(ReportPortalUser user,
+      ReportPortalUser.ProjectDetails projectDetails, String testItemId,
+      FinishTestItemRQ finishExecutionRQ);
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/GetTestItemHandler.java b/src/main/java/com/epam/ta/reportportal/core/item/GetTestItemHandler.java
index 19b44c52c1..a85cdc9a22 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/GetTestItemHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/GetTestItemHandler.java
@@ -26,11 +26,10 @@
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.ws.model.TestItemResource;
 import com.epam.ta.reportportal.ws.model.statistics.StatisticsResource;
-import org.springframework.data.domain.Pageable;
-
-import javax.annotation.Nullable;
 import java.util.List;
 import java.util.Map;
+import javax.annotation.Nullable;
+import org.springframework.data.domain.Pageable;
 
 /**
  * GET operations for {@link TestItem}
@@ -40,125 +39,147 @@
  */
 public interface GetTestItemHandler {
 
-	/**
-	 * Get {@link TestItem} instance
-	 *
-	 * @param testItemId     {@link TestItem#uuid}
-	 * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
-	 * @param user           {@link ReportPortalUser}
-	 * @return {@link TestItemResource}
-	 */
-	TestItemResource getTestItem(String testItemId, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user);
-
-	/**
-	 * Gets {@link TestItem} instances
-	 *
-	 * @param filter         {@link Filter}
-	 * @param pageable       {@link Pageable}
-	 * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
-	 * @param user           {@link ReportPortalUser}
-	 * @return {@link Iterable} of the {@link TestItemResource}
-	 */
-	Iterable<TestItemResource> getTestItems(Queryable filter, Pageable pageable, ReportPortalUser.ProjectDetails projectDetails,
-			ReportPortalUser user, @Nullable Long launchId, @Nullable Long filterId, boolean isLatest, int launchesLimit);
-
-	/**
-	 * Gets {@link TestItem} instances
-	 *
-	 * @param filter         {@link Filter}
-	 * @param pageable       {@link Pageable}
-	 * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
-	 * @param user           {@link ReportPortalUser}
-	 * @return {@link Iterable} of the {@link TestItemResource}
-	 */
-	Iterable<TestItemResource> getTestItemsByProvider(Queryable filter, Pageable pageable, ReportPortalUser.ProjectDetails projectDetails,
-			ReportPortalUser user, Map<String, String> params);
-
-	/**
-	 * Gets accumulated statistics of items by data provider
-	 *
-	 * @param filter         {@link Filter}
-	 * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
-	 * @return Accumulated statistics
-	 */
-	StatisticsResource getStatisticsByProvider(Queryable filter, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user,
-			Map<String, String> providerParams);
-
-	/**
-	 * Get tickets that contains a term as a part inside for specified launch
-	 *
-	 * @param launchId {@link com.epam.ta.reportportal.entity.launch.Launch#id}
-	 * @param term     part of {@link com.epam.ta.reportportal.entity.bts.Ticket#ticketId} to search
-	 * @return {@link List} of {@link com.epam.ta.reportportal.entity.bts.Ticket#ticketId}
-	 */
-	List<String> getTicketIds(Long launchId, String term);
-
-	/**
-	 * Get tickets that contains a term as a part inside for specified project
-	 *
-	 * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
-	 * @param term           part of {@link Ticket#getTicketId()} to search
-	 * @return {@link List} of {@link Ticket#getTicketId()}
-	 */
-	List<String> getTicketIds(ReportPortalUser.ProjectDetails projectDetails, String term);
-
-	/**
-	 * Get specified attribute keys of all test items and launches for project with provided id
-	 *
-	 * @param launchFilterId {@link UserFilter#getId()} fo the {@link com.epam.ta.reportportal.commons.querygen.FilterTarget#LAUNCH_TARGET}
-	 * @param isLatest       Flag defines whether all or latest launches launches will be included in the query condition
-	 * @param launchesLimit  Launches limit
-	 * @param projectDetails {@link ReportPortalUser.ProjectDetails}
-	 * @param keyPart        Part of the {@link ItemAttribute#getKey()} to search
-	 * @return {@link List} of the {@link ItemAttribute#getKey()}
-	 */
-	List<String> getAttributeKeys(Long launchFilterId, boolean isLatest, int launchesLimit, ReportPortalUser.ProjectDetails projectDetails,
-			String keyPart);
-
-	/**
-	 * Get specified attribute keys
-	 *
-	 * @param launchId {@link com.epam.ta.reportportal.entity.launch.Launch#id}
-	 * @param value    part of the {@link com.epam.ta.reportportal.entity.ItemAttribute#key} to search
-	 * @return {@link List} of the {@link com.epam.ta.reportportal.entity.ItemAttribute#key}
-	 */
-	List<String> getAttributeKeys(Long launchId, String value);
-
-	/**
-	 * Get specified attribute values
-	 *
-	 * @param launchId {@link com.epam.ta.reportportal.entity.launch.Launch#id}
-	 * @param value    part of the {@link com.epam.ta.reportportal.entity.ItemAttribute#value} to search
-	 * @return {@link List} of the {@link com.epam.ta.reportportal.entity.ItemAttribute#value}
-	 */
-	List<String> getAttributeValues(Long launchId, String key, String value);
-
-	/**
-	 * Get attributes keys of test items under launches with provided name
-	 * under {@link com.epam.ta.reportportal.entity.project.Project} specified by `projectDetails`
-	 *
-	 * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
-	 * @param launchName     {@link Launch#getName()}
-	 * @param keyPart        part of the {@link ItemAttribute#getKey()} to search
-	 * @return {@link List} of the {@link ItemAttribute#getKey()}
-	 */
-	List<String> getAttributeKeys(ReportPortalUser.ProjectDetails projectDetails, String launchName, String keyPart);
-
-	/**
-	 * Get attributes values of test items under launches with provided name
-	 * under {@link com.epam.ta.reportportal.entity.project.Project} specified by `projectDetails`
-	 *
-	 * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
-	 * @param launchName     {@link Launch#getName()}
-	 * @param key            {@link ItemAttribute#getKey()}
-	 * @param valuePart      part of the {@link ItemAttribute#getValue()} to search
-	 * @return {@link List} of the {@link ItemAttribute#getValue()}
-	 */
-	List<String> getAttributeValues(ReportPortalUser.ProjectDetails projectDetails, String launchName, String key, String valuePart);
-
-	/**
-	 * @param ids array of the {@link com.epam.ta.reportportal.entity.launch.Launch#id}
-	 * @return {@link List} of the {@link TestItemResource}
-	 */
-	List<TestItemResource> getTestItems(Long[] ids, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user);
+  /**
+   * Get {@link TestItem} instance
+   *
+   * @param testItemId     {@link TestItem#uuid}
+   * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
+   * @param user           {@link ReportPortalUser}
+   * @return {@link TestItemResource}
+   */
+  TestItemResource getTestItem(String testItemId, ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user);
+
+  /**
+   * Gets {@link TestItem} instances
+   *
+   * @param filter         {@link Filter}
+   * @param pageable       {@link Pageable}
+   * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
+   * @param user           {@link ReportPortalUser}
+   * @param launchId       Launch id
+   * @param filterId       Filter id
+   * @param isLatest       true if
+   * @param launchesLimit  response limit
+   * @return {@link Iterable} of the {@link TestItemResource}
+   */
+  Iterable<TestItemResource> getTestItems(Queryable filter, Pageable pageable,
+      ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user, @Nullable Long launchId, @Nullable Long filterId, boolean isLatest,
+      int launchesLimit);
+
+  /**
+   * Gets {@link TestItem} instances
+   *
+   * @param filter         {@link Filter}
+   * @param pageable       {@link Pageable}
+   * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
+   * @param user           {@link ReportPortalUser}
+   * @return {@link Iterable} of the {@link TestItemResource}
+   */
+  Iterable<TestItemResource> getTestItemsByProvider(Queryable filter, Pageable pageable,
+      ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user, Map<String, String> params);
+
+  /**
+   * Gets accumulated statistics of items by data provider
+   *
+   * @param filter         {@link Filter}
+   * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
+   * @param user           {@link ReportPortalUser}
+   * @return Accumulated statistics
+   */
+  StatisticsResource getStatisticsByProvider(Queryable filter,
+      ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user,
+      Map<String, String> providerParams);
+
+  /**
+   * Get tickets that contains a term as a part inside for specified launch
+   *
+   * @param launchId {@link com.epam.ta.reportportal.entity.launch.Launch#id}
+   * @param term     part of {@link com.epam.ta.reportportal.entity.bts.Ticket#ticketId} to search
+   * @return {@link List} of {@link com.epam.ta.reportportal.entity.bts.Ticket#ticketId}
+   */
+  List<String> getTicketIds(Long launchId, String term);
+
+  /**
+   * Get tickets that contains a term as a part inside for specified project
+   *
+   * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
+   * @param term           part of {@link Ticket#getTicketId()} to search
+   * @return {@link List} of {@link Ticket#getTicketId()}
+   */
+  List<String> getTicketIds(ReportPortalUser.ProjectDetails projectDetails, String term);
+
+  /**
+   * Get specified attribute keys of all test items and launches for project with provided id
+   *
+   * @param launchFilterId {@link UserFilter#getId()} fo the
+   *                       {@link
+   *                       com.epam.ta.reportportal.commons.querygen.FilterTarget#LAUNCH_TARGET}
+   * @param isLatest       Flag defines whether all or latest launches launches will be included in
+   *                       the query condition
+   * @param launchesLimit  Launches limit
+   * @param projectDetails {@link ReportPortalUser.ProjectDetails}
+   * @param keyPart        Part of the {@link ItemAttribute#getKey()} to search
+   * @return {@link List} of the {@link ItemAttribute#getKey()}
+   */
+  List<String> getAttributeKeys(Long launchFilterId, boolean isLatest, int launchesLimit,
+      ReportPortalUser.ProjectDetails projectDetails,
+      String keyPart);
+
+  /**
+   * Get specified attribute keys
+   *
+   * @param launchId {@link com.epam.ta.reportportal.entity.launch.Launch#id}
+   * @param value    part of the {@link com.epam.ta.reportportal.entity.ItemAttribute#key} to
+   *                 search
+   * @return {@link List} of the {@link com.epam.ta.reportportal.entity.ItemAttribute#key}
+   */
+  List<String> getAttributeKeys(Long launchId, String value);
+
+  /**
+   * Get specified attribute values
+   *
+   * @param launchId {@link com.epam.ta.reportportal.entity.launch.Launch#id}
+   * @param key      Attribute key to search
+   * @param value    part of the {@link com.epam.ta.reportportal.entity.ItemAttribute#value} to
+   *                 search
+   * @return {@link List} of the {@link com.epam.ta.reportportal.entity.ItemAttribute#value}
+   */
+  List<String> getAttributeValues(Long launchId, String key, String value);
+
+  /**
+   * Get attributes keys of test items under launches with provided name under
+   * {@link com.epam.ta.reportportal.entity.project.Project} specified by `projectDetails`
+   *
+   * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
+   * @param launchName     {@link Launch#getName()}
+   * @param keyPart        part of the {@link ItemAttribute#getKey()} to search
+   * @return {@link List} of the {@link ItemAttribute#getKey()}
+   */
+  List<String> getAttributeKeys(ReportPortalUser.ProjectDetails projectDetails, String launchName,
+      String keyPart);
+
+  /**
+   * Get attributes values of test items under launches with provided name under
+   * {@link com.epam.ta.reportportal.entity.project.Project} specified by `projectDetails`
+   *
+   * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
+   * @param launchName     {@link Launch#getName()}
+   * @param key            {@link ItemAttribute#getKey()}
+   * @param valuePart      part of the {@link ItemAttribute#getValue()} to search
+   * @return {@link List} of the {@link ItemAttribute#getValue()}
+   */
+  List<String> getAttributeValues(ReportPortalUser.ProjectDetails projectDetails, String launchName,
+      String key, String valuePart);
+
+  /**
+   * @param ids            array of the {@link com.epam.ta.reportportal.entity.launch.Launch#id}
+   * @param projectDetails {@link ReportPortalUser.ProjectDetails}
+   * @param user           {@link ReportPortalUser}
+   * @return {@link List} of the {@link TestItemResource}
+   */
+  List<TestItemResource> getTestItems(Long[] ids, ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/StartTestItemHandler.java b/src/main/java/com/epam/ta/reportportal/core/item/StartTestItemHandler.java
index 0ff27ea33e..af72cf97a3 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/StartTestItemHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/StartTestItemHandler.java
@@ -27,21 +27,26 @@
  */
 public interface StartTestItemHandler {
 
-	/**
-	 * Start Root item operation
-	 *
-	 * @param projectDetails Project Details
-	 * @param rq             Item details
-	 * @return ItemID and uniqueID of test item
-	 */
-	ItemCreatedRS startRootItem(ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails, StartTestItemRQ rq);
+  /**
+   * Start Root item operation
+   *
+   * @param user           {@link ReportPortalUser}
+   * @param projectDetails Project Details
+   * @param rq             Item details
+   * @return ItemID and uniqueID of test item
+   */
+  ItemCreatedRS startRootItem(ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails,
+      StartTestItemRQ rq);
 
-	/**
-	 * Start child item operation
-	 *
-	 * @param projectDetails Project Details
-	 * @param rq             Item details
-	 * @return ItemID and uniqueID of test item
-	 */
-	ItemCreatedRS startChildItem(ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails, StartTestItemRQ rq, String parentId);
+  /**
+   * Start child item operation
+   *
+   * @param user           {@link ReportPortalUser}
+   * @param projectDetails Project Details
+   * @param rq             Item details
+   * @param parentId       Id of parrent test item
+   * @return ItemID and uniqueID of test item
+   */
+  ItemCreatedRS startChildItem(ReportPortalUser user,
+      ReportPortalUser.ProjectDetails projectDetails, StartTestItemRQ rq, String parentId);
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/TestItemService.java b/src/main/java/com/epam/ta/reportportal/core/item/TestItemService.java
index b271b1f7cd..3a35654534 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/TestItemService.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/TestItemService.java
@@ -16,50 +16,51 @@
 
 package com.epam.ta.reportportal.core.item;
 
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.dao.LaunchRepository;
 import com.epam.ta.reportportal.dao.TestItemRepository;
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.Optional;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.Optional;
-
-import static java.util.Optional.ofNullable;
-
 /**
  * @author Konstantin Antipin
  */
 @Service
 public class TestItemService {
 
-	private final TestItemRepository testItemRepository;
+  private final TestItemRepository testItemRepository;
 
-	private final LaunchRepository launchRepository;
+  private final LaunchRepository launchRepository;
 
-	@Autowired
-	public TestItemService(TestItemRepository testItemRepository, LaunchRepository launchRepository) {
-		this.testItemRepository = testItemRepository;
-		this.launchRepository = launchRepository;
-	}
+  @Autowired
+  public TestItemService(TestItemRepository testItemRepository, LaunchRepository launchRepository) {
+    this.testItemRepository = testItemRepository;
+    this.launchRepository = launchRepository;
+  }
 
-	public Launch getEffectiveLaunch(TestItem testItem) {
+  public Launch getEffectiveLaunch(TestItem testItem) {
 
-		return ofNullable(testItem.getRetryOf()).map(retryParentId -> {
-			TestItem retryParent = testItemRepository.findById(retryParentId)
-					.orElseThrow(() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, testItem.getRetryOf()));
-			return getLaunch(retryParent);
-		}).orElseGet(() -> getLaunch(testItem)).orElseThrow(() -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND));
-	}
+    return ofNullable(testItem.getRetryOf()).map(retryParentId -> {
+          TestItem retryParent = testItemRepository.findById(retryParentId)
+              .orElseThrow(() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND,
+                  testItem.getRetryOf()));
+          return getLaunch(retryParent);
+        }).orElseGet(() -> getLaunch(testItem))
+        .orElseThrow(() -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND));
+  }
 
-	private Optional<Launch> getLaunch(TestItem testItem) {
-		return ofNullable(testItem.getLaunchId()).map(launchRepository::findById)
-				.orElseGet(() -> ofNullable(testItem.getParentId()).flatMap(testItemRepository::findById)
-						.map(TestItem::getLaunchId)
-						.map(launchRepository::findById)
-						.orElseThrow(() -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND)));
-	}
+  private Optional<Launch> getLaunch(TestItem testItem) {
+    return ofNullable(testItem.getLaunchId()).map(launchRepository::findById)
+        .orElseGet(() -> ofNullable(testItem.getParentId()).flatMap(testItemRepository::findById)
+            .map(TestItem::getLaunchId)
+            .map(launchRepository::findById)
+            .orElseThrow(() -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND)));
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/UpdateTestItemHandler.java b/src/main/java/com/epam/ta/reportportal/core/item/UpdateTestItemHandler.java
index c8a1870baa..8cb6dcbac9 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/UpdateTestItemHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/UpdateTestItemHandler.java
@@ -23,7 +23,6 @@
 import com.epam.ta.reportportal.ws.model.issue.Issue;
 import com.epam.ta.reportportal.ws.model.item.ExternalIssueRQ;
 import com.epam.ta.reportportal.ws.model.item.UpdateTestItemRQ;
-
 import java.util.List;
 
 /**
@@ -33,46 +32,53 @@
  */
 public interface UpdateTestItemHandler {
 
-	/**
-	 * Define TestItem issue (or list of issues)
-	 *
-	 * @param projectDetails Project Details
-	 * @param defineIssue    issues request data
-	 * @param user           user
-	 * @return list of defined issues for specified test items
-	 */
-	List<Issue> defineTestItemsIssues(ReportPortalUser.ProjectDetails projectDetails, DefineIssueRQ defineIssue, ReportPortalUser user);
+  /**
+   * Define TestItem issue (or list of issues)
+   *
+   * @param projectDetails Project Details
+   * @param defineIssue    issues request data
+   * @param user           user
+   * @return list of defined issues for specified test items
+   */
+  List<Issue> defineTestItemsIssues(ReportPortalUser.ProjectDetails projectDetails,
+      DefineIssueRQ defineIssue, ReportPortalUser user);
 
-	/**
-	 * Update specified test item
-	 *
-	 * @param projectDetails Project Details
-	 * @param itemId         test item ID
-	 * @param rq             update test item request data
-	 * @param user           request principal name
-	 * @return OperationCompletionRS
-	 */
-	OperationCompletionRS updateTestItem(ReportPortalUser.ProjectDetails projectDetails, Long itemId, UpdateTestItemRQ rq,
-			ReportPortalUser user);
+  /**
+   * Update specified test item
+   *
+   * @param projectDetails Project Details
+   * @param itemId         test item ID
+   * @param rq             update test item request data
+   * @param user           request principal name
+   * @return OperationCompletionRS
+   */
+  OperationCompletionRS updateTestItem(ReportPortalUser.ProjectDetails projectDetails, Long itemId,
+      UpdateTestItemRQ rq,
+      ReportPortalUser user);
 
-	/**
-	 * Add or remove external system issue link directly to the {@link com.epam.ta.reportportal.entity.item.TestItem}
-	 *
-	 * @param request        {@link ExternalIssueRQ}
-	 * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
-	 * @param user           {@link ReportPortalUser}
-	 * @return {@link List} of the {@link OperationCompletionRS}
-	 */
-	List<OperationCompletionRS> processExternalIssues(ExternalIssueRQ request, ReportPortalUser.ProjectDetails projectDetails,
-			ReportPortalUser user);
+  /**
+   * Add or remove external system issue link directly to the
+   * {@link com.epam.ta.reportportal.entity.item.TestItem}
+   *
+   * @param request        {@link ExternalIssueRQ}
+   * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
+   * @param user           {@link ReportPortalUser}
+   * @return {@link List} of the {@link OperationCompletionRS}
+   */
+  List<OperationCompletionRS> processExternalIssues(ExternalIssueRQ request,
+      ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user);
 
-	/**
-	 * Resets items issue to default state
-	 *
-	 * @param itemIds   The {@link List} of the {@link com.epam.ta.reportportal.entity.item.TestItemResults#itemId}
-	 * @param projectId Project id
-	 */
-	void resetItemsIssue(List<Long> itemIds, Long projectId, ReportPortalUser user);
+  /**
+   * Resets items issue to default state
+   *
+   * @param itemIds   The {@link List} of the
+   *                  {@link com.epam.ta.reportportal.entity.item.TestItemResults#itemId}
+   * @param projectId Project id
+   * @param user      {@link ReportPortalUser}
+   */
+  void resetItemsIssue(List<Long> itemIds, Long projectId, ReportPortalUser user);
 
-	OperationCompletionRS bulkInfoUpdate(BulkInfoUpdateRQ bulkUpdateRq, ReportPortalUser.ProjectDetails projectDetails);
+  OperationCompletionRS bulkInfoUpdate(BulkInfoUpdateRQ bulkUpdateRq,
+      ReportPortalUser.ProjectDetails projectDetails);
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/UpdateUniqueId.java b/src/main/java/com/epam/ta/reportportal/core/item/UpdateUniqueId.java
index 3cfb987f0f..96a07e9194 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/UpdateUniqueId.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/UpdateUniqueId.java
@@ -25,191 +25,191 @@
  */
 @Service
 class UpdateUniqueId {
-	//
-	//	private static final Logger LOGGER = LoggerFactory.getLogger(UpdateUniqueId.class);
-	//
-	//	private static final String COLLECTION = "generationCheckpoint";
-	//	private static final String CHECKPOINT = "checkpoint";
-	//	private static final String CHECKPOINT_ID = "testItemId";
-	//
-	//	private static final int BATCH_SIZE = 100;
-	//
-	//	private static final String SECRET = "auto:";
-	//
-	//	//launches cache
-	//	private static final Cache<String, Launch> launchCache = Caffeine.newBuilder().maximumSize(200).build();
-	//
-	//	@Autowired
-	//	private MongoOperations mongoOperations;
-	//
-	//	@Autowired
-	//	private TestItemRepository testItemRepository;
-	//
-	//	private static final AtomicBoolean STARTED = new AtomicBoolean();
-	//
-	//	@EventListener
-	//	public void onContextRefresh(ContextRefreshedEvent event) {
-	//		if (STARTED.compareAndSet(false, true)) {
-	//			if (mongoOperations.collectionExists(COLLECTION)) {
-	//				Executors.newSingleThreadExecutor().execute(this::generateForAll);
-	//			}
-	//		}
-	//	}
-	//
-	//	private void generateForAll() {
-	//		long forUpdate = mongoOperations.count(testItemQuery(), TestItem.class);
-	//		long update = 0;
-	//		boolean isOk;
-	//		String checkpoint = getLastCheckpoint();
-	//		//potential endless loop
-	//		do {
-	//			try (CloseableIterator<TestItem> itemIterator = getItemIterator(checkpoint)) {
-	//				List<TestItem> testItems = new ArrayList<>(BATCH_SIZE);
-	//				int counter = 0;
-	//				while (itemIterator.hasNext()) {
-	//					TestItem testItem = itemIterator.next();
-	//					if (testItem != null) {
-	//						boolean isRemoved = removeIfInvalid(testItem);
-	//						if (!isRemoved) {
-	//							if (checkpoint == null) {
-	//								checkpoint = testItem.getId();
-	//							}
-	//							String uniqueId = generate(testItem);
-	//							testItem.setUniqueId(uniqueId);
-	//							testItems.add(testItem);
-	//							if (testItems.size() == BATCH_SIZE || !itemIterator.hasNext()) {
-	//								createCheckpoint(checkpoint);
-	//								updateTestItems(testItems);
-	//								counter++;
-	//								if (counter == 1000) {
-	//									LOGGER.info("Generated uniqueId for " + update + " items. " + "It is " + ((update / (float) forUpdate)
-	//											* 100) + "% done");
-	//									counter = 0;
-	//								}
-	//								update += testItems.size();
-	//								testItems = new ArrayList<>(BATCH_SIZE);
-	//								checkpoint = null;
-	//							}
-	//						}
-	//					}
-	//				}
-	//				isOk = true;
-	//			} catch (Exception e) {
-	//				LOGGER.warn("Potential endless loop in reason of: ", e);
-	//				//continue generating uniqueId
-	//				isOk = false;
-	//			}
-	//		} while (!isOk);
-	//		STARTED.set(false);
-	//		mongoOperations.getCollection(COLLECTION).drop();
-	//		launchCache.cleanUp();
-	//		LOGGER.info("Generating uniqueId is done!");
-	//		indexUniqueIds();
-	//
-	//	}
-	//
-	//	private void indexUniqueIds() {
-	//		mongoOperations.indexOps(mongoOperations.getCollectionName(TestItem.class))
-	//				.ensureIndex(new Index().on("uniqueId", Sort.Direction.ASC));
-	//	}
-	//
-	//	private void updateTestItems(List<TestItem> testItems) {
-	//		BulkOperations bulk = mongoOperations.bulkOps(BulkOperations.BulkMode.UNORDERED, TestItem.class);
-	//		testItems.forEach(it -> {
-	//			Update update = new Update();
-	//			update.set("uniqueId", it.getUniqueId());
-	//			bulk.updateOne(query(where("_id").is(it.getId())), update);
-	//		});
-	//		bulk.execute();
-	//	}
-	//
-	//	private boolean removeIfInvalid(TestItem item) {
-	//		String launchRef = item.getLaunchRef();
-	//		if (launchRef == null) {
-	//			mongoOperations.remove(query(where("_id").is(item.getId())));
-	//		}
-	//
-	//		Launch launch = mongoOperations.findOne(launchQuery(launchRef), Launch.class);
-	//		if (launch == null) {
-	//			testItemRepository.delete(item.getId());
-	//			return true;
-	//		} else {
-	//			boolean exists = mongoOperations.exists(query(where("_id").is(launch.getProjectRef())), Project.class);
-	//			if (!exists) {
-	//				mongoOperations.remove(query(where("_id").is(launchRef)), Launch.class);
-	//				return true;
-	//			}
-	//		}
-	//		return false;
-	//	}
-	//
-	//	public String generate(TestItem testItem) {
-	//		String forEncoding = prepareForEncoding(testItem);
-	//		return SECRET + DigestUtils.md5Hex(forEncoding);
-	//	}
-	//
-	//	private String prepareForEncoding(TestItem testItem) {
-	//		// using cache for launches
-	//		Launch launch = launchCache.get(testItem.getLaunchRef(),
-	//				k -> mongoOperations.findOne(launchQuery(testItem.getLaunchRef()), Launch.class)
-	//		);
-	//
-	//		String launchName = launch.getName();
-	//		String projectName = launch.getProjectRef();
-	//
-	//		List<String> pathNames = getPathNames(testItem.getPath());
-	//		String itemName = testItem.getName();
-	//		StringJoiner joiner = new StringJoiner(";");
-	//		joiner.add(SECRET).add(projectName).add(launchName);
-	//		if (!CollectionUtils.isEmpty(pathNames)) {
-	//			joiner.add(pathNames.stream().collect(Collectors.joining(",")));
-	//		}
-	//		joiner.add(itemName);
-	//		List<Parameter> parameters = testItem.getParameters();
-	//		if (!CollectionUtils.isEmpty(parameters)) {
-	//			joiner.add(parameters.stream()
-	//					.map(parameter -> (!Strings.isNullOrEmpty(parameter.getKey()) ? parameter.getKey() + "=" : "") + parameter.getValue())
-	//					.collect(Collectors.joining(",")));
-	//		}
-	//		return joiner.toString();
-	//	}
-	//
-	//	private CloseableIterator<TestItem> getItemIterator(String checkpoint) {
-	//		Sort sort = new Sort(new Sort.Order(Sort.Direction.ASC, "_id"));
-	//		Query query = new Query().with(sort).noCursorTimeout();
-	//		if (checkpoint != null) {
-	//			query.addCriteria(where("_id").gte(new ObjectId(checkpoint)));
-	//		}
-	//		query.fields().include("name").include("path").include("launchRef").include("parameters");
-	//		return mongoOperations.stream(query, TestItem.class);
-	//	}
-	//
-	//	private List<String> getPathNames(List<String> path) {
-	//		Map<String, String> names = testItemRepository.findPathNames(path);
-	//		return path.stream().map(names::get).collect(Collectors.toList());
-	//	}
-	//
-	//	private Query launchQuery(String launchId) {
-	//		Query query = query((where("_id").is(launchId)));
-	//		query.fields().include("name");
-	//		query.fields().include("projectRef");
-	//		return query;
-	//	}
-	//
-	//	private Query testItemQuery() {
-	//		Query query = new Query();
-	//		query.fields().include("name").include("path").include("launchRef").include("parameters");
-	//		return query;
-	//	}
-	//
-	//	private String getLastCheckpoint() {
-	//		DBObject checkpoint = mongoOperations.getCollection(COLLECTION).findOne(new BasicDBObject("_id", CHECKPOINT));
-	//		return checkpoint == null ? null : (String) checkpoint.get(CHECKPOINT_ID);
-	//	}
-	//
-	//	private void createCheckpoint(String logId) {
-	//		BasicDBObject checkpoint = new BasicDBObject("_id", CHECKPOINT).append(CHECKPOINT_ID, logId);
-	//		mongoOperations.getCollection(COLLECTION).save(checkpoint);
-	//	}
+  //
+  //	private static final Logger LOGGER = LoggerFactory.getLogger(UpdateUniqueId.class);
+  //
+  //	private static final String COLLECTION = "generationCheckpoint";
+  //	private static final String CHECKPOINT = "checkpoint";
+  //	private static final String CHECKPOINT_ID = "testItemId";
+  //
+  //	private static final int BATCH_SIZE = 100;
+  //
+  //	private static final String SECRET = "auto:";
+  //
+  //	//launches cache
+  //	private static final Cache<String, Launch> launchCache = Caffeine.newBuilder().maximumSize(200).build();
+  //
+  //	@Autowired
+  //	private MongoOperations mongoOperations;
+  //
+  //	@Autowired
+  //	private TestItemRepository testItemRepository;
+  //
+  //	private static final AtomicBoolean STARTED = new AtomicBoolean();
+  //
+  //	@EventListener
+  //	public void onContextRefresh(ContextRefreshedEvent event) {
+  //		if (STARTED.compareAndSet(false, true)) {
+  //			if (mongoOperations.collectionExists(COLLECTION)) {
+  //				Executors.newSingleThreadExecutor().execute(this::generateForAll);
+  //			}
+  //		}
+  //	}
+  //
+  //	private void generateForAll() {
+  //		long forUpdate = mongoOperations.count(testItemQuery(), TestItem.class);
+  //		long update = 0;
+  //		boolean isOk;
+  //		String checkpoint = getLastCheckpoint();
+  //		//potential endless loop
+  //		do {
+  //			try (CloseableIterator<TestItem> itemIterator = getItemIterator(checkpoint)) {
+  //				List<TestItem> testItems = new ArrayList<>(BATCH_SIZE);
+  //				int counter = 0;
+  //				while (itemIterator.hasNext()) {
+  //					TestItem testItem = itemIterator.next();
+  //					if (testItem != null) {
+  //						boolean isRemoved = removeIfInvalid(testItem);
+  //						if (!isRemoved) {
+  //							if (checkpoint == null) {
+  //								checkpoint = testItem.getId();
+  //							}
+  //							String uniqueId = generate(testItem);
+  //							testItem.setUniqueId(uniqueId);
+  //							testItems.add(testItem);
+  //							if (testItems.size() == BATCH_SIZE || !itemIterator.hasNext()) {
+  //								createCheckpoint(checkpoint);
+  //								updateTestItems(testItems);
+  //								counter++;
+  //								if (counter == 1000) {
+  //									LOGGER.info("Generated uniqueId for " + update + " items. " + "It is " + ((update / (float) forUpdate)
+  //											* 100) + "% done");
+  //									counter = 0;
+  //								}
+  //								update += testItems.size();
+  //								testItems = new ArrayList<>(BATCH_SIZE);
+  //								checkpoint = null;
+  //							}
+  //						}
+  //					}
+  //				}
+  //				isOk = true;
+  //			} catch (Exception e) {
+  //				LOGGER.warn("Potential endless loop in reason of: ", e);
+  //				//continue generating uniqueId
+  //				isOk = false;
+  //			}
+  //		} while (!isOk);
+  //		STARTED.set(false);
+  //		mongoOperations.getCollection(COLLECTION).drop();
+  //		launchCache.cleanUp();
+  //		LOGGER.info("Generating uniqueId is done!");
+  //		indexUniqueIds();
+  //
+  //	}
+  //
+  //	private void indexUniqueIds() {
+  //		mongoOperations.indexOps(mongoOperations.getCollectionName(TestItem.class))
+  //				.ensureIndex(new Index().on("uniqueId", Sort.Direction.ASC));
+  //	}
+  //
+  //	private void updateTestItems(List<TestItem> testItems) {
+  //		BulkOperations bulk = mongoOperations.bulkOps(BulkOperations.BulkMode.UNORDERED, TestItem.class);
+  //		testItems.forEach(it -> {
+  //			Update update = new Update();
+  //			update.set("uniqueId", it.getUniqueId());
+  //			bulk.updateOne(query(where("_id").is(it.getId())), update);
+  //		});
+  //		bulk.execute();
+  //	}
+  //
+  //	private boolean removeIfInvalid(TestItem item) {
+  //		String launchRef = item.getLaunchRef();
+  //		if (launchRef == null) {
+  //			mongoOperations.remove(query(where("_id").is(item.getId())));
+  //		}
+  //
+  //		Launch launch = mongoOperations.findOne(launchQuery(launchRef), Launch.class);
+  //		if (launch == null) {
+  //			testItemRepository.delete(item.getId());
+  //			return true;
+  //		} else {
+  //			boolean exists = mongoOperations.exists(query(where("_id").is(launch.getProjectRef())), Project.class);
+  //			if (!exists) {
+  //				mongoOperations.remove(query(where("_id").is(launchRef)), Launch.class);
+  //				return true;
+  //			}
+  //		}
+  //		return false;
+  //	}
+  //
+  //	public String generate(TestItem testItem) {
+  //		String forEncoding = prepareForEncoding(testItem);
+  //		return SECRET + DigestUtils.md5Hex(forEncoding);
+  //	}
+  //
+  //	private String prepareForEncoding(TestItem testItem) {
+  //		// using cache for launches
+  //		Launch launch = launchCache.get(testItem.getLaunchRef(),
+  //				k -> mongoOperations.findOne(launchQuery(testItem.getLaunchRef()), Launch.class)
+  //		);
+  //
+  //		String launchName = launch.getName();
+  //		String projectName = launch.getProjectRef();
+  //
+  //		List<String> pathNames = getPathNames(testItem.getPath());
+  //		String itemName = testItem.getName();
+  //		StringJoiner joiner = new StringJoiner(";");
+  //		joiner.add(SECRET).add(projectName).add(launchName);
+  //		if (!CollectionUtils.isEmpty(pathNames)) {
+  //			joiner.add(pathNames.stream().collect(Collectors.joining(",")));
+  //		}
+  //		joiner.add(itemName);
+  //		List<Parameter> parameters = testItem.getParameters();
+  //		if (!CollectionUtils.isEmpty(parameters)) {
+  //			joiner.add(parameters.stream()
+  //					.map(parameter -> (!Strings.isNullOrEmpty(parameter.getKey()) ? parameter.getKey() + "=" : "") + parameter.getValue())
+  //					.collect(Collectors.joining(",")));
+  //		}
+  //		return joiner.toString();
+  //	}
+  //
+  //	private CloseableIterator<TestItem> getItemIterator(String checkpoint) {
+  //		Sort sort = new Sort(new Sort.Order(Sort.Direction.ASC, "_id"));
+  //		Query query = new Query().with(sort).noCursorTimeout();
+  //		if (checkpoint != null) {
+  //			query.addCriteria(where("_id").gte(new ObjectId(checkpoint)));
+  //		}
+  //		query.fields().include("name").include("path").include("launchRef").include("parameters");
+  //		return mongoOperations.stream(query, TestItem.class);
+  //	}
+  //
+  //	private List<String> getPathNames(List<String> path) {
+  //		Map<String, String> names = testItemRepository.findPathNames(path);
+  //		return path.stream().map(names::get).collect(Collectors.toList());
+  //	}
+  //
+  //	private Query launchQuery(String launchId) {
+  //		Query query = query((where("_id").is(launchId)));
+  //		query.fields().include("name");
+  //		query.fields().include("projectRef");
+  //		return query;
+  //	}
+  //
+  //	private Query testItemQuery() {
+  //		Query query = new Query();
+  //		query.fields().include("name").include("path").include("launchRef").include("parameters");
+  //		return query;
+  //	}
+  //
+  //	private String getLastCheckpoint() {
+  //		DBObject checkpoint = mongoOperations.getCollection(COLLECTION).findOne(new BasicDBObject("_id", CHECKPOINT));
+  //		return checkpoint == null ? null : (String) checkpoint.get(CHECKPOINT_ID);
+  //	}
+  //
+  //	private void createCheckpoint(String logId) {
+  //		BasicDBObject checkpoint = new BasicDBObject("_id", CHECKPOINT).append(CHECKPOINT_ID, logId);
+  //		mongoOperations.getCollection(COLLECTION).save(checkpoint);
+  //	}
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/history/ITestItemsHistoryService.java b/src/main/java/com/epam/ta/reportportal/core/item/history/ITestItemsHistoryService.java
index 011bdafe9b..5df86ae3cb 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/history/ITestItemsHistoryService.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/history/ITestItemsHistoryService.java
@@ -19,49 +19,49 @@
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.ws.model.TestItemHistoryElement;
-
 import java.util.List;
 
 /**
- * Define interface for loading and validating additional data( launches and
- * test Items) which should be used for loading test items history.
+ * Define interface for loading and validating additional data( launches and test Items) which
+ * should be used for loading test items history.
  *
  * @author Aliaksei_Makayed
  */
 public interface ITestItemsHistoryService {
 
-	/**
-	 * Load launches for which history should be loaded
-	 *
-	 * @param quantity           - count items in history
-	 * @param startingLaunchId   - first initial launch in history
-	 * @param projectName        - name of project
-	 * @param showBrokenLaunches - <b>boolean</b> should in_progress and interrupted launches
-	 *                           been included in history:<br>
-	 *                           <code>true</code> - if history should contain all launch
-	 *                           statuses<br>
-	 *                           <code>false</code> - if history should contain only passed and
-	 *                           failed launches
-	 * @return
-	 */
-	List<Launch> loadLaunches(int quantity, Long startingLaunchId, String projectName, boolean showBrokenLaunches);
+  /**
+   * Load launches for which history should be loaded
+   *
+   * @param quantity           - count items in history
+   * @param startingLaunchId   - first initial launch in history
+   * @param projectName        - name of project
+   * @param showBrokenLaunches - <b>boolean</b> should in_progress and interrupted launches been
+   *                           included in history:<br>
+   *                           <code>true</code> - if history should contain all launch
+   *                           statuses<br>
+   *                           <code>false</code> - if history should contain only passed and
+   *                           failed launches
+   * @return {@link List} of {@link Launch} - list of founded launches
+   */
+  List<Launch> loadLaunches(int quantity, Long startingLaunchId, String projectName,
+      boolean showBrokenLaunches);
 
-	/**
-	 * Build ui representation of launch history
-	 *
-	 * @param launch    History launch
-	 * @param testItems History test items
-	 * @return {@link TestItemHistoryElement}
-	 */
-	TestItemHistoryElement buildHistoryElement(Launch launch, List<TestItem> testItems);
+  /**
+   * Build ui representation of launch history
+   *
+   * @param launch    History launch
+   * @param testItems History test items
+   * @return {@link TestItemHistoryElement}
+   */
+  TestItemHistoryElement buildHistoryElement(Launch launch, List<TestItem> testItems);
 
-	/**
-	 * Validate size of history depth
-	 *
-	 * @param historyDepth history depth
-	 */
-	void validateHistoryDepth(int historyDepth);
+  /**
+   * Validate size of history depth
+   *
+   * @param historyDepth history depth
+   */
+  void validateHistoryDepth(int historyDepth);
 
-	void validateItems(List<TestItem> itemsForHistory, List<String> ids, String projectName);
+  void validateItems(List<TestItem> itemsForHistory, List<String> ids, String projectName);
 
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/history/TestItemsHistoryHandler.java b/src/main/java/com/epam/ta/reportportal/core/item/history/TestItemsHistoryHandler.java
index 55ddbd4b1b..0b6ccb81cd 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/history/TestItemsHistoryHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/history/TestItemsHistoryHandler.java
@@ -18,8 +18,8 @@
 
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.querygen.Queryable;
-import com.epam.ta.reportportal.ws.model.TestItemHistoryElement;
 import com.epam.ta.reportportal.core.item.impl.history.param.HistoryRequestParams;
+import com.epam.ta.reportportal.ws.model.TestItemHistoryElement;
 import org.springframework.data.domain.Pageable;
 
 /**
@@ -29,17 +29,19 @@
  */
 public interface TestItemsHistoryHandler {
 
-	/**
-	 * Get history for {@link com.epam.ta.reportportal.entity.item.TestItem}s according to input parameters
-	 *
-	 * @param projectDetails       - project details
-	 * @param filter               - filter
-	 * @param pageable             - paging parameters object
-	 * @param historyRequestParams - {@link HistoryRequestParams}
-	 * @param user                 - {@link ReportPortalUser}
-	 * @return {@link Iterable} of {@link TestItemHistoryElement}
-	 */
-	Iterable<TestItemHistoryElement> getItemsHistory(ReportPortalUser.ProjectDetails projectDetails, Queryable filter, Pageable pageable,
-			HistoryRequestParams historyRequestParams, ReportPortalUser user);
+  /**
+   * Get history for {@link com.epam.ta.reportportal.entity.item.TestItem}s according to input
+   * parameters
+   *
+   * @param projectDetails       - project details
+   * @param filter               - filter
+   * @param pageable             - paging parameters object
+   * @param historyRequestParams - {@link HistoryRequestParams}
+   * @param user                 - {@link ReportPortalUser}
+   * @return {@link Iterable} of {@link TestItemHistoryElement}
+   */
+  Iterable<TestItemHistoryElement> getItemsHistory(ReportPortalUser.ProjectDetails projectDetails,
+      Queryable filter, Pageable pageable,
+      HistoryRequestParams historyRequestParams, ReportPortalUser user);
 
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/identity/IdentityUtil.java b/src/main/java/com/epam/ta/reportportal/core/item/identity/IdentityUtil.java
index a6e1367e04..225c02851d 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/identity/IdentityUtil.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/identity/IdentityUtil.java
@@ -3,7 +3,6 @@
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
-
 import java.util.List;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
@@ -13,48 +12,50 @@
  */
 public class IdentityUtil {
 
-	private IdentityUtil() {
-		//static only
-	}
-
-	/**
-	 * Parse {@link TestItem#getPath()} and get all ids excluding id of the provided {@link TestItem}
-	 *
-	 * @param testItem {@link TestItem}
-	 * @return {@link List} with ids parsed from {@link TestItem#getPath()}
-	 */
-	public static List<Long> getParentIds(TestItem testItem) {
-		return getIds(testItem.getPath(), false);
-	}
-
-	/**
-	 * * Parse {@link TestItem#getPath()} and get all ids including id of the provided {@link TestItem}
-	 *
-	 * @param testItem {@link TestItem}
-	 * @return {@link List} with ids parsed from {@link TestItem#getPath()}
-	 */
-	public static List<Long> getItemTreeIds(TestItem testItem) {
-		return getIds(testItem.getPath(), true);
-	}
-
-	/**
-	 * * Parse {@link TestItem#getPath()} and get all ids including id of the provided {@link TestItem}
-	 *
-	 * @param path {@link TestItem#getPath()}
-	 * @return {@link List} with ids parsed from {@link TestItem#getPath()}
-	 */
-	public static List<Long> getItemTreeIds(String path) {
-		return getIds(path, true);
-	}
-
-	private static List<Long> getIds(String path, boolean includeLast) {
-		String[] ids = path.split("\\.");
-		return Stream.of(ids).limit(includeLast ? ids.length : ids.length - 1).map(id -> {
-			try {
-				return Long.parseLong(id);
-			} catch (NumberFormatException e) {
-				throw new ReportPortalException(ErrorType.BAD_REQUEST_ERROR, "Incorrect path value: " + id);
-			}
-		}).collect(Collectors.toList());
-	}
+  private IdentityUtil() {
+    //static only
+  }
+
+  /**
+   * Parse {@link TestItem#getPath()} and get all ids excluding id of the provided {@link TestItem}
+   *
+   * @param testItem {@link TestItem}
+   * @return {@link List} with ids parsed from {@link TestItem#getPath()}
+   */
+  public static List<Long> getParentIds(TestItem testItem) {
+    return getIds(testItem.getPath(), false);
+  }
+
+  /**
+   * * Parse {@link TestItem#getPath()} and get all ids including id of the provided
+   * {@link TestItem}
+   *
+   * @param testItem {@link TestItem}
+   * @return {@link List} with ids parsed from {@link TestItem#getPath()}
+   */
+  public static List<Long> getItemTreeIds(TestItem testItem) {
+    return getIds(testItem.getPath(), true);
+  }
+
+  /**
+   * * Parse {@link TestItem#getPath()} and get all ids including id of the provided
+   * {@link TestItem}
+   *
+   * @param path {@link TestItem#getPath()}
+   * @return {@link List} with ids parsed from {@link TestItem#getPath()}
+   */
+  public static List<Long> getItemTreeIds(String path) {
+    return getIds(path, true);
+  }
+
+  private static List<Long> getIds(String path, boolean includeLast) {
+    String[] ids = path.split("\\.");
+    return Stream.of(ids).limit(includeLast ? ids.length : ids.length - 1).map(id -> {
+      try {
+        return Long.parseLong(id);
+      } catch (NumberFormatException e) {
+        throw new ReportPortalException(ErrorType.BAD_REQUEST_ERROR, "Incorrect path value: " + id);
+      }
+    }).collect(Collectors.toList());
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/identity/TestCaseHashGenerator.java b/src/main/java/com/epam/ta/reportportal/core/item/identity/TestCaseHashGenerator.java
index 6080561d1b..2c1db6258a 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/identity/TestCaseHashGenerator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/identity/TestCaseHashGenerator.java
@@ -17,7 +17,6 @@
 package com.epam.ta.reportportal.core.item.identity;
 
 import com.epam.ta.reportportal.entity.item.TestItem;
-
 import java.util.List;
 
 /**
@@ -25,5 +24,5 @@
  */
 public interface TestCaseHashGenerator {
 
-	Integer generate(TestItem item, List<Long> parentIds, Long projectId);
+  Integer generate(TestItem item, List<Long> parentIds, Long projectId);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/identity/TestCaseHashGeneratorImpl.java b/src/main/java/com/epam/ta/reportportal/core/item/identity/TestCaseHashGeneratorImpl.java
index b0d54e665a..70837272e5 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/identity/TestCaseHashGeneratorImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/identity/TestCaseHashGeneratorImpl.java
@@ -20,12 +20,11 @@
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.google.api.client.util.Lists;
 import com.google.common.base.Strings;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.stereotype.Service;
-
 import java.util.Comparator;
 import java.util.List;
 import java.util.stream.Collectors;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
@@ -33,36 +32,38 @@
 @Service
 public class TestCaseHashGeneratorImpl implements TestCaseHashGenerator {
 
-	private final TestItemRepository testItemRepository;
+  private final TestItemRepository testItemRepository;
 
-	public TestCaseHashGeneratorImpl(TestItemRepository testItemRepository) {
-		this.testItemRepository = testItemRepository;
-	}
+  public TestCaseHashGeneratorImpl(TestItemRepository testItemRepository) {
+    this.testItemRepository = testItemRepository;
+  }
 
-	@Override
-	public Integer generate(TestItem item, List<Long> parentIds, Long projectId) {
-		return prepare(item, parentIds, projectId).hashCode();
-	}
+  @Override
+  public Integer generate(TestItem item, List<Long> parentIds, Long projectId) {
+    return prepare(item, parentIds, projectId).hashCode();
+  }
 
-	private String prepare(TestItem item, List<Long> parentIds, Long projectId) {
-		List<CharSequence> elements = Lists.newArrayList();
+  private String prepare(TestItem item, List<Long> parentIds, Long projectId) {
+    List<CharSequence> elements = Lists.newArrayList();
 
-		elements.add(projectId.toString());
-		getPathNames(parentIds).stream().filter(StringUtils::isNotEmpty).forEach(elements::add);
-		elements.add(item.getName());
-		item.getParameters()
-				.stream()
-				.map(parameter -> (!Strings.isNullOrEmpty(parameter.getKey()) ? parameter.getKey() + "=" : "") + parameter.getValue())
-				.forEach(elements::add);
+    elements.add(projectId.toString());
+    getPathNames(parentIds).stream().filter(StringUtils::isNotEmpty).forEach(elements::add);
+    elements.add(item.getName());
+    item.getParameters()
+        .stream()
+        .map(parameter ->
+            (!Strings.isNullOrEmpty(parameter.getKey()) ? parameter.getKey() + "=" : "")
+                + parameter.getValue())
+        .forEach(elements::add);
 
-		return String.join(";", elements);
-	}
+    return String.join(";", elements);
+  }
 
-	private List<String> getPathNames(List<Long> parentIds) {
-		return testItemRepository.findAllById(parentIds)
-				.stream()
-				.sorted(Comparator.comparingLong(TestItem::getItemId))
-				.map(TestItem::getName)
-				.collect(Collectors.toList());
-	}
+  private List<String> getPathNames(List<Long> parentIds) {
+    return testItemRepository.findAllById(parentIds)
+        .stream()
+        .sorted(Comparator.comparingLong(TestItem::getItemId))
+        .map(TestItem::getName)
+        .collect(Collectors.toList());
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/identity/TestItemUniqueIdGenerator.java b/src/main/java/com/epam/ta/reportportal/core/item/identity/TestItemUniqueIdGenerator.java
index 7ef810967e..ac1cad69ed 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/identity/TestItemUniqueIdGenerator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/identity/TestItemUniqueIdGenerator.java
@@ -21,73 +21,73 @@
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.google.common.base.Strings;
-import org.apache.commons.codec.digest.DigestUtils;
-import org.apache.commons.collections.CollectionUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
 import java.util.Comparator;
 import java.util.List;
 import java.util.Set;
 import java.util.StringJoiner;
 import java.util.stream.Collectors;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
- * Generates the unique identifier for test item based
- * on Base64 encoding and includes information about project,
- * name of item's launch, full path of item's parent names,
- * item name and parameters.
+ * Generates the unique identifier for test item based on Base64 encoding and includes information
+ * about project, name of item's launch, full path of item's parent names, item name and
+ * parameters.
  *
  * @author Pavel_Bortnik
  */
 @Service
 public class TestItemUniqueIdGenerator implements UniqueIdGenerator {
 
-	private static final String TRAIT = "auto:";
+  private static final String TRAIT = "auto:";
 
-	private TestItemRepository testItemRepository;
+  private TestItemRepository testItemRepository;
 
-	@Autowired
-	public void setTestItemRepository(TestItemRepository testItemRepository) {
-		this.testItemRepository = testItemRepository;
-	}
+  @Autowired
+  public void setTestItemRepository(TestItemRepository testItemRepository) {
+    this.testItemRepository = testItemRepository;
+  }
 
-	@Override
-	public String generate(TestItem testItem, List<Long> parentIds, Launch launch) {
-		String forEncoding = prepareForEncoding(testItem, parentIds, launch);
-		return TRAIT + DigestUtils.md5Hex(forEncoding);
-	}
+  @Override
+  public String generate(TestItem testItem, List<Long> parentIds, Launch launch) {
+    String forEncoding = prepareForEncoding(testItem, parentIds, launch);
+    return TRAIT + DigestUtils.md5Hex(forEncoding);
+  }
 
-	@Override
-	public boolean validate(String encoded) {
-		return !Strings.isNullOrEmpty(encoded) && encoded.startsWith(TRAIT);
-	}
+  @Override
+  public boolean validate(String encoded) {
+    return !Strings.isNullOrEmpty(encoded) && encoded.startsWith(TRAIT);
+  }
 
-	private String prepareForEncoding(TestItem testItem, List<Long> parentIds, Launch launch) {
-		Long projectId = launch.getProjectId();
-		String launchName = launch.getName();
-		List<String> pathNames = getPathNames(parentIds);
-		String itemName = testItem.getName();
-		StringJoiner joiner = new StringJoiner(";");
-		joiner.add(projectId.toString()).add(launchName);
-		if (!CollectionUtils.isEmpty(pathNames)) {
-			joiner.add(String.join(";", pathNames));
-		}
-		joiner.add(itemName);
-		Set<Parameter> parameters = testItem.getParameters();
-		if (!CollectionUtils.isEmpty(parameters)) {
-			joiner.add(parameters.stream()
-					.map(parameter -> (!Strings.isNullOrEmpty(parameter.getKey()) ? parameter.getKey() + "=" : "") + parameter.getValue())
-					.collect(Collectors.joining(",")));
-		}
-		return joiner.toString();
-	}
+  private String prepareForEncoding(TestItem testItem, List<Long> parentIds, Launch launch) {
+    Long projectId = launch.getProjectId();
+    String launchName = launch.getName();
+    List<String> pathNames = getPathNames(parentIds);
+    String itemName = testItem.getName();
+    StringJoiner joiner = new StringJoiner(";");
+    joiner.add(projectId.toString()).add(launchName);
+    if (!CollectionUtils.isEmpty(pathNames)) {
+      joiner.add(String.join(";", pathNames));
+    }
+    joiner.add(itemName);
+    Set<Parameter> parameters = testItem.getParameters();
+    if (!CollectionUtils.isEmpty(parameters)) {
+      joiner.add(parameters.stream()
+          .map(parameter ->
+              (!Strings.isNullOrEmpty(parameter.getKey()) ? parameter.getKey() + "=" : "")
+                  + parameter.getValue())
+          .collect(Collectors.joining(",")));
+    }
+    return joiner.toString();
+  }
 
-	private List<String> getPathNames(List<Long> parentIds) {
-		return testItemRepository.findAllById(parentIds)
-				.stream()
-				.sorted(Comparator.comparingLong(TestItem::getItemId))
-				.map(TestItem::getName)
-				.collect(Collectors.toList());
-	}
+  private List<String> getPathNames(List<Long> parentIds) {
+    return testItemRepository.findAllById(parentIds)
+        .stream()
+        .sorted(Comparator.comparingLong(TestItem::getItemId))
+        .map(TestItem::getName)
+        .collect(Collectors.toList());
+  }
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/identity/UniqueIdGenerator.java b/src/main/java/com/epam/ta/reportportal/core/item/identity/UniqueIdGenerator.java
index 5d0aea3228..2e54282f32 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/identity/UniqueIdGenerator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/identity/UniqueIdGenerator.java
@@ -18,7 +18,6 @@
 
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.launch.Launch;
-
 import java.util.List;
 
 /**
@@ -29,21 +28,22 @@
  */
 public interface UniqueIdGenerator {
 
-	/**
-	 * Generates the unique identifier for test item
-	 *
-	 * @param testItem  source for id
-	 * @param parentIds all {@link TestItem} ancestors' ids
-	 * @return unique id
-	 */
-	String generate(TestItem testItem, List<Long> parentIds, Launch launch);
+  /**
+   * Generates the unique identifier for test item
+   *
+   * @param testItem  source for id
+   * @param launch    {@link Launch}
+   * @param parentIds all {@link TestItem} ancestors' ids
+   * @return unique id
+   */
+  String generate(TestItem testItem, List<Long> parentIds, Launch launch);
 
-	/**
-	 * Validate if string has been generated automatically
-	 *
-	 * @param encoded encoded
-	 * @return true if it has been generated automatically
-	 */
-	boolean validate(String encoded);
+  /**
+   * Validate if string has been generated automatically
+   *
+   * @param encoded encoded
+   * @return true if it has been generated automatically
+   */
+  boolean validate(String encoded);
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/DeleteTestItemHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/DeleteTestItemHandlerImpl.java
index 8ee7e15d19..38b6dc7fb9 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/DeleteTestItemHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/DeleteTestItemHandlerImpl.java
@@ -16,10 +16,25 @@
 
 package com.epam.ta.reportportal.core.item.impl;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import static com.epam.ta.reportportal.commons.Predicates.not;
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
+import static com.epam.ta.reportportal.ws.model.ErrorType.ACCESS_DENIED;
+import static com.epam.ta.reportportal.ws.model.ErrorType.FORBIDDEN_OPERATION;
+import static com.epam.ta.reportportal.ws.model.ErrorType.LAUNCH_IS_NOT_FINISHED;
+import static com.epam.ta.reportportal.ws.model.ErrorType.TEST_ITEM_IS_NOT_FINISHED;
+import static java.util.Optional.ofNullable;
+import static java.util.stream.Collectors.toList;
+import static java.util.stream.Collectors.toSet;
+
+import com.epam.reportportal.events.ElementsDeletedEvent;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.validation.Suppliers;
+import com.epam.ta.reportportal.core.ElementsCounterService;
 import com.epam.ta.reportportal.core.analyzer.auto.LogIndexer;
 import com.epam.ta.reportportal.core.item.DeleteTestItemHandler;
+import com.epam.ta.reportportal.core.log.LogService;
 import com.epam.ta.reportportal.core.remover.ContentRemover;
 import com.epam.ta.reportportal.dao.AttachmentRepository;
 import com.epam.ta.reportportal.dao.LaunchRepository;
@@ -35,23 +50,19 @@
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
 import com.google.common.collect.Sets;
-import org.apache.commons.collections4.CollectionUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
-import java.util.*;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
 import java.util.function.Function;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-import static com.epam.ta.reportportal.commons.Predicates.not;
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
-import static com.epam.ta.reportportal.ws.model.ErrorType.*;
-import static java.util.Optional.ofNullable;
-import static java.util.stream.Collectors.toList;
-import static java.util.stream.Collectors.toSet;
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.stereotype.Service;
 
 /**
  * Default implementation of {@link DeleteTestItemHandler}
@@ -62,139 +73,180 @@
 @Service
 public class DeleteTestItemHandlerImpl implements DeleteTestItemHandler {
 
-	private final TestItemRepository testItemRepository;
-
-	private final ContentRemover<Long> itemContentRemover;
-
-	private final LogIndexer logIndexer;
-
-	private final LaunchRepository launchRepository;
-
-	private final AttachmentRepository attachmentRepository;
-
-	@Autowired
-	public DeleteTestItemHandlerImpl(TestItemRepository testItemRepository, ContentRemover<Long> itemContentRemover, LogIndexer logIndexer, LaunchRepository launchRepository,
-			AttachmentRepository attachmentRepository) {
-		this.testItemRepository = testItemRepository;
-		this.itemContentRemover = itemContentRemover;
-		this.logIndexer = logIndexer;
-		this.launchRepository = launchRepository;
-		this.attachmentRepository = attachmentRepository;
-	}
-
-	@Override
-	public OperationCompletionRS deleteTestItem(Long itemId, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user) {
-		TestItem item = testItemRepository.findById(itemId)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, itemId));
-		Launch launch = launchRepository.findById(item.getLaunchId())
-				.orElseThrow(() -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND, item.getLaunchId()));
-
-		validate(item, launch, user, projectDetails);
-		Optional<Long> parentId = ofNullable(item.getParentId());
-
-		Set<Long> itemsForRemove = Sets.newHashSet(testItemRepository.selectAllDescendantsIds(item.getPath()));
-		itemsForRemove.forEach(itemContentRemover::remove);
-
-		itemContentRemover.remove(item.getItemId());
-		testItemRepository.deleteById(item.getItemId());
-
-		launch.setHasRetries(launchRepository.hasRetries(launch.getId()));
-		parentId.flatMap(testItemRepository::findById)
-				.ifPresent(p -> p.setHasChildren(testItemRepository.hasChildren(p.getItemId(), p.getPath())));
-
-		logIndexer.indexItemsRemoveAsync(projectDetails.getProjectId(), itemsForRemove);
-		attachmentRepository.moveForDeletionByItems(itemsForRemove);
-
-		return COMPOSE_DELETE_RESPONSE.apply(item.getItemId());
-	}
-
-	@Override
-	public List<OperationCompletionRS> deleteTestItems(Collection<Long> ids, ReportPortalUser.ProjectDetails projectDetails,
-			ReportPortalUser user) {
-		List<TestItem> items = testItemRepository.findAllById(ids);
-
-		List<Launch> launches = launchRepository.findAllById(items.stream()
-				.map(TestItem::getLaunchId)
-				.filter(Objects::nonNull)
-				.collect(Collectors.toSet()));
-		Map<Long, List<TestItem>> launchItemMap = items.stream().collect(Collectors.groupingBy(TestItem::getLaunchId));
-		launches.forEach(launch -> launchItemMap.get(launch.getId()).forEach(item -> validate(item, launch, user, projectDetails)));
-
-		Map<Long, PathName> descendantsMapping = testItemRepository.selectPathNames(items);
-
-		Set<Long> idsToDelete = Sets.newHashSet(descendantsMapping.keySet());
-
-		descendantsMapping.forEach((key, value) -> value.getItemPaths().forEach(ip -> {
-			if (idsToDelete.contains(ip.getId())) {
-				idsToDelete.remove(key);
-			}
-		}));
-
-		List<TestItem> parentsToUpdate = testItemRepository.findAllById(items.stream()
-				.filter(it -> idsToDelete.contains(it.getItemId()))
-				.map(TestItem::getParentId)
-				.filter(Objects::nonNull)
-				.collect(toList()));
-
-		Set<Long> removedItems = testItemRepository.findAllById(idsToDelete)
-				.stream()
-				.map(TestItem::getPath)
-				.collect(toList())
-				.stream()
-				.flatMap(path -> testItemRepository.selectAllDescendantsIds(path).stream())
-				.collect(toSet());
-
-		idsToDelete.forEach(itemContentRemover::remove);
-		testItemRepository.deleteAllByItemIdIn(idsToDelete);
-
-		launches.forEach(it -> it.setHasRetries(launchRepository.hasRetries(it.getId())));
-
-		parentsToUpdate.forEach(it -> it.setHasChildren(testItemRepository.hasChildren(it.getItemId(), it.getPath())));
-
-		if (CollectionUtils.isNotEmpty(removedItems)) {
-			logIndexer.indexItemsRemoveAsync(projectDetails.getProjectId(), removedItems);
-			attachmentRepository.moveForDeletionByItems(removedItems);
-		}
-
-		return idsToDelete.stream().map(COMPOSE_DELETE_RESPONSE).collect(toList());
-	}
-
-	private static final Function<Long, OperationCompletionRS> COMPOSE_DELETE_RESPONSE = it -> {
-		String message = formattedSupplier("Test Item with ID = '{}' has been successfully deleted.", it).get();
-		return new OperationCompletionRS(message);
-	};
-
-	/**
-	 * Validate {@link ReportPortalUser} credentials, {@link TestItemResults#getStatus()},
-	 * {@link Launch#getStatus()} and {@link Launch} affiliation to the {@link com.epam.ta.reportportal.entity.project.Project}
-	 *
-	 * @param testItem       {@link TestItem}
-	 * @param user           {@link ReportPortalUser}
-	 * @param projectDetails {@link ReportPortalUser.ProjectDetails}
-	 */
-	private void validate(TestItem testItem, Launch launch, ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails) {
-		if (user.getUserRole() != UserRole.ADMINISTRATOR) {
-			expect(launch.getProjectId(), equalTo(projectDetails.getProjectId())).verify(FORBIDDEN_OPERATION,
-					formattedSupplier("Deleting testItem '{}' is not under specified project '{}'",
-							testItem.getItemId(),
-							projectDetails.getProjectId()
-					)
-			);
-			if (projectDetails.getProjectRole().lowerThan(ProjectRole.PROJECT_MANAGER)) {
-				expect(user.getUserId(), Predicate.isEqual(launch.getUserId())).verify(ACCESS_DENIED, "You are not a launch owner.");
-			}
-		}
-		expect(testItem.getRetryOf(), Objects::isNull).verify(ErrorType.RETRIES_HANDLER_ERROR,
-				Suppliers.formattedSupplier("Unable to delete test item ['{}'] because it is a retry", testItem.getItemId()).get()
-		);
-		expect(testItem.getItemResults().getStatus(), not(it -> it.equals(StatusEnum.IN_PROGRESS))).verify(TEST_ITEM_IS_NOT_FINISHED,
-				formattedSupplier("Unable to delete test item ['{}'] in progress state", testItem.getItemId())
-		);
-		expect(launch.getStatus(), not(it -> it.equals(StatusEnum.IN_PROGRESS))).verify(LAUNCH_IS_NOT_FINISHED,
-				formattedSupplier("Unable to delete test item ['{}'] under launch ['{}'] with 'In progress' state",
-						testItem.getItemId(),
-						launch.getId()
-				)
-		);
-	}
+  private final TestItemRepository testItemRepository;
+
+  private final ContentRemover<Long> itemContentRemover;
+
+  private final LogIndexer logIndexer;
+
+  private final LaunchRepository launchRepository;
+
+  private final AttachmentRepository attachmentRepository;
+
+  private final ApplicationEventPublisher eventPublisher;
+
+  private final ElementsCounterService elementsCounterService;
+
+  private final LogService logService;
+
+  @Autowired
+  public DeleteTestItemHandlerImpl(TestItemRepository testItemRepository,
+      ContentRemover<Long> itemContentRemover, LogIndexer logIndexer,
+      LaunchRepository launchRepository, AttachmentRepository attachmentRepository,
+      ApplicationEventPublisher eventPublisher,
+      ElementsCounterService elementsCounterService, LogService logService) {
+    this.testItemRepository = testItemRepository;
+    this.itemContentRemover = itemContentRemover;
+    this.logIndexer = logIndexer;
+    this.launchRepository = launchRepository;
+    this.attachmentRepository = attachmentRepository;
+    this.eventPublisher = eventPublisher;
+    this.elementsCounterService = elementsCounterService;
+    this.logService = logService;
+  }
+
+  @Override
+  public OperationCompletionRS deleteTestItem(Long itemId,
+      ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user) {
+    TestItem item = testItemRepository.findById(itemId)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, itemId));
+    Launch launch = launchRepository.findById(item.getLaunchId())
+        .orElseThrow(
+            () -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND, item.getLaunchId()));
+
+    validate(item, launch, user, projectDetails);
+    Optional<Long> parentId = ofNullable(item.getParentId());
+
+    Set<Long> itemsForRemove = Sets.newHashSet(
+        testItemRepository.selectAllDescendantsIds(item.getPath()));
+    itemsForRemove.forEach(itemContentRemover::remove);
+
+    eventPublisher.publishEvent(new ElementsDeletedEvent(item,
+        projectDetails.getProjectId(),
+        elementsCounterService.countNumberOfItemElements(item)
+    ));
+    logService.deleteLogMessageByTestItemSet(projectDetails.getProjectId(), itemsForRemove);
+    itemContentRemover.remove(item.getItemId());
+    testItemRepository.deleteById(item.getItemId());
+
+    launch.setHasRetries(launchRepository.hasRetries(launch.getId()));
+    parentId.flatMap(testItemRepository::findById)
+        .ifPresent(
+            p -> p.setHasChildren(testItemRepository.hasChildren(p.getItemId(), p.getPath())));
+
+    logIndexer.indexItemsRemoveAsync(projectDetails.getProjectId(), itemsForRemove);
+    attachmentRepository.moveForDeletionByItems(itemsForRemove);
+
+    return COMPOSE_DELETE_RESPONSE.apply(item.getItemId());
+  }
+
+  @Override
+  public List<OperationCompletionRS> deleteTestItems(Collection<Long> ids,
+      ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user) {
+    List<TestItem> items = testItemRepository.findAllById(ids);
+
+    List<Launch> launches = launchRepository.findAllById(items.stream()
+        .map(TestItem::getLaunchId)
+        .filter(Objects::nonNull)
+        .collect(Collectors.toSet()));
+    Map<Long, List<TestItem>> launchItemMap = items.stream()
+        .collect(Collectors.groupingBy(TestItem::getLaunchId));
+    launches.forEach(launch -> launchItemMap.get(launch.getId())
+        .forEach(item -> validate(item, launch, user, projectDetails)));
+
+    Map<Long, PathName> descendantsMapping = testItemRepository.selectPathNames(items);
+
+    Set<Long> idsToDelete = Sets.newHashSet(descendantsMapping.keySet());
+
+    descendantsMapping.forEach((key, value) -> value.getItemPaths().forEach(ip -> {
+      if (idsToDelete.contains(ip.getId())) {
+        idsToDelete.remove(key);
+      }
+    }));
+
+    List<TestItem> parentsToUpdate = testItemRepository.findAllById(items.stream()
+        .filter(it -> idsToDelete.contains(it.getItemId()))
+        .map(TestItem::getParentId)
+        .filter(Objects::nonNull)
+        .collect(toList()));
+
+    Set<Long> removedItems = testItemRepository.findAllById(idsToDelete)
+        .stream()
+        .map(TestItem::getPath)
+        .collect(toList())
+        .stream()
+        .flatMap(path -> testItemRepository.selectAllDescendantsIds(path).stream())
+        .collect(toSet());
+
+    idsToDelete.forEach(itemContentRemover::remove);
+    eventPublisher.publishEvent(new ElementsDeletedEvent(
+        items,
+        projectDetails.getProjectId(),
+        elementsCounterService.countNumberOfItemElements(items)
+    ));
+    logService.deleteLogMessageByTestItemSet(projectDetails.getProjectId(), removedItems);
+    testItemRepository.deleteAllByItemIdIn(idsToDelete);
+
+    launches.forEach(it -> it.setHasRetries(launchRepository.hasRetries(it.getId())));
+
+    parentsToUpdate.forEach(
+        it -> it.setHasChildren(testItemRepository.hasChildren(it.getItemId(), it.getPath())));
+
+    if (CollectionUtils.isNotEmpty(removedItems)) {
+      logIndexer.indexItemsRemoveAsync(projectDetails.getProjectId(), removedItems);
+      attachmentRepository.moveForDeletionByItems(removedItems);
+    }
+
+    return idsToDelete.stream().map(COMPOSE_DELETE_RESPONSE).collect(toList());
+  }
+
+  private static final Function<Long, OperationCompletionRS> COMPOSE_DELETE_RESPONSE = it -> {
+    String message = formattedSupplier("Test Item with ID = '{}' has been successfully deleted.",
+        it).get();
+    return new OperationCompletionRS(message);
+  };
+
+  /**
+   * Validate {@link ReportPortalUser} credentials, {@link TestItemResults#getStatus()},
+   * {@link Launch#getStatus()} and {@link Launch} affiliation to the
+   * {@link com.epam.ta.reportportal.entity.project.Project}
+   *
+   * @param testItem       {@link TestItem}
+   * @param user           {@link ReportPortalUser}
+   * @param projectDetails {@link ReportPortalUser.ProjectDetails}
+   */
+  private void validate(TestItem testItem, Launch launch, ReportPortalUser user,
+      ReportPortalUser.ProjectDetails projectDetails) {
+    if (user.getUserRole() != UserRole.ADMINISTRATOR) {
+      expect(launch.getProjectId(), equalTo(projectDetails.getProjectId())).verify(
+          FORBIDDEN_OPERATION,
+          formattedSupplier("Deleting testItem '{}' is not under specified project '{}'",
+              testItem.getItemId(),
+              projectDetails.getProjectId()
+          )
+      );
+      if (projectDetails.getProjectRole().lowerThan(ProjectRole.PROJECT_MANAGER)) {
+        expect(user.getUserId(), Predicate.isEqual(launch.getUserId())).verify(ACCESS_DENIED,
+            "You are not a launch owner.");
+      }
+    }
+    expect(testItem.getRetryOf(), Objects::isNull).verify(ErrorType.RETRIES_HANDLER_ERROR,
+        Suppliers.formattedSupplier("Unable to delete test item ['{}'] because it is a retry",
+            testItem.getItemId()).get()
+    );
+    expect(testItem.getItemResults().getStatus(),
+        not(it -> it.equals(StatusEnum.IN_PROGRESS))).verify(TEST_ITEM_IS_NOT_FINISHED,
+        formattedSupplier("Unable to delete test item ['{}'] in progress state",
+            testItem.getItemId())
+    );
+    expect(launch.getStatus(), not(it -> it.equals(StatusEnum.IN_PROGRESS))).verify(
+        LAUNCH_IS_NOT_FINISHED,
+        formattedSupplier(
+            "Unable to delete test item ['{}'] under launch ['{}'] with 'In progress' state",
+            testItem.getItemId(),
+            launch.getId()
+        )
+    );
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/ExternalTicketHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/ExternalTicketHandlerImpl.java
index 3e410375db..03377e97ba 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/ExternalTicketHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/ExternalTicketHandlerImpl.java
@@ -16,6 +16,10 @@
 
 package com.epam.ta.reportportal.core.item.impl;
 
+import static java.util.Optional.ofNullable;
+import static java.util.stream.Collectors.toList;
+import static java.util.stream.Collectors.toSet;
+
 import com.epam.ta.reportportal.core.item.ExternalTicketHandler;
 import com.epam.ta.reportportal.dao.TicketRepository;
 import com.epam.ta.reportportal.entity.bts.Ticket;
@@ -24,18 +28,17 @@
 import com.epam.ta.reportportal.ws.converter.converters.TicketConverter;
 import com.epam.ta.reportportal.ws.model.issue.Issue;
 import com.epam.ta.reportportal.ws.model.item.UnlinkExternalIssueRQ;
-import org.apache.commons.collections.CollectionUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
 import java.time.Instant;
 import java.time.LocalDateTime;
 import java.time.ZoneOffset;
-import java.util.*;
-
-import static java.util.Optional.ofNullable;
-import static java.util.stream.Collectors.toList;
-import static java.util.stream.Collectors.toSet;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
 
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
@@ -43,92 +46,101 @@
 @Component
 public class ExternalTicketHandlerImpl implements ExternalTicketHandler {
 
-	@Autowired
-	private TicketRepository ticketRepository;
+  @Autowired
+  private TicketRepository ticketRepository;
 
-	@Override
-	public void linkExternalTickets(String submitter, List<IssueEntity> issueEntities, List<Issue.ExternalSystemIssue> tickets) {
-		List<Ticket> existedTickets = collectExistedTickets(tickets);
-		Set<Ticket> ticketsFromRq = collectTickets(tickets, submitter);
-		linkTickets(issueEntities, existedTickets, ticketsFromRq);
-	}
+  @Override
+  public void linkExternalTickets(String submitter, List<IssueEntity> issueEntities,
+      List<Issue.ExternalSystemIssue> tickets) {
+    List<Ticket> existedTickets = collectExistedTickets(tickets);
+    Set<Ticket> ticketsFromRq = collectTickets(tickets, submitter);
+    linkTickets(issueEntities, existedTickets, ticketsFromRq);
+  }
 
-	@Override
-	public void unlinkExternalTickets(List<TestItem> items, UnlinkExternalIssueRQ request) {
-		items.forEach(testItem -> {
-			IssueEntity issue = testItem.getItemResults().getIssue();
-			if (issue.getTickets().removeIf(it -> request.getTicketIds().contains(it.getTicketId()))) {
-				issue.setAutoAnalyzed(false);
-			}
-		});
-	}
+  @Override
+  public void unlinkExternalTickets(List<TestItem> items, UnlinkExternalIssueRQ request) {
+    items.forEach(testItem -> {
+      IssueEntity issue = testItem.getItemResults().getIssue();
+      if (issue.getTickets().removeIf(it -> request.getTicketIds().contains(it.getTicketId()))) {
+        issue.setAutoAnalyzed(false);
+      }
+    });
+  }
 
-	@Override
-	public void updateLinking(String submitter, IssueEntity issueEntity, Set<Issue.ExternalSystemIssue> externalTickets) {
-		ofNullable(externalTickets).ifPresent(tickets -> {
-			Set<Ticket> existedTickets = collectTickets(tickets, submitter);
-			issueEntity.getTickets().removeIf(it -> !existedTickets.contains(it));
-			issueEntity.getTickets().addAll(existedTickets);
-			existedTickets.stream().filter(it -> CollectionUtils.isEmpty(it.getIssues())).forEach(it -> it.getIssues().add(issueEntity));
-		});
-	}
+  @Override
+  public void updateLinking(String submitter, IssueEntity issueEntity,
+      Set<Issue.ExternalSystemIssue> externalTickets) {
+    ofNullable(externalTickets).ifPresent(tickets -> {
+      Set<Ticket> existedTickets = collectTickets(tickets, submitter);
+      issueEntity.getTickets().removeIf(it -> !existedTickets.contains(it));
+      issueEntity.getTickets().addAll(existedTickets);
+      existedTickets.stream().filter(it -> CollectionUtils.isEmpty(it.getIssues()))
+          .forEach(it -> it.getIssues().add(issueEntity));
+    });
+  }
 
-	/**
-	 * Finds tickets that are existed in db and removes them from request.
-	 *
-	 * @param externalIssues {@link com.epam.ta.reportportal.ws.model.issue.Issue.ExternalSystemIssue}
-	 * @return List of existed tickets in db.
-	 */
-	private List<Ticket> collectExistedTickets(Collection<Issue.ExternalSystemIssue> externalIssues) {
-		if (CollectionUtils.isEmpty(externalIssues)) {
-			return Collections.emptyList();
-		}
-		List<Ticket> existedTickets = ticketRepository.findByTicketIdIn(externalIssues.stream()
-				.map(Issue.ExternalSystemIssue::getTicketId)
-				.collect(toList()));
-		List<String> existedTicketsIds = existedTickets.stream().map(Ticket::getTicketId).collect(toList());
-		externalIssues.removeIf(it -> existedTicketsIds.contains(it.getTicketId()));
-		return existedTickets;
-	}
+  /**
+   * Finds tickets that are existed in db and removes them from request.
+   *
+   * @param externalIssues {@link
+   *                       com.epam.ta.reportportal.ws.model.issue.Issue.ExternalSystemIssue}
+   * @return List of existed tickets in db.
+   */
+  private List<Ticket> collectExistedTickets(Collection<Issue.ExternalSystemIssue> externalIssues) {
+    if (CollectionUtils.isEmpty(externalIssues)) {
+      return Collections.emptyList();
+    }
+    List<Ticket> existedTickets = ticketRepository.findByTicketIdIn(externalIssues.stream()
+        .map(Issue.ExternalSystemIssue::getTicketId)
+        .collect(toList()));
+    List<String> existedTicketsIds = existedTickets.stream().map(Ticket::getTicketId)
+        .collect(toList());
+    externalIssues.removeIf(it -> existedTicketsIds.contains(it.getTicketId()));
+    return existedTickets;
+  }
 
-	/**
-	 * TODO document this
-	 *
-	 * @param externalIssues {@link com.epam.ta.reportportal.ws.model.issue.Issue.ExternalSystemIssue}
-	 * @param username       {@link com.epam.ta.reportportal.entity.user.User#login}
-	 * @return {@link Set} of the {@link Ticket}
-	 */
-	private Set<Ticket> collectTickets(Collection<Issue.ExternalSystemIssue> externalIssues, String username) {
-		if (CollectionUtils.isEmpty(externalIssues)) {
-			return Collections.emptySet();
-		}
-		return externalIssues.stream().map(it -> {
-			Ticket ticket;
-			Optional<Ticket> ticketOptional = ticketRepository.findByTicketId(it.getTicketId());
-			if (ticketOptional.isPresent()) {
-				ticket = ticketOptional.get();
-				ticket.setUrl(it.getUrl());
-				ticket.setBtsProject(it.getBtsProject());
-				ticket.setBtsUrl(it.getBtsUrl());
-				ticket.setPluginName(it.getPluginName());
-			} else {
-				ticket = TicketConverter.TO_TICKET.apply(it);
-			}
-			ticket.setSubmitter(username);
-			ticket.setSubmitDate(ofNullable(it.getSubmitDate()).map(millis -> LocalDateTime.ofInstant(Instant.ofEpochMilli(millis),
-					ZoneOffset.UTC
-			)).orElse(LocalDateTime.now()));
-			return ticket;
-		}).collect(toSet());
-	}
+  /**
+   * TODO document this
+   *
+   * @param externalIssues {@link
+   *                       com.epam.ta.reportportal.ws.model.issue.Issue.ExternalSystemIssue}
+   * @param username       {@link com.epam.ta.reportportal.entity.user.User#login}
+   * @return {@link Set} of the {@link Ticket}
+   */
+  private Set<Ticket> collectTickets(Collection<Issue.ExternalSystemIssue> externalIssues,
+      String username) {
+    if (CollectionUtils.isEmpty(externalIssues)) {
+      return Collections.emptySet();
+    }
+    return externalIssues.stream().map(it -> {
+      Ticket ticket;
+      Optional<Ticket> ticketOptional = ticketRepository.findByTicketId(it.getTicketId());
+      if (ticketOptional.isPresent()) {
+        ticket = ticketOptional.get();
+        ticket.setUrl(it.getUrl());
+        ticket.setBtsProject(it.getBtsProject());
+        ticket.setBtsUrl(it.getBtsUrl());
+        ticket.setPluginName(it.getPluginName());
+      } else {
+        ticket = TicketConverter.TO_TICKET.apply(it);
+      }
+      ticket.setSubmitter(username);
+      ticket.setSubmitDate(ofNullable(it.getSubmitDate()).map(
+          millis -> LocalDateTime.ofInstant(Instant.ofEpochMilli(millis),
+              ZoneOffset.UTC
+          )).orElse(LocalDateTime.now()));
+      return ticket;
+    }).collect(toSet());
+  }
 
-	private void linkTickets(List<IssueEntity> issueEntities, List<Ticket> existedTickets, Set<Ticket> ticketsFromRq) {
-		List<Ticket> tickets = ticketRepository.saveAll(ticketsFromRq);
-		issueEntities.forEach(entity -> {
-			entity.getTickets().addAll(existedTickets);
-			entity.getTickets().addAll(tickets);
-			entity.setAutoAnalyzed(false);
-		});
-	}
+  private void linkTickets(List<IssueEntity> issueEntities, List<Ticket> existedTickets,
+      Set<Ticket> ticketsFromRq) {
+    List<Ticket> tickets = ticketRepository.saveAll(ticketsFromRq);
+    issueEntities.forEach(entity -> {
+      entity.getTickets().addAll(existedTickets);
+      entity.getTickets().addAll(tickets);
+      entity.setAutoAnalyzed(false);
+    });
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/FinishTestItemHandlerAsyncImpl.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/FinishTestItemHandlerAsyncImpl.java
index cc0535ab99..04dd74a2b7 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/FinishTestItemHandlerAsyncImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/FinishTestItemHandlerAsyncImpl.java
@@ -16,6 +16,10 @@
 
 package com.epam.ta.reportportal.core.item.impl;
 
+import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
+import static com.epam.ta.reportportal.core.configs.rabbit.ReportingConfiguration.EXCHANGE_REPORTING;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.item.FinishTestItemHandler;
 import com.epam.ta.reportportal.exception.ReportPortalException;
@@ -25,18 +29,13 @@
 import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
 import com.epam.ta.reportportal.ws.rabbit.MessageHeaders;
 import com.epam.ta.reportportal.ws.rabbit.RequestType;
+import java.util.Map;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.amqp.core.AmqpTemplate;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 
-import java.util.Map;
-
-import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
-import static com.epam.ta.reportportal.core.configs.rabbit.ReportingConfiguration.EXCHANGE_REPORTING;
-import static java.util.Optional.ofNullable;
-
 /**
  * @author Konstantin Antipin
  */
@@ -44,33 +43,36 @@
 @Qualifier("finishTestItemHandlerAsync")
 public class FinishTestItemHandlerAsyncImpl implements FinishTestItemHandler {
 
-	@Autowired
-	@Qualifier(value = "rabbitTemplate")
-	AmqpTemplate amqpTemplate;
+  @Autowired
+  @Qualifier(value = "rabbitTemplate")
+  AmqpTemplate amqpTemplate;
 
-	@Autowired
-	private ReportingQueueService reportingQueueService;
+  @Autowired
+  private ReportingQueueService reportingQueueService;
 
-	@Override
-	public OperationCompletionRS finishTestItem(ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails, String testItemId,
-			FinishTestItemRQ request) {
+  @Override
+  public OperationCompletionRS finishTestItem(ReportPortalUser user,
+      ReportPortalUser.ProjectDetails projectDetails, String testItemId,
+      FinishTestItemRQ request) {
 
-		// todo: may be problem - no access to repository, so no possibility to validateRoles() here
-		amqpTemplate.convertAndSend(EXCHANGE_REPORTING,
-				reportingQueueService.getReportingQueueKey(ofNullable(request.getLaunchUuid()).filter(StringUtils::isNotEmpty)
-						.orElseThrow(() -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR,
-								"Launch UUID should not be null or empty."
-						))),
-				request,
-				message -> {
-					Map<String, Object> headers = message.getMessageProperties().getHeaders();
-					headers.put(MessageHeaders.REQUEST_TYPE, RequestType.FINISH_TEST);
-					headers.put(MessageHeaders.USERNAME, user.getUsername());
-					headers.put(MessageHeaders.PROJECT_NAME, projectDetails.getProjectName());
-					headers.put(MessageHeaders.ITEM_ID, testItemId);
-					return message;
-				}
-		);
-		return new OperationCompletionRS(formattedSupplier("Accepted finish request for test item ID = {}", testItemId).get());
-	}
+    // todo: may be problem - no access to repository, so no possibility to validateRoles() here
+    amqpTemplate.convertAndSend(EXCHANGE_REPORTING,
+        reportingQueueService.getReportingQueueKey(
+            ofNullable(request.getLaunchUuid()).filter(StringUtils::isNotEmpty)
+                .orElseThrow(() -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR,
+                    "Launch UUID should not be null or empty."
+                ))),
+        request,
+        message -> {
+          Map<String, Object> headers = message.getMessageProperties().getHeaders();
+          headers.put(MessageHeaders.REQUEST_TYPE, RequestType.FINISH_TEST);
+          headers.put(MessageHeaders.USERNAME, user.getUsername());
+          headers.put(MessageHeaders.PROJECT_NAME, projectDetails.getProjectName());
+          headers.put(MessageHeaders.ITEM_ID, testItemId);
+          return message;
+        }
+    );
+    return new OperationCompletionRS(
+        formattedSupplier("Accepted finish request for test item ID = {}", testItemId).get());
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/FinishTestItemHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/FinishTestItemHandlerImpl.java
index d1f7347636..986cbab87c 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/FinishTestItemHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/FinishTestItemHandlerImpl.java
@@ -13,14 +13,42 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package com.epam.ta.reportportal.core.item.impl;
 
+import static com.epam.ta.reportportal.commons.EntityUtils.TO_LOCAL_DATE_TIME;
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
+import static com.epam.ta.reportportal.core.hierarchy.AbstractFinishHierarchyHandler.ATTRIBUTE_KEY_STATUS;
+import static com.epam.ta.reportportal.core.hierarchy.AbstractFinishHierarchyHandler.ATTRIBUTE_VALUE_INTERRUPTED;
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.FAILED;
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.INFO;
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.INTERRUPTED;
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.IN_PROGRESS;
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.PASSED;
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.SKIPPED;
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.WARN;
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.fromValue;
+import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.NOT_ISSUE_FLAG;
+import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.TO_INVESTIGATE;
+import static com.epam.ta.reportportal.entity.project.ProjectRole.PROJECT_MANAGER;
+import static com.epam.ta.reportportal.util.Predicates.ITEM_CAN_BE_INDEXED;
+import static com.epam.ta.reportportal.ws.converter.converters.TestItemConverter.TO_ACTIVITY_RESOURCE;
+import static com.epam.ta.reportportal.ws.model.ErrorType.ACCESS_DENIED;
+import static com.epam.ta.reportportal.ws.model.ErrorType.AMBIGUOUS_TEST_ITEM_STATUS;
+import static com.epam.ta.reportportal.ws.model.ErrorType.FINISH_ITEM_NOT_ALLOWED;
+import static com.epam.ta.reportportal.ws.model.ErrorType.LAUNCH_NOT_FOUND;
+import static com.epam.ta.reportportal.ws.model.ErrorType.TEST_ITEM_NOT_FOUND;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.Preconditions;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.analyzer.auto.LogIndexer;
 import com.epam.ta.reportportal.core.events.MessageBus;
+import com.epam.ta.reportportal.core.events.activity.item.IssueResolvedEvent;
+import com.epam.ta.reportportal.core.events.activity.item.TestItemFinishedEvent;
 import com.epam.ta.reportportal.core.events.activity.item.TestItemStatusChangedEvent;
-import com.epam.ta.reportportal.core.events.activity.item.ItemFinishedEvent;
 import com.epam.ta.reportportal.core.hierarchy.FinishHierarchyHandler;
 import com.epam.ta.reportportal.core.item.ExternalTicketHandler;
 import com.epam.ta.reportportal.core.item.FinishTestItemHandler;
@@ -47,6 +75,13 @@
 import com.epam.ta.reportportal.ws.model.activity.TestItemActivityResource;
 import com.epam.ta.reportportal.ws.model.issue.Issue;
 import com.google.common.collect.Lists;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.Predicate;
+import javax.annotation.Nullable;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.BooleanUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -57,25 +92,6 @@
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import javax.annotation.Nullable;
-import java.util.*;
-import java.util.function.Predicate;
-
-import static com.epam.ta.reportportal.commons.EntityUtils.TO_LOCAL_DATE_TIME;
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
-import static com.epam.ta.reportportal.core.hierarchy.AbstractFinishHierarchyHandler.ATTRIBUTE_KEY_STATUS;
-import static com.epam.ta.reportportal.core.hierarchy.AbstractFinishHierarchyHandler.ATTRIBUTE_VALUE_INTERRUPTED;
-import static com.epam.ta.reportportal.entity.enums.StatusEnum.*;
-import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.NOT_ISSUE_FLAG;
-import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.TO_INVESTIGATE;
-import static com.epam.ta.reportportal.entity.project.ProjectRole.PROJECT_MANAGER;
-import static com.epam.ta.reportportal.util.Predicates.ITEM_CAN_BE_INDEXED;
-import static com.epam.ta.reportportal.ws.converter.converters.TestItemConverter.TO_ACTIVITY_RESOURCE;
-import static com.epam.ta.reportportal.ws.model.ErrorType.*;
-import static java.util.Optional.ofNullable;
-
 /**
  * Default implementation of {@link FinishTestItemHandler}
  *
@@ -86,314 +102,329 @@
 @Transactional
 class FinishTestItemHandlerImpl implements FinishTestItemHandler {
 
-	private final TestItemRepository testItemRepository;
-
-	private final IssueTypeHandler issueTypeHandler;
-
-	private final FinishHierarchyHandler<TestItem> finishHierarchyHandler;
-
-	private final LogIndexer logIndexer;
-
-	private final Map<StatusEnum, StatusChangingStrategy> statusChangingStrategyMapping;
-
-	private final IssueEntityRepository issueEntityRepository;
-
-	private final LaunchRepository launchRepository;
-
-	private final ChangeStatusHandler changeStatusHandler;
-
-	private final RetrySearcher retrySearcher;
-	private final RetryHandler retryHandler;
-
-	private final ApplicationEventPublisher eventPublisher;
-
-	private final MessageBus messageBus;
-
-	private final ExternalTicketHandler externalTicketHandler;
-
-	@Autowired
-	FinishTestItemHandlerImpl(TestItemRepository testItemRepository, IssueTypeHandler issueTypeHandler,
-			@Qualifier("finishTestItemHierarchyHandler") FinishHierarchyHandler<TestItem> finishHierarchyHandler, LogIndexer logIndexer,
-			Map<StatusEnum, StatusChangingStrategy> statusChangingStrategyMapping, IssueEntityRepository issueEntityRepository,
-			ChangeStatusHandler changeStatusHandler, ApplicationEventPublisher eventPublisher, LaunchRepository launchRepository,
-			@Qualifier("uniqueIdRetrySearcher") RetrySearcher retrySearcher, RetryHandler retryHandler, MessageBus messageBus,
-			ExternalTicketHandler externalTicketHandler) {
-		this.testItemRepository = testItemRepository;
-		this.issueTypeHandler = issueTypeHandler;
-		this.finishHierarchyHandler = finishHierarchyHandler;
-		this.logIndexer = logIndexer;
-		this.statusChangingStrategyMapping = statusChangingStrategyMapping;
-		this.issueEntityRepository = issueEntityRepository;
-		this.launchRepository = launchRepository;
-		this.changeStatusHandler = changeStatusHandler;
-		this.eventPublisher = eventPublisher;
-		this.retrySearcher = retrySearcher;
-		this.retryHandler = retryHandler;
-		this.messageBus = messageBus;
-		this.externalTicketHandler = externalTicketHandler;
-	}
-
-	@Override
-	public OperationCompletionRS finishTestItem(ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails, String testItemId,
-			FinishTestItemRQ finishExecutionRQ) {
-		final TestItem testItem = testItemRepository.findByUuid(testItemId)
-				.filter(it -> it.isHasChildren() || (!it.isHasChildren() && it.getItemResults().getStatus() == IN_PROGRESS))
-				.orElseGet(() -> testItemRepository.findIdByUuidForUpdate(testItemId)
-						.flatMap(testItemRepository::findById)
-						.orElseThrow(() -> new ReportPortalException(TEST_ITEM_NOT_FOUND, testItemId)));
-
-		final Launch launch = retrieveLaunch(testItem);
-
-		final TestItemResults testItemResults = processItemResults(user,
-				projectDetails,
-				launch,
-				testItem,
-				finishExecutionRQ,
-				testItem.isHasChildren()
-		);
-
-		final TestItem itemForUpdate = new TestItemBuilder(testItem).addDescription(finishExecutionRQ.getDescription())
-				.addTestCaseId(finishExecutionRQ.getTestCaseId())
-				.addAttributes(finishExecutionRQ.getAttributes())
-				.addTestItemResults(testItemResults)
-				.get();
-
-		testItemRepository.save(itemForUpdate);
-
-		if (BooleanUtils.toBoolean(finishExecutionRQ.isRetry()) || StringUtils.isNotBlank(finishExecutionRQ.getRetryOf())) {
-			Optional.of(testItem)
-					.filter(it -> !it.isHasChildren() && !it.isHasRetries() && Objects.isNull(it.getRetryOf()))
-					.map(TestItem::getParentId)
-					.flatMap(testItemRepository::findById)
-					.ifPresent(parentItem -> ofNullable(finishExecutionRQ.getRetryOf()).flatMap(testItemRepository::findIdByUuidForUpdate)
-							.ifPresentOrElse(retryParentId -> retryHandler.handleRetries(launch, itemForUpdate, retryParentId),
-									() -> retrySearcher.findPreviousRetry(launch, itemForUpdate, parentItem)
-											.ifPresent(previousRetryId -> retryHandler.handleRetries(launch,
-													itemForUpdate,
-													previousRetryId
-											))
-							));
-		}
-
-		return new OperationCompletionRS("TestItem with ID = '" + testItemId + "' successfully finished.");
-	}
-
-	/**
-	 * If test item has descendants, it's status is resolved from statistics
-	 * When status provided, no matter test item has or not descendants, test
-	 * item status is resolved to provided
-	 *
-	 * @param testItem         {@link TestItem}
-	 * @param finishTestItemRQ {@link FinishTestItemRQ}
-	 * @return TestItemResults {@link TestItemResults}
-	 */
-	private TestItemResults processItemResults(ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails, Launch launch,
-			TestItem testItem, FinishTestItemRQ finishTestItemRQ, boolean hasChildren) {
-
-		validateRoles(user, projectDetails, launch);
-		verifyTestItem(testItem, fromValue(finishTestItemRQ.getStatus()), testItem.isHasChildren());
-
-		TestItemResults testItemResults;
-		if (hasChildren) {
-			testItemResults = processParentItemResult(testItem, finishTestItemRQ, launch, user, projectDetails);
-		} else {
-			testItemResults = processChildItemResult(testItem, finishTestItemRQ, user, projectDetails, launch);
-		}
-		testItemResults.setEndTime(TO_LOCAL_DATE_TIME.apply(finishTestItemRQ.getEndTime()));
-		return testItemResults;
-	}
-
-	private Launch retrieveLaunch(TestItem testItem) {
-
-		return ofNullable(testItem.getRetryOf()).map(retryParentId -> {
-			TestItem retryParent = testItemRepository.findById(retryParentId)
-					.orElseThrow(() -> new ReportPortalException(TEST_ITEM_NOT_FOUND, testItem.getRetryOf()));
-			return getLaunch(retryParent);
-		}).orElseGet(() -> getLaunch(testItem)).orElseThrow(() -> new ReportPortalException(LAUNCH_NOT_FOUND));
-	}
-
-	private Optional<Launch> getLaunch(TestItem testItem) {
-		return ofNullable(testItem.getLaunchId()).map(launchRepository::findById)
-				.orElseGet(() -> ofNullable(testItem.getParentId()).flatMap(testItemRepository::findById)
-						.map(TestItem::getLaunchId)
-						.map(launchRepository::findById)
-						.orElseThrow(() -> new ReportPortalException(LAUNCH_NOT_FOUND)));
-	}
-
-	/**
-	 * Validation procedure for specified test item
-	 *
-	 * @param testItem     Test item
-	 * @param actualStatus Actual status of item
-	 * @param hasChildren  Does item contain children
-	 */
-	private void verifyTestItem(TestItem testItem, Optional<StatusEnum> actualStatus, boolean hasChildren) {
-		expect(!actualStatus.isPresent() && !hasChildren, equalTo(Boolean.FALSE)).verify(AMBIGUOUS_TEST_ITEM_STATUS,
-				formattedSupplier(
-						"There is no status provided from request and there are no descendants to check statistics for test item id '{}'",
-						testItem.getItemId()
-				)
-		);
-	}
-
-	private void validateRoles(ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails, Launch launch) {
-		if (user.getUserRole() != UserRole.ADMINISTRATOR) {
-			expect(launch.getProjectId(), equalTo(projectDetails.getProjectId())).verify(ACCESS_DENIED);
-			if (!launch.isRerun() && projectDetails.getProjectRole().lowerThan(PROJECT_MANAGER)) {
-				expect(user.getUserId(), Predicate.isEqual(launch.getUserId())).verify(FINISH_ITEM_NOT_ALLOWED,
-						"You are not a launch owner."
-				);
-			}
-		}
-	}
-
-	private TestItemResults processParentItemResult(TestItem testItem, FinishTestItemRQ finishTestItemRQ, Launch launch,
-			ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails) {
-
-		TestItemResults testItemResults = testItem.getItemResults();
-		Optional<StatusEnum> actualStatus = fromValue(finishTestItemRQ.getStatus());
-
-		if (testItemRepository.hasItemsInStatusByParent(testItem.getItemId(), testItem.getPath(), IN_PROGRESS.name())) {
-			finishHierarchyHandler.finishDescendants(testItem,
-					actualStatus.orElse(INTERRUPTED),
-					finishTestItemRQ.getEndTime(),
-					user,
-					projectDetails
-			);
-			testItemResults.setStatus(resolveStatus(testItem.getItemId()));
-		} else {
-			testItemResults.setStatus(actualStatus.orElseGet(() -> resolveStatus(testItem.getItemId())));
-		}
-
-		testItem.getAttributes()
-				.removeIf(attribute -> ATTRIBUTE_KEY_STATUS.equalsIgnoreCase(attribute.getKey())
-						&& ATTRIBUTE_VALUE_INTERRUPTED.equalsIgnoreCase(attribute.getValue()));
-
-		changeStatusHandler.changeParentStatus(testItem, projectDetails.getProjectId(), user);
-		changeStatusHandler.changeLaunchStatus(launch);
-
-		return testItemResults;
-	}
-
-	private TestItemResults processChildItemResult(TestItem testItem, FinishTestItemRQ finishTestItemRQ, ReportPortalUser user,
-			ReportPortalUser.ProjectDetails projectDetails, Launch launch) {
-		TestItemResults testItemResults = testItem.getItemResults();
-		StatusEnum actualStatus = fromValue(finishTestItemRQ.getStatus()).orElse(INTERRUPTED);
-		Optional<IssueEntity> resolvedIssue = resolveIssue(user,
-				actualStatus,
-				testItem,
-				finishTestItemRQ.getIssue(),
-				projectDetails.getProjectId()
-		);
-
-		if (testItemResults.getStatus() == IN_PROGRESS) {
-			testItemResults.setStatus(actualStatus);
-			resolvedIssue.ifPresent(issue -> updateItemIssue(testItemResults, issue));
-			ofNullable(testItem.getRetryOf()).ifPresentOrElse(retryOf -> {
-			}, () -> {
-				changeStatusHandler.changeParentStatus(testItem, projectDetails.getProjectId(), user);
-				changeStatusHandler.changeLaunchStatus(launch);
-				if (testItem.isHasRetries()) {
-					retryHandler.finishRetries(testItem.getItemId(),
-							JStatusEnum.valueOf(actualStatus.name()),
-							TO_LOCAL_DATE_TIME.apply(finishTestItemRQ.getEndTime())
-					);
-				}
-			});
-		} else {
-			updateFinishedItem(testItemResults, actualStatus, resolvedIssue, testItem, user, projectDetails.getProjectId());
-		}
-
-		testItem.getAttributes()
-				.removeIf(attribute -> ATTRIBUTE_KEY_STATUS.equalsIgnoreCase(attribute.getKey())
-						&& ATTRIBUTE_VALUE_INTERRUPTED.equalsIgnoreCase(attribute.getValue()));
-
-		return testItemResults;
-	}
-
-	private StatusEnum resolveStatus(Long itemId) {
-		return testItemRepository.hasDescendantsNotInStatus(itemId, PASSED.name(), INFO.name(), WARN.name()) ? FAILED : PASSED;
-	}
-
-	private boolean isIssueRequired(TestItem testItem, StatusEnum status) {
-		return Preconditions.statusIn(FAILED, SKIPPED).test(status) && !ofNullable(testItem.getRetryOf()).isPresent()
-				&& testItem.isHasStats();
-	}
-
-	private Optional<IssueEntity> resolveIssue(ReportPortalUser user, StatusEnum status, TestItem testItem, @Nullable Issue issue,
-			Long projectId) {
-
-		if (isIssueRequired(testItem, status)) {
-			return ofNullable(issue).map(is -> {
-				//in provided issue should be locator id or NOT_ISSUE value
-				String locator = is.getIssueType();
-				if (!NOT_ISSUE_FLAG.getValue().equalsIgnoreCase(locator)) {
-					IssueType issueType = issueTypeHandler.defineIssueType(projectId, locator);
-					IssueEntity issueEntity = IssueConverter.TO_ISSUE.apply(is);
-					issueEntity.setIssueType(issueType);
-					if (!CollectionUtils.isEmpty(issue.getExternalSystemIssues())) {
-						externalTicketHandler.linkExternalTickets(user.getUsername(),
-								Lists.newArrayList(issueEntity),
-								new ArrayList<>(issue.getExternalSystemIssues())
-						);
-					}
-					return Optional.of(issueEntity);
-				}
-				return Optional.<IssueEntity>empty();
-			}).orElseGet(() -> {
-				IssueEntity issueEntity = new IssueEntity();
-				IssueType toInvestigate = issueTypeHandler.defineIssueType(projectId, TO_INVESTIGATE.getLocator());
-				issueEntity.setIssueType(toInvestigate);
-				return Optional.of(issueEntity);
-			});
-		}
-		return Optional.empty();
-	}
-
-	private void updateFinishedItem(TestItemResults testItemResults, StatusEnum actualStatus, Optional<IssueEntity> resolvedIssue,
-			TestItem testItem, ReportPortalUser user, Long projectId) {
-
-		resolvedIssue.ifPresent(issue -> deleteOldIssueIndex(actualStatus, testItem, testItemResults, projectId));
-
-		if (testItemResults.getStatus() != actualStatus) {
-			TestItemActivityResource before = TO_ACTIVITY_RESOURCE.apply(testItem, projectId);
-			Optional<StatusChangingStrategy> statusChangingStrategy = ofNullable(statusChangingStrategyMapping.get(actualStatus));
-			if (statusChangingStrategy.isPresent()) {
-				statusChangingStrategy.get().changeStatus(testItem, actualStatus, user);
-			} else {
-				testItemResults.setStatus(actualStatus);
-			}
-			publishUpdateActivity(before, TO_ACTIVITY_RESOURCE.apply(testItem, projectId), user);
-		}
-
-		resolvedIssue.ifPresent(issue -> {
-			updateItemIssue(testItemResults, issue);
-			if (ITEM_CAN_BE_INDEXED.test(testItem)) {
-				eventPublisher.publishEvent(new ItemFinishedEvent(testItem.getItemId(), testItem.getLaunchId(), projectId));
-			}
-		});
-	}
-
-	private void publishUpdateActivity(TestItemActivityResource before, TestItemActivityResource after, ReportPortalUser user) {
-		messageBus.publishActivity(new TestItemStatusChangedEvent(before, after, user.getUserId(), user.getUsername()));
-	}
-
-	private void deleteOldIssueIndex(StatusEnum actualStatus, TestItem testItem, TestItemResults testItemResults, Long projectId) {
-		if (actualStatus == PASSED || ITEM_CAN_BE_INDEXED.test(testItem)) {
-			ofNullable(testItemResults.getIssue()).ifPresent(issue -> logIndexer.indexItemsRemoveAsync(projectId,
-					Collections.singletonList(testItem.getItemId())
-			));
-		}
-	}
-
-	private void updateItemIssue(TestItemResults testItemResults, IssueEntity resolvedIssue) {
-		issueEntityRepository.findById(testItemResults.getItemId()).ifPresent(issueEntity -> {
-			issueEntity.setTestItemResults(null);
-			issueEntityRepository.delete(issueEntity);
-			testItemResults.setIssue(null);
-		});
-		resolvedIssue.setTestItemResults(testItemResults);
-		issueEntityRepository.save(resolvedIssue);
-		testItemResults.setIssue(resolvedIssue);
-	}
+  private final TestItemRepository testItemRepository;
+
+  private final IssueTypeHandler issueTypeHandler;
+
+  private final FinishHierarchyHandler<TestItem> finishHierarchyHandler;
+
+  private final LogIndexer logIndexer;
+
+  private final Map<StatusEnum, StatusChangingStrategy> statusChangingStrategyMapping;
+
+  private final IssueEntityRepository issueEntityRepository;
+
+  private final LaunchRepository launchRepository;
+
+  private final ChangeStatusHandler changeStatusHandler;
+
+  private final RetrySearcher retrySearcher;
+  private final RetryHandler retryHandler;
+
+  private final ApplicationEventPublisher eventPublisher;
+
+  private final MessageBus messageBus;
+
+  private final ExternalTicketHandler externalTicketHandler;
+
+  @Autowired
+  FinishTestItemHandlerImpl(TestItemRepository testItemRepository,
+      IssueTypeHandler issueTypeHandler, @Qualifier("finishTestItemHierarchyHandler")
+  FinishHierarchyHandler<TestItem> finishHierarchyHandler, LogIndexer logIndexer,
+      Map<StatusEnum, StatusChangingStrategy> statusChangingStrategyMapping,
+      IssueEntityRepository issueEntityRepository, ChangeStatusHandler changeStatusHandler,
+      ApplicationEventPublisher eventPublisher, LaunchRepository launchRepository,
+      @Qualifier("uniqueIdRetrySearcher") RetrySearcher retrySearcher, RetryHandler retryHandler,
+      MessageBus messageBus, ExternalTicketHandler externalTicketHandler) {
+    this.testItemRepository = testItemRepository;
+    this.issueTypeHandler = issueTypeHandler;
+    this.finishHierarchyHandler = finishHierarchyHandler;
+    this.logIndexer = logIndexer;
+    this.statusChangingStrategyMapping = statusChangingStrategyMapping;
+    this.issueEntityRepository = issueEntityRepository;
+    this.launchRepository = launchRepository;
+    this.changeStatusHandler = changeStatusHandler;
+    this.eventPublisher = eventPublisher;
+    this.retrySearcher = retrySearcher;
+    this.retryHandler = retryHandler;
+    this.messageBus = messageBus;
+    this.externalTicketHandler = externalTicketHandler;
+  }
+
+  @Override
+  public OperationCompletionRS finishTestItem(ReportPortalUser user,
+      ReportPortalUser.ProjectDetails projectDetails, String testItemId,
+      FinishTestItemRQ finishExecutionRQ) {
+    final TestItem testItem = testItemRepository.findByUuid(testItemId).filter(
+        it -> it.isHasChildren() || (!it.isHasChildren()
+            && it.getItemResults().getStatus() == IN_PROGRESS)).orElseGet(
+        () -> testItemRepository.findIdByUuidForUpdate(testItemId)
+            .flatMap(testItemRepository::findById)
+            .orElseThrow(() -> new ReportPortalException(TEST_ITEM_NOT_FOUND, testItemId)));
+
+    final Launch launch = retrieveLaunch(testItem);
+
+    final TestItemResults testItemResults =
+        processItemResults(user, projectDetails, launch, testItem, finishExecutionRQ,
+            testItem.isHasChildren()
+        );
+
+    final TestItem itemForUpdate =
+        new TestItemBuilder(testItem).addDescription(finishExecutionRQ.getDescription())
+            .addTestCaseId(finishExecutionRQ.getTestCaseId())
+            .overwriteAttributesValues(finishExecutionRQ.getAttributes())
+            .addTestItemResults(testItemResults).get();
+
+    testItemRepository.save(itemForUpdate);
+
+    if (BooleanUtils.toBoolean(finishExecutionRQ.isRetry()) || StringUtils.isNotBlank(
+        finishExecutionRQ.getRetryOf())) {
+      Optional.of(testItem).filter(
+              it -> !it.isHasChildren() && !it.isHasRetries() && Objects.isNull(it.getRetryOf()))
+          .map(TestItem::getParentId).flatMap(testItemRepository::findById).ifPresent(
+              parentItem -> ofNullable(finishExecutionRQ.getRetryOf()).flatMap(
+                  testItemRepository::findIdByUuidForUpdate).ifPresentOrElse(
+                  retryParentId -> retryHandler.handleRetries(launch, itemForUpdate, retryParentId),
+                  () -> retrySearcher.findPreviousRetry(launch, itemForUpdate, parentItem).ifPresent(
+                      previousRetryId -> retryHandler.handleRetries(launch, itemForUpdate,
+                          previousRetryId
+                      ))
+              ));
+    }
+    eventPublisher.publishEvent(
+        new TestItemFinishedEvent(itemForUpdate, projectDetails.getProjectId()));
+
+    return new OperationCompletionRS(
+        "TestItem with ID = '" + testItemId + "' successfully finished.");
+  }
+
+  /**
+   * If test item has descendants, it's status is resolved from statistics When status provided, no
+   * matter test item has or not descendants, test item status is resolved to provided
+   *
+   * @param testItem         {@link TestItem}
+   * @param finishTestItemRQ {@link FinishTestItemRQ}
+   * @return TestItemResults {@link TestItemResults}
+   */
+  private TestItemResults processItemResults(ReportPortalUser user,
+      ReportPortalUser.ProjectDetails projectDetails, Launch launch, TestItem testItem,
+      FinishTestItemRQ finishTestItemRQ, boolean hasChildren) {
+
+    validateRoles(user, projectDetails, launch);
+    verifyTestItem(testItem, fromValue(finishTestItemRQ.getStatus()), testItem.isHasChildren());
+
+    TestItemResults testItemResults;
+    if (hasChildren) {
+      testItemResults =
+          processParentItemResult(testItem, finishTestItemRQ, launch, user, projectDetails);
+    } else {
+      testItemResults =
+          processChildItemResult(testItem, finishTestItemRQ, user, projectDetails, launch);
+    }
+    testItemResults.setEndTime(TO_LOCAL_DATE_TIME.apply(finishTestItemRQ.getEndTime()));
+    return testItemResults;
+  }
+
+  private Launch retrieveLaunch(TestItem testItem) {
+
+    return ofNullable(testItem.getRetryOf()).map(retryParentId -> {
+          TestItem retryParent = testItemRepository.findById(retryParentId)
+              .orElseThrow(() -> new ReportPortalException(TEST_ITEM_NOT_FOUND, testItem.getRetryOf()));
+          return getLaunch(retryParent);
+        }).orElseGet(() -> getLaunch(testItem))
+        .orElseThrow(() -> new ReportPortalException(LAUNCH_NOT_FOUND));
+  }
+
+  private Optional<Launch> getLaunch(TestItem testItem) {
+    return ofNullable(testItem.getLaunchId()).map(launchRepository::findById).orElseGet(
+        () -> ofNullable(testItem.getParentId()).flatMap(testItemRepository::findById)
+            .map(TestItem::getLaunchId).map(launchRepository::findById)
+            .orElseThrow(() -> new ReportPortalException(LAUNCH_NOT_FOUND)));
+  }
+
+  /**
+   * Validation procedure for specified test item
+   *
+   * @param testItem     Test item
+   * @param actualStatus Actual status of item
+   * @param hasChildren  Does item contain children
+   */
+  private void verifyTestItem(TestItem testItem, Optional<StatusEnum> actualStatus,
+      boolean hasChildren) {
+    expect(actualStatus.isEmpty() && !hasChildren, equalTo(Boolean.FALSE)).verify(
+        AMBIGUOUS_TEST_ITEM_STATUS, formattedSupplier(
+            "There is no status provided from request and there are no descendants to check statistics for test item id '{}'",
+            testItem.getItemId()
+        ));
+  }
+
+  private void validateRoles(ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails,
+      Launch launch) {
+    if (user.getUserRole() != UserRole.ADMINISTRATOR) {
+      expect(launch.getProjectId(), equalTo(projectDetails.getProjectId())).verify(ACCESS_DENIED);
+      if (!launch.isRerun() && projectDetails.getProjectRole().lowerThan(PROJECT_MANAGER)) {
+        expect(user.getUserId(), Predicate.isEqual(launch.getUserId())).verify(
+            FINISH_ITEM_NOT_ALLOWED, "You are not a launch owner.");
+      }
+    }
+  }
+
+  private TestItemResults processParentItemResult(TestItem testItem,
+      FinishTestItemRQ finishTestItemRQ, Launch launch, ReportPortalUser user,
+      ReportPortalUser.ProjectDetails projectDetails) {
+
+    TestItemResults testItemResults = testItem.getItemResults();
+    Optional<StatusEnum> actualStatus = fromValue(finishTestItemRQ.getStatus());
+
+    if (testItemRepository.hasItemsInStatusByParent(testItem.getItemId(), testItem.getPath(),
+        IN_PROGRESS.name()
+    )) {
+      finishHierarchyHandler.finishDescendants(testItem, actualStatus.orElse(INTERRUPTED),
+          finishTestItemRQ.getEndTime(), user, projectDetails
+      );
+    }
+
+    testItemResults.setStatus(actualStatus.orElseGet(() -> resolveStatus(testItem.getItemId())));
+
+    testItem.getAttributes().removeIf(
+        attribute -> ATTRIBUTE_KEY_STATUS.equalsIgnoreCase(attribute.getKey())
+            && ATTRIBUTE_VALUE_INTERRUPTED.equalsIgnoreCase(attribute.getValue()));
+
+    changeStatusHandler.changeParentStatus(testItem, projectDetails.getProjectId(), user);
+    changeStatusHandler.changeLaunchStatus(launch);
+
+    return testItemResults;
+  }
+
+  private TestItemResults processChildItemResult(TestItem testItem,
+      FinishTestItemRQ finishTestItemRQ, ReportPortalUser user,
+      ReportPortalUser.ProjectDetails projectDetails, Launch launch) {
+    TestItemResults testItemResults = testItem.getItemResults();
+    StatusEnum actualStatus = fromValue(finishTestItemRQ.getStatus()).orElse(INTERRUPTED);
+    Optional<IssueEntity> resolvedIssue =
+        resolveIssue(user, actualStatus, testItem, finishTestItemRQ.getIssue(),
+            projectDetails.getProjectId()
+        );
+
+    if (testItemResults.getStatus() == IN_PROGRESS) {
+      testItemResults.setStatus(actualStatus);
+      resolvedIssue.ifPresent(issue -> updateItemIssue(testItemResults, issue));
+      ofNullable(testItem.getRetryOf()).ifPresentOrElse(retryOf -> {
+      }, () -> {
+        changeStatusHandler.changeParentStatus(testItem, projectDetails.getProjectId(), user);
+        changeStatusHandler.changeLaunchStatus(launch);
+        if (testItem.isHasRetries()) {
+          retryHandler.finishRetries(testItem.getItemId(), JStatusEnum.valueOf(actualStatus.name()),
+              TO_LOCAL_DATE_TIME.apply(finishTestItemRQ.getEndTime())
+          );
+        }
+      });
+    } else {
+      updateFinishedItem(testItemResults, actualStatus, resolvedIssue, testItem, user,
+          projectDetails.getProjectId()
+      );
+    }
+
+    testItem.getAttributes().removeIf(
+        attribute -> ATTRIBUTE_KEY_STATUS.equalsIgnoreCase(attribute.getKey())
+            && ATTRIBUTE_VALUE_INTERRUPTED.equalsIgnoreCase(attribute.getValue()));
+
+    return testItemResults;
+  }
+
+  private StatusEnum resolveStatus(Long itemId) {
+    return testItemRepository.hasDescendantsNotInStatus(itemId, PASSED.name(), INFO.name(),
+        WARN.name()
+    ) ? FAILED : PASSED;
+  }
+
+  private boolean isIssueRequired(TestItem testItem, StatusEnum status) {
+    return Preconditions.statusIn(FAILED, SKIPPED).test(status) && ofNullable(
+        testItem.getRetryOf()).isEmpty() && testItem.isHasStats();
+  }
+
+  private Optional<IssueEntity> resolveIssue(ReportPortalUser user, StatusEnum status,
+      TestItem testItem, @Nullable Issue issue, Long projectId) {
+
+    if (isIssueRequired(testItem, status)) {
+      return ofNullable(issue).map(is -> {
+        //in provided issue should be locator id or NOT_ISSUE value
+        String locator = is.getIssueType();
+        if (!NOT_ISSUE_FLAG.getValue().equalsIgnoreCase(locator)) {
+          IssueType issueType = issueTypeHandler.defineIssueType(projectId, locator);
+          IssueEntity issueEntity = IssueConverter.TO_ISSUE.apply(is);
+          issueEntity.setIssueType(issueType);
+          if (!CollectionUtils.isEmpty(issue.getExternalSystemIssues())) {
+            externalTicketHandler.linkExternalTickets(user.getUsername(),
+                Lists.newArrayList(issueEntity), new ArrayList<>(issue.getExternalSystemIssues())
+            );
+          }
+          return Optional.of(issueEntity);
+        }
+        return Optional.<IssueEntity>empty();
+      }).orElseGet(() -> {
+        IssueEntity issueEntity = new IssueEntity();
+        IssueType toInvestigate =
+            issueTypeHandler.defineIssueType(projectId, TO_INVESTIGATE.getLocator());
+        issueEntity.setIssueType(toInvestigate);
+        return Optional.of(issueEntity);
+      });
+    }
+    return Optional.empty();
+  }
+
+  private void updateFinishedItem(TestItemResults testItemResults, StatusEnum actualStatus,
+      Optional<IssueEntity> resolvedIssue, TestItem testItem, ReportPortalUser user,
+      Long projectId) {
+
+    resolvedIssue.ifPresent(
+        issue -> deleteOldIssueIndex(actualStatus, testItem, testItemResults, projectId));
+
+    if (testItemResults.getStatus() != actualStatus) {
+      TestItemActivityResource before = TO_ACTIVITY_RESOURCE.apply(testItem, projectId);
+      Optional<StatusChangingStrategy> statusChangingStrategy =
+          ofNullable(statusChangingStrategyMapping.get(actualStatus));
+      if (statusChangingStrategy.isPresent()) {
+        statusChangingStrategy.get().changeStatus(testItem, actualStatus, user, false);
+      } else {
+        testItemResults.setStatus(actualStatus);
+      }
+      publishUpdateActivity(before, TO_ACTIVITY_RESOURCE.apply(testItem, projectId), user);
+    }
+
+    resolvedIssue.ifPresent(issue -> {
+      updateItemIssue(testItemResults, issue);
+      if (ITEM_CAN_BE_INDEXED.test(testItem)) {
+        eventPublisher.publishEvent(
+            new IssueResolvedEvent(testItem.getItemId(), testItem.getLaunchId(), projectId));
+      }
+    });
+  }
+
+  private void publishUpdateActivity(TestItemActivityResource before,
+      TestItemActivityResource after, ReportPortalUser user) {
+    messageBus.publishActivity(
+        new TestItemStatusChangedEvent(before, after, user.getUserId(), user.getUsername()));
+  }
+
+  private void deleteOldIssueIndex(StatusEnum actualStatus, TestItem testItem,
+      TestItemResults testItemResults, Long projectId) {
+    if (actualStatus == PASSED || ITEM_CAN_BE_INDEXED.test(testItem)) {
+      ofNullable(testItemResults.getIssue()).ifPresent(
+          issue -> logIndexer.indexItemsRemoveAsync(projectId,
+              Collections.singletonList(testItem.getItemId())
+          ));
+    }
+  }
+
+  private void updateItemIssue(TestItemResults testItemResults, IssueEntity resolvedIssue) {
+    issueEntityRepository.findById(testItemResults.getItemId()).ifPresent(issueEntity -> {
+      issueEntity.setTestItemResults(null);
+      issueEntityRepository.delete(issueEntity);
+      testItemResults.setIssue(null);
+    });
+    resolvedIssue.setTestItemResults(testItemResults);
+    issueEntityRepository.save(resolvedIssue);
+    testItemResults.setIssue(resolvedIssue);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/IssueTypeHandler.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/IssueTypeHandler.java
index ece6bf1b63..e8b4553b21 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/IssueTypeHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/IssueTypeHandler.java
@@ -16,6 +16,11 @@
 
 package com.epam.ta.reportportal.core.item.impl;
 
+import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
+import static com.epam.ta.reportportal.ws.model.ErrorType.FAILED_TEST_ITEM_ISSUE_TYPE_DEFINITION;
+import static java.util.Optional.ofNullable;
+import static java.util.stream.Collectors.toList;
+
 import com.epam.ta.reportportal.commons.EntityUtils;
 import com.epam.ta.reportportal.dao.TestItemRepository;
 import com.epam.ta.reportportal.entity.item.issue.IssueType;
@@ -23,41 +28,39 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
-import static com.epam.ta.reportportal.ws.model.ErrorType.FAILED_TEST_ITEM_ISSUE_TYPE_DEFINITION;
-import static java.util.Optional.ofNullable;
-import static java.util.stream.Collectors.toList;
-
 /**
  * @author Pavel Bortnik
  */
 @Service
 public class IssueTypeHandler {
 
-	private TestItemRepository testItemRepository;
-
-	@Autowired
-	public void setTestItemRepository(TestItemRepository testItemRepository) {
-		this.testItemRepository = testItemRepository;
-	}
-
-	/**
-	 * Verifies that provided test item issue type is valid, and test item
-	 * domain object could be processed correctly
-	 *
-	 * @param locator   Issue locator
-	 * @param projectId Project id
-	 * @return verified issue type
-	 */
-	public IssueType defineIssueType(Long projectId, String locator) {
-		return testItemRepository.selectIssueTypeByLocator(
-				projectId,
-				ofNullable(locator).map(EntityUtils::normalizeId).orElseThrow(() -> new ReportPortalException("Locator should not be null"))
-		).orElseThrow(() -> new ReportPortalException(FAILED_TEST_ITEM_ISSUE_TYPE_DEFINITION, formattedSupplier(
-				"Invalid test item issue type definition '{}' is requested. Valid issue types' locators are: {}",
-				locator,
-				testItemRepository.selectIssueLocatorsByProject(projectId).stream().map(IssueType::getLocator).collect(toList())
-		)));
-	}
+  private TestItemRepository testItemRepository;
+
+  @Autowired
+  public void setTestItemRepository(TestItemRepository testItemRepository) {
+    this.testItemRepository = testItemRepository;
+  }
+
+  /**
+   * Verifies that provided test item issue type is valid, and test item domain object could be
+   * processed correctly
+   *
+   * @param locator   Issue locator
+   * @param projectId Project id
+   * @return verified issue type
+   */
+  public IssueType defineIssueType(Long projectId, String locator) {
+    return testItemRepository.selectIssueTypeByLocator(
+        projectId,
+        ofNullable(locator).map(EntityUtils::normalizeId)
+            .orElseThrow(() -> new ReportPortalException("Locator should not be null"))
+    ).orElseThrow(
+        () -> new ReportPortalException(FAILED_TEST_ITEM_ISSUE_TYPE_DEFINITION, formattedSupplier(
+            "Invalid test item issue type definition '{}' is requested. Valid issue types' locators are: {}",
+            locator,
+            testItemRepository.selectIssueLocatorsByProject(projectId).stream()
+                .map(IssueType::getLocator).collect(toList())
+        )));
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/LaunchAccessValidator.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/LaunchAccessValidator.java
index 3c258bf82d..5e98ea0eff 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/LaunchAccessValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/LaunchAccessValidator.java
@@ -24,17 +24,19 @@
  */
 public interface LaunchAccessValidator {
 
-	/**
-	 * @param launch       {@link com.epam.ta.reportportal.entity.launch.Launch}
-	 * @param projectDetails {@link ReportPortalUser.ProjectDetails}
-	 * @param user           {@link ReportPortalUser}
-	 */
-	void validate(Launch launch, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user);
+  /**
+   * @param launch         {@link com.epam.ta.reportportal.entity.launch.Launch}
+   * @param projectDetails {@link ReportPortalUser.ProjectDetails}
+   * @param user           {@link ReportPortalUser}
+   */
+  void validate(Launch launch, ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user);
 
-	/**
-	 * @param launchId       {@link com.epam.ta.reportportal.entity.launch.Launch#getId()}
-	 * @param projectDetails {@link ReportPortalUser.ProjectDetails}
-	 * @param user           {@link ReportPortalUser}
-	 */
-	void validate(Long launchId, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user);
+  /**
+   * @param launchId       {@link com.epam.ta.reportportal.entity.launch.Launch#getId()}
+   * @param projectDetails {@link ReportPortalUser.ProjectDetails}
+   * @param user           {@link ReportPortalUser}
+   */
+  void validate(Long launchId, ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/LaunchAccessValidatorImpl.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/LaunchAccessValidatorImpl.java
index 655cbe7a9c..5ccf992ff4 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/LaunchAccessValidatorImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/LaunchAccessValidatorImpl.java
@@ -16,21 +16,22 @@
 
 package com.epam.ta.reportportal.core.item.impl;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
+import static com.epam.ta.reportportal.entity.project.ProjectRole.OPERATOR;
+import static com.epam.ta.reportportal.ws.model.ErrorType.ACCESS_DENIED;
+import static com.epam.ta.reportportal.ws.model.ErrorType.FORBIDDEN_OPERATION;
+import static com.epam.ta.reportportal.ws.model.ErrorType.LAUNCH_NOT_FOUND;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.dao.LaunchRepository;
 import com.epam.ta.reportportal.entity.enums.LaunchModeEnum;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.entity.user.UserRole;
 import com.epam.ta.reportportal.exception.ReportPortalException;
-import org.springframework.stereotype.Service;
-
 import java.util.function.Predicate;
-
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
-import static com.epam.ta.reportportal.entity.project.ProjectRole.OPERATOR;
-import static com.epam.ta.reportportal.ws.model.ErrorType.*;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -38,32 +39,38 @@
 @Service
 public class LaunchAccessValidatorImpl implements LaunchAccessValidator {
 
-	private final LaunchRepository launchRepository;
+  private final LaunchRepository launchRepository;
 
-	public LaunchAccessValidatorImpl(LaunchRepository launchRepository) {
-		this.launchRepository = launchRepository;
-	}
+  public LaunchAccessValidatorImpl(LaunchRepository launchRepository) {
+    this.launchRepository = launchRepository;
+  }
 
-	@Override
-	//TODO separate project validation from launch state validation (mode)
-	public void validate(Launch launch, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user) {
-		if (user.getUserRole() != UserRole.ADMINISTRATOR) {
-			expect(launch.getProjectId(), equalTo(projectDetails.getProjectId())).verify(FORBIDDEN_OPERATION,
-					formattedSupplier("Specified launch with id '{}' not referenced to specified project with id '{}'",
-							launch.getId(),
-							projectDetails.getProjectId()
-					)
-			);
-			expect(projectDetails.getProjectRole() == OPERATOR && launch.getMode() == LaunchModeEnum.DEBUG,
-					Predicate.isEqual(false)
-			).verify(ACCESS_DENIED);
-		}
-	}
+  @Override
+  //TODO separate project validation from launch state validation (mode)
+  public void validate(Launch launch, ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user) {
+    if (user.getUserRole() != UserRole.ADMINISTRATOR) {
+      expect(launch.getProjectId(), equalTo(projectDetails.getProjectId())).verify(
+          FORBIDDEN_OPERATION,
+          formattedSupplier(
+              "Specified launch with id '{}' not referenced to specified project with id '{}'",
+              launch.getId(),
+              projectDetails.getProjectId()
+          )
+      );
+      expect(
+          projectDetails.getProjectRole() == OPERATOR && launch.getMode() == LaunchModeEnum.DEBUG,
+          Predicate.isEqual(false)
+      ).verify(ACCESS_DENIED);
+    }
+  }
 
-	@Override
-	public void validate(Long launchId, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user) {
-		Launch launch = launchRepository.findById(launchId).orElseThrow(() -> new ReportPortalException(LAUNCH_NOT_FOUND, launchId));
-		validate(launch, projectDetails, user);
-	}
+  @Override
+  public void validate(Long launchId, ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user) {
+    Launch launch = launchRepository.findById(launchId)
+        .orElseThrow(() -> new ReportPortalException(LAUNCH_NOT_FOUND, launchId));
+    validate(launch, projectDetails, user);
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/StartTestItemHandlerAsyncImpl.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/StartTestItemHandlerAsyncImpl.java
index 4a63bbe195..ffa9eef04d 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/StartTestItemHandlerAsyncImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/StartTestItemHandlerAsyncImpl.java
@@ -16,6 +16,8 @@
 
 package com.epam.ta.reportportal.core.item.impl;
 
+import static com.epam.ta.reportportal.core.configs.rabbit.ReportingConfiguration.EXCHANGE_REPORTING;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.item.StartTestItemHandler;
 import com.epam.ta.reportportal.util.ReportingQueueService;
@@ -23,17 +25,14 @@
 import com.epam.ta.reportportal.ws.model.item.ItemCreatedRS;
 import com.epam.ta.reportportal.ws.rabbit.MessageHeaders;
 import com.epam.ta.reportportal.ws.rabbit.RequestType;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
 import org.springframework.amqp.core.AmqpTemplate;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 
-import java.util.Map;
-import java.util.Optional;
-import java.util.UUID;
-
-import static com.epam.ta.reportportal.core.configs.rabbit.ReportingConfiguration.EXCHANGE_REPORTING;
-
 /**
  * @author Konstantin Antipin
  */
@@ -41,58 +40,60 @@
 @Qualifier("startTestItemHandlerAsync")
 class StartTestItemHandlerAsyncImpl implements StartTestItemHandler {
 
-	@Autowired
-	@Qualifier(value = "rabbitTemplate")
-	AmqpTemplate amqpTemplate;
+  @Autowired
+  @Qualifier(value = "rabbitTemplate")
+  AmqpTemplate amqpTemplate;
 
-	@Autowired
-	private ReportingQueueService reportingQueueService;
+  @Autowired
+  private ReportingQueueService reportingQueueService;
 
-	@Override
-	public ItemCreatedRS startRootItem(ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails, StartTestItemRQ request) {
+  @Override
+  public ItemCreatedRS startRootItem(ReportPortalUser user,
+      ReportPortalUser.ProjectDetails projectDetails, StartTestItemRQ request) {
 
-		// todo: may be problem - no access to repository, so no possibility to validateRoles() here
-		request.setUuid(Optional.ofNullable(request.getUuid()).orElse(UUID.randomUUID().toString()));
-		amqpTemplate.convertAndSend(EXCHANGE_REPORTING,
-				reportingQueueService.getReportingQueueKey(request.getLaunchUuid()),
-				request,
-				message -> {
-					Map<String, Object> headers = message.getMessageProperties().getHeaders();
-					headers.put(MessageHeaders.REQUEST_TYPE, RequestType.START_TEST);
-					headers.put(MessageHeaders.USERNAME, user.getUsername());
-					headers.put(MessageHeaders.PROJECT_NAME, projectDetails.getProjectName());
-					headers.put(MessageHeaders.PARENT_ITEM_ID, "");
-					return message;
-				}
-		);
+    // todo: may be problem - no access to repository, so no possibility to validateRoles() here
+    request.setUuid(Optional.ofNullable(request.getUuid()).orElse(UUID.randomUUID().toString()));
+    amqpTemplate.convertAndSend(EXCHANGE_REPORTING,
+        reportingQueueService.getReportingQueueKey(request.getLaunchUuid()),
+        request,
+        message -> {
+          Map<String, Object> headers = message.getMessageProperties().getHeaders();
+          headers.put(MessageHeaders.REQUEST_TYPE, RequestType.START_TEST);
+          headers.put(MessageHeaders.USERNAME, user.getUsername());
+          headers.put(MessageHeaders.PROJECT_NAME, projectDetails.getProjectName());
+          headers.put(MessageHeaders.PARENT_ITEM_ID, "");
+          return message;
+        }
+    );
 
-		ItemCreatedRS response = new ItemCreatedRS();
-		response.setId(request.getUuid());
-		return response;
-	}
+    ItemCreatedRS response = new ItemCreatedRS();
+    response.setId(request.getUuid());
+    return response;
+  }
 
-	@Override
-	public ItemCreatedRS startChildItem(ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails, StartTestItemRQ request,
-			String parentId) {
+  @Override
+  public ItemCreatedRS startChildItem(ReportPortalUser user,
+      ReportPortalUser.ProjectDetails projectDetails, StartTestItemRQ request,
+      String parentId) {
 
-		// todo: may be problem - no access to repository, so no possibility to validateRoles() here
-		request.setUuid(Optional.ofNullable(request.getUuid()).orElse(UUID.randomUUID().toString()));
-		amqpTemplate.convertAndSend(
-				EXCHANGE_REPORTING,
-				reportingQueueService.getReportingQueueKey(request.getLaunchUuid()),
-				request,
-				message -> {
-					Map<String, Object> headers = message.getMessageProperties().getHeaders();
-					headers.put(MessageHeaders.REQUEST_TYPE, RequestType.START_TEST);
-					headers.put(MessageHeaders.USERNAME, user.getUsername());
-					headers.put(MessageHeaders.PROJECT_NAME, projectDetails.getProjectName());
-					headers.put(MessageHeaders.PARENT_ITEM_ID, parentId);
-					return message;
-				}
-		);
+    // todo: may be problem - no access to repository, so no possibility to validateRoles() here
+    request.setUuid(Optional.ofNullable(request.getUuid()).orElse(UUID.randomUUID().toString()));
+    amqpTemplate.convertAndSend(
+        EXCHANGE_REPORTING,
+        reportingQueueService.getReportingQueueKey(request.getLaunchUuid()),
+        request,
+        message -> {
+          Map<String, Object> headers = message.getMessageProperties().getHeaders();
+          headers.put(MessageHeaders.REQUEST_TYPE, RequestType.START_TEST);
+          headers.put(MessageHeaders.USERNAME, user.getUsername());
+          headers.put(MessageHeaders.PROJECT_NAME, projectDetails.getProjectName());
+          headers.put(MessageHeaders.PARENT_ITEM_ID, parentId);
+          return message;
+        }
+    );
 
-		ItemCreatedRS response = new ItemCreatedRS();
-		response.setId(request.getUuid());
-		return response;
-	}
+    ItemCreatedRS response = new ItemCreatedRS();
+    response.setId(request.getUuid());
+    return response;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/StartTestItemHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/StartTestItemHandlerImpl.java
index 7051a0f020..c53070507f 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/StartTestItemHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/StartTestItemHandlerImpl.java
@@ -16,6 +16,16 @@
 
 package com.epam.ta.reportportal.core.item.impl;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.ws.model.ErrorType.ACCESS_DENIED;
+import static com.epam.ta.reportportal.ws.model.ErrorType.BAD_REQUEST_ERROR;
+import static com.epam.ta.reportportal.ws.model.ErrorType.CHILD_START_TIME_EARLIER_THAN_PARENT;
+import static com.epam.ta.reportportal.ws.model.ErrorType.LAUNCH_NOT_FOUND;
+import static com.epam.ta.reportportal.ws.model.ErrorType.TEST_ITEM_NOT_FOUND;
+import static java.util.Optional.ofNullable;
+import static org.apache.commons.lang3.BooleanUtils.isTrue;
+
 import com.epam.ta.reportportal.commons.Preconditions;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.item.StartTestItemHandler;
@@ -36,6 +46,9 @@
 import com.epam.ta.reportportal.ws.converter.builders.TestItemBuilder;
 import com.epam.ta.reportportal.ws.model.StartTestItemRQ;
 import com.epam.ta.reportportal.ws.model.item.ItemCreatedRS;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
 import org.apache.commons.lang3.BooleanUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
@@ -46,16 +59,6 @@
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.List;
-import java.util.Objects;
-import java.util.Optional;
-
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.ws.model.ErrorType.*;
-import static java.util.Optional.ofNullable;
-import static org.apache.commons.lang3.BooleanUtils.isTrue;
-
 /**
  * Start Test Item operation default implementation
  *
@@ -67,153 +70,168 @@
 @Transactional
 class StartTestItemHandlerImpl implements StartTestItemHandler {
 
-	private static final Logger LOGGER = LoggerFactory.getLogger(StartTestItemHandlerImpl.class);
-
-	private final TestItemRepository testItemRepository;
-
-	private final LaunchRepository launchRepository;
-
-	private final UniqueIdGenerator uniqueIdGenerator;
-
-	private final TestCaseHashGenerator testCaseHashGenerator;
-
-	private final RerunHandler rerunHandler;
-
-	private final List<ParentItemValidator> parentItemValidators;
-
-	private final RetrySearcher retrySearcher;
-	private final RetryHandler retryHandler;
-
-	@Autowired
-	public StartTestItemHandlerImpl(TestItemRepository testItemRepository, LaunchRepository launchRepository,
-			UniqueIdGenerator uniqueIdGenerator, TestCaseHashGenerator testCaseHashGenerator, RerunHandler rerunHandler,
-			List<ParentItemValidator> parentItemValidators, @Qualifier("uniqueIdRetrySearcher") RetrySearcher retrySearcher,
-			RetryHandler retryHandler) {
-		this.testItemRepository = testItemRepository;
-		this.launchRepository = launchRepository;
-		this.uniqueIdGenerator = uniqueIdGenerator;
-		this.testCaseHashGenerator = testCaseHashGenerator;
-		this.rerunHandler = rerunHandler;
-		this.parentItemValidators = parentItemValidators;
-		this.retrySearcher = retrySearcher;
-		this.retryHandler = retryHandler;
-	}
-
-	@Override
-	public ItemCreatedRS startRootItem(ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails, StartTestItemRQ rq) {
-		Launch launch = launchRepository.findByUuid(rq.getLaunchUuid())
-				.orElseThrow(() -> new ReportPortalException(LAUNCH_NOT_FOUND, rq.getLaunchUuid()));
-		validate(user, projectDetails, rq, launch);
-
-		if (launch.isRerun()) {
-			Optional<ItemCreatedRS> rerunCreatedRs = rerunHandler.handleRootItem(rq, launch);
-			if (rerunCreatedRs.isPresent()) {
-				return rerunCreatedRs.get();
-			}
-		}
-
-		TestItem item = new TestItemBuilder().addStartItemRequest(rq).addAttributes(rq.getAttributes()).addLaunchId(launch.getId()).get();
-		testItemRepository.save(item);
-		generateUniqueId(launch, item, String.valueOf(item.getItemId()));
-
-		LOGGER.debug("Created new root TestItem {}", item.getUuid());
-		return new ItemCreatedRS(item.getUuid(), item.getUniqueId());
-	}
-
-	@Override
-	public ItemCreatedRS startChildItem(ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails, StartTestItemRQ rq,
-			String parentId) {
-		boolean isRetry = BooleanUtils.toBoolean(rq.isRetry()) || StringUtils.isNotBlank(rq.getRetryOf());
-
-		Launch launch = launchRepository.findByUuid(rq.getLaunchUuid())
-				.orElseThrow(() -> new ReportPortalException(LAUNCH_NOT_FOUND, rq.getLaunchUuid()));
-
-		if (launch.isRerun()) {
-			Optional<ItemCreatedRS> rerunCreatedRs = rerunHandler.handleChildItem(rq, launch, parentId);
-			if (rerunCreatedRs.isPresent()) {
-				return rerunCreatedRs.get();
-			}
-		}
-
-		final TestItem parentItem;
-		if (isRetry) {
-			// Lock for test
-			Long lockedParentId = testItemRepository.findIdByUuidForUpdate(parentId)
-					.orElseThrow(() -> new ReportPortalException(TEST_ITEM_NOT_FOUND, parentId));
-			parentItem = testItemRepository.getOne(lockedParentId);
-		} else {
-			parentItem = testItemRepository.findByUuid(parentId)
-					.orElseThrow(() -> new ReportPortalException(TEST_ITEM_NOT_FOUND, parentId));
-		}
-
-		parentItemValidators.forEach(v -> v.validate(rq, parentItem));
-
-		TestItem item = new TestItemBuilder().addStartItemRequest(rq).addAttributes(rq.getAttributes()).addLaunchId(launch.getId()).get();
-
-		if (isRetry) {
-			ofNullable(rq.getRetryOf()).flatMap(testItemRepository::findIdByUuidForUpdate).ifPresentOrElse(retryParentId -> {
-				saveChildItem(launch, item, parentItem);
-				retryHandler.handleRetries(launch, item, retryParentId);
-			}, () -> retrySearcher.findPreviousRetry(launch, item, parentItem).ifPresentOrElse(previousRetryId -> {
-				saveChildItem(launch, item, parentItem);
-				retryHandler.handleRetries(launch, item, previousRetryId);
-			}, () -> saveChildItem(launch, item, parentItem)));
-		} else {
-			saveChildItem(launch, item, parentItem);
-		}
-
-		LOGGER.debug("Created new child TestItem {} with root {}", item.getUuid(), parentId);
-
-		if (rq.isHasStats() && !parentItem.isHasChildren()) {
-			parentItem.setHasChildren(true);
-		}
-
-		return new ItemCreatedRS(item.getUuid(), item.getUniqueId());
-	}
-
-	private TestItem saveChildItem(Launch launch, TestItem childItem, TestItem parentItem) {
-		childItem.setParentId(parentItem.getItemId());
-		testItemRepository.save(childItem);
-		generateUniqueId(launch, childItem, parentItem.getPath() + "." + childItem.getItemId());
-		return childItem;
-	}
-
-	/**
-	 * Generates and sets {@link TestItem#getUniqueId()} and {@link TestItem#getTestCaseId()} if they are empty
-	 *
-	 * @param launch {@link Launch} of {@link TestItem}
-	 * @param item   {@link TestItem}
-	 * @param path   {@link TestItem} path
-	 */
-	private void generateUniqueId(Launch launch, TestItem item, String path) {
-		item.setPath(path);
-		if (Objects.isNull(item.getUniqueId())) {
-			item.setUniqueId(uniqueIdGenerator.generate(item, IdentityUtil.getParentIds(item), launch));
-		}
-		if (Objects.isNull(item.getTestCaseId())) {
-			item.setTestCaseHash(testCaseHashGenerator.generate(item, IdentityUtil.getParentIds(item), launch.getProjectId()));
-		}
-	}
-
-	/**
-	 * Validate {@link ReportPortalUser} credentials, {@link Launch#getStatus()}
-	 * and {@link Launch} affiliation to the {@link Project}
-	 *
-	 * @param user           {@link ReportPortalUser}
-	 * @param projectDetails {@link ReportPortalUser.ProjectDetails}
-	 * @param rq             {@link StartTestItemRQ}
-	 * @param launch         {@link Launch}
-	 */
-	private void validate(ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails, StartTestItemRQ rq, Launch launch) {
-		if (!UserRole.ADMINISTRATOR.equals(user.getUserRole())) {
-			expect(projectDetails.getProjectId(), equalTo(launch.getProjectId())).verify(ACCESS_DENIED);
-		}
-		expect(rq.getStartTime(), Preconditions.sameTimeOrLater(launch.getStartTime())).verify(CHILD_START_TIME_EARLIER_THAN_PARENT,
-				rq.getStartTime(),
-				launch.getStartTime(),
-				launch.getId()
-		);
-		expect(isTrue(BooleanUtils.toBoolean(rq.isRetry())), equalTo(false)).verify(BAD_REQUEST_ERROR, "Root test item can't be a retry.");
-	}
+  private static final Logger LOGGER = LoggerFactory.getLogger(StartTestItemHandlerImpl.class);
+
+  private final TestItemRepository testItemRepository;
+
+  private final LaunchRepository launchRepository;
+
+  private final UniqueIdGenerator uniqueIdGenerator;
+
+  private final TestCaseHashGenerator testCaseHashGenerator;
+
+  private final RerunHandler rerunHandler;
+
+  private final List<ParentItemValidator> parentItemValidators;
+
+  private final RetrySearcher retrySearcher;
+  private final RetryHandler retryHandler;
+
+  @Autowired
+  public StartTestItemHandlerImpl(TestItemRepository testItemRepository,
+      LaunchRepository launchRepository,
+      UniqueIdGenerator uniqueIdGenerator, TestCaseHashGenerator testCaseHashGenerator,
+      RerunHandler rerunHandler,
+      List<ParentItemValidator> parentItemValidators,
+      @Qualifier("uniqueIdRetrySearcher") RetrySearcher retrySearcher,
+      RetryHandler retryHandler) {
+    this.testItemRepository = testItemRepository;
+    this.launchRepository = launchRepository;
+    this.uniqueIdGenerator = uniqueIdGenerator;
+    this.testCaseHashGenerator = testCaseHashGenerator;
+    this.rerunHandler = rerunHandler;
+    this.parentItemValidators = parentItemValidators;
+    this.retrySearcher = retrySearcher;
+    this.retryHandler = retryHandler;
+  }
+
+  @Override
+  public ItemCreatedRS startRootItem(ReportPortalUser user,
+      ReportPortalUser.ProjectDetails projectDetails, StartTestItemRQ rq) {
+    Launch launch = launchRepository.findByUuid(rq.getLaunchUuid())
+        .orElseThrow(() -> new ReportPortalException(LAUNCH_NOT_FOUND, rq.getLaunchUuid()));
+    validate(user, projectDetails, rq, launch);
+
+    if (launch.isRerun()) {
+      Optional<ItemCreatedRS> rerunCreatedRs = rerunHandler.handleRootItem(rq, launch);
+      if (rerunCreatedRs.isPresent()) {
+        return rerunCreatedRs.get();
+      }
+    }
+
+    TestItem item = new TestItemBuilder().addStartItemRequest(rq).addAttributes(rq.getAttributes())
+        .addLaunchId(launch.getId()).get();
+    testItemRepository.save(item);
+    generateUniqueId(launch, item, String.valueOf(item.getItemId()));
+
+    LOGGER.debug("Created new root TestItem {}", item.getUuid());
+    return new ItemCreatedRS(item.getUuid(), item.getUniqueId());
+  }
+
+  @Override
+  public ItemCreatedRS startChildItem(ReportPortalUser user,
+      ReportPortalUser.ProjectDetails projectDetails, StartTestItemRQ rq,
+      String parentId) {
+    boolean isRetry =
+        BooleanUtils.toBoolean(rq.isRetry()) || StringUtils.isNotBlank(rq.getRetryOf());
+
+    Launch launch = launchRepository.findByUuid(rq.getLaunchUuid())
+        .orElseThrow(() -> new ReportPortalException(LAUNCH_NOT_FOUND, rq.getLaunchUuid()));
+
+    if (launch.isRerun()) {
+      Optional<ItemCreatedRS> rerunCreatedRs = rerunHandler.handleChildItem(rq, launch, parentId);
+      if (rerunCreatedRs.isPresent()) {
+        return rerunCreatedRs.get();
+      }
+    }
+
+    final TestItem parentItem;
+    if (isRetry) {
+      // Lock for test
+      Long lockedParentId = testItemRepository.findIdByUuidForUpdate(parentId)
+          .orElseThrow(() -> new ReportPortalException(TEST_ITEM_NOT_FOUND, parentId));
+      parentItem = testItemRepository.getOne(lockedParentId);
+    } else {
+      parentItem = testItemRepository.findByUuid(parentId)
+          .orElseThrow(() -> new ReportPortalException(TEST_ITEM_NOT_FOUND, parentId));
+    }
+
+    parentItemValidators.forEach(v -> v.validate(rq, parentItem));
+
+    TestItem item = new TestItemBuilder().addStartItemRequest(rq).addAttributes(rq.getAttributes())
+        .addLaunchId(launch.getId()).get();
+
+    if (isRetry) {
+      ofNullable(rq.getRetryOf()).flatMap(testItemRepository::findIdByUuidForUpdate)
+          .ifPresentOrElse(retryParentId -> {
+            saveChildItem(launch, item, parentItem);
+            retryHandler.handleRetries(launch, item, retryParentId);
+          }, () -> retrySearcher.findPreviousRetry(launch, item, parentItem)
+              .ifPresentOrElse(previousRetryId -> {
+                saveChildItem(launch, item, parentItem);
+                retryHandler.handleRetries(launch, item, previousRetryId);
+              }, () -> saveChildItem(launch, item, parentItem)));
+    } else {
+      saveChildItem(launch, item, parentItem);
+    }
+
+    LOGGER.debug("Created new child TestItem {} with root {}", item.getUuid(), parentId);
+
+    if (rq.isHasStats() && !parentItem.isHasChildren()) {
+      parentItem.setHasChildren(true);
+    }
+
+    return new ItemCreatedRS(item.getUuid(), item.getUniqueId());
+  }
+
+  private TestItem saveChildItem(Launch launch, TestItem childItem, TestItem parentItem) {
+    childItem.setParentId(parentItem.getItemId());
+    testItemRepository.save(childItem);
+    generateUniqueId(launch, childItem, parentItem.getPath() + "." + childItem.getItemId());
+    return childItem;
+  }
+
+  /**
+   * Generates and sets {@link TestItem#getUniqueId()} and {@link TestItem#getTestCaseId()} if they
+   * are empty
+   *
+   * @param launch {@link Launch} of {@link TestItem}
+   * @param item   {@link TestItem}
+   * @param path   {@link TestItem} path
+   */
+  private void generateUniqueId(Launch launch, TestItem item, String path) {
+    item.setPath(path);
+    if (Objects.isNull(item.getUniqueId())) {
+      item.setUniqueId(uniqueIdGenerator.generate(item, IdentityUtil.getParentIds(item), launch));
+    }
+    if (Objects.isNull(item.getTestCaseId())) {
+      item.setTestCaseHash(testCaseHashGenerator.generate(item, IdentityUtil.getParentIds(item),
+          launch.getProjectId()));
+    }
+  }
+
+  /**
+   * Validate {@link ReportPortalUser} credentials, {@link Launch#getStatus()} and {@link Launch}
+   * affiliation to the {@link Project}
+   *
+   * @param user           {@link ReportPortalUser}
+   * @param projectDetails {@link ReportPortalUser.ProjectDetails}
+   * @param rq             {@link StartTestItemRQ}
+   * @param launch         {@link Launch}
+   */
+  private void validate(ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails,
+      StartTestItemRQ rq, Launch launch) {
+    if (!UserRole.ADMINISTRATOR.equals(user.getUserRole())) {
+      expect(projectDetails.getProjectId(), equalTo(launch.getProjectId())).verify(ACCESS_DENIED);
+    }
+    expect(rq.getStartTime(), Preconditions.sameTimeOrLater(launch.getStartTime())).verify(
+        CHILD_START_TIME_EARLIER_THAN_PARENT,
+        rq.getStartTime(),
+        launch.getStartTime(),
+        launch.getId()
+    );
+    expect(isTrue(BooleanUtils.toBoolean(rq.isRetry())), equalTo(false)).verify(BAD_REQUEST_ERROR,
+        "Root test item can't be a retry.");
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/UpdateTestItemHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/UpdateTestItemHandlerImpl.java
index db88cdf8f1..e6f0742223 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/UpdateTestItemHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/UpdateTestItemHandlerImpl.java
@@ -99,325 +99,351 @@
 @Service
 public class UpdateTestItemHandlerImpl implements UpdateTestItemHandler {
 
-	public static final String INITIAL_STATUS_ATTRIBUTE_KEY = "initialStatus";
-	private static final String MANUALLY_CHANGED_STATUS_ATTRIBUTE_KEY = "manually";
+  public static final String INITIAL_STATUS_ATTRIBUTE_KEY = "initialStatus";
+  private static final String MANUALLY_CHANGED_STATUS_ATTRIBUTE_KEY = "manually";
 
-	private final TestItemService testItemService;
-
-	private final ProjectRepository projectRepository;
+  private final TestItemService testItemService;
 
-	private final TestItemRepository testItemRepository;
+  private final ProjectRepository projectRepository;
 
-	private final ExternalTicketHandler externalTicketHandler;
+  private final TestItemRepository testItemRepository;
 
-	private final IssueTypeHandler issueTypeHandler;
-
-	private final MessageBus messageBus;
-
-	private final LogIndexerService logIndexerService;
-
-	private final IssueEntityRepository issueEntityRepository;
-
-	private final Map<StatusEnum, StatusChangingStrategy> statusChangingStrategyMapping;
-
-	@Autowired
-	public UpdateTestItemHandlerImpl(TestItemService testItemService, ProjectRepository projectRepository,
-			TestItemRepository testItemRepository, ExternalTicketHandler externalTicketHandler, IssueTypeHandler issueTypeHandler,
-			MessageBus messageBus, LogIndexerService logIndexerService, IssueEntityRepository issueEntityRepository,
-			Map<StatusEnum, StatusChangingStrategy> statusChangingStrategyMapping) {
-		this.testItemService = testItemService;
-		this.projectRepository = projectRepository;
-		this.testItemRepository = testItemRepository;
-		this.externalTicketHandler = externalTicketHandler;
-		this.issueTypeHandler = issueTypeHandler;
-		this.messageBus = messageBus;
-		this.logIndexerService = logIndexerService;
-		this.issueEntityRepository = issueEntityRepository;
-		this.statusChangingStrategyMapping = statusChangingStrategyMapping;
-	}
-
-	@Override
-	public List<Issue> defineTestItemsIssues(ReportPortalUser.ProjectDetails projectDetails, DefineIssueRQ defineIssue,
-			ReportPortalUser user) {
-		Project project = projectRepository.findById(projectDetails.getProjectId())
-				.orElseThrow(() -> new ReportPortalException(PROJECT_NOT_FOUND, projectDetails.getProjectId()));
-
-		List<String> errors = new ArrayList<>();
-		List<IssueDefinition> definitions = defineIssue.getIssues();
-		expect(CollectionUtils.isEmpty(definitions), equalTo(false)).verify(FAILED_TEST_ITEM_ISSUE_TYPE_DEFINITION);
-		List<Issue> updated = new ArrayList<>(defineIssue.getIssues().size());
-		List<ItemIssueTypeDefinedEvent> events = new ArrayList<>();
-		List<TestItem> itemsForIndexUpdate = new ArrayList<>();
-		List<Long> itemsForIndexRemove = new ArrayList<>();
-
-		definitions.forEach(issueDefinition -> {
-			try {
-				TestItem testItem = testItemRepository.findById(issueDefinition.getId())
-						.orElseThrow(() -> new BusinessRuleViolationException(formattedSupplier(
-								"Cannot update issue type for test item '{}', cause it is not found.",
-								issueDefinition.getId()
-						).get()));
-
-				verifyTestItem(testItem, issueDefinition.getId());
-				TestItemActivityResource before = TO_ACTIVITY_RESOURCE.apply(testItem, projectDetails.getProjectId());
-
-				Issue issue = issueDefinition.getIssue();
-				IssueType issueType = issueTypeHandler.defineIssueType(projectDetails.getProjectId(), issue.getIssueType());
-
-				IssueEntity issueEntity = new IssueEntityBuilder(testItem.getItemResults().getIssue()).addIssueType(issueType)
-						.addDescription(issue.getComment())
-						.addIgnoreFlag(issue.getIgnoreAnalyzer())
-						.addAutoAnalyzedFlag(issue.getAutoAnalyzed())
-						.get();
-
-				externalTicketHandler.updateLinking(user.getUsername(), issueEntity, issueDefinition.getIssue().getExternalSystemIssues());
-
-				testItem.getItemResults().setIssue(issueEntity);
-				issueEntity.setTestItemResults(testItem.getItemResults());
-				testItemRepository.save(testItem);
-
-				if (ITEM_CAN_BE_INDEXED.test(testItem)) {
-					itemsForIndexUpdate.add(testItem);
-				} else {
-					itemsForIndexRemove.add(testItem.getItemId());
-				}
-
-				updated.add(IssueConverter.TO_MODEL.apply(issueEntity));
-
-				TestItemActivityResource after = TO_ACTIVITY_RESOURCE.apply(testItem, projectDetails.getProjectId());
-
-				events.add(new ItemIssueTypeDefinedEvent(before, after, user.getUserId(), user.getUsername()));
-			} catch (BusinessRuleViolationException e) {
-				errors.add(e.getMessage());
-			}
-		});
-		expect(errors.isEmpty(), equalTo(TRUE)).verify(FAILED_TEST_ITEM_ISSUE_TYPE_DEFINITION, errors.toString());
-
-		logIndexerService.indexDefectsUpdate(project.getId(), AnalyzerUtils.getAnalyzerConfig(project), itemsForIndexUpdate);
-		logIndexerService.indexItemsRemoveAsync(project.getId(), itemsForIndexRemove);
-
-		events.forEach(messageBus::publishActivity);
-		return updated;
-	}
-
-	@Override
-	public OperationCompletionRS updateTestItem(ReportPortalUser.ProjectDetails projectDetails, Long itemId, UpdateTestItemRQ rq,
-			ReportPortalUser user) {
-		TestItem testItem = testItemRepository.findById(itemId)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, itemId));
-
-		validate(projectDetails, user, testItem);
-
-		Optional<StatusEnum> providedStatus = StatusEnum.fromValue(rq.getStatus());
-		if (providedStatus.isPresent() && !providedStatus.get().equals(testItem.getItemResults().getStatus())) {
-			expect(testItem.isHasChildren() && !testItem.getType().sameLevel(TestItemTypeEnum.STEP), equalTo(FALSE)).verify(INCORRECT_REQUEST,
-					"Unable to change status on test item with children"
-			);
-			checkInitialStatusAttribute(testItem, rq);
-			StatusChangingStrategy strategy = statusChangingStrategyMapping.get(providedStatus.get());
-
-			expect(strategy, notNull()).verify(INCORRECT_REQUEST,
-					formattedSupplier("Actual status: '{}' cannot be changed to '{}'.",
-							testItem.getItemResults().getStatus(),
-							providedStatus.get()
-					)
-			);
-			TestItemActivityResource before = TO_ACTIVITY_RESOURCE.apply(testItem, projectDetails.getProjectId());
-			strategy.changeStatus(testItem, providedStatus.get(), user);
-			messageBus.publishActivity(new TestItemStatusChangedEvent(before,
-					TO_ACTIVITY_RESOURCE.apply(testItem, projectDetails.getProjectId()),
-					user.getUserId(),
-					user.getUsername()
-			));
-		}
-		testItem = new TestItemBuilder(testItem).overwriteAttributes(rq.getAttributes()).addDescription(rq.getDescription()).get();
-		testItemRepository.save(testItem);
-
-		return COMPOSE_UPDATE_RESPONSE.apply(itemId);
-	}
-
-	@Override
-	public List<OperationCompletionRS> processExternalIssues(ExternalIssueRQ request, ReportPortalUser.ProjectDetails projectDetails,
-			ReportPortalUser user) {
-		List<String> errors = new ArrayList<>();
-
-		List<TestItem> testItems = testItemRepository.findAllById(request.getTestItemIds());
-
-		testItems.forEach(testItem -> {
-			try {
-				verifyTestItem(testItem, testItem.getItemId());
-			} catch (Exception e) {
-				errors.add(e.getMessage());
-			}
-		});
-		expect(errors.isEmpty(), equalTo(TRUE)).verify(FAILED_TEST_ITEM_ISSUE_TYPE_DEFINITION, errors.toString());
-
-		List<TestItemActivityResource> before = testItems.stream()
-				.map(it -> TO_ACTIVITY_RESOURCE.apply(it, projectDetails.getProjectId()))
-				.collect(Collectors.toList());
-
-		if (LinkExternalIssueRQ.class.equals(request.getClass())) {
-			LinkExternalIssueRQ linkRequest = (LinkExternalIssueRQ) request;
-			externalTicketHandler.linkExternalTickets(user.getUsername(),
-					testItems.stream().map(it -> it.getItemResults().getIssue()).collect(Collectors.toList()),
-					linkRequest.getIssues()
-			);
+  private final ExternalTicketHandler externalTicketHandler;
+
+  private final IssueTypeHandler issueTypeHandler;
+
+  private final MessageBus messageBus;
+
+  private final LogIndexerService logIndexerService;
+
+  private final IssueEntityRepository issueEntityRepository;
+
+  private final Map<StatusEnum, StatusChangingStrategy> statusChangingStrategyMapping;
+
+  @Autowired
+  public UpdateTestItemHandlerImpl(TestItemService testItemService,
+      ProjectRepository projectRepository, TestItemRepository testItemRepository,
+      ExternalTicketHandler externalTicketHandler, IssueTypeHandler issueTypeHandler,
+      MessageBus messageBus, LogIndexerService logIndexerService,
+      IssueEntityRepository issueEntityRepository,
+      Map<StatusEnum, StatusChangingStrategy> statusChangingStrategyMapping) {
+    this.testItemService = testItemService;
+    this.projectRepository = projectRepository;
+    this.testItemRepository = testItemRepository;
+    this.externalTicketHandler = externalTicketHandler;
+    this.issueTypeHandler = issueTypeHandler;
+    this.messageBus = messageBus;
+    this.logIndexerService = logIndexerService;
+    this.issueEntityRepository = issueEntityRepository;
+    this.statusChangingStrategyMapping = statusChangingStrategyMapping;
+  }
+
+  @Override
+  public List<Issue> defineTestItemsIssues(ReportPortalUser.ProjectDetails projectDetails,
+      DefineIssueRQ defineIssue, ReportPortalUser user) {
+    Project project = projectRepository.findById(projectDetails.getProjectId()).orElseThrow(
+        () -> new ReportPortalException(PROJECT_NOT_FOUND, projectDetails.getProjectId()));
+
+    List<String> errors = new ArrayList<>();
+    List<IssueDefinition> definitions = defineIssue.getIssues();
+    expect(CollectionUtils.isEmpty(definitions), equalTo(false)).verify(
+        FAILED_TEST_ITEM_ISSUE_TYPE_DEFINITION);
+    List<Issue> updated = new ArrayList<>(defineIssue.getIssues().size());
+    List<ItemIssueTypeDefinedEvent> events = new ArrayList<>();
+    List<TestItem> itemsForIndexUpdate = new ArrayList<>();
+    List<Long> itemsForIndexRemove = new ArrayList<>();
+
+    definitions.forEach(issueDefinition -> {
+      try {
+        TestItem testItem = testItemRepository.findById(issueDefinition.getId())
+            .orElseThrow(() -> new BusinessRuleViolationException(formattedSupplier(
+                "Cannot update issue type for test item '{}', cause it is not found.",
+                issueDefinition.getId()
+            ).get()));
+
+        verifyTestItem(testItem, issueDefinition.getId());
+        TestItemActivityResource before =
+            TO_ACTIVITY_RESOURCE.apply(testItem, projectDetails.getProjectId());
+
+        Issue issue = issueDefinition.getIssue();
+        IssueType issueType =
+            issueTypeHandler.defineIssueType(projectDetails.getProjectId(), issue.getIssueType());
+
+        IssueEntity issueEntity =
+            new IssueEntityBuilder(testItem.getItemResults().getIssue()).addIssueType(issueType)
+                .addDescription(issue.getComment()).addIgnoreFlag(issue.getIgnoreAnalyzer())
+                .addAutoAnalyzedFlag(issue.getAutoAnalyzed()).get();
+
+        externalTicketHandler.updateLinking(
+            user.getUsername(), issueEntity, issueDefinition.getIssue().getExternalSystemIssues());
+
+        testItem.getItemResults().setIssue(issueEntity);
+        issueEntity.setTestItemResults(testItem.getItemResults());
+        testItemRepository.save(testItem);
+
+        if (ITEM_CAN_BE_INDEXED.test(testItem)) {
+          itemsForIndexUpdate.add(testItem);
+        } else {
+          itemsForIndexRemove.add(testItem.getItemId());
+        }
+
+        updated.add(IssueConverter.TO_MODEL.apply(issueEntity));
+
+        TestItemActivityResource after =
+            TO_ACTIVITY_RESOURCE.apply(testItem, projectDetails.getProjectId());
+
+        events.add(
+            new ItemIssueTypeDefinedEvent(before, after, user.getUserId(), user.getUsername()));
+      } catch (BusinessRuleViolationException e) {
+        errors.add(e.getMessage());
+      }
+    });
+    expect(errors.isEmpty(), equalTo(TRUE)).verify(
+        FAILED_TEST_ITEM_ISSUE_TYPE_DEFINITION, errors.toString());
+
+    if (CollectionUtils.isNotEmpty(itemsForIndexUpdate)) {
+      logIndexerService.indexDefectsUpdate(
+          project.getId(), AnalyzerUtils.getAnalyzerConfig(project), itemsForIndexUpdate);
+    }
+    if (CollectionUtils.isNotEmpty(itemsForIndexRemove)) {
+      logIndexerService.indexItemsRemoveAsync(project.getId(), itemsForIndexRemove);
+    }
+
+    events.forEach(messageBus::publishActivity);
+    return updated;
+  }
+
+  @Override
+  public OperationCompletionRS updateTestItem(ReportPortalUser.ProjectDetails projectDetails,
+      Long itemId, UpdateTestItemRQ rq, ReportPortalUser user) {
+    TestItem testItem = testItemRepository.findById(itemId)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, itemId));
+
+    validate(projectDetails, user, testItem);
+
+    Optional<StatusEnum> providedStatus = StatusEnum.fromValue(rq.getStatus());
+    if (providedStatus.isPresent() && !providedStatus.get()
+        .equals(testItem.getItemResults().getStatus())) {
+      expect(testItem.isHasChildren() && !testItem.getType().sameLevel(TestItemTypeEnum.STEP),
+          equalTo(FALSE)
+      ).verify(INCORRECT_REQUEST, "Unable to change status on test item with children");
+      checkInitialStatusAttribute(testItem, rq);
+      StatusChangingStrategy strategy = statusChangingStrategyMapping.get(providedStatus.get());
+
+      expect(strategy, notNull()).verify(INCORRECT_REQUEST,
+          formattedSupplier("Actual status: '{}' cannot be changed to '{}'.",
+              testItem.getItemResults().getStatus(), providedStatus.get()
+          )
+      );
+      TestItemActivityResource before =
+          TO_ACTIVITY_RESOURCE.apply(testItem, projectDetails.getProjectId());
+      strategy.changeStatus(testItem, providedStatus.get(), user, true);
+      messageBus.publishActivity(new TestItemStatusChangedEvent(before,
+          TO_ACTIVITY_RESOURCE.apply(testItem, projectDetails.getProjectId()), user.getUserId(),
+          user.getUsername()
+      ));
+    }
+    testItem = new TestItemBuilder(testItem).overwriteAttributes(rq.getAttributes())
+        .addDescription(rq.getDescription()).get();
+    testItemRepository.save(testItem);
+
+    return COMPOSE_UPDATE_RESPONSE.apply(itemId);
+  }
+
+  @Override
+  public List<OperationCompletionRS> processExternalIssues(ExternalIssueRQ request,
+      ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user) {
+    List<String> errors = new ArrayList<>();
+
+    List<TestItem> testItems = testItemRepository.findAllById(request.getTestItemIds());
+
+    testItems.forEach(testItem -> {
+      try {
+        verifyTestItem(testItem, testItem.getItemId());
+      } catch (Exception e) {
+        errors.add(e.getMessage());
+      }
+    });
+    expect(errors.isEmpty(), equalTo(TRUE)).verify(
+        FAILED_TEST_ITEM_ISSUE_TYPE_DEFINITION, errors.toString());
+
+    List<TestItemActivityResource> before =
+        testItems.stream().map(it -> TO_ACTIVITY_RESOURCE.apply(it, projectDetails.getProjectId()))
+            .collect(Collectors.toList());
+
+    if (LinkExternalIssueRQ.class.equals(request.getClass())) {
+      LinkExternalIssueRQ linkRequest = (LinkExternalIssueRQ) request;
+      externalTicketHandler.linkExternalTickets(user.getUsername(),
+          testItems.stream().map(it -> it.getItemResults().getIssue()).collect(Collectors.toList()),
+          linkRequest.getIssues()
+      );
     }
 
     if (UnlinkExternalIssueRQ.class.equals(request.getClass())) {
       externalTicketHandler.unlinkExternalTickets(testItems, (UnlinkExternalIssueRQ) request);
     }
     testItemRepository.saveAll(testItems);
-    List<TestItemActivityResource> after = testItems.stream()
-        .map(it -> TO_ACTIVITY_RESOURCE.apply(it, projectDetails.getProjectId()))
-        .collect(Collectors.toList());
+    List<TestItemActivityResource> after =
+        testItems.stream().map(it -> TO_ACTIVITY_RESOURCE.apply(it, projectDetails.getProjectId()))
+            .collect(Collectors.toList());
 
     before.forEach(it -> messageBus.publishActivity(new LinkTicketEvent(it,
         after.stream().filter(t -> t.getId().equals(it.getId())).findFirst().get(),
-        user.getUserId(),
-        user.getUsername(),
-        false
+        user.getUserId(), user.getUsername(), false
     )));
     return testItems.stream().map(TestItem::getItemId).map(COMPOSE_UPDATE_RESPONSE)
         .collect(toList());
   }
 
-	private static final Function<Long, OperationCompletionRS> COMPOSE_UPDATE_RESPONSE = it -> {
-		String message = formattedSupplier("TestItem with ID = '{}' successfully updated.", it).get();
-		return new OperationCompletionRS(message);
-	};
-
-	private void checkInitialStatusAttribute(TestItem item, UpdateTestItemRQ request) {
-		Runnable addInitialStatusAttribute = () -> {
-			ItemAttribute initialStatusAttribute = new ItemAttribute(INITIAL_STATUS_ATTRIBUTE_KEY,
-					item.getItemResults().getStatus().getExecutionCounterField(),
-					true
-			);
-			initialStatusAttribute.setTestItem(item);
-			item.getAttributes().add(initialStatusAttribute);
-		};
-
-		Consumer<ItemAttribute> removeManuallyStatusAttributeIfSameAsInitial = statusAttribute -> extractAttributeResource(request.getAttributes(),
-				MANUALLY_CHANGED_STATUS_ATTRIBUTE_KEY
-		).filter(it -> it.getValue()
-				.equalsIgnoreCase(statusAttribute.getValue())).ifPresent(it -> request.getAttributes().remove(it));
-
-		extractAttribute(item.getAttributes(), INITIAL_STATUS_ATTRIBUTE_KEY).ifPresentOrElse(removeManuallyStatusAttributeIfSameAsInitial,
-				addInitialStatusAttribute
-		);
-	}
-
-	@Override
-	public void resetItemsIssue(List<Long> itemIds, Long projectId, ReportPortalUser user) {
-		itemIds.forEach(itemId -> {
-			TestItem item = testItemRepository.findById(itemId).orElseThrow(() -> new ReportPortalException(TEST_ITEM_NOT_FOUND, itemId));
-			TestItemActivityResource before = TO_ACTIVITY_RESOURCE.apply(item, projectId);
-
-			IssueType issueType = issueTypeHandler.defineIssueType(projectId, TestItemIssueGroup.TO_INVESTIGATE.getLocator());
-			IssueEntity issueEntity = new IssueEntityBuilder(issueEntityRepository.findById(itemId)
-					.orElseThrow(() -> new ReportPortalException(ErrorType.ISSUE_TYPE_NOT_FOUND, itemId))).addIssueType(issueType)
-					.addAutoAnalyzedFlag(false)
-					.get();
-			issueEntityRepository.save(issueEntity);
-			item.getItemResults().setIssue(issueEntity);
-
-			TestItemActivityResource after = TO_ACTIVITY_RESOURCE.apply(item, projectId);
-			if (!StringUtils.equalsIgnoreCase(before.getIssueTypeLongName(), after.getIssueTypeLongName())) {
-				ItemIssueTypeDefinedEvent event = new ItemIssueTypeDefinedEvent(before, after, user.getUserId(), user.getUsername());
-				messageBus.publishActivity(event);
-			}
-		});
-	}
-
-	@Override
-	public OperationCompletionRS bulkInfoUpdate(BulkInfoUpdateRQ bulkUpdateRq, ReportPortalUser.ProjectDetails projectDetails) {
-		expect(projectRepository.existsById(projectDetails.getProjectId()), equalTo(TRUE)).verify(PROJECT_NOT_FOUND,
-				projectDetails.getProjectId()
-		);
-
-		List<TestItem> items = testItemRepository.findAllById(bulkUpdateRq.getIds());
-		items.forEach(it -> ItemInfoUtils.updateDescription(bulkUpdateRq.getDescription(), it.getDescription())
-				.ifPresent(it::setDescription));
-
-		bulkUpdateRq.getAttributes().forEach(it -> {
-			switch (it.getAction()) {
-				case DELETE: {
-					items.forEach(item -> {
-						ItemAttribute toDelete = ItemInfoUtils.findAttributeByResource(item.getAttributes(), it.getFrom());
-						item.getAttributes().remove(toDelete);
-					});
-					break;
-				}
-				case UPDATE: {
-					items.forEach(item -> ItemInfoUtils.updateAttribute(item.getAttributes(), it));
-					break;
-				}
-				case CREATE: {
-					items.stream().filter(item -> ItemInfoUtils.containsAttribute(item.getAttributes(), it.getTo())).forEach(item -> {
-						ItemAttribute itemAttribute = ItemAttributeConverter.FROM_RESOURCE.apply(it.getTo());
-						itemAttribute.setTestItem(item);
-						item.getAttributes().add(itemAttribute);
-					});
-					break;
-				}
-			}
-		});
-
-		return new OperationCompletionRS("Attributes successfully updated");
-	}
-
-	/**
-	 * Validates test item access ability.
-	 *
-	 * @param projectDetails Project
-	 * @param user           User
-	 * @param testItem       Test Item
-	 */
-	private void validate(ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user, TestItem testItem) {
-		Launch launch = testItemService.getEffectiveLaunch(testItem);
-		if (user.getUserRole() != UserRole.ADMINISTRATOR) {
-			expect(launch.getProjectId(), equalTo(projectDetails.getProjectId())).verify(ACCESS_DENIED,
-					"Launch is not under the specified project."
-			);
-			if (projectDetails.getProjectRole().lowerThan(ProjectRole.PROJECT_MANAGER)) {
-				expect(user.getUserId(), Predicate.isEqual(launch.getUserId())).verify(ACCESS_DENIED, "You are not a launch owner.");
-			}
-		}
-	}
-
-	/**
-	 * Complex of domain verification for test item. Verifies that test item
-	 * domain object could be processed correctly.
-	 *
-	 * @param id - test item id
-	 * @throws BusinessRuleViolationException when business rule violation
-	 */
-	private void verifyTestItem(TestItem item, Long id) throws BusinessRuleViolationException {
-		expect(item.getItemResults(),
-				notNull(),
-				formattedSupplier("Test item results were not found for test item with id = '{}", item.getItemId())
-		).verify();
-
-		expect(item.getItemResults().getStatus(),
-				not(status -> Stream.of(StatusEnum.values()).filter(StatusEnum::isPositive).anyMatch(s -> s == status)),
-				formattedSupplier("Issue status update cannot be applied on {} test items, cause it is not allowed.",
-						item.getItemResults().getStatus()
-				)
-		).verify();
-
-		expect(item.isHasChildren(),
-				equalTo(FALSE),
-				formattedSupplier("It is not allowed to update issue type for items with descendants. Test item '{}' has descendants.", id)
-		).verify();
-
-		expect(item.getItemResults().getIssue(),
-				notNull(),
-				formattedSupplier("Cannot update issue type for test item '{}', cause there is no info about actual issue type value.", id)
-		).verify();
-
-		expect(item.getItemResults().getIssue().getIssueType(),
-				notNull(),
-				formattedSupplier("Cannot update issue type for test item {}, cause it's actual issue type value is not provided.", id)
-		).verify();
-	}
+  private static final Function<Long, OperationCompletionRS> COMPOSE_UPDATE_RESPONSE = it -> {
+    String message = formattedSupplier("TestItem with ID = '{}' successfully updated.", it).get();
+    return new OperationCompletionRS(message);
+  };
+
+  private void checkInitialStatusAttribute(TestItem item, UpdateTestItemRQ request) {
+    Runnable addInitialStatusAttribute = () -> {
+      ItemAttribute initialStatusAttribute = new ItemAttribute(INITIAL_STATUS_ATTRIBUTE_KEY,
+          item.getItemResults().getStatus().getExecutionCounterField(), true
+      );
+      initialStatusAttribute.setTestItem(item);
+      item.getAttributes().add(initialStatusAttribute);
+    };
+
+    Consumer<ItemAttribute> removeManuallyStatusAttributeIfSameAsInitial =
+        statusAttribute -> extractAttributeResource(request.getAttributes(),
+            MANUALLY_CHANGED_STATUS_ATTRIBUTE_KEY
+        ).filter(it -> it.getValue().equalsIgnoreCase(statusAttribute.getValue()))
+            .ifPresent(it -> request.getAttributes().remove(it));
+
+    extractAttribute(item.getAttributes(), INITIAL_STATUS_ATTRIBUTE_KEY).ifPresentOrElse(
+        removeManuallyStatusAttributeIfSameAsInitial, addInitialStatusAttribute);
+  }
+
+  @Override
+  public void resetItemsIssue(List<Long> itemIds, Long projectId, ReportPortalUser user) {
+    itemIds.forEach(itemId -> {
+      TestItem item = testItemRepository.findById(itemId)
+          .orElseThrow(() -> new ReportPortalException(TEST_ITEM_NOT_FOUND, itemId));
+      TestItemActivityResource before = TO_ACTIVITY_RESOURCE.apply(item, projectId);
+
+      IssueType issueType = issueTypeHandler.defineIssueType(projectId,
+          TestItemIssueGroup.TO_INVESTIGATE.getLocator()
+      );
+      IssueEntity issueEntity = new IssueEntityBuilder(issueEntityRepository.findById(itemId)
+          .orElseThrow(() -> new ReportPortalException(ErrorType.ISSUE_TYPE_NOT_FOUND,
+              itemId
+          ))).addIssueType(issueType).addAutoAnalyzedFlag(false).get();
+      issueEntityRepository.save(issueEntity);
+      item.getItemResults().setIssue(issueEntity);
+
+      TestItemActivityResource after = TO_ACTIVITY_RESOURCE.apply(item, projectId);
+      if (!StringUtils.equalsIgnoreCase(
+          before.getIssueTypeLongName(), after.getIssueTypeLongName())) {
+        ItemIssueTypeDefinedEvent event =
+            new ItemIssueTypeDefinedEvent(before, after, user.getUserId(), user.getUsername());
+        messageBus.publishActivity(event);
+      }
+    });
+  }
+
+  @Override
+  public OperationCompletionRS bulkInfoUpdate(BulkInfoUpdateRQ bulkUpdateRq,
+      ReportPortalUser.ProjectDetails projectDetails) {
+    expect(projectRepository.existsById(projectDetails.getProjectId()), equalTo(TRUE)).verify(
+        PROJECT_NOT_FOUND, projectDetails.getProjectId());
+
+    List<TestItem> items = testItemRepository.findAllById(bulkUpdateRq.getIds());
+    items.forEach(
+        it -> ItemInfoUtils.updateDescription(bulkUpdateRq.getDescription(), it.getDescription())
+            .ifPresent(it::setDescription));
+
+    bulkUpdateRq.getAttributes().forEach(it -> {
+      switch (it.getAction()) {
+        case DELETE: {
+          items.forEach(item -> {
+            ItemAttribute toDelete =
+                ItemInfoUtils.findAttributeByResource(item.getAttributes(), it.getFrom());
+            item.getAttributes().remove(toDelete);
+          });
+          break;
+        }
+        case UPDATE: {
+          items.forEach(item -> ItemInfoUtils.updateAttribute(item.getAttributes(), it));
+          break;
+        }
+        case CREATE: {
+          items.stream()
+              .filter(item -> ItemInfoUtils.containsAttribute(item.getAttributes(), it.getTo()))
+              .forEach(item -> {
+                ItemAttribute itemAttribute =
+                    ItemAttributeConverter.FROM_RESOURCE.apply(it.getTo());
+                itemAttribute.setTestItem(item);
+                item.getAttributes().add(itemAttribute);
+              });
+          break;
+        }
+      }
+    });
+
+    return new OperationCompletionRS("Attributes successfully updated");
+  }
+
+  /**
+   * Validates test item access ability.
+   *
+   * @param projectDetails Project
+   * @param user           User
+   * @param testItem       Test Item
+   */
+  private void validate(ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user,
+      TestItem testItem) {
+    Launch launch = testItemService.getEffectiveLaunch(testItem);
+    if (user.getUserRole() != UserRole.ADMINISTRATOR) {
+      expect(launch.getProjectId(), equalTo(projectDetails.getProjectId())).verify(ACCESS_DENIED,
+          "Launch is not under the specified project."
+      );
+      if (projectDetails.getProjectRole().lowerThan(ProjectRole.PROJECT_MANAGER)) {
+        expect(user.getUserId(), Predicate.isEqual(launch.getUserId())).verify(
+            ACCESS_DENIED, "You are not a launch owner.");
+      }
+    }
+  }
+
+  /**
+   * Complex of domain verification for test item. Verifies that test item
+   * domain object could be processed correctly.
+   *
+   * @param id - test item id
+   * @throws BusinessRuleViolationException when business rule violation
+   */
+  private void verifyTestItem(TestItem item, Long id) throws BusinessRuleViolationException {
+    expect(item.getItemResults(), notNull(),
+        formattedSupplier("Test item results were not found for test item with id = '{}",
+            item.getItemId()
+        )
+    ).verify();
+
+    expect(item.getItemResults().getStatus(),
+        not(status -> Stream.of(StatusEnum.values()).filter(StatusEnum::isPositive)
+            .anyMatch(s -> s == status)), formattedSupplier(
+            "Issue status update cannot be applied on {} test items, cause it is not allowed.",
+            item.getItemResults().getStatus()
+        )
+    ).verify();
+
+    expect(item.isHasChildren(), equalTo(FALSE), formattedSupplier(
+        "It is not allowed to update issue type for items with descendants. Test item '{}' has descendants.",
+        id
+    )).verify();
+
+    expect(item.getItemResults().getIssue(), notNull(), formattedSupplier(
+        "Cannot update issue type for test item '{}', cause there is no info about actual issue type value.",
+        id
+    )).verify();
+
+    expect(item.getItemResults().getIssue().getIssueType(), notNull(), formattedSupplier(
+        "Cannot update issue type for test item {}, cause it's actual issue type value is not provided.",
+        id
+    )).verify();
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/filter/updater/FilterUpdater.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/filter/updater/FilterUpdater.java
index 231694b8b7..468259be4b 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/filter/updater/FilterUpdater.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/filter/updater/FilterUpdater.java
@@ -23,5 +23,5 @@
  */
 public interface FilterUpdater {
 
-	void update(Queryable filter);
+  void update(Queryable filter);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/filter/updater/IssueTypeConditionReplacer.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/filter/updater/IssueTypeConditionReplacer.java
index 69b7b97809..91db1dde4d 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/filter/updater/IssueTypeConditionReplacer.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/filter/updater/IssueTypeConditionReplacer.java
@@ -16,20 +16,19 @@
 
 package com.epam.ta.reportportal.core.item.impl.filter.updater;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_ISSUE_TYPE;
+import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_ISSUE_TYPE_ID;
+
 import com.epam.ta.reportportal.commons.querygen.Condition;
 import com.epam.ta.reportportal.commons.querygen.ConvertibleCondition;
 import com.epam.ta.reportportal.commons.querygen.FilterCondition;
 import com.epam.ta.reportportal.commons.querygen.Queryable;
 import com.epam.ta.reportportal.dao.IssueTypeRepository;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
 import java.util.List;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
-
-import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_ISSUE_TYPE;
-import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_ISSUE_TYPE_ID;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -37,32 +36,35 @@
 @Service
 public class IssueTypeConditionReplacer implements FilterUpdater {
 
-	private final IssueTypeRepository issueTypeRepository;
+  private final IssueTypeRepository issueTypeRepository;
 
-	@Autowired
-	public IssueTypeConditionReplacer(IssueTypeRepository issueTypeRepository) {
-		this.issueTypeRepository = issueTypeRepository;
-	}
+  @Autowired
+  public IssueTypeConditionReplacer(IssueTypeRepository issueTypeRepository) {
+    this.issueTypeRepository = issueTypeRepository;
+  }
 
-	@Override
-	public void update(Queryable filter) {
-		// Added to fix performance issue.
-		List<String> issueTypeLocators = filter.getFilterConditions()
-				.stream()
-				.map(ConvertibleCondition::getAllConditions)
-				.flatMap(List::stream)
-				.filter(c -> CRITERIA_ISSUE_TYPE.equals(c.getSearchCriteria()) && !c.isNegative() && Condition.IN.equals(c.getCondition()))
-				.map(FilterCondition::getValue)
-				.flatMap(c -> Stream.of(c.split(",")))
-				.collect(Collectors.toList());
+  @Override
+  public void update(Queryable filter) {
+    // Added to fix performance issue.
+    List<String> issueTypeLocators = filter.getFilterConditions()
+        .stream()
+        .map(ConvertibleCondition::getAllConditions)
+        .flatMap(List::stream)
+        .filter(c -> CRITERIA_ISSUE_TYPE.equals(c.getSearchCriteria()) && !c.isNegative()
+            && Condition.IN.equals(c.getCondition()))
+        .map(FilterCondition::getValue)
+        .flatMap(c -> Stream.of(c.split(",")))
+        .collect(Collectors.toList());
 
-		String issueTypeIdsString = issueTypeRepository.getIssueTypeIdsByLocators(issueTypeLocators)
-				.stream()
-				.map(String::valueOf)
-				.collect(Collectors.joining(","));
+    String issueTypeIdsString = issueTypeRepository.getIssueTypeIdsByLocators(issueTypeLocators)
+        .stream()
+        .map(String::valueOf)
+        .collect(Collectors.joining(","));
 
-		FilterCondition oldIssueTypeCondition = new FilterCondition(Condition.IN, false, null, CRITERIA_ISSUE_TYPE);
-		FilterCondition issueTypeIdCondition = new FilterCondition(Condition.IN, false, issueTypeIdsString, CRITERIA_ISSUE_TYPE_ID);
-		filter.replaceSearchCriteria(oldIssueTypeCondition, issueTypeIdCondition);
-	}
+    FilterCondition oldIssueTypeCondition = new FilterCondition(Condition.IN, false, null,
+        CRITERIA_ISSUE_TYPE);
+    FilterCondition issueTypeIdCondition = new FilterCondition(Condition.IN, false,
+        issueTypeIdsString, CRITERIA_ISSUE_TYPE_ID);
+    filter.replaceSearchCriteria(oldIssueTypeCondition, issueTypeIdCondition);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/history/ItemHistoryBaselineEnum.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/history/ItemHistoryBaselineEnum.java
index dc95c21ab9..2d15572b67 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/history/ItemHistoryBaselineEnum.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/history/ItemHistoryBaselineEnum.java
@@ -17,55 +17,57 @@
 package com.epam.ta.reportportal.core.item.impl.history;
 
 import com.epam.ta.reportportal.core.item.impl.history.param.HistoryRequestParams;
-
 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.Optional;
 import java.util.function.Predicate;
 
 /**
- * Enum for {@link com.epam.ta.reportportal.entity.item.history.TestItemHistory} retrieving type resolving.
+ * Enum for {@link com.epam.ta.reportportal.entity.item.history.TestItemHistory} retrieving type
+ * resolving.
  *
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public enum ItemHistoryBaselineEnum {
 
-	COMPARING(1,
-			historyRequestParams -> historyRequestParams.getHistoryType()
-					.map(HistoryRequestParams.HistoryTypeEnum.COMPARING::equals)
-					.orElse(Boolean.FALSE)
-	),
-	FILTER(2, historyRequestParams -> historyRequestParams.getFilterParams().isPresent()),
-	ITEM(3, historyRequestParams -> historyRequestParams.getParentId().isPresent() || historyRequestParams.getItemId().isPresent()),
-	LAUNCH(4, historyRequestParams -> historyRequestParams.getLaunchId().isPresent());
+  COMPARING(1,
+      historyRequestParams -> historyRequestParams.getHistoryType()
+          .map(HistoryRequestParams.HistoryTypeEnum.COMPARING::equals)
+          .orElse(Boolean.FALSE)
+  ),
+  FILTER(2, historyRequestParams -> historyRequestParams.getFilterParams().isPresent()),
+  ITEM(3, historyRequestParams -> historyRequestParams.getParentId().isPresent()
+      || historyRequestParams.getItemId().isPresent()),
+  LAUNCH(4, historyRequestParams -> historyRequestParams.getLaunchId().isPresent());
 
-	private final int priority;
-	private final Predicate<HistoryRequestParams> baseLinePredicate;
+  private final int priority;
+  private final Predicate<HistoryRequestParams> baseLinePredicate;
 
-	/**
-	 * {@link ItemHistoryBaselineEnum} is resolved using {@link Predicate},
-	 * types ordered by `priority` field in ascending order, first matched type is returned.
-	 *
-	 * @param historyRequestParams {@link HistoryRequestParams}
-	 * @return {@link Optional} with {@link ItemHistoryBaselineEnum}
-	 */
-	public static Optional<ItemHistoryBaselineEnum> resolveType(HistoryRequestParams historyRequestParams) {
-		return Arrays.stream(ItemHistoryBaselineEnum.values())
-				.sorted(Comparator.comparingInt(ItemHistoryBaselineEnum::getPriority))
-				.filter(v -> v.getBaseLinePredicate().test(historyRequestParams))
-				.findFirst();
-	}
+  /**
+   * {@link ItemHistoryBaselineEnum} is resolved using {@link Predicate}, types ordered by
+   * `priority` field in ascending order, first matched type is returned.
+   *
+   * @param historyRequestParams {@link HistoryRequestParams}
+   * @return {@link Optional} with {@link ItemHistoryBaselineEnum}
+   */
+  public static Optional<ItemHistoryBaselineEnum> resolveType(
+      HistoryRequestParams historyRequestParams) {
+    return Arrays.stream(ItemHistoryBaselineEnum.values())
+        .sorted(Comparator.comparingInt(ItemHistoryBaselineEnum::getPriority))
+        .filter(v -> v.getBaseLinePredicate().test(historyRequestParams))
+        .findFirst();
+  }
 
-	ItemHistoryBaselineEnum(int priority, Predicate<HistoryRequestParams> baseLinePredicate) {
-		this.priority = priority;
-		this.baseLinePredicate = baseLinePredicate;
-	}
+  ItemHistoryBaselineEnum(int priority, Predicate<HistoryRequestParams> baseLinePredicate) {
+    this.priority = priority;
+    this.baseLinePredicate = baseLinePredicate;
+  }
 
-	public int getPriority() {
-		return priority;
-	}
+  public int getPriority() {
+    return priority;
+  }
 
-	public Predicate<HistoryRequestParams> getBaseLinePredicate() {
-		return baseLinePredicate;
-	}
+  public Predicate<HistoryRequestParams> getBaseLinePredicate() {
+    return baseLinePredicate;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/history/TestItemsHistoryHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/history/TestItemsHistoryHandlerImpl.java
index 02ce4b8c28..2540a28565 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/history/TestItemsHistoryHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/history/TestItemsHistoryHandlerImpl.java
@@ -16,6 +16,17 @@
 
 package com.epam.ta.reportportal.core.item.impl.history;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_PROJECT_ID;
+import static com.epam.ta.reportportal.commons.querygen.constant.LaunchCriteriaConstant.CRITERIA_LAUNCH_MODE;
+import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_HAS_STATS;
+import static com.epam.ta.reportportal.ws.model.ErrorType.UNABLE_LOAD_TEST_ITEM_HISTORY;
+import static com.epam.ta.reportportal.ws.model.ValidationConstraints.MAX_HISTORY_DEPTH_BOUND;
+import static com.epam.ta.reportportal.ws.model.ValidationConstraints.MIN_HISTORY_DEPTH_BOUND;
+import static java.util.Optional.ofNullable;
+import static java.util.stream.Collectors.groupingBy;
+import static java.util.stream.Collectors.toList;
+import static java.util.stream.Collectors.toMap;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.querygen.CompositeFilter;
 import com.epam.ta.reportportal.commons.querygen.Filter;
@@ -39,6 +50,11 @@
 import com.epam.ta.reportportal.ws.model.TestItemHistoryElement;
 import com.epam.ta.reportportal.ws.model.TestItemResource;
 import com.google.common.collect.Lists;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.Predicate;
 import org.jooq.Operator;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
@@ -47,21 +63,6 @@
 import org.springframework.data.repository.support.PageableExecutionUtils;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.function.Function;
-import java.util.function.Predicate;
-
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_PROJECT_ID;
-import static com.epam.ta.reportportal.commons.querygen.constant.LaunchCriteriaConstant.CRITERIA_LAUNCH_MODE;
-import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_HAS_STATS;
-import static com.epam.ta.reportportal.ws.model.ErrorType.UNABLE_LOAD_TEST_ITEM_HISTORY;
-import static com.epam.ta.reportportal.ws.model.ValidationConstraints.MAX_HISTORY_DEPTH_BOUND;
-import static com.epam.ta.reportportal.ws.model.ValidationConstraints.MIN_HISTORY_DEPTH_BOUND;
-import static java.util.Optional.ofNullable;
-import static java.util.stream.Collectors.*;
-
 /**
  * Creating items history based on {@link TestItem#getTestCaseId()} field
  *
@@ -70,107 +71,123 @@
 @Service
 public class TestItemsHistoryHandlerImpl implements TestItemsHistoryHandler {
 
-	@Value("${rp.environment.variable.history.old}")
-	private boolean oldHistory;
-
-	private final TestItemRepository testItemRepository;
-	private final HistoryProviderFactory historyProviderFactory;
-	private final List<ResourceUpdaterProvider<TestItemUpdaterContent, TestItemResource>> resourceUpdaterProviders;
-
-	@Autowired
-	public TestItemsHistoryHandlerImpl(TestItemRepository testItemRepository, HistoryProviderFactory historyProviderFactory,
-			List<ResourceUpdaterProvider<TestItemUpdaterContent, TestItemResource>> resourceUpdaterProviders) {
-		this.testItemRepository = testItemRepository;
-		this.historyProviderFactory = historyProviderFactory;
-		this.resourceUpdaterProviders = resourceUpdaterProviders;
-	}
-
-	@Override
-	public Iterable<TestItemHistoryElement> getItemsHistory(ReportPortalUser.ProjectDetails projectDetails, Queryable filter,
-			Pageable pageable, HistoryRequestParams historyRequestParams, ReportPortalUser user) {
-
-		validateHistoryDepth(historyRequestParams.getHistoryDepth());
-
-		CompositeFilter itemHistoryFilter = new CompositeFilter(Operator.AND,
-				filter,
-				Filter.builder()
-						.withTarget(filter.getTarget().getClazz())
-						.withCondition(FilterCondition.builder()
-								.eq(CRITERIA_PROJECT_ID, String.valueOf(projectDetails.getProjectId()))
-								.build())
-						.withCondition(FilterCondition.builder().eq(CRITERIA_LAUNCH_MODE, LaunchModeEnum.DEFAULT.name()).build())
-						.withCondition(FilterCondition.builder().eq(CRITERIA_HAS_STATS, String.valueOf(Boolean.TRUE)).build())
-						.build()
-		);
-
-		Page<TestItemHistory> testItemHistoryPage = historyProviderFactory.getProvider(historyRequestParams)
-				.orElseThrow(() -> new ReportPortalException(UNABLE_LOAD_TEST_ITEM_HISTORY,
-						"Unable to find suitable history baseline provider"
-				))
-				.provide(itemHistoryFilter, pageable, historyRequestParams, projectDetails, user, !oldHistory);
-
-		return buildHistoryElements(
-				oldHistory ? TestItemResource::getUniqueId : testItemResource -> String.valueOf(testItemResource.getTestCaseHash()),
-				testItemHistoryPage,
-				projectDetails.getProjectId(),
-				pageable
-		);
-
-	}
-
-	private void validateHistoryDepth(int historyDepth) {
-		Predicate<Integer> greaterThan = t -> t > MIN_HISTORY_DEPTH_BOUND;
-		Predicate<Integer> lessThan = t -> t < MAX_HISTORY_DEPTH_BOUND;
-		String historyDepthMessage = Suppliers.formattedSupplier("Items history depth should be greater than '{}' and lower than '{}'",
-				MIN_HISTORY_DEPTH_BOUND,
-				MAX_HISTORY_DEPTH_BOUND
-		)
-				.get();
-		BusinessRule.expect(historyDepth, greaterThan.and(lessThan)).verify(UNABLE_LOAD_TEST_ITEM_HISTORY, historyDepthMessage);
-	}
-
-	private Iterable<TestItemHistoryElement> buildHistoryElements(Function<TestItemResource, String> groupingFunction,
-			Page<TestItemHistory> testItemHistoryPage, Long projectId, Pageable pageable) {
-
-		List<TestItem> testItems = testItemRepository.findAllById(testItemHistoryPage.getContent()
-				.stream()
-				.flatMap(history -> history.getItemIds().stream())
-				.collect(toList()));
-
-		List<ResourceUpdater<TestItemResource>> resourceUpdaters = getResourceUpdaters(projectId, testItems);
-
-		Map<String, Map<Long, TestItemResource>> itemsMapping = testItems.stream().map(item -> {
-			TestItemResource testItemResource = TestItemConverter.TO_RESOURCE.apply(item);
-			resourceUpdaters.forEach(updater -> updater.updateResource(testItemResource));
-			return testItemResource;
-		}).collect(groupingBy(groupingFunction, toMap(TestItemResource::getItemId, res -> res)));
-
-		List<TestItemHistoryElement> testItemHistoryElements = testItemHistoryPage.getContent()
-				.stream()
-				.map(history -> ofNullable(itemsMapping.get(history.getGroupingField())).map(mapping -> {
-					TestItemHistoryElement historyResource = new TestItemHistoryElement();
-					historyResource.setGroupingField(history.getGroupingField());
-					List<TestItemResource> resources = Lists.newArrayList();
-					ofNullable(history.getItemIds()).ifPresent(itemIds -> itemIds.forEach(itemId -> ofNullable(mapping.get(itemId)).ifPresent(
-							resources::add)));
-					historyResource.setResources(resources);
-					return historyResource;
-				}))
-				.filter(Optional::isPresent)
-				.map(Optional::get)
-				.collect(toList());
-
-		return PagedResourcesAssembler.<TestItemHistoryElement>pageConverter().apply(PageableExecutionUtils.getPage(testItemHistoryElements,
-				pageable,
-				testItemHistoryPage::getTotalElements
-		));
-
-	}
-
-	private List<ResourceUpdater<TestItemResource>> getResourceUpdaters(Long projectId, List<TestItem> testItems) {
-		return resourceUpdaterProviders.stream()
-				.map(retriever -> retriever.retrieve(TestItemUpdaterContent.of(projectId, testItems)))
-				.collect(toList());
-
-	}
+  @Value("${rp.environment.variable.history.old}")
+  private boolean oldHistory;
+
+  private final TestItemRepository testItemRepository;
+  private final HistoryProviderFactory historyProviderFactory;
+  private final List<ResourceUpdaterProvider<TestItemUpdaterContent, TestItemResource>> resourceUpdaterProviders;
+
+  @Autowired
+  public TestItemsHistoryHandlerImpl(TestItemRepository testItemRepository,
+      HistoryProviderFactory historyProviderFactory,
+      List<ResourceUpdaterProvider<TestItemUpdaterContent, TestItemResource>> resourceUpdaterProviders) {
+    this.testItemRepository = testItemRepository;
+    this.historyProviderFactory = historyProviderFactory;
+    this.resourceUpdaterProviders = resourceUpdaterProviders;
+  }
+
+  @Override
+  public Iterable<TestItemHistoryElement> getItemsHistory(
+      ReportPortalUser.ProjectDetails projectDetails, Queryable filter,
+      Pageable pageable, HistoryRequestParams historyRequestParams, ReportPortalUser user) {
+
+    validateHistoryDepth(historyRequestParams.getHistoryDepth());
+
+    CompositeFilter itemHistoryFilter = new CompositeFilter(Operator.AND,
+        filter,
+        Filter.builder()
+            .withTarget(filter.getTarget().getClazz())
+            .withCondition(FilterCondition.builder()
+                .eq(CRITERIA_PROJECT_ID, String.valueOf(projectDetails.getProjectId()))
+                .build())
+            .withCondition(
+                FilterCondition.builder().eq(CRITERIA_LAUNCH_MODE, LaunchModeEnum.DEFAULT.name())
+                    .build())
+            .withCondition(
+                FilterCondition.builder().eq(CRITERIA_HAS_STATS, String.valueOf(Boolean.TRUE))
+                    .build())
+            .build()
+    );
+
+    Page<TestItemHistory> testItemHistoryPage = historyProviderFactory.getProvider(
+            historyRequestParams)
+        .orElseThrow(() -> new ReportPortalException(UNABLE_LOAD_TEST_ITEM_HISTORY,
+            "Unable to find suitable history baseline provider"
+        ))
+        .provide(itemHistoryFilter, pageable, historyRequestParams, projectDetails, user,
+            !oldHistory);
+
+    return buildHistoryElements(
+        oldHistory ? TestItemResource::getUniqueId
+            : testItemResource -> String.valueOf(testItemResource.getTestCaseHash()),
+        testItemHistoryPage,
+        projectDetails.getProjectId(),
+        pageable
+    );
+
+  }
+
+  private void validateHistoryDepth(int historyDepth) {
+    Predicate<Integer> greaterThan = t -> t > MIN_HISTORY_DEPTH_BOUND;
+    Predicate<Integer> lessThan = t -> t < MAX_HISTORY_DEPTH_BOUND;
+    String historyDepthMessage = Suppliers.formattedSupplier(
+            "Items history depth should be greater than '{}' and lower than '{}'",
+            MIN_HISTORY_DEPTH_BOUND,
+            MAX_HISTORY_DEPTH_BOUND
+        )
+        .get();
+    BusinessRule.expect(historyDepth, greaterThan.and(lessThan))
+        .verify(UNABLE_LOAD_TEST_ITEM_HISTORY, historyDepthMessage);
+  }
+
+  private Iterable<TestItemHistoryElement> buildHistoryElements(
+      Function<TestItemResource, String> groupingFunction,
+      Page<TestItemHistory> testItemHistoryPage, Long projectId, Pageable pageable) {
+
+    List<TestItem> testItems = testItemRepository.findAllById(testItemHistoryPage.getContent()
+        .stream()
+        .flatMap(history -> history.getItemIds().stream())
+        .collect(toList()));
+
+    List<ResourceUpdater<TestItemResource>> resourceUpdaters = getResourceUpdaters(projectId,
+        testItems);
+
+    Map<String, Map<Long, TestItemResource>> itemsMapping = testItems.stream().map(item -> {
+      TestItemResource testItemResource = TestItemConverter.TO_RESOURCE.apply(item);
+      resourceUpdaters.forEach(updater -> updater.updateResource(testItemResource));
+      return testItemResource;
+    }).collect(groupingBy(groupingFunction, toMap(TestItemResource::getItemId, res -> res)));
+
+    List<TestItemHistoryElement> testItemHistoryElements = testItemHistoryPage.getContent()
+        .stream()
+        .map(history -> ofNullable(itemsMapping.get(history.getGroupingField())).map(mapping -> {
+          TestItemHistoryElement historyResource = new TestItemHistoryElement();
+          historyResource.setGroupingField(history.getGroupingField());
+          List<TestItemResource> resources = Lists.newArrayList();
+          ofNullable(history.getItemIds()).ifPresent(
+              itemIds -> itemIds.forEach(itemId -> ofNullable(mapping.get(itemId)).ifPresent(
+                  resources::add)));
+          historyResource.setResources(resources);
+          return historyResource;
+        }))
+        .filter(Optional::isPresent)
+        .map(Optional::get)
+        .collect(toList());
+
+    return PagedResourcesAssembler.<TestItemHistoryElement>pageConverter()
+        .apply(PageableExecutionUtils.getPage(testItemHistoryElements,
+            pageable,
+            testItemHistoryPage::getTotalElements
+        ));
+
+  }
+
+  private List<ResourceUpdater<TestItemResource>> getResourceUpdaters(Long projectId,
+      List<TestItem> testItems) {
+    return resourceUpdaterProviders.stream()
+        .map(retriever -> retriever.retrieve(TestItemUpdaterContent.of(projectId, testItems)))
+        .collect(toList());
+
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/history/param/HistoryRequestParams.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/history/param/HistoryRequestParams.java
index cbff81424a..368db777c4 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/history/param/HistoryRequestParams.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/history/param/HistoryRequestParams.java
@@ -16,110 +16,118 @@
 
 package com.epam.ta.reportportal.core.item.impl.history.param;
 
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.validation.Suppliers;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
-
 import java.util.Arrays;
 import java.util.Optional;
 
-import static java.util.Optional.ofNullable;
-
 /**
- * NULL-safe container for {@link com.epam.ta.reportportal.ws.controller.TestItemController#getItemsHistory} request params
+ * NULL-safe container for
+ * {@link com.epam.ta.reportportal.ws.controller.TestItemController#getItemsHistory} request params
  *
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public class HistoryRequestParams {
 
-	private int historyDepth;
-	private Long parentId;
-	private Long itemId;
-	private Long launchId;
-	private HistoryTypeEnum historyType;
-	private FilterParams filterParams;
-
-	private HistoryRequestParams(int historyDepth, Long parentId, Long itemId, Long launchId, String historyType, Long filterId,
-			int launchesLimit, boolean isLatest) {
-		this.historyDepth = historyDepth;
-		this.parentId = parentId;
-		this.itemId = itemId;
-		this.launchId = launchId;
-		ofNullable(historyType).ifPresent(type -> this.historyType = HistoryTypeEnum.fromValue(historyType)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR,
-						Suppliers.formattedSupplier("Wrong history type - '{}'", historyType).get()
-				)));
-		ofNullable(filterId).ifPresent(id -> this.filterParams = FilterParams.of(filterId, launchesLimit, isLatest));
-	}
-
-	public enum HistoryTypeEnum {
-		TABLE,
-		LINE,
-		COMPARING;
-
-		public static Optional<HistoryTypeEnum> fromValue(String type) {
-			return Arrays.stream(HistoryTypeEnum.values()).filter(v -> v.name().equalsIgnoreCase(type)).findFirst();
-		}
-	}
-
-	/**
-	 * Container for {@link com.epam.ta.reportportal.ws.controller.TestItemController#getItemsHistory} launch's filter-related request params
-	 */
-	public static final class FilterParams {
-		private Long filterId;
-		private int launchesLimit;
-		private boolean isLatest;
-
-		private FilterParams(Long filterId, int launchesLimit, boolean isLatest) {
-			this.filterId = filterId;
-			this.launchesLimit = launchesLimit;
-			this.isLatest = isLatest;
-		}
-
-		public Long getFilterId() {
-			return filterId;
-		}
-
-		public int getLaunchesLimit() {
-			return launchesLimit;
-		}
-
-		public boolean isLatest() {
-			return isLatest;
-		}
-
-		public static FilterParams of(Long filterId, int launchesLimit, boolean isLatest) {
-			return new FilterParams(filterId, launchesLimit, isLatest);
-		}
-
-	}
-
-	public int getHistoryDepth() {
-		return historyDepth;
-	}
-
-	public Optional<FilterParams> getFilterParams() {
-		return ofNullable(filterParams);
-	}
-
-	public Optional<Long> getParentId() {
-		return ofNullable(parentId);
-	}
-
-	public Optional<Long> getItemId() {
-		return ofNullable(itemId);
-	}
-
-	public Optional<Long> getLaunchId() {
-		return ofNullable(launchId);
-	}
-
-	public Optional<HistoryTypeEnum> getHistoryType() {
-		return ofNullable(historyType);
-	}
-
-	public static HistoryRequestParams of(int historyDepth, Long parentId, Long itemId, Long launchId, String historyType, Long filterId,
-			int launchesLimit, boolean isLatest) {
-		return new HistoryRequestParams(historyDepth, parentId, itemId, launchId, historyType, filterId, launchesLimit, isLatest);
-	}
+  private int historyDepth;
+  private Long parentId;
+  private Long itemId;
+  private Long launchId;
+  private HistoryTypeEnum historyType;
+  private FilterParams filterParams;
+
+  private HistoryRequestParams(int historyDepth, Long parentId, Long itemId, Long launchId,
+      String historyType, Long filterId,
+      int launchesLimit, boolean isLatest) {
+    this.historyDepth = historyDepth;
+    this.parentId = parentId;
+    this.itemId = itemId;
+    this.launchId = launchId;
+    ofNullable(historyType).ifPresent(
+        type -> this.historyType = HistoryTypeEnum.fromValue(historyType)
+            .orElseThrow(() -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR,
+                Suppliers.formattedSupplier("Wrong history type - '{}'", historyType).get()
+            )));
+    ofNullable(filterId).ifPresent(
+        id -> this.filterParams = FilterParams.of(filterId, launchesLimit, isLatest));
+  }
+
+  public enum HistoryTypeEnum {
+    TABLE,
+    LINE,
+    COMPARING;
+
+    public static Optional<HistoryTypeEnum> fromValue(String type) {
+      return Arrays.stream(HistoryTypeEnum.values()).filter(v -> v.name().equalsIgnoreCase(type))
+          .findFirst();
+    }
+  }
+
+  /**
+   * Container for {@link com.epam.ta.reportportal.ws.controller.TestItemController#getItemsHistory}
+   * launch's filter-related request params
+   */
+  public static final class FilterParams {
+
+    private Long filterId;
+    private int launchesLimit;
+    private boolean isLatest;
+
+    private FilterParams(Long filterId, int launchesLimit, boolean isLatest) {
+      this.filterId = filterId;
+      this.launchesLimit = launchesLimit;
+      this.isLatest = isLatest;
+    }
+
+    public Long getFilterId() {
+      return filterId;
+    }
+
+    public int getLaunchesLimit() {
+      return launchesLimit;
+    }
+
+    public boolean isLatest() {
+      return isLatest;
+    }
+
+    public static FilterParams of(Long filterId, int launchesLimit, boolean isLatest) {
+      return new FilterParams(filterId, launchesLimit, isLatest);
+    }
+
+  }
+
+  public int getHistoryDepth() {
+    return historyDepth;
+  }
+
+  public Optional<FilterParams> getFilterParams() {
+    return ofNullable(filterParams);
+  }
+
+  public Optional<Long> getParentId() {
+    return ofNullable(parentId);
+  }
+
+  public Optional<Long> getItemId() {
+    return ofNullable(itemId);
+  }
+
+  public Optional<Long> getLaunchId() {
+    return ofNullable(launchId);
+  }
+
+  public Optional<HistoryTypeEnum> getHistoryType() {
+    return ofNullable(historyType);
+  }
+
+  public static HistoryRequestParams of(int historyDepth, Long parentId, Long itemId, Long launchId,
+      String historyType, Long filterId,
+      int launchesLimit, boolean isLatest) {
+    return new HistoryRequestParams(historyDepth, parentId, itemId, launchId, historyType, filterId,
+        launchesLimit, isLatest);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/history/provider/HistoryProvider.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/history/provider/HistoryProvider.java
index 063e58086f..9218c40f36 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/history/provider/HistoryProvider.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/history/provider/HistoryProvider.java
@@ -18,8 +18,8 @@
 
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.querygen.Queryable;
-import com.epam.ta.reportportal.entity.item.history.TestItemHistory;
 import com.epam.ta.reportportal.core.item.impl.history.param.HistoryRequestParams;
+import com.epam.ta.reportportal.entity.item.history.TestItemHistory;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 
@@ -30,14 +30,18 @@
  */
 public interface HistoryProvider {
 
-	/**
-	 * @param filter               - {@link Queryable}
-	 * @param pageable             - {@link Pageable}
-	 * @param historyRequestParams - {@link HistoryRequestParams}
-	 * @param projectDetails       - {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
-	 * @param user                 - {@link ReportPortalUser}
-	 * @return {@link Page} with {@link TestItemHistory} content
-	 */
-	Page<TestItemHistory> provide(Queryable filter, Pageable pageable, HistoryRequestParams historyRequestParams,
-			ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user, boolean usingHash);
+  /**
+   * @param filter               - {@link Queryable}
+   * @param pageable             - {@link Pageable}
+   * @param historyRequestParams - {@link HistoryRequestParams}
+   * @param projectDetails       -
+   *                             {@link
+   *                             com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
+   * @param user                 - {@link ReportPortalUser}
+   * @param usingHash            - true if need use hash
+   * @return {@link Page} with {@link TestItemHistory} content
+   */
+  Page<TestItemHistory> provide(Queryable filter, Pageable pageable,
+      HistoryRequestParams historyRequestParams,
+      ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user, boolean usingHash);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/history/provider/HistoryProviderFactory.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/history/provider/HistoryProviderFactory.java
index 2612bf338b..d0a8fd83c8 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/history/provider/HistoryProviderFactory.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/history/provider/HistoryProviderFactory.java
@@ -18,11 +18,10 @@
 
 import com.epam.ta.reportportal.core.item.impl.history.ItemHistoryBaselineEnum;
 import com.epam.ta.reportportal.core.item.impl.history.param.HistoryRequestParams;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
 import java.util.Map;
 import java.util.Optional;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -30,14 +29,16 @@
 @Service
 public class HistoryProviderFactory {
 
-	private Map<ItemHistoryBaselineEnum, HistoryProvider> historyProviderMapping;
+  private Map<ItemHistoryBaselineEnum, HistoryProvider> historyProviderMapping;
 
-	@Autowired
-	public HistoryProviderFactory(Map<ItemHistoryBaselineEnum, HistoryProvider> historyProviderMapping) {
-		this.historyProviderMapping = historyProviderMapping;
-	}
+  @Autowired
+  public HistoryProviderFactory(
+      Map<ItemHistoryBaselineEnum, HistoryProvider> historyProviderMapping) {
+    this.historyProviderMapping = historyProviderMapping;
+  }
 
-	public Optional<HistoryProvider> getProvider(HistoryRequestParams historyRequestParams) {
-		return ItemHistoryBaselineEnum.resolveType(historyRequestParams).map(this.historyProviderMapping::get);
-	}
+  public Optional<HistoryProvider> getProvider(HistoryRequestParams historyRequestParams) {
+    return ItemHistoryBaselineEnum.resolveType(historyRequestParams)
+        .map(this.historyProviderMapping::get);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/history/provider/config/ItemHistoryProviderConfiguration.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/history/provider/config/ItemHistoryProviderConfiguration.java
index 6d2c2c6011..f36b3dce7b 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/history/provider/config/ItemHistoryProviderConfiguration.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/history/provider/config/ItemHistoryProviderConfiguration.java
@@ -16,12 +16,14 @@
 
 package com.epam.ta.reportportal.core.item.impl.history.provider.config;
 
-import com.epam.ta.reportportal.core.item.impl.history.provider.impl.ComparingBaselineHistoryProvider;
-import com.epam.ta.reportportal.core.item.impl.history.provider.impl.FilterBaselineHistoryProvider;
 import com.epam.ta.reportportal.core.item.impl.history.ItemHistoryBaselineEnum;
 import com.epam.ta.reportportal.core.item.impl.history.provider.HistoryProvider;
+import com.epam.ta.reportportal.core.item.impl.history.provider.impl.ComparingBaselineHistoryProvider;
+import com.epam.ta.reportportal.core.item.impl.history.provider.impl.FilterBaselineHistoryProvider;
 import com.epam.ta.reportportal.core.item.impl.history.provider.impl.LaunchBaselineHistoryProvider;
 import com.epam.ta.reportportal.core.item.impl.history.provider.impl.TestItemBaselineHistoryProvider;
+import java.util.HashMap;
+import java.util.Map;
 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationContext;
@@ -29,30 +31,31 @@
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
-import java.util.HashMap;
-import java.util.Map;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Configuration
 public class ItemHistoryProviderConfiguration implements ApplicationContextAware {
 
-	private ApplicationContext applicationContext;
-
-	@Autowired
-	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
-		this.applicationContext = applicationContext;
-	}
-
-	@Bean(name = "historyProviderMapping")
-	public Map<ItemHistoryBaselineEnum, HistoryProvider> historyProviderMapping() {
-		Map<ItemHistoryBaselineEnum, HistoryProvider> mapping = new HashMap<>();
-		mapping.put(ItemHistoryBaselineEnum.COMPARING, applicationContext.getBean(ComparingBaselineHistoryProvider.class));
-		mapping.put(ItemHistoryBaselineEnum.FILTER, applicationContext.getBean(FilterBaselineHistoryProvider.class));
-		mapping.put(ItemHistoryBaselineEnum.ITEM, applicationContext.getBean(TestItemBaselineHistoryProvider.class));
-		mapping.put(ItemHistoryBaselineEnum.LAUNCH, applicationContext.getBean(LaunchBaselineHistoryProvider.class));
-		return mapping;
-	}
+  private ApplicationContext applicationContext;
+
+  @Autowired
+  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+    this.applicationContext = applicationContext;
+  }
+
+  @Bean(name = "historyProviderMapping")
+  public Map<ItemHistoryBaselineEnum, HistoryProvider> historyProviderMapping() {
+    Map<ItemHistoryBaselineEnum, HistoryProvider> mapping = new HashMap<>();
+    mapping.put(ItemHistoryBaselineEnum.COMPARING,
+        applicationContext.getBean(ComparingBaselineHistoryProvider.class));
+    mapping.put(ItemHistoryBaselineEnum.FILTER,
+        applicationContext.getBean(FilterBaselineHistoryProvider.class));
+    mapping.put(ItemHistoryBaselineEnum.ITEM,
+        applicationContext.getBean(TestItemBaselineHistoryProvider.class));
+    mapping.put(ItemHistoryBaselineEnum.LAUNCH,
+        applicationContext.getBean(LaunchBaselineHistoryProvider.class));
+    return mapping;
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/history/provider/impl/LaunchBaselineHistoryProvider.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/history/provider/impl/LaunchBaselineHistoryProvider.java
index 29e8a66af3..ec7c80627b 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/history/provider/impl/LaunchBaselineHistoryProvider.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/history/provider/impl/LaunchBaselineHistoryProvider.java
@@ -32,48 +32,51 @@
 import org.springframework.stereotype.Service;
 
 /**
- * Required for retrieving {@link TestItemHistory} content using {@link Launch#getId()} as baseline for {@link TestItemHistory} selection.
+ * Required for retrieving {@link TestItemHistory} content using {@link Launch#getId()} as baseline
+ * for {@link TestItemHistory} selection.
  *
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class LaunchBaselineHistoryProvider implements HistoryProvider {
 
-	private final LaunchRepository launchRepository;
-	private final LaunchAccessValidator launchAccessValidator;
-	private final TestItemRepository testItemRepository;
+  private final LaunchRepository launchRepository;
+  private final LaunchAccessValidator launchAccessValidator;
+  private final TestItemRepository testItemRepository;
 
-	public LaunchBaselineHistoryProvider(LaunchRepository launchRepository, LaunchAccessValidator launchAccessValidator,
-			TestItemRepository testItemRepository) {
-		this.launchRepository = launchRepository;
-		this.launchAccessValidator = launchAccessValidator;
-		this.testItemRepository = testItemRepository;
-	}
+  public LaunchBaselineHistoryProvider(LaunchRepository launchRepository,
+      LaunchAccessValidator launchAccessValidator,
+      TestItemRepository testItemRepository) {
+    this.launchRepository = launchRepository;
+    this.launchAccessValidator = launchAccessValidator;
+    this.testItemRepository = testItemRepository;
+  }
 
-	@Override
-	public Page<TestItemHistory> provide(Queryable filter, Pageable pageable, HistoryRequestParams historyRequestParams,
-			ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user, boolean usingHash) {
-		return historyRequestParams.getLaunchId().map(launchId -> {
-			Launch launch = launchRepository.findById(launchId)
-					.orElseThrow(() -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND, launchId));
-			launchAccessValidator.validate(launch.getId(), projectDetails, user);
+  @Override
+  public Page<TestItemHistory> provide(Queryable filter, Pageable pageable,
+      HistoryRequestParams historyRequestParams,
+      ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user, boolean usingHash) {
+    return historyRequestParams.getLaunchId().map(launchId -> {
+      Launch launch = launchRepository.findById(launchId)
+          .orElseThrow(() -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND, launchId));
+      launchAccessValidator.validate(launch.getId(), projectDetails, user);
 
-			return historyRequestParams.getHistoryType()
-					.filter(HistoryRequestParams.HistoryTypeEnum.LINE::equals)
-					.map(type -> testItemRepository.loadItemsHistoryPage(filter,
-							pageable,
-							projectDetails.getProjectId(),
-							launch.getName(),
-							historyRequestParams.getHistoryDepth(),
-							usingHash
-					))
-					.orElseGet(() -> testItemRepository.loadItemsHistoryPage(filter,
-							pageable,
-							projectDetails.getProjectId(),
-							historyRequestParams.getHistoryDepth(),
-							usingHash
-					));
-		}).orElseGet(() -> Page.empty(pageable));
-	}
+      return historyRequestParams.getHistoryType()
+          .filter(HistoryRequestParams.HistoryTypeEnum.LINE::equals)
+          .map(type -> testItemRepository.loadItemsHistoryPage(filter,
+              pageable,
+              projectDetails.getProjectId(),
+              launch.getName(),
+              historyRequestParams.getHistoryDepth(),
+              usingHash
+          ))
+          .orElseGet(() -> testItemRepository.loadItemsHistoryPage(filter,
+              pageable,
+              projectDetails.getProjectId(),
+              historyRequestParams.getHistoryDepth(),
+              usingHash
+          ));
+    }).orElseGet(() -> Page.empty(pageable));
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/history/provider/impl/TestItemBaselineHistoryProvider.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/history/provider/impl/TestItemBaselineHistoryProvider.java
index d451333c3c..b1512142d9 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/history/provider/impl/TestItemBaselineHistoryProvider.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/history/provider/impl/TestItemBaselineHistoryProvider.java
@@ -16,8 +16,16 @@
 
 package com.epam.ta.reportportal.core.item.impl.history.provider.impl;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_HAS_CHILDREN;
+import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_PARENT_ID;
+import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_PATH;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
-import com.epam.ta.reportportal.commons.querygen.*;
+import com.epam.ta.reportportal.commons.querygen.Condition;
+import com.epam.ta.reportportal.commons.querygen.ConvertibleCondition;
+import com.epam.ta.reportportal.commons.querygen.Filter;
+import com.epam.ta.reportportal.commons.querygen.FilterCondition;
+import com.epam.ta.reportportal.commons.querygen.Queryable;
 import com.epam.ta.reportportal.core.item.TestItemService;
 import com.epam.ta.reportportal.core.item.impl.LaunchAccessValidator;
 import com.epam.ta.reportportal.core.item.impl.history.param.HistoryRequestParams;
@@ -28,6 +36,8 @@
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.List;
+import java.util.stream.Collectors;
 import org.apache.commons.lang3.BooleanUtils;
 import org.jooq.Operator;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -35,11 +45,6 @@
 import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.*;
-
 /**
  * * Required for retrieving {@link TestItemHistory} content.
  *
@@ -48,95 +53,100 @@
 @Service
 public class TestItemBaselineHistoryProvider implements HistoryProvider {
 
-	private final TestItemService testItemService;
-	private final LaunchAccessValidator launchAccessValidator;
-	private final TestItemRepository testItemRepository;
+  private final TestItemService testItemService;
+  private final LaunchAccessValidator launchAccessValidator;
+  private final TestItemRepository testItemRepository;
 
-	@Autowired
-	public TestItemBaselineHistoryProvider(TestItemService testItemService, LaunchAccessValidator launchAccessValidator,
-			TestItemRepository testItemRepository) {
-		this.testItemService = testItemService;
-		this.launchAccessValidator = launchAccessValidator;
-		this.testItemRepository = testItemRepository;
-	}
+  @Autowired
+  public TestItemBaselineHistoryProvider(TestItemService testItemService,
+      LaunchAccessValidator launchAccessValidator,
+      TestItemRepository testItemRepository) {
+    this.testItemService = testItemService;
+    this.launchAccessValidator = launchAccessValidator;
+    this.testItemRepository = testItemRepository;
+  }
 
-	@Override
-	public Page<TestItemHistory> provide(Queryable filter, Pageable pageable, HistoryRequestParams historyRequestParams,
-			ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user, boolean usingHash) {
+  @Override
+  public Page<TestItemHistory> provide(Queryable filter, Pageable pageable,
+      HistoryRequestParams historyRequestParams,
+      ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user, boolean usingHash) {
 
-		return historyRequestParams.getParentId()
-				.map(parentId -> loadHistory(resolveFilter(filter, parentId),
-						pageable,
-						parentId,
-						historyRequestParams,
-						projectDetails,
-						user,
-						usingHash
-				))
-				.orElseGet(() -> historyRequestParams.getItemId()
-						.map(itemId -> loadHistory(filter, pageable, itemId, historyRequestParams, projectDetails, user, usingHash))
-						.orElseGet(() -> Page.empty(pageable)));
-	}
+    return historyRequestParams.getParentId()
+        .map(parentId -> loadHistory(resolveFilter(filter, parentId),
+            pageable,
+            parentId,
+            historyRequestParams,
+            projectDetails,
+            user,
+            usingHash
+        ))
+        .orElseGet(() -> historyRequestParams.getItemId()
+            .map(itemId -> loadHistory(filter, pageable, itemId, historyRequestParams,
+                projectDetails, user, usingHash))
+            .orElseGet(() -> Page.empty(pageable)));
+  }
 
-	/**
-	 * Replace {@link Condition#EQUALS} for parent item by {@link Condition#UNDER}
-	 * if descendants with {@link TestItem#isHasChildren()} == 'false' should be selected
-	 *
-	 * @param filter   {@link Queryable}
-	 * @param parentId Id of the parent {@link TestItem} which descendants' history should be built
-	 * @return Updated {@link Queryable}
-	 */
-	private Queryable resolveFilter(Queryable filter, Long parentId) {
-		return filter.getFilterConditions()
-				.stream()
-				.flatMap(c -> c.getAllConditions().stream())
-				.filter(c -> CRITERIA_HAS_CHILDREN.equalsIgnoreCase(c.getSearchCriteria()) && !BooleanUtils.toBoolean(c.getValue()))
-				.findFirst()
-				.map(notHasChildren -> updateParentFilter(filter, parentId))
-				.orElse(filter);
-	}
+  /**
+   * Replace {@link Condition#EQUALS} for parent item by {@link Condition#UNDER} if descendants with
+   * {@link TestItem#isHasChildren()} == 'false' should be selected
+   *
+   * @param filter   {@link Queryable}
+   * @param parentId Id of the parent {@link TestItem} which descendants' history should be built
+   * @return Updated {@link Queryable}
+   */
+  private Queryable resolveFilter(Queryable filter, Long parentId) {
+    return filter.getFilterConditions()
+        .stream()
+        .flatMap(c -> c.getAllConditions().stream())
+        .filter(c -> CRITERIA_HAS_CHILDREN.equalsIgnoreCase(c.getSearchCriteria())
+            && !BooleanUtils.toBoolean(c.getValue()))
+        .findFirst()
+        .map(notHasChildren -> updateParentFilter(filter, parentId))
+        .orElse(filter);
+  }
 
-	private Queryable updateParentFilter(Queryable parentFilter, Long parentId) {
-		TestItem parent = testItemRepository.findById(parentId)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, parentId));
-		List<ConvertibleCondition> resultConditions = parentFilter.getFilterConditions()
-				.stream()
-				.filter(c -> c.getAllConditions()
-						.stream()
-						.noneMatch(fc -> CRITERIA_PARENT_ID.equalsIgnoreCase(fc.getSearchCriteria())
-								&& Condition.EQUALS.equals(fc.getCondition())))
-				.collect(Collectors.toList());
-		resultConditions.add(FilterCondition.builder()
-				.withOperator(Operator.AND)
-				.withCondition(Condition.UNDER)
-				.withSearchCriteria(CRITERIA_PATH)
-				.withValue(String.valueOf(parent.getPath()))
-				.build());
-		return new Filter(parentFilter.getTarget().getClazz(), resultConditions);
-	}
+  private Queryable updateParentFilter(Queryable parentFilter, Long parentId) {
+    TestItem parent = testItemRepository.findById(parentId)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, parentId));
+    List<ConvertibleCondition> resultConditions = parentFilter.getFilterConditions()
+        .stream()
+        .filter(c -> c.getAllConditions()
+            .stream()
+            .noneMatch(fc -> CRITERIA_PARENT_ID.equalsIgnoreCase(fc.getSearchCriteria())
+                && Condition.EQUALS.equals(fc.getCondition())))
+        .collect(Collectors.toList());
+    resultConditions.add(FilterCondition.builder()
+        .withOperator(Operator.AND)
+        .withCondition(Condition.UNDER)
+        .withSearchCriteria(CRITERIA_PATH)
+        .withValue(String.valueOf(parent.getPath()))
+        .build());
+    return new Filter(parentFilter.getTarget().getClazz(), resultConditions);
+  }
 
-	private Page<TestItemHistory> loadHistory(Queryable filter, Pageable pageable, Long itemId, HistoryRequestParams historyRequestParams,
-			ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user, boolean usingHash) {
-		TestItem testItem = testItemRepository.findById(itemId)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, itemId));
-		Launch launch = testItemService.getEffectiveLaunch(testItem);
-		launchAccessValidator.validate(launch.getId(), projectDetails, user);
+  private Page<TestItemHistory> loadHistory(Queryable filter, Pageable pageable, Long itemId,
+      HistoryRequestParams historyRequestParams,
+      ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user, boolean usingHash) {
+    TestItem testItem = testItemRepository.findById(itemId)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, itemId));
+    Launch launch = testItemService.getEffectiveLaunch(testItem);
+    launchAccessValidator.validate(launch.getId(), projectDetails, user);
 
-		return historyRequestParams.getHistoryType()
-				.filter(HistoryRequestParams.HistoryTypeEnum.LINE::equals)
-				.map(type -> testItemRepository.loadItemsHistoryPage(filter,
-						pageable,
-						projectDetails.getProjectId(),
-						launch.getName(),
-						historyRequestParams.getHistoryDepth(),
-						usingHash
-				))
-				.orElseGet(() -> testItemRepository.loadItemsHistoryPage(filter,
-						pageable,
-						projectDetails.getProjectId(),
-						historyRequestParams.getHistoryDepth(),
-						usingHash
-				));
+    return historyRequestParams.getHistoryType()
+        .filter(HistoryRequestParams.HistoryTypeEnum.LINE::equals)
+        .map(type -> testItemRepository.loadItemsHistoryPage(filter,
+            pageable,
+            projectDetails.getProjectId(),
+            launch.getName(),
+            historyRequestParams.getHistoryDepth(),
+            usingHash
+        ))
+        .orElseGet(() -> testItemRepository.loadItemsHistoryPage(filter,
+            pageable,
+            projectDetails.getProjectId(),
+            historyRequestParams.getHistoryDepth(),
+            usingHash
+        ));
 
-	}
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/merge/strategy/AbstractLaunchMergeStrategy.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/merge/strategy/AbstractLaunchMergeStrategy.java
index 46b5484a5c..30c5adb73c 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/merge/strategy/AbstractLaunchMergeStrategy.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/merge/strategy/AbstractLaunchMergeStrategy.java
@@ -16,6 +16,15 @@
 
 package com.epam.ta.reportportal.core.item.impl.merge.strategy;
 
+import static com.epam.ta.reportportal.commons.EntityUtils.TO_LOCAL_DATE_TIME;
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.IN_PROGRESS;
+import static com.epam.ta.reportportal.ws.converter.converters.ItemAttributeConverter.FROM_RESOURCE;
+import static com.epam.ta.reportportal.ws.model.ErrorType.FINISH_TIME_EARLIER_THAN_START_TIME;
+import static java.util.Optional.ofNullable;
+import static java.util.stream.Collectors.joining;
+import static java.util.stream.Collectors.toList;
+
 import com.epam.ta.reportportal.commons.EntityUtils;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.validation.Suppliers;
@@ -39,157 +48,170 @@
 import com.epam.ta.reportportal.ws.model.launch.Mode;
 import com.epam.ta.reportportal.ws.model.launch.StartLaunchRQ;
 import com.google.common.collect.Sets;
-
-import java.util.*;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
 
-import static com.epam.ta.reportportal.commons.EntityUtils.TO_LOCAL_DATE_TIME;
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.entity.enums.StatusEnum.IN_PROGRESS;
-import static com.epam.ta.reportportal.ws.converter.converters.ItemAttributeConverter.FROM_RESOURCE;
-import static com.epam.ta.reportportal.ws.model.ErrorType.FINISH_TIME_EARLIER_THAN_START_TIME;
-import static java.util.Optional.ofNullable;
-import static java.util.stream.Collectors.joining;
-import static java.util.stream.Collectors.toList;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public abstract class AbstractLaunchMergeStrategy implements LaunchMergeStrategy {
-	protected final LaunchRepository launchRepository;
-
-	private final TestItemRepository testItemRepository;
-	private final LogRepository logRepository;
-	private final AttachmentRepository attachmentRepository;
-	private final TestItemUniqueIdGenerator identifierGenerator;
-
-	protected AbstractLaunchMergeStrategy(LaunchRepository launchRepository, TestItemRepository testItemRepository,
-			LogRepository logRepository, AttachmentRepository attachmentRepository, TestItemUniqueIdGenerator identifierGenerator) {
-		this.launchRepository = launchRepository;
-		this.testItemRepository = testItemRepository;
-		this.logRepository = logRepository;
-		this.attachmentRepository = attachmentRepository;
-		this.identifierGenerator = identifierGenerator;
-	}
-
-	protected Launch createNewLaunch(ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user, MergeLaunchesRQ rq,
-			List<Launch> launchesList) {
-		Launch newLaunch = createResultedLaunch(projectDetails.getProjectId(), user.getUserId(), rq, launchesList);
-		boolean isNameChanged = !newLaunch.getName().equals(launchesList.get(0).getName());
-		updateChildrenOfLaunches(newLaunch, rq.getLaunches(), rq.isExtendSuitesDescription(), isNameChanged);
-
-		return newLaunch;
-	}
-
-	/**
-	 * Create launch that will be the result of merge
-	 *
-	 * @param projectId       {@link Project#getId()}
-	 * @param userId          {@link ReportPortalUser#getUserId()}
-	 * @param mergeLaunchesRQ {@link MergeLaunchesRQ}
-	 * @param launches        {@link List} of the {@link Launch}
-	 * @return launch
-	 */
-	private Launch createResultedLaunch(Long projectId, Long userId, MergeLaunchesRQ mergeLaunchesRQ, List<Launch> launches) {
-		Date startTime = ofNullable(mergeLaunchesRQ.getStartTime()).orElse(EntityUtils.TO_DATE.apply(launches.stream()
-				.min(Comparator.comparing(Launch::getStartTime))
-				.orElseThrow(() -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR, "Invalid launches"))
-				.getStartTime()));
-		Date endTime = ofNullable(mergeLaunchesRQ.getEndTime()).orElse(EntityUtils.TO_DATE.apply(launches.stream()
-				.max(Comparator.comparing(Launch::getEndTime))
-				.orElseThrow(() -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR, "Invalid launches"))
-				.getEndTime()));
-		expect(endTime, time -> !time.before(startTime)).verify(FINISH_TIME_EARLIER_THAN_START_TIME,
-				TO_LOCAL_DATE_TIME.apply(endTime),
-				startTime,
-				projectId
-		);
-
-		StartLaunchRQ startRQ = new StartLaunchRQ();
-		startRQ.setMode(ofNullable(mergeLaunchesRQ.getMode()).orElse(Mode.DEFAULT));
-		startRQ.setDescription(ofNullable(mergeLaunchesRQ.getDescription()).orElse(launches.stream()
-				.map(Launch::getDescription)
-				.collect(joining("\n\n"))));
-		startRQ.setName(ofNullable(mergeLaunchesRQ.getName()).orElse(
-				"Merged: " + launches.stream().map(Launch::getName).distinct().collect(joining(", "))));
-		startRQ.setStartTime(startTime);
-		Launch launch = new LaunchBuilder().addStartRQ(startRQ)
-				.addProject(projectId)
-				.addStatus(IN_PROGRESS.name())
-				.addUserId(userId)
-				.addEndTime(endTime)
-				.get();
-		launch.setHasRetries(launches.stream().anyMatch(Launch::isHasRetries));
-
-		launchRepository.save(launch);
-		launchRepository.refresh(launch);
-		mergeAttributes(mergeLaunchesRQ.getAttributes(), launches, launch);
-		return launch;
-	}
-
-	/**
-	 * Merges launches attributes. Collect all system attributes from existed launches
-	 * and all unique not system attributes from request(if preset, or from exited launches if not) to resulted launch.
-	 *
-	 * @param attributesFromRq {@link Set} of attributes from request
-	 * @param launchesToMerge  {@link List} of {@link Launch} to be merged
-	 * @param resultedLaunch   {@link Launch} - result of merge
-	 */
-
-	private void mergeAttributes(Set<ItemAttributeResource> attributesFromRq, List<Launch> launchesToMerge, Launch resultedLaunch) {
-		Set<ItemAttribute> mergedAttributes = Sets.newHashSet();
-
-		if (attributesFromRq == null) {
-			mergedAttributes.addAll(launchesToMerge.stream()
-					.map(Launch::getAttributes)
-					.flatMap(Collection::stream)
-					.peek(it -> it.setLaunch(resultedLaunch))
-					.collect(Collectors.toSet()));
-		} else {
-			mergedAttributes.addAll(launchesToMerge.stream()
-					.map(Launch::getAttributes)
-					.flatMap(Collection::stream)
-					.filter(ItemAttribute::isSystem)
-					.peek(it -> it.setLaunch(resultedLaunch))
-					.collect(Collectors.toSet()));
-			mergedAttributes.addAll(attributesFromRq.stream()
-					.map(FROM_RESOURCE)
-					.peek(attr -> attr.setLaunch(resultedLaunch))
-					.collect(Collectors.toSet()));
-		}
-		resultedLaunch.setAttributes(mergedAttributes);
-	}
-
-	/**
-	 * Update test-items of specified launches with new LaunchID
-	 *
-	 * @param newLaunch         {@link Launch}
-	 * @param launches          {@link Set} of the {@link Launch}
-	 * @param extendDescription additional description for suite indicator
-	 * @param isNameChanged     launch name change indicator
-	 */
-	private void updateChildrenOfLaunches(Launch newLaunch, Set<Long> launches, boolean extendDescription, boolean isNameChanged) {
-		List<TestItem> testItems = launches.stream().peek(id -> {
-			logRepository.updateLaunchIdByLaunchId(id, newLaunch.getId());
-			attachmentRepository.updateLaunchIdByProjectIdAndLaunchId(newLaunch.getProjectId(), id, newLaunch.getId());
-		}).flatMap(id -> {
-			Launch launch = launchRepository.findById(id).orElseThrow(() -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND, id));
-			return testItemRepository.findTestItemsByLaunchId(launch.getId()).stream().peek(testItem -> {
-				testItem.setLaunchId(newLaunch.getId());
-				if (isNameChanged && identifierGenerator.validate(testItem.getUniqueId())) {
-					testItem.setUniqueId(identifierGenerator.generate(testItem, IdentityUtil.getParentIds(testItem), newLaunch));
-				}
-				if (testItem.getType().sameLevel(TestItemTypeEnum.SUITE)) {
-					// Add launch reference description for top level items
-					Supplier<String> newDescription = Suppliers.formattedSupplier(
-							((null != testItem.getDescription()) ? testItem.getDescription() : "") + (extendDescription ?
-									"\r\n@launch '{} #{}'" :
-									""), launch.getName(), launch.getNumber());
-					testItem.setDescription(newDescription.get());
-				}
-			});
-		}).collect(toList());
-		testItemRepository.saveAll(testItems);
-	}
+
+  protected final LaunchRepository launchRepository;
+
+  private final TestItemRepository testItemRepository;
+  private final LogRepository logRepository;
+  private final AttachmentRepository attachmentRepository;
+  private final TestItemUniqueIdGenerator identifierGenerator;
+
+  protected AbstractLaunchMergeStrategy(LaunchRepository launchRepository,
+      TestItemRepository testItemRepository,
+      LogRepository logRepository, AttachmentRepository attachmentRepository,
+      TestItemUniqueIdGenerator identifierGenerator) {
+    this.launchRepository = launchRepository;
+    this.testItemRepository = testItemRepository;
+    this.logRepository = logRepository;
+    this.attachmentRepository = attachmentRepository;
+    this.identifierGenerator = identifierGenerator;
+  }
+
+  protected Launch createNewLaunch(ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user, MergeLaunchesRQ rq,
+      List<Launch> launchesList) {
+    Launch newLaunch = createResultedLaunch(projectDetails.getProjectId(), user.getUserId(), rq,
+        launchesList);
+    boolean isNameChanged = !newLaunch.getName().equals(launchesList.get(0).getName());
+    updateChildrenOfLaunches(newLaunch, rq.getLaunches(), rq.isExtendSuitesDescription(),
+        isNameChanged);
+
+    return newLaunch;
+  }
+
+  /**
+   * Create launch that will be the result of merge
+   *
+   * @param projectId       {@link Project#getId()}
+   * @param userId          {@link ReportPortalUser#getUserId()}
+   * @param mergeLaunchesRQ {@link MergeLaunchesRQ}
+   * @param launches        {@link List} of the {@link Launch}
+   * @return launch
+   */
+  private Launch createResultedLaunch(Long projectId, Long userId, MergeLaunchesRQ mergeLaunchesRQ,
+      List<Launch> launches) {
+    Date startTime = ofNullable(mergeLaunchesRQ.getStartTime()).orElse(
+        EntityUtils.TO_DATE.apply(launches.stream()
+            .min(Comparator.comparing(Launch::getStartTime))
+            .orElseThrow(
+                () -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR, "Invalid launches"))
+            .getStartTime()));
+    Date endTime = ofNullable(mergeLaunchesRQ.getEndTime()).orElse(
+        EntityUtils.TO_DATE.apply(launches.stream()
+            .max(Comparator.comparing(Launch::getEndTime))
+            .orElseThrow(
+                () -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR, "Invalid launches"))
+            .getEndTime()));
+    expect(endTime, time -> !time.before(startTime)).verify(FINISH_TIME_EARLIER_THAN_START_TIME,
+        TO_LOCAL_DATE_TIME.apply(endTime),
+        startTime,
+        projectId
+    );
+
+    StartLaunchRQ startRQ = new StartLaunchRQ();
+    startRQ.setMode(ofNullable(mergeLaunchesRQ.getMode()).orElse(Mode.DEFAULT));
+    startRQ.setDescription(ofNullable(mergeLaunchesRQ.getDescription()).orElse(launches.stream()
+        .map(Launch::getDescription)
+        .collect(joining("\n\n"))));
+    startRQ.setName(ofNullable(mergeLaunchesRQ.getName()).orElse(
+        "Merged: " + launches.stream().map(Launch::getName).distinct().collect(joining(", "))));
+    startRQ.setStartTime(startTime);
+    Launch launch = new LaunchBuilder().addStartRQ(startRQ)
+        .addProject(projectId)
+        .addStatus(IN_PROGRESS.name())
+        .addUserId(userId)
+        .addEndTime(endTime)
+        .get();
+    launch.setHasRetries(launches.stream().anyMatch(Launch::isHasRetries));
+
+    launchRepository.save(launch);
+    launchRepository.refresh(launch);
+    mergeAttributes(mergeLaunchesRQ.getAttributes(), launches, launch);
+    return launch;
+  }
+
+  /**
+   * Merges launches attributes. Collect all system attributes from existed launches and all unique
+   * not system attributes from request(if preset, or from exited launches if not) to resulted
+   * launch.
+   *
+   * @param attributesFromRq {@link Set} of attributes from request
+   * @param launchesToMerge  {@link List} of {@link Launch} to be merged
+   * @param resultedLaunch   {@link Launch} - result of merge
+   */
+
+  private void mergeAttributes(Set<ItemAttributeResource> attributesFromRq,
+      List<Launch> launchesToMerge, Launch resultedLaunch) {
+    Set<ItemAttribute> mergedAttributes = Sets.newHashSet();
+
+    if (attributesFromRq == null) {
+      mergedAttributes.addAll(launchesToMerge.stream()
+          .map(Launch::getAttributes)
+          .flatMap(Collection::stream)
+          .peek(it -> it.setLaunch(resultedLaunch))
+          .collect(Collectors.toSet()));
+    } else {
+      mergedAttributes.addAll(launchesToMerge.stream()
+          .map(Launch::getAttributes)
+          .flatMap(Collection::stream)
+          .filter(ItemAttribute::isSystem)
+          .peek(it -> it.setLaunch(resultedLaunch))
+          .collect(Collectors.toSet()));
+      mergedAttributes.addAll(attributesFromRq.stream()
+          .map(FROM_RESOURCE)
+          .peek(attr -> attr.setLaunch(resultedLaunch))
+          .collect(Collectors.toSet()));
+    }
+    resultedLaunch.setAttributes(mergedAttributes);
+  }
+
+  /**
+   * Update test-items of specified launches with new LaunchID
+   *
+   * @param newLaunch         {@link Launch}
+   * @param launches          {@link Set} of the {@link Launch}
+   * @param extendDescription additional description for suite indicator
+   * @param isNameChanged     launch name change indicator
+   */
+  private void updateChildrenOfLaunches(Launch newLaunch, Set<Long> launches,
+      boolean extendDescription, boolean isNameChanged) {
+    List<TestItem> testItems = launches.stream().peek(id -> {
+      logRepository.updateLaunchIdByLaunchId(id, newLaunch.getId());
+      attachmentRepository.updateLaunchIdByProjectIdAndLaunchId(newLaunch.getProjectId(), id,
+          newLaunch.getId());
+    }).flatMap(id -> {
+      Launch launch = launchRepository.findById(id)
+          .orElseThrow(() -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND, id));
+      return testItemRepository.findTestItemsByLaunchId(launch.getId()).stream().peek(testItem -> {
+        testItem.setLaunchId(newLaunch.getId());
+        if (isNameChanged && identifierGenerator.validate(testItem.getUniqueId())) {
+          testItem.setUniqueId(
+              identifierGenerator.generate(testItem, IdentityUtil.getParentIds(testItem),
+                  newLaunch));
+        }
+        if (testItem.getType().sameLevel(TestItemTypeEnum.SUITE)) {
+          // Add launch reference description for top level items
+          Supplier<String> newDescription = Suppliers.formattedSupplier(
+              ((null != testItem.getDescription()) ? testItem.getDescription() : "") + (
+                  extendDescription ?
+                      "\r\n@launch '{} #{}'" :
+                      ""), launch.getName(), launch.getNumber());
+          testItem.setDescription(newDescription.get());
+        }
+      });
+    }).collect(toList());
+    testItemRepository.saveAll(testItems);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/merge/strategy/BasicLaunchMergeStrategy.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/merge/strategy/BasicLaunchMergeStrategy.java
index 30d87abb6a..c38fb183e2 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/merge/strategy/BasicLaunchMergeStrategy.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/merge/strategy/BasicLaunchMergeStrategy.java
@@ -24,7 +24,6 @@
 import com.epam.ta.reportportal.dao.TestItemRepository;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.ws.model.launch.MergeLaunchesRQ;
-
 import java.util.List;
 
 /**
@@ -32,26 +31,30 @@
  */
 public class BasicLaunchMergeStrategy extends AbstractLaunchMergeStrategy {
 
-	private final StatisticsCalculationFactory statisticsCalculationFactory;
+  private final StatisticsCalculationFactory statisticsCalculationFactory;
 
-	public BasicLaunchMergeStrategy(LaunchRepository launchRepository, TestItemRepository testItemRepository,
-			LogRepository logRepository, AttachmentRepository attachmentRepository, TestItemUniqueIdGenerator identifierGenerator,
-			StatisticsCalculationFactory statisticsCalculationFactory) {
-		super(launchRepository, testItemRepository, logRepository, attachmentRepository, identifierGenerator);
-		this.statisticsCalculationFactory = statisticsCalculationFactory;
-	}
+  public BasicLaunchMergeStrategy(LaunchRepository launchRepository,
+      TestItemRepository testItemRepository,
+      LogRepository logRepository, AttachmentRepository attachmentRepository,
+      TestItemUniqueIdGenerator identifierGenerator,
+      StatisticsCalculationFactory statisticsCalculationFactory) {
+    super(launchRepository, testItemRepository, logRepository, attachmentRepository,
+        identifierGenerator);
+    this.statisticsCalculationFactory = statisticsCalculationFactory;
+  }
 
-	@Override
-	public Launch mergeLaunches(ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user, MergeLaunchesRQ rq,
-			List<Launch> launchesList) {
+  @Override
+  public Launch mergeLaunches(ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user,
+      MergeLaunchesRQ rq,
+      List<Launch> launchesList) {
 
-		Launch newLaunch = createNewLaunch(projectDetails, user, rq, launchesList);
+    Launch newLaunch = createNewLaunch(projectDetails, user, rq, launchesList);
 
-		newLaunch.setStatistics(statisticsCalculationFactory.getStrategy(MergeStrategyType.BASIC)
-				.recalculateLaunchStatistics(newLaunch, launchesList));
+    newLaunch.setStatistics(statisticsCalculationFactory.getStrategy(MergeStrategyType.BASIC)
+        .recalculateLaunchStatistics(newLaunch, launchesList));
 
-		launchRepository.save(newLaunch);
-		return newLaunch;
+    launchRepository.save(newLaunch);
+    return newLaunch;
 
-	}
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/merge/strategy/BasicStatisticsCalculationStrategy.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/merge/strategy/BasicStatisticsCalculationStrategy.java
index 34c3bc088e..cce94ad14b 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/merge/strategy/BasicStatisticsCalculationStrategy.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/merge/strategy/BasicStatisticsCalculationStrategy.java
@@ -16,32 +16,32 @@
 
 package com.epam.ta.reportportal.core.item.impl.merge.strategy;
 
+import static java.util.Optional.ofNullable;
+import static java.util.stream.Collectors.toMap;
+
 import com.epam.ta.reportportal.core.item.merge.StatisticsCalculationStrategy;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.entity.statistics.Statistics;
-
 import java.util.Collection;
 import java.util.Set;
 import java.util.stream.Collectors;
 
-import static java.util.Optional.ofNullable;
-import static java.util.stream.Collectors.toMap;
-
 /**
  * @author Ivan Budaev
  */
 public class BasicStatisticsCalculationStrategy implements StatisticsCalculationStrategy {
 
-	@Override
-	public Set<Statistics> recalculateLaunchStatistics(Launch newLaunch, Collection<Launch> launches) {
-		return launches.stream()
-				.filter(l -> ofNullable(l.getStatistics()).isPresent())
-				.flatMap(l -> l.getStatistics().stream())
-				.filter(s -> ofNullable(s.getStatisticsField()).isPresent())
-				.collect(toMap(Statistics::getStatisticsField, Statistics::getCounter, Integer::sum))
-				.entrySet()
-				.stream()
-				.map(entry -> new Statistics(entry.getKey(), entry.getValue(), newLaunch.getId()))
-				.collect(Collectors.toSet());
-	}
+  @Override
+  public Set<Statistics> recalculateLaunchStatistics(Launch newLaunch,
+      Collection<Launch> launches) {
+    return launches.stream()
+        .filter(l -> ofNullable(l.getStatistics()).isPresent())
+        .flatMap(l -> l.getStatistics().stream())
+        .filter(s -> ofNullable(s.getStatisticsField()).isPresent())
+        .collect(toMap(Statistics::getStatisticsField, Statistics::getCounter, Integer::sum))
+        .entrySet()
+        .stream()
+        .map(entry -> new Statistics(entry.getKey(), entry.getValue(), newLaunch.getId()))
+        .collect(Collectors.toSet());
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/merge/strategy/DeepLaunchMergeStrategy.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/merge/strategy/DeepLaunchMergeStrategy.java
index b292ed9450..5eeb57ecf9 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/merge/strategy/DeepLaunchMergeStrategy.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/merge/strategy/DeepLaunchMergeStrategy.java
@@ -24,7 +24,6 @@
 import com.epam.ta.reportportal.dao.TestItemRepository;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.ws.model.launch.MergeLaunchesRQ;
-
 import java.util.List;
 
 /**
@@ -32,19 +31,22 @@
  */
 public class DeepLaunchMergeStrategy extends AbstractLaunchMergeStrategy {
 
-	public DeepLaunchMergeStrategy(LaunchRepository launchRepository, TestItemRepository testItemRepository, LogRepository logRepository,
-			AttachmentRepository attachmentRepository, TestItemUniqueIdGenerator identifierGenerator) {
-		super(launchRepository, testItemRepository, logRepository, attachmentRepository, identifierGenerator);
-	}
+  public DeepLaunchMergeStrategy(LaunchRepository launchRepository,
+      TestItemRepository testItemRepository, LogRepository logRepository,
+      AttachmentRepository attachmentRepository, TestItemUniqueIdGenerator identifierGenerator) {
+    super(launchRepository, testItemRepository, logRepository, attachmentRepository,
+        identifierGenerator);
+  }
 
-	@Override
-	public Launch mergeLaunches(ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user, MergeLaunchesRQ rq,
-			List<Launch> launchesList) {
+  @Override
+  public Launch mergeLaunches(ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user,
+      MergeLaunchesRQ rq,
+      List<Launch> launchesList) {
 
-		Launch newLaunch = createNewLaunch(projectDetails, user, rq, launchesList);
-		launchRepository.mergeLaunchTestItems(newLaunch.getId());
-		launchRepository.save(newLaunch);
-		launchRepository.refresh(newLaunch);
-		return newLaunch;
-	}
+    Launch newLaunch = createNewLaunch(projectDetails, user, rq, launchesList);
+    launchRepository.mergeLaunchTestItems(newLaunch.getId());
+    launchRepository.save(newLaunch);
+    launchRepository.refresh(newLaunch);
+    return newLaunch;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/merge/strategy/LaunchMergeFactory.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/merge/strategy/LaunchMergeFactory.java
index 660c5dc912..d74cf24ee3 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/merge/strategy/LaunchMergeFactory.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/merge/strategy/LaunchMergeFactory.java
@@ -17,7 +17,6 @@
 package com.epam.ta.reportportal.core.item.impl.merge.strategy;
 
 import com.epam.ta.reportportal.core.item.merge.LaunchMergeStrategy;
-
 import java.util.Map;
 
 /**
@@ -25,13 +24,13 @@
  */
 public class LaunchMergeFactory {
 
-	private Map<MergeStrategyType, LaunchMergeStrategy> mergeStrategyMapping;
+  private Map<MergeStrategyType, LaunchMergeStrategy> mergeStrategyMapping;
 
-	public LaunchMergeFactory(Map<MergeStrategyType, LaunchMergeStrategy> mergeStrategyMapping) {
-		this.mergeStrategyMapping = mergeStrategyMapping;
-	}
+  public LaunchMergeFactory(Map<MergeStrategyType, LaunchMergeStrategy> mergeStrategyMapping) {
+    this.mergeStrategyMapping = mergeStrategyMapping;
+  }
 
-	public LaunchMergeStrategy getLaunchMergeStrategy(MergeStrategyType type) {
-		return mergeStrategyMapping.get(type);
-	}
+  public LaunchMergeStrategy getLaunchMergeStrategy(MergeStrategyType type) {
+    return mergeStrategyMapping.get(type);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/merge/strategy/MergeStrategyType.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/merge/strategy/MergeStrategyType.java
index 73acc5ac46..c0bce9cdde 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/merge/strategy/MergeStrategyType.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/merge/strategy/MergeStrategyType.java
@@ -22,10 +22,11 @@
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public enum MergeStrategyType {
-	DEEP,
-	BASIC;
+  DEEP,
+  BASIC;
 
-	public static MergeStrategyType fromValue(String value) {
-		return Arrays.stream(MergeStrategyType.values()).filter(type -> type.name().equalsIgnoreCase(value)).findFirst().orElse(null);
-	}
+  public static MergeStrategyType fromValue(String value) {
+    return Arrays.stream(MergeStrategyType.values())
+        .filter(type -> type.name().equalsIgnoreCase(value)).findFirst().orElse(null);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/merge/strategy/StatisticsCalculationFactory.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/merge/strategy/StatisticsCalculationFactory.java
index 864d6551ac..8cf98d6bde 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/merge/strategy/StatisticsCalculationFactory.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/merge/strategy/StatisticsCalculationFactory.java
@@ -17,7 +17,6 @@
 package com.epam.ta.reportportal.core.item.impl.merge.strategy;
 
 import com.epam.ta.reportportal.core.item.merge.StatisticsCalculationStrategy;
-
 import java.util.Map;
 
 /**
@@ -25,13 +24,14 @@
  */
 public class StatisticsCalculationFactory {
 
-	private final Map<MergeStrategyType, StatisticsCalculationStrategy> calculationStrategyMapping;
+  private final Map<MergeStrategyType, StatisticsCalculationStrategy> calculationStrategyMapping;
 
-	public StatisticsCalculationFactory(Map<MergeStrategyType, StatisticsCalculationStrategy> calculationStrategyMapping) {
-		this.calculationStrategyMapping = calculationStrategyMapping;
-	}
+  public StatisticsCalculationFactory(
+      Map<MergeStrategyType, StatisticsCalculationStrategy> calculationStrategyMapping) {
+    this.calculationStrategyMapping = calculationStrategyMapping;
+  }
 
-	public StatisticsCalculationStrategy getStrategy(MergeStrategyType type) {
-		return this.calculationStrategyMapping.get(type);
-	}
+  public StatisticsCalculationStrategy getStrategy(MergeStrategyType type) {
+    return this.calculationStrategyMapping.get(type);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/provider/DataProviderHandler.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/provider/DataProviderHandler.java
index 23b21b0543..dca3f45162 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/provider/DataProviderHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/provider/DataProviderHandler.java
@@ -20,21 +20,22 @@
 import com.epam.ta.reportportal.commons.querygen.Queryable;
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.statistics.Statistics;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-
 import java.util.Map;
 import java.util.Set;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
 
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
  */
 public interface DataProviderHandler {
 
-	Page<TestItem> getTestItems(Queryable filter, Pageable pageable, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user,
-			Map<String, String> params);
+  Page<TestItem> getTestItems(Queryable filter, Pageable pageable,
+      ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user,
+      Map<String, String> params);
 
-	Set<Statistics> accumulateStatistics(Queryable filter, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user,
-			Map<String, String> params);
+  Set<Statistics> accumulateStatistics(Queryable filter,
+      ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user,
+      Map<String, String> params);
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/provider/DataProviderType.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/provider/DataProviderType.java
index 1c6465047c..b14d173a9b 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/provider/DataProviderType.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/provider/DataProviderType.java
@@ -16,32 +16,33 @@
 
 package com.epam.ta.reportportal.core.item.impl.provider;
 
-import javax.annotation.Nullable;
 import java.util.Arrays;
 import java.util.Optional;
+import javax.annotation.Nullable;
 
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
  */
 public enum DataProviderType {
 
-	WIDGET_BASED("widget"),
-	LAUNCH_BASED("launch"),
-	FILTER_BASED("filter"),
-	CLUSTER_BASED("cluster"),
-	BASELINE_BASED("baseline");
+  WIDGET_BASED("widget"),
+  LAUNCH_BASED("launch"),
+  FILTER_BASED("filter"),
+  CLUSTER_BASED("cluster"),
+  BASELINE_BASED("baseline");
 
-	private final String type;
+  private final String type;
 
-	DataProviderType(String type) {
-		this.type = type;
-	}
+  DataProviderType(String type) {
+    this.type = type;
+  }
 
-	public String getType() {
-		return this.type;
-	}
+  public String getType() {
+    return this.type;
+  }
 
-	public static Optional<DataProviderType> findByName(@Nullable String name) {
-		return Arrays.stream(DataProviderType.values()).filter(type -> type.getType().equalsIgnoreCase(name)).findAny();
-	}
+  public static Optional<DataProviderType> findByName(@Nullable String name) {
+    return Arrays.stream(DataProviderType.values())
+        .filter(type -> type.getType().equalsIgnoreCase(name)).findAny();
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/provider/ProviderTypeConfig.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/provider/ProviderTypeConfig.java
index ccd682c3db..67e25422b2 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/provider/ProviderTypeConfig.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/provider/ProviderTypeConfig.java
@@ -16,9 +16,14 @@
 
 package com.epam.ta.reportportal.core.item.impl.provider;
 
-import com.epam.ta.reportportal.core.item.impl.provider.impl.*;
+import com.epam.ta.reportportal.core.item.impl.provider.impl.BaselineLaunchDataProvider;
+import com.epam.ta.reportportal.core.item.impl.provider.impl.CumulativeTestItemDataProviderImpl;
+import com.epam.ta.reportportal.core.item.impl.provider.impl.DelegatingClusterDataProviderHandler;
+import com.epam.ta.reportportal.core.item.impl.provider.impl.LaunchDataProviderHandlerImpl;
+import com.epam.ta.reportportal.core.item.impl.provider.impl.MaterializedWidgetProviderHandlerImpl;
 import com.epam.ta.reportportal.entity.widget.WidgetType;
 import com.google.common.collect.ImmutableMap;
+import java.util.Map;
 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
@@ -26,44 +31,48 @@
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
-import java.util.Map;
-
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
  */
 @Configuration
 public class ProviderTypeConfig {
 
-	private ApplicationContext applicationContext;
+  private ApplicationContext applicationContext;
 
-	@Autowired
-	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
-		this.applicationContext = applicationContext;
-	}
+  @Autowired
+  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+    this.applicationContext = applicationContext;
+  }
 
-	@Bean
-	public DelegatingClusterDataProviderHandler delegatingClusterDataProviderHandler(
-			@Value("${rp.environment.variable.cluster.item.page-size}") Integer maxPageSize,
-			@Autowired LaunchDataProviderHandlerImpl launchDataProviderHandler) {
-		return new DelegatingClusterDataProviderHandler(maxPageSize, launchDataProviderHandler);
-	}
+  @Bean
+  public DelegatingClusterDataProviderHandler delegatingClusterDataProviderHandler(
+      @Value("${rp.environment.variable.cluster.item.page-size}") Integer maxPageSize,
+      @Autowired LaunchDataProviderHandlerImpl launchDataProviderHandler) {
+    return new DelegatingClusterDataProviderHandler(maxPageSize, launchDataProviderHandler);
+  }
 
-	@Bean("testItemDataProviders")
-	public Map<DataProviderType, DataProviderHandler> testItemDataProviders() {
-		return ImmutableMap.<DataProviderType, DataProviderHandler>builder()
-				.put(DataProviderType.WIDGET_BASED, applicationContext.getBean(MaterializedWidgetProviderHandlerImpl.class))
-				.put(DataProviderType.LAUNCH_BASED, applicationContext.getBean(LaunchDataProviderHandlerImpl.class))
-				.put(DataProviderType.FILTER_BASED, applicationContext.getBean(FilterDataProviderImpl.class))
-				.put(DataProviderType.CLUSTER_BASED,applicationContext.getBean(DelegatingClusterDataProviderHandler.class))
-				.put(DataProviderType.BASELINE_BASED,applicationContext.getBean(BaselineLaunchDataProvider.class))
-				.build();
-	}
+  @Bean("testItemDataProviders")
+  public Map<DataProviderType, DataProviderHandler> testItemDataProviders() {
+    return ImmutableMap.<DataProviderType, DataProviderHandler>builder()
+        .put(DataProviderType.WIDGET_BASED,
+            applicationContext.getBean(MaterializedWidgetProviderHandlerImpl.class))
+        .put(DataProviderType.LAUNCH_BASED,
+            applicationContext.getBean(LaunchDataProviderHandlerImpl.class))
+        .put(DataProviderType.FILTER_BASED,
+            applicationContext.getBean(FilterDataProviderImpl.class))
+        .put(DataProviderType.CLUSTER_BASED,
+            applicationContext.getBean(DelegatingClusterDataProviderHandler.class))
+        .put(DataProviderType.BASELINE_BASED,
+            applicationContext.getBean(BaselineLaunchDataProvider.class))
+        .build();
+  }
 
-	@Bean("testItemWidgetDataProviders")
-	public Map<WidgetType, DataProviderHandler> testItemWidgetDataProviders() {
-		return ImmutableMap.<WidgetType, DataProviderHandler>builder()
-				.put(WidgetType.CUMULATIVE, applicationContext.getBean(CumulativeTestItemDataProviderImpl.class))
-				.build();
-	}
+  @Bean("testItemWidgetDataProviders")
+  public Map<WidgetType, DataProviderHandler> testItemWidgetDataProviders() {
+    return ImmutableMap.<WidgetType, DataProviderHandler>builder()
+        .put(WidgetType.CUMULATIVE,
+            applicationContext.getBean(CumulativeTestItemDataProviderImpl.class))
+        .build();
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/provider/impl/BaselineLaunchDataProvider.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/provider/impl/BaselineLaunchDataProvider.java
index 8a68e550f4..1173a2da6f 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/provider/impl/BaselineLaunchDataProvider.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/provider/impl/BaselineLaunchDataProvider.java
@@ -16,8 +16,13 @@
 
 package com.epam.ta.reportportal.core.item.impl.provider.impl;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_LAUNCH_ID;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
-import com.epam.ta.reportportal.commons.querygen.*;
+import com.epam.ta.reportportal.commons.querygen.CompositeFilter;
+import com.epam.ta.reportportal.commons.querygen.Filter;
+import com.epam.ta.reportportal.commons.querygen.FilterCondition;
+import com.epam.ta.reportportal.commons.querygen.Queryable;
 import com.epam.ta.reportportal.core.item.impl.LaunchAccessValidator;
 import com.epam.ta.reportportal.core.item.impl.filter.updater.FilterUpdater;
 import com.epam.ta.reportportal.core.item.impl.provider.DataProviderHandler;
@@ -27,82 +32,89 @@
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.util.ControllerUtils;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
 import org.jooq.Operator;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
 
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_LAUNCH_ID;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class BaselineLaunchDataProvider implements DataProviderHandler {
-	private static final String LAUNCH_ID_PARAM = "launchId";
-	private static final String BASELINE_LAUNCH_ID_PARAM = "baselineLaunchId";
 
-	private final LaunchAccessValidator launchAccessValidator;
-	private final TestItemRepository testItemRepository;
-	private final FilterUpdater filterUpdater;
+  private static final String LAUNCH_ID_PARAM = "launchId";
+  private static final String BASELINE_LAUNCH_ID_PARAM = "baselineLaunchId";
+
+  private final LaunchAccessValidator launchAccessValidator;
+  private final TestItemRepository testItemRepository;
+  private final FilterUpdater filterUpdater;
 
-	@Autowired
-	public BaselineLaunchDataProvider(LaunchAccessValidator launchAccessValidator, TestItemRepository testItemRepository,
-			FilterUpdater filterUpdater) {
-		this.launchAccessValidator = launchAccessValidator;
-		this.testItemRepository = testItemRepository;
-		this.filterUpdater = filterUpdater;
-	}
+  @Autowired
+  public BaselineLaunchDataProvider(LaunchAccessValidator launchAccessValidator,
+      TestItemRepository testItemRepository,
+      FilterUpdater filterUpdater) {
+    this.launchAccessValidator = launchAccessValidator;
+    this.testItemRepository = testItemRepository;
+    this.filterUpdater = filterUpdater;
+  }
 
-	@Override
-	public Page<TestItem> getTestItems(Queryable filter, Pageable pageable, ReportPortalUser.ProjectDetails projectDetails,
-			ReportPortalUser user, Map<String, String> params) {
-		final Queryable targetFilter = getLaunchIdFilter(LAUNCH_ID_PARAM, params, projectDetails, user);
-		final Queryable baselineFilter = getLaunchIdFilter(BASELINE_LAUNCH_ID_PARAM, params, projectDetails, user);
-		filterUpdater.update(filter);
+  @Override
+  public Page<TestItem> getTestItems(Queryable filter, Pageable pageable,
+      ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user, Map<String, String> params) {
+    final Queryable targetFilter = getLaunchIdFilter(LAUNCH_ID_PARAM, params, projectDetails, user);
+    final Queryable baselineFilter = getLaunchIdFilter(BASELINE_LAUNCH_ID_PARAM, params,
+        projectDetails, user);
+    filterUpdater.update(filter);
 
-		return testItemRepository.findAllNotFromBaseline(joinFilters(targetFilter, filter), joinFilters(baselineFilter, filter), pageable);
-	}
+    return testItemRepository.findAllNotFromBaseline(joinFilters(targetFilter, filter),
+        joinFilters(baselineFilter, filter), pageable);
+  }
 
-	@Override
-	public Set<Statistics> accumulateStatistics(Queryable filter, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user,
-			Map<String, String> params) {
-		final Queryable targetFilter = getLaunchIdFilter(LAUNCH_ID_PARAM, params, projectDetails, user);
-		final Queryable baselineFilter = getLaunchIdFilter(BASELINE_LAUNCH_ID_PARAM, params, projectDetails, user);
-		filterUpdater.update(filter);
-		return testItemRepository.accumulateStatisticsByFilterNotFromBaseline(joinFilters(targetFilter, filter),
-				joinFilters(baselineFilter, filter)
-		);
-	}
+  @Override
+  public Set<Statistics> accumulateStatistics(Queryable filter,
+      ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user,
+      Map<String, String> params) {
+    final Queryable targetFilter = getLaunchIdFilter(LAUNCH_ID_PARAM, params, projectDetails, user);
+    final Queryable baselineFilter = getLaunchIdFilter(BASELINE_LAUNCH_ID_PARAM, params,
+        projectDetails, user);
+    filterUpdater.update(filter);
+    return testItemRepository.accumulateStatisticsByFilterNotFromBaseline(
+        joinFilters(targetFilter, filter),
+        joinFilters(baselineFilter, filter)
+    );
+  }
 
-	private Queryable getLaunchIdFilter(String key, Map<String, String> params, ReportPortalUser.ProjectDetails projectDetails,
-			ReportPortalUser user) {
-		final Long launchId = getLaunchId(key, params);
-		launchAccessValidator.validate(launchId, projectDetails, user);
-		return getLaunchIdFilter(launchId);
-	}
+  private Queryable getLaunchIdFilter(String key, Map<String, String> params,
+      ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user) {
+    final Long launchId = getLaunchId(key, params);
+    launchAccessValidator.validate(launchId, projectDetails, user);
+    return getLaunchIdFilter(launchId);
+  }
 
-	private Long getLaunchId(String key, Map<String, String> params) {
-		return Optional.ofNullable(params.get(key))
-				.map(ControllerUtils::safeParseLong)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR,
-						"Launch id must be provided for baseline items provider"
-				));
-	}
+  private Long getLaunchId(String key, Map<String, String> params) {
+    return Optional.ofNullable(params.get(key))
+        .map(ControllerUtils::safeParseLong)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR,
+            "Launch id must be provided for baseline items provider"
+        ));
+  }
 
-	private Queryable getLaunchIdFilter(Long launchId) {
-		return Filter.builder()
-				.withTarget(TestItem.class)
-				.withCondition(FilterCondition.builder().eq(CRITERIA_LAUNCH_ID, String.valueOf(launchId)).build())
-				.build();
-	}
+  private Queryable getLaunchIdFilter(Long launchId) {
+    return Filter.builder()
+        .withTarget(TestItem.class)
+        .withCondition(
+            FilterCondition.builder().eq(CRITERIA_LAUNCH_ID, String.valueOf(launchId)).build())
+        .build();
+  }
 
-	private Queryable joinFilters(Queryable... filters) {
-		return new CompositeFilter(Operator.AND, filters);
-	}
+  private Queryable joinFilters(Queryable... filters) {
+    return new CompositeFilter(Operator.AND, filters);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/provider/impl/CumulativeTestItemDataProviderImpl.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/provider/impl/CumulativeTestItemDataProviderImpl.java
index 26051b8572..8b06c0881c 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/provider/impl/CumulativeTestItemDataProviderImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/provider/impl/CumulativeTestItemDataProviderImpl.java
@@ -16,8 +16,17 @@
 
 package com.epam.ta.reportportal.core.item.impl.provider.impl;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_LAUNCH_ID;
+import static com.epam.ta.reportportal.commons.querygen.constant.ItemAttributeConstant.CRITERIA_LEVEL_ATTRIBUTE;
+import static com.epam.ta.reportportal.core.widget.content.loader.materialized.handler.MaterializedWidgetStateHandler.VIEW_NAME;
+import static com.epam.ta.reportportal.ws.resolver.FilterCriteriaResolver.DEFAULT_FILTER_PREFIX;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
-import com.epam.ta.reportportal.commons.querygen.*;
+import com.epam.ta.reportportal.commons.querygen.CompositeFilter;
+import com.epam.ta.reportportal.commons.querygen.Condition;
+import com.epam.ta.reportportal.commons.querygen.Filter;
+import com.epam.ta.reportportal.commons.querygen.FilterCondition;
+import com.epam.ta.reportportal.commons.querygen.Queryable;
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.core.item.impl.provider.DataProviderHandler;
 import com.epam.ta.reportportal.dao.TestItemRepository;
@@ -25,6 +34,9 @@
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.statistics.Statistics;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 import org.apache.commons.collections4.CollectionUtils;
 import org.jooq.Operator;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -33,56 +45,53 @@
 import org.springframework.stereotype.Component;
 import org.springframework.util.StringUtils;
 
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_LAUNCH_ID;
-import static com.epam.ta.reportportal.commons.querygen.constant.ItemAttributeConstant.CRITERIA_LEVEL_ATTRIBUTE;
-import static com.epam.ta.reportportal.core.widget.content.loader.materialized.handler.MaterializedWidgetStateHandler.VIEW_NAME;
-import static com.epam.ta.reportportal.ws.resolver.FilterCriteriaResolver.DEFAULT_FILTER_PREFIX;
-
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
  */
 @Component
 public class CumulativeTestItemDataProviderImpl implements DataProviderHandler {
 
-	@Autowired
-	private WidgetContentRepository widgetContentRepository;
+  @Autowired
+  private WidgetContentRepository widgetContentRepository;
 
-	@Autowired
-	private TestItemRepository testItemRepository;
+  @Autowired
+  private TestItemRepository testItemRepository;
 
-	@Override
-	public Page<TestItem> getTestItems(Queryable filter, Pageable pageable, ReportPortalUser.ProjectDetails projectDetails,
-			ReportPortalUser user, Map<String, String> params) {
-		filter = updateFilter(filter, params);
-		return testItemRepository.findByFilter(filter, pageable);
+  @Override
+  public Page<TestItem> getTestItems(Queryable filter, Pageable pageable,
+      ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user, Map<String, String> params) {
+    filter = updateFilter(filter, params);
+    return testItemRepository.findByFilter(filter, pageable);
 
-	}
+  }
 
-	@Override
-	public Set<Statistics> accumulateStatistics(Queryable filter, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user,
-			Map<String, String> params) {
-		filter = updateFilter(filter, params);
-		return testItemRepository.accumulateStatisticsByFilter(filter);
-	}
+  @Override
+  public Set<Statistics> accumulateStatistics(Queryable filter,
+      ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user,
+      Map<String, String> params) {
+    filter = updateFilter(filter, params);
+    return testItemRepository.accumulateStatisticsByFilter(filter);
+  }
 
-	public Queryable updateFilter(Queryable filter, Map<String, String> providerParams) {
-		String compositeAttribute = providerParams.get(DEFAULT_FILTER_PREFIX + Condition.HAS_FILTER + CRITERIA_LEVEL_ATTRIBUTE);
-		BusinessRule.expect(compositeAttribute, it -> !StringUtils.isEmpty(it))
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Level attributes must be provided for widget based items provider");
-		List<Long> redirectLaunchIds = widgetContentRepository.getCumulativeLevelRedirectLaunchIds(providerParams.get(VIEW_NAME),
-				compositeAttribute
-		);
-		if (CollectionUtils.isNotEmpty(redirectLaunchIds)) {
-			Queryable launchesBasedFilter = Filter.builder()
-					.withTarget(TestItem.class)
-					.withCondition(FilterCondition.builder().in(CRITERIA_LAUNCH_ID, redirectLaunchIds).build())
-					.build();
-			return new CompositeFilter(Operator.AND, filter, launchesBasedFilter);
-		}
-		return filter;
-	}
+  public Queryable updateFilter(Queryable filter, Map<String, String> providerParams) {
+    String compositeAttribute = providerParams.get(
+        DEFAULT_FILTER_PREFIX + Condition.HAS_FILTER + CRITERIA_LEVEL_ATTRIBUTE);
+    BusinessRule.expect(compositeAttribute, it -> !StringUtils.isEmpty(it))
+        .verify(ErrorType.BAD_REQUEST_ERROR,
+            "Level attributes must be provided for widget based items provider");
+    List<Long> redirectLaunchIds = widgetContentRepository.getCumulativeLevelRedirectLaunchIds(
+        providerParams.get(VIEW_NAME),
+        compositeAttribute
+    );
+    if (CollectionUtils.isNotEmpty(redirectLaunchIds)) {
+      Queryable launchesBasedFilter = Filter.builder()
+          .withTarget(TestItem.class)
+          .withCondition(
+              FilterCondition.builder().in(CRITERIA_LAUNCH_ID, redirectLaunchIds).build())
+          .build();
+      return new CompositeFilter(Operator.AND, filter, launchesBasedFilter);
+    }
+    return filter;
+  }
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/provider/impl/DelegatingClusterDataProviderHandler.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/provider/impl/DelegatingClusterDataProviderHandler.java
index 58bbeefee9..d05d1ff697 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/provider/impl/DelegatingClusterDataProviderHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/provider/impl/DelegatingClusterDataProviderHandler.java
@@ -23,54 +23,56 @@
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.statistics.Statistics;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.Map;
+import java.util.Set;
 import org.apache.commons.lang3.BooleanUtils;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 
-import java.util.Map;
-import java.util.Set;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public class DelegatingClusterDataProviderHandler implements DataProviderHandler {
 
-	public static final String CLUSTER_ID_PARAM = "clusterId";
+  public static final String CLUSTER_ID_PARAM = "clusterId";
 
-	private final Integer maxPageSize;
-	private final DataProviderHandler delegate;
+  private final Integer maxPageSize;
+  private final DataProviderHandler delegate;
 
-	public DelegatingClusterDataProviderHandler(Integer maxPageSize, DataProviderHandler dataProviderHandler) {
-		this.maxPageSize = maxPageSize;
-		this.delegate = dataProviderHandler;
-	}
+  public DelegatingClusterDataProviderHandler(Integer maxPageSize,
+      DataProviderHandler dataProviderHandler) {
+    this.maxPageSize = maxPageSize;
+    this.delegate = dataProviderHandler;
+  }
 
-	@Override
-	public Page<TestItem> getTestItems(Queryable filter, Pageable pageable, ReportPortalUser.ProjectDetails projectDetails,
-			ReportPortalUser user, Map<String, String> params) {
-		validateClusterCondition(filter);
-		validatePageSize(pageable);
-		return delegate.getTestItems(filter, pageable, projectDetails, user, params);
-	}
+  @Override
+  public Page<TestItem> getTestItems(Queryable filter, Pageable pageable,
+      ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user, Map<String, String> params) {
+    validateClusterCondition(filter);
+    validatePageSize(pageable);
+    return delegate.getTestItems(filter, pageable, projectDetails, user, params);
+  }
 
-	@Override
-	public Set<Statistics> accumulateStatistics(Queryable filter, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user,
-			Map<String, String> params) {
-		validateClusterCondition(filter);
-		return delegate.accumulateStatistics(filter, projectDetails, user, params);
-	}
+  @Override
+  public Set<Statistics> accumulateStatistics(Queryable filter,
+      ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user,
+      Map<String, String> params) {
+    validateClusterCondition(filter);
+    return delegate.accumulateStatistics(filter, projectDetails, user, params);
+  }
 
-	private void validateClusterCondition(Queryable filter) {
-		final boolean hasClusterIdCondition = filter.getFilterConditions()
-				.stream()
-				.flatMap(c -> c.getAllConditions().stream())
-				.anyMatch(c -> c.getSearchCriteria().contains(CLUSTER_ID_PARAM));
-		BusinessRule.expect(hasClusterIdCondition, BooleanUtils::isTrue)
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Cluster id condition not provided");
-	}
+  private void validateClusterCondition(Queryable filter) {
+    final boolean hasClusterIdCondition = filter.getFilterConditions()
+        .stream()
+        .flatMap(c -> c.getAllConditions().stream())
+        .anyMatch(c -> c.getSearchCriteria().contains(CLUSTER_ID_PARAM));
+    BusinessRule.expect(hasClusterIdCondition, BooleanUtils::isTrue)
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Cluster id condition not provided");
+  }
 
-	private void validatePageSize(Pageable pageable) {
-		BusinessRule.expect(pageable.getPageSize(), pageSize -> pageSize <= maxPageSize)
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Max page size: " + maxPageSize);
-	}
+  private void validatePageSize(Pageable pageable) {
+    BusinessRule.expect(pageable.getPageSize(), pageSize -> pageSize <= maxPageSize)
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Max page size: " + maxPageSize);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/provider/impl/LaunchDataProviderHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/provider/impl/LaunchDataProviderHandlerImpl.java
index 52a71ffdd7..c3eb72781d 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/provider/impl/LaunchDataProviderHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/provider/impl/LaunchDataProviderHandlerImpl.java
@@ -16,6 +16,8 @@
 
 package com.epam.ta.reportportal.core.item.impl.provider.impl;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_LAUNCH_ID;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.querygen.CompositeFilter;
 import com.epam.ta.reportportal.commons.querygen.Filter;
@@ -30,64 +32,65 @@
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.util.ControllerUtils;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
 import org.jooq.Operator;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Component;
 
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_LAUNCH_ID;
-
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
  */
 @Component
 public class LaunchDataProviderHandlerImpl implements DataProviderHandler {
 
-	private static final String LAUNCH_ID_PARAM = "launchId";
+  private static final String LAUNCH_ID_PARAM = "launchId";
 
-	@Autowired
-	private LaunchAccessValidator launchAccessValidator;
+  @Autowired
+  private LaunchAccessValidator launchAccessValidator;
 
-	@Autowired
-	private TestItemRepository testItemRepository;
+  @Autowired
+  private TestItemRepository testItemRepository;
 
-	@Autowired
-	private FilterUpdater filterUpdater;
+  @Autowired
+  private FilterUpdater filterUpdater;
 
-	@Override
-	public Page<TestItem> getTestItems(Queryable filter, Pageable pageable, ReportPortalUser.ProjectDetails projectDetails,
-			ReportPortalUser user, Map<String, String> params) {
-		filter = updateFilter(filter, projectDetails, user, params);
-		return testItemRepository.findByFilter(filter, pageable);
-	}
+  @Override
+  public Page<TestItem> getTestItems(Queryable filter, Pageable pageable,
+      ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user, Map<String, String> params) {
+    filter = updateFilter(filter, projectDetails, user, params);
+    return testItemRepository.findByFilter(filter, pageable);
+  }
 
-	@Override
-	public Set<Statistics> accumulateStatistics(Queryable filter, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user,
-			Map<String, String> params) {
-		filter = updateFilter(filter, projectDetails, user, params);
-		return testItemRepository.accumulateStatisticsByFilter(filter);
-	}
+  @Override
+  public Set<Statistics> accumulateStatistics(Queryable filter,
+      ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user,
+      Map<String, String> params) {
+    filter = updateFilter(filter, projectDetails, user, params);
+    return testItemRepository.accumulateStatisticsByFilter(filter);
+  }
 
-	private Queryable updateFilter(Queryable filter, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user,
-			Map<String, String> params) {
-		Long launchId = Optional.ofNullable(params.get(LAUNCH_ID_PARAM))
-				.map(ControllerUtils::safeParseLong)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR,
-						"Launch id must be provided for launch based items provider"
-				));
-		launchAccessValidator.validate(launchId, projectDetails, user);
-		Queryable launchBasedFilter = Filter.builder()
-				.withTarget(TestItem.class)
-				.withCondition(FilterCondition.builder().eq(CRITERIA_LAUNCH_ID, String.valueOf(launchId)).build())
-				.build();
+  private Queryable updateFilter(Queryable filter, ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user,
+      Map<String, String> params) {
+    Long launchId = Optional.ofNullable(params.get(LAUNCH_ID_PARAM))
+        .map(ControllerUtils::safeParseLong)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR,
+            "Launch id must be provided for launch based items provider"
+        ));
+    launchAccessValidator.validate(launchId, projectDetails, user);
+    Queryable launchBasedFilter = Filter.builder()
+        .withTarget(TestItem.class)
+        .withCondition(
+            FilterCondition.builder().eq(CRITERIA_LAUNCH_ID, String.valueOf(launchId)).build())
+        .build();
 
-		filterUpdater.update(filter);
+    filterUpdater.update(filter);
 
-		return new CompositeFilter(Operator.AND, filter, launchBasedFilter);
-	}
+    return new CompositeFilter(Operator.AND, filter, launchBasedFilter);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/rerun/RerunSearcher.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/rerun/RerunSearcher.java
index 1d58955f60..4567eec46a 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/rerun/RerunSearcher.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/rerun/RerunSearcher.java
@@ -1,9 +1,9 @@
 package com.epam.ta.reportportal.core.item.impl.rerun;
 
 import com.epam.ta.reportportal.commons.querygen.Queryable;
-
 import java.util.Optional;
 
 public interface RerunSearcher {
-	Optional<Long> findItem(Queryable filter);
+
+  Optional<Long> findItem(Queryable filter);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/rerun/RerunSearcherImpl.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/rerun/RerunSearcherImpl.java
index ecba145523..4a7a5bf3de 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/rerun/RerunSearcherImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/rerun/RerunSearcherImpl.java
@@ -1,25 +1,24 @@
 package com.epam.ta.reportportal.core.item.impl.rerun;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_START_TIME;
+
 import com.epam.ta.reportportal.commons.querygen.Queryable;
 import com.epam.ta.reportportal.dao.TestItemRepository;
+import java.util.Optional;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.Optional;
-
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_START_TIME;
-
 @Service
 public class RerunSearcherImpl implements RerunSearcher {
 
-	private final TestItemRepository testItemRepository;
+  private final TestItemRepository testItemRepository;
 
-	public RerunSearcherImpl(TestItemRepository testItemRepository) {
-		this.testItemRepository = testItemRepository;
-	}
+  public RerunSearcherImpl(TestItemRepository testItemRepository) {
+    this.testItemRepository = testItemRepository;
+  }
 
-	@Override
-	public Optional<Long> findItem(Queryable filter) {
-		return testItemRepository.findIdByFilter(filter, Sort.by(Sort.Order.desc(CRITERIA_START_TIME)));
-	}
+  @Override
+  public Optional<Long> findItem(Queryable filter) {
+    return testItemRepository.findIdByFilter(filter, Sort.by(Sort.Order.desc(CRITERIA_START_TIME)));
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/retry/DefaultRetryHandler.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/retry/DefaultRetryHandler.java
index 96b07a0d7d..cdfd718ca6 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/retry/DefaultRetryHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/retry/DefaultRetryHandler.java
@@ -8,11 +8,10 @@
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.jooq.enums.JStatusEnum;
 import com.epam.ta.reportportal.ws.model.ErrorType;
-import org.springframework.context.ApplicationEventPublisher;
-import org.springframework.stereotype.Service;
-
 import java.time.LocalDateTime;
 import java.util.Objects;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -20,56 +19,59 @@
 @Service
 public class DefaultRetryHandler implements RetryHandler {
 
-	private final TestItemRepository testItemRepository;
-	private final LaunchRepository launchRepository;
-	private final ApplicationEventPublisher eventPublisher;
+  private final TestItemRepository testItemRepository;
+  private final LaunchRepository launchRepository;
+  private final ApplicationEventPublisher eventPublisher;
 
-	public DefaultRetryHandler(TestItemRepository testItemRepository, LaunchRepository launchRepository,
-			ApplicationEventPublisher eventPublisher) {
-		this.testItemRepository = testItemRepository;
-		this.launchRepository = launchRepository;
-		this.eventPublisher = eventPublisher;
-	}
+  public DefaultRetryHandler(TestItemRepository testItemRepository,
+      LaunchRepository launchRepository,
+      ApplicationEventPublisher eventPublisher) {
+    this.testItemRepository = testItemRepository;
+    this.launchRepository = launchRepository;
+    this.eventPublisher = eventPublisher;
+  }
 
-	@Override
-	public void handleRetries(Launch launch, TestItem newRetryParent, Long previousParent) {
-		handleRetries(launch, previousParent, newRetryParent);
-		eventPublisher.publishEvent(ItemRetryEvent.of(launch.getProjectId(), launch.getId(), newRetryParent.getItemId()));
-	}
+  @Override
+  public void handleRetries(Launch launch, TestItem newRetryParent, Long previousParent) {
+    handleRetries(launch, previousParent, newRetryParent);
+    eventPublisher.publishEvent(
+        ItemRetryEvent.of(launch.getProjectId(), launch.getId(), newRetryParent.getItemId()));
+  }
 
-	@Override
-	public void finishRetries(Long retryParentId, JStatusEnum status, LocalDateTime endTime) {
-		testItemRepository.updateStatusAndEndTimeByRetryOfId(retryParentId,
-				JStatusEnum.IN_PROGRESS,
-				JStatusEnum.valueOf(status.name()),
-				endTime
-		);
-	}
+  @Override
+  public void finishRetries(Long retryParentId, JStatusEnum status, LocalDateTime endTime) {
+    testItemRepository.updateStatusAndEndTimeByRetryOfId(retryParentId,
+        JStatusEnum.IN_PROGRESS,
+        JStatusEnum.valueOf(status.name()),
+        endTime
+    );
+  }
 
-	/**
-	 * Handles retry items with new explicitly provided parent
-	 *
-	 * @param launch         {@link Launch}
-	 * @param retryParent    {@link TestItem#getItemId()}
-	 * @param newRetryParent {@link TestItem}
-	 */
-	private void handleRetries(Launch launch, Long retryParent, TestItem newRetryParent) {
-		validateNewParent(retryParent, newRetryParent);
-		testItemRepository.handleRetry(retryParent, newRetryParent.getItemId());
-		updateLaunchRetriesState(launch);
-	}
+  /**
+   * Handles retry items with new explicitly provided parent
+   *
+   * @param launch         {@link Launch}
+   * @param retryParent    {@link TestItem#getItemId()}
+   * @param newRetryParent {@link TestItem}
+   */
+  private void handleRetries(Launch launch, Long retryParent, TestItem newRetryParent) {
+    validateNewParent(retryParent, newRetryParent);
+    testItemRepository.handleRetry(retryParent, newRetryParent.getItemId());
+    updateLaunchRetriesState(launch);
+  }
 
-	private void validateNewParent(Long prevRetryParent, TestItem newRetryParent) {
-		BusinessRule.expect(newRetryParent, i -> !i.getItemId().equals(prevRetryParent))
-				.verify(ErrorType.RETRIES_HANDLER_ERROR, "Previous and new parent 'id' should not be equal");
-		BusinessRule.expect(newRetryParent, i -> Objects.isNull(i.getRetryOf()))
-				.verify(ErrorType.RETRIES_HANDLER_ERROR, "Parent item should not be a retry");
-	}
+  private void validateNewParent(Long prevRetryParent, TestItem newRetryParent) {
+    BusinessRule.expect(newRetryParent, i -> !i.getItemId().equals(prevRetryParent))
+        .verify(ErrorType.RETRIES_HANDLER_ERROR,
+            "Previous and new parent 'id' should not be equal");
+    BusinessRule.expect(newRetryParent, i -> Objects.isNull(i.getRetryOf()))
+        .verify(ErrorType.RETRIES_HANDLER_ERROR, "Parent item should not be a retry");
+  }
 
-	private void updateLaunchRetriesState(Launch launch) {
-		if (!launch.isHasRetries()) {
-			launch.setHasRetries(launchRepository.hasRetries(launch.getId()));
-		}
-	}
+  private void updateLaunchRetriesState(Launch launch) {
+    if (!launch.isHasRetries()) {
+      launch.setHasRetries(launchRepository.hasRetries(launch.getId()));
+    }
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/retry/RetryHandler.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/retry/RetryHandler.java
index f8345e3571..614e52348e 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/retry/RetryHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/retry/RetryHandler.java
@@ -3,7 +3,6 @@
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.jooq.enums.JStatusEnum;
-
 import java.time.LocalDateTime;
 
 /**
@@ -11,7 +10,7 @@
  */
 public interface RetryHandler {
 
-	void handleRetries(Launch launch, TestItem newRetryParent, Long previousParent);
+  void handleRetries(Launch launch, TestItem newRetryParent, Long previousParent);
 
-	void finishRetries(Long retryParentId, JStatusEnum status, LocalDateTime endTime);
+  void finishRetries(Long retryParentId, JStatusEnum status, LocalDateTime endTime);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/retry/RetrySearcher.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/retry/RetrySearcher.java
index f8fee5a0a4..f81d7d8dfd 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/retry/RetrySearcher.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/retry/RetrySearcher.java
@@ -2,11 +2,10 @@
 
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.launch.Launch;
-
 import java.util.Optional;
 
 public interface RetrySearcher {
 
-	Optional<Long> findPreviousRetry(Launch launch, TestItem newItem, TestItem parentItem);
+  Optional<Long> findPreviousRetry(Launch launch, TestItem newItem, TestItem parentItem);
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/retry/UniqueIdRetrySearcher.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/retry/UniqueIdRetrySearcher.java
index e875439180..74b79c555d 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/retry/UniqueIdRetrySearcher.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/retry/UniqueIdRetrySearcher.java
@@ -1,16 +1,15 @@
 package com.epam.ta.reportportal.core.item.impl.retry;
 
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.core.item.identity.IdentityUtil;
 import com.epam.ta.reportportal.core.item.identity.UniqueIdGenerator;
 import com.epam.ta.reportportal.dao.TestItemRepository;
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.launch.Launch;
-import org.springframework.stereotype.Service;
-
 import java.util.Objects;
 import java.util.Optional;
-
-import static java.util.Optional.ofNullable;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -18,28 +17,32 @@
 @Service("uniqueIdRetrySearcher")
 public class UniqueIdRetrySearcher implements RetrySearcher {
 
-	private final UniqueIdGenerator uniqueIdGenerator;
-	private final TestItemRepository testItemRepository;
+  private final UniqueIdGenerator uniqueIdGenerator;
+  private final TestItemRepository testItemRepository;
 
-	public UniqueIdRetrySearcher(UniqueIdGenerator uniqueIdGenerator, TestItemRepository testItemRepository) {
-		this.uniqueIdGenerator = uniqueIdGenerator;
-		this.testItemRepository = testItemRepository;
-	}
+  public UniqueIdRetrySearcher(UniqueIdGenerator uniqueIdGenerator,
+      TestItemRepository testItemRepository) {
+    this.uniqueIdGenerator = uniqueIdGenerator;
+    this.testItemRepository = testItemRepository;
+  }
 
-	@Override
-	public Optional<Long> findPreviousRetry(Launch launch, TestItem newItem, TestItem parentItem) {
-		if (Objects.isNull(newItem.getUniqueId())) {
-			newItem.setUniqueId(uniqueIdGenerator.generate(newItem, IdentityUtil.getItemTreeIds(parentItem), launch));
-		}
-		return ofNullable(newItem.getItemId()).map(itemId -> testItemRepository.findLatestIdByUniqueIdAndLaunchIdAndParentIdAndItemIdNotEqual(
-				newItem.getUniqueId(),
-				launch.getId(),
-				parentItem.getItemId(),
-				itemId
-		))
-				.orElseGet(() -> testItemRepository.findLatestIdByUniqueIdAndLaunchIdAndParentId(newItem.getUniqueId(),
-						launch.getId(),
-						parentItem.getItemId()
-				));
-	}
+  @Override
+  public Optional<Long> findPreviousRetry(Launch launch, TestItem newItem, TestItem parentItem) {
+    if (Objects.isNull(newItem.getUniqueId())) {
+      newItem.setUniqueId(
+          uniqueIdGenerator.generate(newItem, IdentityUtil.getItemTreeIds(parentItem), launch));
+    }
+    return ofNullable(newItem.getItemId()).map(
+            itemId -> testItemRepository.findLatestIdByUniqueIdAndLaunchIdAndParentIdAndItemIdNotEqual(
+                newItem.getUniqueId(),
+                launch.getId(),
+                parentItem.getItemId(),
+                itemId
+            ))
+        .orElseGet(() -> testItemRepository.findLatestIdByUniqueIdAndLaunchIdAndParentId(
+            newItem.getUniqueId(),
+            launch.getId(),
+            parentItem.getItemId()
+        ));
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/status/AbstractStatusChangingStrategy.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/status/AbstractStatusChangingStrategy.java
index f59ce34cea..0fe5d2600f 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/status/AbstractStatusChangingStrategy.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/status/AbstractStatusChangingStrategy.java
@@ -16,6 +16,17 @@
 
 package com.epam.ta.reportportal.core.item.impl.status;
 
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.FAILED;
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.INFO;
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.IN_PROGRESS;
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.PASSED;
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.WARN;
+import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.TO_INVESTIGATE;
+import static com.epam.ta.reportportal.ws.converter.converters.TestItemConverter.TO_ACTIVITY_RESOURCE;
+import static com.epam.ta.reportportal.ws.model.ErrorType.INCORRECT_REQUEST;
+import static com.epam.ta.reportportal.ws.model.ErrorType.PROJECT_NOT_FOUND;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.commons.validation.Suppliers;
@@ -24,7 +35,11 @@
 import com.epam.ta.reportportal.core.events.activity.item.TestItemStatusChangedEvent;
 import com.epam.ta.reportportal.core.item.TestItemService;
 import com.epam.ta.reportportal.core.item.impl.IssueTypeHandler;
-import com.epam.ta.reportportal.dao.*;
+import com.epam.ta.reportportal.dao.IssueEntityRepository;
+import com.epam.ta.reportportal.dao.LaunchRepository;
+import com.epam.ta.reportportal.dao.LogRepository;
+import com.epam.ta.reportportal.dao.ProjectRepository;
+import com.epam.ta.reportportal.dao.TestItemRepository;
 import com.epam.ta.reportportal.entity.enums.StatusEnum;
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.item.issue.IssueEntity;
@@ -35,147 +50,150 @@
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.epam.ta.reportportal.ws.model.activity.TestItemActivityResource;
 import com.google.common.collect.Lists;
-
 import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
 
-import static com.epam.ta.reportportal.entity.enums.StatusEnum.*;
-import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.TO_INVESTIGATE;
-import static com.epam.ta.reportportal.ws.converter.converters.TestItemConverter.TO_ACTIVITY_RESOURCE;
-import static com.epam.ta.reportportal.ws.model.ErrorType.INCORRECT_REQUEST;
-import static com.epam.ta.reportportal.ws.model.ErrorType.PROJECT_NOT_FOUND;
-import static java.util.Optional.ofNullable;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 public abstract class AbstractStatusChangingStrategy implements StatusChangingStrategy {
 
-	private final TestItemService testItemService;
-
-	private final ProjectRepository projectRepository;
-	private final LaunchRepository launchRepository;
-	private final IssueTypeHandler issueTypeHandler;
-	private final MessageBus messageBus;
-
-	protected final TestItemRepository testItemRepository;
-	protected final IssueEntityRepository issueEntityRepository;
-	protected final LogRepository logRepository;
-	protected final LogIndexer logIndexer;
-
-	protected AbstractStatusChangingStrategy(TestItemService testItemService, ProjectRepository projectRepository,
-			LaunchRepository launchRepository, TestItemRepository testItemRepository, IssueTypeHandler issueTypeHandler,
-			MessageBus messageBus, IssueEntityRepository issueEntityRepository, LogRepository logRepository, LogIndexer logIndexer) {
-		this.testItemService = testItemService;
-		this.projectRepository = projectRepository;
-		this.launchRepository = launchRepository;
-		this.testItemRepository = testItemRepository;
-		this.issueTypeHandler = issueTypeHandler;
-		this.messageBus = messageBus;
-		this.issueEntityRepository = issueEntityRepository;
-		this.logRepository = logRepository;
-		this.logIndexer = logIndexer;
-	}
-
-	protected abstract void updateStatus(Project project, Launch launch, TestItem testItem, StatusEnum providedStatus,
-			ReportPortalUser user);
-
-	protected abstract StatusEnum evaluateParentItemStatus(TestItem parentItem, TestItem childItem);
-
-	@Override
-	public void changeStatus(TestItem testItem, StatusEnum providedStatus, ReportPortalUser user) {
-		BusinessRule.expect(testItem.getItemResults().getStatus(), currentStatus -> !IN_PROGRESS.equals(currentStatus))
-				.verify(INCORRECT_REQUEST, Suppliers.formattedSupplier("Unable to update status of test item = '{}' because of '{}' status",
-						testItem.getItemId(),
-						testItem.getItemResults().getStatus()
-				).get());
-		if (providedStatus == testItem.getItemResults().getStatus()) {
-			return;
-		}
-
-		Launch launch = testItemService.getEffectiveLaunch(testItem);
-		Project project = projectRepository.findById(launch.getProjectId())
-				.orElseThrow(() -> new ReportPortalException(PROJECT_NOT_FOUND, launch.getProjectId()));
-
-		updateStatus(project, launch, testItem, providedStatus, user);
-	}
-
-	protected void addToInvestigateIssue(TestItem testItem, Long projectId) {
-		IssueEntity issueEntity = new IssueEntity();
-		IssueType toInvestigate = issueTypeHandler.defineIssueType(projectId, TO_INVESTIGATE.getLocator());
-		issueEntity.setIssueType(toInvestigate);
-		issueEntity.setTestItemResults(testItem.getItemResults());
-		issueEntityRepository.save(issueEntity);
-		testItem.getItemResults().setIssue(issueEntity);
-	}
-
-	protected List<Long> changeParentsStatuses(TestItem testItem, Launch launch, boolean issueRequired, ReportPortalUser user) {
-		List<Long> updatedParents = Lists.newArrayList();
-
-		Long parentId = testItem.getParentId();
-		while (parentId != null) {
-
-			TestItem parent = testItemRepository.findById(parentId)
-					.orElseThrow(() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, testItem.getParentId()));
-
-			StatusEnum currentParentStatus = parent.getItemResults().getStatus();
-			if (!StatusEnum.IN_PROGRESS.equals(currentParentStatus)) {
-
-				StatusEnum newParentStatus = evaluateParentItemStatus(parent, testItem);
-				if (!currentParentStatus.equals(newParentStatus)) {
-					TestItemActivityResource before = TO_ACTIVITY_RESOURCE.apply(parent, launch.getProjectId());
-					parent.getItemResults().setStatus(newParentStatus);
-					updateItem(parent, launch.getProjectId(), issueRequired).ifPresent(updatedParents::add);
-					publishUpdateActivity(before, TO_ACTIVITY_RESOURCE.apply(parent, launch.getProjectId()), user);
-				} else {
-					return updatedParents;
-				}
-
-			} else {
-				return updatedParents;
-			}
-
-			parentId = parent.getParentId();
-		}
-
-		if (launch.getStatus() != IN_PROGRESS) {
-			launch.setStatus(launchRepository.hasRootItemsWithStatusNotEqual(launch.getId(),
-					StatusEnum.PASSED.name(),
-					INFO.name(),
-					WARN.name()
-			) ? FAILED : PASSED);
-		}
-
-		return updatedParents;
-	}
-
-	private Optional<Long> updateItem(TestItem parent, Long projectId, boolean issueRequired) {
-		if (parent.isHasStats() && !parent.isHasChildren()) {
-			updateIssue(parent, projectId, issueRequired);
-			return Optional.of(parent.getItemId());
-		}
-		return Optional.empty();
-	}
-
-	private void updateIssue(TestItem parent, Long projectId, boolean issueRequired) {
-		if (issueRequired) {
-			if (ofNullable(parent.getItemResults().getIssue()).isEmpty()) {
-				addToInvestigateIssue(parent, projectId);
-			}
-		} else {
-			ofNullable(parent.getItemResults().getIssue()).ifPresent(issue -> {
-				issue.setTestItemResults(null);
-				issueEntityRepository.delete(issue);
-				parent.getItemResults().setIssue(null);
-				logIndexer.indexItemsRemoveAsync(projectId, Collections.singletonList(parent.getItemId()));
-			});
-		}
-	}
-
-	private void publishUpdateActivity(TestItemActivityResource before, TestItemActivityResource after, ReportPortalUser user) {
-		messageBus.publishActivity(new TestItemStatusChangedEvent(before, after, user.getUserId(), user.getUsername()));
-	}
+  private final TestItemService testItemService;
+
+  private final ProjectRepository projectRepository;
+  private final LaunchRepository launchRepository;
+  private final IssueTypeHandler issueTypeHandler;
+  private final MessageBus messageBus;
+
+  protected final TestItemRepository testItemRepository;
+  protected final IssueEntityRepository issueEntityRepository;
+  protected final LogRepository logRepository;
+  protected final LogIndexer logIndexer;
+
+  protected AbstractStatusChangingStrategy(TestItemService testItemService,
+      ProjectRepository projectRepository, LaunchRepository launchRepository,
+      TestItemRepository testItemRepository, IssueTypeHandler issueTypeHandler,
+      MessageBus messageBus, IssueEntityRepository issueEntityRepository,
+      LogRepository logRepository, LogIndexer logIndexer) {
+    this.testItemService = testItemService;
+    this.projectRepository = projectRepository;
+    this.launchRepository = launchRepository;
+    this.testItemRepository = testItemRepository;
+    this.issueTypeHandler = issueTypeHandler;
+    this.messageBus = messageBus;
+    this.issueEntityRepository = issueEntityRepository;
+    this.logRepository = logRepository;
+    this.logIndexer = logIndexer;
+  }
+
+  protected abstract void updateStatus(Project project, Launch launch, TestItem testItem,
+      StatusEnum providedStatus, ReportPortalUser user, boolean updateParents);
+
+  protected abstract StatusEnum evaluateParentItemStatus(TestItem parentItem, TestItem childItem);
+
+  @Override
+  public void changeStatus(TestItem testItem, StatusEnum providedStatus, ReportPortalUser user,
+      boolean updateParents) {
+    BusinessRule.expect(testItem.getItemResults().getStatus(),
+        currentStatus -> !IN_PROGRESS.equals(currentStatus)
+    ).verify(
+        INCORRECT_REQUEST, Suppliers.formattedSupplier(
+            "Unable to update status of test item = '{}' because of '{}' status",
+            testItem.getItemId(), testItem.getItemResults().getStatus()
+        ).get());
+    if (providedStatus == testItem.getItemResults().getStatus()) {
+      return;
+    }
+
+    Launch launch = testItemService.getEffectiveLaunch(testItem);
+    Project project = projectRepository.findById(launch.getProjectId())
+        .orElseThrow(() -> new ReportPortalException(PROJECT_NOT_FOUND, launch.getProjectId()));
+
+    updateStatus(project, launch, testItem, providedStatus, user, updateParents);
+  }
+
+  protected void addToInvestigateIssue(TestItem testItem, Long projectId) {
+    IssueEntity issueEntity = new IssueEntity();
+    IssueType toInvestigate =
+        issueTypeHandler.defineIssueType(projectId, TO_INVESTIGATE.getLocator());
+    issueEntity.setIssueType(toInvestigate);
+    issueEntity.setTestItemResults(testItem.getItemResults());
+    issueEntityRepository.save(issueEntity);
+    testItem.getItemResults().setIssue(issueEntity);
+  }
+
+  protected List<Long> changeParentsStatuses(TestItem testItem, Launch launch,
+      boolean issueRequired, ReportPortalUser user) {
+    List<Long> updatedParents = Lists.newArrayList();
+
+    Long parentId = testItem.getParentId();
+    while (parentId != null) {
+
+      TestItem parent = testItemRepository.findById(parentId).orElseThrow(
+          () -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, testItem.getParentId()));
+
+      StatusEnum currentParentStatus = parent.getItemResults().getStatus();
+      if (!StatusEnum.IN_PROGRESS.equals(currentParentStatus)) {
+
+        StatusEnum newParentStatus = evaluateParentItemStatus(parent, testItem);
+        if (!currentParentStatus.equals(newParentStatus)) {
+          TestItemActivityResource before =
+              TO_ACTIVITY_RESOURCE.apply(parent, launch.getProjectId());
+          parent.getItemResults().setStatus(newParentStatus);
+          updateItem(parent, launch.getProjectId(), issueRequired).ifPresent(updatedParents::add);
+          publishUpdateActivity(before, TO_ACTIVITY_RESOURCE.apply(parent, launch.getProjectId()),
+              user
+          );
+        } else {
+          return updatedParents;
+        }
+
+      } else {
+        return updatedParents;
+      }
+
+      parentId = parent.getParentId();
+    }
+
+    if (launch.getStatus() != IN_PROGRESS) {
+      launch.setStatus(
+          launchRepository.hasRootItemsWithStatusNotEqual(launch.getId(), StatusEnum.PASSED.name(),
+              INFO.name(), WARN.name()
+          ) ? FAILED : PASSED);
+    }
+
+    return updatedParents;
+  }
+
+  private Optional<Long> updateItem(TestItem parent, Long projectId, boolean issueRequired) {
+    if (parent.isHasStats() && !parent.isHasChildren()) {
+      updateIssue(parent, projectId, issueRequired);
+      return Optional.of(parent.getItemId());
+    }
+    return Optional.empty();
+  }
+
+  private void updateIssue(TestItem parent, Long projectId, boolean issueRequired) {
+    if (issueRequired) {
+      if (ofNullable(parent.getItemResults().getIssue()).isEmpty()) {
+        addToInvestigateIssue(parent, projectId);
+      }
+    } else {
+      ofNullable(parent.getItemResults().getIssue()).ifPresent(issue -> {
+        issue.setTestItemResults(null);
+        issueEntityRepository.delete(issue);
+        parent.getItemResults().setIssue(null);
+        logIndexer.indexItemsRemoveAsync(projectId, Collections.singletonList(parent.getItemId()));
+      });
+    }
+  }
+
+  private void publishUpdateActivity(TestItemActivityResource before,
+      TestItemActivityResource after, ReportPortalUser user) {
+    messageBus.publishActivity(
+        new TestItemStatusChangedEvent(before, after, user.getUserId(), user.getUsername()));
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/status/ChangeStatusHandler.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/status/ChangeStatusHandler.java
index 1da3afbfee..d282963d37 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/status/ChangeStatusHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/status/ChangeStatusHandler.java
@@ -25,7 +25,7 @@
  */
 public interface ChangeStatusHandler {
 
-	void changeParentStatus(TestItem childItem, Long projectId, ReportPortalUser user);
+  void changeParentStatus(TestItem childItem, Long projectId, ReportPortalUser user);
 
-	void changeLaunchStatus(Launch launch);
+  void changeLaunchStatus(Launch launch);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/status/ChangeStatusHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/status/ChangeStatusHandlerImpl.java
index 9a95751cc2..9d4eef2b72 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/status/ChangeStatusHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/status/ChangeStatusHandlerImpl.java
@@ -16,6 +16,13 @@
 
 package com.epam.ta.reportportal.core.item.impl.status;
 
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.FAILED;
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.INFO;
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.PASSED;
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.WARN;
+import static com.epam.ta.reportportal.ws.converter.converters.TestItemConverter.TO_ACTIVITY_RESOURCE;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.events.MessageBus;
 import com.epam.ta.reportportal.core.events.activity.item.TestItemStatusChangedEvent;
@@ -29,15 +36,10 @@
 import com.epam.ta.reportportal.jooq.enums.JStatusEnum;
 import com.epam.ta.reportportal.ws.model.activity.TestItemActivityResource;
 import com.google.common.collect.Lists;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
 import java.util.Map;
 import java.util.Optional;
-
-import static com.epam.ta.reportportal.entity.enums.StatusEnum.*;
-import static com.epam.ta.reportportal.ws.converter.converters.TestItemConverter.TO_ACTIVITY_RESOURCE;
-import static java.util.Optional.ofNullable;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -45,82 +47,91 @@
 @Service
 public class ChangeStatusHandlerImpl implements ChangeStatusHandler {
 
-	private final TestItemRepository testItemRepository;
-	private final IssueEntityRepository issueEntityRepository;
-	private final MessageBus messageBus;
-	private final LaunchRepository launchRepository;
-	private final Map<StatusEnum, StatusChangingStrategy> statusChangingStrategyMapping;
+  private final TestItemRepository testItemRepository;
+  private final IssueEntityRepository issueEntityRepository;
+  private final MessageBus messageBus;
+  private final LaunchRepository launchRepository;
+  private final Map<StatusEnum, StatusChangingStrategy> statusChangingStrategyMapping;
 
-	@Autowired
-	public ChangeStatusHandlerImpl(TestItemRepository testItemRepository, IssueEntityRepository issueEntityRepository,
-			MessageBus messageBus, LaunchRepository launchRepository,
-			Map<StatusEnum, StatusChangingStrategy> statusChangingStrategyMapping) {
-		this.testItemRepository = testItemRepository;
-		this.issueEntityRepository = issueEntityRepository;
-		this.messageBus = messageBus;
-		this.launchRepository = launchRepository;
-		this.statusChangingStrategyMapping = statusChangingStrategyMapping;
-	}
+  @Autowired
+  public ChangeStatusHandlerImpl(TestItemRepository testItemRepository,
+      IssueEntityRepository issueEntityRepository,
+      MessageBus messageBus, LaunchRepository launchRepository,
+      Map<StatusEnum, StatusChangingStrategy> statusChangingStrategyMapping) {
+    this.testItemRepository = testItemRepository;
+    this.issueEntityRepository = issueEntityRepository;
+    this.messageBus = messageBus;
+    this.launchRepository = launchRepository;
+    this.statusChangingStrategyMapping = statusChangingStrategyMapping;
+  }
 
-	@Override
-	public void changeParentStatus(TestItem childItem, Long projectId, ReportPortalUser user) {
-		ofNullable(childItem.getParentId()).flatMap(testItemRepository::findById).ifPresent(parent -> {
-			if (parent.isHasChildren()) {
-				ofNullable(parent.getItemResults().getIssue()).map(IssueEntity::getIssueId).ifPresent(issueEntityRepository::deleteById);
-			}
-			if (isParentStatusUpdateRequired(parent)) {
-				StatusEnum resolvedStatus = resolveStatus(parent.getItemId());
-				if (parent.getItemResults().getStatus() != resolvedStatus) {
-					TestItemActivityResource before = TO_ACTIVITY_RESOURCE.apply(parent, projectId);
-					changeStatus(parent, resolvedStatus, user);
-					messageBus.publishActivity(new TestItemStatusChangedEvent(before,
-							TO_ACTIVITY_RESOURCE.apply(parent, projectId),
-							user.getUserId(),
-							user.getUsername()
-					));
-					changeParentStatus(parent, projectId, user);
-				}
+  @Override
+  public void changeParentStatus(TestItem childItem, Long projectId, ReportPortalUser user) {
+    ofNullable(childItem.getParentId()).flatMap(testItemRepository::findById).ifPresent(parent -> {
+      if (parent.isHasChildren()) {
+        ofNullable(parent.getItemResults().getIssue()).map(IssueEntity::getIssueId)
+            .ifPresent(issueEntityRepository::deleteById);
+      }
+      if (isParentStatusUpdateRequired(parent)) {
+        StatusEnum resolvedStatus = resolveStatus(parent.getItemId());
+        if (parent.getItemResults().getStatus() != resolvedStatus) {
+          TestItemActivityResource before = TO_ACTIVITY_RESOURCE.apply(parent, projectId);
+          changeStatus(parent, resolvedStatus, user);
+          messageBus.publishActivity(new TestItemStatusChangedEvent(before,
+              TO_ACTIVITY_RESOURCE.apply(parent, projectId),
+              user.getUserId(),
+              user.getUsername()
+          ));
+          changeParentStatus(parent, projectId, user);
+        }
 
-			}
-		});
-	}
+      }
+    });
+  }
 
-	private boolean isParentStatusUpdateRequired(TestItem parent) {
-		return parent.getItemResults().getStatus() != StatusEnum.IN_PROGRESS
-				&& !testItemRepository.hasItemsInStatusByParent(parent.getItemId(), parent.getPath(), StatusEnum.IN_PROGRESS.name());
-	}
+  private boolean isParentStatusUpdateRequired(TestItem parent) {
+    return parent.getItemResults().getStatus() != StatusEnum.IN_PROGRESS
+        && parent.getItemResults().getStatus() != PASSED
+        && parent.getItemResults().getStatus() != FAILED
+        && !testItemRepository.hasItemsInStatusByParent(parent.getItemId(), parent.getPath(),
+        StatusEnum.IN_PROGRESS.name());
+  }
 
-	private StatusEnum resolveStatus(Long itemId) {
-		return testItemRepository.hasDescendantsNotInStatus(itemId, StatusEnum.PASSED.name(), INFO.name(), WARN.name()) ?
-				FAILED :
-				PASSED;
-	}
+  private StatusEnum resolveStatus(Long itemId) {
+    return
+        testItemRepository.hasDescendantsNotInStatus(itemId, StatusEnum.PASSED.name(), INFO.name(),
+            WARN.name()) ?
+            FAILED :
+            PASSED;
+  }
 
-	private void changeStatus(TestItem parent, StatusEnum resolvedStatus, ReportPortalUser user) {
-		if (parent.isHasChildren() || !parent.isHasStats()) {
-			parent.getItemResults().setStatus(resolvedStatus);
-		} else {
-			Optional<StatusChangingStrategy> statusChangingStrategy = ofNullable(statusChangingStrategyMapping.get(resolvedStatus));
-			if (statusChangingStrategy.isPresent()) {
-				statusChangingStrategy.get().changeStatus(parent, resolvedStatus, user);
-			} else {
-				parent.getItemResults().setStatus(resolvedStatus);
-			}
-		}
+  private void changeStatus(TestItem parent, StatusEnum resolvedStatus, ReportPortalUser user) {
+    if (parent.isHasChildren() || !parent.isHasStats()) {
+      parent.getItemResults().setStatus(resolvedStatus);
+    } else {
+      Optional<StatusChangingStrategy> statusChangingStrategy = ofNullable(
+          statusChangingStrategyMapping.get(resolvedStatus));
+      if (statusChangingStrategy.isPresent()) {
+        statusChangingStrategy.get().changeStatus(parent, resolvedStatus, user, false);
+      } else {
+        parent.getItemResults().setStatus(resolvedStatus);
+      }
+    }
 
-	}
+  }
 
-	@Override
-	public void changeLaunchStatus(Launch launch) {
-		if (launch.getStatus() != StatusEnum.IN_PROGRESS) {
-			if (!launchRepository.hasItemsInStatuses(launch.getId(), Lists.newArrayList(JStatusEnum.IN_PROGRESS))) {
-				StatusEnum launchStatus = launchRepository.hasRootItemsWithStatusNotEqual(launch.getId(),
-						StatusEnum.PASSED.name(),
-						INFO.name(),
-						WARN.name()
-				) ? FAILED : PASSED;
-				launch.setStatus(launchStatus);
-			}
-		}
-	}
+  @Override
+  public void changeLaunchStatus(Launch launch) {
+    if (launch.getStatus() != StatusEnum.IN_PROGRESS) {
+      if (!launchRepository.hasItemsInStatuses(launch.getId(),
+          Lists.newArrayList(JStatusEnum.IN_PROGRESS))) {
+        StatusEnum launchStatus = launchRepository.hasRootItemsWithStatusNotEqual(launch.getId(),
+            StatusEnum.PASSED.name(),
+            INFO.name(),
+            WARN.name()
+        ) ? FAILED : PASSED;
+        launch.setStatus(launchStatus);
+      }
+    }
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/status/StatusChangingStrategy.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/status/StatusChangingStrategy.java
index 61c8b09ef0..45758d4685 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/status/StatusChangingStrategy.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/status/StatusChangingStrategy.java
@@ -26,5 +26,6 @@
  */
 public interface StatusChangingStrategy {
 
-	void changeStatus(TestItem testItem, StatusEnum providedStatus, ReportPortalUser user);
+  void changeStatus(TestItem testItem, StatusEnum providedStatus, ReportPortalUser user,
+      boolean updateParents);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/status/ToFailedStatusChangingStrategy.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/status/ToFailedStatusChangingStrategy.java
index 43f93bd2b1..f1fb3a84a8 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/status/ToFailedStatusChangingStrategy.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/status/ToFailedStatusChangingStrategy.java
@@ -16,6 +16,9 @@
 
 package com.epam.ta.reportportal.core.item.impl.status;
 
+import static com.epam.ta.reportportal.commons.Preconditions.statusIn;
+import static com.epam.ta.reportportal.ws.model.ErrorType.INCORRECT_REQUEST;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.commons.validation.Suppliers;
@@ -24,19 +27,20 @@
 import com.epam.ta.reportportal.core.events.MessageBus;
 import com.epam.ta.reportportal.core.item.TestItemService;
 import com.epam.ta.reportportal.core.item.impl.IssueTypeHandler;
-import com.epam.ta.reportportal.dao.*;
+import com.epam.ta.reportportal.dao.IssueEntityRepository;
+import com.epam.ta.reportportal.dao.LaunchRepository;
+import com.epam.ta.reportportal.dao.LogRepository;
+import com.epam.ta.reportportal.dao.ProjectRepository;
+import com.epam.ta.reportportal.dao.TestItemRepository;
 import com.epam.ta.reportportal.entity.enums.StatusEnum;
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.entity.project.Project;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
-
-import static com.epam.ta.reportportal.commons.Preconditions.statusIn;
-import static com.epam.ta.reportportal.ws.model.ErrorType.INCORRECT_REQUEST;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -45,46 +49,47 @@
 @Service
 public class ToFailedStatusChangingStrategy extends AbstractStatusChangingStrategy {
 
-	@Autowired
-	public ToFailedStatusChangingStrategy(TestItemService testItemService, ProjectRepository projectRepository,
-			LaunchRepository launchRepository, TestItemRepository testItemRepository, IssueTypeHandler issueTypeHandler,
-			MessageBus messageBus, IssueEntityRepository issueEntityRepository, LogRepository logRepository, LogIndexer logIndexer) {
-		super(
-				testItemService,
-				projectRepository,
-				launchRepository,
-				testItemRepository,
-				issueTypeHandler,
-				messageBus,
-				issueEntityRepository,
-				logRepository,
-				logIndexer
-		);
-	}
+  @Autowired
+  public ToFailedStatusChangingStrategy(TestItemService testItemService,
+      ProjectRepository projectRepository, LaunchRepository launchRepository,
+      TestItemRepository testItemRepository, IssueTypeHandler issueTypeHandler,
+      MessageBus messageBus, IssueEntityRepository issueEntityRepository,
+      LogRepository logRepository, LogIndexer logIndexer) {
+    super(testItemService, projectRepository, launchRepository, testItemRepository,
+        issueTypeHandler, messageBus, issueEntityRepository, logRepository, logIndexer
+    );
+  }
 
-	@Override
-	protected void updateStatus(Project project, Launch launch, TestItem testItem, StatusEnum providedStatus, ReportPortalUser user) {
-		BusinessRule.expect(providedStatus, statusIn(StatusEnum.FAILED)).verify(
-				INCORRECT_REQUEST,
-				Suppliers.formattedSupplier("Incorrect status - '{}', only '{}' is allowed", providedStatus, StatusEnum.FAILED).get()
-		);
+  @Override
+  protected void updateStatus(Project project, Launch launch, TestItem testItem,
+      StatusEnum providedStatus, ReportPortalUser user, boolean updateParents) {
+    BusinessRule.expect(providedStatus, statusIn(StatusEnum.FAILED)).verify(INCORRECT_REQUEST,
+        Suppliers.formattedSupplier("Incorrect status - '{}', only '{}' is allowed", providedStatus,
+            StatusEnum.FAILED
+        ).get()
+    );
 
-		testItem.getItemResults().setStatus(providedStatus);
-		if (Objects.isNull(testItem.getRetryOf())) {
-			if (testItem.getItemResults().getIssue() == null && testItem.isHasStats()) {
-				addToInvestigateIssue(testItem, project.getId());
-			}
+    testItem.getItemResults().setStatus(providedStatus);
+    if (Objects.isNull(testItem.getRetryOf())) {
+      if (testItem.getItemResults().getIssue() == null && testItem.isHasStats()) {
+        addToInvestigateIssue(testItem, project.getId());
+      }
 
-			List<Long> itemsToReindex = changeParentsStatuses(testItem, launch, true, user);
-			itemsToReindex.add(testItem.getItemId());
-			logIndexer.indexItemsRemove(project.getId(), itemsToReindex);
-			logIndexer.indexItemsLogs(project.getId(), launch.getId(), itemsToReindex, AnalyzerUtils.getAnalyzerConfig(project));
-		}
-	}
+      List<Long> itemsToReindex = new ArrayList<>();
+      if (updateParents) {
+        itemsToReindex = changeParentsStatuses(testItem, launch, true, user);
+      }
+      itemsToReindex.add(testItem.getItemId());
+      logIndexer.indexItemsRemove(project.getId(), itemsToReindex);
+      logIndexer.indexItemsLogs(project.getId(), launch.getId(), itemsToReindex,
+          AnalyzerUtils.getAnalyzerConfig(project)
+      );
+    }
+  }
 
-	@Override
-	protected StatusEnum evaluateParentItemStatus(TestItem parentItem, TestItem childItem) {
-		return StatusEnum.FAILED;
-	}
+  @Override
+  protected StatusEnum evaluateParentItemStatus(TestItem parentItem, TestItem childItem) {
+    return StatusEnum.FAILED;
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/status/ToPassedStatusChangingStrategy.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/status/ToPassedStatusChangingStrategy.java
index 34f7b07d98..babcc18e7e 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/status/ToPassedStatusChangingStrategy.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/status/ToPassedStatusChangingStrategy.java
@@ -16,6 +16,10 @@
 
 package com.epam.ta.reportportal.core.item.impl.status;
 
+import static com.epam.ta.reportportal.commons.Preconditions.statusIn;
+import static com.epam.ta.reportportal.ws.model.ErrorType.INCORRECT_REQUEST;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.commons.validation.Suppliers;
@@ -23,22 +27,21 @@
 import com.epam.ta.reportportal.core.events.MessageBus;
 import com.epam.ta.reportportal.core.item.TestItemService;
 import com.epam.ta.reportportal.core.item.impl.IssueTypeHandler;
-import com.epam.ta.reportportal.dao.*;
+import com.epam.ta.reportportal.dao.IssueEntityRepository;
+import com.epam.ta.reportportal.dao.LaunchRepository;
+import com.epam.ta.reportportal.dao.LogRepository;
+import com.epam.ta.reportportal.dao.ProjectRepository;
+import com.epam.ta.reportportal.dao.TestItemRepository;
 import com.epam.ta.reportportal.entity.enums.StatusEnum;
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.entity.project.Project;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
 import java.util.Collections;
 import java.util.Objects;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
-
-import static com.epam.ta.reportportal.commons.Preconditions.statusIn;
-import static com.epam.ta.reportportal.ws.model.ErrorType.INCORRECT_REQUEST;
-import static java.util.Optional.ofNullable;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -47,58 +50,53 @@
 @Service
 public class ToPassedStatusChangingStrategy extends AbstractStatusChangingStrategy {
 
-	@Autowired
-	protected ToPassedStatusChangingStrategy(TestItemService testItemService, ProjectRepository projectRepository,
-			LaunchRepository launchRepository, IssueTypeHandler issueTypeHandler, MessageBus messageBus,
-			IssueEntityRepository issueEntityRepository, LogRepository logRepository, LogIndexer logIndexer,
-			TestItemRepository testItemRepository) {
-		super(testItemService,
-				projectRepository,
-				launchRepository,
-				testItemRepository,
-				issueTypeHandler,
-				messageBus,
-				issueEntityRepository,
-				logRepository,
-				logIndexer
-		);
-	}
+  @Autowired
+  protected ToPassedStatusChangingStrategy(TestItemService testItemService,
+      ProjectRepository projectRepository, LaunchRepository launchRepository,
+      IssueTypeHandler issueTypeHandler, MessageBus messageBus,
+      IssueEntityRepository issueEntityRepository, LogRepository logRepository,
+      LogIndexer logIndexer, TestItemRepository testItemRepository) {
+    super(testItemService, projectRepository, launchRepository, testItemRepository,
+        issueTypeHandler, messageBus, issueEntityRepository, logRepository, logIndexer
+    );
+  }
 
-	@Override
-	protected void updateStatus(Project project, Launch launch, TestItem testItem, StatusEnum providedStatus, ReportPortalUser user) {
-		BusinessRule.expect(providedStatus, statusIn(StatusEnum.PASSED, StatusEnum.INFO, StatusEnum.WARN))
-				.verify(INCORRECT_REQUEST,
-						Suppliers.formattedSupplier("Incorrect status - '{}', only '{}' are allowed",
-								providedStatus,
-								Stream.of(StatusEnum.PASSED, StatusEnum.INFO, StatusEnum.WARN)
-										.map(StatusEnum::name)
-										.collect(Collectors.joining(", "))
-						).get()
-				);
+  @Override
+  protected void updateStatus(Project project, Launch launch, TestItem testItem,
+      StatusEnum providedStatus, ReportPortalUser user, boolean updateParents) {
+    BusinessRule.expect(providedStatus,
+        statusIn(StatusEnum.PASSED, StatusEnum.INFO, StatusEnum.WARN)
+    ).verify(INCORRECT_REQUEST,
+        Suppliers.formattedSupplier("Incorrect status - '{}', only '{}' are allowed",
+            providedStatus,
+            Stream.of(StatusEnum.PASSED, StatusEnum.INFO, StatusEnum.WARN).map(StatusEnum::name)
+                .collect(Collectors.joining(", "))
+        ).get()
+    );
 
-		testItem.getItemResults().setStatus(providedStatus);
-		if (Objects.isNull(testItem.getRetryOf())) {
-			ofNullable(testItem.getItemResults().getIssue()).ifPresent(issue -> {
-				issue.setTestItemResults(null);
-				issueEntityRepository.delete(issue);
-				testItem.getItemResults().setIssue(null);
-				logIndexer.indexItemsRemoveAsync(project.getId(), Collections.singletonList(testItem.getItemId()));
-			});
+    testItem.getItemResults().setStatus(providedStatus);
+    if (Objects.isNull(testItem.getRetryOf())) {
+      ofNullable(testItem.getItemResults().getIssue()).ifPresent(issue -> {
+        issue.setTestItemResults(null);
+        issueEntityRepository.delete(issue);
+        testItem.getItemResults().setIssue(null);
+        logIndexer.indexItemsRemoveAsync(project.getId(),
+            Collections.singletonList(testItem.getItemId())
+        );
+      });
 
-			changeParentsStatuses(testItem, launch, false, user);
-		}
-	}
+      if (updateParents) {
+        changeParentsStatuses(testItem, launch, false, user);
+      }
+    }
+  }
 
-	@Override
-	protected StatusEnum evaluateParentItemStatus(TestItem parentItem, TestItem childItem) {
-		return testItemRepository.hasDescendantsNotInStatusExcludingById(parentItem.getItemId(),
-				childItem.getItemId(),
-				StatusEnum.PASSED.name(),
-				StatusEnum.INFO.name(),
-				StatusEnum.WARN.name()
-		) ?
-				StatusEnum.FAILED :
-				StatusEnum.PASSED;
-	}
+  @Override
+  protected StatusEnum evaluateParentItemStatus(TestItem parentItem, TestItem childItem) {
+    return testItemRepository.hasDescendantsNotInStatusExcludingById(parentItem.getItemId(),
+        childItem.getItemId(), StatusEnum.PASSED.name(), StatusEnum.INFO.name(),
+        StatusEnum.WARN.name()
+    ) ? StatusEnum.FAILED : StatusEnum.PASSED;
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/status/ToSkippedStatusChangingStrategy.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/status/ToSkippedStatusChangingStrategy.java
index f50b5a3d8d..863896daff 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/status/ToSkippedStatusChangingStrategy.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/status/ToSkippedStatusChangingStrategy.java
@@ -16,6 +16,11 @@
 
 package com.epam.ta.reportportal.core.item.impl.status;
 
+import static com.epam.ta.reportportal.commons.Preconditions.statusIn;
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.FAILED;
+import static com.epam.ta.reportportal.ws.model.ErrorType.INCORRECT_REQUEST;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.commons.validation.Suppliers;
@@ -24,24 +29,24 @@
 import com.epam.ta.reportportal.core.events.MessageBus;
 import com.epam.ta.reportportal.core.item.TestItemService;
 import com.epam.ta.reportportal.core.item.impl.IssueTypeHandler;
-import com.epam.ta.reportportal.dao.*;
+import com.epam.ta.reportportal.dao.IssueEntityRepository;
+import com.epam.ta.reportportal.dao.ItemAttributeRepository;
+import com.epam.ta.reportportal.dao.LaunchRepository;
+import com.epam.ta.reportportal.dao.LogRepository;
+import com.epam.ta.reportportal.dao.ProjectRepository;
+import com.epam.ta.reportportal.dao.TestItemRepository;
 import com.epam.ta.reportportal.entity.ItemAttribute;
 import com.epam.ta.reportportal.entity.enums.StatusEnum;
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.entity.project.Project;
-import org.apache.commons.lang3.BooleanUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
-
-import static com.epam.ta.reportportal.commons.Preconditions.statusIn;
-import static com.epam.ta.reportportal.entity.enums.StatusEnum.FAILED;
-import static com.epam.ta.reportportal.ws.model.ErrorType.INCORRECT_REQUEST;
-import static java.util.Optional.ofNullable;
+import org.apache.commons.lang3.BooleanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -50,72 +55,74 @@
 @Service
 public class ToSkippedStatusChangingStrategy extends AbstractStatusChangingStrategy {
 
-	public static final String SKIPPED_ISSUE_KEY = "skippedIssue";
-
-	private final ItemAttributeRepository itemAttributeRepository;
-
-	@Autowired
-	protected ToSkippedStatusChangingStrategy(TestItemService testItemService, ProjectRepository projectRepository,
-			LaunchRepository launchRepository, TestItemRepository testItemRepository, IssueTypeHandler issueTypeHandler,
-			MessageBus messageBus, IssueEntityRepository issueEntityRepository, LogRepository logRepository, LogIndexer logIndexer,
-			ItemAttributeRepository itemAttributeRepository) {
-		super(testItemService,
-				projectRepository,
-				launchRepository,
-				testItemRepository,
-				issueTypeHandler,
-				messageBus,
-				issueEntityRepository,
-				logRepository,
-				logIndexer
-		);
-		this.itemAttributeRepository = itemAttributeRepository;
-	}
-
-	@Override
-	protected void updateStatus(Project project, Launch launch, TestItem testItem, StatusEnum providedStatus, ReportPortalUser user) {
-		BusinessRule.expect(providedStatus, statusIn(StatusEnum.SKIPPED))
-				.verify(INCORRECT_REQUEST,
-						Suppliers.formattedSupplier("Incorrect status - '{}', only '{}' is allowed", providedStatus, StatusEnum.SKIPPED)
-								.get()
-				);
-
-		testItem.getItemResults().setStatus(providedStatus);
-
-		if (Objects.isNull(testItem.getRetryOf())) {
-			Optional<ItemAttribute> skippedIssueAttribute = itemAttributeRepository.findByLaunchIdAndKeyAndSystem(testItem.getLaunchId(),
-					SKIPPED_ISSUE_KEY,
-					true
-			);
-
-			boolean issueRequired = skippedIssueAttribute.isPresent() && BooleanUtils.toBoolean(skippedIssueAttribute.get().getValue());
-
-			if (issueRequired) {
-				if (testItem.getItemResults().getIssue() == null && testItem.isHasStats()) {
-					addToInvestigateIssue(testItem, project.getId());
-				}
-			} else {
-				ofNullable(testItem.getItemResults().getIssue()).map(issue -> {
-					issue.setTestItemResults(null);
-					testItem.getItemResults().setIssue(null);
-					return issue.getIssueId();
-				}).ifPresent(issueEntityRepository::deleteById);
-			}
-
-			List<Long> itemsToReindex = changeParentsStatuses(testItem, launch, true, user);
-			itemsToReindex.add(testItem.getItemId());
-			logIndexer.indexLaunchesRemove(project.getId(), itemsToReindex);
-
-			if (!issueRequired) {
-				itemsToReindex.remove(itemsToReindex.size() - 1);
-			}
-
-			logIndexer.indexItemsLogs(project.getId(), launch.getId(), itemsToReindex, AnalyzerUtils.getAnalyzerConfig(project));
-		}
-	}
-
-	@Override
-	protected StatusEnum evaluateParentItemStatus(TestItem parentItem, TestItem childItem) {
-		return FAILED;
-	}
+  public static final String SKIPPED_ISSUE_KEY = "skippedIssue";
+
+  private final ItemAttributeRepository itemAttributeRepository;
+
+  @Autowired
+  protected ToSkippedStatusChangingStrategy(TestItemService testItemService,
+      ProjectRepository projectRepository, LaunchRepository launchRepository,
+      TestItemRepository testItemRepository, IssueTypeHandler issueTypeHandler,
+      MessageBus messageBus, IssueEntityRepository issueEntityRepository,
+      LogRepository logRepository, LogIndexer logIndexer,
+      ItemAttributeRepository itemAttributeRepository) {
+    super(testItemService, projectRepository, launchRepository, testItemRepository,
+        issueTypeHandler, messageBus, issueEntityRepository, logRepository, logIndexer
+    );
+    this.itemAttributeRepository = itemAttributeRepository;
+  }
+
+  @Override
+  protected void updateStatus(Project project, Launch launch, TestItem testItem,
+      StatusEnum providedStatus, ReportPortalUser user, boolean updateParents) {
+    BusinessRule.expect(providedStatus, statusIn(StatusEnum.SKIPPED)).verify(INCORRECT_REQUEST,
+        Suppliers.formattedSupplier("Incorrect status - '{}', only '{}' is allowed", providedStatus,
+            StatusEnum.SKIPPED
+        ).get()
+    );
+
+    testItem.getItemResults().setStatus(providedStatus);
+
+    if (Objects.isNull(testItem.getRetryOf())) {
+      Optional<ItemAttribute> skippedIssueAttribute =
+          itemAttributeRepository.findByLaunchIdAndKeyAndSystem(testItem.getLaunchId(),
+              SKIPPED_ISSUE_KEY, true
+          );
+
+      boolean issueRequired = skippedIssueAttribute.isPresent() && BooleanUtils.toBoolean(
+          skippedIssueAttribute.get().getValue());
+
+      if (issueRequired) {
+        if (testItem.getItemResults().getIssue() == null && testItem.isHasStats()) {
+          addToInvestigateIssue(testItem, project.getId());
+        }
+      } else {
+        ofNullable(testItem.getItemResults().getIssue()).map(issue -> {
+          issue.setTestItemResults(null);
+          testItem.getItemResults().setIssue(null);
+          return issue.getIssueId();
+        }).ifPresent(issueEntityRepository::deleteById);
+      }
+
+      List<Long> itemsToReindex = new ArrayList<>();
+      if (updateParents) {
+        itemsToReindex = changeParentsStatuses(testItem, launch, true, user);
+      }
+      itemsToReindex.add(testItem.getItemId());
+      logIndexer.indexItemsRemove(project.getId(), itemsToReindex);
+
+      if (!issueRequired) {
+        itemsToReindex.remove(itemsToReindex.size() - 1);
+      }
+
+      logIndexer.indexItemsLogs(project.getId(), launch.getId(), itemsToReindex,
+          AnalyzerUtils.getAnalyzerConfig(project)
+      );
+    }
+  }
+
+  @Override
+  protected StatusEnum evaluateParentItemStatus(TestItem parentItem, TestItem childItem) {
+    return FAILED;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/merge/LaunchMergeStrategy.java b/src/main/java/com/epam/ta/reportportal/core/item/merge/LaunchMergeStrategy.java
index 6c5658321b..aa786bbf44 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/merge/LaunchMergeStrategy.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/merge/LaunchMergeStrategy.java
@@ -19,7 +19,6 @@
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.ws.model.launch.MergeLaunchesRQ;
-
 import java.util.List;
 
 /**
@@ -27,6 +26,7 @@
  */
 public interface LaunchMergeStrategy {
 
-	Launch mergeLaunches(ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user, MergeLaunchesRQ rq,
-			List<Launch> launchesList);
+  Launch mergeLaunches(ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user,
+      MergeLaunchesRQ rq,
+      List<Launch> launchesList);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/merge/StatisticsCalculationStrategy.java b/src/main/java/com/epam/ta/reportportal/core/item/merge/StatisticsCalculationStrategy.java
index e184bc4627..0518440372 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/merge/StatisticsCalculationStrategy.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/merge/StatisticsCalculationStrategy.java
@@ -18,7 +18,6 @@
 
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.entity.statistics.Statistics;
-
 import java.util.Collection;
 import java.util.Set;
 
@@ -27,5 +26,5 @@
  */
 public interface StatisticsCalculationStrategy {
 
-	Set<Statistics> recalculateLaunchStatistics(Launch newLaunch, Collection<Launch> launches);
+  Set<Statistics> recalculateLaunchStatistics(Launch newLaunch, Collection<Launch> launches);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/utils/DefaultLaunchFilterProvider.java b/src/main/java/com/epam/ta/reportportal/core/item/utils/DefaultLaunchFilterProvider.java
index fa66acb1fa..b1fdecff05 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/utils/DefaultLaunchFilterProvider.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/utils/DefaultLaunchFilterProvider.java
@@ -16,6 +16,12 @@
 
 package com.epam.ta.reportportal.core.item.utils;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_PROJECT_ID;
+import static com.epam.ta.reportportal.commons.querygen.constant.LaunchCriteriaConstant.CRITERIA_LAUNCH_MODE;
+import static com.epam.ta.reportportal.commons.querygen.constant.LaunchCriteriaConstant.CRITERIA_LAUNCH_STATUS;
+import static java.util.Optional.ofNullable;
+import static java.util.stream.Collectors.toList;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.querygen.Condition;
 import com.epam.ta.reportportal.commons.querygen.Filter;
@@ -33,60 +39,58 @@
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.domain.Sort;
 
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_PROJECT_ID;
-import static com.epam.ta.reportportal.commons.querygen.constant.LaunchCriteriaConstant.CRITERIA_LAUNCH_MODE;
-import static com.epam.ta.reportportal.commons.querygen.constant.LaunchCriteriaConstant.CRITERIA_LAUNCH_STATUS;
-import static java.util.Optional.ofNullable;
-import static java.util.stream.Collectors.toList;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public class DefaultLaunchFilterProvider {
 
-	public static Pair<Queryable, Pageable> createDefaultLaunchQueryablePair(ReportPortalUser.ProjectDetails projectDetails,
-			UserFilter userFilter, int launchesLimit) {
-		Queryable launchFilter = createLaunchFilter(projectDetails, userFilter);
-		Pageable launchPageable = createLaunchPageable(userFilter, launchesLimit);
-		return Pair.of(launchFilter, launchPageable);
-	}
+  public static Pair<Queryable, Pageable> createDefaultLaunchQueryablePair(
+      ReportPortalUser.ProjectDetails projectDetails,
+      UserFilter userFilter, int launchesLimit) {
+    Queryable launchFilter = createLaunchFilter(projectDetails, userFilter);
+    Pageable launchPageable = createLaunchPageable(userFilter, launchesLimit);
+    return Pair.of(launchFilter, launchPageable);
+  }
 
-	private static Filter createLaunchFilter(ReportPortalUser.ProjectDetails projectDetails, UserFilter launchFilter) {
+  private static Filter createLaunchFilter(ReportPortalUser.ProjectDetails projectDetails,
+      UserFilter launchFilter) {
 
-		validateLaunchFilterTarget(launchFilter);
+    validateLaunchFilterTarget(launchFilter);
 
-		Filter filter = Filter.builder()
-				.withTarget(launchFilter.getTargetClass().getClassObject())
-				.withCondition(FilterCondition.builder().eq(CRITERIA_PROJECT_ID, String.valueOf(projectDetails.getProjectId())).build())
-				.withCondition(FilterCondition.builder()
-						.withCondition(Condition.NOT_EQUALS)
-						.withSearchCriteria(CRITERIA_LAUNCH_STATUS)
-						.withValue(StatusEnum.IN_PROGRESS.name())
-						.build())
-				.withCondition(FilterCondition.builder().eq(CRITERIA_LAUNCH_MODE, Mode.DEFAULT.toString()).build())
-				.build();
-		filter.getFilterConditions().addAll(launchFilter.getFilterCondition());
-		return filter;
-	}
+    Filter filter = Filter.builder()
+        .withTarget(launchFilter.getTargetClass().getClassObject())
+        .withCondition(FilterCondition.builder()
+            .eq(CRITERIA_PROJECT_ID, String.valueOf(projectDetails.getProjectId())).build())
+        .withCondition(FilterCondition.builder()
+            .withCondition(Condition.NOT_EQUALS)
+            .withSearchCriteria(CRITERIA_LAUNCH_STATUS)
+            .withValue(StatusEnum.IN_PROGRESS.name())
+            .build())
+        .withCondition(
+            FilterCondition.builder().eq(CRITERIA_LAUNCH_MODE, Mode.DEFAULT.toString()).build())
+        .build();
+    filter.getFilterConditions().addAll(launchFilter.getFilterCondition());
+    return filter;
+  }
 
-	private static void validateLaunchFilterTarget(UserFilter launchFilter) {
-		BusinessRule.expect(launchFilter, f -> ObjectType.Launch.equals(f.getTargetClass()))
-				.verify(ErrorType.BAD_REQUEST_ERROR,
-						Suppliers.formattedSupplier("Incorrect filter target - '{}'. Allowed: '{}'",
-								launchFilter.getTargetClass(),
-								ObjectType.Launch
-						)
-				);
-	}
+  private static void validateLaunchFilterTarget(UserFilter launchFilter) {
+    BusinessRule.expect(launchFilter, f -> ObjectType.Launch.equals(f.getTargetClass()))
+        .verify(ErrorType.BAD_REQUEST_ERROR,
+            Suppliers.formattedSupplier("Incorrect filter target - '{}'. Allowed: '{}'",
+                launchFilter.getTargetClass(),
+                ObjectType.Launch
+            )
+        );
+  }
 
-	private static Pageable createLaunchPageable(UserFilter launchFilter, int launchesLimit) {
+  private static Pageable createLaunchPageable(UserFilter launchFilter, int launchesLimit) {
 
-		BusinessRule.expect(launchesLimit, limit -> limit > 0)
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Launches limit should be greater than 0");
+    BusinessRule.expect(launchesLimit, limit -> limit > 0)
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Launches limit should be greater than 0");
 
-		Sort sort = ofNullable(launchFilter.getFilterSorts()).map(sorts -> Sort.by(sorts.stream()
-				.map(s -> Sort.Order.by(s.getField()).with(s.getDirection()))
-				.collect(toList()))).orElseGet(Sort::unsorted);
-		return PageRequest.of(0, launchesLimit, sort);
-	}
+    Sort sort = ofNullable(launchFilter.getFilterSorts()).map(sorts -> Sort.by(sorts.stream()
+        .map(s -> Sort.Order.by(s.getField()).with(s.getDirection()))
+        .collect(toList()))).orElseGet(Sort::unsorted);
+    return PageRequest.of(0, launchesLimit, sort);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/validator/parent/NestedStepConditionValidator.java b/src/main/java/com/epam/ta/reportportal/core/item/validator/parent/NestedStepConditionValidator.java
index b1fa30dbf5..87338a1f1d 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/validator/parent/NestedStepConditionValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/validator/parent/NestedStepConditionValidator.java
@@ -1,31 +1,33 @@
 package com.epam.ta.reportportal.core.item.validator.parent;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.ws.model.ErrorType.BAD_REQUEST_ERROR;
+
 import com.epam.ta.reportportal.commons.validation.Suppliers;
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.ws.model.StartTestItemRQ;
 import org.springframework.core.Ordered;
 import org.springframework.stereotype.Service;
 
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.ws.model.ErrorType.BAD_REQUEST_ERROR;
-
 @Service
 public class NestedStepConditionValidator implements ParentItemValidator, Ordered {
-	@Override
-	public void validate(StartTestItemRQ rq, TestItem parent) {
-		if (!parent.isHasStats()) {
-			expect(rq.isHasStats(), equalTo(Boolean.FALSE)).verify(BAD_REQUEST_ERROR,
-					Suppliers.formattedSupplier("Unable to add a not nested step item, because parent item with ID = '{}' is a nested step",
-							parent.getItemId()
-					)
-							.get()
-			);
-		}
-	}
 
-	@Override
-	public int getOrder() {
-		return 1;
-	}
+  @Override
+  public void validate(StartTestItemRQ rq, TestItem parent) {
+    if (!parent.isHasStats()) {
+      expect(rq.isHasStats(), equalTo(Boolean.FALSE)).verify(BAD_REQUEST_ERROR,
+          Suppliers.formattedSupplier(
+                  "Unable to add a not nested step item, because parent item with ID = '{}' is a nested step",
+                  parent.getItemId()
+              )
+              .get()
+      );
+    }
+  }
+
+  @Override
+  public int getOrder() {
+    return 1;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/validator/parent/ParentItemValidator.java b/src/main/java/com/epam/ta/reportportal/core/item/validator/parent/ParentItemValidator.java
index a0aa192353..ef29f979df 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/validator/parent/ParentItemValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/validator/parent/ParentItemValidator.java
@@ -21,11 +21,11 @@
 
 public interface ParentItemValidator {
 
-	/**
-	 * Verifies if the start of a child item is allowed.
-	 *
-	 * @param rq     Start child item request
-	 * @param parent Parent item
-	 */
-	void validate(StartTestItemRQ rq, TestItem parent);
+  /**
+   * Verifies if the start of a child item is allowed.
+   *
+   * @param rq     Start child item request
+   * @param parent Parent item
+   */
+  void validate(StartTestItemRQ rq, TestItem parent);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/validator/parent/PathLengthValidator.java b/src/main/java/com/epam/ta/reportportal/core/item/validator/parent/PathLengthValidator.java
new file mode 100644
index 0000000000..774e87f54c
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/core/item/validator/parent/PathLengthValidator.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2023 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.core.item.validator.parent;
+
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.ws.model.ErrorType.BAD_REQUEST_ERROR;
+
+import com.epam.ta.reportportal.commons.Predicates;
+import com.epam.ta.reportportal.entity.item.TestItem;
+import com.epam.ta.reportportal.ws.model.StartTestItemRQ;
+import org.springframework.core.Ordered;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author Andrei Piankouski
+ */
+@Service
+public class PathLengthValidator implements ParentItemValidator, Ordered {
+
+  private static final int MAX_PATH_LENGTH = 64;
+
+  @Override
+  public void validate(StartTestItemRQ rq, TestItem parent) {
+    expect(parent.getPath().split("\\.").length >= MAX_PATH_LENGTH,
+        Predicates.equalTo(false)).verify(BAD_REQUEST_ERROR,
+        "Exceeded nesting limit for test item. Max limit is " + MAX_PATH_LENGTH + "."
+    );
+  }
+
+  @Override
+  public int getOrder() {
+    return 4;
+  }
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/validator/parent/RetryConditionValidator.java b/src/main/java/com/epam/ta/reportportal/core/item/validator/parent/RetryConditionValidator.java
index 9a75ffc174..485eabcec5 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/validator/parent/RetryConditionValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/validator/parent/RetryConditionValidator.java
@@ -1,25 +1,27 @@
 package com.epam.ta.reportportal.core.item.validator.parent;
 
+import static com.epam.ta.reportportal.commons.Predicates.isNull;
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.ws.model.ErrorType.UNABLE_TO_SAVE_CHILD_ITEM_FOR_THE_RETRY;
+
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.ws.model.StartTestItemRQ;
 import org.springframework.core.Ordered;
 import org.springframework.stereotype.Service;
 
-import static com.epam.ta.reportportal.commons.Predicates.isNull;
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.ws.model.ErrorType.UNABLE_TO_SAVE_CHILD_ITEM_FOR_THE_RETRY;
-
 @Service
 public class RetryConditionValidator implements ParentItemValidator, Ordered {
-	@Override
-	public void validate(StartTestItemRQ rq, TestItem parent) {
-		if (rq.isHasStats()) {
-			expect(parent.getRetryOf(), isNull()::test).verify(UNABLE_TO_SAVE_CHILD_ITEM_FOR_THE_RETRY, parent.getItemId());
-		}
-	}
 
-	@Override
-	public int getOrder() {
-		return 2;
-	}
+  @Override
+  public void validate(StartTestItemRQ rq, TestItem parent) {
+    if (rq.isHasStats()) {
+      expect(parent.getRetryOf(), isNull()::test).verify(UNABLE_TO_SAVE_CHILD_ITEM_FOR_THE_RETRY,
+          parent.getItemId());
+    }
+  }
+
+  @Override
+  public int getOrder() {
+    return 2;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/validator/parent/StartTimeConditionValidator.java b/src/main/java/com/epam/ta/reportportal/core/item/validator/parent/StartTimeConditionValidator.java
index fba612e821..ed453d8b9e 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/validator/parent/StartTimeConditionValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/validator/parent/StartTimeConditionValidator.java
@@ -1,27 +1,29 @@
 package com.epam.ta.reportportal.core.item.validator.parent;
 
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.ws.model.ErrorType.CHILD_START_TIME_EARLIER_THAN_PARENT;
+
 import com.epam.ta.reportportal.commons.Preconditions;
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.ws.model.StartTestItemRQ;
 import org.springframework.core.Ordered;
 import org.springframework.stereotype.Service;
 
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.ws.model.ErrorType.CHILD_START_TIME_EARLIER_THAN_PARENT;
-
 @Service
 public class StartTimeConditionValidator implements ParentItemValidator, Ordered {
-	@Override
-	public void validate(StartTestItemRQ rq, TestItem parent) {
-		expect(rq.getStartTime(), Preconditions.sameTimeOrLater(parent.getStartTime())).verify(CHILD_START_TIME_EARLIER_THAN_PARENT,
-				rq.getStartTime(),
-				parent.getStartTime(),
-				parent.getItemId()
-		);
-	}
 
-	@Override
-	public int getOrder() {
-		return 3;
-	}
+  @Override
+  public void validate(StartTestItemRQ rq, TestItem parent) {
+    expect(rq.getStartTime(), Preconditions.sameTimeOrLater(parent.getStartTime())).verify(
+        CHILD_START_TIME_EARLIER_THAN_PARENT,
+        rq.getStartTime(),
+        parent.getStartTime(),
+        parent.getItemId()
+    );
+  }
+
+  @Override
+  public int getOrder() {
+    return 3;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/validator/state/NotNestedStepValidator.java b/src/main/java/com/epam/ta/reportportal/core/item/validator/state/NotNestedStepValidator.java
index 0f4e0cfcc1..8248b7c1d9 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/validator/state/NotNestedStepValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/validator/state/NotNestedStepValidator.java
@@ -27,18 +27,18 @@
 @Service
 public class NotNestedStepValidator implements TestItemValidator, Ordered {
 
-	@Override
-	public boolean validate(TestItem item) {
-		return item.isHasStats();
-	}
+  @Override
+  public boolean validate(TestItem item) {
+    return item.isHasStats();
+  }
 
-	@Override
-	public String provide(TestItem item) {
-		return Suppliers.formattedSupplier("Test item = {} is a nested step", item.getItemId()).get();
-	}
+  @Override
+  public String provide(TestItem item) {
+    return Suppliers.formattedSupplier("Test item = {} is a nested step", item.getItemId()).get();
+  }
 
-	@Override
-	public int getOrder() {
-		return 1;
-	}
+  @Override
+  public int getOrder() {
+    return 1;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/validator/state/NotRetryValidator.java b/src/main/java/com/epam/ta/reportportal/core/item/validator/state/NotRetryValidator.java
index c4fda95cc0..2816b0304f 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/validator/state/NotRetryValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/validator/state/NotRetryValidator.java
@@ -18,29 +18,28 @@
 
 import com.epam.ta.reportportal.commons.validation.Suppliers;
 import com.epam.ta.reportportal.entity.item.TestItem;
+import java.util.Objects;
 import org.springframework.core.Ordered;
 import org.springframework.stereotype.Service;
 
-import java.util.Objects;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class NotRetryValidator implements TestItemValidator, Ordered {
 
-	@Override
-	public boolean validate(TestItem item) {
-		return Objects.isNull(item.getRetryOf()) && Objects.nonNull(item.getLaunchId());
-	}
+  @Override
+  public boolean validate(TestItem item) {
+    return Objects.isNull(item.getRetryOf()) && Objects.nonNull(item.getLaunchId());
+  }
 
-	@Override
-	public String provide(TestItem item) {
-		return Suppliers.formattedSupplier("Test item = {} is a retry", item.getItemId()).get();
-	}
+  @Override
+  public String provide(TestItem item) {
+    return Suppliers.formattedSupplier("Test item = {} is a retry", item.getItemId()).get();
+  }
 
-	@Override
-	public int getOrder() {
-		return 2;
-	}
+  @Override
+  public int getOrder() {
+    return 2;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/item/validator/state/TestItemValidator.java b/src/main/java/com/epam/ta/reportportal/core/item/validator/state/TestItemValidator.java
index 52d1747d7c..97e1f28963 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/validator/state/TestItemValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/validator/state/TestItemValidator.java
@@ -24,5 +24,5 @@
  */
 public interface TestItemValidator extends MessageProvider<TestItem> {
 
-	boolean validate(TestItem item);
+  boolean validate(TestItem item);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/jasper/GetJasperReportHandler.java b/src/main/java/com/epam/ta/reportportal/core/jasper/GetJasperReportHandler.java
index a25a69caf1..7cc882eb43 100644
--- a/src/main/java/com/epam/ta/reportportal/core/jasper/GetJasperReportHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/jasper/GetJasperReportHandler.java
@@ -17,11 +17,10 @@
 package com.epam.ta.reportportal.core.jasper;
 
 import com.epam.ta.reportportal.entity.jasper.ReportFormat;
-import net.sf.jasperreports.engine.JRDataSource;
-import net.sf.jasperreports.engine.JasperPrint;
-
 import java.io.OutputStream;
 import java.util.Map;
+import net.sf.jasperreports.engine.JRDataSource;
+import net.sf.jasperreports.engine.JasperPrint;
 
 /**
  * Get export reports utilities
@@ -30,36 +29,37 @@
  */
 public interface GetJasperReportHandler<T> {
 
-	/**
-	 * Generate rendered report representation.
-	 *
-	 * @param params     Parameters for Jasper view
-	 * @param dataSource Data for Jasper view
-	 * @return {@link JasperPrint}
-	 */
-	JasperPrint getJasperPrint(Map<String, Object> params, JRDataSource dataSource);
+  /**
+   * Generate rendered report representation.
+   *
+   * @param params     Parameters for Jasper view
+   * @param dataSource Data for Jasper view
+   * @return {@link JasperPrint}
+   */
+  JasperPrint getJasperPrint(Map<String, Object> params, JRDataSource dataSource);
 
-	/**
-	 * Finds report format and checks whether it's valid
-	 *
-	 * @param format ReportFormat
-	 */
-	ReportFormat getReportFormat(String format);
+  /**
+   * Finds report format and checks whether it's valid
+   *
+   * @param format ReportFormat
+   * @return {@link ReportFormat}
+   */
+  ReportFormat getReportFormat(String format);
 
-	/**
-	 * Convert rendered report to output stream.
-	 *
-	 * @param format       Report format
-	 * @param outputStream Stream report should be written to
-	 * @param jasperPrint  Report Data
-	 */
-	void writeReport(ReportFormat format, OutputStream outputStream, JasperPrint jasperPrint);
+  /**
+   * Convert rendered report to output stream.
+   *
+   * @param format       Report format
+   * @param outputStream Stream report should be written to
+   * @param jasperPrint  Report Data
+   */
+  void writeReport(ReportFormat format, OutputStream outputStream, JasperPrint jasperPrint);
 
-	/**
-	 * Convert entity parameters for {@link JasperPrint} creation
-	 *
-	 * @param entity Entity for report parameters retrieving
-	 * @return {@link Map} with Jasper column name as KEY and Launch parameter as VALUE
-	 */
-	Map<String, Object> convertParams(T entity);
+  /**
+   * Convert entity parameters for {@link JasperPrint} creation
+   *
+   * @param entity Entity for report parameters retrieving
+   * @return {@link Map} with Jasper column name as KEY and Launch parameter as VALUE
+   */
+  Map<String, Object> convertParams(T entity);
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/jasper/JasperReportRender.java b/src/main/java/com/epam/ta/reportportal/core/jasper/JasperReportRender.java
index 3cab70cd1e..935bc98258 100644
--- a/src/main/java/com/epam/ta/reportportal/core/jasper/JasperReportRender.java
+++ b/src/main/java/com/epam/ta/reportportal/core/jasper/JasperReportRender.java
@@ -15,9 +15,19 @@
  */
 package com.epam.ta.reportportal.core.jasper;
 
+import static com.google.common.base.Preconditions.checkArgument;
+
 import com.epam.ta.reportportal.entity.jasper.ReportType;
 import com.google.common.collect.ImmutableMap;
-import net.sf.jasperreports.engine.*;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+import net.sf.jasperreports.engine.JRDataSource;
+import net.sf.jasperreports.engine.JRException;
+import net.sf.jasperreports.engine.JasperCompileManager;
+import net.sf.jasperreports.engine.JasperFillManager;
+import net.sf.jasperreports.engine.JasperPrint;
+import net.sf.jasperreports.engine.JasperReport;
 import net.sf.jasperreports.engine.design.JasperDesign;
 import net.sf.jasperreports.engine.xml.JRXmlLoader;
 import org.slf4j.Logger;
@@ -27,61 +37,59 @@
 import org.springframework.core.io.ResourceLoader;
 import org.springframework.stereotype.Service;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Map;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
 /**
  * Jasper Report render based on provided JRXML template.<br>
  *
  * @author Andrei_Ramanchuk
- * @author Andrei Varabyeu
- * Performance improvements. Load JasperReport only once since it is immutable
+ * @author Andrei Varabyeu Performance improvements. Load JasperReport only once since it is
+ * immutable
  */
 @Service("jasperRender")
 public class JasperReportRender {
 
-	private static final Logger LOGGER = LoggerFactory.getLogger(JasperReportRender.class);
+  private static final Logger LOGGER = LoggerFactory.getLogger(JasperReportRender.class);
 
-	private static final String PROJECTS_REPORT_JRXML_TEMPLATE = "classpath:/templates/report/projects.jrxml";
-	private static final String USERS_REPORT_JRXML_TEMPLATE = "classpath:/templates/report/users.jrxml";
-	private static final String LAUNCH_REPORT_JRXML_TEMPLATE = "classpath:/templates/report/report.jrxml";
-	private static final Map<ReportType, String> reportTypeTemplatePathMapping = ImmutableMap.<ReportType, String>builder().put(ReportType.PROJECT,
-			PROJECTS_REPORT_JRXML_TEMPLATE
-	)
-			.put(ReportType.USER, USERS_REPORT_JRXML_TEMPLATE)
-			.put(ReportType.LAUNCH, LAUNCH_REPORT_JRXML_TEMPLATE)
-			.build();
+  private static final String PROJECTS_REPORT_JRXML_TEMPLATE = "classpath:/templates/report/projects.jrxml";
+  private static final String USERS_REPORT_JRXML_TEMPLATE = "classpath:/templates/report/users.jrxml";
+  private static final String LAUNCH_REPORT_JRXML_TEMPLATE = "classpath:/templates/report/report.jrxml";
+  private static final Map<ReportType, String> reportTypeTemplatePathMapping = ImmutableMap.<ReportType, String>builder()
+      .put(ReportType.PROJECT,
+          PROJECTS_REPORT_JRXML_TEMPLATE
+      )
+      .put(ReportType.USER, USERS_REPORT_JRXML_TEMPLATE)
+      .put(ReportType.LAUNCH, LAUNCH_REPORT_JRXML_TEMPLATE)
+      .build();
 
-	private final Map<ReportType, JasperReport> reportTemplatesMapping;
+  private final Map<ReportType, JasperReport> reportTemplatesMapping;
 
-	@Autowired
-	public JasperReportRender(ResourceLoader resourceLoader) throws JRException, IOException {
+  @Autowired
+  public JasperReportRender(ResourceLoader resourceLoader) throws JRException, IOException {
 
-		ImmutableMap.Builder<ReportType, JasperReport> reportTypeJasperReportBuilder = ImmutableMap.builder();
+    ImmutableMap.Builder<ReportType, JasperReport> reportTypeJasperReportBuilder = ImmutableMap.builder();
 
-		for (Map.Entry<ReportType, String> entry : reportTypeTemplatePathMapping.entrySet()) {
-			Resource reportTemplate = resourceLoader.getResource(entry.getValue());
-			checkArgument(reportTemplate.exists());
-			//TODO investigate stream closing requirement
-			InputStream inputStream = reportTemplate.getInputStream();
+    for (Map.Entry<ReportType, String> entry : reportTypeTemplatePathMapping.entrySet()) {
+      Resource reportTemplate = resourceLoader.getResource(entry.getValue());
+      checkArgument(reportTemplate.exists());
+      //TODO investigate stream closing requirement
+      InputStream inputStream = reportTemplate.getInputStream();
 
-			JasperDesign jasperDesign = JRXmlLoader.load(inputStream);
-			reportTypeJasperReportBuilder.put(entry.getKey(), JasperCompileManager.compileReport(jasperDesign));
-		}
+      JasperDesign jasperDesign = JRXmlLoader.load(inputStream);
+      reportTypeJasperReportBuilder.put(entry.getKey(),
+          JasperCompileManager.compileReport(jasperDesign));
+    }
 
-		reportTemplatesMapping = reportTypeJasperReportBuilder.build();
+    reportTemplatesMapping = reportTypeJasperReportBuilder.build();
 
-	}
+  }
 
-	public JasperPrint generateReportPrint(ReportType reportType, Map<String, Object> params, JRDataSource datasource) {
-		try {
-			return JasperFillManager.fillReport(reportTemplatesMapping.get(reportType), params, datasource);
-		} catch (JRException e) {
-			LOGGER.error("Unable to generate Report", e);
-			return new JasperPrint();
-		}
-	}
+  public JasperPrint generateReportPrint(ReportType reportType, Map<String, Object> params,
+      JRDataSource datasource) {
+    try {
+      return JasperFillManager.fillReport(reportTemplatesMapping.get(reportType), params,
+          datasource);
+    } catch (JRException e) {
+      LOGGER.error("Unable to generate Report", e);
+      return new JasperPrint();
+    }
+  }
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/jasper/TestItemPojo.java b/src/main/java/com/epam/ta/reportportal/core/jasper/TestItemPojo.java
index 2182fca10e..e36f902f0d 100644
--- a/src/main/java/com/epam/ta/reportportal/core/jasper/TestItemPojo.java
+++ b/src/main/java/com/epam/ta/reportportal/core/jasper/TestItemPojo.java
@@ -15,192 +15,211 @@
  */
 package com.epam.ta.reportportal.core.jasper;
 
+import static com.epam.ta.reportportal.core.events.activity.util.ActivityDetailsUtil.EMPTY_STRING;
+import static com.epam.ta.reportportal.core.jasper.util.ExportUtils.COMMENT_PREFIX;
+import static com.epam.ta.reportportal.core.jasper.util.ExportUtils.DESCRIPTION_PREFIX;
+import static com.epam.ta.reportportal.core.jasper.util.ExportUtils.adjustName;
+import static com.epam.ta.reportportal.core.jasper.util.ExportUtils.getStatisticsCounter;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DEFECTS_AUTOMATION_BUG_TOTAL;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DEFECTS_NO_DEFECT_TOTAL;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DEFECTS_PRODUCT_BUG_TOTAL;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DEFECTS_SYSTEM_ISSUE_TOTAL;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DEFECTS_TO_INVESTIGATE_TOTAL;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.EXECUTIONS_FAILED;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.EXECUTIONS_PASSED;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.EXECUTIONS_SKIPPED;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.EXECUTIONS_TOTAL;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.statistics.Statistics;
-
 import java.time.Duration;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
 
-import static com.epam.ta.reportportal.core.events.activity.util.ActivityDetailsUtil.EMPTY_STRING;
-import static com.epam.ta.reportportal.core.jasper.util.ExportUtils.*;
-import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.*;
-import static java.util.Optional.ofNullable;
-
 /**
  * Jasper Reports collection {@link TestItem} POJO
  *
  * @author Andrei_Ramanchuk
  */
 public class TestItemPojo {
-	private String type;
-	private String name;
-	private String status;
-	private Double duration;
-	private Integer total;
-	private Integer passed;
-	private Integer failed;
-	private Integer skipped;
-	private Integer automationBug;
-	private Integer productBug;
-	private Integer systemIssue;
-	private Integer noDefect;
-	private Integer toInvestigate;
-
-	public TestItemPojo(TestItem input) {
-		this.type = input.getType().name();
-		Optional<String> issueDescription = Optional.empty();
-		if (input.getItemResults().getIssue() != null) {
-			issueDescription = ofNullable(input.getItemResults().getIssue().getIssueDescription()).map(it -> COMMENT_PREFIX + it);
-		}
-
-		Optional<String> description = ofNullable(input.getDescription()).map(it -> DESCRIPTION_PREFIX + it);
-
-		this.name = adjustName(input) + description.orElse(EMPTY_STRING) + issueDescription.orElse(EMPTY_STRING);
-		this.status = input.getItemResults().getStatus().name();
-
-		this.duration = Duration.between(input.getStartTime(), input.getItemResults().getEndTime()).toMillis()
-				/ (double) org.apache.commons.lang3.time.DateUtils.MILLIS_PER_SECOND;
-
-		Set<Statistics> statistics = input.getItemResults().getStatistics();
-
-		this.total = getStatisticsCounter(statistics, EXECUTIONS_TOTAL);
-		this.passed = getStatisticsCounter(statistics, EXECUTIONS_PASSED);
-		this.failed = getStatisticsCounter(statistics, EXECUTIONS_FAILED);
-		this.skipped = getStatisticsCounter(statistics, EXECUTIONS_SKIPPED);
-
-		this.automationBug = getStatisticsCounter(statistics, DEFECTS_AUTOMATION_BUG_TOTAL);
-		this.productBug = getStatisticsCounter(statistics, DEFECTS_PRODUCT_BUG_TOTAL);
-		this.systemIssue = getStatisticsCounter(statistics, DEFECTS_SYSTEM_ISSUE_TOTAL);
-		this.noDefect = getStatisticsCounter(statistics, DEFECTS_NO_DEFECT_TOTAL);
-		this.toInvestigate = getStatisticsCounter(statistics, DEFECTS_TO_INVESTIGATE_TOTAL);
-	}
-
-	public void setType(String value) {
-		this.type = value;
-	}
-
-	public String getType() {
-		return type;
-	}
-
-	public void setName(String value) {
-		this.name = value;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public void setStatus(String value) {
-		this.status = value;
-	}
-
-	public String getStatus() {
-		return status;
-	}
-
-	public void setTotal(Integer value) {
-		this.total = value;
-	}
-
-	public Integer getTotal() {
-		return total;
-	}
-
-	public void setPased(Integer value) {
-		this.passed = value;
-	}
-
-	public Integer getPassed() {
-		return passed;
-	}
-
-	public void setFailed(Integer value) {
-		this.failed = value;
-	}
-
-	public Integer getFailed() {
-		return failed;
-	}
-
-	public void setSkipped(Integer value) {
-		this.skipped = value;
-	}
-
-	public Integer getSkipped() {
-		return skipped;
-	}
-
-	public void setAutomationBug(Integer value) {
-		this.automationBug = value;
-	}
-
-	public Integer getAutomationBug() {
-		return automationBug;
-	}
-
-	public void setProductBug(Integer value) {
-		this.productBug = value;
-	}
-
-	public Integer getProductBug() {
-		return productBug;
-	}
-
-	public void setSystemIssue(Integer value) {
-		this.systemIssue = value;
-	}
-
-	public Integer getSystemIssue() {
-		return systemIssue;
-	}
-
-	public void setNoDefect(Integer value) {
-		this.noDefect = value;
-	}
-
-	public Integer getNoDefect() {
-		return noDefect;
-	}
-
-	public void setToInvestigate(Integer value) {
-		this.toInvestigate = value;
-	}
-
-	public Integer getToInvestigate() {
-		return toInvestigate;
-	}
-
-	public Double getDuration() {
-		return duration;
-	}
-
-	public void setDuration(Double duration) {
-		this.duration = duration;
-	}
-
-	public void setPassed(Integer passed) {
-		this.passed = passed;
-	}
-
-	@Override
-	public String toString() {
-		final StringBuilder sb = new StringBuilder("TestItemPojo{");
-		sb.append("type='").append(type).append('\'');
-		sb.append(", name='").append(name).append('\'');
-		sb.append(", status='").append(status).append('\'');
-		sb.append(", duration=").append(duration);
-		sb.append(", total=").append(total);
-		sb.append(", passed=").append(passed);
-		sb.append(", failed=").append(failed);
-		sb.append(", skipped=").append(skipped);
-		sb.append(", automationBug=").append(automationBug);
-		sb.append(", productBug=").append(productBug);
-		sb.append(", systemIssue=").append(systemIssue);
-		sb.append(", noDefect=").append(noDefect);
-		sb.append(", toInvestigate=").append(toInvestigate);
-		sb.append('}');
-		return sb.toString();
-	}
+
+  private String type;
+  private String name;
+  private String status;
+  private Double duration;
+  private Integer total;
+  private Integer passed;
+  private Integer failed;
+  private Integer skipped;
+  private Integer automationBug;
+  private Integer productBug;
+  private Integer systemIssue;
+  private Integer noDefect;
+  private Integer toInvestigate;
+
+  private static final Double EMPTY_DURATION = 0D;
+
+  public TestItemPojo(TestItem input) {
+    this.type = input.getType().name();
+    Optional<String> issueDescription = Optional.empty();
+    if (input.getItemResults().getIssue() != null) {
+      issueDescription = ofNullable(input.getItemResults().getIssue().getIssueDescription()).map(
+          it -> COMMENT_PREFIX + it);
+    }
+
+    Optional<String> description = ofNullable(input.getDescription()).map(
+        it -> DESCRIPTION_PREFIX + it);
+
+    this.name = adjustName(input) + description.orElse(EMPTY_STRING) + issueDescription.orElse(
+        EMPTY_STRING);
+    this.status = input.getItemResults().getStatus().name();
+
+    this.duration = Objects.nonNull(input.getItemResults().getEndTime()) ?
+        Duration.between(input.getStartTime(), input.getItemResults().getEndTime()).toMillis()
+            / (double) org.apache.commons.lang3.time.DateUtils.MILLIS_PER_SECOND :
+        EMPTY_DURATION;
+
+    Set<Statistics> statistics = input.getItemResults().getStatistics();
+
+    this.total = getStatisticsCounter(statistics, EXECUTIONS_TOTAL);
+    this.passed = getStatisticsCounter(statistics, EXECUTIONS_PASSED);
+    this.failed = getStatisticsCounter(statistics, EXECUTIONS_FAILED);
+    this.skipped = getStatisticsCounter(statistics, EXECUTIONS_SKIPPED);
+
+    this.automationBug = getStatisticsCounter(statistics, DEFECTS_AUTOMATION_BUG_TOTAL);
+    this.productBug = getStatisticsCounter(statistics, DEFECTS_PRODUCT_BUG_TOTAL);
+    this.systemIssue = getStatisticsCounter(statistics, DEFECTS_SYSTEM_ISSUE_TOTAL);
+    this.noDefect = getStatisticsCounter(statistics, DEFECTS_NO_DEFECT_TOTAL);
+    this.toInvestigate = getStatisticsCounter(statistics, DEFECTS_TO_INVESTIGATE_TOTAL);
+  }
+
+  public void setType(String value) {
+    this.type = value;
+  }
+
+  public String getType() {
+    return type;
+  }
+
+  public void setName(String value) {
+    this.name = value;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public void setStatus(String value) {
+    this.status = value;
+  }
+
+  public String getStatus() {
+    return status;
+  }
+
+  public void setTotal(Integer value) {
+    this.total = value;
+  }
+
+  public Integer getTotal() {
+    return total;
+  }
+
+  public void setPased(Integer value) {
+    this.passed = value;
+  }
+
+  public Integer getPassed() {
+    return passed;
+  }
+
+  public void setFailed(Integer value) {
+    this.failed = value;
+  }
+
+  public Integer getFailed() {
+    return failed;
+  }
+
+  public void setSkipped(Integer value) {
+    this.skipped = value;
+  }
+
+  public Integer getSkipped() {
+    return skipped;
+  }
+
+  public void setAutomationBug(Integer value) {
+    this.automationBug = value;
+  }
+
+  public Integer getAutomationBug() {
+    return automationBug;
+  }
+
+  public void setProductBug(Integer value) {
+    this.productBug = value;
+  }
+
+  public Integer getProductBug() {
+    return productBug;
+  }
+
+  public void setSystemIssue(Integer value) {
+    this.systemIssue = value;
+  }
+
+  public Integer getSystemIssue() {
+    return systemIssue;
+  }
+
+  public void setNoDefect(Integer value) {
+    this.noDefect = value;
+  }
+
+  public Integer getNoDefect() {
+    return noDefect;
+  }
+
+  public void setToInvestigate(Integer value) {
+    this.toInvestigate = value;
+  }
+
+  public Integer getToInvestigate() {
+    return toInvestigate;
+  }
+
+  public Double getDuration() {
+    return duration;
+  }
+
+  public void setDuration(Double duration) {
+    this.duration = duration;
+  }
+
+  public void setPassed(Integer passed) {
+    this.passed = passed;
+  }
+
+  @Override
+  public String toString() {
+    final StringBuilder sb = new StringBuilder("TestItemPojo{");
+    sb.append("type='").append(type).append('\'');
+    sb.append(", name='").append(name).append('\'');
+    sb.append(", status='").append(status).append('\'');
+    sb.append(", duration=").append(duration);
+    sb.append(", total=").append(total);
+    sb.append(", passed=").append(passed);
+    sb.append(", failed=").append(failed);
+    sb.append(", skipped=").append(skipped);
+    sb.append(", automationBug=").append(automationBug);
+    sb.append(", productBug=").append(productBug);
+    sb.append(", systemIssue=").append(systemIssue);
+    sb.append(", noDefect=").append(noDefect);
+    sb.append(", toInvestigate=").append(toInvestigate);
+    sb.append('}');
+    return sb.toString();
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/jasper/constants/LaunchReportConstants.java b/src/main/java/com/epam/ta/reportportal/core/jasper/constants/LaunchReportConstants.java
index ec4828f5b7..046321f8d5 100644
--- a/src/main/java/com/epam/ta/reportportal/core/jasper/constants/LaunchReportConstants.java
+++ b/src/main/java/com/epam/ta/reportportal/core/jasper/constants/LaunchReportConstants.java
@@ -21,30 +21,30 @@
  */
 public final class LaunchReportConstants {
 
-	/* Defined fields in JRXML template */
-	public final static String LAUNCH_NAME = "LAUNCH_NAME";
-	public final static String LAUNCH_DESC = "LAUNCH_DESCRIPTION";
-	public final static String LAUNCH_TAGS = "LAUNCH_TAGS";
-	public final static String DURATION = "LAUNCH_DURATION";
-	public final static String OWNER = "LAUNCH_OWNER";
+  /* Defined fields in JRXML template */
+  public final static String LAUNCH_NAME = "LAUNCH_NAME";
+  public final static String LAUNCH_DESC = "LAUNCH_DESCRIPTION";
+  public final static String LAUNCH_TAGS = "LAUNCH_TAGS";
+  public final static String DURATION = "LAUNCH_DURATION";
+  public final static String OWNER = "LAUNCH_OWNER";
 
-	/* Launch statistics fields */
-	// TODO could be inject in report as DataSource
-	public final static String TOTAL = "TOTAL";
-	public final static String PASSED = "PASSED";
-	public final static String FAILED = "FAILED";
-	public final static String SKIPPED = "SKIPPED";
-	public final static String AB = "AB";
-	public final static String PB = "PB";
-	public final static String SI = "SI";
-	public final static String ND = "ND";
-	public final static String TI = "TI";
+  /* Launch statistics fields */
+  // TODO could be inject in report as DataSource
+  public final static String TOTAL = "TOTAL";
+  public final static String PASSED = "PASSED";
+  public final static String FAILED = "FAILED";
+  public final static String SKIPPED = "SKIPPED";
+  public final static String AB = "AB";
+  public final static String PB = "PB";
+  public final static String SI = "SI";
+  public final static String ND = "ND";
+  public final static String TI = "TI";
 
-	/* Data sets */
-	public final static String TEST_ITEMS = "TEST_ITEMS";
+  /* Data sets */
+  public final static String TEST_ITEMS = "TEST_ITEMS";
 
-	public LaunchReportConstants() {
+  public LaunchReportConstants() {
 
-		//static only
-	}
+    //static only
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/jasper/constants/ProjectReportConstants.java b/src/main/java/com/epam/ta/reportportal/core/jasper/constants/ProjectReportConstants.java
index 92c3631ba8..09261b81d7 100644
--- a/src/main/java/com/epam/ta/reportportal/core/jasper/constants/ProjectReportConstants.java
+++ b/src/main/java/com/epam/ta/reportportal/core/jasper/constants/ProjectReportConstants.java
@@ -21,15 +21,15 @@
  */
 public final class ProjectReportConstants {
 
-	public static final String PROJECT_TYPE = "Project type";
-	public static final String PROJECT_NAME = "Project name";
-	public static final String ORGANIZATION = "Organization";
-	public static final String MEMBERS = "Members";
-	public static final String LAUNCHES = "Launches";
-	public static final String LAST_LAUNCH_DATE = "Last launch date";
+  public static final String PROJECT_TYPE = "Project type";
+  public static final String PROJECT_NAME = "Project name";
+  public static final String ORGANIZATION = "Organization";
+  public static final String MEMBERS = "Members";
+  public static final String LAUNCHES = "Launches";
+  public static final String LAST_LAUNCH_DATE = "Last launch date";
 
-	private ProjectReportConstants() {
+  private ProjectReportConstants() {
 
-		//static only
-	}
+    //static only
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/jasper/constants/UserReportConstants.java b/src/main/java/com/epam/ta/reportportal/core/jasper/constants/UserReportConstants.java
index 4247de7f81..49eae54d8b 100644
--- a/src/main/java/com/epam/ta/reportportal/core/jasper/constants/UserReportConstants.java
+++ b/src/main/java/com/epam/ta/reportportal/core/jasper/constants/UserReportConstants.java
@@ -21,15 +21,15 @@
  */
 public final class UserReportConstants {
 
-	public static final String FULL_NAME = "Full name";
-	public static final String TYPE = "Type";
-	public static final String LOGIN = "Login";
-	public static final String EMAIL = "Email";
-	public static final String LAST_LOGIN = "Last login";
-	public static final String PROJECTS_AND_ROLES = "Projects and Roles";
+  public static final String FULL_NAME = "Full name";
+  public static final String TYPE = "Type";
+  public static final String LOGIN = "Login";
+  public static final String EMAIL = "Email";
+  public static final String LAST_LOGIN = "Last login";
+  public static final String PROJECTS_AND_ROLES = "Projects and Roles";
 
-	private UserReportConstants() {
+  private UserReportConstants() {
 
-		//static only
-	}
+    //static only
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/jasper/impl/AbstractJasperReportHandler.java b/src/main/java/com/epam/ta/reportportal/core/jasper/impl/AbstractJasperReportHandler.java
index 9292842043..73773ec557 100644
--- a/src/main/java/com/epam/ta/reportportal/core/jasper/impl/AbstractJasperReportHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/jasper/impl/AbstractJasperReportHandler.java
@@ -15,27 +15,33 @@
  */
 package com.epam.ta.reportportal.core.jasper.impl;
 
+import static com.epam.ta.reportportal.ws.model.ErrorType.BAD_REQUEST_ERROR;
+
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.commons.validation.Suppliers;
 import com.epam.ta.reportportal.core.jasper.GetJasperReportHandler;
 import com.epam.ta.reportportal.entity.jasper.ReportFormat;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.io.OutputStream;
+import java.util.Set;
 import net.sf.jasperreports.engine.JRException;
 import net.sf.jasperreports.engine.JasperExportManager;
 import net.sf.jasperreports.engine.JasperPrint;
 import net.sf.jasperreports.engine.export.HtmlExporter;
 import net.sf.jasperreports.engine.export.JRCsvExporter;
 import net.sf.jasperreports.engine.export.JRXlsExporter;
-import net.sf.jasperreports.export.*;
+import net.sf.jasperreports.export.HtmlExporterOutput;
+import net.sf.jasperreports.export.SimpleCsvExporterConfiguration;
+import net.sf.jasperreports.export.SimpleExporterInput;
+import net.sf.jasperreports.export.SimpleHtmlExporterOutput;
+import net.sf.jasperreports.export.SimpleHtmlReportConfiguration;
+import net.sf.jasperreports.export.SimpleOutputStreamExporterOutput;
+import net.sf.jasperreports.export.SimpleWriterExporterOutput;
+import net.sf.jasperreports.export.SimpleXlsReportConfiguration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.OutputStream;
-import java.util.Set;
-
-import static com.epam.ta.reportportal.ws.model.ErrorType.BAD_REQUEST_ERROR;
-
 /**
  * Jasper Reports provider. Basic implementation of
  * {@link com.epam.ta.reportportal.core.jasper.GetJasperReportHandler}
@@ -43,85 +49,88 @@
  * @author Andrei_Ramanchuk
  */
 public abstract class AbstractJasperReportHandler<T> implements GetJasperReportHandler<T> {
-	private static final Logger LOGGER = LoggerFactory.getLogger(AbstractJasperReportHandler.class);
-
-	private final String unsupportedReportFormatExceptionMessage;
-
-	public AbstractJasperReportHandler(String unsupportedReportFormatExceptionMessage) {
-
-		this.unsupportedReportFormatExceptionMessage = unsupportedReportFormatExceptionMessage;
-	}
-
-	@Override
-	public ReportFormat getReportFormat(String view) {
-		ReportFormat reportFormat = ReportFormat.findByName(view)
-				.orElseThrow(() -> new ReportPortalException(BAD_REQUEST_ERROR,
-						Suppliers.formattedSupplier("Unexpected report format: {}", view)
-				));
-
-		BusinessRule.expect(reportFormat, getAvailableReportFormats()::contains)
-				.verify(ErrorType.BAD_REQUEST_ERROR,
-						Suppliers.formattedSupplier(unsupportedReportFormatExceptionMessage, reportFormat.name())
-				);
-
-		return reportFormat;
-	}
-
-	@Override
-	public void writeReport(ReportFormat format, OutputStream outputStream, JasperPrint jasperPrint) {
-		try {
-			switch (format) {
-				case PDF:
-					JasperExportManager.exportReportToPdfStream(jasperPrint, outputStream);
-					break;
-				case HTML:
-					HtmlExporter exporter = new HtmlExporter();
-					exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
-					HtmlExporterOutput exporterOutput = new SimpleHtmlExporterOutput(outputStream);
-					exporter.setExporterOutput(exporterOutput);
-
-					SimpleHtmlReportConfiguration htmlConfig = new SimpleHtmlReportConfiguration();
-					htmlConfig.setWhitePageBackground(false);
-					htmlConfig.setRemoveEmptySpaceBetweenRows(true);
-					exporter.setConfiguration(htmlConfig);
-					exporter.exportReport();
-					break;
-				case XLS:
-					SimpleXlsReportConfiguration configuration = new SimpleXlsReportConfiguration();
-					configuration.setOnePagePerSheet(false);
-					configuration.setDetectCellType(true);
-					configuration.setCollapseRowSpan(false);
-					configuration.setIgnoreGraphics(true);
-
-					JRXlsExporter exporterXLS = new JRXlsExporter();
-					exporterXLS.setExporterInput(new SimpleExporterInput(jasperPrint));
-					exporterXLS.setExporterOutput(new SimpleOutputStreamExporterOutput(outputStream));
-					exporterXLS.setConfiguration(configuration);
-					exporterXLS.exportReport();
-					break;
-				case CSV:
-
-					JRCsvExporter jrCsvExporter = new JRCsvExporter();
-					jrCsvExporter.setExporterInput(new SimpleExporterInput(jasperPrint));
-					jrCsvExporter.setExporterOutput(new SimpleWriterExporterOutput(outputStream));
-					SimpleCsvExporterConfiguration csvExporterConfiguration = new SimpleCsvExporterConfiguration();
-					jrCsvExporter.setConfiguration(csvExporterConfiguration);
-					jrCsvExporter.exportReport();
-					break;
-				default:
-					throw new UnsupportedOperationException(format.getValue());
-			}
-
-		} catch (JRException ex) {
-			LOGGER.error("Unable to generate report!", ex);
-			BusinessRule.fail()
-					.withError(ErrorType.FORBIDDEN_OPERATION,
-							Suppliers.formattedSupplier(" Unexpected issue during report output stream creation: {}",
-									ex.getLocalizedMessage()
-							)
-					);
-		}
-	}
-
-	public abstract Set<ReportFormat> getAvailableReportFormats();
+
+  private static final Logger LOGGER = LoggerFactory.getLogger(AbstractJasperReportHandler.class);
+
+  private final String unsupportedReportFormatExceptionMessage;
+
+  public AbstractJasperReportHandler(String unsupportedReportFormatExceptionMessage) {
+
+    this.unsupportedReportFormatExceptionMessage = unsupportedReportFormatExceptionMessage;
+  }
+
+  @Override
+  public ReportFormat getReportFormat(String view) {
+    ReportFormat reportFormat = ReportFormat.findByName(view)
+        .orElseThrow(() -> new ReportPortalException(BAD_REQUEST_ERROR,
+            Suppliers.formattedSupplier("Unexpected report format: {}", view)
+        ));
+
+    BusinessRule.expect(reportFormat, getAvailableReportFormats()::contains)
+        .verify(ErrorType.BAD_REQUEST_ERROR,
+            Suppliers.formattedSupplier(unsupportedReportFormatExceptionMessage,
+                reportFormat.name())
+        );
+
+    return reportFormat;
+  }
+
+  @Override
+  public void writeReport(ReportFormat format, OutputStream outputStream, JasperPrint jasperPrint) {
+    try {
+      switch (format) {
+        case PDF:
+          JasperExportManager.exportReportToPdfStream(jasperPrint, outputStream);
+          break;
+        case HTML:
+          HtmlExporter exporter = new HtmlExporter();
+          exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
+          HtmlExporterOutput exporterOutput = new SimpleHtmlExporterOutput(outputStream);
+          exporter.setExporterOutput(exporterOutput);
+
+          SimpleHtmlReportConfiguration htmlConfig = new SimpleHtmlReportConfiguration();
+          htmlConfig.setWhitePageBackground(false);
+          htmlConfig.setRemoveEmptySpaceBetweenRows(true);
+          exporter.setConfiguration(htmlConfig);
+          exporter.exportReport();
+          break;
+        case XLS:
+          SimpleXlsReportConfiguration configuration = new SimpleXlsReportConfiguration();
+          configuration.setOnePagePerSheet(false);
+          configuration.setDetectCellType(true);
+          configuration.setCollapseRowSpan(false);
+          configuration.setIgnoreGraphics(true);
+
+          JRXlsExporter exporterXLS = new JRXlsExporter();
+          exporterXLS.setExporterInput(new SimpleExporterInput(jasperPrint));
+          exporterXLS.setExporterOutput(new SimpleOutputStreamExporterOutput(outputStream));
+          exporterXLS.setConfiguration(configuration);
+          exporterXLS.exportReport();
+          break;
+        case CSV:
+
+          JRCsvExporter jrCsvExporter = new JRCsvExporter();
+          jrCsvExporter.setExporterInput(new SimpleExporterInput(jasperPrint));
+          jrCsvExporter.setExporterOutput(new SimpleWriterExporterOutput(outputStream));
+          SimpleCsvExporterConfiguration csvExporterConfiguration = new SimpleCsvExporterConfiguration();
+          jrCsvExporter.setConfiguration(csvExporterConfiguration);
+          jrCsvExporter.exportReport();
+          break;
+        default:
+          throw new UnsupportedOperationException(format.getValue());
+      }
+
+    } catch (JRException ex) {
+      LOGGER.error("Unable to generate report!", ex);
+      BusinessRule.fail()
+          .withError(ErrorType.FORBIDDEN_OPERATION,
+              Suppliers.formattedSupplier(
+                  " Unexpected issue during report output stream creation: {}",
+                  ex.getLocalizedMessage()
+              )
+          );
+    }
+  }
+
+  public abstract Set<ReportFormat> getAvailableReportFormats();
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/jasper/impl/LaunchJasperReportHandler.java b/src/main/java/com/epam/ta/reportportal/core/jasper/impl/LaunchJasperReportHandler.java
index fd6137ea12..35f5dad48f 100644
--- a/src/main/java/com/epam/ta/reportportal/core/jasper/impl/LaunchJasperReportHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/jasper/impl/LaunchJasperReportHandler.java
@@ -16,6 +16,17 @@
 
 package com.epam.ta.reportportal.core.jasper.impl;
 
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DEFECTS_AUTOMATION_BUG_TOTAL;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DEFECTS_NO_DEFECT_TOTAL;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DEFECTS_PRODUCT_BUG_TOTAL;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DEFECTS_SYSTEM_ISSUE_TOTAL;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DEFECTS_TO_INVESTIGATE_TOTAL;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.EXECUTIONS_FAILED;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.EXECUTIONS_PASSED;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.EXECUTIONS_SKIPPED;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.EXECUTIONS_TOTAL;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.core.jasper.JasperReportRender;
 import com.epam.ta.reportportal.core.jasper.constants.LaunchReportConstants;
 import com.epam.ta.reportportal.core.jasper.util.ExportUtils;
@@ -24,20 +35,16 @@
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.entity.statistics.Statistics;
 import com.google.common.collect.Sets;
-import net.sf.jasperreports.engine.JRDataSource;
-import net.sf.jasperreports.engine.JasperPrint;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
 import java.time.Duration;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.*;
-import static java.util.Optional.ofNullable;
+import net.sf.jasperreports.engine.JRDataSource;
+import net.sf.jasperreports.engine.JasperPrint;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -45,60 +52,72 @@
 @Service("launchJasperReportHandler")
 public class LaunchJasperReportHandler extends AbstractJasperReportHandler<Launch> {
 
-	private static final String UNSUPPORTED_REPORT_FORMAT_MESSAGE_EXCEPTION = "Report format - {} is not supported for launch reports.";
-
-	private final Set<ReportFormat> availableReportFormats;
-
-	private final JasperReportRender reportRender;
-
-	@Autowired
-	public LaunchJasperReportHandler(JasperReportRender reportRender) {
-		super(UNSUPPORTED_REPORT_FORMAT_MESSAGE_EXCEPTION);
-		this.reportRender = reportRender;
-		availableReportFormats = Sets.immutableEnumSet(ReportFormat.HTML, ReportFormat.PDF, ReportFormat.XLS);
-	}
-
-	@Override
-	public JasperPrint getJasperPrint(Map<String, Object> params, JRDataSource dataSource) {
-
-		return reportRender.generateReportPrint(ReportType.LAUNCH, params, dataSource);
-	}
-
-	@Override
-	public Map<String, Object> convertParams(Launch launch) {
-		Map<String, Object> params = new HashMap<>();
-
-		params.put(LaunchReportConstants.LAUNCH_NAME, launch.getName() + " #" + launch.getNumber());
-		params.put(LaunchReportConstants.LAUNCH_DESC, launch.getDescription() == null ? "" : launch.getDescription());
-		params.put(LaunchReportConstants.LAUNCH_TAGS,
-				launch.getAttributes()
-						.stream()
-						.map(it -> it.getKey() == null ? it.getValue() : it.getKey().concat(it.getValue()))
-						.collect(Collectors.toList())
-		);
-
-		String duration = ofNullable(launch.getEndTime()).map(endTime -> ExportUtils.durationToShortDHMS(
-				Duration.between(launch.getStartTime(), endTime))).orElse(StringUtils.EMPTY);
-		params.put(LaunchReportConstants.DURATION, duration);
-
-		Set<Statistics> statistics = launch.getStatistics();
-		params.put(LaunchReportConstants.TOTAL, ExportUtils.getStatisticsCounter(statistics, EXECUTIONS_TOTAL));
-		params.put(LaunchReportConstants.PASSED, ExportUtils.getStatisticsCounter(statistics, EXECUTIONS_PASSED));
-		params.put(LaunchReportConstants.FAILED, ExportUtils.getStatisticsCounter(statistics, EXECUTIONS_FAILED));
-		params.put(LaunchReportConstants.SKIPPED, ExportUtils.getStatisticsCounter(statistics, EXECUTIONS_SKIPPED));
-
-		params.put(LaunchReportConstants.AB, ExportUtils.getStatisticsCounter(statistics, DEFECTS_AUTOMATION_BUG_TOTAL));
-		params.put(LaunchReportConstants.PB, ExportUtils.getStatisticsCounter(statistics, DEFECTS_PRODUCT_BUG_TOTAL));
-		params.put(LaunchReportConstants.SI, ExportUtils.getStatisticsCounter(statistics, DEFECTS_SYSTEM_ISSUE_TOTAL));
-		params.put(LaunchReportConstants.ND, ExportUtils.getStatisticsCounter(statistics, DEFECTS_NO_DEFECT_TOTAL));
-		params.put(LaunchReportConstants.TI, ExportUtils.getStatisticsCounter(statistics, DEFECTS_TO_INVESTIGATE_TOTAL));
-
-		return params;
-	}
-
-	@Override
-	public Set<ReportFormat> getAvailableReportFormats() {
-		return availableReportFormats;
-	}
+  private static final String UNSUPPORTED_REPORT_FORMAT_MESSAGE_EXCEPTION = "Report format - {} is not supported for launch reports.";
+
+  private final Set<ReportFormat> availableReportFormats;
+
+  private final JasperReportRender reportRender;
+
+  @Autowired
+  public LaunchJasperReportHandler(JasperReportRender reportRender) {
+    super(UNSUPPORTED_REPORT_FORMAT_MESSAGE_EXCEPTION);
+    this.reportRender = reportRender;
+    availableReportFormats = Sets.immutableEnumSet(ReportFormat.HTML, ReportFormat.PDF,
+        ReportFormat.XLS);
+  }
+
+  @Override
+  public JasperPrint getJasperPrint(Map<String, Object> params, JRDataSource dataSource) {
+
+    return reportRender.generateReportPrint(ReportType.LAUNCH, params, dataSource);
+  }
+
+  @Override
+  public Map<String, Object> convertParams(Launch launch) {
+    Map<String, Object> params = new HashMap<>();
+
+    params.put(LaunchReportConstants.LAUNCH_NAME, launch.getName() + " #" + launch.getNumber());
+    params.put(LaunchReportConstants.LAUNCH_DESC,
+        launch.getDescription() == null ? "" : launch.getDescription());
+    params.put(LaunchReportConstants.LAUNCH_TAGS,
+        launch.getAttributes()
+            .stream()
+            .map(it -> it.getKey() == null ? it.getValue() : it.getKey().concat(it.getValue()))
+            .collect(Collectors.toList())
+    );
+
+    String duration = ofNullable(launch.getEndTime()).map(
+        endTime -> ExportUtils.durationToShortDHMS(
+            Duration.between(launch.getStartTime(), endTime))).orElse(StringUtils.EMPTY);
+    params.put(LaunchReportConstants.DURATION, duration);
+
+    Set<Statistics> statistics = launch.getStatistics();
+    params.put(LaunchReportConstants.TOTAL,
+        ExportUtils.getStatisticsCounter(statistics, EXECUTIONS_TOTAL));
+    params.put(LaunchReportConstants.PASSED,
+        ExportUtils.getStatisticsCounter(statistics, EXECUTIONS_PASSED));
+    params.put(LaunchReportConstants.FAILED,
+        ExportUtils.getStatisticsCounter(statistics, EXECUTIONS_FAILED));
+    params.put(LaunchReportConstants.SKIPPED,
+        ExportUtils.getStatisticsCounter(statistics, EXECUTIONS_SKIPPED));
+
+    params.put(LaunchReportConstants.AB,
+        ExportUtils.getStatisticsCounter(statistics, DEFECTS_AUTOMATION_BUG_TOTAL));
+    params.put(LaunchReportConstants.PB,
+        ExportUtils.getStatisticsCounter(statistics, DEFECTS_PRODUCT_BUG_TOTAL));
+    params.put(LaunchReportConstants.SI,
+        ExportUtils.getStatisticsCounter(statistics, DEFECTS_SYSTEM_ISSUE_TOTAL));
+    params.put(LaunchReportConstants.ND,
+        ExportUtils.getStatisticsCounter(statistics, DEFECTS_NO_DEFECT_TOTAL));
+    params.put(LaunchReportConstants.TI,
+        ExportUtils.getStatisticsCounter(statistics, DEFECTS_TO_INVESTIGATE_TOTAL));
+
+    return params;
+  }
+
+  @Override
+  public Set<ReportFormat> getAvailableReportFormats() {
+    return availableReportFormats;
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/jasper/impl/ProjectJasperReportHandler.java b/src/main/java/com/epam/ta/reportportal/core/jasper/impl/ProjectJasperReportHandler.java
index c0e85ca925..8d058df594 100644
--- a/src/main/java/com/epam/ta/reportportal/core/jasper/impl/ProjectJasperReportHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/jasper/impl/ProjectJasperReportHandler.java
@@ -16,26 +16,25 @@
 
 package com.epam.ta.reportportal.core.jasper.impl;
 
+import static com.epam.ta.reportportal.core.events.activity.util.ActivityDetailsUtil.EMPTY_STRING;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.core.jasper.JasperReportRender;
 import com.epam.ta.reportportal.core.jasper.constants.ProjectReportConstants;
 import com.epam.ta.reportportal.entity.jasper.ReportFormat;
 import com.epam.ta.reportportal.entity.jasper.ReportType;
 import com.epam.ta.reportportal.entity.project.ProjectInfo;
 import com.google.common.collect.Sets;
-import net.sf.jasperreports.engine.JRDataSource;
-import net.sf.jasperreports.engine.JasperPrint;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
-
-import static com.epam.ta.reportportal.core.events.activity.util.ActivityDetailsUtil.EMPTY_STRING;
-import static java.util.Optional.ofNullable;
+import net.sf.jasperreports.engine.JRDataSource;
+import net.sf.jasperreports.engine.JasperPrint;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -43,44 +42,46 @@
 @Service("projectJasperReportHandler")
 public class ProjectJasperReportHandler extends AbstractJasperReportHandler<ProjectInfo> {
 
-	private static final String UNSUPPORTED_REPORT_FORMAT_MESSAGE_EXCEPTION = "Report format - {} is not supported for project reports.";
+  private static final String UNSUPPORTED_REPORT_FORMAT_MESSAGE_EXCEPTION = "Report format - {} is not supported for project reports.";
 
-	private final Set<ReportFormat> availableReportFormats;
+  private final Set<ReportFormat> availableReportFormats;
 
-	private final JasperReportRender reportRender;
+  private final JasperReportRender reportRender;
 
-	@Autowired
-	public ProjectJasperReportHandler(JasperReportRender reportRender) {
-		super(UNSUPPORTED_REPORT_FORMAT_MESSAGE_EXCEPTION);
-		this.reportRender = reportRender;
-		availableReportFormats = Sets.immutableEnumSet(ReportFormat.CSV);
-	}
+  @Autowired
+  public ProjectJasperReportHandler(JasperReportRender reportRender) {
+    super(UNSUPPORTED_REPORT_FORMAT_MESSAGE_EXCEPTION);
+    this.reportRender = reportRender;
+    availableReportFormats = Sets.immutableEnumSet(ReportFormat.CSV);
+  }
 
-	@Override
-	public JasperPrint getJasperPrint(Map<String, Object> params, JRDataSource dataSource) {
+  @Override
+  public JasperPrint getJasperPrint(Map<String, Object> params, JRDataSource dataSource) {
 
-		return reportRender.generateReportPrint(ReportType.PROJECT, params, dataSource);
-	}
+    return reportRender.generateReportPrint(ReportType.PROJECT, params, dataSource);
+  }
 
-	@Override
-	public Map<String, Object> convertParams(ProjectInfo project) {
-		Map<String, Object> params = new HashMap<>();
+  @Override
+  public Map<String, Object> convertParams(ProjectInfo project) {
+    Map<String, Object> params = new HashMap<>();
 
-		params.put(ProjectReportConstants.PROJECT_TYPE, project.getProjectType());
-		params.put(ProjectReportConstants.PROJECT_NAME, project.getName());
-		params.put(ProjectReportConstants.ORGANIZATION, ofNullable(project.getOrganization()).orElse(EMPTY_STRING));
-		params.put(ProjectReportConstants.MEMBERS, project.getUsersQuantity());
-		params.put(ProjectReportConstants.LAUNCHES, project.getLaunchesQuantity());
+    params.put(ProjectReportConstants.PROJECT_TYPE, project.getProjectType());
+    params.put(ProjectReportConstants.PROJECT_NAME, project.getName());
+    params.put(ProjectReportConstants.ORGANIZATION,
+        ofNullable(project.getOrganization()).orElse(EMPTY_STRING));
+    params.put(ProjectReportConstants.MEMBERS, project.getUsersQuantity());
+    params.put(ProjectReportConstants.LAUNCHES, project.getLaunchesQuantity());
 
-		ofNullable(project.getLastRun()).ifPresent(lastRun -> params.put(ProjectReportConstants.LAST_LAUNCH_DATE,
-				DateTimeFormatter.ISO_ZONED_DATE_TIME.format(ZonedDateTime.of(lastRun, ZoneOffset.UTC))
-		));
+    ofNullable(project.getLastRun()).ifPresent(
+        lastRun -> params.put(ProjectReportConstants.LAST_LAUNCH_DATE,
+            DateTimeFormatter.ISO_ZONED_DATE_TIME.format(ZonedDateTime.of(lastRun, ZoneOffset.UTC))
+        ));
 
-		return params;
-	}
+    return params;
+  }
 
-	@Override
-	public Set<ReportFormat> getAvailableReportFormats() {
-		return availableReportFormats;
-	}
+  @Override
+  public Set<ReportFormat> getAvailableReportFormats() {
+    return availableReportFormats;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/jasper/impl/UserJasperReportHandler.java b/src/main/java/com/epam/ta/reportportal/core/jasper/impl/UserJasperReportHandler.java
index 26c49f1e43..53942890a4 100644
--- a/src/main/java/com/epam/ta/reportportal/core/jasper/impl/UserJasperReportHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/jasper/impl/UserJasperReportHandler.java
@@ -16,17 +16,15 @@
 
 package com.epam.ta.reportportal.core.jasper.impl;
 
+import static com.epam.ta.reportportal.ws.converter.builders.UserBuilder.USER_LAST_LOGIN;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.core.jasper.JasperReportRender;
 import com.epam.ta.reportportal.core.jasper.constants.UserReportConstants;
 import com.epam.ta.reportportal.entity.jasper.ReportFormat;
 import com.epam.ta.reportportal.entity.jasper.ReportType;
 import com.epam.ta.reportportal.entity.user.User;
 import com.google.common.collect.Sets;
-import net.sf.jasperreports.engine.JRDataSource;
-import net.sf.jasperreports.engine.JasperPrint;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
 import java.time.Instant;
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
@@ -35,9 +33,10 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.ws.converter.builders.UserBuilder.USER_LAST_LOGIN;
-import static java.util.Optional.ofNullable;
+import net.sf.jasperreports.engine.JRDataSource;
+import net.sf.jasperreports.engine.JasperPrint;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -45,60 +44,64 @@
 @Service("userJasperReportHandler")
 public class UserJasperReportHandler extends AbstractJasperReportHandler<User> {
 
-	private static final String UNSUPPORTED_REPORT_FORMAT_MESSAGE_EXCEPTION = "Report format - {} is not supported for user reports.";
-
-	private final Set<ReportFormat> availableReportFormats;
-
-	private final JasperReportRender reportRender;
-
-	@Autowired
-	public UserJasperReportHandler(JasperReportRender reportRender) {
-		super(UNSUPPORTED_REPORT_FORMAT_MESSAGE_EXCEPTION);
-		this.reportRender = reportRender;
-		availableReportFormats = Sets.immutableEnumSet(ReportFormat.CSV);
-	}
-
-	@Override
-	public JasperPrint getJasperPrint(Map<String, Object> params, JRDataSource dataSource) {
-
-		return reportRender.generateReportPrint(ReportType.USER, params, dataSource);
-	}
-
-	@Override
-	public Map<String, Object> convertParams(User user) {
-		Map<String, Object> params = new HashMap<>();
-
-		params.put(UserReportConstants.FULL_NAME, user.getFullName());
-		params.put(UserReportConstants.TYPE, user.getUserType().name());
-		params.put(UserReportConstants.LOGIN, user.getLogin());
-		params.put(UserReportConstants.EMAIL, user.getEmail());
-
-		params.put(UserReportConstants.PROJECTS_AND_ROLES, user.getProjects().stream().collect(Collectors.toMap(
-				projectUser -> projectUser.getProject().getName(),
-				projectUser -> projectUser.getProjectRole().name(),
-				(prev, curr) -> prev
-		)).entrySet().stream().map(entry -> entry.getKey() + " - " + entry.getValue()).collect(Collectors.joining(", ")));
-
-		ofNullable(user.getMetadata()).ifPresent(metadata -> ofNullable(metadata.getMetadata()).ifPresent(meta -> ofNullable(meta.get(
-				USER_LAST_LOGIN)).ifPresent(lastLogin -> {
-			try {
-				long epochMilli = Long.parseLong(String.valueOf(lastLogin));
-				Instant instant = Instant.ofEpochMilli(epochMilli);
-				params.put(
-						UserReportConstants.LAST_LOGIN,
-						DateTimeFormatter.ISO_ZONED_DATE_TIME.format(ZonedDateTime.ofInstant(instant, ZoneOffset.UTC))
-				);
-			} catch (NumberFormatException e) {
-				//do nothing, null value will be put in the result
-			}
-
-		})));
-
-		return params;
-	}
-
-	@Override
-	public Set<ReportFormat> getAvailableReportFormats() {
-		return availableReportFormats;
-	}
+  private static final String UNSUPPORTED_REPORT_FORMAT_MESSAGE_EXCEPTION = "Report format - {} is not supported for user reports.";
+
+  private final Set<ReportFormat> availableReportFormats;
+
+  private final JasperReportRender reportRender;
+
+  @Autowired
+  public UserJasperReportHandler(JasperReportRender reportRender) {
+    super(UNSUPPORTED_REPORT_FORMAT_MESSAGE_EXCEPTION);
+    this.reportRender = reportRender;
+    availableReportFormats = Sets.immutableEnumSet(ReportFormat.CSV);
+  }
+
+  @Override
+  public JasperPrint getJasperPrint(Map<String, Object> params, JRDataSource dataSource) {
+
+    return reportRender.generateReportPrint(ReportType.USER, params, dataSource);
+  }
+
+  @Override
+  public Map<String, Object> convertParams(User user) {
+    Map<String, Object> params = new HashMap<>();
+
+    params.put(UserReportConstants.FULL_NAME, user.getFullName());
+    params.put(UserReportConstants.TYPE, user.getUserType().name());
+    params.put(UserReportConstants.LOGIN, user.getLogin());
+    params.put(UserReportConstants.EMAIL, user.getEmail());
+
+    params.put(UserReportConstants.PROJECTS_AND_ROLES,
+        user.getProjects().stream().collect(Collectors.toMap(
+                projectUser -> projectUser.getProject().getName(),
+                projectUser -> projectUser.getProjectRole().name(),
+                (prev, curr) -> prev
+            )).entrySet().stream().map(entry -> entry.getKey() + " - " + entry.getValue())
+            .collect(Collectors.joining(", ")));
+
+    ofNullable(user.getMetadata()).ifPresent(
+        metadata -> ofNullable(metadata.getMetadata()).ifPresent(meta -> ofNullable(meta.get(
+            USER_LAST_LOGIN)).ifPresent(lastLogin -> {
+          try {
+            long epochMilli = Long.parseLong(String.valueOf(lastLogin));
+            Instant instant = Instant.ofEpochMilli(epochMilli);
+            params.put(
+                UserReportConstants.LAST_LOGIN,
+                DateTimeFormatter.ISO_ZONED_DATE_TIME.format(
+                    ZonedDateTime.ofInstant(instant, ZoneOffset.UTC))
+            );
+          } catch (NumberFormatException e) {
+            //do nothing, null value will be put in the result
+          }
+
+        })));
+
+    return params;
+  }
+
+  @Override
+  public Set<ReportFormat> getAvailableReportFormats() {
+    return availableReportFormats;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/jasper/util/ExportUtils.java b/src/main/java/com/epam/ta/reportportal/core/jasper/util/ExportUtils.java
index ec2ffd121c..1873869ed8 100644
--- a/src/main/java/com/epam/ta/reportportal/core/jasper/util/ExportUtils.java
+++ b/src/main/java/com/epam/ta/reportportal/core/jasper/util/ExportUtils.java
@@ -18,52 +18,54 @@
 
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.statistics.Statistics;
-import org.apache.commons.lang3.StringUtils;
-
 import java.time.Duration;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
+import org.apache.commons.lang3.StringUtils;
 
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 public class ExportUtils {
-	private static final String SHIFT_PREFIX = "    ";
-	public static final String COMMENT_PREFIX = "\r\n" + " DEFECT COMMENT: ";
-	public static final String DESCRIPTION_PREFIX = "\r\n" + " ITEM DESCRIPTION: ";
 
-	public static int getStatisticsCounter(Set<Statistics> statistics, String statisticsFieldName) {
-		return statistics.stream()
-				.filter(it -> it.getStatisticsField().getName().equals(statisticsFieldName))
-				.mapToInt(Statistics::getCounter)
-				.findAny()
-				.orElse(0);
-	}
+  private static final String SHIFT_PREFIX = "    ";
+  public static final String COMMENT_PREFIX = "\r\n" + " DEFECT COMMENT: ";
+  public static final String DESCRIPTION_PREFIX = "\r\n" + " ITEM DESCRIPTION: ";
+
+  public static int getStatisticsCounter(Set<Statistics> statistics, String statisticsFieldName) {
+    return statistics.stream()
+        .filter(it -> it.getStatisticsField().getName().equals(statisticsFieldName))
+        .mapToInt(Statistics::getCounter)
+        .findAny()
+        .orElse(0);
+  }
 
-	/**
-	 * Add right shifting for child items depends on depth level
-	 *
-	 * @param input - target {@see TestItem}
-	 * @return updated test item name with shifted name
-	 */
-	public static String adjustName(TestItem input) {
-		/* Sync buffer instead builder! */
-		return new StringBuilder(StringUtils.repeat(SHIFT_PREFIX, input.getPath().split("\\.").length)).append(input.getName()).toString();
-	}
+  /**
+   * Add right shifting for child items depends on depth level
+   *
+   * @param input - The target {@link TestItem} for which the name will be updated
+   * @return updated test item name with shifted name
+   */
+  public static String adjustName(TestItem input) {
+    /* Sync buffer instead builder! */
+    return new StringBuilder(
+        StringUtils.repeat(SHIFT_PREFIX, input.getPath().split("\\.").length)).append(
+        input.getName()).toString();
+  }
 
-	/**
-	 * Format launch duration from long to human readable format.
-	 *
-	 * @param duration - input duration
-	 * @return String - formatted output
-	 */
-	public static String durationToShortDHMS(Duration duration) {
-		long days = duration.toDays();
-		long hours = duration.toHours() - TimeUnit.DAYS.toHours(days);
-		long minutes = duration.toMinutes() - TimeUnit.HOURS.toMinutes(hours);
-		long seconds = duration.getSeconds() - TimeUnit.MINUTES.toSeconds(minutes);
-		return days == 0 ?
-				String.format("%02d:%02d:%02d", hours, minutes, seconds) :
-				String.format("%dd%02d:%02d:%02d", days, hours, minutes, seconds);
-	}
+  /**
+   * Format launch duration from long to human readable format.
+   *
+   * @param duration - input duration
+   * @return String - formatted output
+   */
+  public static String durationToShortDHMS(Duration duration) {
+    long days = duration.toDays();
+    long hours = duration.toHours() - TimeUnit.DAYS.toHours(days);
+    long minutes = duration.toMinutes() - TimeUnit.HOURS.toMinutes(hours);
+    long seconds = duration.getSeconds() - TimeUnit.MINUTES.toSeconds(minutes);
+    return days == 0 ?
+        String.format("%02d:%02d:%02d", hours, minutes, seconds) :
+        String.format("%dd%02d:%02d:%02d", days, hours, minutes, seconds);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/jasper/util/JasperDataProvider.java b/src/main/java/com/epam/ta/reportportal/core/jasper/util/JasperDataProvider.java
index 685d2c344e..00e38fab2d 100644
--- a/src/main/java/com/epam/ta/reportportal/core/jasper/util/JasperDataProvider.java
+++ b/src/main/java/com/epam/ta/reportportal/core/jasper/util/JasperDataProvider.java
@@ -15,16 +15,15 @@
  */
 package com.epam.ta.reportportal.core.jasper.util;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+
 import com.epam.ta.reportportal.core.jasper.TestItemPojo;
 import com.epam.ta.reportportal.dao.TestItemRepository;
 import com.epam.ta.reportportal.entity.launch.Launch;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
 import java.util.List;
 import java.util.stream.Collectors;
-
-import static com.google.common.base.Preconditions.checkNotNull;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
  * Initial {@link net.sf.jasperreports.engine.JRDataSource} provider class for RP Jasper Reports
@@ -34,18 +33,18 @@
 @Service("jasperDataProvider")
 public class JasperDataProvider {
 
-	private TestItemRepository testItemRepository;
+  private TestItemRepository testItemRepository;
 
-	@Autowired
-	public JasperDataProvider(TestItemRepository testItemRepository) {
-		this.testItemRepository = checkNotNull(testItemRepository);
-	}
+  @Autowired
+  public JasperDataProvider(TestItemRepository testItemRepository) {
+    this.testItemRepository = checkNotNull(testItemRepository);
+  }
 
-	public List<TestItemPojo> getTestItemsOfLaunch(Launch launch) {
-		/* Get launch referred test items with SORT! */
-		return testItemRepository.findTestItemsByLaunchIdOrderByStartTimeAsc(launch.getId())
-				.stream()
-				.map(TestItemPojo::new)
-				.collect(Collectors.toList());
-	}
+  public List<TestItemPojo> getTestItemsOfLaunch(Launch launch) {
+    /* Get launch referred test items with SORT! */
+    return testItemRepository.findTestItemsByLaunchIdOrderByStartTimeAsc(launch.getId())
+        .stream()
+        .map(TestItemPojo::new)
+        .collect(Collectors.toList());
+  }
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/DeleteLaunchHandler.java b/src/main/java/com/epam/ta/reportportal/core/launch/DeleteLaunchHandler.java
index 04f19fb4ad..3f65e87a77 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/DeleteLaunchHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/DeleteLaunchHandler.java
@@ -30,23 +30,25 @@
 
 public interface DeleteLaunchHandler {
 
-	/**
-	 * Delete {@link com.epam.ta.reportportal.entity.launch.Launch} instance
-	 *
-	 * @param launchId       ID of launch
-	 * @param projectDetails Project Details
-	 * @param user           User
-	 * @return OperationCompletionRS
-	 */
-	OperationCompletionRS deleteLaunch(Long launchId, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user);
+  /**
+   * Delete {@link com.epam.ta.reportportal.entity.launch.Launch} instance
+   *
+   * @param launchId       ID of launch
+   * @param projectDetails Project Details
+   * @param user           User
+   * @return OperationCompletionRS
+   */
+  OperationCompletionRS deleteLaunch(Long launchId, ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user);
 
-	/**
-	 * Bul launches delete.
-	 *
-	 * @param deleteBulkRQ   {@link DeleteBulkRQ}
-	 * @param projectDetails Project Details
-	 * @param user           User
-	 * @return DeleteLaunchesRS
-	 */
-	DeleteBulkRS deleteLaunches(DeleteBulkRQ deleteBulkRQ, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user);
+  /**
+   * Bul launches delete.
+   *
+   * @param deleteBulkRQ   {@link DeleteBulkRQ}
+   * @param projectDetails Project Details
+   * @param user           User
+   * @return DeleteLaunchesRS
+   */
+  DeleteBulkRS deleteLaunches(DeleteBulkRQ deleteBulkRQ,
+      ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user);
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/FinishLaunchHandler.java b/src/main/java/com/epam/ta/reportportal/core/launch/FinishLaunchHandler.java
index d28a092e9b..a7108fb717 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/FinishLaunchHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/FinishLaunchHandler.java
@@ -29,16 +29,18 @@
 
 public interface FinishLaunchHandler {
 
-	/**
-	 * Updates {@link Launch} instance
-	 *
-	 * @param launchId       ID of launch
-	 * @param finishLaunchRQ Request data
-	 * @param projectDetails Project Details
-	 * @param user           User
-	 * @return FinishLaunchRS
-	 */
-	FinishLaunchRS finishLaunch(String launchId, FinishExecutionRQ finishLaunchRQ, ReportPortalUser.ProjectDetails projectDetails,
-			ReportPortalUser user, String baseUrl);
+  /**
+   * Updates {@link Launch} instance
+   *
+   * @param launchId       ID of launch
+   * @param finishLaunchRQ Request data
+   * @param projectDetails Project Details
+   * @param user           User
+   * @param baseUrl        Application base url
+   * @return FinishLaunchRS
+   */
+  FinishLaunchRS finishLaunch(String launchId, FinishExecutionRQ finishLaunchRQ,
+      ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user, String baseUrl);
 
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/GetLaunchHandler.java b/src/main/java/com/epam/ta/reportportal/core/launch/GetLaunchHandler.java
index 84a406c69e..3d0bc531c5 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/GetLaunchHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/GetLaunchHandler.java
@@ -23,12 +23,11 @@
 import com.epam.ta.reportportal.entity.widget.content.ChartStatisticsContent;
 import com.epam.ta.reportportal.ws.model.launch.LaunchResource;
 import com.epam.ta.reportportal.ws.model.launch.cluster.ClusterInfoResource;
-import org.springframework.data.domain.Pageable;
-
-import javax.servlet.http.HttpServletResponse;
 import java.io.OutputStream;
 import java.util.List;
 import java.util.Map;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.data.domain.Pageable;
 
 //import com.epam.ta.reportportal.entity.widget.content.ComparisonStatisticsContent;
 
@@ -40,133 +39,143 @@
  */
 public interface GetLaunchHandler {
 
-	Launch get(Long id);
-
-	/**
-	 * Get Launch resource by specified UUID
-	 *
-	 * @param launchId       Launch uuid
-	 * @param projectDetails Project Details
-	 * @return {@link LaunchResource}
-	 */
-	LaunchResource getLaunch(String launchId, ReportPortalUser.ProjectDetails projectDetails);
-
-	/**
-	 * Get Launch resource by specified Name (for Jenkins Plugin)
-	 *
-	 * @param project  Project Name
-	 * @param pageable Page details
-	 * @param username User name
-	 * @return Response Data
-	 */
-	LaunchResource getLaunchByProjectName(String project, Pageable pageable, Filter filter, String username);
-
-	/**
-	 * Get list of Launch resources for specified project
-	 *
-	 * @param projectDetails Project Details
-	 * @param filter         Filter data
-	 * @param pageable       Page details
-	 * @param userName       Name of User
-	 * @return Response Data
-	 */
-	Iterable<LaunchResource> getProjectLaunches(ReportPortalUser.ProjectDetails projectDetails, Filter filter, Pageable pageable,
-			String userName);
-
-	/**
-	 * Get debug launches
-	 *
-	 * @param projectDetails Project Details
-	 * @param filter         Filter data
-	 * @param pageable       Page details
-	 * @return Response Data
-	 */
-	Iterable<LaunchResource> getDebugLaunches(ReportPortalUser.ProjectDetails projectDetails, Filter filter, Pageable pageable);
-
-	/**
-	 * Get specified launch attribute keys (auto-complete functionality)
-	 *
-	 * @param projectDetails Project Details
-	 * @param value          Tag prefix to be searched
-	 * @return List of found tags
-	 */
-	List<String> getAttributeKeys(ReportPortalUser.ProjectDetails projectDetails, String value);
-
-	/**
-	 * Get specified launch attribute values (auto-complete functionality)
-	 *
-	 * @param projectDetails Project Details
-	 * @param value          Tag prefix to be searched
-	 * @return List of found tags
-	 */
-	List<String> getAttributeValues(ReportPortalUser.ProjectDetails projectDetails, String key, String value);
-
-	/**
-	 * Get launch names of specified project (auto-complete functionality)
-	 *
-	 * @param projectDetails Project Details
-	 * @param value          Launch name prefix
-	 * @return List of found launches
-	 */
-	List<String> getLaunchNames(ReportPortalUser.ProjectDetails projectDetails, String value);
-
-	/**
-	 * Get unique owners of launches in specified mode
-	 *
-	 * @param projectDetails Project Details
-	 * @param value          Owner name prefix
-	 * @param mode           Mode
-	 * @return Response Data
-	 */
-	List<String> getOwners(ReportPortalUser.ProjectDetails projectDetails, String value, String mode);
-
-	/**
-	 * Get launches comparison info
-	 *
-	 * @param projectDetails Project Details
-	 * @param ids            IDs to be looked up
-	 * @return Response Data
-	 * //
-	 */
-	Map<String, List<ChartStatisticsContent>> getLaunchesComparisonInfo(ReportPortalUser.ProjectDetails projectDetails, Long[] ids);
-
-	/**
-	 * Get statuses of specified launches
-	 *
-	 * @param projectDetails Project Details
-	 * @param ids            Launch IDs
-	 * @return Response Data
-	 */
-	Map<String, String> getStatuses(ReportPortalUser.ProjectDetails projectDetails, Long[] ids);
-
-	/**
-	 * Export Launch info according to the {@link ReportFormat} type
-	 *
-	 * @param launchId     {@link com.epam.ta.reportportal.entity.launch.Launch#id}
-	 * @param reportFormat {@link ReportFormat}
-	 * @param outputStream {@link HttpServletResponse#getOutputStream()}
-	 * @param user         Current {@link ReportPortalUser}
-	 */
-	void exportLaunch(Long launchId, ReportFormat reportFormat, OutputStream outputStream, ReportPortalUser user);
-
-	/**
-	 * Get latest launches
-	 *
-	 * @param projectDetails Project Details
-	 * @param filter         Filter data
-	 * @param pageable       Page details
-	 * @return Response Data
-	 */
-	Iterable<LaunchResource> getLatestLaunches(ReportPortalUser.ProjectDetails projectDetails, Filter filter, Pageable pageable);
-
-	/**
-	 * Get Launch resource by specified UUID
-	 *
-	 * @param launchId       Launch uuid
-	 * @param projectDetails Project Details
-	 * @return {@link ClusterInfoResource}
-	 */
-	Iterable<ClusterInfoResource> getClusters(String launchId, ReportPortalUser.ProjectDetails projectDetails, Pageable pageable);
-
-	boolean hasItemsWithIssues(Launch launch);
+  Launch get(Long id);
+
+  /**
+   * Get Launch resource by specified UUID
+   *
+   * @param launchId       Launch uuid
+   * @param projectDetails Project Details
+   * @return {@link LaunchResource}
+   */
+  LaunchResource getLaunch(String launchId, ReportPortalUser.ProjectDetails projectDetails);
+
+  /**
+   * Get Launch resource by specified Name (for Jenkins Plugin)
+   *
+   * @param project  Project Name
+   * @param pageable Page details
+   * @param username User name
+   * @param filter   {@link Filter}
+   * @return Response Data
+   */
+  LaunchResource getLaunchByProjectName(String project, Pageable pageable, Filter filter,
+      String username);
+
+  /**
+   * Get list of Launch resources for specified project
+   *
+   * @param projectDetails Project Details
+   * @param filter         Filter data
+   * @param pageable       Page details
+   * @param userName       Name of User
+   * @return Response Data
+   */
+  Iterable<LaunchResource> getProjectLaunches(ReportPortalUser.ProjectDetails projectDetails,
+      Filter filter, Pageable pageable,
+      String userName);
+
+  /**
+   * Get debug launches
+   *
+   * @param projectDetails Project Details
+   * @param filter         Filter data
+   * @param pageable       Page details
+   * @return Response Data
+   */
+  Iterable<LaunchResource> getDebugLaunches(ReportPortalUser.ProjectDetails projectDetails,
+      Filter filter, Pageable pageable);
+
+  /**
+   * Get specified launch attribute keys (auto-complete functionality)
+   *
+   * @param projectDetails Project Details
+   * @param value          Tag prefix to be searched
+   * @return List of found tags
+   */
+  List<String> getAttributeKeys(ReportPortalUser.ProjectDetails projectDetails, String value);
+
+  /**
+   * Get specified launch attribute values (auto-complete functionality)
+   *
+   * @param projectDetails Project Details
+   * @param value          Tag prefix to be searched
+   * @param key            Attribute key
+   * @return List of found tags
+   */
+  List<String> getAttributeValues(ReportPortalUser.ProjectDetails projectDetails, String key,
+      String value);
+
+  /**
+   * Get launch names of specified project (auto-complete functionality)
+   *
+   * @param projectDetails Project Details
+   * @param value          Launch name prefix
+   * @return List of found launches
+   */
+  List<String> getLaunchNames(ReportPortalUser.ProjectDetails projectDetails, String value);
+
+  /**
+   * Get unique owners of launches in specified mode
+   *
+   * @param projectDetails Project Details
+   * @param value          Owner name prefix
+   * @param mode           Mode
+   * @return Response Data
+   */
+  List<String> getOwners(ReportPortalUser.ProjectDetails projectDetails, String value, String mode);
+
+  /**
+   * Get launches comparison info
+   *
+   * @param projectDetails Project Details
+   * @param ids            IDs to be looked up
+   * @return Response Data //
+   */
+  Map<String, List<ChartStatisticsContent>> getLaunchesComparisonInfo(
+      ReportPortalUser.ProjectDetails projectDetails, Long[] ids);
+
+  /**
+   * Get statuses of specified launches
+   *
+   * @param projectDetails Project Details
+   * @param ids            Launch IDs
+   * @return Response Data
+   */
+  Map<String, String> getStatuses(ReportPortalUser.ProjectDetails projectDetails, Long[] ids);
+
+  /**
+   * Export Launch info according to the {@link ReportFormat} type
+   *
+   * @param launchId     {@link com.epam.ta.reportportal.entity.launch.Launch#id}
+   * @param reportFormat {@link ReportFormat}
+   * @param outputStream {@link HttpServletResponse#getOutputStream()}
+   * @param user         Current {@link ReportPortalUser}
+   */
+  void exportLaunch(Long launchId, ReportFormat reportFormat, OutputStream outputStream,
+      ReportPortalUser user);
+
+  /**
+   * Get latest launches
+   *
+   * @param projectDetails Project Details
+   * @param filter         Filter data
+   * @param pageable       Page details
+   * @return Response Data
+   */
+  Iterable<LaunchResource> getLatestLaunches(ReportPortalUser.ProjectDetails projectDetails,
+      Filter filter, Pageable pageable);
+
+  /**
+   * Get Launch resource by specified UUID
+   *
+   * @param launchId       Launch uuid
+   * @param projectDetails Project Details
+   * @param pageable       Pagination information for the results
+   * @return {@link ClusterInfoResource}
+   */
+  Iterable<ClusterInfoResource> getClusters(String launchId,
+      ReportPortalUser.ProjectDetails projectDetails, Pageable pageable);
+
+  boolean hasItemsWithIssues(Launch launch);
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/MergeLaunchHandler.java b/src/main/java/com/epam/ta/reportportal/core/launch/MergeLaunchHandler.java
index a39b33e3f8..c6026baab4 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/MergeLaunchHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/MergeLaunchHandler.java
@@ -27,14 +27,15 @@
  */
 public interface MergeLaunchHandler {
 
-	/**
-	 * Merges launches.
-	 *
-	 * @param projectDetails  Project Details
-	 * @param user            User
-	 * @param mergeLaunchesRQ Request data
-	 * @return OperationCompletionsRS
-	 */
-	LaunchResource mergeLaunches(ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user, MergeLaunchesRQ mergeLaunchesRQ);
+  /**
+   * Merges launches.
+   *
+   * @param projectDetails  Project Details
+   * @param user            User
+   * @param mergeLaunchesRQ Request data
+   * @return OperationCompletionsRS
+   */
+  LaunchResource mergeLaunches(ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user, MergeLaunchesRQ mergeLaunchesRQ);
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/StartLaunchHandler.java b/src/main/java/com/epam/ta/reportportal/core/launch/StartLaunchHandler.java
index 3d5ae52570..b5c551b266 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/StartLaunchHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/StartLaunchHandler.java
@@ -16,17 +16,16 @@
 
 package com.epam.ta.reportportal.core.launch;
 
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.entity.project.ProjectRole;
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.epam.ta.reportportal.ws.model.launch.Mode;
 import com.epam.ta.reportportal.ws.model.launch.StartLaunchRQ;
 import com.epam.ta.reportportal.ws.model.launch.StartLaunchRS;
-
 import java.util.function.Predicate;
 
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-
 /**
  * Start Launch operation handler
  *
@@ -34,27 +33,30 @@
  */
 public interface StartLaunchHandler {
 
-	/**
-	 * Creates new launch for specified project
-	 *
-	 * @param user           ReportPortal user
-	 * @param projectDetails Project Details
-	 * @param startLaunchRQ  Request Data
-	 * @return StartLaunchRS
-	 */
-	StartLaunchRS startLaunch(ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails, StartLaunchRQ startLaunchRQ);
+  /**
+   * Creates new launch for specified project
+   *
+   * @param user           ReportPortal user
+   * @param projectDetails Project Details
+   * @param startLaunchRQ  Request Data
+   * @return StartLaunchRS
+   */
+  StartLaunchRS startLaunch(ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails,
+      StartLaunchRQ startLaunchRQ);
 
-	/**
-	 * Validate {@link ReportPortalUser} credentials. User with a {@link ProjectRole#CUSTOMER} role can't report
-	 * launches in a debug mode.
-	 *
-	 * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
-	 * @param startLaunchRQ  {@link StartLaunchRQ}
-	 */
-	default void validateRoles(ReportPortalUser.ProjectDetails projectDetails, StartLaunchRQ startLaunchRQ) {
-		expect(
-				Mode.DEBUG.equals(startLaunchRQ.getMode()) && ProjectRole.CUSTOMER.equals(projectDetails.getProjectRole()),
-				Predicate.isEqual(false)
-		).verify(ErrorType.FORBIDDEN_OPERATION);
-	}
+  /**
+   * Validate {@link ReportPortalUser} credentials. User with a {@link ProjectRole#CUSTOMER} role
+   * can't report launches in a debug mode.
+   *
+   * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
+   * @param startLaunchRQ  {@link StartLaunchRQ}
+   */
+  default void validateRoles(ReportPortalUser.ProjectDetails projectDetails,
+      StartLaunchRQ startLaunchRQ) {
+    expect(
+        Mode.DEBUG.equals(startLaunchRQ.getMode()) && ProjectRole.CUSTOMER.equals(
+            projectDetails.getProjectRole()),
+        Predicate.isEqual(false)
+    ).verify(ErrorType.FORBIDDEN_OPERATION);
+  }
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/StopLaunchHandler.java b/src/main/java/com/epam/ta/reportportal/core/launch/StopLaunchHandler.java
index 4ad4539657..3a85ce26b1 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/StopLaunchHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/StopLaunchHandler.java
@@ -20,7 +20,6 @@
 import com.epam.ta.reportportal.ws.model.BulkRQ;
 import com.epam.ta.reportportal.ws.model.FinishExecutionRQ;
 import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
-
 import java.util.List;
 
 /**
@@ -28,26 +27,28 @@
  */
 public interface StopLaunchHandler {
 
-	/**
-	 * Stop Launch instance by user
-	 *
-	 * @param launchId       ID of launch
-	 * @param finishLaunchRQ Request data
-	 * @param projectDetails Project Details
-	 * @param user           User
-	 * @return OperationCompletionRS
-	 */
-	OperationCompletionRS stopLaunch(Long launchId, FinishExecutionRQ finishLaunchRQ, ReportPortalUser.ProjectDetails projectDetails,
-			ReportPortalUser user);
+  /**
+   * Stop Launch instance by user
+   *
+   * @param launchId       ID of launch
+   * @param finishLaunchRQ Request data
+   * @param projectDetails Project Details
+   * @param user           User
+   * @return OperationCompletionRS
+   */
+  OperationCompletionRS stopLaunch(Long launchId, FinishExecutionRQ finishLaunchRQ,
+      ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user);
 
-	/**
-	 * Bulk stop launches operation.
-	 *
-	 * @param bulkRQ         Bulk request
-	 * @param projectDetails Project Details
-	 * @param user           User
-	 * @return OperationCompletionsRS
-	 */
-	List<OperationCompletionRS> stopLaunch(BulkRQ<Long, FinishExecutionRQ> bulkRQ, ReportPortalUser.ProjectDetails projectDetails,
-			ReportPortalUser user);
+  /**
+   * Bulk stop launches operation.
+   *
+   * @param bulkRQ         Bulk request
+   * @param projectDetails Project Details
+   * @param user           User
+   * @return OperationCompletionsRS
+   */
+  List<OperationCompletionRS> stopLaunch(BulkRQ<Long, FinishExecutionRQ> bulkRQ,
+      ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/UpdateLaunchHandler.java b/src/main/java/com/epam/ta/reportportal/core/launch/UpdateLaunchHandler.java
index a212aa10e1..152b24a579 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/UpdateLaunchHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/UpdateLaunchHandler.java
@@ -23,7 +23,6 @@
 import com.epam.ta.reportportal.ws.model.launch.AnalyzeLaunchRQ;
 import com.epam.ta.reportportal.ws.model.launch.UpdateLaunchRQ;
 import com.epam.ta.reportportal.ws.model.launch.cluster.CreateClustersRQ;
-
 import java.util.List;
 
 /**
@@ -35,42 +34,47 @@
  */
 public interface UpdateLaunchHandler {
 
-	/**
-	 * Update specified by id launch.
-	 *
-	 * @param launchId       ID of Launch object
-	 * @param projectDetails Project Details
-	 * @param user           Recipient user
-	 * @param rq             Request Data
-	 * @return OperationCompletionRS - Response Data
-	 */
-	OperationCompletionRS updateLaunch(Long launchId, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user,
-			UpdateLaunchRQ rq);
+  /**
+   * Update specified by id launch.
+   *
+   * @param launchId       ID of Launch object
+   * @param projectDetails Project Details
+   * @param user           Recipient user
+   * @param rq             Request Data
+   * @return OperationCompletionRS - Response Data
+   */
+  OperationCompletionRS updateLaunch(Long launchId, ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user,
+      UpdateLaunchRQ rq);
 
-	/**
-	 * Start launch analyzer on demand
-	 *
-	 * @param projectDetails  Project Details
-	 * @param analyzeLaunchRQ Launch analyze rq
-	 * @param user            User started analysis
-	 * @return OperationCompletionRS - Response Data
-	 */
-	OperationCompletionRS startLaunchAnalyzer(AnalyzeLaunchRQ analyzeLaunchRQ, ReportPortalUser.ProjectDetails projectDetails,
-			ReportPortalUser user);
+  /**
+   * Start launch analyzer on demand
+   *
+   * @param projectDetails  Project Details
+   * @param analyzeLaunchRQ Launch analyze rq
+   * @param user            User started analysis
+   * @return OperationCompletionRS - Response Data
+   */
+  OperationCompletionRS startLaunchAnalyzer(AnalyzeLaunchRQ analyzeLaunchRQ,
+      ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user);
 
-	OperationCompletionRS createClusters(CreateClustersRQ createClustersRQ, ReportPortalUser.ProjectDetails projectDetails,
-			ReportPortalUser user);
+  OperationCompletionRS createClusters(CreateClustersRQ createClustersRQ,
+      ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user);
 
-	/**
-	 * Bulk launch update.
-	 *
-	 * @param rq             Bulk request
-	 * @param projectDetails Project Details
-	 * @param user           User
-	 * @return OperationCompletionRS
-	 */
-	List<OperationCompletionRS> updateLaunch(BulkRQ<Long, UpdateLaunchRQ> rq, ReportPortalUser.ProjectDetails projectDetails,
-			ReportPortalUser user);
+  /**
+   * Bulk launch update.
+   *
+   * @param rq             Bulk request
+   * @param projectDetails Project Details
+   * @param user           User
+   * @return OperationCompletionRS
+   */
+  List<OperationCompletionRS> updateLaunch(BulkRQ<Long, UpdateLaunchRQ> rq,
+      ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user);
 
-	OperationCompletionRS bulkInfoUpdate(BulkInfoUpdateRQ bulkUpdateRq, ReportPortalUser.ProjectDetails projectDetails);
+  OperationCompletionRS bulkInfoUpdate(BulkInfoUpdateRQ bulkUpdateRq,
+      ReportPortalUser.ProjectDetails projectDetails);
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/ClusterGenerator.java b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/ClusterGenerator.java
index ced3a8d491..fdb769c996 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/ClusterGenerator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/ClusterGenerator.java
@@ -23,6 +23,6 @@
  */
 public interface ClusterGenerator {
 
-	void generate(GenerateClustersConfig config);
+  void generate(GenerateClustersConfig config);
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/CreateClusterHandler.java b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/CreateClusterHandler.java
index cada826928..540de65037 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/CreateClusterHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/CreateClusterHandler.java
@@ -23,5 +23,5 @@
  */
 public interface CreateClusterHandler {
 
-	void create(ClusterData clusterData);
+  void create(ClusterData clusterData);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/CreateClusterHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/CreateClusterHandlerImpl.java
index 1b5544a36f..51ed71cfe3 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/CreateClusterHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/CreateClusterHandlerImpl.java
@@ -16,21 +16,20 @@
 
 package com.epam.ta.reportportal.core.launch.cluster;
 
+import static com.epam.ta.reportportal.ws.converter.converters.ClusterConverter.TO_CLUSTER;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.core.analyzer.auto.client.model.cluster.ClusterData;
 import com.epam.ta.reportportal.core.analyzer.auto.client.model.cluster.ClusterInfoRs;
 import com.epam.ta.reportportal.dao.ClusterRepository;
 import com.epam.ta.reportportal.dao.LogRepository;
 import com.epam.ta.reportportal.entity.cluster.Cluster;
+import java.util.Objects;
 import org.apache.commons.collections4.CollectionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.Objects;
-
-import static com.epam.ta.reportportal.ws.converter.converters.ClusterConverter.TO_CLUSTER;
-import static java.util.Optional.ofNullable;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
@@ -38,50 +37,54 @@
 @Transactional
 public class CreateClusterHandlerImpl implements CreateClusterHandler {
 
-	private final ClusterRepository clusterRepository;
-	private final LogRepository logRepository;
+  private final ClusterRepository clusterRepository;
+  private final LogRepository logRepository;
 
-	@Autowired
-	public CreateClusterHandlerImpl(ClusterRepository clusterRepository, LogRepository logRepository) {
-		this.clusterRepository = clusterRepository;
-		this.logRepository = logRepository;
-	}
+  @Autowired
+  public CreateClusterHandlerImpl(ClusterRepository clusterRepository,
+      LogRepository logRepository) {
+    this.clusterRepository = clusterRepository;
+    this.logRepository = logRepository;
+  }
 
-	@Override
-	public void create(ClusterData clusterData) {
-		ofNullable(clusterData.getClusters()).filter(CollectionUtils::isNotEmpty)
-				.ifPresent(clusters -> clusters.stream().filter(c -> Objects.nonNull(c.getClusterId())).forEach(clusterInfoRs -> {
-					final Cluster cluster = saveCluster(clusterData, clusterInfoRs);
-					saveItems(clusterInfoRs, cluster);
-					updateLogs(clusterInfoRs, cluster);
-				}));
-	}
+  @Override
+  public void create(ClusterData clusterData) {
+    ofNullable(clusterData.getClusters()).filter(CollectionUtils::isNotEmpty)
+        .ifPresent(clusters -> clusters.stream().filter(c -> Objects.nonNull(c.getClusterId()))
+            .forEach(clusterInfoRs -> {
+              final Cluster cluster = saveCluster(clusterData, clusterInfoRs);
+              saveItems(clusterInfoRs, cluster);
+              updateLogs(clusterInfoRs, cluster);
+            }));
+  }
 
-	private Cluster saveCluster(ClusterData clusterData, ClusterInfoRs clusterInfoRs) {
-		final Cluster cluster = clusterRepository.findByIndexIdAndLaunchId(clusterInfoRs.getClusterId(), clusterData.getLaunchId())
-				.map(c -> {
-					c.setMessage(clusterInfoRs.getClusterMessage());
-					return c;
-				})
-				.orElseGet(() -> convertToCluster(clusterData, clusterInfoRs));
-		return clusterRepository.save(cluster);
-	}
+  private Cluster saveCluster(ClusterData clusterData, ClusterInfoRs clusterInfoRs) {
+    final Cluster cluster = clusterRepository.findByIndexIdAndLaunchId(clusterInfoRs.getClusterId(),
+            clusterData.getLaunchId())
+        .map(c -> {
+          c.setMessage(clusterInfoRs.getClusterMessage());
+          return c;
+        })
+        .orElseGet(() -> convertToCluster(clusterData, clusterInfoRs));
+    return clusterRepository.save(cluster);
+  }
 
-	private Cluster convertToCluster(ClusterData clusterData, ClusterInfoRs clusterInfoRs) {
-		final Cluster cluster = TO_CLUSTER.apply(clusterInfoRs);
-		cluster.setProjectId(clusterData.getProject());
-		cluster.setLaunchId(clusterData.getLaunchId());
-		return cluster;
-	}
+  private Cluster convertToCluster(ClusterData clusterData, ClusterInfoRs clusterInfoRs) {
+    final Cluster cluster = TO_CLUSTER.apply(clusterInfoRs);
+    cluster.setProjectId(clusterData.getProject());
+    cluster.setLaunchId(clusterData.getLaunchId());
+    return cluster;
+  }
 
-	private void saveItems(ClusterInfoRs clusterInfoRs, Cluster cluster) {
-		ofNullable(clusterInfoRs.getItemIds()).filter(CollectionUtils::isNotEmpty)
-				.ifPresent(itemIds -> clusterRepository.saveClusterTestItems(cluster, itemIds));
-	}
+  private void saveItems(ClusterInfoRs clusterInfoRs, Cluster cluster) {
+    ofNullable(clusterInfoRs.getItemIds()).filter(CollectionUtils::isNotEmpty)
+        .ifPresent(itemIds -> clusterRepository.saveClusterTestItems(cluster, itemIds));
+  }
 
-	private void updateLogs(ClusterInfoRs clusterInfoRs, Cluster cluster) {
-		ofNullable(clusterInfoRs.getLogIds()).filter(CollectionUtils::isNotEmpty)
-				.ifPresent(logIds -> logRepository.updateClusterIdByIdIn(cluster.getId(), clusterInfoRs.getLogIds()));
-	}
+  private void updateLogs(ClusterInfoRs clusterInfoRs, Cluster cluster) {
+    ofNullable(clusterInfoRs.getLogIds()).filter(CollectionUtils::isNotEmpty)
+        .ifPresent(logIds -> logRepository.updateClusterIdByIdIn(cluster.getId(),
+            clusterInfoRs.getLogIds()));
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/GetClusterHandler.java b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/GetClusterHandler.java
index f1a79c83bd..4292007568 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/GetClusterHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/GetClusterHandler.java
@@ -26,7 +26,7 @@
  */
 public interface GetClusterHandler {
 
-	Cluster getById(Long id);
+  Cluster getById(Long id);
 
-	Iterable<ClusterInfoResource> getResources(Launch launch, Pageable pageable);
+  Iterable<ClusterInfoResource> getResources(Launch launch, Pageable pageable);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/GetClusterHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/GetClusterHandlerImpl.java
index 0dbb58f37c..3bc0b38bc9 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/GetClusterHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/GetClusterHandlerImpl.java
@@ -16,6 +16,9 @@
 
 package com.epam.ta.reportportal.core.launch.cluster;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_ID;
+import static com.epam.ta.reportportal.ws.converter.converters.ClusterConverter.TO_CLUSTER_INFO;
+
 import com.epam.reportportal.extension.event.GetClusterResourcesEvent;
 import com.epam.ta.reportportal.dao.ClusterRepository;
 import com.epam.ta.reportportal.entity.cluster.Cluster;
@@ -32,48 +35,48 @@
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_ID;
-import static com.epam.ta.reportportal.ws.converter.converters.ClusterConverter.TO_CLUSTER_INFO;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class GetClusterHandlerImpl implements GetClusterHandler {
 
-	private final ClusterRepository clusterRepository;
-	private final ApplicationEventPublisher eventPublisher;
+  private final ClusterRepository clusterRepository;
+  private final ApplicationEventPublisher eventPublisher;
 
-	@Autowired
-	public GetClusterHandlerImpl(ClusterRepository clusterRepository, ApplicationEventPublisher eventPublisher) {
-		this.clusterRepository = clusterRepository;
-		this.eventPublisher = eventPublisher;
-	}
+  @Autowired
+  public GetClusterHandlerImpl(ClusterRepository clusterRepository,
+      ApplicationEventPublisher eventPublisher) {
+    this.clusterRepository = clusterRepository;
+    this.eventPublisher = eventPublisher;
+  }
 
-	@Override
-	public Cluster getById(Long id) {
-		return clusterRepository.findById(id).orElseThrow(() -> new ReportPortalException(ErrorType.CLUSTER_NOT_FOUND, id));
-	}
+  @Override
+  public Cluster getById(Long id) {
+    return clusterRepository.findById(id)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.CLUSTER_NOT_FOUND, id));
+  }
 
-	@Override
-	public Iterable<ClusterInfoResource> getResources(Launch launch, Pageable pageable) {
+  @Override
+  public Iterable<ClusterInfoResource> getResources(Launch launch, Pageable pageable) {
 
-		final Pageable pageableWithSort = applySort(pageable);
-		final Page<Cluster> clusters = clusterRepository.findAllByLaunchId(launch.getId(), pageableWithSort);
+    final Pageable pageableWithSort = applySort(pageable);
+    final Page<Cluster> clusters = clusterRepository.findAllByLaunchId(launch.getId(),
+        pageableWithSort);
 
-		return getClusterResources(clusters, launch.getId());
-	}
+    return getClusterResources(clusters, launch.getId());
+  }
 
-	private Pageable applySort(Pageable pageable) {
-		final Sort idSort = Sort.by(Sort.Order.asc(CRITERIA_ID));
-		return PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), idSort);
-	}
+  private Pageable applySort(Pageable pageable) {
+    final Sort idSort = Sort.by(Sort.Order.asc(CRITERIA_ID));
+    return PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), idSort);
+  }
 
-	private Iterable<ClusterInfoResource> getClusterResources(Page<Cluster> clusters, Long launchId) {
-		final com.epam.ta.reportportal.ws.model.Page<ClusterInfoResource> clustersPage = PagedResourcesAssembler.pageConverter(
-				TO_CLUSTER_INFO).apply(clusters);
-		eventPublisher.publishEvent(new GetClusterResourcesEvent(clustersPage.getContent(), launchId));
-		return clustersPage;
-	}
+  private Iterable<ClusterInfoResource> getClusterResources(Page<Cluster> clusters, Long launchId) {
+    final com.epam.ta.reportportal.ws.model.Page<ClusterInfoResource> clustersPage = PagedResourcesAssembler.pageConverter(
+        TO_CLUSTER_INFO).apply(clusters);
+    eventPublisher.publishEvent(new GetClusterResourcesEvent(clustersPage.getContent(), launchId));
+    return clustersPage;
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/UniqueErrorAnalysisStarter.java b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/UniqueErrorAnalysisStarter.java
index 0c6c9a4761..b5726506d9 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/UniqueErrorAnalysisStarter.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/UniqueErrorAnalysisStarter.java
@@ -16,41 +16,40 @@
 
 package com.epam.ta.reportportal.core.launch.cluster;
 
+import static com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerUtils.getAnalyzerConfig;
+import static com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerUtils.getUniqueErrorConfig;
+
 import com.epam.ta.reportportal.core.launch.cluster.config.ClusterEntityContext;
 import com.epam.ta.reportportal.core.launch.cluster.config.GenerateClustersConfig;
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
 import com.epam.ta.reportportal.ws.model.project.UniqueErrorConfig;
-import org.apache.commons.collections4.CollectionUtils;
-
 import java.util.Map;
-
-import static com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerUtils.getAnalyzerConfig;
-import static com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerUtils.getUniqueErrorConfig;
+import org.apache.commons.collections4.CollectionUtils;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public class UniqueErrorAnalysisStarter {
 
-	private final ClusterGenerator clusterGenerator;
+  private final ClusterGenerator clusterGenerator;
 
-	public UniqueErrorAnalysisStarter(ClusterGenerator clusterGenerator) {
-		this.clusterGenerator = clusterGenerator;
-	}
+  public UniqueErrorAnalysisStarter(ClusterGenerator clusterGenerator) {
+    this.clusterGenerator = clusterGenerator;
+  }
 
-	public void start(ClusterEntityContext entityContext, Map<String, String> projectConfig) {
+  public void start(ClusterEntityContext entityContext, Map<String, String> projectConfig) {
 
-		final GenerateClustersConfig clustersConfig = new GenerateClustersConfig();
+    final GenerateClustersConfig clustersConfig = new GenerateClustersConfig();
 
-		clustersConfig.setEntityContext(entityContext);
-		clustersConfig.setForUpdate(CollectionUtils.isNotEmpty(entityContext.getItemIds()));
+    clustersConfig.setEntityContext(entityContext);
+    clustersConfig.setForUpdate(CollectionUtils.isNotEmpty(entityContext.getItemIds()));
 
-		final UniqueErrorConfig uniqueErrorConfig = getUniqueErrorConfig(projectConfig);
-		clustersConfig.setCleanNumbers(uniqueErrorConfig.isRemoveNumbers());
+    final UniqueErrorConfig uniqueErrorConfig = getUniqueErrorConfig(projectConfig);
+    clustersConfig.setCleanNumbers(uniqueErrorConfig.isRemoveNumbers());
 
-		final AnalyzerConfig analyzerConfig = getAnalyzerConfig(projectConfig);
-		clustersConfig.setAnalyzerConfig(analyzerConfig);
+    final AnalyzerConfig analyzerConfig = getAnalyzerConfig(projectConfig);
+    clustersConfig.setAnalyzerConfig(analyzerConfig);
 
-		clusterGenerator.generate(clustersConfig);
-	}
+    clusterGenerator.generate(clustersConfig);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/UniqueErrorGenerator.java b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/UniqueErrorGenerator.java
index 1e77f1e66a..ae2e4432c2 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/UniqueErrorGenerator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/UniqueErrorGenerator.java
@@ -16,6 +16,8 @@
 
 package com.epam.ta.reportportal.core.launch.cluster;
 
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+
 import com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerStatusCache;
 import com.epam.ta.reportportal.core.launch.cluster.config.ClusterEntityContext;
 import com.epam.ta.reportportal.core.launch.cluster.config.GenerateClustersConfig;
@@ -23,67 +25,69 @@
 import com.epam.ta.reportportal.pipeline.PipelinePart;
 import com.epam.ta.reportportal.pipeline.TransactionalPipeline;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.List;
+import java.util.function.Predicate;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.function.Predicate;
-
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class UniqueErrorGenerator implements ClusterGenerator {
 
-	private static final Logger LOGGER = LoggerFactory.getLogger(UniqueErrorGeneratorAsync.class);
+  private static final Logger LOGGER = LoggerFactory.getLogger(UniqueErrorGeneratorAsync.class);
 
-	private final AnalyzerStatusCache analyzerStatusCache;
+  private final AnalyzerStatusCache analyzerStatusCache;
 
-	private final PipelineConstructor<GenerateClustersConfig> generateClustersPipelineConstructor;
-	private final TransactionalPipeline transactionalPipeline;
+  private final PipelineConstructor<GenerateClustersConfig> generateClustersPipelineConstructor;
+  private final TransactionalPipeline transactionalPipeline;
 
-	@Autowired
-	public UniqueErrorGenerator(AnalyzerStatusCache analyzerStatusCache,
-			PipelineConstructor<GenerateClustersConfig> generateClustersPipelineConstructor, TransactionalPipeline transactionalPipeline) {
-		this.analyzerStatusCache = analyzerStatusCache;
-		this.generateClustersPipelineConstructor = generateClustersPipelineConstructor;
-		this.transactionalPipeline = transactionalPipeline;
-	}
+  @Autowired
+  public UniqueErrorGenerator(AnalyzerStatusCache analyzerStatusCache,
+      PipelineConstructor<GenerateClustersConfig> generateClustersPipelineConstructor,
+      TransactionalPipeline transactionalPipeline) {
+    this.analyzerStatusCache = analyzerStatusCache;
+    this.generateClustersPipelineConstructor = generateClustersPipelineConstructor;
+    this.transactionalPipeline = transactionalPipeline;
+  }
 
-	@Override
-	public void generate(GenerateClustersConfig config) {
-		fillCache(config.getEntityContext());
-		generateClusters(config);
-	}
+  @Override
+  public void generate(GenerateClustersConfig config) {
+    fillCache(config.getEntityContext());
+    generateClusters(config);
+  }
 
-	protected void fillCache(ClusterEntityContext entityContext) {
-		checkDuplicate(entityContext);
-		analyzerStatusCache.analyzeStarted(AnalyzerStatusCache.CLUSTER_KEY, entityContext.getLaunchId(), entityContext.getProjectId());
-	}
+  protected void fillCache(ClusterEntityContext entityContext) {
+    checkDuplicate(entityContext);
+    analyzerStatusCache.analyzeStarted(AnalyzerStatusCache.CLUSTER_KEY, entityContext.getLaunchId(),
+        entityContext.getProjectId());
+  }
 
-	private void checkDuplicate(ClusterEntityContext entityContext) {
-		expect(analyzerStatusCache.containsLaunchId(AnalyzerStatusCache.CLUSTER_KEY, entityContext.getLaunchId()),
-				Predicate.isEqual(false)
-		).verify(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION, "Clusters creation is in progress.");
-	}
+  private void checkDuplicate(ClusterEntityContext entityContext) {
+    expect(analyzerStatusCache.containsLaunchId(AnalyzerStatusCache.CLUSTER_KEY,
+            entityContext.getLaunchId()),
+        Predicate.isEqual(false)
+    ).verify(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION, "Clusters creation is in progress.");
+  }
 
-	protected void generateClusters(GenerateClustersConfig config) {
-		try {
-			final List<PipelinePart> pipelineParts = generateClustersPipelineConstructor.construct(config);
-			transactionalPipeline.run(pipelineParts);
-		} catch (Exception ex) {
-			LOGGER.error(ex.getMessage(), ex);
-		} finally {
-			cleanCache(config.getEntityContext());
-		}
-	}
+  protected void generateClusters(GenerateClustersConfig config) {
+    try {
+      final List<PipelinePart> pipelineParts = generateClustersPipelineConstructor.construct(
+          config);
+      transactionalPipeline.run(pipelineParts);
+    } catch (Exception ex) {
+      LOGGER.error(ex.getMessage(), ex);
+    } finally {
+      cleanCache(config.getEntityContext());
+    }
+  }
 
-	protected void cleanCache(ClusterEntityContext entityContext) {
-		analyzerStatusCache.analyzeFinished(AnalyzerStatusCache.CLUSTER_KEY, entityContext.getLaunchId());
-	}
+  protected void cleanCache(ClusterEntityContext entityContext) {
+    analyzerStatusCache.analyzeFinished(AnalyzerStatusCache.CLUSTER_KEY,
+        entityContext.getLaunchId());
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/UniqueErrorGeneratorAsync.java b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/UniqueErrorGeneratorAsync.java
index 5e81f964ed..6b311b9605 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/UniqueErrorGeneratorAsync.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/UniqueErrorGeneratorAsync.java
@@ -33,25 +33,26 @@
 @Service
 public class UniqueErrorGeneratorAsync extends UniqueErrorGenerator {
 
-	private static final Logger LOGGER = LoggerFactory.getLogger(UniqueErrorGeneratorAsync.class);
+  private static final Logger LOGGER = LoggerFactory.getLogger(UniqueErrorGeneratorAsync.class);
 
-	private final TaskExecutor logClusterExecutor;
+  private final TaskExecutor logClusterExecutor;
 
-	@Autowired
-	public UniqueErrorGeneratorAsync(AnalyzerStatusCache analyzerStatusCache,
-			PipelineConstructor<GenerateClustersConfig> generateClustersPipelineConstructor, TransactionalPipeline transactionalPipeline,
-			@Qualifier(value = "logClusterExecutor") TaskExecutor logClusterExecutor) {
-		super(analyzerStatusCache, generateClustersPipelineConstructor, transactionalPipeline);
-		this.logClusterExecutor = logClusterExecutor;
-	}
+  @Autowired
+  public UniqueErrorGeneratorAsync(AnalyzerStatusCache analyzerStatusCache,
+      PipelineConstructor<GenerateClustersConfig> generateClustersPipelineConstructor,
+      TransactionalPipeline transactionalPipeline,
+      @Qualifier(value = "logClusterExecutor") TaskExecutor logClusterExecutor) {
+    super(analyzerStatusCache, generateClustersPipelineConstructor, transactionalPipeline);
+    this.logClusterExecutor = logClusterExecutor;
+  }
 
-	@Override
-	protected void generateClusters(GenerateClustersConfig config) {
-		try {
-			logClusterExecutor.execute(() -> super.generateClusters(config));
-		} catch (Exception ex) {
-			LOGGER.error(ex.getMessage(), ex);
-			cleanCache(config.getEntityContext());
-		}
-	}
+  @Override
+  protected void generateClusters(GenerateClustersConfig config) {
+    try {
+      logClusterExecutor.execute(() -> super.generateClusters(config));
+    } catch (Exception ex) {
+      LOGGER.error(ex.getMessage(), ex);
+      cleanCache(config.getEntityContext());
+    }
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/config/ClusterEntityContext.java b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/config/ClusterEntityContext.java
index fe4ffe950e..26fec00822 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/config/ClusterEntityContext.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/config/ClusterEntityContext.java
@@ -24,40 +24,40 @@
  */
 public class ClusterEntityContext {
 
-	private final Long launchId;
-	private final Long projectId;
-
-	private final List<Long> itemIds;
-
-	private ClusterEntityContext(Long launchId, Long projectId) {
-		this.launchId = launchId;
-		this.projectId = projectId;
-		this.itemIds = Collections.emptyList();
-	}
-
-	private ClusterEntityContext(Long launchId, Long projectId, List<Long> itemIds) {
-		this.launchId = launchId;
-		this.projectId = projectId;
-		this.itemIds = itemIds;
-	}
-
-	public Long getLaunchId() {
-		return launchId;
-	}
-
-	public Long getProjectId() {
-		return projectId;
-	}
-
-	public List<Long> getItemIds() {
-		return itemIds;
-	}
-
-	public static ClusterEntityContext  of(Long launchId, Long projectId) {
-		return new ClusterEntityContext(launchId, projectId);
-	}
-
-	public static ClusterEntityContext  of(Long launchId, Long projectId, List<Long> itemIds) {
-		return new ClusterEntityContext(launchId, projectId, itemIds);
-	}
+  private final Long launchId;
+  private final Long projectId;
+
+  private final List<Long> itemIds;
+
+  private ClusterEntityContext(Long launchId, Long projectId) {
+    this.launchId = launchId;
+    this.projectId = projectId;
+    this.itemIds = Collections.emptyList();
+  }
+
+  private ClusterEntityContext(Long launchId, Long projectId, List<Long> itemIds) {
+    this.launchId = launchId;
+    this.projectId = projectId;
+    this.itemIds = itemIds;
+  }
+
+  public Long getLaunchId() {
+    return launchId;
+  }
+
+  public Long getProjectId() {
+    return projectId;
+  }
+
+  public List<Long> getItemIds() {
+    return itemIds;
+  }
+
+  public static ClusterEntityContext of(Long launchId, Long projectId) {
+    return new ClusterEntityContext(launchId, projectId);
+  }
+
+  public static ClusterEntityContext of(Long launchId, Long projectId, List<Long> itemIds) {
+    return new ClusterEntityContext(launchId, projectId, itemIds);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/config/GenerateClustersConfig.java b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/config/GenerateClustersConfig.java
index b77835edc0..641be39f05 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/config/GenerateClustersConfig.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/config/GenerateClustersConfig.java
@@ -23,45 +23,45 @@
  */
 public class GenerateClustersConfig {
 
-	private ClusterEntityContext entityContext;
+  private ClusterEntityContext entityContext;
 
-	private AnalyzerConfig analyzerConfig;
+  private AnalyzerConfig analyzerConfig;
 
-	private boolean forUpdate;
-	private boolean cleanNumbers;
+  private boolean forUpdate;
+  private boolean cleanNumbers;
 
-	public GenerateClustersConfig() {
-	}
+  public GenerateClustersConfig() {
+  }
 
-	public ClusterEntityContext getEntityContext() {
-		return entityContext;
-	}
+  public ClusterEntityContext getEntityContext() {
+    return entityContext;
+  }
 
-	public void setEntityContext(ClusterEntityContext entityContext) {
-		this.entityContext = entityContext;
-	}
+  public void setEntityContext(ClusterEntityContext entityContext) {
+    this.entityContext = entityContext;
+  }
 
-	public AnalyzerConfig getAnalyzerConfig() {
-		return analyzerConfig;
-	}
+  public AnalyzerConfig getAnalyzerConfig() {
+    return analyzerConfig;
+  }
 
-	public void setAnalyzerConfig(AnalyzerConfig analyzerConfig) {
-		this.analyzerConfig = analyzerConfig;
-	}
+  public void setAnalyzerConfig(AnalyzerConfig analyzerConfig) {
+    this.analyzerConfig = analyzerConfig;
+  }
 
-	public boolean isForUpdate() {
-		return forUpdate;
-	}
+  public boolean isForUpdate() {
+    return forUpdate;
+  }
 
-	public void setForUpdate(boolean forUpdate) {
-		this.forUpdate = forUpdate;
-	}
+  public void setForUpdate(boolean forUpdate) {
+    this.forUpdate = forUpdate;
+  }
 
-	public boolean isCleanNumbers() {
-		return cleanNumbers;
-	}
+  public boolean isCleanNumbers() {
+    return cleanNumbers;
+  }
 
-	public void setCleanNumbers(boolean cleanNumbers) {
-		this.cleanNumbers = cleanNumbers;
-	}
+  public void setCleanNumbers(boolean cleanNumbers) {
+    this.cleanNumbers = cleanNumbers;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/DeleteClustersPartProvider.java b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/DeleteClustersPartProvider.java
index 8ad783824a..9a41f2c928 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/DeleteClustersPartProvider.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/DeleteClustersPartProvider.java
@@ -28,26 +28,27 @@
  */
 public class DeleteClustersPartProvider implements PipelinePartProvider<GenerateClustersConfig> {
 
-	private final ClusterRepository clusterRepository;
-	private final LogRepository logRepository;
+  private final ClusterRepository clusterRepository;
+  private final LogRepository logRepository;
 
-	public DeleteClustersPartProvider(ClusterRepository clusterRepository, LogRepository logRepository) {
-		this.clusterRepository = clusterRepository;
-		this.logRepository = logRepository;
-	}
+  public DeleteClustersPartProvider(ClusterRepository clusterRepository,
+      LogRepository logRepository) {
+    this.clusterRepository = clusterRepository;
+    this.logRepository = logRepository;
+  }
 
-	@Override
-	public PipelinePart provide(GenerateClustersConfig config) {
-		return () -> {
-			final ClusterEntityContext entityContext = config.getEntityContext();
-			if (config.isForUpdate()) {
-				logRepository.updateClusterIdSetNullByItemIds(entityContext.getItemIds());
-				clusterRepository.deleteClusterTestItemsByItemIds(entityContext.getItemIds());
-			} else {
-				logRepository.updateClusterIdSetNullByLaunchId(entityContext.getLaunchId());
-				clusterRepository.deleteClusterTestItemsByLaunchId(entityContext.getLaunchId());
-				clusterRepository.deleteAllByLaunchId(entityContext.getLaunchId());
-			}
-		};
-	}
+  @Override
+  public PipelinePart provide(GenerateClustersConfig config) {
+    return () -> {
+      final ClusterEntityContext entityContext = config.getEntityContext();
+      if (config.isForUpdate()) {
+        logRepository.updateClusterIdSetNullByItemIds(entityContext.getItemIds());
+        clusterRepository.deleteClusterTestItemsByItemIds(entityContext.getItemIds());
+      } else {
+        logRepository.updateClusterIdSetNullByLaunchId(entityContext.getLaunchId());
+        clusterRepository.deleteClusterTestItemsByLaunchId(entityContext.getLaunchId());
+        clusterRepository.deleteAllByLaunchId(entityContext.getLaunchId());
+      }
+    };
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/SaveClusterDataPartProvider.java b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/SaveClusterDataPartProvider.java
index e0427c460a..8f908bf5a2 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/SaveClusterDataPartProvider.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/SaveClusterDataPartProvider.java
@@ -22,7 +22,6 @@
 import com.epam.ta.reportportal.core.launch.cluster.pipeline.data.resolver.ClusterDataProviderResolver;
 import com.epam.ta.reportportal.pipeline.PipelinePart;
 import com.epam.ta.reportportal.pipeline.PipelinePartProvider;
-
 import java.util.Optional;
 
 /**
@@ -30,18 +29,20 @@
  */
 public class SaveClusterDataPartProvider implements PipelinePartProvider<GenerateClustersConfig> {
 
-	private final ClusterDataProviderResolver clusterDataProviderResolver;
-	private final CreateClusterHandler createClusterHandler;
-
-	public SaveClusterDataPartProvider(ClusterDataProviderResolver clusterDataProviderResolver, CreateClusterHandler createClusterHandler) {
-		this.clusterDataProviderResolver = clusterDataProviderResolver;
-		this.createClusterHandler = createClusterHandler;
-	}
-
-	@Override
-	public PipelinePart provide(GenerateClustersConfig config) {
-		final Optional<ClusterData> clusterData = clusterDataProviderResolver.resolve(config).flatMap(p -> p.provide(config));
-		return () -> clusterData.ifPresent(createClusterHandler::create);
-	}
+  private final ClusterDataProviderResolver clusterDataProviderResolver;
+  private final CreateClusterHandler createClusterHandler;
+
+  public SaveClusterDataPartProvider(ClusterDataProviderResolver clusterDataProviderResolver,
+      CreateClusterHandler createClusterHandler) {
+    this.clusterDataProviderResolver = clusterDataProviderResolver;
+    this.createClusterHandler = createClusterHandler;
+  }
+
+  @Override
+  public PipelinePart provide(GenerateClustersConfig config) {
+    final Optional<ClusterData> clusterData = clusterDataProviderResolver.resolve(config)
+        .flatMap(p -> p.provide(config));
+    return () -> clusterData.ifPresent(createClusterHandler::create);
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/SaveLastRunAttributePartProvider.java b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/SaveLastRunAttributePartProvider.java
index 395de7c5c9..96e2399f63 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/SaveLastRunAttributePartProvider.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/SaveLastRunAttributePartProvider.java
@@ -21,38 +21,37 @@
 import com.epam.ta.reportportal.dao.ItemAttributeRepository;
 import com.epam.ta.reportportal.pipeline.PipelinePart;
 import com.epam.ta.reportportal.pipeline.PipelinePartProvider;
-
 import java.time.Instant;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
-public class SaveLastRunAttributePartProvider implements PipelinePartProvider<GenerateClustersConfig> {
-
-	public static final String RP_CLUSTER_LAST_RUN_KEY = "rp.cluster.lastRun";
-
-	private final ItemAttributeRepository itemAttributeRepository;
-
-	public SaveLastRunAttributePartProvider(ItemAttributeRepository itemAttributeRepository) {
-		this.itemAttributeRepository = itemAttributeRepository;
-	}
-
-	@Override
-	public PipelinePart provide(GenerateClustersConfig config) {
-		return () -> {
-			final String lastRunDate = String.valueOf(Instant.now().toEpochMilli());
-			final ClusterEntityContext entityContext = config.getEntityContext();
-			itemAttributeRepository.findByLaunchIdAndKeyAndSystem(entityContext.getLaunchId(), RP_CLUSTER_LAST_RUN_KEY, true)
-					.ifPresentOrElse(attr -> {
-								attr.setValue(lastRunDate);
-								itemAttributeRepository.save(attr);
-							},
-							() -> itemAttributeRepository.saveByLaunchId(entityContext.getLaunchId(),
-									RP_CLUSTER_LAST_RUN_KEY,
-									lastRunDate,
-									true
-							)
-					);
-		};
-	}
+public class SaveLastRunAttributePartProvider implements
+    PipelinePartProvider<GenerateClustersConfig> {
+
+  public static final String RP_CLUSTER_LAST_RUN_KEY = "rp.cluster.lastRun";
+
+  private final ItemAttributeRepository itemAttributeRepository;
+
+  public SaveLastRunAttributePartProvider(ItemAttributeRepository itemAttributeRepository) {
+    this.itemAttributeRepository = itemAttributeRepository;
+  }
+
+  @Override
+  public PipelinePart provide(GenerateClustersConfig config) {
+    return () -> {
+      if (config.isForUpdate()) {
+        return;
+      }
+      final String lastRunDate = String.valueOf(Instant.now().toEpochMilli());
+      final ClusterEntityContext entityContext = config.getEntityContext();
+      itemAttributeRepository.deleteAllByLaunchIdAndKeyAndSystem(entityContext.getLaunchId(),
+          RP_CLUSTER_LAST_RUN_KEY, true);
+      itemAttributeRepository.saveByLaunchId(entityContext.getLaunchId(),
+          RP_CLUSTER_LAST_RUN_KEY,
+          lastRunDate,
+          true
+      );
+    };
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/AnalyzerClusterDataProvider.java b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/AnalyzerClusterDataProvider.java
index 6dee500eae..f1fea1c8b4 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/AnalyzerClusterDataProvider.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/AnalyzerClusterDataProvider.java
@@ -16,6 +16,8 @@
 
 package com.epam.ta.reportportal.core.launch.cluster.pipeline.data;
 
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+
 import com.epam.ta.reportportal.core.analyzer.auto.client.AnalyzerServiceClient;
 import com.epam.ta.reportportal.core.analyzer.auto.client.model.cluster.ClusterData;
 import com.epam.ta.reportportal.core.analyzer.auto.client.model.cluster.GenerateClustersRq;
@@ -24,48 +26,46 @@
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.epam.ta.reportportal.ws.model.analyzer.IndexLaunch;
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
-
 import java.util.Optional;
 import java.util.function.Predicate;
 
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public abstract class AnalyzerClusterDataProvider implements ClusterDataProvider {
 
-	private final AnalyzerServiceClient analyzerServiceClient;
+  private final AnalyzerServiceClient analyzerServiceClient;
 
-	public AnalyzerClusterDataProvider(AnalyzerServiceClient analyzerServiceClient) {
-		this.analyzerServiceClient = analyzerServiceClient;
-	}
+  public AnalyzerClusterDataProvider(AnalyzerServiceClient analyzerServiceClient) {
+    this.analyzerServiceClient = analyzerServiceClient;
+  }
 
-	protected abstract Optional<IndexLaunch> prepareIndexLaunch(GenerateClustersConfig config);
+  protected abstract Optional<IndexLaunch> prepareIndexLaunch(GenerateClustersConfig config);
 
-	@Override
-	public Optional<ClusterData> provide(GenerateClustersConfig config) {
-		expect(analyzerServiceClient.hasClients(), Predicate.isEqual(true)).verify(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
-				"There are no analyzer services are deployed."
-		);
-		return getGenerateRq(config).map(analyzerServiceClient::generateClusters);
-	}
+  @Override
+  public Optional<ClusterData> provide(GenerateClustersConfig config) {
+    expect(analyzerServiceClient.hasClients(), Predicate.isEqual(true)).verify(
+        ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
+        "There are no analyzer services are deployed."
+    );
+    return getGenerateRq(config).map(analyzerServiceClient::generateClusters);
+  }
 
-	private Optional<GenerateClustersRq> getGenerateRq(GenerateClustersConfig config) {
-		return prepareIndexLaunch(config).map(indexLaunch -> {
-			final GenerateClustersRq generateClustersRq = new GenerateClustersRq();
-			generateClustersRq.setLaunch(indexLaunch);
-			generateClustersRq.setCleanNumbers(config.isCleanNumbers());
-			generateClustersRq.setForUpdate(config.isForUpdate());
+  private Optional<GenerateClustersRq> getGenerateRq(GenerateClustersConfig config) {
+    return prepareIndexLaunch(config).map(indexLaunch -> {
+      final GenerateClustersRq generateClustersRq = new GenerateClustersRq();
+      generateClustersRq.setLaunch(indexLaunch);
+      generateClustersRq.setCleanNumbers(config.isCleanNumbers());
+      generateClustersRq.setForUpdate(config.isForUpdate());
 
-			final ClusterEntityContext entityContext = config.getEntityContext();
-			generateClustersRq.setProject(entityContext.getProjectId());
+      final ClusterEntityContext entityContext = config.getEntityContext();
+      generateClustersRq.setProject(entityContext.getProjectId());
 
-			final AnalyzerConfig analyzerConfig = config.getAnalyzerConfig();
-			generateClustersRq.setNumberOfLogLines(analyzerConfig.getNumberOfLogLines());
+      final AnalyzerConfig analyzerConfig = config.getAnalyzerConfig();
+      generateClustersRq.setNumberOfLogLines(analyzerConfig.getNumberOfLogLines());
 
-			return generateClustersRq;
-		});
-	}
+      return generateClustersRq;
+    });
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/AnalyzerItemClusterDataProvider.java b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/AnalyzerItemClusterDataProvider.java
index 4066187554..a3a5cbe686 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/AnalyzerItemClusterDataProvider.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/AnalyzerItemClusterDataProvider.java
@@ -25,36 +25,36 @@
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.ws.model.analyzer.IndexLaunch;
-import org.apache.commons.collections4.CollectionUtils;
-
 import java.util.List;
 import java.util.Optional;
+import org.apache.commons.collections4.CollectionUtils;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public class AnalyzerItemClusterDataProvider extends AnalyzerClusterDataProvider {
 
-	private final GetLaunchHandler getLaunchHandler;
-	private final TestItemRepository testItemRepository;
-	private final LaunchPreparerService launchPreparerService;
+  private final GetLaunchHandler getLaunchHandler;
+  private final TestItemRepository testItemRepository;
+  private final LaunchPreparerService launchPreparerService;
 
-	public AnalyzerItemClusterDataProvider(AnalyzerServiceClient analyzerServiceClient, GetLaunchHandler getLaunchHandler,
-			TestItemRepository testItemRepository, LaunchPreparerService launchPreparerService) {
-		super(analyzerServiceClient);
-		this.getLaunchHandler = getLaunchHandler;
-		this.testItemRepository = testItemRepository;
-		this.launchPreparerService = launchPreparerService;
-	}
+  public AnalyzerItemClusterDataProvider(AnalyzerServiceClient analyzerServiceClient,
+      GetLaunchHandler getLaunchHandler,
+      TestItemRepository testItemRepository, LaunchPreparerService launchPreparerService) {
+    super(analyzerServiceClient);
+    this.getLaunchHandler = getLaunchHandler;
+    this.testItemRepository = testItemRepository;
+    this.launchPreparerService = launchPreparerService;
+  }
 
-	@Override
-	protected Optional<IndexLaunch> prepareIndexLaunch(GenerateClustersConfig config) {
-		final ClusterEntityContext entityContext = config.getEntityContext();
-		if (CollectionUtils.isEmpty(entityContext.getItemIds())) {
-			return Optional.empty();
-		}
-		final Launch launch = getLaunchHandler.get(entityContext.getLaunchId());
-		final List<TestItem> testItems = testItemRepository.findAllById(entityContext.getItemIds());
-		return launchPreparerService.prepare(launch, testItems, config.getAnalyzerConfig());
-	}
+  @Override
+  protected Optional<IndexLaunch> prepareIndexLaunch(GenerateClustersConfig config) {
+    final ClusterEntityContext entityContext = config.getEntityContext();
+    if (CollectionUtils.isEmpty(entityContext.getItemIds())) {
+      return Optional.empty();
+    }
+    final Launch launch = getLaunchHandler.get(entityContext.getLaunchId());
+    final List<TestItem> testItems = testItemRepository.findAllById(entityContext.getItemIds());
+    return launchPreparerService.prepare(launch, testItems, config.getAnalyzerConfig());
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/AnalyzerLaunchClusterDataProvider.java b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/AnalyzerLaunchClusterDataProvider.java
index 98475e7ae8..cb4f1e64f4 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/AnalyzerLaunchClusterDataProvider.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/AnalyzerLaunchClusterDataProvider.java
@@ -21,7 +21,6 @@
 import com.epam.ta.reportportal.core.launch.cluster.config.ClusterEntityContext;
 import com.epam.ta.reportportal.core.launch.cluster.config.GenerateClustersConfig;
 import com.epam.ta.reportportal.ws.model.analyzer.IndexLaunch;
-
 import java.util.Optional;
 
 /**
@@ -29,16 +28,17 @@
  */
 public class AnalyzerLaunchClusterDataProvider extends AnalyzerClusterDataProvider {
 
-	private final LaunchPreparerService launchPreparerService;
+  private final LaunchPreparerService launchPreparerService;
 
-	public AnalyzerLaunchClusterDataProvider(AnalyzerServiceClient analyzerServiceClient, LaunchPreparerService launchPreparerService) {
-		super(analyzerServiceClient);
-		this.launchPreparerService = launchPreparerService;
-	}
+  public AnalyzerLaunchClusterDataProvider(AnalyzerServiceClient analyzerServiceClient,
+      LaunchPreparerService launchPreparerService) {
+    super(analyzerServiceClient);
+    this.launchPreparerService = launchPreparerService;
+  }
 
-	@Override
-	protected Optional<IndexLaunch> prepareIndexLaunch(GenerateClustersConfig config) {
-		final ClusterEntityContext entityContext = config.getEntityContext();
-		return launchPreparerService.prepare(entityContext.getLaunchId(), config.getAnalyzerConfig());
-	}
+  @Override
+  protected Optional<IndexLaunch> prepareIndexLaunch(GenerateClustersConfig config) {
+    final ClusterEntityContext entityContext = config.getEntityContext();
+    return launchPreparerService.prepare(entityContext.getLaunchId(), config.getAnalyzerConfig());
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/ClusterDataProvider.java b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/ClusterDataProvider.java
index 3b7f116ffc..a5cfb7bd56 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/ClusterDataProvider.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/ClusterDataProvider.java
@@ -18,7 +18,6 @@
 
 import com.epam.ta.reportportal.core.analyzer.auto.client.model.cluster.ClusterData;
 import com.epam.ta.reportportal.core.launch.cluster.config.GenerateClustersConfig;
-
 import java.util.Optional;
 
 /**
@@ -26,5 +25,5 @@
  */
 public interface ClusterDataProvider {
 
-	Optional<ClusterData> provide(GenerateClustersConfig config);
+  Optional<ClusterData> provide(GenerateClustersConfig config);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/resolver/ClusterDataProviderResolver.java b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/resolver/ClusterDataProviderResolver.java
index 4371de30df..d547d35fce 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/resolver/ClusterDataProviderResolver.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/resolver/ClusterDataProviderResolver.java
@@ -19,7 +19,6 @@
 import com.epam.ta.reportportal.core.launch.cluster.config.GenerateClustersConfig;
 import com.epam.ta.reportportal.core.launch.cluster.pipeline.data.ClusterDataProvider;
 import com.epam.ta.reportportal.core.launch.cluster.pipeline.data.resolver.evaluator.ClusterDataProviderEvaluator;
-
 import java.util.List;
 import java.util.Optional;
 
@@ -28,13 +27,14 @@
  */
 public class ClusterDataProviderResolver {
 
-	private final List<ClusterDataProviderEvaluator> evaluators;
+  private final List<ClusterDataProviderEvaluator> evaluators;
 
-	public ClusterDataProviderResolver(List<ClusterDataProviderEvaluator> evaluators) {
-		this.evaluators = evaluators;
-	}
+  public ClusterDataProviderResolver(List<ClusterDataProviderEvaluator> evaluators) {
+    this.evaluators = evaluators;
+  }
 
-	public Optional<ClusterDataProvider> resolve(GenerateClustersConfig config) {
-		return evaluators.stream().filter(e -> e.supports(config)).map(ClusterDataProviderEvaluator::getProvider).findFirst();
-	}
+  public Optional<ClusterDataProvider> resolve(GenerateClustersConfig config) {
+    return evaluators.stream().filter(e -> e.supports(config))
+        .map(ClusterDataProviderEvaluator::getProvider).findFirst();
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/resolver/evaluator/ClusterDataProviderEvaluator.java b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/resolver/evaluator/ClusterDataProviderEvaluator.java
index 630c0bfe56..1bad46c0b8 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/resolver/evaluator/ClusterDataProviderEvaluator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/resolver/evaluator/ClusterDataProviderEvaluator.java
@@ -18,7 +18,6 @@
 
 import com.epam.ta.reportportal.core.launch.cluster.config.GenerateClustersConfig;
 import com.epam.ta.reportportal.core.launch.cluster.pipeline.data.ClusterDataProvider;
-
 import java.util.function.Predicate;
 
 /**
@@ -26,19 +25,20 @@
  */
 public class ClusterDataProviderEvaluator {
 
-	private final Predicate<GenerateClustersConfig> supportsPredicate;
-	private final ClusterDataProvider clusterDataProvider;
+  private final Predicate<GenerateClustersConfig> supportsPredicate;
+  private final ClusterDataProvider clusterDataProvider;
 
-	public ClusterDataProviderEvaluator(Predicate<GenerateClustersConfig> supportsPredicate, ClusterDataProvider clusterDataProvider) {
-		this.supportsPredicate = supportsPredicate;
-		this.clusterDataProvider = clusterDataProvider;
-	}
+  public ClusterDataProviderEvaluator(Predicate<GenerateClustersConfig> supportsPredicate,
+      ClusterDataProvider clusterDataProvider) {
+    this.supportsPredicate = supportsPredicate;
+    this.clusterDataProvider = clusterDataProvider;
+  }
 
-	public boolean supports(GenerateClustersConfig config) {
-		return supportsPredicate.test(config);
-	}
+  public boolean supports(GenerateClustersConfig config) {
+    return supportsPredicate.test(config);
+  }
 
-	public ClusterDataProvider getProvider() {
-		return clusterDataProvider;
-	}
+  public ClusterDataProvider getProvider() {
+    return clusterDataProvider;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/impl/DeleteLaunchHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/launch/impl/DeleteLaunchHandlerImpl.java
index 3d8c176b72..a1509b40f9 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/impl/DeleteLaunchHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/impl/DeleteLaunchHandlerImpl.java
@@ -16,11 +16,24 @@
 
 package com.epam.ta.reportportal.core.launch.impl;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import static com.epam.ta.reportportal.commons.Predicates.not;
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
+import static com.epam.ta.reportportal.entity.project.ProjectRole.PROJECT_MANAGER;
+import static com.epam.ta.reportportal.ws.converter.converters.LaunchConverter.TO_ACTIVITY_RESOURCE;
+import static com.epam.ta.reportportal.ws.model.ErrorType.ACCESS_DENIED;
+import static com.epam.ta.reportportal.ws.model.ErrorType.FORBIDDEN_OPERATION;
+import static com.epam.ta.reportportal.ws.model.ErrorType.LAUNCH_IS_NOT_FINISHED;
+
+import com.epam.reportportal.events.ElementsDeletedEvent;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
+import com.epam.ta.reportportal.core.ElementsCounterService;
 import com.epam.ta.reportportal.core.analyzer.auto.LogIndexer;
 import com.epam.ta.reportportal.core.events.MessageBus;
 import com.epam.ta.reportportal.core.events.activity.LaunchDeletedEvent;
 import com.epam.ta.reportportal.core.launch.DeleteLaunchHandler;
+import com.epam.ta.reportportal.core.log.LogService;
 import com.epam.ta.reportportal.core.remover.ContentRemover;
 import com.epam.ta.reportportal.dao.AttachmentRepository;
 import com.epam.ta.reportportal.dao.LaunchRepository;
@@ -28,24 +41,23 @@
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.entity.user.UserRole;
 import com.epam.ta.reportportal.exception.ReportPortalException;
-import com.epam.ta.reportportal.ws.model.*;
+import com.epam.ta.reportportal.ws.model.DeleteBulkRQ;
+import com.epam.ta.reportportal.ws.model.DeleteBulkRS;
+import com.epam.ta.reportportal.ws.model.ErrorRS;
+import com.epam.ta.reportportal.ws.model.ErrorType;
+import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
+import com.epam.ta.reportportal.ws.model.activity.LaunchActivityResource;
+import com.google.api.client.util.Maps;
 import com.google.common.collect.Lists;
-import org.apache.commons.collections4.CollectionUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-import static com.epam.ta.reportportal.commons.Predicates.not;
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
-import static com.epam.ta.reportportal.entity.project.ProjectRole.PROJECT_MANAGER;
-import static com.epam.ta.reportportal.ws.converter.converters.LaunchConverter.TO_ACTIVITY_RESOURCE;
-import static com.epam.ta.reportportal.ws.model.ErrorType.*;
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.stereotype.Service;
 
 /**
  * Default implementation of {@link com.epam.ta.reportportal.core.launch.DeleteLaunchHandler}
@@ -57,100 +69,134 @@
 @Service
 public class DeleteLaunchHandlerImpl implements DeleteLaunchHandler {
 
-	private final ContentRemover<Launch> launchContentRemover;
-
-	private final LaunchRepository launchRepository;
-
-	private final MessageBus messageBus;
-
-	private final LogIndexer logIndexer;
-
-	private final AttachmentRepository attachmentRepository;
-
-	@Autowired
-	public DeleteLaunchHandlerImpl(ContentRemover<Launch> launchContentRemover, LaunchRepository launchRepository, MessageBus messageBus,
-			LogIndexer logIndexer, AttachmentRepository attachmentRepository) {
-		this.launchContentRemover = launchContentRemover;
-		this.launchRepository = launchRepository;
-		this.messageBus = messageBus;
-		this.logIndexer = logIndexer;
-		this.attachmentRepository = attachmentRepository;
-	}
-
-	public OperationCompletionRS deleteLaunch(Long launchId, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user) {
-		Launch launch = launchRepository.findById(launchId)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND, launchId));
-		validate(launch, user, projectDetails);
-
-		logIndexer.indexLaunchesRemove(projectDetails.getProjectId(), Lists.newArrayList(launchId));
-		launchContentRemover.remove(launch);
-		launchRepository.delete(launch);
-		attachmentRepository.moveForDeletionByLaunchId(launchId);
-
-		messageBus.publishActivity(new LaunchDeletedEvent(TO_ACTIVITY_RESOURCE.apply(launch), user.getUserId(), user.getUsername()));
-		return new OperationCompletionRS("Launch with ID = '" + launchId + "' successfully deleted.");
-	}
-
-	public DeleteBulkRS deleteLaunches(DeleteBulkRQ deleteBulkRQ, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user) {
-		List<Long> notFound = Lists.newArrayList();
-		List<ReportPortalException> exceptions = Lists.newArrayList();
-		List<Launch> toDelete = Lists.newArrayList();
-		List<Long> launchIds = Lists.newArrayList();
-
-		deleteBulkRQ.getIds().forEach(id -> {
-			Optional<Launch> optionalLaunch = launchRepository.findById(id);
-			if (optionalLaunch.isPresent()) {
-				Launch launch = optionalLaunch.get();
-				try {
-					validate(launch, user, projectDetails);
-					toDelete.add(launch);
-					launchIds.add(id);
-				} catch (ReportPortalException ex) {
-					exceptions.add(ex);
-				}
-			} else {
-				notFound.add(id);
-			}
-		});
-
-		if (CollectionUtils.isNotEmpty(launchIds)) {
-			logIndexer.indexLaunchesRemove(projectDetails.getProjectId(), launchIds);
-			toDelete.forEach(launchContentRemover::remove);
-			launchRepository.deleteAll(toDelete);
-			attachmentRepository.moveForDeletionByLaunchIds(launchIds);
-		}
-
-		toDelete.stream()
-				.map(TO_ACTIVITY_RESOURCE)
-				.forEach(it -> messageBus.publishActivity(new LaunchDeletedEvent(it, user.getUserId(), user.getUsername())));
-
-		return new DeleteBulkRS(launchIds, notFound, exceptions.stream().map(ex -> {
-			ErrorRS errorResponse = new ErrorRS();
-			errorResponse.setErrorType(ex.getErrorType());
-			errorResponse.setMessage(ex.getMessage());
-			return errorResponse;
-		}).collect(Collectors.toList()));
-	}
-
-	/**
-	 * Validate user credentials and {@link Launch#getStatus()}
-	 *
-	 * @param launch         {@link Launch}
-	 * @param user           {@link ReportPortalUser}
-	 * @param projectDetails {@link ReportPortalUser.ProjectDetails}
-	 */
-	private void validate(Launch launch, ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails) {
-		expect(launch, not(l -> StatusEnum.IN_PROGRESS.equals(l.getStatus()))).verify(LAUNCH_IS_NOT_FINISHED,
-				formattedSupplier("Unable to delete launch '{}' in progress state", launch.getId())
-		);
-		if (!UserRole.ADMINISTRATOR.equals(user.getUserRole())) {
-			expect(launch.getProjectId(), equalTo(projectDetails.getProjectId())).verify(FORBIDDEN_OPERATION,
-					formattedSupplier("Target launch '{}' not under specified project '{}'", launch.getId(), projectDetails.getProjectId())
-			);
-			/* Only PROJECT_MANAGER roles could delete launches */
-			if (projectDetails.getProjectRole().lowerThan(PROJECT_MANAGER)) {
-				expect(user.getUserId(), Predicate.isEqual(launch.getUserId())).verify(ACCESS_DENIED, "You are not launch owner.");
-			}
-		}
-	}
+  private final ContentRemover<Launch> launchContentRemover;
+
+  private final LaunchRepository launchRepository;
+
+  private final MessageBus messageBus;
+
+  private final LogIndexer logIndexer;
+
+  private final AttachmentRepository attachmentRepository;
+
+  private final ApplicationEventPublisher eventPublisher;
+
+  private final ElementsCounterService elementsCounterService;
+
+  private final LogService logService;
+
+  @Autowired
+  public DeleteLaunchHandlerImpl(ContentRemover<Launch> launchContentRemover,
+      LaunchRepository launchRepository, MessageBus messageBus,
+      LogIndexer logIndexer, AttachmentRepository attachmentRepository,
+      ApplicationEventPublisher eventPublisher,
+      ElementsCounterService elementsCounterService, LogService logService) {
+    this.launchContentRemover = launchContentRemover;
+    this.launchRepository = launchRepository;
+    this.messageBus = messageBus;
+    this.logIndexer = logIndexer;
+    this.attachmentRepository = attachmentRepository;
+    this.eventPublisher = eventPublisher;
+    this.elementsCounterService = elementsCounterService;
+    this.logService = logService;
+  }
+
+  public OperationCompletionRS deleteLaunch(Long launchId,
+      ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user) {
+    Launch launch = launchRepository.findById(launchId)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND, launchId));
+    validate(launch, user, projectDetails);
+    final Long numberOfLaunchElements = elementsCounterService.countNumberOfLaunchElements(
+        launchId);
+
+    logIndexer.indexLaunchesRemove(projectDetails.getProjectId(), Lists.newArrayList(launchId));
+    launchContentRemover.remove(launch);
+    logService.deleteLogMessageByLaunch(projectDetails.getProjectId(), launch.getId());
+    launchRepository.delete(launch);
+    attachmentRepository.moveForDeletionByLaunchId(launchId);
+
+    messageBus.publishActivity(
+        new LaunchDeletedEvent(TO_ACTIVITY_RESOURCE.apply(launch), user.getUserId(),
+            user.getUsername()));
+    eventPublisher.publishEvent(
+        new ElementsDeletedEvent(launchId, launch.getProjectId(), numberOfLaunchElements));
+    return new OperationCompletionRS("Launch with ID = '" + launchId + "' successfully deleted.");
+  }
+
+  public DeleteBulkRS deleteLaunches(DeleteBulkRQ deleteBulkRQ,
+      ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user) {
+    List<Long> notFound = Lists.newArrayList();
+    List<ReportPortalException> exceptions = Lists.newArrayList();
+    Map<Launch, Long> toDelete = Maps.newHashMap();
+    List<Long> launchIds = Lists.newArrayList();
+
+    deleteBulkRQ.getIds().forEach(id -> {
+      Optional<Launch> optionalLaunch = launchRepository.findById(id);
+      if (optionalLaunch.isPresent()) {
+        Launch launch = optionalLaunch.get();
+        try {
+          validate(launch, user, projectDetails);
+          Long numberOfLaunchElements = elementsCounterService.countNumberOfLaunchElements(
+              launch.getId());
+          toDelete.put(launch, numberOfLaunchElements);
+          launchIds.add(id);
+        } catch (ReportPortalException ex) {
+          exceptions.add(ex);
+        }
+      } else {
+        notFound.add(id);
+      }
+    });
+
+    if (CollectionUtils.isNotEmpty(launchIds)) {
+      logIndexer.indexLaunchesRemove(projectDetails.getProjectId(), launchIds);
+      toDelete.keySet().forEach(launchContentRemover::remove);
+      logService.deleteLogMessageByLaunchList(projectDetails.getProjectId(), launchIds);
+      launchRepository.deleteAll(toDelete.keySet());
+      attachmentRepository.moveForDeletionByLaunchIds(launchIds);
+    }
+
+    toDelete.entrySet().forEach(entry -> {
+      LaunchActivityResource launchActivity = TO_ACTIVITY_RESOURCE.apply(entry.getKey());
+      messageBus.publishActivity(
+          new LaunchDeletedEvent(launchActivity, user.getUserId(), user.getUsername()));
+      eventPublisher.publishEvent(
+          new ElementsDeletedEvent(entry.getKey().getId(), entry.getKey().getProjectId(),
+              entry.getValue()));
+    });
+
+    return new DeleteBulkRS(launchIds, notFound, exceptions.stream().map(ex -> {
+      ErrorRS errorResponse = new ErrorRS();
+      errorResponse.setErrorType(ex.getErrorType());
+      errorResponse.setMessage(ex.getMessage());
+      return errorResponse;
+    }).collect(Collectors.toList()));
+  }
+
+  /**
+   * Validate user credentials and {@link Launch#getStatus()}
+   *
+   * @param launch         {@link Launch}
+   * @param user           {@link ReportPortalUser}
+   * @param projectDetails {@link ReportPortalUser.ProjectDetails}
+   */
+  private void validate(Launch launch, ReportPortalUser user,
+      ReportPortalUser.ProjectDetails projectDetails) {
+    expect(launch, not(l -> StatusEnum.IN_PROGRESS.equals(l.getStatus()))).verify(
+        LAUNCH_IS_NOT_FINISHED,
+        formattedSupplier("Unable to delete launch '{}' in progress state", launch.getId())
+    );
+    if (!UserRole.ADMINISTRATOR.equals(user.getUserRole())) {
+      expect(launch.getProjectId(), equalTo(projectDetails.getProjectId())).verify(
+          FORBIDDEN_OPERATION,
+          formattedSupplier("Target launch '{}' not under specified project '{}'", launch.getId(),
+              projectDetails.getProjectId())
+      );
+      /* Only PROJECT_MANAGER roles could delete launches */
+      if (projectDetails.getProjectRole().lowerThan(PROJECT_MANAGER)) {
+        expect(user.getUserId(), Predicate.isEqual(launch.getUserId())).verify(ACCESS_DENIED,
+            "You are not launch owner.");
+      }
+    }
+  }
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/impl/FinishLaunchHandlerAsyncImpl.java b/src/main/java/com/epam/ta/reportportal/core/launch/impl/FinishLaunchHandlerAsyncImpl.java
index 97402bdcbd..04221771f3 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/impl/FinishLaunchHandlerAsyncImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/impl/FinishLaunchHandlerAsyncImpl.java
@@ -16,6 +16,8 @@
 
 package com.epam.ta.reportportal.core.launch.impl;
 
+import static com.epam.ta.reportportal.core.configs.rabbit.ReportingConfiguration.EXCHANGE_REPORTING;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.launch.FinishLaunchHandler;
 import com.epam.ta.reportportal.util.ReportingQueueService;
@@ -23,15 +25,12 @@
 import com.epam.ta.reportportal.ws.model.launch.FinishLaunchRS;
 import com.epam.ta.reportportal.ws.rabbit.MessageHeaders;
 import com.epam.ta.reportportal.ws.rabbit.RequestType;
+import java.util.Map;
 import org.springframework.amqp.core.AmqpTemplate;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 
-import java.util.Map;
-
-import static com.epam.ta.reportportal.core.configs.rabbit.ReportingConfiguration.EXCHANGE_REPORTING;
-
 /**
  * @author Konstantin Antipin
  */
@@ -39,30 +38,32 @@
 @Qualifier("finishLaunchHandlerAsync")
 public class FinishLaunchHandlerAsyncImpl implements FinishLaunchHandler {
 
-	@Autowired
-	@Qualifier(value = "rabbitTemplate")
-	AmqpTemplate amqpTemplate;
+  @Autowired
+  @Qualifier(value = "rabbitTemplate")
+  AmqpTemplate amqpTemplate;
 
-	@Autowired
-	private ReportingQueueService reportingQueueService;
+  @Autowired
+  private ReportingQueueService reportingQueueService;
 
-	@Override
-	public FinishLaunchRS finishLaunch(String launchId, FinishExecutionRQ request, ReportPortalUser.ProjectDetails projectDetails,
-			ReportPortalUser user, String baseUrl) {
+  @Override
+  public FinishLaunchRS finishLaunch(String launchId, FinishExecutionRQ request,
+      ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user, String baseUrl) {
 
-		// todo: may be problem - no access to repository, so no possibility to validateRoles() here
-		amqpTemplate.convertAndSend(EXCHANGE_REPORTING, reportingQueueService.getReportingQueueKey(launchId), request, message -> {
-			Map<String, Object> headers = message.getMessageProperties().getHeaders();
-			headers.put(MessageHeaders.REQUEST_TYPE, RequestType.FINISH_LAUNCH);
-			headers.put(MessageHeaders.USERNAME, user.getUsername());
-			headers.put(MessageHeaders.PROJECT_NAME, projectDetails.getProjectName());
-			headers.put(MessageHeaders.LAUNCH_ID, launchId);
-			headers.put(MessageHeaders.BASE_URL, baseUrl);
-			return message;
-		});
+    // todo: may be problem - no access to repository, so no possibility to validateRoles() here
+    amqpTemplate.convertAndSend(EXCHANGE_REPORTING,
+        reportingQueueService.getReportingQueueKey(launchId), request, message -> {
+          Map<String, Object> headers = message.getMessageProperties().getHeaders();
+          headers.put(MessageHeaders.REQUEST_TYPE, RequestType.FINISH_LAUNCH);
+          headers.put(MessageHeaders.USERNAME, user.getUsername());
+          headers.put(MessageHeaders.PROJECT_NAME, projectDetails.getProjectName());
+          headers.put(MessageHeaders.LAUNCH_ID, launchId);
+          headers.put(MessageHeaders.BASE_URL, baseUrl);
+          return message;
+        });
 
-		FinishLaunchRS response = new FinishLaunchRS();
-		response.setId(launchId);
-		return response;
-	}
+    FinishLaunchRS response = new FinishLaunchRS();
+    response.setId(launchId);
+    return response;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/impl/FinishLaunchHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/launch/impl/FinishLaunchHandlerImpl.java
index 94a02d5cb1..4e1d71a82a 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/impl/FinishLaunchHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/impl/FinishLaunchHandlerImpl.java
@@ -16,6 +16,14 @@
 
 package com.epam.ta.reportportal.core.launch.impl;
 
+import static com.epam.ta.reportportal.core.launch.util.LaunchValidator.validate;
+import static com.epam.ta.reportportal.core.launch.util.LaunchValidator.validateRoles;
+import static com.epam.ta.reportportal.core.launch.util.LinkGenerator.generateLaunchLink;
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.FAILED;
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.PASSED;
+import static com.epam.ta.reportportal.ws.model.ErrorType.LAUNCH_NOT_FOUND;
+
+import com.epam.reportportal.extension.event.LaunchFinishedPluginEvent;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.events.activity.LaunchFinishedEvent;
 import com.epam.ta.reportportal.core.hierarchy.FinishHierarchyHandler;
@@ -27,6 +35,7 @@
 import com.epam.ta.reportportal.ws.converter.builders.LaunchBuilder;
 import com.epam.ta.reportportal.ws.model.FinishExecutionRQ;
 import com.epam.ta.reportportal.ws.model.launch.FinishLaunchRS;
+import java.util.Optional;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.context.ApplicationEventPublisher;
@@ -34,15 +43,6 @@
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.Optional;
-
-import static com.epam.ta.reportportal.core.launch.util.LaunchValidator.validate;
-import static com.epam.ta.reportportal.core.launch.util.LaunchValidator.validateRoles;
-import static com.epam.ta.reportportal.core.launch.util.LinkGenerator.generateLaunchLink;
-import static com.epam.ta.reportportal.entity.enums.StatusEnum.FAILED;
-import static com.epam.ta.reportportal.entity.enums.StatusEnum.PASSED;
-import static com.epam.ta.reportportal.ws.model.ErrorType.LAUNCH_NOT_FOUND;
-
 /**
  * Default implementation of {@link FinishLaunchHandler}
  *
@@ -53,72 +53,78 @@
 @Transactional
 public class FinishLaunchHandlerImpl implements FinishLaunchHandler {
 
-	private final LaunchRepository launchRepository;
-	private final FinishHierarchyHandler<Launch> finishHierarchyHandler;
-	private final ApplicationEventPublisher eventPublisher;
-
-	@Autowired
-	public FinishLaunchHandlerImpl(LaunchRepository launchRepository,
-			@Qualifier("finishLaunchHierarchyHandler") FinishHierarchyHandler<Launch> finishHierarchyHandler,
-			ApplicationEventPublisher eventPublisher) {
-		this.launchRepository = launchRepository;
-		this.finishHierarchyHandler = finishHierarchyHandler;
-		this.eventPublisher = eventPublisher;
-	}
-
-	@Override
-	public FinishLaunchRS finishLaunch(String launchId, FinishExecutionRQ finishLaunchRQ, ReportPortalUser.ProjectDetails projectDetails,
-			ReportPortalUser user, String baseUrl) {
-		Launch launch = launchRepository.findByUuid(launchId).orElseThrow(() -> new ReportPortalException(LAUNCH_NOT_FOUND, launchId));
-
-		validateRoles(launch, user, projectDetails);
-		validate(launch, finishLaunchRQ);
-
-		Optional<StatusEnum> status = StatusEnum.fromValue(finishLaunchRQ.getStatus());
-
-		Long id = launch.getId();
-
-		final int finishedCount = finishHierarchyHandler.finishDescendants(launch,
-				status.orElse(StatusEnum.INTERRUPTED),
-				finishLaunchRQ.getEndTime(),
-				user,
-				projectDetails
-		);
-		if (finishedCount > 0) {
-			launch.setStatus(launchRepository.hasRootItemsWithStatusNotEqual(id,
-					StatusEnum.PASSED.name(),
-					StatusEnum.INFO.name(),
-					StatusEnum.WARN.name()
-			) ? FAILED : PASSED);
-		} else {
-			launch.setStatus(status.orElseGet(() -> launchRepository.hasRootItemsWithStatusNotEqual(id,
-					StatusEnum.PASSED.name(),
-					StatusEnum.INFO.name(),
-					StatusEnum.WARN.name()
-			) ? FAILED : PASSED));
-		}
-
-		launch = new LaunchBuilder(launch).addDescription(buildDescription(launch.getDescription(), finishLaunchRQ.getDescription()))
-				.addAttributes(finishLaunchRQ.getAttributes())
-				.addEndTime(finishLaunchRQ.getEndTime())
-				.get();
-
-		LaunchFinishedEvent event = new LaunchFinishedEvent(launch, user, baseUrl);
-		eventPublisher.publishEvent(event);
-
-		FinishLaunchRS response = new FinishLaunchRS();
-		response.setId(launch.getUuid());
-		response.setNumber(launch.getNumber());
-		response.setLink(generateLaunchLink(baseUrl, projectDetails.getProjectName(), String.valueOf(launch.getId())));
-		return response;
-	}
-
-	private String buildDescription(String existDescription, String fromRequestDescription) {
-		if (null != existDescription) {
-			return null != fromRequestDescription ? existDescription + " " + fromRequestDescription : existDescription;
-		} else {
-			return null;
-		}
-	}
+  private final LaunchRepository launchRepository;
+  private final FinishHierarchyHandler<Launch> finishHierarchyHandler;
+  private final ApplicationEventPublisher eventPublisher;
+
+  @Autowired
+  public FinishLaunchHandlerImpl(LaunchRepository launchRepository,
+      @Qualifier("finishLaunchHierarchyHandler") FinishHierarchyHandler<Launch> finishHierarchyHandler,
+      ApplicationEventPublisher eventPublisher) {
+    this.launchRepository = launchRepository;
+    this.finishHierarchyHandler = finishHierarchyHandler;
+    this.eventPublisher = eventPublisher;
+  }
+
+  @Override
+  public FinishLaunchRS finishLaunch(String launchId, FinishExecutionRQ finishLaunchRQ,
+      ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user, String baseUrl) {
+    Launch launch = launchRepository.findByUuid(launchId)
+        .orElseThrow(() -> new ReportPortalException(LAUNCH_NOT_FOUND, launchId));
+
+    validateRoles(launch, user, projectDetails);
+    validate(launch, finishLaunchRQ);
+
+    Optional<StatusEnum> status = StatusEnum.fromValue(finishLaunchRQ.getStatus());
+
+    Long id = launch.getId();
+
+    final int finishedCount = finishHierarchyHandler.finishDescendants(launch,
+        status.orElse(StatusEnum.INTERRUPTED),
+        finishLaunchRQ.getEndTime(),
+        user,
+        projectDetails
+    );
+    if (finishedCount > 0) {
+      launch.setStatus(launchRepository.hasRootItemsWithStatusNotEqual(id,
+          StatusEnum.PASSED.name(),
+          StatusEnum.INFO.name(),
+          StatusEnum.WARN.name()
+      ) ? FAILED : PASSED);
+    } else {
+      launch.setStatus(status.orElseGet(() -> launchRepository.hasRootItemsWithStatusNotEqual(id,
+          StatusEnum.PASSED.name(),
+          StatusEnum.INFO.name(),
+          StatusEnum.WARN.name()
+      ) ? FAILED : PASSED));
+    }
+
+    launch = new LaunchBuilder(launch).addDescription(
+            buildDescription(launch.getDescription(), finishLaunchRQ.getDescription()))
+        .addAttributes(finishLaunchRQ.getAttributes())
+        .addEndTime(finishLaunchRQ.getEndTime())
+        .get();
+
+    eventPublisher.publishEvent(
+        new LaunchFinishedPluginEvent(launch.getId(), launch.getProjectId()));
+    eventPublisher.publishEvent(new LaunchFinishedEvent(launch, user, baseUrl));
+
+    FinishLaunchRS response = new FinishLaunchRS();
+    response.setId(launch.getUuid());
+    response.setNumber(launch.getNumber());
+    response.setLink(generateLaunchLink(baseUrl, projectDetails.getProjectName(),
+        String.valueOf(launch.getId())));
+    return response;
+  }
+
+  private String buildDescription(String existDescription, String fromRequestDescription) {
+    if (null != existDescription) {
+      return null != fromRequestDescription ? existDescription + " " + fromRequestDescription
+          : existDescription;
+    } else {
+      return null;
+    }
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/impl/GetLaunchHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/launch/impl/GetLaunchHandlerImpl.java
index c432c07fc2..28d2093850 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/impl/GetLaunchHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/impl/GetLaunchHandlerImpl.java
@@ -16,17 +16,57 @@
 
 package com.epam.ta.reportportal.core.launch.impl;
 
+import static com.epam.ta.reportportal.commons.Preconditions.HAS_ANY_MODE;
+import static com.epam.ta.reportportal.commons.Preconditions.statusIn;
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import static com.epam.ta.reportportal.commons.Predicates.not;
+import static com.epam.ta.reportportal.commons.Predicates.notNull;
+import static com.epam.ta.reportportal.commons.querygen.Condition.EQUALS;
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_ID;
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_PROJECT_ID;
+import static com.epam.ta.reportportal.commons.querygen.constant.LaunchCriteriaConstant.CRITERIA_LAUNCH_MODE;
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DEFECTS_AUTOMATION_BUG_TOTAL;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DEFECTS_NO_DEFECT_TOTAL;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DEFECTS_PRODUCT_BUG_TOTAL;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DEFECTS_SYSTEM_ISSUE_TOTAL;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DEFECTS_TO_INVESTIGATE_TOTAL;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.EXECUTIONS_FAILED;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.EXECUTIONS_PASSED;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.EXECUTIONS_SKIPPED;
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.IN_PROGRESS;
+import static com.epam.ta.reportportal.ws.model.ErrorType.ACCESS_DENIED;
+import static com.epam.ta.reportportal.ws.model.ErrorType.INCORRECT_FILTER_PARAMETERS;
+import static com.epam.ta.reportportal.ws.model.ErrorType.LAUNCH_NOT_FOUND;
+import static com.epam.ta.reportportal.ws.model.ValidationConstraints.MAX_LAUNCH_NAME_LENGTH;
+import static com.epam.ta.reportportal.ws.model.ValidationConstraints.MIN_LAUNCH_NAME_LENGTH;
+import static com.epam.ta.reportportal.ws.model.launch.Mode.DEBUG;
+import static com.epam.ta.reportportal.ws.model.launch.Mode.DEFAULT;
+import static java.util.Collections.singletonMap;
+import static java.util.Optional.ofNullable;
+
 import com.epam.reportportal.extension.event.GetLaunchResourceCollectionEvent;
 import com.epam.ta.reportportal.commons.Predicates;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
-import com.epam.ta.reportportal.commons.querygen.*;
+import com.epam.ta.reportportal.commons.querygen.Condition;
+import com.epam.ta.reportportal.commons.querygen.ConvertibleCondition;
+import com.epam.ta.reportportal.commons.querygen.Filter;
+import com.epam.ta.reportportal.commons.querygen.FilterCondition;
+import com.epam.ta.reportportal.commons.querygen.ProjectFilter;
 import com.epam.ta.reportportal.commons.validation.Suppliers;
 import com.epam.ta.reportportal.core.jasper.GetJasperReportHandler;
 import com.epam.ta.reportportal.core.jasper.constants.LaunchReportConstants;
 import com.epam.ta.reportportal.core.jasper.util.JasperDataProvider;
 import com.epam.ta.reportportal.core.launch.GetLaunchHandler;
 import com.epam.ta.reportportal.core.launch.cluster.GetClusterHandler;
-import com.epam.ta.reportportal.dao.*;
+import com.epam.ta.reportportal.dao.ItemAttributeRepository;
+import com.epam.ta.reportportal.dao.LaunchRepository;
+import com.epam.ta.reportportal.dao.ProjectRepository;
+import com.epam.ta.reportportal.dao.TestItemRepository;
+import com.epam.ta.reportportal.dao.UserRepository;
+import com.epam.ta.reportportal.dao.WidgetContentRepository;
 import com.epam.ta.reportportal.entity.enums.LaunchModeEnum;
 import com.epam.ta.reportportal.entity.enums.StatusEnum;
 import com.epam.ta.reportportal.entity.jasper.ReportFormat;
@@ -44,6 +84,14 @@
 import com.epam.ta.reportportal.ws.model.launch.cluster.ClusterInfoResource;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
+import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
 import net.sf.jasperreports.engine.JREmptyDataSource;
 import net.sf.jasperreports.engine.JasperPrint;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -55,30 +103,6 @@
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.io.OutputStream;
-import java.util.*;
-import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.commons.Preconditions.HAS_ANY_MODE;
-import static com.epam.ta.reportportal.commons.Preconditions.statusIn;
-import static com.epam.ta.reportportal.commons.Predicates.*;
-import static com.epam.ta.reportportal.commons.querygen.Condition.EQUALS;
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_ID;
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_PROJECT_ID;
-import static com.epam.ta.reportportal.commons.querygen.constant.LaunchCriteriaConstant.CRITERIA_LAUNCH_MODE;
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
-import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.*;
-import static com.epam.ta.reportportal.entity.enums.StatusEnum.IN_PROGRESS;
-import static com.epam.ta.reportportal.ws.model.ErrorType.*;
-import static com.epam.ta.reportportal.ws.model.ValidationConstraints.MAX_LAUNCH_NAME_LENGTH;
-import static com.epam.ta.reportportal.ws.model.ValidationConstraints.MIN_LAUNCH_NAME_LENGTH;
-import static com.epam.ta.reportportal.ws.model.launch.Mode.DEBUG;
-import static com.epam.ta.reportportal.ws.model.launch.Mode.DEFAULT;
-import static java.util.Collections.singletonMap;
-import static java.util.Optional.ofNullable;
-
 /**
  * Default implementation of {@link com.epam.ta.reportportal.core.launch.GetLaunchHandler}
  *
@@ -88,281 +112,314 @@
 @Service
 public class GetLaunchHandlerImpl implements GetLaunchHandler {
 
-	private final GetClusterHandler getClusterHandler;
-	private final LaunchRepository launchRepository;
-	private final TestItemRepository testItemRepository;
-	private final ItemAttributeRepository itemAttributeRepository;
-	private final ProjectRepository projectRepository;
-	private final WidgetContentRepository widgetContentRepository;
-	private final UserRepository userRepository;
-	private final JasperDataProvider dataProvider;
-	private final GetJasperReportHandler<Launch> jasperReportHandler;
-	private final LaunchConverter launchConverter;
-	private final ApplicationEventPublisher applicationEventPublisher;
-
-	@Autowired
-	public GetLaunchHandlerImpl(GetClusterHandler getClusterHandler, LaunchRepository launchRepository,
-			TestItemRepository testItemRepository, ItemAttributeRepository itemAttributeRepository, ProjectRepository projectRepository,
-			WidgetContentRepository widgetContentRepository, UserRepository userRepository, JasperDataProvider dataProvider,
-			@Qualifier("launchJasperReportHandler") GetJasperReportHandler<Launch> jasperReportHandler, LaunchConverter launchConverter,
-			ApplicationEventPublisher applicationEventPublisher) {
-		this.getClusterHandler = getClusterHandler;
-		this.launchRepository = launchRepository;
-		this.testItemRepository = testItemRepository;
-		this.itemAttributeRepository = itemAttributeRepository;
-		this.projectRepository = projectRepository;
-		this.widgetContentRepository = widgetContentRepository;
-		this.userRepository = userRepository;
-		this.dataProvider = Preconditions.checkNotNull(dataProvider);
-		this.jasperReportHandler = jasperReportHandler;
-		this.launchConverter = launchConverter;
-		this.applicationEventPublisher = applicationEventPublisher;
-	}
-
-	@Override
-	public Launch get(Long id) {
-		return launchRepository.findById(id).orElseThrow(() -> new ReportPortalException(LAUNCH_NOT_FOUND, id));
-	}
-
-	@Override
-	public LaunchResource getLaunch(String launchId, ReportPortalUser.ProjectDetails projectDetails) {
-		final Launch launch = findLaunch(launchId, projectDetails);
-		return getLaunchResource(launch);
-	}
-
-	private Launch findLaunch(String launchId, ReportPortalUser.ProjectDetails projectDetails) {
-		Launch launch;
-		try {
-			launch = get(Long.parseLong(launchId));
-		} catch (NumberFormatException e) {
-			launch = launchRepository.findByUuid(launchId).orElseThrow(() -> new ReportPortalException(LAUNCH_NOT_FOUND, launchId));
-		}
-		validate(launch, projectDetails);
-		return launch;
-	}
-
-	@Override
-	public LaunchResource getLaunchByProjectName(String projectName, Pageable pageable, Filter filter, String username) {
-		Project project = projectRepository.findByName(projectName)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.PROJECT_NOT_FOUND, projectName));
-
-		Page<Launch> launches = launchRepository.findByFilter(ProjectFilter.of(filter, project.getId()), pageable);
-		expect(launches, notNull()).verify(LAUNCH_NOT_FOUND);
-		return getLaunchResource(launches.iterator().next());
-	}
-
-	private LaunchResource getLaunchResource(Launch launch) {
-		final LaunchResource launchResource = launchConverter.TO_RESOURCE.apply(launch);
-		applicationEventPublisher.publishEvent(new GetLaunchResourceCollectionEvent(Collections.singletonList(launchResource)));
-		return launchResource;
-	}
-
-	@Override
-	public Iterable<LaunchResource> getProjectLaunches(ReportPortalUser.ProjectDetails projectDetails, Filter filter, Pageable pageable,
-			String userName) {
-		validateModeConditions(filter);
-		Project project = projectRepository.findById(projectDetails.getProjectId())
-				.orElseThrow(() -> new ReportPortalException(ErrorType.PROJECT_NOT_FOUND, projectDetails.getProjectId()));
-
-		filter = addLaunchCommonCriteria(DEFAULT, filter);
-		Page<Launch> launches = launchRepository.findByFilter(ProjectFilter.of(filter, project.getId()), pageable);
-		return getLaunchResources(launches);
-	}
-
-	/*
-	 * Changed logic for this method: It should return DEBUG launches for
-	 * project users, for specified user or only owner
-	 */
-	@Override
-	public Iterable<LaunchResource> getDebugLaunches(ReportPortalUser.ProjectDetails projectDetails, Filter filter, Pageable pageable) {
-		validateModeConditions(filter);
-		filter = addLaunchCommonCriteria(DEBUG, filter);
-		Page<Launch> launches = launchRepository.findByFilter(ProjectFilter.of(filter, projectDetails.getProjectId()), pageable);
-		return getLaunchResources(launches);
-	}
-
-	@Override
-	public List<String> getAttributeKeys(ReportPortalUser.ProjectDetails projectDetails, String value) {
-		return itemAttributeRepository.findLaunchAttributeKeys(projectDetails.getProjectId(), value, false);
-	}
-
-	@Override
-	public List<String> getAttributeValues(ReportPortalUser.ProjectDetails projectDetails, String key, String value) {
-		return itemAttributeRepository.findLaunchAttributeValues(projectDetails.getProjectId(), key, value, false);
-	}
-
-	@Override
-	public Iterable<LaunchResource> getLatestLaunches(ReportPortalUser.ProjectDetails projectDetails, Filter filter, Pageable pageable) {
-
-		validateModeConditions(filter);
-
-		Project project = projectRepository.findById(projectDetails.getProjectId())
-				.orElseThrow(() -> new ReportPortalException(ErrorType.PROJECT_NOT_FOUND, projectDetails.getProjectId()));
-
-		filter = addLaunchCommonCriteria(DEFAULT, filter);
-
-		Page<Launch> launches = launchRepository.findAllLatestByFilter(ProjectFilter.of(filter, project.getId()), pageable);
-		return getLaunchResources(launches);
-	}
-
-	@Override
-	@Transactional(readOnly = true)
-	public Iterable<ClusterInfoResource> getClusters(String launchId, ReportPortalUser.ProjectDetails projectDetails, Pageable pageable) {
-		final Launch launch = findLaunch(launchId, projectDetails);
-		return getClusterHandler.getResources(launch, pageable);
-	}
-
-	@Override
-	public boolean hasItemsWithIssues(Launch launch) {
-		return testItemRepository.hasItemsWithIssueByLaunch(launch.getId());
-	}
-
-	private Iterable<LaunchResource> getLaunchResources(Page<Launch> launches) {
-		final com.epam.ta.reportportal.ws.model.Page<LaunchResource> launchResourcePage = PagedResourcesAssembler.pageConverter(
-				launchConverter.TO_RESOURCE).apply(launches);
-		applicationEventPublisher.publishEvent(new GetLaunchResourceCollectionEvent(launchResourcePage.getContent()));
-		return launchResourcePage;
-	}
-
-	@Override
-	public List<String> getLaunchNames(ReportPortalUser.ProjectDetails projectDetails, String value) {
-		expect(value.length() >= MIN_LAUNCH_NAME_LENGTH && value.length() <= MAX_LAUNCH_NAME_LENGTH, equalTo(true)).verify(
-				INCORRECT_FILTER_PARAMETERS,
-				formattedSupplier("Length of the launch name string '{}' is less than {} symbols or more than {} symbols",
-						value,
-						MIN_LAUNCH_NAME_LENGTH,
-						MAX_LAUNCH_NAME_LENGTH
-				)
-		);
-		return launchRepository.getLaunchNamesByModeExcludedByStatus(projectDetails.getProjectId(),
-				value,
-				LaunchModeEnum.DEFAULT,
-				StatusEnum.IN_PROGRESS
-		);
-	}
-
-	@Override
-	public List<String> getOwners(ReportPortalUser.ProjectDetails projectDetails, String value, String mode) {
-		expect(value.length() > 2, equalTo(true)).verify(INCORRECT_FILTER_PARAMETERS,
-				formattedSupplier("Length of the filtering string '{}' is less than 3 symbols", value)
-		);
-
-		LaunchModeEnum launchMode = LaunchModeEnum.findByName(mode)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.INCORRECT_FILTER_PARAMETERS,
-						formattedSupplier("Mode - {} doesn't exist.", mode)
-				));
-
-		return launchRepository.getOwnerNames(projectDetails.getProjectId(), value, launchMode.name());
-	}
-
-	@Override
-	public Map<String, List<ChartStatisticsContent>> getLaunchesComparisonInfo(ReportPortalUser.ProjectDetails projectDetails, Long[] ids) {
-
-		List<String> contentFields = Lists.newArrayList(DEFECTS_AUTOMATION_BUG_TOTAL,
-				DEFECTS_NO_DEFECT_TOTAL,
-				DEFECTS_PRODUCT_BUG_TOTAL,
-				DEFECTS_SYSTEM_ISSUE_TOTAL,
-				DEFECTS_TO_INVESTIGATE_TOTAL,
-				EXECUTIONS_FAILED,
-				EXECUTIONS_PASSED,
-				EXECUTIONS_SKIPPED
-		);
-
-		Filter filter = Filter.builder()
-				.withTarget(Launch.class)
-				.withCondition(new FilterCondition(Condition.IN,
-						false,
-						Arrays.stream(ids).map(String::valueOf).collect(Collectors.joining(",")),
-						CRITERIA_ID
-				))
-				.withCondition(new FilterCondition(EQUALS, false, String.valueOf(projectDetails.getProjectId()), CRITERIA_PROJECT_ID))
-				.build();
-
-		List<ChartStatisticsContent> result = widgetContentRepository.launchesComparisonStatistics(filter,
-				contentFields,
-				Sort.unsorted(),
-				ids.length
-		);
-
-		return singletonMap(RESULT, result);
-
-	}
-
-	@Override
-	public Map<String, String> getStatuses(ReportPortalUser.ProjectDetails projectDetails, Long[] ids) {
-		return launchRepository.getStatuses(projectDetails.getProjectId(), ids);
-	}
-
-	@Override
-	public void exportLaunch(Long launchId, ReportFormat reportFormat, OutputStream outputStream, ReportPortalUser user) {
-
-		Launch launch = launchRepository.findById(launchId)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND, launchId));
-		expect(launch.getStatus(), not(statusIn(IN_PROGRESS))).verify(ErrorType.FORBIDDEN_OPERATION,
-				Suppliers.formattedSupplier("Launch '{}' has IN_PROGRESS status. Impossible to export such elements.", launchId)
-		);
-
-		String userFullName = userRepository.findById(user.getUserId())
-				.map(User::getFullName)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.USER_NOT_FOUND, user.getUserId()));
-
-		Map<String, Object> params = jasperReportHandler.convertParams(launch);
-
-		fillWithAdditionalParams(params, launch, userFullName);
-
-		JasperPrint jasperPrint = jasperReportHandler.getJasperPrint(params, new JREmptyDataSource());
-
-		jasperReportHandler.writeReport(reportFormat, outputStream, jasperPrint);
-
-	}
-
-	/**
-	 * Validate user credentials and launch affiliation to the project
-	 *
-	 * @param launch         {@link Launch}
-	 * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
-	 */
-	private void validate(Launch launch, ReportPortalUser.ProjectDetails projectDetails) {
-		expect(launch.getProjectId(), Predicates.equalTo(projectDetails.getProjectId())).verify(ACCESS_DENIED);
-		if (LaunchModeEnum.DEBUG.equals(launch.getMode())) {
-			expect(projectDetails.getProjectRole(), not(Predicates.equalTo(ProjectRole.CUSTOMER))).verify(ACCESS_DENIED);
-		}
-	}
-
-	/**
-	 * Add to filter project and mode criteria
-	 *
-	 * @param filter Filter to update
-	 * @return Updated filter
-	 */
-	private Filter addLaunchCommonCriteria(Mode mode, Filter filter) {
-		return ofNullable(filter).orElseGet(() -> new Filter(Launch.class, Lists.newArrayList()))
-				.withCondition(FilterCondition.builder().eq(CRITERIA_LAUNCH_MODE, mode.name()).build());
-	}
-
-	/**
-	 * Validate if filter doesn't contain any "mode" related conditions.
-	 *
-	 * @param filter
-	 */
-	private void validateModeConditions(Filter filter) {
-		expect(filter.getFilterConditions()
-				.stream()
-				.map(ConvertibleCondition::getAllConditions)
-				.flatMap(Collection::stream)
-				.anyMatch(HAS_ANY_MODE), equalTo(false)).verify(INCORRECT_FILTER_PARAMETERS,
-				"Filters for 'mode' aren't applicable for project's launches."
-		);
-	}
-
-	private void fillWithAdditionalParams(Map<String, Object> params, Launch launch, String userFullName) {
-
-		Optional<String> owner = userRepository.findById(launch.getUserId()).map(User::getFullName);
-
-		/* Check if launch owner still in system if not - setup principal */
-		params.put(LaunchReportConstants.OWNER, owner.orElse(userFullName));
-
-		params.put(LaunchReportConstants.TEST_ITEMS, dataProvider.getTestItemsOfLaunch(launch));
-	}
+  private final GetClusterHandler getClusterHandler;
+  private final LaunchRepository launchRepository;
+  private final TestItemRepository testItemRepository;
+  private final ItemAttributeRepository itemAttributeRepository;
+  private final ProjectRepository projectRepository;
+  private final WidgetContentRepository widgetContentRepository;
+  private final UserRepository userRepository;
+  private final JasperDataProvider dataProvider;
+  private final GetJasperReportHandler<Launch> jasperReportHandler;
+  private final LaunchConverter launchConverter;
+  private final ApplicationEventPublisher applicationEventPublisher;
+
+  @Autowired
+  public GetLaunchHandlerImpl(GetClusterHandler getClusterHandler,
+      LaunchRepository launchRepository,
+      TestItemRepository testItemRepository, ItemAttributeRepository itemAttributeRepository,
+      ProjectRepository projectRepository,
+      WidgetContentRepository widgetContentRepository, UserRepository userRepository,
+      JasperDataProvider dataProvider,
+      @Qualifier("launchJasperReportHandler") GetJasperReportHandler<Launch> jasperReportHandler,
+      LaunchConverter launchConverter,
+      ApplicationEventPublisher applicationEventPublisher) {
+    this.getClusterHandler = getClusterHandler;
+    this.launchRepository = launchRepository;
+    this.testItemRepository = testItemRepository;
+    this.itemAttributeRepository = itemAttributeRepository;
+    this.projectRepository = projectRepository;
+    this.widgetContentRepository = widgetContentRepository;
+    this.userRepository = userRepository;
+    this.dataProvider = Preconditions.checkNotNull(dataProvider);
+    this.jasperReportHandler = jasperReportHandler;
+    this.launchConverter = launchConverter;
+    this.applicationEventPublisher = applicationEventPublisher;
+  }
+
+  @Override
+  public Launch get(Long id) {
+    return launchRepository.findById(id)
+        .orElseThrow(() -> new ReportPortalException(LAUNCH_NOT_FOUND, id));
+  }
+
+  @Override
+  public LaunchResource getLaunch(String launchId, ReportPortalUser.ProjectDetails projectDetails) {
+    final Launch launch = findLaunch(launchId, projectDetails);
+    return getLaunchResource(launch);
+  }
+
+  private Launch findLaunch(String launchId, ReportPortalUser.ProjectDetails projectDetails) {
+    Launch launch;
+    try {
+      launch = get(Long.parseLong(launchId));
+    } catch (NumberFormatException e) {
+      launch = launchRepository.findByUuid(launchId)
+          .orElseThrow(() -> new ReportPortalException(LAUNCH_NOT_FOUND, launchId));
+    }
+    validate(launch, projectDetails);
+    return launch;
+  }
+
+  @Override
+  public LaunchResource getLaunchByProjectName(String projectName, Pageable pageable, Filter filter,
+      String username) {
+    Project project = projectRepository.findByName(projectName)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.PROJECT_NOT_FOUND, projectName));
+
+    Page<Launch> launches = launchRepository.findByFilter(ProjectFilter.of(filter, project.getId()),
+        pageable);
+    expect(launches, notNull()).verify(LAUNCH_NOT_FOUND);
+    return getLaunchResource(launches.iterator().next());
+  }
+
+  private LaunchResource getLaunchResource(Launch launch) {
+    final LaunchResource launchResource = launchConverter.TO_RESOURCE.apply(launch);
+    applicationEventPublisher.publishEvent(
+        new GetLaunchResourceCollectionEvent(Collections.singletonList(launchResource)));
+    return launchResource;
+  }
+
+  @Override
+  public Iterable<LaunchResource> getProjectLaunches(ReportPortalUser.ProjectDetails projectDetails,
+      Filter filter, Pageable pageable,
+      String userName) {
+    validateModeConditions(filter);
+    Project project = projectRepository.findById(projectDetails.getProjectId())
+        .orElseThrow(() -> new ReportPortalException(ErrorType.PROJECT_NOT_FOUND,
+            projectDetails.getProjectId()));
+
+    filter = addLaunchCommonCriteria(DEFAULT, filter);
+    Page<Launch> launches = launchRepository.findByFilter(ProjectFilter.of(filter, project.getId()),
+        pageable);
+    return getLaunchResources(launches);
+  }
+
+  /*
+   * Changed logic for this method: It should return DEBUG launches for
+   * project users, for specified user or only owner
+   */
+  @Override
+  public Iterable<LaunchResource> getDebugLaunches(ReportPortalUser.ProjectDetails projectDetails,
+      Filter filter, Pageable pageable) {
+    validateModeConditions(filter);
+    filter = addLaunchCommonCriteria(DEBUG, filter);
+    Page<Launch> launches = launchRepository.findByFilter(
+        ProjectFilter.of(filter, projectDetails.getProjectId()), pageable);
+    return getLaunchResources(launches);
+  }
+
+  @Override
+  public List<String> getAttributeKeys(ReportPortalUser.ProjectDetails projectDetails,
+      String value) {
+    return itemAttributeRepository.findLaunchAttributeKeys(projectDetails.getProjectId(), value,
+        false);
+  }
+
+  @Override
+  public List<String> getAttributeValues(ReportPortalUser.ProjectDetails projectDetails, String key,
+      String value) {
+    return itemAttributeRepository.findLaunchAttributeValues(projectDetails.getProjectId(), key,
+        value, false);
+  }
+
+  @Override
+  public Iterable<LaunchResource> getLatestLaunches(ReportPortalUser.ProjectDetails projectDetails,
+      Filter filter, Pageable pageable) {
+
+    validateModeConditions(filter);
+
+    Project project = projectRepository.findById(projectDetails.getProjectId())
+        .orElseThrow(() -> new ReportPortalException(ErrorType.PROJECT_NOT_FOUND,
+            projectDetails.getProjectId()));
+
+    filter = addLaunchCommonCriteria(DEFAULT, filter);
+
+    Page<Launch> launches = launchRepository.findAllLatestByFilter(
+        ProjectFilter.of(filter, project.getId()), pageable);
+    return getLaunchResources(launches);
+  }
+
+  @Override
+  @Transactional(readOnly = true)
+  public Iterable<ClusterInfoResource> getClusters(String launchId,
+      ReportPortalUser.ProjectDetails projectDetails, Pageable pageable) {
+    final Launch launch = findLaunch(launchId, projectDetails);
+    return getClusterHandler.getResources(launch, pageable);
+  }
+
+  @Override
+  public boolean hasItemsWithIssues(Launch launch) {
+    return testItemRepository.hasItemsWithIssueByLaunch(launch.getId());
+  }
+
+  private Iterable<LaunchResource> getLaunchResources(Page<Launch> launches) {
+    final com.epam.ta.reportportal.ws.model.Page<LaunchResource> launchResourcePage = PagedResourcesAssembler.pageConverter(
+        launchConverter.TO_RESOURCE).apply(launches);
+    applicationEventPublisher.publishEvent(
+        new GetLaunchResourceCollectionEvent(launchResourcePage.getContent()));
+    return launchResourcePage;
+  }
+
+  @Override
+  public List<String> getLaunchNames(ReportPortalUser.ProjectDetails projectDetails, String value) {
+    expect(value.length() <= MAX_LAUNCH_NAME_LENGTH, equalTo(true)).verify(
+        INCORRECT_FILTER_PARAMETERS,
+        formattedSupplier("Length of the launch name string '{}' more than {} symbols",
+            value,
+            MAX_LAUNCH_NAME_LENGTH
+        )
+    );
+    return launchRepository.getLaunchNamesByModeExcludedByStatus(projectDetails.getProjectId(),
+        value,
+        LaunchModeEnum.DEFAULT,
+        StatusEnum.IN_PROGRESS
+    );
+  }
+
+  @Override
+  public List<String> getOwners(ReportPortalUser.ProjectDetails projectDetails, String value,
+      String mode) {
+    expect(value.length() > 2, equalTo(true)).verify(INCORRECT_FILTER_PARAMETERS,
+        formattedSupplier("Length of the filtering string '{}' is less than 3 symbols", value)
+    );
+
+    LaunchModeEnum launchMode = LaunchModeEnum.findByName(mode)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.INCORRECT_FILTER_PARAMETERS,
+            formattedSupplier("Mode - {} doesn't exist.", mode)
+        ));
+
+    return launchRepository.getOwnerNames(projectDetails.getProjectId(), value, launchMode.name());
+  }
+
+  @Override
+  public Map<String, List<ChartStatisticsContent>> getLaunchesComparisonInfo(
+      ReportPortalUser.ProjectDetails projectDetails, Long[] ids) {
+
+    List<String> contentFields = Lists.newArrayList(DEFECTS_AUTOMATION_BUG_TOTAL,
+        DEFECTS_NO_DEFECT_TOTAL,
+        DEFECTS_PRODUCT_BUG_TOTAL,
+        DEFECTS_SYSTEM_ISSUE_TOTAL,
+        DEFECTS_TO_INVESTIGATE_TOTAL,
+        EXECUTIONS_FAILED,
+        EXECUTIONS_PASSED,
+        EXECUTIONS_SKIPPED
+    );
+
+    Filter filter = Filter.builder()
+        .withTarget(Launch.class)
+        .withCondition(new FilterCondition(Condition.IN,
+            false,
+            Arrays.stream(ids).map(String::valueOf).collect(Collectors.joining(",")),
+            CRITERIA_ID
+        ))
+        .withCondition(
+            new FilterCondition(EQUALS, false, String.valueOf(projectDetails.getProjectId()),
+                CRITERIA_PROJECT_ID))
+        .build();
+
+    List<ChartStatisticsContent> result = widgetContentRepository.launchesComparisonStatistics(
+        filter,
+        contentFields,
+        Sort.unsorted(),
+        ids.length
+    );
+
+    return singletonMap(RESULT, result);
+
+  }
+
+  @Override
+  public Map<String, String> getStatuses(ReportPortalUser.ProjectDetails projectDetails,
+      Long[] ids) {
+    return launchRepository.getStatuses(projectDetails.getProjectId(), ids);
+  }
+
+  @Override
+  public void exportLaunch(Long launchId, ReportFormat reportFormat, OutputStream outputStream,
+      ReportPortalUser user) {
+
+    Launch launch = launchRepository.findById(launchId)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND, launchId));
+    expect(launch.getStatus(), not(statusIn(IN_PROGRESS))).verify(ErrorType.FORBIDDEN_OPERATION,
+        Suppliers.formattedSupplier(
+            "Launch '{}' has IN_PROGRESS status. Impossible to export such elements.", launchId)
+    );
+
+    String userFullName = userRepository.findById(user.getUserId())
+        .map(User::getFullName)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.USER_NOT_FOUND, user.getUserId()));
+
+    Map<String, Object> params = jasperReportHandler.convertParams(launch);
+
+    fillWithAdditionalParams(params, launch, userFullName);
+
+    JasperPrint jasperPrint = jasperReportHandler.getJasperPrint(params, new JREmptyDataSource());
+
+    jasperReportHandler.writeReport(reportFormat, outputStream, jasperPrint);
+
+  }
+
+  /**
+   * Validate user credentials and launch affiliation to the project
+   *
+   * @param launch         {@link Launch}
+   * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
+   */
+  private void validate(Launch launch, ReportPortalUser.ProjectDetails projectDetails) {
+    expect(launch.getProjectId(), Predicates.equalTo(projectDetails.getProjectId())).verify(
+        ACCESS_DENIED);
+    if (LaunchModeEnum.DEBUG.equals(launch.getMode())) {
+      expect(projectDetails.getProjectRole(), not(Predicates.equalTo(ProjectRole.CUSTOMER))).verify(
+          ACCESS_DENIED);
+    }
+  }
+
+  /**
+   * Add to filter project and mode criteria
+   *
+   * @param filter Filter to update
+   * @return Updated filter
+   */
+  private Filter addLaunchCommonCriteria(Mode mode, Filter filter) {
+    return ofNullable(filter).orElseGet(() -> new Filter(Launch.class, Lists.newArrayList()))
+        .withCondition(FilterCondition.builder().eq(CRITERIA_LAUNCH_MODE, mode.name()).build());
+  }
+
+  /**
+   * Validate if filter doesn't contain any "mode" related conditions.
+   *
+   * @param filter
+   */
+  private void validateModeConditions(Filter filter) {
+    expect(filter.getFilterConditions()
+        .stream()
+        .map(ConvertibleCondition::getAllConditions)
+        .flatMap(Collection::stream)
+        .anyMatch(HAS_ANY_MODE), equalTo(false)).verify(INCORRECT_FILTER_PARAMETERS,
+        "Filters for 'mode' aren't applicable for project's launches."
+    );
+  }
+
+  private void fillWithAdditionalParams(Map<String, Object> params, Launch launch,
+      String userFullName) {
+
+    Optional<String> owner = userRepository.findById(launch.getUserId()).map(User::getFullName);
+
+    /* Check if launch owner still in system if not - setup principal */
+    params.put(LaunchReportConstants.OWNER, owner.orElse(userFullName));
+
+    params.put(LaunchReportConstants.TEST_ITEMS, dataProvider.getTestItemsOfLaunch(launch));
+  }
 
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/impl/MergeLaunchHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/launch/impl/MergeLaunchHandlerImpl.java
index c6a6c5c50a..6d463d219e 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/impl/MergeLaunchHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/impl/MergeLaunchHandlerImpl.java
@@ -16,6 +16,19 @@
 
 package com.epam.ta.reportportal.core.launch.impl;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import static com.epam.ta.reportportal.commons.Predicates.not;
+import static com.epam.ta.reportportal.commons.Predicates.notNull;
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.IN_PROGRESS;
+import static com.epam.ta.reportportal.entity.user.UserRole.ADMINISTRATOR;
+import static com.epam.ta.reportportal.ws.model.ErrorType.ACCESS_DENIED;
+import static com.epam.ta.reportportal.ws.model.ErrorType.FORBIDDEN_OPERATION;
+import static com.epam.ta.reportportal.ws.model.ErrorType.LAUNCH_IS_NOT_FINISHED;
+import static com.epam.ta.reportportal.ws.model.ErrorType.LAUNCH_NOT_FOUND;
+import static com.epam.ta.reportportal.ws.model.ErrorType.PROJECT_NOT_FOUND;
+import static com.epam.ta.reportportal.ws.model.ErrorType.UNSUPPORTED_MERGE_STRATEGY_TYPE;
+
 import com.epam.ta.reportportal.commons.Preconditions;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.validation.Suppliers;
@@ -37,19 +50,12 @@
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.epam.ta.reportportal.ws.model.launch.LaunchResource;
 import com.epam.ta.reportportal.ws.model.launch.MergeLaunchesRQ;
+import java.util.List;
+import java.util.Set;
 import org.apache.commons.collections.CollectionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Set;
-
-import static com.epam.ta.reportportal.commons.Predicates.*;
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.entity.enums.StatusEnum.IN_PROGRESS;
-import static com.epam.ta.reportportal.entity.user.UserRole.ADMINISTRATOR;
-import static com.epam.ta.reportportal.ws.model.ErrorType.*;
-
 /**
  * @author Aliaksei_Makayed
  * @author Andrei_Ramanchuk
@@ -58,102 +64,113 @@
 @Service
 public class MergeLaunchHandlerImpl implements MergeLaunchHandler {
 
-	private final LaunchRepository launchRepository;
-
-	private final TestItemRepository testItemRepository;
-
-	private final ProjectRepository projectRepository;
-
-	private final LaunchMergeFactory launchMergeFactory;
-
-	private final LaunchConverter launchConverter;
-
-	private final LaunchPreparerService launchPreparerService;
-
-	private final LogIndexer logIndexer;
-
-	@Autowired
-	public MergeLaunchHandlerImpl(LaunchRepository launchRepository, TestItemRepository testItemRepository,
-			ProjectRepository projectRepository, LaunchMergeFactory launchMergeFactory, LaunchConverter launchConverter,
-			LaunchPreparerService launchPreparerService, LogIndexer logIndexer) {
-		this.launchRepository = launchRepository;
-		this.testItemRepository = testItemRepository;
-		this.projectRepository = projectRepository;
-		this.launchMergeFactory = launchMergeFactory;
-		this.launchConverter = launchConverter;
-		this.launchPreparerService = launchPreparerService;
-		this.logIndexer = logIndexer;
-	}
-
-	@Override
-	public LaunchResource mergeLaunches(ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user, MergeLaunchesRQ rq) {
-		Project project = projectRepository.findById(projectDetails.getProjectId())
-				.orElseThrow(() -> new ReportPortalException(PROJECT_NOT_FOUND, projectDetails.getProjectName()));
-
-		Set<Long> launchesIds = rq.getLaunches();
-
-		expect(CollectionUtils.isNotEmpty(launchesIds), equalTo(true)).verify(ErrorType.BAD_REQUEST_ERROR,
-				"At least one launch id should be  specified for merging"
-		);
-
-		expect(launchesIds.size() > 0, equalTo(true)).verify(ErrorType.BAD_REQUEST_ERROR,
-				"At least 1 launch id should be provided for merging"
-		);
-
-		List<Launch> launchesList = launchRepository.findAllById(launchesIds);
-
-		expect(launchesIds.size(), equalTo(launchesList.size())).verify(ErrorType.BAD_REQUEST_ERROR,
-				"Not all launches with provided ids were found"
-		);
-
-		validateMergingLaunches(launchesList, user, projectDetails);
-
-		MergeStrategyType type = MergeStrategyType.fromValue(rq.getMergeStrategyType());
-		expect(type, notNull()).verify(UNSUPPORTED_MERGE_STRATEGY_TYPE, type);
-
-		Launch newLaunch = launchMergeFactory.getLaunchMergeStrategy(type).mergeLaunches(projectDetails, user, rq, launchesList);
-		newLaunch.setStatus(StatisticsHelper.getStatusFromStatistics(newLaunch.getStatistics()));
-
-		launchRepository.deleteAll(launchesList);
-
-		logIndexer.indexLaunchLogs(newLaunch, AnalyzerUtils.getAnalyzerConfig(project));
-
-		return launchConverter.TO_RESOURCE.apply(newLaunch);
-	}
-
-	/**
-	 * Validations for merge launches request parameters and data
-	 *
-	 * @param launches       {@link List} of the {@link Launch}
-	 * @param user           {@link ReportPortalUser}
-	 * @param projectDetails {@link ReportPortalUser.ProjectDetails}
-	 */
-	private void validateMergingLaunches(List<Launch> launches, ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails) {
-
-		/*
-		 * ADMINISTRATOR and PROJECT_MANAGER+ users have permission to merge not-only-own
-		 * launches
-		 */
-		boolean isUserValidate = !(user.getUserRole().equals(ADMINISTRATOR) || projectDetails.getProjectRole()
-				.sameOrHigherThan(ProjectRole.PROJECT_MANAGER));
-
-		launches.forEach(launch -> {
-			expect(launch, notNull()).verify(LAUNCH_NOT_FOUND, launch);
+  private final LaunchRepository launchRepository;
 
-			expect(launch.getStatus(), not(Preconditions.statusIn(IN_PROGRESS))).verify(LAUNCH_IS_NOT_FINISHED,
-					Suppliers.formattedSupplier("Cannot merge launch '{}' with status '{}'", launch.getId(), launch.getStatus())
-			);
+  private final TestItemRepository testItemRepository;
 
-			expect(launch.getProjectId(), equalTo(projectDetails.getProjectId())).verify(FORBIDDEN_OPERATION,
-					"Impossible to merge launches from different projects."
-			);
+  private final ProjectRepository projectRepository;
 
-			if (isUserValidate) {
-				expect(launch.getUserId(), equalTo(user.getUserId())).verify(ACCESS_DENIED,
-						"You are not an owner of launches or have less than PROJECT_MANAGER project role."
-				);
-			}
-		});
-	}
+  private final LaunchMergeFactory launchMergeFactory;
+
+  private final LaunchConverter launchConverter;
+
+  private final LaunchPreparerService launchPreparerService;
+
+  private final LogIndexer logIndexer;
+
+  @Autowired
+  public MergeLaunchHandlerImpl(LaunchRepository launchRepository,
+      TestItemRepository testItemRepository,
+      ProjectRepository projectRepository, LaunchMergeFactory launchMergeFactory,
+      LaunchConverter launchConverter,
+      LaunchPreparerService launchPreparerService, LogIndexer logIndexer) {
+    this.launchRepository = launchRepository;
+    this.testItemRepository = testItemRepository;
+    this.projectRepository = projectRepository;
+    this.launchMergeFactory = launchMergeFactory;
+    this.launchConverter = launchConverter;
+    this.launchPreparerService = launchPreparerService;
+    this.logIndexer = logIndexer;
+  }
+
+  @Override
+  public LaunchResource mergeLaunches(ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user, MergeLaunchesRQ rq) {
+    Project project = projectRepository.findById(projectDetails.getProjectId())
+        .orElseThrow(
+            () -> new ReportPortalException(PROJECT_NOT_FOUND, projectDetails.getProjectName()));
+
+    Set<Long> launchesIds = rq.getLaunches();
+
+    expect(CollectionUtils.isNotEmpty(launchesIds), equalTo(true)).verify(
+        ErrorType.BAD_REQUEST_ERROR,
+        "At least one launch id should be  specified for merging"
+    );
+
+    expect(launchesIds.size() > 0, equalTo(true)).verify(ErrorType.BAD_REQUEST_ERROR,
+        "At least 1 launch id should be provided for merging"
+    );
+
+    List<Launch> launchesList = launchRepository.findAllById(launchesIds);
+
+    expect(launchesIds.size(), equalTo(launchesList.size())).verify(ErrorType.BAD_REQUEST_ERROR,
+        "Not all launches with provided ids were found"
+    );
+
+    validateMergingLaunches(launchesList, user, projectDetails);
+
+    MergeStrategyType type = MergeStrategyType.fromValue(rq.getMergeStrategyType());
+    expect(type, notNull()).verify(UNSUPPORTED_MERGE_STRATEGY_TYPE, type);
+
+    Launch newLaunch = launchMergeFactory.getLaunchMergeStrategy(type)
+        .mergeLaunches(projectDetails, user, rq, launchesList);
+    newLaunch.setStatus(StatisticsHelper.getStatusFromStatistics(newLaunch.getStatistics()));
+
+    launchRepository.deleteAll(launchesList);
+
+    logIndexer.indexLaunchLogs(newLaunch, AnalyzerUtils.getAnalyzerConfig(project));
+
+    return launchConverter.TO_RESOURCE.apply(newLaunch);
+  }
+
+  /**
+   * Validations for merge launches request parameters and data
+   *
+   * @param launches       {@link List} of the {@link Launch}
+   * @param user           {@link ReportPortalUser}
+   * @param projectDetails {@link ReportPortalUser.ProjectDetails}
+   */
+  private void validateMergingLaunches(List<Launch> launches, ReportPortalUser user,
+      ReportPortalUser.ProjectDetails projectDetails) {
+
+    /*
+     * ADMINISTRATOR and PROJECT_MANAGER+ users have permission to merge not-only-own
+     * launches
+     */
+    boolean isUserValidate = !(user.getUserRole().equals(ADMINISTRATOR)
+        || projectDetails.getProjectRole()
+        .sameOrHigherThan(ProjectRole.PROJECT_MANAGER));
+
+    launches.forEach(launch -> {
+      expect(launch, notNull()).verify(LAUNCH_NOT_FOUND, launch);
+
+      expect(launch.getStatus(), not(Preconditions.statusIn(IN_PROGRESS))).verify(
+          LAUNCH_IS_NOT_FINISHED,
+          Suppliers.formattedSupplier("Cannot merge launch '{}' with status '{}'", launch.getId(),
+              launch.getStatus())
+      );
+
+      expect(launch.getProjectId(), equalTo(projectDetails.getProjectId())).verify(
+          FORBIDDEN_OPERATION,
+          "Impossible to merge launches from different projects."
+      );
+
+      if (isUserValidate) {
+        expect(launch.getUserId(), equalTo(user.getUserId())).verify(ACCESS_DENIED,
+            "You are not an owner of launches or have less than PROJECT_MANAGER project role."
+        );
+      }
+    });
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/impl/MetadataUpdater.java b/src/main/java/com/epam/ta/reportportal/core/launch/impl/MetadataUpdater.java
index 96a3b499ef..61e1470955 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/impl/MetadataUpdater.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/impl/MetadataUpdater.java
@@ -17,7 +17,6 @@
 package com.epam.ta.reportportal.core.launch.impl;
 
 import com.epam.ta.reportportal.ws.model.launch.LaunchResource;
-
 import java.util.Collection;
 
 /**
@@ -25,13 +24,13 @@
  */
 public class MetadataUpdater implements ResourceUpdater<LaunchResource> {
 
-	@Override
-	public void update(LaunchResource resource) {
+  @Override
+  public void update(LaunchResource resource) {
 
-	}
+  }
 
-	@Override
-	public void update(Collection<LaunchResource> resources) {
+  @Override
+  public void update(Collection<LaunchResource> resources) {
 
-	}
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/impl/ResourceUpdater.java b/src/main/java/com/epam/ta/reportportal/core/launch/impl/ResourceUpdater.java
index 4508e41264..3a9058e63c 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/impl/ResourceUpdater.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/impl/ResourceUpdater.java
@@ -16,8 +16,6 @@
 
 package com.epam.ta.reportportal.core.launch.impl;
 
-import com.epam.ta.reportportal.ws.model.launch.LaunchResource;
-
 import java.util.Collection;
 
 /**
@@ -25,7 +23,7 @@
  */
 public interface ResourceUpdater<T> {
 
-	void update(T resource);
+  void update(T resource);
 
-	void update(Collection<T> resources);
+  void update(Collection<T> resources);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/impl/StartLaunchHandlerAsyncImpl.java b/src/main/java/com/epam/ta/reportportal/core/launch/impl/StartLaunchHandlerAsyncImpl.java
index f60bf87590..9f90037d19 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/impl/StartLaunchHandlerAsyncImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/impl/StartLaunchHandlerAsyncImpl.java
@@ -16,6 +16,8 @@
 
 package com.epam.ta.reportportal.core.launch.impl;
 
+import static com.epam.ta.reportportal.core.configs.rabbit.ReportingConfiguration.EXCHANGE_REPORTING;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.launch.StartLaunchHandler;
 import com.epam.ta.reportportal.util.ReportingQueueService;
@@ -23,16 +25,13 @@
 import com.epam.ta.reportportal.ws.model.launch.StartLaunchRS;
 import com.epam.ta.reportportal.ws.rabbit.MessageHeaders;
 import com.epam.ta.reportportal.ws.rabbit.RequestType;
+import java.util.Map;
+import java.util.UUID;
 import org.springframework.amqp.core.AmqpTemplate;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 
-import java.util.Map;
-import java.util.UUID;
-
-import static com.epam.ta.reportportal.core.configs.rabbit.ReportingConfiguration.EXCHANGE_REPORTING;
-
 /**
  * @author Konstantin Antipin
  */
@@ -40,30 +39,32 @@
 @Qualifier("startLaunchHandlerAsync")
 public class StartLaunchHandlerAsyncImpl implements StartLaunchHandler {
 
-	@Autowired
-	@Qualifier(value = "rabbitTemplate")
-	AmqpTemplate amqpTemplate;
+  @Autowired
+  @Qualifier(value = "rabbitTemplate")
+  AmqpTemplate amqpTemplate;
 
-	@Autowired
-	private ReportingQueueService reportingQueueService;
+  @Autowired
+  private ReportingQueueService reportingQueueService;
 
-	@Override
-	public StartLaunchRS startLaunch(ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails, StartLaunchRQ request) {
-		validateRoles(projectDetails, request);
+  @Override
+  public StartLaunchRS startLaunch(ReportPortalUser user,
+      ReportPortalUser.ProjectDetails projectDetails, StartLaunchRQ request) {
+    validateRoles(projectDetails, request);
 
-		if (request.getUuid() == null) {
-			request.setUuid(UUID.randomUUID().toString());
-		}
-		amqpTemplate.convertAndSend(EXCHANGE_REPORTING, reportingQueueService.getReportingQueueKey(request.getUuid()), request, message -> {
-			Map<String, Object> headers = message.getMessageProperties().getHeaders();
-			headers.put(MessageHeaders.REQUEST_TYPE, RequestType.START_LAUNCH);
-			headers.put(MessageHeaders.USERNAME, user.getUsername());
-			headers.put(MessageHeaders.PROJECT_NAME, projectDetails.getProjectName());
-			return message;
-		});
+    if (request.getUuid() == null) {
+      request.setUuid(UUID.randomUUID().toString());
+    }
+    amqpTemplate.convertAndSend(EXCHANGE_REPORTING,
+        reportingQueueService.getReportingQueueKey(request.getUuid()), request, message -> {
+          Map<String, Object> headers = message.getMessageProperties().getHeaders();
+          headers.put(MessageHeaders.REQUEST_TYPE, RequestType.START_LAUNCH);
+          headers.put(MessageHeaders.USERNAME, user.getUsername());
+          headers.put(MessageHeaders.PROJECT_NAME, projectDetails.getProjectName());
+          return message;
+        });
 
-		StartLaunchRS response = new StartLaunchRS();
-		response.setId(request.getUuid());
-		return response;
-	}
+    StartLaunchRS response = new StartLaunchRS();
+    response.setId(request.getUuid());
+    return response;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/impl/StartLaunchHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/launch/impl/StartLaunchHandlerImpl.java
index 421a1a2f59..43abc35b67 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/impl/StartLaunchHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/impl/StartLaunchHandlerImpl.java
@@ -16,6 +16,8 @@
 
 package com.epam.ta.reportportal.core.launch.impl;
 
+import static com.epam.ta.reportportal.ws.converter.converters.LaunchConverter.TO_ACTIVITY_RESOURCE;
+
 import com.epam.reportportal.extension.event.StartLaunchEvent;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.events.MessageBus;
@@ -27,16 +29,13 @@
 import com.epam.ta.reportportal.ws.converter.builders.LaunchBuilder;
 import com.epam.ta.reportportal.ws.model.launch.StartLaunchRQ;
 import com.epam.ta.reportportal.ws.model.launch.StartLaunchRS;
+import java.util.Optional;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.context.annotation.Primary;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.Optional;
-
-import static com.epam.ta.reportportal.ws.converter.converters.LaunchConverter.TO_ACTIVITY_RESOURCE;
-
 /**
  * Default implementation of {@link com.epam.ta.reportportal.core.launch.StartLaunchHandler}
  *
@@ -47,45 +46,48 @@
 @Transactional
 class StartLaunchHandlerImpl implements StartLaunchHandler {
 
-	private final LaunchRepository launchRepository;
-	private final ApplicationEventPublisher eventPublisher;
-	private final MessageBus messageBus;
-	private final RerunHandler rerunHandler;
+  private final LaunchRepository launchRepository;
+  private final ApplicationEventPublisher eventPublisher;
+  private final MessageBus messageBus;
+  private final RerunHandler rerunHandler;
 
-	@Autowired
-	public StartLaunchHandlerImpl(LaunchRepository launchRepository,
-			ApplicationEventPublisher eventPublisher, MessageBus messageBus, RerunHandler rerunHandler) {
-		this.launchRepository = launchRepository;
-		this.eventPublisher = eventPublisher;
-		this.messageBus = messageBus;
-		this.rerunHandler = rerunHandler;
-	}
+  @Autowired
+  public StartLaunchHandlerImpl(LaunchRepository launchRepository,
+      ApplicationEventPublisher eventPublisher, MessageBus messageBus, RerunHandler rerunHandler) {
+    this.launchRepository = launchRepository;
+    this.eventPublisher = eventPublisher;
+    this.messageBus = messageBus;
+    this.rerunHandler = rerunHandler;
+  }
 
-	@Override
-	@Transactional
-	public StartLaunchRS startLaunch(ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails, StartLaunchRQ request) {
-		validateRoles(projectDetails, request);
+  @Override
+  @Transactional
+  public StartLaunchRS startLaunch(ReportPortalUser user,
+      ReportPortalUser.ProjectDetails projectDetails, StartLaunchRQ request) {
+    validateRoles(projectDetails, request);
 
-		final Launch savedLaunch = Optional.of(request.isRerun())
-				.filter(Boolean::booleanValue)
-				.map(rerun -> rerunHandler.handleLaunch(request, projectDetails.getProjectId(), user))
-				.orElseGet(() -> {
-					Launch launch = new LaunchBuilder().addStartRQ(request)
-							.addAttributes(request.getAttributes())
-							.addProject(projectDetails.getProjectId())
-							.addUserId(user.getUserId())
-							.get();
-					launchRepository.save(launch);
-					launchRepository.refresh(launch);
-					return launch;
-				});
+    final Launch savedLaunch = Optional.of(request.isRerun())
+        .filter(Boolean::booleanValue)
+        .map(rerun -> rerunHandler.handleLaunch(request, projectDetails.getProjectId(), user))
+        .orElseGet(() -> {
+          Launch launch = new LaunchBuilder().addStartRQ(request)
+              .addAttributes(request.getAttributes())
+              .addProject(projectDetails.getProjectId())
+              .addUserId(user.getUserId())
+              .get();
+          launchRepository.save(launch);
+          launchRepository.refresh(launch);
+          return launch;
+        });
 
-		eventPublisher.publishEvent(new StartLaunchEvent(savedLaunch.getId()));
-		messageBus.publishActivity(new LaunchStartedEvent(TO_ACTIVITY_RESOURCE.apply(savedLaunch), user.getUserId(), user.getUsername()));
+    eventPublisher.publishEvent(new StartLaunchEvent(savedLaunch.getId()));
+    messageBus.publishActivity(
+        new LaunchStartedEvent(TO_ACTIVITY_RESOURCE.apply(savedLaunch), user.getUserId(),
+            user.getUsername()));
 
-		StartLaunchRS response = new StartLaunchRS();
-		response.setId(savedLaunch.getUuid());
-		response.setNumber(savedLaunch.getNumber());
-		return response;
-	}
+    StartLaunchRS response = new StartLaunchRS();
+    response.setId(savedLaunch.getUuid());
+    response.setNumber(savedLaunch.getNumber());
+    return response;
+  }
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/impl/StopLaunchHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/launch/impl/StopLaunchHandlerImpl.java
index 696bd66074..7b87a8f0d6 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/impl/StopLaunchHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/impl/StopLaunchHandlerImpl.java
@@ -85,7 +85,8 @@ public OperationCompletionRS stopLaunch(Long launchId, FinishExecutionRQ finishL
 		launchRepository.save(launch);
 		testItemRepository.interruptInProgressItems(launch.getId());
 
-		eventPublisher.publishEvent(new LaunchFinishedEvent(launch, user.getUserId(), user.getUsername()));
+    eventPublisher.publishEvent(
+        new LaunchFinishedEvent(launch, user.getUserId(), user.getUsername(), false));
 		return new OperationCompletionRS("Launch with ID = '" + launchId + "' successfully stopped.");
 	}
 
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/impl/UpdateLaunchHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/launch/impl/UpdateLaunchHandlerImpl.java
index 9adcc092ca..d1dcac32b6 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/impl/UpdateLaunchHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/impl/UpdateLaunchHandlerImpl.java
@@ -16,6 +16,18 @@
 
 package com.epam.ta.reportportal.core.launch.impl;
 
+import static com.epam.ta.reportportal.commons.Preconditions.statusIn;
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import static com.epam.ta.reportportal.commons.Predicates.not;
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.entity.project.ProjectRole.PROJECT_MANAGER;
+import static com.epam.ta.reportportal.entity.project.ProjectUtils.getConfigParameters;
+import static com.epam.ta.reportportal.ws.model.ErrorType.ACCESS_DENIED;
+import static com.epam.ta.reportportal.ws.model.ErrorType.INCORRECT_REQUEST;
+import static com.epam.ta.reportportal.ws.model.ErrorType.LAUNCH_NOT_FOUND;
+import static com.epam.ta.reportportal.ws.model.ErrorType.PROJECT_NOT_FOUND;
+import static java.util.stream.Collectors.toList;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.validation.Suppliers;
 import com.epam.ta.reportportal.core.analyzer.auto.LogIndexer;
@@ -50,24 +62,14 @@
 import com.epam.ta.reportportal.ws.model.launch.cluster.CreateClustersRQ;
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
 import com.google.common.collect.Lists;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Predicate;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.List;
-import java.util.Map;
-import java.util.function.Predicate;
-
-import static com.epam.ta.reportportal.commons.Preconditions.statusIn;
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-import static com.epam.ta.reportportal.commons.Predicates.not;
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.entity.project.ProjectRole.PROJECT_MANAGER;
-import static com.epam.ta.reportportal.entity.project.ProjectUtils.getConfigParameters;
-import static com.epam.ta.reportportal.ws.model.ErrorType.*;
-import static java.util.stream.Collectors.toList;
-
 /**
  * Default implementation of {@link UpdateLaunchHandler}
  *
@@ -77,165 +79,184 @@
 @Service
 public class UpdateLaunchHandlerImpl implements UpdateLaunchHandler {
 
-	private final GetProjectHandler getProjectHandler;
-	private final GetLaunchHandler getLaunchHandler;
-	private final LaunchAccessValidator launchAccessValidator;
-
-	private final LaunchRepository launchRepository;
-
-	private final LogIndexer logIndexer;
-
-	private final Map<AnalyzerType, LaunchAnalysisStrategy> launchAnalysisStrategyMapping;
-
-	private final UniqueErrorAnalysisStarter uniqueErrorAnalysisStarter;
-
-	@Autowired
-	public UpdateLaunchHandlerImpl(GetProjectHandler getProjectHandler, GetLaunchHandler getLaunchHandler,
-			LaunchAccessValidator launchAccessValidator, LaunchRepository launchRepository, LogIndexer logIndexer,
-			Map<AnalyzerType, LaunchAnalysisStrategy> launchAnalysisStrategyMapping,
-			@Qualifier("uniqueErrorAnalysisStarterAsync") UniqueErrorAnalysisStarter uniqueErrorAnalysisStarter) {
-		this.getProjectHandler = getProjectHandler;
-		this.getLaunchHandler = getLaunchHandler;
-		this.launchAccessValidator = launchAccessValidator;
-		this.launchRepository = launchRepository;
-		this.launchAnalysisStrategyMapping = launchAnalysisStrategyMapping;
-		this.logIndexer = logIndexer;
-		this.uniqueErrorAnalysisStarter = uniqueErrorAnalysisStarter;
-	}
-
-	@Override
-	public OperationCompletionRS updateLaunch(Long launchId, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user,
-			UpdateLaunchRQ rq) {
-		Project project = getProjectHandler.get(projectDetails);
-		Launch launch = launchRepository.findById(launchId)
-				.orElseThrow(() -> new ReportPortalException(LAUNCH_NOT_FOUND, launchId.toString()));
-		validate(launch, user, projectDetails, rq.getMode());
-
-		LaunchModeEnum previousMode = launch.getMode();
-
-		launch = new LaunchBuilder(launch).addMode(rq.getMode())
-				.addDescription(rq.getDescription())
-				.overwriteAttributes(rq.getAttributes())
-				.get();
-		launchRepository.save(launch);
-
-		if (!previousMode.equals(launch.getMode())) {
-			reindexLogs(launch, AnalyzerUtils.getAnalyzerConfig(project), project.getId());
-		}
-		return new OperationCompletionRS("Launch with ID = '" + launch.getId() + "' successfully updated.");
-	}
-
-	@Override
-	public List<OperationCompletionRS> updateLaunch(BulkRQ<Long, UpdateLaunchRQ> rq, ReportPortalUser.ProjectDetails projectDetails,
-			ReportPortalUser user) {
-		return rq.getEntities()
-				.entrySet()
-				.stream()
-				.map(entry -> updateLaunch(entry.getKey(), projectDetails, user, entry.getValue()))
-				.collect(toList());
-	}
-
-	@Override
-	public OperationCompletionRS startLaunchAnalyzer(AnalyzeLaunchRQ analyzeRQ, ReportPortalUser.ProjectDetails projectDetails,
-			ReportPortalUser user) {
-		AnalyzerType analyzerType = AnalyzerType.fromString(analyzeRQ.getAnalyzerTypeName());
-		launchAnalysisStrategyMapping.get(analyzerType).analyze(analyzeRQ, projectDetails, user);
-		return new OperationCompletionRS(
-				analyzerType.getName() + " analysis for launch with ID='" + analyzeRQ.getLaunchId() + "' started.");
-	}
-
-	@Override
-	@Transactional
-	public OperationCompletionRS createClusters(CreateClustersRQ createClustersRQ, ReportPortalUser.ProjectDetails projectDetails,
-			ReportPortalUser user) {
-
-		final Launch launch = getLaunchHandler.get(createClustersRQ.getLaunchId());
-		launchAccessValidator.validate(launch, projectDetails, user);
-		//TODO should be put inside *Validator after validators refactoring
-		expect(launch.getStatus(), not(statusIn(StatusEnum.IN_PROGRESS))).verify(INCORRECT_REQUEST, "Cannot analyze launch in progress.");
-
-		final Project project = getProjectHandler.get(launch.getProjectId());
-
-		final Map<String, String> configParameters = getConfigParameters(project.getProjectAttributes());
-		configParameters.put(ProjectAttributeEnum.UNIQUE_ERROR_ANALYZER_REMOVE_NUMBERS.getAttribute(),
-				String.valueOf(createClustersRQ.isRemoveNumbers())
-		);
-		uniqueErrorAnalysisStarter.start(ClusterEntityContext.of(launch.getId(), launch.getProjectId()), configParameters);
-
-		return new OperationCompletionRS(Suppliers.formattedSupplier("Clusters generation for launch with ID='{}' started.", launch.getId())
-				.get());
-	}
-
-	@Override
-	public OperationCompletionRS bulkInfoUpdate(BulkInfoUpdateRQ bulkUpdateRq, ReportPortalUser.ProjectDetails projectDetails) {
-		expect(getProjectHandler.exists(projectDetails.getProjectId()), Predicate.isEqual(true)).verify(PROJECT_NOT_FOUND,
-				projectDetails.getProjectId()
-		);
-
-		List<Launch> launches = launchRepository.findAllById(bulkUpdateRq.getIds());
-		launches.forEach(it -> ItemInfoUtils.updateDescription(bulkUpdateRq.getDescription(), it.getDescription())
-				.ifPresent(it::setDescription));
-
-		bulkUpdateRq.getAttributes().forEach(it -> {
-			switch (it.getAction()) {
-				case DELETE: {
-					launches.forEach(launch -> {
-						ItemAttribute toDelete = ItemInfoUtils.findAttributeByResource(launch.getAttributes(), it.getFrom());
-						launch.getAttributes().remove(toDelete);
-					});
-					break;
-				}
-				case UPDATE: {
-					launches.forEach(launch -> ItemInfoUtils.updateAttribute(launch.getAttributes(), it));
-					break;
-				}
-				case CREATE: {
-					launches.stream()
-							.filter(launch -> ItemInfoUtils.containsAttribute(launch.getAttributes(), it.getTo()))
-							.forEach(launch -> {
-								ItemAttribute itemAttribute = ItemAttributeConverter.FROM_RESOURCE.apply(it.getTo());
-								itemAttribute.setLaunch(launch);
-								launch.getAttributes().add(itemAttribute);
-							});
-					break;
-				}
-			}
-		});
-
-		return new OperationCompletionRS("Attributes successfully updated");
-	}
-
-	/**
-	 * If launch mode has changed - reindex items
-	 *
-	 * @param launch Update launch
-	 */
-	private void reindexLogs(Launch launch, AnalyzerConfig analyzerConfig, Long projectId) {
-		if (LaunchModeEnum.DEBUG.equals(launch.getMode())) {
-			logIndexer.indexLaunchesRemove(projectId, Lists.newArrayList(launch.getId()));
-		} else {
-			logIndexer.indexLaunchLogs(launch, analyzerConfig);
-		}
-	}
-
-	/**
-	 * Valide {@link ReportPortalUser} credentials
-	 *
-	 * @param launch {@link Launch}
-	 * @param user   {@link ReportPortalUser}
-	 * @param mode   {@link Launch#mode}
-	 */
-	//TODO *Validator refactoring
-	private void validate(Launch launch, ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails, Mode mode) {
-		if (projectDetails.getProjectRole() == ProjectRole.CUSTOMER && null != mode) {
-			expect(mode, equalTo(Mode.DEFAULT)).verify(ACCESS_DENIED);
-		}
-		if (user.getUserRole() != UserRole.ADMINISTRATOR) {
-			expect(launch.getProjectId(), equalTo(projectDetails.getProjectId())).verify(ACCESS_DENIED);
-			if (projectDetails.getProjectRole().lowerThan(PROJECT_MANAGER)) {
-				expect(user.getUserId(), Predicate.isEqual(launch.getUserId())).verify(ACCESS_DENIED);
-			}
-		}
-	}
+  private final GetProjectHandler getProjectHandler;
+  private final GetLaunchHandler getLaunchHandler;
+  private final LaunchAccessValidator launchAccessValidator;
+
+  private final LaunchRepository launchRepository;
+
+  private final LogIndexer logIndexer;
+
+  private final Map<AnalyzerType, LaunchAnalysisStrategy> launchAnalysisStrategyMapping;
+
+  private final UniqueErrorAnalysisStarter uniqueErrorAnalysisStarter;
+
+  @Autowired
+  public UpdateLaunchHandlerImpl(GetProjectHandler getProjectHandler,
+      GetLaunchHandler getLaunchHandler,
+      LaunchAccessValidator launchAccessValidator, LaunchRepository launchRepository,
+      LogIndexer logIndexer,
+      Map<AnalyzerType, LaunchAnalysisStrategy> launchAnalysisStrategyMapping,
+      @Qualifier("uniqueErrorAnalysisStarterAsync") UniqueErrorAnalysisStarter uniqueErrorAnalysisStarter) {
+    this.getProjectHandler = getProjectHandler;
+    this.getLaunchHandler = getLaunchHandler;
+    this.launchAccessValidator = launchAccessValidator;
+    this.launchRepository = launchRepository;
+    this.launchAnalysisStrategyMapping = launchAnalysisStrategyMapping;
+    this.logIndexer = logIndexer;
+    this.uniqueErrorAnalysisStarter = uniqueErrorAnalysisStarter;
+  }
+
+  @Override
+  public OperationCompletionRS updateLaunch(Long launchId,
+      ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user,
+      UpdateLaunchRQ rq) {
+    Project project = getProjectHandler.get(projectDetails);
+    Launch launch = launchRepository.findById(launchId)
+        .orElseThrow(() -> new ReportPortalException(LAUNCH_NOT_FOUND, launchId.toString()));
+    validate(launch, user, projectDetails, rq.getMode());
+
+    LaunchModeEnum previousMode = launch.getMode();
+
+    launch = new LaunchBuilder(launch).addMode(rq.getMode())
+        .addDescription(rq.getDescription())
+        .overwriteAttributes(rq.getAttributes())
+        .get();
+    launchRepository.save(launch);
+
+    if (!previousMode.equals(launch.getMode())) {
+      reindexLogs(launch, AnalyzerUtils.getAnalyzerConfig(project), project.getId());
+    }
+    return new OperationCompletionRS(
+        "Launch with ID = '" + launch.getId() + "' successfully updated.");
+  }
+
+  @Override
+  public List<OperationCompletionRS> updateLaunch(BulkRQ<Long, UpdateLaunchRQ> rq,
+      ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user) {
+    return rq.getEntities()
+        .entrySet()
+        .stream()
+        .map(entry -> updateLaunch(entry.getKey(), projectDetails, user, entry.getValue()))
+        .collect(toList());
+  }
+
+  @Override
+  public OperationCompletionRS startLaunchAnalyzer(AnalyzeLaunchRQ analyzeRQ,
+      ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user) {
+    AnalyzerType analyzerType = AnalyzerType.fromString(analyzeRQ.getAnalyzerTypeName());
+    launchAnalysisStrategyMapping.get(analyzerType).analyze(analyzeRQ, projectDetails, user);
+    return new OperationCompletionRS(
+        analyzerType.getName() + " analysis for launch with ID='" + analyzeRQ.getLaunchId()
+            + "' started.");
+  }
+
+  @Override
+  @Transactional
+  public OperationCompletionRS createClusters(CreateClustersRQ createClustersRQ,
+      ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user) {
+
+    final Launch launch = getLaunchHandler.get(createClustersRQ.getLaunchId());
+    launchAccessValidator.validate(launch, projectDetails, user);
+    //TODO should be put inside *Validator after validators refactoring
+    expect(launch.getStatus(), not(statusIn(StatusEnum.IN_PROGRESS))).verify(INCORRECT_REQUEST,
+        "Cannot analyze launch in progress.");
+
+    final Project project = getProjectHandler.get(launch.getProjectId());
+
+    final Map<String, String> configParameters = getConfigParameters(
+        project.getProjectAttributes());
+    configParameters.put(ProjectAttributeEnum.UNIQUE_ERROR_ANALYZER_REMOVE_NUMBERS.getAttribute(),
+        String.valueOf(createClustersRQ.isRemoveNumbers())
+    );
+    uniqueErrorAnalysisStarter.start(ClusterEntityContext.of(launch.getId(), launch.getProjectId()),
+        configParameters);
+
+    return new OperationCompletionRS(
+        Suppliers.formattedSupplier("Clusters generation for launch with ID='{}' started.",
+                launch.getId())
+            .get());
+  }
+
+  @Override
+  public OperationCompletionRS bulkInfoUpdate(BulkInfoUpdateRQ bulkUpdateRq,
+      ReportPortalUser.ProjectDetails projectDetails) {
+    expect(getProjectHandler.exists(projectDetails.getProjectId()), Predicate.isEqual(true)).verify(
+        PROJECT_NOT_FOUND,
+        projectDetails.getProjectId()
+    );
+
+    List<Launch> launches = launchRepository.findAllById(bulkUpdateRq.getIds());
+    launches.forEach(
+        it -> ItemInfoUtils.updateDescription(bulkUpdateRq.getDescription(), it.getDescription())
+            .ifPresent(it::setDescription));
+
+    bulkUpdateRq.getAttributes().forEach(it -> {
+      switch (it.getAction()) {
+        case DELETE: {
+          launches.forEach(launch -> {
+            ItemAttribute toDelete = ItemInfoUtils.findAttributeByResource(launch.getAttributes(),
+                it.getFrom());
+            launch.getAttributes().remove(toDelete);
+          });
+          break;
+        }
+        case UPDATE: {
+          launches.forEach(launch -> ItemInfoUtils.updateAttribute(launch.getAttributes(), it));
+          break;
+        }
+        case CREATE: {
+          launches.stream()
+              .filter(launch -> ItemInfoUtils.containsAttribute(launch.getAttributes(), it.getTo()))
+              .forEach(launch -> {
+                ItemAttribute itemAttribute = ItemAttributeConverter.FROM_RESOURCE.apply(
+                    it.getTo());
+                itemAttribute.setLaunch(launch);
+                launch.getAttributes().add(itemAttribute);
+              });
+          break;
+        }
+      }
+    });
+
+    return new OperationCompletionRS("Attributes successfully updated");
+  }
+
+  /**
+   * If launch mode has changed - reindex items
+   *
+   * @param launch Update launch
+   */
+  private void reindexLogs(Launch launch, AnalyzerConfig analyzerConfig, Long projectId) {
+    if (LaunchModeEnum.DEBUG.equals(launch.getMode())) {
+      logIndexer.indexLaunchesRemove(projectId, Lists.newArrayList(launch.getId()));
+    } else {
+      logIndexer.indexLaunchLogs(launch, analyzerConfig);
+    }
+  }
+
+  /**
+   * Valide {@link ReportPortalUser} credentials
+   *
+   * @param launch {@link Launch}
+   * @param user   {@link ReportPortalUser}
+   * @param mode   {@link Launch#mode}
+   */
+  //TODO *Validator refactoring
+  private void validate(Launch launch, ReportPortalUser user,
+      ReportPortalUser.ProjectDetails projectDetails, Mode mode) {
+    if (projectDetails.getProjectRole() == ProjectRole.CUSTOMER && null != mode) {
+      expect(mode, equalTo(Mode.DEFAULT)).verify(ACCESS_DENIED);
+    }
+    if (user.getUserRole() != UserRole.ADMINISTRATOR) {
+      expect(launch.getProjectId(), equalTo(projectDetails.getProjectId())).verify(ACCESS_DENIED);
+      if (projectDetails.getProjectRole().lowerThan(PROJECT_MANAGER)) {
+        expect(user.getUserId(), Predicate.isEqual(launch.getUserId())).verify(ACCESS_DENIED);
+      }
+    }
+  }
 
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/rerun/RerunHandler.java b/src/main/java/com/epam/ta/reportportal/core/launch/rerun/RerunHandler.java
index 3250affd61..031ac97508 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/rerun/RerunHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/rerun/RerunHandler.java
@@ -22,7 +22,6 @@
 import com.epam.ta.reportportal.ws.model.StartTestItemRQ;
 import com.epam.ta.reportportal.ws.model.item.ItemCreatedRS;
 import com.epam.ta.reportportal.ws.model.launch.StartLaunchRQ;
-
 import java.util.Optional;
 
 /**
@@ -30,31 +29,33 @@
  */
 public interface RerunHandler {
 
-	/**
-	 * Updates launch state and return existed launch to rerun
-	 *
-	 * @param request   Request data
-	 * @param projectId Project ID
-	 * @param user      ReportPortal user
-	 * @return {@link Launch}
-	 */
-	Launch handleLaunch(StartLaunchRQ request, Long projectId, ReportPortalUser user);
+  /**
+   * Updates launch state and return existed launch to rerun
+   *
+   * @param request   Request data
+   * @param projectId Project ID
+   * @param user      ReportPortal user
+   * @return {@link Launch}
+   */
+  Launch handleLaunch(StartLaunchRQ request, Long projectId, ReportPortalUser user);
 
-	/**
-	 * Finds root {@link TestItem} to rerun and creates retries
-	 *
-	 * @param request Request data
-	 * @param launch  {@link Launch}
-	 * @return {@link ItemCreatedRS} if item is rerun, otherwise {@link Optional#empty()}
-	 */
-	Optional<ItemCreatedRS> handleRootItem(StartTestItemRQ request, Launch launch);
+  /**
+   * Finds root {@link TestItem} to rerun and creates retries
+   *
+   * @param request Request data
+   * @param launch  {@link Launch}
+   * @return {@link ItemCreatedRS} if item is rerun, otherwise {@link Optional#empty()}
+   */
+  Optional<ItemCreatedRS> handleRootItem(StartTestItemRQ request, Launch launch);
 
-	/**
-	 * Finds child {@link TestItem} to rerun and creates retries
-	 *
-	 * @param request Request data
-	 * @param launch  {@link Launch}
-	 * @return {@link ItemCreatedRS} if item is rerun, otherwise {@link Optional#empty()}
-	 */
-	Optional<ItemCreatedRS> handleChildItem(StartTestItemRQ request, Launch launch, String parentUuid);
+  /**
+   * Finds child {@link TestItem} to rerun and creates retries
+   *
+   * @param request     Request data
+   * @param launch      {@link Launch}
+   * @param parentUuid  Parent testItem's id
+   * @return {@link ItemCreatedRS} if item is rerun, otherwise {@link Optional#empty()}
+   */
+  Optional<ItemCreatedRS> handleChildItem(StartTestItemRQ request, Launch launch,
+      String parentUuid);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/rerun/RerunHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/launch/rerun/RerunHandlerImpl.java
index 3a734dbbcd..7933d0421e 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/rerun/RerunHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/rerun/RerunHandlerImpl.java
@@ -16,6 +16,13 @@
 
 package com.epam.ta.reportportal.core.launch.rerun;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_LAUNCH_ID;
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_NAME;
+import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_PARENT_ID;
+import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_TEST_CASE_HASH;
+import static com.epam.ta.reportportal.ws.converter.converters.ItemAttributeConverter.TO_LAUNCH_ATTRIBUTE;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.querygen.Condition;
 import com.epam.ta.reportportal.commons.querygen.Filter;
@@ -40,24 +47,16 @@
 import com.epam.ta.reportportal.ws.model.StartTestItemRQ;
 import com.epam.ta.reportportal.ws.model.item.ItemCreatedRS;
 import com.epam.ta.reportportal.ws.model.launch.StartLaunchRQ;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.ApplicationEventPublisher;
-import org.springframework.data.util.Pair;
-import org.springframework.stereotype.Component;
-
 import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_LAUNCH_ID;
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_NAME;
-import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_PARENT_ID;
-import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_TEST_CASE_HASH;
-import static com.epam.ta.reportportal.ws.converter.converters.ItemAttributeConverter.TO_LAUNCH_ATTRIBUTE;
-import static java.util.Optional.ofNullable;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.data.util.Pair;
+import org.springframework.stereotype.Component;
 
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
@@ -65,151 +64,170 @@
 @Component
 public class RerunHandlerImpl implements RerunHandler {
 
-	private final TestItemRepository testItemRepository;
-	private final LaunchRepository launchRepository;
-	private final UniqueIdGenerator uniqueIdGenerator;
-	private final TestCaseHashGenerator testCaseHashGenerator;
-	private final ApplicationEventPublisher eventPublisher;
-	private final RerunSearcher rerunSearcher;
-	private final List<ParentItemValidator> parentItemValidators;
-	private final RetryHandler retryHandler;
-
-	@Autowired
-	public RerunHandlerImpl(TestItemRepository testItemRepository, LaunchRepository launchRepository, UniqueIdGenerator uniqueIdGenerator,
-			TestCaseHashGenerator testCaseHashGenerator, ApplicationEventPublisher eventPublisher, RerunSearcher rerunSearcher,
-			List<ParentItemValidator> parentItemValidators, RetryHandler retryHandler) {
-		this.testItemRepository = testItemRepository;
-		this.launchRepository = launchRepository;
-		this.uniqueIdGenerator = uniqueIdGenerator;
-		this.testCaseHashGenerator = testCaseHashGenerator;
-		this.eventPublisher = eventPublisher;
-		this.rerunSearcher = rerunSearcher;
-		this.parentItemValidators = parentItemValidators;
-		this.retryHandler = retryHandler;
-	}
-
-	@Override
-	public Launch handleLaunch(StartLaunchRQ request, Long projectId, ReportPortalUser user) {
-		Optional<Launch> launchOptional = StringUtils.isEmpty(request.getRerunOf()) ?
-				launchRepository.findLatestByNameAndProjectId(request.getName(), projectId) :
-				launchRepository.findByUuid(request.getRerunOf());
-		Launch launch = launchOptional.orElseThrow(() -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND,
-				ofNullable(request.getRerunOf()).orElse(request.getName())
-		));
-
-		ofNullable(request.getMode()).map(it -> LaunchModeEnum.valueOf(it.name())).ifPresent(launch::setMode);
-		ofNullable(request.getDescription()).ifPresent(launch::setDescription);
-		launch.setStatus(StatusEnum.IN_PROGRESS);
-		ofNullable(request.getAttributes()).map(it -> it.stream()
-				.map(attr -> TO_LAUNCH_ATTRIBUTE.apply(attr, launch))
-				.collect(Collectors.toSet())).ifPresent(launch::setAttributes);
-		ofNullable(request.getUuid()).ifPresent(launch::setUuid);
-		launch.setRerun(true);
-		return launch;
-	}
-
-	@Override
-	public Optional<ItemCreatedRS> handleRootItem(StartTestItemRQ request, Launch launch) {
-		final Integer testCaseHash = getTestCaseHash(request, launch);
-		final Filter parentItemFilter = getRootItemFilter(launch, testCaseHash, request.getName());
-		return rerunSearcher.findItem(parentItemFilter).flatMap(testItemRepository::findById).map(it -> updateRootItem(request, it));
-	}
-
-	private Integer getTestCaseHash(StartTestItemRQ request, Launch launch) {
-		final TestCaseIdEntry testCaseIdEntry = TestItemBuilder.processTestCaseId(request);
-		return ofNullable(testCaseIdEntry.getId()).map(id -> testCaseIdEntry.getHash()).orElseGet(() -> {
-			TestItem newItem = new TestItemBuilder().addStartItemRequest(request).get();
-			return testCaseHashGenerator.generate(newItem, Collections.emptyList(), launch.getProjectId());
-		});
-	}
-
-	@Override
-	public Optional<ItemCreatedRS> handleChildItem(StartTestItemRQ request, Launch launch, String parentUuid) {
-		if (!request.isHasStats()) {
-			return Optional.empty();
-		}
-
-		final Pair<Long, String> pathName = testItemRepository.selectPath(parentUuid)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, parentUuid));
-
-		TestItem newItem = new TestItemBuilder().addLaunchId(launch.getId())
-				.addStartItemRequest(request)
-				.addAttributes(request.getAttributes())
-				.addParentId(pathName.getFirst())
-				.get();
-
-		if (Objects.isNull(newItem.getTestCaseId())) {
-			newItem.setTestCaseHash(testCaseHashGenerator.generate(newItem,
-					IdentityUtil.getItemTreeIds(pathName.getSecond()),
-					launch.getProjectId()
-			));
-		}
-
-		final Filter childItemFilter = getChildItemFilter(launch, newItem.getTestCaseHash(), pathName.getFirst());
-
-		return rerunSearcher.findItem(childItemFilter).flatMap(testItemRepository::findById).flatMap(foundItem -> {
-			if (!foundItem.isHasChildren()) {
-				final TestItem parent = testItemRepository.findIdByUuidForUpdate(parentUuid)
-						.map(testItemRepository::getOne)
-						.orElseThrow(() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, parentUuid));
-				parentItemValidators.forEach(v -> v.validate(request, parent));
-				return Optional.of(handleRetry(launch, newItem, foundItem, parent));
-			}
-
-			if (foundItem.getName().equals(newItem.getName())) {
-				return Optional.of(updateRootItem(request, foundItem));
-			}
-
-			childItemFilter.withCondition(new FilterCondition(Condition.EQUALS, false, newItem.getName(), CRITERIA_NAME));
-			return rerunSearcher.findItem(childItemFilter).flatMap(testItemRepository::findById).map(it -> updateRootItem(request, it));
-		});
-	}
-
-	private Filter getCommonFilter(Long launchId, Integer testCaseHash) {
-		return Filter.builder()
-				.withTarget(TestItem.class)
-				.withCondition(new FilterCondition(Condition.EQUALS, false, String.valueOf(launchId), CRITERIA_LAUNCH_ID))
-				.withCondition(new FilterCondition(Condition.EQUALS, false, String.valueOf(testCaseHash), CRITERIA_TEST_CASE_HASH))
-				.build();
-	}
-
-	private Filter getRootItemFilter(Launch launch, Integer testCaseHash, String name) {
-		return getCommonFilter(launch.getId(), testCaseHash).withCondition(new FilterCondition(Condition.EQUALS,
-				false,
-				name,
-				CRITERIA_NAME
-		)).withCondition(new FilterCondition(Condition.EXISTS, true, "1", CRITERIA_PARENT_ID));
-	}
-
-	private Filter getChildItemFilter(Launch launch, Integer testCaseHash, Long parentId) {
-		return getCommonFilter(launch.getId(), testCaseHash).withCondition(new FilterCondition(Condition.EXISTS,
-				false,
-				String.valueOf(parentId),
-				CRITERIA_PARENT_ID
-		));
-	}
-
-	private ItemCreatedRS handleRetry(Launch launch, TestItem newItem, TestItem foundItem, TestItem parentItem) {
-		eventPublisher.publishEvent(ItemRetryEvent.of(launch.getProjectId(), launch.getId(), foundItem.getItemId()));
-		testItemRepository.save(newItem);
-		newItem.setPath(parentItem.getPath() + "." + newItem.getItemId());
-		generateUniqueId(launch, newItem);
-		retryHandler.handleRetries(launch, newItem, foundItem.getItemId());
-		return new ItemCreatedRS(newItem.getUuid(), newItem.getUniqueId());
-	}
-
-	private void generateUniqueId(Launch launch, TestItem item) {
-		if (null == item.getUniqueId()) {
-			item.setUniqueId(uniqueIdGenerator.generate(item, IdentityUtil.getParentIds(item), launch));
-		}
-	}
-
-	private ItemCreatedRS updateRootItem(StartTestItemRQ request, TestItem foundItem) {
-		foundItem = new TestItemBuilder(foundItem).addDescription(request.getDescription())
-				.overwriteAttributes(request.getAttributes())
-				.addStatus(StatusEnum.IN_PROGRESS)
-				.get();
-		ofNullable(request.getUuid()).ifPresent(foundItem::setUuid);
-		return new ItemCreatedRS(foundItem.getUuid(), foundItem.getUniqueId());
-	}
+  private final TestItemRepository testItemRepository;
+  private final LaunchRepository launchRepository;
+  private final UniqueIdGenerator uniqueIdGenerator;
+  private final TestCaseHashGenerator testCaseHashGenerator;
+  private final ApplicationEventPublisher eventPublisher;
+  private final RerunSearcher rerunSearcher;
+  private final List<ParentItemValidator> parentItemValidators;
+  private final RetryHandler retryHandler;
+
+  @Autowired
+  public RerunHandlerImpl(TestItemRepository testItemRepository, LaunchRepository launchRepository,
+      UniqueIdGenerator uniqueIdGenerator,
+      TestCaseHashGenerator testCaseHashGenerator, ApplicationEventPublisher eventPublisher,
+      RerunSearcher rerunSearcher,
+      List<ParentItemValidator> parentItemValidators, RetryHandler retryHandler) {
+    this.testItemRepository = testItemRepository;
+    this.launchRepository = launchRepository;
+    this.uniqueIdGenerator = uniqueIdGenerator;
+    this.testCaseHashGenerator = testCaseHashGenerator;
+    this.eventPublisher = eventPublisher;
+    this.rerunSearcher = rerunSearcher;
+    this.parentItemValidators = parentItemValidators;
+    this.retryHandler = retryHandler;
+  }
+
+  @Override
+  public Launch handleLaunch(StartLaunchRQ request, Long projectId, ReportPortalUser user) {
+    Optional<Launch> launchOptional = StringUtils.isEmpty(request.getRerunOf()) ?
+        launchRepository.findLatestByNameAndProjectId(request.getName(), projectId) :
+        launchRepository.findByUuid(request.getRerunOf());
+    Launch launch = launchOptional.orElseThrow(
+        () -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND,
+            ofNullable(request.getRerunOf()).orElse(request.getName())
+        ));
+
+    ofNullable(request.getMode()).map(it -> LaunchModeEnum.valueOf(it.name()))
+        .ifPresent(launch::setMode);
+    ofNullable(request.getDescription()).ifPresent(launch::setDescription);
+    launch.setStatus(StatusEnum.IN_PROGRESS);
+    ofNullable(request.getAttributes()).map(it -> it.stream()
+        .map(attr -> TO_LAUNCH_ATTRIBUTE.apply(attr, launch))
+        .collect(Collectors.toSet())).ifPresent(launch::setAttributes);
+    ofNullable(request.getUuid()).ifPresent(launch::setUuid);
+    launch.setRerun(true);
+    return launch;
+  }
+
+  @Override
+  public Optional<ItemCreatedRS> handleRootItem(StartTestItemRQ request, Launch launch) {
+    final Integer testCaseHash = getTestCaseHash(request, launch);
+    final Filter parentItemFilter = getRootItemFilter(launch, testCaseHash, request.getName());
+    return rerunSearcher.findItem(parentItemFilter).flatMap(testItemRepository::findById)
+        .map(it -> updateRootItem(request, it));
+  }
+
+  private Integer getTestCaseHash(StartTestItemRQ request, Launch launch) {
+    final TestCaseIdEntry testCaseIdEntry = TestItemBuilder.processTestCaseId(request);
+    return ofNullable(testCaseIdEntry.getId()).map(id -> testCaseIdEntry.getHash())
+        .orElseGet(() -> {
+          TestItem newItem = new TestItemBuilder().addStartItemRequest(request).get();
+          return testCaseHashGenerator.generate(newItem, Collections.emptyList(),
+              launch.getProjectId());
+        });
+  }
+
+  @Override
+  public Optional<ItemCreatedRS> handleChildItem(StartTestItemRQ request, Launch launch,
+      String parentUuid) {
+    if (!request.isHasStats()) {
+      return Optional.empty();
+    }
+
+    final Pair<Long, String> pathName = testItemRepository.selectPath(parentUuid)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, parentUuid));
+
+    TestItem newItem = new TestItemBuilder().addLaunchId(launch.getId())
+        .addStartItemRequest(request)
+        .addAttributes(request.getAttributes())
+        .addParentId(pathName.getFirst())
+        .get();
+
+    if (Objects.isNull(newItem.getTestCaseId())) {
+      newItem.setTestCaseHash(testCaseHashGenerator.generate(newItem,
+          IdentityUtil.getItemTreeIds(pathName.getSecond()),
+          launch.getProjectId()
+      ));
+    }
+
+    final Filter childItemFilter = getChildItemFilter(launch, newItem.getTestCaseHash(),
+        pathName.getFirst());
+
+    return rerunSearcher.findItem(childItemFilter).flatMap(testItemRepository::findById)
+        .flatMap(foundItem -> {
+          if (!foundItem.isHasChildren()) {
+            final TestItem parent = testItemRepository.findIdByUuidForUpdate(parentUuid)
+                .map(testItemRepository::getOne)
+                .orElseThrow(
+                    () -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, parentUuid));
+            parentItemValidators.forEach(v -> v.validate(request, parent));
+            return Optional.of(handleRetry(launch, newItem, foundItem, parent));
+          }
+
+          if (foundItem.getName().equals(newItem.getName())) {
+            return Optional.of(updateRootItem(request, foundItem));
+          }
+
+          childItemFilter.withCondition(
+              new FilterCondition(Condition.EQUALS, false, newItem.getName(), CRITERIA_NAME));
+          return rerunSearcher.findItem(childItemFilter).flatMap(testItemRepository::findById)
+              .map(it -> updateRootItem(request, it));
+        });
+  }
+
+  private Filter getCommonFilter(Long launchId, Integer testCaseHash) {
+    return Filter.builder()
+        .withTarget(TestItem.class)
+        .withCondition(new FilterCondition(Condition.EQUALS, false, String.valueOf(launchId),
+            CRITERIA_LAUNCH_ID))
+        .withCondition(new FilterCondition(Condition.EQUALS, false, String.valueOf(testCaseHash),
+            CRITERIA_TEST_CASE_HASH))
+        .build();
+  }
+
+  private Filter getRootItemFilter(Launch launch, Integer testCaseHash, String name) {
+    return getCommonFilter(launch.getId(), testCaseHash).withCondition(
+        new FilterCondition(Condition.EQUALS,
+            false,
+            name,
+            CRITERIA_NAME
+        )).withCondition(new FilterCondition(Condition.EXISTS, true, "1", CRITERIA_PARENT_ID));
+  }
+
+  private Filter getChildItemFilter(Launch launch, Integer testCaseHash, Long parentId) {
+    return getCommonFilter(launch.getId(), testCaseHash).withCondition(
+        new FilterCondition(Condition.EQUALS,
+            false,
+            String.valueOf(parentId),
+            CRITERIA_PARENT_ID
+        ));
+  }
+
+  private ItemCreatedRS handleRetry(Launch launch, TestItem newItem, TestItem foundItem,
+      TestItem parentItem) {
+    eventPublisher.publishEvent(
+        ItemRetryEvent.of(launch.getProjectId(), launch.getId(), foundItem.getItemId()));
+    testItemRepository.save(newItem);
+    newItem.setPath(parentItem.getPath() + "." + newItem.getItemId());
+    generateUniqueId(launch, newItem);
+    retryHandler.handleRetries(launch, newItem, foundItem.getItemId());
+    return new ItemCreatedRS(newItem.getUuid(), newItem.getUniqueId());
+  }
+
+  private void generateUniqueId(Launch launch, TestItem item) {
+    if (null == item.getUniqueId()) {
+      item.setUniqueId(uniqueIdGenerator.generate(item, IdentityUtil.getParentIds(item), launch));
+    }
+  }
+
+  private ItemCreatedRS updateRootItem(StartTestItemRQ request, TestItem foundItem) {
+    foundItem = new TestItemBuilder(foundItem).addDescription(request.getDescription())
+        .overwriteAttributes(request.getAttributes())
+        .addStatus(StatusEnum.IN_PROGRESS)
+        .get();
+    ofNullable(request.getUuid()).ifPresent(foundItem::setUuid);
+    return new ItemCreatedRS(foundItem.getUuid(), foundItem.getUniqueId());
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/util/LaunchValidator.java b/src/main/java/com/epam/ta/reportportal/core/launch/util/LaunchValidator.java
index ac4c41589c..e8825eafd2 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/util/LaunchValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/util/LaunchValidator.java
@@ -16,6 +16,21 @@
 
 package com.epam.ta.reportportal.core.launch.util;
 
+import static com.epam.ta.reportportal.commons.EntityUtils.TO_LOCAL_DATE_TIME;
+import static com.epam.ta.reportportal.commons.Preconditions.statusIn;
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import static com.epam.ta.reportportal.commons.Predicates.not;
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.IN_PROGRESS;
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.PASSED;
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.SKIPPED;
+import static com.epam.ta.reportportal.entity.project.ProjectRole.PROJECT_MANAGER;
+import static com.epam.ta.reportportal.ws.model.ErrorType.ACCESS_DENIED;
+import static com.epam.ta.reportportal.ws.model.ErrorType.FINISH_LAUNCH_NOT_ALLOWED;
+import static com.epam.ta.reportportal.ws.model.ErrorType.FINISH_TIME_EARLIER_THAN_START_TIME;
+import static com.epam.ta.reportportal.ws.model.ErrorType.INCORRECT_FINISH_STATUS;
+
 import com.epam.ta.reportportal.commons.Preconditions;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.entity.enums.StatusEnum;
@@ -23,85 +38,83 @@
 import com.epam.ta.reportportal.entity.project.Project;
 import com.epam.ta.reportportal.entity.user.UserRole;
 import com.epam.ta.reportportal.ws.model.FinishExecutionRQ;
-
 import java.util.function.Predicate;
 
-import static com.epam.ta.reportportal.commons.EntityUtils.TO_LOCAL_DATE_TIME;
-import static com.epam.ta.reportportal.commons.Preconditions.statusIn;
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-import static com.epam.ta.reportportal.commons.Predicates.not;
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
-import static com.epam.ta.reportportal.entity.enums.StatusEnum.*;
-import static com.epam.ta.reportportal.entity.project.ProjectRole.PROJECT_MANAGER;
-import static com.epam.ta.reportportal.ws.model.ErrorType.*;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 public class LaunchValidator {
 
-	private LaunchValidator() {
-		//static only
-	}
+  private LaunchValidator() {
+    //static only
+  }
 
-	/**
-	 * Validate {@link Launch#status} and value of the {@link Launch#endTime}
-	 *
-	 * @param launch            {@link Launch}
-	 * @param finishExecutionRQ {@link FinishExecutionRQ}
-	 */
-	public static void validate(Launch launch, FinishExecutionRQ finishExecutionRQ) {
-		expect(launch.getStatus(), equalTo(IN_PROGRESS)).verify(FINISH_LAUNCH_NOT_ALLOWED,
-				formattedSupplier("Launch '{}' already finished with status '{}'", launch.getId(), launch.getStatus())
-		);
+  /**
+   * Validate {@link Launch#status} and value of the {@link Launch#endTime}
+   *
+   * @param launch            {@link Launch}
+   * @param finishExecutionRQ {@link FinishExecutionRQ}
+   */
+  public static void validate(Launch launch, FinishExecutionRQ finishExecutionRQ) {
+    expect(launch.getStatus(), equalTo(IN_PROGRESS)).verify(FINISH_LAUNCH_NOT_ALLOWED,
+        formattedSupplier("Launch '{}' already finished with status '{}'", launch.getId(),
+            launch.getStatus())
+    );
 
-		expect(finishExecutionRQ.getEndTime(), Preconditions.sameTimeOrLater(launch.getStartTime())).verify(
-				FINISH_TIME_EARLIER_THAN_START_TIME,
-				TO_LOCAL_DATE_TIME.apply(finishExecutionRQ.getEndTime()),
-				launch.getStartTime(),
-				launch.getId()
-		);
-	}
+    expect(finishExecutionRQ.getEndTime(),
+        Preconditions.sameTimeOrLater(launch.getStartTime())).verify(
+        FINISH_TIME_EARLIER_THAN_START_TIME,
+        TO_LOCAL_DATE_TIME.apply(finishExecutionRQ.getEndTime()),
+        launch.getStartTime(),
+        launch.getId()
+    );
+  }
 
-	/**
-	 * Validate {@link ReportPortalUser} credentials and {@link Launch} affiliation to the {@link Project}
-	 *
-	 * @param launch         {@link Launch}
-	 * @param user           {@link ReportPortalUser}
-	 * @param projectDetails {@link ReportPortalUser.ProjectDetails}
-	 */
-	public static void validateRoles(Launch launch, ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails) {
-		if (user.getUserRole() != UserRole.ADMINISTRATOR) {
-			expect(launch.getProjectId(), equalTo(projectDetails.getProjectId())).verify(ACCESS_DENIED);
-			if (!launch.isRerun() && projectDetails.getProjectRole().lowerThan(PROJECT_MANAGER)) {
-				expect(user.getUserId(), Predicate.isEqual(launch.getUserId())).verify(ACCESS_DENIED, "You are not launch owner.");
-			}
-		}
-	}
+  /**
+   * Validate {@link ReportPortalUser} credentials and {@link Launch} affiliation to the
+   * {@link Project}
+   *
+   * @param launch         {@link Launch}
+   * @param user           {@link ReportPortalUser}
+   * @param projectDetails {@link ReportPortalUser.ProjectDetails}
+   */
+  public static void validateRoles(Launch launch, ReportPortalUser user,
+      ReportPortalUser.ProjectDetails projectDetails) {
+    if (user.getUserRole() != UserRole.ADMINISTRATOR) {
+      expect(launch.getProjectId(), equalTo(projectDetails.getProjectId())).verify(ACCESS_DENIED);
+      if (!launch.isRerun() && projectDetails.getProjectRole().lowerThan(PROJECT_MANAGER)) {
+        expect(user.getUserId(), Predicate.isEqual(launch.getUserId())).verify(ACCESS_DENIED,
+            "You are not launch owner.");
+      }
+    }
+  }
 
-	/**
-	 * Validate {@link Launch#status}
-	 *
-	 * @param launch               {@link Launch}
-	 * @param providedStatus       {@link StatusEnum} launch status from {@link FinishExecutionRQ}
-	 * @param fromStatisticsStatus {@link StatusEnum} identified launch status
-	 */
-	public static void validateProvidedStatus(Launch launch, StatusEnum providedStatus, StatusEnum fromStatisticsStatus) {
-		/* Validate provided status */
-		expect(providedStatus, not(statusIn(IN_PROGRESS, SKIPPED))).verify(INCORRECT_FINISH_STATUS,
-				formattedSupplier("Cannot finish launch '{}' with status '{}'", launch.getId(), providedStatus)
-		);
-		if (PASSED.equals(providedStatus)) {
-			/* Validate actual launch status */
-			expect(launch.getStatus(), statusIn(IN_PROGRESS, PASSED)).verify(INCORRECT_FINISH_STATUS,
-					formattedSupplier("Cannot finish launch '{}' with current status '{}' as 'PASSED'", launch.getId(), launch.getStatus())
-			);
-			expect(fromStatisticsStatus, statusIn(IN_PROGRESS, PASSED)).verify(INCORRECT_FINISH_STATUS, formattedSupplier(
-					"Cannot finish launch '{}' with calculated automatically status '{}' as 'PASSED'",
-					launch.getId(),
-					fromStatisticsStatus
-			));
-		}
-	}
+  /**
+   * Validate {@link Launch#status}
+   *
+   * @param launch               {@link Launch}
+   * @param providedStatus       {@link StatusEnum} launch status from {@link FinishExecutionRQ}
+   * @param fromStatisticsStatus {@link StatusEnum} identified launch status
+   */
+  public static void validateProvidedStatus(Launch launch, StatusEnum providedStatus,
+      StatusEnum fromStatisticsStatus) {
+    /* Validate provided status */
+    expect(providedStatus, not(statusIn(IN_PROGRESS, SKIPPED))).verify(INCORRECT_FINISH_STATUS,
+        formattedSupplier("Cannot finish launch '{}' with status '{}'", launch.getId(),
+            providedStatus)
+    );
+    if (PASSED.equals(providedStatus)) {
+      /* Validate actual launch status */
+      expect(launch.getStatus(), statusIn(IN_PROGRESS, PASSED)).verify(INCORRECT_FINISH_STATUS,
+          formattedSupplier("Cannot finish launch '{}' with current status '{}' as 'PASSED'",
+              launch.getId(), launch.getStatus())
+      );
+      expect(fromStatisticsStatus, statusIn(IN_PROGRESS, PASSED)).verify(INCORRECT_FINISH_STATUS,
+          formattedSupplier(
+              "Cannot finish launch '{}' with calculated automatically status '{}' as 'PASSED'",
+              launch.getId(),
+              fromStatisticsStatus
+          ));
+    }
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/util/LinkGenerator.java b/src/main/java/com/epam/ta/reportportal/core/launch/util/LinkGenerator.java
index 3511e8ce83..a62c06bb8a 100644
--- a/src/main/java/com/epam/ta/reportportal/core/launch/util/LinkGenerator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/launch/util/LinkGenerator.java
@@ -16,37 +16,36 @@
 
 package com.epam.ta.reportportal.core.launch.util;
 
+import javax.servlet.http.HttpServletRequest;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.http.server.ServletServerHttpRequest;
 import org.springframework.web.util.UriComponentsBuilder;
 
-import javax.servlet.http.HttpServletRequest;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 public final class LinkGenerator {
 
-	private static final String UI_PREFIX = "/ui/#";
-	private static final String LAUNCHES = "/launches/all/";
-
-	private LinkGenerator() {
-		//static only
-	}
-
-	public static String generateLaunchLink(String baseUrl, String projectName, String id) {
-		return StringUtils.isEmpty(baseUrl) ? null : baseUrl + UI_PREFIX + projectName + LAUNCHES + id;
-	}
-
-	public static String composeBaseUrl(HttpServletRequest request) {
-		/*
-		 * Use Uri components since they are aware of x-forwarded-host headers
-		 */
-		return UriComponentsBuilder.fromHttpRequest(new ServletServerHttpRequest(request))
-				.replacePath(null)
-				.replaceQuery(null)
-				.build()
-				.toUri()
-				.toASCIIString();
-	}
+  private static final String UI_PREFIX = "/ui/#";
+  private static final String LAUNCHES = "/launches/all/";
+
+  private LinkGenerator() {
+    //static only
+  }
+
+  public static String generateLaunchLink(String baseUrl, String projectName, String id) {
+    return StringUtils.isEmpty(baseUrl) ? null : baseUrl + UI_PREFIX + projectName + LAUNCHES + id;
+  }
+
+  public static String composeBaseUrl(HttpServletRequest request) {
+    /*
+     * Use Uri components since they are aware of x-forwarded-host headers
+     */
+    return UriComponentsBuilder.fromHttpRequest(new ServletServerHttpRequest(request))
+        .replacePath(null)
+        .replaceQuery(null)
+        .build()
+        .toUri()
+        .toASCIIString();
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/log/CreateLogHandler.java b/src/main/java/com/epam/ta/reportportal/core/log/CreateLogHandler.java
index b04f328524..4e584d1504 100644
--- a/src/main/java/com/epam/ta/reportportal/core/log/CreateLogHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/log/CreateLogHandler.java
@@ -16,6 +16,8 @@
 
 package com.epam.ta.reportportal.core.log;
 
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+
 import com.epam.ta.reportportal.commons.Predicates;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.validation.Suppliers;
@@ -23,41 +25,38 @@
 import com.epam.ta.reportportal.ws.model.EntryCreatedAsyncRS;
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.epam.ta.reportportal.ws.model.log.SaveLogRQ;
-import org.springframework.web.multipart.MultipartFile;
-
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
-
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import org.springframework.web.multipart.MultipartFile;
 
 public interface CreateLogHandler {
 
-	/**
-	 * Creates a new Log
-	 *
-	 * @param createLogRQ    Log details
-	 * @param file           file with log
-	 * @param projectDetails Project details
-	 * @return EntryCreatedRS
-	 */
-	@Nonnull
-	EntryCreatedAsyncRS createLog(@Nonnull SaveLogRQ createLogRQ, @Nullable MultipartFile file,
-			@Nullable ReportPortalUser.ProjectDetails projectDetails);
+  /**
+   * Creates a new Log
+   *
+   * @param createLogRQ    Log details
+   * @param file           file with log
+   * @param projectDetails Project details
+   * @return EntryCreatedRS
+   */
+  @Nonnull
+  EntryCreatedAsyncRS createLog(@Nonnull SaveLogRQ createLogRQ, @Nullable MultipartFile file,
+      @Nullable ReportPortalUser.ProjectDetails projectDetails);
 
-	/**
-	 * Validates business rules related to test item of this log
-	 *
-	 * @param saveLogRQ Save log request
-	 */
-	default void validate(SaveLogRQ saveLogRQ) {
-		// todo : seems we need to loosen (throw out) this time check
+  /**
+   * Validates business rules related to test item of this log
+   *
+   * @param saveLogRQ Save log request
+   */
+  default void validate(SaveLogRQ saveLogRQ) {
+    // todo : seems we need to loosen (throw out) this time check
 //		expect(saveLogRQ.getLogTime(), Preconditions.sameTimeOrLater(testItem.getStartTime())).verify(
 //				ErrorType.LOGGING_IS_NOT_ALLOWED,
 //				Suppliers.formattedSupplier("Log has incorrect log time. Log time should be after parent item's start time.")
 //		);
-		expect(LogLevel.toCustomLogLevel(saveLogRQ.getLevel()), Predicates.notNull()).verify(
-				ErrorType.BAD_SAVE_LOG_REQUEST,
-				Suppliers.formattedSupplier("Cannot convert '{}' to valid 'LogLevel'", saveLogRQ.getLevel())
-		);
-	}
+    expect(LogLevel.toCustomLogLevel(saveLogRQ.getLevel()), Predicates.notNull()).verify(
+        ErrorType.BAD_SAVE_LOG_REQUEST,
+        Suppliers.formattedSupplier("Cannot convert '{}' to valid 'LogLevel'", saveLogRQ.getLevel())
+    );
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/log/DeleteLogHandler.java b/src/main/java/com/epam/ta/reportportal/core/log/DeleteLogHandler.java
index f6805c24ed..d212f2129e 100644
--- a/src/main/java/com/epam/ta/reportportal/core/log/DeleteLogHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/log/DeleteLogHandler.java
@@ -21,13 +21,14 @@
 
 public interface DeleteLogHandler {
 
-	/**
-	 * Delete {@link com.epam.ta.reportportal.entity.log.Log} instance
-	 *
-	 * @param logId          ID of Log
-	 * @param projectDetails Project Details
-	 * @param user           User
-	 * @return OperationCompletionRS
-	 */
-	OperationCompletionRS deleteLog(Long logId, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user);
+  /**
+   * Delete {@link com.epam.ta.reportportal.entity.log.Log} instance
+   *
+   * @param logId          ID of Log
+   * @param projectDetails Project Details
+   * @param user           User
+   * @return OperationCompletionRS
+   */
+  OperationCompletionRS deleteLog(Long logId, ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user);
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/log/ElasticLogService.java b/src/main/java/com/epam/ta/reportportal/core/log/ElasticLogService.java
new file mode 100644
index 0000000000..c836c6d521
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/core/log/ElasticLogService.java
@@ -0,0 +1,332 @@
+package com.epam.ta.reportportal.core.log;
+
+import static com.epam.ta.reportportal.core.configs.rabbit.BackgroundProcessingConfiguration.LOG_MESSAGE_SAVING_ROUTING_KEY;
+import static com.epam.ta.reportportal.core.configs.rabbit.BackgroundProcessingConfiguration.PROCESSING_EXCHANGE_NAME;
+import static com.epam.ta.reportportal.ws.converter.converters.LogConverter.LOG_TO_LOG_FULL;
+import static java.util.stream.Collectors.groupingBy;
+import static java.util.stream.Collectors.mapping;
+import static java.util.stream.Collectors.toList;
+import static java.util.stream.Collectors.toMap;
+
+import com.epam.ta.reportportal.commons.querygen.Queryable;
+import com.epam.ta.reportportal.dao.LaunchRepository;
+import com.epam.ta.reportportal.dao.LogRepository;
+import com.epam.ta.reportportal.dao.TestItemRepository;
+import com.epam.ta.reportportal.dao.custom.ElasticSearchClient;
+import com.epam.ta.reportportal.entity.launch.Launch;
+import com.epam.ta.reportportal.entity.log.Log;
+import com.epam.ta.reportportal.entity.log.LogFull;
+import com.epam.ta.reportportal.entity.log.LogMessage;
+import com.epam.ta.reportportal.ws.model.analyzer.IndexLog;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.logging.log4j.util.Strings;
+import org.springframework.amqp.core.AmqpTemplate;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Primary;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Service;
+
+@Primary
+@Service
+@ConditionalOnProperty(prefix = "rp.elasticsearch", name = "host")
+public class ElasticLogService implements LogService {
+
+  private final AmqpTemplate amqpTemplate;
+  private final ElasticSearchClient elasticSearchClient;
+  private final LogRepository logRepository;
+  private final LaunchRepository launchRepository;
+  private final TestItemRepository testItemRepository;
+
+  public ElasticLogService(@Qualifier(value = "rabbitTemplate") AmqpTemplate amqpTemplate,
+      ElasticSearchClient elasticSearchClient, LogRepository logRepository,
+      LaunchRepository launchRepository, TestItemRepository testItemRepository) {
+    this.amqpTemplate = amqpTemplate;
+    this.elasticSearchClient = elasticSearchClient;
+    this.logRepository = logRepository;
+    this.launchRepository = launchRepository;
+    this.testItemRepository = testItemRepository;
+  }
+
+  public void saveLogMessage(LogFull logFull, Long launchId) {
+    if (Objects.isNull(logFull)) {
+      return;
+    }
+    amqpTemplate.convertAndSend(PROCESSING_EXCHANGE_NAME, LOG_MESSAGE_SAVING_ROUTING_KEY,
+        convertLogToLogMessage(logFull, launchId)
+    );
+  }
+
+  /**
+   * Used only for generation demo data, that send all per message to avoid some object/collection
+   * wrapping during reporting.
+   *
+   * @param logFullList list of {@link LogFull}
+   */
+  public void saveLogMessageList(List<LogFull> logFullList, Long launchId) {
+    if (CollectionUtils.isEmpty(logFullList)) {
+      return;
+    }
+    logFullList.stream().filter(Objects::nonNull)
+        .forEach(logFull -> saveLogMessage(logFull, launchId));
+  }
+
+  @Override
+  public void deleteLogMessage(Long projectId, Long logId) {
+    elasticSearchClient.deleteLogsByLogIdAndProjectId(projectId, logId);
+  }
+
+  @Override
+  public void deleteLogMessageByTestItemSet(Long projectId, Set<Long> itemIds) {
+    elasticSearchClient.deleteLogsByItemSetAndProjectId(projectId, itemIds);
+  }
+
+  @Override
+  public void deleteLogMessageByLaunch(Long projectId, Long launchId) {
+    elasticSearchClient.deleteLogsByLaunchIdAndProjectId(projectId, launchId);
+  }
+
+  @Override
+  public void deleteLogMessageByLaunchList(Long projectId, List<Long> launchIds) {
+    elasticSearchClient.deleteLogsByLaunchListAndProjectId(projectId, launchIds);
+  }
+
+  @Override
+  public void deleteLogMessageByProject(Long projectId) {
+    elasticSearchClient.deleteLogsByProjectId(projectId);
+  }
+
+  @Override
+  public Map<Long, List<IndexLog>> findAllIndexUnderTestItemByLaunchIdAndTestItemIdsAndLogLevelGte(
+      Long launchId, List<Long> itemIds, int logLevel) {
+    Long projectId = launchRepository.findById(launchId).map(Launch::getProjectId).orElseThrow();
+    Map<Long, List<IndexLog>> indexLogMap =
+        logRepository.findAllIndexUnderTestItemByLaunchIdAndTestItemIdsAndLogLevelGte(launchId,
+            itemIds, logLevel
+        );
+    return wrapLogsWithLogMessages(projectId, indexLogMap);
+  }
+
+  private Map<Long, List<IndexLog>> wrapLogsWithLogMessages(Long projectId,
+      Map<Long, List<IndexLog>> indexLogMap) {
+    Map<Long, List<IndexLog>> wrappedMap = new HashMap<>();
+    if (indexLogMap != null && indexLogMap.size() > 0) {
+      List<Long> logIds =
+          indexLogMap.values().stream().flatMap(Collection::stream).map(IndexLog::getLogId)
+              .collect(Collectors.toList());
+      Map<Long, LogMessage> logMessageMap =
+          elasticSearchClient.getLogMessagesByProjectIdAndIds(projectId, logIds);
+
+      wrappedMap = indexLogMap.entrySet().stream().peek(indexLogEntry -> {
+        List<IndexLog> indexLogList = indexLogEntry.getValue().stream().peek(indexLog -> {
+          LogMessage logMessage = logMessageMap.get(indexLog.getLogId());
+          if (logMessage != null) {
+            indexLog.setMessage(logMessage.getLogMessage());
+          }
+        }).collect(toList());
+        indexLogEntry.setValue(indexLogList);
+      }).collect(toMap(Map.Entry::getKey, Map.Entry::getValue));
+    }
+
+    return wrappedMap;
+  }
+
+  @Override
+  public List<String> findMessagesByLaunchIdAndItemIdAndPathAndLevelGte(Long launchId, Long itemId,
+      String path, Integer level) {
+    Long projectId = launchRepository.findById(launchId).map(Launch::getProjectId).orElseThrow();
+    List<Long> logIds =
+        logRepository.findIdsByLaunchIdAndItemIdAndPathAndLevelGte(launchId, itemId, path, level);
+
+    return elasticSearchClient.getLogMessagesByProjectIdAndIds(projectId, logIds).values().stream()
+        .map(LogMessage::getLogMessage).collect(toList());
+  }
+
+  @Override
+  public List<LogFull> findAllUnderTestItemByLaunchIdAndTestItemIdsAndLogLevelGte(Long launchId,
+      List<Long> itemIds, int logLevel) {
+    return wrapLogsWithLogMessages(
+        logRepository.findAllUnderTestItemByLaunchIdAndTestItemIdsAndLogLevelGte(launchId, itemIds,
+            logLevel
+        ));
+  }
+
+  @Override
+  public List<LogFull> findLatestUnderTestItemByLaunchIdAndTestItemIdsAndLogLevelGte(Long launchId,
+      Long itemId, int logLevel, int limit) {
+    return wrapLogsWithLogMessages(
+        logRepository.findLatestUnderTestItemByLaunchIdAndTestItemIdsAndLogLevelGte(launchId,
+            itemId, logLevel, limit
+        ));
+  }
+
+  @Override
+  public List<Log> findAllUnderTestItemByLaunchIdAndTestItemIdsWithLimit(Long launchId,
+      List<Long> itemIds, int limit) {
+    return logRepository.findAllUnderTestItemByLaunchIdAndTestItemIdsWithLimit(launchId, itemIds,
+        limit
+    );
+  }
+
+  @Override
+  public List<Log> findByTestItemId(Long itemId, int limit) {
+    return logRepository.findByTestItemId(itemId, limit);
+  }
+
+  @Override
+  public List<Log> findByTestItemId(Long itemId) {
+    return logRepository.findByTestItemId(itemId);
+  }
+
+  @Override
+  public List<LogFull> findByFilter(Queryable filter) {
+    return wrapLogsWithLogMessages(logRepository.findByFilter(filter));
+  }
+
+  @Override
+  // Possibly need to be refactored after filter investigation
+  public Page<LogFull> findByFilter(Queryable filter, Pageable pageable) {
+    Page<Log> byFilter = logRepository.findByFilter(filter, pageable);
+    return byFilter.map(this::getLogFull);
+  }
+
+  @Override
+  public List<LogFull> findAllById(Iterable<Long> ids) {
+    return wrapLogsWithLogMessages(logRepository.findAllById(ids));
+  }
+
+  @Override
+  public Optional<LogFull> findById(Long id) {
+    return logRepository.findById(id).map(this::getLogFull);
+  }
+
+  @Override
+  public Optional<LogFull> findByUuid(String uuid) {
+    return logRepository.findByUuid(uuid).map(this::getLogFull);
+  }
+
+  @Override
+  public List<Long> selectTestItemIdsByStringLogMessage(Collection<Long> itemIds, Integer logLevel,
+      String pattern) {
+    return testItemRepository.selectIdsByStringLogMessage(itemIds, logLevel, pattern);
+  }
+
+  @Override
+  public List<Long> selectTestItemIdsUnderByStringLogMessage(Long launchId,
+      Collection<Long> itemIds, Integer logLevel, String pattern) {
+    return testItemRepository.selectIdsUnderByStringLogMessage(launchId, itemIds, logLevel,
+        pattern);
+  }
+
+  @Override
+  public List<Long> selectTestItemIdsByRegexLogMessage(Collection<Long> itemIds, Integer logLevel,
+      String pattern) {
+    return testItemRepository.selectIdsByRegexLogMessage(itemIds, logLevel, pattern);
+  }
+
+  @Override
+  public List<Long> selectTestItemIdsUnderByRegexLogMessage(Long launchId, Collection<Long> itemIds,
+      Integer logLevel, String pattern) {
+    return testItemRepository.selectIdsUnderByRegexLogMessage(launchId, itemIds, logLevel, pattern);
+  }
+
+  // TODO : refactoring pattern analyzer and add projectId as parameter
+  // Instead of this method.
+  private Long getProjectId(Collection<Long> itemIds) {
+    Long id = itemIds.stream().findFirst().get();
+    return testItemRepository.findById(id).map(
+        testItem -> launchRepository.findById(testItem.getLaunchId()).map(Launch::getProjectId)
+            .orElseThrow()).orElseThrow();
+  }
+
+  private LogMessage convertLogToLogMessage(LogFull logFull, Long launchId) {
+    Long itemId = Objects.nonNull(logFull.getTestItem()) ? logFull.getTestItem().getItemId() : null;
+    return new LogMessage(logFull.getId(), logFull.getLogTime(), logFull.getLogMessage(), itemId,
+        launchId, logFull.getProjectId()
+    );
+  }
+
+  private List<LogFull> wrapLogsWithLogMessages(List<Log> logList) {
+    List<LogFull> logFullList = new ArrayList<>();
+
+    if (CollectionUtils.isNotEmpty(logList)) {
+      // This part of code for optimization receiving all needed message from elastic
+      // instead of get by single
+      // And for getting message from elastic we need projectId
+      // we get all message per projectId
+      logFullList = new ArrayList<>(logList.size());
+      Map<Long, LogMessage> logMessageMap = new HashMap<>();
+      Map<Long, List<Long>> logIdsGroupByProject = logList.stream()
+          .collect(groupingBy(Log::getProjectId, mapping(Log::getId, Collectors.toList())));
+
+      for (Map.Entry<Long, List<Long>> logIdsPerProject : logIdsGroupByProject.entrySet()) {
+        Long projectId = logIdsPerProject.getKey();
+        List<Long> logIds = logIdsPerProject.getValue();
+        logMessageMap.putAll(
+            elasticSearchClient.getLogMessagesByProjectIdAndIds(projectId, logIds));
+      }
+
+      for (Log log : logList) {
+        String logMessage = (logMessageMap.get(log.getId()) != null) ?
+            logMessageMap.get(log.getId()).getLogMessage() : log.getLogMessage();
+        LogFull logFull = getLogFull(log, logMessage);
+
+        logFullList.add(logFull);
+      }
+    }
+
+    return logFullList;
+  }
+
+  private LogFull getLogFull(Log log) {
+    LogMessage logMessage =
+        elasticSearchClient.getLogMessageByProjectIdAndId(log.getProjectId(), log.getId());
+    String message = (logMessage != null) ? logMessage.getLogMessage() : null;
+
+    return getLogFull(log, message);
+  }
+
+  private LogFull getLogFull(Log log, String logMessage) {
+    LogFull logFull = LOG_TO_LOG_FULL.apply(log);
+    if (Strings.isNotBlank(logMessage)) {
+      logFull.setLogMessage(logMessage);
+    }
+
+    return logFull;
+  }
+
+  private List<Long> selectTestItemIdsUnderByLogMessage(Long launchId, Collection<Long> itemIds,
+      Integer logLevel, String string, boolean selectByPattern) {
+    Long projectId = getProjectId(itemIds);
+    List<Long> matchedItemIds = new ArrayList<>();
+    for (Long itemId : itemIds) {
+      List<Long> logIdsPg =
+          testItemRepository.selectLogIdsUnderWithLogLevelCondition(launchId, itemIds, logLevel);
+
+      List<Long> nestedItemsMatchedIds;
+      if (selectByPattern) {
+        nestedItemsMatchedIds =
+            elasticSearchClient.searchTestItemIdsByLogIdsAndRegexp(projectId, logIdsPg, string);
+      } else {
+        nestedItemsMatchedIds =
+            elasticSearchClient.searchTestItemIdsByLogIdsAndString(projectId, logIdsPg, string);
+      }
+
+      if (CollectionUtils.isNotEmpty(nestedItemsMatchedIds)) {
+        matchedItemIds.add(itemId);
+      }
+    }
+    return matchedItemIds;
+  }
+
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/log/EmptyLogService.java b/src/main/java/com/epam/ta/reportportal/core/log/EmptyLogService.java
new file mode 100644
index 0000000000..34e237dfd9
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/core/log/EmptyLogService.java
@@ -0,0 +1,190 @@
+package com.epam.ta.reportportal.core.log;
+
+import static com.epam.ta.reportportal.ws.converter.converters.LogConverter.LOG_TO_LOG_FULL;
+
+import com.epam.ta.reportportal.commons.querygen.Queryable;
+import com.epam.ta.reportportal.dao.LogRepository;
+import com.epam.ta.reportportal.dao.TestItemRepository;
+import com.epam.ta.reportportal.entity.log.Log;
+import com.epam.ta.reportportal.entity.log.LogFull;
+import com.epam.ta.reportportal.ws.model.analyzer.IndexLog;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Service;
+
+/**
+ * It's temporary class, that's used for gracefully migration logs to Elasticsearch. Will be removed
+ * in the future. That's why, for instance, some methods may be duplicated with ElasticLogService
+ * instead of moving it to some parent class.
+ */
+@Service
+public class EmptyLogService implements LogService {
+
+  private final LogRepository logRepository;
+  private final TestItemRepository testItemRepository;
+
+  public EmptyLogService(LogRepository logRepository, TestItemRepository testItemRepository) {
+    this.logRepository = logRepository;
+    this.testItemRepository = testItemRepository;
+  }
+
+  @Override
+  public void saveLogMessage(LogFull logFull, Long launchId) {
+
+  }
+
+  @Override
+  public void saveLogMessageList(List<LogFull> logFullList, Long launchId) {
+
+  }
+
+  @Override
+  public void deleteLogMessage(Long projectId, Long logId) {
+
+  }
+
+  @Override
+  public void deleteLogMessageByTestItemSet(Long projectId, Set<Long> itemIds) {
+
+  }
+
+  @Override
+  public void deleteLogMessageByLaunch(Long projectId, Long launchId) {
+
+  }
+
+  @Override
+  public void deleteLogMessageByLaunchList(Long projectId, List<Long> launchIds) {
+
+  }
+
+  @Override
+  public void deleteLogMessageByProject(Long projectId) {
+
+  }
+
+  @Override
+  public Map<Long, List<IndexLog>> findAllIndexUnderTestItemByLaunchIdAndTestItemIdsAndLogLevelGte(
+      Long launchId, List<Long> itemIds, int logLevel) {
+    return logRepository.findAllIndexUnderTestItemByLaunchIdAndTestItemIdsAndLogLevelGte(launchId,
+        itemIds, logLevel);
+  }
+
+  @Override
+  public List<String> findMessagesByLaunchIdAndItemIdAndPathAndLevelGte(Long launchId, Long itemId,
+      String path, Integer level) {
+    return logRepository.findMessagesByLaunchIdAndItemIdAndPathAndLevelGte(launchId, itemId, path,
+        level);
+  }
+
+  @Override
+  public List<LogFull> findAllUnderTestItemByLaunchIdAndTestItemIdsAndLogLevelGte(Long launchId,
+      List<Long> itemIds, int logLevel) {
+    return wrapLogsWithLogMessages(
+        logRepository.findAllUnderTestItemByLaunchIdAndTestItemIdsAndLogLevelGte(launchId, itemIds,
+            logLevel));
+  }
+
+  @Override
+  public List<LogFull> findLatestUnderTestItemByLaunchIdAndTestItemIdsAndLogLevelGte(Long launchId,
+      Long itemId, int logLevel, int limit) {
+    return wrapLogsWithLogMessages(
+        logRepository.findLatestUnderTestItemByLaunchIdAndTestItemIdsAndLogLevelGte(launchId,
+            itemId, logLevel, limit));
+  }
+
+  @Override
+  public List<Log> findAllUnderTestItemByLaunchIdAndTestItemIdsWithLimit(Long launchId,
+      List<Long> itemIds, int limit) {
+    return logRepository.findAllUnderTestItemByLaunchIdAndTestItemIdsWithLimit(launchId, itemIds,
+        limit);
+  }
+
+  @Override
+  public List<Log> findByTestItemId(Long itemId, int limit) {
+    return logRepository.findByTestItemId(itemId, limit);
+  }
+
+  @Override
+  public List<Log> findByTestItemId(Long itemId) {
+    return logRepository.findByTestItemId(itemId);
+  }
+
+  @Override
+  public List<LogFull> findByFilter(Queryable filter) {
+    return wrapLogsWithLogMessages(logRepository.findByFilter(filter));
+  }
+
+  @Override
+  public Page<LogFull> findByFilter(Queryable filter, Pageable pageable) {
+    Page<Log> byFilter = logRepository.findByFilter(filter, pageable);
+    return byFilter.map(this::getLogFull);
+  }
+
+  @Override
+  public List<LogFull> findAllById(Iterable<Long> ids) {
+    return wrapLogsWithLogMessages(logRepository.findAllById(ids));
+  }
+
+  @Override
+  public Optional<LogFull> findById(Long id) {
+    return logRepository.findById(id).map(this::getLogFull);
+  }
+
+  @Override
+  public Optional<LogFull> findByUuid(String uuid) {
+    return logRepository.findByUuid(uuid).map(this::getLogFull);
+  }
+
+  private List<LogFull> wrapLogsWithLogMessages(List<Log> logList) {
+    List<LogFull> logFullList = new ArrayList<>();
+    // TODO: check for empty and add log message - tmp
+    if (CollectionUtils.isNotEmpty(logList)) {
+      logFullList = new ArrayList<>(logList.size());
+
+      for (Log log : logList) {
+        LogFull logFull = getLogFull(log);
+
+        logFullList.add(logFull);
+      }
+    }
+
+    return logFullList;
+  }
+
+  private LogFull getLogFull(Log log) {
+    return LOG_TO_LOG_FULL.apply(log);
+  }
+
+  @Override
+  public List<Long> selectTestItemIdsByStringLogMessage(Collection<Long> itemIds, Integer logLevel,
+      String pattern) {
+    return testItemRepository.selectIdsByStringLogMessage(itemIds, logLevel, pattern);
+  }
+
+  @Override
+  public List<Long> selectTestItemIdsUnderByStringLogMessage(Long launchId,
+      Collection<Long> itemIds, Integer logLevel, String pattern) {
+    return testItemRepository.selectIdsUnderByStringLogMessage(launchId, itemIds, logLevel,
+        pattern);
+  }
+
+  @Override
+  public List<Long> selectTestItemIdsByRegexLogMessage(Collection<Long> itemIds, Integer logLevel,
+      String pattern) {
+    return testItemRepository.selectIdsByRegexLogMessage(itemIds, logLevel, pattern);
+  }
+
+  @Override
+  public List<Long> selectTestItemIdsUnderByRegexLogMessage(Long launchId, Collection<Long> itemIds,
+      Integer logLevel, String pattern) {
+    return testItemRepository.selectIdsUnderByRegexLogMessage(launchId, itemIds, logLevel, pattern);
+  }
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/log/GetLogHandler.java b/src/main/java/com/epam/ta/reportportal/core/log/GetLogHandler.java
index 184cab8ba5..7b8b44e682 100644
--- a/src/main/java/com/epam/ta/reportportal/core/log/GetLogHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/log/GetLogHandler.java
@@ -24,10 +24,9 @@
 import com.epam.ta.reportportal.entity.log.Log;
 import com.epam.ta.reportportal.ws.model.log.GetLogsUnderRq;
 import com.epam.ta.reportportal.ws.model.log.LogResource;
-import org.springframework.data.domain.Pageable;
-
 import java.util.List;
 import java.util.Map;
+import org.springframework.data.domain.Pageable;
 
 /**
  * GET operation for {@link Log} entity
@@ -36,56 +35,66 @@
  */
 public interface GetLogHandler {
 
-	/**
-	 * Returns logs for specified filter
-	 *
-	 * @param filterable - filter definition
-	 * @param pageable   - pageable definition
-	 * @return Iterable<LogResource>
-	 */
-	Iterable<LogResource> getLogs(String path, ReportPortalUser.ProjectDetails projectDetails, Filter filterable, Pageable pageable);
+  /**
+   * Returns logs for specified filter
+   *
+   * @param filterable      - filter definition
+   * @param pageable        - pageable definition
+   * @param path            - logs path
+   * @param projectDetails  - project details
+   * @return mapping with {@link TestItem#getItemId()} as key and its list of {@link LogResource} as value
+   */
+  Iterable<LogResource> getLogs(String path, ReportPortalUser.ProjectDetails projectDetails,
+      Filter filterable, Pageable pageable);
 
-	/**
-	 * @param logsUnderRq    {@link GetLogsUnderRq}
-	 * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
-	 * @return mapping with {@link TestItem#getItemId()} as key and its {@link Log} list as value
-	 */
-	Map<Long, List<LogResource>> getLogs(GetLogsUnderRq logsUnderRq, ReportPortalUser.ProjectDetails projectDetails);
+  /**
+   * @param logsUnderRq    {@link GetLogsUnderRq}
+   * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
+   * @return mapping with {@link TestItem#getItemId()} as key and its {@link Log} list as value
+   */
+  Map<Long, List<LogResource>> getLogs(GetLogsUnderRq logsUnderRq,
+      ReportPortalUser.ProjectDetails projectDetails);
 
-	/**
-	 * Returns log by UUID
-	 *
-	 * @param logId          - target log UUID value
-	 * @param projectDetails Project details
-	 * @param user           User
-	 * @return LogResource
-	 */
-	LogResource getLog(String logId, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user);
+  /**
+   * Returns log by UUID
+   *
+   * @param logId          - target log UUID value
+   * @param projectDetails Project details
+   * @param user           User
+   * @return LogResource
+   */
+  LogResource getLog(String logId, ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user);
 
-	/**
-	 * Calculates page number and returns entire page for specified log ID
-	 *
-	 * @param logId          ID of log to find
-	 * @param projectDetails Project details
-	 * @param filterable     Filter for paging
-	 * @param pageable       Paging details
-	 * @return Page Number
-	 */
-	long getPageNumber(Long logId, ReportPortalUser.ProjectDetails projectDetails, Filter filterable, Pageable pageable);
+  /**
+   * Calculates page number and returns entire page for specified log ID
+   *
+   * @param logId          ID of log to find
+   * @param projectDetails Project details
+   * @param filterable     Filter for paging
+   * @param pageable       Paging details
+   * @return Page Number
+   */
+  long getPageNumber(Long logId, ReportPortalUser.ProjectDetails projectDetails, Filter filterable,
+      Pageable pageable);
 
-	/**
-	 * Get logs and nested steps as one collection, filtered and sorted by passed args
-	 *
-	 * @param parentId       {@link Log#testItem} ID or {@link com.epam.ta.reportportal.entity.item.TestItem#parent} ID
-	 * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
-	 * @param params         Request params
-	 * @param queryable      {@link Queryable}
-	 * @param pageable       {@link Pageable}
-	 * @return The {@link Iterable} of {@link LogResource} and {@link com.epam.ta.reportportal.ws.model.NestedStepResource} entities
-	 */
-	Iterable<?> getNestedItems(Long parentId, ReportPortalUser.ProjectDetails projectDetails, Map<String, String> params,
-			Queryable queryable, Pageable pageable);
+  /**
+   * Get logs and nested steps as one collection, filtered and sorted by passed args
+   *
+   * @param parentId       {@link com.epam.ta.reportportal.entity.log.Log#testItem} ID or
+   *                       {@link com.epam.ta.reportportal.entity.item.TestItem#parentId} ID
+   * @param projectDetails {@link com.epam.ta.reportportal.commons.ReportPortalUser.ProjectDetails}
+   * @param params         Request params
+   * @param queryable      {@link Queryable}
+   * @param pageable       {@link Pageable}
+   * @return The {@link Iterable} of {@link LogResource} and
+   * {@link com.epam.ta.reportportal.ws.model.NestedStepResource} entities
+   */
+  Iterable<?> getNestedItems(Long parentId, ReportPortalUser.ProjectDetails projectDetails,
+      Map<String, String> params,
+      Queryable queryable, Pageable pageable);
 
-	List<PagedLogResource> getLogsWithLocation(Long parentId, ReportPortalUser.ProjectDetails projectDetails, Map<String, String> params,
-			Queryable queryable, Pageable pageable);
+  List<PagedLogResource> getLogsWithLocation(Long parentId,
+      ReportPortalUser.ProjectDetails projectDetails, Map<String, String> params,
+      Queryable queryable, Pageable pageable);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/log/LogService.java b/src/main/java/com/epam/ta/reportportal/core/log/LogService.java
index cbb7974402..fa6e4dc4f0 100644
--- a/src/main/java/com/epam/ta/reportportal/core/log/LogService.java
+++ b/src/main/java/com/epam/ta/reportportal/core/log/LogService.java
@@ -1,21 +1,191 @@
 package com.epam.ta.reportportal.core.log;
 
+import com.epam.ta.reportportal.commons.querygen.Queryable;
+import com.epam.ta.reportportal.entity.item.TestItem;
+import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.entity.log.Log;
-
+import com.epam.ta.reportportal.entity.log.LogFull;
+import com.epam.ta.reportportal.ws.model.analyzer.IndexLog;
+import java.util.Collection;
 import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
 
 public interface LogService {
 
-    /**
-     * launchId - temporary, need to bring log launch/testItem to normal value.
-     */
-    void saveLogMessageToElasticSearch(Log log, Long launchId);
-
-    /**
-     * Used only for generation demo data, that send all per message to avoid some object/collection wrapping
-     * during reporting.
-     * @param logList
-     * @param launchId - temporary, need to bring log launch/testItem to normal value.
-     */
-    void saveLogMessageListToElasticSearch(List<Log> logList, Long launchId);
+  /**
+   * launchId - temporary, need to bring log launch/testItem to normal value.
+   *
+   * @param logFull  Log info for saving
+   * @param launchId Log's launch id
+   */
+  void saveLogMessage(LogFull logFull, Long launchId);
+
+  /**
+   * Used only for generation demo data, that send all per message to avoid some object/collection
+   * wrapping during reporting.
+   *
+   * @param logFullList - The {@link List} of {@link LogFull}
+   * @param launchId    - temporary, need to bring log launch/testItem to normal value.
+   */
+  void saveLogMessageList(List<LogFull> logFullList, Long launchId);
+
+  void deleteLogMessage(Long projectId, Long logId);
+
+  void deleteLogMessageByTestItemSet(Long projectId, Set<Long> itemIds);
+
+  void deleteLogMessageByLaunch(Long projectId, Long launchId);
+
+  void deleteLogMessageByLaunchList(Long projectId, List<Long> launchIds);
+
+  void deleteLogMessageByProject(Long projectId);
+
+  /**
+   * Find logs as {@link IndexLog} under {@link TestItem} and group by {@link Log#getTestItem()} ID
+   *
+   * @param launchId {@link} ID of the {@link Launch} to search {@link Log} under
+   * @param itemIds  {@link List} of the {@link Log#getTestItem()} IDs
+   * @param logLevel {@link Log#getLogLevel()}
+   * @return {@link List} of {@link Log}
+   */
+  Map<Long, List<IndexLog>> findAllIndexUnderTestItemByLaunchIdAndTestItemIdsAndLogLevelGte(
+      Long launchId, List<Long> itemIds, int logLevel);
+
+  /**
+   * Retrieves log message of specified test item with log level greather or equals than
+   * {@code level}
+   *
+   * @param launchId {@link TestItem#getLaunchId()}
+   * @param itemId   ID of {@link Log#getTestItem()}
+   * @param path     {@link TestItem#getPath()}
+   * @param level    log level
+   * @return {@link List} of {@link String} of log messages
+   */
+  List<String> findMessagesByLaunchIdAndItemIdAndPathAndLevelGte(Long launchId, Long itemId,
+      String path, Integer level);
+
+  /**
+   * @param launchId {@link} ID of the {@link Launch} to search {@link Log} under
+   * @param itemIds  {@link List} of the {@link Log#getTestItem()} IDs
+   * @param logLevel {@link Log#getLogLevel()}
+   * @return {@link List} of {@link LogFull}
+   */
+  List<LogFull> findAllUnderTestItemByLaunchIdAndTestItemIdsAndLogLevelGte(Long launchId,
+      List<Long> itemIds, int logLevel);
+
+  /**
+   * Find n latest logs for item
+   *
+   * @param launchId {@link} ID of the {@link Launch} to search {@link Log} under
+   * @param itemId   {@link List} of the {@link Log#getTestItem()} IDs
+   * @param logLevel {@link Log#getLogLevel()}
+   * @param limit    Number of logs to be fetch
+   * @return {@link List} of {@link LogFull}
+   */
+  List<LogFull> findLatestUnderTestItemByLaunchIdAndTestItemIdsAndLogLevelGte(Long launchId,
+      Long itemId, int logLevel, int limit);
+
+  /**
+   * @param launchId {@link} ID of the {@link Launch} to search {@link Log} under
+   * @param itemIds  {@link List} of the {@link Log#getTestItem()} IDs
+   * @param limit    Max count of {@link Log} to be loaded
+   * @return {@link List} of {@link Log}
+   */
+  List<Log> findAllUnderTestItemByLaunchIdAndTestItemIdsWithLimit(Long launchId, List<Long> itemIds,
+      int limit);
+
+  /**
+   * Load specified number of last logs for specified test item. binaryData field will be loaded if
+   * it specified in appropriate input parameter, all other fields will be fully loaded.
+   *
+   * @param limit  Max count of logs to be loaded
+   * @param itemId Test Item log belongs to
+   * @return Found logs
+   */
+  List<Log> findByTestItemId(Long itemId, int limit);
+
+  /**
+   * Load specified number of last logs for specified test item. binaryData field will be loaded if
+   * it specified in appropriate input parameter, all other fields will be fully loaded.
+   *
+   * @param itemId Test Item log belongs to
+   * @return Found logs
+   */
+  List<Log> findByTestItemId(Long itemId);
+
+  /**
+   * Executes query built for given filter
+   *
+   * @param filter Filter to build a query
+   * @return List of logFulls found
+   */
+  List<LogFull> findByFilter(Queryable filter);
+
+  /**
+   * Executes query built for given filter and maps result for given page
+   *
+   * @param filter   Filter to build a query
+   * @param pageable {@link Pageable}
+   * @return List of logFulls found
+   */
+  Page<LogFull> findByFilter(Queryable filter, Pageable pageable);
+
+  List<LogFull> findAllById(Iterable<Long> ids);
+
+  Optional<LogFull> findById(Long id);
+
+  Optional<LogFull> findByUuid(String uuid);
+
+  /**
+   * Select item IDs which log's level is greater than or equal to provided and log's message match
+   * to the STRING pattern
+   *
+   * @param itemIds  {@link Collection} of {@link TestItem#getItemId()} which logs should match
+   * @param logLevel {@link Log#getLogLevel()}
+   * @param pattern  CASE SENSITIVE STRING pattern for log message search
+   * @return The {@link List} of the {@link TestItem#getItemId()}
+   */
+  List<Long> selectTestItemIdsByStringLogMessage(Collection<Long> itemIds, Integer logLevel,
+      String pattern);
+
+  /**
+   * Select item IDs which descendants' log's level is greater than or equal to provided and log's
+   * message match to the REGEX pattern
+   *
+   * @param launchId {@link TestItem#getLaunchId()}
+   * @param itemIds  {@link Collection} of {@link TestItem#getItemId()} which logs should match
+   * @param logLevel {@link Log#getLogLevel()}
+   * @param pattern  REGEX pattern for log message search
+   * @return The {@link List} of the {@link TestItem#getItemId()}
+   */
+  List<Long> selectTestItemIdsUnderByStringLogMessage(Long launchId, Collection<Long> itemIds,
+      Integer logLevel, String pattern);
+
+  /**
+   * Select item IDs which log's level is greater than or equal to provided and log's message match
+   * to the REGEX pattern
+   *
+   * @param itemIds  {@link Collection} of {@link TestItem#getItemId()} which logs should match
+   * @param logLevel {@link Log#getLogLevel()}
+   * @param pattern  REGEX pattern for log message search
+   * @return The {@link List} of the {@link TestItem#getItemId()}
+   */
+  List<Long> selectTestItemIdsByRegexLogMessage(Collection<Long> itemIds, Integer logLevel,
+      String pattern);
+
+  /**
+   * Select item IDs which descendants' log's level is greater than or equal to provided and log's
+   * message match to the REGEX pattern
+   *
+   * @param launchId {@link TestItem#getLaunchId()}
+   * @param itemIds  {@link Collection} of {@link TestItem#getItemId()} which logs should match
+   * @param logLevel {@link Log#getLogLevel()}
+   * @param pattern  REGEX pattern for log message search
+   * @return The {@link List} of the {@link TestItem#getItemId()}
+   */
+  List<Long> selectTestItemIdsUnderByRegexLogMessage(Long launchId, Collection<Long> itemIds,
+      Integer logLevel, String pattern);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/log/LogServiceElastic.java b/src/main/java/com/epam/ta/reportportal/core/log/LogServiceElastic.java
deleted file mode 100644
index 8ac6c10edf..0000000000
--- a/src/main/java/com/epam/ta/reportportal/core/log/LogServiceElastic.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.epam.ta.reportportal.core.log;
-
-import com.epam.ta.reportportal.entity.log.Log;
-import com.epam.ta.reportportal.entity.log.LogMessage;
-import org.apache.commons.collections.CollectionUtils;
-import org.springframework.amqp.core.AmqpTemplate;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.context.annotation.Primary;
-import org.springframework.stereotype.Service;
-
-import java.util.List;
-import java.util.Objects;
-
-import static com.epam.ta.reportportal.core.configs.rabbit.BackgroundProcessingConfiguration.LOG_MESSAGE_SAVING_ROUTING_KEY;
-import static com.epam.ta.reportportal.core.configs.rabbit.BackgroundProcessingConfiguration.PROCESSING_EXCHANGE_NAME;
-
-@Primary
-@Service
-@ConditionalOnProperty(prefix = "rp.elasticsearchLogmessage", name = "host")
-public class LogServiceElastic implements LogService {
-    private final AmqpTemplate amqpTemplate;
-
-    public LogServiceElastic(@Qualifier(value = "rabbitTemplate") AmqpTemplate amqpTemplate) {
-        this.amqpTemplate = amqpTemplate;
-    }
-
-    public void saveLogMessageToElasticSearch(Log log, Long launchId) {
-        if (Objects.isNull(log)) return;
-        amqpTemplate.convertAndSend(PROCESSING_EXCHANGE_NAME, LOG_MESSAGE_SAVING_ROUTING_KEY,
-                convertLogToLogMessage(log, launchId));
-    }
-
-    /**
-     * Used only for generation demo data, that send all per message to avoid some object/collection wrapping
-     * during reporting.
-     * @param logList
-     */
-    public void saveLogMessageListToElasticSearch(List<Log> logList, Long launchId) {
-        if (CollectionUtils.isEmpty(logList)) return;
-        logList.stream().filter(Objects::nonNull).forEach(log -> saveLogMessageToElasticSearch(log, launchId));
-    }
-
-    private LogMessage convertLogToLogMessage(Log log, Long launchId) {
-        Long itemId = Objects.nonNull(log.getTestItem()) ? log.getTestItem().getItemId() : null;
-        return new LogMessage(log.getId(), log.getLogTime(), log.getLogMessage(), itemId, launchId, log.getProjectId());
-    }
-}
diff --git a/src/main/java/com/epam/ta/reportportal/core/log/LogServiceEmptyElastic.java b/src/main/java/com/epam/ta/reportportal/core/log/LogServiceEmptyElastic.java
deleted file mode 100644
index 2b17060a30..0000000000
--- a/src/main/java/com/epam/ta/reportportal/core/log/LogServiceEmptyElastic.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.epam.ta.reportportal.core.log;
-
-import com.epam.ta.reportportal.entity.log.Log;
-import org.springframework.stereotype.Service;
-
-import java.util.List;
-
-@Service
-public class LogServiceEmptyElastic implements LogService {
-
-    public LogServiceEmptyElastic() {
-    }
-
-    @Override
-    public void saveLogMessageToElasticSearch(Log log, Long launchId) {
-
-    }
-
-    @Override
-    public void saveLogMessageListToElasticSearch(List<Log> logList, Long launchId) {
-
-    }
-}
diff --git a/src/main/java/com/epam/ta/reportportal/core/log/impl/CreateLogHandlerAsyncImpl.java b/src/main/java/com/epam/ta/reportportal/core/log/impl/CreateLogHandlerAsyncImpl.java
index f2eaef2346..371d492f8b 100644
--- a/src/main/java/com/epam/ta/reportportal/core/log/impl/CreateLogHandlerAsyncImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/log/impl/CreateLogHandlerAsyncImpl.java
@@ -16,6 +16,8 @@
 
 package com.epam.ta.reportportal.core.log.impl;
 
+import static com.epam.ta.reportportal.core.configs.rabbit.ReportingConfiguration.EXCHANGE_REPORTING;
+
 import com.epam.ta.reportportal.commons.BinaryDataMetaInfo;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.configs.rabbit.DeserializablePair;
@@ -25,6 +27,11 @@
 import com.epam.ta.reportportal.ws.model.log.SaveLogRQ;
 import com.epam.ta.reportportal.ws.rabbit.MessageHeaders;
 import com.epam.ta.reportportal.ws.rabbit.RequestType;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
+import javax.annotation.Nonnull;
+import javax.inject.Provider;
 import org.springframework.amqp.core.AmqpTemplate;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
@@ -32,79 +39,71 @@
 import org.springframework.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
 
-import javax.annotation.Nonnull;
-import javax.inject.Provider;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.CompletableFuture;
-
-import static com.epam.ta.reportportal.core.configs.rabbit.ReportingConfiguration.EXCHANGE_REPORTING;
-
 /**
- * Asynchronous implementation of {@link CreateLogHandler} using RabbitMQ
- * to defer binding Log to ID(s)
+ * Asynchronous implementation of {@link CreateLogHandler} using RabbitMQ to defer binding Log to
+ * ID(s)
  *
  * @author Andrei Varabyeu
  */
 @Service("asyncCreateLogHandler")
 public class CreateLogHandlerAsyncImpl implements CreateLogHandler {
 
-	/**
-	 * We are using {@link Provider} there because we need
-	 * {@link SaveLogBinaryDataTaskAsync} with scope prototype. Since current class is in
-	 * singleton scope, we have to find a way to get new instance of job for new
-	 * execution
-	 */
-	@Autowired
-	private Provider<SaveLogBinaryDataTaskAsync> saveLogBinaryDataTask;
-
-	@Autowired
-	@Qualifier("saveLogsTaskExecutor")
-	private TaskExecutor taskExecutor;
-
-	@Autowired
-	private ReportingQueueService reportingQueueService;
-
-	@Autowired
-	@Qualifier(value = "rabbitTemplate")
-	AmqpTemplate amqpTemplate;
-
-	@Override
-	@Nonnull
-	public EntryCreatedAsyncRS createLog(@Nonnull SaveLogRQ request, MultipartFile file, ReportPortalUser.ProjectDetails projectDetails) {
-
-		validate(request);
-
-		request.setUuid(UUID.randomUUID().toString());
-
-		if (file != null) {
-			CompletableFuture.supplyAsync(saveLogBinaryDataTask.get()
-					.withRequest(request)
-					.withFile(file)
-					.withProjectId(projectDetails.getProjectId()), taskExecutor)
-					.thenAccept(metaInfo -> sendMessage(request, metaInfo, projectDetails.getProjectId()));
-		} else {
-			sendMessage(request, null, projectDetails.getProjectId());
-		}
-
-		EntryCreatedAsyncRS response = new EntryCreatedAsyncRS();
-		response.setId(request.getUuid());
-		return response;
-	}
-
-	protected void sendMessage(SaveLogRQ request, BinaryDataMetaInfo metaInfo, Long projectId) {
-		amqpTemplate.convertAndSend(
-				EXCHANGE_REPORTING,
-				reportingQueueService.getReportingQueueKey(request.getLaunchUuid()),
-				DeserializablePair.of(request, metaInfo),
-				message -> {
-					Map<String, Object> headers = message.getMessageProperties().getHeaders();
-					headers.put(MessageHeaders.REQUEST_TYPE, RequestType.LOG);
-					headers.put(MessageHeaders.PROJECT_ID, projectId);
-					headers.put(MessageHeaders.ITEM_ID, request.getItemUuid());
-					return message;
-				}
-		);
-
-	}
+  /**
+   * We are using {@link Provider} there because we need {@link SaveLogBinaryDataTaskAsync} with
+   * scope prototype. Since current class is in singleton scope, we have to find a way to get new
+   * instance of job for new execution
+   */
+  @Autowired
+  private Provider<SaveLogBinaryDataTaskAsync> saveLogBinaryDataTask;
+
+  @Autowired
+  @Qualifier("saveLogsTaskExecutor")
+  private TaskExecutor taskExecutor;
+
+  @Autowired
+  private ReportingQueueService reportingQueueService;
+
+  @Autowired
+  @Qualifier(value = "rabbitTemplate")
+  AmqpTemplate amqpTemplate;
+
+  @Override
+  @Nonnull
+  public EntryCreatedAsyncRS createLog(@Nonnull SaveLogRQ request, MultipartFile file,
+      ReportPortalUser.ProjectDetails projectDetails) {
+
+    validate(request);
+
+    request.setUuid(UUID.randomUUID().toString());
+
+    if (file != null) {
+      CompletableFuture.supplyAsync(saveLogBinaryDataTask.get()
+              .withRequest(request)
+              .withFile(file)
+              .withProjectId(projectDetails.getProjectId()), taskExecutor)
+          .thenAccept(metaInfo -> sendMessage(request, metaInfo, projectDetails.getProjectId()));
+    } else {
+      sendMessage(request, null, projectDetails.getProjectId());
+    }
+
+    EntryCreatedAsyncRS response = new EntryCreatedAsyncRS();
+    response.setId(request.getUuid());
+    return response;
+  }
+
+  protected void sendMessage(SaveLogRQ request, BinaryDataMetaInfo metaInfo, Long projectId) {
+    amqpTemplate.convertAndSend(
+        EXCHANGE_REPORTING,
+        reportingQueueService.getReportingQueueKey(request.getLaunchUuid()),
+        DeserializablePair.of(request, metaInfo),
+        message -> {
+          Map<String, Object> headers = message.getMessageProperties().getHeaders();
+          headers.put(MessageHeaders.REQUEST_TYPE, RequestType.LOG);
+          headers.put(MessageHeaders.PROJECT_ID, projectId);
+          headers.put(MessageHeaders.ITEM_ID, request.getItemUuid());
+          return message;
+        }
+    );
+
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/log/impl/CreateLogHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/log/impl/CreateLogHandlerImpl.java
index 60075463fb..ecaafb91dc 100644
--- a/src/main/java/com/epam/ta/reportportal/core/log/impl/CreateLogHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/log/impl/CreateLogHandlerImpl.java
@@ -16,6 +16,10 @@
 
 package com.epam.ta.reportportal.core.log.impl;
 
+import static com.epam.ta.reportportal.ws.converter.converters.LogConverter.LOG_FULL_TO_LOG;
+import static java.util.Optional.ofNullable;
+
+import com.epam.ta.reportportal.binary.AttachmentBinaryDataService;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.item.TestItemService;
 import com.epam.ta.reportportal.core.log.CreateLogHandler;
@@ -27,11 +31,18 @@
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.entity.log.Log;
+import com.epam.ta.reportportal.entity.log.LogFull;
 import com.epam.ta.reportportal.exception.ReportPortalException;
-import com.epam.ta.reportportal.ws.converter.builders.LogBuilder;
+import com.epam.ta.reportportal.ws.converter.builders.LogFullBuilder;
 import com.epam.ta.reportportal.ws.model.EntryCreatedAsyncRS;
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.epam.ta.reportportal.ws.model.log.SaveLogRQ;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.util.concurrent.CompletableFuture;
+import javax.annotation.Nonnull;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.context.annotation.Primary;
@@ -40,13 +51,6 @@
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.multipart.MultipartFile;
 
-import javax.annotation.Nonnull;
-import javax.inject.Provider;
-import java.time.LocalDateTime;
-import java.time.ZoneOffset;
-
-import static java.util.Optional.ofNullable;
-
 /**
  * Create log handler. Save log and binary data related to it
  *
@@ -58,78 +62,79 @@
 @Transactional
 public class CreateLogHandlerImpl implements CreateLogHandler {
 
-	@Autowired
-	TestItemRepository testItemRepository;
-
-	@Autowired
-	TestItemService testItemService;
-
-	@Autowired
-	LaunchRepository launchRepository;
-
-	@Autowired
-	LogRepository logRepository;
-
-	/**
-	 * We are using {@link Provider} there because we need
-	 * {@link SaveLogBinaryDataTask} with scope prototype. Since current class is in
-	 * singleton scope, we have to find a way to get new instance of job for new
-	 * execution
-	 */
-	@Autowired
-	private Provider<SaveLogBinaryDataTask> saveLogBinaryDataTask;
-
-	@Autowired
-	private LogService logService;
-
-	@Autowired
-	@Qualifier("saveLogsTaskExecutor")
-	private TaskExecutor taskExecutor;
-
-	@Override
-	@Nonnull
-	//TODO check saving an attachment of the item of the project A in the project's B directory
-	public EntryCreatedAsyncRS createLog(@Nonnull SaveLogRQ request, MultipartFile file, ReportPortalUser.ProjectDetails projectDetails) {
-		validate(request);
-
-		final LogBuilder logBuilder = new LogBuilder().addSaveLogRq(request).addProjectId(projectDetails.getProjectId());
-
-		final Launch launch = testItemRepository.findByUuid(request.getItemUuid()).map(item -> {
-			logBuilder.addTestItem(item);
-			return testItemService.getEffectiveLaunch(item);
-		}).orElseGet(() -> launchRepository.findByUuid(request.getLaunchUuid()).map(l -> {
-			logBuilder.addLaunch(l);
-			return l;
-		}).orElseThrow(() -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND, request.getLaunchUuid())));
-
-		final Log log = logBuilder.get();
-		logRepository.save(log);
-		logService.saveLogMessageToElasticSearch(log, launch.getId());
-
-		ofNullable(file).ifPresent(f -> saveBinaryData(f, launch, log));
-
-		return new EntryCreatedAsyncRS(log.getUuid());
-
-	}
-
-	private void saveBinaryData(MultipartFile file, Launch launch, Log log) {
-
-		final AttachmentMetaInfo.AttachmentMetaInfoBuilder metaInfoBuilder = AttachmentMetaInfo.builder()
-				.withProjectId(launch.getProjectId())
-				.withLaunchId(launch.getId())
-				.withLaunchUuid(launch.getUuid())
-				.withLogId(log.getId())
-				.withFileName(file.getOriginalFilename())
-				.withLogUuid(log.getUuid())
-				.withCreationDate(LocalDateTime.now(ZoneOffset.UTC));
-		ofNullable(log.getTestItem()).map(TestItem::getItemId).ifPresent(metaInfoBuilder::withItemId);
-
-		SaveLogBinaryDataTask saveLogBinaryDataTask = this.saveLogBinaryDataTask.get()
-				.withFile(file)
-				.withAttachmentMetaInfo(metaInfoBuilder.build());
-
-		taskExecutor.execute(saveLogBinaryDataTask);
-
-	}
-
+  private static final Logger LOGGER = LoggerFactory.getLogger(CreateLogHandlerImpl.class);
+
+  @Autowired
+  TestItemRepository testItemRepository;
+
+  @Autowired
+  TestItemService testItemService;
+
+  @Autowired
+  LaunchRepository launchRepository;
+
+  @Autowired
+  LogRepository logRepository;
+
+  @Autowired
+  AttachmentBinaryDataService attachmentBinaryDataService;
+
+  @Autowired
+  private LogService logService;
+
+  @Autowired
+  @Qualifier("saveLogsTaskExecutor")
+  private TaskExecutor taskExecutor;
+
+  @Override
+  @Nonnull
+  //TODO check saving an attachment of the item of the project A in the project's B directory
+  public EntryCreatedAsyncRS createLog(@Nonnull SaveLogRQ request, MultipartFile file,
+      ReportPortalUser.ProjectDetails projectDetails) {
+    validate(request);
+
+    final LogFullBuilder logFullBuilder =
+        new LogFullBuilder().addSaveLogRq(request).addProjectId(projectDetails.getProjectId());
+
+    final Launch launch = testItemRepository.findByUuid(request.getItemUuid()).map(item -> {
+      logFullBuilder.addTestItem(item);
+      return testItemService.getEffectiveLaunch(item);
+    }).orElseGet(() -> launchRepository.findByUuid(request.getLaunchUuid()).map(l -> {
+      logFullBuilder.addLaunch(l);
+      return l;
+    }).orElseThrow(
+        () -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND, request.getLaunchUuid())));
+
+    final LogFull logFull = logFullBuilder.get();
+    final Log log = LOG_FULL_TO_LOG.apply(logFull);
+    CompletableFuture.supplyAsync(() -> logRepository.saveAndFlush(log), taskExecutor)
+        .thenAcceptAsync(savedLog -> {
+          logFull.setId(savedLog.getId());
+          logService.saveLogMessage(logFull, launch.getId());
+          if (file != null) {
+            saveBinaryData(file, launch, savedLog);
+          }
+        }, taskExecutor)
+        .exceptionally(e -> {
+              LOGGER.error("Failed to save log with attachments", e);
+              return null;
+            }
+        );
+
+    return new EntryCreatedAsyncRS(log.getUuid());
+  }
+
+  private void saveBinaryData(MultipartFile file, Launch launch, Log savedLog) {
+    final AttachmentMetaInfo.AttachmentMetaInfoBuilder metaInfoBuilder =
+        AttachmentMetaInfo.builder().withProjectId(launch.getProjectId())
+            .withLaunchId(launch.getId()).withLaunchUuid(launch.getUuid())
+            .withLogId(savedLog.getId())
+            .withFileName(file.getOriginalFilename())
+            .withLogUuid(savedLog.getUuid())
+            .withCreationDate(LocalDateTime.now(ZoneOffset.UTC));
+    ofNullable(savedLog.getTestItem()).map(TestItem::getItemId)
+        .ifPresent(metaInfoBuilder::withItemId);
+
+    attachmentBinaryDataService.saveFileAndAttachToLog(file, metaInfoBuilder.build());
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/log/impl/DeleteLogHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/log/impl/DeleteLogHandlerImpl.java
index ca5954a3bd..a305082dd3 100644
--- a/src/main/java/com/epam/ta/reportportal/core/log/impl/DeleteLogHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/log/impl/DeleteLogHandlerImpl.java
@@ -16,11 +16,25 @@
 
 package com.epam.ta.reportportal.core.log.impl;
 
+import static com.epam.ta.reportportal.commons.Preconditions.statusIn;
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import static com.epam.ta.reportportal.commons.Predicates.not;
+import static com.epam.ta.reportportal.commons.Predicates.notNull;
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
+import static com.epam.ta.reportportal.ws.model.ErrorType.ACCESS_DENIED;
+import static com.epam.ta.reportportal.ws.model.ErrorType.FORBIDDEN_OPERATION;
+import static com.epam.ta.reportportal.ws.model.ErrorType.LAUNCH_IS_NOT_FINISHED;
+import static com.epam.ta.reportportal.ws.model.ErrorType.PROJECT_NOT_FOUND;
+import static com.epam.ta.reportportal.ws.model.ErrorType.TEST_ITEM_IS_NOT_FINISHED;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.core.analyzer.auto.LogIndexer;
 import com.epam.ta.reportportal.core.item.TestItemService;
 import com.epam.ta.reportportal.core.log.DeleteLogHandler;
+import com.epam.ta.reportportal.core.log.LogService;
 import com.epam.ta.reportportal.dao.AttachmentRepository;
 import com.epam.ta.reportportal.dao.LogRepository;
 import com.epam.ta.reportportal.dao.ProjectRepository;
@@ -33,19 +47,11 @@
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
-import org.apache.commons.lang3.BooleanUtils;
-import org.springframework.stereotype.Service;
-
 import java.util.Collections;
 import java.util.Objects;
 import java.util.Optional;
-
-import static com.epam.ta.reportportal.commons.Preconditions.statusIn;
-import static com.epam.ta.reportportal.commons.Predicates.*;
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
-import static com.epam.ta.reportportal.ws.model.ErrorType.*;
-import static java.util.Optional.ofNullable;
+import org.apache.commons.lang3.BooleanUtils;
+import org.springframework.stereotype.Service;
 
 /**
  * Delete Logs handler. Basic implementation of
@@ -57,80 +63,99 @@
 @Service
 public class DeleteLogHandlerImpl implements DeleteLogHandler {
 
-	private final LogRepository logRepository;
-
-	private final AttachmentRepository attachmentRepository;
-
-	private final ProjectRepository projectRepository;
-
-	private final TestItemService testItemService;
-
-	private final LogIndexer logIndexer;
-
-	public DeleteLogHandlerImpl(LogRepository logRepository, ProjectRepository projectRepository, TestItemService testItemService,
-			LogIndexer logIndexer, AttachmentRepository attachmentRepository) {
-		this.logRepository = logRepository;
-		this.projectRepository = projectRepository;
-		this.testItemService = testItemService;
-		this.logIndexer = logIndexer;
-		this.attachmentRepository = attachmentRepository;
-	}
-
-	@Override
-	public OperationCompletionRS deleteLog(Long logId, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user) {
-		BusinessRule.expect(projectRepository.existsById(projectDetails.getProjectId()), BooleanUtils::isTrue)
-				.verify(PROJECT_NOT_FOUND, projectDetails.getProjectId());
-
-		Log log = validate(logId, user, projectDetails);
-		try {
-			logRepository.delete(log);
-			ofNullable(log.getAttachment()).ifPresent(attachment -> attachmentRepository.moveForDeletion(attachment.getId()));
-		} catch (Exception exc) {
-			throw new ReportPortalException("Error while Log instance deleting.", exc);
-		}
-
-		logIndexer.cleanIndex(projectDetails.getProjectId(), Collections.singletonList(logId));
-		return new OperationCompletionRS(formattedSupplier("Log with ID = '{}' successfully deleted.", logId).toString());
-	}
-
-	/**
-	 * Validate specified log against parent objects and project
-	 *
-	 * @param logId          - validated log ID value
-	 * @param projectDetails Project details
-	 * @return Log
-	 */
-	private Log validate(Long logId, ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails) {
-
-		Log log = logRepository.findById(logId).orElseThrow(() -> new ReportPortalException(ErrorType.LOG_NOT_FOUND, logId));
-
-		Optional<TestItem> itemOptional = ofNullable(log.getTestItem());
-		Launch launch = ofNullable(log.getTestItem()).map(testItemService::getEffectiveLaunch).orElseGet(log::getLaunch);
-
-		//TODO check if statistics is right in item results
-		if (itemOptional.isPresent()) {
-			expect(itemOptional.get().getItemResults().getStatistics(), notNull()).verify(TEST_ITEM_IS_NOT_FINISHED, formattedSupplier(
-					"Unable to delete log '{}' when test item '{}' in progress state",
-					log.getId(),
-					itemOptional.get().getItemId()
-			));
-		} else {
-			expect(launch.getStatus(), not(statusIn(StatusEnum.IN_PROGRESS))).verify(LAUNCH_IS_NOT_FINISHED,
-					formattedSupplier("Unable to delete log '{}' when launch '{}' in progress state", log.getId(), launch.getId())
-			);
-		}
-
-		expect(launch.getProjectId(), equalTo(projectDetails.getProjectId())).verify(FORBIDDEN_OPERATION,
-				formattedSupplier("Log '{}' not under specified '{}' project", logId, projectDetails.getProjectId())
-		);
-
-		if (user.getUserRole() != UserRole.ADMINISTRATOR && !Objects.equals(user.getUserId(), launch.getUserId())) {
-			/*
-			 * Only PROJECT_MANAGER roles could delete logs
-			 */
-			expect(projectDetails.getProjectRole(), equalTo(ProjectRole.PROJECT_MANAGER)).verify(ACCESS_DENIED);
-		}
-
-		return log;
-	}
+  private final LogRepository logRepository;
+
+  private final AttachmentRepository attachmentRepository;
+
+  private final ProjectRepository projectRepository;
+
+  private final TestItemService testItemService;
+
+  private final LogIndexer logIndexer;
+
+  private final LogService logService;
+
+  public DeleteLogHandlerImpl(LogRepository logRepository, ProjectRepository projectRepository,
+      TestItemService testItemService,
+      LogIndexer logIndexer, AttachmentRepository attachmentRepository, LogService logService) {
+    this.logRepository = logRepository;
+    this.projectRepository = projectRepository;
+    this.testItemService = testItemService;
+    this.logIndexer = logIndexer;
+    this.attachmentRepository = attachmentRepository;
+    this.logService = logService;
+  }
+
+  @Override
+  public OperationCompletionRS deleteLog(Long logId, ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user) {
+    BusinessRule.expect(projectRepository.existsById(projectDetails.getProjectId()),
+            BooleanUtils::isTrue)
+        .verify(PROJECT_NOT_FOUND, projectDetails.getProjectId());
+
+    Log log = validate(logId, user, projectDetails);
+    try {
+      logService.deleteLogMessage(projectDetails.getProjectId(), log.getId());
+      logRepository.delete(log);
+      ofNullable(log.getAttachment()).ifPresent(
+          attachment -> attachmentRepository.moveForDeletion(attachment.getId()));
+    } catch (Exception exc) {
+      throw new ReportPortalException("Error while Log instance deleting.", exc);
+    }
+
+    logIndexer.cleanIndex(projectDetails.getProjectId(), Collections.singletonList(logId));
+    return new OperationCompletionRS(
+        formattedSupplier("Log with ID = '{}' successfully deleted.", logId).toString());
+  }
+
+  /**
+   * Validate specified log against parent objects and project
+   *
+   * @param logId          - validated log ID value
+   * @param projectDetails Project details
+   * @return Log
+   */
+  private Log validate(Long logId, ReportPortalUser user,
+      ReportPortalUser.ProjectDetails projectDetails) {
+
+    Log log = logRepository.findById(logId)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.LOG_NOT_FOUND, logId));
+
+    Optional<TestItem> itemOptional = ofNullable(log.getTestItem());
+    Launch launch = ofNullable(log.getTestItem()).map(testItemService::getEffectiveLaunch)
+        .orElseGet(log::getLaunch);
+
+    //TODO check if statistics is right in item results
+    if (itemOptional.isPresent()) {
+      expect(itemOptional.get().getItemResults().getStatistics(), notNull()).verify(
+          TEST_ITEM_IS_NOT_FINISHED, formattedSupplier(
+              "Unable to delete log '{}' when test item '{}' in progress state",
+              log.getId(),
+              itemOptional.get().getItemId()
+          ));
+    } else {
+      expect(launch.getStatus(), not(statusIn(StatusEnum.IN_PROGRESS))).verify(
+          LAUNCH_IS_NOT_FINISHED,
+          formattedSupplier("Unable to delete log '{}' when launch '{}' in progress state",
+              log.getId(), launch.getId())
+      );
+    }
+
+    expect(launch.getProjectId(), equalTo(projectDetails.getProjectId())).verify(
+        FORBIDDEN_OPERATION,
+        formattedSupplier("Log '{}' not under specified '{}' project", logId,
+            projectDetails.getProjectId())
+    );
+
+    if (user.getUserRole() != UserRole.ADMINISTRATOR && !Objects.equals(user.getUserId(),
+        launch.getUserId())) {
+      /*
+       * Only PROJECT_MANAGER roles could delete logs
+       */
+      expect(projectDetails.getProjectRole(), equalTo(ProjectRole.PROJECT_MANAGER)).verify(
+          ACCESS_DENIED);
+    }
+
+    return log;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/log/impl/GetLogHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/log/impl/GetLogHandlerImpl.java
index ce3a1001fc..c83b40440a 100644
--- a/src/main/java/com/epam/ta/reportportal/core/log/impl/GetLogHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/log/impl/GetLogHandlerImpl.java
@@ -16,10 +16,30 @@
 
 package com.epam.ta.reportportal.core.log.impl;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import static com.epam.ta.reportportal.commons.querygen.constant.LogCriteriaConstant.CRITERIA_ITEM_LAUNCH_ID;
+import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_PATH;
+import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_RETRY_PARENT_LAUNCH_ID;
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
+import static com.epam.ta.reportportal.ws.model.ErrorType.FORBIDDEN_OPERATION;
+import static com.epam.ta.reportportal.ws.model.ErrorType.LOG_NOT_FOUND;
+import static java.util.Optional.ofNullable;
+import static java.util.stream.Collectors.groupingBy;
+import static java.util.stream.Collectors.toMap;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
-import com.epam.ta.reportportal.commons.querygen.*;
+import com.epam.ta.reportportal.commons.querygen.CompositeFilterCondition;
+import com.epam.ta.reportportal.commons.querygen.Condition;
+import com.epam.ta.reportportal.commons.querygen.ConvertibleCondition;
+import com.epam.ta.reportportal.commons.querygen.Filter;
+import com.epam.ta.reportportal.commons.querygen.FilterCondition;
+import com.epam.ta.reportportal.commons.querygen.FilterTarget;
+import com.epam.ta.reportportal.commons.querygen.ProjectFilter;
+import com.epam.ta.reportportal.commons.querygen.Queryable;
 import com.epam.ta.reportportal.core.item.TestItemService;
 import com.epam.ta.reportportal.core.log.GetLogHandler;
+import com.epam.ta.reportportal.core.log.LogService;
 import com.epam.ta.reportportal.dao.LogRepository;
 import com.epam.ta.reportportal.dao.TestItemRepository;
 import com.epam.ta.reportportal.dao.constant.LogRepositoryConstants;
@@ -31,6 +51,7 @@
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.entity.log.Log;
+import com.epam.ta.reportportal.entity.log.LogFull;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.converter.PagedResourcesAssembler;
 import com.epam.ta.reportportal.ws.converter.converters.LogConverter;
@@ -39,6 +60,13 @@
 import com.epam.ta.reportportal.ws.model.log.GetLogsUnderRq;
 import com.epam.ta.reportportal.ws.model.log.LogResource;
 import com.google.common.collect.Lists;
+import java.util.AbstractMap;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 import org.apache.commons.lang3.BooleanUtils;
 import org.jooq.Operator;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -49,22 +77,6 @@
 import org.springframework.lang.Nullable;
 import org.springframework.stereotype.Service;
 
-import java.util.*;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-import static com.epam.ta.reportportal.commons.querygen.constant.LogCriteriaConstant.CRITERIA_ITEM_LAUNCH_ID;
-import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_PATH;
-import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_RETRY_PARENT_LAUNCH_ID;
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
-import static com.epam.ta.reportportal.ws.model.ErrorType.FORBIDDEN_OPERATION;
-import static com.epam.ta.reportportal.ws.model.ErrorType.LOG_NOT_FOUND;
-import static java.util.Optional.ofNullable;
-import static java.util.stream.Collectors.groupingBy;
-import static java.util.stream.Collectors.toMap;
-
 /**
  * Implementation of GET log operations
  *
@@ -74,310 +86,354 @@
 @Service
 public class GetLogHandlerImpl implements GetLogHandler {
 
-	public static final String EXCLUDE_PASSED_LOGS = "excludePassedLogs";
-	public static final String EXCLUDE_EMPTY_STEPS = "excludeEmptySteps";
-	public static final String EXCLUDE_LOG_CONTENT = "excludeLogContent";
-
-	private static final int NESTED_STEP_MAX_PAGE_SIZE = 300;
-
-	private static final int LOG_UNDER_ITEM_BATCH_SIZE = 5;
-
-	private final LogRepository logRepository;
-
-	private final TestItemRepository testItemRepository;
-
-	private final TestItemService testItemService;
-
-	@Autowired
-	public GetLogHandlerImpl(LogRepository logRepository, TestItemRepository testItemRepository, TestItemService testItemService) {
-		this.logRepository = logRepository;
-		this.testItemRepository = testItemRepository;
-		this.testItemService = testItemService;
-	}
-
-	@Override
-	public Iterable<LogResource> getLogs(@Nullable String path, ReportPortalUser.ProjectDetails projectDetails, Filter filterable,
-			Pageable pageable) {
-		ofNullable(path).ifPresent(p -> updateFilter(filterable, p));
-		Page<Log> logPage = logRepository.findByFilter(ProjectFilter.of(filterable, projectDetails.getProjectId()), pageable);
-		return PagedResourcesAssembler.pageConverter(LogConverter.TO_RESOURCE).apply(logPage);
-	}
-
-	@Override
-	public Map<Long, List<LogResource>> getLogs(GetLogsUnderRq logsUnderRq, ReportPortalUser.ProjectDetails projectDetails) {
-
-		final LogLevel logLevel = LogLevel.toLevel(logsUnderRq.getLogLevel())
-				.orElseThrow(() -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR, logsUnderRq.getLogLevel()));
-
-		return testItemRepository.findAllById(logsUnderRq.getItemIds()).stream().collect(toMap(TestItem::getItemId, item -> {
-			final Launch launch = testItemService.getEffectiveLaunch(item);
-			validate(launch, projectDetails);
-			return logRepository.findLatestUnderTestItemByLaunchIdAndTestItemIdsAndLogLevelGte(launch.getId(),
-					item.getItemId(),
-					logLevel.toInt(),
-					LOG_UNDER_ITEM_BATCH_SIZE
-			).stream().map(LogConverter.TO_RESOURCE).collect(Collectors.toList());
-		}));
-	}
-
-	@Override
-	public long getPageNumber(Long logId, ReportPortalUser.ProjectDetails projectDetails, Filter filterable, Pageable pageable) {
-		return logRepository.getPageNumber(logId, filterable, pageable);
-	}
-
-	@Override
-	public LogResource getLog(String logId, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user) {
-		Log log;
-		try {
-			log = findById(Long.parseLong(logId));
-		} catch (NumberFormatException e) {
-			log = findByUuid(logId);
-		}
-		validate(log, projectDetails);
-		return LogConverter.TO_RESOURCE.apply(log);
-	}
-
-	@Override
-	public Iterable<?> getNestedItems(Long parentId, ReportPortalUser.ProjectDetails projectDetails, Map<String, String> params,
-			Queryable queryable, Pageable pageable) {
-
-		TestItem parentItem = testItemRepository.findById(parentId)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, parentId));
-		Launch launch = testItemService.getEffectiveLaunch(parentItem);
-		validate(launch, projectDetails);
-
-		Boolean excludeEmptySteps = ofNullable(params.get(EXCLUDE_EMPTY_STEPS)).map(BooleanUtils::toBoolean).orElse(false);
-		Boolean excludePassedLogs = ofNullable(params.get(EXCLUDE_PASSED_LOGS)).map(BooleanUtils::toBoolean).orElse(false);
-
-		Page<NestedItem> nestedItems = logRepository.findNestedItems(parentId,
-				excludeEmptySteps,
-				isLogsExclusionRequired(parentItem, excludePassedLogs),
-				queryable,
-				pageable
-		);
-
-		List<NestedItem> content = nestedItems.getContent();
-
-		Map<String, List<NestedItem>> result = content.stream().collect(groupingBy(NestedItem::getType));
-
-		Map<Long, Log> logMap = ofNullable(result.get(LogRepositoryConstants.LOG)).map(logs -> logRepository.findAllById(logs.stream()
-				.map(NestedItem::getId)
-				.collect(Collectors.toSet())).stream().collect(toMap(Log::getId, l -> l))).orElseGet(Collections::emptyMap);
-
-		queryable.getFilterConditions().add(getLaunchCondition(launch.getId()));
-		queryable.getFilterConditions().add(getParentPathCondition(parentItem));
-		Map<Long, NestedStep> nestedStepMap = ofNullable(result.get(LogRepositoryConstants.ITEM)).map(testItems -> testItemRepository.findAllNestedStepsByIds(
-				testItems.stream().map(NestedItem::getId).collect(Collectors.toSet()),
-				queryable,
-				excludePassedLogs
-		).stream().collect(toMap(NestedStep::getId, i -> i))).orElseGet(Collections::emptyMap);
-
-		List<Object> resources = Lists.newArrayListWithExpectedSize(content.size());
-		content.forEach(nestedItem -> {
-			if (LogRepositoryConstants.LOG.equals(nestedItem.getType())) {
-				ofNullable(logMap.get(nestedItem.getId())).map(LogConverter.TO_RESOURCE).ifPresent(resources::add);
-			} else if (LogRepositoryConstants.ITEM.equals(nestedItem.getType())) {
-				ofNullable(nestedStepMap.get(nestedItem.getId())).map(TestItemConverter.TO_NESTED_STEP_RESOURCE).ifPresent(resources::add);
-			}
-		});
-
-		return PagedResourcesAssembler.pageConverter()
-				.apply(PageableExecutionUtils.getPage(resources, nestedItems.getPageable(), nestedItems::getTotalElements));
-	}
-
-	@Override
-	public List<PagedLogResource> getLogsWithLocation(Long parentId, ReportPortalUser.ProjectDetails projectDetails,
-			Map<String, String> params, Queryable queryable, Pageable pageable) {
-
-		TestItem parentItem = testItemRepository.findById(parentId)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, parentId));
-		Launch launch = testItemService.getEffectiveLaunch(parentItem);
-		validate(launch, projectDetails);
-
-		Boolean excludeEmptySteps = ofNullable(params.get(EXCLUDE_EMPTY_STEPS)).map(BooleanUtils::toBoolean).orElse(false);
-		Boolean excludePassedLogs = ofNullable(params.get(EXCLUDE_PASSED_LOGS)).map(BooleanUtils::toBoolean).orElse(false);
-		Boolean excludeLogContent = ofNullable(params.get(EXCLUDE_LOG_CONTENT)).map(BooleanUtils::toBoolean).orElse(false);
-
-		List<PagedLogResource> loadedLogs = new LinkedList<>();
-		loadInnerLogs(parentId, loadedLogs, Collections.emptyList(), excludeEmptySteps, excludePassedLogs, queryable, pageable);
-
-		if (!excludeLogContent) {
-			Map<Long, Log> logMap = logRepository.findAllById(loadedLogs.stream()
-					.map(PagedLogResource::getId)
-					.collect(Collectors.toSet())).stream().collect(toMap(Log::getId, l -> l));
-			loadedLogs.forEach(resource -> {
-				final Log model = logMap.get(resource.getId());
-				LogConverter.FILL_WITH_LOG_CONTENT.apply(model, resource);
-			});
-		}
-		return loadedLogs;
-	}
-
-	private void loadInnerLogs(Long parentId, List<PagedLogResource> results, List<Map.Entry<Long, Integer>> pagesLocation,
-			boolean excludeEmptySteps, boolean excludePassedLogs, Queryable queryable, Pageable pageable) {
-
-		TestItem parentItem = testItemRepository.findById(parentId)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, parentId));
-
-		if (isLogsExclusionRequired(parentItem, excludePassedLogs)) {
-			return;
-		}
-
-		final List<NestedItemPage> nestedItems = logRepository.findNestedItemsWithPage(
-				parentId,
-				excludeEmptySteps,
-				isLogsExclusionRequired(parentItem, excludePassedLogs),
-				queryable,
-				pageable
-		);
-		nestedItems.stream()
-				.filter(nestedItem -> nestedItem.getType().equals(LogRepositoryConstants.ITEM)
-						|| nestedItem.getLogLevel() >= LogLevel.ERROR_INT)
-				.forEach(nestedItem -> {
-					List<Map.Entry<Long, Integer>> copy = new LinkedList<>(pagesLocation);
-					copy.add(new AbstractMap.SimpleEntry<>(nestedItem.getId(), nestedItem.getPageNumber()));
-					if (nestedItem.getType().equals(LogRepositoryConstants.ITEM)) {
-						loadInnerLogs(nestedItem.getId(),
-								results,
-								copy,
-								excludeEmptySteps,
-								excludePassedLogs,
-								queryable,
-								PageRequest.of(1, NESTED_STEP_MAX_PAGE_SIZE, pageable.getSort())
-						);
-					} else {
-						PagedLogResource pagedLogResource = new PagedLogResource();
-						pagedLogResource.setId(nestedItem.getId());
-						pagedLogResource.setPagesLocation(copy);
-						results.add(pagedLogResource);
-					}
-				});
-	}
-
-	/**
-	 * Validate log item on existence, availability under specified project,
-	 * etc.
-	 *
-	 * @param log            - log item
-	 * @param projectDetails Project details
-	 */
-	private void validate(Log log, ReportPortalUser.ProjectDetails projectDetails) {
-		Long launchProjectId = ofNullable(log.getTestItem()).map(it -> testItemService.getEffectiveLaunch(it).getProjectId())
-				.orElseGet(() -> log.getLaunch().getProjectId());
-
-		expect(launchProjectId, equalTo(projectDetails.getProjectId())).verify(FORBIDDEN_OPERATION,
-				formattedSupplier("Log '{}' is not under '{}' project", log.getId(), projectDetails.getProjectName())
-		);
-	}
-
-	private void validate(Launch launch, ReportPortalUser.ProjectDetails projectDetails) {
-		expect(launch.getProjectId(), equalTo(projectDetails.getProjectId())).verify(FORBIDDEN_OPERATION,
-				formattedSupplier("Launch '{}' is not under '{}' project", launch.getId(), projectDetails.getProjectName())
-		);
-	}
-
-	/**
-	 * Find log item by id
-	 *
-	 * @param logId - log ID
-	 * @return - log item
-	 */
-	private Log findById(Long logId) {
-		return logRepository.findById(logId).orElseThrow(() -> new ReportPortalException(LOG_NOT_FOUND, logId));
-	}
-
-	/**
-	 * Find log item by uuid
-	 *
-	 * @param logId - log UUID
-	 * @return - log item
-	 */
-	private Log findByUuid(String logId) {
-		return logRepository.findByUuid(logId).orElseThrow(() -> new ReportPortalException(LOG_NOT_FOUND, logId));
-	}
-
-	private FilterCondition getLaunchCondition(Long launchId) {
-		return FilterCondition.builder().eq(CRITERIA_ITEM_LAUNCH_ID, String.valueOf(launchId)).build();
-	}
-
-	/**
-	 * Updates 'filterable' with {@link TestItem#getLaunchId()} condition if {@link TestItem#getRetryOf()} is NULL
-	 * otherwise updates 'filterable' with 'launchId' of the 'retry' parent
-	 *
-	 * @param filterable {@link Filter} with {@link FilterTarget#getClazz()} of {@link Log}
-	 * @param path       {@link TestItem#getPath()} under which {@link Log} entities should be searched
-	 */
-	private void updateFilter(Filter filterable, String path) {
-		TestItem testItem = testItemRepository.findByPath(path)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, path));
-
-		updatePathCondition(testItem, filterable);
-
-		Launch launch = testItemService.getEffectiveLaunch(testItem);
-
-		FilterCondition.ConditionBuilder itemLaunchIdConditionBuilder = FilterCondition.builder()
-				.eq(CRITERIA_ITEM_LAUNCH_ID, String.valueOf(launch.getId()));
-
-		ConvertibleCondition launchIdCondition = ofNullable(testItem.getRetryOf()).map(retryOf -> (ConvertibleCondition) new CompositeFilterCondition(
-				Lists.newArrayList(itemLaunchIdConditionBuilder.withOperator(Operator.OR).build(),
-						FilterCondition.builder()
-								.eq(CRITERIA_RETRY_PARENT_LAUNCH_ID, String.valueOf(launch.getId()))
-								.withOperator(Operator.OR)
-								.build()
-				))).orElseGet(itemLaunchIdConditionBuilder::build);
-
-		filterable.getFilterConditions().add(launchIdCondition);
-
-	}
-
-	/**
-	 * Updates 'path' condition of the {@link TestItem} whose {@link Log} entities should be searched.
-	 * Required when there are 'Nested Steps' under the {@link TestItem} that is a 'retry'
-	 *
-	 * @param testItem   {@link TestItem} containing logs
-	 * @param filterable {@link Filter} with {@link FilterTarget#getClazz()} of {@link Log}
-	 */
-	private void updatePathCondition(TestItem testItem, Filter filterable) {
-		List<ConvertibleCondition> resultConditions = filterable.getFilterConditions()
-				.stream()
-				.flatMap(c -> c.getAllConditions().stream())
-				.filter(c -> BooleanUtils.isFalse(CRITERIA_PATH.equals(c.getSearchCriteria()) && Condition.UNDER.equals(c.getCondition())))
-				.collect(Collectors.toList());
-		filterable.getFilterConditions().clear();
-
-		FilterCondition parentPathCondition = getParentPathCondition(testItem);
-		resultConditions.add(ofNullable(testItem.getRetryOf()).map(retryParent -> (ConvertibleCondition) new CompositeFilterCondition(Lists.newArrayList(
-				parentPathCondition,
-				FilterCondition.builder()
-						.withOperator(Operator.OR)
-						.withCondition(Condition.UNDER)
-						.withSearchCriteria(CRITERIA_PATH)
-						.withValue(String.valueOf(testItem.getPath()))
-						.build()
-		))).orElse(parentPathCondition));
-
-		filterable.getFilterConditions().addAll(resultConditions);
-	}
-
-	private FilterCondition getParentPathCondition(TestItem parent) {
-		String pathValue = ofNullable(parent.getRetryOf()).flatMap(retryParentId -> ofNullable(parent.getParentId()).flatMap(
-				testItemRepository::findById).map(retryParent -> retryParent.getPath() + "." + parent.getItemId()))
-				.orElse(parent.getPath());
-		return FilterCondition.builder().withCondition(Condition.UNDER).withSearchCriteria(CRITERIA_PATH).withValue(pathValue).build();
-	}
-
-	/**
-	 * Method to determine whether logs of the {@link TestItem} with {@link StatusEnum#PASSED}
-	 * should be retrieved with nested steps or should be excluded from the select query
-	 *
-	 * @param parent            {@link Log#getTestItem()}
-	 * @param excludePassedLogs if 'true' logs of the passed items should be excluded
-	 * @return 'true' if logs should be excluded from the select query, else 'false'
-	 */
-	private boolean isLogsExclusionRequired(TestItem parent, boolean excludePassedLogs) {
-		if (excludePassedLogs) {
-			return Stream.of(StatusEnum.values()).filter(StatusEnum::isPositive).anyMatch(s -> s == parent.getItemResults().getStatus());
-		}
-		return false;
-	}
+  public static final String EXCLUDE_PASSED_LOGS = "excludePassedLogs";
+  public static final String EXCLUDE_EMPTY_STEPS = "excludeEmptySteps";
+  public static final String EXCLUDE_LOG_CONTENT = "excludeLogContent";
+
+  private static final int NESTED_STEP_MAX_PAGE_SIZE = 300;
+
+  private static final int LOG_UNDER_ITEM_BATCH_SIZE = 5;
+
+  private final LogRepository logRepository;
+
+  private final LogService logService;
+
+  private final TestItemRepository testItemRepository;
+
+  private final TestItemService testItemService;
+
+  @Autowired
+  public GetLogHandlerImpl(LogRepository logRepository, LogService logService,
+      TestItemRepository testItemRepository, TestItemService testItemService) {
+    this.logRepository = logRepository;
+    this.logService = logService;
+    this.testItemRepository = testItemRepository;
+    this.testItemService = testItemService;
+  }
+
+  @Override
+  public Iterable<LogResource> getLogs(@Nullable String path,
+      ReportPortalUser.ProjectDetails projectDetails, Filter filterable,
+      Pageable pageable) {
+    ofNullable(path).ifPresent(p -> updateFilter(filterable, p));
+    Page<LogFull> logFullPage = logService.findByFilter(
+        ProjectFilter.of(filterable, projectDetails.getProjectId()), pageable);
+    return PagedResourcesAssembler.pageConverter(LogConverter.TO_RESOURCE).apply(logFullPage);
+  }
+
+  @Override
+  public Map<Long, List<LogResource>> getLogs(GetLogsUnderRq logsUnderRq,
+      ReportPortalUser.ProjectDetails projectDetails) {
+
+    final LogLevel logLevel = LogLevel.toLevel(logsUnderRq.getLogLevel())
+        .orElseThrow(() -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR,
+            logsUnderRq.getLogLevel()));
+
+    return testItemRepository.findAllById(logsUnderRq.getItemIds()).stream()
+        .collect(toMap(TestItem::getItemId, item -> {
+          final Launch launch = testItemService.getEffectiveLaunch(item);
+          validate(launch, projectDetails);
+          return logService.findLatestUnderTestItemByLaunchIdAndTestItemIdsAndLogLevelGte(
+              launch.getId(),
+              item.getItemId(),
+              logLevel.toInt(),
+              LOG_UNDER_ITEM_BATCH_SIZE
+          ).stream().map(LogConverter.TO_RESOURCE).collect(Collectors.toList());
+        }));
+  }
+
+  @Override
+  public long getPageNumber(Long logId, ReportPortalUser.ProjectDetails projectDetails,
+      Filter filterable, Pageable pageable) {
+    return logRepository.getPageNumber(logId, filterable, pageable);
+  }
+
+  @Override
+  public LogResource getLog(String logId, ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user) {
+    LogFull logFull;
+    try {
+      logFull = findById(Long.parseLong(logId));
+    } catch (NumberFormatException e) {
+      logFull = findByUuid(logId);
+    }
+    validate(logFull, projectDetails);
+    return LogConverter.TO_RESOURCE.apply(logFull);
+  }
+
+  @Override
+  public Iterable<?> getNestedItems(Long parentId, ReportPortalUser.ProjectDetails projectDetails,
+      Map<String, String> params,
+      Queryable queryable, Pageable pageable) {
+
+    TestItem parentItem = testItemRepository.findById(parentId)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, parentId));
+    Launch launch = testItemService.getEffectiveLaunch(parentItem);
+    validate(launch, projectDetails);
+
+    Boolean excludeEmptySteps = ofNullable(params.get(EXCLUDE_EMPTY_STEPS)).map(
+        BooleanUtils::toBoolean).orElse(false);
+    Boolean excludePassedLogs = ofNullable(params.get(EXCLUDE_PASSED_LOGS)).map(
+        BooleanUtils::toBoolean).orElse(false);
+
+    Page<NestedItem> nestedItems = logRepository.findNestedItems(parentId,
+        excludeEmptySteps,
+        isLogsExclusionRequired(parentItem, excludePassedLogs),
+        queryable,
+        pageable
+    );
+
+    List<NestedItem> content = nestedItems.getContent();
+
+    Map<String, List<NestedItem>> result = content.stream()
+        .collect(groupingBy(NestedItem::getType));
+
+    Map<Long, LogFull> logMap = ofNullable(result.get(LogRepositoryConstants.LOG)).map(
+            logs -> logService.findAllById(logs.stream()
+                .map(NestedItem::getId)
+                .collect(Collectors.toSet())).stream().collect(toMap(LogFull::getId, l -> l)))
+        .orElseGet(Collections::emptyMap);
+
+    queryable.getFilterConditions().add(getLaunchCondition(launch.getId()));
+    queryable.getFilterConditions().add(getParentPathCondition(parentItem));
+    Map<Long, NestedStep> nestedStepMap = ofNullable(result.get(LogRepositoryConstants.ITEM)).map(
+        testItems -> testItemRepository.findAllNestedStepsByIds(
+            testItems.stream().map(NestedItem::getId).collect(Collectors.toSet()),
+            queryable,
+            excludePassedLogs
+        ).stream().collect(toMap(NestedStep::getId, i -> i))).orElseGet(Collections::emptyMap);
+
+    List<Object> resources = Lists.newArrayListWithExpectedSize(content.size());
+    content.forEach(nestedItem -> {
+      if (LogRepositoryConstants.LOG.equals(nestedItem.getType())) {
+        ofNullable(logMap.get(nestedItem.getId())).map(LogConverter.TO_RESOURCE)
+            .ifPresent(resources::add);
+      } else if (LogRepositoryConstants.ITEM.equals(nestedItem.getType())) {
+        ofNullable(nestedStepMap.get(nestedItem.getId())).map(
+            TestItemConverter.TO_NESTED_STEP_RESOURCE).ifPresent(resources::add);
+      }
+    });
+
+    return PagedResourcesAssembler.pageConverter()
+        .apply(PageableExecutionUtils.getPage(resources, nestedItems.getPageable(),
+            nestedItems::getTotalElements));
+  }
+
+  @Override
+  public List<PagedLogResource> getLogsWithLocation(Long parentId,
+      ReportPortalUser.ProjectDetails projectDetails,
+      Map<String, String> params, Queryable queryable, Pageable pageable) {
+
+    TestItem parentItem = testItemRepository.findById(parentId)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, parentId));
+    Launch launch = testItemService.getEffectiveLaunch(parentItem);
+    validate(launch, projectDetails);
+
+    Boolean excludeEmptySteps = ofNullable(params.get(EXCLUDE_EMPTY_STEPS)).map(
+        BooleanUtils::toBoolean).orElse(false);
+    Boolean excludePassedLogs = ofNullable(params.get(EXCLUDE_PASSED_LOGS)).map(
+        BooleanUtils::toBoolean).orElse(false);
+    Boolean excludeLogContent = ofNullable(params.get(EXCLUDE_LOG_CONTENT)).map(
+        BooleanUtils::toBoolean).orElse(false);
+
+    List<PagedLogResource> loadedLogs = new LinkedList<>();
+    loadInnerLogs(parentId, loadedLogs, Collections.emptyList(), excludeEmptySteps,
+        excludePassedLogs, queryable, pageable);
+
+    if (!excludeLogContent) {
+      Map<Long, LogFull> logMap = logService.findAllById(loadedLogs.stream()
+          .map(PagedLogResource::getId)
+          .collect(Collectors.toSet())).stream().collect(toMap(LogFull::getId, l -> l));
+      loadedLogs.forEach(resource -> {
+        final LogFull model = logMap.get(resource.getId());
+        LogConverter.FILL_WITH_LOG_CONTENT.apply(model, resource);
+      });
+    }
+    return loadedLogs;
+  }
+
+  private void loadInnerLogs(Long parentId, List<PagedLogResource> results,
+      List<Map.Entry<Long, Integer>> pagesLocation,
+      boolean excludeEmptySteps, boolean excludePassedLogs, Queryable queryable,
+      Pageable pageable) {
+
+    TestItem parentItem = testItemRepository.findById(parentId)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, parentId));
+
+    if (isLogsExclusionRequired(parentItem, excludePassedLogs)) {
+      return;
+    }
+
+    final List<NestedItemPage> nestedItems = logRepository.findNestedItemsWithPage(
+        parentId,
+        excludeEmptySteps,
+        isLogsExclusionRequired(parentItem, excludePassedLogs),
+        queryable,
+        pageable
+    );
+    nestedItems.stream()
+        .filter(nestedItem -> nestedItem.getType().equals(LogRepositoryConstants.ITEM)
+            || nestedItem.getLogLevel() >= LogLevel.ERROR_INT)
+        .forEach(nestedItem -> {
+          List<Map.Entry<Long, Integer>> copy = new LinkedList<>(pagesLocation);
+          copy.add(new AbstractMap.SimpleEntry<>(nestedItem.getId(), nestedItem.getPageNumber()));
+          if (nestedItem.getType().equals(LogRepositoryConstants.ITEM)) {
+            loadInnerLogs(nestedItem.getId(),
+                results,
+                copy,
+                excludeEmptySteps,
+                excludePassedLogs,
+                queryable,
+                PageRequest.of(1, NESTED_STEP_MAX_PAGE_SIZE, pageable.getSort())
+            );
+          } else {
+            PagedLogResource pagedLogResource = new PagedLogResource();
+            pagedLogResource.setId(nestedItem.getId());
+            pagedLogResource.setPagesLocation(copy);
+            results.add(pagedLogResource);
+          }
+        });
+  }
+
+  /**
+   * Validate log item on existence, availability under specified project, etc.
+   *
+   * @param log            - logFull item
+   * @param projectDetails Project details
+   */
+  private void validate(LogFull log, ReportPortalUser.ProjectDetails projectDetails) {
+    Long launchProjectId = ofNullable(log.getTestItem()).map(
+            it -> testItemService.getEffectiveLaunch(it).getProjectId())
+        .orElseGet(() -> log.getLaunch().getProjectId());
+
+    expect(launchProjectId, equalTo(projectDetails.getProjectId())).verify(FORBIDDEN_OPERATION,
+        formattedSupplier("Log '{}' is not under '{}' project", log.getId(),
+            projectDetails.getProjectName())
+    );
+  }
+
+  private void validate(Launch launch, ReportPortalUser.ProjectDetails projectDetails) {
+    expect(launch.getProjectId(), equalTo(projectDetails.getProjectId())).verify(
+        FORBIDDEN_OPERATION,
+        formattedSupplier("Launch '{}' is not under '{}' project", launch.getId(),
+            projectDetails.getProjectName())
+    );
+  }
+
+  /**
+   * Find logFull item by id
+   *
+   * @param logId - log ID
+   * @return - log item
+   */
+  private LogFull findById(Long logId) {
+    return logService.findById(logId)
+        .orElseThrow(() -> new ReportPortalException(LOG_NOT_FOUND, logId));
+  }
+
+  /**
+   * Find logFull item by uuid
+   *
+   * @param logId - log UUID
+   * @return - log item
+   */
+  private LogFull findByUuid(String logId) {
+    return logService.findByUuid(logId)
+        .orElseThrow(() -> new ReportPortalException(LOG_NOT_FOUND, logId));
+  }
+
+  private FilterCondition getLaunchCondition(Long launchId) {
+    return FilterCondition.builder().eq(CRITERIA_ITEM_LAUNCH_ID, String.valueOf(launchId)).build();
+  }
+
+  /**
+   * Updates 'filterable' with {@link TestItem#getLaunchId()} condition if
+   * {@link TestItem#getRetryOf()} is NULL otherwise updates 'filterable' with 'launchId' of the
+   * 'retry' parent
+   *
+   * @param filterable {@link Filter} with {@link FilterTarget#getClazz()} of {@link Log}
+   * @param path       {@link TestItem#getPath()} under which {@link Log} entities should be
+   *                   searched
+   */
+  private void updateFilter(Filter filterable, String path) {
+    TestItem testItem = testItemRepository.findByPath(path)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, path));
+
+    updatePathCondition(testItem, filterable);
+
+    Launch launch = testItemService.getEffectiveLaunch(testItem);
+
+    FilterCondition.ConditionBuilder itemLaunchIdConditionBuilder = FilterCondition.builder()
+        .eq(CRITERIA_ITEM_LAUNCH_ID, String.valueOf(launch.getId()));
+
+    ConvertibleCondition launchIdCondition = ofNullable(testItem.getRetryOf()).map(
+        retryOf -> (ConvertibleCondition) new CompositeFilterCondition(
+            Lists.newArrayList(itemLaunchIdConditionBuilder.withOperator(Operator.OR).build(),
+                FilterCondition.builder()
+                    .eq(CRITERIA_RETRY_PARENT_LAUNCH_ID, String.valueOf(launch.getId()))
+                    .withOperator(Operator.OR)
+                    .build()
+            ))).orElseGet(itemLaunchIdConditionBuilder::build);
+
+    filterable.getFilterConditions().add(launchIdCondition);
+
+  }
+
+  /**
+   * Updates 'path' condition of the {@link TestItem} whose {@link Log} entities should be searched.
+   * Required when there are 'Nested Steps' under the {@link TestItem} that is a 'retry'
+   *
+   * @param testItem   {@link TestItem} containing logs
+   * @param filterable {@link Filter} with {@link FilterTarget#getClazz()} of {@link Log}
+   */
+  private void updatePathCondition(TestItem testItem, Filter filterable) {
+    List<ConvertibleCondition> resultConditions = filterable.getFilterConditions()
+        .stream()
+        .flatMap(c -> c.getAllConditions().stream())
+        .filter(c -> BooleanUtils.isFalse(
+            CRITERIA_PATH.equals(c.getSearchCriteria()) && Condition.UNDER.equals(
+                c.getCondition())))
+        .collect(Collectors.toList());
+    filterable.getFilterConditions().clear();
+
+    FilterCondition parentPathCondition = getParentPathCondition(testItem);
+    resultConditions.add(ofNullable(testItem.getRetryOf()).map(
+        retryParent -> (ConvertibleCondition) new CompositeFilterCondition(Lists.newArrayList(
+            parentPathCondition,
+            FilterCondition.builder()
+                .withOperator(Operator.OR)
+                .withCondition(Condition.UNDER)
+                .withSearchCriteria(CRITERIA_PATH)
+                .withValue(String.valueOf(testItem.getPath()))
+                .build()
+        ))).orElse(parentPathCondition));
+
+    filterable.getFilterConditions().addAll(resultConditions);
+  }
+
+  private FilterCondition getParentPathCondition(TestItem parent) {
+    String pathValue = ofNullable(parent.getRetryOf()).flatMap(
+            retryParentId -> ofNullable(parent.getParentId()).flatMap(
+                    testItemRepository::findById)
+                .map(retryParent -> retryParent.getPath() + "." + parent.getItemId()))
+        .orElse(parent.getPath());
+    return FilterCondition.builder().withCondition(Condition.UNDER)
+        .withSearchCriteria(CRITERIA_PATH).withValue(pathValue).build();
+  }
+
+  /**
+   * Method to determine whether logs of the {@link TestItem} with {@link StatusEnum#PASSED} should
+   * be retrieved with nested steps or should be excluded from the select query
+   *
+   * @param parent            {@link Log#getTestItem()}
+   * @param excludePassedLogs if 'true' logs of the passed items should be excluded
+   * @return 'true' if logs should be excluded from the select query, else 'false'
+   */
+  private boolean isLogsExclusionRequired(TestItem parent, boolean excludePassedLogs) {
+    if (excludePassedLogs) {
+      return Stream.of(StatusEnum.values()).filter(StatusEnum::isPositive)
+          .anyMatch(s -> s == parent.getItemResults().getStatus());
+    }
+    return false;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/log/impl/PagedLogResource.java b/src/main/java/com/epam/ta/reportportal/core/log/impl/PagedLogResource.java
index 161db1e8a7..24804eb9f8 100644
--- a/src/main/java/com/epam/ta/reportportal/core/log/impl/PagedLogResource.java
+++ b/src/main/java/com/epam/ta/reportportal/core/log/impl/PagedLogResource.java
@@ -1,7 +1,6 @@
 package com.epam.ta.reportportal.core.log.impl;
 
 import com.epam.ta.reportportal.ws.model.log.LogResource;
-
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -11,17 +10,17 @@
  */
 public class PagedLogResource extends LogResource {
 
-	private List<Map.Entry<Long, Integer>> pagesLocation;
+  private List<Map.Entry<Long, Integer>> pagesLocation;
 
-	public PagedLogResource() {
-		pagesLocation = new LinkedList<>();
-	}
+  public PagedLogResource() {
+    pagesLocation = new LinkedList<>();
+  }
 
-	public List<Map.Entry<Long, Integer>> getPagesLocation() {
-		return pagesLocation;
-	}
+  public List<Map.Entry<Long, Integer>> getPagesLocation() {
+    return pagesLocation;
+  }
 
-	public void setPagesLocation(List<Map.Entry<Long, Integer>> pagesLocation) {
-		this.pagesLocation = pagesLocation;
-	}
+  public void setPagesLocation(List<Map.Entry<Long, Integer>> pagesLocation) {
+    this.pagesLocation = pagesLocation;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/log/impl/SaveLogBinaryDataTask.java b/src/main/java/com/epam/ta/reportportal/core/log/impl/SaveLogBinaryDataTask.java
deleted file mode 100644
index d732e2f330..0000000000
--- a/src/main/java/com/epam/ta/reportportal/core/log/impl/SaveLogBinaryDataTask.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 2019 EPAM Systems
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.epam.ta.reportportal.core.log.impl;
-
-import com.epam.ta.reportportal.binary.AttachmentBinaryDataService;
-import com.epam.ta.reportportal.entity.attachment.AttachmentMetaInfo;
-import com.google.common.base.Preconditions;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.multipart.MultipartFile;
-
-/**
- * Save binary data task. Expected to be executed asynchronously. Statefull, so
- * cannot be a singleton bean. Saves binary data, then updates related log entry
- * with saved data id
- * <p>
- * NOTE: run asynchronously in sense of run in Executor. This class is not used with RabbitMQ.
- * It is original implementation for synchronous LogController
- *
- * @author Andrei Varabyeu
- */
-public class SaveLogBinaryDataTask implements Runnable {
-
-	@Autowired
-	private AttachmentBinaryDataService attachmentBinaryDataService;
-
-	/**
-	 * Binary data representation
-	 */
-	private MultipartFile file;
-
-	private AttachmentMetaInfo attachmentMetaInfo;
-
-	@Override
-	public void run() {
-		attachmentBinaryDataService.saveFileAndAttachToLog(file, attachmentMetaInfo);
-	}
-
-	public SaveLogBinaryDataTask withFile(MultipartFile file) {
-		Preconditions.checkNotNull(file, "Binary data shouldn't be null");
-		this.file = file;
-		return this;
-	}
-
-	public SaveLogBinaryDataTask withAttachmentMetaInfo(AttachmentMetaInfo metaInfo) {
-		Preconditions.checkNotNull(metaInfo);
-		this.attachmentMetaInfo = metaInfo;
-		return this;
-	}
-}
diff --git a/src/main/java/com/epam/ta/reportportal/core/log/impl/SaveLogBinaryDataTaskAsync.java b/src/main/java/com/epam/ta/reportportal/core/log/impl/SaveLogBinaryDataTaskAsync.java
index ab83d55340..e7ff9292b2 100644
--- a/src/main/java/com/epam/ta/reportportal/core/log/impl/SaveLogBinaryDataTaskAsync.java
+++ b/src/main/java/com/epam/ta/reportportal/core/log/impl/SaveLogBinaryDataTaskAsync.java
@@ -23,14 +23,13 @@
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.epam.ta.reportportal.ws.model.log.SaveLogRQ;
 import com.google.common.base.Preconditions;
+import java.util.Optional;
+import java.util.function.Supplier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.multipart.MultipartFile;
 
-import java.util.Optional;
-import java.util.function.Supplier;
-
 /**
  * Task to save log's binary data from MultipartFile for the use with queued RabbitMQ log saving.
  * Statefull, so cannot be a singleton bean.
@@ -39,44 +38,46 @@
  */
 public class SaveLogBinaryDataTaskAsync implements Supplier<BinaryDataMetaInfo> {
 
-	private static final Logger LOGGER = LoggerFactory.getLogger(SaveLogBinaryDataTaskAsync.class);
+  private static final Logger LOGGER = LoggerFactory.getLogger(SaveLogBinaryDataTaskAsync.class);
 
-	@Autowired
-	private AttachmentBinaryDataService attachmentBinaryDataService;
+  @Autowired
+  private AttachmentBinaryDataService attachmentBinaryDataService;
 
-	private SaveLogRQ request;
+  private SaveLogRQ request;
 
-	private MultipartFile file;
+  private MultipartFile file;
 
-	private Long projectId;
+  private Long projectId;
 
-	@Override
-	public BinaryDataMetaInfo get() {
-		Optional<BinaryDataMetaInfo> maybeBinaryDataMetaInfo = attachmentBinaryDataService.saveAttachment(AttachmentMetaInfo.builder()
-				.withProjectId(projectId)
-				.withLaunchUuid(request.getLaunchUuid())
-				.withLogUuid(request.getUuid())
-				.build(), file);
-		return maybeBinaryDataMetaInfo.orElseGet(() -> {
-			LOGGER.error("Failed to save log content data into DataStore, projectId {}, itemId {} ", projectId, request.getItemUuid());
-			throw new ReportPortalException(ErrorType.BINARY_DATA_CANNOT_BE_SAVED);
-		});
-	}
+  @Override
+  public BinaryDataMetaInfo get() {
+    Optional<BinaryDataMetaInfo> maybeBinaryDataMetaInfo = attachmentBinaryDataService.saveAttachment(
+        AttachmentMetaInfo.builder()
+            .withProjectId(projectId)
+            .withLaunchUuid(request.getLaunchUuid())
+            .withLogUuid(request.getUuid())
+            .build(), file);
+    return maybeBinaryDataMetaInfo.orElseGet(() -> {
+      LOGGER.error("Failed to save log content data into DataStore, projectId {}, itemId {} ",
+          projectId, request.getItemUuid());
+      throw new ReportPortalException(ErrorType.BINARY_DATA_CANNOT_BE_SAVED);
+    });
+  }
 
-	public SaveLogBinaryDataTaskAsync withRequest(SaveLogRQ request) {
-		Preconditions.checkNotNull(request, "Request shouldn't be null");
-		this.request = request;
-		return this;
-	}
+  public SaveLogBinaryDataTaskAsync withRequest(SaveLogRQ request) {
+    Preconditions.checkNotNull(request, "Request shouldn't be null");
+    this.request = request;
+    return this;
+  }
 
-	public SaveLogBinaryDataTaskAsync withFile(MultipartFile file) {
-		this.file = file;
-		return this;
-	}
+  public SaveLogBinaryDataTaskAsync withFile(MultipartFile file) {
+    this.file = file;
+    return this;
+  }
 
-	public SaveLogBinaryDataTaskAsync withProjectId(Long projectId) {
-		Preconditions.checkNotNull(projectId, "Project id should not be null");
-		this.projectId = projectId;
-		return this;
-	}
+  public SaveLogBinaryDataTaskAsync withProjectId(Long projectId) {
+    Preconditions.checkNotNull(projectId, "Project id should not be null");
+    this.projectId = projectId;
+    return this;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/logging/HttpLogging.java b/src/main/java/com/epam/ta/reportportal/core/logging/HttpLogging.java
index 535c038283..2f6089bc2c 100644
--- a/src/main/java/com/epam/ta/reportportal/core/logging/HttpLogging.java
+++ b/src/main/java/com/epam/ta/reportportal/core/logging/HttpLogging.java
@@ -28,11 +28,11 @@
 @Target(ElementType.METHOD)
 public @interface HttpLogging {
 
-	boolean logHeaders() default true;
+  boolean logHeaders() default true;
 
-	boolean logRequestBody() default true;
+  boolean logRequestBody() default true;
 
-	boolean logResponseBody() default true;
+  boolean logResponseBody() default true;
 
-	boolean logExecutionTime() default true;
+  boolean logExecutionTime() default true;
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/logging/HttpLoggingAspect.java b/src/main/java/com/epam/ta/reportportal/core/logging/HttpLoggingAspect.java
index 28b0492a10..9aca8d05cc 100644
--- a/src/main/java/com/epam/ta/reportportal/core/logging/HttpLoggingAspect.java
+++ b/src/main/java/com/epam/ta/reportportal/core/logging/HttpLoggingAspect.java
@@ -19,6 +19,13 @@
 import ch.qos.logback.classic.Logger;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import java.lang.reflect.Method;
+import java.lang.reflect.Parameter;
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
+import java.util.Enumeration;
+import java.util.concurrent.atomic.AtomicLong;
+import javax.servlet.http.HttpServletRequest;
 import org.aspectj.lang.ProceedingJoinPoint;
 import org.aspectj.lang.annotation.Around;
 import org.aspectj.lang.annotation.Aspect;
@@ -34,14 +41,6 @@
 import org.springframework.web.context.request.ServletRequestAttributes;
 import org.springframework.web.multipart.MultipartHttpServletRequest;
 
-import javax.servlet.http.HttpServletRequest;
-import java.lang.reflect.Method;
-import java.lang.reflect.Parameter;
-import java.net.URLDecoder;
-import java.nio.charset.StandardCharsets;
-import java.util.Enumeration;
-import java.util.concurrent.atomic.AtomicLong;
-
 
 /**
  * @author Konstantin Antipin
@@ -49,179 +48,185 @@
 @Aspect
 public class HttpLoggingAspect {
 
-	private static final String READABLE_CONTENT_TYPES = "text/plain text/html text/xml application/json application/xml application/hal+xml application/hal+json";
-
-	private static final String NEWLINE = "\n";
-	private static final String BODY_DENOMINATOR = "-- Body --";
-	private static final String BODY_BINARY_MARK = "<binary body>";
-
-	private static final AtomicLong COUNTER = new AtomicLong();
-
-	@Autowired
-	private ObjectMapper objectMapper;
-
-	@Around("execution(public * *(..)) && @annotation(annotation)")
-	public Object log(ProceedingJoinPoint joinPoint, HttpLogging annotation) throws Throwable {
-
-		Logger logger = (Logger) LoggerFactory.getLogger(joinPoint.getTarget().getClass());
-
-
-		Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
-
-		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
-		Object requestBody = getBody(joinPoint, method);
-
-		String prefix = method.getName();
-
-		long requestCount = COUNTER.incrementAndGet();
-
-		if (logger.isDebugEnabled()) {
-			logger.debug(formatRequestRecord(requestCount, prefix, request, requestBody, annotation));
-		}
-
-		Object response;
-
-		long start = System.currentTimeMillis();
-		try {
-			response = joinPoint.proceed();
-			long executionTime = System.currentTimeMillis() - start;
-			if (logger.isDebugEnabled()) {
-				logger.debug(formatResponseRecord(requestCount, prefix, response, annotation, executionTime));
-			}
-		} catch (Throwable throwable) {
-			logger.error(" (" + requestCount + ") - Error", throwable);
-			throw throwable;
-		}
-
-		return response;
-	}
-
-	protected Object getBody(ProceedingJoinPoint joinPoint, Method method) {
-		Object body = null;
-		Object[] args = joinPoint.getArgs();
-		Parameter[] parameters = method.getParameters();
-		for (int i = 0; i < parameters.length; i++) {
-			Object arg = args[i];
-
-			if (arg != null) {
-				if (arg instanceof MultipartHttpServletRequest) {
-					body = BODY_BINARY_MARK;
-					break;
-				} else if (parameters[i].isAnnotationPresent(RequestBody.class)) {
-					body = arg;
-					break;
-				}  else if (arg instanceof HttpEntity) {
-					body = ((HttpEntity) arg).getBody();
-					break;
-				}
-			}
-		}
-		return body;
-	}
-
-	protected String formatRequestRecord(long count, String prefix, HttpServletRequest request,
-			Object body, HttpLogging annotation) throws Exception {
-		StringBuilder record = new StringBuilder();
-
-		// uri
-		record.append(prefix)
-				.append(" (").append(count).append(')').append(" - Request")
-				.append(NEWLINE).append(' ').append(request.getMethod())
-				.append(' ').append(URLDecoder.decode(request.getRequestURI(), StandardCharsets.UTF_8.displayName()));
-
-		// headers
-		if (annotation.logHeaders()) {
-			Enumeration<String> names = request.getHeaderNames();
-			while (names.hasMoreElements()) {
-				String name = names.nextElement();
-				Enumeration<String> values = request.getHeaders(name);
-				record.append(NEWLINE).append(' ').append(name).append(':');
-				boolean comma = false;
-				while (values.hasMoreElements()) {
-					if (comma) {
-						record.append(',');
-					} else {
-						comma = true;
-					}
-					record.append(' ').append(values.nextElement());
-				}
-			}
-		}
-
-		// body
-		if (body != null && annotation.logRequestBody()) {
-			try {
-				record.append(NEWLINE).append(' ').append(BODY_DENOMINATOR)
-						.append(NEWLINE).append(' ').append(objectMapper.writeValueAsString(body));
-			} catch (JsonProcessingException e) {
-				// ignore
-			}
-		}
-
-		return record.toString();
-	}
-
-	protected String formatResponseRecord(long count, String prefix, Object response, HttpLogging annotation, long executionTime) throws Exception {
-		boolean binaryBody = false;
-		StringBuilder record = new StringBuilder();
-
-		record.append(prefix).append(" (").append(count).append(')').append(" - Response ");
-		if (annotation.logExecutionTime()) {
-			record.append(" (").append(executionTime).append(" ms)");
-		}
-
-		if (response instanceof ResponseEntity) {
-			HttpStatus status = ((ResponseEntity) response).getStatusCode();
-			record.append(NEWLINE).append(' ').append(status).append(" - ").append(status.getReasonPhrase());
-
-			if (annotation.logHeaders()) {
-				HttpHeaders headers = ((ResponseEntity) response).getHeaders();
-				for (String name : headers.keySet()) {
-					record.append(NEWLINE).append(' ').append(name).append(':');
-					boolean comma = false;
-					for (String value : headers.get(name)) {
-						if (HttpHeaders.CONTENT_TYPE.equals(name) && !readableContent(value)) {
-							binaryBody = true;
-						}
-						if (comma) {
-							record.append(',');
-						} else {
-							comma = true;
-						}
-						record.append(' ').append(value);
-					}
-				}
-			}
-
-			if (annotation.logResponseBody()) {
-				record.append(NEWLINE).append(' ').append(BODY_DENOMINATOR);
-				if (binaryBody) {
-					record.append(NEWLINE).append(' ').append('"').append(BODY_BINARY_MARK).append('"');
-				} else {
-					try {
-						record.append(NEWLINE).append(' ').append(objectMapper.writeValueAsString(((ResponseEntity<?>) response).getBody()));
-					} catch (JsonProcessingException ex) {
-						record.append(NEWLINE).append(' ').append(((ResponseEntity<String>) response).getBody());
-					}
-				}
-			}
-		} else {
-			if (annotation.logResponseBody()) {
-				record.append(NEWLINE).append(' ').append("Status").append(" - ").append("OK (method return)");
-				record.append(NEWLINE).append(' ').append(BODY_DENOMINATOR);
-				try {
-					record.append(NEWLINE).append(' ').append(objectMapper.writeValueAsString(response));
-				} catch (JsonProcessingException ex) {
-					// ignore
-				}
-			}
-		}
-
-		return record.toString();
-	}
-
-	protected boolean readableContent(String value) {
-		int idx = value.indexOf(';');
-		return READABLE_CONTENT_TYPES.contains(value.substring(0, idx > 0 ? idx : value.length()));
-	}
+  private static final String READABLE_CONTENT_TYPES = "text/plain text/html text/xml application/json application/xml application/hal+xml application/hal+json";
+
+  private static final String NEWLINE = "\n";
+  private static final String BODY_DENOMINATOR = "-- Body --";
+  private static final String BODY_BINARY_MARK = "<binary body>";
+
+  private static final AtomicLong COUNTER = new AtomicLong();
+
+  @Autowired
+  private ObjectMapper objectMapper;
+
+  @Around("execution(public * *(..)) && @annotation(annotation)")
+  public Object log(ProceedingJoinPoint joinPoint, HttpLogging annotation) throws Throwable {
+
+    Logger logger = (Logger) LoggerFactory.getLogger(joinPoint.getTarget().getClass());
+
+    Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
+
+    HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
+    Object requestBody = getBody(joinPoint, method);
+
+    String prefix = method.getName();
+
+    long requestCount = COUNTER.incrementAndGet();
+
+    if (logger.isDebugEnabled()) {
+      logger.debug(formatRequestRecord(requestCount, prefix, request, requestBody, annotation));
+    }
+
+    Object response;
+
+    long start = System.currentTimeMillis();
+    try {
+      response = joinPoint.proceed();
+      long executionTime = System.currentTimeMillis() - start;
+      if (logger.isDebugEnabled()) {
+        logger.debug(
+            formatResponseRecord(requestCount, prefix, response, annotation, executionTime));
+      }
+    } catch (Throwable throwable) {
+      logger.error(" (" + requestCount + ") - Error", throwable);
+      throw throwable;
+    }
+
+    return response;
+  }
+
+  protected Object getBody(ProceedingJoinPoint joinPoint, Method method) {
+    Object body = null;
+    Object[] args = joinPoint.getArgs();
+    Parameter[] parameters = method.getParameters();
+    for (int i = 0; i < parameters.length; i++) {
+      Object arg = args[i];
+
+      if (arg != null) {
+        if (arg instanceof MultipartHttpServletRequest) {
+          body = BODY_BINARY_MARK;
+          break;
+        } else if (parameters[i].isAnnotationPresent(RequestBody.class)) {
+          body = arg;
+          break;
+        } else if (arg instanceof HttpEntity) {
+          body = ((HttpEntity) arg).getBody();
+          break;
+        }
+      }
+    }
+    return body;
+  }
+
+  protected String formatRequestRecord(long count, String prefix, HttpServletRequest request,
+      Object body, HttpLogging annotation) throws Exception {
+    StringBuilder record = new StringBuilder();
+
+    // uri
+    record.append(prefix)
+        .append(" (").append(count).append(')').append(" - Request")
+        .append(NEWLINE).append(' ').append(request.getMethod())
+        .append(' ')
+        .append(URLDecoder.decode(request.getRequestURI(), StandardCharsets.UTF_8.displayName()));
+
+    // headers
+    if (annotation.logHeaders()) {
+      Enumeration<String> names = request.getHeaderNames();
+      while (names.hasMoreElements()) {
+        String name = names.nextElement();
+        Enumeration<String> values = request.getHeaders(name);
+        record.append(NEWLINE).append(' ').append(name).append(':');
+        boolean comma = false;
+        while (values.hasMoreElements()) {
+          if (comma) {
+            record.append(',');
+          } else {
+            comma = true;
+          }
+          record.append(' ').append(values.nextElement());
+        }
+      }
+    }
+
+    // body
+    if (body != null && annotation.logRequestBody()) {
+      try {
+        record.append(NEWLINE).append(' ').append(BODY_DENOMINATOR)
+            .append(NEWLINE).append(' ').append(objectMapper.writeValueAsString(body));
+      } catch (JsonProcessingException e) {
+        // ignore
+      }
+    }
+
+    return record.toString();
+  }
+
+  protected String formatResponseRecord(long count, String prefix, Object response,
+      HttpLogging annotation, long executionTime) throws Exception {
+    boolean binaryBody = false;
+    StringBuilder record = new StringBuilder();
+
+    record.append(prefix).append(" (").append(count).append(')').append(" - Response ");
+    if (annotation.logExecutionTime()) {
+      record.append(" (").append(executionTime).append(" ms)");
+    }
+
+    if (response instanceof ResponseEntity) {
+      HttpStatus status = ((ResponseEntity) response).getStatusCode();
+      record.append(NEWLINE).append(' ').append(status).append(" - ")
+          .append(status.getReasonPhrase());
+
+      if (annotation.logHeaders()) {
+        HttpHeaders headers = ((ResponseEntity) response).getHeaders();
+        for (String name : headers.keySet()) {
+          record.append(NEWLINE).append(' ').append(name).append(':');
+          boolean comma = false;
+          for (String value : headers.get(name)) {
+            if (HttpHeaders.CONTENT_TYPE.equals(name) && !readableContent(value)) {
+              binaryBody = true;
+            }
+            if (comma) {
+              record.append(',');
+            } else {
+              comma = true;
+            }
+            record.append(' ').append(value);
+          }
+        }
+      }
+
+      if (annotation.logResponseBody()) {
+        record.append(NEWLINE).append(' ').append(BODY_DENOMINATOR);
+        if (binaryBody) {
+          record.append(NEWLINE).append(' ').append('"').append(BODY_BINARY_MARK).append('"');
+        } else {
+          try {
+            record.append(NEWLINE).append(' ')
+                .append(objectMapper.writeValueAsString(((ResponseEntity<?>) response).getBody()));
+          } catch (JsonProcessingException ex) {
+            record.append(NEWLINE).append(' ')
+                .append(((ResponseEntity<String>) response).getBody());
+          }
+        }
+      }
+    } else {
+      if (annotation.logResponseBody()) {
+        record.append(NEWLINE).append(' ').append("Status").append(" - ")
+            .append("OK (method return)");
+        record.append(NEWLINE).append(' ').append(BODY_DENOMINATOR);
+        try {
+          record.append(NEWLINE).append(' ').append(objectMapper.writeValueAsString(response));
+        } catch (JsonProcessingException ex) {
+          // ignore
+        }
+      }
+    }
+
+    return record.toString();
+  }
+
+  protected boolean readableContent(String value) {
+    int idx = value.indexOf(';');
+    return READABLE_CONTENT_TYPES.contains(value.substring(0, idx > 0 ? idx : value.length()));
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/logging/RabbitMessageLogging.java b/src/main/java/com/epam/ta/reportportal/core/logging/RabbitMessageLogging.java
index 32af374df4..f3359d4e45 100644
--- a/src/main/java/com/epam/ta/reportportal/core/logging/RabbitMessageLogging.java
+++ b/src/main/java/com/epam/ta/reportportal/core/logging/RabbitMessageLogging.java
@@ -28,7 +28,7 @@
 @Target(ElementType.METHOD)
 public @interface RabbitMessageLogging {
 
-	boolean logHeaders() default true;
+  boolean logHeaders() default true;
 
-	boolean logBody() default true;
+  boolean logBody() default true;
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/logging/RabbitMessageLoggingAspect.java b/src/main/java/com/epam/ta/reportportal/core/logging/RabbitMessageLoggingAspect.java
index 121e1c51a4..1c3fb13f1c 100644
--- a/src/main/java/com/epam/ta/reportportal/core/logging/RabbitMessageLoggingAspect.java
+++ b/src/main/java/com/epam/ta/reportportal/core/logging/RabbitMessageLoggingAspect.java
@@ -18,6 +18,10 @@
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import java.lang.reflect.Method;
+import java.lang.reflect.Parameter;
+import java.util.HashMap;
+import java.util.Map;
 import org.aspectj.lang.ProceedingJoinPoint;
 import org.aspectj.lang.annotation.Around;
 import org.aspectj.lang.annotation.Aspect;
@@ -27,14 +31,8 @@
 import org.springframework.amqp.core.Message;
 import org.springframework.amqp.support.converter.MessageConverter;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.messaging.handler.annotation.Header;
 import org.springframework.messaging.handler.annotation.Payload;
-import org.springframework.stereotype.Component;
-import java.lang.reflect.Method;
-import java.lang.reflect.Parameter;
-import java.util.HashMap;
-import java.util.Map;
 
 /**
  * @author Konstantin Antipin
@@ -42,80 +40,83 @@
 @Aspect
 public class RabbitMessageLoggingAspect {
 
-	private static final String NEWLINE = "\n";
-	private static final String BODY_DENOMINATOR = "-- Body --";
-
-	@Autowired
-	private ObjectMapper objectMapper;
-
-	@Autowired
-	private MessageConverter messageConverter;
-
-	@Around("execution(public * *(..)) && @annotation(annotation)")
-	public Object log(ProceedingJoinPoint joinPoint, RabbitMessageLogging annotation) throws Throwable {
-
-		Logger logger = LoggerFactory.getLogger(joinPoint.getTarget().getClass());
-
-		Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
-
-		Map<String, Object> headers = new HashMap<>();
-		Object body = getHeadersAndBody(joinPoint, method, headers);
-
-		String prefix = method.getName();
-
-		if (logger.isDebugEnabled()) {
-			logger.debug(formatMessageRecord(prefix, headers, body, annotation));
-		}
-
-		return joinPoint.proceed();
-	}
-
-	protected Object getHeadersAndBody(ProceedingJoinPoint joinPoint, Method method, Map<String, Object> headers) {
-		Object body = null;
-		Object[] args = joinPoint.getArgs();
-		Parameter[] parameters = method.getParameters();
-		for (int i = 0; i < parameters.length; i++) {
-			Object arg = args[i];
-
-			if (arg != null) {
-				if (arg instanceof Message) {
-					Message message = (Message) arg;
-					body = messageConverter.fromMessage(message);
-					headers.putAll(message.getMessageProperties().getHeaders());
-					break;
-				} else if (parameters[i].isAnnotationPresent(Payload.class)) {
-					body = arg;
-				} else if (parameters[i].isAnnotationPresent(Header.class)) {
-					headers.put(parameters[i].getAnnotation(Header.class).name(), arg);
-				}
-			}
-		}
-		return body;
-	}
-
-	protected String formatMessageRecord(String prefix, Map<String, Object> headers,
-			Object body, RabbitMessageLogging annotation) throws Exception {
-		StringBuilder record = new StringBuilder();
-
-		record.append(prefix).append(" - Rabbit message");
-
-		// headers
-		if (annotation.logHeaders()) {
-			for (Map.Entry<String, Object> entry : headers.entrySet()) {
-				record.append(NEWLINE).append(' ').append(entry.getKey()).append(": ").append(entry.getValue());
-			}
-		}
-
-		// body
-		if (annotation.logBody() && body !=null) {
-			try {
-				record.append(NEWLINE).append(' ').append(BODY_DENOMINATOR)
-						.append(NEWLINE).append(' ').append(objectMapper.writeValueAsString(body));
-			} catch (JsonProcessingException e) {
-				// ignore
-			}
-		}
-
-		return record.toString();
-	}
+  private static final String NEWLINE = "\n";
+  private static final String BODY_DENOMINATOR = "-- Body --";
+
+  @Autowired
+  private ObjectMapper objectMapper;
+
+  @Autowired
+  private MessageConverter messageConverter;
+
+  @Around("execution(public * *(..)) && @annotation(annotation)")
+  public Object log(ProceedingJoinPoint joinPoint, RabbitMessageLogging annotation)
+      throws Throwable {
+
+    Logger logger = LoggerFactory.getLogger(joinPoint.getTarget().getClass());
+
+    Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
+
+    Map<String, Object> headers = new HashMap<>();
+    Object body = getHeadersAndBody(joinPoint, method, headers);
+
+    String prefix = method.getName();
+
+    if (logger.isDebugEnabled()) {
+      logger.debug(formatMessageRecord(prefix, headers, body, annotation));
+    }
+
+    return joinPoint.proceed();
+  }
+
+  protected Object getHeadersAndBody(ProceedingJoinPoint joinPoint, Method method,
+      Map<String, Object> headers) {
+    Object body = null;
+    Object[] args = joinPoint.getArgs();
+    Parameter[] parameters = method.getParameters();
+    for (int i = 0; i < parameters.length; i++) {
+      Object arg = args[i];
+
+      if (arg != null) {
+        if (arg instanceof Message) {
+          Message message = (Message) arg;
+          body = messageConverter.fromMessage(message);
+          headers.putAll(message.getMessageProperties().getHeaders());
+          break;
+        } else if (parameters[i].isAnnotationPresent(Payload.class)) {
+          body = arg;
+        } else if (parameters[i].isAnnotationPresent(Header.class)) {
+          headers.put(parameters[i].getAnnotation(Header.class).name(), arg);
+        }
+      }
+    }
+    return body;
+  }
+
+  protected String formatMessageRecord(String prefix, Map<String, Object> headers,
+      Object body, RabbitMessageLogging annotation) throws Exception {
+    StringBuilder record = new StringBuilder();
+
+    record.append(prefix).append(" - Rabbit message");
+
+    // headers
+    if (annotation.logHeaders()) {
+      for (Map.Entry<String, Object> entry : headers.entrySet()) {
+        record.append(NEWLINE).append(' ').append(entry.getKey()).append(": ")
+            .append(entry.getValue());
+      }
+    }
+
+    // body
+    if (annotation.logBody() && body != null) {
+      try {
+        record.append(NEWLINE).append(' ').append(BODY_DENOMINATOR)
+            .append(NEWLINE).append(' ').append(objectMapper.writeValueAsString(body));
+      } catch (JsonProcessingException e) {
+        // ignore
+      }
+    }
+
+    return record.toString();
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/onboarding/OnboardingService.java b/src/main/java/com/epam/ta/reportportal/core/onboarding/OnboardingService.java
index 567d07bc10..11cb4d0d80 100644
--- a/src/main/java/com/epam/ta/reportportal/core/onboarding/OnboardingService.java
+++ b/src/main/java/com/epam/ta/reportportal/core/onboarding/OnboardingService.java
@@ -22,32 +22,34 @@
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import org.springframework.stereotype.Service;
-
 import java.util.List;
 import java.util.Map;
+import org.springframework.stereotype.Service;
 
 /**
  * @author Antonov Maksim
  */
 @Service
 public class OnboardingService {
-    private final OnboardingRepository onboardingRepository;
-    private final ObjectMapper objectMapper;
 
-    public OnboardingService(OnboardingRepository onboardingRepository, ObjectMapper objectMapper) {
-        this.onboardingRepository = onboardingRepository;
-        this.objectMapper = objectMapper;
-    }
+  private final OnboardingRepository onboardingRepository;
+  private final ObjectMapper objectMapper;
+
+  public OnboardingService(OnboardingRepository onboardingRepository, ObjectMapper objectMapper) {
+    this.onboardingRepository = onboardingRepository;
+    this.objectMapper = objectMapper;
+  }
 
-    public Object getOnboardingDataForPageIfAvailable(String page) {
-        Onboarding onboarding = onboardingRepository.findAvailableOnboardingByPage(page);
-        // possibly use another parsing flow for some onboarding page, for now only text to list of questions
-        try {
-            return (onboarding != null) ? objectMapper.readValue(onboarding.getData(),
-                    new TypeReference<List<Map<String, String>>>() {}) : null;
-        } catch (JsonProcessingException e) {
-            throw new ReportPortalException(ErrorType.UNCLASSIFIED_ERROR, "Unable to parse onboarding data: " + e.getMessage());
-        }
+  public Object getOnboardingDataForPageIfAvailable(String page) {
+    Onboarding onboarding = onboardingRepository.findAvailableOnboardingByPage(page);
+    // possibly use another parsing flow for some onboarding page, for now only text to list of questions
+    try {
+      return (onboarding != null) ? objectMapper.readValue(onboarding.getData(),
+          new TypeReference<List<Map<String, String>>>() {
+          }) : null;
+    } catch (JsonProcessingException e) {
+      throw new ReportPortalException(ErrorType.UNCLASSIFIED_ERROR,
+          "Unable to parse onboarding data: " + e.getMessage());
     }
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/plugin/Pf4jPluginBox.java b/src/main/java/com/epam/ta/reportportal/core/plugin/Pf4jPluginBox.java
index c3c8ed5168..8d5e21efb3 100644
--- a/src/main/java/com/epam/ta/reportportal/core/plugin/Pf4jPluginBox.java
+++ b/src/main/java/com/epam/ta/reportportal/core/plugin/Pf4jPluginBox.java
@@ -18,81 +18,81 @@
 
 import com.epam.ta.reportportal.entity.integration.IntegrationType;
 import com.epam.ta.reportportal.entity.integration.IntegrationTypeDetails;
-import org.pf4j.PluginState;
-import org.pf4j.PluginWrapper;
-
 import java.io.InputStream;
 import java.util.Optional;
+import org.pf4j.PluginState;
+import org.pf4j.PluginWrapper;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public interface Pf4jPluginBox extends PluginBox {
 
-	void startUp();
+  void startUp();
 
-	void shutDown();
+  void shutDown();
 
-	/**
-	 * Start up loaded plugin by id
-	 *
-	 * @param pluginId {@link PluginWrapper#getPluginId()}
-	 * @return {@link PluginState}
-	 */
-	PluginState startUpPlugin(String pluginId);
+  /**
+   * Start up loaded plugin by id
+   *
+   * @param pluginId {@link PluginWrapper#getPluginId()}
+   * @return {@link PluginState}
+   */
+  PluginState startUpPlugin(String pluginId);
 
-	/**
-	 * Load plugin to the plugin manager by plugin file path
-	 *
-	 * @param pluginId               {@link PluginWrapper#getPluginId()}
-	 * @param integrationTypeDetails {@link IntegrationTypeDetails}
-	 * @return {@link PluginWrapper#getPluginId()}
-	 */
-	boolean loadPlugin(String pluginId, IntegrationTypeDetails integrationTypeDetails);
+  /**
+   * Load plugin to the plugin manager by plugin file path
+   *
+   * @param pluginId               {@link PluginWrapper#getPluginId()}
+   * @param integrationTypeDetails {@link IntegrationTypeDetails}
+   * @return {@link PluginWrapper#getPluginId()}
+   */
+  boolean loadPlugin(String pluginId, IntegrationTypeDetails integrationTypeDetails);
 
-	/**
-	 * Unload plugin from the plugin manager by id
-	 *
-	 * @param integrationType {@link IntegrationType}
-	 * @return 'true' if a plugin was successfully unloaded, else 'false'
-	 */
-	boolean unloadPlugin(IntegrationType integrationType);
+  /**
+   * Unload plugin from the plugin manager by id
+   *
+   * @param integrationType {@link IntegrationType}
+   * @return 'true' if a plugin was successfully unloaded, else 'false'
+   */
+  boolean unloadPlugin(IntegrationType integrationType);
 
-	/**
-	 * Delete plugin by id
-	 *
-	 * @param pluginId {@link IntegrationType#getName()}
-	 * @return 'true' if a plugin was successfully deleted, else 'false'
-	 */
-	boolean deletePlugin(String pluginId);
+  /**
+   * Delete plugin by id
+   *
+   * @param pluginId {@link IntegrationType#getName()}
+   * @return 'true' if a plugin was successfully deleted, else 'false'
+   */
+  boolean deletePlugin(String pluginId);
 
-	/**
-	 * Delete plugin
-	 *
-	 * @param pluginWrapper {@link PluginWrapper}
-	 * @return 'true' if a plugin was successfully deleted, else 'false'
-	 */
-	boolean deletePlugin(PluginWrapper pluginWrapper);
+  /**
+   * Delete plugin
+   *
+   * @param pluginWrapper {@link PluginWrapper}
+   * @return 'true' if a plugin was successfully deleted, else 'false'
+   */
+  boolean deletePlugin(PluginWrapper pluginWrapper);
 
 
-	/**
-	 * Get plugin from the plugin manager by id
-	 *
-	 * @param id {@link PluginWrapper#getPluginId()}
-	 * @return {@link PluginWrapper} wrapped in the {@link Optional}
-	 */
-	Optional<PluginWrapper> getPluginById(String id);
+  /**
+   * Get plugin from the plugin manager by id
+   *
+   * @param id {@link PluginWrapper#getPluginId()}
+   * @return {@link PluginWrapper} wrapped in the {@link Optional}
+   */
+  Optional<PluginWrapper> getPluginById(String id);
 
-	/**
-	 * Check if uploading plugins holder contains plugin file name
-	 *
-	 * @param fileName Name of the plugin file in the {@link com.epam.ta.reportportal.plugin.Pf4jPluginManager#uploadingPlugins}
-	 *                 which uploaded state is required
-	 * @return 'true' if {@link com.epam.ta.reportportal.plugin.Pf4jPluginManager#uploadingPlugins} contains plugin file name,
-	 * else 'false'
-	 * @see com.epam.ta.reportportal.plugin.Pf4jPluginManager
-	 */
-	boolean isInUploadingState(String fileName);
+  /**
+   * Check if uploading plugins holder contains plugin file name
+   *
+   * @param fileName Name of the plugin file in the
+   *                 {@link com.epam.ta.reportportal.plugin.Pf4jPluginManager#uploadingPlugins}
+   *                 which uploaded state is required
+   * @return 'true' if {@link com.epam.ta.reportportal.plugin.Pf4jPluginManager#uploadingPlugins}
+   * contains plugin file name, else 'false'
+   * @see com.epam.ta.reportportal.plugin.Pf4jPluginManager
+   */
+  boolean isInUploadingState(String fileName);
 
-	IntegrationType uploadPlugin(String newPluginFileName, InputStream fileStream);
+  IntegrationType uploadPlugin(String newPluginFileName, InputStream fileStream);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/plugin/Plugin.java b/src/main/java/com/epam/ta/reportportal/core/plugin/Plugin.java
index 3c44630cb5..0b53a0e1d7 100644
--- a/src/main/java/com/epam/ta/reportportal/core/plugin/Plugin.java
+++ b/src/main/java/com/epam/ta/reportportal/core/plugin/Plugin.java
@@ -17,7 +17,6 @@
 package com.epam.ta.reportportal.core.plugin;
 
 import com.epam.reportportal.extension.common.ExtensionPoint;
-
 import java.io.Serializable;
 import java.util.Objects;
 
@@ -28,54 +27,54 @@
  */
 public class Plugin implements Serializable {
 
-	private String id;
-	private ExtensionPoint type;
+  private String id;
+  private ExtensionPoint type;
 
-	public Plugin() {
+  public Plugin() {
 
-	}
+  }
 
-	public Plugin(String id, ExtensionPoint type) {
-		this.id = id;
-		this.type = type;
-	}
+  public Plugin(String id, ExtensionPoint type) {
+    this.id = id;
+    this.type = type;
+  }
 
-	public String getId() {
-		return id;
-	}
+  public String getId() {
+    return id;
+  }
 
-	public void setId(String id) {
-		this.id = id;
-	}
+  public void setId(String id) {
+    this.id = id;
+  }
 
-	public ExtensionPoint getType() {
-		return type;
-	}
+  public ExtensionPoint getType() {
+    return type;
+  }
 
-	public void setType(ExtensionPoint type) {
-		this.type = type;
-	}
+  public void setType(ExtensionPoint type) {
+    this.type = type;
+  }
 
-	@Override
-	public boolean equals(Object o) {
-		if (this == o) {
-			return true;
-		}
-		if (o == null || getClass() != o.getClass()) {
-			return false;
-		}
-		Plugin plugin = (Plugin) o;
-		return Objects.equals(type, plugin.type);
-	}
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    Plugin plugin = (Plugin) o;
+    return Objects.equals(type, plugin.type);
+  }
 
-	@Override
-	public int hashCode() {
+  @Override
+  public int hashCode() {
 
-		return Objects.hash(type);
-	}
+    return Objects.hash(type);
+  }
 
-	@Override
-	public String toString() {
-		return "Plugin{" + "type='" + type + '\'' + '}';
-	}
+  @Override
+  public String toString() {
+    return "Plugin{" + "type='" + type + '\'' + '}';
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/plugin/PluginBox.java b/src/main/java/com/epam/ta/reportportal/core/plugin/PluginBox.java
index 6cf8f6110a..90ded6bb7d 100644
--- a/src/main/java/com/epam/ta/reportportal/core/plugin/PluginBox.java
+++ b/src/main/java/com/epam/ta/reportportal/core/plugin/PluginBox.java
@@ -26,31 +26,33 @@
  */
 public interface PluginBox {
 
-	/**
-	 * @return All available plugins
-	 */
-	List<Plugin> getPlugins();
+  /**
+   * @return All available plugins
+   */
+  List<Plugin> getPlugins();
 
-	/**
-	 * @param type Type of plugin
-	 * @return Optional of plugin by given type
-	 */
-	Optional<Plugin> getPlugin(String type);
+  /**
+   * @param type Type of plugin
+   * @return Optional of plugin by given type
+   */
+  Optional<Plugin> getPlugin(String type);
 
-	/**
-	 * Creates (or takes from cache) instance of given plugin
-	 *
-	 * @param name Plugin name / ID
-	 * @param type Type of plugin
-	 * @return Optional of plugin by given type
-	 */
-	<T> Optional<T> getInstance(String name, Class<T> type);
+  /**
+   * Creates (or takes from cache) instance of given plugin
+   *
+   * @param <T>  The Extension Point class
+   * @param name Plugin name / ID
+   * @param type Type of plugin
+   * @return Optional of plugin by given type
+   */
+  <T> Optional<T> getInstance(String name, Class<T> type);
 
-	/**
-	 * Creates (or takes from cache) instance of given plugin
-	 *
-	 * @param type Type of plugin
-	 * @return Optional of plugin by given type
-	 */
-	<T> Optional<T> getInstance(Class<T> type);
+  /**
+   * Creates (or takes from cache) instance of given plugin
+   *
+   * @param <T>  The Extension Point class
+   * @param type Type of plugin
+   * @return Optional of plugin by given type
+   */
+  <T> Optional<T> getInstance(Class<T> type);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/plugin/PluginInfo.java b/src/main/java/com/epam/ta/reportportal/core/plugin/PluginInfo.java
index 1265b49a5d..8a46747750 100644
--- a/src/main/java/com/epam/ta/reportportal/core/plugin/PluginInfo.java
+++ b/src/main/java/com/epam/ta/reportportal/core/plugin/PluginInfo.java
@@ -16,82 +16,82 @@
 
 package com.epam.ta.reportportal.core.plugin;
 
-import javax.annotation.Nullable;
 import java.io.Serializable;
+import javax.annotation.Nullable;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public class PluginInfo implements Serializable {
 
-	private String id;
+  private String id;
 
-	private String version;
+  private String version;
 
-	private String fileId;
+  private String fileId;
 
-	private String fileName;
+  private String fileName;
 
-	private boolean isEnabled;
+  private boolean isEnabled;
 
-	public PluginInfo() {
-	}
+  public PluginInfo() {
+  }
 
-	public PluginInfo(String id, String version) {
-		this.id = id;
-		this.version = version;
-	}
+  public PluginInfo(String id, String version) {
+    this.id = id;
+    this.version = version;
+  }
 
-	public PluginInfo(String id, String version, String fileId, String fileName, boolean isEnabled) {
-		this.id = id;
-		this.version = version;
-		this.fileId = fileId;
-		this.fileName = fileName;
-		this.isEnabled = isEnabled;
-	}
+  public PluginInfo(String id, String version, String fileId, String fileName, boolean isEnabled) {
+    this.id = id;
+    this.version = version;
+    this.fileId = fileId;
+    this.fileName = fileName;
+    this.isEnabled = isEnabled;
+  }
 
-	@Nullable
-	public String getId() {
-		return id;
-	}
+  @Nullable
+  public String getId() {
+    return id;
+  }
 
-	public void setId(String id) {
-		this.id = id;
-	}
+  public void setId(String id) {
+    this.id = id;
+  }
 
-	@Nullable
-	public String getVersion() {
-		return version;
-	}
+  @Nullable
+  public String getVersion() {
+    return version;
+  }
 
-	public void setVersion(String version) {
-		this.version = version;
-	}
+  public void setVersion(String version) {
+    this.version = version;
+  }
 
-	@Nullable
-	public String getFileId() {
-		return fileId;
-	}
+  @Nullable
+  public String getFileId() {
+    return fileId;
+  }
 
-	public void setFileId(String fileId) {
-		this.fileId = fileId;
-	}
+  public void setFileId(String fileId) {
+    this.fileId = fileId;
+  }
 
-	@Nullable
-	public String getFileName() {
-		return fileName;
-	}
+  @Nullable
+  public String getFileName() {
+    return fileName;
+  }
 
-	public void setFileName(String fileName) {
-		this.fileName = fileName;
-	}
+  public void setFileName(String fileName) {
+    this.fileName = fileName;
+  }
 
-	public boolean isEnabled() {
-		return isEnabled;
-	}
+  public boolean isEnabled() {
+    return isEnabled;
+  }
 
-	public void setEnabled(boolean enabled) {
-		isEnabled = enabled;
-	}
+  public void setEnabled(boolean enabled) {
+    isEnabled = enabled;
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/preference/GetPreferenceHandler.java b/src/main/java/com/epam/ta/reportportal/core/preference/GetPreferenceHandler.java
index 7b02894a08..83d48cd36e 100644
--- a/src/main/java/com/epam/ta/reportportal/core/preference/GetPreferenceHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/preference/GetPreferenceHandler.java
@@ -26,6 +26,7 @@
  */
 public interface GetPreferenceHandler {
 
-	PreferenceResource getPreference(ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user);
+  PreferenceResource getPreference(ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user);
 
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/preference/UpdatePreferenceHandler.java b/src/main/java/com/epam/ta/reportportal/core/preference/UpdatePreferenceHandler.java
index 9e5ba56c0a..cfb3c7fdf3 100644
--- a/src/main/java/com/epam/ta/reportportal/core/preference/UpdatePreferenceHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/preference/UpdatePreferenceHandler.java
@@ -25,23 +25,26 @@
  * @author Pavel Bortnik
  */
 public interface UpdatePreferenceHandler {
-	/**
-	 * Add user preference
-	 *
-	 * @param projectDetails Project Details
-	 * @param user           User
-	 * @param filterId       Adding filter id
-	 * @return {@link OperationCompletionRS}
-	 */
-	OperationCompletionRS addPreference(ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user, Long filterId);
 
-	/**
-	 * Remove user preference
-	 *
-	 * @param projectDetails Project Details
-	 * @param user           User
-	 * @param filterId       Removing filter id
-	 * @return {@link OperationCompletionRS}
-	 */
-	OperationCompletionRS removePreference(ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user, Long filterId);
+  /**
+   * Add user preference
+   *
+   * @param projectDetails Project Details
+   * @param user           User
+   * @param filterId       Adding filter id
+   * @return {@link OperationCompletionRS}
+   */
+  OperationCompletionRS addPreference(ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user, Long filterId);
+
+  /**
+   * Remove user preference
+   *
+   * @param projectDetails Project Details
+   * @param user           User
+   * @param filterId       Removing filter id
+   * @return {@link OperationCompletionRS}
+   */
+  OperationCompletionRS removePreference(ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user, Long filterId);
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/preference/impl/GetPreferenceHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/preference/impl/GetPreferenceHandlerImpl.java
index f3d266a168..0835adf044 100644
--- a/src/main/java/com/epam/ta/reportportal/core/preference/impl/GetPreferenceHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/preference/impl/GetPreferenceHandlerImpl.java
@@ -22,40 +22,40 @@
 import com.epam.ta.reportportal.ws.converter.converters.UserFilterConverter;
 import com.epam.ta.reportportal.ws.model.filter.UserFilterResource;
 import com.epam.ta.reportportal.ws.model.preference.PreferenceResource;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
 import java.util.List;
 import java.util.stream.Collectors;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
- * Default implementation of
- * {@link com.epam.ta.reportportal.core.preference.GetPreferenceHandler}
+ * Default implementation of {@link com.epam.ta.reportportal.core.preference.GetPreferenceHandler}
  *
  * @author Dzmitry_Kavalets
  */
 @Service
 public class GetPreferenceHandlerImpl implements GetPreferenceHandler {
 
-	private final UserPreferenceRepository userPreferenceRepository;
+  private final UserPreferenceRepository userPreferenceRepository;
 
-	@Autowired
-	public GetPreferenceHandlerImpl(UserPreferenceRepository userPreferenceRepository) {
-		this.userPreferenceRepository = userPreferenceRepository;
-	}
+  @Autowired
+  public GetPreferenceHandlerImpl(UserPreferenceRepository userPreferenceRepository) {
+    this.userPreferenceRepository = userPreferenceRepository;
+  }
 
-	@Override
-	public PreferenceResource getPreference(ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user) {
-		List<UserPreference> userPreferences = userPreferenceRepository.findByProjectIdAndUserId(projectDetails.getProjectId(),
-				user.getUserId()
-		);
-		PreferenceResource preferenceResource = new PreferenceResource();
-		preferenceResource.setUserId(user.getUserId());
-		preferenceResource.setProjectId(projectDetails.getProjectId());
-		List<UserFilterResource> filters = userPreferences.stream()
-				.map(it -> UserFilterConverter.TO_FILTER_RESOURCE.apply(it.getFilter()))
-				.collect(Collectors.toList());
-		preferenceResource.setFilters(filters);
-		return preferenceResource;
-	}
+  @Override
+  public PreferenceResource getPreference(ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user) {
+    List<UserPreference> userPreferences = userPreferenceRepository.findByProjectIdAndUserId(
+        projectDetails.getProjectId(),
+        user.getUserId()
+    );
+    PreferenceResource preferenceResource = new PreferenceResource();
+    preferenceResource.setUserId(user.getUserId());
+    preferenceResource.setProjectId(projectDetails.getProjectId());
+    List<UserFilterResource> filters = userPreferences.stream()
+        .map(it -> UserFilterConverter.TO_FILTER_RESOURCE.apply(it.getFilter()))
+        .collect(Collectors.toList());
+    preferenceResource.setFilters(filters);
+    return preferenceResource;
+  }
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/CreateProjectHandler.java b/src/main/java/com/epam/ta/reportportal/core/project/CreateProjectHandler.java
index 5b37a34a05..a7fb7e1bd7 100644
--- a/src/main/java/com/epam/ta/reportportal/core/project/CreateProjectHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/project/CreateProjectHandler.java
@@ -29,14 +29,14 @@
  */
 public interface CreateProjectHandler {
 
-	/**
-	 * Create new project
-	 *
-	 * @param createProjectRQ Request Data
-	 * @param user            ReportPortal User
-	 * @return Response data
-	 */
-	EntryCreatedRS createProject(CreateProjectRQ createProjectRQ, ReportPortalUser user);
+  /**
+   * Create new project
+   *
+   * @param createProjectRQ Request Data
+   * @param user            ReportPortal User
+   * @return Response data
+   */
+  EntryCreatedRS createProject(CreateProjectRQ createProjectRQ, ReportPortalUser user);
 
-	Project createPersonal(User user);
+  Project createPersonal(User user);
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/DeleteProjectHandler.java b/src/main/java/com/epam/ta/reportportal/core/project/DeleteProjectHandler.java
index 4a00ae336d..2aa783949c 100644
--- a/src/main/java/com/epam/ta/reportportal/core/project/DeleteProjectHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/project/DeleteProjectHandler.java
@@ -33,6 +33,7 @@ public interface DeleteProjectHandler {
    * Delete specified project.
    *
    * @param projectId Project id
+   * @param user      {@link ReportPortalUser}
    * @return Result of operation
    * @throws ReportPortalException if project not found
    */
@@ -42,6 +43,7 @@ public interface DeleteProjectHandler {
    * Delete specified project.
    *
    * @param ids projects ids
+   * @param user      {@link ReportPortalUser}
    * @return Bulk result of operation
    * @throws ReportPortalException if project not found
    */
@@ -52,6 +54,7 @@ public interface DeleteProjectHandler {
    *
    * @param projectName Project name
    * @param username    User name
+   * @return {@link OperationCompletionRS} info about operation completion
    */
   OperationCompletionRS deleteProjectIndex(String projectName, String username);
 
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/GetProjectHandler.java b/src/main/java/com/epam/ta/reportportal/core/project/GetProjectHandler.java
index e612bdc2d4..81ee3dc926 100644
--- a/src/main/java/com/epam/ta/reportportal/core/project/GetProjectHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/project/GetProjectHandler.java
@@ -24,93 +24,95 @@
 import com.epam.ta.reportportal.ws.model.project.ProjectResource;
 import com.epam.ta.reportportal.ws.model.user.SearchUserResource;
 import com.epam.ta.reportportal.ws.model.user.UserResource;
-import org.springframework.data.domain.Pageable;
-
-import javax.servlet.http.HttpServletResponse;
 import java.io.OutputStream;
 import java.util.List;
 import java.util.Map;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.data.domain.Pageable;
 
 /**
  * @author Andrei_Ramanchuk
  */
 public interface GetProjectHandler {
 
-	/**
-	 * Get project users info
-	 *
-	 * @param projectName {@link com.epam.ta.reportportal.entity.project.Project#name}
-	 * @param filter      {@link Filter}
-	 * @param pageable    {@link Pageable}
-	 * @return list of {@link UserResource}
-	 */
-	Iterable<UserResource> getProjectUsers(String projectName, Filter filter, Pageable pageable);
-
-	boolean exists(Long id);
-
-	Project get(ReportPortalUser.ProjectDetails projectDetails);
-
-	Project get(Long id);
-
-	Project get(String name);
-
-	/**
-	 * Find project entity without fetching related entities
-	 *
-	 * @param name Project name to search
-	 * @return {@link Project}
-	 */
-	Project getRaw(String name);
-
-	/**
-	 * Get project resource information
-	 *
-	 * @param projectName Project name
-	 * @param user        User
-	 * @return {@link ProjectResource}
-	 */
-	ProjectResource getResource(String projectName, ReportPortalUser user);
-
-	/**
-	 * Get list of specified usernames
-	 *
-	 * @param projectDetails Project name
-	 * @param value          Login
-	 * @return List of found user logins
-	 */
-	List<String> getUserNames(ReportPortalUser.ProjectDetails projectDetails, String value);
-
-	/**
-	 * Performs global search for user
-	 *
-	 * @param value login OR full name of user
-	 * @param projectDetails
-	 * @return List of found user resources
-	 */
-	Iterable<SearchUserResource> getUserNames(String value, ReportPortalUser.ProjectDetails projectDetails, Pageable pageable);
-
-	/**
-	 * Get all project names
-	 *
-	 * @return All project names
-	 */
-	List<String> getAllProjectNames();
-
-	/**
-	 * Get all project names, which contain provided term
-	 *
-	 * @return {@link List} of the {@link com.epam.ta.reportportal.entity.project.Project#name}
-	 */
-	List<String> getAllProjectNamesByTerm(String term);
-
-	/**
-	 * Export Projects info according to the {@link ReportFormat} type
-	 *
-	 * @param reportFormat {@link ReportFormat}
-	 * @param filter       {@link Queryable}
-	 * @param outputStream {@link HttpServletResponse#getOutputStream()}
-	 */
-	void exportProjects(ReportFormat reportFormat, Queryable filter, OutputStream outputStream);
-
-	Map<String, Boolean> getAnalyzerIndexingStatus();
+  /**
+   * Get project users info
+   *
+   * @param projectName {@link com.epam.ta.reportportal.entity.project.Project#name}
+   * @param filter      {@link Filter}
+   * @param pageable    {@link Pageable}
+   * @return list of {@link UserResource}
+   */
+  Iterable<UserResource> getProjectUsers(String projectName, Filter filter, Pageable pageable);
+
+  boolean exists(Long id);
+
+  Project get(ReportPortalUser.ProjectDetails projectDetails);
+
+  Project get(Long id);
+
+  Project get(String name);
+
+  /**
+   * Find project entity without fetching related entities
+   *
+   * @param name Project name to search
+   * @return {@link Project}
+   */
+  Project getRaw(String name);
+
+  /**
+   * Get project resource information
+   *
+   * @param projectName Project name
+   * @param user        User
+   * @return {@link ProjectResource}
+   */
+  ProjectResource getResource(String projectName, ReportPortalUser user);
+
+  /**
+   * Get list of specified usernames
+   *
+   * @param projectDetails Project name
+   * @param value          Login
+   * @return List of found user logins
+   */
+  List<String> getUserNames(ReportPortalUser.ProjectDetails projectDetails, String value);
+
+  /**
+   * Performs global search for user
+   *
+   * @param value          login OR full name of user
+   * @param projectDetails {@link ReportPortalUser.ProjectDetails}
+   * @param pageable       {@link Pageable} Page Details
+   * @return List of found user resources
+   */
+  Iterable<SearchUserResource> getUserNames(String value,
+      ReportPortalUser.ProjectDetails projectDetails, Pageable pageable);
+
+  /**
+   * Get all project names
+   *
+   * @return All project names
+   */
+  List<String> getAllProjectNames();
+
+  /**
+   * Get all project names, which contain provided term
+   *
+   * @param term project term
+   * @return {@link List} of the {@link com.epam.ta.reportportal.entity.project.Project#name}
+   */
+  List<String> getAllProjectNamesByTerm(String term);
+
+  /**
+   * Export Projects info according to the {@link ReportFormat} type
+   *
+   * @param reportFormat {@link ReportFormat}
+   * @param filter       {@link Queryable}
+   * @param outputStream {@link HttpServletResponse#getOutputStream()}
+   */
+  void exportProjects(ReportFormat reportFormat, Queryable filter, OutputStream outputStream);
+
+  Map<String, Boolean> getAnalyzerIndexingStatus();
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/GetProjectInfoHandler.java b/src/main/java/com/epam/ta/reportportal/core/project/GetProjectInfoHandler.java
index d37050ec99..8cc231aed3 100644
--- a/src/main/java/com/epam/ta/reportportal/core/project/GetProjectInfoHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/project/GetProjectInfoHandler.java
@@ -19,42 +19,43 @@
 import com.epam.ta.reportportal.commons.querygen.Queryable;
 import com.epam.ta.reportportal.entity.enums.InfoInterval;
 import com.epam.ta.reportportal.ws.model.project.ProjectInfoResource;
-import org.springframework.data.domain.Pageable;
-
 import java.util.Map;
+import org.springframework.data.domain.Pageable;
 
 /**
- * Get {@link com.epam.ta.reportportal.ws.model.project.ProjectInfoResource}
- * request handler
+ * Get {@link com.epam.ta.reportportal.ws.model.project.ProjectInfoResource} request handler
  *
  * @author Dzmitry_Kavalets
  */
 public interface GetProjectInfoHandler {
 
-	/**
-	 * Get all projects info
-	 *
-	 * @return
-	 */
-	Iterable<ProjectInfoResource> getAllProjectsInfo(Queryable filter, Pageable pageable);
+  /**
+   * Get all projects info
+   *
+   * @param filter  Queryable filter to apply on the projects
+   * @param pageable Pagination information for the results
+   * @return An {@link Iterable} of {@link ProjectInfoResource} containing information about all projects
+   */
+  Iterable<ProjectInfoResource> getAllProjectsInfo(Queryable filter, Pageable pageable);
 
-	/**
-	 * Get project info
-	 *
-	 * @param projectName Project name
-	 * @param interval    Interval
-	 * @return Project info resource
-	 */
-	ProjectInfoResource getProjectInfo(String projectName, String interval);
+  /**
+   * Get project info
+   *
+   * @param projectName Project name
+   * @param interval    Interval
+   * @return Project info resource
+   */
+  ProjectInfoResource getProjectInfo(String projectName, String interval);
 
-	/**
-	 * Get widget data content for specified project by specified
-	 * {@link InfoInterval} and {@link com.epam.ta.reportportal.entity.project.email.ProjectInfoWidget}
-	 *
-	 * @param projectName Project name
-	 * @param interval    Interval
-	 * @param widgetCode  Project Info Widget code
-	 * @return
-	 */
-	Map<String, ?> getProjectInfoWidgetContent(String projectName, String interval, String widgetCode);
+  /**
+   * Get widget data content for specified project by specified {@link InfoInterval} and
+   * {@link com.epam.ta.reportportal.entity.project.email.ProjectInfoWidget}
+   *
+   * @param projectName Project name
+   * @param interval    Interval
+   * @param widgetCode  Project Info Widget code
+   * @return Map of widget data content
+   */
+  Map<String, ?> getProjectInfoWidgetContent(String projectName, String interval,
+      String widgetCode);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/ProjectUserHandler.java b/src/main/java/com/epam/ta/reportportal/core/project/ProjectUserHandler.java
index 62a822c075..ef90e454de 100644
--- a/src/main/java/com/epam/ta/reportportal/core/project/ProjectUserHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/project/ProjectUserHandler.java
@@ -7,5 +7,5 @@
 
 public interface ProjectUserHandler {
 
-  ProjectUser assign(User user, Project project, ProjectRole projectRole, User creator);
+  ProjectUser assign(User user, Project project, ProjectRole projectRole, User creator, boolean isSystemEvent);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/UpdateProjectHandler.java b/src/main/java/com/epam/ta/reportportal/core/project/UpdateProjectHandler.java
index d023355467..784fc1f690 100644
--- a/src/main/java/com/epam/ta/reportportal/core/project/UpdateProjectHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/project/UpdateProjectHandler.java
@@ -17,6 +17,7 @@
 package com.epam.ta.reportportal.core.project;
 
 import com.epam.ta.reportportal.commons.ReportPortalUser;
+import com.epam.ta.reportportal.entity.project.Project;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
 import com.epam.ta.reportportal.ws.model.project.AssignUsersRQ;
@@ -31,55 +32,58 @@
  */
 public interface UpdateProjectHandler {
 
-	/**
-	 * Update specified project(projectName, customer and addInfo)
-	 *
-	 * @param projectName     {@link com.epam.ta.reportportal.entity.project.Project#name}
-	 * @param updateProjectRQ Project data
-	 * @param user            ReportPortal user
-	 * @return Operation result
-	 * @throws ReportPortalException
-	 */
-	OperationCompletionRS updateProject(String projectName, UpdateProjectRQ updateProjectRQ, ReportPortalUser user);
+  /**
+   * Update specified project email configuration
+   *
+   * @param projectName                       Project Name
+   * @param updateProjectNotificationConfigRQ Request Data
+   * @param user                              User performing that update
+   * @return Operation Result
+   */
+  OperationCompletionRS updateProjectNotificationConfig(String projectName, ReportPortalUser user,
+      ProjectNotificationConfigDTO updateProjectNotificationConfigRQ);
 
-	/**
-	 * Update specified project email configuration
-	 *
-	 * @param projectName                       Project Name
-	 * @param updateProjectNotificationConfigRQ Request Data
-	 * @param user                              User performing that update
-	 * @return Operation Result
-	 */
-	OperationCompletionRS updateProjectNotificationConfig(String projectName, ReportPortalUser user,
-			ProjectNotificationConfigDTO updateProjectNotificationConfigRQ);
+  /**
+   * Update specified project(projectName, customer and addInfo)
+   *
+   * @param projectName     {@link Project#getName()}
+   * @param updateProjectRQ Project data
+   * @param user            ReportPortal user
+   * @return Operation result
+   * @throws ReportPortalException in case of error due updating project
+   */
+  OperationCompletionRS updateProject(String projectName, UpdateProjectRQ updateProjectRQ,
+      ReportPortalUser user);
 
-	/**
-	 * Un-assign specified user from project
-	 *
-	 * @param projectName     {@link com.epam.ta.reportportal.entity.project.Project#name}
-	 * @param modifier        Modifier User
-	 * @param unassignUsersRQ Request Data
-	 * @return Operation Result
-	 * @throws ReportPortalException
-	 */
-	OperationCompletionRS unassignUsers(String projectName, UnassignUsersRQ unassignUsersRQ, ReportPortalUser modifier);
+  /**
+   * Un-assign specified user from project
+   *
+   * @param projectName     {@link com.epam.ta.reportportal.entity.project.Project#name}
+   * @param modifier        Modifier User
+   * @param unassignUsersRQ Request Data
+   * @return Operation Result
+   * @throws ReportPortalException in case of error due unassign users
+   */
+  OperationCompletionRS unassignUsers(String projectName, UnassignUsersRQ unassignUsersRQ,
+      ReportPortalUser modifier);
 
-	/**
-	 * Assign specified user from project
-	 *
-	 * @param projectName   {@link com.epam.ta.reportportal.entity.project.Project#name}
-	 * @param modifier      Modifier User
-	 * @param assignUsersRQ Request Data
-	 * @return Operation Result
-	 */
-	OperationCompletionRS assignUsers(String projectName, AssignUsersRQ assignUsersRQ, ReportPortalUser modifier);
+  /**
+   * Assign specified user from project
+   *
+   * @param projectName   {@link com.epam.ta.reportportal.entity.project.Project#name}
+   * @param modifier      Modifier User
+   * @param assignUsersRQ Request Data
+   * @return Operation Result
+   */
+  OperationCompletionRS assignUsers(String projectName, AssignUsersRQ assignUsersRQ,
+      ReportPortalUser modifier);
 
-	/**
-	 * Index logs for specified project
-	 *
-	 * @param projectName Project name
-	 * @param user        User
-	 * @return Operation Result
-	 */
-	OperationCompletionRS indexProjectData(String projectName, ReportPortalUser user);
+  /**
+   * Index logs for specified project
+   *
+   * @param projectName Project name
+   * @param user        User
+   * @return Operation Result
+   */
+  OperationCompletionRS indexProjectData(String projectName, ReportPortalUser user);
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/config/ProjectConfigProvider.java b/src/main/java/com/epam/ta/reportportal/core/project/config/ProjectConfigProvider.java
index 6858097dc5..adcc3566e4 100644
--- a/src/main/java/com/epam/ta/reportportal/core/project/config/ProjectConfigProvider.java
+++ b/src/main/java/com/epam/ta/reportportal/core/project/config/ProjectConfigProvider.java
@@ -19,28 +19,27 @@
 import com.epam.ta.reportportal.core.project.GetProjectHandler;
 import com.epam.ta.reportportal.entity.project.Project;
 import com.epam.ta.reportportal.entity.project.ProjectUtils;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.Map;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class ProjectConfigProvider {
 
-	private final GetProjectHandler getProjectHandler;
+  private final GetProjectHandler getProjectHandler;
 
-	@Autowired
-	public ProjectConfigProvider(GetProjectHandler getProjectHandler) {
-		this.getProjectHandler = getProjectHandler;
-	}
+  @Autowired
+  public ProjectConfigProvider(GetProjectHandler getProjectHandler) {
+    this.getProjectHandler = getProjectHandler;
+  }
 
-	@Transactional(readOnly = true)
-	public Map<String, String> provide(Long projectId) {
-		final Project project = getProjectHandler.get(projectId);
-		return ProjectUtils.getConfigParameters(project.getProjectAttributes());
-	}
+  @Transactional(readOnly = true)
+  public Map<String, String> provide(Long projectId) {
+    final Project project = getProjectHandler.get(projectId);
+    return ProjectUtils.getConfigParameters(project.getProjectAttributes());
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/impl/CreateProjectHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/project/impl/CreateProjectHandlerImpl.java
index e40ce5ecfa..fe7570343d 100644
--- a/src/main/java/com/epam/ta/reportportal/core/project/impl/CreateProjectHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/project/impl/CreateProjectHandlerImpl.java
@@ -20,6 +20,7 @@
 import static com.epam.ta.reportportal.commons.Predicates.isPresent;
 import static com.epam.ta.reportportal.commons.Predicates.not;
 import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.core.events.activity.util.ActivityDetailsUtil.RP_SUBJECT_NAME;
 
 import com.epam.reportportal.extension.event.ProjectEvent;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
@@ -155,7 +156,7 @@ public Project createPersonal(User user) {
     final Project personalProject = personalProjectService.generatePersonalProject(user);
     personalProject.getUsers().clear();
     projectRepository.save(personalProject);
-    publishProjectCreatedEvent(null, "ReportPortal", personalProject);
+    publishProjectCreatedEvent(null, RP_SUBJECT_NAME, personalProject);
     return personalProject;
   }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/impl/DeleteProjectHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/project/impl/DeleteProjectHandlerImpl.java
index 4c3b517afc..db3b6140cc 100644
--- a/src/main/java/com/epam/ta/reportportal/core/project/impl/DeleteProjectHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/project/impl/DeleteProjectHandlerImpl.java
@@ -18,8 +18,10 @@
 
 import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
 import static com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerStatusCache.AUTO_ANALYZER_KEY;
+import static com.epam.ta.reportportal.core.events.activity.util.ActivityDetailsUtil.RP_SUBJECT_NAME;
 import static com.epam.ta.reportportal.ws.converter.converters.ExceptionConverter.TO_ERROR_RS;
 
+import com.epam.ta.reportportal.binary.AttachmentBinaryDataService;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.analyzer.auto.LogIndexer;
 import com.epam.ta.reportportal.core.analyzer.auto.client.AnalyzerServiceClient;
@@ -31,7 +33,6 @@
 import com.epam.ta.reportportal.core.events.activity.ProjectIndexEvent;
 import com.epam.ta.reportportal.core.project.DeleteProjectHandler;
 import com.epam.ta.reportportal.core.remover.ContentRemover;
-import com.epam.ta.reportportal.dao.AttachmentRepository;
 import com.epam.ta.reportportal.dao.IssueTypeRepository;
 import com.epam.ta.reportportal.dao.LogRepository;
 import com.epam.ta.reportportal.dao.ProjectRepository;
@@ -41,6 +42,7 @@
 import com.epam.ta.reportportal.entity.project.ProjectIssueType;
 import com.epam.ta.reportportal.entity.user.User;
 import com.epam.ta.reportportal.exception.ReportPortalException;
+import com.epam.ta.reportportal.util.FeatureFlagHandler;
 import com.epam.ta.reportportal.ws.model.DeleteBulkRS;
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
@@ -78,31 +80,34 @@ public class DeleteProjectHandlerImpl implements DeleteProjectHandler {
 
   private final MessageBus messageBus;
 
-  private final AttachmentRepository attachmentRepository;
-
   private final IssueTypeRepository issueTypeRepository;
 
   private final ContentRemover<Project> projectContentRemover;
 
   private final LogRepository logRepository;
 
+  private final AttachmentBinaryDataService attachmentBinaryDataService;
+
+  private final FeatureFlagHandler featureFlagHandler;
+
   @Autowired
   public DeleteProjectHandlerImpl(ProjectRepository projectRepository,
       UserRepository userRepository, LogIndexer logIndexer,
       AnalyzerServiceClient analyzerServiceClient, AnalyzerStatusCache analyzerStatusCache,
-      MessageBus messageBus,
-      AttachmentRepository attachmentRepository, IssueTypeRepository issueTypeRepository,
-      ContentRemover<Project> projectContentRemover, LogRepository logRepository) {
+      MessageBus messageBus, AttachmentBinaryDataService attachmentBinaryDataService,
+      IssueTypeRepository issueTypeRepository, ContentRemover<Project> projectContentRemover,
+      LogRepository logRepository, FeatureFlagHandler featureFlagHandler) {
     this.projectRepository = projectRepository;
     this.userRepository = userRepository;
     this.logIndexer = logIndexer;
     this.analyzerServiceClient = analyzerServiceClient;
     this.analyzerStatusCache = analyzerStatusCache;
     this.messageBus = messageBus;
-    this.attachmentRepository = attachmentRepository;
     this.issueTypeRepository = issueTypeRepository;
     this.projectContentRemover = projectContentRemover;
     this.logRepository = logRepository;
+    this.featureFlagHandler = featureFlagHandler;
+    this.attachmentBinaryDataService = attachmentBinaryDataService;
   }
 
   @Override
@@ -120,7 +125,7 @@ private void publishSpecialProjectDeletedEvent(ReportPortalUser user, Project pr
       String username = user.getUsername();
       publishProjectDeletedEvent(userId, username, project.getId(), project.getName());
     } else {
-      publishProjectDeletedEvent(null, "ReportPortal", project.getId(), "personal_project");
+      publishProjectDeletedEvent(null, RP_SUBJECT_NAME, project.getId(), "personal_project");
     }
   }
 
@@ -151,21 +156,20 @@ public DeleteBulkRS bulkDeleteProjects(List<Long> ids, ReportPortalUser user) {
     publishProjectBulkDeletedEvent(user, deletedProjectsMap.values());
 
     return new DeleteBulkRS(List.copyOf(deletedProjectsMap.keySet()), Collections.emptyList(),
-        exceptions.stream().map(TO_ERROR_RS).collect(Collectors.toList()));
+        exceptions.stream().map(TO_ERROR_RS).collect(Collectors.toList())
+    );
   }
 
   private void publishProjectBulkDeletedEvent(ReportPortalUser user, Collection<String> names) {
-    ProjectBulkDeletedEvent bulkDeletedEvent = new ProjectBulkDeletedEvent(user.getUserId(),
-        user.getUsername(), names);
+    ProjectBulkDeletedEvent bulkDeletedEvent =
+        new ProjectBulkDeletedEvent(user.getUserId(), user.getUsername(), names);
     messageBus.publishActivity(bulkDeletedEvent);
   }
 
   @Override
   public OperationCompletionRS deleteProjectIndex(String projectName, String username) {
     expect(analyzerServiceClient.hasClients(), Predicate.isEqual(true)).verify(
-        ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
-        "There are no analyzer deployed."
-    );
+        ErrorType.UNABLE_INTERACT_WITH_INTEGRATION, "There are no analyzer deployed.");
 
     Project project = projectRepository.findByName(projectName)
         .orElseThrow(() -> new ReportPortalException(ErrorType.PROJECT_NOT_FOUND, projectName));
@@ -174,7 +178,8 @@ public OperationCompletionRS deleteProjectIndex(String projectName, String usern
         .orElseThrow(() -> new ReportPortalException(ErrorType.USER_NOT_FOUND, username));
 
     expect(AnalyzerUtils.getAnalyzerConfig(project).isIndexingRunning(),
-        Predicate.isEqual(false)).verify(ErrorType.FORBIDDEN_OPERATION,
+        Predicate.isEqual(false)
+    ).verify(ErrorType.FORBIDDEN_OPERATION,
         "Index can not be removed until index generation proceeds."
     );
 
@@ -182,35 +187,33 @@ public OperationCompletionRS deleteProjectIndex(String projectName, String usern
         .orElseThrow(
             () -> new ReportPortalException(ErrorType.ANALYZER_NOT_FOUND, AUTO_ANALYZER_KEY));
     expect(analyzeStatus.asMap().containsValue(project.getId()), Predicate.isEqual(false)).verify(
-        ErrorType.FORBIDDEN_OPERATION,
-        "Index can not be removed until index generation proceeds."
-    );
+        ErrorType.FORBIDDEN_OPERATION, "Index can not be removed until index generation proceeds.");
 
     logIndexer.deleteIndex(project.getId());
     messageBus.publishActivity(
         new ProjectIndexEvent(user.getId(), user.getLogin(), project.getId(), project.getName(),
-            false));
+            false
+        ));
     return new OperationCompletionRS(
         "Project index with name = '" + projectName + "' is successfully deleted.");
   }
 
   private OperationCompletionRS deleteProject(Project project) {
-    Set<Long> defaultIssueTypeIds = issueTypeRepository.getDefaultIssueTypes()
-        .stream()
-        .map(IssueType::getId)
-        .collect(Collectors.toSet());
-    Set<IssueType> issueTypesToRemove = project.getProjectIssueTypes()
-        .stream()
-        .map(ProjectIssueType::getIssueType)
-        .filter(issueType -> !defaultIssueTypeIds.contains(issueType.getId()))
-        .collect(Collectors.toSet());
+    Set<Long> defaultIssueTypeIds =
+        issueTypeRepository.getDefaultIssueTypes().stream().map(IssueType::getId)
+            .collect(Collectors.toSet());
+    Set<IssueType> issueTypesToRemove =
+        project.getProjectIssueTypes().stream().map(ProjectIssueType::getIssueType)
+            .filter(issueType -> !defaultIssueTypeIds.contains(issueType.getId()))
+            .collect(Collectors.toSet());
     projectContentRemover.remove(project);
     projectRepository.delete(project);
     issueTypeRepository.deleteAll(issueTypesToRemove);
     logIndexer.deleteIndex(project.getId());
     analyzerServiceClient.removeSuggest(project.getId());
     logRepository.deleteByProjectId(project.getId());
-    attachmentRepository.moveForDeletionByProjectId(project.getId());
+    attachmentBinaryDataService.deleteAllByProjectId(project.getId());
+
     return new OperationCompletionRS(
         "Project with id = '" + project.getId() + "' has been successfully deleted.");
   }
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/impl/ProjectInfoWidgetDataConverter.java b/src/main/java/com/epam/ta/reportportal/core/project/impl/ProjectInfoWidgetDataConverter.java
index d22228187a..fd5ca58e5f 100644
--- a/src/main/java/com/epam/ta/reportportal/core/project/impl/ProjectInfoWidgetDataConverter.java
+++ b/src/main/java/com/epam/ta/reportportal/core/project/impl/ProjectInfoWidgetDataConverter.java
@@ -16,32 +16,42 @@
 
 package com.epam.ta.reportportal.core.project.impl;
 
+import static com.epam.ta.reportportal.core.project.impl.ProjectInfoWidgetDataConverter.ProjectInfoGroup.BY_DAY;
+import static com.epam.ta.reportportal.core.project.impl.ProjectInfoWidgetDataConverter.ProjectInfoGroup.BY_NAME;
+import static com.epam.ta.reportportal.core.statistics.StatisticsHelper.extractStatisticsCount;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DEFECTS_AUTOMATION_BUG_TOTAL;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DEFECTS_PRODUCT_BUG_TOTAL;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DEFECTS_SYSTEM_ISSUE_TOTAL;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DEFECTS_TO_INVESTIGATE_TOTAL;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.EXECUTIONS_TOTAL;
+import static java.time.temporal.ChronoUnit.DAYS;
+import static java.time.temporal.ChronoUnit.WEEKS;
+
 import com.epam.ta.reportportal.entity.enums.InfoInterval;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.entity.statistics.Statistics;
 import com.epam.ta.reportportal.ws.model.widget.ChartObject;
 import com.google.common.collect.Lists;
-import org.joda.time.DateTime;
-import org.joda.time.DateTimeConstants;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.stereotype.Service;
-
 import java.text.DecimalFormat;
 import java.time.LocalDate;
 import java.time.ZoneOffset;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
 import java.time.temporal.IsoFields;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.DoubleSummaryStatistics;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.Map.Entry;
-
-import static com.epam.ta.reportportal.core.project.impl.ProjectInfoWidgetDataConverter.ProjectInfoGroup.BY_DAY;
-import static com.epam.ta.reportportal.core.project.impl.ProjectInfoWidgetDataConverter.ProjectInfoGroup.BY_NAME;
-import static com.epam.ta.reportportal.core.statistics.StatisticsHelper.extractStatisticsCount;
-import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.*;
-import static java.time.temporal.ChronoUnit.DAYS;
-import static java.time.temporal.ChronoUnit.WEEKS;
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeConstants;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Service;
 
 /**
  * Data converter for Report Portal common UI graphics
@@ -51,251 +61,264 @@
 @Service("projectInfoDataConverter")
 public class ProjectInfoWidgetDataConverter {
 
-	private Map<InfoInterval, ProjectInfoGroup> grouping;
+  private Map<InfoInterval, ProjectInfoGroup> grouping;
 
-	@Autowired
-	public ProjectInfoWidgetDataConverter(@Qualifier("groupingStrategy") Map<InfoInterval, ProjectInfoGroup> grouping) {
-		this.grouping = grouping;
-	}
+  @Autowired
+  public ProjectInfoWidgetDataConverter(
+      @Qualifier("groupingStrategy") Map<InfoInterval, ProjectInfoGroup> grouping) {
+    this.grouping = grouping;
+  }
 
-	public enum ProjectInfoGroup {
-		BY_DAY,
-		BY_WEEK,
-		BY_NAME
-	}
+  public enum ProjectInfoGroup {
+    BY_DAY,
+    BY_WEEK,
+    BY_NAME
+  }
 
-	private static DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendValue(IsoFields.WEEK_BASED_YEAR, 4)
-			.appendLiteral("-W")
-			.appendValue(IsoFields.WEEK_OF_WEEK_BASED_YEAR, 2)
-			.toFormatter();
+  private static DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendValue(
+          IsoFields.WEEK_BASED_YEAR, 4)
+      .appendLiteral("-W")
+      .appendValue(IsoFields.WEEK_OF_WEEK_BASED_YEAR, 2)
+      .toFormatter();
 
-	/**
-	 * <b>Percentage Of Investigation</b> project info widget content
-	 *
-	 * @param initial
-	 * @param interval
-	 * @return
-	 */
-	public Map<String, List<ChartObject>> getInvestigatedProjectInfo(List<Launch> initial, InfoInterval interval) {
-		if (initial.isEmpty()) {
-			return new HashMap<>();
-		}
-		final DecimalFormat formatter = new DecimalFormat("###.##");
-		final String INV = "investigated";
-		final String TI = "toInvestigate";
-		Map<String, List<ChartObject>> result = new HashMap<>();
-		Map<String, List<Launch>> grouped = groupBy(initial, grouping.get(interval));
-		Iterator<Entry<String, List<Launch>>> iterator = grouped.entrySet().iterator();
-		while (iterator.hasNext()) {
-			Entry<String, List<Launch>> pair = iterator.next();
-			double investigated = 0;
-			double toInvestigate = 0;
-			List<Launch> group = pair.getValue();
-			ChartObject currentGroup = new ChartObject();
-			currentGroup.setName(pair.getKey());
-			Map<String, String> values = new HashMap<>();
-			for (Launch one : group) {
-				investigated =
-						investigated + extractStatisticsCount(DEFECTS_PRODUCT_BUG_TOTAL, one.getStatistics()) + extractStatisticsCount(
-								DEFECTS_SYSTEM_ISSUE_TOTAL,
-								one.getStatistics()
-						) + extractStatisticsCount(DEFECTS_AUTOMATION_BUG_TOTAL, one.getStatistics());
-				toInvestigate = toInvestigate + extractStatisticsCount(DEFECTS_TO_INVESTIGATE_TOTAL, one.getStatistics());
-			}
-			if ((investigated + toInvestigate) > 0) {
-				double investigatedPercent = (investigated / (investigated + toInvestigate)) * 100;
-				double toInvestigatePercent = 100 - investigatedPercent;
-				values.put(INV, formatter.format(investigatedPercent));
-				values.put(TI, formatter.format(toInvestigatePercent));
-			} else {
-				values.put(INV, "0");
-				values.put(TI, "0");
-			}
-			currentGroup.setValues(values);
-			result.put(pair.getKey(), Collections.singletonList(currentGroup));
-			iterator.remove();
-		}
-		return result;
-	}
+  /**
+   * <b>Percentage Of Investigation</b> project info widget content
+   *
+   * @param initial   A list of {@link Launch} objects to calculate investigation percentages
+   * @param interval  An {@link InfoInterval} representing the grouping interval (e.g., daily, weekly)
+   * @return A {@link Map} with keys representing interval group names and values containing
+   *         {@link List} of {@link ChartObject} instances with investigated and to-investigate percentage information
+   */
+  public Map<String, List<ChartObject>> getInvestigatedProjectInfo(List<Launch> initial,
+      InfoInterval interval) {
+    if (initial.isEmpty()) {
+      return new HashMap<>();
+    }
+    final DecimalFormat formatter = new DecimalFormat("###.##");
+    final String INV = "investigated";
+    final String TI = "toInvestigate";
+    Map<String, List<ChartObject>> result = new HashMap<>();
+    Map<String, List<Launch>> grouped = groupBy(initial, grouping.get(interval));
+    Iterator<Entry<String, List<Launch>>> iterator = grouped.entrySet().iterator();
+    while (iterator.hasNext()) {
+      Entry<String, List<Launch>> pair = iterator.next();
+      double investigated = 0;
+      double toInvestigate = 0;
+      List<Launch> group = pair.getValue();
+      ChartObject currentGroup = new ChartObject();
+      currentGroup.setName(pair.getKey());
+      Map<String, String> values = new HashMap<>();
+      for (Launch one : group) {
+        investigated =
+            investigated + extractStatisticsCount(DEFECTS_PRODUCT_BUG_TOTAL, one.getStatistics())
+                + extractStatisticsCount(
+                DEFECTS_SYSTEM_ISSUE_TOTAL,
+                one.getStatistics()
+            ) + extractStatisticsCount(DEFECTS_AUTOMATION_BUG_TOTAL, one.getStatistics());
+        toInvestigate = toInvestigate + extractStatisticsCount(DEFECTS_TO_INVESTIGATE_TOTAL,
+            one.getStatistics());
+      }
+      if ((investigated + toInvestigate) > 0) {
+        double investigatedPercent = (investigated / (investigated + toInvestigate)) * 100;
+        double toInvestigatePercent = 100 - investigatedPercent;
+        values.put(INV, formatter.format(investigatedPercent));
+        values.put(TI, formatter.format(toInvestigatePercent));
+      } else {
+        values.put(INV, "0");
+        values.put(TI, "0");
+      }
+      currentGroup.setValues(values);
+      result.put(pair.getKey(), Collections.singletonList(currentGroup));
+      iterator.remove();
+    }
+    return result;
+  }
 
-	/**
-	 * <b>Test-cases statistics in unique launches</b> project info widget
-	 * content data-source
-	 *
-	 * @param initial
-	 * @return
-	 */
-	public Map<String, List<ChartObject>> getTestCasesStatisticsProjectInfo(List<Launch> initial) {
-		DecimalFormat formatter = new DecimalFormat("#####.##");
-		final String MIN = "min";
-		final String MAX = "max";
-		final String AVG = "avg";
-		String globalAverageSeria = "Median value in all unique launches";
+  /**
+   * <b>Test-cases statistics in unique launches</b> project info widget
+   * content data-source
+   *
+   * @param initial A list of {@link Launch} objects to calculate test-case statistics
+   * @return A {@link Map} with keys representing launch names and values containing
+   *         {@link List} of {@link ChartObject} instances with min, max, and average statistics
+   */
+  public Map<String, List<ChartObject>> getTestCasesStatisticsProjectInfo(List<Launch> initial) {
+    DecimalFormat formatter = new DecimalFormat("#####.##");
+    final String MIN = "min";
+    final String MAX = "max";
+    final String AVG = "avg";
+    String globalAverageSeria = "Median value in all unique launches";
 
-		if (initial.isEmpty()) {
-			return new HashMap<>();
-		}
+    if (initial.isEmpty()) {
+      return new HashMap<>();
+    }
 
-		Map<String, List<ChartObject>> result = new HashMap<>();
-		Map<String, List<Launch>> grouped = groupBy(initial, BY_NAME);
-		for (Entry<String, List<Launch>> pair : grouped.entrySet()) {
-			ChartObject singleStat = new ChartObject();
-			singleStat.setName(pair.getKey());
-			Map<String, String> values = new HashMap<>();
-			List<Launch> group = pair.getValue();
+    Map<String, List<ChartObject>> result = new HashMap<>();
+    Map<String, List<Launch>> grouped = groupBy(initial, BY_NAME);
+    for (Entry<String, List<Launch>> pair : grouped.entrySet()) {
+      ChartObject singleStat = new ChartObject();
+      singleStat.setName(pair.getKey());
+      Map<String, String> values = new HashMap<>();
+      List<Launch> group = pair.getValue();
 
-			DoubleSummaryStatistics statistics = group.stream()
-					.mapToDouble(launch -> launch.getStatistics()
-							.stream()
-							.filter(it -> it.getStatisticsField().getName().equalsIgnoreCase(EXECUTIONS_TOTAL))
-							.findFirst()
-							.orElse(new Statistics())
-							.getCounter())
-					.summaryStatistics();
+      DoubleSummaryStatistics statistics = group.stream()
+          .mapToDouble(launch -> launch.getStatistics()
+              .stream()
+              .filter(it -> it.getStatisticsField().getName().equalsIgnoreCase(EXECUTIONS_TOTAL))
+              .findFirst()
+              .orElse(new Statistics())
+              .getCounter())
+          .summaryStatistics();
 
-			values.put(MIN, String.valueOf(statistics.getMin()));
-			values.put(MAX, String.valueOf(statistics.getMax()));
-			values.put(AVG, formatter.format(statistics.getAverage()));
-			singleStat.setValues(values);
+      values.put(MIN, String.valueOf(statistics.getMin()));
+      values.put(MAX, String.valueOf(statistics.getMax()));
+      values.put(AVG, formatter.format(statistics.getAverage()));
+      singleStat.setValues(values);
 
-			result.put(pair.getKey(), Collections.singletonList(singleStat));
-		}
+      result.put(pair.getKey(), Collections.singletonList(singleStat));
+    }
 
-		/*
-		 * Separate label for 'Median value in all unique launches' on the table
-		 */
-		// TODO Implement new MEDIAN calculation!
-		result.put(globalAverageSeria, Collections.singletonList(new ChartObject()));
-		return result;
-	}
+    /*
+     * Separate label for 'Median value in all unique launches' on the table
+     */
+    // TODO Implement new MEDIAN calculation!
+    result.put(globalAverageSeria, Collections.singletonList(new ChartObject()));
+    return result;
+  }
 
-	/**
-	 * <b>Quantity of Launches</b> project info widget content
-	 *
-	 * @param initial
-	 * @param interval
-	 * @return
-	 */
-	public Map<String, List<ChartObject>> getLaunchesQuantity(List<Launch> initial, InfoInterval interval) {
-		final String START_PERIOD = "start";
-		final String END_PERIOD = "end";
-		final String COUNT = "count";
-		final String INTERVAL = "interval";
-		HashMap<String, List<ChartObject>> result = new HashMap<>();
-		if (initial.isEmpty()) {
-			return result;
-		}
-		ProjectInfoGroup criteria = grouping.get(interval);
-		Map<String, List<Launch>> grouped = groupBy(initial, criteria);
-		for (Entry<String, List<Launch>> entry : grouped.entrySet()) {
-			List<Launch> launches = entry.getValue();
-			Integer count = null != launches ? launches.size() : 0;
-			ChartObject group = new ChartObject();
-			Map<String, String> values = new HashMap<>();
-			values.put(COUNT, String.valueOf(count));
-			values.put(INTERVAL, interval.getInterval());
-			if (criteria != BY_DAY) {
-				DateTime parse = DateTime.parse(entry.getKey());
-				// TODO remove Yoda time. replace with JDK8
-				values.put(START_PERIOD, parse.withDayOfWeek(DateTimeConstants.MONDAY).toString("yyy-MM-dd"));
-				values.put(END_PERIOD, parse.withDayOfWeek(DateTimeConstants.SUNDAY).toString("yyy-MM-dd"));
-			} else {
-				values.put(START_PERIOD, entry.getKey());
-			}
-			group.setName("Number of launches");
-			group.setValues(values);
-			result.put(entry.getKey(), Collections.singletonList(group));
-		}
-		return result;
-	}
+  /**
+   * <b>Quantity of Launches</b> project info widget content
+   *
+   * @param initial A list of {@link Launch} objects to calculate the quantity of launches
+   * @param interval An {@link InfoInterval} representing the grouping interval (e.g., daily, weekly)
+   * @return A {@link Map} with keys representing interval group names and values containing
+   *         {@link List} of {@link ChartObject} instances with launch quantity information
+   */
+  public Map<String, List<ChartObject>> getLaunchesQuantity(List<Launch> initial,
+      InfoInterval interval) {
+    final String START_PERIOD = "start";
+    final String END_PERIOD = "end";
+    final String COUNT = "count";
+    final String INTERVAL = "interval";
+    HashMap<String, List<ChartObject>> result = new HashMap<>();
+    if (initial.isEmpty()) {
+      return result;
+    }
+    ProjectInfoGroup criteria = grouping.get(interval);
+    Map<String, List<Launch>> grouped = groupBy(initial, criteria);
+    for (Entry<String, List<Launch>> entry : grouped.entrySet()) {
+      List<Launch> launches = entry.getValue();
+      Integer count = null != launches ? launches.size() : 0;
+      ChartObject group = new ChartObject();
+      Map<String, String> values = new HashMap<>();
+      values.put(COUNT, String.valueOf(count));
+      values.put(INTERVAL, interval.getInterval());
+      if (criteria != BY_DAY) {
+        DateTime parse = DateTime.parse(entry.getKey());
+        // TODO remove Yoda time. replace with JDK8
+        values.put(START_PERIOD,
+            parse.withDayOfWeek(DateTimeConstants.MONDAY).toString("yyy-MM-dd"));
+        values.put(END_PERIOD, parse.withDayOfWeek(DateTimeConstants.SUNDAY).toString("yyy-MM-dd"));
+      } else {
+        values.put(START_PERIOD, entry.getKey());
+      }
+      group.setName("Number of launches");
+      group.setValues(values);
+      result.put(entry.getKey(), Collections.singletonList(group));
+    }
+    return result;
+  }
 
-	/**
-	 * <b>Launch statistics line chart</b> project info widget content
-	 *
-	 * @param initial
-	 * @param interval
-	 * @return
-	 */
-	public Map<String, List<ChartObject>> getLaunchesIssues(List<Launch> initial, InfoInterval interval) {
-		HashMap<String, List<ChartObject>> result = new HashMap<>();
-		if (initial.isEmpty()) {
-			return result;
-		}
-		final String PB = "productBug";
-		final String SI = "systemIssue";
-		final String AB = "automationBug";
-		final String TI = "toInvestigate";
+  /**
+   * <b>Launch statistics line chart</b> project info widget content
+   *
+   * @param initial A list of {@link Launch} objects to calculate the issues
+   * @param interval An {@link InfoInterval} representing the grouping interval (e.g., daily, weekly)
+   * @return A {@link Map} with keys representing interval group names and values containing
+   *         {@link List} of {@link ChartObject} instances with issue count information
+   */
+  public Map<String, List<ChartObject>> getLaunchesIssues(List<Launch> initial,
+      InfoInterval interval) {
+    HashMap<String, List<ChartObject>> result = new HashMap<>();
+    if (initial.isEmpty()) {
+      return result;
+    }
+    final String PB = "productBug";
+    final String SI = "systemIssue";
+    final String AB = "automationBug";
+    final String TI = "toInvestigate";
 
-		ProjectInfoGroup criteria = grouping.get(interval);
-		Map<String, List<Launch>> grouped = groupBy(initial, criteria);
-		for (Entry<String, List<Launch>> entry : grouped.entrySet()) {
-			List<Launch> launches = entry.getValue();
-			Integer pbCount = 0;
-			Integer abCount = 0;
-			Integer siCount = 0;
-			Integer tiCount = 0;
-			for (Launch launch : launches) {
-				pbCount += extractStatisticsCount(DEFECTS_PRODUCT_BUG_TOTAL, launch.getStatistics());
-				abCount += extractStatisticsCount(DEFECTS_AUTOMATION_BUG_TOTAL, launch.getStatistics());
-				siCount += extractStatisticsCount(DEFECTS_SYSTEM_ISSUE_TOTAL, launch.getStatistics());
-				tiCount += extractStatisticsCount(DEFECTS_TO_INVESTIGATE_TOTAL, launch.getStatistics());
-			}
-			ChartObject object = new ChartObject();
-			Map<String, String> values = new HashMap<>();
-			values.put(PB, String.valueOf(pbCount));
-			values.put(SI, String.valueOf(siCount));
-			values.put(AB, String.valueOf(abCount));
-			values.put(TI, String.valueOf(tiCount));
-			object.setValues(values);
-			result.put(entry.getKey(), Collections.singletonList(object));
-		}
-		return result;
-	}
+    ProjectInfoGroup criteria = grouping.get(interval);
+    Map<String, List<Launch>> grouped = groupBy(initial, criteria);
+    for (Entry<String, List<Launch>> entry : grouped.entrySet()) {
+      List<Launch> launches = entry.getValue();
+      Integer pbCount = 0;
+      Integer abCount = 0;
+      Integer siCount = 0;
+      Integer tiCount = 0;
+      for (Launch launch : launches) {
+        pbCount += extractStatisticsCount(DEFECTS_PRODUCT_BUG_TOTAL, launch.getStatistics());
+        abCount += extractStatisticsCount(DEFECTS_AUTOMATION_BUG_TOTAL, launch.getStatistics());
+        siCount += extractStatisticsCount(DEFECTS_SYSTEM_ISSUE_TOTAL, launch.getStatistics());
+        tiCount += extractStatisticsCount(DEFECTS_TO_INVESTIGATE_TOTAL, launch.getStatistics());
+      }
+      ChartObject object = new ChartObject();
+      Map<String, String> values = new HashMap<>();
+      values.put(PB, String.valueOf(pbCount));
+      values.put(SI, String.valueOf(siCount));
+      values.put(AB, String.valueOf(abCount));
+      values.put(TI, String.valueOf(tiCount));
+      object.setValues(values);
+      result.put(entry.getKey(), Collections.singletonList(object));
+    }
+    return result;
+  }
 
-	/**
-	 * Utility method for grouping input list of {@link Launch} by
-	 * {@link ProjectInfoGroup} criteria
-	 *
-	 * @param initial
-	 * @param criteria
-	 * @return
-	 */
-	private static Map<String, List<Launch>> groupBy(List<Launch> initial, ProjectInfoGroup criteria) {
-		Map<String, List<Launch>> result = new LinkedHashMap<>();
-		LocalDate prevDate = null;
-		for (Launch launch : initial) {
-			final LocalDate localDate = launch.getStartTime().atZone(ZoneOffset.UTC).toLocalDate();
+  /**
+   * Utility method for grouping input list of {@link Launch} by {@link ProjectInfoGroup} criteria
+   *
+   * @param initial  A list of {@link Launch} objects to be grouped
+   * @param criteria The {@link ProjectInfoGroup} criteria that determines the grouping key
+   * @return A map where the keys represent the grouping parameters (e.g., launch names or formatted dates)
+   *         and the values are lists of {@link Launch} objects grouped under that key
+   */
+  private static Map<String, List<Launch>> groupBy(List<Launch> initial,
+      ProjectInfoGroup criteria) {
+    Map<String, List<Launch>> result = new LinkedHashMap<>();
+    LocalDate prevDate = null;
+    for (Launch launch : initial) {
+      final LocalDate localDate = launch.getStartTime().atZone(ZoneOffset.UTC).toLocalDate();
 
-			String key;
-			switch (criteria) {
-				case BY_NAME:
-					key = launch.getName();
-					break;
-				default:
-					key = formattedDate(criteria, localDate);
-					if (prevDate != null) {
-						while (prevDate.isBefore(localDate)) {
-							if (!result.containsKey(formattedDate(criteria, prevDate))) {
-								result.put(formattedDate(criteria, prevDate), new ArrayList<>());
-							}
-							prevDate = prevDate.plus(1, criteria == BY_DAY ? DAYS : WEEKS);
-						}
-					}
-			}
-			if (!result.containsKey(key)) {
-				result.put(key, Lists.newArrayList(launch));
-			} else {
-				List<Launch> prev = result.get(key);
-				prev.add(launch);
-				result.put(key, prev);
-			}
-			prevDate = localDate;
-		}
-		return result;
-	}
+      String key;
+      switch (criteria) {
+        case BY_NAME:
+          key = launch.getName();
+          break;
+        default:
+          key = formattedDate(criteria, localDate);
+          if (prevDate != null) {
+            while (prevDate.isBefore(localDate)) {
+              if (!result.containsKey(formattedDate(criteria, prevDate))) {
+                result.put(formattedDate(criteria, prevDate), new ArrayList<>());
+              }
+              prevDate = prevDate.plus(1, criteria == BY_DAY ? DAYS : WEEKS);
+            }
+          }
+      }
+      if (!result.containsKey(key)) {
+        result.put(key, Lists.newArrayList(launch));
+      } else {
+        List<Launch> prev = result.get(key);
+        prev.add(launch);
+        result.put(key, prev);
+      }
+      prevDate = localDate;
+    }
+    return result;
+  }
 
-	private static String formattedDate(ProjectInfoGroup criteria, LocalDate localDate) {
-		return criteria == BY_DAY ? localDate.toString() : formatter.format(localDate);
-	}
+  private static String formattedDate(ProjectInfoGroup criteria, LocalDate localDate) {
+    return criteria == BY_DAY ? localDate.toString() : formatter.format(localDate);
+  }
 
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/impl/ProjectUserHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/project/impl/ProjectUserHandlerImpl.java
index 2859370b15..671868258d 100644
--- a/src/main/java/com/epam/ta/reportportal/core/project/impl/ProjectUserHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/project/impl/ProjectUserHandlerImpl.java
@@ -26,14 +26,15 @@ public ProjectUserHandlerImpl(ApplicationEventPublisher eventPublisher,
   }
 
   @Override
-  public ProjectUser assign(User user, Project project, ProjectRole projectRole, User creator) {
+  public ProjectUser assign(User user, Project project, ProjectRole projectRole, User creator,
+      boolean isSystemEvent) {
     final ProjectUser projectUser = new ProjectUser().withProjectRole(projectRole)
         .withUser(user)
         .withProject(project);
     projectUserRepository.save(projectUser);
 
     AssignUserEvent assignUserEvent = new AssignUserEvent(getUserActivityResource(user, project),
-        creator.getId(), creator.getLogin());
+        creator.getId(), creator.getLogin(), isSystemEvent);
     eventPublisher.publishEvent(assignUserEvent);
 
     return projectUser;
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/impl/UpdateProjectHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/project/impl/UpdateProjectHandlerImpl.java
index e14bb10ac9..685702ac58 100644
--- a/src/main/java/com/epam/ta/reportportal/core/project/impl/UpdateProjectHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/project/impl/UpdateProjectHandlerImpl.java
@@ -421,7 +421,8 @@ private void assignUser(String name, ProjectRole projectRole, List<String> assig
     AssignUserEvent assignUserEvent = new AssignUserEvent(
         convertUserToResource(modifyingUser, projectUser),
         authorizedUser.getUserId(),
-        authorizedUser.getUsername());
+        authorizedUser.getUsername(),
+        false);
     applicationEventPublisher.publishEvent(assignUserEvent);
   }
 
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/settings/CreateProjectSettingsHandler.java b/src/main/java/com/epam/ta/reportportal/core/project/settings/CreateProjectSettingsHandler.java
index 07ebde0a09..e0e3297479 100644
--- a/src/main/java/com/epam/ta/reportportal/core/project/settings/CreateProjectSettingsHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/project/settings/CreateProjectSettingsHandler.java
@@ -27,23 +27,25 @@
  */
 public interface CreateProjectSettingsHandler {
 
-	/**
-	 * Create issue sub-type for specified project
-	 *
-	 * @param projectName Project name
-	 * @param user        User
-	 * @param rq          Create issue sub type rq
-	 * @return EntryCreatedRS
-	 */
-	IssueSubTypeCreatedRS createProjectIssueSubType(String projectName, ReportPortalUser user, CreateIssueSubTypeRQ rq);
+  /**
+   * Create issue sub-type for specified project
+   *
+   * @param projectName Project name
+   * @param user        User
+   * @param rq          Create issue sub type rq
+   * @return EntryCreatedRS
+   */
+  IssueSubTypeCreatedRS createProjectIssueSubType(String projectName, ReportPortalUser user,
+      CreateIssueSubTypeRQ rq);
 
-	/**
-	 * Create {@link com.epam.ta.reportportal.entity.pattern.PatternTemplate} entity
-	 *
-	 * @param projectName             {@link com.epam.ta.reportportal.entity.project.Project#name}
-	 * @param createPatternTemplateRQ {@link CreatePatternTemplateRQ}
-	 * @param user                    {@link ReportPortalUser}
-	 * @return {@link EntryCreatedRS}
-	 */
-	EntryCreatedRS createPatternTemplate(String projectName, CreatePatternTemplateRQ createPatternTemplateRQ, ReportPortalUser user);
+  /**
+   * Create {@link com.epam.ta.reportportal.entity.pattern.PatternTemplate} entity
+   *
+   * @param projectName             {@link com.epam.ta.reportportal.entity.project.Project#name}
+   * @param createPatternTemplateRQ {@link CreatePatternTemplateRQ}
+   * @param user                    {@link ReportPortalUser}
+   * @return {@link EntryCreatedRS}
+   */
+  EntryCreatedRS createPatternTemplate(String projectName,
+      CreatePatternTemplateRQ createPatternTemplateRQ, ReportPortalUser user);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/settings/DeleteProjectSettingsHandler.java b/src/main/java/com/epam/ta/reportportal/core/project/settings/DeleteProjectSettingsHandler.java
index 983b2844f3..92cc4db052 100644
--- a/src/main/java/com/epam/ta/reportportal/core/project/settings/DeleteProjectSettingsHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/project/settings/DeleteProjectSettingsHandler.java
@@ -24,24 +24,25 @@
  */
 public interface DeleteProjectSettingsHandler {
 
-	/**
-	 * Remove specified issue sub-type for specified project
-	 *
-	 * @param projectName Project name
-	 * @param user        User
-	 * @param id          Issue id
-	 * @return OperationCompletionRS
-	 */
-	OperationCompletionRS deleteProjectIssueSubType(String projectName, ReportPortalUser user, Long id);
+  /**
+   * Remove specified issue sub-type for specified project
+   *
+   * @param projectName Project name
+   * @param user        User
+   * @param id          Issue id
+   * @return OperationCompletionRS
+   */
+  OperationCompletionRS deleteProjectIssueSubType(String projectName, ReportPortalUser user,
+      Long id);
 
-	/**
-	 * Delete {@link com.epam.ta.reportportal.entity.pattern.PatternTemplate} by ID and project ID
-	 *
-	 * @param projectName {@link com.epam.ta.reportportal.entity.project.Project#name}
-	 * @param user        {@link ReportPortalUser}
-	 * @param id          {@link com.epam.ta.reportportal.entity.pattern.PatternTemplate#id}
-	 * @return {@link OperationCompletionRS}
-	 */
-	OperationCompletionRS deletePatternTemplate(String projectName, ReportPortalUser user, Long id);
+  /**
+   * Delete {@link com.epam.ta.reportportal.entity.pattern.PatternTemplate} by ID and project ID
+   *
+   * @param projectName {@link com.epam.ta.reportportal.entity.project.Project#name}
+   * @param user        {@link ReportPortalUser}
+   * @param id          {@link com.epam.ta.reportportal.entity.pattern.PatternTemplate#id}
+   * @return {@link OperationCompletionRS}
+   */
+  OperationCompletionRS deletePatternTemplate(String projectName, ReportPortalUser user, Long id);
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/settings/GetProjectSettingsHandler.java b/src/main/java/com/epam/ta/reportportal/core/project/settings/GetProjectSettingsHandler.java
index 11c96bfede..f3b4e0f644 100644
--- a/src/main/java/com/epam/ta/reportportal/core/project/settings/GetProjectSettingsHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/project/settings/GetProjectSettingsHandler.java
@@ -23,11 +23,11 @@
  */
 public interface GetProjectSettingsHandler {
 
-	/**
-	 * Provide additional settings for specified project
-	 *
-	 * @param projectName Project name
-	 * @return ProjectSettingsResource
-	 */
-	ProjectSettingsResource getProjectSettings(String projectName);
+  /**
+   * Provide additional settings for specified project
+   *
+   * @param projectName Project name
+   * @return ProjectSettingsResource
+   */
+  ProjectSettingsResource getProjectSettings(String projectName);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/settings/UpdateProjectSettingsHandler.java b/src/main/java/com/epam/ta/reportportal/core/project/settings/UpdateProjectSettingsHandler.java
index 6bc5dbd709..91461da027 100644
--- a/src/main/java/com/epam/ta/reportportal/core/project/settings/UpdateProjectSettingsHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/project/settings/UpdateProjectSettingsHandler.java
@@ -26,23 +26,27 @@
  */
 public interface UpdateProjectSettingsHandler {
 
-	/**
-	 * Update issue sub-type for specified project
-	 *
-	 * @param projectName Project name
-	 * @param rq          Update rq
-	 * @return OperationCompletionRS
-	 */
-	OperationCompletionRS updateProjectIssueSubType(String projectName, ReportPortalUser user, UpdateIssueSubTypeRQ rq);
+  /**
+   * Update issue sub-type for specified project
+   *
+   * @param projectName Project name
+   * @param user        {@link ReportPortalUser}
+   * @param rq          Update rq
+   * @return OperationCompletionRS
+   */
+  OperationCompletionRS updateProjectIssueSubType(String projectName, ReportPortalUser user,
+      UpdateIssueSubTypeRQ rq);
 
-	/**
-	 * Update {@link com.epam.ta.reportportal.entity.pattern.PatternTemplate} by ID and project ID
-	 *
-	 * @param projectName             {@link com.epam.ta.reportportal.entity.project.Project#name}
-	 * @param updatePatternTemplateRQ {@link UpdatePatternTemplateRQ}
-	 * @param user                    {@link ReportPortalUser}
-	 * @return {@link OperationCompletionRS}
-	 */
-	OperationCompletionRS updatePatternTemplate(Long id, String projectName, UpdatePatternTemplateRQ updatePatternTemplateRQ,
-			ReportPortalUser user);
+  /**
+   * Update {@link com.epam.ta.reportportal.entity.pattern.PatternTemplate} by ID and project ID
+   *
+   * @param projectName             {@link com.epam.ta.reportportal.entity.project.Project#name}
+   * @param updatePatternTemplateRQ {@link UpdatePatternTemplateRQ}
+   * @param user                    {@link ReportPortalUser}
+   * @param id                      id of pattern template
+   * @return {@link OperationCompletionRS}
+   */
+  OperationCompletionRS updatePatternTemplate(Long id, String projectName,
+      UpdatePatternTemplateRQ updatePatternTemplateRQ,
+      ReportPortalUser user);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/settings/impl/CreateProjectSettingsHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/project/settings/impl/CreateProjectSettingsHandlerImpl.java
index 979501b713..7389c85fb6 100644
--- a/src/main/java/com/epam/ta/reportportal/core/project/settings/impl/CreateProjectSettingsHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/project/settings/impl/CreateProjectSettingsHandlerImpl.java
@@ -1,201 +1,212 @@
-/*
- * Copyright 2019 EPAM Systems
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.epam.ta.reportportal.core.project.settings.impl;
-
-import com.epam.ta.reportportal.commons.ReportPortalUser;
-import com.epam.ta.reportportal.commons.validation.Suppliers;
-import com.epam.ta.reportportal.core.analyzer.pattern.CreatePatternTemplateHandler;
-import com.epam.ta.reportportal.core.events.MessageBus;
-import com.epam.ta.reportportal.core.events.activity.DefectTypeCreatedEvent;
-import com.epam.ta.reportportal.core.events.activity.PatternCreatedEvent;
-import com.epam.ta.reportportal.core.project.settings.CreateProjectSettingsHandler;
-import com.epam.ta.reportportal.dao.IssueGroupRepository;
-import com.epam.ta.reportportal.dao.IssueTypeRepository;
-import com.epam.ta.reportportal.dao.ProjectRepository;
-import com.epam.ta.reportportal.dao.WidgetRepository;
-import com.epam.ta.reportportal.entity.enums.TestItemIssueGroup;
-import com.epam.ta.reportportal.entity.item.issue.IssueGroup;
-import com.epam.ta.reportportal.entity.item.issue.IssueType;
-import com.epam.ta.reportportal.entity.pattern.PatternTemplate;
-import com.epam.ta.reportportal.entity.pattern.PatternTemplateType;
-import com.epam.ta.reportportal.entity.project.Project;
-import com.epam.ta.reportportal.entity.project.ProjectIssueType;
-import com.epam.ta.reportportal.entity.widget.Widget;
-import com.epam.ta.reportportal.entity.widget.WidgetType;
-import com.epam.ta.reportportal.exception.ReportPortalException;
-import com.epam.ta.reportportal.ws.converter.builders.IssueTypeBuilder;
-import com.epam.ta.reportportal.ws.converter.converters.PatternTemplateConverter;
-import com.epam.ta.reportportal.ws.model.EntryCreatedRS;
-import com.epam.ta.reportportal.ws.model.ErrorType;
-import com.epam.ta.reportportal.ws.model.ValidationConstraints;
-import com.epam.ta.reportportal.ws.model.project.config.CreateIssueSubTypeRQ;
-import com.epam.ta.reportportal.ws.model.project.config.IssueSubTypeCreatedRS;
-import com.epam.ta.reportportal.ws.model.project.config.pattern.CreatePatternTemplateRQ;
-import com.google.common.base.Charsets;
-import com.google.common.collect.ImmutableMap;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.*;
-import static com.epam.ta.reportportal.ws.converter.converters.IssueTypeConverter.TO_ACTIVITY_RESOURCE;
-import static com.epam.ta.reportportal.ws.model.ErrorType.*;
-
-/**
- * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
- */
-@Service
-@Transactional
-public class CreateProjectSettingsHandlerImpl implements CreateProjectSettingsHandler {
-
-	private static final Map<String, String> PREFIX = ImmutableMap.<String, String>builder().put(AUTOMATION_BUG.getValue(), "ab_")
-			.put(PRODUCT_BUG.getValue(), "pb_")
-			.put(SYSTEM_ISSUE.getValue(), "si_")
-			.put(NO_DEFECT.getValue(), "nd_")
-			.put(TO_INVESTIGATE.getValue(), "ti_")
-			.build();
-
-	private final ProjectRepository projectRepository;
-
-	private final WidgetRepository widgetRepository;
-
-	private final IssueGroupRepository issueGroupRepository;
-
-	private final IssueTypeRepository issueTypeRepository;
-
-	private final Map<PatternTemplateType, CreatePatternTemplateHandler> createPatternTemplateMapping;
-
-	private final MessageBus messageBus;
-
-	@Autowired
-	public CreateProjectSettingsHandlerImpl(ProjectRepository projectRepository, WidgetRepository widgetRepository,
-			IssueGroupRepository issueGroupRepository, IssueTypeRepository issueTypeRepository,
-			@Qualifier("createPatternTemplateMapping") Map<PatternTemplateType, CreatePatternTemplateHandler> createPatternTemplateMapping,
-			MessageBus messageBus) {
-		this.projectRepository = projectRepository;
-		this.widgetRepository = widgetRepository;
-		this.issueGroupRepository = issueGroupRepository;
-		this.issueTypeRepository = issueTypeRepository;
-		this.createPatternTemplateMapping = createPatternTemplateMapping;
-		this.messageBus = messageBus;
-	}
-
-	@Override
-	public IssueSubTypeCreatedRS createProjectIssueSubType(String projectName, ReportPortalUser user, CreateIssueSubTypeRQ rq) {
-		Project project = projectRepository.findByName(projectName)
-				.orElseThrow(() -> new ReportPortalException(PROJECT_NOT_FOUND, projectName));
-
-		expect(NOT_ISSUE_FLAG.getValue().equalsIgnoreCase(rq.getTypeRef()), equalTo(false)).verify(INCORRECT_REQUEST,
-				"Impossible to create sub-type for 'Not Issue' type."
-		);
-
-		/* Check if global issue type reference is valid */
-		TestItemIssueGroup expectedGroup = TestItemIssueGroup.fromValue(rq.getTypeRef())
-				.orElseThrow(() -> new ReportPortalException(BAD_REQUEST_ERROR, rq.getTypeRef()));
-
-		List<ProjectIssueType> existingSubTypes = project.getProjectIssueTypes()
-				.stream()
-				.filter(projectIssueType -> projectIssueType.getIssueType().getIssueGroup().getTestItemIssueGroup().equals(expectedGroup))
-				.collect(Collectors.toList());
-
-		expect(existingSubTypes.size() < ValidationConstraints.MAX_ISSUE_SUBTYPES, equalTo(true)).verify(INCORRECT_REQUEST,
-				"Sub Issues count is bound of size limit"
-		);
-
-		String locator = PREFIX.get(expectedGroup.getValue()) + shortUUID();
-		IssueType subType = new IssueTypeBuilder().addLocator(locator)
-				.addIssueGroup(issueGroupRepository.findByTestItemIssueGroup(expectedGroup))
-				.addLongName(rq.getLongName())
-				.addShortName(rq.getShortName())
-				.addHexColor(rq.getColor())
-				.get();
-
-		ProjectIssueType projectIssueType = new ProjectIssueType();
-		projectIssueType.setIssueType(subType);
-		projectIssueType.setProject(project);
-
-		project.getProjectIssueTypes().add(projectIssueType);
-
-		issueTypeRepository.save(subType);
-		projectRepository.save(project);
-
-		updateWidgets(project, subType);
-
-		messageBus.publishActivity(new DefectTypeCreatedEvent(TO_ACTIVITY_RESOURCE.apply(subType),
-				user.getUserId(),
-				user.getUsername(),
-				project.getId()
-		));
-		return new IssueSubTypeCreatedRS(subType.getId(), subType.getLocator());
-	}
-
-	/**
-	 * Update {@link Widget#getContentFields()} of the widgets that support issue type updates ({@link WidgetType#isSupportMultilevelStructure()})
-	 * and have content fields for the same {@link IssueGroup#getTestItemIssueGroup()} as provided issueType
-	 *
-	 * @param project   {@link Project}
-	 * @param issueType {@link IssueType}
-	 */
-	private void updateWidgets(Project project, IssueType issueType) {
-		String issueGroupContentField =
-				"statistics$defects$" + issueType.getIssueGroup().getTestItemIssueGroup().getValue().toLowerCase() + "$";
-		widgetRepository.findAllByProjectIdAndWidgetTypeInAndContentFieldContaining(project.getId(),
-				Arrays.stream(WidgetType.values())
-						.filter(WidgetType::isIssueTypeUpdateSupported)
-						.map(WidgetType::getType)
-						.collect(Collectors.toList()),
-				issueGroupContentField
-		).forEach(widget -> {
-			widget.getContentFields().add(issueGroupContentField + issueType.getLocator());
-			widgetRepository.save(widget);
-		});
-	}
-
-	@Override
-	public EntryCreatedRS createPatternTemplate(String projectName, CreatePatternTemplateRQ createPatternTemplateRQ,
-			ReportPortalUser user) {
-
-		Project project = projectRepository.findByName(projectName)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.PROJECT_NOT_FOUND, projectName));
-
-		PatternTemplate patternTemplate = createPatternTemplateMapping.get(PatternTemplateType.fromString(createPatternTemplateRQ.getType())
-				.orElseThrow(() -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR,
-						Suppliers.formattedSupplier("Unknown pattern template type - '{}'", createPatternTemplateRQ.getType()).get()
-				))).createPatternTemplate(project.getId(), createPatternTemplateRQ);
-
-		messageBus.publishActivity(new PatternCreatedEvent(user.getUserId(),
-				user.getUsername(),
-				PatternTemplateConverter.TO_ACTIVITY_RESOURCE.apply(patternTemplate)
-		));
-		return new EntryCreatedRS(patternTemplate.getId());
-	}
-
-	private static String shortUUID() {
-		long l = ByteBuffer.wrap(UUID.randomUUID().toString().getBytes(Charsets.UTF_8)).getLong();
-		return Long.toString(l, Character.MAX_RADIX);
-	}
-}
+/*
+ * Copyright 2019 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.core.project.settings.impl;
+
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.AUTOMATION_BUG;
+import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.NOT_ISSUE_FLAG;
+import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.NO_DEFECT;
+import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.PRODUCT_BUG;
+import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.SYSTEM_ISSUE;
+import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.TO_INVESTIGATE;
+import static com.epam.ta.reportportal.ws.converter.converters.IssueTypeConverter.TO_ACTIVITY_RESOURCE;
+import static com.epam.ta.reportportal.ws.model.ErrorType.BAD_REQUEST_ERROR;
+import static com.epam.ta.reportportal.ws.model.ErrorType.INCORRECT_REQUEST;
+import static com.epam.ta.reportportal.ws.model.ErrorType.PROJECT_NOT_FOUND;
+
+import com.epam.ta.reportportal.commons.ReportPortalUser;
+import com.epam.ta.reportportal.commons.validation.Suppliers;
+import com.epam.ta.reportportal.core.analyzer.pattern.service.CreatePatternTemplateHandler;
+import com.epam.ta.reportportal.core.events.MessageBus;
+import com.epam.ta.reportportal.core.events.activity.DefectTypeCreatedEvent;
+import com.epam.ta.reportportal.core.events.activity.PatternCreatedEvent;
+import com.epam.ta.reportportal.core.project.settings.CreateProjectSettingsHandler;
+import com.epam.ta.reportportal.dao.IssueGroupRepository;
+import com.epam.ta.reportportal.dao.IssueTypeRepository;
+import com.epam.ta.reportportal.dao.ProjectRepository;
+import com.epam.ta.reportportal.dao.WidgetRepository;
+import com.epam.ta.reportportal.entity.enums.TestItemIssueGroup;
+import com.epam.ta.reportportal.entity.item.issue.IssueGroup;
+import com.epam.ta.reportportal.entity.item.issue.IssueType;
+import com.epam.ta.reportportal.entity.pattern.PatternTemplate;
+import com.epam.ta.reportportal.entity.pattern.PatternTemplateType;
+import com.epam.ta.reportportal.entity.project.Project;
+import com.epam.ta.reportportal.entity.project.ProjectIssueType;
+import com.epam.ta.reportportal.entity.widget.Widget;
+import com.epam.ta.reportportal.entity.widget.WidgetType;
+import com.epam.ta.reportportal.exception.ReportPortalException;
+import com.epam.ta.reportportal.ws.converter.builders.IssueTypeBuilder;
+import com.epam.ta.reportportal.ws.converter.converters.PatternTemplateConverter;
+import com.epam.ta.reportportal.ws.model.EntryCreatedRS;
+import com.epam.ta.reportportal.ws.model.ErrorType;
+import com.epam.ta.reportportal.ws.model.ValidationConstraints;
+import com.epam.ta.reportportal.ws.model.project.config.CreateIssueSubTypeRQ;
+import com.epam.ta.reportportal.ws.model.project.config.IssueSubTypeCreatedRS;
+import com.epam.ta.reportportal.ws.model.project.config.pattern.CreatePatternTemplateRQ;
+import com.google.common.base.Charsets;
+import com.google.common.collect.ImmutableMap;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.UUID;
+import java.util.stream.Collectors;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
+ */
+@Service
+@Transactional
+public class CreateProjectSettingsHandlerImpl implements CreateProjectSettingsHandler {
+
+  private static final Map<String, String> PREFIX = ImmutableMap.<String, String>builder()
+      .put(AUTOMATION_BUG.getValue(), "ab_")
+      .put(PRODUCT_BUG.getValue(), "pb_")
+      .put(SYSTEM_ISSUE.getValue(), "si_")
+      .put(NO_DEFECT.getValue(), "nd_")
+      .put(TO_INVESTIGATE.getValue(), "ti_")
+      .build();
+
+  private final ProjectRepository projectRepository;
+
+  private final WidgetRepository widgetRepository;
+
+  private final IssueGroupRepository issueGroupRepository;
+
+  private final IssueTypeRepository issueTypeRepository;
+
+  private final Map<PatternTemplateType, CreatePatternTemplateHandler> createPatternTemplateMapping;
+
+  private final MessageBus messageBus;
+
+  @Autowired
+  public CreateProjectSettingsHandlerImpl(ProjectRepository projectRepository,
+      WidgetRepository widgetRepository,
+      IssueGroupRepository issueGroupRepository, IssueTypeRepository issueTypeRepository,
+      @Qualifier("createPatternTemplateMapping") Map<PatternTemplateType, CreatePatternTemplateHandler> createPatternTemplateMapping,
+      MessageBus messageBus) {
+    this.projectRepository = projectRepository;
+    this.widgetRepository = widgetRepository;
+    this.issueGroupRepository = issueGroupRepository;
+    this.issueTypeRepository = issueTypeRepository;
+    this.createPatternTemplateMapping = createPatternTemplateMapping;
+    this.messageBus = messageBus;
+  }
+
+  @Override
+  public IssueSubTypeCreatedRS createProjectIssueSubType(String projectName, ReportPortalUser user,
+      CreateIssueSubTypeRQ rq) {
+    Project project = projectRepository.findByName(projectName)
+        .orElseThrow(() -> new ReportPortalException(PROJECT_NOT_FOUND, projectName));
+
+    expect(NOT_ISSUE_FLAG.getValue().equalsIgnoreCase(rq.getTypeRef()), equalTo(false)).verify(
+        INCORRECT_REQUEST,
+        "Impossible to create sub-type for 'Not Issue' type."
+    );
+
+    /* Check if global issue type reference is valid */
+    TestItemIssueGroup expectedGroup = TestItemIssueGroup.fromValue(rq.getTypeRef())
+        .orElseThrow(() -> new ReportPortalException(BAD_REQUEST_ERROR, rq.getTypeRef()));
+
+    expect(
+        project.getProjectIssueTypes().size() < ValidationConstraints.MAX_ISSUE_TYPES_AND_SUBTYPES,
+        equalTo(true)).verify(INCORRECT_REQUEST,
+        "Sub Issues count is bound of size limit"
+    );
+
+    String locator = PREFIX.get(expectedGroup.getValue()) + shortUUID();
+    IssueType subType = new IssueTypeBuilder().addLocator(locator)
+        .addIssueGroup(issueGroupRepository.findByTestItemIssueGroup(expectedGroup))
+        .addLongName(rq.getLongName())
+        .addShortName(rq.getShortName())
+        .addHexColor(rq.getColor())
+        .get();
+
+    ProjectIssueType projectIssueType = new ProjectIssueType();
+    projectIssueType.setIssueType(subType);
+    projectIssueType.setProject(project);
+
+    project.getProjectIssueTypes().add(projectIssueType);
+
+    issueTypeRepository.save(subType);
+    projectRepository.save(project);
+
+    updateWidgets(project, subType);
+
+    messageBus.publishActivity(new DefectTypeCreatedEvent(TO_ACTIVITY_RESOURCE.apply(subType),
+        user.getUserId(),
+        user.getUsername(),
+        project.getId()
+    ));
+    return new IssueSubTypeCreatedRS(subType.getId(), subType.getLocator());
+  }
+
+  /**
+   * Update {@link Widget#getContentFields()} of the widgets that support issue type updates
+   * ({@link WidgetType#isSupportMultilevelStructure()}) and have content fields for the same
+   * {@link IssueGroup#getTestItemIssueGroup()} as provided issueType
+   *
+   * @param project   {@link Project}
+   * @param issueType {@link IssueType}
+   */
+  private void updateWidgets(Project project, IssueType issueType) {
+    String issueGroupContentField =
+        "statistics$defects$" + issueType.getIssueGroup().getTestItemIssueGroup().getValue()
+            .toLowerCase() + "$";
+    widgetRepository.findAllByProjectIdAndWidgetTypeInAndContentFieldContaining(project.getId(),
+        Arrays.stream(WidgetType.values())
+            .filter(WidgetType::isIssueTypeUpdateSupported)
+            .map(WidgetType::getType)
+            .collect(Collectors.toList()),
+        issueGroupContentField
+    ).forEach(widget -> {
+      widget.getContentFields().add(issueGroupContentField + issueType.getLocator());
+      widgetRepository.save(widget);
+    });
+  }
+
+  @Override
+  public EntryCreatedRS createPatternTemplate(String projectName,
+      CreatePatternTemplateRQ createPatternTemplateRQ,
+      ReportPortalUser user) {
+
+    Project project = projectRepository.findByName(projectName)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.PROJECT_NOT_FOUND, projectName));
+
+    PatternTemplate patternTemplate = createPatternTemplateMapping.get(
+        PatternTemplateType.fromString(createPatternTemplateRQ.getType())
+            .orElseThrow(() -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR,
+                Suppliers.formattedSupplier("Unknown pattern template type - '{}'",
+                    createPatternTemplateRQ.getType()).get()
+            ))).createPatternTemplate(project.getId(), createPatternTemplateRQ);
+
+    messageBus.publishActivity(new PatternCreatedEvent(user.getUserId(),
+        user.getUsername(),
+        PatternTemplateConverter.TO_ACTIVITY_RESOURCE.apply(patternTemplate)
+    ));
+    return new EntryCreatedRS(patternTemplate.getId());
+  }
+
+  private static String shortUUID() {
+    long l = ByteBuffer.wrap(UUID.randomUUID().toString().getBytes(Charsets.UTF_8)).getLong();
+    return Long.toString(l, Character.MAX_RADIX);
+  }
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/settings/impl/GetProjectSettingsHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/project/settings/impl/GetProjectSettingsHandlerImpl.java
index 71bd7874c1..f7f14e91ec 100644
--- a/src/main/java/com/epam/ta/reportportal/core/project/settings/impl/GetProjectSettingsHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/project/settings/impl/GetProjectSettingsHandlerImpl.java
@@ -34,17 +34,17 @@
 @Transactional(readOnly = true)
 public class GetProjectSettingsHandlerImpl implements GetProjectSettingsHandler {
 
-	private final ProjectRepository repository;
+  private final ProjectRepository repository;
 
-	@Autowired
-	public GetProjectSettingsHandlerImpl(ProjectRepository repository) {
-		this.repository = repository;
-	}
+  @Autowired
+  public GetProjectSettingsHandlerImpl(ProjectRepository repository) {
+    this.repository = repository;
+  }
 
-	@Override
-	public ProjectSettingsResource getProjectSettings(String projectName) {
-		Project project = repository.findByName(projectName)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.PROJECT_NOT_FOUND, projectName));
-		return ProjectSettingsConverter.TO_PROJECT_SETTINGS_RESOURCE.apply(project);
-	}
+  @Override
+  public ProjectSettingsResource getProjectSettings(String projectName) {
+    Project project = repository.findByName(projectName)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.PROJECT_NOT_FOUND, projectName));
+    return ProjectSettingsConverter.TO_PROJECT_SETTINGS_RESOURCE.apply(project);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/settings/impl/UpdateProjectSettingsHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/project/settings/impl/UpdateProjectSettingsHandlerImpl.java
index a098f0435a..7c99aab66f 100644
--- a/src/main/java/com/epam/ta/reportportal/core/project/settings/impl/UpdateProjectSettingsHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/project/settings/impl/UpdateProjectSettingsHandlerImpl.java
@@ -16,6 +16,21 @@
 
 package com.epam.ta.reportportal.core.project.settings.impl;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import static com.epam.ta.reportportal.commons.Predicates.in;
+import static com.epam.ta.reportportal.commons.Predicates.not;
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.AUTOMATION_BUG;
+import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.NO_DEFECT;
+import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.PRODUCT_BUG;
+import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.SYSTEM_ISSUE;
+import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.TO_INVESTIGATE;
+import static com.epam.ta.reportportal.ws.converter.converters.IssueTypeConverter.TO_ACTIVITY_RESOURCE;
+import static com.epam.ta.reportportal.ws.model.ErrorType.FORBIDDEN_OPERATION;
+import static com.epam.ta.reportportal.ws.model.ErrorType.ISSUE_TYPE_NOT_FOUND;
+import static com.epam.ta.reportportal.ws.model.ErrorType.PROJECT_NOT_FOUND;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.commons.validation.Suppliers;
@@ -40,21 +55,13 @@
 import com.epam.ta.reportportal.ws.model.project.config.UpdateOneIssueSubTypeRQ;
 import com.epam.ta.reportportal.ws.model.project.config.pattern.UpdatePatternTemplateRQ;
 import com.google.common.collect.Sets;
+import java.util.List;
+import java.util.stream.Collectors;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.List;
-import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.commons.Predicates.*;
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.*;
-import static com.epam.ta.reportportal.ws.converter.converters.IssueTypeConverter.TO_ACTIVITY_RESOURCE;
-import static com.epam.ta.reportportal.ws.model.ErrorType.*;
-import static java.util.Optional.ofNullable;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
@@ -62,104 +69,119 @@
 @Transactional
 public class UpdateProjectSettingsHandlerImpl implements UpdateProjectSettingsHandler {
 
-	private final ProjectRepository projectRepository;
-
-	private final PatternTemplateRepository patternTemplateRepository;
-
-	private final MessageBus messageBus;
-
-	@Autowired
-	public UpdateProjectSettingsHandlerImpl(ProjectRepository projectRepository, PatternTemplateRepository patternTemplateRepository,
-			MessageBus messageBus) {
-		this.projectRepository = projectRepository;
-		this.patternTemplateRepository = patternTemplateRepository;
-		this.messageBus = messageBus;
-	}
-
-	@Override
-	public OperationCompletionRS updateProjectIssueSubType(String projectName, ReportPortalUser user,
-			UpdateIssueSubTypeRQ updateIssueSubTypeRQ) {
-		expect(updateIssueSubTypeRQ.getIds().size() > 0, equalTo(true)).verify(FORBIDDEN_OPERATION,
-				"Please specify at least one item data for update."
-		);
-
-		Project project = projectRepository.findByName(projectName)
-				.orElseThrow(() -> new ReportPortalException(PROJECT_NOT_FOUND, projectName));
-
-		List<IssueTypeActivityResource> issueTypeActivityResources = updateIssueSubTypeRQ.getIds()
-				.stream()
-				.map(subTypeRQ -> TO_ACTIVITY_RESOURCE.apply(validateAndUpdate(subTypeRQ,
-						project.getProjectIssueTypes().stream().map(ProjectIssueType::getIssueType).collect(Collectors.toList())
-				)))
-				.collect(Collectors.toList());
-
-		projectRepository.save(project);
-		issueTypeActivityResources.forEach(it -> messageBus.publishActivity(new DefectTypeUpdatedEvent(it,
-				user.getUserId(),
-				user.getUsername(),
-				project.getId()
-		)));
-		return new OperationCompletionRS("Issue sub-type(s) was updated successfully.");
-	}
-
-	@Override
-	public OperationCompletionRS updatePatternTemplate(Long id, String projectName, UpdatePatternTemplateRQ updatePatternTemplateRQ,
-			ReportPortalUser user) {
-
-		Project project = projectRepository.findByName(projectName)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.PROJECT_NOT_FOUND, projectName));
-
-		PatternTemplate patternTemplate = patternTemplateRepository.findById(id)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.PATTERN_TEMPLATE_NOT_FOUND_IN_PROJECT, id, project.getId()));
-
-		final String name = StringUtils.trim(updatePatternTemplateRQ.getName());
-
-		if (!patternTemplate.getName().equalsIgnoreCase(name)) {
-			BusinessRule.expect(patternTemplateRepository.existsByProjectIdAndNameIgnoreCase(
-					project.getId(), name
-			), equalTo(false)).verify(ErrorType.RESOURCE_ALREADY_EXISTS, name);
-		}
-
-		PatternTemplateActivityResource before = PatternTemplateConverter.TO_ACTIVITY_RESOURCE.apply(patternTemplate);
-
-		patternTemplate.setName(name);
-		patternTemplate.setEnabled(updatePatternTemplateRQ.getEnabled());
-
-		PatternTemplateActivityResource after = PatternTemplateConverter.TO_ACTIVITY_RESOURCE.apply(patternTemplate);
-
-		messageBus.publishActivity(new PatternUpdatedEvent(user.getUserId(), user.getUsername(), before, after));
-
-		return new OperationCompletionRS(Suppliers.formattedSupplier("Pattern template with ID = '{}' has been successfully updated", id)
-				.get());
-
-	}
-
-	private IssueType validateAndUpdate(UpdateOneIssueSubTypeRQ issueSubTypeRQ, List<IssueType> issueTypes) {
-		/* Check if global issue type reference is valid */
-		TestItemIssueGroup expectedGroup = TestItemIssueGroup.fromValue(issueSubTypeRQ.getTypeRef())
-				.orElseThrow(() -> new ReportPortalException(ISSUE_TYPE_NOT_FOUND, issueSubTypeRQ.getTypeRef()));
-
-		IssueType exist = issueTypes.stream()
-				.filter(issueType -> issueType.getLocator().equalsIgnoreCase(issueSubTypeRQ.getLocator()))
-				.findFirst()
-				.orElseThrow(() -> new ReportPortalException(ISSUE_TYPE_NOT_FOUND, issueSubTypeRQ.getLocator()));
-
-		expect(exist.getIssueGroup().getTestItemIssueGroup().equals(expectedGroup), equalTo(true)).verify(FORBIDDEN_OPERATION,
-				"You cannot change sub-type references to global type."
-		);
-
-		expect(exist.getLocator(),
-				not(in(Sets.newHashSet(AUTOMATION_BUG.getLocator(),
-						PRODUCT_BUG.getLocator(),
-						SYSTEM_ISSUE.getLocator(),
-						NO_DEFECT.getLocator(),
-						TO_INVESTIGATE.getLocator()
-				)))
-		).verify(FORBIDDEN_OPERATION, "You cannot remove predefined global issue types.");
-
-		ofNullable(issueSubTypeRQ.getLongName()).ifPresent(exist::setLongName);
-		ofNullable(issueSubTypeRQ.getShortName()).ifPresent(exist::setShortName);
-		ofNullable(issueSubTypeRQ.getColor()).ifPresent(exist::setHexColor);
-		return exist;
-	}
+  private final ProjectRepository projectRepository;
+
+  private final PatternTemplateRepository patternTemplateRepository;
+
+  private final MessageBus messageBus;
+
+  @Autowired
+  public UpdateProjectSettingsHandlerImpl(ProjectRepository projectRepository,
+      PatternTemplateRepository patternTemplateRepository,
+      MessageBus messageBus) {
+    this.projectRepository = projectRepository;
+    this.patternTemplateRepository = patternTemplateRepository;
+    this.messageBus = messageBus;
+  }
+
+  @Override
+  public OperationCompletionRS updateProjectIssueSubType(String projectName, ReportPortalUser user,
+      UpdateIssueSubTypeRQ updateIssueSubTypeRQ) {
+    expect(updateIssueSubTypeRQ.getIds().size() > 0, equalTo(true)).verify(FORBIDDEN_OPERATION,
+        "Please specify at least one item data for update."
+    );
+
+    Project project = projectRepository.findByName(projectName)
+        .orElseThrow(() -> new ReportPortalException(PROJECT_NOT_FOUND, projectName));
+
+    List<IssueTypeActivityResource> issueTypeActivityResources = updateIssueSubTypeRQ.getIds()
+        .stream()
+        .map(subTypeRQ -> TO_ACTIVITY_RESOURCE.apply(validateAndUpdate(subTypeRQ,
+            project.getProjectIssueTypes().stream().map(ProjectIssueType::getIssueType)
+                .collect(Collectors.toList())
+        )))
+        .collect(Collectors.toList());
+
+    projectRepository.save(project);
+    issueTypeActivityResources.forEach(
+        it -> messageBus.publishActivity(new DefectTypeUpdatedEvent(it,
+            user.getUserId(),
+            user.getUsername(),
+            project.getId()
+        )));
+    return new OperationCompletionRS("Issue sub-type(s) was updated successfully.");
+  }
+
+  @Override
+  public OperationCompletionRS updatePatternTemplate(Long id, String projectName,
+      UpdatePatternTemplateRQ updatePatternTemplateRQ,
+      ReportPortalUser user) {
+
+    Project project = projectRepository.findByName(projectName)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.PROJECT_NOT_FOUND, projectName));
+
+    PatternTemplate patternTemplate = patternTemplateRepository.findById(id)
+        .orElseThrow(
+            () -> new ReportPortalException(ErrorType.PATTERN_TEMPLATE_NOT_FOUND_IN_PROJECT, id,
+                project.getId()));
+
+    final String name = StringUtils.trim(updatePatternTemplateRQ.getName());
+
+    if (!patternTemplate.getName().equalsIgnoreCase(name)) {
+      BusinessRule.expect(patternTemplateRepository.existsByProjectIdAndNameIgnoreCase(
+          project.getId(), name
+      ), equalTo(false)).verify(ErrorType.RESOURCE_ALREADY_EXISTS, name);
+    }
+
+    PatternTemplateActivityResource before = PatternTemplateConverter.TO_ACTIVITY_RESOURCE.apply(
+        patternTemplate);
+
+    patternTemplate.setName(name);
+    patternTemplate.setEnabled(updatePatternTemplateRQ.getEnabled());
+
+    PatternTemplateActivityResource after = PatternTemplateConverter.TO_ACTIVITY_RESOURCE.apply(
+        patternTemplate);
+
+    messageBus.publishActivity(
+        new PatternUpdatedEvent(user.getUserId(), user.getUsername(), before, after));
+
+    return new OperationCompletionRS(
+        Suppliers.formattedSupplier("Pattern template with ID = '{}' has been successfully updated",
+                id)
+            .get());
+
+  }
+
+  private IssueType validateAndUpdate(UpdateOneIssueSubTypeRQ issueSubTypeRQ,
+      List<IssueType> issueTypes) {
+    /* Check if global issue type reference is valid */
+    TestItemIssueGroup expectedGroup = TestItemIssueGroup.fromValue(issueSubTypeRQ.getTypeRef())
+        .orElseThrow(
+            () -> new ReportPortalException(ISSUE_TYPE_NOT_FOUND, issueSubTypeRQ.getTypeRef()));
+
+    IssueType exist = issueTypes.stream()
+        .filter(issueType -> issueType.getLocator().equalsIgnoreCase(issueSubTypeRQ.getLocator()))
+        .findFirst()
+        .orElseThrow(
+            () -> new ReportPortalException(ISSUE_TYPE_NOT_FOUND, issueSubTypeRQ.getLocator()));
+
+    expect(exist.getIssueGroup().getTestItemIssueGroup().equals(expectedGroup),
+        equalTo(true)).verify(FORBIDDEN_OPERATION,
+        "You cannot change sub-type references to global type."
+    );
+
+    expect(exist.getLocator(),
+        not(in(Sets.newHashSet(AUTOMATION_BUG.getLocator(),
+            PRODUCT_BUG.getLocator(),
+            SYSTEM_ISSUE.getLocator(),
+            NO_DEFECT.getLocator(),
+            TO_INVESTIGATE.getLocator()
+        )))
+    ).verify(FORBIDDEN_OPERATION, "You cannot remove predefined global issue types.");
+
+    ofNullable(issueSubTypeRQ.getLongName()).ifPresent(exist::setLongName);
+    ofNullable(issueSubTypeRQ.getShortName()).ifPresent(exist::setShortName);
+    ofNullable(issueSubTypeRQ.getColor()).ifPresent(exist::setHexColor);
+    return exist;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/CreateProjectNotificationHandler.java b/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/CreateProjectNotificationHandler.java
new file mode 100644
index 0000000000..55cd982c36
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/CreateProjectNotificationHandler.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2022 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.core.project.settings.notification;
+
+import com.epam.ta.reportportal.commons.ReportPortalUser;
+import com.epam.ta.reportportal.entity.project.Project;
+import com.epam.ta.reportportal.ws.model.EntryCreatedRS;
+import com.epam.ta.reportportal.ws.model.project.email.SenderCaseDTO;
+
+/**
+ * @author <a href="mailto:chingiskhan_kalanov@epam.com">Chingiskhan Kalanov</a>
+ */
+public interface CreateProjectNotificationHandler {
+
+  EntryCreatedRS createNotification(Project project, SenderCaseDTO createNotificationRQ,
+      ReportPortalUser user);
+
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/CreateProjectNotificationHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/CreateProjectNotificationHandlerImpl.java
new file mode 100644
index 0000000000..29879a1487
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/CreateProjectNotificationHandlerImpl.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2022 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.core.project.settings.notification;
+
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+
+import com.epam.ta.reportportal.commons.ReportPortalUser;
+import com.epam.ta.reportportal.core.events.MessageBus;
+import com.epam.ta.reportportal.core.events.activity.NotificationsConfigUpdatedEvent;
+import com.epam.ta.reportportal.core.project.validator.notification.ProjectNotificationValidator;
+import com.epam.ta.reportportal.dao.SenderCaseRepository;
+import com.epam.ta.reportportal.entity.project.Project;
+import com.epam.ta.reportportal.entity.project.email.SenderCase;
+import com.epam.ta.reportportal.ws.converter.converters.NotificationConfigConverter;
+import com.epam.ta.reportportal.ws.converter.converters.ProjectConverter;
+import com.epam.ta.reportportal.ws.model.EntryCreatedRS;
+import com.epam.ta.reportportal.ws.model.ErrorType;
+import com.epam.ta.reportportal.ws.model.project.ProjectResource;
+import com.epam.ta.reportportal.ws.model.project.email.ProjectNotificationConfigDTO;
+import com.epam.ta.reportportal.ws.model.project.email.SenderCaseDTO;
+import java.util.Optional;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author <a href="mailto:chingiskhan_kalanov@epam.com">Chingiskhan Kalanov</a>
+ */
+@Service
+public class CreateProjectNotificationHandlerImpl implements CreateProjectNotificationHandler {
+
+  private final SenderCaseRepository senderCaseRepository;
+  private final MessageBus messageBus;
+  private final ProjectConverter projectConverter;
+  private final ProjectNotificationValidator projectNotificationValidator;
+
+  public CreateProjectNotificationHandlerImpl(SenderCaseRepository senderCaseRepository,
+      MessageBus messageBus,
+      ProjectConverter projectConverter,
+      ProjectNotificationValidator projectNotificationValidator) {
+    this.senderCaseRepository = senderCaseRepository;
+    this.messageBus = messageBus;
+    this.projectConverter = projectConverter;
+    this.projectNotificationValidator = projectNotificationValidator;
+  }
+
+  @Override
+  public EntryCreatedRS createNotification(Project project, SenderCaseDTO createNotificationRQ,
+      ReportPortalUser user) {
+    expect(senderCaseRepository.findByProjectIdAndRuleNameIgnoreCase(project.getId(),
+            createNotificationRQ.getRuleName()),
+        Optional::isEmpty)
+        .verify(ErrorType.RESOURCE_ALREADY_EXISTS, createNotificationRQ.getRuleName());
+
+    projectNotificationValidator.validateCreateRQ(project, createNotificationRQ);
+
+    SenderCase senderCase = NotificationConfigConverter.TO_CASE_MODEL.apply(createNotificationRQ);
+    senderCase.setId(null);
+    senderCase.setProject(project);
+    senderCaseRepository.save(senderCase);
+
+    ProjectResource projectResource = projectConverter.TO_PROJECT_RESOURCE.apply(project);
+    ProjectNotificationConfigDTO projectNotificationConfigDTO = projectResource.getConfiguration()
+        .getProjectConfig();
+    projectNotificationConfigDTO.getSenderCases().add(createNotificationRQ);
+
+    messageBus.publishActivity(new NotificationsConfigUpdatedEvent(projectResource,
+        projectResource.getConfiguration().getProjectConfig(),
+        user.getUserId(),
+        user.getUsername()
+    ));
+
+    return new EntryCreatedRS(senderCase.getId());
+  }
+
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/DeleteProjectNotificationHandler.java b/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/DeleteProjectNotificationHandler.java
new file mode 100644
index 0000000000..28e6165771
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/DeleteProjectNotificationHandler.java
@@ -0,0 +1,32 @@
+/*
+ *
+ * Copyright 2022 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.epam.ta.reportportal.core.project.settings.notification;
+
+import com.epam.ta.reportportal.commons.ReportPortalUser;
+import com.epam.ta.reportportal.entity.project.Project;
+import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
+
+/**
+ * @author <a href="mailto:chingiskhan_kalanov@epam.com">Chingiskhan Kalanov</a>
+ */
+public interface DeleteProjectNotificationHandler {
+
+  OperationCompletionRS deleteNotification(Project project, Long notificationId,
+      ReportPortalUser user);
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/DeleteProjectNotificationHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/DeleteProjectNotificationHandlerImpl.java
new file mode 100644
index 0000000000..9c914c8203
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/DeleteProjectNotificationHandlerImpl.java
@@ -0,0 +1,91 @@
+/*
+ *
+ * Copyright 2022 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.epam.ta.reportportal.core.project.settings.notification;
+
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static java.util.Optional.ofNullable;
+
+import com.epam.ta.reportportal.commons.ReportPortalUser;
+import com.epam.ta.reportportal.commons.validation.Suppliers;
+import com.epam.ta.reportportal.core.events.MessageBus;
+import com.epam.ta.reportportal.core.events.activity.NotificationsConfigUpdatedEvent;
+import com.epam.ta.reportportal.dao.SenderCaseRepository;
+import com.epam.ta.reportportal.entity.project.Project;
+import com.epam.ta.reportportal.entity.project.email.SenderCase;
+import com.epam.ta.reportportal.ws.converter.converters.ProjectConverter;
+import com.epam.ta.reportportal.ws.model.ErrorType;
+import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
+import com.epam.ta.reportportal.ws.model.project.ProjectResource;
+import com.epam.ta.reportportal.ws.model.project.email.ProjectNotificationConfigDTO;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author <a href="mailto:chingiskhan_kalanov@epam.com">Chingiskhan Kalanov</a>
+ */
+@Service
+public class DeleteProjectNotificationHandlerImpl implements DeleteProjectNotificationHandler {
+
+  private final SenderCaseRepository senderCaseRepository;
+  private final MessageBus messageBus;
+  private final ProjectConverter projectConverter;
+
+  public DeleteProjectNotificationHandlerImpl(SenderCaseRepository senderCaseRepository,
+      MessageBus messageBus,
+      ProjectConverter projectConverter) {
+    this.senderCaseRepository = senderCaseRepository;
+    this.messageBus = messageBus;
+    this.projectConverter = projectConverter;
+  }
+
+  @Override
+  public OperationCompletionRS deleteNotification(Project project, Long notificationId,
+      ReportPortalUser user) {
+    Optional<SenderCase> senderCase = senderCaseRepository.findById(notificationId);
+    expect(senderCase,
+        (notification) -> notification.map(
+            ntf -> Objects.equals(ntf.getProject().getId(), project.getId())).orElse(false))
+        .verify(
+            ErrorType.BAD_REQUEST_ERROR,
+            Suppliers.formattedSupplier(
+                "Notification '{}' not found. Did you use correct Notification ID?",
+                notificationId).get()
+        );
+    senderCaseRepository.deleteSenderCaseById(notificationId);
+
+    ProjectResource projectResource = projectConverter.TO_PROJECT_RESOURCE.apply(project);
+    ProjectNotificationConfigDTO projectNotificationConfigDTO = projectResource.getConfiguration()
+        .getProjectConfig();
+    ofNullable(projectNotificationConfigDTO.getSenderCases()).ifPresent(
+        scs -> projectNotificationConfigDTO.setSenderCases(
+            scs.stream().filter(sc -> !Objects.equals(sc.getId(), notificationId))
+                .collect(Collectors.toList())
+        ));
+
+    messageBus.publishActivity(new NotificationsConfigUpdatedEvent(projectResource,
+        projectResource.getConfiguration().getProjectConfig(),
+        user.getUserId(),
+        user.getUsername()
+    ));
+
+    return new OperationCompletionRS("Notification rule was deleted successfully.");
+  }
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/GetProjectNotificationsHandler.java b/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/GetProjectNotificationsHandler.java
new file mode 100644
index 0000000000..052be9282d
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/GetProjectNotificationsHandler.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2022 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.core.project.settings.notification;
+
+import com.epam.ta.reportportal.ws.model.project.email.SenderCaseDTO;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:chingiskhan_kalanov@epam.com">Chingiskhan Kalanov</a>
+ */
+public interface GetProjectNotificationsHandler {
+
+  List<SenderCaseDTO> getProjectNotifications(Long projectId);
+
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/GetProjectNotificationsHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/GetProjectNotificationsHandlerImpl.java
new file mode 100644
index 0000000000..ebb99190b6
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/GetProjectNotificationsHandlerImpl.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2022 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.core.project.settings.notification;
+
+import com.epam.ta.reportportal.dao.SenderCaseRepository;
+import com.epam.ta.reportportal.ws.converter.converters.NotificationConfigConverter;
+import com.epam.ta.reportportal.ws.model.project.email.SenderCaseDTO;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author <a href="mailto:chingiskhan_kalanov@epam.com">Chingiskhan Kalanov</a>
+ */
+@Service
+public class GetProjectNotificationsHandlerImpl implements GetProjectNotificationsHandler {
+
+  private final SenderCaseRepository senderCaseRepository;
+
+  @Autowired
+  public GetProjectNotificationsHandlerImpl(SenderCaseRepository senderCaseRepository) {
+    this.senderCaseRepository = senderCaseRepository;
+  }
+
+  @Override
+  public List<SenderCaseDTO> getProjectNotifications(Long projectId) {
+    return senderCaseRepository.findAllByProjectId(projectId).stream()
+        .map(NotificationConfigConverter.TO_CASE_RESOURCE)
+        .collect(Collectors.toList());
+  }
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/ProjectRecipientHandler.java b/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/ProjectRecipientHandler.java
index ef2adbf88b..dfb66cf7cc 100644
--- a/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/ProjectRecipientHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/ProjectRecipientHandler.java
@@ -11,5 +11,5 @@
  */
 public interface ProjectRecipientHandler {
 
-	void handle(Iterable<User> users, Project project);
+  void handle(Iterable<User> users, Project project);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/RecipientRemover.java b/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/RecipientRemover.java
index 08a4a93fe7..0534c9725e 100644
--- a/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/RecipientRemover.java
+++ b/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/RecipientRemover.java
@@ -1,17 +1,16 @@
 package com.epam.ta.reportportal.core.project.settings.notification;
 
+import static java.util.Arrays.asList;
+import static java.util.stream.Collectors.toSet;
+import static java.util.stream.StreamSupport.stream;
+
 import com.epam.ta.reportportal.dao.SenderCaseRepository;
 import com.epam.ta.reportportal.entity.project.Project;
 import com.epam.ta.reportportal.entity.user.User;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
 import java.util.List;
 import java.util.Set;
-
-import static java.util.Arrays.asList;
-import static java.util.stream.Collectors.toSet;
-import static java.util.stream.StreamSupport.stream;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
  * @author Ivan Budaev
@@ -19,26 +18,27 @@
 @Service
 public class RecipientRemover implements ProjectRecipientHandler {
 
-	private final SenderCaseRepository senderCaseRepository;
+  private final SenderCaseRepository senderCaseRepository;
 
-	@Autowired
-	public RecipientRemover(SenderCaseRepository senderCaseRepository) {
-		this.senderCaseRepository = senderCaseRepository;
-	}
+  @Autowired
+  public RecipientRemover(SenderCaseRepository senderCaseRepository) {
+    this.senderCaseRepository = senderCaseRepository;
+  }
 
-	/**
-	 * @param users   {@link User} collection to remove from project recipient list
-	 * @param project {@link Project}
-	 */
-	@Override
-	public void handle(Iterable<User> users, Project project) {
-		final Set<String> toExclude = stream(users.spliterator(), false).map(user -> asList(user.getEmail().toLowerCase(),
-				user.getLogin().toLowerCase()
-		)).flatMap(List::stream).collect(toSet());
-		/* Current recipients of specified project */
-		senderCaseRepository.findAllByProjectId(project.getId()).forEach(senderCase -> {
-			// saved - list of saved user emails before changes
-			senderCaseRepository.deleteRecipients(senderCase.getId(), toExclude);
-		});
-	}
+  /**
+   * @param users   {@link User} collection to remove from project recipient list
+   * @param project {@link Project}
+   */
+  @Override
+  public void handle(Iterable<User> users, Project project) {
+    final Set<String> toExclude = stream(users.spliterator(), false).map(
+        user -> asList(user.getEmail().toLowerCase(),
+            user.getLogin().toLowerCase()
+        )).flatMap(List::stream).collect(toSet());
+    /* Current recipients of specified project */
+    senderCaseRepository.findAllByProjectId(project.getId()).forEach(senderCase -> {
+      // saved - list of saved user emails before changes
+      senderCaseRepository.deleteRecipients(senderCase.getId(), toExclude);
+    });
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/UpdateProjectNotificationHandler.java b/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/UpdateProjectNotificationHandler.java
new file mode 100644
index 0000000000..11e785b0b5
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/UpdateProjectNotificationHandler.java
@@ -0,0 +1,34 @@
+/*
+ *
+ * Copyright 2022 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.epam.ta.reportportal.core.project.settings.notification;
+
+import com.epam.ta.reportportal.commons.ReportPortalUser;
+import com.epam.ta.reportportal.entity.project.Project;
+import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
+import com.epam.ta.reportportal.ws.model.project.email.SenderCaseDTO;
+
+/**
+ * @author <a href="mailto:chingiskhan_kalanov@epam.com">Chingiskhan Kalanov</a>
+ */
+public interface UpdateProjectNotificationHandler {
+
+  OperationCompletionRS updateNotification(Project project, SenderCaseDTO updateNotificationRQ,
+      ReportPortalUser user);
+
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/UpdateProjectNotificationHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/UpdateProjectNotificationHandlerImpl.java
new file mode 100644
index 0000000000..4a51f5be29
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/core/project/settings/notification/UpdateProjectNotificationHandlerImpl.java
@@ -0,0 +1,93 @@
+/*
+ *
+ * Copyright 2022 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.epam.ta.reportportal.core.project.settings.notification;
+
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+
+import com.epam.ta.reportportal.commons.ReportPortalUser;
+import com.epam.ta.reportportal.commons.validation.Suppliers;
+import com.epam.ta.reportportal.core.events.MessageBus;
+import com.epam.ta.reportportal.core.events.activity.NotificationsConfigUpdatedEvent;
+import com.epam.ta.reportportal.core.project.validator.notification.ProjectNotificationValidator;
+import com.epam.ta.reportportal.dao.SenderCaseRepository;
+import com.epam.ta.reportportal.entity.project.Project;
+import com.epam.ta.reportportal.entity.project.email.SenderCase;
+import com.epam.ta.reportportal.ws.converter.converters.NotificationConfigConverter;
+import com.epam.ta.reportportal.ws.converter.converters.ProjectConverter;
+import com.epam.ta.reportportal.ws.model.ErrorType;
+import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
+import com.epam.ta.reportportal.ws.model.project.ProjectResource;
+import com.epam.ta.reportportal.ws.model.project.email.ProjectNotificationConfigDTO;
+import com.epam.ta.reportportal.ws.model.project.email.SenderCaseDTO;
+import java.util.Objects;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author <a href="mailto:chingiskhan_kalanov@epam.com">Chingiskhan Kalanov</a>
+ */
+@Service
+public class UpdateProjectNotificationHandlerImpl implements UpdateProjectNotificationHandler {
+
+  private final SenderCaseRepository senderCaseRepository;
+  private final MessageBus messageBus;
+  private final ProjectConverter projectConverter;
+  private final ProjectNotificationValidator projectNotificationValidator;
+
+  public UpdateProjectNotificationHandlerImpl(SenderCaseRepository senderCaseRepository,
+      MessageBus messageBus,
+      ProjectConverter projectConverter,
+      ProjectNotificationValidator projectNotificationValidator) {
+    this.senderCaseRepository = senderCaseRepository;
+    this.messageBus = messageBus;
+    this.projectConverter = projectConverter;
+    this.projectNotificationValidator = projectNotificationValidator;
+  }
+
+  @Override
+  public OperationCompletionRS updateNotification(Project project,
+      SenderCaseDTO updateNotificationRQ, ReportPortalUser user) {
+    expect(updateNotificationRQ.getId(), Objects::nonNull).verify(ErrorType.BAD_REQUEST_ERROR,
+        "Please specify notification Id");
+    expect(senderCaseRepository.findById(updateNotificationRQ.getId()),
+        (notification) -> notification.map(
+            ntf -> Objects.equals(ntf.getProject().getId(), project.getId())).orElse(false))
+        .verify(ErrorType.BAD_REQUEST_ERROR,
+            Suppliers.formattedSupplier(
+                "Notification '{}' not found. Did you use correct Notification ID?",
+                updateNotificationRQ.getId()).get()
+        );
+    projectNotificationValidator.validateUpdateRQ(project, updateNotificationRQ);
+    SenderCase notification = NotificationConfigConverter.TO_CASE_MODEL.apply(updateNotificationRQ);
+    notification.setProject(project);
+    senderCaseRepository.save(notification);
+
+    ProjectResource projectResource = projectConverter.TO_PROJECT_RESOURCE.apply(project);
+    ProjectNotificationConfigDTO projectNotificationConfigDTO = projectResource.getConfiguration()
+        .getProjectConfig();
+    projectNotificationConfigDTO.getSenderCases().add(updateNotificationRQ);
+
+    messageBus.publishActivity(new NotificationsConfigUpdatedEvent(projectResource,
+        projectResource.getConfiguration().getProjectConfig(),
+        user.getUserId(),
+        user.getUsername()
+    ));
+
+    return new OperationCompletionRS("Notification rule was updated successfully.");
+  }
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/validator/attribute/DelayBoundLessRule.java b/src/main/java/com/epam/ta/reportportal/core/project/validator/attribute/DelayBoundLessRule.java
index f19b04308b..e2707312f1 100644
--- a/src/main/java/com/epam/ta/reportportal/core/project/validator/attribute/DelayBoundLessRule.java
+++ b/src/main/java/com/epam/ta/reportportal/core/project/validator/attribute/DelayBoundLessRule.java
@@ -4,19 +4,19 @@
 
 public class DelayBoundLessRule {
 
-	private final ProjectAttributeEnum lower;
-	private final ProjectAttributeEnum higher;
+  private final ProjectAttributeEnum lower;
+  private final ProjectAttributeEnum higher;
 
-	public DelayBoundLessRule(ProjectAttributeEnum lower, ProjectAttributeEnum higher) {
-		this.lower = lower;
-		this.higher = higher;
-	}
+  public DelayBoundLessRule(ProjectAttributeEnum lower, ProjectAttributeEnum higher) {
+    this.lower = lower;
+    this.higher = higher;
+  }
 
-	public ProjectAttributeEnum getLower() {
-		return lower;
-	}
+  public ProjectAttributeEnum getLower() {
+    return lower;
+  }
 
-	public ProjectAttributeEnum getHigher() {
-		return higher;
-	}
+  public ProjectAttributeEnum getHigher() {
+    return higher;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/validator/attribute/DelayBoundValidator.java b/src/main/java/com/epam/ta/reportportal/core/project/validator/attribute/DelayBoundValidator.java
index 3795df3da6..ae44312b20 100644
--- a/src/main/java/com/epam/ta/reportportal/core/project/validator/attribute/DelayBoundValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/project/validator/attribute/DelayBoundValidator.java
@@ -1,58 +1,61 @@
 package com.epam.ta.reportportal.core.project.validator.attribute;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import static com.epam.ta.reportportal.entity.enums.ProjectAttributeEnum.FOREVER_ALIAS;
+import static com.epam.ta.reportportal.ws.model.ErrorType.BAD_REQUEST_ERROR;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.commons.validation.Suppliers;
 import com.epam.ta.reportportal.entity.enums.ProjectAttributeEnum;
 import com.epam.ta.reportportal.exception.ReportPortalException;
-
 import java.util.List;
 import java.util.Map;
 
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-import static com.epam.ta.reportportal.entity.enums.ProjectAttributeEnum.FOREVER_ALIAS;
-import static com.epam.ta.reportportal.ws.model.ErrorType.BAD_REQUEST_ERROR;
-import static java.util.Optional.ofNullable;
-
 public class DelayBoundValidator {
 
-	private final List<DelayBoundLessRule> rules;
-
-	public DelayBoundValidator(List<DelayBoundLessRule> rules) {
-		this.rules = rules;
-	}
-
-	public void validate(Map<String, String> currentAttributes, Map<ProjectAttributeEnum, Long> newAttributes) {
-		rules.forEach(rule -> {
-			Long lowerDelay = ofNullable(newAttributes.get(rule.getLower())).orElseGet(() -> getCurrentDelay(currentAttributes,
-					rule.getLower()
-			));
-			Long higherDelay = ofNullable(newAttributes.get(rule.getHigher())).orElseGet(() -> getCurrentDelay(currentAttributes,
-					rule.getHigher()
-			));
-
-			BusinessRule.expect(lowerDelay <= higherDelay, equalTo(Boolean.TRUE))
-					.verify(BAD_REQUEST_ERROR,
-							Suppliers.formattedSupplier("Delay of '{}' should not be higher than '{}'",
-									rule.getLower().getAttribute(),
-									rule.getHigher().getAttribute()
-							).toString()
-					);
-		});
-	}
-
-	private Long getCurrentDelay(Map<String, String> currentAttributes, ProjectAttributeEnum attribute) {
-		return ofNullable(currentAttributes.get(attribute.getAttribute())).map(this::resolveDelay)
-				.orElseThrow(() -> new ReportPortalException(BAD_REQUEST_ERROR,
-						Suppliers.formattedSupplier("Attribute - {} was not found"),
-						attribute.getAttribute()
-				));
-	}
-
-	private Long resolveDelay(String value) {
-		try {
-			return FOREVER_ALIAS.equals(value) ? Long.MAX_VALUE : Long.parseLong(value);
-		} catch (NumberFormatException exc) {
-			throw new ReportPortalException(BAD_REQUEST_ERROR, exc.getMessage());
-		}
-	}
+  private final List<DelayBoundLessRule> rules;
+
+  public DelayBoundValidator(List<DelayBoundLessRule> rules) {
+    this.rules = rules;
+  }
+
+  public void validate(Map<String, String> currentAttributes,
+      Map<ProjectAttributeEnum, Long> newAttributes) {
+    rules.forEach(rule -> {
+      Long lowerDelay = ofNullable(newAttributes.get(rule.getLower())).orElseGet(
+          () -> getCurrentDelay(currentAttributes,
+              rule.getLower()
+          ));
+      Long higherDelay = ofNullable(newAttributes.get(rule.getHigher())).orElseGet(
+          () -> getCurrentDelay(currentAttributes,
+              rule.getHigher()
+          ));
+
+      BusinessRule.expect(lowerDelay <= higherDelay, equalTo(Boolean.TRUE))
+          .verify(BAD_REQUEST_ERROR,
+              Suppliers.formattedSupplier("Delay of '{}' should not be higher than '{}'",
+                  rule.getLower().getAttribute(),
+                  rule.getHigher().getAttribute()
+              ).toString()
+          );
+    });
+  }
+
+  private Long getCurrentDelay(Map<String, String> currentAttributes,
+      ProjectAttributeEnum attribute) {
+    return ofNullable(currentAttributes.get(attribute.getAttribute())).map(this::resolveDelay)
+        .orElseThrow(() -> new ReportPortalException(BAD_REQUEST_ERROR,
+            Suppliers.formattedSupplier("Attribute - {} was not found"),
+            attribute.getAttribute()
+        ));
+  }
+
+  private Long resolveDelay(String value) {
+    try {
+      return FOREVER_ALIAS.equals(value) ? Long.MAX_VALUE : Long.parseLong(value);
+    } catch (NumberFormatException exc) {
+      throw new ReportPortalException(BAD_REQUEST_ERROR, exc.getMessage());
+    }
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/validator/attribute/ProjectAttributeValidator.java b/src/main/java/com/epam/ta/reportportal/core/project/validator/attribute/ProjectAttributeValidator.java
index 8ded892e13..cb7f9649b9 100644
--- a/src/main/java/com/epam/ta/reportportal/core/project/validator/attribute/ProjectAttributeValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/project/validator/attribute/ProjectAttributeValidator.java
@@ -1,89 +1,94 @@
 package com.epam.ta.reportportal.core.project.validator.attribute;
 
+import static com.epam.ta.reportportal.commons.Predicates.isPresent;
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.entity.enums.ProjectAttributeEnum.FOREVER_ALIAS;
+import static com.epam.ta.reportportal.ws.model.ErrorType.BAD_REQUEST_ERROR;
+import static java.util.Optional.ofNullable;
+import static java.util.stream.Collectors.toSet;
+
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.entity.AnalyzeMode;
 import com.epam.ta.reportportal.entity.enums.ProjectAttributeEnum;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
-import org.apache.commons.lang3.BooleanUtils;
-
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.commons.Predicates.isPresent;
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.entity.enums.ProjectAttributeEnum.FOREVER_ALIAS;
-import static com.epam.ta.reportportal.ws.model.ErrorType.BAD_REQUEST_ERROR;
-import static java.util.Optional.ofNullable;
-import static java.util.stream.Collectors.toSet;
+import org.apache.commons.lang3.BooleanUtils;
 
 //TODO need refactoring - split attributes validation logic
 public class ProjectAttributeValidator {
 
-	private final DelayBoundValidator delayBoundValidator;
-
-	public ProjectAttributeValidator(DelayBoundValidator delayBoundValidator) {
-		this.delayBoundValidator = delayBoundValidator;
-	}
-
-	public void verifyProjectAttributes(Map<String, String> currentAttributes, Map<String, String> newAttributes) {
-		Set<String> incompatibleAttributes = newAttributes.keySet()
-				.stream()
-				.filter(it -> !ProjectAttributeEnum.isPresent(it))
-				.collect(toSet());
-		expect(incompatibleAttributes, Set::isEmpty).verify(BAD_REQUEST_ERROR, incompatibleAttributes);
-
-		ofNullable(newAttributes.get(ProjectAttributeEnum.AUTO_ANALYZER_MODE.getAttribute())).ifPresent(analyzerMode -> expect(AnalyzeMode.fromString(
-				analyzerMode), isPresent()).verify(ErrorType.BAD_REQUEST_ERROR, analyzerMode));
-
-		ofNullable(newAttributes.get(ProjectAttributeEnum.SEARCH_LOGS_MIN_SHOULD_MATCH.getAttribute())).ifPresent(attr -> BusinessRule.expect(
-				validatePercentage(attr),
-				BooleanUtils::isTrue
-		).verify(BAD_REQUEST_ERROR, ProjectAttributeEnum.SEARCH_LOGS_MIN_SHOULD_MATCH));
-
-		final Map<ProjectAttributeEnum, Long> delays = validateDelays(newAttributes,
-				List.of(ProjectAttributeEnum.KEEP_SCREENSHOTS,
-						ProjectAttributeEnum.KEEP_LOGS,
-						ProjectAttributeEnum.KEEP_LAUNCHES,
-						ProjectAttributeEnum.INTERRUPT_JOB_TIME
-				)
-		);
-
-		delayBoundValidator.validate(currentAttributes, delays);
-	}
-
-	private Map<ProjectAttributeEnum, Long> validateDelays(Map<String, String> attributes, List<ProjectAttributeEnum> projectAttributes) {
-		return projectAttributes.stream()
-				.filter(it -> attributes.containsKey(it.getAttribute()))
-				.collect(Collectors.toMap(a -> a, a -> getDelay(attributes.get(a.getAttribute()))));
-	}
-
-	private Long getDelay(String value) {
-		final Long delay = FOREVER_ALIAS.equals(value) ? Long.MAX_VALUE : getLong(value);
-		BusinessRule.expect(delay, d -> d >= 0).verify(BAD_REQUEST_ERROR, "Delay attribute value should be greater than 0");
-		return delay;
-	}
-
-	private boolean validatePercentage(String value) {
-		final int percent = getInt(value);
-		return percent >= 0 && percent <= 100;
-	}
-
-	private Long getLong(String value) {
-		try {
-			return Long.parseLong(value);
-		} catch (NumberFormatException exc) {
-			throw new ReportPortalException(BAD_REQUEST_ERROR, exc.getMessage());
-		}
-	}
-
-	private Integer getInt(String value) {
-		try {
-			return Integer.parseInt(value);
-		} catch (NumberFormatException exc) {
-			throw new ReportPortalException(BAD_REQUEST_ERROR, exc.getMessage());
-		}
-	}
+  private final DelayBoundValidator delayBoundValidator;
+
+  public ProjectAttributeValidator(DelayBoundValidator delayBoundValidator) {
+    this.delayBoundValidator = delayBoundValidator;
+  }
+
+  public void verifyProjectAttributes(Map<String, String> currentAttributes,
+      Map<String, String> newAttributes) {
+    Set<String> incompatibleAttributes = newAttributes.keySet()
+        .stream()
+        .filter(it -> !ProjectAttributeEnum.isPresent(it))
+        .collect(toSet());
+    expect(incompatibleAttributes, Set::isEmpty).verify(BAD_REQUEST_ERROR, incompatibleAttributes);
+
+    ofNullable(newAttributes.get(ProjectAttributeEnum.AUTO_ANALYZER_MODE.getAttribute())).ifPresent(
+        analyzerMode -> expect(AnalyzeMode.fromString(
+            analyzerMode), isPresent()).verify(ErrorType.BAD_REQUEST_ERROR, analyzerMode));
+
+    ofNullable(newAttributes.get(
+        ProjectAttributeEnum.SEARCH_LOGS_MIN_SHOULD_MATCH.getAttribute())).ifPresent(
+        attr -> BusinessRule.expect(
+            validatePercentage(attr),
+            BooleanUtils::isTrue
+        ).verify(BAD_REQUEST_ERROR, ProjectAttributeEnum.SEARCH_LOGS_MIN_SHOULD_MATCH));
+
+    final Map<ProjectAttributeEnum, Long> delays = validateDelays(newAttributes,
+        List.of(ProjectAttributeEnum.KEEP_SCREENSHOTS,
+            ProjectAttributeEnum.KEEP_LOGS,
+            ProjectAttributeEnum.KEEP_LAUNCHES,
+            ProjectAttributeEnum.INTERRUPT_JOB_TIME
+        )
+    );
+
+    delayBoundValidator.validate(currentAttributes, delays);
+  }
+
+  private Map<ProjectAttributeEnum, Long> validateDelays(Map<String, String> attributes,
+      List<ProjectAttributeEnum> projectAttributes) {
+    return projectAttributes.stream()
+        .filter(it -> attributes.containsKey(it.getAttribute()))
+        .collect(Collectors.toMap(a -> a, a -> getDelay(attributes.get(a.getAttribute()))));
+  }
+
+  private Long getDelay(String value) {
+    final Long delay = FOREVER_ALIAS.equals(value) ? Long.MAX_VALUE : getLong(value);
+    BusinessRule.expect(delay, d -> d >= 0)
+        .verify(BAD_REQUEST_ERROR, "Delay attribute value should be greater than 0");
+    return delay;
+  }
+
+  private boolean validatePercentage(String value) {
+    final int percent = getInt(value);
+    return percent >= 0 && percent <= 100;
+  }
+
+  private Long getLong(String value) {
+    try {
+      return Long.parseLong(value);
+    } catch (NumberFormatException exc) {
+      throw new ReportPortalException(BAD_REQUEST_ERROR, exc.getMessage());
+    }
+  }
+
+  private Integer getInt(String value) {
+    try {
+      return Integer.parseInt(value);
+    } catch (NumberFormatException exc) {
+      throw new ReportPortalException(BAD_REQUEST_ERROR, exc.getMessage());
+    }
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/validator/notification/ProjectNotificationValidator.java b/src/main/java/com/epam/ta/reportportal/core/project/validator/notification/ProjectNotificationValidator.java
new file mode 100644
index 0000000000..d71e8aef83
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/core/project/validator/notification/ProjectNotificationValidator.java
@@ -0,0 +1,126 @@
+/*
+ *
+ * Copyright 2022 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.epam.ta.reportportal.core.project.validator.notification;
+
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import static com.epam.ta.reportportal.commons.Predicates.notNull;
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
+import static com.epam.ta.reportportal.entity.enums.SendCase.findByName;
+import static com.epam.ta.reportportal.ws.model.ErrorType.BAD_REQUEST_ERROR;
+import static java.util.Optional.ofNullable;
+import static java.util.stream.Collectors.toList;
+
+import com.epam.ta.reportportal.dao.SenderCaseRepository;
+import com.epam.ta.reportportal.entity.project.Project;
+import com.epam.ta.reportportal.util.email.EmailRulesValidator;
+import com.epam.ta.reportportal.ws.converter.converters.NotificationConfigConverter;
+import com.epam.ta.reportportal.ws.model.project.email.SenderCaseDTO;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author <a href="mailto:chingiskhan_kalanov@epam.com">Chingiskhan Kalanov</a>
+ */
+@Service
+public class ProjectNotificationValidator {
+
+  private final SenderCaseRepository senderCaseRepository;
+
+  @Autowired
+  public ProjectNotificationValidator(SenderCaseRepository senderCaseRepository) {
+    this.senderCaseRepository = senderCaseRepository;
+  }
+
+  public void validateCreateRQ(Project project, SenderCaseDTO senderCaseDTO) {
+    validateRecipients(senderCaseDTO);
+
+    normalizeCreateNotificationRQ(project, senderCaseDTO);
+
+    Optional<SenderCaseDTO> duplicate = senderCaseRepository.findAllByProjectId(project.getId())
+        .stream()
+        .map(NotificationConfigConverter.TO_CASE_RESOURCE)
+        .filter(existing -> equalsWithoutRuleName(existing, senderCaseDTO))
+        .findFirst();
+    expect(duplicate, Optional::isEmpty).verify(BAD_REQUEST_ERROR,
+        "Project email settings contain duplicate cases");
+  }
+
+  public void validateUpdateRQ(Project project, SenderCaseDTO senderCaseDTO) {
+    validateRecipients(senderCaseDTO);
+
+    normalizeCreateNotificationRQ(project, senderCaseDTO);
+
+    Optional<SenderCaseDTO> duplicate = senderCaseRepository.findAllByProjectId(project.getId())
+        .stream()
+        .filter(senderCase -> !Objects.equals(senderCase.getId(), senderCaseDTO.getId()))
+        .map(NotificationConfigConverter.TO_CASE_RESOURCE)
+        .filter(o1 -> equalsWithoutRuleName(o1, senderCaseDTO))
+        .findFirst();
+    expect(duplicate, Optional::isEmpty).verify(BAD_REQUEST_ERROR,
+        "Project email settings contain duplicate cases");
+  }
+
+  private void validateRecipients(SenderCaseDTO senderCaseDTO) {
+    List<String> recipients = senderCaseDTO.getRecipients();
+    expect(findByName(senderCaseDTO.getSendCase()), Optional::isPresent)
+        .verify(BAD_REQUEST_ERROR, senderCaseDTO.getSendCase());
+    expect(recipients, notNull()).verify(BAD_REQUEST_ERROR, "Recipients list should not be null");
+    expect(recipients.isEmpty(), equalTo(false))
+        .verify(BAD_REQUEST_ERROR,
+            formattedSupplier("Empty recipients list for email case '{}' ", senderCaseDTO));
+  }
+
+  private void normalizeCreateNotificationRQ(Project project, SenderCaseDTO createNotificationRQ) {
+    createNotificationRQ.setRecipients(
+        createNotificationRQ.getRecipients().stream().map(recipient -> {
+          EmailRulesValidator.validateRecipient(project, recipient);
+          return recipient.trim();
+        }).distinct().collect(toList())
+    );
+    ofNullable(createNotificationRQ.getLaunchNames()).ifPresent(
+        launchNames -> createNotificationRQ.setLaunchNames(
+            launchNames.stream().map(name -> {
+              EmailRulesValidator.validateLaunchName(name);
+              return name.trim();
+            }).distinct().collect(toList()))
+    );
+    ofNullable(createNotificationRQ.getAttributes()).ifPresent(
+        attributes -> createNotificationRQ.setAttributes(
+            attributes.stream().peek(attribute -> {
+              EmailRulesValidator.validateLaunchAttribute(attribute);
+              attribute.setValue(attribute.getValue().trim());
+            }).collect(Collectors.toSet()))
+    );
+  }
+
+  private boolean equalsWithoutRuleName(SenderCaseDTO senderCase, SenderCaseDTO toCompare) {
+    return CollectionUtils.isEqualCollection(senderCase.getRecipients(), toCompare.getRecipients())
+        && Objects.equals(senderCase.getSendCase(), toCompare.getSendCase())
+        && CollectionUtils.isEqualCollection(senderCase.getLaunchNames(),
+        toCompare.getLaunchNames())
+        && CollectionUtils.isEqualCollection(senderCase.getAttributes(), toCompare.getAttributes())
+        && Objects.equals(senderCase.getAttributesOperator(), toCompare.getAttributesOperator());
+  }
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/remover/ContentRemover.java b/src/main/java/com/epam/ta/reportportal/core/remover/ContentRemover.java
index 20c26c9441..265b4e4edb 100644
--- a/src/main/java/com/epam/ta/reportportal/core/remover/ContentRemover.java
+++ b/src/main/java/com/epam/ta/reportportal/core/remover/ContentRemover.java
@@ -5,5 +5,5 @@
  */
 public interface ContentRemover<T> {
 
-	void remove(T entity);
+  void remove(T entity);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/remover/item/ItemClusterRemover.java b/src/main/java/com/epam/ta/reportportal/core/remover/item/ItemClusterRemover.java
index 721d04d250..e916caaa77 100644
--- a/src/main/java/com/epam/ta/reportportal/core/remover/item/ItemClusterRemover.java
+++ b/src/main/java/com/epam/ta/reportportal/core/remover/item/ItemClusterRemover.java
@@ -27,15 +27,15 @@
 @Service
 public class ItemClusterRemover implements ContentRemover<Long> {
 
-	private final ClusterRepository clusterRepository;
+  private final ClusterRepository clusterRepository;
 
-	@Autowired
-	public ItemClusterRemover(ClusterRepository clusterRepository) {
-		this.clusterRepository = clusterRepository;
-	}
+  @Autowired
+  public ItemClusterRemover(ClusterRepository clusterRepository) {
+    this.clusterRepository = clusterRepository;
+  }
 
-	@Override
-	public void remove(Long itemId) {
-		clusterRepository.deleteClusterTestItemsByItemId(itemId);
-	}
+  @Override
+  public void remove(Long itemId) {
+    clusterRepository.deleteClusterTestItemsByItemId(itemId);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/remover/launch/LaunchClusterRemover.java b/src/main/java/com/epam/ta/reportportal/core/remover/launch/LaunchClusterRemover.java
index da0afca66b..0daff4456d 100644
--- a/src/main/java/com/epam/ta/reportportal/core/remover/launch/LaunchClusterRemover.java
+++ b/src/main/java/com/epam/ta/reportportal/core/remover/launch/LaunchClusterRemover.java
@@ -28,16 +28,16 @@
 @Service
 public class LaunchClusterRemover implements ContentRemover<Launch> {
 
-	private final ClusterRepository clusterRepository;
+  private final ClusterRepository clusterRepository;
 
-	@Autowired
-	public LaunchClusterRemover(ClusterRepository clusterRepository) {
-		this.clusterRepository = clusterRepository;
-	}
+  @Autowired
+  public LaunchClusterRemover(ClusterRepository clusterRepository) {
+    this.clusterRepository = clusterRepository;
+  }
 
-	@Override
-	public void remove(Launch launch) {
-		clusterRepository.deleteClusterTestItemsByLaunchId(launch.getId());
-		clusterRepository.deleteAllByLaunchId(launch.getId());
-	}
+  @Override
+  public void remove(Launch launch) {
+    clusterRepository.deleteClusterTestItemsByLaunchId(launch.getId());
+    clusterRepository.deleteAllByLaunchId(launch.getId());
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/remover/project/ProjectClusterRemover.java b/src/main/java/com/epam/ta/reportportal/core/remover/project/ProjectClusterRemover.java
index f633521c80..c7baa0e58e 100644
--- a/src/main/java/com/epam/ta/reportportal/core/remover/project/ProjectClusterRemover.java
+++ b/src/main/java/com/epam/ta/reportportal/core/remover/project/ProjectClusterRemover.java
@@ -28,16 +28,16 @@
 @Service
 public class ProjectClusterRemover implements ContentRemover<Project> {
 
-	private final ClusterRepository clusterRepository;
+  private final ClusterRepository clusterRepository;
 
-	@Autowired
-	public ProjectClusterRemover(ClusterRepository clusterRepository) {
-		this.clusterRepository = clusterRepository;
-	}
+  @Autowired
+  public ProjectClusterRemover(ClusterRepository clusterRepository) {
+    this.clusterRepository = clusterRepository;
+  }
 
-	@Override
-	public void remove(Project project) {
-		clusterRepository.deleteClusterTestItemsByProjectId(project.getId());
-		clusterRepository.deleteAllByProjectId(project.getId());
-	}
+  @Override
+  public void remove(Project project) {
+    clusterRepository.deleteClusterTestItemsByProjectId(project.getId());
+    clusterRepository.deleteAllByProjectId(project.getId());
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/remover/project/ProjectContentRemover.java b/src/main/java/com/epam/ta/reportportal/core/remover/project/ProjectContentRemover.java
index 0de8986f42..7eb913216c 100644
--- a/src/main/java/com/epam/ta/reportportal/core/remover/project/ProjectContentRemover.java
+++ b/src/main/java/com/epam/ta/reportportal/core/remover/project/ProjectContentRemover.java
@@ -18,7 +18,6 @@
 
 import com.epam.ta.reportportal.core.remover.ContentRemover;
 import com.epam.ta.reportportal.entity.project.Project;
-
 import java.util.List;
 
 /**
@@ -26,14 +25,14 @@
  */
 public class ProjectContentRemover implements ContentRemover<Project> {
 
-	private final List<ContentRemover<Project>> removers;
+  private final List<ContentRemover<Project>> removers;
 
-	public ProjectContentRemover(List<ContentRemover<Project>> removers) {
-		this.removers = removers;
-	}
+  public ProjectContentRemover(List<ContentRemover<Project>> removers) {
+    this.removers = removers;
+  }
 
-	@Override
-	public void remove(Project project) {
-		removers.forEach(r -> r.remove(project));
-	}
+  @Override
+  public void remove(Project project) {
+    removers.forEach(r -> r.remove(project));
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/remover/project/ProjectWidgetRemover.java b/src/main/java/com/epam/ta/reportportal/core/remover/project/ProjectWidgetRemover.java
index d1c7d45174..9c50d69602 100644
--- a/src/main/java/com/epam/ta/reportportal/core/remover/project/ProjectWidgetRemover.java
+++ b/src/main/java/com/epam/ta/reportportal/core/remover/project/ProjectWidgetRemover.java
@@ -6,34 +6,33 @@
 import com.epam.ta.reportportal.entity.project.Project;
 import com.epam.ta.reportportal.entity.widget.Widget;
 import com.epam.ta.reportportal.entity.widget.WidgetType;
+import java.util.Collections;
+import java.util.List;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 
-import java.util.Collections;
-import java.util.List;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class ProjectWidgetRemover implements ContentRemover<Project> {
 
-	private final WidgetRepository widgetRepository;
-	private final WidgetContentRemover widgetContentRemover;
+  private final WidgetRepository widgetRepository;
+  private final WidgetContentRemover widgetContentRemover;
 
-	@Autowired
-	public ProjectWidgetRemover(WidgetRepository widgetRepository,
-			@Qualifier("delegatingStateContentRemover") WidgetContentRemover widgetContentRemover) {
-		this.widgetRepository = widgetRepository;
-		this.widgetContentRemover = widgetContentRemover;
-	}
+  @Autowired
+  public ProjectWidgetRemover(WidgetRepository widgetRepository,
+      @Qualifier("delegatingStateContentRemover") WidgetContentRemover widgetContentRemover) {
+    this.widgetRepository = widgetRepository;
+    this.widgetContentRemover = widgetContentRemover;
+  }
 
-	@Override
-	public void remove(Project project) {
-		List<Widget> widgets = widgetRepository.findAllByProjectIdAndWidgetTypeIn(project.getId(),
-				Collections.singletonList(WidgetType.COMPONENT_HEALTH_CHECK_TABLE.getType())
-		);
-		widgets.forEach(widgetContentRemover::removeContent);
-	}
+  @Override
+  public void remove(Project project) {
+    List<Widget> widgets = widgetRepository.findAllByProjectIdAndWidgetTypeIn(project.getId(),
+        Collections.singletonList(WidgetType.COMPONENT_HEALTH_CHECK_TABLE.getType())
+    );
+    widgets.forEach(widgetContentRemover::removeContent);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/remover/user/UserContentRemover.java b/src/main/java/com/epam/ta/reportportal/core/remover/user/UserContentRemover.java
new file mode 100644
index 0000000000..c966c748af
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/core/remover/user/UserContentRemover.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2022 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.core.remover.user;
+
+import com.epam.ta.reportportal.core.remover.ContentRemover;
+import com.epam.ta.reportportal.entity.user.User;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:chingiskhan_kalanov@epam.com">Chingiskhan Kalanov</a>
+ */
+public class UserContentRemover implements ContentRemover<User> {
+
+  private final List<ContentRemover<User>> removers;
+
+  public UserContentRemover(List<ContentRemover<User>> removers) {
+    this.removers = removers;
+  }
+
+  @Override
+  public void remove(User user) {
+    removers.forEach(r -> r.remove(user));
+  }
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/remover/user/UserPhotoRemover.java b/src/main/java/com/epam/ta/reportportal/core/remover/user/UserPhotoRemover.java
new file mode 100644
index 0000000000..977867cd60
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/core/remover/user/UserPhotoRemover.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2022 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.core.remover.user;
+
+import static java.util.Optional.ofNullable;
+
+import com.epam.ta.reportportal.core.remover.ContentRemover;
+import com.epam.ta.reportportal.dao.AttachmentRepository;
+import com.epam.ta.reportportal.entity.attachment.Attachment;
+import com.epam.ta.reportportal.entity.user.User;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author <a href="mailto:chingiskhan_kalanov@epam.com">Chingiskhan Kalanov</a>
+ */
+@Service
+public class UserPhotoRemover implements ContentRemover<User> {
+
+  private static final String ATTACHMENT_CONTENT_TYPE = "attachmentContentType";
+
+  private final AttachmentRepository attachmentRepository;
+
+  @Autowired
+  public UserPhotoRemover(AttachmentRepository attachmentRepository) {
+    this.attachmentRepository = attachmentRepository;
+  }
+
+  @Override
+  public void remove(User user) {
+    ofNullable(user.getAttachment()).ifPresent(fileId -> {
+      List<Long> attachmentsIds = new ArrayList<>(2);
+      attachmentsIds.add(prepareAttachmentAndGetId(fileId));
+      Optional.ofNullable(user.getAttachmentThumbnail())
+          .ifPresent(thumbnailId -> attachmentsIds.add(prepareAttachmentAndGetId(thumbnailId)));
+      ofNullable(user.getMetadata()).ifPresent(
+          metadata -> metadata.getMetadata().remove(ATTACHMENT_CONTENT_TYPE));
+      attachmentRepository.moveForDeletion(attachmentsIds);
+    });
+  }
+
+  private Long prepareAttachmentAndGetId(String fileId) {
+    Attachment attachment = new Attachment();
+    attachment.setFileId(fileId);
+    attachment.setCreationDate(LocalDateTime.now());
+    return attachmentRepository.save(attachment).getId();
+  }
+}
diff --git a/src/main/java/com/epam/ta/reportportal/core/remover/user/UserWidgetRemover.java b/src/main/java/com/epam/ta/reportportal/core/remover/user/UserWidgetRemover.java
index ad5013043b..9d743e28e0 100644
--- a/src/main/java/com/epam/ta/reportportal/core/remover/user/UserWidgetRemover.java
+++ b/src/main/java/com/epam/ta/reportportal/core/remover/user/UserWidgetRemover.java
@@ -22,11 +22,10 @@
 import com.epam.ta.reportportal.entity.user.User;
 import com.epam.ta.reportportal.entity.widget.Widget;
 import com.epam.ta.reportportal.entity.widget.WidgetType;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.stereotype.Service;
-
 import java.util.Collections;
 import java.util.List;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -34,20 +33,20 @@
 @Service
 public class UserWidgetRemover implements ContentRemover<User> {
 
-	private final WidgetRepository widgetRepository;
-	private final WidgetContentRemover widgetContentRemover;
+  private final WidgetRepository widgetRepository;
+  private final WidgetContentRemover widgetContentRemover;
 
-	public UserWidgetRemover(WidgetRepository widgetRepository,
-			@Qualifier("delegatingStateContentRemover") WidgetContentRemover widgetContentRemover) {
-		this.widgetRepository = widgetRepository;
-		this.widgetContentRemover = widgetContentRemover;
-	}
+  public UserWidgetRemover(WidgetRepository widgetRepository,
+      @Qualifier("delegatingStateContentRemover") WidgetContentRemover widgetContentRemover) {
+    this.widgetRepository = widgetRepository;
+    this.widgetContentRemover = widgetContentRemover;
+  }
 
-	@Override
-	public void remove(User user) {
-		List<Widget> widgets = widgetRepository.findAllByOwnerAndWidgetTypeIn(user.getLogin(),
-				Collections.singletonList(WidgetType.COMPONENT_HEALTH_CHECK_TABLE.getType())
-		);
-		widgets.forEach(widgetContentRemover::removeContent);
-	}
+  @Override
+  public void remove(User user) {
+    List<Widget> widgets = widgetRepository.findAllByOwnerAndWidgetTypeIn(user.getLogin(),
+        Collections.singletonList(WidgetType.COMPONENT_HEALTH_CHECK_TABLE.getType())
+    );
+    widgets.forEach(widgetContentRemover::removeContent);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/statistics/StatisticsHelper.java b/src/main/java/com/epam/ta/reportportal/core/statistics/StatisticsHelper.java
index 9c4c794e5c..5d84cf435b 100644
--- a/src/main/java/com/epam/ta/reportportal/core/statistics/StatisticsHelper.java
+++ b/src/main/java/com/epam/ta/reportportal/core/statistics/StatisticsHelper.java
@@ -16,62 +16,66 @@
 
 package com.epam.ta.reportportal.core.statistics;
 
+import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.NOT_ISSUE_FLAG;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.entity.enums.StatusEnum;
 import com.epam.ta.reportportal.entity.enums.TestItemIssueGroup;
 import com.epam.ta.reportportal.entity.statistics.Statistics;
 import com.epam.ta.reportportal.entity.statistics.StatisticsField;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
-
 import java.util.Arrays;
 import java.util.Set;
 import java.util.function.Predicate;
 import java.util.stream.Stream;
 
-import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.NOT_ISSUE_FLAG;
-import static java.util.Optional.ofNullable;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public final class StatisticsHelper {
 
-	private static final String TOTAL = "statistics$executions$total";
-	private static final String PASSED = "statistics$executions$passed";
-	private static final String SKIPPED = "statistics$executions$skipped";
-	private static final String FAILED = "statistics$executions$failed";
+  private static final String TOTAL = "statistics$executions$total";
+  private static final String PASSED = "statistics$executions$passed";
+  private static final String SKIPPED = "statistics$executions$skipped";
+  private static final String FAILED = "statistics$executions$failed";
 
-	private StatisticsHelper() {
-		//static only
-	}
+  private StatisticsHelper() {
+    //static only
+  }
 
-	public static StatusEnum getStatusFromStatistics(Set<Statistics> statistics) {
-		return statistics.stream().anyMatch(FAILED_PREDICATE) ? StatusEnum.FAILED : StatusEnum.PASSED;
-	}
+  public static StatusEnum getStatusFromStatistics(Set<Statistics> statistics) {
+    return statistics.stream().anyMatch(FAILED_PREDICATE) ? StatusEnum.FAILED : StatusEnum.PASSED;
+  }
 
-	private final static Predicate<Statistics> FAILED_PREDICATE = statistics -> {
-		StatisticsField statisticsField = ofNullable(statistics.getStatisticsField()).orElseThrow(() -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR,
-				"Statistics should contain a name field."
-		));
-		String field = statisticsField.getName();
-		Integer counter = statistics.getCounter();
-		return (field.contains("failed") || field.contains("skipped") || field.contains("to_investigate")) && counter > 0;
-	};
+  private final static Predicate<Statistics> FAILED_PREDICATE = statistics -> {
+    StatisticsField statisticsField = ofNullable(statistics.getStatisticsField()).orElseThrow(
+        () -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR,
+            "Statistics should contain a name field."
+        ));
+    String field = statisticsField.getName();
+    Integer counter = statistics.getCounter();
+    return
+        (field.contains("failed") || field.contains("skipped") || field.contains("to_investigate"))
+            && counter > 0;
+  };
 
-	public static Integer extractStatisticsCount(String statisticsField, Set<Statistics> statistics) {
-		return statistics.stream()
-				.filter(it -> it.getStatisticsField().getName().equalsIgnoreCase(statisticsField))
-				.findFirst()
-				.orElse(new Statistics())
-				.getCounter();
-	}
+  public static Integer extractStatisticsCount(String statisticsField, Set<Statistics> statistics) {
+    return statistics.stream()
+        .filter(it -> it.getStatisticsField().getName().equalsIgnoreCase(statisticsField))
+        .findFirst()
+        .orElse(new Statistics())
+        .getCounter();
+  }
 
-	public static Stream<String> defaultStatisticsFields() {
-		return Stream.concat(
-				Arrays.stream(TestItemIssueGroup.values())
-						.filter(value -> !value.getIssueCounterField().equalsIgnoreCase(NOT_ISSUE_FLAG.getIssueCounterField()))
-						.map(value -> "statistics$defects$" + value.getValue().toLowerCase() + "$" + value.getLocator()),
-				Stream.of(TOTAL, PASSED, SKIPPED, FAILED)
-		);
-	}
+  public static Stream<String> defaultStatisticsFields() {
+    return Stream.concat(
+        Arrays.stream(TestItemIssueGroup.values())
+            .filter(value -> !value.getIssueCounterField()
+                .equalsIgnoreCase(NOT_ISSUE_FLAG.getIssueCounterField()))
+            .map(value -> "statistics$defects$" + value.getValue().toLowerCase() + "$"
+                + value.getLocator()),
+        Stream.of(TOTAL, PASSED, SKIPPED, FAILED)
+    );
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/user/CreateUserHandler.java b/src/main/java/com/epam/ta/reportportal/core/user/CreateUserHandler.java
index 9741a99305..b10b1c7ea7 100644
--- a/src/main/java/com/epam/ta/reportportal/core/user/CreateUserHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/user/CreateUserHandler.java
@@ -19,7 +19,13 @@
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
 import com.epam.ta.reportportal.ws.model.YesNoRS;
-import com.epam.ta.reportportal.ws.model.user.*;
+import com.epam.ta.reportportal.ws.model.user.CreateUserBidRS;
+import com.epam.ta.reportportal.ws.model.user.CreateUserRQ;
+import com.epam.ta.reportportal.ws.model.user.CreateUserRQConfirm;
+import com.epam.ta.reportportal.ws.model.user.CreateUserRQFull;
+import com.epam.ta.reportportal.ws.model.user.CreateUserRS;
+import com.epam.ta.reportportal.ws.model.user.ResetPasswordRQ;
+import com.epam.ta.reportportal.ws.model.user.RestorePasswordRQ;
 
 /**
  * Post request handler
@@ -28,56 +34,57 @@
  */
 public interface CreateUserHandler {
 
-	/**
-	 * Create completed user object by administrator
-	 *
-	 * @param request  Create request
-	 * @param user     User that creates request
-	 * @param basicUrl App URL for user URL to be created
-	 * @return Operation result
-	 */
-	CreateUserRS createUserByAdmin(CreateUserRQFull request, ReportPortalUser user, String basicUrl);
+  /**
+   * Create completed user object by administrator
+   *
+   * @param request  Create request
+   * @param user     User that creates request
+   * @param basicUrl App URL for user URL to be created
+   * @return Operation result
+   */
+  CreateUserRS createUserByAdmin(CreateUserRQFull request, ReportPortalUser user, String basicUrl);
 
-	/**
-	 * Create new User (confirm invitation)
-	 *
-	 * @param request Create request
-	 * @param uuid    Create UUID
-	 * @return Operation result
-	 */
-	CreateUserRS createUser(CreateUserRQConfirm request, String uuid);
+  /**
+   * Create new User (confirm invitation)
+   *
+   * @param request Create request
+   * @param uuid    Create UUID
+   * @return Operation result
+   */
+  CreateUserRS createUser(CreateUserRQConfirm request, String uuid);
 
-	/**
-	 * Create user bid (send invitation)
-	 *
-	 * @param request  Create Request
-	 * @param username Username/User that creates the request
-	 * @return Operation result
-	 */
-	CreateUserBidRS createUserBid(CreateUserRQ request, ReportPortalUser username, String userRegURL);
+  /**
+   * Create user bid (send invitation)
+   *
+   * @param request    Create Request
+   * @param username   Username/User that creates the request
+   * @param userRegURL User registration url
+   * @return Operation result
+   */
+  CreateUserBidRS createUserBid(CreateUserRQ request, ReportPortalUser username, String userRegURL);
 
-	/**
-	 * Create restore password bid
-	 *
-	 * @param rq      Restore RQ
-	 * @param baseUrl App Base URL for reset URL to be built
-	 * @return Operation result
-	 */
-	OperationCompletionRS createRestorePasswordBid(RestorePasswordRQ rq, String baseUrl);
+  /**
+   * Create restore password bid
+   *
+   * @param rq      Restore RQ
+   * @param baseUrl App Base URL for reset URL to be built
+   * @return Operation result
+   */
+  OperationCompletionRS createRestorePasswordBid(RestorePasswordRQ rq, String baseUrl);
 
-	/**
-	 * Reset password
-	 *
-	 * @param rq
-	 * @return Operation result
-	 */
-	OperationCompletionRS resetPassword(ResetPasswordRQ rq);
+  /**
+   * Reset password
+   *
+   * @param rq request for reset password
+   * @return Operation result
+   */
+  OperationCompletionRS resetPassword(ResetPasswordRQ rq);
 
-	/**
-	 * Verify reset password bid exist
-	 *
-	 * @param uuid Reset Password UUID
-	 * @return {@link YesNoRS}
-	 */
-	YesNoRS isResetPasswordBidExist(String uuid);
+  /**
+   * Verify reset password bid exist
+   *
+   * @param uuid Reset Password UUID
+   * @return {@link YesNoRS}
+   */
+  YesNoRS isResetPasswordBidExist(String uuid);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/user/DeleteUserHandler.java b/src/main/java/com/epam/ta/reportportal/core/user/DeleteUserHandler.java
index 531b5f4048..b14a0c9b4f 100644
--- a/src/main/java/com/epam/ta/reportportal/core/user/DeleteUserHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/user/DeleteUserHandler.java
@@ -27,14 +27,16 @@
  * @author Aliaksandr_Kazantsau
  */
 public interface DeleteUserHandler {
-	/**
-	 * Delete User
-	 *
-	 * @param userId      User to be deleted
-	 * @param currentUser User performing the edit operation
-	 * @return Operation result
-	 */
-	OperationCompletionRS deleteUser(Long userId, ReportPortalUser currentUser);
+
+  /**
+   * Delete User, User Personal Project, User Photo. User Dashboard, Widgets, Filters still
+   * available.
+   *
+   * @param userId      User to be deleted
+   * @param currentUser User performing the edit operation
+   * @return Operation result
+   */
+  OperationCompletionRS deleteUser(Long userId, ReportPortalUser currentUser);
 
 	DeleteBulkRS deleteUsers(List<Long> ids, ReportPortalUser currentUser);
 
diff --git a/src/main/java/com/epam/ta/reportportal/core/user/EditUserHandler.java b/src/main/java/com/epam/ta/reportportal/core/user/EditUserHandler.java
index 77077703a7..bd79cc62f0 100644
--- a/src/main/java/com/epam/ta/reportportal/core/user/EditUserHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/user/EditUserHandler.java
@@ -29,39 +29,40 @@
  */
 public interface EditUserHandler {
 
-	/**
-	 * Edit User
-	 *
-	 * @param username   Name of user
-	 * @param editUserRQ Edit request
-	 * @param editor     User performing the edit operation
-	 * @return Completion result
-	 */
-	OperationCompletionRS editUser(String username, EditUserRQ editUserRQ, ReportPortalUser editor);
+  /**
+   * Edit User
+   *
+   * @param username   Name of user
+   * @param editUserRQ Edit request
+   * @param editor     User performing the edit operation
+   * @return Completion result
+   */
+  OperationCompletionRS editUser(String username, EditUserRQ editUserRQ, ReportPortalUser editor);
 
-	/**
-	 * Upload photo
-	 *
-	 * @param username Name of user
-	 * @param file     New photo
-	 * @return Completion result
-	 */
-	OperationCompletionRS uploadPhoto(String username, MultipartFile file);
+  /**
+   * Upload photo
+   *
+   * @param username Name of user
+   * @param file     New photo
+   * @return Completion result
+   */
+  OperationCompletionRS uploadPhoto(String username, MultipartFile file);
 
-	/**
-	 * Delete user's photo
-	 *
-	 * @param username Name of user
-	 * @return Completion result
-	 */
-	OperationCompletionRS deletePhoto(String username);
+  /**
+   * Delete user's photo
+   *
+   * @param username Name of user
+   * @return Completion result
+   */
+  OperationCompletionRS deletePhoto(String username);
 
-	/**
-	 * Change password
-	 *
-	 * @param currentUser      User performing the edit operation
-	 * @param changePasswordRQ Request body
-	 * @return Completion result
-	 */
-	OperationCompletionRS changePassword(ReportPortalUser currentUser, ChangePasswordRQ changePasswordRQ);
+  /**
+   * Change password
+   *
+   * @param currentUser      User performing the edit operation
+   * @param changePasswordRQ Request body
+   * @return Completion result
+   */
+  OperationCompletionRS changePassword(ReportPortalUser currentUser,
+      ChangePasswordRQ changePasswordRQ);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/user/GetUserHandler.java b/src/main/java/com/epam/ta/reportportal/core/user/GetUserHandler.java
index 2ec3853f4b..11ad6bd045 100644
--- a/src/main/java/com/epam/ta/reportportal/core/user/GetUserHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/user/GetUserHandler.java
@@ -23,80 +23,80 @@
 import com.epam.ta.reportportal.ws.model.YesNoRS;
 import com.epam.ta.reportportal.ws.model.user.UserBidRS;
 import com.epam.ta.reportportal.ws.model.user.UserResource;
-import org.springframework.data.domain.Pageable;
-
-import javax.servlet.http.HttpServletResponse;
 import java.io.OutputStream;
 import java.util.Map;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.data.domain.Pageable;
 
 /**
  * @author Andrei_Ramanchuk
  */
 public interface GetUserHandler {
 
-	/**
-	 * Get specified user info
-	 *
-	 * @param username    Username
-	 * @param currentUser Logged-in username
-	 * @return {@link UserResource}
-	 */
-	UserResource getUser(String username, ReportPortalUser currentUser);
+  /**
+   * Get specified user info
+   *
+   * @param username    Username
+   * @param currentUser Logged-in username
+   * @return {@link UserResource}
+   */
+  UserResource getUser(String username, ReportPortalUser currentUser);
 
-	/**
-	 * Get logged-in user info
-	 *
-	 * @param currentUser Logged-in username
-	 * @return {@link UserResource}
-	 */
-	UserResource getUser(ReportPortalUser currentUser);
+  /**
+   * Get logged-in user info
+   *
+   * @param currentUser Logged-in username
+   * @return {@link UserResource}
+   */
+  UserResource getUser(ReportPortalUser currentUser);
 
-	/**
-	 * Get information about user registration bid
-	 *
-	 * @param uuid UUID
-	 * @return {@link UserBidRS}
-	 */
-	UserBidRS getBidInformation(String uuid);
+  /**
+   * Get information about user registration bid
+   *
+   * @param uuid UUID
+   * @return {@link UserBidRS}
+   */
+  UserBidRS getBidInformation(String uuid);
 
-	/**
-	 * Validate existence of username or email
-	 *
-	 * @param username User name
-	 * @param email    email
-	 * @return {@link YesNoRS}
-	 */
-	YesNoRS validateInfo(String username, String email);
+  /**
+   * Validate existence of username or email
+   *
+   * @param username User name
+   * @param email    email
+   * @return {@link YesNoRS}
+   */
+  YesNoRS validateInfo(String username, String email);
 
-	/**
-	 * Get all users by filter with paging
-	 *
-	 * @param filter         Filter
-	 * @param pageable       Paging
-	 * @param projectDetails Project details
-	 * @return Page of users
-	 */
-	Iterable<UserResource> getUsers(Filter filter, Pageable pageable, ReportPortalUser.ProjectDetails projectDetails);
+  /**
+   * Get all users by filter with paging
+   *
+   * @param filter         Filter
+   * @param pageable       Paging
+   * @param projectDetails Project details
+   * @return Page of users
+   */
+  Iterable<UserResource> getUsers(Filter filter, Pageable pageable,
+      ReportPortalUser.ProjectDetails projectDetails);
 
-	Map<String, UserResource.AssignedProject> getUserProjects(String userName);
+  Map<String, UserResource.AssignedProject> getUserProjects(String userName);
 
-	/**
-	 * Get page of users with filter
-	 *
-	 * @param filter   Filter
-	 * @param pageable Paging
-	 * @return Page of {@link UserResource}
-	 */
-	Iterable<UserResource> getAllUsers(Queryable filter, Pageable pageable);
+  /**
+   * Get page of users with filter
+   *
+   * @param filter   Filter
+   * @param pageable Paging
+   * @return Page of {@link UserResource}
+   */
+  Iterable<UserResource> getAllUsers(Queryable filter, Pageable pageable);
 
-	/**
-	 * Export Users info according to the {@link ReportFormat} type
-	 *
-	 * @param reportFormat {@link ReportFormat}
-	 * @param filter       {@link Filter}
-	 * @param outputStream {@link HttpServletResponse#getOutputStream()}
-	 */
-	void exportUsers(ReportFormat reportFormat, OutputStream outputStream, Queryable filter);
+  /**
+   * Export Users info according to the {@link ReportFormat} type
+   *
+   * @param reportFormat {@link ReportFormat}
+   * @param filter       {@link Filter}
+   * @param outputStream {@link HttpServletResponse#getOutputStream()}
+   */
+  void exportUsers(ReportFormat reportFormat, OutputStream outputStream, Queryable filter);
 
-	Iterable<UserResource> searchUsers(String term, Pageable pageable);
+  Iterable<UserResource> searchUsers(String term, Pageable pageable);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/user/impl/ApiKeyHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/user/impl/ApiKeyHandlerImpl.java
index a018144c73..bc81adebd3 100644
--- a/src/main/java/com/epam/ta/reportportal/core/user/impl/ApiKeyHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/user/impl/ApiKeyHandlerImpl.java
@@ -18,6 +18,7 @@
 
 import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
 import static com.epam.ta.reportportal.ws.model.ErrorType.BAD_REQUEST_ERROR;
+import static com.epam.ta.reportportal.ws.model.ErrorType.NOT_FOUND;
 
 import com.epam.ta.reportportal.commons.Predicates;
 import com.epam.ta.reportportal.commons.validation.Suppliers;
@@ -29,6 +30,7 @@
 import com.epam.ta.reportportal.ws.converter.converters.ApiKeyConverter;
 import com.epam.ta.reportportal.ws.model.ApiKeyRS;
 import com.epam.ta.reportportal.ws.model.ApiKeysRS;
+import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
 import com.google.common.annotations.VisibleForTesting;
 import java.nio.ByteBuffer;
@@ -37,6 +39,7 @@
 import java.util.Base64;
 import java.util.List;
 import java.util.UUID;
+import java.util.function.Predicate;
 import java.util.stream.Collectors;
 import javax.xml.bind.DatatypeConverter;
 import org.apache.commons.codec.digest.DigestUtils;
@@ -92,6 +95,8 @@ public ApiKeyRS createApiKey(String name, Long userId) {
 
   @Override
   public OperationCompletionRS deleteApiKey(Long id) {
+    expect(apiKeyRepository.existsById(id), Predicates.equalTo(true))
+        .verify(NOT_FOUND, "Api key");
     apiKeyRepository.deleteById(id);
     return new OperationCompletionRS("Api key with ID = '" + id + "' was successfully deleted.");
   }
diff --git a/src/main/java/com/epam/ta/reportportal/core/user/impl/CreateUserHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/user/impl/CreateUserHandlerImpl.java
index a43751c234..5baa5625e9 100644
--- a/src/main/java/com/epam/ta/reportportal/core/user/impl/CreateUserHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/user/impl/CreateUserHandlerImpl.java
@@ -38,6 +38,7 @@
 import com.epam.ta.reportportal.auth.authenticator.UserAuthenticator;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.validation.Suppliers;
+import com.epam.ta.reportportal.core.events.activity.CreateInvitationLinkEvent;
 import com.epam.ta.reportportal.core.events.activity.UserCreatedEvent;
 import com.epam.ta.reportportal.core.integration.GetIntegrationHandler;
 import com.epam.ta.reportportal.core.project.CreateProjectHandler;
@@ -47,6 +48,7 @@
 import com.epam.ta.reportportal.dao.RestorePasswordBidRepository;
 import com.epam.ta.reportportal.dao.UserCreationBidRepository;
 import com.epam.ta.reportportal.dao.UserRepository;
+import com.epam.ta.reportportal.entity.Metadata;
 import com.epam.ta.reportportal.entity.enums.IntegrationGroupEnum;
 import com.epam.ta.reportportal.entity.integration.Integration;
 import com.epam.ta.reportportal.entity.project.Project;
@@ -75,6 +77,8 @@
 import com.epam.ta.reportportal.ws.model.user.CreateUserRS;
 import com.epam.ta.reportportal.ws.model.user.ResetPasswordRQ;
 import com.epam.ta.reportportal.ws.model.user.RestorePasswordRQ;
+import com.google.common.collect.Maps;
+import java.util.Map;
 import java.util.Optional;
 import java.util.function.Predicate;
 import javax.persistence.PersistenceException;
@@ -96,6 +100,9 @@
 @Service
 public class CreateUserHandlerImpl implements CreateUserHandler {
 
+  public static final String BID_TYPE = "type";
+  public static final String INTERNAL_BID_TYPE = "internal";
+
   private final UserRepository userRepository;
 
   private final UserAuthenticator userAuthenticator;
@@ -156,7 +163,7 @@ public CreateUserRS createUserByAdmin(CreateUserRQFull request, ReportPortalUser
 
     normalize(request);
 
-    Pair<UserActivityResource, CreateUserRS> pair = saveUser(request, administrator);
+    Pair<UserActivityResource, CreateUserRS> pair = saveUser(request, administrator, false);
 
     emailExecutorService.execute(() -> emailServiceFactory.getDefaultEmailService(true)
         .sendCreateUserConfirmationEmail(request, basicUrl));
@@ -205,7 +212,7 @@ private String getNormalized(String original) {
   }
 
   private Pair<UserActivityResource, CreateUserRS> saveUser(CreateUserRQFull request,
-      User creator) {
+      User creator, boolean isSystemEvent) {
 
     final Project projectToAssign =
         getProjectHandler.getRaw(normalizeId(request.getDefaultProject()));
@@ -220,7 +227,7 @@ private Pair<UserActivityResource, CreateUserRS> saveUser(CreateUserRQFull reque
       userRepository.save(user);
       UserActivityResource userActivityResource = getUserActivityResource(user);
       UserCreatedEvent userCreatedEvent = new UserCreatedEvent(userActivityResource,
-          creator.getId(), creator.getLogin());
+          creator.getId(), creator.getLogin(), isSystemEvent);
       eventPublisher.publishEvent(userCreatedEvent);
     } catch (PersistenceException pe) {
       if (pe.getCause() instanceof ConstraintViolationException) {
@@ -234,9 +241,9 @@ private Pair<UserActivityResource, CreateUserRS> saveUser(CreateUserRQFull reque
 
     userAuthenticator.authenticate(user);
 
-    projectUserHandler.assign(user, projectToAssign, projectRole, creator);
+    projectUserHandler.assign(user, projectToAssign, projectRole, creator, false);
     final Project personalProject = createProjectHandler.createPersonal(user);
-    projectUserHandler.assign(user, personalProject, ProjectRole.PROJECT_MANAGER, creator);
+    projectUserHandler.assign(user, personalProject, ProjectRole.PROJECT_MANAGER, creator, isSystemEvent);
 
     final CreateUserRS response = new CreateUserRS();
     response.setId(user.getId());
@@ -265,7 +272,7 @@ private User convert(CreateUserRQFull request) {
   @Override
   @Transactional
   public CreateUserRS createUser(CreateUserRQConfirm request, String uuid) {
-    final UserCreationBid bid = userCreationBidRepository.findById(uuid)
+    final UserCreationBid bid = userCreationBidRepository.findByUuidAndType(uuid, INTERNAL_BID_TYPE)
         .orElseThrow(() -> new ReportPortalException(INCORRECT_REQUEST,
             "Impossible to register user. UUID expired or already registered."
         ));
@@ -277,7 +284,7 @@ public CreateUserRS createUser(CreateUserRQConfirm request, String uuid) {
         "Email from bid not match.");
 
     User invitingUser = bid.getInvitingUser();
-    final Pair<UserActivityResource, CreateUserRS> pair = saveUser(createUserRQFull, invitingUser);
+    final Pair<UserActivityResource, CreateUserRS> pair = saveUser(createUserRQFull, invitingUser, true);
 
     userCreationBidRepository.deleteAllByEmail(createUserRQFull.getEmail());
 
@@ -291,7 +298,7 @@ private CreateUserRQFull convertToCreateRequest(CreateUserRQConfirm request,
     createUserRQFull.setEmail(request.getEmail());
     createUserRQFull.setFullName(request.getFullName());
     createUserRQFull.setPassword(request.getPassword());
-    createUserRQFull.setDefaultProject(bid.getDefaultProject().getName());
+    createUserRQFull.setDefaultProject(bid.getProjectName());
     createUserRQFull.setAccountRole(UserRole.USER.name());
     createUserRQFull.setProjectRole(bid.getRole());
     return createUserRQFull;
@@ -333,6 +340,7 @@ public CreateUserBidRS createUserBid(CreateUserRQ request, ReportPortalUser logg
         () -> new ReportPortalException(ROLE_NOT_FOUND, request.getRole())).name());
 
     UserCreationBid bid = UserCreationBidConverter.TO_USER.apply(request, defaultProject);
+    bid.setMetadata(getUserCreationBidMetadata());
     bid.setInvitingUser(userRepository.getById(loggedInUser.getUserId()));
     try {
       userCreationBidRepository.save(bid);
@@ -346,6 +354,10 @@ public CreateUserBidRS createUserBid(CreateUserRQ request, ReportPortalUser logg
         .sendCreateUserConfirmationEmail("User registration confirmation",
             new String[] {bid.getEmail()}, emailLink.toString()));
 
+    eventPublisher.publishEvent(
+        new CreateInvitationLinkEvent(loggedInUser.getUserId(), loggedInUser.getUsername(),
+            defaultProject.getId()));
+
     CreateUserBidRS response = new CreateUserBidRS();
     String msg = "Bid for user creation with email '" + request.getEmail()
         + "' is successfully registered. Confirmation info will be send on provided email. "
@@ -357,6 +369,12 @@ public CreateUserBidRS createUserBid(CreateUserRQ request, ReportPortalUser logg
     return response;
   }
 
+  private Metadata getUserCreationBidMetadata() {
+    final Map<String, Object> meta = Maps.newHashMapWithExpectedSize(1);
+    meta.put(BID_TYPE, INTERNAL_BID_TYPE);
+    return new Metadata(meta);
+  }
+
   @Override
   public OperationCompletionRS createRestorePasswordBid(RestorePasswordRQ rq, String baseUrl) {
     String email = normalizeId(rq.getEmail());
diff --git a/src/main/java/com/epam/ta/reportportal/core/user/impl/GetUserHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/user/impl/GetUserHandlerImpl.java
index a30ee5ac32..6459fbf948 100644
--- a/src/main/java/com/epam/ta/reportportal/core/user/impl/GetUserHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/user/impl/GetUserHandlerImpl.java
@@ -16,6 +16,14 @@
 
 package com.epam.ta.reportportal.core.user.impl;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_PROJECT_ID;
+import static com.epam.ta.reportportal.commons.querygen.constant.UserCriteriaConstant.CRITERIA_EMAIL;
+import static com.epam.ta.reportportal.commons.querygen.constant.UserCriteriaConstant.CRITERIA_EXPIRED;
+import static com.epam.ta.reportportal.commons.querygen.constant.UserCriteriaConstant.CRITERIA_USER;
+import static com.epam.ta.reportportal.core.user.impl.CreateUserHandlerImpl.INTERNAL_BID_TYPE;
+import static java.util.Optional.ofNullable;
+import static java.util.stream.Collectors.toMap;
+
 import com.epam.ta.reportportal.commons.EntityUtils;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.querygen.Condition;
@@ -42,6 +50,11 @@
 import com.epam.ta.reportportal.ws.model.user.UserBidRS;
 import com.epam.ta.reportportal.ws.model.user.UserResource;
 import com.google.common.base.Preconditions;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
 import net.sf.jasperreports.engine.JRDataSource;
 import net.sf.jasperreports.engine.JasperPrint;
 import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
@@ -52,17 +65,6 @@
 import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
 
-import java.io.OutputStream;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_PROJECT_ID;
-import static com.epam.ta.reportportal.commons.querygen.constant.UserCriteriaConstant.*;
-import static java.util.Optional.ofNullable;
-import static java.util.stream.Collectors.toMap;
-
 /**
  * Implementation for GET user operations
  *
@@ -71,129 +73,139 @@
 @Service
 public class GetUserHandlerImpl implements GetUserHandler {
 
-	private final UserRepository userRepository;
-
-	private final UserCreationBidRepository userCreationBidRepository;
-
-	private final ProjectRepository projectRepository;
-
-	private final PersonalProjectService personalProjectService;
-
-	private final GetJasperReportHandler<User> jasperReportHandler;
-
-	@Autowired
-	public GetUserHandlerImpl(UserRepository userRepo, UserCreationBidRepository userCreationBidRepository,
-			ProjectRepository projectRepository, PersonalProjectService personalProjectService,
-			@Qualifier("userJasperReportHandler") GetJasperReportHandler<User> jasperReportHandler) {
-		this.userRepository = Preconditions.checkNotNull(userRepo);
-		this.userCreationBidRepository = Preconditions.checkNotNull(userCreationBidRepository);
-		this.projectRepository = projectRepository;
-		this.personalProjectService = personalProjectService;
-		this.jasperReportHandler = jasperReportHandler;
-	}
-
-	@Override
-	public UserResource getUser(String username, ReportPortalUser loggedInUser) {
-
-		User user = userRepository.findByLogin(username.toLowerCase())
-				.orElseThrow(() -> new ReportPortalException(ErrorType.USER_NOT_FOUND, username));
-		return UserConverter.TO_RESOURCE.apply(user);
-	}
-
-	@Override
-	public UserResource getUser(ReportPortalUser loggedInUser) {
-		User user = userRepository.findByLogin(loggedInUser.getUsername())
-				.orElseThrow(() -> new ReportPortalException(ErrorType.USER_NOT_FOUND, loggedInUser.getUsername()));
-		return UserConverter.TO_RESOURCE.apply(user);
-	}
-
-	@Override
-	public Iterable<UserResource> getUsers(Filter filter, Pageable pageable, ReportPortalUser.ProjectDetails projectDetails) {
-		// Active users only
-		filter.withCondition(new FilterCondition(Condition.EQUALS, false, "false", CRITERIA_EXPIRED));
-		filter.withCondition(new FilterCondition(Condition.EQUALS,
-				false,
-				String.valueOf(projectDetails.getProjectId()),
-				CRITERIA_PROJECT_ID
-		));
-
-		return PagedResourcesAssembler.pageConverter(UserConverter.TO_RESOURCE)
-				.apply(userRepository.findByFilterExcluding(filter, pageable, "email"));
-	}
-
-	@Override
-	public UserBidRS getBidInformation(String uuid) {
-		Optional<UserCreationBid> bid = userCreationBidRepository.findById(uuid);
-		return bid.map(b -> {
-			UserBidRS rs = new UserBidRS();
-			rs.setIsActive(true);
-			rs.setEmail(b.getEmail());
-			rs.setUuid(b.getUuid());
-			return rs;
-		}).orElseGet(() -> {
-			UserBidRS rs = new UserBidRS();
-			rs.setIsActive(false);
-			return rs;
-		});
-	}
-
-	@Override
-	public YesNoRS validateInfo(String username, String email) {
-		if (null != username) {
-			Optional<User> user = userRepository.findByLogin(EntityUtils.normalizeId(username));
-			return user.isPresent() ? new YesNoRS(true) : new YesNoRS(false);
-		} else if (null != email) {
-			Optional<User> user = userRepository.findByEmail(EntityUtils.normalizeId(email));
-			return user.isPresent() ? new YesNoRS(true) : new YesNoRS(false);
-		}
-		return new YesNoRS(false);
-	}
-
-	@Override
-	public Map<String, UserResource.AssignedProject> getUserProjects(String userName) {
-		return projectRepository.findUserProjects(userName).stream().collect(toMap(Project::getName, it -> {
-			UserResource.AssignedProject assignedProject = new UserResource.AssignedProject();
-			assignedProject.setEntryType(it.getProjectType().name());
-			ProjectUser projectUser = ProjectUtils.findUserConfigByLogin(it, userName);
-
-			ofNullable(ofNullable(projectUser).orElseThrow(() -> new ReportPortalException(ErrorType.USER_NOT_FOUND, userName))
-					.getProjectRole()).ifPresent(role -> assignedProject.setProjectRole(role.name()));
-
-			return assignedProject;
-		}));
-	}
-
-	@Override
-	public Iterable<UserResource> getAllUsers(Queryable filter, Pageable pageable) {
-		final Page<User> users = userRepository.findByFilter(filter, pageable);
-		return PagedResourcesAssembler.pageConverter(UserConverter.TO_RESOURCE).apply(users);
-	}
-
-	@Override
-	public void exportUsers(ReportFormat reportFormat, OutputStream outputStream, Queryable filter) {
-
-		final List<User> users = userRepository.findByFilter(filter);
-
-		List<? extends Map<String, ?>> data = users.stream().map(jasperReportHandler::convertParams).collect(Collectors.toList());
-
-		JRDataSource jrDataSource = new JRBeanCollectionDataSource(data);
-
-		//don't provide any params to not overwrite params from the Jasper template
-		JasperPrint jasperPrint = jasperReportHandler.getJasperPrint(null, jrDataSource);
-
-		jasperReportHandler.writeReport(reportFormat, outputStream, jasperPrint);
-	}
-
-	@Override
-	public Iterable<UserResource> searchUsers(String term, Pageable pageable) {
-
-		Filter filter = Filter.builder()
-				.withTarget(User.class)
-				.withCondition(new FilterCondition(Operator.OR, Condition.CONTAINS, false, term, CRITERIA_USER))
-				.withCondition(new FilterCondition(Operator.OR, Condition.CONTAINS, false, term, CRITERIA_EMAIL))
-				.build();
-		return PagedResourcesAssembler.pageConverter(UserConverter.TO_RESOURCE).apply(userRepository.findByFilter(filter, pageable));
-
-	}
+  private final UserRepository userRepository;
+
+  private final UserCreationBidRepository userCreationBidRepository;
+
+  private final ProjectRepository projectRepository;
+
+  private final PersonalProjectService personalProjectService;
+
+  private final GetJasperReportHandler<User> jasperReportHandler;
+
+  @Autowired
+  public GetUserHandlerImpl(UserRepository userRepo,
+      UserCreationBidRepository userCreationBidRepository,
+      ProjectRepository projectRepository, PersonalProjectService personalProjectService,
+      @Qualifier("userJasperReportHandler") GetJasperReportHandler<User> jasperReportHandler) {
+    this.userRepository = Preconditions.checkNotNull(userRepo);
+    this.userCreationBidRepository = Preconditions.checkNotNull(userCreationBidRepository);
+    this.projectRepository = projectRepository;
+    this.personalProjectService = personalProjectService;
+    this.jasperReportHandler = jasperReportHandler;
+  }
+
+  @Override
+  public UserResource getUser(String username, ReportPortalUser loggedInUser) {
+
+    User user = userRepository.findByLogin(username.toLowerCase())
+        .orElseThrow(() -> new ReportPortalException(ErrorType.USER_NOT_FOUND, username));
+    return UserConverter.TO_RESOURCE.apply(user);
+  }
+
+  @Override
+  public UserResource getUser(ReportPortalUser loggedInUser) {
+    User user = userRepository.findByLogin(loggedInUser.getUsername())
+        .orElseThrow(
+            () -> new ReportPortalException(ErrorType.USER_NOT_FOUND, loggedInUser.getUsername()));
+    return UserConverter.TO_RESOURCE.apply(user);
+  }
+
+  @Override
+  public Iterable<UserResource> getUsers(Filter filter, Pageable pageable,
+      ReportPortalUser.ProjectDetails projectDetails) {
+    // Active users only
+    filter.withCondition(new FilterCondition(Condition.EQUALS, false, "false", CRITERIA_EXPIRED));
+    filter.withCondition(new FilterCondition(Condition.EQUALS,
+        false,
+        String.valueOf(projectDetails.getProjectId()),
+        CRITERIA_PROJECT_ID
+    ));
+
+    return PagedResourcesAssembler.pageConverter(UserConverter.TO_RESOURCE)
+        .apply(userRepository.findByFilterExcluding(filter, pageable, "email"));
+  }
+
+  @Override
+  public UserBidRS getBidInformation(String uuid) {
+    Optional<UserCreationBid> bid = userCreationBidRepository.findByUuidAndType(uuid,
+        INTERNAL_BID_TYPE);
+    return bid.map(b -> {
+      UserBidRS rs = new UserBidRS();
+      rs.setIsActive(true);
+      rs.setEmail(b.getEmail());
+      rs.setUuid(b.getUuid());
+      return rs;
+    }).orElseGet(() -> {
+      UserBidRS rs = new UserBidRS();
+      rs.setIsActive(false);
+      return rs;
+    });
+  }
+
+  @Override
+  public YesNoRS validateInfo(String username, String email) {
+    if (null != username) {
+      Optional<User> user = userRepository.findByLogin(EntityUtils.normalizeId(username));
+      return user.isPresent() ? new YesNoRS(true) : new YesNoRS(false);
+    } else if (null != email) {
+      Optional<User> user = userRepository.findByEmail(EntityUtils.normalizeId(email));
+      return user.isPresent() ? new YesNoRS(true) : new YesNoRS(false);
+    }
+    return new YesNoRS(false);
+  }
+
+  @Override
+  public Map<String, UserResource.AssignedProject> getUserProjects(String userName) {
+    return projectRepository.findUserProjects(userName).stream()
+        .collect(toMap(Project::getName, it -> {
+          UserResource.AssignedProject assignedProject = new UserResource.AssignedProject();
+          assignedProject.setEntryType(it.getProjectType().name());
+          ProjectUser projectUser = ProjectUtils.findUserConfigByLogin(it, userName);
+
+          ofNullable(ofNullable(projectUser).orElseThrow(
+                  () -> new ReportPortalException(ErrorType.USER_NOT_FOUND, userName))
+              .getProjectRole()).ifPresent(role -> assignedProject.setProjectRole(role.name()));
+
+          return assignedProject;
+        }));
+  }
+
+  @Override
+  public Iterable<UserResource> getAllUsers(Queryable filter, Pageable pageable) {
+    final Page<User> users = userRepository.findByFilter(filter, pageable);
+    return PagedResourcesAssembler.pageConverter(UserConverter.TO_RESOURCE).apply(users);
+  }
+
+  @Override
+  public void exportUsers(ReportFormat reportFormat, OutputStream outputStream, Queryable filter) {
+
+    final List<User> users = userRepository.findByFilter(filter);
+
+    List<? extends Map<String, ?>> data = users.stream().map(jasperReportHandler::convertParams)
+        .collect(Collectors.toList());
+
+    JRDataSource jrDataSource = new JRBeanCollectionDataSource(data);
+
+    //don't provide any params to not overwrite params from the Jasper template
+    JasperPrint jasperPrint = jasperReportHandler.getJasperPrint(null, jrDataSource);
+
+    jasperReportHandler.writeReport(reportFormat, outputStream, jasperPrint);
+  }
+
+  @Override
+  public Iterable<UserResource> searchUsers(String term, Pageable pageable) {
+
+    Filter filter = Filter.builder()
+        .withTarget(User.class)
+        .withCondition(
+            new FilterCondition(Operator.OR, Condition.CONTAINS, false, term, CRITERIA_USER))
+        .withCondition(
+            new FilterCondition(Operator.OR, Condition.CONTAINS, false, term, CRITERIA_EMAIL))
+        .build();
+    return PagedResourcesAssembler.pageConverter(UserConverter.TO_RESOURCE)
+        .apply(userRepository.findByFilter(filter, pageable));
+
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/CreateWidgetHandler.java b/src/main/java/com/epam/ta/reportportal/core/widget/CreateWidgetHandler.java
index 37db1da3ea..1d5c8cf0ab 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/CreateWidgetHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/CreateWidgetHandler.java
@@ -25,14 +25,15 @@
  */
 public interface CreateWidgetHandler {
 
-	/**
-	 * Creates a new widget
-	 *
-	 * @param createWidgetRQ Widget details
-	 * @param projectDetails Project details
-	 * @param user           User
-	 * @return EntryCreatedRS
-	 */
-	EntryCreatedRS createWidget(WidgetRQ createWidgetRQ, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user);
+  /**
+   * Creates a new widget
+   *
+   * @param createWidgetRQ Widget details
+   * @param projectDetails Project details
+   * @param user           User
+   * @return EntryCreatedRS
+   */
+  EntryCreatedRS createWidget(WidgetRQ createWidgetRQ,
+      ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user);
 
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/UpdateWidgetHandler.java b/src/main/java/com/epam/ta/reportportal/core/widget/UpdateWidgetHandler.java
index 78700815bc..df8f2bea0d 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/UpdateWidgetHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/UpdateWidgetHandler.java
@@ -20,7 +20,6 @@
 import com.epam.ta.reportportal.entity.widget.Widget;
 import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
 import com.epam.ta.reportportal.ws.model.widget.WidgetRQ;
-
 import java.util.Collection;
 
 /**
@@ -28,10 +27,17 @@
  */
 public interface UpdateWidgetHandler {
 
-	/**
-	 * Update widget with specified id
-	 */
-	OperationCompletionRS updateWidget(Long widgetId, WidgetRQ updateRQ, ReportPortalUser.ProjectDetails projectDetails,
-			ReportPortalUser user);
+  /**
+   * Update a widget with a specified id.
+   *
+   * @param widgetId The ID of the widget to be updated
+   * @param updateRQ The {@link WidgetRQ} containing the updated information for the widget
+   * @param projectDetails The {@link ReportPortalUser.ProjectDetails} for the project associated with the widget
+   * @param user The {@link ReportPortalUser} who is updating the widget
+   * @return An {@link OperationCompletionRS} instance indicating the result of the update operation
+   */
+  OperationCompletionRS updateWidget(Long widgetId, WidgetRQ updateRQ,
+      ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user);
 
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/BuildFilterStrategy.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/BuildFilterStrategy.java
index 427a1f7e64..203df47db0 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/BuildFilterStrategy.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/BuildFilterStrategy.java
@@ -18,9 +18,8 @@
 
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.entity.widget.Widget;
-import org.springframework.data.domain.Sort;
-
 import java.util.Map;
+import org.springframework.data.domain.Sort;
 
 /**
  * Strategy definition interface for building widget specific filters
@@ -29,12 +28,13 @@
  */
 public interface BuildFilterStrategy {
 
-	/**
-	 * Get widget content with predefined filter in accordance with used
-	 * strategy
-	 *
-	 * @return
-	 */
-	Map<Filter, Sort> buildFilter(Widget widget);
+  /**
+   * Get widget content with predefined filter in accordance with used strategy
+   *
+   * @param widget the widget to apply the filters and sorting on
+   * @return Map of filters and sorts where the key is the {@link Filter}
+   * and the value is the corresponding {@link Sort} for the given widget
+   */
+  Map<Filter, Sort> buildFilter(Widget widget);
 
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/LoadContentStrategy.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/LoadContentStrategy.java
index a6805fd429..e0db040728 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/LoadContentStrategy.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/LoadContentStrategy.java
@@ -18,10 +18,9 @@
 
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
-import org.springframework.data.domain.Sort;
-
 import java.util.List;
 import java.util.Map;
+import org.springframework.data.domain.Sort;
 
 /**
  * Strategy definition interface for loading widget content.
@@ -30,6 +29,7 @@
  */
 public interface LoadContentStrategy {
 
-	Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMap, WidgetOptions widgetOptions, int limit);
+  Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMap,
+      WidgetOptions widgetOptions, int limit);
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/MaterializedLoadContentStrategy.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/MaterializedLoadContentStrategy.java
index 0a0fab75c3..1397d471b2 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/MaterializedLoadContentStrategy.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/MaterializedLoadContentStrategy.java
@@ -1,14 +1,13 @@
 package com.epam.ta.reportportal.core.widget.content;
 
 import com.epam.ta.reportportal.entity.widget.Widget;
-import org.springframework.util.MultiValueMap;
-
 import java.util.Map;
+import org.springframework.util.MultiValueMap;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public interface MaterializedLoadContentStrategy {
 
-	Map<String, Object> loadContent(Widget widget, MultiValueMap<String, String> params);
+  Map<String, Object> loadContent(Widget widget, MultiValueMap<String, String> params);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/MaterializedLoadContentStrategyImpl.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/MaterializedLoadContentStrategyImpl.java
index 0398456e4b..5d2593a3fb 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/MaterializedLoadContentStrategyImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/MaterializedLoadContentStrategyImpl.java
@@ -1,11 +1,15 @@
 package com.epam.ta.reportportal.core.widget.content;
 
+import static com.epam.ta.reportportal.core.widget.content.updater.MaterializedWidgetStateUpdater.STATE;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.core.widget.content.loader.materialized.handler.MaterializedWidgetStateHandler;
 import com.epam.ta.reportportal.core.widget.util.WidgetOptionUtil;
 import com.epam.ta.reportportal.entity.widget.Widget;
 import com.epam.ta.reportportal.entity.widget.WidgetState;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
@@ -13,33 +17,30 @@
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.MultiValueMap;
 
-import java.util.Map;
-
-import static com.epam.ta.reportportal.core.widget.content.updater.MaterializedWidgetStateUpdater.STATE;
-import static java.util.Optional.ofNullable;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class MaterializedLoadContentStrategyImpl implements MaterializedLoadContentStrategy {
 
-	private final Map<WidgetState, MaterializedWidgetStateHandler> widgetStateHandlerMapping;
+  private final Map<WidgetState, MaterializedWidgetStateHandler> widgetStateHandlerMapping;
 
-	@Autowired
-	public MaterializedLoadContentStrategyImpl(@Qualifier("widgetStateHandlerMapping") Map<WidgetState, MaterializedWidgetStateHandler> widgetStateHandlerMapping) {
-		this.widgetStateHandlerMapping = widgetStateHandlerMapping;
-	}
+  @Autowired
+  public MaterializedLoadContentStrategyImpl(
+      @Qualifier("widgetStateHandlerMapping") Map<WidgetState, MaterializedWidgetStateHandler> widgetStateHandlerMapping) {
+    this.widgetStateHandlerMapping = widgetStateHandlerMapping;
+  }
 
-	@Override
-	@Transactional(propagation = Propagation.REQUIRES_NEW)
-	public Map<String, Object> loadContent(Widget widget, MultiValueMap<String, String> params) {
+  @Override
+  @Transactional(propagation = Propagation.REQUIRES_NEW)
+  public Map<String, Object> loadContent(Widget widget, MultiValueMap<String, String> params) {
 
-		WidgetState widgetState = ofNullable(WidgetOptionUtil.getValueByKey(STATE,
-				widget.getWidgetOptions()
-		)).flatMap(WidgetState::findByName)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.UNABLE_LOAD_WIDGET_CONTENT, "Widget state not provided"));
+    WidgetState widgetState = ofNullable(WidgetOptionUtil.getValueByKey(STATE,
+        widget.getWidgetOptions()
+    )).flatMap(WidgetState::findByName)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.UNABLE_LOAD_WIDGET_CONTENT,
+            "Widget state not provided"));
 
-		return widgetStateHandlerMapping.get(widgetState).handleWidgetState(widget, params);
-	}
+    return widgetStateHandlerMapping.get(widgetState).handleWidgetState(widget, params);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/MultilevelLoadContentStrategy.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/MultilevelLoadContentStrategy.java
index fe8997ffd7..945f56dd37 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/MultilevelLoadContentStrategy.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/MultilevelLoadContentStrategy.java
@@ -18,17 +18,17 @@
 
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
-import org.springframework.data.domain.Sort;
-import org.springframework.util.MultiValueMap;
-
 import java.util.List;
 import java.util.Map;
+import org.springframework.data.domain.Sort;
+import org.springframework.util.MultiValueMap;
 
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 public interface MultilevelLoadContentStrategy {
 
-	Map<String, Object> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMap, WidgetOptions widgetOptions,
-			String[] attributes, MultiValueMap<String, String> params, int limit);
+  Map<String, Object> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMap,
+      WidgetOptions widgetOptions,
+      String[] attributes, MultiValueMap<String, String> params, int limit);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/constant/ContentLoaderConstants.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/constant/ContentLoaderConstants.java
index cb6a330586..571dccd381 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/constant/ContentLoaderConstants.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/constant/ContentLoaderConstants.java
@@ -21,26 +21,26 @@
  */
 public final class ContentLoaderConstants {
 
-	public static final String CONTENT_FIELDS_DELIMITER = ",";
+  public static final String CONTENT_FIELDS_DELIMITER = ",";
 
-	public static final String RESULT = "result";
-	public static final String LATEST_OPTION = "latest";
-	public static final String LATEST_LAUNCH = "latestLaunch";
-	public static final String LAUNCH_NAME_FIELD = "launchNameFilter";
-	public static final String USER = "user";
-	public static final String ACTION_TYPE = "actionType";
-	public static final String ATTRIBUTES = "attributes";
-	public static final String ATTRIBUTE_KEY = "attributeKey";
-	public static final String PATTERN_TEMPLATE_NAME = "patternTemplateName";
-	public static final String ITEM_TYPE = "type";
-	public static final String INCLUDE_METHODS = "includeMethods";
-	public static final String FLAKY = "flaky";
-	public static final String CUSTOM_COLUMNS = "customColumns";
-	public static final String TIMELINE = "timeline";
-	public static final String ATTRIBUTE_KEYS = "attributeKeys";
-	public static final String MIN_PASSING_RATE = "minPassingRate";
+  public static final String RESULT = "result";
+  public static final String LATEST_OPTION = "latest";
+  public static final String LATEST_LAUNCH = "latestLaunch";
+  public static final String LAUNCH_NAME_FIELD = "launchNameFilter";
+  public static final String USER = "user";
+  public static final String ACTION_TYPE = "actionType";
+  public static final String ATTRIBUTES = "attributes";
+  public static final String ATTRIBUTE_KEY = "attributeKey";
+  public static final String PATTERN_TEMPLATE_NAME = "patternTemplateName";
+  public static final String ITEM_TYPE = "type";
+  public static final String INCLUDE_METHODS = "includeMethods";
+  public static final String FLAKY = "flaky";
+  public static final String CUSTOM_COLUMNS = "customColumns";
+  public static final String TIMELINE = "timeline";
+  public static final String ATTRIBUTE_KEYS = "attributeKeys";
+  public static final String MIN_PASSING_RATE = "minPassingRate";
 
-	private ContentLoaderConstants() {
-		//static only
-	}
+  private ContentLoaderConstants() {
+    //static only
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/filter/AbstractStatisticsFilterStrategy.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/filter/AbstractStatisticsFilterStrategy.java
index cec5d9641d..823d330b40 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/filter/AbstractStatisticsFilterStrategy.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/filter/AbstractStatisticsFilterStrategy.java
@@ -16,6 +16,8 @@
 
 package com.epam.ta.reportportal.core.widget.content.filter;
 
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.core.widget.content.BuildFilterStrategy;
 import com.epam.ta.reportportal.entity.filter.FilterSort;
@@ -23,45 +25,44 @@
 import com.epam.ta.reportportal.entity.widget.Widget;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
-import org.springframework.data.domain.Sort;
-
 import java.util.Collections;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
-
-import static java.util.Optional.ofNullable;
+import org.springframework.data.domain.Sort;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public abstract class AbstractStatisticsFilterStrategy implements BuildFilterStrategy {
 
-	@Override
-	public Map<Filter, Sort> buildFilter(Widget widget) {
-		return buildFilterSortMap(widget, widget.getProject().getId());
-	}
+  @Override
+  public Map<Filter, Sort> buildFilter(Widget widget) {
+    return buildFilterSortMap(widget, widget.getProject().getId());
+  }
 
-	protected Map<Filter, Sort> buildFilterSortMap(Widget widget, Long projectId) {
-		Map<Filter, Sort> filterSortMap = Maps.newLinkedHashMap();
-		Set<UserFilter> userFilters = Optional.ofNullable(widget.getFilters()).orElse(Collections.emptySet());
-		Filter defaultFilter = buildDefaultFilter(widget, projectId);
-		Optional.ofNullable(defaultFilter).ifPresent(f -> filterSortMap.put(defaultFilter, Sort.unsorted()));
-		userFilters.forEach(userFilter -> {
-			Filter filter = new Filter(userFilter.getId(),
-					userFilter.getTargetClass().getClassObject(),
-					Lists.newArrayList(userFilter.getFilterCondition())
-			);
-			Optional<Set<FilterSort>> filterSorts = ofNullable(userFilter.getFilterSorts());
-			Sort sort = Sort.by(filterSorts.map(filterSort -> filterSort.stream()
-					.map(s -> Sort.Order.by(s.getField()).with(s.getDirection()))
-					.collect(Collectors.toList())).orElseGet(Collections::emptyList));
-			filterSortMap.put(filter, sort);
-		});
+  protected Map<Filter, Sort> buildFilterSortMap(Widget widget, Long projectId) {
+    Map<Filter, Sort> filterSortMap = Maps.newLinkedHashMap();
+    Set<UserFilter> userFilters = Optional.ofNullable(widget.getFilters())
+        .orElse(Collections.emptySet());
+    Filter defaultFilter = buildDefaultFilter(widget, projectId);
+    Optional.ofNullable(defaultFilter)
+        .ifPresent(f -> filterSortMap.put(defaultFilter, Sort.unsorted()));
+    userFilters.forEach(userFilter -> {
+      Filter filter = new Filter(userFilter.getId(),
+          userFilter.getTargetClass().getClassObject(),
+          Lists.newArrayList(userFilter.getFilterCondition())
+      );
+      Optional<Set<FilterSort>> filterSorts = ofNullable(userFilter.getFilterSorts());
+      Sort sort = Sort.by(filterSorts.map(filterSort -> filterSort.stream()
+          .map(s -> Sort.Order.by(s.getField()).with(s.getDirection()))
+          .collect(Collectors.toList())).orElseGet(Collections::emptyList));
+      filterSortMap.put(filter, sort);
+    });
 
-		return filterSortMap;
-	}
+    return filterSortMap;
+  }
 
-	protected abstract Filter buildDefaultFilter(Widget widget, Long projectId);
+  protected abstract Filter buildDefaultFilter(Widget widget, Long projectId);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/filter/ActivityFilterStrategy.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/filter/ActivityFilterStrategy.java
index a2f095acd3..75eddc9b58 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/filter/ActivityFilterStrategy.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/filter/ActivityFilterStrategy.java
@@ -16,36 +16,36 @@
 
 package com.epam.ta.reportportal.core.widget.content.filter;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_PROJECT_ID;
+
 import com.epam.ta.reportportal.commons.querygen.Condition;
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.querygen.FilterCondition;
 import com.epam.ta.reportportal.entity.activity.Activity;
 import com.epam.ta.reportportal.entity.widget.Widget;
 import com.google.common.collect.Lists;
+import java.util.Map;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.Map;
-
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_PROJECT_ID;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service("activityFilterStrategy")
 public class ActivityFilterStrategy extends AbstractStatisticsFilterStrategy {
 
-	@Override
-	public Map<Filter, Sort> buildFilter(Widget widget) {
+  @Override
+  public Map<Filter, Sort> buildFilter(Widget widget) {
 
-		return super.buildFilter(widget);
-	}
+    return super.buildFilter(widget);
+  }
 
-	@Override
-	protected Filter buildDefaultFilter(Widget widget, Long projectId) {
-		return new Filter(
-				Activity.class,
-				Lists.newArrayList(new FilterCondition(Condition.EQUALS, false, String.valueOf(projectId), CRITERIA_PROJECT_ID))
-		);
-	}
+  @Override
+  protected Filter buildDefaultFilter(Widget widget, Long projectId) {
+    return new Filter(
+        Activity.class,
+        Lists.newArrayList(new FilterCondition(Condition.EQUALS, false, String.valueOf(projectId),
+            CRITERIA_PROJECT_ID))
+    );
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/filter/GeneralLaunchFilterStrategy.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/filter/GeneralLaunchFilterStrategy.java
index 13d7657840..b389158520 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/filter/GeneralLaunchFilterStrategy.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/filter/GeneralLaunchFilterStrategy.java
@@ -16,6 +16,9 @@
 
 package com.epam.ta.reportportal.core.widget.content.filter;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.LaunchCriteriaConstant.CRITERIA_LAUNCH_MODE;
+import static com.epam.ta.reportportal.commons.querygen.constant.LaunchCriteriaConstant.CRITERIA_LAUNCH_STATUS;
+
 import com.epam.ta.reportportal.commons.querygen.Condition;
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.querygen.FilterCondition;
@@ -23,25 +26,22 @@
 import com.epam.ta.reportportal.entity.widget.Widget;
 import com.epam.ta.reportportal.ws.model.launch.Mode;
 import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
 import org.springframework.stereotype.Service;
 
-import static com.epam.ta.reportportal.commons.querygen.constant.LaunchCriteriaConstant.CRITERIA_LAUNCH_MODE;
-import static com.epam.ta.reportportal.commons.querygen.constant.LaunchCriteriaConstant.CRITERIA_LAUNCH_STATUS;
-
 /**
  * @author Pavel Bortnik
  */
 @Service("generalLaunchFilterStrategy")
 public class GeneralLaunchFilterStrategy extends ProjectFilterStrategy {
 
-	@Override
-	protected Filter buildDefaultFilter(Widget widget, Long projectId) {
-		Filter filter = super.buildDefaultFilter(widget, projectId);
-		filter.withConditions(Lists.newArrayList(
-				new FilterCondition(Condition.NOT_EQUALS, false, StatusEnum.IN_PROGRESS.name(), CRITERIA_LAUNCH_STATUS),
-				new FilterCondition(Condition.EQUALS, false, Mode.DEFAULT.toString(), CRITERIA_LAUNCH_MODE)
-		));
-		return filter;
-	}
+  @Override
+  protected Filter buildDefaultFilter(Widget widget, Long projectId) {
+    Filter filter = super.buildDefaultFilter(widget, projectId);
+    filter.withConditions(Lists.newArrayList(
+        new FilterCondition(Condition.NOT_EQUALS, false, StatusEnum.IN_PROGRESS.name(),
+            CRITERIA_LAUNCH_STATUS),
+        new FilterCondition(Condition.EQUALS, false, Mode.DEFAULT.toString(), CRITERIA_LAUNCH_MODE)
+    ));
+    return filter;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/filter/LaunchHistoryFilterStrategy.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/filter/LaunchHistoryFilterStrategy.java
index cc4d404e3d..ff500d15ff 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/filter/LaunchHistoryFilterStrategy.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/filter/LaunchHistoryFilterStrategy.java
@@ -16,6 +16,11 @@
 
 package com.epam.ta.reportportal.core.widget.content.filter;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_NAME;
+import static com.epam.ta.reportportal.commons.querygen.constant.LaunchCriteriaConstant.CRITERIA_LAUNCH_STATUS;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LAUNCH_NAME_FIELD;
+import static java.util.stream.Collectors.joining;
+
 import com.epam.ta.reportportal.commons.querygen.Condition;
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.querygen.FilterCondition;
@@ -25,43 +30,42 @@
 import com.epam.ta.reportportal.entity.widget.Widget;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.stream.Stream;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
 
-import java.util.stream.Stream;
-
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_NAME;
-import static com.epam.ta.reportportal.commons.querygen.constant.LaunchCriteriaConstant.CRITERIA_LAUNCH_STATUS;
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LAUNCH_NAME_FIELD;
-import static java.util.stream.Collectors.joining;
-
 /**
  * @author Pavel Bortnik
  */
 @Service("launchHistoryFilterStrategy")
 public class LaunchHistoryFilterStrategy extends GeneralLaunchFilterStrategy {
 
-	@Override
-	protected Filter buildDefaultFilter(Widget widget, Long projectId) {
-		validateWidgetOptions(widget.getWidgetOptions());
-		String launchName = WidgetOptionUtil.getValueByKey(LAUNCH_NAME_FIELD, widget.getWidgetOptions());
-		Filter filter = super.buildDefaultFilter(widget, projectId);
-		return filter.withCondition(new FilterCondition(Condition.EQUALS, false, launchName, CRITERIA_NAME))
-				.withCondition(new FilterCondition(
-						Condition.IN,
-						false,
-						Stream.of(StatusEnum.FAILED, StatusEnum.PASSED, StatusEnum.STOPPED).map(Enum::name).collect(joining(",")),
-						CRITERIA_LAUNCH_STATUS
-				));
-	}
+  @Override
+  protected Filter buildDefaultFilter(Widget widget, Long projectId) {
+    validateWidgetOptions(widget.getWidgetOptions());
+    String launchName = WidgetOptionUtil.getValueByKey(LAUNCH_NAME_FIELD,
+        widget.getWidgetOptions());
+    Filter filter = super.buildDefaultFilter(widget, projectId);
+    return filter.withCondition(
+            new FilterCondition(Condition.EQUALS, false, launchName, CRITERIA_NAME))
+        .withCondition(new FilterCondition(
+            Condition.IN,
+            false,
+            Stream.of(StatusEnum.FAILED, StatusEnum.PASSED, StatusEnum.STOPPED).map(Enum::name)
+                .collect(joining(",")),
+            CRITERIA_LAUNCH_STATUS
+        ));
+  }
 
-	/**
-	 * Validate provided widget options. For current widget launch name should be specified.
-	 *
-	 * @param widgetOptions Map of stored widget options.
-	 */
-	private void validateWidgetOptions(WidgetOptions widgetOptions) {
-		BusinessRule.expect(WidgetOptionUtil.getValueByKey(LAUNCH_NAME_FIELD, widgetOptions), StringUtils::isNotBlank)
-				.verify(ErrorType.UNABLE_LOAD_WIDGET_CONTENT, LAUNCH_NAME_FIELD + " should be specified for widget.");
-	}
+  /**
+   * Validate provided widget options. For current widget launch name should be specified.
+   *
+   * @param widgetOptions Map of stored widget options.
+   */
+  private void validateWidgetOptions(WidgetOptions widgetOptions) {
+    BusinessRule.expect(WidgetOptionUtil.getValueByKey(LAUNCH_NAME_FIELD, widgetOptions),
+            StringUtils::isNotBlank)
+        .verify(ErrorType.UNABLE_LOAD_WIDGET_CONTENT,
+            LAUNCH_NAME_FIELD + " should be specified for widget.");
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/filter/ProductStatusFilterStrategy.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/filter/ProductStatusFilterStrategy.java
index fbfdda3a03..2e8ae64098 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/filter/ProductStatusFilterStrategy.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/filter/ProductStatusFilterStrategy.java
@@ -16,6 +16,9 @@
 
 package com.epam.ta.reportportal.core.widget.content.filter;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_PROJECT_ID;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.querygen.Condition;
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.querygen.FilterCondition;
@@ -24,18 +27,13 @@
 import com.epam.ta.reportportal.entity.widget.Widget;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import org.springframework.data.domain.Sort;
-import org.springframework.stereotype.Service;
-
 import java.util.Collections;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_PROJECT_ID;
-import static java.util.Optional.ofNullable;
+import org.springframework.data.domain.Sort;
+import org.springframework.stereotype.Service;
 
 /**
  * @author Pavel Bortnik
@@ -43,32 +41,33 @@
 @Service("productStatusFilterStrategy")
 public class ProductStatusFilterStrategy extends AbstractStatisticsFilterStrategy {
 
-	@Override
-	protected Map<Filter, Sort> buildFilterSortMap(Widget widget, Long projectId) {
-		Map<Filter, Sort> filterSortMap = Maps.newLinkedHashMap();
-		Optional.ofNullable(widget.getFilters()).orElse(Collections.emptySet()).forEach(userFilter -> {
-			Filter filter = new Filter(
-					userFilter.getId(),
-					userFilter.getTargetClass().getClassObject(),
-					Lists.newArrayList(userFilter.getFilterCondition())
-			);
-			filter.withConditions(buildDefaultFilter(widget, projectId).getFilterConditions());
+  @Override
+  protected Map<Filter, Sort> buildFilterSortMap(Widget widget, Long projectId) {
+    Map<Filter, Sort> filterSortMap = Maps.newLinkedHashMap();
+    Optional.ofNullable(widget.getFilters()).orElse(Collections.emptySet()).forEach(userFilter -> {
+      Filter filter = new Filter(
+          userFilter.getId(),
+          userFilter.getTargetClass().getClassObject(),
+          Lists.newArrayList(userFilter.getFilterCondition())
+      );
+      filter.withConditions(buildDefaultFilter(widget, projectId).getFilterConditions());
 
-			Optional<Set<FilterSort>> filterSorts = ofNullable(userFilter.getFilterSorts());
+      Optional<Set<FilterSort>> filterSorts = ofNullable(userFilter.getFilterSorts());
 
-			Sort sort = Sort.by(filterSorts.map(filterSort -> filterSort.stream()
-					.map(s -> Sort.Order.by(s.getField()).with(s.getDirection()))
-					.collect(Collectors.toList())).orElseGet(Collections::emptyList));
+      Sort sort = Sort.by(filterSorts.map(filterSort -> filterSort.stream()
+          .map(s -> Sort.Order.by(s.getField()).with(s.getDirection()))
+          .collect(Collectors.toList())).orElseGet(Collections::emptyList));
 
-			filterSortMap.put(filter, sort);
-		});
-		return filterSortMap;
-	}
+      filterSortMap.put(filter, sort);
+    });
+    return filterSortMap;
+  }
 
-	protected Filter buildDefaultFilter(Widget widget, Long projectId) {
-		return new Filter(
-				Launch.class,
-				Lists.newArrayList(new FilterCondition(Condition.EQUALS, false, String.valueOf(projectId), CRITERIA_PROJECT_ID))
-		);
-	}
+  protected Filter buildDefaultFilter(Widget widget, Long projectId) {
+    return new Filter(
+        Launch.class,
+        Lists.newArrayList(new FilterCondition(Condition.EQUALS, false, String.valueOf(projectId),
+            CRITERIA_PROJECT_ID))
+    );
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/filter/ProjectFilterStrategy.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/filter/ProjectFilterStrategy.java
index 382f571375..6a0cff29e2 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/filter/ProjectFilterStrategy.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/filter/ProjectFilterStrategy.java
@@ -16,27 +16,27 @@
 
 package com.epam.ta.reportportal.core.widget.content.filter;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_PROJECT_ID;
+
 import com.epam.ta.reportportal.commons.querygen.Condition;
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.querygen.FilterCondition;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.entity.widget.Widget;
 import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
 import org.springframework.stereotype.Service;
 
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_PROJECT_ID;
-
 /**
  * @author Pavel Bortnik
  */
 @Service("projectFilterStrategy")
 public class ProjectFilterStrategy extends AbstractStatisticsFilterStrategy {
 
-	@Override
-	protected Filter buildDefaultFilter(Widget widget, Long projectId) {
-		return new Filter(Launch.class,
-				Lists.newArrayList(new FilterCondition(Condition.EQUALS, false, String.valueOf(projectId), CRITERIA_PROJECT_ID))
-		);
-	}
+  @Override
+  protected Filter buildDefaultFilter(Widget widget, Long projectId) {
+    return new Filter(Launch.class,
+        Lists.newArrayList(new FilterCondition(Condition.EQUALS, false, String.valueOf(projectId),
+            CRITERIA_PROJECT_ID))
+    );
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/AbstractStatisticsContentLoader.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/AbstractStatisticsContentLoader.java
index a74dc68339..49785a7618 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/AbstractStatisticsContentLoader.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/AbstractStatisticsContentLoader.java
@@ -16,143 +16,197 @@
 
 package com.epam.ta.reportportal.core.widget.content.loader;
 
-import com.epam.ta.reportportal.entity.widget.content.AbstractLaunchStatisticsContent;
-import com.epam.ta.reportportal.entity.widget.content.ChartStatisticsContent;
-import org.apache.commons.collections.MapUtils;
-import org.joda.time.DateTime;
+import static java.util.Optional.ofNullable;
+import static net.sf.jasperreports.types.date.FixedDate.DATE_PATTERN;
 
-import java.time.format.DateTimeFormatter;
-import java.util.*;
+import com.epam.ta.reportportal.entity.widget.content.ChartStatisticsContent;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.LongSummaryStatistics;
+import java.util.Map;
+import java.util.Optional;
 import java.util.function.BinaryOperator;
 import java.util.function.Function;
 import java.util.stream.Collectors;
-
-import static java.util.Optional.ofNullable;
-import static net.sf.jasperreports.types.date.FixedDate.DATE_PATTERN;
+import org.apache.commons.collections.MapUtils;
+import org.joda.time.DateTime;
 
 /**
  * @author Andrei_Ramanchuk
  */
 public abstract class AbstractStatisticsContentLoader {
 
-	/**
-	 * Return lists of objects grouped by specified period
-	 *
-	 * @param input
-	 * @param period
-	 * @return
-	 */
-	protected Map<String, ChartStatisticsContent> groupByDate(List<ChartStatisticsContent> input, Period period) {
-		if (input.isEmpty()) {
-			return Collections.emptyMap();
-		}
-		final Map<String, ChartStatisticsContent> chart = new LinkedHashMap<>();
-
-		switch (period) {
-			case DAY:
-			case WEEK:
-				proceedDailyChart(chart, input);
-				groupStatistics(DATE_PATTERN, input, chart);
-				break;
-			case MONTH:
-				proceedDailyChart(chart, input);
-				groupStatistics("yyyy-MM", input, chart);
-				break;
-		}
-
-		return chart;
-	}
-
-	protected Map<String, ChartStatisticsContent> maxByDate(List<ChartStatisticsContent> statisticsContents, Period period,
-			String contentField) {
-		final Function<ChartStatisticsContent, String> chartObjectToDate = chartObject -> new DateTime(chartObject.getStartTime().getTime())
-				.toString(DATE_PATTERN);
-		final BinaryOperator<ChartStatisticsContent> chartObjectReducer = (o1, o2) -> Integer.parseInt(o1.getValues().get(contentField)) > Integer.parseInt(o2.getValues().get(contentField)) ?
-				o1 :
-				o2;
-		final Map<String, Optional<ChartStatisticsContent>> groupByDate = statisticsContents.stream()
-				.filter(content -> MapUtils.isNotEmpty(content.getValues()) && ofNullable(content.getValues()
-						.get(contentField)).isPresent())
-				.sorted(Comparator.comparing(ChartStatisticsContent::getStartTime))
-				.collect(Collectors.groupingBy(chartObjectToDate, LinkedHashMap::new, Collectors.reducing(chartObjectReducer)));
-		final Map<String, ChartStatisticsContent> range = groupByDate(statisticsContents, period);
-		final LinkedHashMap<String, ChartStatisticsContent> result = new LinkedHashMap<>();
-		// used forEach cause aspectj compiler can't infer types properly
-		range.forEach((key, value) -> result.put(key,
-				groupByDate.getOrDefault(key, Optional.of(createChartObject(statisticsContents.get(0)))).get()
-		));
-		return result;
-	}
-
-	private void groupStatistics(String groupingPattern, List<ChartStatisticsContent> statisticsContents,
-			Map<String, ChartStatisticsContent> chart) {
-
-		Map<String, List<ChartStatisticsContent>> groupedStatistics = statisticsContents.stream()
-				.collect(Collectors.groupingBy(c -> new DateTime(c.getStartTime()).toString(groupingPattern),
-						LinkedHashMap::new,
-						Collectors.toList()
-				));
-
-		groupedStatistics.forEach((key, contents) -> chart.keySet().stream().filter(k -> k.startsWith(key)).findFirst().ifPresent(k -> {
-			ChartStatisticsContent content = chart.get(k);
-			contents.add(content);
-			Map<String, String> values = contents.stream()
-					.map(v -> v.getValues().entrySet())
-					.flatMap(Collection::stream)
-					.collect(Collectors.toMap(Map.Entry::getKey,
-							entry -> ofNullable(entry.getValue()).orElse("0"),
-							(prev, curr) -> prev = String.valueOf(Double.parseDouble(prev) + Double.parseDouble(curr))
-					));
-
-			content.setValues(values);
-
-			chart.put(k, content);
-		}));
-	}
-
-	private void proceedDailyChart(Map<String, ChartStatisticsContent> chart, List<ChartStatisticsContent> statisticsContents) {
-		statisticsContents.stream().sorted(Comparator.comparing(AbstractLaunchStatisticsContent::getStartTime)).forEach(sc -> {
-			chart.put(
-					sc.getStartTime().toLocalDateTime().format(DateTimeFormatter.ISO_DATE),
-					createChartObject(sc)
-			);
-		});
-	}
-
-	private ChartStatisticsContent createChartObject(ChartStatisticsContent input) {
-		final ChartStatisticsContent chartObject = new ChartStatisticsContent();
-		chartObject.setValues(input.getValues().entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> "0")));
-		return chartObject;
-	}
-
-	/**
-	 * Timeline periods enumerator
-	 *
-	 * @author Andrei_Ramanchuk
-	 */
-	public enum Period {
-		// @formatter:off
-		DAY(1),
-		WEEK(7),
-		MONTH(30);
-		// @formatter:on
-
-		private int value;
-
-		Period(int value) {
-			this.value = value;
-		}
-
-		public int getValue() {
-			return value;
-		}
-
-		public static boolean isPresent(String name) {
-			return findByName(name).isPresent();
-		}
-
-		public static Optional<Period> findByName(String name) {
-			return Arrays.stream(Period.values()).filter(time -> time.name().equalsIgnoreCase(name)).findAny();
-		}
-	}
+  /**
+   * Return lists of objects grouped by specified period
+   *
+   * @param input   A list of {@link ChartStatisticsContent} objects to be grouped
+   * @param period  The {@link Period} that defines the desired time grouping (e.g., DAY, WEEK, MONTH)
+   * @return A map where keys represent the grouped time periods, and values are instances of
+   *         {@link ChartStatisticsContent} containing aggregated statistical data for each group
+   */
+  protected Map<String, ChartStatisticsContent> groupByDate(List<ChartStatisticsContent> input,
+      Period period) {
+
+    final LongSummaryStatistics statistics = input.stream()
+        .mapToLong(object -> object.getStartTime().getTime()).summaryStatistics();
+    final DateTime start = new DateTime(statistics.getMin());
+    final DateTime end = new DateTime(statistics.getMax());
+    if (input.isEmpty()) {
+      return Collections.emptyMap();
+    }
+    final Map<String, ChartStatisticsContent> chart = new LinkedHashMap<>();
+
+    switch (period) {
+      case DAY:
+        proceedDailyChart(chart, start, end, input);
+        groupStatistics(DATE_PATTERN, input, chart);
+        break;
+      case WEEK:
+        proceedDailyChart(chart, start, end, input);
+        groupStatistics(DATE_PATTERN, input, chart);
+        break;
+      case MONTH:
+        proceedMonthlyChart(chart, start, end, input);
+        groupStatistics("yyyy-MM", input, chart);
+        break;
+    }
+
+    return chart;
+  }
+
+  protected Map<String, ChartStatisticsContent> maxByDate(
+      List<ChartStatisticsContent> statisticsContents, Period period,
+      String contentField) {
+    final Function<ChartStatisticsContent, String> chartObjectToDate = chartObject -> new DateTime(
+        chartObject.getStartTime().getTime())
+        .toString(DATE_PATTERN);
+    final BinaryOperator<ChartStatisticsContent> chartObjectReducer = (o1, o2) ->
+        Integer.parseInt(o1.getValues().get(contentField)) > Integer.parseInt(
+            o2.getValues().get(contentField)) ?
+            o1 :
+            o2;
+    final Map<String, Optional<ChartStatisticsContent>> groupByDate = statisticsContents.stream()
+        .filter(
+            content -> MapUtils.isNotEmpty(content.getValues()) && ofNullable(content.getValues()
+                .get(contentField)).isPresent())
+        .sorted(Comparator.comparing(ChartStatisticsContent::getStartTime))
+        .collect(Collectors.groupingBy(chartObjectToDate, LinkedHashMap::new,
+            Collectors.reducing(chartObjectReducer)));
+    final Map<String, ChartStatisticsContent> range = groupByDate(statisticsContents, period);
+    final LinkedHashMap<String, ChartStatisticsContent> result = new LinkedHashMap<>();
+    // used forEach cause aspectj compiler can't infer types properly
+    range.forEach((key, value) -> result.put(key,
+        groupByDate.getOrDefault(key, Optional.of(createChartObject(statisticsContents.get(0))))
+            .get()
+    ));
+    return result;
+  }
+
+  private void groupStatistics(String groupingPattern,
+      List<ChartStatisticsContent> statisticsContents,
+      Map<String, ChartStatisticsContent> chart) {
+
+    Map<String, List<ChartStatisticsContent>> groupedStatistics = statisticsContents.stream()
+        .collect(
+            Collectors.groupingBy(c -> new DateTime(c.getStartTime()).toString(groupingPattern),
+                LinkedHashMap::new,
+                Collectors.toList()
+            ));
+
+    groupedStatistics.forEach(
+        (key, contents) -> chart.keySet().stream().filter(k -> k.startsWith(key)).findFirst()
+            .ifPresent(k -> {
+              ChartStatisticsContent content = chart.get(k);
+              contents.add(content);
+              Map<String, String> values = contents.stream()
+                  .map(v -> v.getValues().entrySet())
+                  .flatMap(Collection::stream)
+                  .collect(Collectors.toMap(Map.Entry::getKey,
+                      entry -> ofNullable(entry.getValue()).orElse("0"),
+                      (prev, curr) -> prev = String.valueOf(
+                          Double.parseDouble(prev) + Double.parseDouble(curr))
+                  ));
+
+              content.setValues(values);
+
+              chart.put(k, content);
+            }));
+  }
+
+  private void proceedDailyChart(Map<String, ChartStatisticsContent> chart, DateTime intermediate,
+      DateTime end,
+      List<ChartStatisticsContent> statisticsContents) {
+
+    while (intermediate.isBefore(end)) {
+      chart.put(intermediate.toString(DATE_PATTERN), createChartObject(statisticsContents.get(0)));
+      intermediate = intermediate.plusDays(1);
+    }
+
+    chart.put(end.toString(DATE_PATTERN), createChartObject(statisticsContents.get(0)));
+
+  }
+
+  private void proceedMonthlyChart(Map<String, ChartStatisticsContent> chart, DateTime intermediate,
+      DateTime end,
+      List<ChartStatisticsContent> statisticsContents) {
+    while (intermediate.isBefore(end)) {
+      if (intermediate.getYear() == end.getYear()) {
+        if (intermediate.getMonthOfYear() != end.getMonthOfYear()) {
+          chart.put(intermediate.toString(DATE_PATTERN),
+              createChartObject(statisticsContents.get(0)));
+        }
+      } else {
+        chart.put(intermediate.toString(DATE_PATTERN),
+            createChartObject(statisticsContents.get(0)));
+      }
+
+      intermediate = intermediate.plusMonths(1);
+    }
+
+    chart.put(end.toString(DATE_PATTERN), createChartObject(statisticsContents.get(0)));
+
+  }
+
+  private ChartStatisticsContent createChartObject(ChartStatisticsContent input) {
+    final ChartStatisticsContent chartObject = new ChartStatisticsContent();
+    chartObject.setValues(input.getValues().entrySet().stream()
+        .collect(Collectors.toMap(Map.Entry::getKey, entry -> "0")));
+    return chartObject;
+  }
+
+  /**
+   * Timeline periods enumerator
+   *
+   * @author Andrei_Ramanchuk
+   */
+  public enum Period {
+    // @formatter:off
+    DAY(1),
+    WEEK(7),
+    MONTH(30);
+    // @formatter:on
+
+    private int value;
+
+    Period(int value) {
+      this.value = value;
+    }
+
+    public int getValue() {
+      return value;
+    }
+
+    public static boolean isPresent(String name) {
+      return findByName(name).isPresent();
+    }
+
+    public static Optional<Period> findByName(String name) {
+      return Arrays.stream(Period.values()).filter(time -> time.name().equalsIgnoreCase(name))
+          .findAny();
+    }
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/BugTrendChartContentLoader.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/BugTrendChartContentLoader.java
index 9763ecba16..bffbe3a570 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/BugTrendChartContentLoader.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/BugTrendChartContentLoader.java
@@ -16,42 +16,43 @@
 
 package com.epam.ta.reportportal.core.widget.content.loader;
 
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_SORTS;
+import static java.util.Collections.emptyMap;
+import static java.util.Collections.singletonMap;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.core.widget.content.LoadContentStrategy;
 import com.epam.ta.reportportal.dao.WidgetContentRepository;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.entity.widget.content.ChartStatisticsContent;
+import java.util.List;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_SORTS;
-import static java.util.Collections.emptyMap;
-import static java.util.Collections.singletonMap;
-
 /**
  * @author Pavel Bortnik
  */
 @Service
 public class BugTrendChartContentLoader implements LoadContentStrategy {
 
-	@Autowired
-	private WidgetContentRepository widgetContentRepository;
+  @Autowired
+  private WidgetContentRepository widgetContentRepository;
 
-	@Override
-	public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions,
-			int limit) {
+  @Override
+  public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions,
+      int limit) {
 
-		Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
+    Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
 
-		Sort sort = GROUP_SORTS.apply(filterSortMapping.values());
+    Sort sort = GROUP_SORTS.apply(filterSortMapping.values());
 
-		List<ChartStatisticsContent> result = widgetContentRepository.bugTrendStatistics(filter, contentFields, sort, limit);
-		return result.isEmpty() ? emptyMap() : singletonMap(RESULT, result);
-	}
+    List<ChartStatisticsContent> result = widgetContentRepository.bugTrendStatistics(filter,
+        contentFields, sort, limit);
+    return result.isEmpty() ? emptyMap() : singletonMap(RESULT, result);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/CasesTrendContentLoader.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/CasesTrendContentLoader.java
index 3998e75572..5f258d58cd 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/CasesTrendContentLoader.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/CasesTrendContentLoader.java
@@ -16,93 +16,101 @@
 
 package com.epam.ta.reportportal.core.widget.content.loader;
 
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.TIMELINE;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_SORTS;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DELTA;
+import static java.util.Collections.emptyMap;
+import static java.util.Collections.singletonMap;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.core.widget.content.LoadContentStrategy;
 import com.epam.ta.reportportal.core.widget.util.WidgetOptionUtil;
 import com.epam.ta.reportportal.dao.WidgetContentRepository;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.entity.widget.content.ChartStatisticsContent;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.TIMELINE;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_SORTS;
-import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DELTA;
-import static java.util.Collections.emptyMap;
-import static java.util.Collections.singletonMap;
-
 /**
  * @author Pavel Bortnik
  */
 @Service
-public class CasesTrendContentLoader extends AbstractStatisticsContentLoader implements LoadContentStrategy {
-
-	@Autowired
-	private WidgetContentRepository widgetContentRepository;
-
-	@Override
-	public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions,
-			int limit) {
-
-		Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
-
-		Sort sort = GROUP_SORTS.apply(filterSortMapping.values());
-
-		String contentField = contentFields.get(0);
-		List<ChartStatisticsContent> content = widgetContentRepository.casesTrendStatistics(filter, contentField, sort, limit);
-
-		return CollectionUtils.isEmpty(content) ? emptyMap() : calculateStatistics(widgetOptions, content, contentField, sort);
-	}
-
-	private Map<String, ?> calculateStatistics(WidgetOptions widgetOptions, List<ChartStatisticsContent> content, String contentField,
-			Sort sort) {
-		String timeLineOption = WidgetOptionUtil.getValueByKey(TIMELINE, widgetOptions);
-
-		if (StringUtils.isNotBlank(timeLineOption)) {
-			Optional<Period> period = Period.findByName(timeLineOption);
-			if (period.isPresent()) {
-				Map<String, ChartStatisticsContent> statistics = maxByDate(content, period.get(), contentField);
-				calculateDelta(statistics, sort, contentField);
-				return singletonMap(RESULT, statistics);
-			}
-
-		}
-
-		return singletonMap(RESULT, content);
-	}
-
-	private void calculateDelta(Map<String, ChartStatisticsContent> statistics, Sort sort, String contentField) {
-
-		if (sort.get().anyMatch(Sort.Order::isAscending)) {
-			ArrayList<String> keys = new ArrayList<>(statistics.keySet());
-			/* Last element in map */
-			int previous = Integer.parseInt(statistics.get(keys.get(keys.size() - 1)).getValues().get(contentField));
-			/* Iteration in reverse order */
-			for (int i = keys.size() - 1; i >= 0; i--) {
-				int current = Integer.parseInt(statistics.get(keys.get(i)).getValues().get(contentField));
-				statistics.get(keys.get(i)).getValues().put(DELTA, String.valueOf(current - previous));
-				previous = current;
-			}
-		} else {
-			int previousValue = Integer.parseInt(new ArrayList<>(statistics.values()).get(0).getValues().get(contentField));
-			for (ChartStatisticsContent content : statistics.values()) {
-				Map<String, String> values = content.getValues();
-				int currentValue = Integer.parseInt(values.get(contentField));
-				values.put(DELTA, String.valueOf(currentValue - previousValue));
-				previousValue = currentValue;
-			}
-		}
-
-	}
+public class CasesTrendContentLoader extends AbstractStatisticsContentLoader implements
+    LoadContentStrategy {
+
+  @Autowired
+  private WidgetContentRepository widgetContentRepository;
+
+  @Override
+  public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions,
+      int limit) {
+
+    Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
+
+    Sort sort = GROUP_SORTS.apply(filterSortMapping.values());
+
+    String contentField = contentFields.get(0);
+    List<ChartStatisticsContent> content = widgetContentRepository.casesTrendStatistics(filter,
+        contentField, sort, limit);
+
+    return CollectionUtils.isEmpty(content) ? emptyMap()
+        : calculateStatistics(widgetOptions, content, contentField, sort);
+  }
+
+  private Map<String, ?> calculateStatistics(WidgetOptions widgetOptions,
+      List<ChartStatisticsContent> content, String contentField,
+      Sort sort) {
+    String timeLineOption = WidgetOptionUtil.getValueByKey(TIMELINE, widgetOptions);
+
+    if (StringUtils.isNotBlank(timeLineOption)) {
+      Optional<Period> period = Period.findByName(timeLineOption);
+      if (period.isPresent()) {
+        Map<String, ChartStatisticsContent> statistics = maxByDate(content, period.get(),
+            contentField);
+        calculateDelta(statistics, sort, contentField);
+        return singletonMap(RESULT, statistics);
+      }
+
+    }
+
+    return singletonMap(RESULT, content);
+  }
+
+  private void calculateDelta(Map<String, ChartStatisticsContent> statistics, Sort sort,
+      String contentField) {
+
+    if (sort.get().anyMatch(Sort.Order::isAscending)) {
+      ArrayList<String> keys = new ArrayList<>(statistics.keySet());
+      /* Last element in map */
+      int previous = Integer.parseInt(
+          statistics.get(keys.get(keys.size() - 1)).getValues().get(contentField));
+      /* Iteration in reverse order */
+      for (int i = keys.size() - 1; i >= 0; i--) {
+        int current = Integer.parseInt(statistics.get(keys.get(i)).getValues().get(contentField));
+        statistics.get(keys.get(i)).getValues().put(DELTA, String.valueOf(current - previous));
+        previous = current;
+      }
+    } else {
+      int previousValue = Integer.parseInt(
+          new ArrayList<>(statistics.values()).get(0).getValues().get(contentField));
+      for (ChartStatisticsContent content : statistics.values()) {
+        Map<String, String> values = content.getValues();
+        int currentValue = Integer.parseInt(values.get(contentField));
+        values.put(DELTA, String.valueOf(currentValue - previousValue));
+        previousValue = currentValue;
+      }
+    }
+
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/ChartInvestigatedContentLoader.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/ChartInvestigatedContentLoader.java
index 5a77ada6a7..3f08ce5405 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/ChartInvestigatedContentLoader.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/ChartInvestigatedContentLoader.java
@@ -16,12 +16,27 @@
 
 package com.epam.ta.reportportal.core.widget.content.loader;
 
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.TIMELINE;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_SORTS;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.INVESTIGATED;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.PERCENTAGE_MULTIPLIER;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.TO_INVESTIGATE;
+import static java.util.Collections.emptyMap;
+import static java.util.Collections.singletonMap;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.core.widget.content.LoadContentStrategy;
 import com.epam.ta.reportportal.core.widget.util.WidgetOptionUtil;
 import com.epam.ta.reportportal.dao.WidgetContentRepository;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.entity.widget.content.ChartStatisticsContent;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -29,75 +44,69 @@
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.math.BigDecimal;
-import java.math.RoundingMode;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.TIMELINE;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_SORTS;
-import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.*;
-import static java.util.Collections.emptyMap;
-import static java.util.Collections.singletonMap;
-
 /**
  * @author Pavel Bortnik
  */
 @Service
-public class ChartInvestigatedContentLoader extends AbstractStatisticsContentLoader implements LoadContentStrategy {
-
-	@Autowired
-	private WidgetContentRepository widgetContentRepository;
-
-	@Override
-	public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions,
-			int limit) {
-
-		Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
-
-		Sort sort = GROUP_SORTS.apply(filterSortMapping.values());
-
-		String timeLineOption = WidgetOptionUtil.getValueByKey(TIMELINE, widgetOptions);
-
-		if (StringUtils.isNotBlank(timeLineOption)) {
-			Optional<Period> period = Period.findByName(timeLineOption);
-			if (period.isPresent()) {
-				Map<String, ChartStatisticsContent> statistics = groupByDate(widgetContentRepository.timelineInvestigatedStatistics(filter,
-						sort,
-						limit
-				), period.get());
-				return MapUtils.isEmpty(statistics) ? emptyMap() : calculateInvestigatedPercentage(statistics);
-			}
-
-		}
-
-		List<ChartStatisticsContent> content = widgetContentRepository.investigatedStatistics(filter, sort, limit);
-
-		return CollectionUtils.isEmpty(content) ? emptyMap() : singletonMap(RESULT, content);
-	}
-
-	private Map<String, ?> calculateInvestigatedPercentage(Map<String, ChartStatisticsContent> investigatedStatistics) {
-
-		investigatedStatistics.values().forEach(c -> {
-			Map<String, String> values = c.getValues();
-			BigDecimal divisor = BigDecimal.valueOf(Double.parseDouble(values.get(INVESTIGATED)));
-			if (0 != divisor.intValue()) {
-				values.put(TO_INVESTIGATE,
-						String.valueOf(BigDecimal.valueOf(PERCENTAGE_MULTIPLIER * Double.parseDouble(values.get(TO_INVESTIGATE)))
-								.divide(divisor, 2, RoundingMode.FLOOR)
-								.doubleValue())
-				);
-				values.put(INVESTIGATED, String.valueOf(PERCENTAGE_MULTIPLIER - Double.parseDouble(values.get(TO_INVESTIGATE))));
-			} else {
-				values.put(INVESTIGATED, "0");
-				values.put(TO_INVESTIGATE, "0");
-			}
-		});
-
-		return singletonMap(RESULT, investigatedStatistics);
-	}
+public class ChartInvestigatedContentLoader extends AbstractStatisticsContentLoader implements
+    LoadContentStrategy {
+
+  @Autowired
+  private WidgetContentRepository widgetContentRepository;
+
+  @Override
+  public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions,
+      int limit) {
+
+    Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
+
+    Sort sort = GROUP_SORTS.apply(filterSortMapping.values());
+
+    String timeLineOption = WidgetOptionUtil.getValueByKey(TIMELINE, widgetOptions);
+
+    if (StringUtils.isNotBlank(timeLineOption)) {
+      Optional<Period> period = Period.findByName(timeLineOption);
+      if (period.isPresent()) {
+        Map<String, ChartStatisticsContent> statistics = groupByDate(
+            widgetContentRepository.timelineInvestigatedStatistics(filter,
+                sort,
+                limit
+            ), period.get());
+        return MapUtils.isEmpty(statistics) ? emptyMap()
+            : calculateInvestigatedPercentage(statistics);
+      }
+
+    }
+
+    List<ChartStatisticsContent> content = widgetContentRepository.investigatedStatistics(filter,
+        sort, limit);
+
+    return CollectionUtils.isEmpty(content) ? emptyMap() : singletonMap(RESULT, content);
+  }
+
+  private Map<String, ?> calculateInvestigatedPercentage(
+      Map<String, ChartStatisticsContent> investigatedStatistics) {
+
+    investigatedStatistics.values().forEach(c -> {
+      Map<String, String> values = c.getValues();
+      BigDecimal divisor = BigDecimal.valueOf(Double.parseDouble(values.get(INVESTIGATED)));
+      if (0 != divisor.intValue()) {
+        values.put(TO_INVESTIGATE,
+            String.valueOf(BigDecimal.valueOf(
+                    PERCENTAGE_MULTIPLIER * Double.parseDouble(values.get(TO_INVESTIGATE)))
+                .divide(divisor, 2, RoundingMode.FLOOR)
+                .doubleValue())
+        );
+        values.put(INVESTIGATED,
+            String.valueOf(PERCENTAGE_MULTIPLIER - Double.parseDouble(values.get(TO_INVESTIGATE))));
+      } else {
+        values.put(INVESTIGATED, "0");
+        values.put(TO_INVESTIGATE, "0");
+      }
+    });
+
+    return singletonMap(RESULT, investigatedStatistics);
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/ComponentHealthCheckContentLoader.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/ComponentHealthCheckContentLoader.java
index 14506d4832..574804d49b 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/ComponentHealthCheckContentLoader.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/ComponentHealthCheckContentLoader.java
@@ -16,7 +16,27 @@
 
 package com.epam.ta.reportportal.core.widget.content.loader;
 
-import com.epam.ta.reportportal.commons.querygen.*;
+import static com.epam.ta.reportportal.commons.querygen.constant.ItemAttributeConstant.CRITERIA_COMPOSITE_ATTRIBUTE;
+import static com.epam.ta.reportportal.commons.querygen.constant.ItemAttributeConstant.KEY_VALUE_SEPARATOR;
+import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_HAS_CHILDREN;
+import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_HAS_STATS;
+import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_RETRY_PARENT_ID;
+import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_STATUS;
+import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_TYPE;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.ATTRIBUTE_KEYS;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LATEST_OPTION;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_SORTS;
+import static java.util.Collections.emptyMap;
+import static java.util.Optional.ofNullable;
+import static java.util.stream.Collectors.joining;
+
+import com.epam.ta.reportportal.commons.querygen.CompositeFilterCondition;
+import com.epam.ta.reportportal.commons.querygen.Condition;
+import com.epam.ta.reportportal.commons.querygen.ConvertibleCondition;
+import com.epam.ta.reportportal.commons.querygen.Filter;
+import com.epam.ta.reportportal.commons.querygen.FilterCondition;
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.core.widget.content.MultilevelLoadContentStrategy;
 import com.epam.ta.reportportal.core.widget.util.WidgetOptionUtil;
@@ -28,27 +48,16 @@
 import com.epam.ta.reportportal.entity.widget.content.healthcheck.ComponentHealthCheckContent;
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.google.common.collect.Lists;
-import org.apache.commons.collections.CollectionUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.domain.Sort;
-import org.springframework.stereotype.Service;
-import org.springframework.util.MultiValueMap;
-
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.IntStream;
-
-import static com.epam.ta.reportportal.commons.querygen.constant.ItemAttributeConstant.CRITERIA_COMPOSITE_ATTRIBUTE;
-import static com.epam.ta.reportportal.commons.querygen.constant.ItemAttributeConstant.KEY_VALUE_SEPARATOR;
-import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.*;
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.*;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_SORTS;
-import static java.util.Collections.emptyMap;
-import static java.util.Optional.ofNullable;
-import static java.util.stream.Collectors.joining;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Sort;
+import org.springframework.stereotype.Service;
+import org.springframework.util.MultiValueMap;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -56,86 +65,91 @@
 @Service
 public class ComponentHealthCheckContentLoader implements MultilevelLoadContentStrategy {
 
-	public static final Integer MAX_LEVEL_NUMBER = 10;
-
-	private final WidgetContentRepository widgetContentRepository;
-
-	@Autowired
-	public ComponentHealthCheckContentLoader(WidgetContentRepository widgetContentRepository) {
-		this.widgetContentRepository = widgetContentRepository;
-	}
-
-	@Override
-	public Map<String, Object> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions,
-			String[] attributes, MultiValueMap<String, String> params, int limit) {
-
-		List<String> attributeKeys = WidgetOptionUtil.getListByKey(ATTRIBUTE_KEYS, widgetOptions);
-		List<String> attributeValues = ofNullable(attributes).map(Arrays::asList).orElseGet(Collections::emptyList);
-
-		int currentLevel = attributeValues.size();
-		BusinessRule.expect(attributeKeys, keys -> keys.size() > currentLevel)
-				.verify(ErrorType.UNABLE_LOAD_WIDGET_CONTENT, "Incorrect level definition");
-
-		Filter launchesFilter = GROUP_FILTERS.apply(filterSortMapping.keySet());
-		Sort launchesSort = GROUP_SORTS.apply(filterSortMapping.values());
-
-		boolean latestMode = WidgetOptionUtil.getBooleanByKey(LATEST_OPTION, widgetOptions);
-
-		Filter testItemFilter = Filter.builder()
-				.withTarget(TestItem.class)
-				.withCondition(getTestItemCondition(attributeKeys, attributeValues))
-				.build();
-
-		String currentLevelKey = attributeKeys.get(currentLevel);
-
-		List<ComponentHealthCheckContent> content = widgetContentRepository.componentHealthCheck(launchesFilter,
-				launchesSort,
-				latestMode,
-				limit,
-				testItemFilter,
-				currentLevelKey
-		);
-
-		return CollectionUtils.isNotEmpty(content) ? Collections.singletonMap(RESULT, content) : emptyMap();
-	}
-
-	private ConvertibleCondition getTestItemCondition(List<String> attributeKeys, List<String> attributeValues) {
-
-		List<ConvertibleCondition> conditions = Lists.newArrayList(FilterCondition.builder()
-						.eq(CRITERIA_HAS_STATS, String.valueOf(Boolean.TRUE))
-						.build(),
-				FilterCondition.builder().eq(CRITERIA_HAS_CHILDREN, String.valueOf(Boolean.FALSE)).build(),
-				FilterCondition.builder().eq(CRITERIA_TYPE, TestItemTypeEnum.STEP.name()).build(),
-				FilterCondition.builder()
-						.withCondition(Condition.EXISTS)
-						.withNegative(true)
-						.withSearchCriteria(CRITERIA_RETRY_PARENT_ID)
-						.withValue(String.valueOf(0L))
-						.build(),
-				FilterCondition.builder()
-						.withCondition(Condition.NOT_EQUALS)
-						.withNegative(false)
-						.withSearchCriteria(CRITERIA_STATUS)
-						.withValue(StatusEnum.IN_PROGRESS.name())
-						.build()
-		);
-
-		if (CollectionUtils.isNotEmpty(attributeValues)) {
-			String attributeCriteria = IntStream.range(0, attributeValues.size()).mapToObj(index -> {
-				String attributeKey = attributeKeys.get(index);
-				String attributeValue = attributeValues.get(index);
-				return String.join(KEY_VALUE_SEPARATOR, attributeKey, attributeValue);
-			}).collect(joining(","));
-
-			conditions.add(FilterCondition.builder()
-					.withCondition(Condition.HAS)
-					.withNegative(false)
-					.withSearchCriteria(CRITERIA_COMPOSITE_ATTRIBUTE)
-					.withValue(attributeCriteria)
-					.build());
-		}
-
-		return new CompositeFilterCondition(conditions);
-
-	}
+  public static final Integer MAX_LEVEL_NUMBER = 10;
+
+  private final WidgetContentRepository widgetContentRepository;
+
+  @Autowired
+  public ComponentHealthCheckContentLoader(WidgetContentRepository widgetContentRepository) {
+    this.widgetContentRepository = widgetContentRepository;
+  }
+
+  @Override
+  public Map<String, Object> loadContent(List<String> contentFields,
+      Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions,
+      String[] attributes, MultiValueMap<String, String> params, int limit) {
+
+    List<String> attributeKeys = WidgetOptionUtil.getListByKey(ATTRIBUTE_KEYS, widgetOptions);
+    List<String> attributeValues = ofNullable(attributes).map(Arrays::asList)
+        .orElseGet(Collections::emptyList);
+
+    int currentLevel = attributeValues.size();
+    BusinessRule.expect(attributeKeys, keys -> keys.size() > currentLevel)
+        .verify(ErrorType.UNABLE_LOAD_WIDGET_CONTENT, "Incorrect level definition");
+
+    Filter launchesFilter = GROUP_FILTERS.apply(filterSortMapping.keySet());
+    Sort launchesSort = GROUP_SORTS.apply(filterSortMapping.values());
+
+    boolean latestMode = WidgetOptionUtil.getBooleanByKey(LATEST_OPTION, widgetOptions);
+
+    Filter testItemFilter = Filter.builder()
+        .withTarget(TestItem.class)
+        .withCondition(getTestItemCondition(attributeKeys, attributeValues))
+        .build();
+
+    String currentLevelKey = attributeKeys.get(currentLevel);
+
+    List<ComponentHealthCheckContent> content = widgetContentRepository.componentHealthCheck(
+        launchesFilter,
+        launchesSort,
+        latestMode,
+        limit,
+        testItemFilter,
+        currentLevelKey
+    );
+
+    return CollectionUtils.isNotEmpty(content) ? Collections.singletonMap(RESULT, content)
+        : emptyMap();
+  }
+
+  private ConvertibleCondition getTestItemCondition(List<String> attributeKeys,
+      List<String> attributeValues) {
+
+    List<ConvertibleCondition> conditions = Lists.newArrayList(FilterCondition.builder()
+            .eq(CRITERIA_HAS_STATS, String.valueOf(Boolean.TRUE))
+            .build(),
+        FilterCondition.builder().eq(CRITERIA_HAS_CHILDREN, String.valueOf(Boolean.FALSE)).build(),
+        FilterCondition.builder().eq(CRITERIA_TYPE, TestItemTypeEnum.STEP.name()).build(),
+        FilterCondition.builder()
+            .withCondition(Condition.EXISTS)
+            .withNegative(true)
+            .withSearchCriteria(CRITERIA_RETRY_PARENT_ID)
+            .withValue(String.valueOf(0L))
+            .build(),
+        FilterCondition.builder()
+            .withCondition(Condition.NOT_EQUALS)
+            .withNegative(false)
+            .withSearchCriteria(CRITERIA_STATUS)
+            .withValue(StatusEnum.IN_PROGRESS.name())
+            .build()
+    );
+
+    if (CollectionUtils.isNotEmpty(attributeValues)) {
+      String attributeCriteria = IntStream.range(0, attributeValues.size()).mapToObj(index -> {
+        String attributeKey = attributeKeys.get(index);
+        String attributeValue = attributeValues.get(index);
+        return String.join(KEY_VALUE_SEPARATOR, attributeKey, attributeValue);
+      }).collect(joining(","));
+
+      conditions.add(FilterCondition.builder()
+          .withCondition(Condition.HAS)
+          .withNegative(false)
+          .withSearchCriteria(CRITERIA_COMPOSITE_ATTRIBUTE)
+          .withValue(attributeCriteria)
+          .build());
+    }
+
+    return new CompositeFilterCondition(conditions);
+
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/FlakyCasesTableContentLoader.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/FlakyCasesTableContentLoader.java
index f12c470966..585e1e3cfa 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/FlakyCasesTableContentLoader.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/FlakyCasesTableContentLoader.java
@@ -16,6 +16,15 @@
 
 package com.epam.ta.reportportal.core.widget.content.loader;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_NAME;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.FLAKY;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.INCLUDE_METHODS;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LATEST_LAUNCH;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LAUNCH_NAME_FIELD;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
+import static java.util.Collections.emptyMap;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.querygen.Condition;
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.querygen.FilterCondition;
@@ -28,58 +37,56 @@
 import com.epam.ta.reportportal.entity.widget.content.FlakyCasesTableContent;
 import com.epam.ta.reportportal.entity.widget.content.LatestLaunchContent;
 import com.google.common.collect.ImmutableMap;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.BooleanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_NAME;
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.*;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
-import static java.util.Collections.emptyMap;
-import static java.util.Optional.ofNullable;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class FlakyCasesTableContentLoader implements LoadContentStrategy {
 
-	@Autowired
-	private WidgetContentRepository widgetRepository;
+  @Autowired
+  private WidgetContentRepository widgetRepository;
 
-	@Autowired
-	private LaunchRepository launchRepository;
+  @Autowired
+  private LaunchRepository launchRepository;
 
-	@Override
-	public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions,
-			int limit) {
+  @Override
+  public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions,
+      int limit) {
 
-		Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
-		String launchName = WidgetOptionUtil.getValueByKey(LAUNCH_NAME_FIELD, widgetOptions);
-		filter.withCondition(new FilterCondition(Condition.EQUALS, false, launchName, CRITERIA_NAME));
+    Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
+    String launchName = WidgetOptionUtil.getValueByKey(LAUNCH_NAME_FIELD, widgetOptions);
+    filter.withCondition(new FilterCondition(Condition.EQUALS, false, launchName, CRITERIA_NAME));
 
-		return launchRepository.findLatestByFilter(filter)
-				.map(l -> loadContent(l, filter, widgetOptions, limit))
-				.orElseGet(Collections::emptyMap);
+    return launchRepository.findLatestByFilter(filter)
+        .map(l -> loadContent(l, filter, widgetOptions, limit))
+        .orElseGet(Collections::emptyMap);
 
-	}
+  }
 
-	private Map<String, ?> loadContent(Launch launch, Filter filter, WidgetOptions widgetOptions, int limit) {
-		LatestLaunchContent latestLaunchContent = new LatestLaunchContent(launch);
+  private Map<String, ?> loadContent(Launch launch, Filter filter, WidgetOptions widgetOptions,
+      int limit) {
+    LatestLaunchContent latestLaunchContent = new LatestLaunchContent(launch);
 
-		List<FlakyCasesTableContent> flakyCasesTableContent = widgetRepository.flakyCasesStatistics(filter,
-				ofNullable(widgetOptions.getOptions().get(INCLUDE_METHODS)).map(v -> BooleanUtils.toBoolean(String.valueOf(v)))
-						.orElse(false),
-				limit
-		);
-		return CollectionUtils.isEmpty(flakyCasesTableContent) ?
-				emptyMap() :
-				ImmutableMap.<String, Object>builder().put(LATEST_LAUNCH, latestLaunchContent).put(FLAKY, flakyCasesTableContent).build();
-	}
+    List<FlakyCasesTableContent> flakyCasesTableContent = widgetRepository.flakyCasesStatistics(
+        filter,
+        ofNullable(widgetOptions.getOptions().get(INCLUDE_METHODS)).map(
+                v -> BooleanUtils.toBoolean(String.valueOf(v)))
+            .orElse(false),
+        limit
+    );
+    return CollectionUtils.isEmpty(flakyCasesTableContent) ?
+        emptyMap() :
+        ImmutableMap.<String, Object>builder().put(LATEST_LAUNCH, latestLaunchContent)
+            .put(FLAKY, flakyCasesTableContent).build();
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/LaunchExecutionAndIssueStatisticsContentLoader.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/LaunchExecutionAndIssueStatisticsContentLoader.java
index 73034fdad1..693dbff593 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/LaunchExecutionAndIssueStatisticsContentLoader.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/LaunchExecutionAndIssueStatisticsContentLoader.java
@@ -16,43 +16,44 @@
 
 package com.epam.ta.reportportal.core.widget.content.loader;
 
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_SORTS;
+import static java.util.Collections.emptyMap;
+import static java.util.Collections.singletonMap;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.core.widget.content.LoadContentStrategy;
 import com.epam.ta.reportportal.dao.WidgetContentRepository;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.entity.widget.content.ChartStatisticsContent;
+import java.util.List;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_SORTS;
-import static java.util.Collections.emptyMap;
-import static java.util.Collections.singletonMap;
-
 /**
  * @author Pavel Bortnik
  */
 @Service
 public class LaunchExecutionAndIssueStatisticsContentLoader implements LoadContentStrategy {
 
-	@Autowired
-	private WidgetContentRepository widgetContentRepository;
+  @Autowired
+  private WidgetContentRepository widgetContentRepository;
 
-	@Override
-	public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions,
-			int limit) {
+  @Override
+  public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions,
+      int limit) {
 
-		Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
-		Sort sort = GROUP_SORTS.apply(filterSortMapping.values());
+    Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
+    Sort sort = GROUP_SORTS.apply(filterSortMapping.values());
 
-		List<ChartStatisticsContent> content = widgetContentRepository.launchStatistics(filter, contentFields, sort, limit);
+    List<ChartStatisticsContent> content = widgetContentRepository.launchStatistics(filter,
+        contentFields, sort, limit);
 
-		return content.isEmpty() ? emptyMap() : singletonMap(RESULT, content);
-	}
+    return content.isEmpty() ? emptyMap() : singletonMap(RESULT, content);
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/LaunchesComparisonContentLoader.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/LaunchesComparisonContentLoader.java
index 6c1adf2880..5e3422d4c5 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/LaunchesComparisonContentLoader.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/LaunchesComparisonContentLoader.java
@@ -16,25 +16,24 @@
 
 package com.epam.ta.reportportal.core.widget.content.loader;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_START_TIME;
+import static com.epam.ta.reportportal.commons.querygen.constant.LaunchCriteriaConstant.CRITERIA_LAUNCH_NUMBER;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
+import static java.util.Collections.emptyMap;
+import static java.util.Collections.singletonMap;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.core.widget.content.LoadContentStrategy;
 import com.epam.ta.reportportal.dao.WidgetContentRepository;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.entity.widget.content.ChartStatisticsContent;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.domain.Sort;
-import org.springframework.stereotype.Service;
-
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
-
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_START_TIME;
-import static com.epam.ta.reportportal.commons.querygen.constant.LaunchCriteriaConstant.CRITERIA_LAUNCH_NUMBER;
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
-import static java.util.Collections.emptyMap;
-import static java.util.Collections.singletonMap;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Sort;
+import org.springframework.stereotype.Service;
 
 /**
  * @author Pavel Bortnik
@@ -42,24 +41,27 @@
 @Service
 public class LaunchesComparisonContentLoader implements LoadContentStrategy {
 
-	@Autowired
-	private WidgetContentRepository widgetContentRepository;
+  @Autowired
+  private WidgetContentRepository widgetContentRepository;
 
-	@Override
-	public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions,
-			int limit) {
+  @Override
+  public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions,
+      int limit) {
 
-		Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
-		Sort sort = Sort.by(Sort.Order.desc(CRITERIA_START_TIME), Sort.Order.desc(CRITERIA_LAUNCH_NUMBER));
+    Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
+    Sort sort = Sort.by(Sort.Order.desc(CRITERIA_START_TIME),
+        Sort.Order.desc(CRITERIA_LAUNCH_NUMBER));
 
-		List<ChartStatisticsContent> result = widgetContentRepository.launchesComparisonStatistics(filter, contentFields, sort, limit);
+    List<ChartStatisticsContent> result = widgetContentRepository.launchesComparisonStatistics(
+        filter, contentFields, sort, limit);
 
-		if (result.isEmpty()) {
-			return emptyMap();
-		} else {
-			Collections.reverse(result);
-			return singletonMap(RESULT, result);
-		}
-	}
+    if (result.isEmpty()) {
+      return emptyMap();
+    } else {
+      Collections.reverse(result);
+      return singletonMap(RESULT, result);
+    }
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/LaunchesDurationContentLoader.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/LaunchesDurationContentLoader.java
index 6928cb1478..206aa12bed 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/LaunchesDurationContentLoader.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/LaunchesDurationContentLoader.java
@@ -16,48 +16,49 @@
 
 package com.epam.ta.reportportal.core.widget.content.loader;
 
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LATEST_OPTION;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_SORTS;
+import static java.util.Collections.emptyMap;
+import static java.util.Collections.singletonMap;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.core.widget.content.LoadContentStrategy;
 import com.epam.ta.reportportal.core.widget.util.WidgetOptionUtil;
 import com.epam.ta.reportportal.dao.WidgetContentRepository;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.entity.widget.content.LaunchesDurationContent;
+import java.util.List;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LATEST_OPTION;
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_SORTS;
-import static java.util.Collections.emptyMap;
-import static java.util.Collections.singletonMap;
-
 /**
  * @author Pavel Bortnik
  */
 @Service
 public class LaunchesDurationContentLoader implements LoadContentStrategy {
 
-	@Autowired
-	private WidgetContentRepository widgetContentRepository;
+  @Autowired
+  private WidgetContentRepository widgetContentRepository;
 
-	@Override
-	public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions,
-			int limit) {
+  @Override
+  public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions,
+      int limit) {
 
-		Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
+    Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
 
-		Sort sort = GROUP_SORTS.apply(filterSortMapping.values());
+    Sort sort = GROUP_SORTS.apply(filterSortMapping.values());
 
-		boolean latestMode = WidgetOptionUtil.getBooleanByKey(LATEST_OPTION, widgetOptions);
+    boolean latestMode = WidgetOptionUtil.getBooleanByKey(LATEST_OPTION, widgetOptions);
 
-		List<LaunchesDurationContent> result = widgetContentRepository.launchesDurationStatistics(filter, sort, latestMode, limit);
+    List<LaunchesDurationContent> result = widgetContentRepository.launchesDurationStatistics(
+        filter, sort, latestMode, limit);
 
-		return result.isEmpty() ? emptyMap() : singletonMap(RESULT, result);
-	}
+    return result.isEmpty() ? emptyMap() : singletonMap(RESULT, result);
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/LaunchesTableContentLoader.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/LaunchesTableContentLoader.java
index 6bb2ef1993..a9f9ba9e9e 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/LaunchesTableContentLoader.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/LaunchesTableContentLoader.java
@@ -16,44 +16,45 @@
 
 package com.epam.ta.reportportal.core.widget.content.loader;
 
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_SORTS;
+import static java.util.Collections.emptyMap;
+import static java.util.Collections.singletonMap;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.core.widget.content.LoadContentStrategy;
 import com.epam.ta.reportportal.dao.WidgetContentRepository;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.entity.widget.content.LaunchesTableContent;
+import java.util.List;
+import java.util.Map;
 import org.apache.commons.collections.CollectionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_SORTS;
-import static java.util.Collections.emptyMap;
-import static java.util.Collections.singletonMap;
-
 /**
  * @author Pavel Bortnik
  */
 @Service
 public class LaunchesTableContentLoader implements LoadContentStrategy {
 
-	@Autowired
-	private WidgetContentRepository widgetContentRepository;
+  @Autowired
+  private WidgetContentRepository widgetContentRepository;
 
-	@Override
-	public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions,
-			int limit) {
+  @Override
+  public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions,
+      int limit) {
 
-		Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
-		Sort sort = GROUP_SORTS.apply(filterSortMapping.values());
+    Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
+    Sort sort = GROUP_SORTS.apply(filterSortMapping.values());
 
-		List<LaunchesTableContent> content = widgetContentRepository.launchesTableStatistics(filter, contentFields, sort, limit);
+    List<LaunchesTableContent> content = widgetContentRepository.launchesTableStatistics(filter,
+        contentFields, sort, limit);
 
-		return CollectionUtils.isEmpty(content) ? emptyMap() : singletonMap(RESULT, content);
-	}
+    return CollectionUtils.isEmpty(content) ? emptyMap() : singletonMap(RESULT, content);
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/LineChartContentLoader.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/LineChartContentLoader.java
index 4048bd0486..d6400b492c 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/LineChartContentLoader.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/LineChartContentLoader.java
@@ -16,12 +16,23 @@
 
 package com.epam.ta.reportportal.core.widget.content.loader;
 
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.TIMELINE;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_SORTS;
+import static java.util.Collections.emptyMap;
+import static java.util.Collections.singletonMap;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.core.widget.content.LoadContentStrategy;
 import com.epam.ta.reportportal.core.widget.util.WidgetOptionUtil;
 import com.epam.ta.reportportal.dao.WidgetContentRepository;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.entity.widget.content.ChartStatisticsContent;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.logging.log4j.util.Strings;
@@ -29,46 +40,39 @@
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.TIMELINE;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_SORTS;
-import static java.util.Collections.emptyMap;
-import static java.util.Collections.singletonMap;
-import static java.util.Optional.ofNullable;
-
 /**
  * @author Pavel Bortnik
  */
 @Service
-public class LineChartContentLoader extends AbstractStatisticsContentLoader implements LoadContentStrategy {
+public class LineChartContentLoader extends AbstractStatisticsContentLoader implements
+    LoadContentStrategy {
 
-	@Autowired
-	private WidgetContentRepository widgetContentRepository;
+  @Autowired
+  private WidgetContentRepository widgetContentRepository;
 
-	@Override
-	public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions,
-			int limit) {
+  @Override
+  public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions,
+      int limit) {
 
-		Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
-		Sort sort = GROUP_SORTS.apply(filterSortMapping.values());
+    Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
+    Sort sort = GROUP_SORTS.apply(filterSortMapping.values());
 
-		List<ChartStatisticsContent> content = widgetContentRepository.launchStatistics(filter, contentFields, sort, limit);
+    List<ChartStatisticsContent> content = widgetContentRepository.launchStatistics(filter,
+        contentFields, sort, limit);
 
-		String timeLineOption = ofNullable(widgetOptions).map(wo -> WidgetOptionUtil.getValueByKey(TIMELINE, wo)).orElse(Strings.EMPTY);
-		if (StringUtils.isNotBlank(timeLineOption)) {
-			Optional<Period> period = Period.findByName(timeLineOption);
-			if (period.isPresent()) {
-				return CollectionUtils.isEmpty(content) ? emptyMap() : singletonMap(RESULT, groupByDate(content, period.get()));
-			}
+    String timeLineOption = ofNullable(widgetOptions).map(
+        wo -> WidgetOptionUtil.getValueByKey(TIMELINE, wo)).orElse(Strings.EMPTY);
+    if (StringUtils.isNotBlank(timeLineOption)) {
+      Optional<Period> period = Period.findByName(timeLineOption);
+      if (period.isPresent()) {
+        return CollectionUtils.isEmpty(content) ? emptyMap()
+            : singletonMap(RESULT, groupByDate(content, period.get()));
+      }
 
-		}
+    }
 
-		return CollectionUtils.isEmpty(content) ? emptyMap() : singletonMap(RESULT, content);
-	}
+    return CollectionUtils.isEmpty(content) ? emptyMap() : singletonMap(RESULT, content);
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/MostTimeConsumingContentLoader.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/MostTimeConsumingContentLoader.java
index 8e6b406042..830dcce37a 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/MostTimeConsumingContentLoader.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/MostTimeConsumingContentLoader.java
@@ -16,6 +16,23 @@
 
 package com.epam.ta.reportportal.core.widget.content.loader;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_LAUNCH_ID;
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_NAME;
+import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_HAS_CHILDREN;
+import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_HAS_STATS;
+import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_STATUS;
+import static com.epam.ta.reportportal.core.filter.predefined.PredefinedFilters.HAS_METHOD_OR_CLASS;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.CONTENT_FIELDS_DELIMITER;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.INCLUDE_METHODS;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.ITEM_TYPE;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LATEST_LAUNCH;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LAUNCH_NAME_FIELD;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
+import static com.epam.ta.reportportal.jooq.enums.JTestItemTypeEnum.STEP;
+import static java.util.Collections.emptyMap;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.querygen.Condition;
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.querygen.FilterCondition;
@@ -32,6 +49,10 @@
 import com.epam.ta.reportportal.entity.widget.content.MostTimeConsumingTestCasesContent;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Lists;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.BooleanUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -39,109 +60,107 @@
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_LAUNCH_ID;
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_NAME;
-import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.*;
-import static com.epam.ta.reportportal.core.filter.predefined.PredefinedFilters.HAS_METHOD_OR_CLASS;
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.*;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
-import static com.epam.ta.reportportal.jooq.enums.JTestItemTypeEnum.STEP;
-import static java.util.Collections.emptyMap;
-import static java.util.Optional.ofNullable;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class MostTimeConsumingContentLoader implements LoadContentStrategy {
 
-	public static final int MOST_TIME_CONSUMING_CASES_COUNT = 20;
-
-	private final LaunchRepository launchRepository;
-	private final WidgetContentRepository widgetContentRepository;
-
-	@Autowired
-	public MostTimeConsumingContentLoader(LaunchRepository launchRepository, WidgetContentRepository widgetContentRepository) {
-		this.launchRepository = launchRepository;
-		this.widgetContentRepository = widgetContentRepository;
-	}
-
-	@Override
-	public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMap, WidgetOptions widgetOptions, int limit) {
-
-		Filter filter = GROUP_FILTERS.apply(filterSortMap.keySet());
-		String launchName = WidgetOptionUtil.getValueByKey(LAUNCH_NAME_FIELD, widgetOptions);
-
-		return launchRepository.findLatestByFilter(filter.withCondition(FilterCondition.builder().eq(CRITERIA_NAME, launchName).build()))
-				.map(l -> loadContent(l, widgetOptions, contentFields))
-				.orElseGet(Collections::emptyMap);
-
-	}
-
-	private Map<String, ?> loadContent(Launch launch, WidgetOptions widgetOptions, List<String> contentFields) {
-		final List<MostTimeConsumingTestCasesContent> content = widgetContentRepository.mostTimeConsumingTestCasesStatistics(buildItemFilter(
-				launch.getId(),
-				widgetOptions,
-				contentFields
-		), MOST_TIME_CONSUMING_CASES_COUNT);
-
-		return content.isEmpty() ?
-				emptyMap() :
-				ImmutableMap.<String, Object>builder().put(LATEST_LAUNCH, new LatestLaunchContent(launch)).put(RESULT, content).build();
-	}
-
-	private Filter buildItemFilter(Long launchId, WidgetOptions widgetOptions, List<String> contentFields) {
-		Filter filter = Filter.builder()
-				.withTarget(TestItem.class)
-				.withCondition(FilterCondition.builder().eq(CRITERIA_LAUNCH_ID, String.valueOf(launchId)).build())
-				.build();
-		filter = updateFilterWithStatuses(filter, contentFields);
-		filter = updateFilterWithTestItemTypes(filter,
-				ofNullable(widgetOptions.getOptions().get(INCLUDE_METHODS)).map(v -> BooleanUtils.toBoolean(String.valueOf(v)))
-						.orElse(false)
-		);
-		return filter.withCondition(FilterCondition.builder().eq(CRITERIA_HAS_CHILDREN, Boolean.FALSE.toString()).build())
-				.withCondition(FilterCondition.builder().eq(CRITERIA_HAS_STATS, Boolean.TRUE.toString()).build());
-	}
-
-	private Filter updateFilterWithStatuses(Filter filter, List<String> contentFields) {
-		if (CollectionUtils.isNotEmpty(contentFields)) {
-			String statusCriteria = contentFields.stream()
-					.filter(StringUtils::isNotBlank)
-					.map(it -> it.split("\\$"))
-					.map(split -> split[split.length - 1].toUpperCase())
-					.filter(cf -> StatusEnum.fromValue(cf).isPresent())
-					.collect(Collectors.joining(", "));
-			return filter.withCondition(FilterCondition.builder()
-					.withSearchCriteria(CRITERIA_STATUS)
-					.withCondition(Condition.IN)
-					.withValue(statusCriteria)
-					.build());
-		}
-		return filter;
-	}
-
-	private Filter updateFilterWithTestItemTypes(Filter filter, boolean includeMethodsFlag) {
-		return includeMethodsFlag ? updateFilterWithStepAndBeforeAfterMethods(filter) : updateFilterWithStepTestItem(filter);
-	}
-
-	private Filter updateFilterWithStepTestItem(Filter filter) {
-		return filter.withCondition(FilterCondition.builder().eq(ITEM_TYPE, STEP.getLiteral()).build());
-	}
-
-	private Filter updateFilterWithStepAndBeforeAfterMethods(Filter filter) {
-		List<TestItemTypeEnum> itemTypes = Lists.newArrayList(TestItemTypeEnum.STEP);
-		itemTypes.addAll(HAS_METHOD_OR_CLASS);
-
-		return filter.withCondition(FilterCondition.builder()
-				.withCondition(Condition.IN)
-				.withSearchCriteria(ITEM_TYPE)
-				.withValue(itemTypes.stream().map(TestItemTypeEnum::name).collect(Collectors.joining(CONTENT_FIELDS_DELIMITER)))
-				.build());
-	}
+  public static final int MOST_TIME_CONSUMING_CASES_COUNT = 20;
+
+  private final LaunchRepository launchRepository;
+  private final WidgetContentRepository widgetContentRepository;
+
+  @Autowired
+  public MostTimeConsumingContentLoader(LaunchRepository launchRepository,
+      WidgetContentRepository widgetContentRepository) {
+    this.launchRepository = launchRepository;
+    this.widgetContentRepository = widgetContentRepository;
+  }
+
+  @Override
+  public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMap,
+      WidgetOptions widgetOptions, int limit) {
+
+    Filter filter = GROUP_FILTERS.apply(filterSortMap.keySet());
+    String launchName = WidgetOptionUtil.getValueByKey(LAUNCH_NAME_FIELD, widgetOptions);
+
+    return launchRepository.findLatestByFilter(
+            filter.withCondition(FilterCondition.builder().eq(CRITERIA_NAME, launchName).build()))
+        .map(l -> loadContent(l, widgetOptions, contentFields))
+        .orElseGet(Collections::emptyMap);
+
+  }
+
+  private Map<String, ?> loadContent(Launch launch, WidgetOptions widgetOptions,
+      List<String> contentFields) {
+    final List<MostTimeConsumingTestCasesContent> content = widgetContentRepository.mostTimeConsumingTestCasesStatistics(
+        buildItemFilter(
+            launch.getId(),
+            widgetOptions,
+            contentFields
+        ), MOST_TIME_CONSUMING_CASES_COUNT);
+
+    return content.isEmpty() ?
+        emptyMap() :
+        ImmutableMap.<String, Object>builder().put(LATEST_LAUNCH, new LatestLaunchContent(launch))
+            .put(RESULT, content).build();
+  }
+
+  private Filter buildItemFilter(Long launchId, WidgetOptions widgetOptions,
+      List<String> contentFields) {
+    Filter filter = Filter.builder()
+        .withTarget(TestItem.class)
+        .withCondition(
+            FilterCondition.builder().eq(CRITERIA_LAUNCH_ID, String.valueOf(launchId)).build())
+        .build();
+    filter = updateFilterWithStatuses(filter, contentFields);
+    filter = updateFilterWithTestItemTypes(filter,
+        ofNullable(widgetOptions.getOptions().get(INCLUDE_METHODS)).map(
+                v -> BooleanUtils.toBoolean(String.valueOf(v)))
+            .orElse(false)
+    );
+    return filter.withCondition(
+            FilterCondition.builder().eq(CRITERIA_HAS_CHILDREN, Boolean.FALSE.toString()).build())
+        .withCondition(
+            FilterCondition.builder().eq(CRITERIA_HAS_STATS, Boolean.TRUE.toString()).build());
+  }
+
+  private Filter updateFilterWithStatuses(Filter filter, List<String> contentFields) {
+    if (CollectionUtils.isNotEmpty(contentFields)) {
+      String statusCriteria = contentFields.stream()
+          .filter(StringUtils::isNotBlank)
+          .map(it -> it.split("\\$"))
+          .map(split -> split[split.length - 1].toUpperCase())
+          .filter(cf -> StatusEnum.fromValue(cf).isPresent())
+          .collect(Collectors.joining(", "));
+      return filter.withCondition(FilterCondition.builder()
+          .withSearchCriteria(CRITERIA_STATUS)
+          .withCondition(Condition.IN)
+          .withValue(statusCriteria)
+          .build());
+    }
+    return filter;
+  }
+
+  private Filter updateFilterWithTestItemTypes(Filter filter, boolean includeMethodsFlag) {
+    return includeMethodsFlag ? updateFilterWithStepAndBeforeAfterMethods(filter)
+        : updateFilterWithStepTestItem(filter);
+  }
+
+  private Filter updateFilterWithStepTestItem(Filter filter) {
+    return filter.withCondition(FilterCondition.builder().eq(ITEM_TYPE, STEP.getLiteral()).build());
+  }
+
+  private Filter updateFilterWithStepAndBeforeAfterMethods(Filter filter) {
+    List<TestItemTypeEnum> itemTypes = Lists.newArrayList(TestItemTypeEnum.STEP);
+    itemTypes.addAll(HAS_METHOD_OR_CLASS);
+
+    return filter.withCondition(FilterCondition.builder()
+        .withCondition(Condition.IN)
+        .withSearchCriteria(ITEM_TYPE)
+        .withValue(itemTypes.stream().map(TestItemTypeEnum::name)
+            .collect(Collectors.joining(CONTENT_FIELDS_DELIMITER)))
+        .build());
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/NotPassedTestsContentLoader.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/NotPassedTestsContentLoader.java
index 55f2585d9b..1ef5293bbc 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/NotPassedTestsContentLoader.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/NotPassedTestsContentLoader.java
@@ -16,43 +16,44 @@
 
 package com.epam.ta.reportportal.core.widget.content.loader;
 
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_SORTS;
+import static java.util.Collections.emptyMap;
+import static java.util.Collections.singletonMap;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.core.widget.content.LoadContentStrategy;
 import com.epam.ta.reportportal.dao.WidgetContentRepository;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.entity.widget.content.NotPassedCasesContent;
+import java.util.List;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_SORTS;
-import static java.util.Collections.emptyMap;
-import static java.util.Collections.singletonMap;
-
 /**
  * @author Pavel Bortnik
  */
 @Service
 public class NotPassedTestsContentLoader implements LoadContentStrategy {
 
-	@Autowired
-	private WidgetContentRepository widgetContentRepository;
+  @Autowired
+  private WidgetContentRepository widgetContentRepository;
 
-	@Override
-	public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions,
-			int limit) {
+  @Override
+  public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions,
+      int limit) {
 
-		Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
-		Sort sort = GROUP_SORTS.apply(filterSortMapping.values());
+    Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
+    Sort sort = GROUP_SORTS.apply(filterSortMapping.values());
 
-		List<NotPassedCasesContent> result = widgetContentRepository.notPassedCasesStatistics(filter, sort, limit);
+    List<NotPassedCasesContent> result = widgetContentRepository.notPassedCasesStatistics(filter,
+        sort, limit);
 
-		return result.isEmpty() ? emptyMap() : singletonMap(RESULT, result);
-	}
+    return result.isEmpty() ? emptyMap() : singletonMap(RESULT, result);
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/OverallStatisticsContentLoader.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/OverallStatisticsContentLoader.java
index aa73d15389..ad8f1c878b 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/OverallStatisticsContentLoader.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/OverallStatisticsContentLoader.java
@@ -16,49 +16,51 @@
 
 package com.epam.ta.reportportal.core.widget.content.loader;
 
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LATEST_OPTION;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_SORTS;
+import static java.util.Collections.emptyMap;
+import static java.util.Collections.singletonMap;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.core.widget.content.LoadContentStrategy;
 import com.epam.ta.reportportal.core.widget.util.WidgetOptionUtil;
 import com.epam.ta.reportportal.dao.WidgetContentRepository;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.entity.widget.content.OverallStatisticsContent;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
 import org.apache.commons.collections.MapUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LATEST_OPTION;
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_SORTS;
-import static java.util.Collections.emptyMap;
-import static java.util.Collections.singletonMap;
-
 /**
  * @author Pavel Bortnik
  */
 @Service
 public class OverallStatisticsContentLoader implements LoadContentStrategy {
 
-	@Autowired
-	private WidgetContentRepository widgetContentRepository;
+  @Autowired
+  private WidgetContentRepository widgetContentRepository;
 
-	@Override
-	public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions,
-			int limit) {
+  @Override
+  public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions,
+      int limit) {
 
-		Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
-		Sort sort = GROUP_SORTS.apply(filterSortMapping.values());
+    Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
+    Sort sort = GROUP_SORTS.apply(filterSortMapping.values());
 
-		boolean latestMode = WidgetOptionUtil.getBooleanByKey(LATEST_OPTION, widgetOptions);
+    boolean latestMode = WidgetOptionUtil.getBooleanByKey(LATEST_OPTION, widgetOptions);
 
-		OverallStatisticsContent content = widgetContentRepository.overallStatisticsContent(filter, sort, contentFields, latestMode, limit);
+    OverallStatisticsContent content = widgetContentRepository.overallStatisticsContent(filter,
+        sort, contentFields, latestMode, limit);
 
-		return MapUtils.isEmpty(content.getValues()) ? emptyMap() : singletonMap(RESULT, Collections.singletonList(content));
-	}
+    return MapUtils.isEmpty(content.getValues()) ? emptyMap()
+        : singletonMap(RESULT, Collections.singletonList(content));
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/PassingRatePerLaunchContentLoader.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/PassingRatePerLaunchContentLoader.java
index 15f48292d0..bad29eb139 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/PassingRatePerLaunchContentLoader.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/PassingRatePerLaunchContentLoader.java
@@ -16,6 +16,13 @@
 
 package com.epam.ta.reportportal.core.widget.content.loader;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_NAME;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LAUNCH_NAME_FIELD;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
+import static java.util.Collections.emptyMap;
+import static java.util.Collections.singletonMap;
+
 import com.epam.ta.reportportal.commons.querygen.Condition;
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.querygen.FilterCondition;
@@ -26,20 +33,12 @@
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.entity.widget.content.PassingRateStatisticsResult;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.domain.Sort;
-import org.springframework.stereotype.Service;
-
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
-
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_NAME;
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LAUNCH_NAME_FIELD;
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
-import static java.util.Collections.emptyMap;
-import static java.util.Collections.singletonMap;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Sort;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -47,30 +46,33 @@
 @Service
 public class PassingRatePerLaunchContentLoader implements LoadContentStrategy {
 
-	@Autowired
-	private LaunchRepository launchRepository;
+  @Autowired
+  private LaunchRepository launchRepository;
 
-	@Autowired
-	private WidgetContentRepository widgetContentRepository;
+  @Autowired
+  private WidgetContentRepository widgetContentRepository;
 
-	@Override
-	public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions,
-			int limit) {
+  @Override
+  public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions,
+      int limit) {
 
-		String launchName = WidgetOptionUtil.getValueByKey(LAUNCH_NAME_FIELD, widgetOptions);
-		Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
+    String launchName = WidgetOptionUtil.getValueByKey(LAUNCH_NAME_FIELD, widgetOptions);
+    Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
 
-		return launchRepository.findLatestByFilter(filter.withCondition(new FilterCondition(Condition.EQUALS,
-				false,
-				launchName,
-				CRITERIA_NAME
-		))).map(this::loadContent).orElseGet(Collections::emptyMap);
+    return launchRepository.findLatestByFilter(
+        filter.withCondition(new FilterCondition(Condition.EQUALS,
+            false,
+            launchName,
+            CRITERIA_NAME
+        ))).map(this::loadContent).orElseGet(Collections::emptyMap);
 
-	}
+  }
 
-	private Map<String, ?> loadContent(Launch launch) {
-		PassingRateStatisticsResult result = widgetContentRepository.passingRatePerLaunchStatistics(launch.getId());
-		return result.getTotal() != 0 ? singletonMap(RESULT, result) : emptyMap();
-	}
+  private Map<String, ?> loadContent(Launch launch) {
+    PassingRateStatisticsResult result = widgetContentRepository.passingRatePerLaunchStatistics(
+        launch.getId());
+    return result.getTotal() != 0 ? singletonMap(RESULT, result) : emptyMap();
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/PassingRateSummaryContentLoader.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/PassingRateSummaryContentLoader.java
index c26a3e510e..a23f0c2bc6 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/PassingRateSummaryContentLoader.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/PassingRateSummaryContentLoader.java
@@ -16,42 +16,43 @@
 
 package com.epam.ta.reportportal.core.widget.content.loader;
 
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_SORTS;
+import static java.util.Collections.emptyMap;
+import static java.util.Collections.singletonMap;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.core.widget.content.LoadContentStrategy;
 import com.epam.ta.reportportal.dao.WidgetContentRepository;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.entity.widget.content.PassingRateStatisticsResult;
+import java.util.List;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_SORTS;
-import static java.util.Collections.emptyMap;
-import static java.util.Collections.singletonMap;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class PassingRateSummaryContentLoader implements LoadContentStrategy {
 
-	@Autowired
-	private WidgetContentRepository widgetContentRepository;
+  @Autowired
+  private WidgetContentRepository widgetContentRepository;
 
-	@Override
-	public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions,
-			int limit) {
+  @Override
+  public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions,
+      int limit) {
 
-		Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
-		Sort sort = GROUP_SORTS.apply(filterSortMapping.values());
+    Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
+    Sort sort = GROUP_SORTS.apply(filterSortMapping.values());
 
-		PassingRateStatisticsResult result = widgetContentRepository.summaryPassingRateStatistics(filter, sort, limit);
-		return result.getTotal() != 0 ? singletonMap(RESULT, result) : emptyMap();
-	}
+    PassingRateStatisticsResult result = widgetContentRepository.summaryPassingRateStatistics(
+        filter, sort, limit);
+    return result.getTotal() != 0 ? singletonMap(RESULT, result) : emptyMap();
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/ProductStatusContentLoader.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/ProductStatusContentLoader.java
index 5c55a6446b..39ee85a339 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/ProductStatusContentLoader.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/ProductStatusContentLoader.java
@@ -22,4 +22,5 @@
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public interface ProductStatusContentLoader extends LoadContentStrategy {
+
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/ProductStatusFilterGroupedContentLoader.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/ProductStatusFilterGroupedContentLoader.java
index 43dc545c1f..fc2be5abbd 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/ProductStatusFilterGroupedContentLoader.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/ProductStatusFilterGroupedContentLoader.java
@@ -16,47 +16,51 @@
 
 package com.epam.ta.reportportal.core.widget.content.loader;
 
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.CUSTOM_COLUMNS;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LATEST_OPTION;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
+import static java.util.Collections.emptyMap;
+import static java.util.Collections.singletonMap;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.core.widget.util.WidgetOptionUtil;
 import com.epam.ta.reportportal.dao.WidgetContentRepository;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.entity.widget.content.ProductStatusStatisticsContent;
+import java.util.List;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.*;
-import static java.util.Collections.emptyMap;
-import static java.util.Collections.singletonMap;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class ProductStatusFilterGroupedContentLoader implements ProductStatusContentLoader {
 
-	@Autowired
-	private WidgetContentRepository widgetContentRepository;
+  @Autowired
+  private WidgetContentRepository widgetContentRepository;
 
-	@Override
-	public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions,
-			int limit) {
+  @Override
+  public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions,
+      int limit) {
 
-		Map<String, String> attributeColumns = WidgetOptionUtil.getMapByKey(CUSTOM_COLUMNS, widgetOptions);
+    Map<String, String> attributeColumns = WidgetOptionUtil.getMapByKey(CUSTOM_COLUMNS,
+        widgetOptions);
 
-		boolean latestMode = WidgetOptionUtil.getBooleanByKey(LATEST_OPTION, widgetOptions);
+    boolean latestMode = WidgetOptionUtil.getBooleanByKey(LATEST_OPTION, widgetOptions);
 
-		final Map<String, List<ProductStatusStatisticsContent>> content = widgetContentRepository.productStatusGroupedByFilterStatistics(filterSortMapping,
-				contentFields,
-				attributeColumns,
-				latestMode,
-				limit
-		);
+    final Map<String, List<ProductStatusStatisticsContent>> content = widgetContentRepository.productStatusGroupedByFilterStatistics(
+        filterSortMapping,
+        contentFields,
+        attributeColumns,
+        latestMode,
+        limit
+    );
 
-		return content.isEmpty() ? emptyMap() : singletonMap(RESULT, content);
-	}
+    return content.isEmpty() ? emptyMap() : singletonMap(RESULT, content);
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/ProductStatusLaunchGroupedContentLoader.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/ProductStatusLaunchGroupedContentLoader.java
index dedfbc031b..7778419b26 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/ProductStatusLaunchGroupedContentLoader.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/ProductStatusLaunchGroupedContentLoader.java
@@ -16,53 +16,57 @@
 
 package com.epam.ta.reportportal.core.widget.content.loader;
 
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.CUSTOM_COLUMNS;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LATEST_OPTION;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_SORTS;
+import static java.util.Collections.emptyMap;
+import static java.util.Collections.singletonMap;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.core.widget.util.WidgetOptionUtil;
 import com.epam.ta.reportportal.dao.WidgetContentRepository;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.entity.widget.content.ProductStatusStatisticsContent;
+import java.util.List;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.*;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_SORTS;
-import static java.util.Collections.emptyMap;
-import static java.util.Collections.singletonMap;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class ProductStatusLaunchGroupedContentLoader implements ProductStatusContentLoader {
 
-	@Autowired
-	private WidgetContentRepository widgetContentRepository;
+  @Autowired
+  private WidgetContentRepository widgetContentRepository;
 
-	@Override
-	public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions,
-			int limit) {
+  @Override
+  public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions,
+      int limit) {
 
-		Map<String, String> attributeColumns = WidgetOptionUtil.getMapByKey(CUSTOM_COLUMNS, widgetOptions);
+    Map<String, String> attributeColumns = WidgetOptionUtil.getMapByKey(CUSTOM_COLUMNS,
+        widgetOptions);
 
-		Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
-		Sort sort = GROUP_SORTS.apply(filterSortMapping.values());
+    Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
+    Sort sort = GROUP_SORTS.apply(filterSortMapping.values());
 
-		boolean latestMode = WidgetOptionUtil.getBooleanByKey(LATEST_OPTION, widgetOptions);
+    boolean latestMode = WidgetOptionUtil.getBooleanByKey(LATEST_OPTION, widgetOptions);
 
-		final List<ProductStatusStatisticsContent> content = widgetContentRepository.productStatusGroupedByLaunchesStatistics(filter,
-				contentFields,
-				attributeColumns,
-				sort,
-				latestMode,
-				limit
-		);
+    final List<ProductStatusStatisticsContent> content = widgetContentRepository.productStatusGroupedByLaunchesStatistics(
+        filter,
+        contentFields,
+        attributeColumns,
+        sort,
+        latestMode,
+        limit
+    );
 
-		return content.isEmpty() ? emptyMap() : singletonMap(RESULT, content);
-	}
+    return content.isEmpty() ? emptyMap() : singletonMap(RESULT, content);
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/TopPatternContentLoader.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/TopPatternContentLoader.java
index 0ddacd1536..6a14deaa57 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/TopPatternContentLoader.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/TopPatternContentLoader.java
@@ -16,57 +16,61 @@
 
 package com.epam.ta.reportportal.core.widget.content.loader;
 
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.ATTRIBUTE_KEY;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LATEST_OPTION;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.PATTERN_TEMPLATE_NAME;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_SORTS;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.core.widget.content.MultilevelLoadContentStrategy;
 import com.epam.ta.reportportal.core.widget.util.WidgetOptionUtil;
 import com.epam.ta.reportportal.dao.WidgetContentRepository;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.entity.widget.content.TopPatternTemplatesContent;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 import org.springframework.util.MultiValueMap;
 
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.*;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_SORTS;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class TopPatternContentLoader implements MultilevelLoadContentStrategy {
 
-	public static final Integer TOP_PATTERN_TEMPLATES_ATTRIBUTES_COUNT = 15;
+  public static final Integer TOP_PATTERN_TEMPLATES_ATTRIBUTES_COUNT = 15;
 
-	@Autowired
-	private WidgetContentRepository widgetContentRepository;
+  @Autowired
+  private WidgetContentRepository widgetContentRepository;
 
-	@Override
-	public Map<String, Object> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions,
-			String[] attributes, MultiValueMap<String, String> params, int limit) {
-		final List<TopPatternTemplatesContent> content = getContent(filterSortMapping, widgetOptions, params, limit);
-		return content.isEmpty() ? Collections.emptyMap() : Collections.singletonMap(RESULT, content);
-	}
+  @Override
+  public Map<String, Object> loadContent(List<String> contentFields,
+      Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions,
+      String[] attributes, MultiValueMap<String, String> params, int limit) {
+    final List<TopPatternTemplatesContent> content = getContent(filterSortMapping, widgetOptions,
+        params, limit);
+    return content.isEmpty() ? Collections.emptyMap() : Collections.singletonMap(RESULT, content);
+  }
 
-	private List<TopPatternTemplatesContent> getContent(Map<Filter, Sort> filterSortMapping,
-			WidgetOptions widgetOptions, MultiValueMap<String, String> params, int limit) {
-		Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
-		Sort sort = GROUP_SORTS.apply(filterSortMapping.values());
+  private List<TopPatternTemplatesContent> getContent(Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions, MultiValueMap<String, String> params, int limit) {
+    Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
+    Sort sort = GROUP_SORTS.apply(filterSortMapping.values());
 
-		List<TopPatternTemplatesContent> content = widgetContentRepository.patternTemplate(filter,
-				sort,
-				WidgetOptionUtil.getValueByKey(ATTRIBUTE_KEY, widgetOptions),
-				params.getFirst(PATTERN_TEMPLATE_NAME),
-				WidgetOptionUtil.getBooleanByKey(LATEST_OPTION, widgetOptions), limit,
-				TOP_PATTERN_TEMPLATES_ATTRIBUTES_COUNT
-		);
-		Collections.reverse(content);
-		return content;
-	}
+    List<TopPatternTemplatesContent> content = widgetContentRepository.patternTemplate(filter,
+        sort,
+        WidgetOptionUtil.getValueByKey(ATTRIBUTE_KEY, widgetOptions),
+        params.getFirst(PATTERN_TEMPLATE_NAME),
+        WidgetOptionUtil.getBooleanByKey(LATEST_OPTION, widgetOptions), limit,
+        TOP_PATTERN_TEMPLATES_ATTRIBUTES_COUNT
+    );
+    Collections.reverse(content);
+    return content;
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/TopTestCasesContentLoader.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/TopTestCasesContentLoader.java
index 19fb7baead..5c96974860 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/TopTestCasesContentLoader.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/TopTestCasesContentLoader.java
@@ -16,6 +16,14 @@
 
 package com.epam.ta.reportportal.core.widget.content.loader;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_NAME;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.INCLUDE_METHODS;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LATEST_LAUNCH;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LAUNCH_NAME_FIELD;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.querygen.Condition;
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.querygen.FilterCondition;
@@ -26,21 +34,15 @@
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.ws.converter.converters.LaunchConverter;
 import com.google.common.collect.ImmutableMap;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
 import org.apache.commons.lang3.BooleanUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_NAME;
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.*;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
-import static java.util.Optional.ofNullable;
-
 /**
  * Content loader for {@link com.epam.ta.reportportal.entity.widget.WidgetType#TOP_TEST_CASES}
  *
@@ -49,45 +51,48 @@
 @Service
 public class TopTestCasesContentLoader implements LoadContentStrategy {
 
-	private final LaunchRepository launchRepository;
+  private final LaunchRepository launchRepository;
 
-	private final LaunchConverter launchConverter;
+  private final LaunchConverter launchConverter;
 
-	private final WidgetContentRepository widgetContentRepository;
+  private final WidgetContentRepository widgetContentRepository;
 
-	@Autowired
-	public TopTestCasesContentLoader(LaunchRepository launchRepository, LaunchConverter launchConverter,
-			WidgetContentRepository widgetContentRepository) {
-		this.launchRepository = launchRepository;
-		this.launchConverter = launchConverter;
-		this.widgetContentRepository = widgetContentRepository;
-	}
+  @Autowired
+  public TopTestCasesContentLoader(LaunchRepository launchRepository,
+      LaunchConverter launchConverter,
+      WidgetContentRepository widgetContentRepository) {
+    this.launchRepository = launchRepository;
+    this.launchConverter = launchConverter;
+    this.widgetContentRepository = widgetContentRepository;
+  }
 
-	@Override
-	public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions,
-			int limit) {
-		String criteria = contentFields.get(0);
-		Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet())
-				.withCondition(new FilterCondition(Condition.EQUALS,
-						false,
-						WidgetOptionUtil.getValueByKey(LAUNCH_NAME_FIELD, widgetOptions),
-						CRITERIA_NAME
-				));
+  @Override
+  public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions,
+      int limit) {
+    String criteria = contentFields.get(0);
+    Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet())
+        .withCondition(new FilterCondition(Condition.EQUALS,
+            false,
+            WidgetOptionUtil.getValueByKey(LAUNCH_NAME_FIELD, widgetOptions),
+            CRITERIA_NAME
+        ));
 
-		return launchRepository.findLatestByFilter(filter)
-				.map(it -> Pair.of(it,
-						widgetContentRepository.topItemsByCriteria(filter,
-								criteria,
-								limit,
-								ofNullable(widgetOptions.getOptions()
-										.get(INCLUDE_METHODS)).map(v -> BooleanUtils.toBoolean(String.valueOf(v))).orElse(false)
-						)
-				))
-				.filter(it -> !it.getRight().isEmpty())
-				.map(it -> (Map<String, ?>) ImmutableMap.<String, Object>builder().put(LATEST_LAUNCH,
-						launchConverter.TO_RESOURCE.apply(it.getLeft())
-				).put(RESULT, it.getRight()).build())
-				.orElse(Collections.emptyMap());
-	}
+    return launchRepository.findLatestByFilter(filter)
+        .map(it -> Pair.of(it,
+            widgetContentRepository.topItemsByCriteria(filter,
+                criteria,
+                limit,
+                ofNullable(widgetOptions.getOptions()
+                    .get(INCLUDE_METHODS)).map(v -> BooleanUtils.toBoolean(String.valueOf(v)))
+                    .orElse(false)
+            )
+        ))
+        .filter(it -> !it.getRight().isEmpty())
+        .map(it -> (Map<String, ?>) ImmutableMap.<String, Object>builder().put(LATEST_LAUNCH,
+            launchConverter.TO_RESOURCE.apply(it.getLeft())
+        ).put(RESULT, it.getRight()).build())
+        .orElse(Collections.emptyMap());
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/UniqueBugContentLoader.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/UniqueBugContentLoader.java
index d5f54c93cc..43ea8b56c6 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/UniqueBugContentLoader.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/UniqueBugContentLoader.java
@@ -16,47 +16,48 @@
 
 package com.epam.ta.reportportal.core.widget.content.loader;
 
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LATEST_OPTION;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
+import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_SORTS;
+import static java.util.Collections.emptyMap;
+import static java.util.Collections.singletonMap;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.core.widget.content.LoadContentStrategy;
 import com.epam.ta.reportportal.core.widget.util.WidgetOptionUtil;
 import com.epam.ta.reportportal.dao.WidgetContentRepository;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.entity.widget.content.UniqueBugContent;
+import java.util.List;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LATEST_OPTION;
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_FILTERS;
-import static com.epam.ta.reportportal.core.widget.util.WidgetFilterUtil.GROUP_SORTS;
-import static java.util.Collections.emptyMap;
-import static java.util.Collections.singletonMap;
-
 /**
  * @author Pavel Bortnik
  */
 @Service
 public class UniqueBugContentLoader implements LoadContentStrategy {
 
-	@Autowired
-	private WidgetContentRepository widgetRepository;
+  @Autowired
+  private WidgetContentRepository widgetRepository;
 
-	@Override
-	public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions,
-			int limit) {
+  @Override
+  public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions,
+      int limit) {
 
-		Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
-		Sort sort = GROUP_SORTS.apply(filterSortMapping.values());
+    Filter filter = GROUP_FILTERS.apply(filterSortMapping.keySet());
+    Sort sort = GROUP_SORTS.apply(filterSortMapping.values());
 
-		boolean latestMode = WidgetOptionUtil.getBooleanByKey(LATEST_OPTION, widgetOptions);
+    boolean latestMode = WidgetOptionUtil.getBooleanByKey(LATEST_OPTION, widgetOptions);
 
-		Map<String, UniqueBugContent> content = widgetRepository.uniqueBugStatistics(filter, sort, latestMode, limit);
+    Map<String, UniqueBugContent> content = widgetRepository.uniqueBugStatistics(filter, sort,
+        latestMode, limit);
 
-		return content.isEmpty() ? emptyMap() : singletonMap(RESULT, content);
-	}
+    return content.isEmpty() ? emptyMap() : singletonMap(RESULT, content);
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/CumulativeTrendChartContentLoaderImpl.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/CumulativeTrendChartContentLoaderImpl.java
index be71ac9583..5e29129ce2 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/CumulativeTrendChartContentLoaderImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/CumulativeTrendChartContentLoaderImpl.java
@@ -16,29 +16,28 @@
 
 package com.epam.ta.reportportal.core.widget.content.loader.materialized;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.ItemAttributeConstant.KEY_VALUE_SEPARATOR;
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.ATTRIBUTES;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
+import static com.epam.ta.reportportal.core.widget.content.loader.materialized.handler.MaterializedWidgetStateHandler.VIEW_NAME;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.core.widget.util.WidgetOptionUtil;
 import com.epam.ta.reportportal.dao.WidgetContentRepository;
 import com.epam.ta.reportportal.entity.widget.Widget;
 import com.epam.ta.reportportal.entity.widget.content.CumulativeTrendChartEntry;
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.google.common.collect.ImmutableMap;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.util.MultiValueMap;
-
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.commons.querygen.constant.ItemAttributeConstant.KEY_VALUE_SEPARATOR;
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.ATTRIBUTES;
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
-import static com.epam.ta.reportportal.core.widget.content.loader.materialized.handler.MaterializedWidgetStateHandler.VIEW_NAME;
-import static java.util.Optional.ofNullable;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.MultiValueMap;
 
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
@@ -46,40 +45,44 @@
 @Service
 public class CumulativeTrendChartContentLoaderImpl implements MaterializedWidgetContentLoader {
 
-	@Autowired
-	private WidgetContentRepository widgetContentRepository;
+  @Autowired
+  private WidgetContentRepository widgetContentRepository;
 
-	@Override
-	public Map<String, Object> loadContent(Widget widget, MultiValueMap<String, String> params) {
-		List<CumulativeTrendChartEntry> content;
-		List<String> storedAttributes = WidgetOptionUtil.getListByKey(ATTRIBUTES, widget.getWidgetOptions());
-		List<String> providedAttributes = ofNullable(params.get(ATTRIBUTES)).map(attributes -> attributes.stream()
-				.filter(StringUtils::isNotBlank)
-				.collect(Collectors.toList())).orElseGet(Collections::emptyList);
-		if (providedAttributes.isEmpty()) {
-			content = widgetContentRepository.cumulativeTrendChart(
-					(String) widget.getWidgetOptions().getOptions().get(VIEW_NAME),
-					storedAttributes.get(0),
-					storedAttributes.size() > 1 ? storedAttributes.get(1) : null,
-					null
-			);
-		} else {
-			verifyProvidedAttributes(storedAttributes, providedAttributes);
-			content = widgetContentRepository.cumulativeTrendChart(
-					(String) widget.getWidgetOptions().getOptions().get(VIEW_NAME),
-					storedAttributes.get(1),
-					null,
-					providedAttributes.get(0)
-			);
-		}
+  @Override
+  public Map<String, Object> loadContent(Widget widget, MultiValueMap<String, String> params) {
+    List<CumulativeTrendChartEntry> content;
+    List<String> storedAttributes = WidgetOptionUtil.getListByKey(ATTRIBUTES,
+        widget.getWidgetOptions());
+    List<String> providedAttributes = ofNullable(params.get(ATTRIBUTES)).map(
+        attributes -> attributes.stream()
+            .filter(StringUtils::isNotBlank)
+            .collect(Collectors.toList())).orElseGet(Collections::emptyList);
+    if (providedAttributes.isEmpty()) {
+      content = widgetContentRepository.cumulativeTrendChart(
+          (String) widget.getWidgetOptions().getOptions().get(VIEW_NAME),
+          storedAttributes.get(0),
+          storedAttributes.size() > 1 ? storedAttributes.get(1) : null,
+          null
+      );
+    } else {
+      verifyProvidedAttributes(storedAttributes, providedAttributes);
+      content = widgetContentRepository.cumulativeTrendChart(
+          (String) widget.getWidgetOptions().getOptions().get(VIEW_NAME),
+          storedAttributes.get(1),
+          null,
+          providedAttributes.get(0)
+      );
+    }
 
-		return ImmutableMap.<String, Object>builder().put(RESULT, content).build();
-	}
+    return ImmutableMap.<String, Object>builder().put(RESULT, content).build();
+  }
 
-	private void verifyProvidedAttributes(List<String> storedKeys, List<String> providedAttributes) {
-		String[] split = providedAttributes.get(0).split(KEY_VALUE_SEPARATOR);
-		expect(split.length, Predicate.isEqual(2)).verify(ErrorType.BAD_REQUEST_ERROR, ATTRIBUTES);
-		expect(storedKeys.contains(split[0]), Predicate.isEqual(true)).verify(ErrorType.BAD_REQUEST_ERROR, ATTRIBUTES);
-		expect(StringUtils.isNoneEmpty(split[1]), Predicate.isEqual(true)).verify(ErrorType.BAD_REQUEST_ERROR, ATTRIBUTES);
-	}
+  private void verifyProvidedAttributes(List<String> storedKeys, List<String> providedAttributes) {
+    String[] split = providedAttributes.get(0).split(KEY_VALUE_SEPARATOR);
+    expect(split.length, Predicate.isEqual(2)).verify(ErrorType.BAD_REQUEST_ERROR, ATTRIBUTES);
+    expect(storedKeys.contains(split[0]), Predicate.isEqual(true)).verify(
+        ErrorType.BAD_REQUEST_ERROR, ATTRIBUTES);
+    expect(StringUtils.isNoneEmpty(split[1]), Predicate.isEqual(true)).verify(
+        ErrorType.BAD_REQUEST_ERROR, ATTRIBUTES);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/HealthCheckTableReadyContentLoader.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/HealthCheckTableReadyContentLoader.java
index d824c61e25..8e68f5a94d 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/HealthCheckTableReadyContentLoader.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/HealthCheckTableReadyContentLoader.java
@@ -1,5 +1,15 @@
 package com.epam.ta.reportportal.core.widget.content.loader.materialized;
 
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.ATTRIBUTES;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.ATTRIBUTE_KEYS;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.RESULT;
+import static com.epam.ta.reportportal.core.widget.content.loader.materialized.handler.MaterializedWidgetStateHandler.VIEW_NAME;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.EXECUTIONS_PASSED;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.EXECUTIONS_TOTAL;
+import static java.util.Collections.emptyMap;
+import static java.util.Optional.ofNullable;
+import static java.util.stream.Collectors.groupingBy;
+
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.core.widget.util.WidgetOptionUtil;
 import com.epam.ta.reportportal.dao.WidgetContentRepository;
@@ -14,13 +24,6 @@
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.collect.ImmutableMap;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.domain.Sort;
-import org.springframework.stereotype.Service;
-import org.springframework.util.MultiValueMap;
-
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.util.Collection;
@@ -29,14 +32,12 @@
 import java.util.Map;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
-
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.*;
-import static com.epam.ta.reportportal.core.widget.content.loader.materialized.handler.MaterializedWidgetStateHandler.VIEW_NAME;
-import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.EXECUTIONS_PASSED;
-import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.EXECUTIONS_TOTAL;
-import static java.util.Collections.emptyMap;
-import static java.util.Optional.ofNullable;
-import static java.util.stream.Collectors.groupingBy;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Sort;
+import org.springframework.stereotype.Service;
+import org.springframework.util.MultiValueMap;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -44,94 +45,108 @@
 @Service(value = "healthCheckTableReadyContentLoader")
 public class HealthCheckTableReadyContentLoader implements MaterializedWidgetContentLoader {
 
-	public static final String SORT = "sort";
-	public static final String CUSTOM_COLUMN = "customColumn";
-
-	public static final String TOTAL = "total";
-	public static final String STATISTICS = "statistics";
-	public static final String PASSING_RATE = "passingRate";
-
-	private final WidgetContentRepository widgetContentRepository;
-	private final ObjectMapper objectMapper;
-
-	@Autowired
-	public HealthCheckTableReadyContentLoader(WidgetContentRepository widgetContentRepository, ObjectMapper objectMapper) {
-		this.widgetContentRepository = widgetContentRepository;
-		this.objectMapper = objectMapper;
-	}
-
-	@Override
-	public Map<String, Object> loadContent(Widget widget, MultiValueMap<String, String> params) {
-		HealthCheckTableGetParams getParams = getParams(widget.getWidgetOptions(),
-				ofNullable(params.get(ATTRIBUTES)).map(attributes -> attributes.stream()
-						.filter(StringUtils::isNotBlank)
-						.collect(Collectors.toList())).orElseGet(Collections::emptyList)
-		);
-		List<HealthCheckTableContent> content = widgetContentRepository.componentHealthCheckTable(getParams);
-
-		if (CollectionUtils.isEmpty(content)) {
-			return emptyMap();
-		}
-
-		Map<String, Integer> totalStatistics = content.stream()
-				.map(HealthCheckTableContent::getStatistics)
-				.map(Map::entrySet)
-				.flatMap(Collection::stream)
-				.collect(groupingBy(Map.Entry::getKey, Collectors.summingInt(Map.Entry::getValue)));
-
-		return ImmutableMap.<String, Object>builder().put(RESULT, content)
-				.put(TOTAL,
-						ImmutableMap.<String, Object>builder().put(STATISTICS, totalStatistics)
-								.put(PASSING_RATE, calculatePassingRate(totalStatistics))
-								.build()
-				)
-				.build();
-	}
-
-	private HealthCheckTableGetParams getParams(WidgetOptions widgetOptions, List<String> attributeValues) {
-		List<String> attributeKeys = WidgetOptionUtil.getListByKey(ATTRIBUTE_KEYS, widgetOptions);
-		int currentLevel = attributeValues.size();
-		BusinessRule.expect(attributeKeys, keys -> keys.size() > currentLevel)
-				.verify(ErrorType.UNABLE_LOAD_WIDGET_CONTENT, "Incorrect level definition");
-
-		String viewName = ofNullable(WidgetOptionUtil.getValueByKey(VIEW_NAME, widgetOptions)).orElseThrow(() -> new ReportPortalException(
-				ErrorType.UNABLE_LOAD_WIDGET_CONTENT,
-				"Widget view name not provided"
-		));
-		String currentLevelKey = attributeKeys.get(currentLevel);
-		boolean includeCustomColumn = ofNullable(WidgetOptionUtil.getValueByKey(CUSTOM_COLUMN, widgetOptions)).isPresent();
-
-		return HealthCheckTableGetParams.of(viewName,
-				currentLevelKey,
-				resolveSort(widgetOptions),
-				includeCustomColumn,
-				getLevelEntries(attributeKeys, attributeValues)
-		);
-
-	}
-
-	private Sort resolveSort(WidgetOptions widgetOptions) {
-		return ofNullable(widgetOptions).flatMap(wo -> ofNullable(wo.getOptions()).map(options -> options.get(SORT))).map(s -> {
-			try {
-				SortEntry sortEntry = objectMapper.readValue(objectMapper.writeValueAsString(s), SortEntry.class);
-				return Sort.by(sortEntry.isAsc() ? Sort.Direction.ASC : Sort.Direction.DESC, sortEntry.getSortingColumn());
-			} catch (JsonProcessingException e) {
-				throw new ReportPortalException(ErrorType.UNABLE_LOAD_WIDGET_CONTENT, "Sort format error: " + e.getMessage());
-			}
-		}).orElseThrow(() -> new ReportPortalException(ErrorType.UNABLE_LOAD_WIDGET_CONTENT, "Sort parameter not provided"));
-	}
-
-	private List<LevelEntry> getLevelEntries(List<String> attributeKeys, List<String> attributeValues) {
-		return IntStream.range(0, attributeValues.size()).mapToObj(index -> {
-			String attributeKey = attributeKeys.get(index);
-			String attributeValue = attributeValues.get(index);
-			return LevelEntry.of(attributeKey, attributeValue);
-		}).collect(Collectors.toList());
-	}
-
-	private double calculatePassingRate(Map<String, Integer> totalStatistics) {
-		double passingRate = 100.0 * totalStatistics.getOrDefault(EXECUTIONS_PASSED, 0) / totalStatistics.getOrDefault(EXECUTIONS_TOTAL, 1);
-		return new BigDecimal(passingRate).setScale(2, RoundingMode.HALF_UP).doubleValue();
-	}
+  public static final String SORT = "sort";
+  public static final String CUSTOM_COLUMN = "customColumn";
+
+  public static final String TOTAL = "total";
+  public static final String STATISTICS = "statistics";
+  public static final String PASSING_RATE = "passingRate";
+
+  private final WidgetContentRepository widgetContentRepository;
+  private final ObjectMapper objectMapper;
+
+  @Autowired
+  public HealthCheckTableReadyContentLoader(WidgetContentRepository widgetContentRepository,
+      ObjectMapper objectMapper) {
+    this.widgetContentRepository = widgetContentRepository;
+    this.objectMapper = objectMapper;
+  }
+
+  @Override
+  public Map<String, Object> loadContent(Widget widget, MultiValueMap<String, String> params) {
+    HealthCheckTableGetParams getParams = getParams(widget.getWidgetOptions(),
+        ofNullable(params.get(ATTRIBUTES)).map(attributes -> attributes.stream()
+            .filter(StringUtils::isNotBlank)
+            .collect(Collectors.toList())).orElseGet(Collections::emptyList)
+    );
+    List<HealthCheckTableContent> content = widgetContentRepository.componentHealthCheckTable(
+        getParams);
+
+    if (CollectionUtils.isEmpty(content)) {
+      return emptyMap();
+    }
+
+    Map<String, Integer> totalStatistics = content.stream()
+        .map(HealthCheckTableContent::getStatistics)
+        .map(Map::entrySet)
+        .flatMap(Collection::stream)
+        .collect(groupingBy(Map.Entry::getKey, Collectors.summingInt(Map.Entry::getValue)));
+
+    return ImmutableMap.<String, Object>builder().put(RESULT, content)
+        .put(TOTAL,
+            ImmutableMap.<String, Object>builder().put(STATISTICS, totalStatistics)
+                .put(PASSING_RATE, calculatePassingRate(totalStatistics))
+                .build()
+        )
+        .build();
+  }
+
+  private HealthCheckTableGetParams getParams(WidgetOptions widgetOptions,
+      List<String> attributeValues) {
+    List<String> attributeKeys = WidgetOptionUtil.getListByKey(ATTRIBUTE_KEYS, widgetOptions);
+    int currentLevel = attributeValues.size();
+    BusinessRule.expect(attributeKeys, keys -> keys.size() > currentLevel)
+        .verify(ErrorType.UNABLE_LOAD_WIDGET_CONTENT, "Incorrect level definition");
+
+    String viewName = ofNullable(
+        WidgetOptionUtil.getValueByKey(VIEW_NAME, widgetOptions)).orElseThrow(
+        () -> new ReportPortalException(
+            ErrorType.UNABLE_LOAD_WIDGET_CONTENT,
+            "Widget view name not provided"
+        ));
+    String currentLevelKey = attributeKeys.get(currentLevel);
+    boolean includeCustomColumn = ofNullable(
+        WidgetOptionUtil.getValueByKey(CUSTOM_COLUMN, widgetOptions)).isPresent();
+
+    return HealthCheckTableGetParams.of(viewName,
+        currentLevelKey,
+        resolveSort(widgetOptions),
+        includeCustomColumn,
+        getLevelEntries(attributeKeys, attributeValues)
+    );
+
+  }
+
+  private Sort resolveSort(WidgetOptions widgetOptions) {
+    return ofNullable(widgetOptions).flatMap(
+        wo -> ofNullable(wo.getOptions()).map(options -> options.get(SORT))).map(s -> {
+      try {
+        SortEntry sortEntry = objectMapper.readValue(objectMapper.writeValueAsString(s),
+            SortEntry.class);
+        return Sort.by(sortEntry.isAsc() ? Sort.Direction.ASC : Sort.Direction.DESC,
+            sortEntry.getSortingColumn());
+      } catch (JsonProcessingException e) {
+        throw new ReportPortalException(ErrorType.UNABLE_LOAD_WIDGET_CONTENT,
+            "Sort format error: " + e.getMessage());
+      }
+    }).orElseThrow(() -> new ReportPortalException(ErrorType.UNABLE_LOAD_WIDGET_CONTENT,
+        "Sort parameter not provided"));
+  }
+
+  private List<LevelEntry> getLevelEntries(List<String> attributeKeys,
+      List<String> attributeValues) {
+    return IntStream.range(0, attributeValues.size()).mapToObj(index -> {
+      String attributeKey = attributeKeys.get(index);
+      String attributeValue = attributeValues.get(index);
+      return LevelEntry.of(attributeKey, attributeValue);
+    }).collect(Collectors.toList());
+  }
+
+  private double calculatePassingRate(Map<String, Integer> totalStatistics) {
+    double passingRate =
+        100.0 * totalStatistics.getOrDefault(EXECUTIONS_PASSED, 0) / totalStatistics.getOrDefault(
+            EXECUTIONS_TOTAL, 1);
+    return new BigDecimal(passingRate).setScale(2, RoundingMode.HALF_UP).doubleValue();
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/MaterializedWidgetContentLoader.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/MaterializedWidgetContentLoader.java
index f5b3c5fd9b..7e72360a15 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/MaterializedWidgetContentLoader.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/MaterializedWidgetContentLoader.java
@@ -1,14 +1,13 @@
 package com.epam.ta.reportportal.core.widget.content.loader.materialized;
 
 import com.epam.ta.reportportal.entity.widget.Widget;
-import org.springframework.util.MultiValueMap;
-
 import java.util.Map;
+import org.springframework.util.MultiValueMap;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public interface MaterializedWidgetContentLoader {
 
-	Map<String, Object> loadContent(Widget widget, MultiValueMap<String, String> params);
+  Map<String, Object> loadContent(Widget widget, MultiValueMap<String, String> params);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/generator/AbstractViewGenerator.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/generator/AbstractViewGenerator.java
index d11638f56a..6993b9f8c3 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/generator/AbstractViewGenerator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/generator/AbstractViewGenerator.java
@@ -16,58 +16,59 @@
 
 package com.epam.ta.reportportal.core.widget.content.loader.materialized.generator;
 
+import static com.epam.ta.reportportal.core.widget.content.loader.materialized.handler.MaterializedWidgetStateHandler.VIEW_NAME;
+import static com.epam.ta.reportportal.core.widget.content.updater.MaterializedWidgetStateUpdater.STATE;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.core.widget.util.WidgetOptionUtil;
 import com.epam.ta.reportportal.dao.WidgetRepository;
 import com.epam.ta.reportportal.entity.widget.Widget;
 import com.epam.ta.reportportal.entity.widget.WidgetState;
 import com.epam.ta.reportportal.ws.converter.builders.WidgetBuilder;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.util.Date;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.data.domain.Sort;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.MultiValueMap;
 
-import java.time.LocalDateTime;
-import java.time.ZoneOffset;
-import java.util.Date;
-
-import static com.epam.ta.reportportal.core.widget.content.loader.materialized.handler.MaterializedWidgetStateHandler.VIEW_NAME;
-import static com.epam.ta.reportportal.core.widget.content.updater.MaterializedWidgetStateUpdater.STATE;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public abstract class AbstractViewGenerator implements ViewGenerator {
 
-	public static final Logger LOGGER = LoggerFactory.getLogger(AbstractViewGenerator.class);
+  public static final Logger LOGGER = LoggerFactory.getLogger(AbstractViewGenerator.class);
 
-	private static final String LAST_REFRESH = "lastRefresh";
+  private static final String LAST_REFRESH = "lastRefresh";
 
-	private final WidgetRepository widgetRepository;
+  private final WidgetRepository widgetRepository;
 
-	public AbstractViewGenerator(WidgetRepository widgetRepository) {
-		this.widgetRepository = widgetRepository;
-	}
+  public AbstractViewGenerator(WidgetRepository widgetRepository) {
+    this.widgetRepository = widgetRepository;
+  }
 
-	protected abstract void generateView(boolean refresh, String viewName, Widget widget, Filter launchesFilter, Sort launchesSort,
-			MultiValueMap<String, String> params);
+  protected abstract void generateView(boolean refresh, String viewName, Widget widget,
+      Filter launchesFilter, Sort launchesSort,
+      MultiValueMap<String, String> params);
 
-	@Transactional
-	public void generate(boolean refresh, String viewName, Widget widget, Filter launchesFilter, Sort launchesSort,
-			MultiValueMap<String, String> params) {
-		LOGGER.debug("Widget {} - {}. Generation started", widget.getWidgetType(), widget.getId());
-		generateView(refresh, viewName, widget, launchesFilter, launchesSort, params);
-		LOGGER.debug("Widget {} - {}. Generation finished", widget.getWidgetType(), widget.getId());
-		widgetRepository.save(new WidgetBuilder(widget).addOption(STATE, WidgetState.READY.getValue())
-				.addOption(VIEW_NAME, viewName)
-				.addOption(LAST_REFRESH, Date.from(LocalDateTime.now().atZone(ZoneOffset.UTC).toInstant()))
-				.get());
-		LOGGER.debug("Widget {} - {}. State updated to: {}",
-				widget.getWidgetType(),
-				widget.getId(),
-				WidgetOptionUtil.getValueByKey(STATE, widget.getWidgetOptions())
-		);
-	}
+  @Transactional
+  public void generate(boolean refresh, String viewName, Widget widget, Filter launchesFilter,
+      Sort launchesSort,
+      MultiValueMap<String, String> params) {
+    LOGGER.debug("Widget {} - {}. Generation started", widget.getWidgetType(), widget.getId());
+    generateView(refresh, viewName, widget, launchesFilter, launchesSort, params);
+    LOGGER.debug("Widget {} - {}. Generation finished", widget.getWidgetType(), widget.getId());
+    widgetRepository.save(new WidgetBuilder(widget).addOption(STATE, WidgetState.READY.getValue())
+        .addOption(VIEW_NAME, viewName)
+        .addOption(LAST_REFRESH, Date.from(LocalDateTime.now().atZone(ZoneOffset.UTC).toInstant()))
+        .get());
+    LOGGER.debug("Widget {} - {}. State updated to: {}",
+        widget.getWidgetType(),
+        widget.getId(),
+        WidgetOptionUtil.getValueByKey(STATE, widget.getWidgetOptions())
+    );
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/generator/CumulativeTrendChartViewGenerator.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/generator/CumulativeTrendChartViewGenerator.java
index fbfcac48bc..1be9646c51 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/generator/CumulativeTrendChartViewGenerator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/generator/CumulativeTrendChartViewGenerator.java
@@ -16,38 +16,40 @@
 
 package com.epam.ta.reportportal.core.widget.content.loader.materialized.generator;
 
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.ATTRIBUTES;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.core.widget.util.WidgetOptionUtil;
 import com.epam.ta.reportportal.dao.WidgetContentRepository;
 import com.epam.ta.reportportal.dao.WidgetRepository;
 import com.epam.ta.reportportal.entity.widget.Widget;
+import java.util.List;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 import org.springframework.util.MultiValueMap;
 
-import java.util.List;
-
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.ATTRIBUTES;
-
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
  */
 @Service
 public class CumulativeTrendChartViewGenerator extends AbstractViewGenerator {
 
-	private final WidgetContentRepository widgetContentRepository;
-
-	@Autowired
-	public CumulativeTrendChartViewGenerator(WidgetRepository widgetRepository, WidgetContentRepository widgetContentRepository) {
-		super(widgetRepository);
-		this.widgetContentRepository = widgetContentRepository;
-	}
-
-	@Override
-	protected void generateView(boolean refresh, String viewName, Widget widget, Filter launchesFilter, Sort launchesSort,
-			MultiValueMap<String, String> params) {
-		List<String> attributes = WidgetOptionUtil.getListByKey(ATTRIBUTES, widget.getWidgetOptions());
-		widgetContentRepository.generateCumulativeTrendChartView(refresh, viewName, launchesFilter, launchesSort, attributes, widget.getItemsCount());
-	}
+  private final WidgetContentRepository widgetContentRepository;
+
+  @Autowired
+  public CumulativeTrendChartViewGenerator(WidgetRepository widgetRepository,
+      WidgetContentRepository widgetContentRepository) {
+    super(widgetRepository);
+    this.widgetContentRepository = widgetContentRepository;
+  }
+
+  @Override
+  protected void generateView(boolean refresh, String viewName, Widget widget,
+      Filter launchesFilter, Sort launchesSort,
+      MultiValueMap<String, String> params) {
+    List<String> attributes = WidgetOptionUtil.getListByKey(ATTRIBUTES, widget.getWidgetOptions());
+    widgetContentRepository.generateCumulativeTrendChartView(refresh, viewName, launchesFilter,
+        launchesSort, attributes, widget.getItemsCount());
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/generator/FailedViewStateGenerator.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/generator/FailedViewStateGenerator.java
index 10bbdb4f21..fceca05e7e 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/generator/FailedViewStateGenerator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/generator/FailedViewStateGenerator.java
@@ -16,6 +16,8 @@
 
 package com.epam.ta.reportportal.core.widget.content.loader.materialized.generator;
 
+import static com.epam.ta.reportportal.core.widget.content.updater.MaterializedWidgetStateUpdater.STATE;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.core.widget.util.WidgetOptionUtil;
 import com.epam.ta.reportportal.dao.WidgetRepository;
@@ -27,36 +29,36 @@
 import org.springframework.data.domain.Sort;
 import org.springframework.util.MultiValueMap;
 
-import static com.epam.ta.reportportal.core.widget.content.updater.MaterializedWidgetStateUpdater.STATE;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public class FailedViewStateGenerator implements ViewGenerator {
 
-	public static final Logger LOGGER = LoggerFactory.getLogger(FailedViewStateGenerator.class);
-
-	private final ViewGenerator delegate;
-	private final WidgetRepository widgetRepository;
-
-	public FailedViewStateGenerator(ViewGenerator delegate, WidgetRepository widgetRepository) {
-		this.delegate = delegate;
-		this.widgetRepository = widgetRepository;
-	}
-
-	@Override
-	public void generate(boolean refresh, String viewName, Widget widget, Filter launchesFilter, Sort launchesSort,
-			MultiValueMap<String, String> params) {
-		try {
-			delegate.generate(refresh, viewName, widget, launchesFilter, launchesSort, params);
-		} catch (Exception exc) {
-			LOGGER.error("Error during view creation: " + exc.getMessage());
-			widgetRepository.save(new WidgetBuilder(widget).addOption(STATE, WidgetState.FAILED.getValue()).get());
-			LOGGER.error("Generation failed. Widget {} - {}. State updated to: {}",
-					widget.getWidgetType(),
-					widget.getId(),
-					WidgetOptionUtil.getValueByKey(STATE, widget.getWidgetOptions())
-			);
-		}
-	}
+  public static final Logger LOGGER = LoggerFactory.getLogger(FailedViewStateGenerator.class);
+
+  private final ViewGenerator delegate;
+  private final WidgetRepository widgetRepository;
+
+  public FailedViewStateGenerator(ViewGenerator delegate, WidgetRepository widgetRepository) {
+    this.delegate = delegate;
+    this.widgetRepository = widgetRepository;
+  }
+
+  @Override
+  public void generate(boolean refresh, String viewName, Widget widget, Filter launchesFilter,
+      Sort launchesSort,
+      MultiValueMap<String, String> params) {
+    try {
+      delegate.generate(refresh, viewName, widget, launchesFilter, launchesSort, params);
+    } catch (Exception exc) {
+      LOGGER.error("Error during view creation: " + exc.getMessage());
+      widgetRepository.save(
+          new WidgetBuilder(widget).addOption(STATE, WidgetState.FAILED.getValue()).get());
+      LOGGER.error("Generation failed. Widget {} - {}. State updated to: {}",
+          widget.getWidgetType(),
+          widget.getId(),
+          WidgetOptionUtil.getValueByKey(STATE, widget.getWidgetOptions())
+      );
+    }
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/generator/HealthCheckTableGenerator.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/generator/HealthCheckTableGenerator.java
index dc98f49b9b..f1418d25e6 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/generator/HealthCheckTableGenerator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/generator/HealthCheckTableGenerator.java
@@ -1,53 +1,57 @@
 package com.epam.ta.reportportal.core.widget.content.loader.materialized.generator;
 
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.ATTRIBUTE_KEYS;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LATEST_OPTION;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.core.widget.util.WidgetOptionUtil;
 import com.epam.ta.reportportal.dao.WidgetContentRepository;
 import com.epam.ta.reportportal.dao.WidgetRepository;
 import com.epam.ta.reportportal.entity.widget.Widget;
 import com.epam.ta.reportportal.entity.widget.content.healthcheck.HealthCheckTableInitParams;
+import java.util.List;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 import org.springframework.util.MultiValueMap;
 
-import java.util.List;
-
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.ATTRIBUTE_KEYS;
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LATEST_OPTION;
-import static java.util.Optional.ofNullable;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class HealthCheckTableGenerator extends AbstractViewGenerator {
 
-	public static final String CUSTOM_COLUMN = "customColumn";
-
-	private final WidgetContentRepository widgetContentRepository;
-
-	@Autowired
-	public HealthCheckTableGenerator(WidgetRepository widgetRepository, WidgetContentRepository widgetContentRepository) {
-		super(widgetRepository);
-		this.widgetContentRepository = widgetContentRepository;
-	}
-
-	@Override
-	protected void generateView(boolean refresh, String viewName, Widget widget, Filter launchesFilter, Sort launchesSort,
-			MultiValueMap<String, String> params) {
-		widgetContentRepository.generateComponentHealthCheckTable(refresh,
-				getInitParams(widget, viewName),
-				launchesFilter,
-				launchesSort,
-				widget.getItemsCount(),
-				WidgetOptionUtil.getBooleanByKey(LATEST_OPTION, widget.getWidgetOptions())
-		);
-	}
-
-	private HealthCheckTableInitParams getInitParams(Widget widget, String viewName) {
-		List<String> attributeKeys = WidgetOptionUtil.getListByKey(ATTRIBUTE_KEYS, widget.getWidgetOptions());
-		return ofNullable(WidgetOptionUtil.getValueByKey(CUSTOM_COLUMN, widget.getWidgetOptions())).map(custom -> HealthCheckTableInitParams
-				.of(viewName, attributeKeys, custom)).orElseGet(() -> HealthCheckTableInitParams.of(viewName, attributeKeys));
-	}
+  public static final String CUSTOM_COLUMN = "customColumn";
+
+  private final WidgetContentRepository widgetContentRepository;
+
+  @Autowired
+  public HealthCheckTableGenerator(WidgetRepository widgetRepository,
+      WidgetContentRepository widgetContentRepository) {
+    super(widgetRepository);
+    this.widgetContentRepository = widgetContentRepository;
+  }
+
+  @Override
+  protected void generateView(boolean refresh, String viewName, Widget widget,
+      Filter launchesFilter, Sort launchesSort,
+      MultiValueMap<String, String> params) {
+    widgetContentRepository.generateComponentHealthCheckTable(refresh,
+        getInitParams(widget, viewName),
+        launchesFilter,
+        launchesSort,
+        widget.getItemsCount(),
+        WidgetOptionUtil.getBooleanByKey(LATEST_OPTION, widget.getWidgetOptions())
+    );
+  }
+
+  private HealthCheckTableInitParams getInitParams(Widget widget, String viewName) {
+    List<String> attributeKeys = WidgetOptionUtil.getListByKey(ATTRIBUTE_KEYS,
+        widget.getWidgetOptions());
+    return ofNullable(WidgetOptionUtil.getValueByKey(CUSTOM_COLUMN, widget.getWidgetOptions())).map(
+            custom -> HealthCheckTableInitParams
+                .of(viewName, attributeKeys, custom))
+        .orElseGet(() -> HealthCheckTableInitParams.of(viewName, attributeKeys));
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/generator/ViewGenerator.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/generator/ViewGenerator.java
index 35739bcaf7..0e0873f9a5 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/generator/ViewGenerator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/generator/ViewGenerator.java
@@ -10,6 +10,7 @@
  */
 public interface ViewGenerator {
 
-	void generate(boolean refresh, String viewName, Widget widget, Filter launchesFilter, Sort launchesSort,
-			MultiValueMap<String, String> params);
+  void generate(boolean refresh, String viewName, Widget widget, Filter launchesFilter,
+      Sort launchesSort,
+      MultiValueMap<String, String> params);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/handler/CreatedMaterializedWidgetStateHandler.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/handler/CreatedMaterializedWidgetStateHandler.java
index 360943ec30..0f696d3e0a 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/handler/CreatedMaterializedWidgetStateHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/handler/CreatedMaterializedWidgetStateHandler.java
@@ -1,40 +1,41 @@
 package com.epam.ta.reportportal.core.widget.content.loader.materialized.handler;
 
+import static com.epam.ta.reportportal.core.widget.content.updater.MaterializedWidgetStateUpdater.STATE;
+import static java.util.Collections.emptyMap;
+
 import com.epam.ta.reportportal.core.events.widget.GenerateWidgetViewEvent;
 import com.epam.ta.reportportal.dao.WidgetRepository;
 import com.epam.ta.reportportal.entity.widget.Widget;
 import com.epam.ta.reportportal.entity.widget.WidgetState;
 import com.epam.ta.reportportal.ws.converter.builders.WidgetBuilder;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.stereotype.Service;
 import org.springframework.util.MultiValueMap;
 
-import java.util.Map;
-
-import static com.epam.ta.reportportal.core.widget.content.updater.MaterializedWidgetStateUpdater.STATE;
-import static java.util.Collections.emptyMap;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class CreatedMaterializedWidgetStateHandler implements MaterializedWidgetStateHandler {
 
-	private final WidgetRepository widgetRepository;
-	protected ApplicationEventPublisher eventPublisher;
-
-	public CreatedMaterializedWidgetStateHandler(WidgetRepository widgetRepository,
-			@Qualifier("webApplicationContext") ApplicationEventPublisher eventPublisher) {
-		this.widgetRepository = widgetRepository;
-		this.eventPublisher = eventPublisher;
-	}
-
-	@Override
-	public Map<String, Object> handleWidgetState(Widget widget, MultiValueMap<String, String> params) {
-		widgetRepository.save(new WidgetBuilder(widget).addOption(STATE, WidgetState.RENDERING.getValue()).get());
-		eventPublisher.publishEvent(new GenerateWidgetViewEvent(widget.getId(), params));
-		return emptyMap();
-	}
+  private final WidgetRepository widgetRepository;
+  protected ApplicationEventPublisher eventPublisher;
+
+  public CreatedMaterializedWidgetStateHandler(WidgetRepository widgetRepository,
+      @Qualifier("webApplicationContext") ApplicationEventPublisher eventPublisher) {
+    this.widgetRepository = widgetRepository;
+    this.eventPublisher = eventPublisher;
+  }
+
+  @Override
+  public Map<String, Object> handleWidgetState(Widget widget,
+      MultiValueMap<String, String> params) {
+    widgetRepository.save(
+        new WidgetBuilder(widget).addOption(STATE, WidgetState.RENDERING.getValue()).get());
+    eventPublisher.publishEvent(new GenerateWidgetViewEvent(widget.getId(), params));
+    return emptyMap();
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/handler/EmptyMaterializedWidgetStateHandler.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/handler/EmptyMaterializedWidgetStateHandler.java
index bf12f40845..280bba84ff 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/handler/EmptyMaterializedWidgetStateHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/handler/EmptyMaterializedWidgetStateHandler.java
@@ -1,11 +1,10 @@
 package com.epam.ta.reportportal.core.widget.content.loader.materialized.handler;
 
 import com.epam.ta.reportportal.entity.widget.Widget;
-import org.springframework.stereotype.Service;
-import org.springframework.util.MultiValueMap;
-
 import java.util.Collections;
 import java.util.Map;
+import org.springframework.stereotype.Service;
+import org.springframework.util.MultiValueMap;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -13,8 +12,9 @@
 @Service
 public class EmptyMaterializedWidgetStateHandler implements MaterializedWidgetStateHandler {
 
-	@Override
-	public Map<String, Object> handleWidgetState(Widget widget, MultiValueMap<String, String> params) {
-		return Collections.emptyMap();
-	}
+  @Override
+  public Map<String, Object> handleWidgetState(Widget widget,
+      MultiValueMap<String, String> params) {
+    return Collections.emptyMap();
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/handler/FailedMaterializedWidgetStateHandler.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/handler/FailedMaterializedWidgetStateHandler.java
index 026fbf94b1..3e1b31e03a 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/handler/FailedMaterializedWidgetStateHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/handler/FailedMaterializedWidgetStateHandler.java
@@ -1,34 +1,34 @@
 package com.epam.ta.reportportal.core.widget.content.loader.materialized.handler;
 
 import com.epam.ta.reportportal.entity.widget.Widget;
+import java.util.Collections;
+import java.util.Map;
 import org.apache.commons.lang3.BooleanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 import org.springframework.util.MultiValueMap;
 
-import java.util.Collections;
-import java.util.Map;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class FailedMaterializedWidgetStateHandler implements MaterializedWidgetStateHandler {
 
-	private final MaterializedWidgetStateHandler refreshWidgetStateHandler;
+  private final MaterializedWidgetStateHandler refreshWidgetStateHandler;
 
-	@Autowired
-	public FailedMaterializedWidgetStateHandler(
-			@Qualifier("createdMaterializedWidgetStateHandler") MaterializedWidgetStateHandler refreshWidgetStateHandler) {
-		this.refreshWidgetStateHandler = refreshWidgetStateHandler;
-	}
+  @Autowired
+  public FailedMaterializedWidgetStateHandler(
+      @Qualifier("createdMaterializedWidgetStateHandler") MaterializedWidgetStateHandler refreshWidgetStateHandler) {
+    this.refreshWidgetStateHandler = refreshWidgetStateHandler;
+  }
 
-	@Override
-	public Map<String, Object> handleWidgetState(Widget widget, MultiValueMap<String, String> params) {
-		if (BooleanUtils.toBoolean(params.getFirst(REFRESH))) {
-			return refreshWidgetStateHandler.handleWidgetState(widget, params);
-		}
-		return Collections.emptyMap();
-	}
+  @Override
+  public Map<String, Object> handleWidgetState(Widget widget,
+      MultiValueMap<String, String> params) {
+    if (BooleanUtils.toBoolean(params.getFirst(REFRESH))) {
+      return refreshWidgetStateHandler.handleWidgetState(widget, params);
+    }
+    return Collections.emptyMap();
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/handler/MaterializedWidgetStateHandler.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/handler/MaterializedWidgetStateHandler.java
index 7a45f48660..08fbdf7c5d 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/handler/MaterializedWidgetStateHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/handler/MaterializedWidgetStateHandler.java
@@ -1,17 +1,16 @@
 package com.epam.ta.reportportal.core.widget.content.loader.materialized.handler;
 
 import com.epam.ta.reportportal.entity.widget.Widget;
-import org.springframework.util.MultiValueMap;
-
 import java.util.Map;
+import org.springframework.util.MultiValueMap;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public interface MaterializedWidgetStateHandler {
 
-	String REFRESH = "refresh";
-	String VIEW_NAME = "viewName";
+  String REFRESH = "refresh";
+  String VIEW_NAME = "viewName";
 
-	Map<String, Object> handleWidgetState(Widget widget, MultiValueMap<String, String> params);
+  Map<String, Object> handleWidgetState(Widget widget, MultiValueMap<String, String> params);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/handler/ReadyMaterializedWidgetStateHandler.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/handler/ReadyMaterializedWidgetStateHandler.java
index 661d0bbef3..1bd3eb099b 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/handler/ReadyMaterializedWidgetStateHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/handler/ReadyMaterializedWidgetStateHandler.java
@@ -1,51 +1,52 @@
 package com.epam.ta.reportportal.core.widget.content.loader.materialized.handler;
 
+import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.core.widget.content.loader.materialized.MaterializedWidgetContentLoader;
 import com.epam.ta.reportportal.entity.widget.Widget;
 import com.epam.ta.reportportal.entity.widget.WidgetType;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.Collections;
+import java.util.Map;
 import org.apache.commons.lang3.BooleanUtils;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 import org.springframework.util.MultiValueMap;
 
-import java.util.Collections;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
-import static java.util.Optional.ofNullable;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class ReadyMaterializedWidgetStateHandler implements MaterializedWidgetStateHandler {
 
-	private final MaterializedWidgetStateHandler refreshWidgetStateHandler;
-	private final Map<WidgetType, MaterializedWidgetContentLoader> materializedWidgetContentLoaderMapping;
-
-	public ReadyMaterializedWidgetStateHandler(
-			@Qualifier("createdMaterializedWidgetStateHandler") MaterializedWidgetStateHandler refreshWidgetStateHandler,
-			@Qualifier("materializedWidgetContentLoaderMapping")
-					Map<WidgetType, MaterializedWidgetContentLoader> materializedWidgetContentLoaderMapping) {
-		this.refreshWidgetStateHandler = refreshWidgetStateHandler;
-		this.materializedWidgetContentLoaderMapping = materializedWidgetContentLoaderMapping;
-	}
-
-	@Override
-	public Map<String, Object> handleWidgetState(Widget widget, MultiValueMap<String, String> params) {
-
-		if (BooleanUtils.toBoolean(params.getFirst(REFRESH))) {
-			return refreshWidgetStateHandler.handleWidgetState(widget, params);
-		}
-
-		WidgetType widgetType = WidgetType.findByName(widget.getWidgetType())
-				.orElseThrow(() -> new ReportPortalException(ErrorType.UNABLE_TO_CREATE_WIDGET,
-						formattedSupplier("Unsupported widget type '{}'", widget.getWidgetType())
-				));
-
-		return ofNullable(materializedWidgetContentLoaderMapping.get(widgetType)).map(loader -> loader.loadContent(widget, params))
-				.orElseGet(Collections::emptyMap);
-	}
+  private final MaterializedWidgetStateHandler refreshWidgetStateHandler;
+  private final Map<WidgetType, MaterializedWidgetContentLoader> materializedWidgetContentLoaderMapping;
+
+  public ReadyMaterializedWidgetStateHandler(
+      @Qualifier("createdMaterializedWidgetStateHandler") MaterializedWidgetStateHandler refreshWidgetStateHandler,
+      @Qualifier("materializedWidgetContentLoaderMapping")
+      Map<WidgetType, MaterializedWidgetContentLoader> materializedWidgetContentLoaderMapping) {
+    this.refreshWidgetStateHandler = refreshWidgetStateHandler;
+    this.materializedWidgetContentLoaderMapping = materializedWidgetContentLoaderMapping;
+  }
+
+  @Override
+  public Map<String, Object> handleWidgetState(Widget widget,
+      MultiValueMap<String, String> params) {
+
+    if (BooleanUtils.toBoolean(params.getFirst(REFRESH))) {
+      return refreshWidgetStateHandler.handleWidgetState(widget, params);
+    }
+
+    WidgetType widgetType = WidgetType.findByName(widget.getWidgetType())
+        .orElseThrow(() -> new ReportPortalException(ErrorType.UNABLE_TO_CREATE_WIDGET,
+            formattedSupplier("Unsupported widget type '{}'", widget.getWidgetType())
+        ));
+
+    return ofNullable(materializedWidgetContentLoaderMapping.get(widgetType)).map(
+            loader -> loader.loadContent(widget, params))
+        .orElseGet(Collections::emptyMap);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/util/ProductStatusContentLoaderManager.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/util/ProductStatusContentLoaderManager.java
index a81482fb09..93daa4e7eb 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/util/ProductStatusContentLoaderManager.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/loader/util/ProductStatusContentLoaderManager.java
@@ -16,6 +16,8 @@
 
 package com.epam.ta.reportportal.core.widget.content.loader.util;
 
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.core.widget.content.LoadContentStrategy;
 import com.epam.ta.reportportal.core.widget.content.loader.ProductStatusContentLoader;
@@ -23,38 +25,37 @@
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.List;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
-
-import static java.util.Optional.ofNullable;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class ProductStatusContentLoaderManager implements LoadContentStrategy {
 
-	private final Map<String, ProductStatusContentLoader> productStatusContentLoader;
+  private final Map<String, ProductStatusContentLoader> productStatusContentLoader;
 
-	@Autowired
-	public ProductStatusContentLoaderManager(
-			@Qualifier("productStatusContentLoader") Map<String, ProductStatusContentLoader> productStatusContentLoader) {
-		this.productStatusContentLoader = productStatusContentLoader;
-	}
+  @Autowired
+  public ProductStatusContentLoaderManager(
+      @Qualifier("productStatusContentLoader") Map<String, ProductStatusContentLoader> productStatusContentLoader) {
+    this.productStatusContentLoader = productStatusContentLoader;
+  }
 
-	@Override
-	public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions,
-			int limit) {
+  @Override
+  public Map<String, ?> loadContent(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions,
+      int limit) {
 
-		String strategy = WidgetOptionUtil.getValueByKey("strategy", widgetOptions);
+    String strategy = WidgetOptionUtil.getValueByKey("strategy", widgetOptions);
 
-		return ofNullable(productStatusContentLoader.get(strategy)).orElseThrow(() -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR,
-				"Wrong strategy type. Allowed: \"filter\", \"launch\". But found: " + strategy
-		)).loadContent(contentFields, filterSortMapping, widgetOptions, limit);
-	}
+    return ofNullable(productStatusContentLoader.get(strategy)).orElseThrow(
+        () -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR,
+            "Wrong strategy type. Allowed: \"filter\", \"launch\". But found: " + strategy
+        )).loadContent(contentFields, filterSortMapping, widgetOptions, limit);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/materialized/generator/MaterializedViewNameGenerator.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/materialized/generator/MaterializedViewNameGenerator.java
index e61fafa329..8b0a6ffcc9 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/materialized/generator/MaterializedViewNameGenerator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/materialized/generator/MaterializedViewNameGenerator.java
@@ -25,10 +25,11 @@
 @Component
 public class MaterializedViewNameGenerator {
 
-	private static final String VIEW_PREFIX = "widget";
-	private static final String NAME_SEPARATOR = "_";
+  private static final String VIEW_PREFIX = "widget";
+  private static final String NAME_SEPARATOR = "_";
 
-	public String generate(Widget widget) {
-		return String.join(NAME_SEPARATOR, VIEW_PREFIX, String.valueOf(widget.getProject().getId()), String.valueOf(widget.getId()));
-	}
+  public String generate(Widget widget) {
+    return String.join(NAME_SEPARATOR, VIEW_PREFIX, String.valueOf(widget.getProject().getId()),
+        String.valueOf(widget.getId()));
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/materialized/state/WidgetStateResolver.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/materialized/state/WidgetStateResolver.java
index 3f4861da24..c04bb3c612 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/materialized/state/WidgetStateResolver.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/materialized/state/WidgetStateResolver.java
@@ -16,6 +16,9 @@
 
 package com.epam.ta.reportportal.core.widget.content.materialized.state;
 
+import static com.epam.ta.reportportal.core.widget.content.updater.MaterializedWidgetStateUpdater.STATE;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.core.widget.util.WidgetOptionUtil;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.entity.widget.WidgetState;
@@ -23,17 +26,16 @@
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import org.springframework.stereotype.Component;
 
-import static com.epam.ta.reportportal.core.widget.content.updater.MaterializedWidgetStateUpdater.STATE;
-import static java.util.Optional.ofNullable;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Component
 public class WidgetStateResolver {
 
-	public WidgetState resolve(WidgetOptions widgetOptions) {
-		return ofNullable(WidgetOptionUtil.getValueByKey(STATE, widgetOptions)).flatMap(WidgetState::findByName)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.UNABLE_LOAD_WIDGET_CONTENT, "Widget state not provided"));
-	}
+  public WidgetState resolve(WidgetOptions widgetOptions) {
+    return ofNullable(WidgetOptionUtil.getValueByKey(STATE, widgetOptions)).flatMap(
+            WidgetState::findByName)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.UNABLE_LOAD_WIDGET_CONTENT,
+            "Widget state not provided"));
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/remover/DelegatingStateContentRemover.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/remover/DelegatingStateContentRemover.java
index 5ff4462ae8..5a568315ca 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/remover/DelegatingStateContentRemover.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/remover/DelegatingStateContentRemover.java
@@ -16,44 +16,46 @@
 
 package com.epam.ta.reportportal.core.widget.content.remover;
 
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.core.widget.content.materialized.state.WidgetStateResolver;
 import com.epam.ta.reportportal.entity.widget.Widget;
 import com.epam.ta.reportportal.entity.widget.WidgetState;
 import com.epam.ta.reportportal.entity.widget.WidgetType;
 import com.google.common.collect.Lists;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.Map;
-
-import static java.util.Optional.ofNullable;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class DelegatingStateContentRemover implements WidgetContentRemover {
 
-	private final WidgetStateResolver widgetStateResolver;
-	private final Map<WidgetState, WidgetContentRemover> widgetContentRemoverMapping;
-
-	@Autowired
-	public DelegatingStateContentRemover(WidgetStateResolver widgetStateResolver, Map<WidgetState, WidgetContentRemover> widgetContentRemoverMapping) {
-		this.widgetStateResolver = widgetStateResolver;
-		this.widgetContentRemoverMapping = widgetContentRemoverMapping;
-	}
-
-	@Override
-	public void removeContent(Widget widget) {
-		if (supports(widget)) {
-			final WidgetState state = widgetStateResolver.resolve(widget.getWidgetOptions());
-			ofNullable(widgetContentRemoverMapping.get(state)).ifPresent(remover -> remover.removeContent(widget));
-		}
-	}
-
-	private boolean supports(Widget widget) {
-		return Lists.newArrayList(WidgetType.COMPONENT_HEALTH_CHECK_TABLE.getType(), WidgetType.CUMULATIVE.getType())
-				.contains(widget.getWidgetType());
-	}
+  private final WidgetStateResolver widgetStateResolver;
+  private final Map<WidgetState, WidgetContentRemover> widgetContentRemoverMapping;
+
+  @Autowired
+  public DelegatingStateContentRemover(WidgetStateResolver widgetStateResolver,
+      Map<WidgetState, WidgetContentRemover> widgetContentRemoverMapping) {
+    this.widgetStateResolver = widgetStateResolver;
+    this.widgetContentRemoverMapping = widgetContentRemoverMapping;
+  }
+
+  @Override
+  public void removeContent(Widget widget) {
+    if (supports(widget)) {
+      final WidgetState state = widgetStateResolver.resolve(widget.getWidgetOptions());
+      ofNullable(widgetContentRemoverMapping.get(state)).ifPresent(
+          remover -> remover.removeContent(widget));
+    }
+  }
+
+  private boolean supports(Widget widget) {
+    return Lists.newArrayList(WidgetType.COMPONENT_HEALTH_CHECK_TABLE.getType(),
+            WidgetType.CUMULATIVE.getType())
+        .contains(widget.getWidgetType());
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/remover/MaterializedViewRemover.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/remover/MaterializedViewRemover.java
index 1c73a0df8e..76555600e4 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/remover/MaterializedViewRemover.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/remover/MaterializedViewRemover.java
@@ -16,32 +16,32 @@
 
 package com.epam.ta.reportportal.core.widget.content.remover;
 
+import static com.epam.ta.reportportal.core.widget.content.loader.materialized.handler.MaterializedWidgetStateHandler.VIEW_NAME;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.core.widget.util.WidgetOptionUtil;
 import com.epam.ta.reportportal.dao.WidgetContentRepository;
 import com.epam.ta.reportportal.entity.widget.Widget;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import static com.epam.ta.reportportal.core.widget.content.loader.materialized.handler.MaterializedWidgetStateHandler.VIEW_NAME;
-import static java.util.Optional.ofNullable;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class MaterializedViewRemover implements WidgetContentRemover {
 
-	private final WidgetContentRepository widgetContentRepository;
+  private final WidgetContentRepository widgetContentRepository;
 
-	@Autowired
-	public MaterializedViewRemover(WidgetContentRepository widgetContentRepository) {
-		this.widgetContentRepository = widgetContentRepository;
-	}
+  @Autowired
+  public MaterializedViewRemover(WidgetContentRepository widgetContentRepository) {
+    this.widgetContentRepository = widgetContentRepository;
+  }
 
-	@Override
-	public void removeContent(Widget widget) {
-		ofNullable(WidgetOptionUtil.getValueByKey(VIEW_NAME,
-				widget.getWidgetOptions()
-		)).ifPresent(widgetContentRepository::removeWidgetView);
-	}
+  @Override
+  public void removeContent(Widget widget) {
+    ofNullable(WidgetOptionUtil.getValueByKey(VIEW_NAME,
+        widget.getWidgetOptions()
+    )).ifPresent(widgetContentRepository::removeWidgetView);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/remover/StaleMaterializedViewRemover.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/remover/StaleMaterializedViewRemover.java
index d5886e64c1..766a16e215 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/remover/StaleMaterializedViewRemover.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/remover/StaleMaterializedViewRemover.java
@@ -20,10 +20,9 @@
 import com.epam.ta.reportportal.dao.StaleMaterializedViewRepository;
 import com.epam.ta.reportportal.entity.materialized.StaleMaterializedView;
 import com.epam.ta.reportportal.entity.widget.Widget;
-import org.springframework.stereotype.Service;
-
 import java.time.LocalDateTime;
 import java.time.ZoneOffset;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -31,26 +30,26 @@
 @Service
 public class StaleMaterializedViewRemover implements WidgetContentRemover {
 
-	private final MaterializedViewNameGenerator materializedViewNameGenerator;
-	private final StaleMaterializedViewRepository staleMaterializedViewRepository;
-
-	public StaleMaterializedViewRemover(MaterializedViewNameGenerator materializedViewNameGenerator,
-			StaleMaterializedViewRepository staleMaterializedViewRepository) {
-		this.materializedViewNameGenerator = materializedViewNameGenerator;
-		this.staleMaterializedViewRepository = staleMaterializedViewRepository;
-	}
-
-	@Override
-	public void removeContent(Widget widget) {
-		final StaleMaterializedView staleView = getStaleView(widget);
-		staleMaterializedViewRepository.insert(staleView);
-	}
-
-	private StaleMaterializedView getStaleView(Widget widget) {
-		final String viewName = materializedViewNameGenerator.generate(widget);
-		final StaleMaterializedView view = new StaleMaterializedView();
-		view.setName(viewName);
-		view.setCreationDate(LocalDateTime.now(ZoneOffset.UTC));
-		return view;
-	}
+  private final MaterializedViewNameGenerator materializedViewNameGenerator;
+  private final StaleMaterializedViewRepository staleMaterializedViewRepository;
+
+  public StaleMaterializedViewRemover(MaterializedViewNameGenerator materializedViewNameGenerator,
+      StaleMaterializedViewRepository staleMaterializedViewRepository) {
+    this.materializedViewNameGenerator = materializedViewNameGenerator;
+    this.staleMaterializedViewRepository = staleMaterializedViewRepository;
+  }
+
+  @Override
+  public void removeContent(Widget widget) {
+    final StaleMaterializedView staleView = getStaleView(widget);
+    staleMaterializedViewRepository.insert(staleView);
+  }
+
+  private StaleMaterializedView getStaleView(Widget widget) {
+    final String viewName = materializedViewNameGenerator.generate(widget);
+    final StaleMaterializedView view = new StaleMaterializedView();
+    view.setName(viewName);
+    view.setCreationDate(LocalDateTime.now(ZoneOffset.UTC));
+    return view;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/remover/WidgetContentRemover.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/remover/WidgetContentRemover.java
index 9a2b6ba652..2852c0ee82 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/remover/WidgetContentRemover.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/remover/WidgetContentRemover.java
@@ -23,6 +23,6 @@
  */
 public interface WidgetContentRemover {
 
-	void removeContent(Widget widget);
+  void removeContent(Widget widget);
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/ComponentHealthCheckPostProcessor.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/ComponentHealthCheckPostProcessor.java
index 9cbfb5dd2d..4130fd1ada 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/ComponentHealthCheckPostProcessor.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/ComponentHealthCheckPostProcessor.java
@@ -12,22 +12,22 @@
 @Component
 public class ComponentHealthCheckPostProcessor implements WidgetPostProcessor {
 
-	private final WidgetValidator componentHealthCheckValidator;
+  private final WidgetValidator componentHealthCheckValidator;
 
-	@Autowired
-	public ComponentHealthCheckPostProcessor(WidgetValidator componentHealthCheckValidator) {
-		this.componentHealthCheckValidator = componentHealthCheckValidator;
-	}
+  @Autowired
+  public ComponentHealthCheckPostProcessor(WidgetValidator componentHealthCheckValidator) {
+    this.componentHealthCheckValidator = componentHealthCheckValidator;
+  }
 
-	@Override
-	public boolean supports(Widget widget) {
-		return WidgetType.COMPONENT_HEALTH_CHECK.getType().equalsIgnoreCase(widget.getWidgetType());
-	}
+  @Override
+  public boolean supports(Widget widget) {
+    return WidgetType.COMPONENT_HEALTH_CHECK.getType().equalsIgnoreCase(widget.getWidgetType());
+  }
 
-	@Override
-	public void postProcess(Widget widget) {
-		if (supports(widget)) {
-			componentHealthCheckValidator.validate(widget);
-		}
-	}
+  @Override
+  public void postProcess(Widget widget) {
+    if (supports(widget)) {
+      componentHealthCheckValidator.validate(widget);
+    }
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/ComponentHealthCheckTablePostProcessor.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/ComponentHealthCheckTablePostProcessor.java
index 1496ebc100..b3361bc852 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/ComponentHealthCheckTablePostProcessor.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/ComponentHealthCheckTablePostProcessor.java
@@ -12,26 +12,27 @@
 @Component
 public class ComponentHealthCheckTablePostProcessor implements WidgetPostProcessor {
 
-	private final WidgetValidator componentHealthCheckTableValidator;
-	private final WidgetUpdater materializedWidgetStateUpdater;
+  private final WidgetValidator componentHealthCheckTableValidator;
+  private final WidgetUpdater materializedWidgetStateUpdater;
 
-	@Autowired
-	public ComponentHealthCheckTablePostProcessor(WidgetValidator componentHealthCheckTableValidator,
-			WidgetUpdater materializedWidgetStateUpdater) {
-		this.componentHealthCheckTableValidator = componentHealthCheckTableValidator;
-		this.materializedWidgetStateUpdater = materializedWidgetStateUpdater;
-	}
+  @Autowired
+  public ComponentHealthCheckTablePostProcessor(WidgetValidator componentHealthCheckTableValidator,
+      WidgetUpdater materializedWidgetStateUpdater) {
+    this.componentHealthCheckTableValidator = componentHealthCheckTableValidator;
+    this.materializedWidgetStateUpdater = materializedWidgetStateUpdater;
+  }
 
-	@Override
-	public boolean supports(Widget widget) {
-		return WidgetType.COMPONENT_HEALTH_CHECK_TABLE.getType().equalsIgnoreCase(widget.getWidgetType());
-	}
+  @Override
+  public boolean supports(Widget widget) {
+    return WidgetType.COMPONENT_HEALTH_CHECK_TABLE.getType()
+        .equalsIgnoreCase(widget.getWidgetType());
+  }
 
-	@Override
-	public void postProcess(Widget widget) {
-		if (supports(widget)) {
-			componentHealthCheckTableValidator.validate(widget);
-			materializedWidgetStateUpdater.update(widget);
-		}
-	}
+  @Override
+  public void postProcess(Widget widget) {
+    if (supports(widget)) {
+      componentHealthCheckTableValidator.validate(widget);
+      materializedWidgetStateUpdater.update(widget);
+    }
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/CumulativeTrendChartPostProcessor.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/CumulativeTrendChartPostProcessor.java
index e847b7a677..9da422bc27 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/CumulativeTrendChartPostProcessor.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/CumulativeTrendChartPostProcessor.java
@@ -12,26 +12,27 @@
 @Component
 public class CumulativeTrendChartPostProcessor implements WidgetPostProcessor {
 
-	private final WidgetValidator cumulativeTrendChartValidator;
+  private final WidgetValidator cumulativeTrendChartValidator;
 
-	private final WidgetUpdater materializedWidgetStateUpdater;
+  private final WidgetUpdater materializedWidgetStateUpdater;
 
-	@Autowired
-	public CumulativeTrendChartPostProcessor(WidgetValidator cumulativeTrendChartValidator, WidgetUpdater materializedWidgetStateUpdater) {
-		this.cumulativeTrendChartValidator = cumulativeTrendChartValidator;
-		this.materializedWidgetStateUpdater = materializedWidgetStateUpdater;
-	}
+  @Autowired
+  public CumulativeTrendChartPostProcessor(WidgetValidator cumulativeTrendChartValidator,
+      WidgetUpdater materializedWidgetStateUpdater) {
+    this.cumulativeTrendChartValidator = cumulativeTrendChartValidator;
+    this.materializedWidgetStateUpdater = materializedWidgetStateUpdater;
+  }
 
-	@Override
-	public boolean supports(Widget widget) {
-		return WidgetType.CUMULATIVE.getType().equalsIgnoreCase(widget.getWidgetType());
-	}
+  @Override
+  public boolean supports(Widget widget) {
+    return WidgetType.CUMULATIVE.getType().equalsIgnoreCase(widget.getWidgetType());
+  }
 
-	@Override
-	public void postProcess(Widget widget) {
-		if (supports(widget)) {
-			cumulativeTrendChartValidator.validate(widget);
-			materializedWidgetStateUpdater.update(widget);
-		}
-	}
+  @Override
+  public void postProcess(Widget widget) {
+    if (supports(widget)) {
+      cumulativeTrendChartValidator.validate(widget);
+      materializedWidgetStateUpdater.update(widget);
+    }
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/MaterializedWidgetStateUpdater.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/MaterializedWidgetStateUpdater.java
index 83dc5f37ed..65406e8336 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/MaterializedWidgetStateUpdater.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/MaterializedWidgetStateUpdater.java
@@ -11,10 +11,10 @@
 @Component
 public class MaterializedWidgetStateUpdater implements WidgetUpdater {
 
-	public static final String STATE = "state";
+  public static final String STATE = "state";
 
-	@Override
-	public void update(Widget widget) {
-		new WidgetBuilder(widget).addOption(STATE, WidgetState.CREATED.getValue());
-	}
+  @Override
+  public void update(Widget widget) {
+    new WidgetBuilder(widget).addOption(STATE, WidgetState.CREATED.getValue());
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/WidgetPostProcessor.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/WidgetPostProcessor.java
index eb2f90e93e..e053e98b47 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/WidgetPostProcessor.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/WidgetPostProcessor.java
@@ -9,14 +9,14 @@
  */
 public interface WidgetPostProcessor {
 
-	/**
-	 * @param widget {@link Widget}
-	 * @return 'true' if provided widget is supported by post processor otherwise 'false'
-	 */
-	boolean supports(Widget widget);
+  /**
+   * @param widget {@link Widget}
+   * @return 'true' if provided widget is supported by post processor otherwise 'false'
+   */
+  boolean supports(Widget widget);
 
-	/**
-	 * @param widget {@link Widget} for post processing
-	 */
-	void postProcess(Widget widget);
+  /**
+   * @param widget {@link Widget} for post processing
+   */
+  void postProcess(Widget widget);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/WidgetUpdater.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/WidgetUpdater.java
index e8de22a0ac..383f22645d 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/WidgetUpdater.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/WidgetUpdater.java
@@ -9,9 +9,9 @@
  */
 public interface WidgetUpdater {
 
-	/**
-	 * @param widget {@link Widget} to update
-	 */
-	void update(Widget widget);
+  /**
+   * @param widget {@link Widget} to update
+   */
+  void update(Widget widget);
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/ActivityContentValidator.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/ActivityContentValidator.java
index af64ca24bb..e5c1d36b58 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/ActivityContentValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/ActivityContentValidator.java
@@ -16,39 +16,41 @@
 
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.List;
+import java.util.Map;
 import org.apache.commons.collections.MapUtils;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-
 /**
  * @author Pavel Bortnik
  */
 @Service
 public class ActivityContentValidator implements WidgetValidatorStrategy {
 
-	@Override
-	public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions, int limit) {
-		validateFilterSortMapping(filterSortMapping);
-	}
-
-	/**
-	 * Mapping should not be empty
-	 *
-	 * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as value for each filter
-	 */
-	private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
-		expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true)).verify(ErrorType.BAD_REQUEST_ERROR,
-				"Filter-Sort mapping should not be empty"
-		);
-	}
+  @Override
+  public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions, int limit) {
+    validateFilterSortMapping(filterSortMapping);
+  }
+
+  /**
+   * Mapping should not be empty
+   *
+   * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as
+   *                          value for each filter
+   */
+  private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
+    expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true)).verify(
+        ErrorType.BAD_REQUEST_ERROR,
+        "Filter-Sort mapping should not be empty"
+    );
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/BugTrendChartContentValidator.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/BugTrendChartContentValidator.java
index ffdcae2cde..5c66db1dad 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/BugTrendChartContentValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/BugTrendChartContentValidator.java
@@ -16,57 +16,59 @@
 
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import static com.epam.ta.reportportal.core.widget.util.ContentFieldPatternConstants.EXECUTIONS_FAILED_REGEX;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.core.widget.util.ContentFieldMatcherUtil;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.List;
+import java.util.Map;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-import static com.epam.ta.reportportal.core.widget.util.ContentFieldPatternConstants.EXECUTIONS_FAILED_REGEX;
-
 /**
  * @author Pavel Bortnik
  */
 @Service
 public class BugTrendChartContentValidator implements WidgetValidatorStrategy {
 
-	@Override
-	public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions, int limit) {
-		validateFilterSortMapping(filterSortMapping);
-		validateContentFields(contentFields);
-	}
+  @Override
+  public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions, int limit) {
+    validateFilterSortMapping(filterSortMapping);
+    validateContentFields(contentFields);
+  }
 
-	/**
-	 * Mapping should not be empty
-	 *
-	 * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as value for each filter
-	 */
-	private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
-		BusinessRule.expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true))
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Filter-Sort mapping should not be empty");
-	}
+  /**
+   * Mapping should not be empty
+   *
+   * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as
+   *                          value for each filter
+   */
+  private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
+    BusinessRule.expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true))
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Filter-Sort mapping should not be empty");
+  }
 
-	/**
-	 * Validate provided content fields.
-	 *
-	 * <p>
-	 * The value of content field should not be empty.
-	 * All content fields should match the pattern {@link com.epam.ta.reportportal.core.widget.util.ContentFieldPatternConstants#DEFECTS_REGEX}
-	 *
-	 * @param contentFields List of provided content.
-	 */
-	private void validateContentFields(List<String> contentFields) {
-		BusinessRule.expect(CollectionUtils.isNotEmpty(contentFields), equalTo(true))
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Content fields should not be empty");
-		BusinessRule.expect(ContentFieldMatcherUtil.match(EXECUTIONS_FAILED_REGEX, contentFields), equalTo(true))
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Bad content fields format");
-	}
+  /**
+   * Validate provided content fields.
+   *
+   * <p>
+   * The value of content field should not be empty. All content fields should match the pattern
+   * {@link com.epam.ta.reportportal.core.widget.util.ContentFieldPatternConstants#DEFECTS_REGEX}
+   *
+   * @param contentFields List of provided content.
+   */
+  private void validateContentFields(List<String> contentFields) {
+    BusinessRule.expect(CollectionUtils.isNotEmpty(contentFields), equalTo(true))
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Content fields should not be empty");
+    BusinessRule.expect(ContentFieldMatcherUtil.match(EXECUTIONS_FAILED_REGEX, contentFields),
+            equalTo(true))
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Bad content fields format");
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/CasesTrendContentValidator.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/CasesTrendContentValidator.java
index 622603ec40..af92dacbc6 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/CasesTrendContentValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/CasesTrendContentValidator.java
@@ -16,60 +16,64 @@
 
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import static com.epam.ta.reportportal.core.widget.util.ContentFieldPatternConstants.EXECUTIONS_TOTAL_REGEX;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.core.widget.util.ContentFieldMatcherUtil;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.List;
+import java.util.Map;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-import static com.epam.ta.reportportal.core.widget.util.ContentFieldPatternConstants.EXECUTIONS_TOTAL_REGEX;
-
 /**
  * @author Pavel Bortnik
  */
 @Service
 public class CasesTrendContentValidator implements WidgetValidatorStrategy {
 
-	@Override
-	public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions, int limit) {
-		validateFilterSortMapping(filterSortMapping);
-		validateContentFields(contentFields);
-	}
+  @Override
+  public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions, int limit) {
+    validateFilterSortMapping(filterSortMapping);
+    validateContentFields(contentFields);
+  }
 
-	/**
-	 * Mapping should not be empty
-	 *
-	 * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as value for each filter
-	 */
-	private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
-		BusinessRule.expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true))
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Filter-Sort mapping should not be empty");
-	}
+  /**
+   * Mapping should not be empty
+   *
+   * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as
+   *                          value for each filter
+   */
+  private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
+    BusinessRule.expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true))
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Filter-Sort mapping should not be empty");
+  }
 
-	/**
-	 * Validate provided content fields.
-	 * <p>
-	 * The value of content field should not be empty
-	 * Content fields should contain only 1 value
-	 * Content field value should match the pattern {@link com.epam.ta.reportportal.core.widget.util.ContentFieldPatternConstants#EXECUTIONS_TOTAL_REGEX}
-	 *
-	 * @param contentFields List of provided content.
-	 */
-	private void validateContentFields(List<String> contentFields) {
-		BusinessRule.expect(CollectionUtils.isNotEmpty(contentFields), equalTo(true))
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Content fields should not be empty");
-		BusinessRule.expect(contentFields.size(), equalTo(1))
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Test cases growth widget content fields should contain only 1 value");
-		BusinessRule.expect(ContentFieldMatcherUtil.match(EXECUTIONS_TOTAL_REGEX, contentFields), equalTo(true))
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Bad content fields format");
-	}
+  /**
+   * Validate provided content fields.
+   * <p>
+   * The value of content field should not be empty Content fields should contain only 1 value
+   * Content field value should match the pattern
+   * {@link
+   * com.epam.ta.reportportal.core.widget.util.ContentFieldPatternConstants#EXECUTIONS_TOTAL_REGEX}
+   *
+   * @param contentFields List of provided content.
+   */
+  private void validateContentFields(List<String> contentFields) {
+    BusinessRule.expect(CollectionUtils.isNotEmpty(contentFields), equalTo(true))
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Content fields should not be empty");
+    BusinessRule.expect(contentFields.size(), equalTo(1))
+        .verify(ErrorType.BAD_REQUEST_ERROR,
+            "Test cases growth widget content fields should contain only 1 value");
+    BusinessRule.expect(ContentFieldMatcherUtil.match(EXECUTIONS_TOTAL_REGEX, contentFields),
+            equalTo(true))
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Bad content fields format");
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/ChartInvestigatedContentValidator.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/ChartInvestigatedContentValidator.java
index 3c53a552c2..cf52c58ce0 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/ChartInvestigatedContentValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/ChartInvestigatedContentValidator.java
@@ -16,38 +16,39 @@
 
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.List;
+import java.util.Map;
 import org.apache.commons.collections.MapUtils;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-
 /**
  * @author Pavel Bortnik
  */
 @Service
 public class ChartInvestigatedContentValidator implements WidgetValidatorStrategy {
 
-	@Override
-	public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions, int limit) {
-		validateFilterSortMapping(filterSortMapping);
-	}
-
-	/**
-	 * Mapping should not be empty
-	 *
-	 * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as value for each filter
-	 */
-	private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
-		BusinessRule.expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true))
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Filter-Sort mapping should not be empty");
-	}
+  @Override
+  public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions, int limit) {
+    validateFilterSortMapping(filterSortMapping);
+  }
+
+  /**
+   * Mapping should not be empty
+   *
+   * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as
+   *                          value for each filter
+   */
+  private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
+    BusinessRule.expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true))
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Filter-Sort mapping should not be empty");
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/ComponentHealthCheckContentValidator.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/ComponentHealthCheckContentValidator.java
index 7919985188..4d317b31bf 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/ComponentHealthCheckContentValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/ComponentHealthCheckContentValidator.java
@@ -16,68 +16,75 @@
 
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.ATTRIBUTE_KEYS;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.MIN_PASSING_RATE;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.core.widget.util.WidgetOptionUtil;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.*;
-
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.ATTRIBUTE_KEYS;
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.MIN_PASSING_RATE;
-import static java.util.Optional.ofNullable;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class ComponentHealthCheckContentValidator implements MultilevelValidatorStrategy {
 
-	public static final Integer MAX_LEVEL_NUMBER = 10;
+  public static final Integer MAX_LEVEL_NUMBER = 10;
 
-	@Override
-	public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions, String[] attributes,
-			Map<String, String> params, int limit) {
+  @Override
+  public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions, String[] attributes,
+      Map<String, String> params, int limit) {
 
-		validateWidgetOptions(widgetOptions);
+    validateWidgetOptions(widgetOptions);
 
-		List<String> attributeKeys = WidgetOptionUtil.getListByKey(ATTRIBUTE_KEYS, widgetOptions);
-		validateAttributeKeys(attributeKeys);
+    List<String> attributeKeys = WidgetOptionUtil.getListByKey(ATTRIBUTE_KEYS, widgetOptions);
+    validateAttributeKeys(attributeKeys);
 
-		List<String> attributeValues = ofNullable(attributes).map(Arrays::asList).orElseGet(Collections::emptyList);
+    List<String> attributeValues = ofNullable(attributes).map(Arrays::asList)
+        .orElseGet(Collections::emptyList);
 
-		validateAttributeValues(attributeValues);
-	}
+    validateAttributeValues(attributeValues);
+  }
 
-	private void validateAttributeKeys(List<String> attributeKeys) {
-		BusinessRule.expect(attributeKeys, CollectionUtils::isNotEmpty)
-				.verify(ErrorType.UNABLE_LOAD_WIDGET_CONTENT, "No keys were specified");
-		BusinessRule.expect(attributeKeys, cf -> cf.size() <= MAX_LEVEL_NUMBER)
-				.verify(ErrorType.UNABLE_LOAD_WIDGET_CONTENT, "Keys number is incorrect. Maximum keys count = " + MAX_LEVEL_NUMBER);
-		attributeKeys.forEach(cf -> BusinessRule.expect(cf, StringUtils::isNotBlank)
-				.verify(ErrorType.UNABLE_LOAD_WIDGET_CONTENT, "Current level key should be not blank"));
-	}
+  private void validateAttributeKeys(List<String> attributeKeys) {
+    BusinessRule.expect(attributeKeys, CollectionUtils::isNotEmpty)
+        .verify(ErrorType.UNABLE_LOAD_WIDGET_CONTENT, "No keys were specified");
+    BusinessRule.expect(attributeKeys, cf -> cf.size() <= MAX_LEVEL_NUMBER)
+        .verify(ErrorType.UNABLE_LOAD_WIDGET_CONTENT,
+            "Keys number is incorrect. Maximum keys count = " + MAX_LEVEL_NUMBER);
+    attributeKeys.forEach(cf -> BusinessRule.expect(cf, StringUtils::isNotBlank)
+        .verify(ErrorType.UNABLE_LOAD_WIDGET_CONTENT, "Current level key should be not blank"));
+  }
 
-	private void validateWidgetOptions(WidgetOptions widgetOptions) {
-		BusinessRule.expect(widgetOptions, Objects::nonNull).verify(ErrorType.UNABLE_LOAD_WIDGET_CONTENT, "Widgets options not provided");
-		Integer passingRate = WidgetOptionUtil.getIntegerByKey(MIN_PASSING_RATE, widgetOptions)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.UNABLE_LOAD_WIDGET_CONTENT,
-						"Minimum passing rate option was not specified"
-				));
-		BusinessRule.expect(passingRate, v -> v >= 0 && v <= 100)
-				.verify(ErrorType.UNABLE_LOAD_WIDGET_CONTENT,
-						"Minimum passing rate value should be greater or equal to 0 and less or equal to 100"
-				);
-	}
+  private void validateWidgetOptions(WidgetOptions widgetOptions) {
+    BusinessRule.expect(widgetOptions, Objects::nonNull)
+        .verify(ErrorType.UNABLE_LOAD_WIDGET_CONTENT, "Widgets options not provided");
+    Integer passingRate = WidgetOptionUtil.getIntegerByKey(MIN_PASSING_RATE, widgetOptions)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.UNABLE_LOAD_WIDGET_CONTENT,
+            "Minimum passing rate option was not specified"
+        ));
+    BusinessRule.expect(passingRate, v -> v >= 0 && v <= 100)
+        .verify(ErrorType.UNABLE_LOAD_WIDGET_CONTENT,
+            "Minimum passing rate value should be greater or equal to 0 and less or equal to 100"
+        );
+  }
 
-	private void validateAttributeValues(List<String> attributeValues) {
-		attributeValues.forEach(value -> BusinessRule.expect(value, Objects::nonNull)
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Attribute value should be not null"));
-	}
+  private void validateAttributeValues(List<String> attributeValues) {
+    attributeValues.forEach(value -> BusinessRule.expect(value, Objects::nonNull)
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Attribute value should be not null"));
+  }
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/CumulativeTrendChartValidator.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/CumulativeTrendChartValidator.java
index a77bc12c65..9a43600aec 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/CumulativeTrendChartValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/CumulativeTrendChartValidator.java
@@ -16,59 +16,63 @@
 
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static com.epam.ta.reportportal.core.widget.util.ContentFieldPatternConstants.COMBINED_CONTENT_FIELDS_REGEX;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.core.widget.util.ContentFieldMatcherUtil;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.List;
+import java.util.Map;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static com.epam.ta.reportportal.core.widget.util.ContentFieldPatternConstants.COMBINED_CONTENT_FIELDS_REGEX;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class CumulativeTrendChartValidator implements MultilevelValidatorStrategy {
 
-	@Override
-	public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions, String[] attributes,
-			Map<String, String> params, int limit) {
-		validateFilterSortMapping(filterSortMapping);
-		validateContentFields(contentFields);
-	}
+  @Override
+  public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions, String[] attributes,
+      Map<String, String> params, int limit) {
+    validateFilterSortMapping(filterSortMapping);
+    validateContentFields(contentFields);
+  }
 
-	/**
-	 * Mapping should not be empty
-	 *
-	 * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as value for each filter
-	 */
-	private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
-		expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true)).verify(ErrorType.BAD_REQUEST_ERROR,
-				"Filter-Sort mapping should not be empty"
-		);
-	}
+  /**
+   * Mapping should not be empty
+   *
+   * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as
+   *                          value for each filter
+   */
+  private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
+    expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true)).verify(
+        ErrorType.BAD_REQUEST_ERROR,
+        "Filter-Sort mapping should not be empty"
+    );
+  }
 
-	/**
-	 * Validate provided content fields.
-	 * The value of content field should not be empty
-	 * All content fields should match the pattern {@link com.epam.ta.reportportal.core.widget.util.ContentFieldPatternConstants#COMBINED_CONTENT_FIELDS_REGEX}
-	 *
-	 * @param contentFields List of provided content.
-	 */
-	private void validateContentFields(List<String> contentFields) {
-		expect(CollectionUtils.isNotEmpty(contentFields), equalTo(true)).verify(ErrorType.BAD_REQUEST_ERROR,
-				"Content fields should not be empty"
-		);
-		expect(ContentFieldMatcherUtil.match(COMBINED_CONTENT_FIELDS_REGEX, contentFields),
-				equalTo(true)
-		).verify(ErrorType.BAD_REQUEST_ERROR, "Bad content fields format");
-	}
+  /**
+   * Validate provided content fields. The value of content field should not be empty All content
+   * fields should match the pattern
+   * {@link
+   * com.epam.ta.reportportal.core.widget.util.ContentFieldPatternConstants#COMBINED_CONTENT_FIELDS_REGEX}
+   *
+   * @param contentFields List of provided content.
+   */
+  private void validateContentFields(List<String> contentFields) {
+    expect(CollectionUtils.isNotEmpty(contentFields), equalTo(true)).verify(
+        ErrorType.BAD_REQUEST_ERROR,
+        "Content fields should not be empty"
+    );
+    expect(ContentFieldMatcherUtil.match(COMBINED_CONTENT_FIELDS_REGEX, contentFields),
+        equalTo(true)
+    ).verify(ErrorType.BAD_REQUEST_ERROR, "Bad content fields format");
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/FlakyCasesTableContentValidator.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/FlakyCasesTableContentValidator.java
index d9b8c8ad60..5bd00c4856 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/FlakyCasesTableContentValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/FlakyCasesTableContentValidator.java
@@ -16,22 +16,21 @@
 
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LAUNCH_NAME_FIELD;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.core.widget.util.WidgetOptionUtil;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.List;
+import java.util.Map;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LAUNCH_NAME_FIELD;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
@@ -48,7 +47,7 @@ public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMap
     /**
      * Mapping should not be empty
      *
-     * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as value for each filter
+     * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as* value for each filter
      */
     private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
         BusinessRule.expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true))
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchExecutionAndIssueStatisticsContentValidator.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchExecutionAndIssueStatisticsContentValidator.java
index f67f6991a4..c3520738cd 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchExecutionAndIssueStatisticsContentValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchExecutionAndIssueStatisticsContentValidator.java
@@ -16,55 +16,58 @@
 
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import static com.epam.ta.reportportal.core.widget.util.ContentFieldPatternConstants.COMBINED_CONTENT_FIELDS_REGEX;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.core.widget.util.ContentFieldMatcherUtil;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.List;
+import java.util.Map;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-import static com.epam.ta.reportportal.core.widget.util.ContentFieldPatternConstants.COMBINED_CONTENT_FIELDS_REGEX;
-
 /**
  * @author Pavel Bortnik
  */
 @Service
 public class LaunchExecutionAndIssueStatisticsContentValidator implements WidgetValidatorStrategy {
 
-	@Override
-	public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions, int limit) {
-		validateFilterSortMapping(filterSortMapping);
-		validateContentFields(contentFields);
-	}
+  @Override
+  public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions, int limit) {
+    validateFilterSortMapping(filterSortMapping);
+    validateContentFields(contentFields);
+  }
 
-	/**
-	 * Mapping should not be empty
-	 *
-	 * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as value for each filter
-	 */
-	private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
-		BusinessRule.expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true))
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Filter-Sort mapping should not be empty");
-	}
+  /**
+   * Mapping should not be empty
+   *
+   * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as
+   *                          value for each filter
+   */
+  private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
+    BusinessRule.expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true))
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Filter-Sort mapping should not be empty");
+  }
 
-	/**
-	 * Validate provided content fields.
-	 * The value of content field should not be empty
-	 * All content fields should match the pattern {@link com.epam.ta.reportportal.core.widget.util.ContentFieldPatternConstants#COMBINED_CONTENT_FIELDS_REGEX}
-	 *
-	 * @param contentFields List of provided content.
-	 */
-	private void validateContentFields(List<String> contentFields) {
-		BusinessRule.expect(CollectionUtils.isNotEmpty(contentFields), equalTo(true))
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Content fields should not be empty");
-		BusinessRule.expect(ContentFieldMatcherUtil.match(COMBINED_CONTENT_FIELDS_REGEX, contentFields), equalTo(true))
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Bad content fields format");
-	}
+  /**
+   * Validate provided content fields. The value of content field should not be empty All content
+   * fields should match the pattern
+   * {@link
+   * com.epam.ta.reportportal.core.widget.util.ContentFieldPatternConstants#COMBINED_CONTENT_FIELDS_REGEX}
+   *
+   * @param contentFields List of provided content.
+   */
+  private void validateContentFields(List<String> contentFields) {
+    BusinessRule.expect(CollectionUtils.isNotEmpty(contentFields), equalTo(true))
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Content fields should not be empty");
+    BusinessRule.expect(ContentFieldMatcherUtil.match(COMBINED_CONTENT_FIELDS_REGEX, contentFields),
+            equalTo(true))
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Bad content fields format");
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchesComparisonContentValidator.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchesComparisonContentValidator.java
index 9071a6b0bd..24e5b15175 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchesComparisonContentValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchesComparisonContentValidator.java
@@ -16,56 +16,59 @@
 
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import static com.epam.ta.reportportal.core.widget.util.ContentFieldPatternConstants.COMBINED_CONTENT_FIELDS_REGEX;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.core.widget.util.ContentFieldMatcherUtil;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.List;
+import java.util.Map;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-import static com.epam.ta.reportportal.core.widget.util.ContentFieldPatternConstants.COMBINED_CONTENT_FIELDS_REGEX;
-
 /**
  * @author Pavel Bortnik
  */
 @Service
 public class LaunchesComparisonContentValidator implements WidgetValidatorStrategy {
 
-	@Override
-	public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions, int limit) {
-		validateFilterSortMapping(filterSortMapping);
-		validateContentFields(contentFields);
-	}
+  @Override
+  public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions, int limit) {
+    validateFilterSortMapping(filterSortMapping);
+    validateContentFields(contentFields);
+  }
 
-	/**
-	 * Mapping should not be empty
-	 *
-	 * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as value for each filter
-	 */
-	private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
-		BusinessRule.expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true))
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Filter-Sort mapping should not be empty");
-	}
+  /**
+   * Mapping should not be empty
+   *
+   * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as
+   *                          value for each filter
+   */
+  private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
+    BusinessRule.expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true))
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Filter-Sort mapping should not be empty");
+  }
 
-	/**
-	 * Validate provided content fields.
-	 * The value of content field should not be empty
-	 * All content fields should match the pattern {@link com.epam.ta.reportportal.core.widget.util.ContentFieldPatternConstants#COMBINED_CONTENT_FIELDS_REGEX}
-	 *
-	 * @param contentFields List of provided content.
-	 */
-	private void validateContentFields(List<String> contentFields) {
-		BusinessRule.expect(CollectionUtils.isNotEmpty(contentFields), equalTo(true))
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Content fields should not be empty");
-		BusinessRule.expect(ContentFieldMatcherUtil.match(COMBINED_CONTENT_FIELDS_REGEX, contentFields), equalTo(true))
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Bad content fields format");
-	}
+  /**
+   * Validate provided content fields. The value of content field should not be empty All content
+   * fields should match the pattern
+   * {@link
+   * com.epam.ta.reportportal.core.widget.util.ContentFieldPatternConstants#COMBINED_CONTENT_FIELDS_REGEX}
+   *
+   * @param contentFields List of provided content.
+   */
+  private void validateContentFields(List<String> contentFields) {
+    BusinessRule.expect(CollectionUtils.isNotEmpty(contentFields), equalTo(true))
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Content fields should not be empty");
+    BusinessRule.expect(ContentFieldMatcherUtil.match(COMBINED_CONTENT_FIELDS_REGEX, contentFields),
+            equalTo(true))
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Bad content fields format");
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchesDurationContentValidator.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchesDurationContentValidator.java
index 71beabf5bc..7419b57e7e 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchesDurationContentValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchesDurationContentValidator.java
@@ -16,38 +16,39 @@
 
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.List;
+import java.util.Map;
 import org.apache.commons.collections.MapUtils;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-
 /**
  * @author Pavel Bortnik
  */
 @Service
 public class LaunchesDurationContentValidator implements WidgetValidatorStrategy {
 
-	@Override
-	public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions, int limit) {
-		validateFilterSortMapping(filterSortMapping);
-	}
-
-	/**
-	 * Mapping should not be empty
-	 *
-	 * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as value for each filter
-	 */
-	private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
-		BusinessRule.expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true))
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Filter-Sort mapping should not be empty");
-	}
+  @Override
+  public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions, int limit) {
+    validateFilterSortMapping(filterSortMapping);
+  }
+
+  /**
+   * Mapping should not be empty
+   *
+   * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as
+   *                          value for each filter
+   */
+  private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
+    BusinessRule.expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true))
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Filter-Sort mapping should not be empty");
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchesTableContentValidator.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchesTableContentValidator.java
index 2e59de36a0..56eae71d8a 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchesTableContentValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchesTableContentValidator.java
@@ -16,50 +16,50 @@
 
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.List;
+import java.util.Map;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-
 /**
  * @author Pavel Bortnik
  */
 @Service
 public class LaunchesTableContentValidator implements WidgetValidatorStrategy {
 
-	@Override
-	public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions, int limit) {
-		validateFilterSortMapping(filterSortMapping);
-		validateContentFields(contentFields);
-	}
+  @Override
+  public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions, int limit) {
+    validateFilterSortMapping(filterSortMapping);
+    validateContentFields(contentFields);
+  }
 
-	/**
-	 * Mapping should not be empty
-	 *
-	 * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as value for each filter
-	 */
-	private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
-		BusinessRule.expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true))
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Filter-Sort mapping should not be empty");
-	}
+  /**
+   * Mapping should not be empty
+   *
+   * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as
+   *                          value for each filter
+   */
+  private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
+    BusinessRule.expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true))
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Filter-Sort mapping should not be empty");
+  }
 
-	/**
-	 * Validate provided content fields.
-	 * The value of content field should not be empty
-	 *
-	 * @param contentFields List of provided content.
-	 */
-	private void validateContentFields(List<String> contentFields) {
-		BusinessRule.expect(CollectionUtils.isNotEmpty(contentFields), equalTo(true))
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Content fields should not be empty");
-	}
+  /**
+   * Validate provided content fields. The value of content field should not be empty
+   *
+   * @param contentFields List of provided content.
+   */
+  private void validateContentFields(List<String> contentFields) {
+    BusinessRule.expect(CollectionUtils.isNotEmpty(contentFields), equalTo(true))
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Content fields should not be empty");
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LineChartContentValidator.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LineChartContentValidator.java
index 0f4381ee75..dd2ea8f2e7 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LineChartContentValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LineChartContentValidator.java
@@ -16,55 +16,58 @@
 
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import static com.epam.ta.reportportal.core.widget.util.ContentFieldPatternConstants.COMBINED_CONTENT_FIELDS_REGEX;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.core.widget.util.ContentFieldMatcherUtil;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.List;
+import java.util.Map;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-import static com.epam.ta.reportportal.core.widget.util.ContentFieldPatternConstants.COMBINED_CONTENT_FIELDS_REGEX;
-
 /**
  * @author Pavel Bortnik
  */
 @Service
 public class LineChartContentValidator implements WidgetValidatorStrategy {
 
-	@Override
-	public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions, int limit) {
-		validateFilterSortMapping(filterSortMapping);
-		validateContentFields(contentFields);
-	}
+  @Override
+  public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions, int limit) {
+    validateFilterSortMapping(filterSortMapping);
+    validateContentFields(contentFields);
+  }
 
-	/**
-	 * Mapping should not be empty
-	 *
-	 * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as value for each filter
-	 */
-	private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
-		BusinessRule.expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true))
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Filter-Sort mapping should not be empty");
-	}
+  /**
+   * Mapping should not be empty
+   *
+   * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as
+   *                          value for each filter
+   */
+  private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
+    BusinessRule.expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true))
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Filter-Sort mapping should not be empty");
+  }
 
-	/**
-	 * Validate provided content fields.
-	 * The value of content field should not be empty
-	 * All content fields should match the pattern {@link com.epam.ta.reportportal.core.widget.util.ContentFieldPatternConstants#COMBINED_CONTENT_FIELDS_REGEX}
-	 *
-	 * @param contentFields List of provided content.
-	 */
-	private void validateContentFields(List<String> contentFields) {
-		BusinessRule.expect(CollectionUtils.isNotEmpty(contentFields), equalTo(true))
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Content fields should not be empty");
-		BusinessRule.expect(ContentFieldMatcherUtil.match(COMBINED_CONTENT_FIELDS_REGEX, contentFields), equalTo(true))
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Bad content fields format");
-	}
+  /**
+   * Validate provided content fields. The value of content field should not be empty All content
+   * fields should match the pattern
+   * {@link
+   * com.epam.ta.reportportal.core.widget.util.ContentFieldPatternConstants#COMBINED_CONTENT_FIELDS_REGEX}
+   *
+   * @param contentFields List of provided content.
+   */
+  private void validateContentFields(List<String> contentFields) {
+    BusinessRule.expect(CollectionUtils.isNotEmpty(contentFields), equalTo(true))
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Content fields should not be empty");
+    BusinessRule.expect(ContentFieldMatcherUtil.match(COMBINED_CONTENT_FIELDS_REGEX, contentFields),
+            equalTo(true))
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Bad content fields format");
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/MostTimeConsumingContentValidator.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/MostTimeConsumingContentValidator.java
index 139862dcad..6764f9062e 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/MostTimeConsumingContentValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/MostTimeConsumingContentValidator.java
@@ -16,52 +16,55 @@
 
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LAUNCH_NAME_FIELD;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.core.widget.util.WidgetOptionUtil;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.List;
+import java.util.Map;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LAUNCH_NAME_FIELD;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class MostTimeConsumingContentValidator implements WidgetValidatorStrategy {
 
-	@Override
-	public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMap, WidgetOptions widgetOptions, int limit) {
-		validateFilterSortMapping(filterSortMap);
-		validateWidgetOptions(widgetOptions);
-	}
+  @Override
+  public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMap,
+      WidgetOptions widgetOptions, int limit) {
+    validateFilterSortMapping(filterSortMap);
+    validateWidgetOptions(widgetOptions);
+  }
 
-	/**
-	 * Mapping should not be empty
-	 *
-	 * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as value for each filter
-	 */
-	private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
-		BusinessRule.expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true))
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Filter-Sort mapping should not be empty");
-	}
+  /**
+   * Mapping should not be empty
+   *
+   * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as
+   *                          value for each filter
+   */
+  private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
+    BusinessRule.expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true))
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Filter-Sort mapping should not be empty");
+  }
 
-	/**
-	 * Validate provided widget options. For current widget launch name should be specified.
-	 *
-	 * @param widgetOptions Map of stored widget options.
-	 */
-	private void validateWidgetOptions(WidgetOptions widgetOptions) {
-		BusinessRule.expect(WidgetOptionUtil.getValueByKey(LAUNCH_NAME_FIELD, widgetOptions), StringUtils::isNotBlank)
-				.verify(ErrorType.UNABLE_LOAD_WIDGET_CONTENT, LAUNCH_NAME_FIELD + " should be specified for widget.");
-	}
+  /**
+   * Validate provided widget options. For current widget launch name should be specified.
+   *
+   * @param widgetOptions Map of stored widget options.
+   */
+  private void validateWidgetOptions(WidgetOptions widgetOptions) {
+    BusinessRule.expect(WidgetOptionUtil.getValueByKey(LAUNCH_NAME_FIELD, widgetOptions),
+            StringUtils::isNotBlank)
+        .verify(ErrorType.UNABLE_LOAD_WIDGET_CONTENT,
+            LAUNCH_NAME_FIELD + " should be specified for widget.");
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/MultilevelValidatorStrategy.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/MultilevelValidatorStrategy.java
index 9bc705678e..ae4737f04b 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/MultilevelValidatorStrategy.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/MultilevelValidatorStrategy.java
@@ -2,12 +2,13 @@
 
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
-import org.springframework.data.domain.Sort;
-
 import java.util.List;
 import java.util.Map;
+import org.springframework.data.domain.Sort;
 
 public interface MultilevelValidatorStrategy {
-	void validate(List<String> contentFields, Map<Filter, Sort> filterSortMap, WidgetOptions widgetOptions,
-			String[] attributes, Map<String, String> params, int limit);
+
+  void validate(List<String> contentFields, Map<Filter, Sort> filterSortMap,
+      WidgetOptions widgetOptions,
+      String[] attributes, Map<String, String> params, int limit);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/NotPassedTestsContentValidator.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/NotPassedTestsContentValidator.java
index b0c05e8d68..ce922ca15d 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/NotPassedTestsContentValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/NotPassedTestsContentValidator.java
@@ -16,37 +16,38 @@
 
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.List;
+import java.util.Map;
 import org.apache.commons.collections.MapUtils;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-
 /**
  * @author Pavel Bortnik
  */
 @Service
 public class NotPassedTestsContentValidator implements WidgetValidatorStrategy {
 
-	@Override
-	public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions, int limit) {
-		validateFilterSortMapping(filterSortMapping);
-	}
+  @Override
+  public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions, int limit) {
+    validateFilterSortMapping(filterSortMapping);
+  }
 
-	/**
-	 * Mapping should not be empty
-	 *
-	 * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as value for each filter
-	 */
-	private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
-		BusinessRule.expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true))
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Filter-Sort mapping should not be empty");
-	}
+  /**
+   * Mapping should not be empty
+   *
+   * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as
+   *                          value for each filter
+   */
+  private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
+    BusinessRule.expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true))
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Filter-Sort mapping should not be empty");
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/OverallStatisticsContentValidator.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/OverallStatisticsContentValidator.java
index 7ab2d1c2ee..1d7a6652a2 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/OverallStatisticsContentValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/OverallStatisticsContentValidator.java
@@ -16,39 +16,39 @@
 
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.List;
+import java.util.Map;
 import org.apache.commons.collections.CollectionUtils;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-
 /**
  * @author Pavel Bortnik
  */
 @Service
 public class OverallStatisticsContentValidator implements WidgetValidatorStrategy {
 
-	@Override
-	public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions, int limit) {
-		validateContentFields(contentFields);
-	}
+  @Override
+  public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions, int limit) {
+    validateContentFields(contentFields);
+  }
 
-	/**
-	 * Validate provided content fields.
-	 * <p>
-	 * The value of at least one of the content fields should not be empty
-	 *
-	 * @param contentFields List of provided content.
-	 */
-	private void validateContentFields(List<String> contentFields) {
-		BusinessRule.expect(CollectionUtils.isNotEmpty(contentFields), equalTo(true))
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Content fields should not be empty");
-	}
+  /**
+   * Validate provided content fields.
+   * <p>
+   * The value of at least one of the content fields should not be empty
+   *
+   * @param contentFields List of provided content.
+   */
+  private void validateContentFields(List<String> contentFields) {
+    BusinessRule.expect(CollectionUtils.isNotEmpty(contentFields), equalTo(true))
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Content fields should not be empty");
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/PassingRatePerLaunchContentValidator.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/PassingRatePerLaunchContentValidator.java
index 0f869ceac5..4b6dca07e4 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/PassingRatePerLaunchContentValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/PassingRatePerLaunchContentValidator.java
@@ -16,52 +16,55 @@
 
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LAUNCH_NAME_FIELD;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.core.widget.util.WidgetOptionUtil;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.List;
+import java.util.Map;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LAUNCH_NAME_FIELD;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class PassingRatePerLaunchContentValidator implements WidgetValidatorStrategy {
 
-	@Override
-	public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions, int limit) {
-		validateFilterSortMapping(filterSortMapping);
-		validateWidgetOptions(widgetOptions);
-	}
+  @Override
+  public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions, int limit) {
+    validateFilterSortMapping(filterSortMapping);
+    validateWidgetOptions(widgetOptions);
+  }
 
-	/**
-	 * Mapping should not be empty
-	 *
-	 * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as value for each filter
-	 */
-	private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
-		BusinessRule.expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true))
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Filter-Sort mapping should not be empty");
-	}
+  /**
+   * Mapping should not be empty
+   *
+   * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as
+   *                          value for each filter
+   */
+  private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
+    BusinessRule.expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true))
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Filter-Sort mapping should not be empty");
+  }
 
-	/**
-	 * Validate provided widget options. For current widget launch name should be specified.
-	 *
-	 * @param widgetOptions Map of stored widget options.
-	 */
-	private void validateWidgetOptions(WidgetOptions widgetOptions) {
-		BusinessRule.expect(WidgetOptionUtil.getValueByKey(LAUNCH_NAME_FIELD, widgetOptions), StringUtils::isNotEmpty)
-				.verify(ErrorType.UNABLE_LOAD_WIDGET_CONTENT, LAUNCH_NAME_FIELD + " should be specified for widget.");
-	}
+  /**
+   * Validate provided widget options. For current widget launch name should be specified.
+   *
+   * @param widgetOptions Map of stored widget options.
+   */
+  private void validateWidgetOptions(WidgetOptions widgetOptions) {
+    BusinessRule.expect(WidgetOptionUtil.getValueByKey(LAUNCH_NAME_FIELD, widgetOptions),
+            StringUtils::isNotEmpty)
+        .verify(ErrorType.UNABLE_LOAD_WIDGET_CONTENT,
+            LAUNCH_NAME_FIELD + " should be specified for widget.");
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/PassingRateSummaryContentValidator.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/PassingRateSummaryContentValidator.java
index 31d1bc819b..bf23857362 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/PassingRateSummaryContentValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/PassingRateSummaryContentValidator.java
@@ -16,38 +16,39 @@
 
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.List;
+import java.util.Map;
 import org.apache.commons.collections.MapUtils;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class PassingRateSummaryContentValidator implements WidgetValidatorStrategy {
 
-	@Override
-	public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions, int limit) {
-		validateFilterSortMapping(filterSortMapping);
-	}
-
-	/**
-	 * Mapping should not be empty
-	 *
-	 * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as value for each filter
-	 */
-	private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
-		BusinessRule.expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true))
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Filter-Sort mapping should not be empty");
-	}
+  @Override
+  public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions, int limit) {
+    validateFilterSortMapping(filterSortMapping);
+  }
+
+  /**
+   * Mapping should not be empty
+   *
+   * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as
+   *                          value for each filter
+   */
+  private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
+    BusinessRule.expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true))
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Filter-Sort mapping should not be empty");
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/ProductStatusContentValidator.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/ProductStatusContentValidator.java
index 7f158a176f..2c0aa0d1d1 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/ProductStatusContentValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/ProductStatusContentValidator.java
@@ -1,49 +1,52 @@
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.List;
+import java.util.Map;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class ProductStatusContentValidator implements WidgetValidatorStrategy {
-	@Override
-	public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMap, WidgetOptions widgetOptions, int limit) {
-		validateFilterSortMapping(filterSortMap);
-		validateContentFields(contentFields);
-	}
 
-	/**
-	 * Mapping should not be empty
-	 *
-	 * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as value for each filter
-	 */
-	private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
-		BusinessRule.expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true))
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Filter-Sort mapping should not be empty");
-	}
+  @Override
+  public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMap,
+      WidgetOptions widgetOptions, int limit) {
+    validateFilterSortMapping(filterSortMap);
+    validateContentFields(contentFields);
+  }
+
+  /**
+   * Mapping should not be empty
+   *
+   * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as
+   *                          value for each filter
+   */
+  private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
+    BusinessRule.expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true))
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Filter-Sort mapping should not be empty");
+  }
 
-	/**
-	 * Validate provided content fields.
-	 * The value of content field should not be empty
-	 * All content fields should match the pattern {@link com.epam.ta.reportportal.core.widget.util.ContentFieldPatternConstants#COMBINED_CONTENT_FIELDS_REGEX}
-	 *
-	 * @param contentFields List of provided content.
-	 */
-	private void validateContentFields(List<String> contentFields) {
-		BusinessRule.expect(CollectionUtils.isNotEmpty(contentFields), equalTo(true))
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Content fields should not be empty");
-	}
+  /**
+   * Validate provided content fields. The value of content field should not be empty All content
+   * fields should match the pattern
+   * {@link
+   * com.epam.ta.reportportal.core.widget.util.ContentFieldPatternConstants#COMBINED_CONTENT_FIELDS_REGEX}
+   *
+   * @param contentFields List of provided content.
+   */
+  private void validateContentFields(List<String> contentFields) {
+    BusinessRule.expect(CollectionUtils.isNotEmpty(contentFields), equalTo(true))
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Content fields should not be empty");
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/TopPatternContentValidator.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/TopPatternContentValidator.java
index bd1db7fc92..636166d07c 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/TopPatternContentValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/TopPatternContentValidator.java
@@ -16,40 +16,42 @@
 
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.List;
+import java.util.Map;
 import org.apache.commons.collections.MapUtils;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class TopPatternContentValidator implements MultilevelValidatorStrategy {
 
-	@Override
-	public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions, String[] attributes,
-			Map<String, String> params, int limit) {
-
-		validateFilterSortMapping(filterSortMapping);
-	}
-
-	/**
-	 * Mapping should not be empty
-	 *
-	 * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as value for each filter
-	 */
-	private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
-		expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true)).verify(ErrorType.BAD_REQUEST_ERROR,
-				"Filter-Sort mapping should not be empty"
-		);
-	}
+  @Override
+  public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions, String[] attributes,
+      Map<String, String> params, int limit) {
+
+    validateFilterSortMapping(filterSortMapping);
+  }
+
+  /**
+   * Mapping should not be empty
+   *
+   * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as
+   *                          value for each filter
+   */
+  private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
+    expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true)).verify(
+        ErrorType.BAD_REQUEST_ERROR,
+        "Filter-Sort mapping should not be empty"
+    );
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/TopTestCasesContentValidator.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/TopTestCasesContentValidator.java
index b80fee461b..52c976971b 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/TopTestCasesContentValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/TopTestCasesContentValidator.java
@@ -16,19 +16,18 @@
 
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.ws.model.ErrorType;
-import org.apache.commons.collections.CollectionUtils;
-import org.springframework.data.domain.Sort;
-import org.springframework.stereotype.Service;
-
 import java.util.List;
 import java.util.Map;
 import java.util.function.Predicate;
-
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.data.domain.Sort;
+import org.springframework.stereotype.Service;
 
 /**
  * Content loader for {@link com.epam.ta.reportportal.entity.widget.WidgetType#TOP_TEST_CASES}
@@ -44,18 +43,19 @@ public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMap
         validateWidgetLimit(limit);
 	}
 
-	/**
-	 * Validate provided content fields. For current widget it should be only one field specified in content fields.
-	 * Example is 'executions$failed', so widget would be created by 'failed' criteria.
-	 *
-	 * @param contentFields List of provided content.
-	 */
-	private void validateContentFields(List<String> contentFields) {
-		BusinessRule.expect(CollectionUtils.isNotEmpty(contentFields), equalTo(true))
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Content fields should not be empty");
-		BusinessRule.expect(contentFields.size(), Predicate.isEqual(1))
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Only one content field could be specified.");
-	}
+  /**
+   * Validate provided content fields. For current widget it should be only one field specified in
+   * content fields. Example is 'executions$failed', so widget would be created by 'failed'
+   * criteria.
+   *
+   * @param contentFields List of provided content.
+   */
+  private void validateContentFields(List<String> contentFields) {
+    BusinessRule.expect(CollectionUtils.isNotEmpty(contentFields), equalTo(true))
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Content fields should not be empty");
+    BusinessRule.expect(contentFields.size(), Predicate.isEqual(1))
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Only one content field could be specified.");
+  }
 
     /**
      * Validate provided widget launches count. For current widget launches count should in the range from 2 to 100.
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/UniqueBugContentValidator.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/UniqueBugContentValidator.java
index 6c00b19dd6..7c0066a3fb 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/UniqueBugContentValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/UniqueBugContentValidator.java
@@ -16,38 +16,39 @@
 
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.List;
+import java.util.Map;
 import org.apache.commons.collections.MapUtils;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-
 /**
  * @author Pavel Bortnik
  */
 @Service
 public class UniqueBugContentValidator implements WidgetValidatorStrategy {
 
-	@Override
-	public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping, WidgetOptions widgetOptions, int limit) {
-		validateFilterSortMapping(filterSortMapping);
-	}
-
-	/**
-	 * Mapping should not be empty
-	 *
-	 * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as value for each filter
-	 */
-	private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
-		BusinessRule.expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true))
-				.verify(ErrorType.BAD_REQUEST_ERROR, "Filter-Sort mapping should not be empty");
-	}
+  @Override
+  public void validate(List<String> contentFields, Map<Filter, Sort> filterSortMapping,
+      WidgetOptions widgetOptions, int limit) {
+    validateFilterSortMapping(filterSortMapping);
+  }
+
+  /**
+   * Mapping should not be empty
+   *
+   * @param filterSortMapping Map of ${@link Filter} for query building as key and ${@link Sort} as
+   *                          value for each filter
+   */
+  private void validateFilterSortMapping(Map<Filter, Sort> filterSortMapping) {
+    BusinessRule.expect(MapUtils.isNotEmpty(filterSortMapping), equalTo(true))
+        .verify(ErrorType.BAD_REQUEST_ERROR, "Filter-Sort mapping should not be empty");
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/WidgetContentFieldsValidator.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/WidgetContentFieldsValidator.java
index 484c5aad1d..9482202977 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/WidgetContentFieldsValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/WidgetContentFieldsValidator.java
@@ -1,69 +1,71 @@
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
+
 import com.epam.ta.reportportal.core.widget.content.BuildFilterStrategy;
 import com.epam.ta.reportportal.entity.widget.Widget;
 import com.epam.ta.reportportal.entity.widget.WidgetType;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.google.common.collect.Lists;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Component;
 
-import java.util.Map;
-
-import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
-
 @Component("widgetContentFieldsValidator")
 public class WidgetContentFieldsValidator implements WidgetValidator {
 
-	private Map<WidgetType, BuildFilterStrategy> buildFilterStrategyMapping;
+  private Map<WidgetType, BuildFilterStrategy> buildFilterStrategyMapping;
 
-	private Map<WidgetType, WidgetValidatorStrategy> widgetValidatorLoader;
+  private Map<WidgetType, WidgetValidatorStrategy> widgetValidatorLoader;
 
-	private Map<WidgetType, MultilevelValidatorStrategy> multilevelValidatorLoader;
+  private Map<WidgetType, MultilevelValidatorStrategy> multilevelValidatorLoader;
 
-	@Autowired
-	@Qualifier("buildFilterStrategy")
-	public void setBuildFilterStrategy(Map<WidgetType, BuildFilterStrategy> buildFilterStrategyMapping) {
-		this.buildFilterStrategyMapping = buildFilterStrategyMapping;
-	}
+  @Autowired
+  @Qualifier("buildFilterStrategy")
+  public void setBuildFilterStrategy(
+      Map<WidgetType, BuildFilterStrategy> buildFilterStrategyMapping) {
+    this.buildFilterStrategyMapping = buildFilterStrategyMapping;
+  }
 
-	@Autowired
-	@Qualifier("widgetValidatorLoader")
-	public void setWidgetValidatorLoader(Map<WidgetType, WidgetValidatorStrategy> widgetValidatorLoader) {
-		this.widgetValidatorLoader = widgetValidatorLoader;
-	}
+  @Autowired
+  @Qualifier("widgetValidatorLoader")
+  public void setWidgetValidatorLoader(
+      Map<WidgetType, WidgetValidatorStrategy> widgetValidatorLoader) {
+    this.widgetValidatorLoader = widgetValidatorLoader;
+  }
 
-	@Autowired
-	@Qualifier("multilevelValidatorLoader")
-	public void setMultilevelValidatorLoader(Map<WidgetType, MultilevelValidatorStrategy> multilevelValidatorLoader) {
-		this.multilevelValidatorLoader = multilevelValidatorLoader;
-	}
+  @Autowired
+  @Qualifier("multilevelValidatorLoader")
+  public void setMultilevelValidatorLoader(
+      Map<WidgetType, MultilevelValidatorStrategy> multilevelValidatorLoader) {
+    this.multilevelValidatorLoader = multilevelValidatorLoader;
+  }
 
-	@Override
-	public void validate(Widget widget) {
-		WidgetType widgetType = WidgetType.findByName(widget.getWidgetType())
-				.orElseThrow(() -> new ReportPortalException(ErrorType.INCORRECT_REQUEST,
-						formattedSupplier("Unsupported widget type '{}'", widget.getWidgetType())
-				));
+  @Override
+  public void validate(Widget widget) {
+    WidgetType widgetType = WidgetType.findByName(widget.getWidgetType())
+        .orElseThrow(() -> new ReportPortalException(ErrorType.INCORRECT_REQUEST,
+            formattedSupplier("Unsupported widget type '{}'", widget.getWidgetType())
+        ));
 
-		if (widgetType.isSupportMultilevelStructure()) {
-			multilevelValidatorLoader.get(widgetType)
-					.validate(Lists.newArrayList(widget.getContentFields()),
-							buildFilterStrategyMapping.get(widgetType).buildFilter(widget),
-							widget.getWidgetOptions(),
-							null,
-							null,
-							widget.getItemsCount()
-					);
-		} else {
-			widgetValidatorLoader.get(widgetType)
-					.validate(Lists.newArrayList(widget.getContentFields()),
-							buildFilterStrategyMapping.get(widgetType).buildFilter(widget),
-							widget.getWidgetOptions(),
-							widget.getItemsCount()
-					);
-		}
-	}
+    if (widgetType.isSupportMultilevelStructure()) {
+      multilevelValidatorLoader.get(widgetType)
+          .validate(Lists.newArrayList(widget.getContentFields()),
+              buildFilterStrategyMapping.get(widgetType).buildFilter(widget),
+              widget.getWidgetOptions(),
+              null,
+              null,
+              widget.getItemsCount()
+          );
+    } else {
+      widgetValidatorLoader.get(widgetType)
+          .validate(Lists.newArrayList(widget.getContentFields()),
+              buildFilterStrategyMapping.get(widgetType).buildFilter(widget),
+              widget.getWidgetOptions(),
+              widget.getItemsCount()
+          );
+    }
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/WidgetValidator.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/WidgetValidator.java
index fe236452a8..e4f0604c2d 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/WidgetValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/WidgetValidator.java
@@ -4,5 +4,5 @@
 
 public interface WidgetValidator {
 
-	void validate(Widget widget);
+  void validate(Widget widget);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/WidgetValidatorStrategy.java b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/WidgetValidatorStrategy.java
index acb7e55555..6d06e6e3a7 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/WidgetValidatorStrategy.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/content/updater/validator/WidgetValidatorStrategy.java
@@ -2,10 +2,9 @@
 
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
-import org.springframework.data.domain.Sort;
-
 import java.util.List;
 import java.util.Map;
+import org.springframework.data.domain.Sort;
 
 /**
  * Interface for widget parameters validation.
@@ -14,5 +13,6 @@
  */
 public interface WidgetValidatorStrategy {
 
-	void validate(List<String> contentFields, Map<Filter, Sort> filterSortMap, WidgetOptions widgetOptions, int limit);
+  void validate(List<String> contentFields, Map<Filter, Sort> filterSortMap,
+      WidgetOptions widgetOptions, int limit);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/util/ContentFieldMatcherUtil.java b/src/main/java/com/epam/ta/reportportal/core/widget/util/ContentFieldMatcherUtil.java
index dd9a282a28..50395b0c1f 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/util/ContentFieldMatcherUtil.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/util/ContentFieldMatcherUtil.java
@@ -25,13 +25,13 @@
  */
 public final class ContentFieldMatcherUtil {
 
-	private ContentFieldMatcherUtil() {
-		//static only
-	}
+  private ContentFieldMatcherUtil() {
+    //static only
+  }
 
-	public static boolean match(final String patternValue, Collection<String> contentFields) {
-		Pattern pattern = Pattern.compile(patternValue);
-		return contentFields.stream().map(pattern::matcher).allMatch(Matcher::matches);
+  public static boolean match(final String patternValue, Collection<String> contentFields) {
+    Pattern pattern = Pattern.compile(patternValue);
+    return contentFields.stream().map(pattern::matcher).allMatch(Matcher::matches);
 
-	}
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/util/ContentFieldPatternConstants.java b/src/main/java/com/epam/ta/reportportal/core/widget/util/ContentFieldPatternConstants.java
index 31da00efbe..4be5380364 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/util/ContentFieldPatternConstants.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/util/ContentFieldPatternConstants.java
@@ -16,63 +16,73 @@
 
 package com.epam.ta.reportportal.core.widget.util;
 
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DEFECTS_KEY;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.EXECUTIONS_KEY;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.TOTAL;
+
 import com.epam.ta.reportportal.entity.enums.StatusEnum;
 import com.epam.ta.reportportal.entity.enums.TestItemIssueGroup;
-
 import java.util.Arrays;
 import java.util.stream.Collectors;
 
-import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.*;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  * <p>
- * Regex patterns for @{@link com.epam.ta.reportportal.entity.widget.Widget#contentFields} validation
+ * Regex patterns for @{@link com.epam.ta.reportportal.entity.widget.Widget#contentFields}
+ * validation
  */
 public final class ContentFieldPatternConstants {
 
-	private static final String CONTENT_FIELD_SPLITTER = "\\$";
-
-	static {
-
-		EXECUTIONS_REGEX = "^" + "statistics" + CONTENT_FIELD_SPLITTER + EXECUTIONS_KEY + CONTENT_FIELD_SPLITTER + "(" + Arrays.stream(
-				StatusEnum.values()).map(StatusEnum::getExecutionCounterField).collect(Collectors.joining("|")) + "|" + TOTAL + ")" + "$";
-
-		DEFECTS_REGEX = "^" + "statistics" + CONTENT_FIELD_SPLITTER + DEFECTS_KEY + CONTENT_FIELD_SPLITTER + "(" + Arrays.stream(
-				TestItemIssueGroup.values()).map(ig -> ig.getValue().toLowerCase()).collect(Collectors.joining("|")) + ")"
-				+ CONTENT_FIELD_SPLITTER + "[\\w\\d]+" + "$";
-	}
-
-	/*
-		^statistics\\$executions\\$total$
-	 */
-	public static final String EXECUTIONS_TOTAL_REGEX =
-			"^" + "statistics" + CONTENT_FIELD_SPLITTER + EXECUTIONS_KEY + CONTENT_FIELD_SPLITTER + TOTAL + "$";
-
-	/*
-		^statistics\\$executions\\$(passed|failed|skipped|total)$
-	 */
-	public static final String EXECUTIONS_REGEX;
-
-	/*
-		^statistics\\$executions\\$failed$
-	 */
-	public static final String EXECUTIONS_FAILED_REGEX =
-			"^" + "statistics" + CONTENT_FIELD_SPLITTER + EXECUTIONS_KEY + CONTENT_FIELD_SPLITTER
-					+ StatusEnum.FAILED.getExecutionCounterField() + "$";
-
-	/*
-		^statistics\\$defects\\$(automation_bug|product_bug|no_defect|system_issue|to_investigate)\\$[\\w\\d]+$
-	 */
-	public static final String DEFECTS_REGEX;
-
-	/*
-		((^statistics\\$defects\\$(automation_bug|product_bug|no_defect|system_issue|to_investigate)\\$[\\w\\d]+$)|(^statistics\\$executions\\$(passed|failed|skipped|total)$))
-	 */
-	public static final String COMBINED_CONTENT_FIELDS_REGEX = "(" + DEFECTS_REGEX + ")" + "|" + "(" + EXECUTIONS_REGEX + ")";
-
-	private ContentFieldPatternConstants() {
-		//static only
-	}
+  private static final String CONTENT_FIELD_SPLITTER = "\\$";
+
+  static {
+
+    EXECUTIONS_REGEX =
+        "^" + "statistics" + CONTENT_FIELD_SPLITTER + EXECUTIONS_KEY + CONTENT_FIELD_SPLITTER + "("
+            + Arrays.stream(
+                StatusEnum.values()).map(StatusEnum::getExecutionCounterField)
+            .collect(Collectors.joining("|")) + "|" + TOTAL + ")" + "$";
+
+    DEFECTS_REGEX =
+        "^" + "statistics" + CONTENT_FIELD_SPLITTER + DEFECTS_KEY + CONTENT_FIELD_SPLITTER + "("
+            + Arrays.stream(
+                TestItemIssueGroup.values()).map(ig -> ig.getValue().toLowerCase())
+            .collect(Collectors.joining("|")) + ")"
+            + CONTENT_FIELD_SPLITTER + "[\\w\\d]+" + "$";
+  }
+
+  /*
+    ^statistics\\$executions\\$total$
+   */
+  public static final String EXECUTIONS_TOTAL_REGEX =
+      "^" + "statistics" + CONTENT_FIELD_SPLITTER + EXECUTIONS_KEY + CONTENT_FIELD_SPLITTER + TOTAL
+          + "$";
+
+  /*
+    ^statistics\\$executions\\$(passed|failed|skipped|total)$
+   */
+  public static final String EXECUTIONS_REGEX;
+
+  /*
+    ^statistics\\$executions\\$failed$
+   */
+  public static final String EXECUTIONS_FAILED_REGEX =
+      "^" + "statistics" + CONTENT_FIELD_SPLITTER + EXECUTIONS_KEY + CONTENT_FIELD_SPLITTER
+          + StatusEnum.FAILED.getExecutionCounterField() + "$";
+
+  /*
+    ^statistics\\$defects\\$(automation_bug|product_bug|no_defect|system_issue|to_investigate)\\$[\\w\\d]+$
+   */
+  public static final String DEFECTS_REGEX;
+
+  /*
+    ((^statistics\\$defects\\$(automation_bug|product_bug|no_defect|system_issue|to_investigate)\\$[\\w\\d]+$)|(^statistics\\$executions\\$(passed|failed|skipped|total)$))
+   */
+  public static final String COMBINED_CONTENT_FIELDS_REGEX =
+      "(" + DEFECTS_REGEX + ")" + "|" + "(" + EXECUTIONS_REGEX + ")";
+
+  private ContentFieldPatternConstants() {
+    //static only
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/util/WidgetFilterUtil.java b/src/main/java/com/epam/ta/reportportal/core/widget/util/WidgetFilterUtil.java
index c97367978a..370bf584c2 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/util/WidgetFilterUtil.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/util/WidgetFilterUtil.java
@@ -16,40 +16,44 @@
 
 package com.epam.ta.reportportal.core.widget.util;
 
+import static java.util.Optional.ofNullable;
+import static java.util.stream.Collectors.toList;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.google.common.collect.Lists;
-import org.springframework.data.domain.Sort;
-
 import java.util.Collection;
 import java.util.Set;
 import java.util.function.Function;
-
-import static java.util.Optional.ofNullable;
-import static java.util.stream.Collectors.toList;
+import org.springframework.data.domain.Sort;
 
 /**
  * @author Pavel Bortnik
  */
 public class WidgetFilterUtil {
 
-	private WidgetFilterUtil() {
-		//static only
-	}
-
-	public static final Function<Set<Filter>, Filter> GROUP_FILTERS = filters -> {
-		Filter filter = ofNullable(filters).map(Collection::stream)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR, "Filters set should not be empty"))
-				.findFirst()
-				.orElseThrow(() -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR, "No filters for widget were found"));
-		filter.withConditions(filters.stream().map(Filter::getFilterConditions).flatMap(Collection::stream).collect(toList()));
-
-		return filter;
-	};
-
-	public static final Function<Collection<Sort>, Sort> GROUP_SORTS = sorts -> Sort.by(ofNullable(sorts).map(s -> s.stream()
-			.flatMap(sortStream -> Lists.newArrayList(sortStream.iterator()).stream())
-			.collect(toList())).orElseGet(Lists::newArrayList));
+  private WidgetFilterUtil() {
+    //static only
+  }
+
+  public static final Function<Set<Filter>, Filter> GROUP_FILTERS = filters -> {
+    Filter filter = ofNullable(filters).map(Collection::stream)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR,
+            "Filters set should not be empty"))
+        .findFirst()
+        .orElseThrow(() -> new ReportPortalException(ErrorType.BAD_REQUEST_ERROR,
+            "No filters for widget were found"));
+    filter.withConditions(
+        filters.stream().map(Filter::getFilterConditions).flatMap(Collection::stream)
+            .collect(toList()));
+
+    return filter;
+  };
+
+  public static final Function<Collection<Sort>, Sort> GROUP_SORTS = sorts -> Sort.by(
+      ofNullable(sorts).map(s -> s.stream()
+          .flatMap(sortStream -> Lists.newArrayList(sortStream.iterator()).stream())
+          .collect(toList())).orElseGet(Lists::newArrayList));
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/core/widget/util/WidgetOptionUtil.java b/src/main/java/com/epam/ta/reportportal/core/widget/util/WidgetOptionUtil.java
index 622d19fbeb..39a035942d 100644
--- a/src/main/java/com/epam/ta/reportportal/core/widget/util/WidgetOptionUtil.java
+++ b/src/main/java/com/epam/ta/reportportal/core/widget/util/WidgetOptionUtil.java
@@ -16,78 +16,88 @@
 
 package com.epam.ta.reportportal.core.widget.util;
 
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.validation.Suppliers;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
-import org.apache.commons.collections.MapUtils;
-import org.apache.commons.lang3.BooleanUtils;
-
-import javax.annotation.Nullable;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
-
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
-import static java.util.Optional.ofNullable;
+import javax.annotation.Nullable;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang3.BooleanUtils;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public final class WidgetOptionUtil {
 
-	private WidgetOptionUtil() {
-		//static only
-	}
-
-	@Nullable
-	public static String getValueByKey(String key, WidgetOptions widgetOptions) {
-
-		Optional<Object> value = ofNullable(widgetOptions).flatMap(wo -> ofNullable(wo.getOptions()).map(options -> options.get(key)));
-
-		value.ifPresent(v -> expect(v, String.class::isInstance).verify(ErrorType.OBJECT_RETRIEVAL_ERROR,
-				Suppliers.formattedSupplier("Wrong widget option value type for key = '{}'. String expected.", key)
-		));
-
-		return (String) value.orElse(null);
-	}
-
-	public static <K, V> Map<K, V> getMapByKey(String key, WidgetOptions widgetOptions) {
-		Optional<Object> value = ofNullable(widgetOptions).flatMap(wo -> ofNullable(wo.getOptions()).map(options -> options.get(key)));
-
-		value.ifPresent(v -> expect(v, Map.class::isInstance).verify(ErrorType.OBJECT_RETRIEVAL_ERROR,
-				Suppliers.formattedSupplier("Wrong widget option value type for key = '{}'. Map expected.", key)
-		));
-
-		return (Map<K, V>) value.orElseGet(Collections::emptyMap);
-	}
-
-	public static boolean getBooleanByKey(String key, WidgetOptions widgetOptions) {
-
-		return ofNullable(widgetOptions).map(wo -> MapUtils.isNotEmpty(wo.getOptions()) && ofNullable(wo.getOptions()
-				.get(key)).map(v -> BooleanUtils.toBoolean(String.valueOf(v))).orElse(false)).orElse(false);
-	}
-
-	public static Optional<Integer> getIntegerByKey(String key, WidgetOptions widgetOptions) {
-		return ofNullable(widgetOptions).flatMap(wo -> ofNullable(wo.getOptions()).map(options -> options.get(key))).map(value -> {
-			try {
-				return Integer.parseInt(String.valueOf(value));
-			} catch (NumberFormatException ex) {
-				throw new ReportPortalException(ErrorType.BAD_REQUEST_ERROR,
-						Suppliers.formattedSupplier("Error during parsing integer value of key = '{}'", key).get()
-				);
-			}
-		});
-	}
-
-	public static <T> List<T> getListByKey(String key, WidgetOptions widgetOptions) {
-		Optional<Object> value = ofNullable(widgetOptions).flatMap(wo -> ofNullable(wo.getOptions()).map(options -> options.get(key)));
-
-		value.ifPresent(v -> expect(v, List.class::isInstance).verify(ErrorType.OBJECT_RETRIEVAL_ERROR,
-				Suppliers.formattedSupplier("Wrong widget option value type for key = '{}'. List expected.", key)
-		));
-
-		return (List<T>) value.orElse(Collections.emptyList());
-	}
+  private WidgetOptionUtil() {
+    //static only
+  }
+
+  @Nullable
+  public static String getValueByKey(String key, WidgetOptions widgetOptions) {
+
+    Optional<Object> value = ofNullable(widgetOptions).flatMap(
+        wo -> ofNullable(wo.getOptions()).map(options -> options.get(key)));
+
+    value.ifPresent(
+        v -> expect(v, String.class::isInstance).verify(ErrorType.OBJECT_RETRIEVAL_ERROR,
+            Suppliers.formattedSupplier(
+                "Wrong widget option value type for key = '{}'. String expected.", key)
+        ));
+
+    return (String) value.orElse(null);
+  }
+
+  public static <K, V> Map<K, V> getMapByKey(String key, WidgetOptions widgetOptions) {
+    Optional<Object> value = ofNullable(widgetOptions).flatMap(
+        wo -> ofNullable(wo.getOptions()).map(options -> options.get(key)));
+
+    value.ifPresent(v -> expect(v, Map.class::isInstance).verify(ErrorType.OBJECT_RETRIEVAL_ERROR,
+        Suppliers.formattedSupplier("Wrong widget option value type for key = '{}'. Map expected.",
+            key)
+    ));
+
+    return (Map<K, V>) value.orElseGet(Collections::emptyMap);
+  }
+
+  public static boolean getBooleanByKey(String key, WidgetOptions widgetOptions) {
+
+    return ofNullable(widgetOptions).map(
+            wo -> MapUtils.isNotEmpty(wo.getOptions()) && ofNullable(wo.getOptions()
+                .get(key)).map(v -> BooleanUtils.toBoolean(String.valueOf(v))).orElse(false))
+        .orElse(false);
+  }
+
+  public static Optional<Integer> getIntegerByKey(String key, WidgetOptions widgetOptions) {
+    return ofNullable(widgetOptions).flatMap(
+        wo -> ofNullable(wo.getOptions()).map(options -> options.get(key))).map(value -> {
+      try {
+        return Integer.parseInt(String.valueOf(value));
+      } catch (NumberFormatException ex) {
+        throw new ReportPortalException(ErrorType.BAD_REQUEST_ERROR,
+            Suppliers.formattedSupplier("Error during parsing integer value of key = '{}'", key)
+                .get()
+        );
+      }
+    });
+  }
+
+  public static <T> List<T> getListByKey(String key, WidgetOptions widgetOptions) {
+    Optional<Object> value = ofNullable(widgetOptions).flatMap(
+        wo -> ofNullable(wo.getOptions()).map(options -> options.get(key)));
+
+    value.ifPresent(v -> expect(v, List.class::isInstance).verify(ErrorType.OBJECT_RETRIEVAL_ERROR,
+        Suppliers.formattedSupplier("Wrong widget option value type for key = '{}'. List expected.",
+            key)
+    ));
+
+    return (List<T>) value.orElse(Collections.emptyList());
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/demodata/model/DemoDataRq.java b/src/main/java/com/epam/ta/reportportal/demodata/model/DemoDataRq.java
index 892391e328..73b11af39a 100644
--- a/src/main/java/com/epam/ta/reportportal/demodata/model/DemoDataRq.java
+++ b/src/main/java/com/epam/ta/reportportal/demodata/model/DemoDataRq.java
@@ -22,22 +22,22 @@
 @JsonInclude(JsonInclude.Include.NON_NULL)
 public class DemoDataRq {
 
-	@JsonProperty(defaultValue = "true")
-	private boolean createDashboard = true;
+  @JsonProperty(defaultValue = "true")
+  private boolean createDashboard = true;
 
-	public boolean isCreateDashboard() {
-		return createDashboard;
-	}
+  public boolean isCreateDashboard() {
+    return createDashboard;
+  }
 
-	public void setCreateDashboard(boolean createDashboard) {
-		this.createDashboard = createDashboard;
-	}
+  public void setCreateDashboard(boolean createDashboard) {
+    this.createDashboard = createDashboard;
+  }
 
-	@Override
-	public String toString() {
-		final StringBuilder sb = new StringBuilder("DemoDataRq{");
-		sb.append("createDashboard=").append(createDashboard);
-		sb.append('}');
-		return sb.toString();
-	}
+  @Override
+  public String toString() {
+    final StringBuilder sb = new StringBuilder("DemoDataRq{");
+    sb.append("createDashboard=").append(createDashboard);
+    sb.append('}');
+    return sb.toString();
+  }
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/demodata/model/DemoDataRs.java b/src/main/java/com/epam/ta/reportportal/demodata/model/DemoDataRs.java
index 6b8ad738f4..9b5066d1f0 100644
--- a/src/main/java/com/epam/ta/reportportal/demodata/model/DemoDataRs.java
+++ b/src/main/java/com/epam/ta/reportportal/demodata/model/DemoDataRs.java
@@ -18,7 +18,6 @@
 
 import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.annotation.JsonProperty;
-
 import java.util.List;
 
 /**
@@ -27,25 +26,25 @@
 @JsonInclude(JsonInclude.Include.NON_NULL)
 public class DemoDataRs {
 
-	@JsonProperty
-	private Long dashboardId;
+  @JsonProperty
+  private Long dashboardId;
 
-	@JsonProperty
-	private List<Long> launchIds;
+  @JsonProperty
+  private List<Long> launchIds;
 
-	public Long getDashboardId() {
-		return dashboardId;
-	}
+  public Long getDashboardId() {
+    return dashboardId;
+  }
 
-	public void setDashboardId(Long dashboardId) {
-		this.dashboardId = dashboardId;
-	}
+  public void setDashboardId(Long dashboardId) {
+    this.dashboardId = dashboardId;
+  }
 
-	public List<Long> getLaunchIds() {
-		return launchIds;
-	}
+  public List<Long> getLaunchIds() {
+    return launchIds;
+  }
 
-	public void setLaunchIds(List<Long> launchIds) {
-		this.launchIds = launchIds;
-	}
+  public void setLaunchIds(List<Long> launchIds) {
+    this.launchIds = launchIds;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/demodata/model/DemoItemMetadata.java b/src/main/java/com/epam/ta/reportportal/demodata/model/DemoItemMetadata.java
index a11e2f1ae4..ec2631efd3 100644
--- a/src/main/java/com/epam/ta/reportportal/demodata/model/DemoItemMetadata.java
+++ b/src/main/java/com/epam/ta/reportportal/demodata/model/DemoItemMetadata.java
@@ -24,91 +24,91 @@
  */
 public class DemoItemMetadata {
 
-	private String name;
+  private String name;
 
-	private String parentId;
+  private String parentId;
 
-	private boolean retry;
+  private boolean retry;
 
-	private boolean nested;
+  private boolean nested;
 
-	private TestItemTypeEnum type;
+  private TestItemTypeEnum type;
 
-	private StatusEnum status;
+  private StatusEnum status;
 
-	private String issue;
+  private String issue;
 
-	private int logCount;
+  private int logCount;
 
-	public DemoItemMetadata withName(String name) {
-		this.name = name;
-		return this;
-	}
+  public DemoItemMetadata withName(String name) {
+    this.name = name;
+    return this;
+  }
 
-	public DemoItemMetadata withParentId(String parentId) {
-		this.parentId = parentId;
-		return this;
-	}
+  public DemoItemMetadata withParentId(String parentId) {
+    this.parentId = parentId;
+    return this;
+  }
 
-	public DemoItemMetadata withRetry(boolean retry) {
-		this.retry = retry;
-		return this;
-	}
+  public DemoItemMetadata withRetry(boolean retry) {
+    this.retry = retry;
+    return this;
+  }
 
-	public DemoItemMetadata withNested(boolean nested) {
-		this.nested = nested;
-		return this;
-	}
+  public DemoItemMetadata withNested(boolean nested) {
+    this.nested = nested;
+    return this;
+  }
 
-	public DemoItemMetadata withType(TestItemTypeEnum type) {
-		this.type = type;
-		return this;
-	}
+  public DemoItemMetadata withType(TestItemTypeEnum type) {
+    this.type = type;
+    return this;
+  }
 
-	public DemoItemMetadata withStatus(StatusEnum status) {
-		this.status = status;
-		return this;
-	}
+  public DemoItemMetadata withStatus(StatusEnum status) {
+    this.status = status;
+    return this;
+  }
 
-	public DemoItemMetadata withIssue(String issue) {
-		this.issue = issue;
-		return this;
-	}
+  public DemoItemMetadata withIssue(String issue) {
+    this.issue = issue;
+    return this;
+  }
 
-	public DemoItemMetadata withLogCount(int logCount) {
-		this.logCount = logCount;
-		return this;
-	}
+  public DemoItemMetadata withLogCount(int logCount) {
+    this.logCount = logCount;
+    return this;
+  }
 
-	public String getName() {
-		return name;
-	}
+  public String getName() {
+    return name;
+  }
 
-	public String getParentId() {
-		return parentId;
-	}
+  public String getParentId() {
+    return parentId;
+  }
 
-	public boolean isRetry() {
-		return retry;
-	}
+  public boolean isRetry() {
+    return retry;
+  }
 
-	public boolean isNested() {
-		return nested;
-	}
+  public boolean isNested() {
+    return nested;
+  }
 
-	public TestItemTypeEnum getType() {
-		return type;
-	}
+  public TestItemTypeEnum getType() {
+    return type;
+  }
 
-	public StatusEnum getStatus() {
-		return status;
-	}
+  public StatusEnum getStatus() {
+    return status;
+  }
 
-	public String getIssue() {
-		return issue;
-	}
+  public String getIssue() {
+    return issue;
+  }
 
-	public int getLogCount() {
-		return logCount;
-	}
+  public int getLogCount() {
+    return logCount;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/demodata/model/DemoLaunch.java b/src/main/java/com/epam/ta/reportportal/demodata/model/DemoLaunch.java
index 284fbfc484..63da75a7e1 100644
--- a/src/main/java/com/epam/ta/reportportal/demodata/model/DemoLaunch.java
+++ b/src/main/java/com/epam/ta/reportportal/demodata/model/DemoLaunch.java
@@ -1,22 +1,21 @@
 package com.epam.ta.reportportal.demodata.model;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
-
 import java.util.List;
 
 public class DemoLaunch {
 
-	@JsonProperty(value = "suites")
-	private List<Suite> suites;
+  @JsonProperty(value = "suites")
+  private List<Suite> suites;
 
-	public DemoLaunch() {
-	}
+  public DemoLaunch() {
+  }
 
-	public List<Suite> getSuites() {
-		return suites;
-	}
+  public List<Suite> getSuites() {
+    return suites;
+  }
 
-	public void setSuites(List<Suite> suites) {
-		this.suites = suites;
-	}
+  public void setSuites(List<Suite> suites) {
+    this.suites = suites;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/demodata/model/RootMetaData.java b/src/main/java/com/epam/ta/reportportal/demodata/model/RootMetaData.java
index a27aed18bb..840afefbc1 100644
--- a/src/main/java/com/epam/ta/reportportal/demodata/model/RootMetaData.java
+++ b/src/main/java/com/epam/ta/reportportal/demodata/model/RootMetaData.java
@@ -4,29 +4,31 @@
 
 public class RootMetaData {
 
-	private final String launchUuid;
-	private final ReportPortalUser user;
-	private final ReportPortalUser.ProjectDetails projectDetails;
-
-	private RootMetaData(String launchUuid, ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails) {
-		this.launchUuid = launchUuid;
-		this.user = user;
-		this.projectDetails = projectDetails;
-	}
-
-	public String getLaunchUuid() {
-		return launchUuid;
-	}
-
-	public ReportPortalUser getUser() {
-		return user;
-	}
-
-	public ReportPortalUser.ProjectDetails getProjectDetails() {
-		return projectDetails;
-	}
-
-	public static RootMetaData of(String launchUuid, ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails) {
-		return new RootMetaData(launchUuid, user, projectDetails);
-	}
+  private final String launchUuid;
+  private final ReportPortalUser user;
+  private final ReportPortalUser.ProjectDetails projectDetails;
+
+  private RootMetaData(String launchUuid, ReportPortalUser user,
+      ReportPortalUser.ProjectDetails projectDetails) {
+    this.launchUuid = launchUuid;
+    this.user = user;
+    this.projectDetails = projectDetails;
+  }
+
+  public String getLaunchUuid() {
+    return launchUuid;
+  }
+
+  public ReportPortalUser getUser() {
+    return user;
+  }
+
+  public ReportPortalUser.ProjectDetails getProjectDetails() {
+    return projectDetails;
+  }
+
+  public static RootMetaData of(String launchUuid, ReportPortalUser user,
+      ReportPortalUser.ProjectDetails projectDetails) {
+    return new RootMetaData(launchUuid, user, projectDetails);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/demodata/model/Step.java b/src/main/java/com/epam/ta/reportportal/demodata/model/Step.java
index 6e4fa55940..45c0a6977b 100644
--- a/src/main/java/com/epam/ta/reportportal/demodata/model/Step.java
+++ b/src/main/java/com/epam/ta/reportportal/demodata/model/Step.java
@@ -2,34 +2,34 @@
 
 public class Step extends TestingModel {
 
-	private String name;
-	private String status;
-	private String issue;
+  private String name;
+  private String status;
+  private String issue;
 
-	public Step() {
-	}
+  public Step() {
+  }
 
-	public String getName() {
-		return name;
-	}
+  public String getName() {
+    return name;
+  }
 
-	public void setName(String name) {
-		this.name = name;
-	}
+  public void setName(String name) {
+    this.name = name;
+  }
 
-	public String getStatus() {
-		return status;
-	}
+  public String getStatus() {
+    return status;
+  }
 
-	public void setStatus(String status) {
-		this.status = status;
-	}
+  public void setStatus(String status) {
+    this.status = status;
+  }
 
-	public String getIssue() {
-		return issue;
-	}
+  public String getIssue() {
+    return issue;
+  }
 
-	public void setIssue(String issue) {
-		this.issue = issue;
-	}
+  public void setIssue(String issue) {
+    this.issue = issue;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/demodata/model/Suite.java b/src/main/java/com/epam/ta/reportportal/demodata/model/Suite.java
index 0cc316919f..2d102ad686 100644
--- a/src/main/java/com/epam/ta/reportportal/demodata/model/Suite.java
+++ b/src/main/java/com/epam/ta/reportportal/demodata/model/Suite.java
@@ -4,43 +4,43 @@
 
 public class Suite extends TestingModel {
 
-	private String type;
-	private String name;
-	private String status;
-	private List<Test> tests;
+  private String type;
+  private String name;
+  private String status;
+  private List<Test> tests;
 
-	public Suite() {
-	}
+  public Suite() {
+  }
 
-	public String getType() {
-		return type;
-	}
+  public String getType() {
+    return type;
+  }
 
-	public void setType(String type) {
-		this.type = type;
-	}
+  public void setType(String type) {
+    this.type = type;
+  }
 
-	public String getName() {
-		return name;
-	}
+  public String getName() {
+    return name;
+  }
 
-	public void setName(String name) {
-		this.name = name;
-	}
+  public void setName(String name) {
+    this.name = name;
+  }
 
-	public String getStatus() {
-		return status;
-	}
+  public String getStatus() {
+    return status;
+  }
 
-	public void setStatus(String status) {
-		this.status = status;
-	}
+  public void setStatus(String status) {
+    this.status = status;
+  }
 
-	public List<Test> getTests() {
-		return tests;
-	}
+  public List<Test> getTests() {
+    return tests;
+  }
 
-	public void setTests(List<Test> tests) {
-		this.tests = tests;
-	}
+  public void setTests(List<Test> tests) {
+    this.tests = tests;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/demodata/model/Test.java b/src/main/java/com/epam/ta/reportportal/demodata/model/Test.java
index 17ebe432c2..6662e2dd90 100644
--- a/src/main/java/com/epam/ta/reportportal/demodata/model/Test.java
+++ b/src/main/java/com/epam/ta/reportportal/demodata/model/Test.java
@@ -4,43 +4,43 @@
 
 public class Test extends TestingModel {
 
-	private String name;
-	private String status;
-	private String issue;
-	private List<Step> steps;
+  private String name;
+  private String status;
+  private String issue;
+  private List<Step> steps;
 
-	public Test() {
-	}
+  public Test() {
+  }
 
-	public String getName() {
-		return name;
-	}
+  public String getName() {
+    return name;
+  }
 
-	public void setName(String name) {
-		this.name = name;
-	}
+  public void setName(String name) {
+    this.name = name;
+  }
 
-	public String getStatus() {
-		return status;
-	}
+  public String getStatus() {
+    return status;
+  }
 
-	public void setStatus(String status) {
-		this.status = status;
-	}
+  public void setStatus(String status) {
+    this.status = status;
+  }
 
-	public String getIssue() {
-		return issue;
-	}
+  public String getIssue() {
+    return issue;
+  }
 
-	public void setIssue(String issue) {
-		this.issue = issue;
-	}
+  public void setIssue(String issue) {
+    this.issue = issue;
+  }
 
-	public List<Step> getSteps() {
-		return steps;
-	}
+  public List<Step> getSteps() {
+    return steps;
+  }
 
-	public void setSteps(List<Step> steps) {
-		this.steps = steps;
-	}
+  public void setSteps(List<Step> steps) {
+    this.steps = steps;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/demodata/model/TestingModel.java b/src/main/java/com/epam/ta/reportportal/demodata/model/TestingModel.java
index 16b4aabd4f..effdb029f9 100644
--- a/src/main/java/com/epam/ta/reportportal/demodata/model/TestingModel.java
+++ b/src/main/java/com/epam/ta/reportportal/demodata/model/TestingModel.java
@@ -2,25 +2,25 @@
 
 public class TestingModel {
 
-	private boolean hasBefore;
-	private boolean hasAfter;
+  private boolean hasBefore;
+  private boolean hasAfter;
 
-	public TestingModel() {
-	}
+  public TestingModel() {
+  }
 
-	public boolean isHasBefore() {
-		return hasBefore;
-	}
+  public boolean isHasBefore() {
+    return hasBefore;
+  }
 
-	public void setHasBefore(boolean hasBefore) {
-		this.hasBefore = hasBefore;
-	}
+  public void setHasBefore(boolean hasBefore) {
+    this.hasBefore = hasBefore;
+  }
 
-	public boolean isHasAfter() {
-		return hasAfter;
-	}
+  public boolean isHasAfter() {
+    return hasAfter;
+  }
 
-	public void setHasAfter(boolean hasAfter) {
-		this.hasAfter = hasAfter;
-	}
+  public void setHasAfter(boolean hasAfter) {
+    this.hasAfter = hasAfter;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/demodata/service/Attachment.java b/src/main/java/com/epam/ta/reportportal/demodata/service/Attachment.java
index 41f76b6b0f..853efe596f 100644
--- a/src/main/java/com/epam/ta/reportportal/demodata/service/Attachment.java
+++ b/src/main/java/com/epam/ta/reportportal/demodata/service/Attachment.java
@@ -16,9 +16,14 @@
 
 package com.epam.ta.reportportal.demodata.service;
 
-import org.springframework.core.io.ClassPathResource;
+import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
+import static org.springframework.http.MediaType.APPLICATION_PDF_VALUE;
+import static org.springframework.http.MediaType.APPLICATION_XML_VALUE;
+import static org.springframework.http.MediaType.IMAGE_PNG_VALUE;
+import static org.springframework.http.MediaType.TEXT_HTML_VALUE;
+import static org.springframework.http.MediaType.TEXT_PLAIN_VALUE;
 
-import static org.springframework.http.MediaType.*;
+import org.springframework.core.io.ClassPathResource;
 
 /**
  * @author Pavel_Bortnik
diff --git a/src/main/java/com/epam/ta/reportportal/demodata/service/Constants.java b/src/main/java/com/epam/ta/reportportal/demodata/service/Constants.java
index 98fc8286d1..131c1afd05 100644
--- a/src/main/java/com/epam/ta/reportportal/demodata/service/Constants.java
+++ b/src/main/java/com/epam/ta/reportportal/demodata/service/Constants.java
@@ -21,14 +21,14 @@
  */
 class Constants {
 
-	private Constants() {
-		//static only
-	}
+  private Constants() {
+    //static only
+  }
 
-	static final String NAME = "Demo Api Tests";
-	static final String PACKAGE = "com.epam.ta.reportportal.demodata.";
-	static final String ITEM_WITH_NESTED_STEPS_NAME = "Test with nested steps";
-	static final int STORY_PROBABILITY = 30;
-	static final int CONTENT_PROBABILITY = 60;
-	static final int ATTRIBUTES_COUNT = 3;
+  static final String NAME = "Demo Api Tests";
+  static final String PACKAGE = "com.epam.ta.reportportal.demodata.";
+  static final String ITEM_WITH_NESTED_STEPS_NAME = "Test with nested steps";
+  static final int STORY_PROBABILITY = 30;
+  static final int CONTENT_PROBABILITY = 60;
+  static final int ATTRIBUTES_COUNT = 3;
 }
diff --git a/src/main/java/com/epam/ta/reportportal/demodata/service/ContentUtils.java b/src/main/java/com/epam/ta/reportportal/demodata/service/ContentUtils.java
index 19240e300c..ddf95cfb71 100644
--- a/src/main/java/com/epam/ta/reportportal/demodata/service/ContentUtils.java
+++ b/src/main/java/com/epam/ta/reportportal/demodata/service/ContentUtils.java
@@ -16,6 +16,12 @@
 
 package com.epam.ta.reportportal.demodata.service;
 
+import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.AUTOMATION_BUG;
+import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.PRODUCT_BUG;
+import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.SYSTEM_ISSUE;
+import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.TO_INVESTIGATE;
+import static java.nio.charset.StandardCharsets.UTF_8;
+
 import com.epam.ta.reportportal.entity.enums.TestItemIssueGroup;
 import com.epam.ta.reportportal.entity.enums.TestItemTypeEnum;
 import com.epam.ta.reportportal.exception.ReportPortalException;
@@ -24,9 +30,6 @@
 import com.google.common.base.CaseFormat;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Range;
-import org.apache.commons.lang3.tuple.Pair;
-import org.springframework.core.io.ClassPathResource;
-
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
@@ -37,146 +40,152 @@
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
-
-import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.*;
-import static java.nio.charset.StandardCharsets.UTF_8;
+import org.apache.commons.lang3.tuple.Pair;
+import org.springframework.core.io.ClassPathResource;
 
 /**
- * By reason of demo data generation is used not so often,
- * we don't need to cache the files' content.
+ * By reason of demo data generation is used not so often, we don't need to cache the files'
+ * content.
  *
  * @author Pavel_Bortnik
  */
 public final class ContentUtils {
 
-	private static final int MAX_ERROR_LOGS_COUNT = 2;
-
-	private static final int ERRORS_COUNT = 9;
-
-	private static final Range<Integer> PROBABILITY_RANGE = Range.openClosed(0, 100);
-
-	private static SplittableRandom random = new SplittableRandom();
-
-	private static final Map<TestItemIssueGroup, Supplier<Issue>> ISSUE_MAPPING = Map.of(PRODUCT_BUG,
-			() -> getIssue(PRODUCT_BUG.getLocator(), bugDescription("demo/content/comments/product.txt")),
-			AUTOMATION_BUG,
-			() -> getIssue(AUTOMATION_BUG.getLocator(), bugDescription("demo/content/comments/automation.txt")),
-			SYSTEM_ISSUE,
-			() -> getIssue(SYSTEM_ISSUE.getLocator(), bugDescription("demo/content/comments/system.txt")),
-			TO_INVESTIGATE,
-			() -> getIssue(TO_INVESTIGATE.getLocator(), bugDescription("demo/content/comments/investigate.txt"))
-	);
-
-	private ContentUtils() {
-		//static only
-	}
-
-	public static String getNameFromType(TestItemTypeEnum type) {
-		return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, type.name());
-	}
-
-	public static Set<ItemAttributesRQ> getAttributesInRange(int limit) {
-		List<Pair<String, String>> content = readAttributes("demo/content/attributes.txt");
-		int fromIndex = random.nextInt(content.size() - limit);
-		return content.subList(fromIndex, fromIndex + limit).stream().map(it -> {
-			if (it.getKey().isEmpty()) {
-				return new ItemAttributesRQ(null, it.getValue());
-			} else {
-				return new ItemAttributesRQ(it.getKey(), it.getValue());
-			}
-		}).collect(Collectors.toSet());
-
-	}
-
-	public static String getSuiteDescription() {
-		List<String> content = readToList("demo/content/suite-description.txt");
-		return content.get(random.nextInt(content.size()));
-	}
-
-	public static String getStepDescription() {
-		List<String> content = readToList("demo/content/step-description.txt");
-		return content.get(random.nextInt(content.size()));
-	}
-
-	public static String getTestDescription() {
-		List<String> content = readToList("demo/content/test-description.txt");
-		return content.get(random.nextInt(content.size()));
-	}
-
-	public static String getLaunchDescription() {
-		return readToString("demo/content/description.txt");
-	}
-
-	public static List<String> getErrorLogs() {
-		return IntStream.range(0, MAX_ERROR_LOGS_COUNT).mapToObj(i -> {
-			int errorNumber = random.nextInt(1, ERRORS_COUNT);
-			return readToString("demo/errors/" + errorNumber + ".txt");
-		}).collect(Collectors.toList());
-	}
-
-	public static String getLogMessage() {
-		List<String> logs = readToList("demo/content/demo_logs.txt");
-		return logs.get(random.nextInt(logs.size()));
-	}
-
-	public static boolean getWithProbability(int probability) {
-		Preconditions.checkArgument(PROBABILITY_RANGE.contains(probability), "%s is not in range [%s]", probability, PROBABILITY_RANGE);
-		return Range.closedOpen(PROBABILITY_RANGE.lowerEndpoint(), probability).contains(random.nextInt(PROBABILITY_RANGE.upperEndpoint()));
-	}
-
-	public static Issue getIssue(TestItemIssueGroup group) {
-		return ISSUE_MAPPING.get(group).get();
-	}
-
-	private static Issue getIssue(String locator, String comment) {
-		Issue issue = new Issue();
-		issue.setIssueType(locator);
-		issue.setComment(comment);
-		return issue;
-	}
-
-	private static String bugDescription(String resource) {
-		String description = null;
-		if (random.nextBoolean()) {
-			List<String> descriptions = readToList(resource);
-			description = descriptions.get(random.nextInt(descriptions.size()));
-		}
-		return description;
-	}
-
-	private static List<String> readToList(String resource) {
-		List<String> content;
-		try (BufferedReader reader = new BufferedReader(new InputStreamReader(new ClassPathResource(resource).getInputStream(), UTF_8))) {
-			content = reader.lines().collect(Collectors.toList());
-		} catch (IOException e) {
-			throw new ReportPortalException("Missing demo content.", e);
-		}
-		return content;
-	}
-
-	private static List<Pair<String, String>> readAttributes(String resource) {
-		List<Pair<String, String>> content;
-		try (BufferedReader reader = new BufferedReader(new InputStreamReader(new ClassPathResource(resource).getInputStream(), UTF_8))) {
-			content = reader.lines().map(it -> {
-				if (it.contains(":")) {
-					return Pair.of(it.split(":")[0], it.split(":")[1]);
-				} else {
-					return Pair.of("", it);
-				}
-			}).collect(Collectors.toList());
-		} catch (IOException e) {
-			throw new ReportPortalException("Missing demo content.", e);
-		}
-		return content;
-	}
-
-	private static String readToString(String resource) {
-		String content;
-		try (BufferedReader reader = new BufferedReader(new InputStreamReader(new ClassPathResource(resource).getInputStream(), UTF_8))) {
-			content = reader.lines().collect(Collectors.joining("\n"));
-		} catch (IOException e) {
-			throw new ReportPortalException("Missing demo content.", e);
-		}
-		return content;
-	}
+  private static final int MAX_ERROR_LOGS_COUNT = 2;
+
+  private static final int ERRORS_COUNT = 9;
+
+  private static final Range<Integer> PROBABILITY_RANGE = Range.openClosed(0, 100);
+
+  private static SplittableRandom random = new SplittableRandom();
+
+  private static final Map<TestItemIssueGroup, Supplier<Issue>> ISSUE_MAPPING = Map.of(PRODUCT_BUG,
+      () -> getIssue(PRODUCT_BUG.getLocator(), bugDescription("demo/content/comments/product.txt")),
+      AUTOMATION_BUG,
+      () -> getIssue(AUTOMATION_BUG.getLocator(),
+          bugDescription("demo/content/comments/automation.txt")),
+      SYSTEM_ISSUE,
+      () -> getIssue(SYSTEM_ISSUE.getLocator(), bugDescription("demo/content/comments/system.txt")),
+      TO_INVESTIGATE,
+      () -> getIssue(TO_INVESTIGATE.getLocator(),
+          bugDescription("demo/content/comments/investigate.txt"))
+  );
+
+  private ContentUtils() {
+    //static only
+  }
+
+  public static String getNameFromType(TestItemTypeEnum type) {
+    return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, type.name());
+  }
+
+  public static Set<ItemAttributesRQ> getAttributesInRange(int limit) {
+    List<Pair<String, String>> content = readAttributes("demo/content/attributes.txt");
+    int fromIndex = random.nextInt(content.size() - limit);
+    return content.subList(fromIndex, fromIndex + limit).stream().map(it -> {
+      if (it.getKey().isEmpty()) {
+        return new ItemAttributesRQ(null, it.getValue());
+      } else {
+        return new ItemAttributesRQ(it.getKey(), it.getValue());
+      }
+    }).collect(Collectors.toSet());
+
+  }
+
+  public static String getSuiteDescription() {
+    List<String> content = readToList("demo/content/suite-description.txt");
+    return content.get(random.nextInt(content.size()));
+  }
+
+  public static String getStepDescription() {
+    List<String> content = readToList("demo/content/step-description.txt");
+    return content.get(random.nextInt(content.size()));
+  }
+
+  public static String getTestDescription() {
+    List<String> content = readToList("demo/content/test-description.txt");
+    return content.get(random.nextInt(content.size()));
+  }
+
+  public static String getLaunchDescription() {
+    return readToString("demo/content/description.txt");
+  }
+
+  public static List<String> getErrorLogs() {
+    return IntStream.range(0, MAX_ERROR_LOGS_COUNT).mapToObj(i -> {
+      int errorNumber = random.nextInt(1, ERRORS_COUNT);
+      return readToString("demo/errors/" + errorNumber + ".txt");
+    }).collect(Collectors.toList());
+  }
+
+  public static String getLogMessage() {
+    List<String> logs = readToList("demo/content/demo_logs.txt");
+    return logs.get(random.nextInt(logs.size()));
+  }
+
+  public static boolean getWithProbability(int probability) {
+    Preconditions.checkArgument(PROBABILITY_RANGE.contains(probability), "%s is not in range [%s]",
+        probability, PROBABILITY_RANGE);
+    return Range.closedOpen(PROBABILITY_RANGE.lowerEndpoint(), probability)
+        .contains(random.nextInt(PROBABILITY_RANGE.upperEndpoint()));
+  }
+
+  public static Issue getIssue(TestItemIssueGroup group) {
+    return ISSUE_MAPPING.get(group).get();
+  }
+
+  private static Issue getIssue(String locator, String comment) {
+    Issue issue = new Issue();
+    issue.setIssueType(locator);
+    issue.setComment(comment);
+    return issue;
+  }
+
+  private static String bugDescription(String resource) {
+    String description = null;
+    if (random.nextBoolean()) {
+      List<String> descriptions = readToList(resource);
+      description = descriptions.get(random.nextInt(descriptions.size()));
+    }
+    return description;
+  }
+
+  private static List<String> readToList(String resource) {
+    List<String> content;
+    try (BufferedReader reader = new BufferedReader(
+        new InputStreamReader(new ClassPathResource(resource).getInputStream(), UTF_8))) {
+      content = reader.lines().collect(Collectors.toList());
+    } catch (IOException e) {
+      throw new ReportPortalException("Missing demo content.", e);
+    }
+    return content;
+  }
+
+  private static List<Pair<String, String>> readAttributes(String resource) {
+    List<Pair<String, String>> content;
+    try (BufferedReader reader = new BufferedReader(
+        new InputStreamReader(new ClassPathResource(resource).getInputStream(), UTF_8))) {
+      content = reader.lines().map(it -> {
+        if (it.contains(":")) {
+          return Pair.of(it.split(":")[0], it.split(":")[1]);
+        } else {
+          return Pair.of("", it);
+        }
+      }).collect(Collectors.toList());
+    } catch (IOException e) {
+      throw new ReportPortalException("Missing demo content.", e);
+    }
+    return content;
+  }
+
+  private static String readToString(String resource) {
+    String content;
+    try (BufferedReader reader = new BufferedReader(
+        new InputStreamReader(new ClassPathResource(resource).getInputStream(), UTF_8))) {
+      content = reader.lines().collect(Collectors.joining("\n"));
+    } catch (IOException e) {
+      throw new ReportPortalException("Missing demo content.", e);
+    }
+    return content;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/demodata/service/DefaultDemoDataFacade.java b/src/main/java/com/epam/ta/reportportal/demodata/service/DefaultDemoDataFacade.java
index c3dbfb2c49..cc147439b8 100644
--- a/src/main/java/com/epam/ta/reportportal/demodata/service/DefaultDemoDataFacade.java
+++ b/src/main/java/com/epam/ta/reportportal/demodata/service/DefaultDemoDataFacade.java
@@ -16,6 +16,9 @@
 
 package com.epam.ta.reportportal.demodata.service;
 
+import static com.epam.ta.reportportal.demodata.service.Constants.NAME;
+import static java.util.stream.Collectors.toList;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.dao.UserRepository;
 import com.epam.ta.reportportal.demodata.model.DemoLaunch;
@@ -30,84 +33,87 @@
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Stream;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.core.task.TaskExecutor;
 import org.springframework.stereotype.Service;
 import org.springframework.util.ResourceUtils;
 
-import java.io.IOException;
-import java.util.List;
-import java.util.concurrent.CompletableFuture;
-import java.util.stream.Stream;
-
-import static com.epam.ta.reportportal.demodata.service.Constants.NAME;
-import static java.util.stream.Collectors.toList;
-
 /**
  * @author Ihar Kahadouski
  */
 @Service
 public class DefaultDemoDataFacade implements DemoDataFacade {
 
-	public static final int LAUNCH_LOGS_COUNT = 10;
-
-	private final ObjectMapper objectMapper;
-
-	private final DemoDataLaunchService demoDataLaunchService;
-	private final DemoLogsService demoLogsService;
-	private final SuiteGeneratorResolver suiteGeneratorResolver;
-
-	private final TaskExecutor executor;
-
-	private final UserRepository userRepository;
-
-	@Value("classpath:demo/launch/")
-	private String resourceFolder;
-
-	@Value("${rp.environment.variable.demo.source}")
-	private String[] sources;
-
-	public DefaultDemoDataFacade(DemoDataLaunchService demoDataLaunchService, DemoLogsService demoLogsService, ObjectMapper objectMapper,
-			SuiteGeneratorResolver suiteGeneratorResolver, UserRepository userRepository,
-			@Qualifier("demoDataTaskExecutor") TaskExecutor executor) {
-		this.demoDataLaunchService = demoDataLaunchService;
-		this.suiteGeneratorResolver = suiteGeneratorResolver;
-		this.demoLogsService = demoLogsService;
-		this.objectMapper = objectMapper;
-		this.userRepository = userRepository;
-		this.executor = executor;
-	}
-
-	@Override
-	public List<Long> generateDemoLaunches(ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails) {
-		return CompletableFuture.supplyAsync(() -> Stream.of(sources).map(source -> resourceFolder + source).map(source -> {
-			try {
-				final DemoLaunch demoLaunch = objectMapper.readValue(ResourceUtils.getURL(source), new TypeReference<DemoLaunch>() {
-				});
-				return generateLaunch(demoLaunch, user, projectDetails);
-			} catch (IOException e) {
-				throw new ReportPortalException("Unable to load suites description. " + e.getMessage(), e);
-			}
-		}).collect(toList()), executor).join();
-	}
-
-	private Long generateLaunch(DemoLaunch demoLaunch, ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails) {
-
-		final User creator = userRepository.findById(user.getUserId())
-				.orElseThrow(() -> new ReportPortalException(ErrorType.USER_NOT_FOUND, user.getUsername()));
-
-		final Launch launch = demoDataLaunchService.startLaunch(NAME, creator, projectDetails);
-
-		demoLaunch.getSuites().forEach(suite -> {
-			final SuiteGeneratorType suiteGeneratorType = SuiteGeneratorType.valueOf(suite.getType());
-			final SuiteGenerator suiteGenerator = suiteGeneratorResolver.resolve(suiteGeneratorType);
-			suiteGenerator.generateSuites(suite, RootMetaData.of(launch.getUuid(), user, projectDetails));
-		});
-
-		demoDataLaunchService.finishLaunch(launch.getUuid());
-		final List<Log> logs = demoLogsService.generateLaunchLogs(LAUNCH_LOGS_COUNT, launch.getUuid(), launch.getStatus());
-		demoLogsService.attachFiles(logs, projectDetails.getProjectId(), launch.getUuid());
-		return launch.getId();
-	}
+  public static final int LAUNCH_LOGS_COUNT = 10;
+
+  private final ObjectMapper objectMapper;
+
+  private final DemoDataLaunchService demoDataLaunchService;
+  private final DemoLogsService demoLogsService;
+  private final SuiteGeneratorResolver suiteGeneratorResolver;
+
+  private final TaskExecutor executor;
+
+  private final UserRepository userRepository;
+
+  @Value("classpath:demo/launch/")
+  private String resourceFolder;
+
+  @Value("${rp.environment.variable.demo.source}")
+  private String[] sources;
+
+  public DefaultDemoDataFacade(DemoDataLaunchService demoDataLaunchService,
+      DemoLogsService demoLogsService, ObjectMapper objectMapper,
+      SuiteGeneratorResolver suiteGeneratorResolver, UserRepository userRepository,
+      @Qualifier("demoDataTaskExecutor") TaskExecutor executor) {
+    this.demoDataLaunchService = demoDataLaunchService;
+    this.suiteGeneratorResolver = suiteGeneratorResolver;
+    this.demoLogsService = demoLogsService;
+    this.objectMapper = objectMapper;
+    this.userRepository = userRepository;
+    this.executor = executor;
+  }
+
+  @Override
+  public List<Long> generateDemoLaunches(ReportPortalUser user,
+      ReportPortalUser.ProjectDetails projectDetails) {
+    return CompletableFuture.supplyAsync(
+        () -> Stream.of(sources).map(source -> resourceFolder + source).map(source -> {
+          try {
+            final DemoLaunch demoLaunch = objectMapper.readValue(ResourceUtils.getURL(source),
+                new TypeReference<DemoLaunch>() {
+                });
+            return generateLaunch(demoLaunch, user, projectDetails);
+          } catch (IOException e) {
+            throw new ReportPortalException("Unable to load suites description. " + e.getMessage(),
+                e);
+          }
+        }).collect(toList()), executor).join();
+  }
+
+  private Long generateLaunch(DemoLaunch demoLaunch, ReportPortalUser user,
+      ReportPortalUser.ProjectDetails projectDetails) {
+
+    final User creator = userRepository.findById(user.getUserId())
+        .orElseThrow(() -> new ReportPortalException(ErrorType.USER_NOT_FOUND, user.getUsername()));
+
+    final Launch launch = demoDataLaunchService.startLaunch(NAME, creator, projectDetails);
+
+    demoLaunch.getSuites().forEach(suite -> {
+      final SuiteGeneratorType suiteGeneratorType = SuiteGeneratorType.valueOf(suite.getType());
+      final SuiteGenerator suiteGenerator = suiteGeneratorResolver.resolve(suiteGeneratorType);
+      suiteGenerator.generateSuites(suite, RootMetaData.of(launch.getUuid(), user, projectDetails));
+    });
+
+    final List<Log> logs = demoLogsService.generateLaunchLogs(LAUNCH_LOGS_COUNT, launch.getUuid(),
+        launch.getStatus());
+    demoDataLaunchService.finishLaunch(launch.getUuid());
+    demoLogsService.attachFiles(logs, projectDetails.getProjectId(), launch.getUuid());
+    return launch.getId();
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/demodata/service/DemoDataFacade.java b/src/main/java/com/epam/ta/reportportal/demodata/service/DemoDataFacade.java
index ced9588b35..164beb4f2f 100644
--- a/src/main/java/com/epam/ta/reportportal/demodata/service/DemoDataFacade.java
+++ b/src/main/java/com/epam/ta/reportportal/demodata/service/DemoDataFacade.java
@@ -19,19 +19,20 @@
 package com.epam.ta.reportportal.demodata.service;
 
 import com.epam.ta.reportportal.commons.ReportPortalUser;
-
 import java.util.List;
 
 /**
  * @author Pavel Bortnik
  */
 public interface DemoDataFacade {
-	/**
-	 * Generates demo launches
-	 *
-	 * @param user
-	 * @param projectDetails
-	 * @return {@link List} of generated launch ids
-	 */
-	List<Long> generateDemoLaunches(ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails);
+
+  /**
+   * Generates demo launches
+   *
+   * @param user            {@link ReportPortalUser}
+   * @param projectDetails  {@link ReportPortalUser.ProjectDetails}
+   * @return {@link List} of generated launch ids
+   */
+  List<Long> generateDemoLaunches(ReportPortalUser user,
+      ReportPortalUser.ProjectDetails projectDetails);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/demodata/service/DemoDataLaunchService.java b/src/main/java/com/epam/ta/reportportal/demodata/service/DemoDataLaunchService.java
index 3f331cee07..9f6fdf2ebb 100644
--- a/src/main/java/com/epam/ta/reportportal/demodata/service/DemoDataLaunchService.java
+++ b/src/main/java/com/epam/ta/reportportal/demodata/service/DemoDataLaunchService.java
@@ -16,6 +16,10 @@
 
 package com.epam.ta.reportportal.demodata.service;
 
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.PASSED;
+import static com.epam.ta.reportportal.ws.model.ErrorType.LAUNCH_NOT_FOUND;
+
+import com.epam.reportportal.extension.event.LaunchFinishedPluginEvent;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.dao.LaunchRepository;
 import com.epam.ta.reportportal.dao.TestItemRepository;
@@ -28,19 +32,16 @@
 import com.epam.ta.reportportal.ws.model.launch.Mode;
 import com.epam.ta.reportportal.ws.model.launch.StartLaunchRQ;
 import com.google.common.collect.Sets;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
 import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.util.Date;
 import java.util.Random;
 import java.util.Set;
 import java.util.UUID;
-
-import static com.epam.ta.reportportal.entity.enums.StatusEnum.PASSED;
-import static com.epam.ta.reportportal.ws.model.ErrorType.LAUNCH_NOT_FOUND;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
@@ -48,62 +49,73 @@
 @Service
 public class DemoDataLaunchService {
 
-	private final String[] platformValues = { "linux", "windows", "macos", "ios", "android", "windows mobile", "ubuntu", "mint", "arch",
-			"windows 10", "windows 7", "windows server", "debian", "alpine" };
+  private final String[] platformValues = {"linux", "windows", "macos", "ios", "android",
+      "windows mobile", "ubuntu", "mint", "arch",
+      "windows 10", "windows 7", "windows server", "debian", "alpine"};
 
-	private final LaunchRepository launchRepository;
-	private final TestItemRepository testItemRepository;
+  private final LaunchRepository launchRepository;
+  private final TestItemRepository testItemRepository;
+  private final ApplicationEventPublisher eventPublisher;
 
-	@Autowired
-	public DemoDataLaunchService(LaunchRepository launchRepository, TestItemRepository testItemRepository) {
-		this.launchRepository = launchRepository;
-		this.testItemRepository = testItemRepository;
-	}
+  @Autowired
+  public DemoDataLaunchService(LaunchRepository launchRepository,
+      TestItemRepository testItemRepository,
+      ApplicationEventPublisher eventPublisher) {
+    this.launchRepository = launchRepository;
+    this.testItemRepository = testItemRepository;
+    this.eventPublisher = eventPublisher;
+  }
 
-	@Transactional
-	public Launch startLaunch(String name, User user, ReportPortalUser.ProjectDetails projectDetails) {
-		StartLaunchRQ rq = new StartLaunchRQ();
-		rq.setMode(Mode.DEFAULT);
-		rq.setDescription(ContentUtils.getLaunchDescription());
-		LocalDateTime now = LocalDateTime.now();
-		rq.setName(name);
-		rq.setStartTime(Date.from(now.atZone(ZoneId.systemDefault()).toInstant()));
-		rq.setUuid(UUID.randomUUID().toString());
-		Set<ItemAttributesRQ> attributes = Sets.newHashSet(new ItemAttributesRQ("platform",
-						platformValues[new Random().nextInt(platformValues.length)]
-				),
-				new ItemAttributesRQ(null, "demo"),
-				new ItemAttributesRQ("build",
-						"3." + now.getDayOfMonth() + "." + now.getHour() + "." + now.getMinute() + "." + now.getSecond()
-				)
-		);
-		Launch launch = new LaunchBuilder().addStartRQ(rq).addAttributes(attributes).addProject(projectDetails.getProjectId()).get();
-		launch.setUserId(user.getId());
-		launchRepository.save(launch);
-		launchRepository.refresh(launch);
-		return launch;
-	}
+  @Transactional
+  public Launch startLaunch(String name, User user,
+      ReportPortalUser.ProjectDetails projectDetails) {
+    StartLaunchRQ rq = new StartLaunchRQ();
+    rq.setMode(Mode.DEFAULT);
+    rq.setDescription(ContentUtils.getLaunchDescription());
+    LocalDateTime now = LocalDateTime.now();
+    rq.setName(name);
+    rq.setStartTime(Date.from(now.atZone(ZoneId.systemDefault()).toInstant()));
+    rq.setUuid(UUID.randomUUID().toString());
+    Set<ItemAttributesRQ> attributes = Sets.newHashSet(new ItemAttributesRQ("platform",
+            platformValues[new Random().nextInt(platformValues.length)]
+        ),
+        new ItemAttributesRQ(null, "demo"),
+        new ItemAttributesRQ("build",
+            "3." + now.getDayOfMonth() + "." + now.getHour() + "." + now.getMinute() + "."
+                + now.getSecond()
+        )
+    );
+    Launch launch = new LaunchBuilder().addStartRQ(rq).addAttributes(attributes)
+        .addProject(projectDetails.getProjectId()).get();
+    launch.setUserId(user.getId());
+    launchRepository.save(launch);
+    launchRepository.refresh(launch);
+    return launch;
+  }
 
-	@Transactional
-	public void finishLaunch(String launchId) {
-		Launch launch = launchRepository.findByUuid(launchId).orElseThrow(() -> new ReportPortalException(LAUNCH_NOT_FOUND, launchId));
+  @Transactional
+  public void finishLaunch(String launchId) {
+    Launch launch = launchRepository.findByUuid(launchId)
+        .orElseThrow(() -> new ReportPortalException(LAUNCH_NOT_FOUND, launchId));
 
-		if (testItemRepository.hasItemsInStatusByLaunch(launch.getId(), StatusEnum.IN_PROGRESS)) {
-			testItemRepository.interruptInProgressItems(launch.getId());
-		}
+    if (testItemRepository.hasItemsInStatusByLaunch(launch.getId(), StatusEnum.IN_PROGRESS)) {
+      testItemRepository.interruptInProgressItems(launch.getId());
+    }
 
-		launch = new LaunchBuilder(launch).addEndTime(new Date()).get();
+    launch = new LaunchBuilder(launch).addEndTime(new Date()).get();
 
-		StatusEnum fromStatisticsStatus = PASSED;
-		if (launchRepository.hasRootItemsWithStatusNotEqual(launch.getId(),
-				StatusEnum.PASSED.name(),
-				StatusEnum.INFO.name(),
-				StatusEnum.WARN.name()
-		)) {
-			fromStatisticsStatus = StatusEnum.FAILED;
-		}
-		launch.setStatus(fromStatisticsStatus);
+    StatusEnum fromStatisticsStatus = PASSED;
+    if (launchRepository.hasRootItemsWithStatusNotEqual(launch.getId(),
+        StatusEnum.PASSED.name(),
+        StatusEnum.INFO.name(),
+        StatusEnum.WARN.name()
+    )) {
+      fromStatisticsStatus = StatusEnum.FAILED;
+    }
+    launch.setStatus(fromStatisticsStatus);
 
-		launchRepository.save(launch);
-	}
+    launchRepository.save(launch);
+    eventPublisher.publishEvent(
+        new LaunchFinishedPluginEvent(launch.getId(), launch.getProjectId()));
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/demodata/service/DemoDataService.java b/src/main/java/com/epam/ta/reportportal/demodata/service/DemoDataService.java
index 4f338679f3..88c2b66253 100644
--- a/src/main/java/com/epam/ta/reportportal/demodata/service/DemoDataService.java
+++ b/src/main/java/com/epam/ta/reportportal/demodata/service/DemoDataService.java
@@ -19,34 +19,36 @@
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.demodata.model.DemoDataRq;
 import com.epam.ta.reportportal.demodata.model.DemoDataRs;
+import java.util.List;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-
 /**
  * @author Ihar Kahadouski
  */
 @Service
 public class DemoDataService {
 
-	private final DemoDashboardsService demoDashboardsService;
-	private final DemoDataFacade demoDataFacade;
-
-	@Autowired
-	public DemoDataService(DemoDashboardsService demoDashboardsService, DemoDataFacade demoDataFacade) {
-		this.demoDashboardsService = demoDashboardsService;
-		this.demoDataFacade = demoDataFacade;
-	}
-
-	public DemoDataRs generate(DemoDataRq demoDataRq, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user) {
-		DemoDataRs demoDataRs = new DemoDataRs();
-		final List<Long> launchIds = demoDataFacade.generateDemoLaunches(user, projectDetails);
-		demoDataRs.setLaunchIds(launchIds);
-		if (demoDataRq.isCreateDashboard()) {
-			demoDashboardsService.generate(user, projectDetails.getProjectId()).ifPresent(it -> demoDataRs.setDashboardId(it.getId()));
-		}
-
-		return demoDataRs;
-	}
+  private final DemoDashboardsService demoDashboardsService;
+  private final DemoDataFacade demoDataFacade;
+
+  @Autowired
+  public DemoDataService(DemoDashboardsService demoDashboardsService,
+      DemoDataFacade demoDataFacade) {
+    this.demoDashboardsService = demoDashboardsService;
+    this.demoDataFacade = demoDataFacade;
+  }
+
+  public DemoDataRs generate(DemoDataRq demoDataRq, ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user) {
+    DemoDataRs demoDataRs = new DemoDataRs();
+    final List<Long> launchIds = demoDataFacade.generateDemoLaunches(user, projectDetails);
+    demoDataRs.setLaunchIds(launchIds);
+    if (demoDataRq.isCreateDashboard()) {
+      demoDashboardsService.generate(user, projectDetails.getProjectId())
+          .ifPresent(it -> demoDataRs.setDashboardId(it.getId()));
+    }
+
+    return demoDataRs;
+  }
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/demodata/service/DemoDataTestItemService.java b/src/main/java/com/epam/ta/reportportal/demodata/service/DemoDataTestItemService.java
index d238942ef2..8d41ab3fde 100644
--- a/src/main/java/com/epam/ta/reportportal/demodata/service/DemoDataTestItemService.java
+++ b/src/main/java/com/epam/ta/reportportal/demodata/service/DemoDataTestItemService.java
@@ -16,6 +16,11 @@
 
 package com.epam.ta.reportportal.demodata.service;
 
+import static com.epam.ta.reportportal.demodata.service.Constants.ATTRIBUTES_COUNT;
+import static com.epam.ta.reportportal.demodata.service.Constants.PACKAGE;
+import static com.epam.ta.reportportal.entity.enums.TestItemTypeEnum.SUITE;
+import static com.epam.ta.reportportal.entity.enums.TestItemTypeEnum.TEST;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.item.FinishTestItemHandler;
 import com.epam.ta.reportportal.core.item.StartTestItemHandler;
@@ -26,97 +31,99 @@
 import com.epam.ta.reportportal.entity.enums.TestItemTypeEnum;
 import com.epam.ta.reportportal.ws.model.FinishTestItemRQ;
 import com.epam.ta.reportportal.ws.model.StartTestItemRQ;
+import java.util.Date;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.Date;
-
-import static com.epam.ta.reportportal.demodata.service.Constants.ATTRIBUTES_COUNT;
-import static com.epam.ta.reportportal.demodata.service.Constants.PACKAGE;
-import static com.epam.ta.reportportal.entity.enums.TestItemTypeEnum.SUITE;
-import static com.epam.ta.reportportal.entity.enums.TestItemTypeEnum.TEST;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @Service
 public class DemoDataTestItemService {
 
-	private final StartTestItemHandler startTestItemHandler;
-	private final FinishTestItemHandler finishTestItemHandler;
-
-	@Autowired
-	public DemoDataTestItemService(StartTestItemHandler startTestItemHandler, FinishTestItemHandler finishTestItemHandler) {
-		this.startTestItemHandler = startTestItemHandler;
-		this.finishTestItemHandler = finishTestItemHandler;
-	}
-
-	@Transactional
-	public String startRootItem(DemoItemMetadata metadata, RootMetaData rootMetaData) {
-
-		StartTestItemRQ rq = new StartTestItemRQ();
-		rq.setName(metadata.getName());
-		rq.setCodeRef(PACKAGE + metadata.getName());
-		rq.setLaunchUuid(rootMetaData.getLaunchUuid());
-		rq.setStartTime(new Date());
-		rq.setType(metadata.getType().name());
-		if (metadata.getType().sameLevel(SUITE)) {
-			rq.setAttributes(ContentUtils.getAttributesInRange(ATTRIBUTES_COUNT));
-			rq.setDescription(ContentUtils.getSuiteDescription());
-		}
-
-		return startTestItemHandler.startRootItem(rootMetaData.getUser(), rootMetaData.getProjectDetails(), rq).getId();
-	}
-
-	@Transactional
-	public void finishRootItem(String rootItemId, ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails) {
-		FinishTestItemRQ rq = new FinishTestItemRQ();
-		rq.setEndTime(new Date());
-		finishTestItemHandler.finishTestItem(user, projectDetails, rootItemId, rq);
-	}
-
-	@Transactional
-	public String startTestItem(DemoItemMetadata metadata, RootMetaData rootMetaData) {
-
-		StartTestItemRQ rq = new StartTestItemRQ();
-		if (hasChildren(metadata.getType())) {
-			rq.setAttributes(ContentUtils.getAttributesInRange(ATTRIBUTES_COUNT));
-			rq.setDescription(ContentUtils.getTestDescription());
-		} else {
-			rq.setAttributes(ContentUtils.getAttributesInRange(ATTRIBUTES_COUNT));
-			rq.setDescription(ContentUtils.getStepDescription());
-		}
-		rq.setHasStats(!metadata.isNested());
-		rq.setCodeRef(PACKAGE + metadata.getName());
-		rq.setRetry(metadata.isRetry());
-		rq.setLaunchUuid(rootMetaData.getLaunchUuid());
-		rq.setStartTime(new Date());
-		rq.setName(metadata.getName());
-		rq.setType(metadata.getType().name());
-
-		return startTestItemHandler.startChildItem(rootMetaData.getUser(), rootMetaData.getProjectDetails(), rq, metadata.getParentId())
-				.getId();
-	}
-
-	@Transactional
-	public void finishTestItem(String testItemId, StatusEnum status, RootMetaData rootMetaData) {
-		FinishTestItemRQ rq = new FinishTestItemRQ();
-		rq.setEndTime(new Date());
-		rq.setStatus(status.name());
-		finishTestItemHandler.finishTestItem(rootMetaData.getUser(), rootMetaData.getProjectDetails(), testItemId, rq);
-	}
-
-	@Transactional
-	public void finishTestItem(String testItemId, StatusEnum status, RootMetaData rootMetaData, String issue) {
-		FinishTestItemRQ rq = new FinishTestItemRQ();
-		rq.setEndTime(new Date());
-		rq.setStatus(status.name());
-		TestItemIssueGroup.fromValue(issue).ifPresent(group -> rq.setIssue(ContentUtils.getIssue(group)));
-		finishTestItemHandler.finishTestItem(rootMetaData.getUser(), rootMetaData.getProjectDetails(), testItemId, rq);
-	}
-
-	private boolean hasChildren(TestItemTypeEnum testItemType) {
-		return testItemType == TEST || testItemType == SUITE;
-	}
+  private final StartTestItemHandler startTestItemHandler;
+  private final FinishTestItemHandler finishTestItemHandler;
+
+  @Autowired
+  public DemoDataTestItemService(StartTestItemHandler startTestItemHandler,
+      FinishTestItemHandler finishTestItemHandler) {
+    this.startTestItemHandler = startTestItemHandler;
+    this.finishTestItemHandler = finishTestItemHandler;
+  }
+
+  @Transactional
+  public String startRootItem(DemoItemMetadata metadata, RootMetaData rootMetaData) {
+
+    StartTestItemRQ rq = new StartTestItemRQ();
+    rq.setName(metadata.getName());
+    rq.setCodeRef(PACKAGE + metadata.getName());
+    rq.setLaunchUuid(rootMetaData.getLaunchUuid());
+    rq.setStartTime(new Date());
+    rq.setType(metadata.getType().name());
+    if (metadata.getType().sameLevel(SUITE)) {
+      rq.setAttributes(ContentUtils.getAttributesInRange(ATTRIBUTES_COUNT));
+      rq.setDescription(ContentUtils.getSuiteDescription());
+    }
+
+    return startTestItemHandler.startRootItem(rootMetaData.getUser(),
+        rootMetaData.getProjectDetails(), rq).getId();
+  }
+
+  @Transactional
+  public void finishRootItem(String rootItemId, ReportPortalUser user,
+      ReportPortalUser.ProjectDetails projectDetails) {
+    FinishTestItemRQ rq = new FinishTestItemRQ();
+    rq.setEndTime(new Date());
+    finishTestItemHandler.finishTestItem(user, projectDetails, rootItemId, rq);
+  }
+
+  @Transactional
+  public String startTestItem(DemoItemMetadata metadata, RootMetaData rootMetaData) {
+
+    StartTestItemRQ rq = new StartTestItemRQ();
+    if (hasChildren(metadata.getType())) {
+      rq.setAttributes(ContentUtils.getAttributesInRange(ATTRIBUTES_COUNT));
+      rq.setDescription(ContentUtils.getTestDescription());
+    } else {
+      rq.setAttributes(ContentUtils.getAttributesInRange(ATTRIBUTES_COUNT));
+      rq.setDescription(ContentUtils.getStepDescription());
+    }
+    rq.setHasStats(!metadata.isNested());
+    rq.setCodeRef(PACKAGE + metadata.getName());
+    rq.setRetry(metadata.isRetry());
+    rq.setLaunchUuid(rootMetaData.getLaunchUuid());
+    rq.setStartTime(new Date());
+    rq.setName(metadata.getName());
+    rq.setType(metadata.getType().name());
+
+    return startTestItemHandler.startChildItem(rootMetaData.getUser(),
+            rootMetaData.getProjectDetails(), rq, metadata.getParentId())
+        .getId();
+  }
+
+  @Transactional
+  public void finishTestItem(String testItemId, StatusEnum status, RootMetaData rootMetaData) {
+    FinishTestItemRQ rq = new FinishTestItemRQ();
+    rq.setEndTime(new Date());
+    rq.setStatus(status.name());
+    finishTestItemHandler.finishTestItem(rootMetaData.getUser(), rootMetaData.getProjectDetails(),
+        testItemId, rq);
+  }
+
+  @Transactional
+  public void finishTestItem(String testItemId, StatusEnum status, RootMetaData rootMetaData,
+      String issue) {
+    FinishTestItemRQ rq = new FinishTestItemRQ();
+    rq.setEndTime(new Date());
+    rq.setStatus(status.name());
+    TestItemIssueGroup.fromValue(issue)
+        .ifPresent(group -> rq.setIssue(ContentUtils.getIssue(group)));
+    finishTestItemHandler.finishTestItem(rootMetaData.getUser(), rootMetaData.getProjectDetails(),
+        testItemId, rq);
+  }
+
+  private boolean hasChildren(TestItemTypeEnum testItemType) {
+    return testItemType == TEST || testItemType == SUITE;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/demodata/service/DemoLogsService.java b/src/main/java/com/epam/ta/reportportal/demodata/service/DemoLogsService.java
index f41b4fbf2c..ce21a02fb7 100644
--- a/src/main/java/com/epam/ta/reportportal/demodata/service/DemoLogsService.java
+++ b/src/main/java/com/epam/ta/reportportal/demodata/service/DemoLogsService.java
@@ -27,8 +27,11 @@
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.entity.log.Log;
+import com.epam.ta.reportportal.entity.log.LogFull;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.HashMap;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
@@ -43,7 +46,9 @@
 import static com.epam.ta.reportportal.entity.enums.LogLevel.*;
 import static com.epam.ta.reportportal.entity.enums.StatusEnum.FAILED;
 import static com.epam.ta.reportportal.util.MultipartFileUtils.getMultipartFile;
+import static com.epam.ta.reportportal.ws.converter.converters.LogConverter.LOG_FULL_TO_LOG;
 import static java.util.stream.Collectors.toList;
+import static org.apache.commons.collections4.CollectionUtils.isNotEmpty;
 
 @Service
 public class DemoLogsService {
@@ -74,55 +79,75 @@ public DemoLogsService(@Value("${rp.environment.variable.demo.attachment.probabi
 	public List<Log> generateLaunchLogs(int count, String launchUUid, StatusEnum status) {
 		final Launch launch = launchRepository.findByUuid(launchUUid)
 				.orElseThrow(() -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND, launchUUid));
-		final List<Log> logs = IntStream.range(0, count)
-				.mapToObj(it -> getLog(launch, ContentUtils.getLogMessage(), infoLevel()))
+		final List<LogFull> logFulls = IntStream.range(0, count)
+				.mapToObj(it -> getLogFull(launch, ContentUtils.getLogMessage(), infoLevel()))
 				.collect(toList());
 		if (FAILED.equals(status)) {
 			List<String> errors = ContentUtils.getErrorLogs();
-			logs.addAll(errors.stream().map(msg -> getLog(launch, msg, errorLevel())).collect(toList()));
+			logFulls.addAll(
+					errors.stream().map(msg -> getLogFull(launch, msg, errorLevel())).collect(toList()));
 		}
+		List<Log> logs = logFulls.stream().map(LOG_FULL_TO_LOG).collect(toList());
 		logRepository.saveAll(logs);
-		logService.saveLogMessageListToElasticSearch(logs, launch.getId());
+		fillIdByUuid(logFulls, logs);
+		logService.saveLogMessageList(logFulls, launch.getId());
 
 		return logs;
 	}
 
-	private Log getLog(Launch launch, String message, LogLevel logLevel) {
-		Log log = new Log();
-		log.setLogLevel(logLevel.toInt());
-		log.setLogTime(LocalDateTime.now());
-		log.setLaunch(launch);
-		log.setProjectId(launch.getProjectId());
-		log.setLogMessage(message);
-		log.setUuid(UUID.randomUUID().toString());
-		return log;
+	private LogFull getLogFull(Launch launch, String message, LogLevel logLevel) {
+		LogFull logFull = new LogFull();
+		logFull.setLogLevel(logLevel.toInt());
+		logFull.setLogTime(LocalDateTime.now());
+		logFull.setLaunch(launch);
+		logFull.setProjectId(launch.getProjectId());
+		logFull.setLogMessage(message);
+		logFull.setUuid(UUID.randomUUID().toString());
+		return logFull;
 	}
 
 	public List<Log> generateItemLogs(int count, Long projectId, String itemUuid, StatusEnum status) {
 		final TestItem testItem = testItemRepository.findByUuid(itemUuid)
 				.orElseThrow(() -> new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, itemUuid));
-		List<Log> logs = IntStream.range(0, count)
-				.mapToObj(it -> getLog(projectId, testItem, infoLevel(), ContentUtils.getLogMessage()))
+		List<LogFull> logFulls = IntStream.range(0, count)
+				.mapToObj(it -> getLogFull(projectId, testItem, infoLevel(), ContentUtils.getLogMessage()))
 				.collect(toList());
 		if (FAILED.equals(status)) {
 			List<String> errors = ContentUtils.getErrorLogs();
-			logs.addAll(errors.stream().map(msg -> getLog(projectId, testItem, errorLevel(), msg)).collect(toList()));
+			logFulls.addAll(errors.stream().map(msg -> getLogFull(projectId, testItem, errorLevel(), msg))
+					.collect(toList()));
 		}
+		List<Log> logs = logFulls.stream().map(LOG_FULL_TO_LOG).collect(toList());
 		logRepository.saveAll(logs);
-		logService.saveLogMessageListToElasticSearch(logs, testItem.getLaunchId());
+		fillIdByUuid(logFulls, logs);
+		logService.saveLogMessageList(logFulls, testItem.getLaunchId());
 
 		return logs;
 	}
 
-	private Log getLog(Long projectId, TestItem testItem, LogLevel logLevel, String logMessage) {
-		Log log = new Log();
-		log.setLogLevel(logLevel.toInt());
-		log.setLogTime(LocalDateTime.now());
-		log.setTestItem(testItem);
-		log.setProjectId(projectId);
-		log.setLogMessage(logMessage);
-		log.setUuid(UUID.randomUUID().toString());
-		return log;
+	private LogFull getLogFull(Long projectId, TestItem testItem, LogLevel logLevel,
+			String logMessage) {
+		LogFull logFull = new LogFull();
+		logFull.setLogLevel(logLevel.toInt());
+		logFull.setLogTime(LocalDateTime.now());
+		logFull.setTestItem(testItem);
+		logFull.setProjectId(projectId);
+		logFull.setLogMessage(logMessage);
+		logFull.setUuid(UUID.randomUUID().toString());
+		return logFull;
+	}
+
+	private void fillIdByUuid(List<LogFull> logFulls, List<Log> logs) {
+		if (isNotEmpty(logFulls) && isNotEmpty(logs)) {
+			Map<String, Long> logIdsMap = new HashMap<>(logs.size());
+			for (Log log : logs) {
+				logIdsMap.put(log.getUuid(), log.getId());
+			}
+
+			for (LogFull logFull : logFulls) {
+				logFull.setId(logIdsMap.get(logFull.getUuid()));
+			}
+		}
 	}
 
 	public void attachFiles(List<Log> logs, Long projectId, String launchUuid) {
diff --git a/src/main/java/com/epam/ta/reportportal/demodata/service/generator/DefaultSuiteGenerator.java b/src/main/java/com/epam/ta/reportportal/demodata/service/generator/DefaultSuiteGenerator.java
index 46cb2858fa..71c01d913f 100644
--- a/src/main/java/com/epam/ta/reportportal/demodata/service/generator/DefaultSuiteGenerator.java
+++ b/src/main/java/com/epam/ta/reportportal/demodata/service/generator/DefaultSuiteGenerator.java
@@ -1,149 +1,173 @@
 package com.epam.ta.reportportal.demodata.service.generator;
 
-import com.epam.ta.reportportal.demodata.model.*;
+import static com.epam.ta.reportportal.demodata.service.ContentUtils.getNameFromType;
+import static com.epam.ta.reportportal.entity.enums.TestItemTypeEnum.AFTER_CLASS;
+import static com.epam.ta.reportportal.entity.enums.TestItemTypeEnum.AFTER_METHOD;
+import static com.epam.ta.reportportal.entity.enums.TestItemTypeEnum.AFTER_SUITE;
+import static com.epam.ta.reportportal.entity.enums.TestItemTypeEnum.BEFORE_CLASS;
+import static com.epam.ta.reportportal.entity.enums.TestItemTypeEnum.BEFORE_METHOD;
+import static com.epam.ta.reportportal.entity.enums.TestItemTypeEnum.BEFORE_SUITE;
+import static com.epam.ta.reportportal.entity.enums.TestItemTypeEnum.STEP;
+import static com.epam.ta.reportportal.entity.enums.TestItemTypeEnum.SUITE;
+import static com.epam.ta.reportportal.entity.enums.TestItemTypeEnum.TEST;
+import static java.util.Optional.ofNullable;
+
+import com.epam.ta.reportportal.demodata.model.DemoItemMetadata;
+import com.epam.ta.reportportal.demodata.model.RootMetaData;
+import com.epam.ta.reportportal.demodata.model.Suite;
+import com.epam.ta.reportportal.demodata.model.Test;
 import com.epam.ta.reportportal.demodata.service.DemoDataTestItemService;
 import com.epam.ta.reportportal.demodata.service.DemoLogsService;
 import com.epam.ta.reportportal.entity.enums.StatusEnum;
 import com.epam.ta.reportportal.entity.enums.TestItemTypeEnum;
 import com.epam.ta.reportportal.entity.log.Log;
+import java.util.List;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-
-import static com.epam.ta.reportportal.demodata.service.ContentUtils.getNameFromType;
-import static com.epam.ta.reportportal.entity.enums.TestItemTypeEnum.*;
-import static java.util.Optional.ofNullable;
-
 @Service
 public class DefaultSuiteGenerator implements SuiteGenerator {
 
-	public static final int BEFORE_AFTER_LOGS_COUNT = 2;
-	public static final int SUITE_LOGS_COUNT = 3;
-	public static final int TEST_LOGS_COUNT = 3;
-	public static final int STEP_LOGS_COUNT = 5;
-
-	protected final DemoDataTestItemService demoDataTestItemService;
-	private final DemoLogsService demoLogsService;
-
-	@Autowired
-	public DefaultSuiteGenerator(DemoDataTestItemService demoDataTestItemService, DemoLogsService demoLogsService) {
-		this.demoDataTestItemService = demoDataTestItemService;
-		this.demoLogsService = demoLogsService;
-	}
-
-	@Override
-	public void generateSuites(Suite suite, RootMetaData rootMetaData) {
-
-		final StatusEnum suiteStatus = StatusEnum.valueOf(suite.getStatus());
-
-		if (suite.isHasBefore()) {
-			final DemoItemMetadata beforeMetaData = getMetadata(getNameFromType(BEFORE_SUITE),
-					BEFORE_SUITE,
-					suiteStatus,
-					null
-			).withLogCount(BEFORE_AFTER_LOGS_COUNT);
-			createStep(beforeMetaData, rootMetaData);
-		}
-
-		final DemoItemMetadata suiteMetaData = getMetadata(suite.getName(), SUITE, suiteStatus, null);
-		final String suiteId = demoDataTestItemService.startRootItem(suiteMetaData, rootMetaData);
-
-		suite.getTests().forEach(test -> {
-			final StatusEnum testStatus = StatusEnum.valueOf(test.getStatus());
-
-			if (test.isHasBefore()) {
-				final DemoItemMetadata beforeMetaData = getMetadata(getNameFromType(BEFORE_CLASS),
-						BEFORE_CLASS,
-						testStatus,
-						suiteId
-				).withLogCount(BEFORE_AFTER_LOGS_COUNT);
-				createStep(beforeMetaData, rootMetaData);
-			}
-			generateTest(suiteId, rootMetaData, test, testStatus);
-			if (test.isHasAfter()) {
-				final DemoItemMetadata afterMetaData = getMetadata(getNameFromType(AFTER_CLASS),
-						AFTER_CLASS,
-						testStatus,
-						suiteId
-				).withLogCount(BEFORE_AFTER_LOGS_COUNT);
-				createStep(afterMetaData, rootMetaData);
-			}
-		});
-
-		demoDataTestItemService.finishTestItem(suiteId, suiteStatus, rootMetaData);
-		generateLogs(SUITE_LOGS_COUNT, suiteId, suiteStatus, rootMetaData);
-
-		if (suite.isHasAfter()) {
-			createStep(getMetadata(getNameFromType(AFTER_SUITE), AFTER_SUITE, suiteStatus, null).withLogCount(BEFORE_AFTER_LOGS_COUNT),
-					rootMetaData
-			);
-		}
-	}
-
-	protected DemoItemMetadata getMetadata(String name, TestItemTypeEnum type, StatusEnum status, String parentId) {
-		return new DemoItemMetadata().withName(name).withType(type).withStatus(status).withParentId(parentId);
-	}
-
-	protected void createStep(DemoItemMetadata stepMetaData, RootMetaData rootMetaData) {
-		final String stepId = ofNullable(stepMetaData.getParentId()).map(parentId -> demoDataTestItemService.startTestItem(stepMetaData,
-				rootMetaData
-		)).orElseGet(() -> demoDataTestItemService.startRootItem(stepMetaData, rootMetaData));
-
-		generateLogs(stepMetaData.getLogCount(), stepId, stepMetaData.getStatus(), rootMetaData);
-		ofNullable(stepMetaData.getIssue()).ifPresentOrElse(issue -> demoDataTestItemService.finishTestItem(stepId,
-				stepMetaData.getStatus(),
-				rootMetaData,
-				issue
-		), () -> demoDataTestItemService.finishTestItem(stepId, stepMetaData.getStatus(), rootMetaData));
-	}
-
-	protected void generateTest(String suiteId, RootMetaData rootMetaData, Test test, StatusEnum testStatus) {
-		final String testId = startTest(suiteId, rootMetaData, test, testStatus);
-		generateSteps(rootMetaData, test, testId);
-
-		ofNullable(test.getIssue()).ifPresentOrElse(issue -> demoDataTestItemService.finishTestItem(testId,
-				testStatus,
-				rootMetaData,
-				issue
-		), () -> demoDataTestItemService.finishTestItem(testId, testStatus, rootMetaData));
-		generateLogs(TEST_LOGS_COUNT, testId, testStatus, rootMetaData);
-	}
-
-	protected String startTest(String suiteId, RootMetaData rootMetaData, Test test, StatusEnum testStatus) {
-		final DemoItemMetadata testMetaData = getMetadata(test.getName(), TEST, testStatus, suiteId).withIssue(test.getIssue());
-		return demoDataTestItemService.startTestItem(testMetaData, rootMetaData);
-	}
-
-	private void generateSteps(RootMetaData rootMetaData, Test test, String testId) {
-		test.getSteps().forEach(step -> {
-			final StatusEnum stepStatus = StatusEnum.valueOf(step.getStatus());
-			if (step.isHasBefore()) {
-				final DemoItemMetadata beforeMetaData = getMetadata(getNameFromType(BEFORE_METHOD),
-						BEFORE_METHOD,
-						stepStatus,
-						testId
-				).withLogCount(BEFORE_AFTER_LOGS_COUNT);
-				createStep(beforeMetaData, rootMetaData);
-			}
-			final DemoItemMetadata stepMetaData = getMetadata(step.getName(), STEP, stepStatus, testId).withLogCount(STEP_LOGS_COUNT)
-					.withIssue(step.getIssue());
-			createStep(stepMetaData, rootMetaData);
-			if (step.isHasBefore()) {
-				final DemoItemMetadata afterMetaData = getMetadata(getNameFromType(AFTER_METHOD),
-						AFTER_METHOD,
-						stepStatus,
-						testId
-				).withLogCount(BEFORE_AFTER_LOGS_COUNT);
-				createStep(afterMetaData, rootMetaData);
-			}
-		});
-	}
-
-	private void generateLogs(int count, String itemId, StatusEnum status, RootMetaData rootMetaData) {
-		final Long projectId = rootMetaData.getProjectDetails().getProjectId();
-		List<Log> logs = demoLogsService.generateItemLogs(count, projectId, itemId, status);
-		demoLogsService.attachFiles(logs, projectId, itemId, rootMetaData.getLaunchUuid());
-	}
+  public static final int BEFORE_AFTER_LOGS_COUNT = 2;
+  public static final int SUITE_LOGS_COUNT = 3;
+  public static final int TEST_LOGS_COUNT = 3;
+  public static final int STEP_LOGS_COUNT = 5;
+
+  protected final DemoDataTestItemService demoDataTestItemService;
+  private final DemoLogsService demoLogsService;
+
+  @Autowired
+  public DefaultSuiteGenerator(DemoDataTestItemService demoDataTestItemService,
+      DemoLogsService demoLogsService) {
+    this.demoDataTestItemService = demoDataTestItemService;
+    this.demoLogsService = demoLogsService;
+  }
+
+  @Override
+  public void generateSuites(Suite suite, RootMetaData rootMetaData) {
+
+    final StatusEnum suiteStatus = StatusEnum.valueOf(suite.getStatus());
+
+    if (suite.isHasBefore()) {
+      final DemoItemMetadata beforeMetaData = getMetadata(getNameFromType(BEFORE_SUITE),
+          BEFORE_SUITE,
+          suiteStatus,
+          null
+      ).withLogCount(BEFORE_AFTER_LOGS_COUNT);
+      createStep(beforeMetaData, rootMetaData);
+    }
+
+    final DemoItemMetadata suiteMetaData = getMetadata(suite.getName(), SUITE, suiteStatus, null);
+    final String suiteId = demoDataTestItemService.startRootItem(suiteMetaData, rootMetaData);
+
+    suite.getTests().forEach(test -> {
+      final StatusEnum testStatus = StatusEnum.valueOf(test.getStatus());
+
+      if (test.isHasBefore()) {
+        final DemoItemMetadata beforeMetaData = getMetadata(getNameFromType(BEFORE_CLASS),
+            BEFORE_CLASS,
+            testStatus,
+            suiteId
+        ).withLogCount(BEFORE_AFTER_LOGS_COUNT);
+        createStep(beforeMetaData, rootMetaData);
+      }
+      generateTest(suiteId, rootMetaData, test, testStatus);
+      if (test.isHasAfter()) {
+        final DemoItemMetadata afterMetaData = getMetadata(getNameFromType(AFTER_CLASS),
+            AFTER_CLASS,
+            testStatus,
+            suiteId
+        ).withLogCount(BEFORE_AFTER_LOGS_COUNT);
+        createStep(afterMetaData, rootMetaData);
+      }
+    });
+
+    demoDataTestItemService.finishTestItem(suiteId, suiteStatus, rootMetaData);
+    generateLogs(SUITE_LOGS_COUNT, suiteId, suiteStatus, rootMetaData);
+
+    if (suite.isHasAfter()) {
+      createStep(
+          getMetadata(getNameFromType(AFTER_SUITE), AFTER_SUITE, suiteStatus, null).withLogCount(
+              BEFORE_AFTER_LOGS_COUNT),
+          rootMetaData
+      );
+    }
+  }
+
+  protected DemoItemMetadata getMetadata(String name, TestItemTypeEnum type, StatusEnum status,
+      String parentId) {
+    return new DemoItemMetadata().withName(name).withType(type).withStatus(status)
+        .withParentId(parentId);
+  }
+
+  protected void createStep(DemoItemMetadata stepMetaData, RootMetaData rootMetaData) {
+    final String stepId = ofNullable(stepMetaData.getParentId()).map(
+        parentId -> demoDataTestItemService.startTestItem(stepMetaData,
+            rootMetaData
+        )).orElseGet(() -> demoDataTestItemService.startRootItem(stepMetaData, rootMetaData));
+
+    generateLogs(stepMetaData.getLogCount(), stepId, stepMetaData.getStatus(), rootMetaData);
+    ofNullable(stepMetaData.getIssue()).ifPresentOrElse(
+        issue -> demoDataTestItemService.finishTestItem(stepId,
+            stepMetaData.getStatus(),
+            rootMetaData,
+            issue
+        ), () -> demoDataTestItemService.finishTestItem(stepId, stepMetaData.getStatus(),
+            rootMetaData));
+  }
+
+  protected void generateTest(String suiteId, RootMetaData rootMetaData, Test test,
+      StatusEnum testStatus) {
+    final String testId = startTest(suiteId, rootMetaData, test, testStatus);
+    generateSteps(rootMetaData, test, testId);
+
+    ofNullable(test.getIssue()).ifPresentOrElse(
+        issue -> demoDataTestItemService.finishTestItem(testId,
+            testStatus,
+            rootMetaData,
+            issue
+        ), () -> demoDataTestItemService.finishTestItem(testId, testStatus, rootMetaData));
+    generateLogs(TEST_LOGS_COUNT, testId, testStatus, rootMetaData);
+  }
+
+  protected String startTest(String suiteId, RootMetaData rootMetaData, Test test,
+      StatusEnum testStatus) {
+    final DemoItemMetadata testMetaData = getMetadata(test.getName(), TEST, testStatus,
+        suiteId).withIssue(test.getIssue());
+    return demoDataTestItemService.startTestItem(testMetaData, rootMetaData);
+  }
+
+  private void generateSteps(RootMetaData rootMetaData, Test test, String testId) {
+    test.getSteps().forEach(step -> {
+      final StatusEnum stepStatus = StatusEnum.valueOf(step.getStatus());
+      if (step.isHasBefore()) {
+        final DemoItemMetadata beforeMetaData = getMetadata(getNameFromType(BEFORE_METHOD),
+            BEFORE_METHOD,
+            stepStatus,
+            testId
+        ).withLogCount(BEFORE_AFTER_LOGS_COUNT);
+        createStep(beforeMetaData, rootMetaData);
+      }
+      final DemoItemMetadata stepMetaData = getMetadata(step.getName(), STEP, stepStatus,
+          testId).withLogCount(STEP_LOGS_COUNT)
+          .withIssue(step.getIssue());
+      createStep(stepMetaData, rootMetaData);
+      if (step.isHasBefore()) {
+        final DemoItemMetadata afterMetaData = getMetadata(getNameFromType(AFTER_METHOD),
+            AFTER_METHOD,
+            stepStatus,
+            testId
+        ).withLogCount(BEFORE_AFTER_LOGS_COUNT);
+        createStep(afterMetaData, rootMetaData);
+      }
+    });
+  }
+
+  private void generateLogs(int count, String itemId, StatusEnum status,
+      RootMetaData rootMetaData) {
+    final Long projectId = rootMetaData.getProjectDetails().getProjectId();
+    List<Log> logs = demoLogsService.generateItemLogs(count, projectId, itemId, status);
+    demoLogsService.attachFiles(logs, projectId, itemId, rootMetaData.getLaunchUuid());
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/demodata/service/generator/SuiteGenerator.java b/src/main/java/com/epam/ta/reportportal/demodata/service/generator/SuiteGenerator.java
index 9bcc578d4a..1001c23639 100644
--- a/src/main/java/com/epam/ta/reportportal/demodata/service/generator/SuiteGenerator.java
+++ b/src/main/java/com/epam/ta/reportportal/demodata/service/generator/SuiteGenerator.java
@@ -5,6 +5,6 @@
 
 public interface SuiteGenerator {
 
-	void generateSuites(Suite suite, RootMetaData rootMetaData);
+  void generateSuites(Suite suite, RootMetaData rootMetaData);
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/demodata/service/generator/SuiteGeneratorResolver.java b/src/main/java/com/epam/ta/reportportal/demodata/service/generator/SuiteGeneratorResolver.java
index d68ecf6848..1a2d8ff76f 100644
--- a/src/main/java/com/epam/ta/reportportal/demodata/service/generator/SuiteGeneratorResolver.java
+++ b/src/main/java/com/epam/ta/reportportal/demodata/service/generator/SuiteGeneratorResolver.java
@@ -1,18 +1,17 @@
 package com.epam.ta.reportportal.demodata.service.generator;
 
 import com.epam.ta.reportportal.demodata.service.generator.model.SuiteGeneratorType;
-
 import java.util.Map;
 
 public class SuiteGeneratorResolver {
 
-	private final Map<SuiteGeneratorType, SuiteGenerator> suiteGeneratorMapping;
+  private final Map<SuiteGeneratorType, SuiteGenerator> suiteGeneratorMapping;
 
-	public SuiteGeneratorResolver(Map<SuiteGeneratorType, SuiteGenerator> suiteGeneratorMapping) {
-		this.suiteGeneratorMapping = suiteGeneratorMapping;
-	}
+  public SuiteGeneratorResolver(Map<SuiteGeneratorType, SuiteGenerator> suiteGeneratorMapping) {
+    this.suiteGeneratorMapping = suiteGeneratorMapping;
+  }
 
-	public SuiteGenerator resolve(SuiteGeneratorType type) {
-		return suiteGeneratorMapping.get(type);
-	}
+  public SuiteGenerator resolve(SuiteGeneratorType type) {
+    return suiteGeneratorMapping.get(type);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/demodata/service/generator/SuiteWithNestedStepsGenerator.java b/src/main/java/com/epam/ta/reportportal/demodata/service/generator/SuiteWithNestedStepsGenerator.java
index f5de74e2b0..23763f970f 100644
--- a/src/main/java/com/epam/ta/reportportal/demodata/service/generator/SuiteWithNestedStepsGenerator.java
+++ b/src/main/java/com/epam/ta/reportportal/demodata/service/generator/SuiteWithNestedStepsGenerator.java
@@ -1,5 +1,7 @@
 package com.epam.ta.reportportal.demodata.service.generator;
 
+import static com.epam.ta.reportportal.entity.enums.TestItemTypeEnum.STEP;
+
 import com.epam.ta.reportportal.demodata.model.DemoItemMetadata;
 import com.epam.ta.reportportal.demodata.model.RootMetaData;
 import com.epam.ta.reportportal.demodata.model.Test;
@@ -9,26 +11,27 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import static com.epam.ta.reportportal.entity.enums.TestItemTypeEnum.STEP;
-
 @Service
 public class SuiteWithNestedStepsGenerator extends DefaultSuiteGenerator {
 
-	@Autowired
-	public SuiteWithNestedStepsGenerator(DemoDataTestItemService demoDataTestItemService, DemoLogsService demoLogsService) {
-		super(demoDataTestItemService, demoLogsService);
-	}
+  @Autowired
+  public SuiteWithNestedStepsGenerator(DemoDataTestItemService demoDataTestItemService,
+      DemoLogsService demoLogsService) {
+    super(demoDataTestItemService, demoLogsService);
+  }
 
-	@Override
-	protected void createStep(DemoItemMetadata stepMetaData, RootMetaData rootMetaData) {
-		super.createStep(stepMetaData.withNested(true), rootMetaData);
-	}
+  @Override
+  protected void createStep(DemoItemMetadata stepMetaData, RootMetaData rootMetaData) {
+    super.createStep(stepMetaData.withNested(true), rootMetaData);
+  }
 
-	@Override
-	protected String startTest(String suiteId, RootMetaData rootMetaData, Test test, StatusEnum testStatus) {
-		final String testId = super.startTest(suiteId, rootMetaData, test, testStatus);
-		final DemoItemMetadata stepParentMetadata = getMetadata(test.getName(), STEP, testStatus, testId);
-		return demoDataTestItemService.startTestItem(stepParentMetadata, rootMetaData);
-	}
+  @Override
+  protected String startTest(String suiteId, RootMetaData rootMetaData, Test test,
+      StatusEnum testStatus) {
+    final String testId = super.startTest(suiteId, rootMetaData, test, testStatus);
+    final DemoItemMetadata stepParentMetadata = getMetadata(test.getName(), STEP, testStatus,
+        testId);
+    return demoDataTestItemService.startTestItem(stepParentMetadata, rootMetaData);
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/demodata/service/generator/SuiteWithRetriesGenerator.java b/src/main/java/com/epam/ta/reportportal/demodata/service/generator/SuiteWithRetriesGenerator.java
index d74c4aa130..b269ac455b 100644
--- a/src/main/java/com/epam/ta/reportportal/demodata/service/generator/SuiteWithRetriesGenerator.java
+++ b/src/main/java/com/epam/ta/reportportal/demodata/service/generator/SuiteWithRetriesGenerator.java
@@ -5,37 +5,37 @@
 import com.epam.ta.reportportal.demodata.service.DemoDataTestItemService;
 import com.epam.ta.reportportal.demodata.service.DemoLogsService;
 import com.epam.ta.reportportal.entity.enums.StatusEnum;
+import java.util.stream.IntStream;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.stream.IntStream;
-
 @Service
 public class SuiteWithRetriesGenerator extends DefaultSuiteGenerator {
 
-	private static final int RETRIES_COUNT = 3;
+  private static final int RETRIES_COUNT = 3;
 
-	@Autowired
-	public SuiteWithRetriesGenerator(DemoDataTestItemService demoDataTestItemService, DemoLogsService demoLogsService) {
-		super(demoDataTestItemService, demoLogsService);
-	}
+  @Autowired
+  public SuiteWithRetriesGenerator(DemoDataTestItemService demoDataTestItemService,
+      DemoLogsService demoLogsService) {
+    super(demoDataTestItemService, demoLogsService);
+  }
 
-	@Override
-	protected void createStep(DemoItemMetadata stepMetaData, RootMetaData rootMetaData) {
-		super.createStep(stepMetaData, rootMetaData);
-		if (stepMetaData.getStatus() != StatusEnum.PASSED) {
-			generateRetries(stepMetaData, rootMetaData);
-		}
-	}
+  @Override
+  protected void createStep(DemoItemMetadata stepMetaData, RootMetaData rootMetaData) {
+    super.createStep(stepMetaData, rootMetaData);
+    if (stepMetaData.getStatus() != StatusEnum.PASSED) {
+      generateRetries(stepMetaData, rootMetaData);
+    }
+  }
 
-	private void generateRetries(final DemoItemMetadata metadata, RootMetaData rootMetaData) {
-		IntStream.range(0, RETRIES_COUNT).forEach(i -> {
-			final DemoItemMetadata retryMetaData = getMetadata(metadata.getName(),
-					metadata.getType(),
-					metadata.getStatus(),
-					metadata.getParentId()
-			).withIssue(metadata.getIssue()).withRetry(true);
-			super.createStep(retryMetaData, rootMetaData);
-		});
-	}
+  private void generateRetries(final DemoItemMetadata metadata, RootMetaData rootMetaData) {
+    IntStream.range(0, RETRIES_COUNT).forEach(i -> {
+      final DemoItemMetadata retryMetaData = getMetadata(metadata.getName(),
+          metadata.getType(),
+          metadata.getStatus(),
+          metadata.getParentId()
+      ).withIssue(metadata.getIssue()).withRetry(true);
+      super.createStep(retryMetaData, rootMetaData);
+    });
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/demodata/service/generator/model/SuiteGeneratorType.java b/src/main/java/com/epam/ta/reportportal/demodata/service/generator/model/SuiteGeneratorType.java
index 23034b944d..c97039bfb8 100644
--- a/src/main/java/com/epam/ta/reportportal/demodata/service/generator/model/SuiteGeneratorType.java
+++ b/src/main/java/com/epam/ta/reportportal/demodata/service/generator/model/SuiteGeneratorType.java
@@ -1,5 +1,5 @@
 package com.epam.ta.reportportal.demodata.service.generator.model;
 
 public enum SuiteGeneratorType {
-	DEFAULT, RETRY, NESTED;
+  DEFAULT, RETRY, NESTED;
 }
diff --git a/src/main/java/com/epam/ta/reportportal/exception/DataStorageException.java b/src/main/java/com/epam/ta/reportportal/exception/DataStorageException.java
index 0c0688031a..4723799721 100644
--- a/src/main/java/com/epam/ta/reportportal/exception/DataStorageException.java
+++ b/src/main/java/com/epam/ta/reportportal/exception/DataStorageException.java
@@ -24,15 +24,15 @@
 // TODO add binding to this exception
 public class DataStorageException extends ReportPortalException {
 
-	private static final long serialVersionUID = -6822780391660931103L;
+  private static final long serialVersionUID = -6822780391660931103L;
 
-	public DataStorageException(String message) {
-		super(message);
+  public DataStorageException(String message) {
+    super(message);
 
-	}
+  }
 
-	public DataStorageException(String message, Throwable e) {
-		super(message, e);
-	}
+  public DataStorageException(String message, Throwable e) {
+    super(message, e);
+  }
 
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/exception/HandlerNotDefinedException.java b/src/main/java/com/epam/ta/reportportal/exception/HandlerNotDefinedException.java
index ed67888b5b..3f1f852d9b 100644
--- a/src/main/java/com/epam/ta/reportportal/exception/HandlerNotDefinedException.java
+++ b/src/main/java/com/epam/ta/reportportal/exception/HandlerNotDefinedException.java
@@ -24,10 +24,10 @@
 // TODO add mapping for this exception
 public class HandlerNotDefinedException extends RuntimeException {
 
-	private static final long serialVersionUID = 7447853618838625617L;
+  private static final long serialVersionUID = 7447853618838625617L;
 
-	public HandlerNotDefinedException(String message) {
-		super(message);
-	}
+  public HandlerNotDefinedException(String message) {
+    super(message);
+  }
 
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/exception/PermissionNotDefinedException.java b/src/main/java/com/epam/ta/reportportal/exception/PermissionNotDefinedException.java
index 472004eac4..28c406bcdc 100644
--- a/src/main/java/com/epam/ta/reportportal/exception/PermissionNotDefinedException.java
+++ b/src/main/java/com/epam/ta/reportportal/exception/PermissionNotDefinedException.java
@@ -24,10 +24,10 @@
 // TODO add exception mapping
 public class PermissionNotDefinedException extends RuntimeException {
 
-	private static final long serialVersionUID = 843053936838256383L;
+  private static final long serialVersionUID = 843053936838256383L;
 
-	public PermissionNotDefinedException(String exception) {
-		super(exception);
-	}
+  public PermissionNotDefinedException(String exception) {
+    super(exception);
+  }
 
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/exception/UserAccountExpiredException.java b/src/main/java/com/epam/ta/reportportal/exception/UserAccountExpiredException.java
index 9da477393d..35fa3d3da0 100644
--- a/src/main/java/com/epam/ta/reportportal/exception/UserAccountExpiredException.java
+++ b/src/main/java/com/epam/ta/reportportal/exception/UserAccountExpiredException.java
@@ -20,9 +20,9 @@
 
 public class UserAccountExpiredException extends AccountExpiredException {
 
-	private static final long serialVersionUID = -1313818913697889296L;
+  private static final long serialVersionUID = -1313818913697889296L;
 
-	public UserAccountExpiredException(String msg) {
-		super(msg);
-	}
+  public UserAccountExpiredException(String msg) {
+    super(msg);
+  }
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/health/JobsHealthIndicator.java b/src/main/java/com/epam/ta/reportportal/health/JobsHealthIndicator.java
new file mode 100644
index 0000000000..337797d126
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/health/JobsHealthIndicator.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2023 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.health;
+
+import java.util.Map;
+import java.util.Optional;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.actuate.health.AbstractHealthIndicator;
+import org.springframework.boot.actuate.health.Health;
+import org.springframework.boot.actuate.health.Health.Builder;
+import org.springframework.boot.actuate.health.Status;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+
+/**
+ * Health Indicator for jobs service.
+ *
+ * @author Siarhei Hrabko
+ */
+@Component
+public class JobsHealthIndicator extends AbstractHealthIndicator {
+
+  private static Logger LOGGER = LoggerFactory.getLogger(JobsHealthIndicator.class);
+  private static final String ERROR_MESSAGE = "Jobs service health check failed";
+  RestTemplate restTemplate;
+
+  @Value("${rp.jobs.baseUrl}")
+  private String jobsBaseUrl;
+
+  public JobsHealthIndicator() {
+    super(ERROR_MESSAGE);
+    this.restTemplate = new RestTemplate();
+  }
+
+  @Override
+  protected void doHealthCheck(Builder builder) {
+    try {
+      var jobsHealthRs = restTemplate.getForObject(jobsBaseUrl + "/health", Map.class);
+
+      var jobsStatus = new Status((String) jobsHealthRs.get("status"));
+      builder.status(jobsStatus);
+
+      Optional.ofNullable(jobsHealthRs.get("components"))
+          .map(Map.class::cast)
+          .ifPresent(builder::withDetails);
+
+      builder.build();
+
+    } catch (Exception e) {
+      LOGGER.error("{} : {}", ERROR_MESSAGE, e.getMessage());
+      builder.unknown()
+          .withException(e)
+          .build();
+    }
+  }
+
+  @Override
+  public Health getHealth(boolean includeDetails) {
+    return super.getHealth(includeDetails);
+  }
+
+}
diff --git a/src/main/java/com/epam/ta/reportportal/info/AnalyzerInfoContributor.java b/src/main/java/com/epam/ta/reportportal/info/AnalyzerInfoContributor.java
index 5ed6725d06..07aaff5c23 100644
--- a/src/main/java/com/epam/ta/reportportal/info/AnalyzerInfoContributor.java
+++ b/src/main/java/com/epam/ta/reportportal/info/AnalyzerInfoContributor.java
@@ -19,13 +19,12 @@
 import com.epam.ta.reportportal.core.analyzer.auto.client.RabbitMqManagementClient;
 import com.google.common.collect.ImmutableMap;
 import com.rabbitmq.http.client.domain.ExchangeInfo;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
 import java.util.Map;
 import java.util.Set;
 import java.util.function.Function;
 import java.util.stream.Collectors;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
 
 /**
  * Shows list of supported analyzers
@@ -35,19 +34,19 @@
 @Component
 public class AnalyzerInfoContributor implements ExtensionContributor {
 
-	private final RabbitMqManagementClient managementClient;
+  private final RabbitMqManagementClient managementClient;
 
-	@Autowired
-	public AnalyzerInfoContributor(RabbitMqManagementClient managementClient) {
-		this.managementClient = managementClient;
-	}
+  @Autowired
+  public AnalyzerInfoContributor(RabbitMqManagementClient managementClient) {
+    this.managementClient = managementClient;
+  }
 
-	@Override
-	public Map<String, ?> contribute() {
-		Set<Object> analyzersInfo = managementClient.getAnalyzerExchangesInfo()
-				.stream()
-				.map((Function<ExchangeInfo, Object>) ExchangeInfo::getArguments)
-				.collect(Collectors.toSet());
-		return ImmutableMap.<String, Object>builder().put("analyzers", analyzersInfo).build();
-	}
+  @Override
+  public Map<String, ?> contribute() {
+    Set<Object> analyzersInfo = managementClient.getAnalyzerExchangesInfo()
+        .stream()
+        .map((Function<ExchangeInfo, Object>) ExchangeInfo::getArguments)
+        .collect(Collectors.toSet());
+    return ImmutableMap.<String, Object>builder().put("analyzers", analyzersInfo).build();
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/info/EnvironmentVariablesInfoContributor.java b/src/main/java/com/epam/ta/reportportal/info/EnvironmentVariablesInfoContributor.java
index d187e9422b..303624734e 100644
--- a/src/main/java/com/epam/ta/reportportal/info/EnvironmentVariablesInfoContributor.java
+++ b/src/main/java/com/epam/ta/reportportal/info/EnvironmentVariablesInfoContributor.java
@@ -17,11 +17,10 @@
 package com.epam.ta.reportportal.info;
 
 import com.google.common.collect.ImmutableMap;
-import org.springframework.boot.actuate.info.MapInfoContributor;
-import org.springframework.stereotype.Component;
-
 import java.util.Map;
 import java.util.stream.Collectors;
+import org.springframework.boot.actuate.info.MapInfoContributor;
+import org.springframework.stereotype.Component;
 
 /**
  * Collects provided environment variables with rp prefix.
@@ -31,15 +30,16 @@
 @Component
 public class EnvironmentVariablesInfoContributor extends MapInfoContributor {
 
-	private static final String RP_ENV_PREFIX = "RP_ENVIRONMENT_VARIABLE_";
+  private static final String RP_ENV_PREFIX = "RP_ENVIRONMENT_VARIABLE_";
 
-	public EnvironmentVariablesInfoContributor() {
-		super(ImmutableMap.<String, Object>builder().put("environment",
-				System.getenv()
-						.entrySet()
-						.stream()
-						.filter(it -> it.getKey().startsWith(RP_ENV_PREFIX))
-						.collect(Collectors.toMap(e -> e.getKey().replaceFirst(RP_ENV_PREFIX, "").toLowerCase(), Map.Entry::getValue))
-		).build());
-	}
+  public EnvironmentVariablesInfoContributor() {
+    super(ImmutableMap.<String, Object>builder().put("environment",
+        System.getenv()
+            .entrySet()
+            .stream()
+            .filter(it -> it.getKey().startsWith(RP_ENV_PREFIX))
+            .collect(Collectors.toMap(e -> e.getKey().replaceFirst(RP_ENV_PREFIX, "").toLowerCase(),
+                Map.Entry::getValue))
+    ).build());
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/info/ExtensionContributor.java b/src/main/java/com/epam/ta/reportportal/info/ExtensionContributor.java
index 148b56032b..5e44a1d93b 100644
--- a/src/main/java/com/epam/ta/reportportal/info/ExtensionContributor.java
+++ b/src/main/java/com/epam/ta/reportportal/info/ExtensionContributor.java
@@ -21,5 +21,6 @@
  * @author Pavel_Bortnik
  */
 public interface ExtensionContributor {
-	Map<String, ?> contribute();
+
+  Map<String, ?> contribute();
 }
diff --git a/src/main/java/com/epam/ta/reportportal/info/ExtensionsInfoContributor.java b/src/main/java/com/epam/ta/reportportal/info/ExtensionsInfoContributor.java
index abd44a7238..43c577f7e1 100644
--- a/src/main/java/com/epam/ta/reportportal/info/ExtensionsInfoContributor.java
+++ b/src/main/java/com/epam/ta/reportportal/info/ExtensionsInfoContributor.java
@@ -18,12 +18,11 @@
 import com.epam.ta.reportportal.core.plugin.Pf4jPluginBox;
 import com.epam.ta.reportportal.core.plugin.Plugin;
 import com.google.common.collect.ImmutableMap;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
 import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
 
 /**
  * Shows list of supported extensions providers.
@@ -34,16 +33,17 @@
 @Component
 public class ExtensionsInfoContributor implements ExtensionContributor {
 
-	private static final String EXTENSION_KEY = "extension";
+  private static final String EXTENSION_KEY = "extension";
 
-	private static final String BUGTRACKING_KEY = "bugtracking";
+  private static final String BUGTRACKING_KEY = "bugtracking";
 
-	@Autowired
-	private Pf4jPluginBox pluginBox;
+  @Autowired
+  private Pf4jPluginBox pluginBox;
 
-	@Override
-	public Map<String, ?> contribute() {
-		Set<String> names = pluginBox.getPlugins().stream().map(Plugin::getId).collect(Collectors.toSet());
-		return ImmutableMap.<String, Object>builder().put(EXTENSION_KEY, names).build();
-	}
+  @Override
+  public Map<String, ?> contribute() {
+    Set<String> names = pluginBox.getPlugins().stream().map(Plugin::getId)
+        .collect(Collectors.toSet());
+    return ImmutableMap.<String, Object>builder().put(EXTENSION_KEY, names).build();
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/info/InfoContributorComposite.java b/src/main/java/com/epam/ta/reportportal/info/InfoContributorComposite.java
index 2248c5ef67..18ce35be7c 100644
--- a/src/main/java/com/epam/ta/reportportal/info/InfoContributorComposite.java
+++ b/src/main/java/com/epam/ta/reportportal/info/InfoContributorComposite.java
@@ -15,15 +15,14 @@
  */
 package com.epam.ta.reportportal.info;
 
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.actuate.info.Info;
 import org.springframework.boot.actuate.info.InfoContributor;
 import org.springframework.stereotype.Component;
 
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
 /**
  * @author Pavel Bortnik
  */
@@ -31,20 +30,20 @@
 @Component
 public class InfoContributorComposite implements InfoContributor {
 
-	private static final String EXTENSIONS_KEY = "extensions";
+  private static final String EXTENSIONS_KEY = "extensions";
 
-	private final List<ExtensionContributor> infoContributors;
+  private final List<ExtensionContributor> infoContributors;
 
-	@Autowired
-	public InfoContributorComposite(List<ExtensionContributor> infoContributors) {
-		this.infoContributors = infoContributors;
-	}
+  @Autowired
+  public InfoContributorComposite(List<ExtensionContributor> infoContributors) {
+    this.infoContributors = infoContributors;
+  }
 
-	@Override
-	public void contribute(Info.Builder builder) {
-		builder.withDetail(EXTENSIONS_KEY, infoContributors.stream()
-				.map(ExtensionContributor::contribute)
-				.flatMap(map -> map.entrySet().stream())
-				.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)));
-	}
+  @Override
+  public void contribute(Info.Builder builder) {
+    builder.withDetail(EXTENSIONS_KEY, infoContributors.stream()
+        .map(ExtensionContributor::contribute)
+        .flatMap(map -> map.entrySet().stream())
+        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)));
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/info/JobSchedulerInfoContributor.java b/src/main/java/com/epam/ta/reportportal/info/JobSchedulerInfoContributor.java
index ce5051e328..493dbec833 100644
--- a/src/main/java/com/epam/ta/reportportal/info/JobSchedulerInfoContributor.java
+++ b/src/main/java/com/epam/ta/reportportal/info/JobSchedulerInfoContributor.java
@@ -17,6 +17,10 @@
 
 import com.epam.ta.reportportal.core.configs.Conditions;
 import com.epam.ta.reportportal.exception.ReportPortalException;
+import java.util.Collections;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 import org.apache.commons.collections.MapUtils;
 import org.quartz.Scheduler;
 import org.quartz.SchedulerException;
@@ -29,14 +33,8 @@
 import org.springframework.context.annotation.Conditional;
 import org.springframework.stereotype.Component;
 
-import java.util.Collections;
-import java.util.Map;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
 /**
- * Collects info about existing jobs and how much it is left
- * to the next trigger execution
+ * Collects info about existing jobs and how much it is left to the next trigger execution
  *
  * @author Pavel Bortnik
  */
@@ -44,37 +42,39 @@
 @Conditional(Conditions.NotTestCondition.class)
 public class JobSchedulerInfoContributor implements InfoContributor {
 
-	private static final Logger LOGGER = LoggerFactory.getLogger(JobSchedulerInfoContributor.class);
+  private static final Logger LOGGER = LoggerFactory.getLogger(JobSchedulerInfoContributor.class);
 
-	@Autowired
-	private Scheduler scheduler;
+  @Autowired
+  private Scheduler scheduler;
 
-	@Override
-	public void contribute(Info.Builder builder) {
-		try {
-			Map<String, Map<String, Long>> triggersInfo = scheduler.getTriggerGroupNames().stream().flatMap(name -> {
-				try {
-					return scheduler.getJobKeys(GroupMatcher.groupEquals(name)).stream();
-				} catch (SchedulerException e) {
-					LOGGER.warn(e.getMessage());
-					return Stream.empty();
-				}
-			}).collect(Collectors.toList()).stream().flatMap(key -> {
-				try {
-					return scheduler.getTriggersOfJob(key).stream();
-				} catch (SchedulerException e) {
-					LOGGER.warn(e.getMessage());
-					return Stream.empty();
-				}
-			}).collect(Collectors.toMap(
-					t -> t.getKey().getName(),
-					t -> Collections.singletonMap("triggersIn", t.getNextFireTime().getTime() - System.currentTimeMillis())
-			));
-			if (MapUtils.isNotEmpty(triggersInfo)) {
-				builder.withDetail("jobs", triggersInfo);
-			}
-		} catch (SchedulerException e) {
-			throw new ReportPortalException(e.getMessage());
-		}
-	}
+  @Override
+  public void contribute(Info.Builder builder) {
+    try {
+      Map<String, Map<String, Long>> triggersInfo = scheduler.getTriggerGroupNames().stream()
+          .flatMap(name -> {
+            try {
+              return scheduler.getJobKeys(GroupMatcher.groupEquals(name)).stream();
+            } catch (SchedulerException e) {
+              LOGGER.warn(e.getMessage());
+              return Stream.empty();
+            }
+          }).collect(Collectors.toList()).stream().flatMap(key -> {
+            try {
+              return scheduler.getTriggersOfJob(key).stream();
+            } catch (SchedulerException e) {
+              LOGGER.warn(e.getMessage());
+              return Stream.empty();
+            }
+          }).collect(Collectors.toMap(
+              t -> t.getKey().getName(),
+              t -> Collections.singletonMap("triggersIn",
+                  t.getNextFireTime().getTime() - System.currentTimeMillis())
+          ));
+      if (MapUtils.isNotEmpty(triggersInfo)) {
+        builder.withDetail("jobs", triggersInfo);
+      }
+    } catch (SchedulerException e) {
+      throw new ReportPortalException(e.getMessage());
+    }
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/info/JobsInfoContributor.java b/src/main/java/com/epam/ta/reportportal/info/JobsInfoContributor.java
new file mode 100644
index 0000000000..6f1a975e85
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/info/JobsInfoContributor.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2023 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.info;
+
+import com.epam.ta.reportportal.exception.ReportPortalException;
+import com.epam.ta.reportportal.ws.validation.JaskonRequiredPropertiesValidator;
+import java.util.Map;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.actuate.info.Info.Builder;
+import org.springframework.boot.actuate.info.InfoContributor;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+
+/**
+ * Picks actuator info from <i>jobs</i> service and shows it as part of <i>service-api</i>.
+ *
+ * @author Siarhei Hrabko
+ */
+@Component
+public class JobsInfoContributor implements InfoContributor {
+
+  private static final Logger LOGGER = LoggerFactory.getLogger(JobsInfoContributor.class);
+
+  private final RestTemplate restTemplate;
+
+  @Value("${rp.jobs.baseUrl}")
+  private String jobsBaseUrl;
+
+  public JobsInfoContributor() {
+    this.restTemplate = new RestTemplate();
+  }
+
+  @Override
+  public void contribute(Builder builder) {
+    try {
+      var jobsInfoRs = restTemplate.getForObject(jobsBaseUrl + "/info", Map.class);
+      builder
+          .withDetail("jobsInfo", jobsInfoRs)
+          .build();
+    } catch (Exception e) {
+      LOGGER.error("Jobs service was not found");
+    }
+  }
+}
diff --git a/src/main/java/com/epam/ta/reportportal/info/ServerSettingsInfoContributor.java b/src/main/java/com/epam/ta/reportportal/info/ServerSettingsInfoContributor.java
index 07eba5b043..9a494c5379 100644
--- a/src/main/java/com/epam/ta/reportportal/info/ServerSettingsInfoContributor.java
+++ b/src/main/java/com/epam/ta/reportportal/info/ServerSettingsInfoContributor.java
@@ -18,12 +18,11 @@
 import com.epam.ta.reportportal.dao.ServerSettingsRepository;
 import com.epam.ta.reportportal.entity.ServerSettings;
 import com.epam.ta.reportportal.ws.converter.converters.ServerSettingsConverter;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
 
 /**
  * Shows list of supported analytics providers and other server settings.
@@ -34,21 +33,21 @@
 @Component
 public class ServerSettingsInfoContributor implements ExtensionContributor {
 
-	private final ServerSettingsRepository settingsRepository;
+  private final ServerSettingsRepository settingsRepository;
 
-	@Autowired
-	@SuppressWarnings("SpringJavaAutowiringInspection")
-	public ServerSettingsInfoContributor(ServerSettingsRepository settingsRepository) {
-		this.settingsRepository = settingsRepository;
-	}
+  @Autowired
+  @SuppressWarnings("SpringJavaAutowiringInspection")
+  public ServerSettingsInfoContributor(ServerSettingsRepository settingsRepository) {
+    this.settingsRepository = settingsRepository;
+  }
 
-	@Override
-	public Map<String, ?> contribute() {
-		Map<String, Object> info = new HashMap<>();
-		List<ServerSettings> all = settingsRepository.selectServerSettings();
-		Map<String, String> result = ServerSettingsConverter.TO_RESOURCE.apply(all);
-		info.put("result", result);
-		return info;
+  @Override
+  public Map<String, ?> contribute() {
+    Map<String, Object> info = new HashMap<>();
+    List<ServerSettings> all = settingsRepository.selectServerSettings();
+    Map<String, String> result = ServerSettingsConverter.TO_RESOURCE.apply(all);
+    info.put("result", result);
+    return info;
 
-	}
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/job/CleanExpiredCreationBidsJob.java b/src/main/java/com/epam/ta/reportportal/job/CleanExpiredCreationBidsJob.java
index 14142edbf9..de8cb99f9b 100644
--- a/src/main/java/com/epam/ta/reportportal/job/CleanExpiredCreationBidsJob.java
+++ b/src/main/java/com/epam/ta/reportportal/job/CleanExpiredCreationBidsJob.java
@@ -17,6 +17,9 @@
 package com.epam.ta.reportportal.job;
 
 import com.epam.ta.reportportal.dao.UserCreationBidRepository;
+import java.sql.Date;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
 import org.quartz.Job;
 import org.quartz.JobExecutionContext;
 import org.quartz.JobExecutionException;
@@ -26,24 +29,22 @@
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.sql.Date;
-import java.time.LocalDateTime;
-import java.time.ZoneOffset;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @Service
 public class CleanExpiredCreationBidsJob implements Job {
-	private static final Logger LOGGER = LoggerFactory.getLogger(CleanExpiredCreationBidsJob.class);
 
-	@Autowired
-	private UserCreationBidRepository repository;
+  private static final Logger LOGGER = LoggerFactory.getLogger(CleanExpiredCreationBidsJob.class);
+
+  @Autowired
+  private UserCreationBidRepository repository;
 
-	@Override
-	@Transactional
-	public void execute(JobExecutionContext context) throws JobExecutionException {
-		int deletedCount = repository.expireBidsOlderThan(Date.from(LocalDateTime.now().minusDays(1).toInstant(ZoneOffset.UTC)));
-		LOGGER.info("Cleaning expired user creation bids finished. Deleted {} bids", deletedCount);
-	}
+  @Override
+  @Transactional
+  public void execute(JobExecutionContext context) throws JobExecutionException {
+    int deletedCount = repository.expireBidsOlderThan(
+        Date.from(LocalDateTime.now().minusDays(1).toInstant(ZoneOffset.UTC)));
+    LOGGER.info("Cleaning expired user creation bids finished. Deleted {} bids", deletedCount);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/job/CleanOutdatedPluginsJob.java b/src/main/java/com/epam/ta/reportportal/job/CleanOutdatedPluginsJob.java
index d3750089c1..f9b332dfd7 100644
--- a/src/main/java/com/epam/ta/reportportal/job/CleanOutdatedPluginsJob.java
+++ b/src/main/java/com/epam/ta/reportportal/job/CleanOutdatedPluginsJob.java
@@ -16,6 +16,8 @@
 
 package com.epam.ta.reportportal.job;
 
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.validation.Suppliers;
 import com.epam.ta.reportportal.core.configs.Conditions;
 import com.epam.ta.reportportal.core.plugin.Pf4jPluginBox;
@@ -23,6 +25,14 @@
 import com.epam.ta.reportportal.dao.IntegrationTypeRepository;
 import com.epam.ta.reportportal.entity.integration.IntegrationType;
 import com.epam.ta.reportportal.job.service.PluginLoaderService;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import javax.validation.constraints.NotNull;
 import org.pf4j.PluginWrapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -32,17 +42,6 @@
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 
-import javax.validation.constraints.NotNull;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.List;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import static java.util.Optional.ofNullable;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
@@ -50,96 +49,107 @@
 @Service
 public class CleanOutdatedPluginsJob {
 
-	private static final Logger LOGGER = LoggerFactory.getLogger(CleanOutdatedPluginsJob.class);
-
-	private final String pluginsTempPath;
-
-	private final IntegrationTypeRepository integrationTypeRepository;
-
-	private final Pf4jPluginBox pluginBox;
-
-	private final PluginLoaderService pluginLoaderService;
-
-	@Autowired
-	public CleanOutdatedPluginsJob(@Value("${rp.plugins.temp.path}") String pluginsTempPath,
-			IntegrationTypeRepository integrationTypeRepository, Pf4jPluginBox pf4jPluginBox, PluginLoaderService pluginLoaderService) {
-		this.pluginsTempPath = pluginsTempPath;
-		this.integrationTypeRepository = integrationTypeRepository;
-		this.pluginBox = pf4jPluginBox;
-		this.pluginLoaderService = pluginLoaderService;
-	}
-
-	@Scheduled(fixedDelayString = "${com.ta.reportportal.job.clean.outdated.plugins.cron}")
-	public void execute() {
-
-		removeTemporaryPlugins();
-
-		List<IntegrationType> integrationTypes = integrationTypeRepository.findAll();
-		integrationTypes.stream()
-				.filter(it -> it.getDetails() == null || it.getDetails().getDetails() == null)
-				.forEach(pluginLoaderService::checkAndDeleteIntegrationType);
-
-		unloadRemovedPlugins(integrationTypes);
-		unloadDisabledPlugins(integrationTypes);
-	}
-
-	private void removeTemporaryPlugins() {
-		Path tempPluginsPath = Paths.get(pluginsTempPath);
-
-		LOGGER.debug("Searching for temporary plugins...");
-		try (Stream<Path> pathStream = Files.walk(tempPluginsPath)) {
-			pathStream.filter(Files::isRegularFile).forEach(path -> ofNullable(path.getFileName()).ifPresent(fileName -> {
-				if (!pluginBox.isInUploadingState(fileName.toString())) {
-					try {
-						Files.deleteIfExists(path);
-						LOGGER.debug(Suppliers.formattedSupplier("Temporary plugin - '{}' has been removed", path).get());
-					} catch (IOException e) {
-						LOGGER.error("Error has occurred during temporary plugin file removing", e);
-					}
-				} else {
-					LOGGER.debug(Suppliers.formattedSupplier("Uploading of the plugin - '{}' is still in progress.", path).get());
-				}
-			}));
-		} catch (IOException e) {
-			LOGGER.error("Error has occurred during temporary plugins folder listing", e);
-		}
-		LOGGER.debug("Temporary plugins removing has finished...");
-	}
-
-	private void unloadRemovedPlugins(List<IntegrationType> integrationTypes) {
-
-		LOGGER.debug("Unloading of removed plugins...");
-
-		List<String> pluginIds = pluginBox.getPlugins().stream().map(Plugin::getId).collect(Collectors.toList());
-
-		pluginIds.removeAll(integrationTypes.stream().map(IntegrationType::getName).collect(Collectors.toList()));
-
-		pluginIds.forEach(pluginId -> pluginBox.getPluginById(pluginId).ifPresent(plugin -> {
-
-			if (!isPluginStillBeingUploaded(plugin)) {
-				if (!pluginBox.deletePlugin(plugin)) {
-					LOGGER.error("Error has occurred during plugin file removing from the plugins directory");
-				}
-			}
-		}));
-
-		LOGGER.debug("Unloading of removed plugins has finished...");
-	}
-
-	private boolean isPluginStillBeingUploaded(@NotNull PluginWrapper pluginWrapper) {
-		return pluginBox.isInUploadingState(pluginWrapper.getPluginPath().getFileName().toString());
-	}
-
-	private void unloadDisabledPlugins(List<IntegrationType> integrationTypes) {
-
-		List<IntegrationType> disabledPlugins = integrationTypes.stream().filter(it -> !it.isEnabled()).collect(Collectors.toList());
-
-		disabledPlugins.forEach(dp -> pluginBox.getPluginById(dp.getName()).ifPresent(plugin -> {
-			if (pluginBox.unloadPlugin(dp)) {
-				LOGGER.debug(Suppliers.formattedSupplier("Plugin - '{}' has been successfully unloaded.", plugin.getPluginId()).get());
-			} else {
-				LOGGER.error(Suppliers.formattedSupplier("Error during unloading the plugin with id = '{}'.", plugin.getPluginId()).get());
-			}
-		}));
-	}
+  private static final Logger LOGGER = LoggerFactory.getLogger(CleanOutdatedPluginsJob.class);
+
+  private final String pluginsTempPath;
+
+  private final IntegrationTypeRepository integrationTypeRepository;
+
+  private final Pf4jPluginBox pluginBox;
+
+  private final PluginLoaderService pluginLoaderService;
+
+  @Autowired
+  public CleanOutdatedPluginsJob(@Value("${rp.plugins.temp.path}") String pluginsTempPath,
+      IntegrationTypeRepository integrationTypeRepository, Pf4jPluginBox pf4jPluginBox,
+      PluginLoaderService pluginLoaderService) {
+    this.pluginsTempPath = pluginsTempPath;
+    this.integrationTypeRepository = integrationTypeRepository;
+    this.pluginBox = pf4jPluginBox;
+    this.pluginLoaderService = pluginLoaderService;
+  }
+
+  @Scheduled(fixedDelayString = "${com.ta.reportportal.job.clean.outdated.plugins.cron}")
+  public void execute() {
+
+    removeTemporaryPlugins();
+
+    List<IntegrationType> integrationTypes = integrationTypeRepository.findAll();
+    integrationTypes.stream()
+        .filter(it -> it.getDetails() == null || it.getDetails().getDetails() == null)
+        .forEach(pluginLoaderService::checkAndDeleteIntegrationType);
+
+    unloadRemovedPlugins(integrationTypes);
+    unloadDisabledPlugins(integrationTypes);
+  }
+
+  private void removeTemporaryPlugins() {
+    Path tempPluginsPath = Paths.get(pluginsTempPath);
+
+    LOGGER.debug("Searching for temporary plugins...");
+    try (Stream<Path> pathStream = Files.walk(tempPluginsPath)) {
+      pathStream.filter(Files::isRegularFile)
+          .forEach(path -> ofNullable(path.getFileName()).ifPresent(fileName -> {
+            if (!pluginBox.isInUploadingState(fileName.toString())) {
+              try {
+                Files.deleteIfExists(path);
+                LOGGER.debug(
+                    Suppliers.formattedSupplier("Temporary plugin - '{}' has been removed", path)
+                        .get());
+              } catch (IOException e) {
+                LOGGER.error("Error has occurred during temporary plugin file removing", e);
+              }
+            } else {
+              LOGGER.debug(Suppliers.formattedSupplier(
+                  "Uploading of the plugin - '{}' is still in progress.", path).get());
+            }
+          }));
+    } catch (IOException e) {
+      LOGGER.error("Error has occurred during temporary plugins folder listing", e);
+    }
+    LOGGER.debug("Temporary plugins removing has finished...");
+  }
+
+  private void unloadRemovedPlugins(List<IntegrationType> integrationTypes) {
+
+    LOGGER.debug("Unloading of removed plugins...");
+
+    List<String> pluginIds = pluginBox.getPlugins().stream().map(Plugin::getId)
+        .collect(Collectors.toList());
+
+    pluginIds.removeAll(
+        integrationTypes.stream().map(IntegrationType::getName).collect(Collectors.toList()));
+
+    pluginIds.forEach(pluginId -> pluginBox.getPluginById(pluginId).ifPresent(plugin -> {
+
+      if (!isPluginStillBeingUploaded(plugin)) {
+        if (!pluginBox.deletePlugin(plugin)) {
+          LOGGER.error("Error has occurred during plugin file removing from the plugins directory");
+        }
+      }
+    }));
+
+    LOGGER.debug("Unloading of removed plugins has finished...");
+  }
+
+  private boolean isPluginStillBeingUploaded(@NotNull PluginWrapper pluginWrapper) {
+    return pluginBox.isInUploadingState(pluginWrapper.getPluginPath().getFileName().toString());
+  }
+
+  private void unloadDisabledPlugins(List<IntegrationType> integrationTypes) {
+
+    List<IntegrationType> disabledPlugins = integrationTypes.stream().filter(it -> !it.isEnabled())
+        .collect(Collectors.toList());
+
+    disabledPlugins.forEach(dp -> pluginBox.getPluginById(dp.getName()).ifPresent(plugin -> {
+      if (pluginBox.unloadPlugin(dp)) {
+        LOGGER.debug(Suppliers.formattedSupplier("Plugin - '{}' has been successfully unloaded.",
+            plugin.getPluginId()).get());
+      } else {
+        LOGGER.error(
+            Suppliers.formattedSupplier("Error during unloading the plugin with id = '{}'.",
+                plugin.getPluginId()).get());
+      }
+    }));
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/job/FlushingDataJob.java b/src/main/java/com/epam/ta/reportportal/job/FlushingDataJob.java
index f357e0da80..7ab883321b 100644
--- a/src/main/java/com/epam/ta/reportportal/job/FlushingDataJob.java
+++ b/src/main/java/com/epam/ta/reportportal/job/FlushingDataJob.java
@@ -99,7 +99,7 @@ public class FlushingDataJob implements Job {
   @Value("${datastore.bucketPostfix}")
   private String bucketPostfix;
 
-  @Value("${datastore.defaultBucketName")
+  @Value("${datastore.defaultBucketName}")
   private String defaultBucketName;
 
   @Override
@@ -130,11 +130,7 @@ public void execute(JobExecutionContext context) {
    * Get exclusive lock. Kill all running transactions. Truncate tables
    */
   private void truncateTables() {
-    jdbcTemplate.execute("BEGIN; " + "SELECT PG_ADVISORY_XACT_LOCK(1);"
-        + "SELECT PG_TERMINATE_BACKEND(pid) FROM pg_stat_activity WHERE datname = 'reportportal'\n"
-        + "AND pid <> PG_BACKEND_PID()\n"
-        + "AND state IN "
-        + "('idle', 'idle in transaction', 'idle in transaction (aborted)', 'disabled'); "
+    jdbcTemplate.execute("BEGIN; "
         + "TRUNCATE TABLE launch RESTART IDENTITY CASCADE;"
         + "TRUNCATE TABLE activity RESTART IDENTITY CASCADE;"
         + "TRUNCATE TABLE owned_entity RESTART IDENTITY CASCADE;"
@@ -145,7 +141,6 @@ private void truncateTables() {
   private void restartSequences() {
     jdbcTemplate.execute("ALTER SEQUENCE project_id_seq RESTART WITH 2");
     jdbcTemplate.execute("ALTER SEQUENCE users_id_seq RESTART WITH 2");
-    jdbcTemplate.execute("ALTER SEQUENCE oauth_access_token_id_seq RESTART WITH 2");
     jdbcTemplate.execute("ALTER SEQUENCE project_attribute_attribute_id_seq RESTART WITH 15");
     jdbcTemplate.execute("ALTER SEQUENCE statistics_field_sf_id_seq RESTART WITH 15");
   }
@@ -153,7 +148,7 @@ private void restartSequences() {
   private void createDefaultUser() {
     final CreateUserRQFull request = new CreateUserRQFull();
     request.setLogin("default");
-    request.setPassword(passwordEncoder.encode("1q2w3e"));
+    request.setPassword("1q2w3e");
     request.setEmail("defaultemail@domain.com");
     User user = new UserBuilder().addCreateUserFullRQ(request)
         .addUserRole(UserRole.USER)
diff --git a/src/main/java/com/epam/ta/reportportal/job/InterruptBrokenLaunchesJob.java b/src/main/java/com/epam/ta/reportportal/job/InterruptBrokenLaunchesJob.java
index c9d974c88d..362f728e3c 100644
--- a/src/main/java/com/epam/ta/reportportal/job/InterruptBrokenLaunchesJob.java
+++ b/src/main/java/com/epam/ta/reportportal/job/InterruptBrokenLaunchesJob.java
@@ -16,6 +16,10 @@
 
 package com.epam.ta.reportportal.job;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_ID;
+import static com.epam.ta.reportportal.job.PageUtil.iterateOverPages;
+import static java.time.Duration.ofSeconds;
+
 import com.epam.ta.reportportal.core.events.activity.LaunchFinishedEvent;
 import com.epam.ta.reportportal.dao.LaunchRepository;
 import com.epam.ta.reportportal.dao.LogRepository;
@@ -25,6 +29,10 @@
 import com.epam.ta.reportportal.entity.enums.StatusEnum;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.entity.project.ProjectUtils;
+import java.time.Duration;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.util.stream.Stream;
 import org.apache.commons.lang3.math.NumberUtils;
 import org.quartz.Job;
 import org.quartz.JobExecutionContext;
@@ -36,15 +44,6 @@
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.time.Duration;
-import java.time.LocalDateTime;
-import java.time.ZoneOffset;
-import java.util.stream.Stream;
-
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_ID;
-import static com.epam.ta.reportportal.job.PageUtil.iterateOverPages;
-import static java.time.Duration.ofSeconds;
-
 /**
  * Finds jobs witn duration more than defined and finishes them with interrupted
  * {@link StatusEnum#INTERRUPTED} status
@@ -54,102 +53,110 @@
 @Service
 public class InterruptBrokenLaunchesJob implements Job {
 
-	private static final Logger LOGGER = LoggerFactory.getLogger(InterruptBrokenLaunchesJob.class);
-
-	private final ApplicationEventPublisher eventPublisher;
-
-	private final LaunchRepository launchRepository;
-
-	private final TestItemRepository testItemRepository;
-
-	private final LogRepository logRepository;
-
-	private final ProjectRepository projectRepository;
-
-	@Autowired
-	public InterruptBrokenLaunchesJob(ApplicationEventPublisher eventPublisher, LaunchRepository launchRepository, TestItemRepository testItemRepository, LogRepository logRepository,
-			ProjectRepository projectRepository) {
-		this.eventPublisher = eventPublisher;
-		this.launchRepository = launchRepository;
-		this.testItemRepository = testItemRepository;
-		this.logRepository = logRepository;
-		this.projectRepository = projectRepository;
-	}
-
-	@Override
-	@Transactional
-	public void execute(JobExecutionContext context) {
-		LOGGER.info("Interrupt broken launches job has been started");
-		iterateOverPages(
-				Sort.by(Sort.Order.asc(CRITERIA_ID)),
-				projectRepository::findAllIdsAndProjectAttributes,
-				projects -> projects.forEach(project -> {
-					ProjectUtils.extractAttributeValue(project, ProjectAttributeEnum.INTERRUPT_JOB_TIME).ifPresent(it -> {
-						Duration maxDuration = ofSeconds(NumberUtils.toLong(it, 0L));
-						try (Stream<Long> ids = launchRepository.streamIdsWithStatusAndStartTimeBefore(project.getId(),
-								StatusEnum.IN_PROGRESS,
-								LocalDateTime.now(ZoneOffset.UTC).minus(maxDuration)
-						)) {
-							ids.forEach(launchId -> {
-								if (!testItemRepository.hasItemsInStatusByLaunch(launchId, StatusEnum.IN_PROGRESS)) {
-									/*
-									 * There are no test items for this launch. Just INTERRUPT
-									 * this launch
-									 */
-									interruptLaunch(launchId);
-								} else {
-									/*
-									 * Well, there are some test items started for specified
-									 * launch
-									 */
-									if (!testItemRepository.hasItemsInStatusAddedLately(launchId, maxDuration, StatusEnum.IN_PROGRESS)) {
-										/*
-										 * If there are logs, we have to check whether them
-										 * expired
-										 */
-										if (testItemRepository.hasLogs(launchId, maxDuration, StatusEnum.IN_PROGRESS)) {
-											/*
-											 * If there are logs which are still valid
-											 * (probably automation project keep writing
-											 * something)
-											 */
-											if (!logRepository.hasLogsAddedLately(maxDuration, launchId, StatusEnum.IN_PROGRESS)) {
-												interruptItems(launchId);
-											}
-										} else {
-											/*
-											 * If not just INTERRUPT all found items and launch
-											 */
-											interruptItems(launchId);
-										}
-									}
-								}
-							});
-						} catch (Exception ex) {
-							LOGGER.error("Interrupting broken launches has been failed", ex);
-							//do nothing
-						}
-					});
-				})
-		);
-	}
-
-	private void interruptLaunch(Long launchId) {
-		launchRepository.findById(launchId).ifPresent(launch -> {
-			launch.setStatus(StatusEnum.INTERRUPTED);
-			launch.setEndTime(LocalDateTime.now(ZoneOffset.UTC));
-			launchRepository.save(launch);
-			publishFinishEvent(launch);
-		});
-	}
-
-	private void publishFinishEvent(Launch launch) {
-		final LaunchFinishedEvent event = new LaunchFinishedEvent(launch);
-		eventPublisher.publishEvent(event);
-	}
-
-	private void interruptItems(Long launchId) {
-		testItemRepository.interruptInProgressItems(launchId);
-		interruptLaunch(launchId);
-	}
+  private static final Logger LOGGER = LoggerFactory.getLogger(InterruptBrokenLaunchesJob.class);
+
+  private final ApplicationEventPublisher eventPublisher;
+
+  private final LaunchRepository launchRepository;
+
+  private final TestItemRepository testItemRepository;
+
+  private final LogRepository logRepository;
+
+  private final ProjectRepository projectRepository;
+
+  @Autowired
+  public InterruptBrokenLaunchesJob(ApplicationEventPublisher eventPublisher,
+      LaunchRepository launchRepository, TestItemRepository testItemRepository,
+      LogRepository logRepository,
+      ProjectRepository projectRepository) {
+    this.eventPublisher = eventPublisher;
+    this.launchRepository = launchRepository;
+    this.testItemRepository = testItemRepository;
+    this.logRepository = logRepository;
+    this.projectRepository = projectRepository;
+  }
+
+  @Override
+  @Transactional
+  public void execute(JobExecutionContext context) {
+    LOGGER.info("Interrupt broken launches job has been started");
+    iterateOverPages(
+        Sort.by(Sort.Order.asc(CRITERIA_ID)),
+        projectRepository::findAllIdsAndProjectAttributes,
+        projects -> projects.forEach(project -> {
+          ProjectUtils.extractAttributeValue(project, ProjectAttributeEnum.INTERRUPT_JOB_TIME)
+              .ifPresent(it -> {
+                Duration maxDuration = ofSeconds(NumberUtils.toLong(it, 0L));
+                try (Stream<Long> ids = launchRepository.streamIdsWithStatusAndStartTimeBefore(
+                    project.getId(),
+                    StatusEnum.IN_PROGRESS,
+                    LocalDateTime.now(ZoneOffset.UTC).minus(maxDuration)
+                )) {
+                  ids.forEach(launchId -> {
+                    if (!testItemRepository.hasItemsInStatusByLaunch(launchId,
+                        StatusEnum.IN_PROGRESS)) {
+                      /*
+                       * There are no test items for this launch. Just INTERRUPT
+                       * this launch
+                       */
+                      interruptLaunch(launchId);
+                    } else {
+                      /*
+                       * Well, there are some test items started for specified
+                       * launch
+                       */
+                      if (!testItemRepository.hasItemsInStatusAddedLately(launchId, maxDuration,
+                          StatusEnum.IN_PROGRESS)) {
+                        /*
+                         * If there are logs, we have to check whether them
+                         * expired
+                         */
+                        if (testItemRepository.hasLogs(launchId, maxDuration,
+                            StatusEnum.IN_PROGRESS)) {
+                          /*
+                           * If there are logs which are still valid
+                           * (probably automation project keep writing
+                           * something)
+                           */
+                          if (!logRepository.hasLogsAddedLately(maxDuration, launchId,
+                              StatusEnum.IN_PROGRESS)) {
+                            interruptItems(launchId);
+                          }
+                        } else {
+                          /*
+                           * If not just INTERRUPT all found items and launch
+                           */
+                          interruptItems(launchId);
+                        }
+                      }
+                    }
+                  });
+                } catch (Exception ex) {
+                  LOGGER.error("Interrupting broken launches has been failed", ex);
+                  //do nothing
+                }
+              });
+        })
+    );
+  }
+
+  private void interruptLaunch(Long launchId) {
+    launchRepository.findById(launchId).ifPresent(launch -> {
+      launch.setStatus(StatusEnum.INTERRUPTED);
+      launch.setEndTime(LocalDateTime.now(ZoneOffset.UTC));
+      launchRepository.save(launch);
+      publishFinishEvent(launch);
+    });
+  }
+
+  private void publishFinishEvent(Launch launch) {
+    final LaunchFinishedEvent event = new LaunchFinishedEvent(launch);
+    eventPublisher.publishEvent(event);
+  }
+
+  private void interruptItems(Long launchId) {
+    testItemRepository.interruptInProgressItems(launchId);
+    interruptLaunch(launchId);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/job/JobExecutorDelegate.java b/src/main/java/com/epam/ta/reportportal/job/JobExecutorDelegate.java
index 4ea700ad56..38d92c5e40 100644
--- a/src/main/java/com/epam/ta/reportportal/job/JobExecutorDelegate.java
+++ b/src/main/java/com/epam/ta/reportportal/job/JobExecutorDelegate.java
@@ -28,20 +28,20 @@
 @Service
 public class JobExecutorDelegate {
 
-	/**
-	 * Default TaskScheduler
-	 *
-	 * @see org.springframework.scheduling.TaskScheduler
-	 */
-	@Autowired
-	private TaskScheduler taskScheduler;
+  /**
+   * Default TaskScheduler
+   *
+   * @see org.springframework.scheduling.TaskScheduler
+   */
+  @Autowired
+  private TaskScheduler taskScheduler;
 
-	/**
-	 * Submits self cancelable job
-	 *
-	 * @param selfCancelableJob
-	 */
-	public void submitJob(SelfCancelableJob selfCancelableJob) {
-		taskScheduler.schedule(selfCancelableJob, selfCancelableJob);
-	}
+  /**
+   * Submits self cancelable job
+   *
+   * @param selfCancelableJob link to job class
+   */
+  public void submitJob(SelfCancelableJob selfCancelableJob) {
+    taskScheduler.schedule(selfCancelableJob, selfCancelableJob);
+  }
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/job/LoadPluginsJob.java b/src/main/java/com/epam/ta/reportportal/job/LoadPluginsJob.java
index 23fb87bc8d..5ab29ced26 100644
--- a/src/main/java/com/epam/ta/reportportal/job/LoadPluginsJob.java
+++ b/src/main/java/com/epam/ta/reportportal/job/LoadPluginsJob.java
@@ -26,6 +26,12 @@
 import com.epam.ta.reportportal.filesystem.DataStore;
 import com.epam.ta.reportportal.job.service.PluginLoaderService;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.List;
 import org.apache.commons.io.FileUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -35,13 +41,6 @@
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.List;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
@@ -49,61 +48,80 @@
 @Service
 public class LoadPluginsJob {
 
-	private static final Logger LOGGER = LoggerFactory.getLogger(LoadPluginsJob.class);
-
-	private final IntegrationTypeRepository integrationTypeRepository;
-
-	private final PluginLoaderService pluginLoaderService;
-
-	private final String pluginsRootPath;
-
-	private final Pf4jPluginBox pluginBox;
-
-	private final DataStore dataStore;
-
-	@Autowired
-	public LoadPluginsJob(@Value("${rp.plugins.path}") String pluginsRootPath, IntegrationTypeRepository integrationTypeRepository,
-			PluginLoaderService pluginLoaderService, Pf4jPluginBox pf4jPluginBox, DataStore dataStore) {
-		this.integrationTypeRepository = integrationTypeRepository;
-		this.pluginLoaderService = pluginLoaderService;
-		this.pluginBox = pf4jPluginBox;
-		this.dataStore = dataStore;
-		this.pluginsRootPath = pluginsRootPath;
-	}
-
-	@Scheduled(fixedDelayString = "${com.ta.reportportal.job.load.plugins.cron}")
-	public void execute() {
-		List<PluginInfo> notLoadedPlugins = pluginLoaderService.getNotLoadedPluginsInfo();
-
-		notLoadedPlugins.forEach(pluginInfo -> {
-			try (InputStream inputStream = dataStore.load(pluginInfo.getFileId())) {
-				LOGGER.debug("Plugin loading has started...");
-
-				if (!Files.exists(Paths.get(pluginsRootPath, pluginInfo.getFileName()))) {
-					LOGGER.debug("Copying plugin file...");
-					FileUtils.copyToFile(inputStream, new File(pluginsRootPath, pluginInfo.getFileName()));
-				}
-
-				if (pluginInfo.isEnabled()) {
-					IntegrationType integrationType = integrationTypeRepository.findByName(pluginInfo.getId())
-							.orElseThrow(() -> new ReportPortalException(ErrorType.INTEGRATION_NOT_FOUND, pluginInfo.getId()));
-
-					boolean isLoaded = pluginBox.loadPlugin(integrationType.getName(), integrationType.getDetails());
-
-					if (isLoaded) {
-						LOGGER.debug(Suppliers.formattedSupplier("Plugin - '{}' has been successfully started.", integrationType.getName())
-								.get());
-					} else {
-						LOGGER.error(Suppliers.formattedSupplier("Plugin - '{}' has not been started.", integrationType.getName()).get());
-					}
-				}
-
-			} catch (IOException ex) {
-				LOGGER.error("Error has occurred during plugin copying from the Data store", ex);
-				//do nothing
-			}
-		});
-
-	}
+  private static final Logger LOGGER = LoggerFactory.getLogger(LoadPluginsJob.class);
+
+  private final IntegrationTypeRepository integrationTypeRepository;
+
+  private final PluginLoaderService pluginLoaderService;
+
+  private final String pluginsRootPath;
+
+  private final Pf4jPluginBox pluginBox;
+
+  private final DataStore dataStore;
+
+  @Autowired
+  public LoadPluginsJob(@Value("${rp.plugins.path}") String pluginsRootPath,
+      IntegrationTypeRepository integrationTypeRepository,
+      PluginLoaderService pluginLoaderService, Pf4jPluginBox pf4jPluginBox, DataStore dataStore) {
+    this.integrationTypeRepository = integrationTypeRepository;
+    this.pluginLoaderService = pluginLoaderService;
+    this.pluginBox = pf4jPluginBox;
+    this.dataStore = dataStore;
+    this.pluginsRootPath = pluginsRootPath;
+  }
+
+  @Scheduled(fixedDelayString = "${com.ta.reportportal.job.load.plugins.cron}")
+  public void execute() {
+    List<PluginInfo> notLoadedPlugins = pluginLoaderService.getNotLoadedPluginsInfo();
+
+    notLoadedPlugins.forEach(pluginInfo -> {
+      try (InputStream inputStream = dataStore.load(pluginInfo.getFileId())) {
+        LOGGER.debug("Plugin loading has started...");
+
+        if (!Files.exists(Paths.get(pluginsRootPath, pluginInfo.getFileName()))) {
+          LOGGER.debug("Copying plugin file...");
+          FileUtils.copyToFile(inputStream, new File(pluginsRootPath, pluginInfo.getFileName()));
+        }
+
+        if (pluginInfo.isEnabled()) {
+          IntegrationType integrationType = integrationTypeRepository.findByName(pluginInfo.getId())
+              .orElseThrow(() -> new ReportPortalException(ErrorType.INTEGRATION_NOT_FOUND,
+                  pluginInfo.getId()));
+
+          unloadPlugin(integrationType);
+
+          boolean isLoaded = pluginBox.loadPlugin(integrationType.getName(),
+              integrationType.getDetails());
+
+          if (isLoaded) {
+            LOGGER.debug(Suppliers.formattedSupplier("Plugin - '{}' has been successfully started.",
+                    integrationType.getName())
+                .get());
+          } else {
+            LOGGER.error(Suppliers.formattedSupplier("Plugin - '{}' has not been started.",
+                integrationType.getName()).get());
+          }
+        }
+
+      } catch (IOException ex) {
+        LOGGER.error("Error has occurred during plugin copying from the Data store", ex);
+        //do nothing
+      }
+    });
+
+  }
+
+  private void unloadPlugin(IntegrationType integrationType) {
+    pluginBox.getPluginById(integrationType.getName()).ifPresent(plugin -> {
+
+      if (!pluginBox.unloadPlugin(integrationType)) {
+        throw new ReportPortalException(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
+            Suppliers.formattedSupplier("Error during unloading the plugin with id = '{}'",
+                integrationType.getName()).get()
+        );
+      }
+    });
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/job/PageUtil.java b/src/main/java/com/epam/ta/reportportal/job/PageUtil.java
index c8a9200fa3..d25bcd7663 100644
--- a/src/main/java/com/epam/ta/reportportal/job/PageUtil.java
+++ b/src/main/java/com/epam/ta/reportportal/job/PageUtil.java
@@ -15,76 +15,80 @@
  */
 package com.epam.ta.reportportal.job;
 
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.domain.Sort;
 
-import java.util.List;
-import java.util.function.Consumer;
-import java.util.function.Function;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public class PageUtil {
 
-	private PageUtil() {
-		//static only
-	}
+  private PageUtil() {
+    //static only
+  }
 
-	private static final int DEFAULT_PAGE_SIZE = 50;
+  private static final int DEFAULT_PAGE_SIZE = 50;
 
-	/**
-	 * Iterates over all pages found
-	 *
-	 * @param getFunc  Get Page function
-	 * @param consumer Page processor
-	 * @param <T>      Type of page entity
-	 */
-	public static <T> void iterateOverPages(Sort sort, Function<Pageable, Page<T>> getFunc, Consumer<List<T>> consumer) {
-		iterateOverPages(DEFAULT_PAGE_SIZE, sort, getFunc, consumer);
-	}
+  /**
+   * Iterates over all pages found
+   *
+   * @param getFunc  Get Page function
+   * @param consumer Page processor
+   * @param sort     Sort by
+   * @param <T>      Type of page entity
+   */
+  public static <T> void iterateOverPages(Sort sort, Function<Pageable, Page<T>> getFunc,
+      Consumer<List<T>> consumer) {
+    iterateOverPages(DEFAULT_PAGE_SIZE, sort, getFunc, consumer);
+  }
 
-	/**
-	 * Iterates over all pages found
-	 *
-	 * @param pageSize page size
-	 * @param getFunc  Get Page function
-	 * @param consumer Page processor
-	 * @param <T>      Type of page entity
-	 */
-	public static <T> void iterateOverPages(int pageSize, Sort sort, Function<Pageable, Page<T>> getFunc, Consumer<List<T>> consumer) {
-		//first page
-		Page<T> pageData = getFunc.apply(PageRequest.of(0, pageSize, sort));
-		List<T> content = pageData.getContent();
-		consumer.accept(content);
+  /**
+   * Iterates over all pages found
+   *
+   * @param pageSize page size
+   * @param getFunc  Get Page function
+   * @param consumer Page processor
+   * @param sort     Sort by
+   * @param <T>      Type of page entity
+   */
+  public static <T> void iterateOverPages(int pageSize, Sort sort,
+      Function<Pageable, Page<T>> getFunc, Consumer<List<T>> consumer) {
+    //first page
+    Page<T> pageData = getFunc.apply(PageRequest.of(0, pageSize, sort));
+    List<T> content = pageData.getContent();
+    consumer.accept(content);
 
-		while (!pageData.isLast()) {
-			pageData = getFunc.apply(pageData.nextPageable());
-			consumer.accept(pageData.getContent());
-		}
-	}
+    while (!pageData.isLast()) {
+      pageData = getFunc.apply(pageData.nextPageable());
+      consumer.accept(pageData.getContent());
+    }
+  }
 
-	/**
-	 * Iterates over all pages found
-	 *
-	 * @param pageSize page size
-	 * @param getFunc  Get {@link List} content function
-	 * @param consumer Page processor
-	 * @param <T>      Type of {@link List} entity
-	 */
-	public static <T> void iterateOverContent(int pageSize, Function<Pageable, List<T>> getFunc, Consumer<List<T>> consumer) {
-		//first page
-		Pageable pageRequest = PageRequest.of(0, pageSize);
-		List<T> content = getFunc.apply(pageRequest);
-		consumer.accept(content);
+  /**
+   * Iterates over all pages found
+   *
+   * @param pageSize page size
+   * @param getFunc  Get {@link List} content function
+   * @param consumer Page processor
+   * @param <T>      Type of {@link List} entity
+   */
+  public static <T> void iterateOverContent(int pageSize, Function<Pageable, List<T>> getFunc,
+      Consumer<List<T>> consumer) {
+    //first page
+    Pageable pageRequest = PageRequest.of(0, pageSize);
+    List<T> content = getFunc.apply(pageRequest);
+    consumer.accept(content);
 
-		while (content.size() >= pageSize) {
-			pageRequest = pageRequest.next();
-			content = getFunc.apply(pageRequest);
-			consumer.accept(content);
-		}
-	}
+    while (content.size() >= pageSize) {
+      pageRequest = pageRequest.next();
+      content = getFunc.apply(pageRequest);
+      consumer.accept(content);
+    }
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/job/SelfCancelableJob.java b/src/main/java/com/epam/ta/reportportal/job/SelfCancelableJob.java
index 339b49e726..863c852f52 100644
--- a/src/main/java/com/epam/ta/reportportal/job/SelfCancelableJob.java
+++ b/src/main/java/com/epam/ta/reportportal/job/SelfCancelableJob.java
@@ -16,41 +16,40 @@
 
 package com.epam.ta.reportportal.job;
 
+import java.util.Date;
 import org.springframework.scheduling.Trigger;
 import org.springframework.scheduling.TriggerContext;
 
-import java.util.Date;
-
 /**
- * Job contains run method and trigger. The main idea to provide possibility to
- * cancel next execution from run method. User can override job, call
- * {@link SelfCancelableJob#oneMoreTime(boolean)} method and this way cancel
- * next execution. In case if we need job to keep executed, we do not call
- * anything, next execution time calculation delegated to provided trigger
+ * Job contains run method and trigger. The main idea to provide possibility to cancel next
+ * execution from run method. User can override job, call
+ * {@link SelfCancelableJob#oneMoreTime(boolean)} method and this way cancel next execution. In case
+ * if we need job to keep executed, we do not call anything, next execution time calculation
+ * delegated to provided trigger
  *
  * @author Andrei Varabyeu
  */
 public abstract class SelfCancelableJob implements Runnable, Trigger {
 
-	private Trigger triggerDelegate;
+  private Trigger triggerDelegate;
 
-	private boolean oneMoreTime = true;
+  private boolean oneMoreTime = true;
 
-	public SelfCancelableJob(Trigger trigger) {
-		this.triggerDelegate = trigger;
-	}
+  public SelfCancelableJob(Trigger trigger) {
+    this.triggerDelegate = trigger;
+  }
 
-	@Override
-	public Date nextExecutionTime(TriggerContext triggerContext) {
-		if (oneMoreTime) {
-			return triggerDelegate.nextExecutionTime(triggerContext);
-		} else {
-			return null;
-		}
-	}
+  @Override
+  public Date nextExecutionTime(TriggerContext triggerContext) {
+    if (oneMoreTime) {
+      return triggerDelegate.nextExecutionTime(triggerContext);
+    } else {
+      return null;
+    }
+  }
 
-	protected void oneMoreTime(boolean oneMoreTime) {
-		this.oneMoreTime = oneMoreTime;
-	}
+  protected void oneMoreTime(boolean oneMoreTime) {
+    this.oneMoreTime = oneMoreTime;
+  }
 
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/job/service/PluginLoaderService.java b/src/main/java/com/epam/ta/reportportal/job/service/PluginLoaderService.java
index 7898899f82..f13627e4f3 100644
--- a/src/main/java/com/epam/ta/reportportal/job/service/PluginLoaderService.java
+++ b/src/main/java/com/epam/ta/reportportal/job/service/PluginLoaderService.java
@@ -18,7 +18,6 @@
 
 import com.epam.ta.reportportal.core.plugin.PluginInfo;
 import com.epam.ta.reportportal.entity.integration.IntegrationType;
-
 import java.util.List;
 
 /**
@@ -26,7 +25,7 @@
  */
 public interface PluginLoaderService {
 
-	List<PluginInfo> getNotLoadedPluginsInfo();
+  List<PluginInfo> getNotLoadedPluginsInfo();
 
-	void checkAndDeleteIntegrationType(IntegrationType integrationType);
+  void checkAndDeleteIntegrationType(IntegrationType integrationType);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/job/service/impl/PluginLoaderServiceImpl.java b/src/main/java/com/epam/ta/reportportal/job/service/impl/PluginLoaderServiceImpl.java
index 8e60707422..7f66702472 100644
--- a/src/main/java/com/epam/ta/reportportal/job/service/impl/PluginLoaderServiceImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/job/service/impl/PluginLoaderServiceImpl.java
@@ -16,6 +16,10 @@
 
 package com.epam.ta.reportportal.job.service.impl;
 
+import static com.epam.reportportal.extension.common.IntegrationTypeProperties.FILE_ID;
+import static com.epam.reportportal.extension.common.IntegrationTypeProperties.FILE_NAME;
+import static com.epam.reportportal.extension.common.IntegrationTypeProperties.VERSION;
+
 import com.epam.reportportal.extension.common.IntegrationTypeProperties;
 import com.epam.ta.reportportal.commons.validation.Suppliers;
 import com.epam.ta.reportportal.core.plugin.Pf4jPluginBox;
@@ -26,13 +30,6 @@
 import com.epam.ta.reportportal.job.service.PluginLoaderService;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
-import org.pf4j.PluginWrapper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
 import java.io.IOException;
 import java.nio.file.Files;
 import java.util.Arrays;
@@ -40,8 +37,12 @@
 import java.util.Map;
 import java.util.Optional;
 import java.util.stream.Stream;
-
-import static com.epam.reportportal.extension.common.IntegrationTypeProperties.*;
+import org.pf4j.PluginWrapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -49,95 +50,101 @@
 @Service
 public class PluginLoaderServiceImpl implements PluginLoaderService {
 
-	private static final Logger LOGGER = LoggerFactory.getLogger(PluginLoaderServiceImpl.class);
-
-	private final IntegrationTypeRepository integrationTypeRepository;
-	private final Pf4jPluginBox pluginBox;
-
-	@Autowired
-	public PluginLoaderServiceImpl(IntegrationTypeRepository integrationTypeRepository, Pf4jPluginBox pluginBox) {
-		this.integrationTypeRepository = integrationTypeRepository;
-		this.pluginBox = pluginBox;
-	}
-
-	@Override
-	public List<PluginInfo> getNotLoadedPluginsInfo() {
-
-		LOGGER.debug("Searching for not loaded plugins...");
-
-		List<PluginInfo> notLoadedPlugins = Lists.newArrayList();
-
-		integrationTypeRepository.findAll()
-				.stream()
-				.filter(IntegrationType::isEnabled)
-				.filter(it -> it.getDetails() != null && it.getDetails().getDetails() != null)
-				.filter(this::isMandatoryFieldsExist)
-				.forEach(it -> {
-
-					Map<IntegrationTypeProperties, Object> pluginProperties = retrievePluginProperties(it);
-
-					Optional<PluginWrapper> pluginWrapper = pluginBox.getPluginById(it.getName());
-					if (pluginWrapper.isEmpty() || !String.valueOf(pluginProperties.get(VERSION))
-							.equalsIgnoreCase(pluginWrapper.get().getDescriptor().getVersion())) {
-
-						PluginInfo pluginInfo = new PluginInfo(it.getName(),
-								String.valueOf(pluginProperties.get(VERSION)),
-								String.valueOf(pluginProperties.get(FILE_ID)),
-								String.valueOf(pluginProperties.get(FILE_NAME)),
-								it.isEnabled()
-						);
-
-						notLoadedPlugins.add(pluginInfo);
-					}
-
-				});
-
-		LOGGER.debug(Suppliers.formattedSupplier("{} not loaded plugins have been found", notLoadedPlugins.size()).get());
-
-		return notLoadedPlugins;
-	}
-
-	@Transactional
-	@Override
-	public void checkAndDeleteIntegrationType(IntegrationType integrationType) {
-		if (isIntegrationTypeAvailableForRemoving(integrationType)) {
-			integrationTypeRepository.deleteById(integrationType.getId());
-		}
-	}
-
-	private boolean isMandatoryFieldsExist(IntegrationType integrationType) {
-		Map<String, Object> details = integrationType.getDetails().getDetails();
-		return Stream.of(FILE_ID, VERSION, FILE_NAME).allMatch(property -> property.getValue(details).isPresent());
-
-	}
-
-	private Map<IntegrationTypeProperties, Object> retrievePluginProperties(IntegrationType integrationType) {
-
-		Map<String, Object> details = integrationType.getDetails().getDetails();
-		Map<IntegrationTypeProperties, Object> pluginProperties = Maps.newHashMapWithExpectedSize(IntegrationTypeProperties.values().length);
-		Arrays.stream(IntegrationTypeProperties.values())
-				.forEach(property -> property.getValue(details).ifPresent(value -> pluginProperties.put(property, value)));
-		return pluginProperties;
-	}
-
-	private boolean isIntegrationTypeAvailableForRemoving(IntegrationType integrationType) {
-		/* hack: while email, ad, ldap, saml aren't  plugins - it shouldn't be proceeded as a plugin */
-		if (ReservedIntegrationTypeEnum.fromName(integrationType.getName()).isPresent()) {
-			return false;
-		} else {
-			return pluginBox.getPluginById(integrationType.getName()).map(p -> {
-				if (pluginBox.unloadPlugin(integrationType)) {
-					try {
-						Files.deleteIfExists(p.getPluginPath());
-						return true;
-					} catch (IOException ex) {
-						LOGGER.error("Error has occurred during plugin removing from the root directory", ex);
-						return false;
-					}
-				} else {
-					return false;
-				}
-			}).orElse(true);
-		}
-	}
+  private static final Logger LOGGER = LoggerFactory.getLogger(PluginLoaderServiceImpl.class);
+
+  private final IntegrationTypeRepository integrationTypeRepository;
+  private final Pf4jPluginBox pluginBox;
+
+  @Autowired
+  public PluginLoaderServiceImpl(IntegrationTypeRepository integrationTypeRepository,
+      Pf4jPluginBox pluginBox) {
+    this.integrationTypeRepository = integrationTypeRepository;
+    this.pluginBox = pluginBox;
+  }
+
+  @Override
+  public List<PluginInfo> getNotLoadedPluginsInfo() {
+
+    LOGGER.debug("Searching for not loaded plugins...");
+
+    List<PluginInfo> notLoadedPlugins = Lists.newArrayList();
+
+    integrationTypeRepository.findAll()
+        .stream()
+        .filter(IntegrationType::isEnabled)
+        .filter(it -> it.getDetails() != null && it.getDetails().getDetails() != null)
+        .filter(this::isMandatoryFieldsExist)
+        .forEach(it -> {
+
+          Map<IntegrationTypeProperties, Object> pluginProperties = retrievePluginProperties(it);
+
+          Optional<PluginWrapper> pluginWrapper = pluginBox.getPluginById(it.getName());
+          if (pluginWrapper.isEmpty() || !String.valueOf(pluginProperties.get(VERSION))
+              .equalsIgnoreCase(pluginWrapper.get().getDescriptor().getVersion())) {
+
+            PluginInfo pluginInfo = new PluginInfo(it.getName(),
+                String.valueOf(pluginProperties.get(VERSION)),
+                String.valueOf(pluginProperties.get(FILE_ID)),
+                String.valueOf(pluginProperties.get(FILE_NAME)),
+                it.isEnabled()
+            );
+
+            notLoadedPlugins.add(pluginInfo);
+          }
+
+        });
+
+    LOGGER.debug(Suppliers.formattedSupplier("{} not loaded plugins have been found",
+        notLoadedPlugins.size()).get());
+
+    return notLoadedPlugins;
+  }
+
+  @Transactional
+  @Override
+  public void checkAndDeleteIntegrationType(IntegrationType integrationType) {
+    if (isIntegrationTypeAvailableForRemoving(integrationType)) {
+      integrationTypeRepository.deleteById(integrationType.getId());
+    }
+  }
+
+  private boolean isMandatoryFieldsExist(IntegrationType integrationType) {
+    Map<String, Object> details = integrationType.getDetails().getDetails();
+    return Stream.of(FILE_ID, VERSION, FILE_NAME)
+        .allMatch(property -> property.getValue(details).isPresent());
+
+  }
+
+  private Map<IntegrationTypeProperties, Object> retrievePluginProperties(
+      IntegrationType integrationType) {
+
+    Map<String, Object> details = integrationType.getDetails().getDetails();
+    Map<IntegrationTypeProperties, Object> pluginProperties = Maps.newHashMapWithExpectedSize(
+        IntegrationTypeProperties.values().length);
+    Arrays.stream(IntegrationTypeProperties.values())
+        .forEach(property -> property.getValue(details)
+            .ifPresent(value -> pluginProperties.put(property, value)));
+    return pluginProperties;
+  }
+
+  private boolean isIntegrationTypeAvailableForRemoving(IntegrationType integrationType) {
+    /* hack: while email, ad, ldap, saml aren't  plugins - it shouldn't be proceeded as a plugin */
+    if (ReservedIntegrationTypeEnum.fromName(integrationType.getName()).isPresent()) {
+      return false;
+    } else {
+      return pluginBox.getPluginById(integrationType.getName()).map(p -> {
+        if (pluginBox.unloadPlugin(integrationType)) {
+          try {
+            Files.deleteIfExists(p.getPluginPath());
+            return true;
+          } catch (IOException ex) {
+            LOGGER.error("Error has occurred during plugin removing from the root directory", ex);
+            return false;
+          }
+        } else {
+          return false;
+        }
+      }).orElse(true);
+    }
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/pipeline/PipelineConstructor.java b/src/main/java/com/epam/ta/reportportal/pipeline/PipelineConstructor.java
index c02294706f..2c3a23b24b 100644
--- a/src/main/java/com/epam/ta/reportportal/pipeline/PipelineConstructor.java
+++ b/src/main/java/com/epam/ta/reportportal/pipeline/PipelineConstructor.java
@@ -24,13 +24,13 @@
  */
 public class PipelineConstructor<T> {
 
-	private final List<PipelinePartProvider<T>> providers;
+  private final List<PipelinePartProvider<T>> providers;
 
-	public PipelineConstructor(List<PipelinePartProvider<T>> providers) {
-		this.providers = providers;
-	}
+  public PipelineConstructor(List<PipelinePartProvider<T>> providers) {
+    this.providers = providers;
+  }
 
-	public List<PipelinePart> construct(T source) {
-		return providers.stream().map(p -> p.provide(source)).collect(Collectors.toList());
-	}
+  public List<PipelinePart> construct(T source) {
+    return providers.stream().map(p -> p.provide(source)).collect(Collectors.toList());
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/pipeline/PipelinePart.java b/src/main/java/com/epam/ta/reportportal/pipeline/PipelinePart.java
index 4f69ae0d77..65e7549325 100644
--- a/src/main/java/com/epam/ta/reportportal/pipeline/PipelinePart.java
+++ b/src/main/java/com/epam/ta/reportportal/pipeline/PipelinePart.java
@@ -21,5 +21,5 @@
  */
 public interface PipelinePart {
 
-	void handle();
+  void handle();
 }
diff --git a/src/main/java/com/epam/ta/reportportal/pipeline/PipelinePartProvider.java b/src/main/java/com/epam/ta/reportportal/pipeline/PipelinePartProvider.java
index 59dad7450b..55b9e13a7a 100644
--- a/src/main/java/com/epam/ta/reportportal/pipeline/PipelinePartProvider.java
+++ b/src/main/java/com/epam/ta/reportportal/pipeline/PipelinePartProvider.java
@@ -21,5 +21,5 @@
  */
 public interface PipelinePartProvider<T> {
 
-	PipelinePart provide(T source);
+  PipelinePart provide(T source);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/pipeline/TransactionalPipeline.java b/src/main/java/com/epam/ta/reportportal/pipeline/TransactionalPipeline.java
index ca3d0b70a1..d5ed5f04c3 100644
--- a/src/main/java/com/epam/ta/reportportal/pipeline/TransactionalPipeline.java
+++ b/src/main/java/com/epam/ta/reportportal/pipeline/TransactionalPipeline.java
@@ -16,19 +16,18 @@
 
 package com.epam.ta.reportportal.pipeline;
 
+import java.util.List;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.List;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
 public class TransactionalPipeline {
 
-	@Transactional
-	public void run(List<PipelinePart> parts) {
-		parts.forEach(PipelinePart::handle);
-	}
+  @Transactional
+  public void run(List<PipelinePart> parts) {
+    parts.forEach(PipelinePart::handle);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/plugin/Pf4jPluginManager.java b/src/main/java/com/epam/ta/reportportal/plugin/Pf4jPluginManager.java
index 38c7e5daaa..07b539354e 100644
--- a/src/main/java/com/epam/ta/reportportal/plugin/Pf4jPluginManager.java
+++ b/src/main/java/com/epam/ta/reportportal/plugin/Pf4jPluginManager.java
@@ -16,6 +16,9 @@
 
 package com.epam.ta.reportportal.plugin;
 
+import static com.epam.ta.reportportal.commons.Predicates.equalTo;
+import static java.util.Optional.ofNullable;
+
 import com.epam.reportportal.extension.ReportPortalExtensionPoint;
 import com.epam.reportportal.extension.common.ExtensionPoint;
 import com.epam.reportportal.extension.common.IntegrationTypeProperties;
@@ -37,6 +40,16 @@
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.google.common.cache.Cache;
 import com.google.common.cache.CacheBuilder;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -50,639 +63,700 @@
 import org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory;
 import org.springframework.context.ApplicationEventPublisher;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.commons.Predicates.equalTo;
-import static java.util.Optional.ofNullable;
-
 /**
- * {@link Pf4jPluginManager#uploadingPlugins} Holder for the plugin cleaning job: {@link com.epam.ta.reportportal.job.CleanOutdatedPluginsJob}
- * to prevent the removing of the plugins that are still being processed within the database transaction with
+ * {@link Pf4jPluginManager#uploadingPlugins} Holder for the plugin cleaning job:
+ * {@link com.epam.ta.reportportal.job.CleanOutdatedPluginsJob} to prevent the removing of the
+ * plugins that are still being processed within the database transaction with
  * {@link com.epam.ta.reportportal.entity.integration.IntegrationType} in uncommitted state
  */
 public class Pf4jPluginManager implements Pf4jPluginBox {
 
-	public static final Logger LOGGER = LoggerFactory.getLogger(Pf4jPluginManager.class);
-
-	public static final String LOAD_KEY = "load";
-	public static final String UNLOAD_KEY = "unload";
-
-	private static final long MAXIMUM_UPLOADED_PLUGINS = 50;
-	private static final long PLUGIN_LIVE_TIME = 2;
-
-	private final String pluginsDir;
-	private final String pluginsTempDir;
-	private final String resourcesDir;
-
-	private final Cache<String, Path> uploadingPlugins;
-
-	private final PluginLoader pluginLoader;
-	private final IntegrationTypeRepository integrationTypeRepository;
-
-	private final PluginManager pluginManager;
-	private final AutowireCapableBeanFactory autowireCapableBeanFactory;
-
-	private final ApplicationEventPublisher applicationEventPublisher;
-
-	public Pf4jPluginManager(String pluginsDir, String pluginsTempPath, String resourcesDir, PluginLoader pluginLoader,
-			IntegrationTypeRepository integrationTypeRepository, PluginManager pluginManager,
-			AutowireCapableBeanFactory autowireCapableBeanFactory, ApplicationEventPublisher applicationEventPublisher) throws IOException {
-		this.pluginsDir = pluginsDir;
-		Files.createDirectories(Paths.get(this.pluginsDir));
-		this.resourcesDir = resourcesDir;
-		Files.createDirectories(Paths.get(this.resourcesDir));
-		this.pluginsTempDir = pluginsTempPath;
-		Files.createDirectories(Paths.get(this.pluginsTempDir));
-		this.autowireCapableBeanFactory = autowireCapableBeanFactory;
-		this.applicationEventPublisher = applicationEventPublisher;
-		this.pluginLoader = pluginLoader;
-		this.integrationTypeRepository = integrationTypeRepository;
-		this.uploadingPlugins = CacheBuilder.newBuilder()
-				.maximumSize(MAXIMUM_UPLOADED_PLUGINS)
-				.expireAfterWrite(PLUGIN_LIVE_TIME, TimeUnit.MINUTES)
-				.build();
-		this.pluginManager = pluginManager;
-	}
-
-	@Override
-	public List<Plugin> getPlugins() {
-		return this.pluginManager.getPlugins()
-				.stream()
-				.flatMap(plugin -> pluginManager.getExtensionClasses(plugin.getPluginId())
-						.stream()
-						.map(ExtensionPoint::findByExtension)
-						.filter(Optional::isPresent)
-						.map(it -> new Plugin(plugin.getPluginId(), it.get())))
-				.collect(Collectors.toList());
-	}
-
-	@Override
-	public Optional<Plugin> getPlugin(String type) {
-		return getPlugins().stream().filter(p -> p.getType().name().equalsIgnoreCase(type)).findAny();
-	}
-
-	@Override
-	public <T> Optional<T> getInstance(String name, Class<T> extension) {
-		return pluginManager.getExtensions(extension, name).stream().findFirst();
-	}
-
-	@Override
-	public <T> Optional<T> getInstance(Class<T> extension) {
-		return pluginManager.getExtensions(extension).stream().findFirst();
-	}
-
-	@Override
-	public void startUp() {
-		// load and start all enabled plugins of application
-		integrationTypeRepository.findAll()
-				.stream()
-				.filter(IntegrationType::isEnabled)
-				.forEach(integrationType -> ofNullable(integrationType.getDetails()).ifPresent(integrationTypeDetails -> {
-					try {
-						loadPlugin(integrationType.getName(), integrationTypeDetails);
-					} catch (Exception ex) {
-						LOGGER.error("Unable to load plugin '{}'", integrationType.getName());
-					}
-				}));
-
-	}
-
-	@Override
-	public void shutDown() {
-		// stop and unload all plugins
-		pluginManager.stopPlugins();
-		pluginManager.getPlugins().forEach(p -> pluginManager.unloadPlugin(p.getPluginId()));
-	}
-
-	@Override
-	public PluginState startUpPlugin(String pluginId) {
-
-		PluginWrapper pluginWrapper = ofNullable(pluginManager.getPlugin(pluginId)).orElseThrow(() -> new ReportPortalException(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
-				"Plugin not found: " + pluginId
-		));
-
-		return pluginManager.startPlugin(pluginWrapper.getPluginId());
-	}
-
-	@Override
-	public boolean loadPlugin(String pluginId, IntegrationTypeDetails integrationTypeDetails) {
-		return ofNullable(integrationTypeDetails.getDetails()).map(details -> {
-			String fileName = IntegrationTypeProperties.FILE_NAME.getValue(details)
-					.map(String::valueOf)
-					.orElseThrow(() -> new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR,
-							Suppliers.formattedSupplier("'File name' property of the plugin - '{}' is not specified", pluginId).get()
-					));
-
-			Path pluginPath = Paths.get(pluginsDir, fileName);
-			if (Files.notExists(pluginPath)) {
-				String fileId = IntegrationTypeProperties.FILE_ID.getValue(details)
-						.map(String::valueOf)
-						.orElseThrow(() -> new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR,
-								Suppliers.formattedSupplier("'File id' property of the plugin - '{}' is not specified", pluginId).get()
-						));
-				try {
-					pluginLoader.copyFromDataStore(fileId, pluginPath, Paths.get(resourcesDir, pluginId));
-				} catch (IOException e) {
-					throw new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR,
-							Suppliers.formattedSupplier("Unable to load plugin - '{}' from the data store", pluginId).get()
-					);
-				}
-			} else {
-				copyPluginResources(pluginPath, pluginId);
-			}
-
-			return ofNullable(pluginManager.loadPlugin(pluginPath)).map(id -> {
-				if (PluginState.STARTED == pluginManager.startPlugin(pluginId)) {
-					Optional<org.pf4j.ExtensionPoint> extensionPoint = this.getInstance(pluginId, org.pf4j.ExtensionPoint.class);
-					extensionPoint.ifPresent(extension -> LOGGER.info(Suppliers.formattedSupplier("Plugin - '{}' initialized.", pluginId)
-							.get()));
-					applicationEventPublisher.publishEvent(new PluginEvent(pluginId, LOAD_KEY));
-					return true;
-				} else {
-					return false;
-				}
-			}).orElse(Boolean.FALSE);
-		}).orElse(Boolean.FALSE);
-
-	}
-
-	private void copyPluginResources(Path pluginPath, String pluginId) {
-		try {
-			pluginLoader.copyPluginResource(pluginPath, Paths.get(resourcesDir, pluginId));
-		} catch (IOException e) {
-			throw new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR,
-					Suppliers.formattedSupplier("Unable to load resources of the - '{}' plugin", pluginId).get()
-			);
-		}
-	}
-
-	@Override
-	public boolean unloadPlugin(IntegrationType integrationType) {
-		applicationEventPublisher.publishEvent(new PluginEvent(integrationType.getName(), UNLOAD_KEY));
-		destroyDependency(integrationType.getName());
-		return pluginManager.unloadPlugin(integrationType.getName());
-	}
-
-	@Override
-	public boolean deletePlugin(String pluginId) {
-		return integrationTypeRepository.findByName(pluginId).map(this::deletePlugin).orElse(Boolean.TRUE);
-	}
-
-	@Override
-	public boolean deletePlugin(PluginWrapper pluginWrapper) {
-		return integrationTypeRepository.findByName(pluginWrapper.getPluginId()).map(this::deletePlugin).orElseGet(() -> {
-			applicationEventPublisher.publishEvent(new PluginEvent(pluginWrapper.getPluginId(), UNLOAD_KEY));
-			deletePluginResources(Paths.get(resourcesDir, pluginWrapper.getPluginId()).toString());
-			destroyDependency(pluginWrapper.getPluginId());
-			return pluginManager.deletePlugin(pluginWrapper.getPluginId());
-		});
-	}
-
-	private boolean deletePlugin(IntegrationType integrationType) {
-		Optional<Map<String, Object>> pluginData = ofNullable(integrationType.getDetails()).map(IntegrationTypeDetails::getDetails);
-		pluginData.ifPresent(this::deletePluginResources);
-
-		applicationEventPublisher.publishEvent(new PluginEvent(integrationType.getName(), UNLOAD_KEY));
-
-		boolean pluginRemoved = ofNullable(pluginManager.getPlugin(integrationType.getName())).map(pluginWrapper -> {
-			destroyDependency(pluginWrapper.getPluginId());
-			if (integrationType.isEnabled()) {
-				return pluginManager.deletePlugin(integrationType.getName());
-			}
-			return true;
-		}).orElse(Boolean.TRUE);
-
-		boolean pluginFileRemoved = pluginData.map(this::deletePluginFile).orElse(Boolean.TRUE);
-
-		return pluginRemoved && pluginFileRemoved;
-	}
-
-	private void deletePluginResources(Map<String, Object> details) {
-		IntegrationTypeProperties.RESOURCES_DIRECTORY.getValue(details).map(String::valueOf).ifPresent(this::deletePluginResources);
-		IntegrationTypeProperties.FILE_ID.getValue(details).map(String::valueOf).ifPresent(pluginLoader::deleteFromDataStore);
-	}
-
-	private void deletePluginResources(String resourcesDir) {
-		try {
-			FileUtils.deleteDirectory(FileUtils.getFile(resourcesDir));
-		} catch (IOException e) {
-			throw new ReportPortalException(ErrorType.PLUGIN_REMOVE_ERROR, "Unable to delete plugin resources.");
-		}
-	}
-
-	private boolean deletePluginFile(Map<String, Object> details) {
-		return IntegrationTypeProperties.FILE_NAME.getValue(details)
-				.map(String::valueOf)
-				.map(fileName -> Paths.get(pluginsDir, fileName))
-				.map(path -> {
-					try {
-						if (Files.exists(path)) {
-							return Files.deleteIfExists(path);
-						} else {
-							return true;
-						}
-					} catch (IOException e) {
-						throw new ReportPortalException(ErrorType.PLUGIN_REMOVE_ERROR,
-								"Error during plugin file removing from the filesystem: " + e.getMessage()
-						);
-					}
-
-				})
-				.orElse(Boolean.TRUE);
-	}
-
-	@Override
-	public Optional<PluginWrapper> getPluginById(String id) {
-		return ofNullable(pluginManager.getPlugin(id));
-	}
-
-	@Override
-	public boolean isInUploadingState(String fileName) {
-		return uploadingPlugins.asMap().containsKey(fileName);
-	}
-
-	@Override
-	public IntegrationType uploadPlugin(final String uploadedPluginName, final InputStream fileStream) {
-		PluginInfo newPluginInfo = resolvePluginInfo(uploadedPluginName, fileStream);
-		IntegrationTypeDetails pluginDetails = pluginLoader.resolvePluginDetails(newPluginInfo);
-
-		Optional<PluginWrapper> previousPlugin = getPluginById(newPluginInfo.getId());
-		previousPlugin.ifPresent(this::unloadPreviousPlugin);
-
-		return ofNullable(pluginManager.loadPlugin(Paths.get(pluginsTempDir, uploadedPluginName))).map(pluginId -> {
-			IntegrationTypeDetails newPluginDetails = copyPlugin(newPluginInfo, pluginDetails, uploadedPluginName);
-			try {
-				IntegrationType newIntegrationType = startUpPlugin(newPluginDetails);
-				applicationEventPublisher.publishEvent(new PluginEvent(newIntegrationType.getName(), LOAD_KEY));
-				previousPlugin.ifPresent(this::deletePreviousPlugin);
-				deleteTempPlugin(uploadedPluginName);
-				return newIntegrationType;
-			} catch (Exception ex) {
-				previousPlugin.ifPresent(p -> loadPreviousPlugin(p, newPluginDetails));
-				throw new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR, ex.getMessage());
-			}
-		}).orElseThrow(() -> {
-			previousPlugin.ifPresent(p -> loadPreviousPlugin(p, pluginDetails));
-			deleteTempPlugin(uploadedPluginName);
-
-			throw new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR,
-					Suppliers.formattedSupplier("Failed to load new plugin from file = '{}'", uploadedPluginName).get()
-			);
-		});
-	}
-
-	/**
-	 * Uploads the plugin file to the temp directory and extracts it's info.
-	 * Presence of the plugin version is mandatory
-	 *
-	 * @param fileName   Plugin file name to upload
-	 * @param fileStream {@link InputStream} of the plugin file
-	 * @return {@link PluginInfo}
-	 */
-	private PluginInfo resolvePluginInfo(final String fileName, InputStream fileStream) {
-		Path tempPluginPath = uploadTempPlugin(fileName, fileStream);
-
-		try {
-			PluginInfo newPluginInfo = pluginLoader.extractPluginInfo(tempPluginPath);
-			BusinessRule.expect(validatePluginMetaInfo(newPluginInfo), equalTo(Boolean.TRUE))
-					.verify(ErrorType.PLUGIN_UPLOAD_ERROR, "Plugin version should be specified.");
-			return newPluginInfo;
-		} catch (PluginException e) {
-			removeUploadingPlugin(fileName);
-			throw new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR, e.getMessage());
-		}
-	}
-
-	/**
-	 * Upload plugin file to the temporary plugins directory.
-	 *
-	 * @param fileName   Plugin file name to upload
-	 * @param fileStream {@link InputStream} of the plugin file
-	 * @return {@link Path} to the temporary uploaded  plugin file
-	 */
-	private Path uploadTempPlugin(String fileName, InputStream fileStream) {
-		Path pluginsTempDirPath = Paths.get(pluginsTempDir);
-		createTempPluginsFolderIfNotExists(pluginsTempDirPath);
-
-		validateFileExtension(fileName);
-
-		try {
-			Path pluginPath = Paths.get(pluginsTempDir, fileName);
-			addUploadingPlugin(fileName, pluginPath);
-			pluginLoader.savePlugin(pluginPath, fileStream);
-			return pluginPath;
-		} catch (IOException e) {
-			removeUploadingPlugin(fileName);
-			throw new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR,
-					Suppliers.formattedSupplier("Unable to copy the new plugin file with name = '{}' to the temp directory", fileName).get()
-			);
-		}
-	}
-
-	/**
-	 * Create a new temporary directory for plugins if not exists
-	 *
-	 * @param path Path of the new directory
-	 */
-	private void createTempPluginsFolderIfNotExists(Path path) {
-		if (!Files.isDirectory(path)) {
-			try {
-				Files.createDirectories(path);
-			} catch (IOException e) {
-
-				throw new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR,
-						Suppliers.formattedSupplier("Unable to create directory = '{}'", path).get()
-				);
-			}
-		}
-	}
-
-	/**
-	 * Resolve and validate file type.
-	 * Allowed values: {@link PluginFileExtension#values()}
-	 *
-	 * @param fileName uploaded plugin file name
-	 */
-	private void validateFileExtension(String fileName) {
-		String resolvedExtension = FilenameUtils.getExtension(fileName);
-		Optional<PluginFileExtension> byExtension = PluginFileExtension.findByExtension("." + resolvedExtension);
-		BusinessRule.expect(byExtension, Optional::isPresent)
-				.verify(ErrorType.PLUGIN_UPLOAD_ERROR,
-						Suppliers.formattedSupplier("Unsupported plugin file extension = '{}'", resolvedExtension).get()
-				);
-	}
-
-	/**
-	 * Add plugin file name to the uploading plugins holder
-	 *
-	 * @param fileName Name of the plugin file to put to the {@link com.epam.ta.reportportal.plugin.Pf4jPluginManager#uploadingPlugins}
-	 * @param path     Full path to the plugin file
-	 * @see com.epam.ta.reportportal.plugin.Pf4jPluginManager
-	 */
-	private void addUploadingPlugin(String fileName, Path path) {
-		uploadingPlugins.put(fileName, path);
-	}
-
-	private boolean validatePluginMetaInfo(PluginInfo newPluginInfo) {
-		return ofNullable(newPluginInfo.getVersion()).map(StringUtils::isNotBlank).orElse(Boolean.FALSE);
-	}
-
-	private void unloadPreviousPlugin(PluginWrapper pluginWrapper) {
-		destroyDependency(pluginWrapper.getPluginId());
-		if (!pluginManager.unloadPlugin(pluginWrapper.getPluginId())) {
-			throw new ReportPortalException(ErrorType.PLUGIN_REMOVE_ERROR,
-					Suppliers.formattedSupplier("Failed to stop old plugin with id = '{}'", pluginWrapper.getPluginId()).get()
-			);
-		}
-	}
-
-	private void destroyDependency(String name) {
-		AbstractAutowireCapableBeanFactory beanFactory = (AbstractAutowireCapableBeanFactory) this.autowireCapableBeanFactory;
-		if (beanFactory.containsSingleton(name)) {
-			beanFactory.destroySingleton(name);
-		}
-	}
-
-	/**
-	 * Validates the new plugin in the temporary plugins' directory, uploads it to the root plugins' directory and to the {@link DataStore}
-	 *
-	 * @param newPluginInfo      Resolved {@link PluginInfo} of the new plugin
-	 * @param uploadedPluginName Original plugin file name
-	 * @param pluginDetails      {@link IntegrationTypeDetails} with the info about the new plugin
-	 * @return updated {@link IntegrationTypeDetails}
-	 */
-	private IntegrationTypeDetails copyPlugin(PluginInfo newPluginInfo, IntegrationTypeDetails pluginDetails, String uploadedPluginName) {
-		String newPluginId = newPluginInfo.getId();
-		startUpPlugin(newPluginId);
-		validateNewPluginExtensionClasses(newPluginId, uploadedPluginName);
-		pluginManager.unloadPlugin(newPluginId);
-
-		final String newPluginFileName = generatePluginFileName(newPluginInfo, uploadedPluginName);
-		IntegrationTypeProperties.FILE_NAME.setValue(pluginDetails, newPluginFileName);
-
-		final String fileId = savePlugin(uploadedPluginName, newPluginFileName);
-		IntegrationTypeProperties.FILE_ID.setValue(pluginDetails, fileId);
-
-		copyPluginToRootDirectory(newPluginId, fileId, newPluginFileName);
-		removeUploadingPlugin(uploadedPluginName);
-
-		return pluginDetails;
-	}
-
-	/**
-	 * Validates plugin's extension class/classes and reloads the previous plugin if it is present and the validation failed
-	 *
-	 * @param newPluginId       Id of the new plugin
-	 * @param newPluginFileName New plugin file name
-	 * @see PluginLoader#validatePluginExtensionClasses(PluginWrapper))
-	 */
-	private void validateNewPluginExtensionClasses(String newPluginId, String newPluginFileName) {
-		PluginWrapper newPlugin = getPluginById(newPluginId).orElseThrow(() -> new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR,
-				Suppliers.formattedSupplier("Plugin with id = '{}' has not been found.", newPluginId).get()
-		));
-		if (!pluginLoader.validatePluginExtensionClasses(newPlugin)) {
-			pluginManager.unloadPlugin(newPluginId);
-			deleteTempPlugin(newPluginFileName);
-
-			throw new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR,
-					Suppliers.formattedSupplier("New plugin with id = '{}' doesn't have mandatory extension classes.", newPluginId).get()
-			);
-
-		}
-	}
-
-	private void deleteTempPlugin(String tempPluginFileName) {
-		try {
-			pluginLoader.deleteTempPlugin(pluginsTempDir, tempPluginFileName);
-		} catch (IOException e) {
-			//error during temp plugin is not crucial, temp files cleaning will be delegated to the plugins cleaning job
-			LOGGER.error("Error during temp plugin file removing: '{}'", e.getMessage());
-		} finally {
-			removeUploadingPlugin(tempPluginFileName);
-		}
-	}
-
-	private String generatePluginFileName(PluginInfo pluginInfo, final String originalFileName) {
-		return pluginInfo.getId() + "-" + pluginInfo.getVersion() + "." + FilenameUtils.getExtension(originalFileName);
-	}
-
-	/**
-	 * Saves plugin file to the instance of the configured {@link DataStore}
-	 *
-	 * @param uploadedPluginName Original plugin file name
-	 * @param newPluginFileName  New plugin file name
-	 * @return File id
-	 */
-	private String savePlugin(final String uploadedPluginName, final String newPluginFileName) {
-		try (InputStream fileStream = FileUtils.openInputStream(FileUtils.getFile(pluginsTempDir, uploadedPluginName))) {
-			return pluginLoader.saveToDataStore(newPluginFileName, fileStream);
-		} catch (Exception e) {
-			throw new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR,
-					Suppliers.formattedSupplier("Unable to upload new plugin file = '{}' to the data store", uploadedPluginName).get()
-			);
-		}
-	}
-
-	private void copyPluginToRootDirectory(final String newPluginId, final String fileId, final String newPluginFileName) {
-		try {
-			pluginLoader.copyFromDataStore(fileId, Paths.get(pluginsDir, newPluginFileName), Paths.get(resourcesDir, newPluginId));
-		} catch (IOException e) {
-			throw new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR,
-					Suppliers.formattedSupplier("Unable to copy new plugin file = '{}' from the data store to the root directory",
-							newPluginFileName
-					).get()
-			);
-		}
-	}
-
-	/**
-	 * Remove plugin file name from the uploading plugins holder
-	 *
-	 * @param fileName Name of the plugin file to remove from the {@link com.epam.ta.reportportal.plugin.Pf4jPluginManager#uploadingPlugins}
-	 * @see com.epam.ta.reportportal.plugin.Pf4jPluginManager
-	 */
-	private void removeUploadingPlugin(String fileName) {
-		uploadingPlugins.invalidate(fileName);
-	}
-
-	/**
-	 * Starts the new plugin and saves it's info as {@link IntegrationType} object in the database
-	 *
-	 * @param pluginDetails {@link IntegrationTypeDetails} with the info about the new plugin
-	 * @return {@link IntegrationType} object with the updated info about the new plugin
-	 */
-	private IntegrationType startUpPlugin(final IntegrationTypeDetails pluginDetails) {
-
-		String newPluginFileName = IntegrationTypeProperties.FILE_NAME.getValue(pluginDetails.getDetails())
-				.map(String::valueOf)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR, "Unable to resolve 'fileName' property"));
-
-		return ofNullable(pluginManager.loadPlugin(Paths.get(pluginsDir, newPluginFileName))).map(newLoadedPluginId -> {
-			startUpPlugin(newLoadedPluginId);
-
-			Optional<IntegrationType> oldIntegrationType = integrationTypeRepository.findByName(newLoadedPluginId);
-			oldIntegrationType.ifPresent(it -> IntegrationTypeProperties.FILE_ID.getValue(pluginDetails.getDetails())
-					.map(String::valueOf)
-					.ifPresent(fileId -> deletePreviousPluginFile(it, fileId)));
-
-			IntegrationTypeBuilder integrationTypeBuilder = oldIntegrationType.map(IntegrationTypeBuilder::new)
-					.orElseGet(IntegrationTypeBuilder::new);
-			integrationTypeBuilder.setName(newLoadedPluginId).setIntegrationGroup(IntegrationGroupEnum.OTHER);
-
-			Optional<ReportPortalExtensionPoint> instance = getInstance(newLoadedPluginId, ReportPortalExtensionPoint.class);
-
-			instance.ifPresent(extensionPoint -> {
-				pluginDetails.getDetails().putAll(extensionPoint.getPluginParams());
-				pluginDetails.getDetails()
-						.put(IntegrationTypeProperties.RESOURCES_DIRECTORY.getAttribute(),
-								Paths.get(resourcesDir, newLoadedPluginId).toString()
-						);
-				integrationTypeBuilder.setDetails(pluginDetails);
-				integrationTypeBuilder.setIntegrationGroup(IntegrationGroupEnum.valueOf(extensionPoint.getIntegrationGroup().name()));
-			});
-
-			integrationTypeBuilder.setEnabled(true);
-			return integrationTypeRepository.save(integrationTypeBuilder.get());
-
-		})
-				.orElseThrow(() -> new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR,
-						Suppliers.formattedSupplier("Error during loading the plugin file = '{}'", newPluginFileName).get()
-				));
-
-	}
-
-	private void deletePreviousPluginFile(IntegrationType oldIntegrationType, String newFileId) {
-		try {
-			ofNullable(oldIntegrationType.getDetails()).flatMap(details -> ofNullable(details.getDetails()))
-					.flatMap(IntegrationTypeProperties.FILE_ID::getValue)
-					.map(String::valueOf)
-					.ifPresent(oldFileId -> {
-						if (!oldFileId.equals(newFileId)) {
-							pluginLoader.deleteFromDataStore(oldFileId);
-						}
-					});
-		} catch (Exception ex) {
-			LOGGER.error("Error during removing old plugin file from the Data store: {}", ex.getMessage());
-		}
-	}
-
-	private void deletePreviousPlugin(PluginWrapper previousPlugin) {
-		try {
-			Files.deleteIfExists(previousPlugin.getPluginPath());
-		} catch (IOException e) {
-			LOGGER.error("Unable to delete the old plugin file with id = '{}'", previousPlugin.getPluginId());
-		}
-	}
-
-	/**
-	 * Load and start up the previous plugin
-	 *
-	 * @param previousPlugin   {@link PluginWrapper} with mandatory data for plugin loading: {@link PluginWrapper#getPluginPath()}
-	 * @param newPluginDetails {@link IntegrationTypeDetails} of the plugin which uploading ended up with an error
-	 * @return {@link PluginState}
-	 */
-	private PluginState loadPreviousPlugin(PluginWrapper previousPlugin, IntegrationTypeDetails newPluginDetails) {
-		if (previousPlugin.getPluginState() == PluginState.STARTED) {
-			return previousPlugin.getPluginState();
-		}
-
-		IntegrationTypeProperties.FILE_ID.getValue(newPluginDetails.getDetails()).map(String::valueOf).ifPresent(fileId -> {
-			try {
-				pluginLoader.deleteFromDataStore(fileId);
-			} catch (Exception e) {
-				LOGGER.error("Unable to delete new plugin file from the DataStore: '{}'", e.getMessage());
-			}
-		});
-
-		PluginState pluginState = ofNullable(pluginManager.getPlugin(previousPlugin.getPluginId())).map(loadedPlugin -> {
-			if (previousPlugin.getDescriptor().getVersion().equals(loadedPlugin.getDescriptor().getVersion())) {
-				return loadedPlugin.getPluginState();
-			} else {
-				pluginManager.deletePlugin(loadedPlugin.getPluginId());
-				deletePluginResources(String.valueOf(Paths.get(resourcesDir, loadedPlugin.getPluginId())));
-				return PluginState.DISABLED;
-			}
-		}).orElse(PluginState.DISABLED);
-
-		if (pluginState != PluginState.STARTED) {
-			try {
-				Path oldPluginPath = previousPlugin.getPluginPath();
-				PluginInfo oldPluginInfo = pluginLoader.extractPluginInfo(oldPluginPath);
-				String oldPluginFileName = generatePluginFileName(oldPluginInfo, oldPluginPath.toFile().getName());
-				try (InputStream fileStream = Files.newInputStream(oldPluginPath)) {
-					pluginLoader.saveToDataStore(oldPluginFileName, fileStream);
-				} catch (Exception e) {
-					throw new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR,
-							Suppliers.formattedSupplier("Unable to upload old plugin file = '{}' to the data store", oldPluginFileName)
-									.get()
-					);
-				}
-				copyPluginResources(oldPluginPath, previousPlugin.getPluginId());
-				return startUpPlugin(ofNullable(pluginManager.loadPlugin(oldPluginPath)).orElseThrow(() -> new ReportPortalException(
-						ErrorType.PLUGIN_UPLOAD_ERROR,
-						Suppliers.formattedSupplier("Unable to reload previousPlugin with id = '{}': '{}'", previousPlugin.getPluginId())
-								.get()
-				)));
-			} catch (PluginException e) {
-				throw new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR,
-						Suppliers.formattedSupplier("Unable to reload previousPlugin with id = '{}': '{}'",
-								previousPlugin.getPluginId(),
-								e.getMessage()
-						).get()
-				);
-			}
-		}
-
-		return PluginState.STARTED;
-
-	}
+  public static final Logger LOGGER = LoggerFactory.getLogger(Pf4jPluginManager.class);
+
+  public static final String LOAD_KEY = "load";
+  public static final String UNLOAD_KEY = "unload";
+
+  private static final long MAXIMUM_UPLOADED_PLUGINS = 50;
+  private static final long PLUGIN_LIVE_TIME = 2;
+
+  private final String pluginsDir;
+  private final String pluginsTempDir;
+  private final String resourcesDir;
+
+  private final Cache<String, Path> uploadingPlugins;
+
+  private final PluginLoader pluginLoader;
+  private final IntegrationTypeRepository integrationTypeRepository;
+
+  private final PluginManager pluginManager;
+  private final AutowireCapableBeanFactory autowireCapableBeanFactory;
+
+  private final ApplicationEventPublisher applicationEventPublisher;
+
+  public Pf4jPluginManager(String pluginsDir, String pluginsTempPath, String resourcesDir,
+      PluginLoader pluginLoader,
+      IntegrationTypeRepository integrationTypeRepository, PluginManager pluginManager,
+      AutowireCapableBeanFactory autowireCapableBeanFactory,
+      ApplicationEventPublisher applicationEventPublisher) throws IOException {
+    this.pluginsDir = pluginsDir;
+    Files.createDirectories(Paths.get(this.pluginsDir));
+    this.resourcesDir = resourcesDir;
+    Files.createDirectories(Paths.get(this.resourcesDir));
+    this.pluginsTempDir = pluginsTempPath;
+    Files.createDirectories(Paths.get(this.pluginsTempDir));
+    this.autowireCapableBeanFactory = autowireCapableBeanFactory;
+    this.applicationEventPublisher = applicationEventPublisher;
+    this.pluginLoader = pluginLoader;
+    this.integrationTypeRepository = integrationTypeRepository;
+    this.uploadingPlugins = CacheBuilder.newBuilder()
+        .maximumSize(MAXIMUM_UPLOADED_PLUGINS)
+        .expireAfterWrite(PLUGIN_LIVE_TIME, TimeUnit.MINUTES)
+        .build();
+    this.pluginManager = pluginManager;
+  }
+
+  @Override
+  public List<Plugin> getPlugins() {
+    return this.pluginManager.getPlugins()
+        .stream()
+        .flatMap(plugin -> pluginManager.getExtensionClasses(plugin.getPluginId())
+            .stream()
+            .map(ExtensionPoint::findByExtension)
+            .filter(Optional::isPresent)
+            .map(it -> new Plugin(plugin.getPluginId(), it.get())))
+        .collect(Collectors.toList());
+  }
+
+  @Override
+  public Optional<Plugin> getPlugin(String type) {
+    return getPlugins().stream().filter(p -> p.getType().name().equalsIgnoreCase(type)).findAny();
+  }
+
+  @Override
+  public <T> Optional<T> getInstance(String name, Class<T> extension) {
+    return pluginManager.getExtensions(extension, name).stream().findFirst();
+  }
+
+  @Override
+  public <T> Optional<T> getInstance(Class<T> extension) {
+    return pluginManager.getExtensions(extension).stream().findFirst();
+  }
+
+  @Override
+  public void startUp() {
+    // load and start all enabled plugins of application
+    integrationTypeRepository.findAll()
+        .stream()
+        .filter(IntegrationType::isEnabled)
+        .forEach(integrationType -> ofNullable(integrationType.getDetails()).ifPresent(
+            integrationTypeDetails -> {
+              try {
+                loadPlugin(integrationType.getName(), integrationTypeDetails);
+              } catch (Exception ex) {
+                LOGGER.error("Unable to load plugin '{}'", integrationType.getName());
+              }
+            }));
+
+  }
+
+  @Override
+  public void shutDown() {
+    // stop and unload all plugins
+    pluginManager.stopPlugins();
+    pluginManager.getPlugins().forEach(p -> pluginManager.unloadPlugin(p.getPluginId()));
+  }
+
+  @Override
+  public PluginState startUpPlugin(String pluginId) {
+
+    PluginWrapper pluginWrapper = ofNullable(pluginManager.getPlugin(pluginId)).orElseThrow(
+        () -> new ReportPortalException(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION,
+            "Plugin not found: " + pluginId
+        ));
+
+    return pluginManager.startPlugin(pluginWrapper.getPluginId());
+  }
+
+  @Override
+  public boolean loadPlugin(String pluginId, IntegrationTypeDetails integrationTypeDetails) {
+    return ofNullable(integrationTypeDetails.getDetails()).map(details -> {
+      String fileName = IntegrationTypeProperties.FILE_NAME.getValue(details)
+          .map(String::valueOf)
+          .orElseThrow(() -> new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR,
+              Suppliers.formattedSupplier(
+                  "'File name' property of the plugin - '{}' is not specified", pluginId).get()
+          ));
+
+      Path pluginPath = Paths.get(pluginsDir, fileName);
+      if (Files.notExists(pluginPath)) {
+        String fileId = IntegrationTypeProperties.FILE_ID.getValue(details)
+            .map(String::valueOf)
+            .orElseThrow(() -> new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR,
+                Suppliers.formattedSupplier(
+                    "'File id' property of the plugin - '{}' is not specified", pluginId).get()
+            ));
+        try {
+          pluginLoader.copyFromDataStore(fileId, pluginPath, Paths.get(resourcesDir, pluginId));
+        } catch (IOException e) {
+          throw new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR,
+              Suppliers.formattedSupplier("Unable to load plugin - '{}' from the data store",
+                  pluginId).get()
+          );
+        }
+      } else {
+        copyPluginResources(pluginPath, pluginId);
+      }
+
+      return ofNullable(pluginManager.loadPlugin(pluginPath)).map(id -> {
+        if (PluginState.STARTED == pluginManager.startPlugin(pluginId)) {
+          Optional<org.pf4j.ExtensionPoint> extensionPoint = this.getInstance(pluginId,
+              org.pf4j.ExtensionPoint.class);
+          extensionPoint.ifPresent(extension -> LOGGER.info(
+              Suppliers.formattedSupplier("Plugin - '{}' initialized.", pluginId)
+                  .get()));
+          applicationEventPublisher.publishEvent(new PluginEvent(pluginId, LOAD_KEY));
+          return true;
+        } else {
+          return false;
+        }
+      }).orElse(Boolean.FALSE);
+    }).orElse(Boolean.FALSE);
+
+  }
+
+  private void copyPluginResources(Path pluginPath, String pluginId) {
+    try {
+      pluginLoader.copyPluginResource(pluginPath, Paths.get(resourcesDir, pluginId));
+    } catch (IOException e) {
+      throw new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR,
+          Suppliers.formattedSupplier("Unable to load resources of the - '{}' plugin", pluginId)
+              .get()
+      );
+    }
+  }
+
+  @Override
+  public boolean unloadPlugin(IntegrationType integrationType) {
+    applicationEventPublisher.publishEvent(new PluginEvent(integrationType.getName(), UNLOAD_KEY));
+    destroyDependency(integrationType.getName());
+    return pluginManager.unloadPlugin(integrationType.getName());
+  }
+
+  @Override
+  public boolean deletePlugin(String pluginId) {
+    return integrationTypeRepository.findByName(pluginId).map(this::deletePlugin)
+        .orElse(Boolean.TRUE);
+  }
+
+  @Override
+  public boolean deletePlugin(PluginWrapper pluginWrapper) {
+    return integrationTypeRepository.findByName(pluginWrapper.getPluginId()).map(this::deletePlugin)
+        .orElseGet(() -> {
+          applicationEventPublisher.publishEvent(
+              new PluginEvent(pluginWrapper.getPluginId(), UNLOAD_KEY));
+          deletePluginResources(Paths.get(resourcesDir, pluginWrapper.getPluginId()).toString());
+          destroyDependency(pluginWrapper.getPluginId());
+          return pluginManager.deletePlugin(pluginWrapper.getPluginId());
+        });
+  }
+
+  private boolean deletePlugin(IntegrationType integrationType) {
+    Optional<Map<String, Object>> pluginData = ofNullable(integrationType.getDetails()).map(
+        IntegrationTypeDetails::getDetails);
+    pluginData.ifPresent(this::deletePluginResources);
+
+    applicationEventPublisher.publishEvent(new PluginEvent(integrationType.getName(), UNLOAD_KEY));
+
+    boolean pluginRemoved = ofNullable(pluginManager.getPlugin(integrationType.getName())).map(
+        pluginWrapper -> {
+          destroyDependency(pluginWrapper.getPluginId());
+          if (integrationType.isEnabled()) {
+            return pluginManager.deletePlugin(integrationType.getName());
+          }
+          return true;
+        }).orElse(Boolean.TRUE);
+
+    boolean pluginFileRemoved = pluginData.map(this::deletePluginFile).orElse(Boolean.TRUE);
+
+    return pluginRemoved && pluginFileRemoved;
+  }
+
+  private void deletePluginResources(Map<String, Object> details) {
+    IntegrationTypeProperties.RESOURCES_DIRECTORY.getValue(details).map(String::valueOf)
+        .ifPresent(this::deletePluginResources);
+    IntegrationTypeProperties.FILE_ID.getValue(details).map(String::valueOf)
+        .ifPresent(pluginLoader::deleteFromDataStore);
+  }
+
+  private void deletePluginResources(String resourcesDir) {
+    try {
+      FileUtils.deleteDirectory(FileUtils.getFile(resourcesDir));
+    } catch (IOException e) {
+      throw new ReportPortalException(ErrorType.PLUGIN_REMOVE_ERROR,
+          "Unable to delete plugin resources.");
+    }
+  }
+
+  private boolean deletePluginFile(Map<String, Object> details) {
+    return IntegrationTypeProperties.FILE_NAME.getValue(details)
+        .map(String::valueOf)
+        .map(fileName -> Paths.get(pluginsDir, fileName))
+        .map(path -> {
+          try {
+            if (Files.exists(path)) {
+              return Files.deleteIfExists(path);
+            } else {
+              return true;
+            }
+          } catch (IOException e) {
+            throw new ReportPortalException(ErrorType.PLUGIN_REMOVE_ERROR,
+                "Error during plugin file removing from the filesystem: " + e.getMessage()
+            );
+          }
+
+        })
+        .orElse(Boolean.TRUE);
+  }
+
+  @Override
+  public Optional<PluginWrapper> getPluginById(String id) {
+    return ofNullable(pluginManager.getPlugin(id));
+  }
+
+  @Override
+  public boolean isInUploadingState(String fileName) {
+    return uploadingPlugins.asMap().containsKey(fileName);
+  }
+
+  @Override
+  public IntegrationType uploadPlugin(final String uploadedPluginName,
+      final InputStream fileStream) {
+    PluginInfo newPluginInfo = resolvePluginInfo(uploadedPluginName, fileStream);
+    IntegrationTypeDetails pluginDetails = pluginLoader.resolvePluginDetails(newPluginInfo);
+
+    Optional<PluginWrapper> previousPlugin = getPluginById(newPluginInfo.getId());
+    previousPlugin.ifPresent(this::unloadPreviousPlugin);
+
+    return ofNullable(pluginManager.loadPlugin(Paths.get(pluginsTempDir, uploadedPluginName))).map(
+        pluginId -> {
+          IntegrationTypeDetails newPluginDetails = copyPlugin(newPluginInfo, pluginDetails,
+              uploadedPluginName);
+          try {
+            IntegrationType newIntegrationType = startUpPlugin(newPluginDetails);
+            applicationEventPublisher.publishEvent(
+                new PluginEvent(newIntegrationType.getName(), LOAD_KEY));
+            previousPlugin.ifPresent(this::deletePreviousPlugin);
+            deleteTempPlugin(uploadedPluginName);
+            return newIntegrationType;
+          } catch (Exception ex) {
+            previousPlugin.ifPresent(p -> loadPreviousPlugin(p, newPluginDetails));
+            Throwable exception = ex;
+            String exMessage = exception.toString();
+            while (exception.getCause() != null) {
+              exception = exception.getCause();
+              exMessage += exception.toString() + "\n";
+            }
+            throw new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR, exMessage);
+          }
+        }).orElseThrow(() -> {
+      previousPlugin.ifPresent(p -> loadPreviousPlugin(p, pluginDetails));
+      deleteTempPlugin(uploadedPluginName);
+
+      throw new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR,
+          Suppliers.formattedSupplier("Failed to load new plugin from file = '{}'",
+              uploadedPluginName).get()
+      );
+    });
+  }
+
+  /**
+   * Uploads the plugin file to the temp directory and extracts it's info. Presence of the plugin
+   * version is mandatory
+   *
+   * @param fileName   Plugin file name to upload
+   * @param fileStream {@link InputStream} of the plugin file
+   * @return {@link PluginInfo}
+   */
+  private PluginInfo resolvePluginInfo(final String fileName, InputStream fileStream) {
+    Path tempPluginPath = uploadTempPlugin(fileName, fileStream);
+
+    try {
+      PluginInfo newPluginInfo = pluginLoader.extractPluginInfo(tempPluginPath);
+      BusinessRule.expect(validatePluginMetaInfo(newPluginInfo), equalTo(Boolean.TRUE))
+          .verify(ErrorType.PLUGIN_UPLOAD_ERROR, "Plugin version should be specified.");
+      return newPluginInfo;
+    } catch (PluginException e) {
+      removeUploadingPlugin(fileName);
+      throw new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR, e.getMessage());
+    }
+  }
+
+  /**
+   * Upload plugin file to the temporary plugins directory.
+   *
+   * @param fileName   Plugin file name to upload
+   * @param fileStream {@link InputStream} of the plugin file
+   * @return {@link Path} to the temporary uploaded  plugin file
+   */
+  private Path uploadTempPlugin(String fileName, InputStream fileStream) {
+    Path pluginsTempDirPath = Paths.get(pluginsTempDir);
+    createTempPluginsFolderIfNotExists(pluginsTempDirPath);
+
+    validateFileExtension(fileName);
+
+    try {
+      Path pluginPath = Paths.get(pluginsTempDir, fileName);
+      addUploadingPlugin(fileName, pluginPath);
+      pluginLoader.savePlugin(pluginPath, fileStream);
+      return pluginPath;
+    } catch (IOException e) {
+      removeUploadingPlugin(fileName);
+      throw new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR,
+          Suppliers.formattedSupplier(
+                  "Unable to copy the new plugin file with name = '{}' to the temp directory", fileName)
+              .get()
+      );
+    }
+  }
+
+  /**
+   * Create a new temporary directory for plugins if not exists
+   *
+   * @param path Path of the new directory
+   */
+  private void createTempPluginsFolderIfNotExists(Path path) {
+    if (!Files.isDirectory(path)) {
+      try {
+        Files.createDirectories(path);
+      } catch (IOException e) {
+
+        throw new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR,
+            Suppliers.formattedSupplier("Unable to create directory = '{}'", path).get()
+        );
+      }
+    }
+  }
+
+  /**
+   * Resolve and validate file type. Allowed values: {@link PluginFileExtension#values()}
+   *
+   * @param fileName uploaded plugin file name
+   */
+  private void validateFileExtension(String fileName) {
+    String resolvedExtension = FilenameUtils.getExtension(fileName);
+    Optional<PluginFileExtension> byExtension = PluginFileExtension.findByExtension(
+        "." + resolvedExtension);
+    BusinessRule.expect(byExtension, Optional::isPresent)
+        .verify(ErrorType.PLUGIN_UPLOAD_ERROR,
+            Suppliers.formattedSupplier("Unsupported plugin file extension = '{}'",
+                resolvedExtension).get()
+        );
+  }
+
+  /**
+   * Add plugin file name to the uploading plugins holder
+   *
+   * @param fileName Name of the plugin file to put to the
+   *                 {@link com.epam.ta.reportportal.plugin.Pf4jPluginManager#uploadingPlugins}
+   * @param path     Full path to the plugin file
+   * @see com.epam.ta.reportportal.plugin.Pf4jPluginManager
+   */
+  private void addUploadingPlugin(String fileName, Path path) {
+    uploadingPlugins.put(fileName, path);
+  }
+
+  private boolean validatePluginMetaInfo(PluginInfo newPluginInfo) {
+    return ofNullable(newPluginInfo.getVersion()).map(StringUtils::isNotBlank)
+        .orElse(Boolean.FALSE);
+  }
+
+  private void unloadPreviousPlugin(PluginWrapper pluginWrapper) {
+    destroyDependency(pluginWrapper.getPluginId());
+    if (!pluginManager.unloadPlugin(pluginWrapper.getPluginId())) {
+      throw new ReportPortalException(ErrorType.PLUGIN_REMOVE_ERROR,
+          Suppliers.formattedSupplier("Failed to stop old plugin with id = '{}'",
+              pluginWrapper.getPluginId()).get()
+      );
+    }
+  }
+
+  private void destroyDependency(String name) {
+    AbstractAutowireCapableBeanFactory beanFactory = (AbstractAutowireCapableBeanFactory) this.autowireCapableBeanFactory;
+    if (beanFactory.containsSingleton(name)) {
+      beanFactory.destroySingleton(name);
+    }
+  }
+
+  /**
+   * Validates the new plugin in the temporary plugins' directory, uploads it to the root plugins'
+   * directory and to the {@link DataStore}
+   *
+   * @param newPluginInfo      Resolved {@link PluginInfo} of the new plugin
+   * @param uploadedPluginName Original plugin file name
+   * @param pluginDetails      {@link IntegrationTypeDetails} with the info about the new plugin
+   * @return updated {@link IntegrationTypeDetails}
+   */
+  private IntegrationTypeDetails copyPlugin(PluginInfo newPluginInfo,
+      IntegrationTypeDetails pluginDetails, String uploadedPluginName) {
+    String newPluginId = newPluginInfo.getId();
+    startUpPlugin(newPluginId);
+    validateNewPluginExtensionClasses(newPluginId, uploadedPluginName);
+    pluginManager.unloadPlugin(newPluginId);
+
+    final String newPluginFileName = generatePluginFileName(newPluginInfo, uploadedPluginName);
+    IntegrationTypeProperties.FILE_NAME.setValue(pluginDetails, newPluginFileName);
+
+    final String fileId = savePlugin(uploadedPluginName, newPluginFileName);
+    IntegrationTypeProperties.FILE_ID.setValue(pluginDetails, fileId);
+
+    copyPluginToRootDirectory(newPluginId, fileId, newPluginFileName);
+    removeUploadingPlugin(uploadedPluginName);
+
+    return pluginDetails;
+  }
+
+  /**
+   * Validates plugin's extension class/classes and reloads the previous plugin if it is present and
+   * the validation failed
+   *
+   * @param newPluginId       Id of the new plugin
+   * @param newPluginFileName New plugin file name
+   * @see PluginLoader#validatePluginExtensionClasses(PluginWrapper))
+   */
+  private void validateNewPluginExtensionClasses(String newPluginId, String newPluginFileName) {
+    PluginWrapper newPlugin = getPluginById(newPluginId).orElseThrow(
+        () -> new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR,
+            Suppliers.formattedSupplier("Plugin with id = '{}' has not been found.", newPluginId)
+                .get()
+        ));
+    if (!pluginLoader.validatePluginExtensionClasses(newPlugin)) {
+      pluginManager.unloadPlugin(newPluginId);
+      deleteTempPlugin(newPluginFileName);
+
+      throw new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR,
+          Suppliers.formattedSupplier(
+                  "New plugin with id = '{}' doesn't have mandatory extension classes.", newPluginId)
+              .get()
+      );
+
+    }
+  }
+
+  private void deleteTempPlugin(String tempPluginFileName) {
+    try {
+      pluginLoader.deleteTempPlugin(pluginsTempDir, tempPluginFileName);
+    } catch (IOException e) {
+      //error during temp plugin is not crucial, temp files cleaning will be delegated to the plugins cleaning job
+      LOGGER.error("Error during temp plugin file removing: '{}'", e.getMessage());
+    } finally {
+      removeUploadingPlugin(tempPluginFileName);
+    }
+  }
+
+  private String generatePluginFileName(PluginInfo pluginInfo, final String originalFileName) {
+    return pluginInfo.getId() + "-" + pluginInfo.getVersion() + "." + FilenameUtils.getExtension(
+        originalFileName);
+  }
+
+  /**
+   * Saves plugin file to the instance of the configured {@link DataStore}
+   *
+   * @param uploadedPluginName Original plugin file name
+   * @param newPluginFileName  New plugin file name
+   * @return File id
+   */
+  private String savePlugin(final String uploadedPluginName, final String newPluginFileName) {
+    try (InputStream fileStream = FileUtils.openInputStream(
+        FileUtils.getFile(pluginsTempDir, uploadedPluginName))) {
+      return pluginLoader.saveToDataStore(newPluginFileName, fileStream);
+    } catch (Exception e) {
+      throw new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR,
+          Suppliers.formattedSupplier("Unable to upload new plugin file = '{}' to the data store",
+              uploadedPluginName).get()
+      );
+    }
+  }
+
+  private void copyPluginToRootDirectory(final String newPluginId, final String fileId,
+      final String newPluginFileName) {
+    try {
+      pluginLoader.copyFromDataStore(fileId, Paths.get(pluginsDir, newPluginFileName),
+          Paths.get(resourcesDir, newPluginId));
+    } catch (IOException e) {
+      throw new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR,
+          Suppliers.formattedSupplier(
+              "Unable to copy new plugin file = '{}' from the data store to the root directory",
+              newPluginFileName
+          ).get()
+      );
+    }
+  }
+
+  /**
+   * Remove plugin file name from the uploading plugins holder
+   *
+   * @param fileName Name of the plugin file to remove from the
+   *                 {@link com.epam.ta.reportportal.plugin.Pf4jPluginManager#uploadingPlugins}
+   * @see com.epam.ta.reportportal.plugin.Pf4jPluginManager
+   */
+  private void removeUploadingPlugin(String fileName) {
+    uploadingPlugins.invalidate(fileName);
+  }
+
+  /**
+   * Starts the new plugin and saves it's info as {@link IntegrationType} object in the database
+   *
+   * @param pluginDetails {@link IntegrationTypeDetails} with the info about the new plugin
+   * @return {@link IntegrationType} object with the updated info about the new plugin
+   */
+  private IntegrationType startUpPlugin(final IntegrationTypeDetails pluginDetails) {
+
+    String newPluginFileName = IntegrationTypeProperties.FILE_NAME.getValue(
+            pluginDetails.getDetails())
+        .map(String::valueOf)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR,
+            "Unable to resolve 'fileName' property"));
+
+    return ofNullable(pluginManager.loadPlugin(Paths.get(pluginsDir, newPluginFileName))).map(
+            newLoadedPluginId -> {
+              startUpPlugin(newLoadedPluginId);
+
+              Optional<IntegrationType> oldIntegrationType = integrationTypeRepository.findByName(
+                  newLoadedPluginId);
+              oldIntegrationType.ifPresent(
+                  it -> IntegrationTypeProperties.FILE_ID.getValue(pluginDetails.getDetails())
+                      .map(String::valueOf)
+                      .ifPresent(fileId -> deletePreviousPluginFile(it, fileId)));
+
+              IntegrationTypeBuilder integrationTypeBuilder = oldIntegrationType.map(
+                      IntegrationTypeBuilder::new)
+                  .orElseGet(IntegrationTypeBuilder::new);
+              integrationTypeBuilder.setName(newLoadedPluginId)
+                  .setIntegrationGroup(IntegrationGroupEnum.OTHER);
+
+              Optional<ReportPortalExtensionPoint> instance = getInstance(newLoadedPluginId,
+                  ReportPortalExtensionPoint.class);
+
+              instance.ifPresent(extensionPoint -> {
+                pluginDetails.getDetails().putAll(extensionPoint.getPluginParams());
+                pluginDetails.getDetails()
+                    .put(IntegrationTypeProperties.RESOURCES_DIRECTORY.getAttribute(),
+                        Paths.get(resourcesDir, newLoadedPluginId).toString()
+                    );
+                integrationTypeBuilder.setDetails(pluginDetails);
+                integrationTypeBuilder.setIntegrationGroup(
+                    IntegrationGroupEnum.valueOf(extensionPoint.getIntegrationGroup().name()));
+              });
+
+              integrationTypeBuilder.setEnabled(true);
+              return integrationTypeRepository.save(integrationTypeBuilder.get());
+
+            })
+        .orElseThrow(() -> new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR,
+            Suppliers.formattedSupplier("Error during loading the plugin file = '{}'",
+                newPluginFileName).get()
+        ));
+
+  }
+
+  private void deletePreviousPluginFile(IntegrationType oldIntegrationType, String newFileId) {
+    try {
+      ofNullable(oldIntegrationType.getDetails()).flatMap(
+              details -> ofNullable(details.getDetails()))
+          .flatMap(IntegrationTypeProperties.FILE_ID::getValue)
+          .map(String::valueOf)
+          .ifPresent(oldFileId -> {
+            if (!oldFileId.equals(newFileId)) {
+              pluginLoader.deleteFromDataStore(oldFileId);
+            }
+          });
+    } catch (Exception ex) {
+      LOGGER.error("Error during removing old plugin file from the Data store: {}",
+          ex.getMessage());
+    }
+  }
+
+  private void deletePreviousPlugin(PluginWrapper previousPlugin) {
+    try {
+      Files.deleteIfExists(previousPlugin.getPluginPath());
+    } catch (IOException e) {
+      LOGGER.error("Unable to delete the old plugin file with id = '{}'",
+          previousPlugin.getPluginId());
+    }
+  }
+
+  /**
+   * Load and start up the previous plugin
+   *
+   * @param previousPlugin   {@link PluginWrapper} with mandatory data for plugin loading:
+   *                         {@link PluginWrapper#getPluginPath()}
+   * @param newPluginDetails {@link IntegrationTypeDetails} of the plugin which uploading ended up
+   *                         with an error
+   * @return {@link PluginState}
+   */
+  private PluginState loadPreviousPlugin(PluginWrapper previousPlugin,
+      IntegrationTypeDetails newPluginDetails) {
+    if (previousPlugin.getPluginState() == PluginState.STARTED) {
+      return previousPlugin.getPluginState();
+    }
+
+    IntegrationTypeProperties.FILE_ID.getValue(newPluginDetails.getDetails()).map(String::valueOf)
+        .ifPresent(fileId -> {
+          try {
+            pluginLoader.deleteFromDataStore(fileId);
+          } catch (Exception e) {
+            LOGGER.error("Unable to delete new plugin file from the DataStore: '{}'",
+                e.getMessage());
+          }
+        });
+
+    PluginState pluginState = ofNullable(pluginManager.getPlugin(previousPlugin.getPluginId())).map(
+        loadedPlugin -> {
+          if (previousPlugin.getDescriptor().getVersion()
+              .equals(loadedPlugin.getDescriptor().getVersion())) {
+            return loadedPlugin.getPluginState();
+          } else {
+            pluginManager.deletePlugin(loadedPlugin.getPluginId());
+            deletePluginResources(
+                String.valueOf(Paths.get(resourcesDir, loadedPlugin.getPluginId())));
+            return PluginState.DISABLED;
+          }
+        }).orElse(PluginState.DISABLED);
+
+    if (pluginState != PluginState.STARTED) {
+      try {
+        Path oldPluginPath = previousPlugin.getPluginPath();
+        PluginInfo oldPluginInfo = pluginLoader.extractPluginInfo(oldPluginPath);
+        String oldPluginFileName = generatePluginFileName(oldPluginInfo,
+            oldPluginPath.toFile().getName());
+        try (InputStream fileStream = Files.newInputStream(oldPluginPath)) {
+          pluginLoader.saveToDataStore(oldPluginFileName, fileStream);
+        } catch (Exception e) {
+          throw new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR,
+              Suppliers.formattedSupplier(
+                      "Unable to upload old plugin file = '{}' to the data store", oldPluginFileName)
+                  .get()
+          );
+        }
+        copyPluginResources(oldPluginPath, previousPlugin.getPluginId());
+        return startUpPlugin(ofNullable(pluginManager.loadPlugin(oldPluginPath)).orElseThrow(
+            () -> new ReportPortalException(
+                ErrorType.PLUGIN_UPLOAD_ERROR,
+                Suppliers.formattedSupplier("Unable to reload previousPlugin with id = '{}': '{}'",
+                        previousPlugin.getPluginId())
+                    .get()
+            )));
+      } catch (PluginException e) {
+        throw new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR,
+            Suppliers.formattedSupplier("Unable to reload previousPlugin with id = '{}': '{}'",
+                previousPlugin.getPluginId(),
+                e.getMessage()
+            ).get()
+        );
+      }
+    }
+
+    return PluginState.STARTED;
+
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/plugin/ReportPortalExtensionFactory.java b/src/main/java/com/epam/ta/reportportal/plugin/ReportPortalExtensionFactory.java
index 429cd2402d..ec6db33aaa 100644
--- a/src/main/java/com/epam/ta/reportportal/plugin/ReportPortalExtensionFactory.java
+++ b/src/main/java/com/epam/ta/reportportal/plugin/ReportPortalExtensionFactory.java
@@ -17,6 +17,9 @@
 package com.epam.ta.reportportal.plugin;
 
 import com.epam.reportportal.extension.common.IntegrationTypeProperties;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.Map;
 import org.pf4j.DefaultExtensionFactory;
 import org.pf4j.PluginManager;
 import org.pf4j.PluginWrapper;
@@ -24,60 +27,58 @@
 import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
 import org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory;
 
-import java.nio.file.Paths;
-import java.util.HashMap;
-import java.util.Map;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public class ReportPortalExtensionFactory extends DefaultExtensionFactory {
 
-	private final String resourcesDir;
-	private final PluginManager pluginManager;
-	private final AbstractAutowireCapableBeanFactory beanFactory;
+  private final String resourcesDir;
+  private final PluginManager pluginManager;
+  private final AbstractAutowireCapableBeanFactory beanFactory;
 
-	public ReportPortalExtensionFactory(String resourcesDir, PluginManager pluginManager, AutowireCapableBeanFactory context) {
-		this.resourcesDir = resourcesDir;
-		this.pluginManager = pluginManager;
-		this.beanFactory = (AbstractAutowireCapableBeanFactory) context;
-	}
+  public ReportPortalExtensionFactory(String resourcesDir, PluginManager pluginManager,
+      AutowireCapableBeanFactory context) {
+    this.resourcesDir = resourcesDir;
+    this.pluginManager = pluginManager;
+    this.beanFactory = (AbstractAutowireCapableBeanFactory) context;
+  }
 
-	@Override
-	public Object create(Class<?> extensionClass) {
-		PluginWrapper pluginWrapper = pluginManager.whichPlugin(extensionClass);
-		if (beanFactory.containsSingleton(pluginWrapper.getPluginId())) {
-			return beanFactory.getSingleton(pluginWrapper.getPluginId());
-		} else {
-			return createExtension(extensionClass, pluginWrapper);
-		}
-	}
+  @Override
+  public Object create(Class<?> extensionClass) {
+    PluginWrapper pluginWrapper = pluginManager.whichPlugin(extensionClass);
+    if (beanFactory.containsSingleton(pluginWrapper.getPluginId())) {
+      return beanFactory.getSingleton(pluginWrapper.getPluginId());
+    } else {
+      return createExtension(extensionClass, pluginWrapper);
+    }
+  }
 
-	private Object createExtension(Class<?> extensionClass, PluginWrapper pluginWrapper) {
-		Map<String, Object> initParams = getInitParams(pluginWrapper);
-		Object plugin = createPlugin(extensionClass, initParams);
-		beanFactory.autowireBean(plugin);
-		beanFactory.initializeBean(plugin, pluginWrapper.getDescriptor().getPluginId());
-		beanFactory.registerSingleton(pluginWrapper.getDescriptor().getPluginId(), plugin);
-		if (DisposableBean.class.isAssignableFrom(extensionClass)) {
-			beanFactory.registerDisposableBean(pluginWrapper.getDescriptor().getPluginId(), (DisposableBean) plugin);
-		}
-		return plugin;
-	}
+  private Object createExtension(Class<?> extensionClass, PluginWrapper pluginWrapper) {
+    Map<String, Object> initParams = getInitParams(pluginWrapper);
+    Object plugin = createPlugin(extensionClass, initParams);
+    beanFactory.autowireBean(plugin);
+    beanFactory.initializeBean(plugin, pluginWrapper.getDescriptor().getPluginId());
+    beanFactory.registerSingleton(pluginWrapper.getDescriptor().getPluginId(), plugin);
+    if (DisposableBean.class.isAssignableFrom(extensionClass)) {
+      beanFactory.registerDisposableBean(pluginWrapper.getDescriptor().getPluginId(),
+          (DisposableBean) plugin);
+    }
+    return plugin;
+  }
 
-	private Object createPlugin(Class<?> extensionClass, Map<String, Object> initParams) {
-		try {
-			return extensionClass.getDeclaredConstructor(Map.class).newInstance(initParams);
-		} catch (Exception ex) {
-			return super.create(extensionClass);
-		}
-	}
+  private Object createPlugin(Class<?> extensionClass, Map<String, Object> initParams) {
+    try {
+      return extensionClass.getDeclaredConstructor(Map.class).newInstance(initParams);
+    } catch (Exception ex) {
+      return super.create(extensionClass);
+    }
+  }
 
-	private Map<String, Object> getInitParams(PluginWrapper pluginWrapper) {
-		Map<String, Object> initParams = new HashMap<>();
-		initParams.put(IntegrationTypeProperties.RESOURCES_DIRECTORY.getAttribute(),
-				Paths.get(resourcesDir, pluginWrapper.getPluginId())
-		);
-		return initParams;
-	}
+  private Map<String, Object> getInitParams(PluginWrapper pluginWrapper) {
+    Map<String, Object> initParams = new HashMap<>();
+    initParams.put(IntegrationTypeProperties.RESOURCES_DIRECTORY.getAttribute(),
+        Paths.get(resourcesDir, pluginWrapper.getPluginId())
+    );
+    return initParams;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/util/ApplicationContextAwareFactoryBean.java b/src/main/java/com/epam/ta/reportportal/util/ApplicationContextAwareFactoryBean.java
index 0d94bff420..e5ff3721f5 100644
--- a/src/main/java/com/epam/ta/reportportal/util/ApplicationContextAwareFactoryBean.java
+++ b/src/main/java/com/epam/ta/reportportal/util/ApplicationContextAwareFactoryBean.java
@@ -23,94 +23,92 @@
 import org.springframework.beans.factory.InitializingBean;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContextAware;
-import org.springframework.core.Ordered;
-import org.springframework.core.annotation.Order;
 import org.springframework.lang.NonNull;
 
 /**
- * {@link FactoryBean} with access to {@link ApplicationContext} with lazy
- * initialization
+ * {@link FactoryBean} with access to {@link ApplicationContext} with lazy initialization
  *
  * @param <T> - type of bean
  * @author Andrei Varabyeu
  */
-public abstract class ApplicationContextAwareFactoryBean<T> implements FactoryBean<T>, ApplicationContextAware, InitializingBean {
+public abstract class ApplicationContextAwareFactoryBean<T> implements FactoryBean<T>,
+    ApplicationContextAware, InitializingBean {
 
-	/**
-	 * Application context holder
-	 */
-	private ApplicationContext applicationContext;
+  /**
+   * Application context holder
+   */
+  private ApplicationContext applicationContext;
 
-	/**
-	 * Supplier of bean to be created
-	 */
-	private Supplier<T> beanSupplier;
+  /**
+   * Supplier of bean to be created
+   */
+  private Supplier<T> beanSupplier;
 
-	/**
-	 * Whether is bean to be creates going to be singleton
-	 */
-	private boolean singleton = true;
+  /**
+   * Whether is bean to be creates going to be singleton
+   */
+  private boolean singleton = true;
 
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see
-	 * org.springframework.context.ApplicationContextAware#setApplicationContext
-	 * (org.springframework.context.ApplicationContext)
-	 */
-	@Override
-	public void setApplicationContext(@NonNull ApplicationContext applicationContext) throws BeansException {
-		this.applicationContext = applicationContext;
-	}
+  /*
+   * (non-Javadoc)
+   *
+   * @see
+   * org.springframework.context.ApplicationContextAware#setApplicationContext
+   * (org.springframework.context.ApplicationContext)
+   */
+  @Override
+  public void setApplicationContext(@NonNull ApplicationContext applicationContext)
+      throws BeansException {
+    this.applicationContext = applicationContext;
+  }
 
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.springframework.beans.factory.FactoryBean#getObject()
-	 */
-	@Override
-	public T getObject() {
-		return beanSupplier.get();
-	}
+  /*
+   * (non-Javadoc)
+   *
+   * @see org.springframework.beans.factory.FactoryBean#getObject()
+   */
+  @Override
+  public T getObject() {
+    return beanSupplier.get();
+  }
 
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.springframework.beans.factory.FactoryBean#isSingleton()
-	 */
-	@Override
-	public boolean isSingleton() {
-		return this.singleton;
-	}
+  /*
+   * (non-Javadoc)
+   *
+   * @see org.springframework.beans.factory.FactoryBean#isSingleton()
+   */
+  @Override
+  public boolean isSingleton() {
+    return this.singleton;
+  }
 
-	public void setSingleton(boolean singleton) {
-		this.singleton = singleton;
-	}
+  public void setSingleton(boolean singleton) {
+    this.singleton = singleton;
+  }
 
-	/**
-	 * Instantiates supplier for bean to be created. This mades possible
-	 * lazy-initialization
-	 */
-	@Override
-	public void afterPropertiesSet() {
-		Supplier<T> supplier = this::createInstance;
+  /**
+   * Instantiates supplier for bean to be created. This mades possible lazy-initialization
+   */
+  @Override
+  public void afterPropertiesSet() {
+    Supplier<T> supplier = this::createInstance;
 
-		this.beanSupplier = isSingleton() ? Suppliers.memoize(supplier) : supplier;
-	}
+    this.beanSupplier = isSingleton() ? Suppliers.memoize(supplier) : supplier;
+  }
 
-	protected ApplicationContext getApplicationContext() {
-		return applicationContext;
-	}
+  protected ApplicationContext getApplicationContext() {
+    return applicationContext;
+  }
 
-	/**
-	 * Template method that subclasses must override to construct the object
-	 * returned by this factory.
-	 * <p>
-	 * Invoked on initialization of this FactoryBean in case of a singleton;
-	 * else, on each {@link #getObject()} call.
-	 *
-	 * @return the object returned by this factory
-	 * @see #getObject()
-	 */
-	protected abstract T createInstance();
+  /**
+   * Template method that subclasses must override to construct the object returned by this
+   * factory.
+   * <p>
+   * Invoked on initialization of this FactoryBean in case of a singleton; else, on each
+   * {@link #getObject()} call.
+   *
+   * @return the object returned by this factory
+   * @see #getObject()
+   */
+  protected abstract T createInstance();
 }
diff --git a/src/main/java/com/epam/ta/reportportal/util/BinaryDataResponseWriter.java b/src/main/java/com/epam/ta/reportportal/util/BinaryDataResponseWriter.java
new file mode 100644
index 0000000000..463f002999
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/util/BinaryDataResponseWriter.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2022 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.util;
+
+import com.epam.ta.reportportal.entity.attachment.BinaryData;
+import com.epam.ta.reportportal.exception.ReportPortalException;
+import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.io.IOException;
+import java.io.InputStream;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.io.IOUtils;
+
+/**
+ * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
+ */
+public class BinaryDataResponseWriter {
+
+  /**
+   * Copies data from provided {@link InputStream} to Response
+   *
+   * @param binaryData File data
+   * @param response   Response object
+   */
+  public void write(BinaryData binaryData, HttpServletResponse response) {
+    try {
+      response.setContentType(binaryData.getContentType());
+      IOUtils.copy(binaryData.getInputStream(), response.getOutputStream());
+    } catch (IOException e) {
+      throw new ReportPortalException(ErrorType.UNABLE_TO_LOAD_BINARY_DATA, e.getMessage());
+    }
+  }
+}
diff --git a/src/main/java/com/epam/ta/reportportal/util/ControllerUtils.java b/src/main/java/com/epam/ta/reportportal/util/ControllerUtils.java
index 073f25a86a..3c0f441574 100644
--- a/src/main/java/com/epam/ta/reportportal/util/ControllerUtils.java
+++ b/src/main/java/com/epam/ta/reportportal/util/ControllerUtils.java
@@ -19,85 +19,94 @@
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.epam.ta.reportportal.ws.model.log.SaveLogRQ;
-import org.springframework.util.MultiValueMap;
-import org.springframework.web.multipart.MultipartFile;
-import org.springframework.web.multipart.MultipartHttpServletRequest;
-
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
 import javax.servlet.http.HttpServletRequest;
 import javax.validation.ConstraintViolation;
 import javax.validation.Path;
 import javax.validation.Validator;
-import java.util.*;
+import org.apache.commons.collections4.MultiValuedMap;
+import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
 
 /**
  * @author Konstantin Antipin
  */
 public class ControllerUtils {
 
-	/**
-	 * Tries to find request part or file with specified name in multipart attachments
-	 * map.
-	 *
-	 * @param filename File name
-	 * @param files    Files map
-	 * @return Found file
-	 */
-	public static MultipartFile findByFileName(String filename, Map<String, MultipartFile> files) {
-		/* Request part name? */
-		if (files.containsKey(filename)) {
-			return files.get(filename);
-		}
-		/* Filename? */
-		for (MultipartFile file : files.values()) {
-			if (filename.equals(file.getOriginalFilename())) {
-				return file;
-			}
-		}
-		return null;
-	}
+  /**
+   * Tries to find request part or file with specified name in multipart attachments map.
+   *
+   * @param filename File name
+   * @param files    Files map
+   * @return Found file
+   */
+  public static MultipartFile findByFileName(String filename, MultiValuedMap<String, MultipartFile> files) {
+    /* Request part name? */
+    if (files.containsKey(filename)) {
+      var multipartFile = files.get(filename).stream()
+          .findFirst()
+          .get();
+      files.get(filename).remove(multipartFile);
+      return multipartFile;
+    }
+    /* Filename? */
+    for (MultipartFile file : files.values()) {
+      if (filename.equals(file.getOriginalFilename())) {
+        return file;
+      }
+    }
+    return null;
+  }
+
+  public static Long safeParseLong(String value) {
+    try {
+      return Long.parseLong(value);
+    } catch (NumberFormatException e) {
+      throw new ReportPortalException(ErrorType.BAD_REQUEST_ERROR,
+          "The provided parameter must be a number");
+    }
+  }
 
-	public static Long safeParseLong(String value) {
-		try {
-			return Long.parseLong(value);
-		} catch (NumberFormatException e) {
-			throw new ReportPortalException(ErrorType.BAD_REQUEST_ERROR, "The provided parameter must be a number");
-		}
-	}
-	public static Integer safeParseInt(String value) {
-		try {
-			return Integer.parseInt(value);
-		} catch (NumberFormatException e) {
-			throw new ReportPortalException(ErrorType.BAD_REQUEST_ERROR, "The provided parameter must be a number");
-		}
-	}
+  public static Integer safeParseInt(String value) {
+    try {
+      return Integer.parseInt(value);
+    } catch (NumberFormatException e) {
+      throw new ReportPortalException(ErrorType.BAD_REQUEST_ERROR,
+          "The provided parameter must be a number");
+    }
+  }
 
-	public static void validateSaveRQ(Validator validator, SaveLogRQ saveLogRQ) {
-		Set<ConstraintViolation<SaveLogRQ>> constraintViolations = validator.validate(saveLogRQ);
-		if (constraintViolations != null && !constraintViolations.isEmpty()) {
-			StringBuilder messageBuilder = new StringBuilder();
-			for (ConstraintViolation<SaveLogRQ> constraintViolation : constraintViolations) {
-				messageBuilder.append("[");
-				messageBuilder.append("Incorrect value in save log request '");
-				messageBuilder.append(constraintViolation.getInvalidValue());
-				messageBuilder.append("' in field '");
-				Iterator<Path.Node> iterator = constraintViolation.getPropertyPath().iterator();
-				messageBuilder.append(iterator.hasNext() ? iterator.next().getName() : "");
-				messageBuilder.append("'.]");
-			}
-			throw new ReportPortalException(ErrorType.INCORRECT_REQUEST, messageBuilder.toString());
-		}
-	}
+  public static void validateSaveRQ(Validator validator, SaveLogRQ saveLogRQ) {
+    Set<ConstraintViolation<SaveLogRQ>> constraintViolations = validator.validate(saveLogRQ);
+    if (constraintViolations != null && !constraintViolations.isEmpty()) {
+      StringBuilder messageBuilder = new StringBuilder();
+      for (ConstraintViolation<SaveLogRQ> constraintViolation : constraintViolations) {
+        messageBuilder.append("[");
+        messageBuilder.append("Incorrect value in save log request '");
+        messageBuilder.append(constraintViolation.getInvalidValue());
+        messageBuilder.append("' in field '");
+        Iterator<Path.Node> iterator = constraintViolation.getPropertyPath().iterator();
+        messageBuilder.append(iterator.hasNext() ? iterator.next().getName() : "");
+        messageBuilder.append("'.]");
+      }
+      throw new ReportPortalException(ErrorType.INCORRECT_REQUEST, messageBuilder.toString());
+    }
+  }
 
-	public static Map<String, MultipartFile> getUploadedFiles(HttpServletRequest request) {
-		Map<String, MultipartFile> uploadedFiles = new HashMap<>();
-		if (request instanceof MultipartHttpServletRequest) {
-			MultiValueMap<String, MultipartFile> multiFileMap = (((MultipartHttpServletRequest) request)).getMultiFileMap();
-			for (List<MultipartFile> multipartFiles : multiFileMap.values()) {
-				for (MultipartFile file : multipartFiles) {
-					uploadedFiles.put(file.getOriginalFilename(), file);
-				}
-			}
-		}
-		return uploadedFiles;
-	}
+  public static MultiValuedMap<String, MultipartFile> getUploadedFiles(HttpServletRequest request) {
+    MultiValuedMap<String, MultipartFile> uploadedFiles = new ArrayListValuedHashMap<>();
+    if (request instanceof MultipartHttpServletRequest) {
+      MultiValueMap<String, MultipartFile> multiFileMap = (((MultipartHttpServletRequest) request)).getMultiFileMap();
+      for (List<MultipartFile> multipartFiles : multiFileMap.values()) {
+        for (MultipartFile file : multipartFiles) {
+          uploadedFiles.put(file.getOriginalFilename(), file);
+        }
+      }
+    }
+    return uploadedFiles;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/util/DateTimeProvider.java b/src/main/java/com/epam/ta/reportportal/util/DateTimeProvider.java
index ab4faf9751..db9b4ffad2 100644
--- a/src/main/java/com/epam/ta/reportportal/util/DateTimeProvider.java
+++ b/src/main/java/com/epam/ta/reportportal/util/DateTimeProvider.java
@@ -16,9 +16,8 @@
 
 package com.epam.ta.reportportal.util;
 
-import org.springframework.stereotype.Component;
-
 import java.time.LocalDateTime;
+import org.springframework.stereotype.Component;
 
 /**
  * Class to ease writing/testing of date-based logic.
@@ -28,7 +27,7 @@
 @Component
 public class DateTimeProvider {
 
-	public LocalDateTime localDateTimeNow() {
-		return LocalDateTime.now();
-	}
+  public LocalDateTime localDateTimeNow() {
+    return LocalDateTime.now();
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/util/ItemInfoUtils.java b/src/main/java/com/epam/ta/reportportal/util/ItemInfoUtils.java
index 89f22fbb5c..14890df9e4 100644
--- a/src/main/java/com/epam/ta/reportportal/util/ItemInfoUtils.java
+++ b/src/main/java/com/epam/ta/reportportal/util/ItemInfoUtils.java
@@ -16,83 +16,91 @@
 
 package com.epam.ta.reportportal.util;
 
+import static com.epam.ta.reportportal.util.Predicates.ITEM_ATTRIBUTE_EQUIVALENCE;
+import static com.epam.ta.reportportal.ws.model.ErrorType.INCORRECT_REQUEST;
+
 import com.epam.ta.reportportal.entity.ItemAttribute;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.BulkInfoUpdateRQ;
 import com.epam.ta.reportportal.ws.model.attribute.ItemAttributeResource;
 import com.epam.ta.reportportal.ws.model.attribute.UpdateItemAttributeRQ;
-import org.apache.commons.collections.CollectionUtils;
-
 import java.util.Collection;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
-
-import static com.epam.ta.reportportal.util.Predicates.ITEM_ATTRIBUTE_EQUIVALENCE;
-import static com.epam.ta.reportportal.ws.model.ErrorType.INCORRECT_REQUEST;
+import org.apache.commons.collections.CollectionUtils;
 
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  * <p>
  * Util class. Contains methods for updating
- * {@link com.epam.ta.reportportal.entity.launch.Launch}/{@link com.epam.ta.reportportal.entity.item.TestItem} attributes and description.
+ * {@link com.epam.ta.reportportal.entity.launch.Launch}/{@link
+ * com.epam.ta.reportportal.entity.item.TestItem} attributes and description.
  */
 public class ItemInfoUtils {
 
-	private ItemInfoUtils() {
-		//static only
-	}
+  private ItemInfoUtils() {
+    //static only
+  }
 
-	public static Optional<String> updateDescription(BulkInfoUpdateRQ.Description descriptionRq, String existDescription) {
-		if (!Objects.isNull(descriptionRq) && !Objects.isNull(descriptionRq.getComment())) {
-			switch (descriptionRq.getAction()) {
-				case UPDATE: {
-					return Optional.of(existDescription + " " + descriptionRq.getComment());
-				}
-				case CREATE: {
-					return Optional.of(descriptionRq.getComment());
-				}
-				default: {
-					return Optional.empty();
-				}
-			}
-		} else {
-			return Optional.empty();
-		}
-	}
+  public static Optional<String> updateDescription(BulkInfoUpdateRQ.Description descriptionRq,
+      String existDescription) {
+    if (!Objects.isNull(descriptionRq) && !Objects.isNull(descriptionRq.getComment())) {
+      switch (descriptionRq.getAction()) {
+        case UPDATE: {
+          return Optional.of(existDescription + " " + descriptionRq.getComment());
+        }
+        case CREATE: {
+          return Optional.of(descriptionRq.getComment());
+        }
+        default: {
+          return Optional.empty();
+        }
+      }
+    } else {
+      return Optional.empty();
+    }
+  }
 
-	public static ItemAttribute findAttributeByResource(Set<ItemAttribute> attributes, ItemAttributeResource resource) {
-		return attributes.stream()
-				.filter(attr -> ITEM_ATTRIBUTE_EQUIVALENCE.test(attr, resource))
-				.findAny()
-				.orElseThrow(() -> new ReportPortalException(INCORRECT_REQUEST, "Cannot delete not common attribute"));
-	}
+  public static ItemAttribute findAttributeByResource(Set<ItemAttribute> attributes,
+      ItemAttributeResource resource) {
+    return attributes.stream()
+        .filter(attr -> ITEM_ATTRIBUTE_EQUIVALENCE.test(attr, resource))
+        .findAny()
+        .orElseThrow(() -> new ReportPortalException(INCORRECT_REQUEST,
+            "Cannot delete not common attribute"));
+  }
 
-	public static void updateAttribute(Set<ItemAttribute> attributes, UpdateItemAttributeRQ updateItemAttributeRQ) {
-		ItemAttribute itemAttribute = attributes.stream()
-				.filter(attr -> ITEM_ATTRIBUTE_EQUIVALENCE.test(attr, updateItemAttributeRQ.getFrom()))
-				.findAny()
-				.orElseThrow(() -> new ReportPortalException(INCORRECT_REQUEST, "Cannot update not common attribute"));
-		attributes.remove(itemAttribute);
-		itemAttribute.setKey(updateItemAttributeRQ.getTo().getKey());
-		itemAttribute.setValue(updateItemAttributeRQ.getTo().getValue());
-		attributes.add(itemAttribute);
-	}
+  public static void updateAttribute(Set<ItemAttribute> attributes,
+      UpdateItemAttributeRQ updateItemAttributeRQ) {
+    ItemAttribute itemAttribute = attributes.stream()
+        .filter(attr -> ITEM_ATTRIBUTE_EQUIVALENCE.test(attr, updateItemAttributeRQ.getFrom()))
+        .findAny()
+        .orElseThrow(() -> new ReportPortalException(INCORRECT_REQUEST,
+            "Cannot update not common attribute"));
+    attributes.remove(itemAttribute);
+    itemAttribute.setKey(updateItemAttributeRQ.getTo().getKey());
+    itemAttribute.setValue(updateItemAttributeRQ.getTo().getValue());
+    attributes.add(itemAttribute);
+  }
 
-	public static boolean containsAttribute(Set<ItemAttribute> attributes, ItemAttributeResource resource) {
-		return attributes.stream().noneMatch(attr -> ITEM_ATTRIBUTE_EQUIVALENCE.test(attr, resource));
-	}
+  public static boolean containsAttribute(Set<ItemAttribute> attributes,
+      ItemAttributeResource resource) {
+    return attributes.stream().noneMatch(attr -> ITEM_ATTRIBUTE_EQUIVALENCE.test(attr, resource));
+  }
 
-	public static Optional<ItemAttribute> extractAttribute(Collection<ItemAttribute> collection, String key) {
-		return CollectionUtils.isEmpty(collection) ?
-				Optional.empty() :
-				collection.stream().filter(it -> key.equalsIgnoreCase(it.getKey())).findAny();
-	}
+  public static Optional<ItemAttribute> extractAttribute(Collection<ItemAttribute> collection,
+      String key) {
+    return CollectionUtils.isEmpty(collection) ?
+        Optional.empty() :
+        collection.stream().filter(it -> key.equalsIgnoreCase(it.getKey())).findAny();
+  }
 
-	public static Optional<ItemAttributeResource> extractAttributeResource(Collection<ItemAttributeResource> collection, String key) {
-		return CollectionUtils.isEmpty(collection) ?
-				Optional.empty() :
-				collection.stream().filter(it -> key.equalsIgnoreCase(it.getKey())).findAny();
-	}
+  public static Optional<ItemAttributeResource> extractAttributeResource(
+      Collection<ItemAttributeResource> collection, String key) {
+    return CollectionUtils.isEmpty(collection) ?
+        Optional.empty() :
+        collection.stream().filter(it -> key.equalsIgnoreCase(it.getKey())).findAny();
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/util/Predicates.java b/src/main/java/com/epam/ta/reportportal/util/Predicates.java
index 19d9aff7b0..40e840f958 100644
--- a/src/main/java/com/epam/ta/reportportal/util/Predicates.java
+++ b/src/main/java/com/epam/ta/reportportal/util/Predicates.java
@@ -23,7 +23,6 @@
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.ws.model.attribute.ItemAttributeResource;
 import com.google.common.base.CharMatcher;
-
 import java.util.Objects;
 import java.util.Set;
 import java.util.function.BiPredicate;
@@ -36,39 +35,42 @@
  */
 public class Predicates {
 
-	private static final Set<TestItemTypeEnum> INDEXED_ITEM_TYPES = Set.of(TestItemTypeEnum.STEP,
-			TestItemTypeEnum.BEFORE_METHOD,
-			TestItemTypeEnum.AFTER_METHOD
-	);
+  private static final Set<TestItemTypeEnum> INDEXED_ITEM_TYPES = Set.of(TestItemTypeEnum.STEP,
+      TestItemTypeEnum.BEFORE_METHOD,
+      TestItemTypeEnum.AFTER_METHOD
+  );
 
-	/**
-	 * Checks if the test item is suitable for indexing in analyzer.
-	 */
-	public static final Predicate<TestItem> ITEM_CAN_BE_INDEXED = testItem -> testItem != null
-			&& INDEXED_ITEM_TYPES.contains(testItem.getType()) && testItem.getItemResults().getIssue() != null && !testItem.getItemResults()
-			.getIssue()
-			.getIgnoreAnalyzer();
-	/**
-	 * Checks if the launch is suitable for indexing in analyzer
-	 */
-	public static final Predicate<Launch> LAUNCH_CAN_BE_INDEXED = launch -> launch != null
-			&& LaunchModeEnum.DEFAULT.equals(launch.getMode());
-	/**
-	 * Checks if not system item attribute has specified key and value
-	 */
-	public static final BiPredicate<ItemAttribute, ItemAttributeResource> ITEM_ATTRIBUTE_EQUIVALENCE = (attribute, resource) -> {
-		boolean valueAndSystemEquivalence = attribute.getValue().equals(resource.getValue()) && !attribute.isSystem();
-		return Objects.isNull(attribute.getKey()) ?
-				Objects.isNull(resource.getKey()) && valueAndSystemEquivalence :
-				attribute.getKey().equals(resource.getKey()) && valueAndSystemEquivalence;
-	};
-	private static final String SPECIAL_CHARACTERS = "-/@#$%^&_+=()";
-	/**
-	 * Checker whether string contains special characters only
-	 */
-	public static final Predicate<String> SPECIAL_CHARS_ONLY = str -> CharMatcher.anyOf(SPECIAL_CHARACTERS).matchesAllOf(str);
+  /**
+   * Checks if the test item is suitable for indexing in analyzer.
+   */
+  public static final Predicate<TestItem> ITEM_CAN_BE_INDEXED = testItem -> testItem != null
+      && INDEXED_ITEM_TYPES.contains(testItem.getType())
+      && testItem.getItemResults().getIssue() != null && !testItem.getItemResults()
+      .getIssue()
+      .getIgnoreAnalyzer();
+  /**
+   * Checks if the launch is suitable for indexing in analyzer
+   */
+  public static final Predicate<Launch> LAUNCH_CAN_BE_INDEXED = launch -> launch != null
+      && LaunchModeEnum.DEFAULT.equals(launch.getMode());
+  /**
+   * Checks if not system item attribute has specified key and value
+   */
+  public static final BiPredicate<ItemAttribute, ItemAttributeResource> ITEM_ATTRIBUTE_EQUIVALENCE = (attribute, resource) -> {
+    boolean valueAndSystemEquivalence =
+        attribute.getValue().equals(resource.getValue()) && !attribute.isSystem();
+    return Objects.isNull(attribute.getKey()) ?
+        Objects.isNull(resource.getKey()) && valueAndSystemEquivalence :
+        attribute.getKey().equals(resource.getKey()) && valueAndSystemEquivalence;
+  };
+  private static final String SPECIAL_CHARACTERS = "-/@#$%^&_+=()";
+  /**
+   * Checker whether string contains special characters only
+   */
+  public static final Predicate<String> SPECIAL_CHARS_ONLY = str -> CharMatcher.anyOf(
+      SPECIAL_CHARACTERS).matchesAllOf(str);
 
-	private Predicates() {
-		//statics only
-	}
+  private Predicates() {
+    //statics only
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/util/ReportingQueueService.java b/src/main/java/com/epam/ta/reportportal/util/ReportingQueueService.java
index 1fc8897b06..754e127119 100644
--- a/src/main/java/com/epam/ta/reportportal/util/ReportingQueueService.java
+++ b/src/main/java/com/epam/ta/reportportal/util/ReportingQueueService.java
@@ -16,43 +16,42 @@
 
 package com.epam.ta.reportportal.util;
 
+import java.util.UUID;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 
-import java.util.UUID;
-
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
  */
 @Component
 public class ReportingQueueService {
 
-	private static final String UUID_REGEX = "[0-9a-fA-F]{8}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{12}";
-
-	private int queueAmount;
-
-	public int getQueueAmount() {
-		return queueAmount;
-	}
-
-	@Value("${rp.amqp.queues}")
-	public void setQueueAmount(int queueAmount) {
-		this.queueAmount = queueAmount;
-	}
-
-	/**
-	 * Mapping launchId to reporting queue key.
-	 * Not sure if uniform distribution will be produced, intuitively would be uniform with random UUID input.
-	 * As {@link UUID#hashCode} may return negative int,
-	 * take absolute value by trimming high sign bit of complement representation
-	 *
-	 * @param launchUuid
-	 * @return
-	 */
-	public String getReportingQueueKey(String launchUuid) {
-		int value = launchUuid.matches(UUID_REGEX) ? UUID.fromString(launchUuid).hashCode() : launchUuid.hashCode();
-		value = value & 0x7fffffff;
-		return String.valueOf(value % queueAmount);
-	}
+  private static final String UUID_REGEX = "[0-9a-fA-F]{8}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{12}";
+
+  private int queueAmount;
+
+  public int getQueueAmount() {
+    return queueAmount;
+  }
+
+  @Value("${rp.amqp.queues}")
+  public void setQueueAmount(int queueAmount) {
+    this.queueAmount = queueAmount;
+  }
+
+  /**
+   * Mapping launchId to reporting queue key. Not sure if uniform distribution will be produced,
+   * intuitively would be uniform with random UUID input. As {@link UUID#hashCode} may return
+   * negative int, take absolute value by trimming high sign bit of complement representation
+   *
+   * @param launchUuid
+   * @return
+   */
+  public String getReportingQueueKey(String launchUuid) {
+    int value = launchUuid.matches(UUID_REGEX) ? UUID.fromString(launchUuid).hashCode()
+        : launchUuid.hashCode();
+    value = value & 0x7fffffff;
+    return String.valueOf(value % queueAmount);
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/util/email/EmailRulesValidator.java b/src/main/java/com/epam/ta/reportportal/util/email/EmailRulesValidator.java
index 19ff559dc8..da4778c975 100644
--- a/src/main/java/com/epam/ta/reportportal/util/email/EmailRulesValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/util/email/EmailRulesValidator.java
@@ -16,12 +16,6 @@
 
 package com.epam.ta.reportportal.util.email;
 
-import com.epam.ta.reportportal.entity.project.Project;
-import com.epam.ta.reportportal.entity.project.ProjectUtils;
-import com.epam.ta.reportportal.ws.model.ErrorType;
-import com.epam.ta.reportportal.ws.model.attribute.ItemAttributeResource;
-import org.apache.commons.lang3.StringUtils;
-
 import static com.epam.ta.reportportal.commons.Predicates.equalTo;
 import static com.epam.ta.reportportal.commons.Predicates.notNull;
 import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
@@ -30,52 +24,66 @@
 import static com.epam.ta.reportportal.util.UserUtils.isEmailValid;
 import static com.epam.ta.reportportal.ws.model.ErrorType.BAD_REQUEST_ERROR;
 import static com.epam.ta.reportportal.ws.model.ErrorType.USER_NOT_FOUND;
-import static com.epam.ta.reportportal.ws.model.ValidationConstraints.*;
+import static com.epam.ta.reportportal.ws.model.ValidationConstraints.MAX_LOGIN_LENGTH;
+import static com.epam.ta.reportportal.ws.model.ValidationConstraints.MAX_NAME_LENGTH;
+import static com.epam.ta.reportportal.ws.model.ValidationConstraints.MIN_LOGIN_LENGTH;
 import static com.google.common.base.Strings.isNullOrEmpty;
 
+import com.epam.ta.reportportal.entity.project.Project;
+import com.epam.ta.reportportal.entity.project.ProjectUtils;
+import com.epam.ta.reportportal.ws.model.ErrorType;
+import com.epam.ta.reportportal.ws.model.attribute.ItemAttributeResource;
+import org.apache.commons.lang3.StringUtils;
+
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public final class EmailRulesValidator {
 
-	private EmailRulesValidator() {
+  private EmailRulesValidator() {
 
-		//static only
-	}
+    //static only
+  }
 
-	public static void validateRecipient(Project project, String recipient) {
-		expect(recipient, notNull()).verify(BAD_REQUEST_ERROR, formattedSupplier("Provided recipient email '{}' is invalid", recipient));
-		if (recipient.contains("@")) {
-			expect(isEmailValid(recipient), equalTo(true)).verify(BAD_REQUEST_ERROR,
-					formattedSupplier("Provided recipient email '{}' is invalid", recipient)
-			);
-		} else {
-			final String login = recipient.trim();
-			expect(MIN_LOGIN_LENGTH <= login.length() && login.length() <= MAX_LOGIN_LENGTH, equalTo(true)).verify(BAD_REQUEST_ERROR,
-					"Acceptable login length  [" + MIN_LOGIN_LENGTH + ".." + MAX_LOGIN_LENGTH + "]"
-			);
-			if (!getOwner().equals(login)) {
-				expect(ProjectUtils.doesHaveUser(project, login.toLowerCase()), equalTo(true)).verify(USER_NOT_FOUND,
-						login,
-						String.format("User not found in project %s", project.getId())
-				);
-			}
-		}
-	}
+  public static void validateRecipient(Project project, String recipient) {
+    expect(recipient, notNull()).verify(BAD_REQUEST_ERROR,
+        formattedSupplier("Provided recipient email '{}' is invalid", recipient));
+    if (recipient.contains("@")) {
+      expect(isEmailValid(recipient), equalTo(true)).verify(BAD_REQUEST_ERROR,
+          formattedSupplier("Provided recipient email '{}' is invalid", recipient)
+      );
+    } else {
+      final String login = recipient.trim();
+      expect(MIN_LOGIN_LENGTH <= login.length() && login.length() <= MAX_LOGIN_LENGTH,
+          equalTo(true)).verify(BAD_REQUEST_ERROR,
+          "Acceptable login length  [" + MIN_LOGIN_LENGTH + ".." + MAX_LOGIN_LENGTH + "]"
+      );
+      if (!getOwner().equals(login)) {
+        expect(ProjectUtils.doesHaveUser(project, login.toLowerCase()), equalTo(true)).verify(
+            USER_NOT_FOUND,
+            login,
+            String.format("User not found in project %s", project.getId())
+        );
+      }
+    }
+  }
 
-	public static void validateLaunchName(String name) {
-		expect(StringUtils.isBlank(name), equalTo(false)).verify(BAD_REQUEST_ERROR,
-				"Launch name values cannot be empty. Please specify it or not include in request."
-		);
-		expect(name.length() <= MAX_NAME_LENGTH, equalTo(true)).verify(BAD_REQUEST_ERROR,
-				formattedSupplier("One of provided launch names '{}' is too long. Acceptable name length is [1..256]", name)
-		);
-	}
+  public static void validateLaunchName(String name) {
+    expect(StringUtils.isBlank(name), equalTo(false)).verify(BAD_REQUEST_ERROR,
+        "Launch name values cannot be empty. Please specify it or not include in request."
+    );
+    expect(name.length() <= MAX_NAME_LENGTH, equalTo(true)).verify(BAD_REQUEST_ERROR,
+        formattedSupplier(
+            "One of provided launch names '{}' is too long. Acceptable name length is [1..256]",
+            name)
+    );
+  }
 
-	public static void validateLaunchAttribute(ItemAttributeResource attribute) {
-		expect(attribute, notNull()).verify(ErrorType.BAD_REQUEST_ERROR, "Launch attribute cannot be null.");
-		expect(isNullOrEmpty(attribute.getValue()), equalTo(false)).verify(BAD_REQUEST_ERROR,
-				"Attribute' values cannot be empty. Please specify them or do not include in a request."
-		);
-	}
+  public static void validateLaunchAttribute(ItemAttributeResource attribute) {
+    expect(attribute, notNull()).verify(ErrorType.BAD_REQUEST_ERROR,
+        "Launch attribute cannot be null.");
+    expect(isNullOrEmpty(attribute.getValue()), equalTo(false)).verify(BAD_REQUEST_ERROR,
+        "Attribute' values cannot be empty. Please specify them or do not include in a request."
+    );
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/util/email/EmailService.java b/src/main/java/com/epam/ta/reportportal/util/email/EmailService.java
index f07b8b0b2f..60736fe8bd 100644
--- a/src/main/java/com/epam/ta/reportportal/util/email/EmailService.java
+++ b/src/main/java/com/epam/ta/reportportal/util/email/EmailService.java
@@ -45,6 +45,7 @@
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.Properties;
 import java.util.Set;
@@ -55,7 +56,8 @@
 import javax.mail.internet.InternetAddress;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.FileUrlResource;
+import org.springframework.core.io.Resource;
 import org.springframework.mail.javamail.JavaMailSender;
 import org.springframework.mail.javamail.JavaMailSenderImpl;
 import org.springframework.mail.javamail.MimeMessageHelper;
@@ -73,10 +75,8 @@ public class EmailService extends JavaMailSenderImpl {
   private static final String FINISH_LAUNCH_EMAIL_SUBJECT =
       " ReportPortal Notification: [%s] launch '%s' #%s finished";
   private static final String URL_FORMAT = "%s/launches/all";
-  private static final String FULL_ATTRIBUTE_FILTER_FORMAT =
-      "%s?filter.has.key=%s&filter.has.value=%s";
-  private static final String VALUE_ATTRIBUTE_FILTER_FORMAT = "%s?filter.has.value=%s";
-  private static final String EMAIL_TEMPLATE_PREFIX = "templates/email/";
+  private static final String COMPOSITE_ATTRIBUTE_FILTER_FORMAT = "%s?launchesParams=filter.has.compositeAttribute=%s";
+  private static final String TEMPLATE_IMAGES_PREFIX = "templates/email/images/";
   private TemplateEngine templateEngine;
   /* Default value for FROM project notifications field */
   private String from;
@@ -117,6 +117,7 @@ public void sendCreateUserConfirmationEmail(final String subject, final String[]
    * Finish launch notification
    *
    * @param recipients List of recipients
+   * @param project    {@link Project}
    * @param url        ReportPortal URL
    * @param launch     Launch
    */
@@ -218,13 +219,13 @@ private String getUrl(String baseUrl) {
 
   private String buildAttributesLink(String basicUrl, ItemAttribute attribute) {
     if (null != attribute.getKey()) {
-      return format(FULL_ATTRIBUTE_FILTER_FORMAT,
+      return format(COMPOSITE_ATTRIBUTE_FILTER_FORMAT,
           basicUrl,
-          urlPathSegmentEscaper().escape(attribute.getKey()),
+          urlPathSegmentEscaper().escape(attribute.getKey()) + ":" +
           urlPathSegmentEscaper().escape(attribute.getValue())
       );
     } else {
-      return format(VALUE_ATTRIBUTE_FILTER_FORMAT, basicUrl,
+      return format(COMPOSITE_ATTRIBUTE_FILTER_FORMAT, basicUrl,
           urlPathSegmentEscaper().escape(attribute.getValue()));
     }
   }
@@ -385,14 +386,17 @@ private boolean isAddressValid(String from) {
   }
 
   private void attachSocialImages(MimeMessageHelper message) throws MessagingException {
-    message.addInline("ic-github.png", emailTemplateResource("ic-github.png"));
     message.addInline("ic-twitter.png", emailTemplateResource("ic-twitter.png"));
-    message.addInline("ic-youtube.png", emailTemplateResource("ic-youtube.png"));
     message.addInline("ic-slack.png", emailTemplateResource("ic-slack.png"));
+    message.addInline("ic-youtube.png", emailTemplateResource("ic-youtube.png"));
+    message.addInline("ic-linkedin.png", emailTemplateResource("ic-linkedin.png"));
+    message.addInline("ic-facebook.png", emailTemplateResource("ic-facebook.png"));
+    message.addInline("ic-github.png", emailTemplateResource("ic-github.png"));
   }
 
-  private ClassPathResource emailTemplateResource(String resource) {
-    return new ClassPathResource(EMAIL_TEMPLATE_PREFIX + resource);
+  private Resource emailTemplateResource(String resource) {
+    return new FileUrlResource(Objects.requireNonNull(
+        EmailService.class.getClassLoader().getResource(TEMPLATE_IMAGES_PREFIX + resource)));
   }
 
   public void sendAccountSelfDeletionNotification(String recipient) {
@@ -460,6 +464,7 @@ private void attachNewSocialImages(MimeMessageHelper message) throws MessagingEx
     message.addInline("new-ic-slack.png", emailTemplateResource("new-ic-slack.png"));
     message.addInline("new-ic-youtube.png", emailTemplateResource("new-ic-youtube.png"));
     message.addInline("new-ic-linkedin.png", emailTemplateResource("new-ic-linkedin.png"));
+    message.addInline("new-ic-facebook.png", emailTemplateResource("new-ic-facebook.png"));
     message.addInline("new-ic-github.png", emailTemplateResource("new-ic-github.png"));
   }
 
diff --git a/src/main/java/com/epam/ta/reportportal/util/email/MailServiceFactory.java b/src/main/java/com/epam/ta/reportportal/util/email/MailServiceFactory.java
index 5319fee8a2..02013f978b 100644
--- a/src/main/java/com/epam/ta/reportportal/util/email/MailServiceFactory.java
+++ b/src/main/java/com/epam/ta/reportportal/util/email/MailServiceFactory.java
@@ -149,6 +149,7 @@ public Optional<EmailService> getDefaultEmailService() {
   /**
    * Build mail service based on default server configs
    *
+   * @param integration  {@link Integration}
    * @return Built email service
    */
   public Optional<EmailService> getDefaultEmailService(Integration integration) {
@@ -160,6 +161,8 @@ public Optional<EmailService> getDefaultEmailService(Integration integration) {
   /**
    * Build mail service based on default server configs and check connection
    *
+   * @param integration     {@link Integration}
+   * @param checkConnection true if need to check connection with integration
    * @return Built email service
    */
   @Transactional(propagation = Propagation.REQUIRES_NEW)
@@ -179,6 +182,7 @@ public EmailService getEmailService(Integration integration, boolean checkConnec
   /**
    * Build mail service based on default server configs and check connection
    *
+   * @param checkConnection true if need to check connection with integration
    * @return Built email service
    */
   @Transactional(propagation = Propagation.REQUIRES_NEW)
diff --git a/src/main/java/com/epam/ta/reportportal/util/email/constant/IssueRegexConstant.java b/src/main/java/com/epam/ta/reportportal/util/email/constant/IssueRegexConstant.java
index 126d4f4179..65e945375a 100644
--- a/src/main/java/com/epam/ta/reportportal/util/email/constant/IssueRegexConstant.java
+++ b/src/main/java/com/epam/ta/reportportal/util/email/constant/IssueRegexConstant.java
@@ -21,14 +21,14 @@
  */
 public final class IssueRegexConstant {
 
-	public static final String PRODUCT_BUG_ISSUE_REGEX = "^statistics\\$defects\\$product_bug\\$((?!total$).)+.*$";
-	public static final String NO_DEFECT_ISSUE_REGEX = "^statistics\\$defects\\$no_defect\\$((?!total$).)+.*$";
-	public static final String SYSTEM_ISSUE_REGEX = "^statistics\\$defects\\$system_issue\\$((?!total$).)+.*$";
-	public static final String AUTOMATION_BUG_ISSUE_REGEX = "^statistics\\$defects\\$automation_bug\\$((?!total$).)+.*$";
-	public static final String TO_INVESTIGATE_ISSUE_REGEX = "^statistics\\$defects\\$to_investigate\\$((?!total$).)+.*$";
+  public static final String PRODUCT_BUG_ISSUE_REGEX = "^statistics\\$defects\\$product_bug\\$((?!total$).)+.*$";
+  public static final String NO_DEFECT_ISSUE_REGEX = "^statistics\\$defects\\$no_defect\\$((?!total$).)+.*$";
+  public static final String SYSTEM_ISSUE_REGEX = "^statistics\\$defects\\$system_issue\\$((?!total$).)+.*$";
+  public static final String AUTOMATION_BUG_ISSUE_REGEX = "^statistics\\$defects\\$automation_bug\\$((?!total$).)+.*$";
+  public static final String TO_INVESTIGATE_ISSUE_REGEX = "^statistics\\$defects\\$to_investigate\\$((?!total$).)+.*$";
 
-	private IssueRegexConstant() {
-		//static only
-	}
+  private IssueRegexConstant() {
+    //static only
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/util/message/MessageProvider.java b/src/main/java/com/epam/ta/reportportal/util/message/MessageProvider.java
index b6da102529..2365848d50 100644
--- a/src/main/java/com/epam/ta/reportportal/util/message/MessageProvider.java
+++ b/src/main/java/com/epam/ta/reportportal/util/message/MessageProvider.java
@@ -21,5 +21,5 @@
  */
 public interface MessageProvider<T> {
 
-	String provide(T source);
+  String provide(T source);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/ActivityController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/ActivityController.java
index 8623127a10..f35a45596f 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/controller/ActivityController.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/controller/ActivityController.java
@@ -16,13 +16,16 @@
 
  package com.epam.ta.reportportal.ws.controller;
 
+ import static com.epam.ta.reportportal.auth.permissions.Permissions.ASSIGNED_TO_PROJECT;
+ import static org.springframework.http.HttpStatus.OK;
+
  import com.epam.ta.reportportal.commons.EntityUtils;
  import com.epam.ta.reportportal.commons.ReportPortalUser;
  import com.epam.ta.reportportal.commons.querygen.Filter;
- import com.epam.ta.reportportal.commons.querygen.Queryable;
  import com.epam.ta.reportportal.core.activity.ActivityHandler;
  import com.epam.ta.reportportal.entity.activity.Activity;
  import com.epam.ta.reportportal.util.ProjectExtractor;
+ import com.epam.ta.reportportal.ws.model.ActivityEventResource;
  import com.epam.ta.reportportal.ws.model.ActivityResource;
  import com.epam.ta.reportportal.ws.resolver.FilterFor;
  import com.epam.ta.reportportal.ws.resolver.SortFor;
@@ -32,10 +35,11 @@
  import org.springframework.security.access.prepost.PreAuthorize;
  import org.springframework.security.core.annotation.AuthenticationPrincipal;
  import org.springframework.transaction.annotation.Transactional;
- import org.springframework.web.bind.annotation.*;
-
- import static com.epam.ta.reportportal.auth.permissions.Permissions.ASSIGNED_TO_PROJECT;
- import static org.springframework.http.HttpStatus.OK;
+ import org.springframework.web.bind.annotation.PathVariable;
+ import org.springframework.web.bind.annotation.RequestMapping;
+ import org.springframework.web.bind.annotation.RequestMethod;
+ import org.springframework.web.bind.annotation.ResponseStatus;
+ import org.springframework.web.bind.annotation.RestController;
 
  /**
   * @author Ihar_Kahadouski
@@ -70,7 +74,8 @@ public ActivityResource getActivity(@PathVariable String projectName, @PathVaria
 	 @RequestMapping(value = "/item/{itemId}", method = RequestMethod.GET)
 	 @ResponseStatus(OK)
 	 @ApiOperation("Get activities for test item")
-	 public Iterable<ActivityResource> getTestItemActivities(@PathVariable String projectName, @PathVariable Long itemId,
+   public Iterable<ActivityEventResource> getTestItemActivities(@PathVariable String projectName,
+       @PathVariable Long itemId,
 			 @FilterFor(Activity.class) Filter filter, @SortFor(Activity.class) Pageable pageable,
 			 @AuthenticationPrincipal ReportPortalUser user) {
 		 ReportPortalUser.ProjectDetails projectDetails = projectExtractor.extractProjectDetailsAdmin(
diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/ActivityEventController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/ActivityEventController.java
index b0dafd0c2b..bcfa33bdbc 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/controller/ActivityEventController.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/controller/ActivityEventController.java
@@ -19,15 +19,19 @@
 import static com.epam.ta.reportportal.auth.permissions.Permissions.ADMIN_ONLY;
 
 import com.epam.ta.reportportal.commons.ReportPortalUser;
+import com.epam.ta.reportportal.commons.querygen.Condition;
 import com.epam.ta.reportportal.commons.querygen.Queryable;
 import com.epam.ta.reportportal.core.activityevent.ActivityEventHandler;
 import com.epam.ta.reportportal.core.filter.SearchCriteriaService;
 import com.epam.ta.reportportal.core.filter.predefined.PredefinedFilterType;
 import com.epam.ta.reportportal.entity.activity.Activity;
+import com.epam.ta.reportportal.util.ProjectExtractor;
 import com.epam.ta.reportportal.ws.model.ActivityEventResource;
 import com.epam.ta.reportportal.ws.model.PagedResponse;
 import com.epam.ta.reportportal.ws.model.SearchCriteriaRQ;
+import com.epam.ta.reportportal.ws.resolver.FilterCriteriaResolver;
 import io.swagger.annotations.ApiOperation;
+import java.util.List;
 import javax.validation.constraints.Max;
 import javax.validation.constraints.Min;
 import org.springframework.data.domain.PageRequest;
@@ -37,6 +41,8 @@
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.security.core.annotation.AuthenticationPrincipal;
 import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -54,11 +60,14 @@
 public class ActivityEventController {
 
   private final ActivityEventHandler activityEventHandler;
+  private final ProjectExtractor projectExtractor;
   private final SearchCriteriaService searchCriteriaService;
 
   public ActivityEventController(ActivityEventHandler activityEventHandler,
+      ProjectExtractor projectExtractor,
       SearchCriteriaService searchCriteriaService) {
     this.activityEventHandler = activityEventHandler;
+    this.projectExtractor = projectExtractor;
     this.searchCriteriaService = searchCriteriaService;
   }
 
@@ -92,4 +101,14 @@ public PagedResponse<ActivityEventResource> getActivities(
     return activityEventHandler.getActivityEventsHistory(filter, pageable);
   }
 
+  @GetMapping("/{projectName}/subjectName")
+  @PreAuthorize(ADMIN_ONLY)
+  @ApiOperation(value = "Load project activities subjectNames by filter", notes = "Only for current project")
+  public List<String> getProjectSubjectName(@PathVariable String projectName,
+      @RequestParam(FilterCriteriaResolver.DEFAULT_FILTER_PREFIX + Condition.CNT
+          + "subjectName") String value,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return activityEventHandler.getSubjectNames(
+        projectExtractor.extractProjectDetails(user, projectName), value);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/BugTrackingSystemController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/BugTrackingSystemController.java
index 9d3361be33..82a0c12a6f 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/controller/BugTrackingSystemController.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/controller/BugTrackingSystemController.java
@@ -16,6 +16,9 @@
 
 package com.epam.ta.reportportal.ws.controller;
 
+import static com.epam.ta.reportportal.auth.permissions.Permissions.ADMIN_ONLY;
+import static com.epam.ta.reportportal.auth.permissions.Permissions.PROJECT_MANAGER;
+
 import com.epam.ta.reportportal.commons.EntityUtils;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.bts.handler.CreateTicketHandler;
@@ -25,18 +28,21 @@
 import com.epam.ta.reportportal.ws.model.externalsystem.PostTicketRQ;
 import com.epam.ta.reportportal.ws.model.externalsystem.Ticket;
 import io.swagger.annotations.ApiOperation;
+import java.util.List;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.security.core.annotation.AuthenticationPrincipal;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-import static com.epam.ta.reportportal.auth.permissions.Permissions.ADMIN_ONLY;
-import static com.epam.ta.reportportal.auth.permissions.Permissions.PROJECT_MANAGER;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
 
 /**
  * Controller implementation for working with external systems.
@@ -48,79 +54,90 @@
 @RequestMapping("/v1/bts")
 public class BugTrackingSystemController {
 
-	private final ProjectExtractor projectExtractor;
-	private final CreateTicketHandler createTicketHandler;
-	private final GetTicketHandler getTicketHandler;
+  private final ProjectExtractor projectExtractor;
+  private final CreateTicketHandler createTicketHandler;
+  private final GetTicketHandler getTicketHandler;
 
-	@Autowired
-	public BugTrackingSystemController(ProjectExtractor projectExtractor, CreateTicketHandler createTicketHandler, GetTicketHandler getTicketHandler) {
-		this.projectExtractor = projectExtractor;
-		this.createTicketHandler = createTicketHandler;
-		this.getTicketHandler = getTicketHandler;
-	}
+  @Autowired
+  public BugTrackingSystemController(ProjectExtractor projectExtractor,
+      CreateTicketHandler createTicketHandler, GetTicketHandler getTicketHandler) {
+    this.projectExtractor = projectExtractor;
+    this.createTicketHandler = createTicketHandler;
+    this.getTicketHandler = getTicketHandler;
+  }
 
-	@Transactional(readOnly = true)
-	@GetMapping(value = "/{projectName}/{integrationId}/fields-set")
-	@ResponseStatus(HttpStatus.OK)
-	@ApiOperation("Get list of fields required for posting ticket in concrete integration")
-	@PreAuthorize(PROJECT_MANAGER)
-	public List<PostFormField> getSetOfIntegrationSystemFields(@RequestParam(value = "issueType") String issuetype,
-			@PathVariable String projectName, @PathVariable Long integrationId, @AuthenticationPrincipal ReportPortalUser user) {
-		return getTicketHandler.getSubmitTicketFields(issuetype,
-				integrationId,
-				projectExtractor.extractProjectDetails(user, EntityUtils.normalizeId(projectName))
-		);
-	}
+  @Transactional(readOnly = true)
+  @GetMapping(value = "/{projectName}/{integrationId}/fields-set")
+  @ResponseStatus(HttpStatus.OK)
+  @ApiOperation("Get list of fields required for posting ticket in concrete integration")
+  @PreAuthorize(PROJECT_MANAGER)
+  public List<PostFormField> getSetOfIntegrationSystemFields(
+      @RequestParam(value = "issueType") String issuetype,
+      @PathVariable String projectName, @PathVariable Long integrationId,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return getTicketHandler.getSubmitTicketFields(issuetype,
+        integrationId,
+        projectExtractor.extractProjectDetails(user, EntityUtils.normalizeId(projectName))
+    );
+  }
 
-	@Transactional(readOnly = true)
-	@GetMapping(value = "/{projectName}/{integrationId}/issue_types")
-	@ResponseStatus(HttpStatus.OK)
-	@ApiOperation("Get list of allowable issue types for bug tracking system")
-	@PreAuthorize(PROJECT_MANAGER)
-	public List<String> getAllowableIssueTypes(@PathVariable String projectName, @PathVariable Long integrationId,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return getTicketHandler.getAllowableIssueTypes(integrationId, projectExtractor.extractProjectDetails(user, EntityUtils.normalizeId(projectName)));
-	}
+  @Transactional(readOnly = true)
+  @GetMapping(value = "/{projectName}/{integrationId}/issue_types")
+  @ResponseStatus(HttpStatus.OK)
+  @ApiOperation("Get list of allowable issue types for bug tracking system")
+  @PreAuthorize(PROJECT_MANAGER)
+  public List<String> getAllowableIssueTypes(@PathVariable String projectName,
+      @PathVariable Long integrationId,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return getTicketHandler.getAllowableIssueTypes(integrationId,
+        projectExtractor.extractProjectDetails(user, EntityUtils.normalizeId(projectName)));
+  }
 
-	@Transactional(readOnly = true)
-	@GetMapping(value = "/{integrationId}/fields-set")
-	@ResponseStatus(HttpStatus.OK)
-	@ApiOperation("Get list of fields required for posting ticket")
-	@PreAuthorize(ADMIN_ONLY)
-	public List<PostFormField> getSetOfIntegrationSystemFields(@RequestParam(value = "issueType") String issueType,
-			@PathVariable Long integrationId, @AuthenticationPrincipal ReportPortalUser user) {
-		return getTicketHandler.getSubmitTicketFields(issueType, integrationId);
-	}
+  @Transactional(readOnly = true)
+  @GetMapping(value = "/{integrationId}/fields-set")
+  @ResponseStatus(HttpStatus.OK)
+  @ApiOperation("Get list of fields required for posting ticket")
+  @PreAuthorize(ADMIN_ONLY)
+  public List<PostFormField> getSetOfIntegrationSystemFields(
+      @RequestParam(value = "issueType") String issueType,
+      @PathVariable Long integrationId, @AuthenticationPrincipal ReportPortalUser user) {
+    return getTicketHandler.getSubmitTicketFields(issueType, integrationId);
+  }
 
-	@Transactional(readOnly = true)
-	@GetMapping(value = "/{integrationId}/issue_types")
-	@ResponseStatus(HttpStatus.OK)
-	@ApiOperation("Get list of existed issue types in bts")
-	@PreAuthorize(ADMIN_ONLY)
-	public List<String> getAllowableIssueTypes(@PathVariable Long integrationId, @AuthenticationPrincipal ReportPortalUser user) {
-		return getTicketHandler.getAllowableIssueTypes(integrationId);
-	}
+  @Transactional(readOnly = true)
+  @GetMapping(value = "/{integrationId}/issue_types")
+  @ResponseStatus(HttpStatus.OK)
+  @ApiOperation("Get list of existed issue types in bts")
+  @PreAuthorize(ADMIN_ONLY)
+  public List<String> getAllowableIssueTypes(@PathVariable Long integrationId,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return getTicketHandler.getAllowableIssueTypes(integrationId);
+  }
 
-	@Transactional
-	@PostMapping(value = "/{projectName}/{integrationId}/ticket")
-	@ResponseStatus(HttpStatus.CREATED)
-	@ApiOperation("Post ticket to the bts integration")
-	public Ticket createIssue(@Validated @RequestBody PostTicketRQ ticketRQ, @PathVariable String projectName,
-			@PathVariable Long integrationId, @AuthenticationPrincipal ReportPortalUser user) {
-		return createTicketHandler.createIssue(ticketRQ,
-				integrationId,
-				projectExtractor.extractProjectDetails(user, EntityUtils.normalizeId(projectName)),
-				user
-		);
-	}
+  @Transactional
+  @PostMapping(value = "/{projectName}/{integrationId}/ticket")
+  @ResponseStatus(HttpStatus.CREATED)
+  @ApiOperation("Post ticket to the bts integration")
+  public Ticket createIssue(@Validated @RequestBody PostTicketRQ ticketRQ,
+      @PathVariable String projectName,
+      @PathVariable Long integrationId, @AuthenticationPrincipal ReportPortalUser user) {
+    return createTicketHandler.createIssue(ticketRQ,
+        integrationId,
+        projectExtractor.extractProjectDetails(user, EntityUtils.normalizeId(projectName)),
+        user
+    );
+  }
 
-	@Transactional(readOnly = true)
-	@GetMapping(value = "/{projectName}/ticket/{ticketId}")
-	@ResponseStatus(HttpStatus.OK)
-	@ApiOperation("Get ticket from the bts integration")
-	public Ticket getTicket(@PathVariable String ticketId, @PathVariable String projectName, @RequestParam(value = "btsUrl") String btsUrl,
-			@RequestParam(value = "btsProject") String btsProject, @AuthenticationPrincipal ReportPortalUser user) {
-		return getTicketHandler.getTicket(ticketId, btsUrl, btsProject, projectExtractor.extractProjectDetails(user, EntityUtils.normalizeId(projectName)));
-	}
+  @Transactional(readOnly = true)
+  @GetMapping(value = "/{projectName}/ticket/{ticketId}")
+  @ResponseStatus(HttpStatus.OK)
+  @ApiOperation("Get ticket from the bts integration")
+  public Ticket getTicket(@PathVariable String ticketId, @PathVariable String projectName,
+      @RequestParam(value = "btsUrl") String btsUrl,
+      @RequestParam(value = "btsProject") String btsProject,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return getTicketHandler.getTicket(ticketId, btsUrl, btsProject,
+        projectExtractor.extractProjectDetails(user, EntityUtils.normalizeId(projectName)));
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/DashboardController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/DashboardController.java
index f0378eafef..e1b8291bd6 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/controller/DashboardController.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/controller/DashboardController.java
@@ -79,14 +79,16 @@ public DashboardController(ProjectExtractor projectExtractor,
 		this.deleteDashboardHandler = deleteDashboardHandler;
 	}
 
-	@Transactional
-	@PostMapping
-	@ResponseStatus(CREATED)
-	@ApiOperation("Create dashboard for specified project")
-	public EntryCreatedRS createDashboard(@PathVariable String projectName, @RequestBody @Validated CreateDashboardRQ createRQ,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return createDashboardHandler.createDashboard(projectExtractor.extractProjectDetails(user, projectName), createRQ, user);
-	}
+  @Transactional
+  @PostMapping
+  @ResponseStatus(CREATED)
+  @ApiOperation("Create dashboard for specified project")
+  public EntryCreatedRS createDashboard(@PathVariable String projectName,
+      @RequestBody @Validated CreateDashboardRQ createRQ,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return createDashboardHandler.createDashboard(
+        projectExtractor.extractProjectDetails(user, projectName), createRQ, user);
+  }
 
 	@Transactional(readOnly = true)
 	@GetMapping
@@ -138,12 +140,13 @@ public OperationCompletionRS deleteDashboard(@PathVariable String projectName, @
 		return deleteDashboardHandler.deleteDashboard(dashboardId, projectExtractor.extractProjectDetails(user, projectName), user);
 	}
 
-	@Transactional
-	@GetMapping(value = "/{dashboardId}")
-	@ResponseStatus(OK)
-	@ApiOperation("Get specified dashboard by ID for specified project")
-	public DashboardResource getDashboard(@PathVariable String projectName, @PathVariable Long dashboardId,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return getDashboardHandler.getDashboard(dashboardId, projectExtractor.extractProjectDetails(user, projectName));
+  @Transactional
+  @GetMapping(value = "/{dashboardId}")
+  @ResponseStatus(OK)
+  @ApiOperation("Get specified dashboard by ID for specified project")
+  public DashboardResource getDashboard(@PathVariable String projectName,
+      @PathVariable Long dashboardId,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return getDashboardHandler.getDashboard(dashboardId, projectExtractor.extractProjectDetails(user, projectName));
 	}
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/DeprecatedUserController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/DeprecatedUserController.java
new file mode 100644
index 0000000000..0c542985dd
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/ws/controller/DeprecatedUserController.java
@@ -0,0 +1,268 @@
+package com.epam.ta.reportportal.ws.controller;
+
+import static com.epam.ta.reportportal.auth.permissions.Permissions.ADMIN_ONLY;
+import static com.epam.ta.reportportal.auth.permissions.Permissions.ALLOWED_TO_EDIT_USER;
+import static org.springframework.http.HttpStatus.CREATED;
+import static org.springframework.http.HttpStatus.OK;
+
+import com.epam.ta.reportportal.commons.ReportPortalUser;
+import com.epam.ta.reportportal.commons.querygen.Filter;
+import com.epam.ta.reportportal.commons.querygen.Queryable;
+import com.epam.ta.reportportal.core.jasper.GetJasperReportHandler;
+import com.epam.ta.reportportal.core.user.ApiKeyHandler;
+import com.epam.ta.reportportal.core.user.CreateUserHandler;
+import com.epam.ta.reportportal.core.user.DeleteUserHandler;
+import com.epam.ta.reportportal.core.user.EditUserHandler;
+import com.epam.ta.reportportal.core.user.GetUserHandler;
+import com.epam.ta.reportportal.entity.user.User;
+import com.epam.ta.reportportal.entity.user.UserRole;
+import com.epam.ta.reportportal.ws.model.ApiKeyRQ;
+import com.epam.ta.reportportal.ws.model.ApiKeyRS;
+import com.epam.ta.reportportal.ws.model.ApiKeysRS;
+import com.epam.ta.reportportal.ws.model.DeleteBulkRQ;
+import com.epam.ta.reportportal.ws.model.DeleteBulkRS;
+import com.epam.ta.reportportal.ws.model.ModelViews;
+import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
+import com.epam.ta.reportportal.ws.model.YesNoRS;
+import com.epam.ta.reportportal.ws.model.user.ChangePasswordRQ;
+import com.epam.ta.reportportal.ws.model.user.CreateUserBidRS;
+import com.epam.ta.reportportal.ws.model.user.CreateUserRQ;
+import com.epam.ta.reportportal.ws.model.user.CreateUserRQConfirm;
+import com.epam.ta.reportportal.ws.model.user.CreateUserRQFull;
+import com.epam.ta.reportportal.ws.model.user.CreateUserRS;
+import com.epam.ta.reportportal.ws.model.user.EditUserRQ;
+import com.epam.ta.reportportal.ws.model.user.ResetPasswordRQ;
+import com.epam.ta.reportportal.ws.model.user.RestorePasswordRQ;
+import com.epam.ta.reportportal.ws.model.user.UserBidRS;
+import com.epam.ta.reportportal.ws.model.user.UserResource;
+import com.epam.ta.reportportal.ws.resolver.ActiveRole;
+import com.epam.ta.reportportal.ws.resolver.FilterFor;
+import com.epam.ta.reportportal.ws.resolver.ResponseView;
+import com.epam.ta.reportportal.ws.resolver.SortFor;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import java.util.Map;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.data.domain.Pageable;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.security.core.annotation.AuthenticationPrincipal;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/v1/user")
+@Deprecated
+@Api(tags = "deprecated-user-controller", hidden = false, description = "Deprecated UserController")
+public class DeprecatedUserController extends UserController {
+
+  @Autowired
+  public DeprecatedUserController(CreateUserHandler createUserMessageHandler,
+      EditUserHandler editUserMessageHandler, DeleteUserHandler deleteUserHandler,
+      GetUserHandler getUserHandler,
+      @Qualifier("userJasperReportHandler") GetJasperReportHandler<User> jasperReportHandler,
+      ApiKeyHandler apiKeyHandler) {
+    super(createUserMessageHandler, editUserMessageHandler, deleteUserHandler, getUserHandler,
+        jasperReportHandler, apiKeyHandler
+    );
+  }
+
+  @Override
+  @PostMapping
+  @ResponseStatus(CREATED)
+  @PreAuthorize(ADMIN_ONLY)
+  @ApiOperation(value = "Create specified user (DEPRECATED)", notes = "Allowable only for users with administrator role")
+  public CreateUserRS createUserByAdmin(@RequestBody @Validated CreateUserRQFull rq,
+      @AuthenticationPrincipal ReportPortalUser currentUser, HttpServletRequest request) {
+    return super.createUserByAdmin(rq, currentUser, request);
+  }
+
+  @Transactional
+  @PostMapping(value = "/bid")
+  @ResponseStatus(CREATED)
+  @PreAuthorize("(hasPermission(#createUserRQ.getDefaultProject(), 'projectManagerPermission')) || hasRole('ADMINISTRATOR')")
+  @ApiOperation("Register invitation for user who will be created (DEPRECATED)")
+  public CreateUserBidRS createUserBid(@RequestBody @Validated CreateUserRQ createUserRQ,
+      @AuthenticationPrincipal ReportPortalUser currentUser, HttpServletRequest request) {
+    return super.createUserBid(createUserRQ, currentUser, request);
+  }
+
+  @PostMapping(value = "/registration")
+  @ResponseStatus(CREATED)
+  @ApiOperation("Activate invitation and create user in system (DEPRECATED)")
+  public CreateUserRS createUser(@RequestBody @Validated CreateUserRQConfirm request,
+      @RequestParam(value = "uuid") String uuid) {
+    return super.createUser(request, uuid);
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping(value = "/registration")
+  @ApiOperation(value = "Get user's registration info (DEPRECATED)")
+  public UserBidRS getUserBidInfo(@RequestParam(value = "uuid") String uuid) {
+    return super.getUserBidInfo(uuid);
+  }
+
+  @DeleteMapping(value = "/{id}")
+  @ApiOperation(value = "Delete specified user (DEPRECATED)")
+  public OperationCompletionRS deleteUser(@PathVariable(value = "id") Long userId,
+      @AuthenticationPrincipal ReportPortalUser currentUser) {
+    return super.deleteUser(userId, currentUser);
+  }
+
+  @DeleteMapping
+  @PreAuthorize(ADMIN_ONLY)
+  @ResponseStatus(OK)
+  @ApiOperation("Delete specified users by ids (DEPRECATED)")
+  public DeleteBulkRS deleteUsers(@RequestBody @Valid DeleteBulkRQ deleteBulkRQ,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return super.deleteUsers(deleteBulkRQ, user);
+  }
+
+  @Transactional
+  @PutMapping(value = "/{login}")
+  @PreAuthorize(ALLOWED_TO_EDIT_USER)
+  @ApiOperation(value = "Edit specified user (DEPRECATED)", notes = "Only for administrators and profile's owner")
+  public OperationCompletionRS editUser(@PathVariable String login,
+      @RequestBody @Validated EditUserRQ editUserRQ, @ActiveRole UserRole role,
+      @AuthenticationPrincipal ReportPortalUser currentUser) {
+    return super.editUser(login, editUserRQ, role, currentUser);
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping(value = "/{login}")
+  @ResponseView(ModelViews.FullUserView.class)
+  @PreAuthorize(ALLOWED_TO_EDIT_USER)
+  @ApiOperation(value = "Return information about specified user (DEPRECATED)", notes = "Only for administrators and profile's owner")
+  public UserResource getUser(@PathVariable String login,
+      @AuthenticationPrincipal ReportPortalUser currentUser) {
+    return super.getUser(login, currentUser);
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping(value = { "", "/" })
+  @ApiOperation("Return information about current logged-in user (DEPRECATED)")
+  public UserResource getMyself(@AuthenticationPrincipal ReportPortalUser currentUser) {
+    return super.getMyself(currentUser);
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping(value = "/all")
+  @ResponseView(ModelViews.FullUserView.class)
+  @PreAuthorize(ADMIN_ONLY)
+  @ApiOperation(value = "Return information about all users (DEPRECATED)", notes = "Allowable only for users with administrator role")
+  public Iterable<UserResource> getUsers(@FilterFor(User.class) Filter filter,
+      @SortFor(User.class) Pageable pageable, @FilterFor(User.class) Queryable queryable,
+      @AuthenticationPrincipal ReportPortalUser currentUser) {
+    return super.getUsers(filter, pageable, queryable, currentUser);
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping(value = "/registration/info")
+  @ApiOperation(value = "Validate registration information (DEPRECATED)")
+  public YesNoRS validateInfo(@RequestParam(value = "username", required = false) String username,
+      @RequestParam(value = "email", required = false) String email) {
+    return super.validateInfo(username, email);
+  }
+
+  @Transactional
+  @PostMapping(value = "/password/restore")
+  @ResponseStatus(OK)
+  @ApiOperation("Create a restore password request (DEPRECATED)")
+  public OperationCompletionRS restorePassword(@RequestBody @Validated RestorePasswordRQ rq,
+      HttpServletRequest request) {
+    return super.restorePassword(rq, request);
+  }
+
+  @Transactional
+  @PostMapping(value = "/password/reset")
+  @ResponseStatus(OK)
+  @ApiOperation("Reset password (DEPRECATED")
+  public OperationCompletionRS resetPassword(@RequestBody @Validated ResetPasswordRQ rq) {
+    return super.resetPassword(rq);
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping(value = "/password/reset/{uuid}")
+  @ResponseStatus(OK)
+  @ApiOperation("Check if a restore password bid exists (DEPRECATED)")
+  public YesNoRS isRestorePasswordBidExist(@PathVariable String uuid) {
+    return super.isRestorePasswordBidExist(uuid);
+  }
+
+  @Transactional
+  @PostMapping(value = "/password/change")
+  @ResponseStatus(OK)
+  @ApiOperation("Change own password (DEPRECATED)")
+  public OperationCompletionRS changePassword(
+      @RequestBody @Validated ChangePasswordRQ changePasswordRQ,
+      @AuthenticationPrincipal ReportPortalUser currentUser) {
+    return super.changePassword(changePasswordRQ, currentUser);
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping(value = "/{userName}/projects")
+  @ResponseStatus(OK)
+  @ApiOperation(value = "Get user's projects (DEPRECATED)")
+  public Map<String, UserResource.AssignedProject> getUserProjects(@PathVariable String userName,
+      @AuthenticationPrincipal ReportPortalUser currentUser) {
+    return super.getUserProjects(userName, currentUser);
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping(value = "/search")
+  @ResponseStatus(OK)
+  @PreAuthorize(ADMIN_ONLY)
+  @ApiOperation(value = "Find users by term (DEPRECATED)", notes = "Only for administrators")
+  public Iterable<UserResource> findUsers(@RequestParam(value = "term") String term,
+      Pageable pageable, @AuthenticationPrincipal ReportPortalUser user) {
+    return super.findUsers(term, pageable, user);
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping(value = "/export")
+  @PreAuthorize(ADMIN_ONLY)
+  @ApiOperation(value = "Exports information about all users (DEPRECATED)", notes = "Allowable only for users with administrator role")
+  public void export(@ApiParam(allowableValues = "csv")
+  @RequestParam(value = "view", required = false, defaultValue = "csv") String view,
+      @FilterFor(User.class) Filter filter, @FilterFor(User.class) Queryable queryable,
+      @AuthenticationPrincipal ReportPortalUser currentUser, HttpServletResponse response) {
+    super.export(view, filter, queryable, currentUser, response);
+  }
+
+  @PostMapping(value = "/{userId}/api-keys")
+  @ResponseStatus(CREATED)
+  @ApiOperation("Create new Api Key for current user (DEPRECATED)")
+  public ApiKeyRS createApiKey(@RequestBody @Validated ApiKeyRQ apiKeyRQ,
+      @AuthenticationPrincipal ReportPortalUser currentUser, @PathVariable Long userId) {
+    return super.createApiKey(apiKeyRQ, currentUser, userId);
+  }
+
+  @DeleteMapping(value = "/{userId}/api-keys/{keyId}")
+  @ResponseStatus(OK)
+  @ApiOperation("Delete specified Api Key (DEPRECATED)")
+  public OperationCompletionRS deleteApiKey(@PathVariable Long keyId, @PathVariable Long userId) {
+    return super.deleteApiKey(keyId, userId);
+  }
+
+  @GetMapping(value = "/{userId}/api-keys")
+  @ResponseStatus(OK)
+  @ApiOperation("Get List of users Api Keys (DEPRECATED)")
+  public ApiKeysRS getUsersApiKeys(@AuthenticationPrincipal ReportPortalUser currentUser,
+      @PathVariable Long userId) {
+    return super.getUsersApiKeys(currentUser, userId);
+  }
+}
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/FileStorageController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/FileStorageController.java
index 01c6ec14b9..c0dff7cca4 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/controller/FileStorageController.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/controller/FileStorageController.java
@@ -16,6 +16,10 @@
 
 package com.epam.ta.reportportal.ws.controller;
 
+import static com.epam.ta.reportportal.auth.permissions.Permissions.ADMIN_ONLY;
+import static com.epam.ta.reportportal.auth.permissions.Permissions.ASSIGNED_TO_PROJECT;
+import static com.epam.ta.reportportal.auth.permissions.Permissions.NOT_CUSTOMER;
+
 import com.epam.ta.reportportal.commons.EntityUtils;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.file.DeleteFilesHandler;
@@ -27,6 +31,9 @@
 import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
 import com.google.common.net.HttpHeaders;
 import io.swagger.annotations.ApiOperation;
+import java.io.IOException;
+import java.io.InputStream;
+import javax.servlet.http.HttpServletResponse;
 import org.apache.commons.io.IOUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
@@ -34,15 +41,15 @@
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.security.core.annotation.AuthenticationPrincipal;
 import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.multipart.MultipartFile;
 
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.InputStream;
-
-import static com.epam.ta.reportportal.auth.permissions.Permissions.*;
-
 /**
  * @author Dzianis_Shybeka
  */
@@ -50,74 +57,76 @@
 @RequestMapping("/v1/data")
 public class FileStorageController {
 
-	private final ProjectExtractor projectExtractor;
-	private final EditUserHandler editUserHandler;
-	private final GetFileHandler getFileHandler;
-	private final DeleteFilesHandler deleteFilesHandler;
+  private final ProjectExtractor projectExtractor;
+  private final EditUserHandler editUserHandler;
+  private final GetFileHandler getFileHandler;
+  private final DeleteFilesHandler deleteFilesHandler;
 
-	@Autowired
-	public FileStorageController(ProjectExtractor projectExtractor, EditUserHandler editUserHandler, GetFileHandler getFileHandler, DeleteFilesHandler deleteFilesHandler) {
-		this.projectExtractor = projectExtractor;
-		this.editUserHandler = editUserHandler;
-		this.getFileHandler = getFileHandler;
-		this.deleteFilesHandler = deleteFilesHandler;
-	}
+  @Autowired
+  public FileStorageController(ProjectExtractor projectExtractor, EditUserHandler editUserHandler,
+      GetFileHandler getFileHandler, DeleteFilesHandler deleteFilesHandler) {
+    this.projectExtractor = projectExtractor;
+    this.editUserHandler = editUserHandler;
+    this.getFileHandler = getFileHandler;
+    this.deleteFilesHandler = deleteFilesHandler;
+  }
 
-	@Transactional(readOnly = true)
-	@PreAuthorize(ASSIGNED_TO_PROJECT)
-	@GetMapping(value = "/{projectName}/{dataId}")
-	public void getFile(@PathVariable String projectName, @PathVariable("dataId") Long dataId, HttpServletResponse response,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		toResponse(response, getFileHandler.loadFileById(dataId, projectExtractor.extractProjectDetails(user, projectName)));
-	}
+  @Transactional(readOnly = true)
+  @PreAuthorize(ASSIGNED_TO_PROJECT)
+  @GetMapping(value = "/{projectName}/{dataId}")
+  public void getFile(@PathVariable String projectName, @PathVariable("dataId") Long dataId,
+      HttpServletResponse response,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    toResponse(response, getFileHandler.loadFileById(dataId,
+        projectExtractor.extractProjectDetails(user, projectName)));
+  }
 
-	/**
-	 * (non-Javadoc)
-	 */
-	@Transactional(readOnly = true)
-	@GetMapping(value = "/photo")
-	@ApiOperation("Get photo of current user")
-	public void getMyPhoto(@AuthenticationPrincipal ReportPortalUser user, HttpServletResponse response,
-			@RequestParam(value = "loadThumbnail", required = false) boolean loadThumbnail) {
-		toResponse(response, getFileHandler.getUserPhoto(user, loadThumbnail));
-	}
+  @Transactional(readOnly = true)
+  @GetMapping(value = "/photo")
+  @ApiOperation("Get photo of current user")
+  public void getMyPhoto(@AuthenticationPrincipal ReportPortalUser user,
+      HttpServletResponse response,
+      @RequestParam(value = "loadThumbnail", required = false) boolean loadThumbnail) {
+    toResponse(response, getFileHandler.getUserPhoto(user, loadThumbnail));
+  }
 
-	/**
-	 * (non-Javadoc)
-	 */
-	@Transactional(readOnly = true)
-	@PreAuthorize(NOT_CUSTOMER)
-	@GetMapping(value = "/{projectName}/userphoto")
-	@ApiOperation("Get user's photo")
-	public void getUserPhoto(@PathVariable String projectName, @RequestParam(value = "id") String username,
-			@RequestParam(value = "loadThumbnail", required = false) boolean loadThumbnail, HttpServletResponse response,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		BinaryData userPhoto = getFileHandler.getUserPhoto(EntityUtils.normalizeId(username), user, projectName, loadThumbnail);
-		toResponse(response, userPhoto);
-	}
+  @Transactional(readOnly = true)
+  @PreAuthorize(NOT_CUSTOMER)
+  @GetMapping(value = "/{projectName}/userphoto")
+  @ApiOperation("Get user's photo")
+  public void getUserPhoto(@PathVariable String projectName,
+      @RequestParam(value = "id") String username,
+      @RequestParam(value = "loadThumbnail", required = false) boolean loadThumbnail,
+      HttpServletResponse response,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    BinaryData userPhoto = getFileHandler.getUserPhoto(EntityUtils.normalizeId(username), user,
+        projectName, loadThumbnail);
+    toResponse(response, userPhoto);
+  }
 
-	@Transactional
-	@PostMapping(value = "/photo", consumes = { MediaType.MULTIPART_FORM_DATA_VALUE })
-	@ApiOperation("Upload user's photo")
-	public OperationCompletionRS uploadPhoto(@RequestParam("file") MultipartFile file, @AuthenticationPrincipal ReportPortalUser user) {
-		return editUserHandler.uploadPhoto(EntityUtils.normalizeId(user.getUsername()), file);
-	}
+  @Transactional
+  @PostMapping(value = "/photo", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
+  @ApiOperation("Upload user's photo")
+  public OperationCompletionRS uploadPhoto(@RequestParam("file") MultipartFile file,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return editUserHandler.uploadPhoto(EntityUtils.normalizeId(user.getUsername()), file);
+  }
 
-	@Transactional
-	@DeleteMapping(value = "/photo")
-	@ApiOperation("Delete user's photo")
-	public OperationCompletionRS deletePhoto(@AuthenticationPrincipal ReportPortalUser user) {
-		return editUserHandler.deletePhoto(EntityUtils.normalizeId(user.getUsername()));
-	}
+  @Transactional
+  @DeleteMapping(value = "/photo")
+  @ApiOperation("Delete user's photo")
+  public OperationCompletionRS deletePhoto(@AuthenticationPrincipal ReportPortalUser user) {
+    return editUserHandler.deletePhoto(EntityUtils.normalizeId(user.getUsername()));
+  }
 
-	@Transactional
-	@PreAuthorize(ADMIN_ONLY)
-	@PostMapping(value = "/clean", consumes = { MediaType.MULTIPART_FORM_DATA_VALUE })
-	@ApiOperation("Remove attachments from file storage according to uploaded csv file")
-	public OperationCompletionRS removeAttachmentsByCsv(@RequestParam("file") MultipartFile file,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return deleteFilesHandler.removeFilesByCsv(file);
-	}
+  @Transactional
+  @PreAuthorize(ADMIN_ONLY)
+  @PostMapping(value = "/clean", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
+  @ApiOperation("Remove attachments from file storage according to uploaded csv file")
+  public OperationCompletionRS removeAttachmentsByCsv(@RequestParam("file") MultipartFile file,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return deleteFilesHandler.removeFilesByCsv(file);
+  }
 
 	/**
 	 * Copies data from provided {@link InputStream} to Response
diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/IntegrationController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/IntegrationController.java
index 3627f1732b..69bcb8ab3b 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/controller/IntegrationController.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/controller/IntegrationController.java
@@ -16,6 +16,12 @@
 
 package com.epam.ta.reportportal.ws.controller;
 
+import static com.epam.ta.reportportal.auth.permissions.Permissions.ADMIN_ONLY;
+import static com.epam.ta.reportportal.auth.permissions.Permissions.ASSIGNED_TO_PROJECT;
+import static com.epam.ta.reportportal.auth.permissions.Permissions.PROJECT_MANAGER;
+import static com.epam.ta.reportportal.commons.EntityUtils.normalizeId;
+import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.integration.CreateIntegrationHandler;
 import com.epam.ta.reportportal.core.integration.DeleteIntegrationHandler;
@@ -27,20 +33,23 @@
 import com.epam.ta.reportportal.ws.model.integration.IntegrationRQ;
 import com.epam.ta.reportportal.ws.model.integration.IntegrationResource;
 import io.swagger.annotations.ApiOperation;
+import java.util.List;
+import java.util.Map;
+import javax.validation.Valid;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.security.core.annotation.AuthenticationPrincipal;
 import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.bind.annotation.*;
-
-import javax.validation.Valid;
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.auth.permissions.Permissions.*;
-import static com.epam.ta.reportportal.commons.EntityUtils.normalizeId;
-import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -49,192 +58,216 @@
 @RequestMapping(value = "/v1/integration")
 public class IntegrationController {
 
-	private final ProjectExtractor projectExtractor;
-	private final DeleteIntegrationHandler deleteIntegrationHandler;
-	private final GetIntegrationHandler getIntegrationHandler;
-	private final CreateIntegrationHandler createIntegrationHandler;
-	private final ExecuteIntegrationHandler executeIntegrationHandler;
-
-	@Autowired
-	public IntegrationController(ProjectExtractor projectExtractor, DeleteIntegrationHandler deleteIntegrationHandler,
-			GetIntegrationHandler getIntegrationHandler, CreateIntegrationHandler createIntegrationHandler,
-			ExecuteIntegrationHandler executeIntegrationHandler) {
-		this.projectExtractor = projectExtractor;
-		this.deleteIntegrationHandler = deleteIntegrationHandler;
-		this.getIntegrationHandler = getIntegrationHandler;
-		this.createIntegrationHandler = createIntegrationHandler;
-		this.executeIntegrationHandler = executeIntegrationHandler;
-	}
-
-	@Transactional(readOnly = true)
-	@GetMapping("/global/all")
-	@ResponseStatus(HttpStatus.OK)
-	@ApiOperation("Get available global integrations")
-	public List<IntegrationResource> getGlobalIntegrations(@AuthenticationPrincipal ReportPortalUser reportPortalUser) {
-		return getIntegrationHandler.getGlobalIntegrations();
-	}
-
-	@Transactional(readOnly = true)
-	@GetMapping("/global/all/{pluginName}")
-	@ResponseStatus(HttpStatus.OK)
-	@ApiOperation("Get available global integrations for plugin")
-	public List<IntegrationResource> getGlobalIntegrations(@AuthenticationPrincipal ReportPortalUser reportPortalUser,
-			@PathVariable String pluginName) {
-		return getIntegrationHandler.getGlobalIntegrations(pluginName);
-	}
-
-	@Transactional(readOnly = true)
-	@GetMapping("/project/{projectName}/all")
-	@ResponseStatus(HttpStatus.OK)
-	@PreAuthorize(ASSIGNED_TO_PROJECT)
-	@ApiOperation("Get available project integrations")
-	public List<IntegrationResource> getProjectIntegrations(@PathVariable String projectName,
-			@AuthenticationPrincipal ReportPortalUser reportPortalUser) {
-		return getIntegrationHandler.getProjectIntegrations(normalizeId(projectName));
-	}
-
-	@Transactional(readOnly = true)
-	@GetMapping("/project/{projectName}/all/{pluginName}")
-	@ResponseStatus(HttpStatus.OK)
-	@PreAuthorize(ASSIGNED_TO_PROJECT)
-	@ApiOperation("Get available project integrations for plugin")
-	public List<IntegrationResource> getProjectIntegrations(@AuthenticationPrincipal ReportPortalUser reportPortalUser,
-			@PathVariable String projectName, @PathVariable String pluginName) {
-		return getIntegrationHandler.getProjectIntegrations(pluginName, normalizeId(projectName));
-	}
-
-	@Transactional
-	@PostMapping(value = "/{pluginName}")
-	@ResponseStatus(HttpStatus.CREATED)
-	@ApiOperation("Create global Report Portal integration instance")
-	@PreAuthorize(ADMIN_ONLY)
-	public EntryCreatedRS createGlobalIntegration(@RequestBody @Valid IntegrationRQ createRequest, @PathVariable String pluginName,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return createIntegrationHandler.createGlobalIntegration(createRequest, pluginName, user);
-	}
-
-	@Transactional
-	@PostMapping(value = "/{projectName}/{pluginName}")
-	@ResponseStatus(HttpStatus.CREATED)
-	@ApiOperation("Create project Report Portal integration instance")
-	@PreAuthorize(PROJECT_MANAGER)
-	public EntryCreatedRS createProjectIntegration(@RequestBody @Valid IntegrationRQ createRequest, @PathVariable String pluginName,
-			@PathVariable String projectName, @AuthenticationPrincipal ReportPortalUser user) {
-		return createIntegrationHandler.createProjectIntegration(normalizeId(projectName), createRequest, pluginName, user);
-
-	}
-
-	@Transactional(readOnly = true)
-	@GetMapping(value = "{projectName}/{integrationId}/connection/test")
-	@ResponseStatus(HttpStatus.OK)
-	@PreAuthorize(ASSIGNED_TO_PROJECT)
-	@ApiOperation("Test connection to the integration through the project config")
-	public boolean testIntegrationConnection(@PathVariable Long integrationId, @PathVariable String projectName,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return getIntegrationHandler.testConnection(integrationId, normalizeId(projectName));
-	}
-
-	@Transactional(readOnly = true)
-	@GetMapping(value = "/{integrationId}/connection/test")
-	@ResponseStatus(HttpStatus.OK)
-	@PreAuthorize(ADMIN_ONLY)
-	@ApiOperation("Test connection to the global integration")
-	public boolean testIntegrationConnection(@PathVariable Long integrationId, @AuthenticationPrincipal ReportPortalUser user) {
-		return getIntegrationHandler.testConnection(integrationId);
-	}
-
-	@Transactional(readOnly = true)
-	@GetMapping(value = "/{integrationId}")
-	@ResponseStatus(HttpStatus.OK)
-	@ApiOperation("Get global Report Portal integration instance")
-	@PreAuthorize(ADMIN_ONLY)
-	public IntegrationResource getGlobalIntegration(@PathVariable Long integrationId, @AuthenticationPrincipal ReportPortalUser user) {
-		return getIntegrationHandler.getGlobalIntegrationById(integrationId);
-	}
-
-	@Transactional(readOnly = true)
-	@GetMapping(value = "/{projectName}/{integrationId}")
-	@ResponseStatus(HttpStatus.OK)
-	@ApiOperation("Get integration instance")
-	@PreAuthorize(ASSIGNED_TO_PROJECT)
-	public IntegrationResource getProjectIntegration(@PathVariable String projectName, @PathVariable Long integrationId,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return getIntegrationHandler.getProjectIntegrationById(integrationId, normalizeId(projectName));
-	}
-
-	@Transactional
-	@PutMapping(value = "/{integrationId}")
-	@ResponseStatus(HttpStatus.OK)
-	@ApiOperation("Update global Report Portal integration instance")
-	@PreAuthorize(ADMIN_ONLY)
-	public OperationCompletionRS updateGlobalIntegration(@PathVariable Long integrationId, @RequestBody @Valid IntegrationRQ updateRequest,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return createIntegrationHandler.updateGlobalIntegration(integrationId, updateRequest, user);
-
-	}
-
-	@Transactional
-	@PutMapping(value = "/{projectName}/{integrationId}")
-	@ResponseStatus(HttpStatus.OK)
-	@ApiOperation("Update project integration instance")
-	@PreAuthorize(PROJECT_MANAGER)
-	public OperationCompletionRS updateProjectIntegration(@PathVariable Long integrationId, @RequestBody @Valid IntegrationRQ updateRequest,
-			@PathVariable String projectName, @AuthenticationPrincipal ReportPortalUser user) {
-		return createIntegrationHandler.updateProjectIntegration(integrationId, normalizeId(projectName), updateRequest, user);
-
-	}
-
-	@Transactional
-	@DeleteMapping(value = "/{integrationId}")
-	@ResponseStatus(HttpStatus.OK)
-	@ApiOperation("Delete global integration instance")
-	@PreAuthorize(ADMIN_ONLY)
-	public OperationCompletionRS deleteGlobalIntegration(@PathVariable Long integrationId, @AuthenticationPrincipal ReportPortalUser user) {
-		return deleteIntegrationHandler.deleteGlobalIntegration(integrationId, user);
-	}
-
-	@Transactional
-	@DeleteMapping(value = "/all/{type}")
-	@ResponseStatus(HttpStatus.OK)
-	@ApiOperation("Delete all global integrations by type")
-	@PreAuthorize(ADMIN_ONLY)
-	public OperationCompletionRS deleteAllIntegrations(@PathVariable String type, @AuthenticationPrincipal ReportPortalUser user) {
-		return deleteIntegrationHandler.deleteGlobalIntegrationsByType(type, user);
-	}
-
-	@Transactional
-	@DeleteMapping(value = "/{projectName}/{integrationId}")
-	@ResponseStatus(HttpStatus.OK)
-	@ApiOperation("Delete project integration instance")
-	@PreAuthorize(PROJECT_MANAGER)
-	public OperationCompletionRS deleteProjectIntegration(@PathVariable String projectName, @PathVariable Long integrationId,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return deleteIntegrationHandler.deleteProjectIntegration(integrationId, normalizeId(projectName), user);
-	}
-
-	@Transactional
-	@DeleteMapping(value = "/{projectName}/all/{type}")
-	@ResponseStatus(HttpStatus.OK)
-	@ApiOperation("Delete all integrations assigned to specified project")
-	@PreAuthorize(PROJECT_MANAGER)
-	public OperationCompletionRS deleteAllProjectIntegrations(@PathVariable String type, @PathVariable String projectName,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return deleteIntegrationHandler.deleteProjectIntegrationsByType(type, normalizeId(projectName), user);
-	}
-
-	@Transactional
-	@PutMapping(value = "{projectName}/{integrationId}/{command}", consumes = { APPLICATION_JSON_VALUE })
-	@ResponseStatus(HttpStatus.OK)
-	@PreAuthorize(ASSIGNED_TO_PROJECT)
-	@ApiOperation("Execute command to the integration instance")
-	public Object executeIntegrationCommand(@PathVariable String projectName, @PathVariable("integrationId") Long integrationId,
-			@PathVariable("command") String command, @RequestBody Map<String, Object> executionParams,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return executeIntegrationHandler.executeCommand(projectExtractor.extractProjectDetails(user, projectName),
-				integrationId,
-				command,
-				executionParams
-		);
-	}
+  private final ProjectExtractor projectExtractor;
+  private final DeleteIntegrationHandler deleteIntegrationHandler;
+  private final GetIntegrationHandler getIntegrationHandler;
+  private final CreateIntegrationHandler createIntegrationHandler;
+  private final ExecuteIntegrationHandler executeIntegrationHandler;
+
+  @Autowired
+  public IntegrationController(ProjectExtractor projectExtractor,
+      DeleteIntegrationHandler deleteIntegrationHandler,
+      GetIntegrationHandler getIntegrationHandler,
+      CreateIntegrationHandler createIntegrationHandler,
+      ExecuteIntegrationHandler executeIntegrationHandler) {
+    this.projectExtractor = projectExtractor;
+    this.deleteIntegrationHandler = deleteIntegrationHandler;
+    this.getIntegrationHandler = getIntegrationHandler;
+    this.createIntegrationHandler = createIntegrationHandler;
+    this.executeIntegrationHandler = executeIntegrationHandler;
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping("/global/all")
+  @ResponseStatus(HttpStatus.OK)
+  @ApiOperation("Get available global integrations")
+  public List<IntegrationResource> getGlobalIntegrations(
+      @AuthenticationPrincipal ReportPortalUser reportPortalUser) {
+    return getIntegrationHandler.getGlobalIntegrations();
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping("/global/all/{pluginName}")
+  @ResponseStatus(HttpStatus.OK)
+  @ApiOperation("Get available global integrations for plugin")
+  public List<IntegrationResource> getGlobalIntegrations(
+      @AuthenticationPrincipal ReportPortalUser reportPortalUser,
+      @PathVariable String pluginName) {
+    return getIntegrationHandler.getGlobalIntegrations(pluginName);
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping("/project/{projectName}/all")
+  @ResponseStatus(HttpStatus.OK)
+  @PreAuthorize(ASSIGNED_TO_PROJECT)
+  @ApiOperation("Get available project integrations")
+  public List<IntegrationResource> getProjectIntegrations(@PathVariable String projectName,
+      @AuthenticationPrincipal ReportPortalUser reportPortalUser) {
+    return getIntegrationHandler.getProjectIntegrations(normalizeId(projectName));
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping("/project/{projectName}/all/{pluginName}")
+  @ResponseStatus(HttpStatus.OK)
+  @PreAuthorize(ASSIGNED_TO_PROJECT)
+  @ApiOperation("Get available project integrations for plugin")
+  public List<IntegrationResource> getProjectIntegrations(
+      @AuthenticationPrincipal ReportPortalUser reportPortalUser,
+      @PathVariable String projectName, @PathVariable String pluginName) {
+    return getIntegrationHandler.getProjectIntegrations(pluginName, normalizeId(projectName));
+  }
+
+  @Transactional
+  @PostMapping(value = "/{pluginName}")
+  @ResponseStatus(HttpStatus.CREATED)
+  @ApiOperation("Create global Report Portal integration instance")
+  @PreAuthorize(ADMIN_ONLY)
+  public EntryCreatedRS createGlobalIntegration(@RequestBody @Valid IntegrationRQ createRequest,
+      @PathVariable String pluginName,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return createIntegrationHandler.createGlobalIntegration(createRequest, pluginName, user);
+  }
+
+  @Transactional
+  @PostMapping(value = "/{projectName}/{pluginName}")
+  @ResponseStatus(HttpStatus.CREATED)
+  @ApiOperation("Create project Report Portal integration instance")
+  @PreAuthorize(PROJECT_MANAGER)
+  public EntryCreatedRS createProjectIntegration(@RequestBody @Valid IntegrationRQ createRequest,
+      @PathVariable String pluginName,
+      @PathVariable String projectName, @AuthenticationPrincipal ReportPortalUser user) {
+    return createIntegrationHandler.createProjectIntegration(normalizeId(projectName),
+        createRequest, pluginName, user);
+
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping(value = "{projectName}/{integrationId}/connection/test")
+  @ResponseStatus(HttpStatus.OK)
+  @PreAuthorize(ASSIGNED_TO_PROJECT)
+  @ApiOperation("Test connection to the integration through the project config")
+  public boolean testIntegrationConnection(@PathVariable Long integrationId,
+      @PathVariable String projectName,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return getIntegrationHandler.testConnection(integrationId, normalizeId(projectName));
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping(value = "/{integrationId}/connection/test")
+  @ResponseStatus(HttpStatus.OK)
+  @PreAuthorize(ADMIN_ONLY)
+  @ApiOperation("Test connection to the global integration")
+  public boolean testIntegrationConnection(@PathVariable Long integrationId,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return getIntegrationHandler.testConnection(integrationId);
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping(value = "/{integrationId}")
+  @ResponseStatus(HttpStatus.OK)
+  @ApiOperation("Get global Report Portal integration instance")
+  @PreAuthorize(ADMIN_ONLY)
+  public IntegrationResource getGlobalIntegration(@PathVariable Long integrationId,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return getIntegrationHandler.getGlobalIntegrationById(integrationId);
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping(value = "/{projectName}/{integrationId}")
+  @ResponseStatus(HttpStatus.OK)
+  @ApiOperation("Get integration instance")
+  @PreAuthorize(ASSIGNED_TO_PROJECT)
+  public IntegrationResource getProjectIntegration(@PathVariable String projectName,
+      @PathVariable Long integrationId,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return getIntegrationHandler.getProjectIntegrationById(integrationId, normalizeId(projectName));
+  }
+
+  @Transactional
+  @PutMapping(value = "/{integrationId}")
+  @ResponseStatus(HttpStatus.OK)
+  @ApiOperation("Update global Report Portal integration instance")
+  @PreAuthorize(ADMIN_ONLY)
+  public OperationCompletionRS updateGlobalIntegration(@PathVariable Long integrationId,
+      @RequestBody @Valid IntegrationRQ updateRequest,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return createIntegrationHandler.updateGlobalIntegration(integrationId, updateRequest, user);
+
+  }
+
+  @Transactional
+  @PutMapping(value = "/{projectName}/{integrationId}")
+  @ResponseStatus(HttpStatus.OK)
+  @ApiOperation("Update project integration instance")
+  @PreAuthorize(PROJECT_MANAGER)
+  public OperationCompletionRS updateProjectIntegration(@PathVariable Long integrationId,
+      @RequestBody @Valid IntegrationRQ updateRequest,
+      @PathVariable String projectName, @AuthenticationPrincipal ReportPortalUser user) {
+    return createIntegrationHandler.updateProjectIntegration(integrationId,
+        normalizeId(projectName), updateRequest, user);
+
+  }
+
+  @Transactional
+  @DeleteMapping(value = "/{integrationId}")
+  @ResponseStatus(HttpStatus.OK)
+  @ApiOperation("Delete global integration instance")
+  @PreAuthorize(ADMIN_ONLY)
+  public OperationCompletionRS deleteGlobalIntegration(@PathVariable Long integrationId,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return deleteIntegrationHandler.deleteGlobalIntegration(integrationId, user);
+  }
+
+  @Transactional
+  @DeleteMapping(value = "/all/{type}")
+  @ResponseStatus(HttpStatus.OK)
+  @ApiOperation("Delete all global integrations by type")
+  @PreAuthorize(ADMIN_ONLY)
+  public OperationCompletionRS deleteAllIntegrations(@PathVariable String type,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return deleteIntegrationHandler.deleteGlobalIntegrationsByType(type, user);
+  }
+
+  @Transactional
+  @DeleteMapping(value = "/{projectName}/{integrationId}")
+  @ResponseStatus(HttpStatus.OK)
+  @ApiOperation("Delete project integration instance")
+  @PreAuthorize(PROJECT_MANAGER)
+  public OperationCompletionRS deleteProjectIntegration(@PathVariable String projectName,
+      @PathVariable Long integrationId,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return deleteIntegrationHandler.deleteProjectIntegration(integrationId,
+        normalizeId(projectName), user);
+  }
+
+  @Transactional
+  @DeleteMapping(value = "/{projectName}/all/{type}")
+  @ResponseStatus(HttpStatus.OK)
+  @ApiOperation("Delete all integrations assigned to specified project")
+  @PreAuthorize(PROJECT_MANAGER)
+  public OperationCompletionRS deleteAllProjectIntegrations(@PathVariable String type,
+      @PathVariable String projectName,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return deleteIntegrationHandler.deleteProjectIntegrationsByType(type, normalizeId(projectName),
+        user);
+  }
+
+  @Transactional
+  @PutMapping(value = "{projectName}/{integrationId}/{command}", consumes = {
+      APPLICATION_JSON_VALUE})
+  @ResponseStatus(HttpStatus.OK)
+  @PreAuthorize(ASSIGNED_TO_PROJECT)
+  @ApiOperation("Execute command to the integration instance")
+  public Object executeIntegrationCommand(@PathVariable String projectName,
+      @PathVariable("integrationId") Long integrationId,
+      @PathVariable("command") String command, @RequestBody Map<String, Object> executionParams,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return executeIntegrationHandler.executeCommand(
+        projectExtractor.extractProjectDetails(user, projectName),
+        integrationId,
+        command,
+        executionParams
+    );
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/InternalApiController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/InternalApiController.java
index b39ed0bd44..45fb274192 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/controller/InternalApiController.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/controller/InternalApiController.java
@@ -20,8 +20,7 @@
 import org.springframework.web.bind.annotation.RequestMapping;
 
 /**
- * Allowed for internal (other services) clients ONLY
- * Provides direct access to DAO layer
+ * Allowed for internal (other services) clients ONLY Provides direct access to DAO layer
  *
  * @author Andrei Varabyeu
  */
@@ -30,20 +29,20 @@
 //@PreAuthorize("hasRole('COMPONENT')")
 public class InternalApiController {
 
-	//	private final ExternalSystemRepository externalSystemRepository;
-	//
-	//	@Autowired
-	//	public InternalApiController(ExternalSystemRepository externalSystemRepository) {
-	//		this.externalSystemRepository = externalSystemRepository;
-	//	}
-	//
-	//	@RequestMapping(value = "/external-system/{systemId}", method = RequestMethod.GET)
-	//	@ResponseBody
-	//	@ResponseStatus(HttpStatus.OK)
-	//
-	//	public ExternalSystemResource getExternalSystem(@PathVariable String systemId) {
-	//		ExternalSystem externalSystem = externalSystemRepository.findOne(systemId);
-	//		BusinessRule.expect(externalSystem, Predicates.notNull()).verify(ErrorType.EXTERNAL_SYSTEM_NOT_FOUND, systemId);
-	//		return ExternalSystemConverter.TO_RESOURCE.apply(externalSystem);
-	//	}
+  //	private final ExternalSystemRepository externalSystemRepository;
+  //
+  //	@Autowired
+  //	public InternalApiController(ExternalSystemRepository externalSystemRepository) {
+  //		this.externalSystemRepository = externalSystemRepository;
+  //	}
+  //
+  //	@RequestMapping(value = "/external-system/{systemId}", method = RequestMethod.GET)
+  //	@ResponseBody
+  //	@ResponseStatus(HttpStatus.OK)
+  //
+  //	public ExternalSystemResource getExternalSystem(@PathVariable String systemId) {
+  //		ExternalSystem externalSystem = externalSystemRepository.findOne(systemId);
+  //		BusinessRule.expect(externalSystem, Predicates.notNull()).verify(ErrorType.EXTERNAL_SYSTEM_NOT_FOUND, systemId);
+  //		return ExternalSystemConverter.TO_RESOURCE.apply(externalSystem);
+  //	}
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/LaunchAsyncController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/LaunchAsyncController.java
index 5b2cffec4c..ee4e818e9e 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/controller/LaunchAsyncController.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/controller/LaunchAsyncController.java
@@ -15,6 +15,12 @@
  */
 package com.epam.ta.reportportal.ws.controller;
 
+import static com.epam.ta.reportportal.auth.permissions.Permissions.ALLOWED_TO_REPORT;
+import static com.epam.ta.reportportal.commons.EntityUtils.normalizeId;
+import static com.epam.ta.reportportal.core.launch.util.LinkGenerator.composeBaseUrl;
+import static org.springframework.http.HttpStatus.CREATED;
+import static org.springframework.http.HttpStatus.OK;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.launch.FinishLaunchHandler;
 import com.epam.ta.reportportal.core.launch.MergeLaunchHandler;
@@ -22,24 +28,27 @@
 import com.epam.ta.reportportal.core.logging.HttpLogging;
 import com.epam.ta.reportportal.util.ProjectExtractor;
 import com.epam.ta.reportportal.ws.model.FinishExecutionRQ;
-import com.epam.ta.reportportal.ws.model.launch.*;
+import com.epam.ta.reportportal.ws.model.launch.FinishLaunchRS;
+import com.epam.ta.reportportal.ws.model.launch.LaunchResource;
+import com.epam.ta.reportportal.ws.model.launch.MergeLaunchesRQ;
+import com.epam.ta.reportportal.ws.model.launch.StartLaunchRQ;
+import com.epam.ta.reportportal.ws.model.launch.StartLaunchRS;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
+import javax.servlet.http.HttpServletRequest;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.security.core.annotation.AuthenticationPrincipal;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import javax.servlet.http.HttpServletRequest;
-
-import static com.epam.ta.reportportal.auth.permissions.Permissions.ALLOWED_TO_REPORT;
-import static com.epam.ta.reportportal.commons.EntityUtils.normalizeId;
-import static com.epam.ta.reportportal.core.launch.util.LinkGenerator.composeBaseUrl;
-import static org.springframework.http.HttpStatus.CREATED;
-import static org.springframework.http.HttpStatus.OK;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
 
 /**
  * Controller implementation for async reporting client API for
@@ -51,58 +60,65 @@
 @RequestMapping("/v2/{projectName}/launch")
 public class LaunchAsyncController {
 
-	private final ProjectExtractor projectExtractor;
-	private final StartLaunchHandler startLaunchHandler;
-	private final FinishLaunchHandler finishLaunchHandler;
-	private final MergeLaunchHandler mergeLaunchesHandler;
+  private final ProjectExtractor projectExtractor;
+  private final StartLaunchHandler startLaunchHandler;
+  private final FinishLaunchHandler finishLaunchHandler;
+  private final MergeLaunchHandler mergeLaunchesHandler;
 
-	@Autowired
-	public LaunchAsyncController(ProjectExtractor projectExtractor, @Qualifier("startLaunchHandlerAsync") StartLaunchHandler startLaunchHandler,
-			@Qualifier("finishLaunchHandlerAsync") FinishLaunchHandler finishLaunchHandler, MergeLaunchHandler mergeLaunchesHandler) {
-		this.projectExtractor = projectExtractor;
-		this.startLaunchHandler = startLaunchHandler;
-		this.finishLaunchHandler = finishLaunchHandler;
-		this.mergeLaunchesHandler = mergeLaunchesHandler;
-	}
+  @Autowired
+  public LaunchAsyncController(ProjectExtractor projectExtractor,
+      @Qualifier("startLaunchHandlerAsync") StartLaunchHandler startLaunchHandler,
+      @Qualifier("finishLaunchHandlerAsync") FinishLaunchHandler finishLaunchHandler,
+      MergeLaunchHandler mergeLaunchesHandler) {
+    this.projectExtractor = projectExtractor;
+    this.startLaunchHandler = startLaunchHandler;
+    this.finishLaunchHandler = finishLaunchHandler;
+    this.mergeLaunchesHandler = mergeLaunchesHandler;
+  }
 
-	@HttpLogging
-	@PostMapping
-	@PreAuthorize(ALLOWED_TO_REPORT)
-	@ResponseStatus(CREATED)
-	@ApiOperation("Starts launch for specified project")
-	public StartLaunchRS startLaunch(@PathVariable String projectName,
-			@ApiParam(value = "Start launch request body", required = true) @RequestBody @Validated StartLaunchRQ startLaunchRQ,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return startLaunchHandler.startLaunch(user, projectExtractor.extractProjectDetails(user, normalizeId(projectName)), startLaunchRQ);
-	}
+  @HttpLogging
+  @PostMapping
+  @PreAuthorize(ALLOWED_TO_REPORT)
+  @ResponseStatus(CREATED)
+  @ApiOperation("Starts launch for specified project")
+  public StartLaunchRS startLaunch(@PathVariable String projectName,
+      @ApiParam(value = "Start launch request body", required = true) @RequestBody @Validated StartLaunchRQ startLaunchRQ,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return startLaunchHandler.startLaunch(user,
+        projectExtractor.extractProjectDetails(user, normalizeId(projectName)), startLaunchRQ);
+  }
 
-	@HttpLogging
-	@PutMapping(value = "/{launchId}/finish")
-	@PreAuthorize(ALLOWED_TO_REPORT)
-	@ResponseStatus(OK)
-	@ApiOperation("Finish launch for specified project")
-	public FinishLaunchRS finishLaunch(@PathVariable String projectName, @PathVariable String launchId,
-			@RequestBody @Validated FinishExecutionRQ finishLaunchRQ, @AuthenticationPrincipal ReportPortalUser user,
-			HttpServletRequest request) {
-		return finishLaunchHandler.finishLaunch(
-				launchId,
-				finishLaunchRQ,
-				projectExtractor.extractProjectDetails(user, normalizeId(projectName)),
-				user,
-				composeBaseUrl(request)
-		);
-	}
+  @HttpLogging
+  @PutMapping(value = "/{launchId}/finish")
+  @PreAuthorize(ALLOWED_TO_REPORT)
+  @ResponseStatus(OK)
+  @ApiOperation("Finish launch for specified project")
+  public FinishLaunchRS finishLaunch(@PathVariable String projectName,
+      @PathVariable String launchId,
+      @RequestBody @Validated FinishExecutionRQ finishLaunchRQ,
+      @AuthenticationPrincipal ReportPortalUser user,
+      HttpServletRequest request) {
+    return finishLaunchHandler.finishLaunch(
+        launchId,
+        finishLaunchRQ,
+        projectExtractor.extractProjectDetails(user, normalizeId(projectName)),
+        user,
+        composeBaseUrl(request)
+    );
+  }
 
-	@HttpLogging
-	@Transactional
-	@PostMapping("/merge")
-	@PreAuthorize(ALLOWED_TO_REPORT)
-	@ResponseStatus(OK)
-	@ApiOperation("Merge set of specified launches in common one")
-	public LaunchResource mergeLaunches(@PathVariable String projectName,
-			@ApiParam(value = "Merge launches request body", required = true) @RequestBody @Validated MergeLaunchesRQ mergeLaunchesRQ,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return mergeLaunchesHandler.mergeLaunches(projectExtractor.extractProjectDetails(user, normalizeId(projectName)), user, mergeLaunchesRQ);
-	}
+  @HttpLogging
+  @Transactional
+  @PostMapping("/merge")
+  @PreAuthorize(ALLOWED_TO_REPORT)
+  @ResponseStatus(OK)
+  @ApiOperation("Merge set of specified launches in common one")
+  public LaunchResource mergeLaunches(@PathVariable String projectName,
+      @ApiParam(value = "Merge launches request body", required = true) @RequestBody @Validated MergeLaunchesRQ mergeLaunchesRQ,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return mergeLaunchesHandler.mergeLaunches(
+        projectExtractor.extractProjectDetails(user, normalizeId(projectName)), user,
+        mergeLaunchesRQ);
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/LaunchController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/LaunchController.java
index 5949add2c2..30412173f8 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/controller/LaunchController.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/controller/LaunchController.java
@@ -15,18 +15,45 @@
  */
 package com.epam.ta.reportportal.ws.controller;
 
+import static com.epam.ta.reportportal.auth.permissions.Permissions.ALLOWED_TO_REPORT;
+import static com.epam.ta.reportportal.auth.permissions.Permissions.ASSIGNED_TO_PROJECT;
+import static com.epam.ta.reportportal.auth.permissions.Permissions.PROJECT_MANAGER_OR_ADMIN;
+import static com.epam.ta.reportportal.commons.EntityUtils.normalizeId;
+import static com.epam.ta.reportportal.core.launch.util.LinkGenerator.composeBaseUrl;
+import static org.springframework.http.HttpStatus.CREATED;
+import static org.springframework.http.HttpStatus.OK;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.core.imprt.ImportLaunchHandler;
 import com.epam.ta.reportportal.core.jasper.GetJasperReportHandler;
-import com.epam.ta.reportportal.core.launch.*;
+import com.epam.ta.reportportal.core.launch.DeleteLaunchHandler;
+import com.epam.ta.reportportal.core.launch.FinishLaunchHandler;
+import com.epam.ta.reportportal.core.launch.GetLaunchHandler;
+import com.epam.ta.reportportal.core.launch.MergeLaunchHandler;
+import com.epam.ta.reportportal.core.launch.StartLaunchHandler;
+import com.epam.ta.reportportal.core.launch.StopLaunchHandler;
+import com.epam.ta.reportportal.core.launch.UpdateLaunchHandler;
 import com.epam.ta.reportportal.entity.jasper.ReportFormat;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.entity.widget.content.ChartStatisticsContent;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.util.ProjectExtractor;
-import com.epam.ta.reportportal.ws.model.*;
-import com.epam.ta.reportportal.ws.model.launch.*;
+import com.epam.ta.reportportal.ws.model.BulkInfoUpdateRQ;
+import com.epam.ta.reportportal.ws.model.BulkRQ;
+import com.epam.ta.reportportal.ws.model.DeleteBulkRQ;
+import com.epam.ta.reportportal.ws.model.DeleteBulkRS;
+import com.epam.ta.reportportal.ws.model.ErrorType;
+import com.epam.ta.reportportal.ws.model.FinishExecutionRQ;
+import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
+import com.epam.ta.reportportal.ws.model.launch.AnalyzeLaunchRQ;
+import com.epam.ta.reportportal.ws.model.launch.FinishLaunchRS;
+import com.epam.ta.reportportal.ws.model.launch.LaunchImportRQ;
+import com.epam.ta.reportportal.ws.model.launch.LaunchResource;
+import com.epam.ta.reportportal.ws.model.launch.MergeLaunchesRQ;
+import com.epam.ta.reportportal.ws.model.launch.StartLaunchRQ;
+import com.epam.ta.reportportal.ws.model.launch.StartLaunchRS;
+import com.epam.ta.reportportal.ws.model.launch.UpdateLaunchRQ;
 import com.epam.ta.reportportal.ws.model.launch.cluster.ClusterInfoResource;
 import com.epam.ta.reportportal.ws.model.launch.cluster.CreateClustersRQ;
 import com.epam.ta.reportportal.ws.resolver.FilterFor;
@@ -36,6 +63,13 @@
 import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.Map;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.data.domain.Pageable;
@@ -44,30 +78,24 @@
 import org.springframework.security.core.annotation.AuthenticationPrincipal;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RequestPart;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.multipart.MultipartFile;
 
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.validation.Valid;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.auth.permissions.Permissions.ALLOWED_TO_REPORT;
-import static com.epam.ta.reportportal.auth.permissions.Permissions.PROJECT_MANAGER_OR_ADMIN;
-import static com.epam.ta.reportportal.commons.EntityUtils.normalizeId;
-import static com.epam.ta.reportportal.core.launch.util.LinkGenerator.composeBaseUrl;
-import static org.springframework.http.HttpStatus.CREATED;
-import static org.springframework.http.HttpStatus.OK;
-
 /**
- * Controller implementation for
- * {@link com.epam.ta.reportportal.entity.launch.Launch} entity
+ * Controller implementation for {@link com.epam.ta.reportportal.entity.launch.Launch} entity
  * <p>
- * Note: please use EntityUtils for forced lower case for user names and project
- * names
+ * Note: please use EntityUtils for forced lower case for user names and project names
  * </p>
  *
  * @author Andrei Varabyeu
@@ -78,343 +106,370 @@
 @RequestMapping("/v1/{projectName}/launch")
 public class LaunchController {
 
-	private final ProjectExtractor projectExtractor;
-	private final StartLaunchHandler startLaunchHandler;
-	private final FinishLaunchHandler finishLaunchHandler;
-	private final StopLaunchHandler stopLaunchHandler;
-	private final DeleteLaunchHandler deleteLaunchMessageHandler;
-	private final GetLaunchHandler getLaunchMessageHandler;
-	private final UpdateLaunchHandler updateLaunchHandler;
-	private final MergeLaunchHandler mergeLaunchesHandler;
-	private final ImportLaunchHandler importLaunchHandler;
-	private final GetJasperReportHandler<Launch> getJasperHandler;
-
-	@Autowired
-	public LaunchController(ProjectExtractor projectExtractor, StartLaunchHandler startLaunchHandler, FinishLaunchHandler finishLaunchHandler,
-			StopLaunchHandler stopLaunchHandler, DeleteLaunchHandler deleteLaunchMessageHandler, GetLaunchHandler getLaunchMessageHandler,
-			UpdateLaunchHandler updateLaunchHandler, MergeLaunchHandler mergeLaunchesHandler, ImportLaunchHandler importLaunchHandler,
-			@Qualifier("launchJasperReportHandler") GetJasperReportHandler<Launch> getJasperHandler) {
-		this.projectExtractor = projectExtractor;
-		this.startLaunchHandler = startLaunchHandler;
-		this.finishLaunchHandler = finishLaunchHandler;
-		this.stopLaunchHandler = stopLaunchHandler;
-		this.deleteLaunchMessageHandler = deleteLaunchMessageHandler;
-		this.getLaunchMessageHandler = getLaunchMessageHandler;
-		this.updateLaunchHandler = updateLaunchHandler;
-		this.mergeLaunchesHandler = mergeLaunchesHandler;
-		this.importLaunchHandler = importLaunchHandler;
-		this.getJasperHandler = getJasperHandler;
-	}
-
-	/* Report client API */
-
-	@PostMapping
-	@PreAuthorize(ALLOWED_TO_REPORT)
-	@ResponseStatus(CREATED)
-	@ApiOperation("Starts launch for specified project")
-	public StartLaunchRS startLaunch(@PathVariable String projectName,
-			@ApiParam(value = "Start launch request body", required = true) @RequestBody @Validated @Valid StartLaunchRQ startLaunchRQ,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return startLaunchHandler.startLaunch(user, projectExtractor.extractProjectDetails(user, normalizeId(projectName)), startLaunchRQ);
-	}
-
-	@PutMapping(value = "/{launchId}/finish")
-	@PreAuthorize(ALLOWED_TO_REPORT)
-	@ResponseStatus(OK)
-	@ApiOperation("Finish launch for specified project")
-	public FinishLaunchRS finishLaunch(@PathVariable String projectName, @PathVariable String launchId,
-			@RequestBody @Validated FinishExecutionRQ finishLaunchRQ, @AuthenticationPrincipal ReportPortalUser user,
-			HttpServletRequest request) {
-		return finishLaunchHandler.finishLaunch(launchId,
-				finishLaunchRQ,
-				projectExtractor.extractProjectDetails(user, normalizeId(projectName)),
-				user,
-				composeBaseUrl(request)
-		);
-	}
-
-	/* Frontend API */
-
-	@Transactional
-	@PutMapping("/{launchId}/stop")
-	@PreAuthorize(ALLOWED_TO_REPORT)
-	@ResponseStatus(OK)
-	@ApiOperation("Force finish launch for specified project")
-	public OperationCompletionRS forceFinishLaunch(@PathVariable String projectName, @PathVariable Long launchId,
-			@RequestBody @Validated FinishExecutionRQ finishExecutionRQ, @AuthenticationPrincipal ReportPortalUser user) {
-		return stopLaunchHandler.stopLaunch(launchId, finishExecutionRQ, projectExtractor.extractProjectDetails(user, normalizeId(projectName)), user);
-	}
-
-	@Transactional
-	@PutMapping("/stop")
-	@PreAuthorize(ALLOWED_TO_REPORT)
-	@ResponseStatus(OK)
-	@ApiOperation("Force finish launch")
-	public List<OperationCompletionRS> bulkForceFinish(@PathVariable String projectName,
-			@RequestBody @Validated BulkRQ<Long, FinishExecutionRQ> rq, @AuthenticationPrincipal ReportPortalUser user) {
-		return stopLaunchHandler.stopLaunch(rq, projectExtractor.extractProjectDetails(user, normalizeId(projectName)), user);
-	}
-
-	@Transactional
-	@PutMapping("/{launchId}/update")
-	@PreAuthorize(ALLOWED_TO_REPORT)
-	@ResponseStatus(OK)
-	@ApiOperation("Updates launch for specified project")
-	public OperationCompletionRS updateLaunch(@PathVariable String projectName, @PathVariable Long launchId,
-			@RequestBody @Validated UpdateLaunchRQ updateLaunchRQ, @AuthenticationPrincipal ReportPortalUser user) {
-		return updateLaunchHandler.updateLaunch(launchId, projectExtractor.extractProjectDetails(user, normalizeId(projectName)), user, updateLaunchRQ);
-	}
-
-	@Transactional
-	@PutMapping("/update")
-	@PreAuthorize(ALLOWED_TO_REPORT)
-	@ResponseStatus(OK)
-	@ApiOperation("Updates launches for specified project")
-	public List<OperationCompletionRS> updateLaunches(@PathVariable String projectName,
-			@RequestBody @Validated BulkRQ<Long, UpdateLaunchRQ> rq, @AuthenticationPrincipal ReportPortalUser user) {
-		return updateLaunchHandler.updateLaunch(rq, projectExtractor.extractProjectDetails(user, normalizeId(projectName)), user);
-	}
-
-	@Transactional
-	@DeleteMapping("/{launchId}")
-	@PreAuthorize(ALLOWED_TO_REPORT)
-	@ResponseStatus(OK)
-	@ApiOperation("Delete specified launch by ID")
-	public OperationCompletionRS deleteLaunch(@PathVariable String projectName, @PathVariable Long launchId,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return deleteLaunchMessageHandler.deleteLaunch(launchId, projectExtractor.extractProjectDetails(user, normalizeId(projectName)), user);
-	}
-
-	@Transactional(readOnly = true)
-	@GetMapping("/{launchId}")
-	@ResponseStatus(OK)
-	@ApiOperation("Get specified launch by ID")
-	public LaunchResource getLaunch(@PathVariable String projectName, @PathVariable String launchId,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return getLaunchMessageHandler.getLaunch(launchId, projectExtractor.extractProjectDetails(user, normalizeId(projectName)));
-	}
-
-	@Transactional(readOnly = true)
-	@GetMapping("/uuid/{launchId}")
-	@ResponseStatus(OK)
-	@ApiOperation("Get specified launch by UUID")
-	public LaunchResource getLaunchByUuid(@PathVariable String projectName, @PathVariable String launchId,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return getLaunchMessageHandler.getLaunch(launchId, projectExtractor.extractProjectDetails(user, normalizeId(projectName)));
-	}
-
-	@Transactional(readOnly = true)
-	@GetMapping
-	@ResponseStatus(OK)
-	@ApiOperation("Get list of project launches by filter")
-	public Iterable<LaunchResource> getProjectLaunches(@PathVariable String projectName, @FilterFor(Launch.class) Filter filter,
-			@SortFor(Launch.class) Pageable pageable, @AuthenticationPrincipal ReportPortalUser user) {
-		return getLaunchMessageHandler.getProjectLaunches(projectExtractor.extractProjectDetails(user, normalizeId(projectName)),
-				filter,
-				pageable,
-				user.getUsername()
-		);
-	}
-
-	@Transactional(readOnly = true)
-	@GetMapping(value = "/latest")
-	@ResponseStatus(OK)
-	@ApiOperation("Get list of latest project launches by filter")
-	public Iterable<LaunchResource> getLatestLaunches(@PathVariable String projectName, @FilterFor(Launch.class) Filter filter,
-			@SortFor(Launch.class) Pageable pageable, @AuthenticationPrincipal ReportPortalUser user) {
-		return getLaunchMessageHandler.getLatestLaunches(projectExtractor.extractProjectDetails(user, normalizeId(projectName)), filter, pageable);
-	}
-
-	@GetMapping(value = "/mode")
-	@ResponseBody
-	@ResponseStatus(OK)
-	@ApiOperation("Get launches of specified project from DEBUG mode")
-	public Iterable<LaunchResource> getDebugLaunches(@PathVariable String projectName, @FilterFor(Launch.class) Filter filter,
-			@SortFor(Launch.class) Pageable pageable, @AuthenticationPrincipal ReportPortalUser user) {
-		return getLaunchMessageHandler.getDebugLaunches(projectExtractor.extractProjectDetails(user, normalizeId(projectName)), filter, pageable);
-	}
-
-	@Transactional(readOnly = true)
-	@GetMapping(value = "/attribute/keys")
-	@ResponseStatus(OK)
-	@ApiOperation("Get all unique attribute keys of project launches")
-	public List<String> getAttributeKeys(@PathVariable String projectName,
-			@RequestParam(value = "filter." + "cnt." + "attributeKey") String value, @AuthenticationPrincipal ReportPortalUser user) {
-		return getLaunchMessageHandler.getAttributeKeys(projectExtractor.extractProjectDetails(user, normalizeId(projectName)), value);
-	}
-
-	@Transactional(readOnly = true)
-	@GetMapping(value = "/attribute/values")
-	@ResponseStatus(OK)
-	@ApiOperation("Get all unique attribute values of project launches")
-	public List<String> getAttributeValues(@PathVariable String projectName,
-			@RequestParam(value = "filter." + "eq." + "attributeKey", required = false) String key,
-			@RequestParam(value = "filter." + "cnt." + "attributeValue") String value, @AuthenticationPrincipal ReportPortalUser user) {
-		return getLaunchMessageHandler.getAttributeValues(projectExtractor.extractProjectDetails(user, normalizeId(projectName)), key, value);
-	}
-
-	@GetMapping(value = "/cluster/{launchId}")
-	@ResponseStatus(OK)
-	@ApiOperation("Get all index clusters of the launch")
-	public Iterable<ClusterInfoResource> getClusters(@PathVariable String projectName, @PathVariable String launchId, Pageable pageable,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return getLaunchMessageHandler.getClusters(launchId,
-				projectExtractor.extractProjectDetails(user, normalizeId(projectName)),
-				pageable
-		);
-	}
-
-	@Transactional
-	@PutMapping(value = "/info")
-	@PreAuthorize(PROJECT_MANAGER_OR_ADMIN)
-	@ResponseStatus(OK)
-	@ApiOperation("Bulk update attributes and description")
-	public OperationCompletionRS bulkUpdate(@PathVariable String projectName, @RequestBody @Validated BulkInfoUpdateRQ bulkInfoUpdateRQ,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return updateLaunchHandler.bulkInfoUpdate(bulkInfoUpdateRQ, projectExtractor.extractProjectDetails(user, projectName));
-	}
-
-	@Transactional(readOnly = true)
-	@GetMapping(value = "/owners")
-	@ResponseStatus(OK)
-	@ApiOperation("Get all unique owners of project launches")
-	public List<String> getAllOwners(@PathVariable String projectName, @RequestParam(value = "filter." + "cnt." + "user") String value,
-			@RequestParam(value = "mode", required = false, defaultValue = "DEFAULT") String mode,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return getLaunchMessageHandler.getOwners(projectExtractor.extractProjectDetails(user, normalizeId(projectName)), value, mode);
-	}
-
-	@Transactional(readOnly = true)
-	@GetMapping(value = "/names")
-	@ResponseStatus(OK)
-	@ApiOperation("Get launch names of project")
-	public List<String> getAllLaunchNames(@PathVariable String projectName, @RequestParam(value = "filter." + "cnt." + "name") String value,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return getLaunchMessageHandler.getLaunchNames(projectExtractor.extractProjectDetails(user, normalizeId(projectName)), value);
-	}
-
-	@Transactional(readOnly = true)
-	@GetMapping(value = "/compare")
-	@ResponseStatus(OK)
-	@ApiOperation("Compare launches")
-	public Map<String, List<ChartStatisticsContent>> compareLaunches(@PathVariable String projectName,
-			@RequestParam(value = "ids") Long[] ids, @AuthenticationPrincipal ReportPortalUser user) {
-		return getLaunchMessageHandler.getLaunchesComparisonInfo(projectExtractor.extractProjectDetails(user, normalizeId(projectName)), ids);
-	}
-
-	@Transactional
-	@PostMapping("/merge")
-	@PreAuthorize(ALLOWED_TO_REPORT)
-	@ResponseStatus(OK)
-	@ApiOperation("Merge set of specified launches in common one")
-	public LaunchResource mergeLaunches(@PathVariable String projectName,
-			@ApiParam(value = "Merge launches request body", required = true) @RequestBody @Validated MergeLaunchesRQ mergeLaunchesRQ,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return mergeLaunchesHandler.mergeLaunches(projectExtractor.extractProjectDetails(user, normalizeId(projectName)), user, mergeLaunchesRQ);
-	}
-
-	@Transactional
-	@PostMapping(value = "/analyze")
-	@ResponseStatus(OK)
-	@ApiOperation("Start launch auto-analyzer on demand")
-	public OperationCompletionRS startLaunchAnalyzer(@PathVariable String projectName,
-			@RequestBody @Validated AnalyzeLaunchRQ analyzeLaunchRQ, @AuthenticationPrincipal ReportPortalUser user) {
-		return updateLaunchHandler.startLaunchAnalyzer(analyzeLaunchRQ, projectExtractor.extractProjectDetails(user, normalizeId(projectName)), user);
-	}
-
-	@PostMapping(value = "/cluster")
-	@ResponseStatus(OK)
-	@ApiOperation("Create launch clusters")
-	public OperationCompletionRS createClusters(@PathVariable String projectName,
-			@RequestBody @Validated CreateClustersRQ createClustersRQ, @AuthenticationPrincipal ReportPortalUser user) {
-		return updateLaunchHandler.createClusters(createClustersRQ, projectExtractor.extractProjectDetails(user, normalizeId(projectName)), user);
-	}
-
-	@Transactional(readOnly = true)
-	@GetMapping(value = "/status")
-	@ResponseStatus(OK)
-
-	public Map<String, String> getStatuses(@PathVariable String projectName, @RequestParam(value = "ids") Long[] ids,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return getLaunchMessageHandler.getStatuses(projectExtractor.extractProjectDetails(user, normalizeId(projectName)), ids);
-	}
-
-	@Transactional(readOnly = true)
-	@GetMapping(value = "/{launchId}/report")
-	@ResponseStatus(OK)
-	@ApiOperation(value = "Export specified launch", notes = "Only following formats are supported: pdf (by default), xls, html.")
-	public void getLaunchReport(@PathVariable String projectName, @PathVariable Long launchId,
-			@ApiParam(allowableValues = "pdf, xls, html") @RequestParam(value = "view", required = false, defaultValue = "pdf") String view,
-			@AuthenticationPrincipal ReportPortalUser user, HttpServletResponse response) {
-
-		ReportFormat format = getJasperHandler.getReportFormat(view);
-		response.setContentType(format.getContentType());
-
-		response.setHeader(HttpHeaders.CONTENT_DISPOSITION,
-				String.format("attachment; filename=\"RP_LAUNCH_%s_Report.%s\"", format.name(), format.getValue())
-		);
-
-		try (OutputStream outputStream = response.getOutputStream()) {
-			getLaunchMessageHandler.exportLaunch(launchId, format, outputStream, user);
-		} catch (IOException e) {
-			throw new ReportPortalException(ErrorType.BAD_REQUEST_ERROR, "Unable to write data to the response.");
-		}
-	}
-
-	@Transactional
-	@DeleteMapping
-	@PreAuthorize(ALLOWED_TO_REPORT)
-	@ResponseStatus(OK)
-	@ApiOperation("Delete specified launches by ids")
-	public DeleteBulkRS deleteLaunches(@PathVariable String projectName, @RequestBody @Valid DeleteBulkRQ deleteBulkRQ,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return deleteLaunchMessageHandler.deleteLaunches(deleteBulkRQ, projectExtractor.extractProjectDetails(user, normalizeId(projectName)), user);
-	}
-
-  @ApiImplicitParams({
-      @ApiImplicitParam(
-          name = "launchName",
-          dataType = "string",
-          paramType = "query",
-          value = "Override Launch Name"
-      ),
-      @ApiImplicitParam(
-          name = "description",
-          dataType = "string",
-          paramType = "query",
-          value = "Override Launch Description"
-      ),
-      @ApiImplicitParam(
-          name = "attributeKey",
-          dataType = "string",
-          paramType = "query",
-          value = "Add Launch attribute key"
-      ),
-      @ApiImplicitParam(
-          name = "attributeValue",
-          dataType = "string",
-          paramType = "query",
-          value = "Add Launch attribute value"
-      ),
-      @ApiImplicitParam(
-          name = "skippedIsNotIssue",
-          dataType = "boolean",
-          paramType = "query",
-          value = "true: no defect type is applied to skipped issue"
-      )
-  })
-  @PostMapping(value = "/import", consumes = { MediaType.MULTIPART_FORM_DATA_VALUE })
+  private final ProjectExtractor projectExtractor;
+  private final StartLaunchHandler startLaunchHandler;
+  private final FinishLaunchHandler finishLaunchHandler;
+  private final StopLaunchHandler stopLaunchHandler;
+  private final DeleteLaunchHandler deleteLaunchMessageHandler;
+  private final GetLaunchHandler getLaunchMessageHandler;
+  private final UpdateLaunchHandler updateLaunchHandler;
+  private final MergeLaunchHandler mergeLaunchesHandler;
+  private final ImportLaunchHandler importLaunchHandler;
+  private final GetJasperReportHandler<Launch> getJasperHandler;
+
+  @Autowired
+  public LaunchController(ProjectExtractor projectExtractor, StartLaunchHandler startLaunchHandler,
+      FinishLaunchHandler finishLaunchHandler,
+      StopLaunchHandler stopLaunchHandler, DeleteLaunchHandler deleteLaunchMessageHandler,
+      GetLaunchHandler getLaunchMessageHandler,
+      UpdateLaunchHandler updateLaunchHandler, MergeLaunchHandler mergeLaunchesHandler,
+      ImportLaunchHandler importLaunchHandler,
+      @Qualifier("launchJasperReportHandler") GetJasperReportHandler<Launch> getJasperHandler) {
+    this.projectExtractor = projectExtractor;
+    this.startLaunchHandler = startLaunchHandler;
+    this.finishLaunchHandler = finishLaunchHandler;
+    this.stopLaunchHandler = stopLaunchHandler;
+    this.deleteLaunchMessageHandler = deleteLaunchMessageHandler;
+    this.getLaunchMessageHandler = getLaunchMessageHandler;
+    this.updateLaunchHandler = updateLaunchHandler;
+    this.mergeLaunchesHandler = mergeLaunchesHandler;
+    this.importLaunchHandler = importLaunchHandler;
+    this.getJasperHandler = getJasperHandler;
+  }
+
+  /* Report client API */
+
+  @PostMapping
+  @PreAuthorize(ALLOWED_TO_REPORT)
+  @ResponseStatus(CREATED)
+  @ApiOperation("Starts launch for specified project")
+  public StartLaunchRS startLaunch(@PathVariable String projectName,
+      @ApiParam(value = "Start launch request body", required = true) @RequestBody @Validated @Valid StartLaunchRQ startLaunchRQ,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return startLaunchHandler.startLaunch(user,
+        projectExtractor.extractProjectDetails(user, normalizeId(projectName)), startLaunchRQ);
+  }
+
+  @PutMapping(value = "/{launchId}/finish")
+  @PreAuthorize(ALLOWED_TO_REPORT)
+  @ResponseStatus(OK)
+  @ApiOperation("Finish launch for specified project")
+  public FinishLaunchRS finishLaunch(@PathVariable String projectName,
+      @PathVariable String launchId,
+      @RequestBody @Validated FinishExecutionRQ finishLaunchRQ,
+      @AuthenticationPrincipal ReportPortalUser user,
+      HttpServletRequest request) {
+    return finishLaunchHandler.finishLaunch(launchId,
+        finishLaunchRQ,
+        projectExtractor.extractProjectDetails(user, normalizeId(projectName)),
+        user,
+        composeBaseUrl(request)
+    );
+  }
+
+  /* Frontend API */
+
+  @Transactional
+  @PutMapping("/{launchId}/stop")
+  @PreAuthorize(ALLOWED_TO_REPORT)
+  @ResponseStatus(OK)
+  @ApiOperation("Force finish launch for specified project")
+  public OperationCompletionRS forceFinishLaunch(@PathVariable String projectName,
+      @PathVariable Long launchId,
+      @RequestBody @Validated FinishExecutionRQ finishExecutionRQ,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return stopLaunchHandler.stopLaunch(launchId, finishExecutionRQ,
+        projectExtractor.extractProjectDetails(user, normalizeId(projectName)), user);
+  }
+
+  @Transactional
+  @PutMapping("/stop")
+  @PreAuthorize(ALLOWED_TO_REPORT)
+  @ResponseStatus(OK)
+  @ApiOperation("Force finish launch")
+  public List<OperationCompletionRS> bulkForceFinish(@PathVariable String projectName,
+      @RequestBody @Validated BulkRQ<Long, FinishExecutionRQ> rq,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return stopLaunchHandler.stopLaunch(rq,
+        projectExtractor.extractProjectDetails(user, normalizeId(projectName)), user);
+  }
+
+  @Transactional
+  @PutMapping("/{launchId}/update")
+  @PreAuthorize(ALLOWED_TO_REPORT)
+  @ResponseStatus(OK)
+  @ApiOperation("Updates launch for specified project")
+  public OperationCompletionRS updateLaunch(@PathVariable String projectName,
+      @PathVariable Long launchId,
+      @RequestBody @Validated UpdateLaunchRQ updateLaunchRQ,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return updateLaunchHandler.updateLaunch(launchId,
+        projectExtractor.extractProjectDetails(user, normalizeId(projectName)), user,
+        updateLaunchRQ);
+  }
+
+  @Transactional
+  @PutMapping("/update")
+  @PreAuthorize(ALLOWED_TO_REPORT)
+  @ResponseStatus(OK)
+  @ApiOperation("Updates launches for specified project")
+  public List<OperationCompletionRS> updateLaunches(@PathVariable String projectName,
+      @RequestBody @Validated BulkRQ<Long, UpdateLaunchRQ> rq,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return updateLaunchHandler.updateLaunch(rq,
+        projectExtractor.extractProjectDetails(user, normalizeId(projectName)), user);
+  }
+
+  @Transactional
+  @DeleteMapping("/{launchId}")
+  @PreAuthorize(ALLOWED_TO_REPORT)
+  @ResponseStatus(OK)
+  @ApiOperation("Delete specified launch by ID")
+  public OperationCompletionRS deleteLaunch(@PathVariable String projectName,
+      @PathVariable Long launchId,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return deleteLaunchMessageHandler.deleteLaunch(launchId,
+        projectExtractor.extractProjectDetails(user, normalizeId(projectName)), user);
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping("/{launchId}")
+  @ResponseStatus(OK)
+  @ApiOperation("Get specified launch by ID")
+  public LaunchResource getLaunch(@PathVariable String projectName, @PathVariable String launchId,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return getLaunchMessageHandler.getLaunch(launchId,
+        projectExtractor.extractProjectDetails(user, normalizeId(projectName)));
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping("/uuid/{launchId}")
+  @ResponseStatus(OK)
+  @ApiOperation("Get specified launch by UUID")
+  public LaunchResource getLaunchByUuid(@PathVariable String projectName,
+      @PathVariable String launchId,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return getLaunchMessageHandler.getLaunch(launchId,
+        projectExtractor.extractProjectDetails(user, normalizeId(projectName)));
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping
+  @ResponseStatus(OK)
+  @ApiOperation("Get list of project launches by filter")
+  public Iterable<LaunchResource> getProjectLaunches(@PathVariable String projectName,
+      @FilterFor(Launch.class) Filter filter,
+      @SortFor(Launch.class) Pageable pageable, @AuthenticationPrincipal ReportPortalUser user) {
+    return getLaunchMessageHandler.getProjectLaunches(
+        projectExtractor.extractProjectDetails(user, normalizeId(projectName)),
+        filter,
+        pageable,
+        user.getUsername()
+    );
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping(value = "/latest")
+  @ResponseStatus(OK)
+  @ApiOperation("Get list of latest project launches by filter")
+  public Iterable<LaunchResource> getLatestLaunches(@PathVariable String projectName,
+      @FilterFor(Launch.class) Filter filter,
+      @SortFor(Launch.class) Pageable pageable, @AuthenticationPrincipal ReportPortalUser user) {
+    return getLaunchMessageHandler.getLatestLaunches(
+        projectExtractor.extractProjectDetails(user, normalizeId(projectName)), filter, pageable);
+  }
+
+  @GetMapping(value = "/mode")
+  @ResponseBody
+  @ResponseStatus(OK)
+  @ApiOperation("Get launches of specified project from DEBUG mode")
+  public Iterable<LaunchResource> getDebugLaunches(@PathVariable String projectName,
+      @FilterFor(Launch.class) Filter filter,
+      @SortFor(Launch.class) Pageable pageable, @AuthenticationPrincipal ReportPortalUser user) {
+    return getLaunchMessageHandler.getDebugLaunches(
+        projectExtractor.extractProjectDetails(user, normalizeId(projectName)), filter, pageable);
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping(value = "/attribute/keys")
+  @ResponseStatus(OK)
+  @ApiOperation("Get all unique attribute keys of project launches")
+  public List<String> getAttributeKeys(@PathVariable String projectName,
+      @RequestParam(value = "filter." + "cnt." + "attributeKey") String value,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return getLaunchMessageHandler.getAttributeKeys(
+        projectExtractor.extractProjectDetails(user, normalizeId(projectName)), value);
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping(value = "/attribute/values")
+  @ResponseStatus(OK)
+  @ApiOperation("Get all unique attribute values of project launches")
+  public List<String> getAttributeValues(@PathVariable String projectName,
+      @RequestParam(value = "filter." + "eq." + "attributeKey", required = false) String key,
+      @RequestParam(value = "filter." + "cnt." + "attributeValue") String value,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return getLaunchMessageHandler.getAttributeValues(
+        projectExtractor.extractProjectDetails(user, normalizeId(projectName)), key, value);
+  }
+
+  @GetMapping(value = "/cluster/{launchId}")
+  @ResponseStatus(OK)
+  @ApiOperation("Get all index clusters of the launch")
+  public Iterable<ClusterInfoResource> getClusters(@PathVariable String projectName,
+      @PathVariable String launchId, Pageable pageable,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return getLaunchMessageHandler.getClusters(launchId,
+        projectExtractor.extractProjectDetails(user, normalizeId(projectName)),
+        pageable
+    );
+  }
+
+  @Transactional
+  @PutMapping(value = "/info")
+  @PreAuthorize(PROJECT_MANAGER_OR_ADMIN)
+  @ResponseStatus(OK)
+  @ApiOperation("Bulk update attributes and description")
+  public OperationCompletionRS bulkUpdate(@PathVariable String projectName,
+      @RequestBody @Validated BulkInfoUpdateRQ bulkInfoUpdateRQ,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return updateLaunchHandler.bulkInfoUpdate(bulkInfoUpdateRQ,
+        projectExtractor.extractProjectDetails(user, projectName));
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping(value = "/owners")
+  @ResponseStatus(OK)
+  @ApiOperation("Get all unique owners of project launches")
+  public List<String> getAllOwners(@PathVariable String projectName,
+      @RequestParam(value = "filter." + "cnt." + "user") String value,
+      @RequestParam(value = "mode", required = false, defaultValue = "DEFAULT") String mode,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return getLaunchMessageHandler.getOwners(
+        projectExtractor.extractProjectDetails(user, normalizeId(projectName)), value, mode);
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping(value = "/names")
+  @ResponseStatus(OK)
+  @ApiOperation("Get launch names of project")
+  public List<String> getAllLaunchNames(@PathVariable String projectName,
+      @RequestParam(value = "filter." + "cnt."
+          + "name", required = false, defaultValue = "") String value,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return getLaunchMessageHandler.getLaunchNames(
+        projectExtractor.extractProjectDetails(user, normalizeId(projectName)), value);
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping(value = "/compare")
+  @ResponseStatus(OK)
+  @ApiOperation("Compare launches")
+  public Map<String, List<ChartStatisticsContent>> compareLaunches(@PathVariable String projectName,
+      @RequestParam(value = "ids") Long[] ids, @AuthenticationPrincipal ReportPortalUser user) {
+    return getLaunchMessageHandler.getLaunchesComparisonInfo(
+        projectExtractor.extractProjectDetails(user, normalizeId(projectName)), ids);
+  }
+
+  @Transactional
+  @PostMapping("/merge")
+  @PreAuthorize(ALLOWED_TO_REPORT)
+  @ResponseStatus(OK)
+  @ApiOperation("Merge set of specified launches in common one")
+  public LaunchResource mergeLaunches(@PathVariable String projectName,
+      @ApiParam(value = "Merge launches request body", required = true) @RequestBody @Validated MergeLaunchesRQ mergeLaunchesRQ,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return mergeLaunchesHandler.mergeLaunches(
+        projectExtractor.extractProjectDetails(user, normalizeId(projectName)), user,
+        mergeLaunchesRQ);
+  }
+
+  @Transactional
+  @PostMapping(value = "/analyze")
+  @ResponseStatus(OK)
+  @ApiOperation("Start launch auto-analyzer on demand")
+  public OperationCompletionRS startLaunchAnalyzer(@PathVariable String projectName,
+      @RequestBody @Validated AnalyzeLaunchRQ analyzeLaunchRQ,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return updateLaunchHandler.startLaunchAnalyzer(analyzeLaunchRQ,
+        projectExtractor.extractProjectDetails(user, normalizeId(projectName)), user);
+  }
+
+  @PostMapping(value = "/cluster")
+  @ResponseStatus(OK)
+  @ApiOperation("Create launch clusters")
+  public OperationCompletionRS createClusters(@PathVariable String projectName,
+      @RequestBody @Validated CreateClustersRQ createClustersRQ,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return updateLaunchHandler.createClusters(createClustersRQ,
+        projectExtractor.extractProjectDetails(user, normalizeId(projectName)), user);
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping(value = "/status")
+  @ResponseStatus(OK)
+
+  public Map<String, String> getStatuses(@PathVariable String projectName,
+      @RequestParam(value = "ids") Long[] ids,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return getLaunchMessageHandler.getStatuses(
+        projectExtractor.extractProjectDetails(user, normalizeId(projectName)), ids);
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping(value = "/{launchId}/report")
+  @ResponseStatus(OK)
+  @PreAuthorize(ASSIGNED_TO_PROJECT)
+  @ApiOperation(value = "Export specified launch", notes = "Only following formats are supported: pdf (by default), xls, html.")
+  public void getLaunchReport(@PathVariable String projectName, @PathVariable Long launchId,
+      @ApiParam(allowableValues = "pdf, xls, html") @RequestParam(value = "view", required = false, defaultValue = "pdf") String view,
+      @AuthenticationPrincipal ReportPortalUser user, HttpServletResponse response) {
+
+    ReportFormat format = getJasperHandler.getReportFormat(view);
+    response.setContentType(format.getContentType());
+
+    response.setHeader(HttpHeaders.CONTENT_DISPOSITION,
+        String.format("attachment; filename=\"RP_LAUNCH_%s_Report.%s\"", format.name(),
+            format.getValue())
+    );
+
+    try (OutputStream outputStream = response.getOutputStream()) {
+      getLaunchMessageHandler.exportLaunch(launchId, format, outputStream, user);
+    } catch (IOException e) {
+      throw new ReportPortalException(ErrorType.BAD_REQUEST_ERROR,
+          "Unable to write data to the response.");
+    }
+  }
+
+  @Transactional
+  @DeleteMapping
+  @PreAuthorize(ALLOWED_TO_REPORT)
+  @ResponseStatus(OK)
+  @ApiOperation("Delete specified launches by ids")
+  public DeleteBulkRS deleteLaunches(@PathVariable String projectName,
+      @RequestBody @Valid DeleteBulkRQ deleteBulkRQ,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return deleteLaunchMessageHandler.deleteLaunches(deleteBulkRQ,
+        projectExtractor.extractProjectDetails(user, normalizeId(projectName)), user);
+  }
+
+  @ApiImplicitParams(
+      @ApiImplicitParam(name = "launchImportRq", dataType = "LaunchImportRQ", paramType = "body")
+  )
+  @PostMapping(value = "/import", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
   @ResponseStatus(OK)
   @ApiOperation(value = "Import junit xml report", notes = "Only following formats are supported: zip and xml.")
-  public OperationCompletionRS importLaunch(@PathVariable String projectName, @RequestParam("file") MultipartFile file,
+  public OperationCompletionRS importLaunch(@PathVariable String projectName,
+      @RequestParam("file") MultipartFile file,
       @AuthenticationPrincipal ReportPortalUser user, HttpServletRequest request,
-      @ApiParam(required = false) @RequestParam Map<String, String> params) {
-    return importLaunchHandler.importLaunch(projectExtractor.extractProjectDetails(user, normalizeId(projectName)),
+      @RequestPart(required = false) @Valid LaunchImportRQ launchImportRq) {
+    return importLaunchHandler.importLaunch(
+        projectExtractor.extractProjectDetails(user, normalizeId(projectName)),
         user,
         "XUNIT",
         file,
         composeBaseUrl(request),
-        params
+        launchImportRq
     );
   }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/LogAsyncController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/LogAsyncController.java
index a63bdd1cf7..980ac468fa 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/controller/LogAsyncController.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/controller/LogAsyncController.java
@@ -16,6 +16,13 @@
 
 package com.epam.ta.reportportal.ws.controller;
 
+import static com.epam.ta.reportportal.auth.permissions.Permissions.ALLOWED_TO_REPORT;
+import static com.epam.ta.reportportal.auth.permissions.Permissions.ASSIGNED_TO_PROJECT;
+import static com.epam.ta.reportportal.util.ControllerUtils.findByFileName;
+import static com.epam.ta.reportportal.util.ControllerUtils.getUploadedFiles;
+import static com.epam.ta.reportportal.util.ControllerUtils.validateSaveRQ;
+import static org.springframework.http.HttpStatus.CREATED;
+
 import com.epam.ta.reportportal.commons.Predicates;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
@@ -23,9 +30,16 @@
 import com.epam.ta.reportportal.core.log.CreateLogHandler;
 import com.epam.ta.reportportal.core.logging.HttpLogging;
 import com.epam.ta.reportportal.util.ProjectExtractor;
-import com.epam.ta.reportportal.ws.model.*;
+import com.epam.ta.reportportal.ws.model.BatchElementCreatedRS;
+import com.epam.ta.reportportal.ws.model.BatchSaveOperatingRS;
+import com.epam.ta.reportportal.ws.model.Constants;
+import com.epam.ta.reportportal.ws.model.EntryCreatedAsyncRS;
+import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.epam.ta.reportportal.ws.model.log.SaveLogRQ;
 import io.swagger.annotations.ApiOperation;
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.Validator;
+import org.apache.commons.collections4.MultiValuedMap;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -34,19 +48,16 @@
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.security.core.annotation.AuthenticationPrincipal;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestPart;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.multipart.MultipartFile;
 import springfox.documentation.annotations.ApiIgnore;
 
-import javax.servlet.http.HttpServletRequest;
-import javax.validation.Validator;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.auth.permissions.Permissions.ALLOWED_TO_REPORT;
-import static com.epam.ta.reportportal.auth.permissions.Permissions.ASSIGNED_TO_PROJECT;
-import static com.epam.ta.reportportal.util.ControllerUtils.*;
-import static org.springframework.http.HttpStatus.CREATED;
-
 /**
  * @author Konstantin Antipin
  */
@@ -55,94 +66,104 @@
 @PreAuthorize(ASSIGNED_TO_PROJECT)
 public class LogAsyncController {
 
-	private final ProjectExtractor projectExtractor;
-	private final CreateLogHandler createLogHandler;
-	private final Validator validator;
+  private final ProjectExtractor projectExtractor;
+  private final CreateLogHandler createLogHandler;
+  private final Validator validator;
 
-	@Autowired
-	public LogAsyncController(ProjectExtractor projectExtractor, @Qualifier("asyncCreateLogHandler") CreateLogHandler createLogHandler, Validator validator) {
-		this.projectExtractor = projectExtractor;
-		this.createLogHandler = createLogHandler;
-		this.validator = validator;
-	}
+  @Autowired
+  public LogAsyncController(ProjectExtractor projectExtractor,
+      @Qualifier("asyncCreateLogHandler") CreateLogHandler createLogHandler, Validator validator) {
+    this.projectExtractor = projectExtractor;
+    this.createLogHandler = createLogHandler;
+    this.validator = validator;
+  }
 
-	/**
-	 * @deprecated in favour of {@link LogAsyncController#createLogEntry(String, SaveLogRQ, ReportPortalUser)} because of mapping collisions
-	 */
-	/* Report client API */
-	@Deprecated
-	@HttpLogging
-	@PostMapping(consumes = { MediaType.APPLICATION_JSON_VALUE })
-	@ResponseStatus(CREATED)
-	@ApiIgnore
-	@PreAuthorize(ALLOWED_TO_REPORT)
-	public EntryCreatedAsyncRS createLog(@PathVariable String projectName, @RequestBody SaveLogRQ createLogRQ,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		validateSaveRQ(validator, createLogRQ);
-		return createLogHandler.createLog(createLogRQ, null, projectExtractor.extractProjectDetails(user, projectName));
-	}
+  /**
+   * @deprecated in favour of
+   * {@link LogAsyncController#createLogEntry(String, SaveLogRQ, ReportPortalUser)} because of
+   * mapping collisions
+   */
+  /* Report client API */
+  @Deprecated
+  @HttpLogging
+  @PostMapping(consumes = {MediaType.APPLICATION_JSON_VALUE})
+  @ResponseStatus(CREATED)
+  @ApiIgnore
+  @PreAuthorize(ALLOWED_TO_REPORT)
+  public EntryCreatedAsyncRS createLog(@PathVariable String projectName,
+      @RequestBody SaveLogRQ createLogRQ,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    validateSaveRQ(validator, createLogRQ);
+    return createLogHandler.createLog(createLogRQ, null,
+        projectExtractor.extractProjectDetails(user, projectName));
+  }
 
-	@HttpLogging
-	@PostMapping(value = "/entry", consumes = { MediaType.APPLICATION_JSON_VALUE })
-	@ResponseStatus(CREATED)
-	@ApiOperation("Create log")
-	@PreAuthorize(ALLOWED_TO_REPORT)
-	public EntryCreatedAsyncRS createLogEntry(@PathVariable String projectName, @RequestBody SaveLogRQ createLogRQ,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		validateSaveRQ(validator, createLogRQ);
-		return createLogHandler.createLog(createLogRQ, null, projectExtractor.extractProjectDetails(user, projectName));
-	}
+  @HttpLogging
+  @PostMapping(value = "/entry", consumes = {MediaType.APPLICATION_JSON_VALUE})
+  @ResponseStatus(CREATED)
+  @ApiOperation("Create log")
+  @PreAuthorize(ALLOWED_TO_REPORT)
+  public EntryCreatedAsyncRS createLogEntry(@PathVariable String projectName,
+      @RequestBody SaveLogRQ createLogRQ,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    validateSaveRQ(validator, createLogRQ);
+    return createLogHandler.createLog(createLogRQ, null,
+        projectExtractor.extractProjectDetails(user, projectName));
+  }
 
-	@HttpLogging
-	@PostMapping(consumes = { MediaType.MULTIPART_FORM_DATA_VALUE })
-	@ApiOperation("Create log (batching operation)")
-	// Specific handler should be added for springfox in case of similar POST
-	// request mappings
-	//	@Async
-	@PreAuthorize(ALLOWED_TO_REPORT)
-	public ResponseEntity<BatchSaveOperatingRS> createLog(@PathVariable String projectName,
-			@RequestPart(value = Constants.LOG_REQUEST_JSON_PART) SaveLogRQ[] createLogRQs, HttpServletRequest request,
-			@AuthenticationPrincipal ReportPortalUser user) {
+  @HttpLogging
+  @PostMapping(consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
+  @ApiOperation("Create log (batching operation)")
+  // Specific handler should be added for springfox in case of similar POST
+  // request mappings
+  //	@Async
+  @PreAuthorize(ALLOWED_TO_REPORT)
+  public ResponseEntity<BatchSaveOperatingRS> createLog(@PathVariable String projectName,
+      @RequestPart(value = Constants.LOG_REQUEST_JSON_PART) SaveLogRQ[] createLogRQs,
+      HttpServletRequest request,
+      @AuthenticationPrincipal ReportPortalUser user) {
 
-		/*
-		 * Since this is multipart request we can retrieve list of uploaded
-		 * attachments
-		 */
-		Map<String, MultipartFile> uploadedFiles = getUploadedFiles(request);
-		BatchSaveOperatingRS response = new BatchSaveOperatingRS();
-		EntryCreatedAsyncRS responseItem;
-		/* Go through all provided save log request items */
-		for (SaveLogRQ createLogRq : createLogRQs) {
-			try {
-				validateSaveRQ(validator, createLogRq);
-				String filename = createLogRq.getFile() == null ? null : createLogRq.getFile().getName();
-				if (StringUtils.isEmpty(filename)) {
-					/*
-					 * There is no filename in request. Use simple save
-					 * method
-					 */
-					responseItem = createLog(projectName, createLogRq, user);
+    /*
+     * Since this is multipart request we can retrieve list of uploaded
+     * attachments
+     */
+    MultiValuedMap<String, MultipartFile> uploadedFiles = getUploadedFiles(request);
+    BatchSaveOperatingRS response = new BatchSaveOperatingRS();
+    EntryCreatedAsyncRS responseItem;
+    /* Go through all provided save log request items */
+    for (SaveLogRQ createLogRq : createLogRQs) {
+      try {
+        validateSaveRQ(validator, createLogRq);
+        String filename = createLogRq.getFile() == null ? null : createLogRq.getFile().getName();
+        if (StringUtils.isEmpty(filename)) {
+          /*
+           * There is no filename in request. Use simple save
+           * method
+           */
+          responseItem = createLog(projectName, createLogRq, user);
 
-				} else {
-					/* Find by request part */
-					MultipartFile data = findByFileName(filename, uploadedFiles);
-					BusinessRule.expect(data, Predicates.notNull()).verify(
-							ErrorType.BINARY_DATA_CANNOT_BE_SAVED,
-							Suppliers.formattedSupplier("There is no request part or file with name {}", filename)
-					);
-					/*
-					 * If provided content type is null or this is octet
-					 * stream, try to detect real content type of binary
-					 * data
-					 */
-					//noinspection ConstantConditions
-					responseItem = createLogHandler.createLog(createLogRq, data, projectExtractor.extractProjectDetails(user, projectName));
-				}
-				response.addResponse(new BatchElementCreatedRS(responseItem.getId()));
-			} catch (Exception e) {
-				response.addResponse(new BatchElementCreatedRS(ExceptionUtils.getStackTrace(e), ExceptionUtils.getMessage(e)));
-			}
-		}
-		return new ResponseEntity<>(response, CREATED);
-	}
+        } else {
+          /* Find by request part */
+          MultipartFile data = findByFileName(filename, uploadedFiles);
+          BusinessRule.expect(data, Predicates.notNull()).verify(
+              ErrorType.BINARY_DATA_CANNOT_BE_SAVED,
+              Suppliers.formattedSupplier("There is no request part or file with name {}", filename)
+          );
+          /*
+           * If provided content type is null or this is octet
+           * stream, try to detect real content type of binary
+           * data
+           */
+          //noinspection ConstantConditions
+          responseItem = createLogHandler.createLog(createLogRq, data,
+              projectExtractor.extractProjectDetails(user, projectName));
+        }
+        response.addResponse(new BatchElementCreatedRS(responseItem.getId()));
+      } catch (Exception e) {
+        response.addResponse(new BatchElementCreatedRS(ExceptionUtils.getStackTrace(e),
+            ExceptionUtils.getMessage(e)));
+      }
+    }
+    return new ResponseEntity<>(response, CREATED);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/LogController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/LogController.java
index 425c3aaa71..c55898dc0d 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/controller/LogController.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/controller/LogController.java
@@ -16,6 +16,17 @@
 
 package com.epam.ta.reportportal.ws.controller;
 
+import static com.epam.ta.reportportal.auth.permissions.Permissions.ALLOWED_TO_REPORT;
+import static com.epam.ta.reportportal.auth.permissions.Permissions.ASSIGNED_TO_PROJECT;
+import static com.epam.ta.reportportal.commons.querygen.Condition.UNDR;
+import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_PATH;
+import static com.epam.ta.reportportal.util.ControllerUtils.findByFileName;
+import static com.epam.ta.reportportal.util.ControllerUtils.getUploadedFiles;
+import static com.epam.ta.reportportal.util.ControllerUtils.validateSaveRQ;
+import static com.epam.ta.reportportal.ws.resolver.FilterCriteriaResolver.DEFAULT_FILTER_PREFIX;
+import static org.springframework.http.HttpStatus.CREATED;
+import static org.springframework.http.HttpStatus.OK;
+
 import com.epam.ta.reportportal.commons.Predicates;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.querygen.Filter;
@@ -28,13 +39,28 @@
 import com.epam.ta.reportportal.core.log.impl.PagedLogResource;
 import com.epam.ta.reportportal.entity.log.Log;
 import com.epam.ta.reportportal.util.ProjectExtractor;
-import com.epam.ta.reportportal.ws.model.*;
-import com.epam.ta.reportportal.ws.model.log.*;
+import com.epam.ta.reportportal.ws.model.BatchElementCreatedRS;
+import com.epam.ta.reportportal.ws.model.BatchSaveOperatingRS;
+import com.epam.ta.reportportal.ws.model.Constants;
+import com.epam.ta.reportportal.ws.model.EntryCreatedAsyncRS;
+import com.epam.ta.reportportal.ws.model.ErrorType;
+import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
+import com.epam.ta.reportportal.ws.model.log.GetLogsUnderRq;
+import com.epam.ta.reportportal.ws.model.log.LogResource;
+import com.epam.ta.reportportal.ws.model.log.SaveLogRQ;
+import com.epam.ta.reportportal.ws.model.log.SearchLogRq;
+import com.epam.ta.reportportal.ws.model.log.SearchLogRs;
 import com.epam.ta.reportportal.ws.resolver.FilterFor;
 import com.epam.ta.reportportal.ws.resolver.SortFor;
 import com.google.common.collect.ImmutableMap;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.Validator;
+import org.apache.commons.collections4.MultiValuedMap;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -45,25 +71,19 @@
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.security.core.annotation.AuthenticationPrincipal;
 import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RequestPart;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.multipart.MultipartFile;
 import springfox.documentation.annotations.ApiIgnore;
 
-import javax.servlet.http.HttpServletRequest;
-import javax.validation.Validator;
-import java.io.Serializable;
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.auth.permissions.Permissions.ALLOWED_TO_REPORT;
-import static com.epam.ta.reportportal.auth.permissions.Permissions.ASSIGNED_TO_PROJECT;
-import static com.epam.ta.reportportal.commons.querygen.Condition.UNDR;
-import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_PATH;
-import static com.epam.ta.reportportal.util.ControllerUtils.*;
-import static com.epam.ta.reportportal.ws.resolver.FilterCriteriaResolver.DEFAULT_FILTER_PREFIX;
-import static org.springframework.http.HttpStatus.CREATED;
-import static org.springframework.http.HttpStatus.OK;
-
 /**
  * @author Pavel Bortnik
  */
@@ -72,179 +92,214 @@
 @PreAuthorize(ASSIGNED_TO_PROJECT)
 public class LogController {
 
-	private final ProjectExtractor projectExtractor;
-	private final CreateLogHandler createLogHandler;
-	private final DeleteLogHandler deleteLogHandler;
-	private final GetLogHandler getLogHandler;
-	private final SearchLogService searchLogService;
-	private final Validator validator;
-
-	@Autowired
-	public LogController(ProjectExtractor projectExtractor, @Autowired CreateLogHandler createLogHandler, DeleteLogHandler deleteLogHandler, GetLogHandler getLogHandler,
-			SearchLogService searchLogService, Validator validator) {
-		this.projectExtractor = projectExtractor;
-		this.createLogHandler = createLogHandler;
-		this.deleteLogHandler = deleteLogHandler;
-		this.getLogHandler = getLogHandler;
-		this.searchLogService = searchLogService;
-		this.validator = validator;
-	}
-
-	/**
-	 * @deprecated in favour of {@link LogController#createLogEntry(String, SaveLogRQ, ReportPortalUser)} because of mapping collisions
-	 */
-	/* Report client API */
-	@Deprecated
-	@PostMapping(consumes = { MediaType.APPLICATION_JSON_VALUE })
-	@ResponseStatus(CREATED)
-	@ApiIgnore
-	@PreAuthorize(ALLOWED_TO_REPORT)
-	public EntryCreatedAsyncRS createLog(@PathVariable String projectName, @RequestBody SaveLogRQ createLogRQ,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		validateSaveRQ(validator, createLogRQ);
-		return createLogHandler.createLog(createLogRQ, null, projectExtractor.extractProjectDetails(user, projectName));
-	}
-
-	/* Report client API */
-	@PostMapping(value = "/entry", consumes = { MediaType.APPLICATION_JSON_VALUE })
-	@ResponseStatus(CREATED)
-	@ApiOperation("Create log")
-	@PreAuthorize(ALLOWED_TO_REPORT)
-	public EntryCreatedAsyncRS createLogEntry(@PathVariable String projectName, @RequestBody SaveLogRQ createLogRQ,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		validateSaveRQ(validator, createLogRQ);
-		return createLogHandler.createLog(createLogRQ, null, projectExtractor.extractProjectDetails(user, projectName));
-	}
-
-	@PostMapping(consumes = { MediaType.MULTIPART_FORM_DATA_VALUE })
-	@ApiOperation("Create log (batching operation)")
-	// Specific handler should be added for springfox in case of similar POST
-	// request mappings
-	//	@Async
-	@PreAuthorize(ALLOWED_TO_REPORT)
-	public ResponseEntity<BatchSaveOperatingRS> createLog(@PathVariable String projectName,
-			@RequestPart(value = Constants.LOG_REQUEST_JSON_PART) SaveLogRQ[] createLogRQs, HttpServletRequest request,
-			@AuthenticationPrincipal ReportPortalUser user) {
-
-		/*
-		 * Since this is multipart request we can retrieve list of uploaded
-		 * attachments
-		 */
-		Map<String, MultipartFile> uploadedFiles = getUploadedFiles(request);
-		BatchSaveOperatingRS response = new BatchSaveOperatingRS();
-		EntryCreatedAsyncRS responseItem;
-		/* Go through all provided save log request items */
-		for (SaveLogRQ createLogRq : createLogRQs) {
-			try {
-				validateSaveRQ(validator, createLogRq);
-				String filename = createLogRq.getFile() == null ? null : createLogRq.getFile().getName();
-				if (StringUtils.isEmpty(filename)) {
-					/*
-					 * There is no filename in request. Use simple save
-					 * method
-					 */
-					responseItem = createLog(projectName, createLogRq, user);
-
-				} else {
-					/* Find by request part */
-					MultipartFile data = findByFileName(filename, uploadedFiles);
-					BusinessRule.expect(data, Predicates.notNull()).verify(ErrorType.BINARY_DATA_CANNOT_BE_SAVED,
-							Suppliers.formattedSupplier("There is no request part or file with name {}", filename)
-					);
-					/*
-					 * If provided content type is null or this is octet
-					 * stream, try to detect real content type of binary
-					 * data
-					 */
-					//noinspection ConstantConditions
-					responseItem = createLogHandler.createLog(createLogRq, data, projectExtractor.extractProjectDetails(user, projectName));
-				}
-				response.addResponse(new BatchElementCreatedRS(responseItem.getId()));
-			} catch (Exception e) {
-				response.addResponse(new BatchElementCreatedRS(ExceptionUtils.getStackTrace(e), ExceptionUtils.getMessage(e)));
-			}
-		}
-		return new ResponseEntity<>(response, CREATED);
-	}
-
-
-	/* Frontend API */
-
-	@RequestMapping(value = "/{logId}", method = RequestMethod.DELETE)
-	@ApiOperation("Delete log")
-	@Transactional
-	public OperationCompletionRS deleteLog(@PathVariable String projectName, @PathVariable Long logId,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return deleteLogHandler.deleteLog(logId, projectExtractor.extractProjectDetails(user, projectName), user);
-	}
-
-	@RequestMapping(method = RequestMethod.GET)
-	@ApiOperation("Get logs by filter")
-	@Transactional(readOnly = true)
-	public Iterable<LogResource> getLogs(@PathVariable String projectName,
-			@RequestParam(value = DEFAULT_FILTER_PREFIX + UNDR + CRITERIA_PATH, required = false) String underPath,
-			@FilterFor(Log.class) Filter filter,
-			@SortDefault({ "logTime" }) @SortFor(Log.class) Pageable pageable, @AuthenticationPrincipal ReportPortalUser user) {
-		return getLogHandler.getLogs(underPath, projectExtractor.extractProjectDetails(user, projectName), filter, pageable);
-	}
-
-	@PostMapping(value = "/under")
-	@ApiOperation("Get logs under items")
-	@Transactional(readOnly = true)
-	public Map<Long, List<LogResource>> getLogsUnder(@PathVariable String projectName,
-			@RequestBody GetLogsUnderRq logsUnderRq, @AuthenticationPrincipal ReportPortalUser user) {
-		return getLogHandler.getLogs(logsUnderRq, projectExtractor.extractProjectDetails(user, projectName));
-	}
-
-	@GetMapping(value = "/{logId}/page")
-	@ApiOperation("Get logs by filter")
-	@Transactional(readOnly = true)
-	public Map<String, Serializable> getPageNumber(@PathVariable String projectName, @PathVariable Long logId,
-			@FilterFor(Log.class) Filter filter, @SortFor(Log.class) Pageable pageable, @AuthenticationPrincipal ReportPortalUser user) {
-		return ImmutableMap.<String, Serializable>builder().put("number",
-				getLogHandler.getPageNumber(logId, projectExtractor.extractProjectDetails(user, projectName), filter, pageable)
-		).build();
-	}
-
-	@GetMapping(value = "/{logId}")
-	@ApiOperation("Get log by ID")
-	@Transactional(readOnly = true)
-	public LogResource getLog(@PathVariable String projectName, @PathVariable String logId,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return getLogHandler.getLog(logId, projectExtractor.extractProjectDetails(user, projectName), user);
-	}
-
-	@GetMapping(value = "/uuid/{logId}")
-	@ApiOperation("Get log by UUID")
-	@Transactional(readOnly = true)
-	public LogResource getLogByUuid(@PathVariable String projectName, @PathVariable String logId,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return getLogHandler.getLog(logId, projectExtractor.extractProjectDetails(user, projectName), user);
-	}
-
-	@GetMapping(value = "/nested/{parentId}")
-	@ApiOperation("Get nested steps with logs for the parent Test Item")
-	@Transactional(readOnly = true)
-	public Iterable<?> getNestedItems(@PathVariable String projectName, @PathVariable Long parentId,
-			@ApiParam(required = false) @RequestParam Map<String, String> params, @FilterFor(Log.class) Filter filter,
-			@SortFor(Log.class) Pageable pageable, @AuthenticationPrincipal ReportPortalUser user) {
-		return getLogHandler.getNestedItems(parentId, projectExtractor.extractProjectDetails(user, projectName), params, filter, pageable);
-	}
-
-	@GetMapping(value = "/locations/{parentId}")
-	@ApiOperation("Get next or previous log in test item")
-	@Transactional(readOnly = true)
-	public List<PagedLogResource> getErrorPage(@PathVariable String projectName, @PathVariable Long parentId, @RequestParam Map<String, String> params,
-			@FilterFor(Log.class) Filter filter, @SortFor(Log.class) Pageable pageable, @AuthenticationPrincipal ReportPortalUser user) {
-		return getLogHandler.getLogsWithLocation(parentId, projectExtractor.extractProjectDetails(user, projectName), params, filter, pageable);
-	}
-
-	@PostMapping("search/{itemId}")
-	@ResponseStatus(OK)
-	@ApiOperation("Search test items with similar error logs")
-	public Iterable<SearchLogRs> searchLogs(@PathVariable String projectName, @RequestBody SearchLogRq request, @PathVariable Long itemId,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return searchLogService.search(itemId, request, projectExtractor.extractProjectDetails(user, projectName));
-	}
+  private final ProjectExtractor projectExtractor;
+  private final CreateLogHandler createLogHandler;
+  private final DeleteLogHandler deleteLogHandler;
+  private final GetLogHandler getLogHandler;
+  private final SearchLogService searchLogService;
+  private final Validator validator;
+
+  @Autowired
+  public LogController(ProjectExtractor projectExtractor,
+      @Autowired CreateLogHandler createLogHandler, DeleteLogHandler deleteLogHandler,
+      GetLogHandler getLogHandler,
+      SearchLogService searchLogService, Validator validator) {
+    this.projectExtractor = projectExtractor;
+    this.createLogHandler = createLogHandler;
+    this.deleteLogHandler = deleteLogHandler;
+    this.getLogHandler = getLogHandler;
+    this.searchLogService = searchLogService;
+    this.validator = validator;
+  }
+
+  /**
+   * @deprecated in favour of
+   * {@link LogController#createLogEntry(String, SaveLogRQ, ReportPortalUser)} because of mapping
+   * collisions
+   */
+  /* Report client API */
+  @Deprecated
+  @PostMapping(consumes = {MediaType.APPLICATION_JSON_VALUE})
+  @ResponseStatus(CREATED)
+  @ApiIgnore
+  @PreAuthorize(ALLOWED_TO_REPORT)
+  public EntryCreatedAsyncRS createLog(@PathVariable String projectName,
+      @RequestBody SaveLogRQ createLogRQ,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    validateSaveRQ(validator, createLogRQ);
+    return createLogHandler.createLog(createLogRQ, null,
+        projectExtractor.extractProjectDetails(user, projectName));
+  }
+
+  /* Report client API */
+  @PostMapping(value = "/entry", consumes = {MediaType.APPLICATION_JSON_VALUE})
+  @ResponseStatus(CREATED)
+  @ApiOperation("Create log")
+  @PreAuthorize(ALLOWED_TO_REPORT)
+  public EntryCreatedAsyncRS createLogEntry(@PathVariable String projectName,
+      @RequestBody SaveLogRQ createLogRQ,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    validateSaveRQ(validator, createLogRQ);
+    return createLogHandler.createLog(createLogRQ, null,
+        projectExtractor.extractProjectDetails(user, projectName));
+  }
+
+  @PostMapping(consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
+  @ApiOperation("Create log (batching operation)")
+  // Specific handler should be added for springfox in case of similar POST
+  // request mappings
+  //	@Async
+  @PreAuthorize(ALLOWED_TO_REPORT)
+  public ResponseEntity<BatchSaveOperatingRS> createLog(@PathVariable String projectName,
+      @RequestPart(value = Constants.LOG_REQUEST_JSON_PART) SaveLogRQ[] createLogRQs,
+      HttpServletRequest request,
+      @AuthenticationPrincipal ReportPortalUser user) {
+
+    /*
+     * Since this is multipart request we can retrieve list of uploaded
+     * attachments
+     */
+    MultiValuedMap<String, MultipartFile> uploadedFiles = getUploadedFiles(request);
+    BatchSaveOperatingRS response = new BatchSaveOperatingRS();
+    EntryCreatedAsyncRS responseItem;
+    /* Go through all provided save log request items */
+    for (SaveLogRQ createLogRq : createLogRQs) {
+      try {
+        validateSaveRQ(validator, createLogRq);
+        String filename = createLogRq.getFile() == null ? null : createLogRq.getFile().getName();
+        if (StringUtils.isEmpty(filename)) {
+          /*
+           * There is no filename in request. Use simple save
+           * method
+           */
+          responseItem = createLog(projectName, createLogRq, user);
+
+        } else {
+          /* Find by request part */
+          MultipartFile data = findByFileName(filename, uploadedFiles);
+          BusinessRule.expect(data, Predicates.notNull())
+              .verify(ErrorType.BINARY_DATA_CANNOT_BE_SAVED,
+                  Suppliers.formattedSupplier("There is no request part or file with name {}",
+                      filename)
+              );
+          /*
+           * If provided content type is null or this is octet
+           * stream, try to detect real content type of binary
+           * data
+           */
+          //noinspection ConstantConditions
+          responseItem = createLogHandler.createLog(createLogRq, data,
+              projectExtractor.extractProjectDetails(user, projectName));
+        }
+        response.addResponse(new BatchElementCreatedRS(responseItem.getId()));
+      } catch (Exception e) {
+        response.addResponse(new BatchElementCreatedRS(ExceptionUtils.getStackTrace(e),
+            ExceptionUtils.getMessage(e)));
+      }
+    }
+    return new ResponseEntity<>(response, CREATED);
+  }
+
+
+  /* Frontend API */
+
+  @RequestMapping(value = "/{logId}", method = RequestMethod.DELETE)
+  @ApiOperation("Delete log")
+  @Transactional
+  public OperationCompletionRS deleteLog(@PathVariable String projectName, @PathVariable Long logId,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return deleteLogHandler.deleteLog(logId,
+        projectExtractor.extractProjectDetails(user, projectName), user);
+  }
+
+  @RequestMapping(method = RequestMethod.GET)
+  @ApiOperation("Get logs by filter")
+  @Transactional(readOnly = true)
+  public Iterable<LogResource> getLogs(@PathVariable String projectName,
+      @RequestParam(value = DEFAULT_FILTER_PREFIX + UNDR
+          + CRITERIA_PATH, required = false) String underPath,
+      @FilterFor(Log.class) Filter filter,
+      @SortDefault({"logTime"}) @SortFor(Log.class) Pageable pageable,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return getLogHandler.getLogs(underPath,
+        projectExtractor.extractProjectDetails(user, projectName), filter, pageable);
+  }
+
+  @PostMapping(value = "/under")
+  @ApiOperation("Get logs under items")
+  @Transactional(readOnly = true)
+  public Map<Long, List<LogResource>> getLogsUnder(@PathVariable String projectName,
+      @RequestBody GetLogsUnderRq logsUnderRq, @AuthenticationPrincipal ReportPortalUser user) {
+    return getLogHandler.getLogs(logsUnderRq,
+        projectExtractor.extractProjectDetails(user, projectName));
+  }
+
+  @GetMapping(value = "/{logId}/page")
+  @ApiOperation("Get logs by filter")
+  @Transactional(readOnly = true)
+  public Map<String, Serializable> getPageNumber(@PathVariable String projectName,
+      @PathVariable Long logId,
+      @FilterFor(Log.class) Filter filter, @SortFor(Log.class) Pageable pageable,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return ImmutableMap.<String, Serializable>builder().put("number",
+        getLogHandler.getPageNumber(logId,
+            projectExtractor.extractProjectDetails(user, projectName), filter, pageable)
+    ).build();
+  }
+
+  @GetMapping(value = "/{logId}")
+  @ApiOperation("Get log by ID")
+  @Transactional(readOnly = true)
+  public LogResource getLog(@PathVariable String projectName, @PathVariable String logId,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return getLogHandler.getLog(logId, projectExtractor.extractProjectDetails(user, projectName),
+        user);
+  }
+
+  /**
+   * @deprecated Need to remove in version 6.0. This API significantly impacts database performance
+   * - high IO operations on getting log record by UUID from production-like database amount.
+   */
+  @Deprecated(since = "5.8", forRemoval = true)
+  @GetMapping(value = "/uuid/{logId}")
+  @ApiOperation("Get log by UUID (Will be removed in version 6.0)")
+  @Transactional(readOnly = true)
+  public LogResource getLogByUuid(@PathVariable String projectName, @PathVariable String logId,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return getLogHandler.getLog(logId, projectExtractor.extractProjectDetails(user, projectName),
+        user);
+  }
+
+  @GetMapping(value = "/nested/{parentId}")
+  @ApiOperation("Get nested steps with logs for the parent Test Item")
+  @Transactional(readOnly = true)
+  public Iterable<?> getNestedItems(@PathVariable String projectName, @PathVariable Long parentId,
+      @ApiParam(required = false) @RequestParam Map<String, String> params,
+      @FilterFor(Log.class) Filter filter,
+      @SortFor(Log.class) Pageable pageable, @AuthenticationPrincipal ReportPortalUser user) {
+    return getLogHandler.getNestedItems(parentId,
+        projectExtractor.extractProjectDetails(user, projectName), params, filter, pageable);
+  }
+
+  @GetMapping(value = "/locations/{parentId}")
+  @ApiOperation("Get next or previous log in test item")
+  @Transactional(readOnly = true)
+  public List<PagedLogResource> getErrorPage(@PathVariable String projectName,
+      @PathVariable Long parentId, @RequestParam Map<String, String> params,
+      @FilterFor(Log.class) Filter filter, @SortFor(Log.class) Pageable pageable,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return getLogHandler.getLogsWithLocation(parentId,
+        projectExtractor.extractProjectDetails(user, projectName), params, filter, pageable);
+  }
+
+  @PostMapping("search/{itemId}")
+  @ResponseStatus(OK)
+  @ApiOperation("Search test items with similar error logs")
+  public Iterable<SearchLogRs> searchLogs(@PathVariable String projectName,
+      @RequestBody SearchLogRq request, @PathVariable Long itemId,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return searchLogService.search(itemId, request,
+        projectExtractor.extractProjectDetails(user, projectName));
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/OnboardingController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/OnboardingController.java
index e30680e4a1..92aebdda3a 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/controller/OnboardingController.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/controller/OnboardingController.java
@@ -29,15 +29,16 @@
 @RequestMapping("/v1/onboarding")
 public class OnboardingController {
 
-    private final OnboardingService onboardingService;
+  private final OnboardingService onboardingService;
 
-    public OnboardingController(OnboardingService onboardingService) {
-        this.onboardingService = onboardingService;
-    }
+  public OnboardingController(OnboardingService onboardingService) {
+    this.onboardingService = onboardingService;
+  }
 
-    /**
-     * Provide unstructured onboarding information. Possible json or string(html, js, etc), or something else.
-     */
+  /**
+   * Provide unstructured onboarding information. Possible json or string(html, js, etc), or
+   * something else.
+   */
     @GetMapping(value = { "" })
     @ApiOperation("Return onboarding information for page if available, -1 otherwise")
     public Object onBoarding(@RequestParam(value = "page", defaultValue = "GENERAL") String page) {
diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/PluginPublicController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/PluginPublicController.java
new file mode 100644
index 0000000000..b616ce2210
--- /dev/null
+++ b/src/main/java/com/epam/ta/reportportal/ws/controller/PluginPublicController.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2022 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.ws.controller;
+
+import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
+
+import com.epam.ta.reportportal.core.integration.ExecuteIntegrationHandler;
+import com.epam.ta.reportportal.core.integration.plugin.GetPluginHandler;
+import com.epam.ta.reportportal.core.integration.plugin.binary.PluginFilesProvider;
+import com.epam.ta.reportportal.entity.attachment.BinaryData;
+import com.epam.ta.reportportal.util.BinaryDataResponseWriter;
+import com.epam.ta.reportportal.ws.model.integration.IntegrationTypeResource;
+import io.swagger.annotations.ApiOperation;
+import java.util.List;
+import java.util.Map;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
+ */
+@RestController
+@RequestMapping(value = "/v1/plugin/public")
+public class PluginPublicController {
+
+  private final PluginFilesProvider pluginPublicFilesProvider;
+  private final BinaryDataResponseWriter binaryDataResponseWriter;
+  private final ExecuteIntegrationHandler executeIntegrationHandler;
+  private final GetPluginHandler getPluginHandler;
+
+  public PluginPublicController(PluginFilesProvider pluginPublicFilesProvider,
+      BinaryDataResponseWriter binaryDataResponseWriter,
+      ExecuteIntegrationHandler executeIntegrationHandler, GetPluginHandler getPluginHandler) {
+    this.pluginPublicFilesProvider = pluginPublicFilesProvider;
+    this.binaryDataResponseWriter = binaryDataResponseWriter;
+    this.executeIntegrationHandler = executeIntegrationHandler;
+    this.getPluginHandler = getPluginHandler;
+  }
+
+  @GetMapping(value = "/{pluginName}/file/{name}")
+  @ResponseStatus(HttpStatus.OK)
+  @ApiOperation("Get public plugin file without authentication")
+  public void getPublicFile(@PathVariable(value = "pluginName") String pluginName,
+      @PathVariable(value = "name") String fileName,
+      HttpServletResponse response) {
+    final BinaryData binaryData = pluginPublicFilesProvider.load(pluginName, fileName);
+    binaryDataResponseWriter.write(binaryData, response);
+  }
+
+  @PutMapping(value = "/{pluginName}/{command}", consumes = {APPLICATION_JSON_VALUE})
+  @ResponseStatus(HttpStatus.OK)
+  @ApiOperation("Execute public command without authentication")
+  public Object executePublicPluginCommand(@PathVariable("pluginName") String pluginName,
+      @PathVariable("command") String command, @RequestBody Map<String, Object> executionParams) {
+    return executeIntegrationHandler.executePublicCommand(pluginName, command, executionParams);
+  }
+
+  @GetMapping
+  @ResponseStatus(HttpStatus.OK)
+  @ApiOperation("Get all available public plugins")
+  public List<IntegrationTypeResource> getPlugins() {
+    return getPluginHandler.getPublicPlugins();
+  }
+}
diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/ProjectSettingsController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/ProjectSettingsController.java
index 491ea0b9a7..f4cc134fbf 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/controller/ProjectSettingsController.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/controller/ProjectSettingsController.java
@@ -16,11 +16,23 @@
 
 package com.epam.ta.reportportal.ws.controller;
 
+import static com.epam.ta.reportportal.auth.permissions.Permissions.ASSIGNED_TO_PROJECT;
+import static com.epam.ta.reportportal.auth.permissions.Permissions.PROJECT_MANAGER;
+import static com.epam.ta.reportportal.auth.permissions.Permissions.PROJECT_MANAGER_OR_ADMIN;
+import static com.epam.ta.reportportal.commons.EntityUtils.normalizeId;
+import static org.springframework.http.HttpStatus.CREATED;
+import static org.springframework.http.HttpStatus.OK;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
+import com.epam.ta.reportportal.core.project.GetProjectHandler;
 import com.epam.ta.reportportal.core.project.settings.CreateProjectSettingsHandler;
 import com.epam.ta.reportportal.core.project.settings.DeleteProjectSettingsHandler;
 import com.epam.ta.reportportal.core.project.settings.GetProjectSettingsHandler;
 import com.epam.ta.reportportal.core.project.settings.UpdateProjectSettingsHandler;
+import com.epam.ta.reportportal.core.project.settings.notification.CreateProjectNotificationHandler;
+import com.epam.ta.reportportal.core.project.settings.notification.DeleteProjectNotificationHandler;
+import com.epam.ta.reportportal.core.project.settings.notification.GetProjectNotificationsHandler;
+import com.epam.ta.reportportal.core.project.settings.notification.UpdateProjectNotificationHandler;
 import com.epam.ta.reportportal.ws.model.EntryCreatedRS;
 import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
 import com.epam.ta.reportportal.ws.model.project.config.CreateIssueSubTypeRQ;
@@ -29,22 +41,27 @@
 import com.epam.ta.reportportal.ws.model.project.config.UpdateIssueSubTypeRQ;
 import com.epam.ta.reportportal.ws.model.project.config.pattern.CreatePatternTemplateRQ;
 import com.epam.ta.reportportal.ws.model.project.config.pattern.UpdatePatternTemplateRQ;
+import com.epam.ta.reportportal.ws.model.project.email.SenderCaseDTO;
 import io.swagger.annotations.ApiOperation;
+import java.util.List;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.security.core.annotation.AuthenticationPrincipal;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import static com.epam.ta.reportportal.auth.permissions.Permissions.ASSIGNED_TO_PROJECT;
-import static com.epam.ta.reportportal.auth.permissions.Permissions.PROJECT_MANAGER;
-import static com.epam.ta.reportportal.commons.EntityUtils.normalizeId;
-import static org.springframework.http.HttpStatus.CREATED;
-import static org.springframework.http.HttpStatus.OK;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
 
 /**
- * Projects settings controller.
- * Provides resources for manipulation of various project settings items.
+ * Projects settings controller. Provides resources for manipulation of various project settings
+ * items.
  *
  * @author Andrei_Ramanchuk
  */
@@ -53,82 +70,165 @@
 @PreAuthorize(ASSIGNED_TO_PROJECT)
 public class ProjectSettingsController {
 
-	private final CreateProjectSettingsHandler createHandler;
-
-	private final UpdateProjectSettingsHandler updateHandler;
-
-	private final DeleteProjectSettingsHandler deleteHandler;
-
-	private final GetProjectSettingsHandler getHandler;
-
-	@Autowired
-	public ProjectSettingsController(CreateProjectSettingsHandler createHandler, UpdateProjectSettingsHandler updateHandler,
-			DeleteProjectSettingsHandler deleteHandler, GetProjectSettingsHandler getHandler) {
-		this.createHandler = createHandler;
-		this.updateHandler = updateHandler;
-		this.deleteHandler = deleteHandler;
-		this.getHandler = getHandler;
-	}
-
-	@PostMapping("/sub-type")
-	@ResponseStatus(CREATED)
-	@PreAuthorize(PROJECT_MANAGER)
-	@ApiOperation("Creation of custom project specific issue sub-type")
-	public IssueSubTypeCreatedRS createProjectIssueSubType(@PathVariable String projectName,
-			@RequestBody @Validated CreateIssueSubTypeRQ request, @AuthenticationPrincipal ReportPortalUser user) {
-		return createHandler.createProjectIssueSubType(normalizeId(projectName), user, request);
-	}
-
-	@PutMapping("/sub-type")
-	@ResponseStatus(OK)
-	@PreAuthorize(PROJECT_MANAGER)
-	@ApiOperation("Update of custom project specific issue sub-type")
-	public OperationCompletionRS updateProjectIssueSubType(@PathVariable String projectName,
-			@RequestBody @Validated UpdateIssueSubTypeRQ request, @AuthenticationPrincipal ReportPortalUser user) {
-		return updateHandler.updateProjectIssueSubType(normalizeId(projectName), user, request);
-	}
-
-	@DeleteMapping("/sub-type/{id}")
-	@ResponseStatus(OK)
-	@PreAuthorize(PROJECT_MANAGER)
-	@ApiOperation("Delete custom project specific issue sub-type")
-	public OperationCompletionRS deleteProjectIssueSubType(@PathVariable String projectName, @PathVariable Long id,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return deleteHandler.deleteProjectIssueSubType(normalizeId(projectName), user, id);
-	}
-
-	@GetMapping
-	@ResponseStatus(OK)
-	@PreAuthorize(ASSIGNED_TO_PROJECT)
-	@ApiOperation(value = "Get project specific issue sub-types", notes = "Only for users that are assigned to the project")
-	public ProjectSettingsResource getProjectSettings(@PathVariable String projectName, @AuthenticationPrincipal ReportPortalUser user) {
-		return getHandler.getProjectSettings(normalizeId(projectName));
-	}
-
-	@PostMapping("/pattern")
-	@ResponseStatus(CREATED)
-	@PreAuthorize(PROJECT_MANAGER)
-	@ApiOperation("Create pattern template for items' log messages pattern analysis")
-	public EntryCreatedRS createPatternTemplate(@PathVariable String projectName,
-			@RequestBody @Validated CreatePatternTemplateRQ createPatternTemplateRQ, @AuthenticationPrincipal ReportPortalUser user) {
-		return createHandler.createPatternTemplate(normalizeId(projectName), createPatternTemplateRQ, user);
-	}
-
-	@PutMapping("/pattern/{id}")
-	@ResponseStatus(OK)
-	@PreAuthorize(PROJECT_MANAGER)
-	@ApiOperation("Update pattern template for items' log messages pattern analysis")
-	public OperationCompletionRS updatePatternTemplate(@PathVariable String projectName, @PathVariable Long id,
-			@RequestBody @Validated UpdatePatternTemplateRQ updatePatternTemplateRQ, @AuthenticationPrincipal ReportPortalUser user) {
-		return updateHandler.updatePatternTemplate(id, normalizeId(projectName), updatePatternTemplateRQ, user);
-	}
-
-	@DeleteMapping("/pattern/{id}")
-	@ResponseStatus(OK)
-	@PreAuthorize(PROJECT_MANAGER)
-	@ApiOperation("Delete pattern template for items' log messages pattern analysis")
-	public OperationCompletionRS deletePatternTemplate(@PathVariable String projectName, @PathVariable Long id,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return deleteHandler.deletePatternTemplate(normalizeId(projectName), user, id);
-	}
+  private final CreateProjectSettingsHandler createHandler;
+
+  private final UpdateProjectSettingsHandler updateHandler;
+
+  private final DeleteProjectSettingsHandler deleteHandler;
+
+  private final GetProjectSettingsHandler getHandler;
+
+  private final GetProjectHandler getProjectHandler;
+
+  private final GetProjectNotificationsHandler getProjectNotificationsHandler;
+
+  private final CreateProjectNotificationHandler createProjectNotificationHandler;
+
+  private final UpdateProjectNotificationHandler updateProjectNotificationHandler;
+
+  private final DeleteProjectNotificationHandler deleteNotificationHandler;
+
+  @Autowired
+  public ProjectSettingsController(CreateProjectSettingsHandler createHandler,
+      UpdateProjectSettingsHandler updateHandler,
+      DeleteProjectSettingsHandler deleteHandler, GetProjectSettingsHandler getHandler,
+      GetProjectHandler getProjectHandler,
+      GetProjectNotificationsHandler getProjectNotificationsHandler,
+      CreateProjectNotificationHandler createProjectNotificationHandler,
+      UpdateProjectNotificationHandler updateProjectNotificationHandler,
+      DeleteProjectNotificationHandler deleteNotificationHandler) {
+    this.createHandler = createHandler;
+    this.updateHandler = updateHandler;
+    this.deleteHandler = deleteHandler;
+    this.getHandler = getHandler;
+    this.getProjectHandler = getProjectHandler;
+    this.getProjectNotificationsHandler = getProjectNotificationsHandler;
+    this.createProjectNotificationHandler = createProjectNotificationHandler;
+    this.updateProjectNotificationHandler = updateProjectNotificationHandler;
+    this.deleteNotificationHandler = deleteNotificationHandler;
+  }
+
+  @PostMapping("/sub-type")
+  @ResponseStatus(CREATED)
+  @PreAuthorize(PROJECT_MANAGER)
+  @ApiOperation("Creation of custom project specific issue sub-type")
+  public IssueSubTypeCreatedRS createProjectIssueSubType(@PathVariable String projectName,
+      @RequestBody @Validated CreateIssueSubTypeRQ request,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return createHandler.createProjectIssueSubType(normalizeId(projectName), user, request);
+  }
+
+  @PutMapping("/sub-type")
+  @ResponseStatus(OK)
+  @PreAuthorize(PROJECT_MANAGER)
+  @ApiOperation("Update of custom project specific issue sub-type")
+  public OperationCompletionRS updateProjectIssueSubType(@PathVariable String projectName,
+      @RequestBody @Validated UpdateIssueSubTypeRQ request,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return updateHandler.updateProjectIssueSubType(normalizeId(projectName), user, request);
+  }
+
+  @DeleteMapping("/sub-type/{id}")
+  @ResponseStatus(OK)
+  @PreAuthorize(PROJECT_MANAGER)
+  @ApiOperation("Delete custom project specific issue sub-type")
+  public OperationCompletionRS deleteProjectIssueSubType(@PathVariable String projectName,
+      @PathVariable Long id,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return deleteHandler.deleteProjectIssueSubType(normalizeId(projectName), user, id);
+  }
+
+  @GetMapping
+  @ResponseStatus(OK)
+  @PreAuthorize(ASSIGNED_TO_PROJECT)
+  @ApiOperation(value = "Get project specific issue sub-types", notes = "Only for users that are assigned to the project")
+  public ProjectSettingsResource getProjectSettings(@PathVariable String projectName,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return getHandler.getProjectSettings(normalizeId(projectName));
+  }
+
+  @PostMapping("/pattern")
+  @ResponseStatus(CREATED)
+  @PreAuthorize(PROJECT_MANAGER)
+  @ApiOperation("Create pattern template for items' log messages pattern analysis")
+  public EntryCreatedRS createPatternTemplate(@PathVariable String projectName,
+      @RequestBody @Validated CreatePatternTemplateRQ createPatternTemplateRQ,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return createHandler.createPatternTemplate(normalizeId(projectName), createPatternTemplateRQ,
+        user);
+  }
+
+  @PutMapping("/pattern/{id}")
+  @ResponseStatus(OK)
+  @PreAuthorize(PROJECT_MANAGER)
+  @ApiOperation("Update pattern template for items' log messages pattern analysis")
+  public OperationCompletionRS updatePatternTemplate(@PathVariable String projectName,
+      @PathVariable Long id,
+      @RequestBody @Validated UpdatePatternTemplateRQ updatePatternTemplateRQ,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return updateHandler.updatePatternTemplate(id, normalizeId(projectName),
+        updatePatternTemplateRQ, user);
+  }
+
+  @DeleteMapping("/pattern/{id}")
+  @ResponseStatus(OK)
+  @PreAuthorize(PROJECT_MANAGER)
+  @ApiOperation("Delete pattern template for items' log messages pattern analysis")
+  public OperationCompletionRS deletePatternTemplate(@PathVariable String projectName,
+      @PathVariable Long id,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return deleteHandler.deletePatternTemplate(normalizeId(projectName), user, id);
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping("/notification")
+  @ResponseStatus(OK)
+  @PreAuthorize(ASSIGNED_TO_PROJECT)
+  @ApiOperation(value = "Returns notifications config of specified project", notes = "Only for users assigned to specified project")
+  public List<SenderCaseDTO> getNotifications(@PathVariable String projectName) {
+    return getProjectNotificationsHandler.getProjectNotifications(
+        getProjectHandler.get(normalizeId(projectName)).getId());
+  }
+
+  @Transactional
+  @PostMapping("/notification")
+  @ResponseStatus(CREATED)
+  @PreAuthorize(PROJECT_MANAGER_OR_ADMIN)
+  @ApiOperation(value = "Creates notification for specified project", notes = "Only for users with PROJECT_MANAGER or ADMIN roles")
+  public EntryCreatedRS createNotification(@PathVariable String projectName,
+      @RequestBody @Validated SenderCaseDTO createNotificationRQ,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return createProjectNotificationHandler.createNotification(
+        getProjectHandler.get(normalizeId(projectName)),
+        createNotificationRQ,
+        user
+    );
+  }
+
+  @Transactional
+  @PutMapping("/notification")
+  @ResponseStatus(CREATED)
+  @PreAuthorize(PROJECT_MANAGER_OR_ADMIN)
+  @ApiOperation(value = "Updates notification for specified project", notes = "Only for users with PROJECT_MANAGER or ADMIN roles")
+  public OperationCompletionRS updateNotification(@PathVariable String projectName,
+      @RequestBody @Validated SenderCaseDTO updateNotificationRQ,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return updateProjectNotificationHandler.updateNotification(
+        getProjectHandler.get(normalizeId(projectName)),
+        updateNotificationRQ,
+        user
+    );
+  }
+
+  @Transactional
+  @DeleteMapping("/notification/{notificationId:\\d+}")
+  @ResponseStatus(OK)
+  @PreAuthorize(PROJECT_MANAGER_OR_ADMIN)
+  @ApiOperation(value = "Deletes notification for specified project", notes = "Only for users with PROJECT_MANAGER or ADMIN roles")
+  public OperationCompletionRS deleteNotification(@PathVariable String projectName,
+      @PathVariable Long notificationId,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return deleteNotificationHandler.deleteNotification(
+        getProjectHandler.get(normalizeId(projectName)), notificationId, user);
+  }
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/SettingsController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/SettingsController.java
index fd5149a070..f9726ff2df 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/controller/SettingsController.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/controller/SettingsController.java
@@ -16,22 +16,26 @@
 
 package com.epam.ta.reportportal.ws.controller;
 
+import static com.epam.ta.reportportal.auth.permissions.Permissions.ADMIN_ONLY;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.admin.ServerAdminHandler;
 import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
 import com.epam.ta.reportportal.ws.model.settings.AnalyticsResource;
 import io.swagger.annotations.ApiOperation;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.security.core.annotation.AuthenticationPrincipal;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.Map;
-
-import static com.epam.ta.reportportal.auth.permissions.Permissions.ADMIN_ONLY;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
 
 /**
  * @author Andrei_Ramanchuk
@@ -42,27 +46,28 @@
 @PreAuthorize(ADMIN_ONLY)
 public class SettingsController {
 
-	private final ServerAdminHandler serverHandler;
+  private final ServerAdminHandler serverHandler;
 
-	@Autowired
-	public SettingsController(ServerAdminHandler serverHandler) {
-		this.serverHandler = serverHandler;
-	}
+  @Autowired
+  public SettingsController(ServerAdminHandler serverHandler) {
+    this.serverHandler = serverHandler;
+  }
 
-	@Transactional
-	@RequestMapping(value = "/analytics", method = { RequestMethod.PUT, RequestMethod.POST })
-	@ResponseStatus(HttpStatus.OK)
-	@ApiOperation(value = "Update analytics settings")
-	public OperationCompletionRS saveAnalyticsSettings(@RequestBody @Validated AnalyticsResource request,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return serverHandler.saveAnalyticsSettings(request);
-	}
+  @Transactional
+  @RequestMapping(value = "/analytics", method = {RequestMethod.PUT, RequestMethod.POST})
+  @ResponseStatus(HttpStatus.OK)
+  @ApiOperation(value = "Update analytics settings")
+  public OperationCompletionRS saveAnalyticsSettings(
+      @RequestBody @Validated AnalyticsResource request,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return serverHandler.saveAnalyticsSettings(request);
+  }
 
-	@Transactional(readOnly = true)
-	@GetMapping
-	@ResponseStatus(HttpStatus.OK)
-	@ApiOperation(value = "Get server settings")
-	public Map<String, String> getServerSettings(@AuthenticationPrincipal ReportPortalUser user) {
-		return serverHandler.getServerSettings();
-	}
+  @Transactional(readOnly = true)
+  @GetMapping
+  @ResponseStatus(HttpStatus.OK)
+  @ApiOperation(value = "Get server settings")
+  public Map<String, String> getServerSettings(@AuthenticationPrincipal ReportPortalUser user) {
+    return serverHandler.getServerSettings();
+  }
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/TestItemAsyncController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/TestItemAsyncController.java
index 67a59c59ce..0b234f8aa5 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/controller/TestItemAsyncController.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/controller/TestItemAsyncController.java
@@ -16,6 +16,11 @@
 
 package com.epam.ta.reportportal.ws.controller;
 
+import static com.epam.ta.reportportal.auth.permissions.Permissions.ALLOWED_TO_REPORT;
+import static com.epam.ta.reportportal.auth.permissions.Permissions.ASSIGNED_TO_PROJECT;
+import static org.springframework.http.HttpStatus.CREATED;
+import static org.springframework.http.HttpStatus.OK;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.item.FinishTestItemHandler;
 import com.epam.ta.reportportal.core.item.StartTestItemHandler;
@@ -31,12 +36,13 @@
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.security.core.annotation.AuthenticationPrincipal;
 import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import static com.epam.ta.reportportal.auth.permissions.Permissions.ALLOWED_TO_REPORT;
-import static com.epam.ta.reportportal.auth.permissions.Permissions.ASSIGNED_TO_PROJECT;
-import static org.springframework.http.HttpStatus.CREATED;
-import static org.springframework.http.HttpStatus.OK;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
 
 /**
  * Controller implementation for async reporting client API for
@@ -50,46 +56,53 @@
 @PreAuthorize(ASSIGNED_TO_PROJECT)
 public class TestItemAsyncController {
 
-	private final ProjectExtractor projectExtractor;
-	private final StartTestItemHandler startTestItemHandler;
-	private final FinishTestItemHandler finishTestItemHandler;
+  private final ProjectExtractor projectExtractor;
+  private final StartTestItemHandler startTestItemHandler;
+  private final FinishTestItemHandler finishTestItemHandler;
 
-	@Autowired
-	public TestItemAsyncController(ProjectExtractor projectExtractor, @Qualifier("startTestItemHandlerAsync") StartTestItemHandler startTestItemHandler,
-			@Qualifier("finishTestItemHandlerAsync") FinishTestItemHandler finishTestItemHandler) {
-		this.projectExtractor = projectExtractor;
-		this.startTestItemHandler = startTestItemHandler;
-		this.finishTestItemHandler = finishTestItemHandler;
-	}
+  @Autowired
+  public TestItemAsyncController(ProjectExtractor projectExtractor,
+      @Qualifier("startTestItemHandlerAsync") StartTestItemHandler startTestItemHandler,
+      @Qualifier("finishTestItemHandlerAsync") FinishTestItemHandler finishTestItemHandler) {
+    this.projectExtractor = projectExtractor;
+    this.startTestItemHandler = startTestItemHandler;
+    this.finishTestItemHandler = finishTestItemHandler;
+  }
 
-	@HttpLogging
-	@PostMapping
-	@ResponseStatus(CREATED)
-	@ApiOperation("Start a root test item")
-	@PreAuthorize(ALLOWED_TO_REPORT)
-	public EntryCreatedAsyncRS startRootItem(@PathVariable String projectName, @AuthenticationPrincipal ReportPortalUser user,
-			@RequestBody @Validated StartTestItemRQ startTestItemRQ) {
-		return startTestItemHandler.startRootItem(user, projectExtractor.extractProjectDetails(user, projectName), startTestItemRQ);
-	}
+  @HttpLogging
+  @PostMapping
+  @ResponseStatus(CREATED)
+  @ApiOperation("Start a root test item")
+  @PreAuthorize(ALLOWED_TO_REPORT)
+  public EntryCreatedAsyncRS startRootItem(@PathVariable String projectName,
+      @AuthenticationPrincipal ReportPortalUser user,
+      @RequestBody @Validated StartTestItemRQ startTestItemRQ) {
+    return startTestItemHandler.startRootItem(user,
+        projectExtractor.extractProjectDetails(user, projectName), startTestItemRQ);
+  }
 
-	@HttpLogging
-	@PostMapping("/{parentItem}")
-	@ResponseStatus(CREATED)
-	@ApiOperation("Start a child test item")
-	@PreAuthorize(ALLOWED_TO_REPORT)
-	public EntryCreatedAsyncRS startChildItem(@PathVariable String projectName, @AuthenticationPrincipal ReportPortalUser user,
-			@PathVariable String parentItem, @RequestBody @Validated StartTestItemRQ startTestItemRQ) {
-		return startTestItemHandler.startChildItem(user, projectExtractor.extractProjectDetails(user, projectName), startTestItemRQ, parentItem);
-	}
+  @HttpLogging
+  @PostMapping("/{parentItem}")
+  @ResponseStatus(CREATED)
+  @ApiOperation("Start a child test item")
+  @PreAuthorize(ALLOWED_TO_REPORT)
+  public EntryCreatedAsyncRS startChildItem(@PathVariable String projectName,
+      @AuthenticationPrincipal ReportPortalUser user,
+      @PathVariable String parentItem, @RequestBody @Validated StartTestItemRQ startTestItemRQ) {
+    return startTestItemHandler.startChildItem(user,
+        projectExtractor.extractProjectDetails(user, projectName), startTestItemRQ, parentItem);
+  }
 
-	@HttpLogging
-	@PutMapping("/{testItemId}")
-	@ResponseStatus(OK)
-	@ApiOperation("Finish test item")
-	@PreAuthorize(ALLOWED_TO_REPORT)
-	public OperationCompletionRS finishTestItem(@PathVariable String projectName, @AuthenticationPrincipal ReportPortalUser user,
-			@PathVariable String testItemId, @RequestBody @Validated FinishTestItemRQ finishExecutionRQ) {
-		return finishTestItemHandler.finishTestItem(user, projectExtractor.extractProjectDetails(user, projectName), testItemId, finishExecutionRQ);
-	}
+  @HttpLogging
+  @PutMapping("/{testItemId}")
+  @ResponseStatus(OK)
+  @ApiOperation("Finish test item")
+  @PreAuthorize(ALLOWED_TO_REPORT)
+  public OperationCompletionRS finishTestItem(@PathVariable String projectName,
+      @AuthenticationPrincipal ReportPortalUser user,
+      @PathVariable String testItemId, @RequestBody @Validated FinishTestItemRQ finishExecutionRQ) {
+    return finishTestItemHandler.finishTestItem(user,
+        projectExtractor.extractProjectDetails(user, projectName), testItemId, finishExecutionRQ);
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/TestItemController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/TestItemController.java
index 9a8854cba7..ae6cf080ab 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/controller/TestItemController.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/controller/TestItemController.java
@@ -16,6 +16,21 @@
 
 package com.epam.ta.reportportal.ws.controller;
 
+import static com.epam.ta.reportportal.auth.permissions.Permissions.ALLOWED_TO_REPORT;
+import static com.epam.ta.reportportal.auth.permissions.Permissions.ASSIGNED_TO_PROJECT;
+import static com.epam.ta.reportportal.auth.permissions.Permissions.PROJECT_MANAGER_OR_ADMIN;
+import static com.epam.ta.reportportal.commons.EntityUtils.normalizeId;
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_ID;
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_LAUNCH_ID;
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_NAME;
+import static com.epam.ta.reportportal.commons.querygen.constant.ItemAttributeConstant.CRITERIA_ITEM_ATTRIBUTE_KEY;
+import static com.epam.ta.reportportal.commons.querygen.constant.ItemAttributeConstant.CRITERIA_ITEM_ATTRIBUTE_VALUE;
+import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_PARENT_ID;
+import static com.epam.ta.reportportal.ws.resolver.FilterCriteriaResolver.DEFAULT_FILTER_PREFIX;
+import static java.util.Optional.ofNullable;
+import static org.springframework.http.HttpStatus.CREATED;
+import static org.springframework.http.HttpStatus.OK;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.querygen.CompositeFilter;
 import com.epam.ta.reportportal.commons.querygen.Condition;
@@ -24,12 +39,22 @@
 import com.epam.ta.reportportal.core.analyzer.auto.client.model.SuggestInfo;
 import com.epam.ta.reportportal.core.analyzer.auto.impl.SuggestItemService;
 import com.epam.ta.reportportal.core.analyzer.auto.impl.SuggestedItem;
-import com.epam.ta.reportportal.core.item.*;
+import com.epam.ta.reportportal.core.item.DeleteTestItemHandler;
+import com.epam.ta.reportportal.core.item.FinishTestItemHandler;
+import com.epam.ta.reportportal.core.item.GetTestItemHandler;
+import com.epam.ta.reportportal.core.item.StartTestItemHandler;
+import com.epam.ta.reportportal.core.item.UpdateTestItemHandler;
 import com.epam.ta.reportportal.core.item.history.TestItemsHistoryHandler;
 import com.epam.ta.reportportal.core.item.impl.history.param.HistoryRequestParams;
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.util.ProjectExtractor;
-import com.epam.ta.reportportal.ws.model.*;
+import com.epam.ta.reportportal.ws.model.BulkInfoUpdateRQ;
+import com.epam.ta.reportportal.ws.model.EntryCreatedAsyncRS;
+import com.epam.ta.reportportal.ws.model.FinishTestItemRQ;
+import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
+import com.epam.ta.reportportal.ws.model.StartTestItemRQ;
+import com.epam.ta.reportportal.ws.model.TestItemHistoryElement;
+import com.epam.ta.reportportal.ws.model.TestItemResource;
 import com.epam.ta.reportportal.ws.model.issue.DefineIssueRQ;
 import com.epam.ta.reportportal.ws.model.issue.Issue;
 import com.epam.ta.reportportal.ws.model.item.LinkExternalIssueRQ;
@@ -39,6 +64,11 @@
 import com.epam.ta.reportportal.ws.resolver.FilterFor;
 import com.epam.ta.reportportal.ws.resolver.SortFor;
 import io.swagger.annotations.ApiOperation;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.annotation.Nullable;
 import org.apache.commons.lang3.StringUtils;
 import org.jooq.Operator;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -47,377 +77,437 @@
 import org.springframework.security.core.annotation.AuthenticationPrincipal;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import javax.annotation.Nullable;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import static com.epam.ta.reportportal.auth.permissions.Permissions.*;
-import static com.epam.ta.reportportal.commons.EntityUtils.normalizeId;
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.*;
-import static com.epam.ta.reportportal.commons.querygen.constant.ItemAttributeConstant.CRITERIA_ITEM_ATTRIBUTE_KEY;
-import static com.epam.ta.reportportal.commons.querygen.constant.ItemAttributeConstant.CRITERIA_ITEM_ATTRIBUTE_VALUE;
-import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_PARENT_ID;
-import static com.epam.ta.reportportal.ws.resolver.FilterCriteriaResolver.DEFAULT_FILTER_PREFIX;
-import static java.util.Optional.ofNullable;
-import static org.springframework.http.HttpStatus.CREATED;
-import static org.springframework.http.HttpStatus.OK;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
 
 /**
- * Controller implementation for
- * {@link com.epam.ta.reportportal.entity.item.TestItem} entity
- * <p>
+ * Controller implementation for {@link com.epam.ta.reportportal.entity.item.TestItem} entity
  */
 @RestController
 @RequestMapping("/v1/{projectName}/item")
 @PreAuthorize(ASSIGNED_TO_PROJECT)
 public class TestItemController {
 
-	public static final String HISTORY_TYPE_PARAM = "type";
-	public static final String FILTER_ID_REQUEST_PARAM = "filterId";
-	public static final String IS_LATEST_LAUNCHES_REQUEST_PARAM = "isLatest";
-	public static final String LAUNCHES_LIMIT_REQUEST_PARAM = "launchesLimit";
-	private static final String HISTORY_DEPTH_PARAM = "historyDepth";
-	private static final String HISTORY_DEPTH_DEFAULT_VALUE = "5";
-	private static final String LAUNCHES_LIMIT_DEFAULT_VALUE = "0";
-
-	private final ProjectExtractor projectExtractor;
-	private final StartTestItemHandler startTestItemHandler;
-	private final DeleteTestItemHandler deleteTestItemHandler;
-	private final FinishTestItemHandler finishTestItemHandler;
-	private final UpdateTestItemHandler updateTestItemHandler;
-	private final GetTestItemHandler getTestItemHandler;
-	private final TestItemsHistoryHandler testItemsHistoryHandler;
-	private final SuggestItemService suggestItemService;
-
-	@Autowired
-	public TestItemController(ProjectExtractor projectExtractor, StartTestItemHandler startTestItemHandler, DeleteTestItemHandler deleteTestItemHandler,
-			FinishTestItemHandler finishTestItemHandler, UpdateTestItemHandler updateTestItemHandler, GetTestItemHandler getTestItemHandler,
-			TestItemsHistoryHandler testItemsHistoryHandler, SuggestItemService suggestItemService) {
-		this.projectExtractor = projectExtractor;
-		this.startTestItemHandler = startTestItemHandler;
-		this.deleteTestItemHandler = deleteTestItemHandler;
-		this.finishTestItemHandler = finishTestItemHandler;
-		this.updateTestItemHandler = updateTestItemHandler;
-		this.getTestItemHandler = getTestItemHandler;
-		this.testItemsHistoryHandler = testItemsHistoryHandler;
-		this.suggestItemService = suggestItemService;
-	}
-
-	/* Report client API */
-
-	@PostMapping
-	@ResponseStatus(CREATED)
-	@ApiOperation("Start a root test item")
-	@PreAuthorize(ALLOWED_TO_REPORT)
-	public EntryCreatedAsyncRS startRootItem(@PathVariable String projectName, @AuthenticationPrincipal ReportPortalUser user,
-			@RequestBody @Validated StartTestItemRQ startTestItemRQ) {
-		return startTestItemHandler.startRootItem(user, projectExtractor.extractProjectDetails(user, projectName), startTestItemRQ);
-	}
-
-	@PostMapping("/{parentItem}")
-	@ResponseStatus(CREATED)
-	@ApiOperation("Start a child test item")
-	@PreAuthorize(ALLOWED_TO_REPORT)
-	public EntryCreatedAsyncRS startChildItem(@PathVariable String projectName, @AuthenticationPrincipal ReportPortalUser user,
-			@PathVariable String parentItem, @RequestBody @Validated StartTestItemRQ startTestItemRQ) {
-		return startTestItemHandler.startChildItem(user, projectExtractor.extractProjectDetails(user, projectName), startTestItemRQ, parentItem);
-	}
-
-	@PutMapping("/{testItemId}")
-	@ResponseStatus(OK)
-	@ApiOperation("Finish test item")
-	@PreAuthorize(ALLOWED_TO_REPORT)
-	public OperationCompletionRS finishTestItem(@PathVariable String projectName, @AuthenticationPrincipal ReportPortalUser user,
-			@PathVariable String testItemId, @RequestBody @Validated FinishTestItemRQ finishExecutionRQ) {
-		return finishTestItemHandler.finishTestItem(user, projectExtractor.extractProjectDetails(user, projectName), testItemId, finishExecutionRQ);
-	}
-
-
-	/* Frontend API */
-
-	@Transactional(readOnly = true)
-	@GetMapping("/{itemId}")
-	@ResponseStatus(OK)
-	@ApiOperation("Find test item by ID")
-	public TestItemResource getTestItem(@PathVariable String projectName, @AuthenticationPrincipal ReportPortalUser user,
-			@PathVariable String itemId) {
-		return getTestItemHandler.getTestItem(itemId, projectExtractor.extractProjectDetails(user, projectName), user);
-
-	}
-
-	@Transactional(readOnly = true)
-	@GetMapping("/uuid/{itemId}")
-	@ResponseStatus(OK)
-	@ApiOperation("Find test item by UUID")
-	public TestItemResource getTestItemByUuid(@PathVariable String projectName, @AuthenticationPrincipal ReportPortalUser user,
-			@PathVariable String itemId) {
-		return getTestItemHandler.getTestItem(itemId, projectExtractor.extractProjectDetails(user, projectName), user);
-
-	}
-
-	@Transactional(readOnly = true)
-	@GetMapping("/suggest/{itemId}")
-	@ResponseStatus(OK)
-	@ApiOperation("Search suggested items in analyzer for provided one")
-	public List<SuggestedItem> getSuggestedItems(@PathVariable String projectName, @AuthenticationPrincipal ReportPortalUser user,
-			@PathVariable Long itemId) {
-		return suggestItemService.suggestItems(itemId, projectExtractor.extractProjectDetails(user, projectName), user);
-	}
-
-	@GetMapping("/suggest/cluster/{clusterId}")
-	@ResponseStatus(OK)
-	@ApiOperation("Search suggested items in analyzer for provided one")
-	public List<SuggestedItem> getSuggestedClusterItems(@PathVariable String projectName, @AuthenticationPrincipal ReportPortalUser user,
-			@PathVariable Long clusterId) {
-		return suggestItemService.suggestClusterItems(clusterId, projectExtractor.extractProjectDetails(user, projectName), user);
-	}
-
-	@Transactional
-	@PutMapping("/suggest/choice")
-	@ResponseStatus(OK)
-	@ApiOperation("Handle user choice from suggested items")
-	public OperationCompletionRS handleSuggestChoose(@PathVariable String projectName, @AuthenticationPrincipal ReportPortalUser user,
-			@RequestBody @Validated List<SuggestInfo> request) {
-		projectExtractor.extractProjectDetails(user, projectName);
-		return suggestItemService.handleSuggestChoice(request);
-	}
-
-	//TODO check pre-defined filter
-	@Transactional(readOnly = true)
-	@GetMapping
-	@ResponseStatus(OK)
-	@ApiOperation("Find test items by specified filter")
-	public Iterable<TestItemResource> getTestItems(@PathVariable String projectName, @AuthenticationPrincipal ReportPortalUser user,
-			@Nullable @RequestParam(value = DEFAULT_FILTER_PREFIX + Condition.EQ + CRITERIA_LAUNCH_ID, required = false) Long launchId,
-			@Nullable @RequestParam(value = FILTER_ID_REQUEST_PARAM, required = false) Long filterId,
-			@RequestParam(value = IS_LATEST_LAUNCHES_REQUEST_PARAM, defaultValue = "false", required = false) boolean isLatest,
-			@RequestParam(value = LAUNCHES_LIMIT_REQUEST_PARAM, defaultValue = "0", required = false) int launchesLimit,
-			@FilterFor(TestItem.class) Filter filter, @FilterFor(TestItem.class) Queryable predefinedFilter,
-			@SortFor(TestItem.class) Pageable pageable) {
-		return getTestItemHandler.getTestItems(new CompositeFilter(Operator.AND, filter, predefinedFilter),
-				pageable,
-				projectExtractor.extractProjectDetails(user, projectName),
-				user,
-				launchId,
-				filterId,
-				isLatest,
-				launchesLimit
-		);
-	}
-
-	@Transactional(readOnly = true)
-	@GetMapping("/v2")
-	@ResponseStatus(OK)
-	@ApiOperation("Find test items by specified filter")
-	public Iterable<TestItemResource> getTestItemsV2(@PathVariable String projectName, @AuthenticationPrincipal ReportPortalUser user,
-			@RequestParam Map<String, String> params, @FilterFor(TestItem.class) Filter filter,
-			@FilterFor(TestItem.class) Queryable predefinedFilter, @SortFor(TestItem.class) Pageable pageable) {
-		// tmp return null for project, to fix perf issue
-		if ("libg-140".equalsIgnoreCase(projectName)) return null;
-		return getTestItemHandler.getTestItemsByProvider(new CompositeFilter(Operator.AND, filter, predefinedFilter),
-				pageable,
-				projectExtractor.extractProjectDetails(user, projectName),
-				user,
-				params
-		);
-	}
-
-	@Transactional(readOnly = true)
-	@GetMapping("/statistics")
-	@ResponseStatus(OK)
-	@ApiOperation("Find accumulated statistics of items by specified filter")
-	public StatisticsResource getTestItems(@PathVariable String projectName, @AuthenticationPrincipal ReportPortalUser user,
-			@FilterFor(TestItem.class) Filter filter, @FilterFor(TestItem.class) Queryable predefinedFilter,
-			@RequestParam Map<String, String> params) {
-		return getTestItemHandler.getStatisticsByProvider(new CompositeFilter(Operator.AND, filter, predefinedFilter),
-				projectExtractor.extractProjectDetails(user, projectName),
-				user,
-				params
-		);
-	}
-
-	@Transactional
-	@DeleteMapping("/{itemId}")
-	@ResponseStatus(OK)
-	@ApiOperation("Delete test item")
-	public OperationCompletionRS deleteTestItem(@PathVariable String projectName, @AuthenticationPrincipal ReportPortalUser user,
-			@PathVariable Long itemId) {
-		return deleteTestItemHandler.deleteTestItem(itemId, projectExtractor.extractProjectDetails(user, projectName), user);
-	}
-
-	@Transactional
-	@DeleteMapping
-	@ResponseStatus(OK)
-	@ApiOperation("Delete test items by specified ids")
-	public List<OperationCompletionRS> deleteTestItems(@PathVariable String projectName, @AuthenticationPrincipal ReportPortalUser user,
-			@RequestParam(value = "ids") Set<Long> ids) {
-		return deleteTestItemHandler.deleteTestItems(ids, projectExtractor.extractProjectDetails(user, projectName), user);
-	}
-
-	@Transactional
-	@PutMapping
-	@ResponseStatus(OK)
-	@ApiOperation("Update issues of specified test items")
-	public List<Issue> defineTestItemIssueType(@PathVariable String projectName, @AuthenticationPrincipal ReportPortalUser user,
-			@RequestBody @Validated DefineIssueRQ request) {
-		return updateTestItemHandler.defineTestItemsIssues(projectExtractor.extractProjectDetails(user, projectName), request, user);
-	}
-
-	@Transactional(readOnly = true)
-	@GetMapping("/history")
-	@ResponseStatus(OK)
-	@ApiOperation("Load history of test items")
-	public Iterable<TestItemHistoryElement> getItemsHistory(@PathVariable String projectName,
-			@AuthenticationPrincipal ReportPortalUser user, @FilterFor(TestItem.class) Filter filter,
-			@FilterFor(TestItem.class) Queryable predefinedFilter, @SortFor(TestItem.class) Pageable pageable,
-			@Nullable @RequestParam(value = DEFAULT_FILTER_PREFIX + Condition.EQ + CRITERIA_PARENT_ID, required = false) Long parentId,
-			@Nullable @RequestParam(value = DEFAULT_FILTER_PREFIX + Condition.EQ + CRITERIA_ID, required = false) Long itemId,
-			@Nullable @RequestParam(value = DEFAULT_FILTER_PREFIX + Condition.EQ + CRITERIA_LAUNCH_ID, required = false) Long launchId,
-			@Nullable @RequestParam(value = HISTORY_TYPE_PARAM, required = false) String type,
-			@Nullable @RequestParam(value = FILTER_ID_REQUEST_PARAM, required = false) Long filterId,
-			@RequestParam(value = IS_LATEST_LAUNCHES_REQUEST_PARAM, defaultValue = "false", required = false) boolean isLatest,
-			@RequestParam(value = LAUNCHES_LIMIT_REQUEST_PARAM, defaultValue = "0", required = false) int launchesLimit,
-			@RequestParam(value = HISTORY_DEPTH_PARAM, required = false, defaultValue = HISTORY_DEPTH_DEFAULT_VALUE) int historyDepth) {
-
-		return testItemsHistoryHandler.getItemsHistory(projectExtractor.extractProjectDetails(user, projectName),
-				new CompositeFilter(Operator.AND, filter, predefinedFilter),
-				pageable,
-				HistoryRequestParams.of(historyDepth, parentId, itemId, launchId, type, filterId, launchesLimit, isLatest),
-				user
-		);
-	}
-
-	@Transactional(readOnly = true)
-	@GetMapping("/ticket/ids")
-	@ResponseStatus(OK)
-	@ApiOperation("Get tickets that contains a term as a part inside for specified launch")
-	public List<String> getTicketIds(@AuthenticationPrincipal ReportPortalUser user, @PathVariable String projectName,
-			@RequestParam(value = "launch") Long id, @RequestParam(value = "term") String term) {
-		return getTestItemHandler.getTicketIds(id, normalizeId(term));
-	}
-
-	@Transactional(readOnly = true)
-	@GetMapping("/ticket/ids/all")
-	@ResponseStatus(OK)
-	@ApiOperation("Get tickets that contains a term as a part inside for specified launch")
-	public List<String> getTicketIdsForProject(@AuthenticationPrincipal ReportPortalUser user, @PathVariable String projectName,
-			@RequestParam(value = "term") String term) {
-		return getTestItemHandler.getTicketIds(projectExtractor.extractProjectDetails(user, projectName), normalizeId(term));
-	}
-
-	//TODO EPMRPP-59414
-	@Transactional(readOnly = true)
-	@GetMapping("/attribute/keys")
-	@ResponseStatus(OK)
-	@ApiOperation("Get all unique attribute keys of specified launch")
-	public List<String> getAttributeKeys(@PathVariable String projectName, @AuthenticationPrincipal ReportPortalUser user,
-			@RequestParam(value = "launch") Long id,
-			@RequestParam(value = DEFAULT_FILTER_PREFIX + Condition.CNT + CRITERIA_ITEM_ATTRIBUTE_KEY) String value) {
-		return getTestItemHandler.getAttributeKeys(id, value);
-	}
-
-	//TODO EPMRPP-59414
-	@Transactional(readOnly = true)
-	@GetMapping("/attribute/keys/all")
-	@ResponseStatus(OK)
-	@ApiOperation("Get all unique attribute keys of specified launch")
-	public List<String> getAttributeKeysForProject(@PathVariable String projectName, @AuthenticationPrincipal ReportPortalUser user,
-			@RequestParam(value = DEFAULT_FILTER_PREFIX + Condition.CNT + CRITERIA_ITEM_ATTRIBUTE_KEY) String value,
-			@RequestParam(value = FILTER_ID_REQUEST_PARAM) Long launchFilterId,
-			@RequestParam(value = IS_LATEST_LAUNCHES_REQUEST_PARAM, defaultValue = "false", required = false) boolean isLatest,
-			@RequestParam(value = LAUNCHES_LIMIT_REQUEST_PARAM, defaultValue = "0") int launchesLimit) {
-		return getTestItemHandler.getAttributeKeys(launchFilterId,
-				isLatest,
-				launchesLimit,
-				projectExtractor.extractProjectDetails(user, projectName),
-				value
-		);
-	}
-
-	//TODO EPMRPP-59414
-	@Transactional(readOnly = true)
-	@GetMapping("/attribute/values")
-	@ResponseStatus(OK)
-	@ApiOperation("Get all unique attribute values of specified launch")
-	public List<String> getAttributeValues(@PathVariable String projectName, @AuthenticationPrincipal ReportPortalUser user,
-			@RequestParam(value = "launch") Long id,
-			@RequestParam(value = DEFAULT_FILTER_PREFIX + Condition.EQ + CRITERIA_ITEM_ATTRIBUTE_KEY, required = false) String key,
-			@RequestParam(value = DEFAULT_FILTER_PREFIX + Condition.CNT + CRITERIA_ITEM_ATTRIBUTE_VALUE) String value) {
-		return getTestItemHandler.getAttributeValues(id, key, value);
-	}
-
-	@Transactional(readOnly = true)
-	@GetMapping("/step/attribute/keys")
-	@ResponseStatus(OK)
-	@ApiOperation("Get all unique attribute keys of step items under specified project")
-	public List<String> getAttributeKeys(@PathVariable String projectName, @AuthenticationPrincipal ReportPortalUser user,
-			@RequestParam(value = DEFAULT_FILTER_PREFIX + Condition.EQ + CRITERIA_NAME, required = false) String launchName,
-			@RequestParam(value = DEFAULT_FILTER_PREFIX + Condition.CNT + CRITERIA_ITEM_ATTRIBUTE_KEY) String value) {
-		return ofNullable(launchName).filter(StringUtils::isNotBlank)
-				.map(name -> getTestItemHandler.getAttributeKeys(projectExtractor.extractProjectDetails(user, projectName), name, value))
-				.orElseGet(Collections::emptyList);
-	}
-
-	@Transactional(readOnly = true)
-	@GetMapping("/step/attribute/values")
-	@ResponseStatus(OK)
-	@ApiOperation("Get all unique attribute values of step items under specified project")
-	public List<String> getAttributeValues(@PathVariable String projectName, @AuthenticationPrincipal ReportPortalUser user,
-			@RequestParam(value = DEFAULT_FILTER_PREFIX + Condition.EQ + CRITERIA_NAME, required = false) String launchName,
-			@RequestParam(value = DEFAULT_FILTER_PREFIX + Condition.EQ + CRITERIA_ITEM_ATTRIBUTE_KEY, required = false) String key,
-			@RequestParam(value = DEFAULT_FILTER_PREFIX + Condition.CNT + CRITERIA_ITEM_ATTRIBUTE_VALUE) String value) {
-		return ofNullable(launchName).filter(StringUtils::isNotBlank)
-				.map(name -> getTestItemHandler.getAttributeValues(projectExtractor.extractProjectDetails(user, projectName), name, key, value))
-				.orElseGet(Collections::emptyList);
-	}
-
-	@Transactional
-	@PutMapping(value = "/info")
-	@PreAuthorize(PROJECT_MANAGER_OR_ADMIN)
-	@ResponseStatus(OK)
-	@ApiOperation("Bulk update attributes and description")
-	public OperationCompletionRS bulkUpdate(@PathVariable String projectName, @RequestBody @Validated BulkInfoUpdateRQ bulkInfoUpdateRQ,
-			@AuthenticationPrincipal ReportPortalUser user) {
-		return updateTestItemHandler.bulkInfoUpdate(bulkInfoUpdateRQ, projectExtractor.extractProjectDetails(user, projectName));
-	}
-
-	@Transactional
-	@PutMapping("/{itemId}/update")
-	@ResponseStatus(OK)
-	@ApiOperation("Update test item")
-	public OperationCompletionRS updateTestItem(@PathVariable String projectName, @AuthenticationPrincipal ReportPortalUser user,
-			@PathVariable Long itemId, @RequestBody @Validated UpdateTestItemRQ rq) {
-		return updateTestItemHandler.updateTestItem(projectExtractor.extractProjectDetails(user, projectName), itemId, rq, user);
-	}
-
-	@Transactional
-	@PutMapping("/issue/link")
-	@ResponseStatus(OK)
-	@ApiOperation("Attach external issue for specified test items")
-	public List<OperationCompletionRS> linkExternalIssues(@PathVariable String projectName, @AuthenticationPrincipal ReportPortalUser user,
-			@RequestBody @Validated LinkExternalIssueRQ rq) {
-		return updateTestItemHandler.processExternalIssues(rq, projectExtractor.extractProjectDetails(user, projectName), user);
-	}
-
-	@Transactional
-	@PutMapping("/issue/unlink")
-	@ResponseStatus(OK)
-	@ApiOperation("Unlink external issue for specified test items")
-	public List<OperationCompletionRS> unlinkExternalIssues(@PathVariable String projectName,
-			@AuthenticationPrincipal ReportPortalUser user, @RequestBody @Validated UnlinkExternalIssueRQ rq) {
-		return updateTestItemHandler.processExternalIssues(rq, projectExtractor.extractProjectDetails(user, projectName), user);
-	}
-
-	@Transactional(readOnly = true)
-	@GetMapping("/items")
-	@ResponseStatus(OK)
-	@ApiOperation("Get test items by specified ids")
-	public List<TestItemResource> getTestItems(@PathVariable String projectName, @AuthenticationPrincipal ReportPortalUser user,
-			@RequestParam(value = "ids") Long[] ids) {
-		return getTestItemHandler.getTestItems(ids, projectExtractor.extractProjectDetails(user, projectName), user);
-	}
+  public static final String HISTORY_TYPE_PARAM = "type";
+  public static final String FILTER_ID_REQUEST_PARAM = "filterId";
+  public static final String IS_LATEST_LAUNCHES_REQUEST_PARAM = "isLatest";
+  public static final String LAUNCHES_LIMIT_REQUEST_PARAM = "launchesLimit";
+  private static final String HISTORY_DEPTH_PARAM = "historyDepth";
+  private static final String HISTORY_DEPTH_DEFAULT_VALUE = "5";
+  private static final String LAUNCHES_LIMIT_DEFAULT_VALUE = "0";
+
+  private final ProjectExtractor projectExtractor;
+  private final StartTestItemHandler startTestItemHandler;
+  private final DeleteTestItemHandler deleteTestItemHandler;
+  private final FinishTestItemHandler finishTestItemHandler;
+  private final UpdateTestItemHandler updateTestItemHandler;
+  private final GetTestItemHandler getTestItemHandler;
+  private final TestItemsHistoryHandler testItemsHistoryHandler;
+  private final SuggestItemService suggestItemService;
+
+  @Autowired
+  public TestItemController(ProjectExtractor projectExtractor,
+      StartTestItemHandler startTestItemHandler, DeleteTestItemHandler deleteTestItemHandler,
+      FinishTestItemHandler finishTestItemHandler, UpdateTestItemHandler updateTestItemHandler,
+      GetTestItemHandler getTestItemHandler,
+      TestItemsHistoryHandler testItemsHistoryHandler, SuggestItemService suggestItemService) {
+    this.projectExtractor = projectExtractor;
+    this.startTestItemHandler = startTestItemHandler;
+    this.deleteTestItemHandler = deleteTestItemHandler;
+    this.finishTestItemHandler = finishTestItemHandler;
+    this.updateTestItemHandler = updateTestItemHandler;
+    this.getTestItemHandler = getTestItemHandler;
+    this.testItemsHistoryHandler = testItemsHistoryHandler;
+    this.suggestItemService = suggestItemService;
+  }
+
+  /* Report client API */
+
+  @PostMapping
+  @ResponseStatus(CREATED)
+  @ApiOperation("Start a root test item")
+  @PreAuthorize(ALLOWED_TO_REPORT)
+  public EntryCreatedAsyncRS startRootItem(@PathVariable String projectName,
+      @AuthenticationPrincipal ReportPortalUser user,
+      @RequestBody @Validated StartTestItemRQ startTestItemRQ) {
+    return startTestItemHandler.startRootItem(user,
+        projectExtractor.extractProjectDetails(user, projectName), startTestItemRQ);
+  }
+
+  @PostMapping("/{parentItem}")
+  @ResponseStatus(CREATED)
+  @ApiOperation("Start a child test item")
+  @PreAuthorize(ALLOWED_TO_REPORT)
+  public EntryCreatedAsyncRS startChildItem(@PathVariable String projectName,
+      @AuthenticationPrincipal ReportPortalUser user,
+      @PathVariable String parentItem, @RequestBody @Validated StartTestItemRQ startTestItemRQ) {
+    return startTestItemHandler.startChildItem(user,
+        projectExtractor.extractProjectDetails(user, projectName), startTestItemRQ, parentItem);
+  }
+
+  @PutMapping("/{testItemId}")
+  @ResponseStatus(OK)
+  @ApiOperation("Finish test item")
+  @PreAuthorize(ALLOWED_TO_REPORT)
+  public OperationCompletionRS finishTestItem(@PathVariable String projectName,
+      @AuthenticationPrincipal ReportPortalUser user,
+      @PathVariable String testItemId, @RequestBody @Validated FinishTestItemRQ finishExecutionRQ) {
+    return finishTestItemHandler.finishTestItem(user,
+        projectExtractor.extractProjectDetails(user, projectName), testItemId, finishExecutionRQ);
+  }
+
+
+  /* Frontend API */
+
+  @Transactional(readOnly = true)
+  @GetMapping("/{itemId}")
+  @ResponseStatus(OK)
+  @ApiOperation("Find test item by ID")
+  public TestItemResource getTestItem(@PathVariable String projectName,
+      @AuthenticationPrincipal ReportPortalUser user,
+      @PathVariable String itemId) {
+    return getTestItemHandler.getTestItem(itemId,
+        projectExtractor.extractProjectDetails(user, projectName), user);
+
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping("/uuid/{itemId}")
+  @ResponseStatus(OK)
+  @ApiOperation("Find test item by UUID")
+  public TestItemResource getTestItemByUuid(@PathVariable String projectName,
+      @AuthenticationPrincipal ReportPortalUser user,
+      @PathVariable String itemId) {
+    return getTestItemHandler.getTestItem(itemId,
+        projectExtractor.extractProjectDetails(user, projectName), user);
+
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping("/suggest/{itemId}")
+  @ResponseStatus(OK)
+  @ApiOperation("Search suggested items in analyzer for provided one")
+  public List<SuggestedItem> getSuggestedItems(@PathVariable String projectName,
+      @AuthenticationPrincipal ReportPortalUser user,
+      @PathVariable Long itemId) {
+    return suggestItemService.suggestItems(itemId,
+        projectExtractor.extractProjectDetails(user, projectName), user);
+  }
+
+  @GetMapping("/suggest/cluster/{clusterId}")
+  @ResponseStatus(OK)
+  @ApiOperation("Search suggested items in analyzer for provided one")
+  public List<SuggestedItem> getSuggestedClusterItems(@PathVariable String projectName,
+      @AuthenticationPrincipal ReportPortalUser user,
+      @PathVariable Long clusterId) {
+    return suggestItemService.suggestClusterItems(clusterId,
+        projectExtractor.extractProjectDetails(user, projectName), user);
+  }
+
+  @Transactional
+  @PutMapping("/suggest/choice")
+  @ResponseStatus(OK)
+  @ApiOperation("Handle user choice from suggested items")
+  public OperationCompletionRS handleSuggestChoose(@PathVariable String projectName,
+      @AuthenticationPrincipal ReportPortalUser user,
+      @RequestBody @Validated List<SuggestInfo> request) {
+    projectExtractor.extractProjectDetails(user, projectName);
+    return suggestItemService.handleSuggestChoice(request);
+  }
+
+  //TODO check pre-defined filter
+  @Transactional(readOnly = true)
+  @GetMapping
+  @ResponseStatus(OK)
+  @ApiOperation("Find test items by specified filter")
+  public Iterable<TestItemResource> getTestItems(@PathVariable String projectName,
+      @AuthenticationPrincipal ReportPortalUser user,
+      @Nullable @RequestParam(value = DEFAULT_FILTER_PREFIX + Condition.EQ
+          + CRITERIA_LAUNCH_ID, required = false) Long launchId,
+      @Nullable @RequestParam(value = FILTER_ID_REQUEST_PARAM, required = false) Long filterId,
+      @RequestParam(value = IS_LATEST_LAUNCHES_REQUEST_PARAM, defaultValue = "false", required = false) boolean isLatest,
+      @RequestParam(value = LAUNCHES_LIMIT_REQUEST_PARAM, defaultValue = "0", required = false) int launchesLimit,
+      @FilterFor(TestItem.class) Filter filter,
+      @FilterFor(TestItem.class) Queryable predefinedFilter,
+      @SortFor(TestItem.class) Pageable pageable) {
+    return getTestItemHandler.getTestItems(
+        new CompositeFilter(Operator.AND, filter, predefinedFilter),
+        pageable,
+        projectExtractor.extractProjectDetails(user, projectName),
+        user,
+        launchId,
+        filterId,
+        isLatest,
+        launchesLimit
+    );
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping("/v2")
+  @ResponseStatus(OK)
+  @ApiOperation("Find test items by specified filter")
+  public Iterable<TestItemResource> getTestItemsV2(@PathVariable String projectName,
+      @AuthenticationPrincipal ReportPortalUser user,
+      @RequestParam Map<String, String> params, @FilterFor(TestItem.class) Filter filter,
+      @FilterFor(TestItem.class) Queryable predefinedFilter,
+      @SortFor(TestItem.class) Pageable pageable) {
+    // tmp return null for project, to fix perf issue
+    if ("libg-140".equalsIgnoreCase(projectName)) {
+      return null;
+    }
+    return getTestItemHandler.getTestItemsByProvider(
+        new CompositeFilter(Operator.AND, filter, predefinedFilter),
+        pageable,
+        projectExtractor.extractProjectDetails(user, projectName),
+        user,
+        params
+    );
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping("/statistics")
+  @ResponseStatus(OK)
+  @ApiOperation("Find accumulated statistics of items by specified filter")
+  public StatisticsResource getTestItems(@PathVariable String projectName,
+      @AuthenticationPrincipal ReportPortalUser user,
+      @FilterFor(TestItem.class) Filter filter,
+      @FilterFor(TestItem.class) Queryable predefinedFilter,
+      @RequestParam Map<String, String> params) {
+    return getTestItemHandler.getStatisticsByProvider(
+        new CompositeFilter(Operator.AND, filter, predefinedFilter),
+        projectExtractor.extractProjectDetails(user, projectName),
+        user,
+        params
+    );
+  }
+
+  @Transactional
+  @DeleteMapping("/{itemId}")
+  @ResponseStatus(OK)
+  @ApiOperation("Delete test item")
+  public OperationCompletionRS deleteTestItem(@PathVariable String projectName,
+      @AuthenticationPrincipal ReportPortalUser user,
+      @PathVariable Long itemId) {
+    return deleteTestItemHandler.deleteTestItem(itemId,
+        projectExtractor.extractProjectDetails(user, projectName), user);
+  }
+
+  @Transactional
+  @DeleteMapping
+  @ResponseStatus(OK)
+  @ApiOperation("Delete test items by specified ids")
+  public List<OperationCompletionRS> deleteTestItems(@PathVariable String projectName,
+      @AuthenticationPrincipal ReportPortalUser user,
+      @RequestParam(value = "ids") Set<Long> ids) {
+    return deleteTestItemHandler.deleteTestItems(ids,
+        projectExtractor.extractProjectDetails(user, projectName), user);
+  }
+
+  @Transactional
+  @PutMapping
+  @ResponseStatus(OK)
+  @ApiOperation("Update issues of specified test items")
+  public List<Issue> defineTestItemIssueType(@PathVariable String projectName,
+      @AuthenticationPrincipal ReportPortalUser user,
+      @RequestBody @Validated DefineIssueRQ request) {
+    return updateTestItemHandler.defineTestItemsIssues(
+        projectExtractor.extractProjectDetails(user, projectName), request, user);
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping("/history")
+  @ResponseStatus(OK)
+  @ApiOperation("Load history of test items")
+  public Iterable<TestItemHistoryElement> getItemsHistory(@PathVariable String projectName,
+      @AuthenticationPrincipal ReportPortalUser user, @FilterFor(TestItem.class) Filter filter,
+      @FilterFor(TestItem.class) Queryable predefinedFilter,
+      @SortFor(TestItem.class) Pageable pageable,
+      @Nullable @RequestParam(value = DEFAULT_FILTER_PREFIX + Condition.EQ
+          + CRITERIA_PARENT_ID, required = false) Long parentId,
+      @Nullable @RequestParam(value = DEFAULT_FILTER_PREFIX + Condition.EQ
+          + CRITERIA_ID, required = false) Long itemId,
+      @Nullable @RequestParam(value = DEFAULT_FILTER_PREFIX + Condition.EQ
+          + CRITERIA_LAUNCH_ID, required = false) Long launchId,
+      @Nullable @RequestParam(value = HISTORY_TYPE_PARAM, required = false) String type,
+      @Nullable @RequestParam(value = FILTER_ID_REQUEST_PARAM, required = false) Long filterId,
+      @RequestParam(value = IS_LATEST_LAUNCHES_REQUEST_PARAM, defaultValue = "false", required = false) boolean isLatest,
+      @RequestParam(value = LAUNCHES_LIMIT_REQUEST_PARAM, defaultValue = "0", required = false) int launchesLimit,
+      @RequestParam(value = HISTORY_DEPTH_PARAM, required = false, defaultValue = HISTORY_DEPTH_DEFAULT_VALUE) int historyDepth) {
+
+    return testItemsHistoryHandler.getItemsHistory(
+        projectExtractor.extractProjectDetails(user, projectName),
+        new CompositeFilter(Operator.AND, filter, predefinedFilter),
+        pageable,
+        HistoryRequestParams.of(historyDepth, parentId, itemId, launchId, type, filterId,
+            launchesLimit, isLatest),
+        user
+    );
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping("/ticket/ids")
+  @ResponseStatus(OK)
+  @ApiOperation("Get tickets that contains a term as a part inside for specified launch")
+  public List<String> getTicketIds(@AuthenticationPrincipal ReportPortalUser user,
+      @PathVariable String projectName,
+      @RequestParam(value = "launch") Long id, @RequestParam(value = "term") String term) {
+    return getTestItemHandler.getTicketIds(id, normalizeId(term));
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping("/ticket/ids/all")
+  @ResponseStatus(OK)
+  @ApiOperation("Get tickets that contains a term as a part inside for specified launch")
+  public List<String> getTicketIdsForProject(@AuthenticationPrincipal ReportPortalUser user,
+      @PathVariable String projectName,
+      @RequestParam(value = "term") String term) {
+    return getTestItemHandler.getTicketIds(
+        projectExtractor.extractProjectDetails(user, projectName), normalizeId(term));
+  }
+
+  //TODO EPMRPP-59414
+  @Transactional(readOnly = true)
+  @GetMapping("/attribute/keys")
+  @ResponseStatus(OK)
+  @ApiOperation("Get all unique attribute keys of specified launch")
+  public List<String> getAttributeKeys(@PathVariable String projectName,
+      @AuthenticationPrincipal ReportPortalUser user,
+      @RequestParam(value = "launch") Long id,
+      @RequestParam(value = DEFAULT_FILTER_PREFIX + Condition.CNT
+          + CRITERIA_ITEM_ATTRIBUTE_KEY) String value) {
+    return getTestItemHandler.getAttributeKeys(id, value);
+  }
+
+  //TODO EPMRPP-59414
+  @Transactional(readOnly = true)
+  @GetMapping("/attribute/keys/all")
+  @ResponseStatus(OK)
+  @ApiOperation("Get all unique attribute keys of specified launch")
+  public List<String> getAttributeKeysForProject(@PathVariable String projectName,
+      @AuthenticationPrincipal ReportPortalUser user,
+      @RequestParam(value = DEFAULT_FILTER_PREFIX + Condition.CNT
+          + CRITERIA_ITEM_ATTRIBUTE_KEY) String value,
+      @RequestParam(value = FILTER_ID_REQUEST_PARAM) Long launchFilterId,
+      @RequestParam(value = IS_LATEST_LAUNCHES_REQUEST_PARAM, defaultValue = "false", required = false) boolean isLatest,
+      @RequestParam(value = LAUNCHES_LIMIT_REQUEST_PARAM, defaultValue = "0") int launchesLimit) {
+    return getTestItemHandler.getAttributeKeys(launchFilterId,
+        isLatest,
+        launchesLimit,
+        projectExtractor.extractProjectDetails(user, projectName),
+        value
+    );
+  }
+
+  //TODO EPMRPP-59414
+  @Transactional(readOnly = true)
+  @GetMapping("/attribute/values")
+  @ResponseStatus(OK)
+  @ApiOperation("Get all unique attribute values of specified launch")
+  public List<String> getAttributeValues(@PathVariable String projectName,
+      @AuthenticationPrincipal ReportPortalUser user,
+      @RequestParam(value = "launch") Long id,
+      @RequestParam(value = DEFAULT_FILTER_PREFIX + Condition.EQ
+          + CRITERIA_ITEM_ATTRIBUTE_KEY, required = false) String key,
+      @RequestParam(value = DEFAULT_FILTER_PREFIX + Condition.CNT
+          + CRITERIA_ITEM_ATTRIBUTE_VALUE) String value) {
+    return getTestItemHandler.getAttributeValues(id, key, value);
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping("/step/attribute/keys")
+  @ResponseStatus(OK)
+  @ApiOperation("Get all unique attribute keys of step items under specified project")
+  public List<String> getAttributeKeys(@PathVariable String projectName,
+      @AuthenticationPrincipal ReportPortalUser user,
+      @RequestParam(value = DEFAULT_FILTER_PREFIX + Condition.EQ
+          + CRITERIA_NAME, required = false) String launchName,
+      @RequestParam(value = DEFAULT_FILTER_PREFIX + Condition.CNT
+          + CRITERIA_ITEM_ATTRIBUTE_KEY) String value) {
+    return ofNullable(launchName).filter(StringUtils::isNotBlank)
+        .map(name -> getTestItemHandler.getAttributeKeys(
+            projectExtractor.extractProjectDetails(user, projectName), name, value))
+        .orElseGet(Collections::emptyList);
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping("/step/attribute/values")
+  @ResponseStatus(OK)
+  @ApiOperation("Get all unique attribute values of step items under specified project")
+  public List<String> getAttributeValues(@PathVariable String projectName,
+      @AuthenticationPrincipal ReportPortalUser user,
+      @RequestParam(value = DEFAULT_FILTER_PREFIX + Condition.EQ
+          + CRITERIA_NAME, required = false) String launchName,
+      @RequestParam(value = DEFAULT_FILTER_PREFIX + Condition.EQ
+          + CRITERIA_ITEM_ATTRIBUTE_KEY, required = false) String key,
+      @RequestParam(value = DEFAULT_FILTER_PREFIX + Condition.CNT
+          + CRITERIA_ITEM_ATTRIBUTE_VALUE) String value) {
+    return ofNullable(launchName).filter(StringUtils::isNotBlank)
+        .map(name -> getTestItemHandler.getAttributeValues(
+            projectExtractor.extractProjectDetails(user, projectName), name, key, value))
+        .orElseGet(Collections::emptyList);
+  }
+
+  @Transactional
+  @PutMapping(value = "/info")
+  @PreAuthorize(PROJECT_MANAGER_OR_ADMIN)
+  @ResponseStatus(OK)
+  @ApiOperation("Bulk update attributes and description")
+  public OperationCompletionRS bulkUpdate(@PathVariable String projectName,
+      @RequestBody @Validated BulkInfoUpdateRQ bulkInfoUpdateRQ,
+      @AuthenticationPrincipal ReportPortalUser user) {
+    return updateTestItemHandler.bulkInfoUpdate(bulkInfoUpdateRQ,
+        projectExtractor.extractProjectDetails(user, projectName));
+  }
+
+  @Transactional
+  @PutMapping("/{itemId}/update")
+  @ResponseStatus(OK)
+  @ApiOperation("Update test item")
+  public OperationCompletionRS updateTestItem(@PathVariable String projectName,
+      @AuthenticationPrincipal ReportPortalUser user,
+      @PathVariable Long itemId, @RequestBody @Validated UpdateTestItemRQ rq) {
+    return updateTestItemHandler.updateTestItem(
+        projectExtractor.extractProjectDetails(user, projectName), itemId, rq, user);
+  }
+
+  @Transactional
+  @PutMapping("/issue/link")
+  @ResponseStatus(OK)
+  @ApiOperation("Attach external issue for specified test items")
+  public List<OperationCompletionRS> linkExternalIssues(@PathVariable String projectName,
+      @AuthenticationPrincipal ReportPortalUser user,
+      @RequestBody @Validated LinkExternalIssueRQ rq) {
+    return updateTestItemHandler.processExternalIssues(rq,
+        projectExtractor.extractProjectDetails(user, projectName), user);
+  }
+
+  @Transactional
+  @PutMapping("/issue/unlink")
+  @ResponseStatus(OK)
+  @ApiOperation("Unlink external issue for specified test items")
+  public List<OperationCompletionRS> unlinkExternalIssues(@PathVariable String projectName,
+      @AuthenticationPrincipal ReportPortalUser user,
+      @RequestBody @Validated UnlinkExternalIssueRQ rq) {
+    return updateTestItemHandler.processExternalIssues(rq,
+        projectExtractor.extractProjectDetails(user, projectName), user);
+  }
+
+  @Transactional(readOnly = true)
+  @GetMapping("/items")
+  @ResponseStatus(OK)
+  @ApiOperation("Get test items by specified ids")
+  public List<TestItemResource> getTestItems(@PathVariable String projectName,
+      @AuthenticationPrincipal ReportPortalUser user,
+      @RequestParam(value = "ids") Long[] ids) {
+    return getTestItemHandler.getTestItems(ids,
+        projectExtractor.extractProjectDetails(user, projectName), user);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/UserController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/UserController.java
index 4252f9033d..d2ccfd71c3 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/controller/UserController.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/controller/UserController.java
@@ -89,7 +89,7 @@
 import org.springframework.web.bind.annotation.RestController;
 
 @RestController
-@RequestMapping("/v1/user")
+@RequestMapping("/users")
 public class UserController {
 
   private final CreateUserHandler createUserMessageHandler;
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/LogResourceAssembler.java b/src/main/java/com/epam/ta/reportportal/ws/converter/LogResourceAssembler.java
index a76fa30d37..79910bbbe5 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/LogResourceAssembler.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/LogResourceAssembler.java
@@ -16,7 +16,7 @@
 
 package com.epam.ta.reportportal.ws.converter;
 
-import com.epam.ta.reportportal.entity.log.Log;
+import com.epam.ta.reportportal.entity.log.LogFull;
 import com.epam.ta.reportportal.ws.converter.converters.LogConverter;
 import com.epam.ta.reportportal.ws.model.log.LogResource;
 import org.springframework.stereotype.Service;
@@ -27,10 +27,10 @@
  * @author Andrei Varabyeu
  */
 @Service
-public class LogResourceAssembler extends PagedResourcesAssembler<Log, LogResource> {
+public class LogResourceAssembler extends PagedResourcesAssembler<LogFull, LogResource> {
 
-	@Override
-	public LogResource toResource(Log log) {
-		return LogConverter.TO_RESOURCE.apply(log);
-	}
+  @Override
+  public LogResource toResource(LogFull log) {
+    return LogConverter.TO_RESOURCE.apply(log);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/ResourceAssembler.java b/src/main/java/com/epam/ta/reportportal/ws/converter/ResourceAssembler.java
index 0569f859cc..1d3a44ed54 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/ResourceAssembler.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/ResourceAssembler.java
@@ -16,7 +16,6 @@
 package com.epam.ta.reportportal.ws.converter;
 
 import com.google.common.base.Preconditions;
-
 import java.util.ArrayList;
 import java.util.List;
 import java.util.function.Function;
@@ -26,36 +25,36 @@
  */
 public abstract class ResourceAssembler<T, R> implements Function<T, R> {
 
-	/**
-	 * Converts all given entities into resources.
-	 *
-	 * @param entities must not be {@literal null}.
-	 * @return
-	 * @see #toResource(Object)
-	 */
-	public List<R> toResources(Iterable<? extends T> entities) {
-
-		Preconditions.checkNotNull(entities);
-		List<R> result = new ArrayList<>();
-
-		for (T entity : entities) {
-			result.add(toResource(entity));
-		}
-
-		return result;
-	}
-
-	@Override
-	public R apply(T t) {
-		return toResource(t);
-	}
-
-	/**
-	 * Converts the given entity into an another one
-	 *
-	 * @param entity Entity to convert
-	 * @return Converted entity
-	 */
-	abstract R toResource(T entity);
+  /**
+   * Converts all given entities into resources.
+   *
+   * @param entities must not be {@literal null}.
+   * @return List of resources
+   * @see #toResource(Object)
+   */
+  public List<R> toResources(Iterable<? extends T> entities) {
+
+    Preconditions.checkNotNull(entities);
+    List<R> result = new ArrayList<>();
+
+    for (T entity : entities) {
+      result.add(toResource(entity));
+    }
+
+    return result;
+  }
+
+  @Override
+  public R apply(T t) {
+    return toResource(t);
+  }
+
+  /**
+   * Converts the given entity into an another one
+   *
+   * @param entity Entity to convert
+   * @return Converted entity
+   */
+  abstract R toResource(T entity);
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/TestItemResourceAssembler.java b/src/main/java/com/epam/ta/reportportal/ws/converter/TestItemResourceAssembler.java
index aee42a2be8..cf5ac71417 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/TestItemResourceAssembler.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/TestItemResourceAssembler.java
@@ -16,15 +16,14 @@
 
 package com.epam.ta.reportportal.ws.converter;
 
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.entity.item.PathName;
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.ws.converter.converters.TestItemConverter;
 import com.epam.ta.reportportal.ws.model.TestItemResource;
-import org.springframework.stereotype.Component;
-
 import javax.annotation.Nullable;
-
-import static java.util.Optional.ofNullable;
+import org.springframework.stereotype.Component;
 
 /**
  * @author Pavel Bortnik
@@ -32,14 +31,15 @@
 @Component
 public class TestItemResourceAssembler extends PagedResourcesAssembler<TestItem, TestItemResource> {
 
-	@Override
-	public TestItemResource toResource(TestItem entity) {
-		return TestItemConverter.TO_RESOURCE.apply(entity);
-	}
+  @Override
+  public TestItemResource toResource(TestItem entity) {
+    return TestItemConverter.TO_RESOURCE.apply(entity);
+  }
 
-	public TestItemResource toResource(TestItem entity, @Nullable PathName pathName) {
-		TestItemResource resource = TestItemConverter.TO_RESOURCE.apply(entity);
-		ofNullable(pathName).ifPresent(pn -> resource.setPathNames(TestItemConverter.PATH_NAME_TO_RESOURCE.apply(pn)));
-		return resource;
-	}
+  public TestItemResource toResource(TestItem entity, @Nullable PathName pathName) {
+    TestItemResource resource = TestItemConverter.TO_RESOURCE.apply(entity);
+    ofNullable(pathName).ifPresent(
+        pn -> resource.setPathNames(TestItemConverter.PATH_NAME_TO_RESOURCE.apply(pn)));
+    return resource;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/AttachmentBuilder.java b/src/main/java/com/epam/ta/reportportal/ws/converter/builders/AttachmentBuilder.java
index 2280f86df6..cf8c7027d1 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/AttachmentBuilder.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/builders/AttachmentBuilder.java
@@ -18,7 +18,6 @@
 
 import com.epam.ta.reportportal.commons.BinaryDataMetaInfo;
 import com.epam.ta.reportportal.entity.attachment.Attachment;
-
 import java.util.function.Supplier;
 
 /**
@@ -26,48 +25,49 @@
  */
 public class AttachmentBuilder implements Supplier<Attachment> {
 
-	private final Attachment attachment;
+  private final Attachment attachment;
 
-	public AttachmentBuilder() {
-		this.attachment = new Attachment();
-	}
+  public AttachmentBuilder() {
+    this.attachment = new Attachment();
+  }
 
-	public AttachmentBuilder withFileId(String fileId) {
-		attachment.setFileId(fileId);
-		return this;
-	}
+  public AttachmentBuilder withFileId(String fileId) {
+    attachment.setFileId(fileId);
+    return this;
+  }
 
-	public AttachmentBuilder withThumbnailId(String thumbnailId) {
-		attachment.setThumbnailId(thumbnailId);
-		return this;
-	}
+  public AttachmentBuilder withThumbnailId(String thumbnailId) {
+    attachment.setThumbnailId(thumbnailId);
+    return this;
+  }
 
-	public AttachmentBuilder withContentType(String contentType) {
-		attachment.setContentType(contentType);
-		return this;
-	}
+  public AttachmentBuilder withContentType(String contentType) {
+    attachment.setContentType(contentType);
+    return this;
+  }
 
-	public AttachmentBuilder withProjectId(Long projectId) {
-		attachment.setProjectId(projectId);
-		return this;
-	}
+  public AttachmentBuilder withProjectId(Long projectId) {
+    attachment.setProjectId(projectId);
+    return this;
+  }
 
-	public AttachmentBuilder withLaunchId(Long launchId) {
-		attachment.setLaunchId(launchId);
-		return this;
-	}
+  public AttachmentBuilder withLaunchId(Long launchId) {
+    attachment.setLaunchId(launchId);
+    return this;
+  }
 
-	public AttachmentBuilder withItemId(Long itemId) {
-		attachment.setItemId(itemId);
-		return this;
-	}
+  public AttachmentBuilder withItemId(Long itemId) {
+    attachment.setItemId(itemId);
+    return this;
+  }
 
-	public AttachmentBuilder withMetaInfo(BinaryDataMetaInfo metaInfo) {
-		return withFileId(metaInfo.getFileId()).withThumbnailId(metaInfo.getThumbnailFileId()).withContentType(metaInfo.getContentType());
-	}
+  public AttachmentBuilder withMetaInfo(BinaryDataMetaInfo metaInfo) {
+    return withFileId(metaInfo.getFileId()).withThumbnailId(metaInfo.getThumbnailFileId())
+        .withContentType(metaInfo.getContentType());
+  }
 
-	@Override
-	public Attachment get() {
-		return attachment;
-	}
+  @Override
+  public Attachment get() {
+    return attachment;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/IntegrationBuilder.java b/src/main/java/com/epam/ta/reportportal/ws/converter/builders/IntegrationBuilder.java
index d8eebdb2bf..64e946ff33 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/IntegrationBuilder.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/builders/IntegrationBuilder.java
@@ -20,7 +20,6 @@
 import com.epam.ta.reportportal.entity.integration.IntegrationParams;
 import com.epam.ta.reportportal.entity.integration.IntegrationType;
 import com.epam.ta.reportportal.entity.project.Project;
-
 import java.time.LocalDateTime;
 import java.util.function.Supplier;
 
@@ -29,53 +28,53 @@
  */
 public class IntegrationBuilder implements Supplier<Integration> {
 
-	private Integration integration;
+  private Integration integration;
 
-	public IntegrationBuilder() {
-		integration = new Integration();
-	}
+  public IntegrationBuilder() {
+    integration = new Integration();
+  }
 
-	public IntegrationBuilder(Integration integration) {
-		this.integration = integration;
-	}
+  public IntegrationBuilder(Integration integration) {
+    this.integration = integration;
+  }
 
-	public IntegrationBuilder withCreationDate(LocalDateTime date) {
-		this.integration.setCreationDate(date);
-		return this;
-	}
+  public IntegrationBuilder withCreationDate(LocalDateTime date) {
+    this.integration.setCreationDate(date);
+    return this;
+  }
 
-	public IntegrationBuilder withCreator(String creator) {
-		this.integration.setCreator(creator);
-		return this;
-	}
+  public IntegrationBuilder withCreator(String creator) {
+    this.integration.setCreator(creator);
+    return this;
+  }
 
-	public IntegrationBuilder withEnabled(boolean enabled) {
-		this.integration.setEnabled(enabled);
-		return this;
-	}
+  public IntegrationBuilder withEnabled(boolean enabled) {
+    this.integration.setEnabled(enabled);
+    return this;
+  }
 
-	public IntegrationBuilder withName(String name) {
-		this.integration.setName(name);
-		return this;
-	}
+  public IntegrationBuilder withName(String name) {
+    this.integration.setName(name);
+    return this;
+  }
 
-	public IntegrationBuilder withType(IntegrationType type) {
-		this.integration.setType(type);
-		return this;
-	}
+  public IntegrationBuilder withType(IntegrationType type) {
+    this.integration.setType(type);
+    return this;
+  }
 
-	public IntegrationBuilder withProject(Project project) {
-		this.integration.setProject(project);
-		return this;
-	}
+  public IntegrationBuilder withProject(Project project) {
+    this.integration.setProject(project);
+    return this;
+  }
 
-	public IntegrationBuilder withParams(IntegrationParams params) {
-		this.integration.setParams(params);
-		return this;
-	}
+  public IntegrationBuilder withParams(IntegrationParams params) {
+    this.integration.setParams(params);
+    return this;
+  }
 
-	@Override
-	public Integration get() {
-		return integration;
-	}
+  @Override
+  public Integration get() {
+    return integration;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/IntegrationTypeBuilder.java b/src/main/java/com/epam/ta/reportportal/ws/converter/builders/IntegrationTypeBuilder.java
index d65861350b..11300f0e9a 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/IntegrationTypeBuilder.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/builders/IntegrationTypeBuilder.java
@@ -20,60 +20,59 @@
 import com.epam.ta.reportportal.entity.integration.IntegrationType;
 import com.epam.ta.reportportal.entity.integration.IntegrationTypeDetails;
 import com.google.common.collect.Maps;
-
-import javax.validation.constraints.NotNull;
 import java.time.LocalDateTime;
 import java.util.function.Supplier;
+import javax.validation.constraints.NotNull;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public class IntegrationTypeBuilder implements Supplier<IntegrationType> {
 
-	private final IntegrationType integrationType;
+  private final IntegrationType integrationType;
 
-	public IntegrationTypeBuilder() {
-		this.integrationType = new IntegrationType();
-		this.integrationType.setCreationDate(LocalDateTime.now());
-		integrationType.setDetails(createIntegrationTypeDetails());
-	}
+  public IntegrationTypeBuilder() {
+    this.integrationType = new IntegrationType();
+    this.integrationType.setCreationDate(LocalDateTime.now());
+    integrationType.setDetails(createIntegrationTypeDetails());
+  }
 
-	public IntegrationTypeBuilder(final IntegrationType integrationType) {
-		this.integrationType = integrationType;
-		if (this.integrationType.getDetails() == null) {
-			this.integrationType.setDetails(createIntegrationTypeDetails());
-		}
-	}
+  public IntegrationTypeBuilder(final IntegrationType integrationType) {
+    this.integrationType = integrationType;
+    if (this.integrationType.getDetails() == null) {
+      this.integrationType.setDetails(createIntegrationTypeDetails());
+    }
+  }
 
-	public static IntegrationTypeDetails createIntegrationTypeDetails() {
-		IntegrationTypeDetails integrationTypeDetails = new IntegrationTypeDetails();
-		integrationTypeDetails.setDetails(Maps.newHashMap());
-		return integrationTypeDetails;
-	}
+  public static IntegrationTypeDetails createIntegrationTypeDetails() {
+    IntegrationTypeDetails integrationTypeDetails = new IntegrationTypeDetails();
+    integrationTypeDetails.setDetails(Maps.newHashMap());
+    return integrationTypeDetails;
+  }
 
-	public IntegrationTypeBuilder setName(String name) {
-		integrationType.setName(name);
-		return this;
-	}
+  public IntegrationTypeBuilder setName(String name) {
+    integrationType.setName(name);
+    return this;
+  }
 
-	public IntegrationTypeBuilder setIntegrationGroup(IntegrationGroupEnum integrationGroup) {
-		integrationType.setIntegrationGroup(integrationGroup);
-		return this;
-	}
+  public IntegrationTypeBuilder setIntegrationGroup(IntegrationGroupEnum integrationGroup) {
+    integrationType.setIntegrationGroup(integrationGroup);
+    return this;
+  }
 
-	public IntegrationTypeBuilder setDetails(IntegrationTypeDetails typeDetails) {
-		integrationType.setDetails(typeDetails);
-		return this;
-	}
+  public IntegrationTypeBuilder setDetails(IntegrationTypeDetails typeDetails) {
+    integrationType.setDetails(typeDetails);
+    return this;
+  }
 
-	public IntegrationTypeBuilder setEnabled(boolean enabled) {
-		integrationType.setEnabled(enabled);
-		return this;
-	}
+  public IntegrationTypeBuilder setEnabled(boolean enabled) {
+    integrationType.setEnabled(enabled);
+    return this;
+  }
 
-	@NotNull
-	@Override
-	public IntegrationType get() {
-		return integrationType;
-	}
+  @NotNull
+  @Override
+  public IntegrationType get() {
+    return integrationType;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/IssueEntityBuilder.java b/src/main/java/com/epam/ta/reportportal/ws/converter/builders/IssueEntityBuilder.java
index 1d88c45933..1944e65a2d 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/IssueEntityBuilder.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/builders/IssueEntityBuilder.java
@@ -19,7 +19,6 @@
 import com.epam.ta.reportportal.entity.item.issue.IssueEntity;
 import com.epam.ta.reportportal.entity.item.issue.IssueType;
 import com.google.common.base.Preconditions;
-
 import java.util.function.Supplier;
 
 /**
@@ -27,42 +26,42 @@
  */
 public class IssueEntityBuilder implements Supplier<IssueEntity> {
 
-	private IssueEntity issueEntity;
+  private IssueEntity issueEntity;
 
-	public IssueEntityBuilder() {
-		this.issueEntity = new IssueEntity();
-	}
+  public IssueEntityBuilder() {
+    this.issueEntity = new IssueEntity();
+  }
 
-	public IssueEntityBuilder(IssueEntity issueEntity) {
-		this.issueEntity = issueEntity;
-	}
+  public IssueEntityBuilder(IssueEntity issueEntity) {
+    this.issueEntity = issueEntity;
+  }
 
-	public IssueEntityBuilder addIssueType(IssueType issueType) {
-		Preconditions.checkNotNull(issueType);
-		issueEntity.setIssueType(issueType);
-		return this;
-	}
+  public IssueEntityBuilder addIssueType(IssueType issueType) {
+    Preconditions.checkNotNull(issueType);
+    issueEntity.setIssueType(issueType);
+    return this;
+  }
 
-	public IssueEntityBuilder addDescription(String comment) {
-		if (null != comment) {
-			issueEntity.setIssueDescription(comment.trim());
-		}
-		return this;
-	}
+  public IssueEntityBuilder addDescription(String comment) {
+    if (null != comment) {
+      issueEntity.setIssueDescription(comment.trim());
+    }
+    return this;
+  }
 
-	public IssueEntityBuilder addIgnoreFlag(boolean ignoreAnalyzer) {
-		issueEntity.setIgnoreAnalyzer(ignoreAnalyzer);
-		return this;
-	}
+  public IssueEntityBuilder addIgnoreFlag(boolean ignoreAnalyzer) {
+    issueEntity.setIgnoreAnalyzer(ignoreAnalyzer);
+    return this;
+  }
 
-	public IssueEntityBuilder addAutoAnalyzedFlag(boolean autoAnalyzed) {
-		issueEntity.setAutoAnalyzed(autoAnalyzed);
-		return this;
-	}
+  public IssueEntityBuilder addAutoAnalyzedFlag(boolean autoAnalyzed) {
+    issueEntity.setAutoAnalyzed(autoAnalyzed);
+    return this;
+  }
 
-	@Override
-	public IssueEntity get() {
-		return this.issueEntity;
-	}
+  @Override
+  public IssueEntity get() {
+    return this.issueEntity;
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/IssueTypeBuilder.java b/src/main/java/com/epam/ta/reportportal/ws/converter/builders/IssueTypeBuilder.java
index 60069092e8..39c4ca1ce7 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/IssueTypeBuilder.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/builders/IssueTypeBuilder.java
@@ -19,7 +19,6 @@
 import com.epam.ta.reportportal.entity.item.issue.IssueGroup;
 import com.epam.ta.reportportal.entity.item.issue.IssueType;
 import com.epam.ta.reportportal.entity.project.Project;
-
 import java.util.function.Supplier;
 
 /**
@@ -27,53 +26,53 @@
  */
 public class IssueTypeBuilder implements Supplier<IssueType> {
 
-	private IssueType issueType;
+  private IssueType issueType;
 
-	public IssueTypeBuilder() {
-		this.issueType = new IssueType();
-	}
+  public IssueTypeBuilder() {
+    this.issueType = new IssueType();
+  }
 
-	public IssueTypeBuilder(IssueType issueType) {
-		this.issueType = issueType;
-	}
+  public IssueTypeBuilder(IssueType issueType) {
+    this.issueType = issueType;
+  }
 
-	public IssueTypeBuilder addLocator(String locator) {
-		issueType.setLocator(locator);
-		return this;
-	}
+  public IssueTypeBuilder addLocator(String locator) {
+    issueType.setLocator(locator);
+    return this;
+  }
 
-	public IssueTypeBuilder addIssueGroup(IssueGroup issueGroup) {
-		issueType.setIssueGroup(issueGroup);
-		return this;
-	}
+  public IssueTypeBuilder addIssueGroup(IssueGroup issueGroup) {
+    issueType.setIssueGroup(issueGroup);
+    return this;
+  }
 
-	public IssueTypeBuilder addLongName(String longName) {
-		issueType.setLongName(longName);
-		return this;
-	}
+  public IssueTypeBuilder addLongName(String longName) {
+    issueType.setLongName(longName);
+    return this;
+  }
 
-	public IssueTypeBuilder addShortName(String shortName) {
-		issueType.setShortName(shortName.toUpperCase());
-		return this;
-	}
+  public IssueTypeBuilder addShortName(String shortName) {
+    issueType.setShortName(shortName.toUpperCase());
+    return this;
+  }
 
-	public IssueTypeBuilder addHexColor(String color) {
-		issueType.setHexColor(color);
-		return this;
-	}
+  public IssueTypeBuilder addHexColor(String color) {
+    issueType.setHexColor(color);
+    return this;
+  }
 
-	public IssueTypeBuilder addProject(Project project) {
-		//		issueType.getProjects().add(project);
-		return this;
-	}
+  public IssueTypeBuilder addProject(Project project) {
+    //		issueType.getProjects().add(project);
+    return this;
+  }
 
-	//	public IssueTypeBuilder addProjectList(List<Project> projects) {
-	//		issueType.getProjects().addAll(projects);
-	//		return this;
-	//	}
+  //	public IssueTypeBuilder addProjectList(List<Project> projects) {
+  //		issueType.getProjects().addAll(projects);
+  //		return this;
+  //	}
 
-	@Override
-	public IssueType get() {
-		return issueType;
-	}
+  @Override
+  public IssueType get() {
+    return issueType;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/LaunchBuilder.java b/src/main/java/com/epam/ta/reportportal/ws/converter/builders/LaunchBuilder.java
index 649c542896..de875316f3 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/LaunchBuilder.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/builders/LaunchBuilder.java
@@ -16,6 +16,9 @@
 
 package com.epam.ta.reportportal.ws.converter.builders;
 
+import static com.epam.ta.reportportal.ws.converter.converters.ItemAttributeConverter.FROM_RESOURCE;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.EntityUtils;
 import com.epam.ta.reportportal.entity.ItemAttribute;
 import com.epam.ta.reportportal.entity.enums.LaunchModeEnum;
@@ -28,112 +31,110 @@
 import com.epam.ta.reportportal.ws.model.launch.Mode;
 import com.epam.ta.reportportal.ws.model.launch.StartLaunchRQ;
 import com.google.common.base.Preconditions;
-import org.apache.commons.lang3.StringUtils;
-
 import java.util.Date;
 import java.util.Optional;
 import java.util.Set;
 import java.util.UUID;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.ws.converter.converters.ItemAttributeConverter.FROM_RESOURCE;
-import static java.util.Optional.ofNullable;
+import org.apache.commons.lang3.StringUtils;
 
 public class LaunchBuilder implements Supplier<Launch> {
 
-	private static final int LAUNCH_DESCRIPTION_LENGTH_LIMIT = 2048;
-	private static final int DESCRIPTION_START_SYMBOL_INDEX = 0;
-
-	private Launch launch;
-
-	public LaunchBuilder() {
-		this.launch = new Launch();
-	}
-
-	public LaunchBuilder(Launch launch) {
-		this.launch = launch;
-	}
-
-	public LaunchBuilder addStartRQ(StartLaunchRQ request) {
-		Preconditions.checkNotNull(request, ErrorType.BAD_REQUEST_ERROR);
-		launch.setStartTime(EntityUtils.TO_LOCAL_DATE_TIME.apply(request.getStartTime()));
-		launch.setName(request.getName().trim());
-		launch.setStatus(StatusEnum.IN_PROGRESS);
-		launch.setUuid(Optional.ofNullable(request.getUuid()).orElse(UUID.randomUUID().toString()));
-		addDescription(request.getDescription());
-		LaunchModeEnum.findByName(ofNullable(request.getMode()).map(Enum::name).orElse(LaunchModeEnum.DEFAULT.name()))
-				.ifPresent(it -> launch.setMode(it));
-		return this;
-	}
-
-	public LaunchBuilder addDescription(String description) {
-		ofNullable(description).ifPresent(it -> launch.setDescription(StringUtils.substring(it.trim(),
-				DESCRIPTION_START_SYMBOL_INDEX,
-				LAUNCH_DESCRIPTION_LENGTH_LIMIT
-		)));
-		return this;
-	}
-
-	public LaunchBuilder addUserId(Long userId) {
-		launch.setUserId(userId);
-		return this;
-	}
-
-	public LaunchBuilder addProject(Long projectId) {
-		launch.setProjectId(projectId);
-		return this;
-	}
-
-	public LaunchBuilder addAttribute(ItemAttributeResource attributeResource) {
-		ItemAttribute itemAttribute = FROM_RESOURCE.apply(attributeResource);
-		itemAttribute.setLaunch(launch);
-		launch.getAttributes().add(itemAttribute);
-		return this;
-	}
-
-	public LaunchBuilder addAttributes(Set<ItemAttributesRQ> attributes) {
-		ofNullable(attributes).ifPresent(it -> launch.getAttributes().addAll(it.stream().map(val -> {
-			ItemAttribute itemAttribute = FROM_RESOURCE.apply(val);
-			itemAttribute.setLaunch(launch);
-			return itemAttribute;
-		}).collect(Collectors.toSet())));
-		return this;
-	}
-
-	public LaunchBuilder overwriteAttributes(Set<ItemAttributeResource> attributes) {
-		if (attributes != null) {
-			final Set<ItemAttribute> overwrittenAttributes = launch.getAttributes()
-					.stream()
-					.filter(ItemAttribute::isSystem)
-					.collect(Collectors.toSet());
-			attributes.stream().map(val -> {
-				ItemAttribute itemAttribute = FROM_RESOURCE.apply(val);
-				itemAttribute.setLaunch(launch);
-				return itemAttribute;
-			}).forEach(overwrittenAttributes::add);
-			launch.setAttributes(overwrittenAttributes);
-		}
-		return this;
-	}
-
-	public LaunchBuilder addMode(Mode mode) {
-		ofNullable(mode).ifPresent(it -> launch.setMode(LaunchModeEnum.valueOf(it.name())));
-		return this;
-	}
-
-	public LaunchBuilder addStatus(String status) {
-		launch.setStatus(StatusEnum.fromValue(status).orElseThrow(() -> new ReportPortalException(ErrorType.INCORRECT_FINISH_STATUS)));
-		return this;
-	}
-
-	public LaunchBuilder addEndTime(Date date) {
-		launch.setEndTime(EntityUtils.TO_LOCAL_DATE_TIME.apply(date));
-		return this;
-	}
-
-	@Override
-	public Launch get() {
-		return launch;
-	}
+  private static final int LAUNCH_DESCRIPTION_LENGTH_LIMIT = 2048;
+  private static final int DESCRIPTION_START_SYMBOL_INDEX = 0;
+
+  private Launch launch;
+
+  public LaunchBuilder() {
+    this.launch = new Launch();
+  }
+
+  public LaunchBuilder(Launch launch) {
+    this.launch = launch;
+  }
+
+  public LaunchBuilder addStartRQ(StartLaunchRQ request) {
+    Preconditions.checkNotNull(request, ErrorType.BAD_REQUEST_ERROR);
+    launch.setStartTime(EntityUtils.TO_LOCAL_DATE_TIME.apply(request.getStartTime()));
+    launch.setName(request.getName().trim());
+    launch.setStatus(StatusEnum.IN_PROGRESS);
+    launch.setUuid(Optional.ofNullable(request.getUuid()).orElse(UUID.randomUUID().toString()));
+    addDescription(request.getDescription());
+    LaunchModeEnum.findByName(
+            ofNullable(request.getMode()).map(Enum::name).orElse(LaunchModeEnum.DEFAULT.name()))
+        .ifPresent(it -> launch.setMode(it));
+    return this;
+  }
+
+  public LaunchBuilder addDescription(String description) {
+    ofNullable(description).ifPresent(it -> launch.setDescription(StringUtils.substring(it.trim(),
+        DESCRIPTION_START_SYMBOL_INDEX,
+        LAUNCH_DESCRIPTION_LENGTH_LIMIT
+    )));
+    return this;
+  }
+
+  public LaunchBuilder addUserId(Long userId) {
+    launch.setUserId(userId);
+    return this;
+  }
+
+  public LaunchBuilder addProject(Long projectId) {
+    launch.setProjectId(projectId);
+    return this;
+  }
+
+  public LaunchBuilder addAttribute(ItemAttributeResource attributeResource) {
+    ItemAttribute itemAttribute = FROM_RESOURCE.apply(attributeResource);
+    itemAttribute.setLaunch(launch);
+    launch.getAttributes().add(itemAttribute);
+    return this;
+  }
+
+  public LaunchBuilder addAttributes(Set<ItemAttributesRQ> attributes) {
+    ofNullable(attributes).ifPresent(it -> launch.getAttributes().addAll(it.stream().map(val -> {
+      ItemAttribute itemAttribute = FROM_RESOURCE.apply(val);
+      itemAttribute.setLaunch(launch);
+      return itemAttribute;
+    }).collect(Collectors.toSet())));
+    return this;
+  }
+
+  public LaunchBuilder overwriteAttributes(Set<ItemAttributeResource> attributes) {
+    if (attributes != null) {
+      final Set<ItemAttribute> overwrittenAttributes = launch.getAttributes()
+          .stream()
+          .filter(ItemAttribute::isSystem)
+          .collect(Collectors.toSet());
+      attributes.stream().map(val -> {
+        ItemAttribute itemAttribute = FROM_RESOURCE.apply(val);
+        itemAttribute.setLaunch(launch);
+        return itemAttribute;
+      }).forEach(overwrittenAttributes::add);
+      launch.setAttributes(overwrittenAttributes);
+    }
+    return this;
+  }
+
+  public LaunchBuilder addMode(Mode mode) {
+    ofNullable(mode).ifPresent(it -> launch.setMode(LaunchModeEnum.valueOf(it.name())));
+    return this;
+  }
+
+  public LaunchBuilder addStatus(String status) {
+    launch.setStatus(StatusEnum.fromValue(status)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.INCORRECT_FINISH_STATUS)));
+    return this;
+  }
+
+  public LaunchBuilder addEndTime(Date date) {
+    launch.setEndTime(EntityUtils.TO_LOCAL_DATE_TIME.apply(date));
+    return this;
+  }
+
+  @Override
+  public Launch get() {
+    return launch;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/LogBuilder.java b/src/main/java/com/epam/ta/reportportal/ws/converter/builders/LogFullBuilder.java
similarity index 51%
rename from src/main/java/com/epam/ta/reportportal/ws/converter/builders/LogBuilder.java
rename to src/main/java/com/epam/ta/reportportal/ws/converter/builders/LogFullBuilder.java
index 8fd4622cdc..9f679b4dce 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/LogBuilder.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/builders/LogFullBuilder.java
@@ -16,55 +16,54 @@
 
 package com.epam.ta.reportportal.ws.converter.builders;
 
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.EntityUtils;
 import com.epam.ta.reportportal.entity.enums.LogLevel;
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.launch.Launch;
-import com.epam.ta.reportportal.entity.log.Log;
+import com.epam.ta.reportportal.entity.log.LogFull;
 import com.epam.ta.reportportal.ws.model.log.SaveLogRQ;
-
 import java.util.UUID;
 import java.util.function.Supplier;
 
-import static java.util.Optional.ofNullable;
-
 /**
  * @author Pavel Bortnik
  */
-public class LogBuilder implements Supplier<Log> {
+public class LogFullBuilder implements Supplier<LogFull> {
 
-	private final Log log;
+  private final LogFull logFull;
 
-	public LogBuilder() {
-		log = new Log();
-	}
+  public LogFullBuilder() {
+    logFull = new LogFull();
+  }
 
-	public LogBuilder addSaveLogRq(SaveLogRQ createLogRQ) {
-		log.setLogLevel(LogLevel.toCustomLogLevel(createLogRQ.getLevel()));
-		log.setLogMessage(ofNullable(createLogRQ.getMessage()).orElse("NULL"));
-		log.setLogTime(EntityUtils.TO_LOCAL_DATE_TIME.apply(createLogRQ.getLogTime()));
-		log.setUuid(ofNullable(createLogRQ.getUuid()).orElse(UUID.randomUUID().toString()));
-		return this;
-	}
+  public LogFullBuilder addSaveLogRq(SaveLogRQ createLogRQ) {
+    logFull.setLogLevel(LogLevel.toCustomLogLevel(createLogRQ.getLevel()));
+    logFull.setLogMessage(ofNullable(createLogRQ.getMessage()).orElse("NULL"));
+    logFull.setLogTime(EntityUtils.TO_LOCAL_DATE_TIME.apply(createLogRQ.getLogTime()));
+    logFull.setUuid(ofNullable(createLogRQ.getUuid()).orElse(UUID.randomUUID().toString()));
+    return this;
+  }
 
-	public LogBuilder addTestItem(TestItem testItem) {
-		log.setTestItem(testItem);
-		return this;
-	}
+  public LogFullBuilder addTestItem(TestItem testItem) {
+    logFull.setTestItem(testItem);
+    return this;
+  }
 
-	public LogBuilder addLaunch(Launch launch) {
-		log.setLaunch(launch);
-		return this;
-	}
+  public LogFullBuilder addLaunch(Launch launch) {
+    logFull.setLaunch(launch);
+    return this;
+  }
 
-	public LogBuilder addProjectId(Long projectId) {
-		log.setProjectId(projectId);
-		return this;
-	}
+  public LogFullBuilder addProjectId(Long projectId) {
+    logFull.setProjectId(projectId);
+    return this;
+  }
 
-	@Override
-	public Log get() {
-		return log;
-	}
+  @Override
+  public LogFull get() {
+    return logFull;
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/PatternTemplateBuilder.java b/src/main/java/com/epam/ta/reportportal/ws/converter/builders/PatternTemplateBuilder.java
index 18f009392f..f60ef03f0c 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/PatternTemplateBuilder.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/builders/PatternTemplateBuilder.java
@@ -22,59 +22,60 @@
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.epam.ta.reportportal.ws.model.project.config.pattern.CreatePatternTemplateRQ;
-import org.apache.commons.lang3.StringUtils;
-
 import java.util.function.Supplier;
+import org.apache.commons.lang3.StringUtils;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public class PatternTemplateBuilder implements Supplier<PatternTemplate> {
 
-	private PatternTemplate patternTemplate;
+  private PatternTemplate patternTemplate;
 
-	public PatternTemplateBuilder() {
-		patternTemplate = new PatternTemplate();
-	}
+  public PatternTemplateBuilder() {
+    patternTemplate = new PatternTemplate();
+  }
 
-	public PatternTemplateBuilder withCreateRequest(CreatePatternTemplateRQ createRequest) {
-		patternTemplate.setTemplateType(PatternTemplateType.fromString(createRequest.getType()).orElseThrow(() -> new ReportPortalException(
-				ErrorType.BAD_REQUEST_ERROR,
-				Suppliers.formattedSupplier("Unknown pattern template type - '{}'", createRequest.getType()).get()
-		)));
-		patternTemplate.setName(StringUtils.trim(createRequest.getName()));
-		patternTemplate.setValue(createRequest.getValue());
-		patternTemplate.setEnabled(createRequest.getEnabled());
-		return this;
-	}
+  public PatternTemplateBuilder withCreateRequest(CreatePatternTemplateRQ createRequest) {
+    patternTemplate.setTemplateType(PatternTemplateType.fromString(createRequest.getType())
+        .orElseThrow(() -> new ReportPortalException(
+            ErrorType.BAD_REQUEST_ERROR,
+            Suppliers.formattedSupplier("Unknown pattern template type - '{}'",
+                createRequest.getType()).get()
+        )));
+    patternTemplate.setName(StringUtils.trim(createRequest.getName()));
+    patternTemplate.setValue(createRequest.getValue());
+    patternTemplate.setEnabled(createRequest.getEnabled());
+    return this;
+  }
 
-	public PatternTemplateBuilder withName(String name) {
-		patternTemplate.setName(StringUtils.trim(name));
-		return this;
-	}
+  public PatternTemplateBuilder withName(String name) {
+    patternTemplate.setName(StringUtils.trim(name));
+    return this;
+  }
 
-	public PatternTemplateBuilder withValue(String value) {
-		patternTemplate.setValue(value);
-		return this;
-	}
+  public PatternTemplateBuilder withValue(String value) {
+    patternTemplate.setValue(value);
+    return this;
+  }
 
-	public PatternTemplateBuilder withType(PatternTemplateType type) {
-		patternTemplate.setTemplateType(type);
-		return this;
-	}
+  public PatternTemplateBuilder withType(PatternTemplateType type) {
+    patternTemplate.setTemplateType(type);
+    return this;
+  }
 
-	public PatternTemplateBuilder withEnabled(boolean isEnabled) {
-		patternTemplate.setEnabled(isEnabled);
-		return this;
-	}
+  public PatternTemplateBuilder withEnabled(boolean isEnabled) {
+    patternTemplate.setEnabled(isEnabled);
+    return this;
+  }
 
-	public PatternTemplateBuilder withProjectId(Long projectId) {
-		patternTemplate.setProjectId(projectId);
-		return this;
-	}
+  public PatternTemplateBuilder withProjectId(Long projectId) {
+    patternTemplate.setProjectId(projectId);
+    return this;
+  }
 
-	@Override
-	public PatternTemplate get() {
-		return patternTemplate;
-	}
+  @Override
+  public PatternTemplate get() {
+    return patternTemplate;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/TestCaseIdEntry.java b/src/main/java/com/epam/ta/reportportal/ws/converter/builders/TestCaseIdEntry.java
index d0c8d82df4..5a39771e01 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/TestCaseIdEntry.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/builders/TestCaseIdEntry.java
@@ -23,37 +23,37 @@
  */
 public class TestCaseIdEntry {
 
-	private String id;
+  private String id;
 
-	private int hash;
+  private int hash;
 
-	public String getId() {
-		return id;
-	}
+  public String getId() {
+    return id;
+  }
 
-	public int getHash() {
-		return hash;
-	}
+  public int getHash() {
+    return hash;
+  }
 
-	TestCaseIdEntry(String id, int hash) {
-		this.id = isCropNeeded(id) ? cropTestCaseId(id) : id;
-		this.hash = hash;
-	}
+  TestCaseIdEntry(String id, int hash) {
+    this.id = isCropNeeded(id) ? cropTestCaseId(id) : id;
+    this.hash = hash;
+  }
 
-	TestCaseIdEntry(int hash) {
-		this.hash = hash;
-	}
+  TestCaseIdEntry(int hash) {
+    this.hash = hash;
+  }
 
-	public static TestCaseIdEntry empty() {
-		return new TestCaseIdEntry(0);
-	}
+  public static TestCaseIdEntry empty() {
+    return new TestCaseIdEntry(0);
+  }
 
-	private static boolean isCropNeeded(String testCaseId) {
-		return Objects.nonNull(testCaseId) && testCaseId.length() > 1024;
-	}
+  private static boolean isCropNeeded(String testCaseId) {
+    return Objects.nonNull(testCaseId) && testCaseId.length() > 1024;
+  }
 
-	private static String cropTestCaseId(String testCaseId) {
-		return testCaseId.substring(0, 1011) + "[" + testCaseId.substring(1011).hashCode() + "]";
-	}
+  private static String cropTestCaseId(String testCaseId) {
+    return testCaseId.substring(0, 1011) + "[" + testCaseId.substring(1011).hashCode() + "]";
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/TestItemBuilder.java b/src/main/java/com/epam/ta/reportportal/ws/converter/builders/TestItemBuilder.java
index 2a2eab4111..504b9885b0 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/TestItemBuilder.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/builders/TestItemBuilder.java
@@ -16,6 +16,10 @@
 
 package com.epam.ta.reportportal.ws.converter.builders;
 
+import static com.epam.ta.reportportal.ws.converter.converters.ItemAttributeConverter.FROM_RESOURCE;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.EntityUtils;
 import com.epam.ta.reportportal.entity.ItemAttribute;
 import com.epam.ta.reportportal.entity.enums.StatusEnum;
@@ -29,175 +33,197 @@
 import com.epam.ta.reportportal.ws.model.StartTestItemRQ;
 import com.epam.ta.reportportal.ws.model.attribute.ItemAttributeResource;
 import com.epam.ta.reportportal.ws.model.attribute.ItemAttributesRQ;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.lang3.StringUtils;
-
-import javax.annotation.Nullable;
 import java.time.LocalDateTime;
 import java.time.temporal.ChronoUnit;
-import java.util.*;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.UUID;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.ws.converter.converters.ItemAttributeConverter.FROM_RESOURCE;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static java.util.Optional.ofNullable;
+import javax.annotation.Nullable;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
 
 public class TestItemBuilder implements Supplier<TestItem> {
 
-	private static final int TEST_ITEM_DESCRIPTION_LENGTH_LIMIT = 2048;
-	private static final int DESCRIPTION_START_SYMBOL_INDEX = 0;
-	public static final String PARAMETER_NULL_VALUE = "NULL";
-
-	private TestItem testItem;
-
-	public TestItemBuilder() {
-		testItem = new TestItem();
-	}
-
-	public TestItemBuilder(TestItem testItem) {
-		this.testItem = testItem;
-	}
-
-	public TestItemBuilder addStartItemRequest(StartTestItemRQ rq) {
-
-		testItem.setStartTime(EntityUtils.TO_LOCAL_DATE_TIME.apply(rq.getStartTime()));
-		testItem.setName(rq.getName().trim());
-		testItem.setUniqueId(rq.getUniqueId());
-		testItem.setUuid(Optional.ofNullable(rq.getUuid()).orElse(UUID.randomUUID().toString()));
-		testItem.setHasStats(rq.isHasStats());
-
-		TestCaseIdEntry testCaseIdEntry = processTestCaseId(rq);
-		testItem.setTestCaseId(testCaseIdEntry.getId());
-		testItem.setTestCaseHash(testCaseIdEntry.getHash());
-
-		testItem.setCodeRef(rq.getCodeRef());
-
-		TestItemResults testItemResults = new TestItemResults();
-		testItemResults.setStatus(StatusEnum.IN_PROGRESS);
-
-		testItemResults.setTestItem(testItem);
-		testItem.setItemResults(testItemResults);
-
-		addDescription(rq.getDescription());
-		addParameters(rq.getParameters());
-		addType(rq.getType());
-		return this;
-	}
-
-	public TestItemBuilder addLaunchId(Long launchId) {
-		testItem.setLaunchId(launchId);
-		return this;
-	}
-
-	public TestItemBuilder addParentId(Long parentId) {
-		testItem.setParentId(parentId);
-		return this;
-	}
-
-	public TestItemBuilder addType(String typeValue) {
-		TestItemTypeEnum type = TestItemTypeEnum.fromValue(typeValue)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.UNSUPPORTED_TEST_ITEM_TYPE, typeValue));
-		testItem.setType(type);
-		return this;
-	}
-
-	public TestItemBuilder addDescription(String description) {
-		ofNullable(description).ifPresent(it -> testItem.setDescription(StringUtils.substring(it.trim(),
-				DESCRIPTION_START_SYMBOL_INDEX,
-				TEST_ITEM_DESCRIPTION_LENGTH_LIMIT
-		)));
-		return this;
-	}
-
-	public TestItemBuilder addStatus(StatusEnum statusEnum) {
-		testItem.getItemResults().setStatus(statusEnum);
-		return this;
-	}
-
-	public TestItemBuilder addTestCaseId(@Nullable String testCaseId) {
-		ofNullable(testCaseId).map(caseId -> new TestCaseIdEntry(testCaseId, testCaseId.hashCode())).ifPresent(entry -> {
-			testItem.setTestCaseId(entry.getId());
-			testItem.setTestCaseHash(entry.getHash());
-		});
-		return this;
-	}
-
-	public TestItemBuilder addAttributes(Set<ItemAttributesRQ> attributes) {
-		ofNullable(attributes).ifPresent(it -> testItem.getAttributes().addAll(it.stream().map(val -> {
-			ItemAttribute itemAttribute = FROM_RESOURCE.apply(val);
-			itemAttribute.setTestItem(testItem);
-			return itemAttribute;
-		}).collect(Collectors.toSet())));
-		return this;
-	}
-
-	public TestItemBuilder overwriteAttributes(Set<? extends ItemAttributeResource> attributes) {
-		if (attributes != null) {
-			final Set<ItemAttribute> overwrittenAttributes = testItem.getAttributes()
-					.stream()
-					.filter(ItemAttribute::isSystem)
-					.collect(Collectors.toSet());
-			attributes.stream().map(val -> {
-				ItemAttribute itemAttribute = FROM_RESOURCE.apply(val);
-				itemAttribute.setTestItem(testItem);
-				return itemAttribute;
-			}).forEach(overwrittenAttributes::add);
-			testItem.setAttributes(overwrittenAttributes);
-		}
-		return this;
-	}
-
-	public TestItemBuilder addTestItemResults(TestItemResults testItemResults) {
-		checkNotNull(testItemResults, "Provided value shouldn't be null");
-		testItem.setItemResults(testItemResults);
-		addDuration(testItemResults.getEndTime());
-		return this;
-	}
-
-	public TestItemBuilder addDuration(LocalDateTime endTime) {
-		checkNotNull(endTime, "Provided value shouldn't be null");
-		checkNotNull(testItem.getItemResults(), "Test item results shouldn't be null");
-
-		//converts to seconds
-		testItem.getItemResults().setDuration(ChronoUnit.MILLIS.between(testItem.getStartTime(), endTime) / 1000d);
-		return this;
-	}
-
-	public TestItemBuilder addParameters(List<ParameterResource> parameters) {
-		if (!CollectionUtils.isEmpty(parameters)) {
-			testItem.setParameters(parameters.stream().map(it -> {
-				Parameter parameter = new Parameter();
-				parameter.setKey(it.getKey());
-				parameter.setValue(ofNullable(it.getValue()).orElse(PARAMETER_NULL_VALUE));
-				return parameter;
-			}).collect(Collectors.toSet()));
-		}
-		return this;
-	}
-
-	public static TestCaseIdEntry processTestCaseId(StartTestItemRQ startTestItemRQ) {
-		final String testCaseId = startTestItemRQ.getTestCaseId();
-		if (Objects.nonNull(testCaseId)) {
-			return new TestCaseIdEntry(testCaseId, testCaseId.hashCode());
-		} else {
-			final String codeRef = startTestItemRQ.getCodeRef();
-			if (Objects.nonNull(codeRef)) {
-				String id = compose(codeRef, startTestItemRQ.getParameters());
-				return new TestCaseIdEntry(id, id.hashCode());
-			}
-		}
-		return TestCaseIdEntry.empty();
-	}
-
-	private static String compose(String codeRef, List<ParameterResource> parameters) {
-		return CollectionUtils.isEmpty(parameters) ?
-				codeRef :
-				codeRef + "[" + parameters.stream().map(ParameterResource::getValue).collect(Collectors.joining(",")) + "]";
-	}
-
-	@Override
-	public TestItem get() {
-		return this.testItem;
-	}
+  private static final int TEST_ITEM_DESCRIPTION_LENGTH_LIMIT = 2048;
+  private static final int DESCRIPTION_START_SYMBOL_INDEX = 0;
+  public static final String PARAMETER_NULL_VALUE = "NULL";
+
+  private TestItem testItem;
+
+  public TestItemBuilder() {
+    testItem = new TestItem();
+  }
+
+  public TestItemBuilder(TestItem testItem) {
+    this.testItem = testItem;
+  }
+
+  public TestItemBuilder addStartItemRequest(StartTestItemRQ rq) {
+
+    testItem.setStartTime(EntityUtils.TO_LOCAL_DATE_TIME.apply(rq.getStartTime()));
+    testItem.setName(rq.getName().trim());
+    testItem.setUniqueId(rq.getUniqueId());
+    testItem.setUuid(Optional.ofNullable(rq.getUuid()).orElse(UUID.randomUUID().toString()));
+    testItem.setHasStats(rq.isHasStats());
+
+    TestCaseIdEntry testCaseIdEntry = processTestCaseId(rq);
+    testItem.setTestCaseId(testCaseIdEntry.getId());
+    testItem.setTestCaseHash(testCaseIdEntry.getHash());
+
+    testItem.setCodeRef(rq.getCodeRef());
+
+    TestItemResults testItemResults = new TestItemResults();
+    testItemResults.setStatus(StatusEnum.IN_PROGRESS);
+
+    testItemResults.setTestItem(testItem);
+    testItem.setItemResults(testItemResults);
+
+    addDescription(rq.getDescription());
+    addParameters(rq.getParameters());
+    addType(rq.getType());
+    return this;
+  }
+
+  public TestItemBuilder addLaunchId(Long launchId) {
+    testItem.setLaunchId(launchId);
+    return this;
+  }
+
+  public TestItemBuilder addParentId(Long parentId) {
+    testItem.setParentId(parentId);
+    return this;
+  }
+
+  public TestItemBuilder addType(String typeValue) {
+    TestItemTypeEnum type = TestItemTypeEnum.fromValue(typeValue)
+        .orElseThrow(
+            () -> new ReportPortalException(ErrorType.UNSUPPORTED_TEST_ITEM_TYPE, typeValue));
+    testItem.setType(type);
+    return this;
+  }
+
+  public TestItemBuilder addDescription(String description) {
+    ofNullable(description).ifPresent(it -> testItem.setDescription(StringUtils.substring(it.trim(),
+        DESCRIPTION_START_SYMBOL_INDEX,
+        TEST_ITEM_DESCRIPTION_LENGTH_LIMIT
+    )));
+    return this;
+  }
+
+  public TestItemBuilder addStatus(StatusEnum statusEnum) {
+    testItem.getItemResults().setStatus(statusEnum);
+    return this;
+  }
+
+  public TestItemBuilder addTestCaseId(@Nullable String testCaseId) {
+    ofNullable(testCaseId).map(caseId -> new TestCaseIdEntry(testCaseId, testCaseId.hashCode()))
+        .ifPresent(entry -> {
+          testItem.setTestCaseId(entry.getId());
+          testItem.setTestCaseHash(entry.getHash());
+        });
+    return this;
+  }
+
+  public TestItemBuilder addAttributes(Set<ItemAttributesRQ> attributes) {
+    ofNullable(attributes).ifPresent(it -> testItem.getAttributes().addAll(it.stream().map(val -> {
+      ItemAttribute itemAttribute = FROM_RESOURCE.apply(val);
+      itemAttribute.setTestItem(testItem);
+      return itemAttribute;
+    }).collect(Collectors.toSet())));
+    return this;
+  }
+
+  public TestItemBuilder overwriteAttributesValues(Set<? extends ItemAttributeResource> attributes) {
+    if (attributes != null) {
+      attributes.forEach(val -> {
+        ItemAttribute itemAttribute = FROM_RESOURCE.apply(val);
+        itemAttribute.setTestItem(testItem);
+        Optional<ItemAttribute> existingAttr = testItem.getAttributes().stream()
+            .filter(attr -> Objects.nonNull(attr.getKey()) && attr.getKey()
+                .equals(itemAttribute.getKey()))
+            .findFirst();
+        if (existingAttr.isPresent()) {
+          existingAttr.get().setValue(itemAttribute.getValue());
+        } else {
+          testItem.getAttributes().add(itemAttribute);
+        }
+      });
+    }
+    return this;
+  }
+
+  public TestItemBuilder overwriteAttributes(Set<? extends ItemAttributeResource> attributes) {
+    if (attributes != null) {
+      final Set<ItemAttribute> overwrittenAttributes = testItem.getAttributes()
+          .stream()
+          .filter(ItemAttribute::isSystem)
+          .collect(Collectors.toSet());
+      attributes.stream().map(val -> {
+        ItemAttribute itemAttribute = FROM_RESOURCE.apply(val);
+        itemAttribute.setTestItem(testItem);
+        return itemAttribute;
+      }).forEach(overwrittenAttributes::add);
+      testItem.setAttributes(overwrittenAttributes);
+    }
+    return this;
+  }
+
+  public TestItemBuilder addTestItemResults(TestItemResults testItemResults) {
+    checkNotNull(testItemResults, "Provided value shouldn't be null");
+    testItem.setItemResults(testItemResults);
+    addDuration(testItemResults.getEndTime());
+    return this;
+  }
+
+  public TestItemBuilder addDuration(LocalDateTime endTime) {
+    checkNotNull(endTime, "Provided value shouldn't be null");
+    checkNotNull(testItem.getItemResults(), "Test item results shouldn't be null");
+
+    //converts to seconds
+    testItem.getItemResults()
+        .setDuration(ChronoUnit.MILLIS.between(testItem.getStartTime(), endTime) / 1000d);
+    return this;
+  }
+
+  public TestItemBuilder addParameters(List<ParameterResource> parameters) {
+    if (!CollectionUtils.isEmpty(parameters)) {
+      testItem.setParameters(parameters.stream().map(it -> {
+        Parameter parameter = new Parameter();
+        parameter.setKey(it.getKey());
+        parameter.setValue(ofNullable(it.getValue()).orElse(PARAMETER_NULL_VALUE));
+        return parameter;
+      }).collect(Collectors.toSet()));
+    }
+    return this;
+  }
+
+  public static TestCaseIdEntry processTestCaseId(StartTestItemRQ startTestItemRQ) {
+    final String testCaseId = startTestItemRQ.getTestCaseId();
+    if (Objects.nonNull(testCaseId)) {
+      return new TestCaseIdEntry(testCaseId, testCaseId.hashCode());
+    } else {
+      final String codeRef = startTestItemRQ.getCodeRef();
+      if (Objects.nonNull(codeRef)) {
+        String id = compose(codeRef, startTestItemRQ.getParameters());
+        return new TestCaseIdEntry(id, id.hashCode());
+      }
+    }
+    return TestCaseIdEntry.empty();
+  }
+
+  private static String compose(String codeRef, List<ParameterResource> parameters) {
+    return CollectionUtils.isEmpty(parameters) ?
+        codeRef :
+        codeRef + "[" + parameters.stream().map(ParameterResource::getValue)
+            .collect(Collectors.joining(",")) + "]";
+  }
+
+  @Override
+  public TestItem get() {
+    return this.testItem;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/UserBuilder.java b/src/main/java/com/epam/ta/reportportal/ws/converter/builders/UserBuilder.java
index 97272a07cb..1586fc65f1 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/UserBuilder.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/builders/UserBuilder.java
@@ -16,6 +16,8 @@
 
 package com.epam.ta.reportportal.ws.converter.builders;
 
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.EntityUtils;
 import com.epam.ta.reportportal.entity.Metadata;
 import com.epam.ta.reportportal.entity.user.User;
@@ -23,65 +25,62 @@
 import com.epam.ta.reportportal.entity.user.UserType;
 import com.epam.ta.reportportal.ws.model.user.CreateUserRQConfirm;
 import com.epam.ta.reportportal.ws.model.user.CreateUserRQFull;
-
 import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.function.Supplier;
 
-import static java.util.Optional.ofNullable;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public class UserBuilder implements Supplier<User> {
 
-	public static final String USER_LAST_LOGIN = "last_login";
-	private User user;
+  public static final String USER_LAST_LOGIN = "last_login";
+  private User user;
 
-	public UserBuilder() {
-		user = new User();
-	}
+  public UserBuilder() {
+    user = new User();
+  }
 
-	public UserBuilder(User user) {
-		this.user = user;
-	}
+  public UserBuilder(User user) {
+    this.user = user;
+  }
 
-	public UserBuilder addCreateUserRQ(CreateUserRQConfirm request) {
-		ofNullable(request).ifPresent(r -> fillUser(r.getLogin(), r.getEmail(), r.getFullName()));
-		return this;
-	}
+  public UserBuilder addCreateUserRQ(CreateUserRQConfirm request) {
+    ofNullable(request).ifPresent(r -> fillUser(r.getLogin(), r.getEmail(), r.getFullName()));
+    return this;
+  }
 
-	public UserBuilder addCreateUserFullRQ(CreateUserRQFull request) {
-		ofNullable(request).ifPresent(it -> fillUser(it.getLogin(), it.getEmail(), it.getFullName()));
-		return this;
-	}
+  public UserBuilder addCreateUserFullRQ(CreateUserRQFull request) {
+    ofNullable(request).ifPresent(it -> fillUser(it.getLogin(), it.getEmail(), it.getFullName()));
+    return this;
+  }
 
-	public UserBuilder addPassword(String password) {
-		user.setPassword(password);
-		return this;
-	}
+  public UserBuilder addPassword(String password) {
+    user.setPassword(password);
+    return this;
+  }
 
-	public UserBuilder addUserRole(UserRole userRole) {
-		user.setRole(userRole);
-		return this;
-	}
+  public UserBuilder addUserRole(UserRole userRole) {
+    user.setRole(userRole);
+    return this;
+  }
 
-	@Override
-	public User get() {
+  @Override
+  public User get() {
 
-		//TODO check for existing of the default project etc.
-		return user;
-	}
+    //TODO check for existing of the default project etc.
+    return user;
+  }
 
-	private void fillUser(String login, String email, String fullName) {
-		user.setLogin(EntityUtils.normalizeId(login));
-		ofNullable(email).map(String::trim).map(EntityUtils::normalizeId).ifPresent(user::setEmail);
-		user.setFullName(fullName);
-		user.setUserType(UserType.INTERNAL);
-		user.setExpired(false);
-		Map<String, Object> meta = new HashMap<>();
-		meta.put(USER_LAST_LOGIN, new Date());
-		user.setMetadata(new Metadata(meta));
-	}
+  private void fillUser(String login, String email, String fullName) {
+    user.setLogin(EntityUtils.normalizeId(login));
+    ofNullable(email).map(String::trim).map(EntityUtils::normalizeId).ifPresent(user::setEmail);
+    user.setFullName(fullName);
+    user.setUserType(UserType.INTERNAL);
+    user.setExpired(false);
+    Map<String, Object> meta = new HashMap<>();
+    meta.put(USER_LAST_LOGIN, new Date());
+    user.setMetadata(new Metadata(meta));
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/UserPreferenceBuilder.java b/src/main/java/com/epam/ta/reportportal/ws/converter/builders/UserPreferenceBuilder.java
index 6da3de8ede..6780a78d1b 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/UserPreferenceBuilder.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/builders/UserPreferenceBuilder.java
@@ -20,7 +20,6 @@
 import com.epam.ta.reportportal.entity.preference.UserPreference;
 import com.epam.ta.reportportal.entity.project.Project;
 import com.epam.ta.reportportal.entity.user.User;
-
 import java.util.function.Supplier;
 
 /**
@@ -28,33 +27,33 @@
  */
 public class UserPreferenceBuilder implements Supplier<UserPreference> {
 
-	private UserPreference userPreference;
-
-	public UserPreferenceBuilder() {
-		userPreference = new UserPreference();
-	}
-
-	public UserPreferenceBuilder withProject(Long id) {
-		Project project = new Project();
-		project.setId(id);
-		userPreference.setProject(project);
-		return this;
-	}
-
-	public UserPreferenceBuilder withUser(Long id) {
-		User user = new User();
-		user.setId(id);
-		userPreference.setUser(user);
-		return this;
-	}
-
-	public UserPreferenceBuilder withFilter(UserFilter filter) {
-		userPreference.setFilter(filter);
-		return this;
-	}
-
-	@Override
-	public UserPreference get() {
-		return userPreference;
-	}
+  private UserPreference userPreference;
+
+  public UserPreferenceBuilder() {
+    userPreference = new UserPreference();
+  }
+
+  public UserPreferenceBuilder withProject(Long id) {
+    Project project = new Project();
+    project.setId(id);
+    userPreference.setProject(project);
+    return this;
+  }
+
+  public UserPreferenceBuilder withUser(Long id) {
+    User user = new User();
+    user.setId(id);
+    userPreference.setUser(user);
+    return this;
+  }
+
+  public UserPreferenceBuilder withFilter(UserFilter filter) {
+    userPreference.setFilter(filter);
+    return this;
+  }
+
+  @Override
+  public UserPreference get() {
+    return userPreference;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ActivityEventConverter.java b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ActivityEventConverter.java
index e88c449149..3889e3bab4 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ActivityEventConverter.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ActivityEventConverter.java
@@ -19,6 +19,7 @@
 import com.epam.ta.reportportal.commons.EntityUtils;
 import com.epam.ta.reportportal.entity.activity.Activity;
 import com.epam.ta.reportportal.ws.model.ActivityEventResource;
+import java.util.Objects;
 import java.util.function.Function;
 
 /**
@@ -43,6 +44,7 @@ private ActivityEventConverter() {
           .projectName(activity.getProjectName())
           .subjectName(activity.getSubjectName())
           .subjectType(activity.getSubjectType().getValue())
+          .subjectId(Objects.toString(activity.getSubjectId(), null))
           .details(activity.getDetails())
           .build();
 
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/BaseEntityConverter.java b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/BaseEntityConverter.java
index 04fc3153d3..96f6c2086b 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/BaseEntityConverter.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/BaseEntityConverter.java
@@ -26,14 +26,14 @@
  */
 public final class BaseEntityConverter {
 
-	private BaseEntityConverter() {
-		//static only
-	}
+  private BaseEntityConverter() {
+    //static only
+  }
 
-	public static final Function<? super OwnedEntity, OwnedEntityResource> TO_OWNED_ENTITY = shareable -> {
-		OwnedEntityResource ownedEntity = new OwnedEntityResource();
-		ownedEntity.setId(String.valueOf(shareable.getId()));
-		ownedEntity.setOwner(shareable.getOwner());
-		return ownedEntity;
-	};
+  public static final Function<? super OwnedEntity, OwnedEntityResource> TO_OWNED_ENTITY = shareable -> {
+    OwnedEntityResource ownedEntity = new OwnedEntityResource();
+    ownedEntity.setId(String.valueOf(shareable.getId()));
+    ownedEntity.setOwner(shareable.getOwner());
+    return ownedEntity;
+  };
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ClusterConverter.java b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ClusterConverter.java
index 6db9ef203e..4b08a0ae6f 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ClusterConverter.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ClusterConverter.java
@@ -19,7 +19,6 @@
 import com.epam.ta.reportportal.core.analyzer.auto.client.model.cluster.ClusterInfoRs;
 import com.epam.ta.reportportal.entity.cluster.Cluster;
 import com.epam.ta.reportportal.ws.model.launch.cluster.ClusterInfoResource;
-
 import java.util.function.Function;
 
 /**
@@ -27,23 +26,23 @@
  */
 public class ClusterConverter {
 
-	private ClusterConverter() {
-		//static only
-	}
+  private ClusterConverter() {
+    //static only
+  }
 
-	public static final Function<ClusterInfoRs, Cluster> TO_CLUSTER = rs -> {
-		final Cluster cluster = new Cluster();
-		cluster.setIndexId(rs.getClusterId());
-		cluster.setMessage(rs.getClusterMessage());
-		return cluster;
-	};
+  public static final Function<ClusterInfoRs, Cluster> TO_CLUSTER = rs -> {
+    final Cluster cluster = new Cluster();
+    cluster.setIndexId(rs.getClusterId());
+    cluster.setMessage(rs.getClusterMessage());
+    return cluster;
+  };
 
-	public static final Function<Cluster, ClusterInfoResource> TO_CLUSTER_INFO = c -> {
-		final ClusterInfoResource resource = new ClusterInfoResource();
-		resource.setId(c.getId());
-		resource.setIndex(c.getIndexId());
-		resource.setLaunchId(c.getLaunchId());
-		resource.setMessage(c.getMessage());
-		return resource;
-	};
+  public static final Function<Cluster, ClusterInfoResource> TO_CLUSTER_INFO = c -> {
+    final ClusterInfoResource resource = new ClusterInfoResource();
+    resource.setId(c.getId());
+    resource.setIndex(c.getIndexId());
+    resource.setLaunchId(c.getLaunchId());
+    resource.setMessage(c.getMessage());
+    return resource;
+  };
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ExceptionConverter.java b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ExceptionConverter.java
index 3f821ce5af..5bda88f895 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ExceptionConverter.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ExceptionConverter.java
@@ -2,19 +2,18 @@
 
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorRS;
-
 import java.util.function.Function;
 
 public class ExceptionConverter {
 
-	private ExceptionConverter() {
-		//static only
-	}
+  private ExceptionConverter() {
+    //static only
+  }
 
-	public static final Function<ReportPortalException, ErrorRS> TO_ERROR_RS = ex -> {
-		ErrorRS errorResponse = new ErrorRS();
-		errorResponse.setErrorType(ex.getErrorType());
-		errorResponse.setMessage(ex.getMessage());
-		return errorResponse;
-	};
+  public static final Function<ReportPortalException, ErrorRS> TO_ERROR_RS = ex -> {
+    ErrorRS errorResponse = new ErrorRS();
+    errorResponse.setErrorType(ex.getErrorType());
+    errorResponse.setMessage(ex.getMessage());
+    return errorResponse;
+  };
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/IntegrationConverter.java b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/IntegrationConverter.java
index 62a9fe8833..0200049578 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/IntegrationConverter.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/IntegrationConverter.java
@@ -16,6 +16,8 @@
 
 package com.epam.ta.reportportal.ws.converter.converters;
 
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.EntityUtils;
 import com.epam.ta.reportportal.core.integration.util.property.AuthProperties;
 import com.epam.ta.reportportal.core.integration.util.property.BtsProperties;
@@ -27,7 +29,6 @@
 import com.epam.ta.reportportal.ws.model.integration.AuthFlowEnum;
 import com.epam.ta.reportportal.ws.model.integration.IntegrationResource;
 import com.epam.ta.reportportal.ws.model.integration.IntegrationTypeResource;
-
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -35,67 +36,70 @@
 import java.util.function.Function;
 import java.util.function.Predicate;
 
-import static java.util.Optional.ofNullable;
-
 /**
  * @author Pavel Bortnik
  */
 public final class IntegrationConverter {
 
-	private static final List<String> IGNORE_FIELDS = List.of(EmailSettingsEnum.PASSWORD.getAttribute(),
-			SauceLabsProperties.ACCESS_TOKEN.getName(),
-			BtsProperties.OAUTH_ACCESS_KEY.getName(),
-			BtsProperties.API_TOKEN.getName(),
-			AuthProperties.MANAGER_PASSWORD.getName()
-	);
+  private static final List<String> IGNORE_FIELDS = List.of(
+      EmailSettingsEnum.PASSWORD.getAttribute(),
+      SauceLabsProperties.ACCESS_TOKEN.getName(),
+      BtsProperties.OAUTH_ACCESS_KEY.getName(),
+      BtsProperties.API_TOKEN.getName(),
+      AuthProperties.MANAGER_PASSWORD.getName()
+  );
 
-	private static final Predicate<Map.Entry<String, Object>> IGNORE_FIELDS_CONDITION = entry -> IGNORE_FIELDS.stream()
-			.noneMatch(field -> field.equalsIgnoreCase(entry.getKey()));
+  private static final Predicate<Map.Entry<String, Object>> IGNORE_FIELDS_CONDITION = entry -> IGNORE_FIELDS.stream()
+      .noneMatch(field -> field.equalsIgnoreCase(entry.getKey()));
 
-	public static final Function<Integration, IntegrationResource> TO_INTEGRATION_RESOURCE = integration -> {
-		IntegrationResource resource = new IntegrationResource();
-		resource.setId(integration.getId());
-		resource.setName(integration.getName());
-		resource.setCreator(integration.getCreator());
-		resource.setCreationDate(EntityUtils.TO_DATE.apply(integration.getCreationDate()));
-		resource.setEnabled(integration.isEnabled());
-		ofNullable(integration.getProject()).ifPresent(p -> resource.setProjectId(p.getId()));
-		ofNullable(integration.getParams()).flatMap(IntegrationConverter::convertToResourceParams)
-				.ifPresent(resource::setIntegrationParams);
-		IntegrationTypeResource type = new IntegrationTypeResource();
-		type.setId(integration.getType().getId());
-		type.setName(integration.getType().getName());
-		type.setEnabled(integration.getType().isEnabled());
-		type.setCreationDate(EntityUtils.TO_DATE.apply(integration.getType().getCreationDate()));
-		type.setGroupType(integration.getType().getIntegrationGroup().name());
-		ofNullable(integration.getType().getDetails()).ifPresent(it -> type.setDetails(it.getDetails()));
-		ofNullable(integration.getType().getAuthFlow()).ifPresent(it -> type.setAuthFlow(AuthFlowEnum.valueOf(it.name())));
-		resource.setIntegrationType(type);
+  public static final Function<Integration, IntegrationResource> TO_INTEGRATION_RESOURCE = integration -> {
+    IntegrationResource resource = new IntegrationResource();
+    resource.setId(integration.getId());
+    resource.setName(integration.getName());
+    resource.setCreator(integration.getCreator());
+    resource.setCreationDate(EntityUtils.TO_DATE.apply(integration.getCreationDate()));
+    resource.setEnabled(integration.isEnabled());
+    ofNullable(integration.getProject()).ifPresent(p -> resource.setProjectId(p.getId()));
+    ofNullable(integration.getParams()).flatMap(IntegrationConverter::convertToResourceParams)
+        .ifPresent(resource::setIntegrationParams);
+    IntegrationTypeResource type = new IntegrationTypeResource();
+    type.setId(integration.getType().getId());
+    type.setName(integration.getType().getName());
+    type.setEnabled(integration.getType().isEnabled());
+    type.setCreationDate(EntityUtils.TO_DATE.apply(integration.getType().getCreationDate()));
+    type.setGroupType(integration.getType().getIntegrationGroup().name());
+    ofNullable(integration.getType().getDetails()).ifPresent(
+        it -> type.setDetails(it.getDetails()));
+    ofNullable(integration.getType().getAuthFlow()).ifPresent(
+        it -> type.setAuthFlow(AuthFlowEnum.valueOf(it.name())));
+    resource.setIntegrationType(type);
 
-		return resource;
-	};
+    return resource;
+  };
 
-	private static Optional<Map<String, Object>> convertToResourceParams(IntegrationParams it) {
-		return ofNullable(it.getParams()).map(p -> p.entrySet()
-				.stream()
-				.filter(IGNORE_FIELDS_CONDITION)
-				.collect(HashMap::new, (resourceParams, entry) -> resourceParams.put(entry.getKey(), entry.getValue()), Map::putAll));
-	}
+  private static Optional<Map<String, Object>> convertToResourceParams(IntegrationParams it) {
+    return ofNullable(it.getParams()).map(p -> p.entrySet()
+        .stream()
+        .filter(IGNORE_FIELDS_CONDITION)
+        .collect(HashMap::new,
+            (resourceParams, entry) -> resourceParams.put(entry.getKey(), entry.getValue()),
+            Map::putAll));
+  }
 
-	public static final Function<Integration, IntegrationActivityResource> TO_ACTIVITY_RESOURCE = integration -> {
-		IntegrationActivityResource resource = new IntegrationActivityResource();
-		resource.setId(integration.getId());
-		resource.setName(integration.getName());
-		ofNullable(integration.getProject()).ifPresent(p -> {
-			resource.setProjectId(p.getId());
-			resource.setProjectName(p.getName());
-		});
-		resource.setTypeName(integration.getType().getName());
-		return resource;
-	};
+  public static final Function<Integration, IntegrationActivityResource> TO_ACTIVITY_RESOURCE = integration -> {
+    IntegrationActivityResource resource = new IntegrationActivityResource();
+    resource.setId(integration.getId());
+    resource.setName(integration.getName());
+    ofNullable(integration.getProject()).ifPresent(p -> {
+      resource.setProjectId(p.getId());
+      resource.setProjectName(p.getName());
+    });
+    resource.setTypeName(integration.getType().getName());
+    return resource;
+  };
 
-	private IntegrationConverter() {
-		//static only
-	}
+  private IntegrationConverter() {
+    //static only
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/IntegrationFieldsConverter.java b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/IntegrationFieldsConverter.java
index 9dba5e0a6d..08b28e97da 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/IntegrationFieldsConverter.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/IntegrationFieldsConverter.java
@@ -16,71 +16,69 @@
 
 package com.epam.ta.reportportal.ws.converter.converters;
 
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.entity.bts.DefectFieldAllowedValue;
 import com.epam.ta.reportportal.entity.bts.DefectFormField;
 import com.epam.ta.reportportal.ws.model.externalsystem.AllowedValue;
 import com.epam.ta.reportportal.ws.model.externalsystem.PostFormField;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Sets;
-import org.apache.commons.collections.CollectionUtils;
-
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.function.Function;
 import java.util.stream.Collectors;
-
-import static java.util.Optional.ofNullable;
+import org.apache.commons.collections.CollectionUtils;
 
 /**
  * @author Pavel Bortnik
  */
 public final class IntegrationFieldsConverter {
 
-	private IntegrationFieldsConverter() {
-		//static only
-	}
-
-	public static final Function<PostFormField, DefectFormField> FIELD_TO_DB = field -> {
-		Preconditions.checkNotNull(field);
-		DefectFormField defectFormField = new DefectFormField();
-		defectFormField.setFieldId(field.getId());
-		defectFormField.setType(field.getFieldType());
-		defectFormField.setRequired(field.getIsRequired());
-		if (!CollectionUtils.isEmpty(field.getValue())) {
-			defectFormField.setValues(new HashSet<>(field.getValue()));
-		}
-
-		defectFormField.setDefectFieldAllowedValues(ofNullable(field.getDefinedValues()).map(dvs -> dvs.stream()
-				.map(IntegrationFieldsConverter.VALUE_TO_DB)
-				.collect(Collectors.toSet())).orElseGet(Sets::newHashSet));
-		return defectFormField;
-	};
-
-	public static final Function<DefectFormField, PostFormField> FIELD_TO_MODEL = defectFormField -> {
-		Preconditions.checkNotNull(defectFormField);
-		PostFormField postFormField = new PostFormField();
-		postFormField.setId(defectFormField.getFieldId());
-		postFormField.setFieldType(defectFormField.getType());
-		postFormField.setIsRequired(defectFormField.isRequired());
-		postFormField.setDefinedValues(defectFormField.getDefectFieldAllowedValues().stream().map(IntegrationFieldsConverter.VALUE_TO_MODEL)
-				.collect(Collectors.toList()));
-		postFormField.setValue(new ArrayList<>(defectFormField.getValues()));
-		return postFormField;
-	};
+  public static final Function<AllowedValue, DefectFieldAllowedValue> VALUE_TO_DB = value -> {
+    Preconditions.checkNotNull(value);
+    DefectFieldAllowedValue allowedValue = new DefectFieldAllowedValue();
+    allowedValue.setValueId(value.getValueId());
+    allowedValue.setValueName(value.getValueName());
+    return allowedValue;
+  };
+  public static final Function<PostFormField, DefectFormField> FIELD_TO_DB = field -> {
+    Preconditions.checkNotNull(field);
+    DefectFormField defectFormField = new DefectFormField();
+    defectFormField.setFieldId(field.getId());
+    defectFormField.setType(field.getFieldType());
+    defectFormField.setRequired(field.getIsRequired());
+    if (!CollectionUtils.isEmpty(field.getValue())) {
+      defectFormField.setValues(new HashSet<>(field.getValue()));
+    }
 
-	public static final Function<AllowedValue, DefectFieldAllowedValue> VALUE_TO_DB = value -> {
-		Preconditions.checkNotNull(value);
-		DefectFieldAllowedValue allowedValue = new DefectFieldAllowedValue();
-		allowedValue.setValueId(value.getValueId());
-		allowedValue.setValueName(value.getValueName());
-		return allowedValue;
-	};
+    defectFormField.setDefectFieldAllowedValues(
+        ofNullable(field.getDefinedValues()).map(dvs -> dvs.stream()
+            .map(IntegrationFieldsConverter.VALUE_TO_DB)
+            .collect(Collectors.toSet())).orElseGet(Sets::newHashSet));
+    return defectFormField;
+  };
+  public static final Function<DefectFieldAllowedValue, AllowedValue> VALUE_TO_MODEL = defectFieldAllowedValue -> {
+    Preconditions.checkNotNull(defectFieldAllowedValue);
+    AllowedValue allowedValue = new AllowedValue();
+    allowedValue.setValueId(defectFieldAllowedValue.getValueId());
+    allowedValue.setValueName(defectFieldAllowedValue.getValueName());
+    return allowedValue;
+  };
+  public static final Function<DefectFormField, PostFormField> FIELD_TO_MODEL = defectFormField -> {
+    Preconditions.checkNotNull(defectFormField);
+    PostFormField postFormField = new PostFormField();
+    postFormField.setId(defectFormField.getFieldId());
+    postFormField.setFieldType(defectFormField.getType());
+    postFormField.setIsRequired(defectFormField.isRequired());
+    postFormField.setDefinedValues(defectFormField.getDefectFieldAllowedValues().stream()
+        .map(IntegrationFieldsConverter.VALUE_TO_MODEL)
+        .collect(Collectors.toList()));
+    postFormField.setValue(new ArrayList<>(defectFormField.getValues()));
+    return postFormField;
+  };
 
-	public static final Function<DefectFieldAllowedValue, AllowedValue> VALUE_TO_MODEL = defectFieldAllowedValue -> {
-		Preconditions.checkNotNull(defectFieldAllowedValue);
-		AllowedValue allowedValue = new AllowedValue();
-		allowedValue.setValueId(defectFieldAllowedValue.getValueId());
-		allowedValue.setValueName(defectFieldAllowedValue.getValueName());
-		return allowedValue;
-	};
+  private IntegrationFieldsConverter() {
+    //static only
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/IntegrationTypeConverter.java b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/IntegrationTypeConverter.java
index 6cc2c0f62e..ee68f161e9 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/IntegrationTypeConverter.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/IntegrationTypeConverter.java
@@ -16,31 +16,31 @@
 
 package com.epam.ta.reportportal.ws.converter.converters;
 
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.EntityUtils;
 import com.epam.ta.reportportal.entity.integration.IntegrationType;
 import com.epam.ta.reportportal.ws.model.integration.IntegrationTypeResource;
-
 import java.util.function.Function;
 
-import static java.util.Optional.ofNullable;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public final class IntegrationTypeConverter {
 
-	public static final Function<IntegrationType, IntegrationTypeResource> TO_RESOURCE = integrationType -> {
-		IntegrationTypeResource resource = new IntegrationTypeResource();
-		resource.setId(integrationType.getId());
-		resource.setName(integrationType.getName());
-		resource.setEnabled(integrationType.isEnabled());
-		resource.setCreationDate(EntityUtils.TO_DATE.apply(integrationType.getCreationDate()));
-		resource.setGroupType(integrationType.getIntegrationGroup().name());
-		ofNullable(integrationType.getDetails()).ifPresent(it -> resource.setDetails(integrationType.getDetails().getDetails()));
-		return resource;
-	};
+  public static final Function<IntegrationType, IntegrationTypeResource> TO_RESOURCE = integrationType -> {
+    IntegrationTypeResource resource = new IntegrationTypeResource();
+    resource.setId(integrationType.getId());
+    resource.setName(integrationType.getName());
+    resource.setEnabled(integrationType.isEnabled());
+    resource.setCreationDate(EntityUtils.TO_DATE.apply(integrationType.getCreationDate()));
+    resource.setGroupType(integrationType.getIntegrationGroup().name());
+    ofNullable(integrationType.getDetails()).ifPresent(
+        it -> resource.setDetails(integrationType.getDetails().getDetails()));
+    return resource;
+  };
 
-	private IntegrationTypeConverter() {
-		//static only
-	}
+  private IntegrationTypeConverter() {
+    //static only
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/IssueConverter.java b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/IssueConverter.java
index 869018255f..10bc73c11d 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/IssueConverter.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/IssueConverter.java
@@ -20,7 +20,6 @@
 import com.epam.ta.reportportal.entity.item.issue.IssueEntity;
 import com.epam.ta.reportportal.ws.model.issue.Issue;
 import com.google.common.base.Preconditions;
-
 import java.util.Optional;
 import java.util.function.Function;
 import java.util.stream.Collectors;
@@ -30,44 +29,45 @@
  */
 public final class IssueConverter {
 
-	private IssueConverter() {
-		//static only
-	}
+  private IssueConverter() {
+    //static only
+  }
 
-	public static final Function<Issue, IssueEntity> TO_ISSUE = from -> {
-		IssueEntity issue = new IssueEntity();
-		issue.setAutoAnalyzed(from.getAutoAnalyzed());
-		issue.setIgnoreAnalyzer(from.getIgnoreAnalyzer());
-		issue.setIssueDescription(from.getComment());
-		return issue;
-	};
+  public static final Function<Issue, IssueEntity> TO_ISSUE = from -> {
+    IssueEntity issue = new IssueEntity();
+    issue.setAutoAnalyzed(from.getAutoAnalyzed());
+    issue.setIgnoreAnalyzer(from.getIgnoreAnalyzer());
+    issue.setIssueDescription(from.getComment());
+    return issue;
+  };
 
-	/**
-	 * Converts external system from db to model
-	 */
-	public static final Function<Ticket, Issue.ExternalSystemIssue> TO_MODEL_EXTERNAL = externalSystemIssue -> {
-		Issue.ExternalSystemIssue ticket = new Issue.ExternalSystemIssue();
-		ticket.setTicketId(externalSystemIssue.getTicketId());
-		ticket.setBtsUrl(externalSystemIssue.getBtsUrl());
-		ticket.setUrl(externalSystemIssue.getUrl());
-		ticket.setBtsProject(externalSystemIssue.getBtsProject());
-		ticket.setPluginName(externalSystemIssue.getPluginName());
-		return ticket;
-	};
-	/**
-	 * Converts issue from db to model
-	 */
-	public static final Function<IssueEntity, Issue> TO_MODEL = issueEntity -> {
-		Preconditions.checkNotNull(issueEntity);
-		Issue issue = new Issue();
-		issue.setIssueType(issueEntity.getIssueType().getLocator());
-		issue.setAutoAnalyzed(issueEntity.getAutoAnalyzed());
-		issue.setIgnoreAnalyzer(issueEntity.getIgnoreAnalyzer());
-		issue.setComment(issueEntity.getIssueDescription());
+  /**
+   * Converts external system from db to model
+   */
+  public static final Function<Ticket, Issue.ExternalSystemIssue> TO_MODEL_EXTERNAL = externalSystemIssue -> {
+    Issue.ExternalSystemIssue ticket = new Issue.ExternalSystemIssue();
+    ticket.setTicketId(externalSystemIssue.getTicketId());
+    ticket.setBtsUrl(externalSystemIssue.getBtsUrl());
+    ticket.setUrl(externalSystemIssue.getUrl());
+    ticket.setBtsProject(externalSystemIssue.getBtsProject());
+    ticket.setPluginName(externalSystemIssue.getPluginName());
+    return ticket;
+  };
+  /**
+   * Converts issue from db to model
+   */
+  public static final Function<IssueEntity, Issue> TO_MODEL = issueEntity -> {
+    Preconditions.checkNotNull(issueEntity);
+    Issue issue = new Issue();
+    issue.setIssueType(issueEntity.getIssueType().getLocator());
+    issue.setAutoAnalyzed(issueEntity.getAutoAnalyzed());
+    issue.setIgnoreAnalyzer(issueEntity.getIgnoreAnalyzer());
+    issue.setComment(issueEntity.getIssueDescription());
 
-		Optional.ofNullable(issueEntity.getTickets()).ifPresent(tickets -> {
-			issue.setExternalSystemIssues(tickets.stream().map(IssueConverter.TO_MODEL_EXTERNAL).collect(Collectors.toSet()));
-		});
-		return issue;
-	};
+    Optional.ofNullable(issueEntity.getTickets()).ifPresent(tickets -> {
+      issue.setExternalSystemIssues(
+          tickets.stream().map(IssueConverter.TO_MODEL_EXTERNAL).collect(Collectors.toSet()));
+    });
+    return issue;
+  };
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/IssueTypeConverter.java b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/IssueTypeConverter.java
index 73605a8287..98e0423176 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/IssueTypeConverter.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/IssueTypeConverter.java
@@ -18,7 +18,6 @@
 
 import com.epam.ta.reportportal.entity.item.issue.IssueType;
 import com.epam.ta.reportportal.ws.model.activity.IssueTypeActivityResource;
-
 import java.util.function.Function;
 
 /**
@@ -26,14 +25,14 @@
  */
 public class IssueTypeConverter {
 
-	private IssueTypeConverter() {
-		//static only
-	}
+  private IssueTypeConverter() {
+    //static only
+  }
 
-	public static final Function<IssueType, IssueTypeActivityResource> TO_ACTIVITY_RESOURCE = issueType -> {
-		IssueTypeActivityResource resource = new IssueTypeActivityResource();
-		resource.setId(issueType.getId());
-		resource.setLongName(issueType.getLongName());
-		return resource;
-	};
+  public static final Function<IssueType, IssueTypeActivityResource> TO_ACTIVITY_RESOURCE = issueType -> {
+    IssueTypeActivityResource resource = new IssueTypeActivityResource();
+    resource.setId(issueType.getId());
+    resource.setLongName(issueType.getLongName());
+    return resource;
+  };
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/LaunchConverter.java b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/LaunchConverter.java
index 1cbd1ed0dd..eeceb6ae92 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/LaunchConverter.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/LaunchConverter.java
@@ -16,6 +16,10 @@
 
 package com.epam.ta.reportportal.ws.converter.converters;
 
+import static java.util.Optional.ofNullable;
+import static java.util.stream.Collectors.groupingBy;
+import static java.util.stream.Collectors.toSet;
+
 import com.epam.ta.reportportal.commons.EntityUtils;
 import com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerStatusCache;
 import com.epam.ta.reportportal.dao.UserRepository;
@@ -28,17 +32,12 @@
 import com.epam.ta.reportportal.ws.model.launch.LaunchResource;
 import com.epam.ta.reportportal.ws.model.launch.Mode;
 import com.google.common.base.Preconditions;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
 import java.util.Collections;
 import java.util.Map;
 import java.util.Set;
 import java.util.function.Function;
-
-import static java.util.Optional.ofNullable;
-import static java.util.stream.Collectors.groupingBy;
-import static java.util.stream.Collectors.toSet;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
  * @author Pavel Bortnik
@@ -46,57 +45,63 @@
 @Service
 public class LaunchConverter {
 
-	@Autowired
-	private AnalyzerStatusCache analyzerStatusCache;
+  @Autowired
+  private AnalyzerStatusCache analyzerStatusCache;
 
-	@Autowired
-	private UserRepository userRepository;
+  @Autowired
+  private UserRepository userRepository;
 
-	@Autowired
-	private ItemAttributeTypeResolver itemAttributeTypeResolver;
+  @Autowired
+  private ItemAttributeTypeResolver itemAttributeTypeResolver;
 
-	@Autowired
-	private Map<ItemAttributeType, ResourceAttributeHandler<LaunchResource>> resourceAttributeUpdaterMapping;
+  @Autowired
+  private Map<ItemAttributeType, ResourceAttributeHandler<LaunchResource>> resourceAttributeUpdaterMapping;
 
-	public static final Function<Launch, LaunchActivityResource> TO_ACTIVITY_RESOURCE = launch -> {
-		LaunchActivityResource resource = new LaunchActivityResource();
-		resource.setId(launch.getId());
-		resource.setProjectId(launch.getProjectId());
-		resource.setName(launch.getName() + " #" + launch.getNumber());
-		return resource;
-	};
+  public static final Function<Launch, LaunchActivityResource> TO_ACTIVITY_RESOURCE = launch -> {
+    LaunchActivityResource resource = new LaunchActivityResource();
+    resource.setId(launch.getId());
+    resource.setProjectId(launch.getProjectId());
+    resource.setName(launch.getName() + " #" + launch.getNumber());
+    return resource;
+  };
 
-	public Function<Launch, LaunchResource> TO_RESOURCE = db -> {
+  public Function<Launch, LaunchResource> TO_RESOURCE = db -> {
 
-		Preconditions.checkNotNull(db);
+    Preconditions.checkNotNull(db);
 
-		LaunchResource resource = new LaunchResource();
-		resource.setLaunchId(db.getId());
-		resource.setUuid(db.getUuid());
-		resource.setName(db.getName());
-		resource.setNumber(db.getNumber());
-		resource.setDescription(db.getDescription());
-		resource.setStatus(db.getStatus() == null ? null : db.getStatus().toString());
-		resource.setStartTime(db.getStartTime() == null ? null : EntityUtils.TO_DATE.apply(db.getStartTime()));
-		resource.setEndTime(db.getEndTime() == null ? null : EntityUtils.TO_DATE.apply(db.getEndTime()));
-		ofNullable(db.getLastModified()).map(EntityUtils.TO_DATE).ifPresent(resource::setLastModified);
-		ofNullable(db.getAttributes()).ifPresent(attributes -> updateAttributes(resource, attributes));
-		ofNullable(resource.getAttributes()).ifPresentOrElse(a -> {
-		}, () -> resource.setAttributes(Collections.emptySet()));
-		resource.setMode(db.getMode() == null ? null : Mode.valueOf(db.getMode().name()));
-		resource.setAnalyzers(analyzerStatusCache.getStartedAnalyzers(db.getId()));
-		resource.setStatisticsResource(StatisticsConverter.TO_RESOURCE.apply(db.getStatistics()));
-		resource.setApproximateDuration(db.getApproximateDuration());
-		resource.setHasRetries(db.isHasRetries());
-		//TODO replace with single select on higher level to prevent selection for each launch
-		ofNullable(db.getUserId()).flatMap(id -> userRepository.findLoginById(id)).ifPresent(resource::setOwner);
-		resource.setRerun(db.isRerun());
-		return resource;
-	};
+    LaunchResource resource = new LaunchResource();
+    resource.setLaunchId(db.getId());
+    resource.setUuid(db.getUuid());
+    resource.setName(db.getName());
+    resource.setNumber(db.getNumber());
+    resource.setDescription(db.getDescription());
+    resource.setStatus(db.getStatus() == null ? null : db.getStatus().toString());
+    resource.setStartTime(
+        db.getStartTime() == null ? null : EntityUtils.TO_DATE.apply(db.getStartTime()));
+    resource.setEndTime(
+        db.getEndTime() == null ? null : EntityUtils.TO_DATE.apply(db.getEndTime()));
+    ofNullable(db.getLastModified()).map(EntityUtils.TO_DATE).ifPresent(resource::setLastModified);
+    ofNullable(db.getAttributes()).ifPresent(attributes -> updateAttributes(resource, attributes));
+    ofNullable(resource.getAttributes()).ifPresentOrElse(a -> {
+    }, () -> resource.setAttributes(Collections.emptySet()));
+    resource.setMode(db.getMode() == null ? null : Mode.valueOf(db.getMode().name()));
+    resource.setAnalyzers(analyzerStatusCache.getStartedAnalyzers(db.getId()));
+    resource.setStatisticsResource(StatisticsConverter.TO_RESOURCE.apply(db.getStatistics()));
+    resource.setApproximateDuration(db.getApproximateDuration());
+    resource.setHasRetries(db.isHasRetries());
+    //TODO replace with single select on higher level to prevent selection for each launch
+    ofNullable(db.getUserId()).flatMap(id -> userRepository.findLoginById(id))
+        .ifPresent(resource::setOwner);
+    resource.setRerun(db.isRerun());
+    return resource;
+  };
 
-	private void updateAttributes(LaunchResource resource, Set<ItemAttribute> attributes) {
-		final Map<ItemAttributeType, Set<ItemAttribute>> attributeMapping = attributes.stream()
-				.collect(groupingBy(attr -> itemAttributeTypeResolver.resolve(attr).orElse(ItemAttributeType.UNRESOLVED), toSet()));
-		attributeMapping.forEach((type, attr) -> resourceAttributeUpdaterMapping.get(type).handle(resource, attr));
-	}
+  private void updateAttributes(LaunchResource resource, Set<ItemAttribute> attributes) {
+    final Map<ItemAttributeType, Set<ItemAttribute>> attributeMapping = attributes.stream()
+        .collect(groupingBy(
+            attr -> itemAttributeTypeResolver.resolve(attr).orElse(ItemAttributeType.UNRESOLVED),
+            toSet()));
+    attributeMapping.forEach(
+        (type, attr) -> resourceAttributeUpdaterMapping.get(type).handle(resource, attr));
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/LogConverter.java b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/LogConverter.java
index 548fcbd6d6..05a4ca0801 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/LogConverter.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/LogConverter.java
@@ -16,20 +16,20 @@
 
 package com.epam.ta.reportportal.ws.converter.converters;
 
+import static java.util.Optional.ofNullable;
+import static org.apache.commons.lang3.StringUtils.isNotEmpty;
+
 import com.epam.ta.reportportal.commons.EntityUtils;
 import com.epam.ta.reportportal.core.log.impl.PagedLogResource;
 import com.epam.ta.reportportal.entity.enums.LogLevel;
 import com.epam.ta.reportportal.entity.log.Log;
+import com.epam.ta.reportportal.entity.log.LogFull;
 import com.epam.ta.reportportal.ws.model.log.LogResource;
 import com.epam.ta.reportportal.ws.model.log.SearchLogRs;
 import com.google.common.base.Preconditions;
-
 import java.util.function.BiFunction;
 import java.util.function.Function;
 
-import static java.util.Optional.ofNullable;
-import static org.apache.commons.lang3.StringUtils.isNotEmpty;
-
 /**
  * Converts internal DB model to DTO
  *
@@ -37,53 +37,89 @@
  */
 public final class LogConverter {
 
-	private LogConverter() {
-		//static only
-	}
-
-	public static final Function<Log, LogResource> TO_RESOURCE = model -> {
-		Preconditions.checkNotNull(model);
-		LogResource resource = new LogResource();
-		fillWithLogContent(model, resource);
-		return resource;
-	};
-
-	private static void fillWithLogContent(Log model, LogResource resource) {
-		resource.setId(model.getId());
-		resource.setUuid(model.getUuid());
-		resource.setMessage(ofNullable(model.getLogMessage()).orElse("NULL"));
-		resource.setLogTime(EntityUtils.TO_DATE.apply(model.getLogTime()));
-
-		if (isBinaryDataExists(model)) {
-
-			LogResource.BinaryContent binaryContent = new LogResource.BinaryContent();
-
-			binaryContent.setBinaryDataId(String.valueOf(model.getAttachment().getId()));
-			binaryContent.setContentType(model.getAttachment().getContentType());
-			binaryContent.setThumbnailId(model.getAttachment().getThumbnailId());
-			resource.setBinaryContent(binaryContent);
-		}
-
-		ofNullable(model.getTestItem()).ifPresent(testItem -> resource.setItemId(testItem.getItemId()));
-		ofNullable(model.getLaunch()).ifPresent(launch -> resource.setLaunchId(launch.getId()));
-		ofNullable(model.getLogLevel()).ifPresent(level -> resource.setLevel(LogLevel.toLevel(level).toString()));
-	}
-
-	public static final BiFunction<Log, PagedLogResource, PagedLogResource> FILL_WITH_LOG_CONTENT = (model, pagedLog) -> {
-		fillWithLogContent(model, pagedLog);
-		return pagedLog;
-	};
-
-	public static final Function<Log, SearchLogRs.LogEntry> TO_LOG_ENTRY = log -> {
-		SearchLogRs.LogEntry logEntry = new SearchLogRs.LogEntry();
-		logEntry.setMessage(log.getLogMessage());
-		logEntry.setLevel(LogLevel.toLevel(log.getLogLevel()).name());
-		return logEntry;
-	};
-
-	private static boolean isBinaryDataExists(Log log) {
-		return ofNullable(log.getAttachment()).map(a -> isNotEmpty(a.getContentType()) || isNotEmpty(a.getThumbnailId())
-				|| isNotEmpty(a.getFileId())).orElse(false);
-	}
+  private LogConverter() {
+    //static only
+  }
+
+  public static final Function<LogFull, LogResource> TO_RESOURCE = model -> {
+    Preconditions.checkNotNull(model);
+    LogResource resource = new LogResource();
+    fillWithLogContent(model, resource);
+    return resource;
+  };
+
+  private static void fillWithLogContent(LogFull model, LogResource resource) {
+    resource.setId(model.getId());
+    resource.setUuid(model.getUuid());
+    resource.setMessage(ofNullable(model.getLogMessage()).orElse("NULL"));
+    resource.setLogTime(EntityUtils.TO_DATE.apply(model.getLogTime()));
+
+    if (isBinaryDataExists(model)) {
+
+      LogResource.BinaryContent binaryContent = new LogResource.BinaryContent();
+
+      binaryContent.setBinaryDataId(String.valueOf(model.getAttachment().getId()));
+      binaryContent.setContentType(model.getAttachment().getContentType());
+      binaryContent.setThumbnailId(model.getAttachment().getThumbnailId());
+      resource.setBinaryContent(binaryContent);
+    }
+
+    ofNullable(model.getTestItem()).ifPresent(testItem -> resource.setItemId(testItem.getItemId()));
+    ofNullable(model.getLaunch()).ifPresent(launch -> resource.setLaunchId(launch.getId()));
+    ofNullable(model.getLogLevel()).ifPresent(
+        level -> resource.setLevel(LogLevel.toLevel(level).toString()));
+  }
+
+  public static final BiFunction<LogFull, PagedLogResource, PagedLogResource> FILL_WITH_LOG_CONTENT = (model, pagedLog) -> {
+    fillWithLogContent(model, pagedLog);
+    return pagedLog;
+  };
+
+  public static final Function<LogFull, SearchLogRs.LogEntry> TO_LOG_ENTRY = log -> {
+    SearchLogRs.LogEntry logEntry = new SearchLogRs.LogEntry();
+    logEntry.setMessage(log.getLogMessage());
+    logEntry.setLevel(LogLevel.toLevel(log.getLogLevel()).name());
+    return logEntry;
+  };
+
+  public static final Function<LogFull, Log> LOG_FULL_TO_LOG = logFull -> {
+    Log log = new Log();
+    log.setAttachment(logFull.getAttachment());
+    log.setClusterId(logFull.getClusterId());
+    log.setId(logFull.getId());
+    log.setLastModified(logFull.getLastModified());
+    log.setLaunch(logFull.getLaunch());
+    log.setLogLevel(logFull.getLogLevel());
+    log.setLogMessage(logFull.getLogMessage());
+    log.setLogTime(logFull.getLogTime());
+    log.setProjectId(logFull.getProjectId());
+    log.setTestItem(logFull.getTestItem());
+    log.setUuid(logFull.getUuid());
+
+    return log;
+  };
+
+  public static final Function<Log, LogFull> LOG_TO_LOG_FULL = log -> {
+    LogFull logFull = new LogFull();
+    logFull.setAttachment(log.getAttachment());
+    logFull.setClusterId(log.getClusterId());
+    logFull.setId(log.getId());
+    logFull.setLastModified(log.getLastModified());
+    logFull.setLaunch(log.getLaunch());
+    logFull.setLogLevel(log.getLogLevel());
+    logFull.setLogMessage(log.getLogMessage());
+    logFull.setLogTime(log.getLogTime());
+    logFull.setProjectId(log.getProjectId());
+    logFull.setTestItem(log.getTestItem());
+    logFull.setUuid(log.getUuid());
+
+    return logFull;
+  };
+
+  private static boolean isBinaryDataExists(LogFull log) {
+    return ofNullable(log.getAttachment()).map(
+        a -> isNotEmpty(a.getContentType()) || isNotEmpty(a.getThumbnailId())
+            || isNotEmpty(a.getFileId())).orElse(false);
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/NotificationConfigConverter.java b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/NotificationConfigConverter.java
index 3efafa9ea4..f2a6feb6e3 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/NotificationConfigConverter.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/NotificationConfigConverter.java
@@ -22,6 +22,7 @@
 import com.epam.ta.reportportal.entity.project.email.SenderCase;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import com.epam.ta.reportportal.ws.model.ValidationConstraints;
 import com.epam.ta.reportportal.ws.model.attribute.ItemAttributeResource;
 import com.epam.ta.reportportal.ws.model.project.email.SenderCaseDTO;
 import com.google.common.base.Preconditions;
@@ -66,16 +67,30 @@ private NotificationConfigConverter() {
 		resource.setRecipients(Lists.newArrayList(model.getRecipients()));
 		resource.setEnabled(model.isEnabled());
 		resource.setAttributesOperator(model.getAttributesOperator().getOperator());
+		resource.setRuleName(model.getRuleName());
+		resource.setId(model.getId());
 		return resource;
 	};
 
 	public static final Function<ItemAttributeResource, LaunchAttributeRule> TO_ATTRIBUTE_RULE_MODEL = resource -> {
 		LaunchAttributeRule launchAttributeRule = new LaunchAttributeRule();
+		cutAttributeToMaxLength(resource);
 		launchAttributeRule.setKey(resource.getKey());
 		launchAttributeRule.setValue(resource.getValue());
 		return launchAttributeRule;
 	};
 
+	private static void cutAttributeToMaxLength(ItemAttributeResource entity) {
+		String key = entity.getKey();
+		String value = entity.getValue();
+		if (key != null && key.length() > ValidationConstraints.MAX_ATTRIBUTE_LENGTH) {
+			entity.setKey(key.trim().substring(0, ValidationConstraints.MAX_ATTRIBUTE_LENGTH));
+		}
+		if (value != null && value.length() > ValidationConstraints.MAX_ATTRIBUTE_LENGTH) {
+			entity.setValue(value.trim().substring(0, ValidationConstraints.MAX_ATTRIBUTE_LENGTH));
+		}
+	}
+
 	public final static Function<SenderCaseDTO, SenderCase> TO_CASE_MODEL = resource -> {
 		SenderCase senderCase = new SenderCase();
 		ofNullable(resource.getAttributes()).ifPresent(attributes -> senderCase.setLaunchAttributeRules(attributes.stream()
@@ -93,6 +108,8 @@ private NotificationConfigConverter() {
 				)));
 		senderCase.setEnabled(resource.isEnabled());
 		senderCase.setAttributesOperator(LogicalOperator.valueOf(resource.getAttributesOperator()));
+		senderCase.setRuleName(resource.getRuleName());
+		senderCase.setId(resource.getId());
 		return senderCase;
 	};
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/OAuthDetailsConverters.java b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/OAuthDetailsConverters.java
index 85d0188d0a..12ca1baf80 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/OAuthDetailsConverters.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/OAuthDetailsConverters.java
@@ -23,39 +23,39 @@
  */
 public final class OAuthDetailsConverters {
 
-	private OAuthDetailsConverters() {
-		//static only
-	}
+  private OAuthDetailsConverters() {
+    //static only
+  }
 
-	//	public final static Function<OAuthDetailsResource, OAuth2LoginDetails> FROM_RESOURCE = resource -> {
-	//		Preconditions.checkNotNull(resource);
-	//		OAuth2LoginDetails db = new OAuth2LoginDetails();
-	//		db.setClientAuthenticationScheme(resource.getClientAuthenticationScheme());
-	//		db.setUserAuthorizationUri(resource.getUserAuthorizationUri());
-	//		db.setAccessTokenUri(resource.getAccessTokenUri());
-	//		db.setClientId(resource.getClientId());
-	//		db.setClientSecret(resource.getClientSecret());
-	//		db.setGrantType(resource.getGrantType());
-	//		db.setScope(resource.getScope());
-	//		db.setRestrictions(resource.getRestrictions());
-	//		db.setAuthenticationScheme(resource.getAuthenticationScheme());
-	//		db.setTokenName(resource.getTokenName());
-	//		return db;
-	//	};
-	//
-	//	public final static Function<OAuth2LoginDetails, OAuthDetailsResource> TO_RESOURCE = db -> {
-	//		Preconditions.checkNotNull(db);
-	//		OAuthDetailsResource resource = new OAuthDetailsResource();
-	//		resource.setClientAuthenticationScheme(db.getClientAuthenticationScheme());
-	//		resource.setUserAuthorizationUri(db.getUserAuthorizationUri());
-	//		resource.setAccessTokenUri(db.getAccessTokenUri());
-	//		resource.setClientId(db.getClientId());
-	//		resource.setClientSecret(db.getClientSecret());
-	//		resource.setGrantType(db.getGrantType());
-	//		resource.setScope(db.getScope());
-	//		resource.setRestrictions(db.getRestrictions());
-	//		resource.setAuthenticationScheme(db.getAuthenticationScheme());
-	//		resource.setTokenName(db.getTokenName());
-	//		return resource;
-	//	};
+  //	public final static Function<OAuthDetailsResource, OAuth2LoginDetails> FROM_RESOURCE = resource -> {
+  //		Preconditions.checkNotNull(resource);
+  //		OAuth2LoginDetails db = new OAuth2LoginDetails();
+  //		db.setClientAuthenticationScheme(resource.getClientAuthenticationScheme());
+  //		db.setUserAuthorizationUri(resource.getUserAuthorizationUri());
+  //		db.setAccessTokenUri(resource.getAccessTokenUri());
+  //		db.setClientId(resource.getClientId());
+  //		db.setClientSecret(resource.getClientSecret());
+  //		db.setGrantType(resource.getGrantType());
+  //		db.setScope(resource.getScope());
+  //		db.setRestrictions(resource.getRestrictions());
+  //		db.setAuthenticationScheme(resource.getAuthenticationScheme());
+  //		db.setTokenName(resource.getTokenName());
+  //		return db;
+  //	};
+  //
+  //	public final static Function<OAuth2LoginDetails, OAuthDetailsResource> TO_RESOURCE = db -> {
+  //		Preconditions.checkNotNull(db);
+  //		OAuthDetailsResource resource = new OAuthDetailsResource();
+  //		resource.setClientAuthenticationScheme(db.getClientAuthenticationScheme());
+  //		resource.setUserAuthorizationUri(db.getUserAuthorizationUri());
+  //		resource.setAccessTokenUri(db.getAccessTokenUri());
+  //		resource.setClientId(db.getClientId());
+  //		resource.setClientSecret(db.getClientSecret());
+  //		resource.setGrantType(db.getGrantType());
+  //		resource.setScope(db.getScope());
+  //		resource.setRestrictions(db.getRestrictions());
+  //		resource.setAuthenticationScheme(db.getAuthenticationScheme());
+  //		resource.setTokenName(db.getTokenName());
+  //		return resource;
+  //	};
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ParametersConverter.java b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ParametersConverter.java
index e590384d7e..b1a829e943 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ParametersConverter.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ParametersConverter.java
@@ -17,7 +17,6 @@
 
 import com.epam.ta.reportportal.entity.item.Parameter;
 import com.epam.ta.reportportal.ws.model.ParameterResource;
-
 import java.util.function.Function;
 
 /**
@@ -27,22 +26,22 @@
  */
 public final class ParametersConverter {
 
-	private ParametersConverter() {
-		//static only
-	}
+  private ParametersConverter() {
+    //static only
+  }
 
-	public static final Function<ParameterResource, Parameter> TO_MODEL = resource -> {
-		Parameter parameters = new Parameter();
-		parameters.setKey(resource.getKey());
-		parameters.setValue(resource.getValue());
-		return parameters;
-	};
+  public static final Function<ParameterResource, Parameter> TO_MODEL = resource -> {
+    Parameter parameters = new Parameter();
+    parameters.setKey(resource.getKey());
+    parameters.setValue(resource.getValue());
+    return parameters;
+  };
 
-	public static final Function<Parameter, ParameterResource> TO_RESOURCE = model -> {
-		ParameterResource parameter = new ParameterResource();
-		parameter.setKey(model.getKey());
-		parameter.setValue(model.getValue());
-		return parameter;
-	};
+  public static final Function<Parameter, ParameterResource> TO_RESOURCE = model -> {
+    ParameterResource parameter = new ParameterResource();
+    parameter.setKey(model.getKey());
+    parameter.setValue(model.getValue());
+    return parameter;
+  };
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/PatternTemplateConverter.java b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/PatternTemplateConverter.java
index ff5691fb95..9c5214db63 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/PatternTemplateConverter.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/PatternTemplateConverter.java
@@ -19,7 +19,6 @@
 import com.epam.ta.reportportal.entity.pattern.PatternTemplate;
 import com.epam.ta.reportportal.ws.model.activity.PatternTemplateActivityResource;
 import com.epam.ta.reportportal.ws.model.project.config.pattern.PatternTemplateResource;
-
 import java.util.function.Function;
 
 /**
@@ -27,27 +26,27 @@
  */
 public class PatternTemplateConverter {
 
-	private PatternTemplateConverter() {
-		//static only
-	}
-
-	public static final Function<PatternTemplate, PatternTemplateResource> TO_RESOURCE = patternTemplate -> {
-		PatternTemplateResource resource = new PatternTemplateResource();
-		resource.setId(patternTemplate.getId());
-		resource.setType(patternTemplate.getTemplateType().name());
-		resource.setName(patternTemplate.getName());
-		resource.setValue(patternTemplate.getValue());
-		resource.setEnabled(patternTemplate.isEnabled());
-
-		return resource;
-	};
-
-	public static final Function<PatternTemplate, PatternTemplateActivityResource> TO_ACTIVITY_RESOURCE = patternTemplate -> {
-		PatternTemplateActivityResource resource = new PatternTemplateActivityResource();
-		resource.setId(patternTemplate.getId());
-		resource.setName(patternTemplate.getName());
-		resource.setEnabled(patternTemplate.isEnabled());
-		resource.setProjectId(patternTemplate.getProjectId());
-		return resource;
-	};
+  private PatternTemplateConverter() {
+    //static only
+  }
+
+  public static final Function<PatternTemplate, PatternTemplateResource> TO_RESOURCE = patternTemplate -> {
+    PatternTemplateResource resource = new PatternTemplateResource();
+    resource.setId(patternTemplate.getId());
+    resource.setType(patternTemplate.getTemplateType().name());
+    resource.setName(patternTemplate.getName());
+    resource.setValue(patternTemplate.getValue());
+    resource.setEnabled(patternTemplate.isEnabled());
+
+    return resource;
+  };
+
+  public static final Function<PatternTemplate, PatternTemplateActivityResource> TO_ACTIVITY_RESOURCE = patternTemplate -> {
+    PatternTemplateActivityResource resource = new PatternTemplateActivityResource();
+    resource.setId(patternTemplate.getId());
+    resource.setName(patternTemplate.getName());
+    resource.setEnabled(patternTemplate.isEnabled());
+    resource.setProjectId(patternTemplate.getProjectId());
+    return resource;
+  };
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ProjectActivityConverter.java b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ProjectActivityConverter.java
index ff99f823e3..6bdb4d288c 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ProjectActivityConverter.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ProjectActivityConverter.java
@@ -19,7 +19,6 @@
 import com.epam.ta.reportportal.entity.project.Project;
 import com.epam.ta.reportportal.entity.project.ProjectUtils;
 import com.epam.ta.reportportal.ws.model.activity.ProjectAttributesActivityResource;
-
 import java.util.function.Function;
 
 /**
@@ -27,16 +26,16 @@
  */
 public final class ProjectActivityConverter {
 
-	private ProjectActivityConverter() {
-		//static only
-	}
+  private ProjectActivityConverter() {
+    //static only
+  }
 
-	public static final Function<Project, ProjectAttributesActivityResource> TO_ACTIVITY_RESOURCE = project -> {
-		ProjectAttributesActivityResource resource = new ProjectAttributesActivityResource();
-		resource.setProjectId(project.getId());
-		resource.setProjectName(project.getName());
-		resource.setConfig(ProjectUtils.getConfigParameters(project.getProjectAttributes()));
-		return resource;
-	};
+  public static final Function<Project, ProjectAttributesActivityResource> TO_ACTIVITY_RESOURCE = project -> {
+    ProjectAttributesActivityResource resource = new ProjectAttributesActivityResource();
+    resource.setProjectId(project.getId());
+    resource.setProjectName(project.getName());
+    resource.setConfig(ProjectUtils.getConfigParameters(project.getProjectAttributes()));
+    return resource;
+  };
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ProjectSettingsConverter.java b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ProjectSettingsConverter.java
index b7dd91f275..66deb60f28 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ProjectSettingsConverter.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ProjectSettingsConverter.java
@@ -16,6 +16,8 @@
 
 package com.epam.ta.reportportal.ws.converter.converters;
 
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.commons.EntityUtils;
 import com.epam.ta.reportportal.entity.item.issue.IssueType;
 import com.epam.ta.reportportal.entity.project.Project;
@@ -25,63 +27,60 @@
 import com.epam.ta.reportportal.ws.model.project.config.IssueSubTypeResource;
 import com.epam.ta.reportportal.ws.model.project.config.ProjectSettingsResource;
 import com.google.common.base.Preconditions;
-
 import java.util.List;
 import java.util.Map;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
-import static java.util.Optional.ofNullable;
-
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
  */
 public final class ProjectSettingsConverter {
 
-	private ProjectSettingsConverter() {
-		//static only
-	}
+  private ProjectSettingsConverter() {
+    //static only
+  }
 
-	public static final Function<ProjectInfo, ProjectInfoResource> TO_PROJECT_INFO_RESOURCE = project -> {
-		Preconditions.checkNotNull(project);
-		ProjectInfoResource resource = new ProjectInfoResource();
-		resource.setUsersQuantity(project.getUsersQuantity());
-		resource.setLaunchesQuantity(project.getLaunchesQuantity());
-		resource.setProjectId(project.getId());
-		resource.setProjectName(project.getName());
-		resource.setCreationDate(EntityUtils.TO_DATE.apply(project.getCreationDate()));
-		resource.setLastRun(ofNullable(project.getLastRun()).map(EntityUtils.TO_DATE).orElse(null));
-		resource.setEntryType(project.getProjectType());
-		resource.setOrganization(project.getOrganization());
-		return resource;
-	};
+  public static final Function<ProjectInfo, ProjectInfoResource> TO_PROJECT_INFO_RESOURCE = project -> {
+    Preconditions.checkNotNull(project);
+    ProjectInfoResource resource = new ProjectInfoResource();
+    resource.setUsersQuantity(project.getUsersQuantity());
+    resource.setLaunchesQuantity(project.getLaunchesQuantity());
+    resource.setProjectId(project.getId());
+    resource.setProjectName(project.getName());
+    resource.setCreationDate(EntityUtils.TO_DATE.apply(project.getCreationDate()));
+    resource.setLastRun(ofNullable(project.getLastRun()).map(EntityUtils.TO_DATE).orElse(null));
+    resource.setEntryType(project.getProjectType());
+    resource.setOrganization(project.getOrganization());
+    return resource;
+  };
 
-	public static final Function<IssueType, IssueSubTypeResource> TO_SUBTYPE_RESOURCE = issueType -> {
-		IssueSubTypeResource issueSubTypeResource = new IssueSubTypeResource();
-		issueSubTypeResource.setId(issueType.getId());
-		issueSubTypeResource.setLocator(issueType.getLocator());
-		issueSubTypeResource.setColor(issueType.getHexColor());
-		issueSubTypeResource.setLongName(issueType.getLongName());
-		issueSubTypeResource.setShortName(issueType.getShortName());
-		issueSubTypeResource.setTypeRef(issueType.getIssueGroup().getTestItemIssueGroup().getValue());
-		return issueSubTypeResource;
-	};
+  public static final Function<IssueType, IssueSubTypeResource> TO_SUBTYPE_RESOURCE = issueType -> {
+    IssueSubTypeResource issueSubTypeResource = new IssueSubTypeResource();
+    issueSubTypeResource.setId(issueType.getId());
+    issueSubTypeResource.setLocator(issueType.getLocator());
+    issueSubTypeResource.setColor(issueType.getHexColor());
+    issueSubTypeResource.setLongName(issueType.getLongName());
+    issueSubTypeResource.setShortName(issueType.getShortName());
+    issueSubTypeResource.setTypeRef(issueType.getIssueGroup().getTestItemIssueGroup().getValue());
+    return issueSubTypeResource;
+  };
 
-	public static final Function<List<IssueType>, Map<String, List<IssueSubTypeResource>>> TO_PROJECT_SUB_TYPES_RESOURCE = issueTypes -> issueTypes
-			.stream()
-			.collect(Collectors.groupingBy(
-					it -> it.getIssueGroup().getTestItemIssueGroup().getValue(),
-					Collectors.mapping(TO_SUBTYPE_RESOURCE, Collectors.toList())
-			));
+  public static final Function<List<IssueType>, Map<String, List<IssueSubTypeResource>>> TO_PROJECT_SUB_TYPES_RESOURCE = issueTypes -> issueTypes
+      .stream()
+      .collect(Collectors.groupingBy(
+          it -> it.getIssueGroup().getTestItemIssueGroup().getValue(),
+          Collectors.mapping(TO_SUBTYPE_RESOURCE, Collectors.toList())
+      ));
 
-	public static final Function<Project, ProjectSettingsResource> TO_PROJECT_SETTINGS_RESOURCE = project -> {
-		ProjectSettingsResource resource = new ProjectSettingsResource();
-		resource.setProjectId(project.getId());
-		resource.setSubTypes(TO_PROJECT_SUB_TYPES_RESOURCE.apply(project.getProjectIssueTypes()
-				.stream()
-				.map(ProjectIssueType::getIssueType)
-				.collect(Collectors.toList())));
-		return resource;
-	};
+  public static final Function<Project, ProjectSettingsResource> TO_PROJECT_SETTINGS_RESOURCE = project -> {
+    ProjectSettingsResource resource = new ProjectSettingsResource();
+    resource.setProjectId(project.getId());
+    resource.setSubTypes(TO_PROJECT_SUB_TYPES_RESOURCE.apply(project.getProjectIssueTypes()
+        .stream()
+        .map(ProjectIssueType::getIssueType)
+        .collect(Collectors.toList())));
+    return resource;
+  };
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/RestorePasswordBidConverter.java b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/RestorePasswordBidConverter.java
index d7f7108482..ab08b88c3e 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/RestorePasswordBidConverter.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/RestorePasswordBidConverter.java
@@ -19,7 +19,6 @@
 import com.epam.ta.reportportal.entity.user.RestorePasswordBid;
 import com.epam.ta.reportportal.ws.model.user.RestorePasswordRQ;
 import com.google.common.base.Preconditions;
-
 import java.util.UUID;
 import java.util.function.Function;
 
@@ -30,15 +29,15 @@
  */
 public final class RestorePasswordBidConverter {
 
-	private RestorePasswordBidConverter() {
-		//static only
-	}
+  private RestorePasswordBidConverter() {
+    //static only
+  }
 
-	public static final Function<RestorePasswordRQ, RestorePasswordBid> TO_BID = request -> {
-		Preconditions.checkNotNull(request);
-		RestorePasswordBid bid = new RestorePasswordBid();
-		bid.setEmail(request.getEmail());
-		bid.setUuid(UUID.randomUUID().toString());
-		return bid;
-	};
+  public static final Function<RestorePasswordRQ, RestorePasswordBid> TO_BID = request -> {
+    Preconditions.checkNotNull(request);
+    RestorePasswordBid bid = new RestorePasswordBid();
+    bid.setEmail(request.getEmail());
+    bid.setUuid(UUID.randomUUID().toString());
+    return bid;
+  };
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ServerSettingsConverter.java b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ServerSettingsConverter.java
index 4a3fe0382c..78ecd5b7e5 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ServerSettingsConverter.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ServerSettingsConverter.java
@@ -16,16 +16,15 @@
 
 package com.epam.ta.reportportal.ws.converter.converters;
 
+import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+
 import com.epam.ta.reportportal.entity.ServerSettings;
 import com.epam.ta.reportportal.ws.model.ErrorType;
-import org.apache.commons.collections4.CollectionUtils;
-
 import java.util.List;
 import java.util.Map;
 import java.util.function.Function;
 import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.commons.validation.BusinessRule.expect;
+import org.apache.commons.collections4.CollectionUtils;
 
 /**
  * Converts internal DB model to DTO
@@ -34,13 +33,15 @@
  */
 public final class ServerSettingsConverter {
 
-	private ServerSettingsConverter() {
-		//static only
-	}
+  private ServerSettingsConverter() {
+    //static only
+  }
 
-	public static final Function<List<ServerSettings>, Map<String, String>> TO_RESOURCE = serverSettings -> {
-		expect(serverSettings, CollectionUtils::isNotEmpty).verify(ErrorType.SERVER_SETTINGS_NOT_FOUND, "default");
-		return serverSettings.stream().collect(Collectors.toMap(ServerSettings::getKey, ServerSettings::getValue));
-	};
+  public static final Function<List<ServerSettings>, Map<String, String>> TO_RESOURCE = serverSettings -> {
+    expect(serverSettings, CollectionUtils::isNotEmpty).verify(ErrorType.SERVER_SETTINGS_NOT_FOUND,
+        "default");
+    return serverSettings.stream()
+        .collect(Collectors.toMap(ServerSettings::getKey, ServerSettings::getValue));
+  };
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/StatisticsConverter.java b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/StatisticsConverter.java
index 5505a003c9..f736e464ca 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/StatisticsConverter.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/StatisticsConverter.java
@@ -16,44 +16,47 @@
 
 package com.epam.ta.reportportal.ws.converter.converters;
 
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DEFECTS_KEY;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.EXECUTIONS_KEY;
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.entity.statistics.Statistics;
 import com.epam.ta.reportportal.ws.model.statistics.StatisticsResource;
-import org.apache.commons.lang3.StringUtils;
-
 import java.util.Set;
 import java.util.function.Function;
 import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DEFECTS_KEY;
-import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.EXECUTIONS_KEY;
-import static java.util.Optional.ofNullable;
+import org.apache.commons.lang3.StringUtils;
 
 /**
  * @author Pavel Bortnik
  */
 public final class StatisticsConverter {
 
-	private StatisticsConverter() {
-		//static only
-	}
-
-	public static final Function<Set<Statistics>, StatisticsResource> TO_RESOURCE = statistics -> {
-		StatisticsResource statisticsResource = new StatisticsResource();
-		statisticsResource.setDefects(statistics.stream()
-				.filter(it -> ofNullable(it.getStatisticsField()).isPresent() && StringUtils.isNotEmpty(it.getStatisticsField().getName()))
-				.filter(it -> it.getCounter() > 0 && it.getStatisticsField().getName().contains(DEFECTS_KEY))
-				.collect(Collectors.groupingBy(it -> it.getStatisticsField().getName().split("\\$")[2],
-						Collectors.groupingBy(it -> it.getStatisticsField().getName().split("\\$")[3],
-								Collectors.summingInt(Statistics::getCounter)
-						)
-				)));
-		statisticsResource.setExecutions(statistics.stream()
-				.filter(it -> ofNullable(it.getStatisticsField()).isPresent() && StringUtils.isNotEmpty(it.getStatisticsField().getName()))
-				.filter(it -> it.getCounter() > 0 && it.getStatisticsField().getName().contains(EXECUTIONS_KEY))
-				.collect(Collectors.groupingBy(it -> it.getStatisticsField().getName().split("\\$")[2],
-						Collectors.summingInt(Statistics::getCounter)
-				)));
-		return statisticsResource;
-
-	};
+  private StatisticsConverter() {
+    //static only
+  }
+
+  public static final Function<Set<Statistics>, StatisticsResource> TO_RESOURCE = statistics -> {
+    StatisticsResource statisticsResource = new StatisticsResource();
+    statisticsResource.setDefects(statistics.stream()
+        .filter(it -> ofNullable(it.getStatisticsField()).isPresent() && StringUtils.isNotEmpty(
+            it.getStatisticsField().getName()))
+        .filter(
+            it -> it.getCounter() > 0 && it.getStatisticsField().getName().contains(DEFECTS_KEY))
+        .collect(Collectors.groupingBy(it -> it.getStatisticsField().getName().split("\\$")[2],
+            Collectors.groupingBy(it -> it.getStatisticsField().getName().split("\\$")[3],
+                Collectors.summingInt(Statistics::getCounter)
+            )
+        )));
+    statisticsResource.setExecutions(statistics.stream()
+        .filter(it -> ofNullable(it.getStatisticsField()).isPresent() && StringUtils.isNotEmpty(
+            it.getStatisticsField().getName()))
+        .filter(
+            it -> it.getCounter() > 0 && it.getStatisticsField().getName().contains(EXECUTIONS_KEY))
+        .collect(Collectors.groupingBy(it -> it.getStatisticsField().getName().split("\\$")[2],
+            Collectors.summingInt(Statistics::getCounter)
+        )));
+    return statisticsResource;
+
+  };
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/TestItemConverter.java b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/TestItemConverter.java
index 611b001118..19ec0aaabf 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/TestItemConverter.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/TestItemConverter.java
@@ -16,6 +16,9 @@
 
 package com.epam.ta.reportportal.ws.converter.converters;
 
+import static java.util.Optional.ofNullable;
+import static java.util.stream.Collectors.toSet;
+
 import com.epam.ta.reportportal.commons.EntityUtils;
 import com.epam.ta.reportportal.entity.item.NestedStep;
 import com.epam.ta.reportportal.entity.item.PathName;
@@ -28,15 +31,11 @@
 import com.epam.ta.reportportal.ws.model.item.ItemPathName;
 import com.epam.ta.reportportal.ws.model.item.LaunchPathName;
 import com.epam.ta.reportportal.ws.model.item.PathNameResource;
-import org.apache.commons.collections.CollectionUtils;
-
 import java.util.Objects;
 import java.util.function.BiFunction;
 import java.util.function.Function;
 import java.util.stream.Collectors;
-
-import static java.util.Optional.ofNullable;
-import static java.util.stream.Collectors.toSet;
+import org.apache.commons.collections.CollectionUtils;
 
 /**
  * Converts internal DB model to DTO
@@ -45,101 +44,106 @@
  */
 public final class TestItemConverter {
 
-	private TestItemConverter() {
-		//static only
-	}
+  private TestItemConverter() {
+    //static only
+  }
 
-	public static final Function<TestItem, TestItemResource> TO_RESOURCE = item -> {
-		TestItemResource resource = new TestItemResource();
-		resource.setDescription(item.getDescription());
-		resource.setUniqueId(item.getUniqueId());
-		resource.setTestCaseId(item.getTestCaseId());
-		resource.setTestCaseHash(item.getTestCaseHash());
-		resource.setUuid(item.getUuid());
-		resource.setAttributes(item.getAttributes()
-				.stream()
-				.filter(it -> !it.isSystem())
-				.map(it -> new ItemAttributeResource(it.getKey(), it.getValue()))
-				.collect(toSet()));
-		resource.setEndTime(EntityUtils.TO_DATE.apply(item.getItemResults().getEndTime()));
-		resource.setItemId(item.getItemId());
-		if (null != item.getParameters()) {
-			resource.setParameters(item.getParameters().stream().map(ParametersConverter.TO_RESOURCE).collect(Collectors.toList()));
-		}
-		ofNullable(item.getItemResults().getIssue()).ifPresent(i -> {
-			if (!Objects.isNull(i.getIssueId())) {
-				resource.setIssue(IssueConverter.TO_MODEL.apply(i));
-			}
-		});
-		resource.setName(item.getName());
-		resource.setStartTime(EntityUtils.TO_DATE.apply(item.getStartTime()));
-		resource.setStatus(item.getItemResults().getStatus() != null ? item.getItemResults().getStatus().toString() : null);
-		resource.setType(item.getType() != null ? item.getType().name() : null);
-		resource.setHasChildren(item.isHasChildren());
-		resource.setHasStats(item.isHasStats());
-		resource.setCodeRef(item.getCodeRef());
+  public static final Function<TestItem, TestItemResource> TO_RESOURCE = item -> {
+    TestItemResource resource = new TestItemResource();
+    resource.setDescription(item.getDescription());
+    resource.setUniqueId(item.getUniqueId());
+    resource.setTestCaseId(item.getTestCaseId());
+    resource.setTestCaseHash(item.getTestCaseHash());
+    resource.setUuid(item.getUuid());
+    resource.setAttributes(item.getAttributes()
+        .stream()
+        .filter(it -> !it.isSystem())
+        .map(it -> new ItemAttributeResource(it.getKey(), it.getValue()))
+        .collect(toSet()));
+    resource.setEndTime(EntityUtils.TO_DATE.apply(item.getItemResults().getEndTime()));
+    resource.setItemId(item.getItemId());
+    if (null != item.getParameters()) {
+      resource.setParameters(item.getParameters().stream().map(ParametersConverter.TO_RESOURCE)
+          .collect(Collectors.toList()));
+    }
+    ofNullable(item.getItemResults().getIssue()).ifPresent(i -> {
+      if (!Objects.isNull(i.getIssueId())) {
+        resource.setIssue(IssueConverter.TO_MODEL.apply(i));
+      }
+    });
+    resource.setName(item.getName());
+    resource.setStartTime(EntityUtils.TO_DATE.apply(item.getStartTime()));
+    resource.setStatus(
+        item.getItemResults().getStatus() != null ? item.getItemResults().getStatus().toString()
+            : null);
+    resource.setType(item.getType() != null ? item.getType().name() : null);
+    resource.setHasChildren(item.isHasChildren());
+    resource.setHasStats(item.isHasStats());
+    resource.setCodeRef(item.getCodeRef());
 
-		ofNullable(item.getParentId()).ifPresent(resource::setParent);
-		ofNullable(item.getLaunchId()).ifPresent(resource::setLaunchId);
-		resource.setPatternTemplates(item.getPatternTemplateTestItems()
-				.stream()
-				.map(patternTemplateTestItem -> patternTemplateTestItem.getPatternTemplate().getName())
-				.collect(toSet()));
-		resource.setPath(item.getPath());
-		resource.setStatisticsResource(StatisticsConverter.TO_RESOURCE.apply(item.getItemResults().getStatistics()));
-		return resource;
-	};
+    ofNullable(item.getParentId()).ifPresent(resource::setParent);
+    ofNullable(item.getLaunchId()).ifPresent(resource::setLaunchId);
+    resource.setPatternTemplates(item.getPatternTemplateTestItems()
+        .stream()
+        .map(patternTemplateTestItem -> patternTemplateTestItem.getPatternTemplate().getName())
+        .collect(toSet()));
+    resource.setPath(item.getPath());
+    resource.setStatisticsResource(
+        StatisticsConverter.TO_RESOURCE.apply(item.getItemResults().getStatistics()));
+    return resource;
+  };
 
-	public static final Function<PathName, PathNameResource> PATH_NAME_TO_RESOURCE = pathName -> {
+  public static final Function<PathName, PathNameResource> PATH_NAME_TO_RESOURCE = pathName -> {
 
-		PathNameResource pathNameResource = new PathNameResource();
-		ofNullable(pathName.getLaunchPathName()).ifPresent(lpn -> pathNameResource.setLaunchPathName(new LaunchPathName(lpn.getName(),
-				lpn.getNumber()
-		)));
-		ofNullable(pathName.getItemPaths()).ifPresent(itemPaths -> {
-			if (CollectionUtils.isNotEmpty(itemPaths)) {
-				pathNameResource.setItemPaths(itemPaths.stream()
-						.map(path -> new ItemPathName(path.getId(), path.getName()))
-						.collect(Collectors.toList()));
-			}
-		});
+    PathNameResource pathNameResource = new PathNameResource();
+    ofNullable(pathName.getLaunchPathName()).ifPresent(
+        lpn -> pathNameResource.setLaunchPathName(new LaunchPathName(lpn.getName(),
+            lpn.getNumber()
+        )));
+    ofNullable(pathName.getItemPaths()).ifPresent(itemPaths -> {
+      if (CollectionUtils.isNotEmpty(itemPaths)) {
+        pathNameResource.setItemPaths(itemPaths.stream()
+            .map(path -> new ItemPathName(path.getId(), path.getName()))
+            .collect(Collectors.toList()));
+      }
+    });
 
-		return pathNameResource;
+    return pathNameResource;
 
-	};
+  };
 
-	public static final Function<NestedStep, NestedStepResource> TO_NESTED_STEP_RESOURCE = item -> {
-		NestedStepResource resource = new NestedStepResource();
-		resource.setId(item.getId());
-		resource.setName(item.getName());
-		resource.setUuid(item.getUuid());
-		resource.setStartTime(EntityUtils.TO_DATE.apply(item.getStartTime()));
-		resource.setEndTime(EntityUtils.TO_DATE.apply(item.getEndTime()));
-		resource.setStatus(item.getStatus() != null ? item.getStatus().toString() : null);
-		resource.setType(item.getType() != null ? item.getType().name() : null);
-		resource.setHasContent(item.isHasContent());
-		resource.setAttachmentsCount(item.getAttachmentsCount());
-		resource.setDuration(item.getDuration());
+  public static final Function<NestedStep, NestedStepResource> TO_NESTED_STEP_RESOURCE = item -> {
+    NestedStepResource resource = new NestedStepResource();
+    resource.setId(item.getId());
+    resource.setName(item.getName());
+    resource.setUuid(item.getUuid());
+    resource.setStartTime(EntityUtils.TO_DATE.apply(item.getStartTime()));
+    resource.setEndTime(EntityUtils.TO_DATE.apply(item.getEndTime()));
+    resource.setStatus(item.getStatus() != null ? item.getStatus().toString() : null);
+    resource.setType(item.getType() != null ? item.getType().name() : null);
+    resource.setHasContent(item.isHasContent());
+    resource.setAttachmentsCount(item.getAttachmentsCount());
+    resource.setDuration(item.getDuration());
 
-		return resource;
-	};
+    return resource;
+  };
 
-	public static final BiFunction<TestItem, Long, TestItemActivityResource> TO_ACTIVITY_RESOURCE = (testItem, projectId) -> {
-		TestItemActivityResource resource = new TestItemActivityResource();
-		resource.setId(testItem.getItemId());
-		resource.setName(testItem.getName());
-		resource.setStatus(testItem.getItemResults().getStatus().name());
-		resource.setProjectId(projectId);
-		IssueEntity issue = testItem.getItemResults().getIssue();
-		if (issue != null) {
-			resource.setAutoAnalyzed(issue.getAutoAnalyzed());
-			resource.setIgnoreAnalyzer(issue.getIgnoreAnalyzer());
-			resource.setIssueDescription(issue.getIssueDescription());
-			resource.setIssueTypeLongName(issue.getIssueType().getLongName());
-			ofNullable(issue.getTickets()).ifPresent(it -> resource.setTickets(it.stream()
-					.map(ticket -> ticket.getTicketId().concat(":").concat(ticket.getUrl()))
-					.collect(Collectors.joining(", "))));
-		}
-		return resource;
-	};
+  public static final BiFunction<TestItem, Long, TestItemActivityResource> TO_ACTIVITY_RESOURCE = (testItem, projectId) -> {
+    TestItemActivityResource resource = new TestItemActivityResource();
+    resource.setId(testItem.getItemId());
+    resource.setName(testItem.getName());
+    resource.setStatus(testItem.getItemResults().getStatus().name());
+    resource.setProjectId(projectId);
+    IssueEntity issue = testItem.getItemResults().getIssue();
+    if (issue != null) {
+      resource.setAutoAnalyzed(issue.getAutoAnalyzed());
+      resource.setIgnoreAnalyzer(issue.getIgnoreAnalyzer());
+      resource.setIssueDescription(issue.getIssueDescription());
+      resource.setIssueTypeLongName(issue.getIssueType().getLongName());
+      ofNullable(issue.getTickets()).ifPresent(it -> resource.setTickets(it.stream()
+          .map(ticket -> ticket.getTicketId().concat(":").concat(ticket.getUrl()))
+          .collect(Collectors.joining(", "))));
+    }
+    return resource;
+  };
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/TicketConverter.java b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/TicketConverter.java
index 8d81ef5fc5..73052d8db0 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/TicketConverter.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/TicketConverter.java
@@ -19,7 +19,6 @@
 import com.epam.ta.reportportal.entity.bts.Ticket;
 import com.epam.ta.reportportal.ws.model.issue.Issue;
 import com.google.common.base.Preconditions;
-
 import java.util.function.Function;
 
 /**
@@ -27,18 +26,18 @@
  */
 public final class TicketConverter {
 
-	private TicketConverter() {
-		//static only
-	}
+  private TicketConverter() {
+    //static only
+  }
 
-	public static final Function<Issue.ExternalSystemIssue, Ticket> TO_TICKET = issue -> {
-		Preconditions.checkNotNull(issue);
-		Ticket ticket = new Ticket();
-		ticket.setBtsUrl(issue.getBtsUrl());
-		ticket.setBtsProject(issue.getBtsProject());
-		ticket.setTicketId(issue.getTicketId());
-		ticket.setUrl(issue.getUrl());
-		ticket.setPluginName(issue.getPluginName());
-		return ticket;
-	};
+  public static final Function<Issue.ExternalSystemIssue, Ticket> TO_TICKET = issue -> {
+    Preconditions.checkNotNull(issue);
+    Ticket ticket = new Ticket();
+    ticket.setBtsUrl(issue.getBtsUrl());
+    ticket.setBtsProject(issue.getBtsProject());
+    ticket.setTicketId(issue.getTicketId());
+    ticket.setUrl(issue.getUrl());
+    ticket.setPluginName(issue.getPluginName());
+    return ticket;
+  };
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/UserCreationBidConverter.java b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/UserCreationBidConverter.java
index 1819d62263..137353c8a4 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/UserCreationBidConverter.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/UserCreationBidConverter.java
@@ -21,7 +21,6 @@
 import com.epam.ta.reportportal.entity.user.UserCreationBid;
 import com.epam.ta.reportportal.ws.model.user.CreateUserRQ;
 import com.google.common.base.Preconditions;
-
 import java.util.UUID;
 import java.util.function.BiFunction;
 
@@ -32,17 +31,17 @@
  */
 public final class UserCreationBidConverter {
 
-	private UserCreationBidConverter() {
-		//static only
-	}
+  private UserCreationBidConverter() {
+    //static only
+  }
 
-	public static final BiFunction<CreateUserRQ, Project, UserCreationBid> TO_USER = (request, project) -> {
-		Preconditions.checkNotNull(request);
-		UserCreationBid user = new UserCreationBid();
-		user.setUuid(UUID.randomUUID().toString());
-		user.setEmail(EntityUtils.normalizeId(request.getEmail().trim()));
-		user.setDefaultProject(project);
-		user.setRole(request.getRole());
-		return user;
-	};
+  public static final BiFunction<CreateUserRQ, Project, UserCreationBid> TO_USER = (request, project) -> {
+    Preconditions.checkNotNull(request);
+    UserCreationBid user = new UserCreationBid();
+    user.setUuid(UUID.randomUUID().toString());
+    user.setEmail(EntityUtils.normalizeId(request.getEmail().trim()));
+    user.setProjectName(project.getName());
+    user.setRole(request.getRole());
+    return user;
+  };
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/WidgetConverter.java b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/WidgetConverter.java
index 1f59e20fcc..87b95395e9 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/WidgetConverter.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/WidgetConverter.java
@@ -38,75 +38,76 @@
  */
 public class WidgetConverter {
 
-	public static final Function<DashboardWidget, DashboardResource.WidgetObjectModel> TO_OBJECT_MODEL = dashboardWidget -> {
-		DashboardResource.WidgetObjectModel objectModel = new DashboardResource.WidgetObjectModel();
-		objectModel.setName(dashboardWidget.getWidgetName());
-		objectModel.setWidgetType(dashboardWidget.getWidgetType());
-		objectModel.setWidgetId(dashboardWidget.getId().getWidgetId());
-		objectModel.setWidgetPosition(new Position(dashboardWidget.getPositionX(), dashboardWidget.getPositionY()));
-		objectModel.setWidgetSize(new Size(dashboardWidget.getWidth(), dashboardWidget.getHeight()));
-		ofNullable(dashboardWidget.getWidget().getWidgetOptions()).ifPresent(wo -> objectModel.setWidgetOptions(wo.getOptions()));
-		return objectModel;
-	};
+  public static final Function<DashboardWidget, DashboardResource.WidgetObjectModel> TO_OBJECT_MODEL = dashboardWidget -> {
+    DashboardResource.WidgetObjectModel objectModel = new DashboardResource.WidgetObjectModel();
+    objectModel.setName(dashboardWidget.getWidgetName());
+    objectModel.setWidgetType(dashboardWidget.getWidgetType());
+    objectModel.setWidgetId(dashboardWidget.getId().getWidgetId());
+    objectModel.setWidgetPosition(new Position(dashboardWidget.getPositionX(), dashboardWidget.getPositionY()));
+    objectModel.setWidgetSize(new Size(dashboardWidget.getWidth(), dashboardWidget.getHeight()));
+    ofNullable(dashboardWidget.getWidget().getWidgetOptions()).ifPresent(wo -> objectModel.setWidgetOptions(wo.getOptions()));
+    return objectModel;
+  };
 
-	public static final Function<Widget, WidgetResource> TO_WIDGET_RESOURCE = widget -> {
-		WidgetResource widgetResource = new WidgetResource();
-		widgetResource.setWidgetId(widget.getId());
-		widgetResource.setName(widget.getName());
-		widgetResource.setWidgetType(widget.getWidgetType());
-		widgetResource.setDescription(widget.getDescription());
-		widgetResource.setOwner(widget.getOwner());
-		ofNullable(widget.getFilters()).ifPresent(filter -> widgetResource.setAppliedFilters(UserFilterConverter.FILTER_SET_TO_FILTER_RESOURCE
-				.apply(filter)));
-		ContentParameters contentParameters = new ContentParameters();
-		contentParameters.setItemsCount(widget.getItemsCount());
-		ofNullable(widget.getWidgetOptions()).ifPresent(wo -> contentParameters.setWidgetOptions(wo.getOptions()));
-		contentParameters.setContentFields(Lists.newArrayList(widget.getContentFields()));
-		widgetResource.setContentParameters(contentParameters);
-		return widgetResource;
-	};
+  public static final Function<Widget, WidgetResource> TO_WIDGET_RESOURCE = widget -> {
+    WidgetResource widgetResource = new WidgetResource();
+    widgetResource.setWidgetId(widget.getId());
+    widgetResource.setName(widget.getName());
+    widgetResource.setWidgetType(widget.getWidgetType());
+    widgetResource.setDescription(widget.getDescription());
+    widgetResource.setOwner(widget.getOwner());
+    ofNullable(widget.getFilters()).ifPresent(filter -> widgetResource.setAppliedFilters(UserFilterConverter.FILTER_SET_TO_FILTER_RESOURCE
+        .apply(filter)));
+    ContentParameters contentParameters = new ContentParameters();
+    contentParameters.setItemsCount(widget.getItemsCount());
+    ofNullable(widget.getWidgetOptions()).ifPresent(wo -> contentParameters.setWidgetOptions(wo.getOptions()));
+    contentParameters.setContentFields(Lists.newArrayList(widget.getContentFields()));
+    widgetResource.setContentParameters(contentParameters);
+    return widgetResource;
+  };
 
-	public static final Function<Widget, WidgetActivityResource> TO_ACTIVITY_RESOURCE = widget -> {
-		WidgetActivityResource resource = new WidgetActivityResource();
-		resource.setId(widget.getId());
-		resource.setProjectId(widget.getProject().getId());
-		resource.setName(widget.getName());
-		resource.setDescription(widget.getDescription());
-		resource.setItemsCount(widget.getItemsCount());
-		resource.setContentFields(Sets.newHashSet(widget.getContentFields()));
-		ofNullable(widget.getWidgetOptions()).ifPresent(wo -> resource.setWidgetOptions(wo.getOptions()));
-		return resource;
-	};
+  public static final Function<Widget, WidgetActivityResource> TO_ACTIVITY_RESOURCE = widget -> {
+    WidgetActivityResource resource = new WidgetActivityResource();
+    resource.setId(widget.getId());
+    resource.setProjectId(widget.getProject().getId());
+    resource.setName(widget.getName());
+    resource.setDescription(widget.getDescription());
+    resource.setItemsCount(widget.getItemsCount());
+    resource.setContentFields(Sets.newHashSet(widget.getContentFields()));
+    ofNullable(widget.getWidgetOptions()).ifPresent(wo -> resource.setWidgetOptions(wo.getOptions()));
+    return resource;
+  };
 
-	/**
-	 * Creates many-to-many object representation of dashboards and widgets
-	 *
-	 * @param model     Widget model object
-	 * @param dashboard Dashboard
-	 * @param widget    Widget
-	 * @return many-to-many object representation
-	 */
-	public static DashboardWidget toDashboardWidget(DashboardResource.WidgetObjectModel model, Dashboard dashboard, Widget widget,
-			boolean isCreatedOn) {
+  /**
+   * Creates many-to-many object representation of dashboards and widgets
+   *
+   * @param model       Widget model object
+   * @param dashboard   Dashboard
+   * @param widget      Widget
+   * @param isCreatedOn true if widget was created
+   * @return many-to-many object representation
+   */
+  public static DashboardWidget toDashboardWidget(DashboardResource.WidgetObjectModel model, Dashboard dashboard, Widget widget,
+      boolean isCreatedOn) {
 
-		DashboardWidgetId id = new DashboardWidgetId();
-		id.setDashboardId(dashboard.getId());
-		id.setWidgetId(model.getWidgetId());
+    DashboardWidgetId id = new DashboardWidgetId();
+    id.setDashboardId(dashboard.getId());
+    id.setWidgetId(model.getWidgetId());
 
-		DashboardWidget dashboardWidget = new DashboardWidget();
-		dashboardWidget.setId(id);
-		dashboardWidget.setWidgetType(widget.getWidgetType());
-		dashboardWidget.setWidgetName(widget.getName());
-		dashboardWidget.setPositionX(model.getWidgetPosition().getX());
-		dashboardWidget.setPositionY(model.getWidgetPosition().getY());
-		dashboardWidget.setWidth(model.getWidgetSize().getWidth());
-		dashboardWidget.setHeight(model.getWidgetSize().getHeight());
-		dashboardWidget.setDashboard(dashboard);
-		dashboardWidget.setWidget(widget);
-		dashboardWidget.setCreatedOn(isCreatedOn);
-		dashboardWidget.setWidgetOwner(widget.getOwner());
+    DashboardWidget dashboardWidget = new DashboardWidget();
+    dashboardWidget.setId(id);
+    dashboardWidget.setWidgetType(widget.getWidgetType());
+    dashboardWidget.setWidgetName(widget.getName());
+    dashboardWidget.setPositionX(model.getWidgetPosition().getX());
+    dashboardWidget.setPositionY(model.getWidgetPosition().getY());
+    dashboardWidget.setWidth(model.getWidgetSize().getWidth());
+    dashboardWidget.setHeight(model.getWidgetSize().getHeight());
+    dashboardWidget.setDashboard(dashboard);
+    dashboardWidget.setWidget(widget);
+    dashboardWidget.setCreatedOn(isCreatedOn);
+    dashboardWidget.setWidgetOwner(widget.getOwner());
 
-		return dashboardWidget;
-	}
+    return dashboardWidget;
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/ItemAttributeType.java b/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/ItemAttributeType.java
index 294566c256..7fa3c7ab1d 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/ItemAttributeType.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/ItemAttributeType.java
@@ -20,7 +20,7 @@
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public enum ItemAttributeType {
-	PUBLIC,
-	SYSTEM,
-	UNRESOLVED
+  PUBLIC,
+  SYSTEM,
+  UNRESOLVED
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/ResourceAttributeHandler.java b/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/ResourceAttributeHandler.java
index 150c0445ec..81680ba8bd 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/ResourceAttributeHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/ResourceAttributeHandler.java
@@ -17,7 +17,6 @@
 package com.epam.ta.reportportal.ws.converter.resource.handler.attribute;
 
 import com.epam.ta.reportportal.entity.ItemAttribute;
-
 import java.util.Collection;
 
 /**
@@ -25,6 +24,6 @@
  */
 public interface ResourceAttributeHandler<T> {
 
-	void handle(T resource, Collection<ItemAttribute> attributes);
+  void handle(T resource, Collection<ItemAttribute> attributes);
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/launch/LaunchResourceAttributeLogger.java b/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/launch/LaunchResourceAttributeLogger.java
index c157b1ea33..226ebc48e9 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/launch/LaunchResourceAttributeLogger.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/launch/LaunchResourceAttributeLogger.java
@@ -19,28 +19,28 @@
 import com.epam.ta.reportportal.entity.ItemAttribute;
 import com.epam.ta.reportportal.ws.converter.resource.handler.attribute.ResourceAttributeHandler;
 import com.epam.ta.reportportal.ws.model.launch.LaunchResource;
+import java.util.Collection;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.Collection;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public class LaunchResourceAttributeLogger implements ResourceAttributeHandler<LaunchResource> {
 
-	private static final Logger LOGGER = LoggerFactory.getLogger(LaunchResourceAttributeLogger.class);
+  private static final Logger LOGGER = LoggerFactory.getLogger(LaunchResourceAttributeLogger.class);
 
-	private final String baseMessage;
+  private final String baseMessage;
 
-	public LaunchResourceAttributeLogger(String baseMessage) {
-		this.baseMessage = baseMessage;
-	}
+  public LaunchResourceAttributeLogger(String baseMessage) {
+    this.baseMessage = baseMessage;
+  }
 
-	@Override
-	public void handle(LaunchResource resource, Collection<ItemAttribute> attributes) {
-		if (LOGGER.isDebugEnabled()) {
-			LOGGER.debug(baseMessage + " Launch - {}, attributes - {}", resource.getLaunchId(), attributes);
-		}
-	}
+  @Override
+  public void handle(LaunchResource resource, Collection<ItemAttribute> attributes) {
+    if (LOGGER.isDebugEnabled()) {
+      LOGGER.debug(baseMessage + " Launch - {}, attributes - {}", resource.getLaunchId(),
+          attributes);
+    }
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/launch/LaunchResourceAttributeUpdater.java b/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/launch/LaunchResourceAttributeUpdater.java
index b427400704..1ff7947d06 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/launch/LaunchResourceAttributeUpdater.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/launch/LaunchResourceAttributeUpdater.java
@@ -16,22 +16,23 @@
 
 package com.epam.ta.reportportal.ws.converter.resource.handler.attribute.launch;
 
+import static java.util.stream.Collectors.toSet;
+
 import com.epam.ta.reportportal.entity.ItemAttribute;
 import com.epam.ta.reportportal.ws.converter.resource.handler.attribute.ResourceAttributeHandler;
 import com.epam.ta.reportportal.ws.model.attribute.ItemAttributeResource;
 import com.epam.ta.reportportal.ws.model.launch.LaunchResource;
-
 import java.util.Collection;
 
-import static java.util.stream.Collectors.toSet;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public class LaunchResourceAttributeUpdater implements ResourceAttributeHandler<LaunchResource> {
 
-	@Override
-	public void handle(LaunchResource resource, Collection<ItemAttribute> attributes) {
-		resource.setAttributes(attributes.stream().map(it -> new ItemAttributeResource(it.getKey(), it.getValue())).collect(toSet()));
-	}
+  @Override
+  public void handle(LaunchResource resource, Collection<ItemAttribute> attributes) {
+    resource.setAttributes(
+        attributes.stream().map(it -> new ItemAttributeResource(it.getKey(), it.getValue()))
+            .collect(toSet()));
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/matcher/ItemAttributeTypeMatcher.java b/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/matcher/ItemAttributeTypeMatcher.java
index dbb199ba72..a2822a28f6 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/matcher/ItemAttributeTypeMatcher.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/matcher/ItemAttributeTypeMatcher.java
@@ -24,7 +24,7 @@
  */
 public interface ItemAttributeTypeMatcher {
 
-	boolean matches(ItemAttribute attribute);
+  boolean matches(ItemAttribute attribute);
 
-	ItemAttributeType getType();
+  ItemAttributeType getType();
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/matcher/PredicateItemAttributeTypeMatcher.java b/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/matcher/PredicateItemAttributeTypeMatcher.java
index 08f49bfae2..bb5997a517 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/matcher/PredicateItemAttributeTypeMatcher.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/matcher/PredicateItemAttributeTypeMatcher.java
@@ -18,7 +18,6 @@
 
 import com.epam.ta.reportportal.entity.ItemAttribute;
 import com.epam.ta.reportportal.ws.converter.resource.handler.attribute.ItemAttributeType;
-
 import java.util.function.Predicate;
 
 /**
@@ -26,21 +25,22 @@
  */
 public class PredicateItemAttributeTypeMatcher implements ItemAttributeTypeMatcher {
 
-	private final Predicate<ItemAttribute> predicate;
-	private final ItemAttributeType type;
+  private final Predicate<ItemAttribute> predicate;
+  private final ItemAttributeType type;
 
-	public PredicateItemAttributeTypeMatcher(Predicate<ItemAttribute> predicate, ItemAttributeType type) {
-		this.predicate = predicate;
-		this.type = type;
-	}
+  public PredicateItemAttributeTypeMatcher(Predicate<ItemAttribute> predicate,
+      ItemAttributeType type) {
+    this.predicate = predicate;
+    this.type = type;
+  }
 
-	@Override
-	public boolean matches(ItemAttribute attribute) {
-		return predicate.test(attribute);
-	}
+  @Override
+  public boolean matches(ItemAttribute attribute) {
+    return predicate.test(attribute);
+  }
 
-	@Override
-	public ItemAttributeType getType() {
-		return type;
-	}
+  @Override
+  public ItemAttributeType getType() {
+    return type;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/resolver/ItemAttributeTypeResolver.java b/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/resolver/ItemAttributeTypeResolver.java
index a41429c69f..afd4758407 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/resolver/ItemAttributeTypeResolver.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/resolver/ItemAttributeTypeResolver.java
@@ -18,7 +18,6 @@
 
 import com.epam.ta.reportportal.entity.ItemAttribute;
 import com.epam.ta.reportportal.ws.converter.resource.handler.attribute.ItemAttributeType;
-
 import java.util.Optional;
 
 /**
@@ -26,6 +25,6 @@
  */
 public interface ItemAttributeTypeResolver {
 
-	Optional<ItemAttributeType> resolve(ItemAttribute attribute);
+  Optional<ItemAttributeType> resolve(ItemAttribute attribute);
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/resolver/ItemAttributeTypeResolverDelegate.java b/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/resolver/ItemAttributeTypeResolverDelegate.java
index 22ad04177f..7de9450e90 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/resolver/ItemAttributeTypeResolverDelegate.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/resolver/ItemAttributeTypeResolverDelegate.java
@@ -19,7 +19,6 @@
 import com.epam.ta.reportportal.entity.ItemAttribute;
 import com.epam.ta.reportportal.ws.converter.resource.handler.attribute.ItemAttributeType;
 import com.epam.ta.reportportal.ws.converter.resource.handler.attribute.matcher.ItemAttributeTypeMatcher;
-
 import java.util.List;
 import java.util.Optional;
 
@@ -28,14 +27,15 @@
  */
 public class ItemAttributeTypeResolverDelegate implements ItemAttributeTypeResolver {
 
-	private final List<ItemAttributeTypeMatcher> matchers;
+  private final List<ItemAttributeTypeMatcher> matchers;
 
-	public ItemAttributeTypeResolverDelegate(List<ItemAttributeTypeMatcher> matchers) {
-		this.matchers = matchers;
-	}
+  public ItemAttributeTypeResolverDelegate(List<ItemAttributeTypeMatcher> matchers) {
+    this.matchers = matchers;
+  }
 
-	@Override
-	public Optional<ItemAttributeType> resolve(ItemAttribute attribute) {
-		return matchers.stream().filter(m -> m.matches(attribute)).findFirst().map(ItemAttributeTypeMatcher::getType);
-	}
+  @Override
+  public Optional<ItemAttributeType> resolve(ItemAttribute attribute) {
+    return matchers.stream().filter(m -> m.matches(attribute)).findFirst()
+        .map(ItemAttributeTypeMatcher::getType);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/utils/ResourceUpdater.java b/src/main/java/com/epam/ta/reportportal/ws/converter/utils/ResourceUpdater.java
index a069fbfc91..794e4d1b33 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/utils/ResourceUpdater.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/utils/ResourceUpdater.java
@@ -21,5 +21,5 @@
  */
 public interface ResourceUpdater<R> {
 
-	void updateResource(R resource);
+  void updateResource(R resource);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/utils/ResourceUpdaterProvider.java b/src/main/java/com/epam/ta/reportportal/ws/converter/utils/ResourceUpdaterProvider.java
index b3e7db48d7..47254f3810 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/utils/ResourceUpdaterProvider.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/utils/ResourceUpdaterProvider.java
@@ -21,5 +21,5 @@
  */
 public interface ResourceUpdaterProvider<C extends ResourceUpdaterContent, R> {
 
-	ResourceUpdater<R> retrieve(C updaterContent);
+  ResourceUpdater<R> retrieve(C updaterContent);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/utils/item/content/TestItemUpdaterContent.java b/src/main/java/com/epam/ta/reportportal/ws/converter/utils/item/content/TestItemUpdaterContent.java
index ffaa22fcc0..155d717b34 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/utils/item/content/TestItemUpdaterContent.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/utils/item/content/TestItemUpdaterContent.java
@@ -18,7 +18,6 @@
 
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.ws.converter.utils.ResourceUpdaterContent;
-
 import java.util.List;
 
 /**
@@ -26,23 +25,23 @@
  */
 public final class TestItemUpdaterContent implements ResourceUpdaterContent {
 
-	private final Long projectId;
-	private final List<TestItem> testItems;
+  private final Long projectId;
+  private final List<TestItem> testItems;
 
-	private TestItemUpdaterContent(Long projectId, List<TestItem> testItems) {
-		this.projectId = projectId;
-		this.testItems = testItems;
-	}
+  private TestItemUpdaterContent(Long projectId, List<TestItem> testItems) {
+    this.projectId = projectId;
+    this.testItems = testItems;
+  }
 
-	public Long getProjectId() {
-		return projectId;
-	}
+  public Long getProjectId() {
+    return projectId;
+  }
 
-	public List<TestItem> getTestItems() {
-		return testItems;
-	}
+  public List<TestItem> getTestItems() {
+    return testItems;
+  }
 
-	public static TestItemUpdaterContent of(Long projectId, List<TestItem> testItems) {
-		return new TestItemUpdaterContent(projectId, testItems);
-	}
+  public static TestItemUpdaterContent of(Long projectId, List<TestItem> testItems) {
+    return new TestItemUpdaterContent(projectId, testItems);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/utils/item/provider/PathNameUpdaterProvider.java b/src/main/java/com/epam/ta/reportportal/ws/converter/utils/item/provider/PathNameUpdaterProvider.java
index 5b42f070bf..ed707962aa 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/utils/item/provider/PathNameUpdaterProvider.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/utils/item/provider/PathNameUpdaterProvider.java
@@ -23,28 +23,29 @@
 import com.epam.ta.reportportal.ws.converter.utils.item.content.TestItemUpdaterContent;
 import com.epam.ta.reportportal.ws.converter.utils.item.updater.PathNameUpdater;
 import com.epam.ta.reportportal.ws.model.TestItemResource;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.Map;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
-public class PathNameUpdaterProvider implements ResourceUpdaterProvider<TestItemUpdaterContent, TestItemResource> {
+public class PathNameUpdaterProvider implements
+    ResourceUpdaterProvider<TestItemUpdaterContent, TestItemResource> {
 
-	private final TestItemRepository testItemRepository;
+  private final TestItemRepository testItemRepository;
 
-	@Autowired
-	public PathNameUpdaterProvider(TestItemRepository testItemRepository) {
-		this.testItemRepository = testItemRepository;
-	}
+  @Autowired
+  public PathNameUpdaterProvider(TestItemRepository testItemRepository) {
+    this.testItemRepository = testItemRepository;
+  }
 
-	@Override
-	public ResourceUpdater<TestItemResource> retrieve(TestItemUpdaterContent updaterContent) {
-		Map<Long, PathName> pathNamesMapping = testItemRepository.selectPathNames(updaterContent.getTestItems());
+  @Override
+  public ResourceUpdater<TestItemResource> retrieve(TestItemUpdaterContent updaterContent) {
+    Map<Long, PathName> pathNamesMapping = testItemRepository.selectPathNames(
+        updaterContent.getTestItems());
 
-		return PathNameUpdater.of(pathNamesMapping);
-	}
+    return PathNameUpdater.of(pathNamesMapping);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/utils/item/provider/RetriesUpdaterProvider.java b/src/main/java/com/epam/ta/reportportal/ws/converter/utils/item/provider/RetriesUpdaterProvider.java
index 762b29bab2..46b8d3e11e 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/utils/item/provider/RetriesUpdaterProvider.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/utils/item/provider/RetriesUpdaterProvider.java
@@ -16,42 +16,43 @@
 
 package com.epam.ta.reportportal.ws.converter.utils.item.provider;
 
+import static java.util.stream.Collectors.groupingBy;
+
 import com.epam.ta.reportportal.dao.TestItemRepository;
 import com.epam.ta.reportportal.entity.item.TestItem;
-import com.epam.ta.reportportal.ws.converter.utils.ResourceUpdaterProvider;
 import com.epam.ta.reportportal.ws.converter.utils.ResourceUpdater;
+import com.epam.ta.reportportal.ws.converter.utils.ResourceUpdaterProvider;
 import com.epam.ta.reportportal.ws.converter.utils.item.content.TestItemUpdaterContent;
 import com.epam.ta.reportportal.ws.converter.utils.item.updater.RetriesUpdater;
 import com.epam.ta.reportportal.ws.model.TestItemResource;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
-
-import static java.util.stream.Collectors.groupingBy;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Service
-public class RetriesUpdaterProvider implements ResourceUpdaterProvider<TestItemUpdaterContent, TestItemResource> {
-
-	private final TestItemRepository testItemRepository;
-
-	@Autowired
-	public RetriesUpdaterProvider(TestItemRepository testItemRepository) {
-		this.testItemRepository = testItemRepository;
-	}
-
-	@Override
-	public ResourceUpdater<TestItemResource> retrieve(TestItemUpdaterContent updaterContent) {
-		Map<Long, List<TestItem>> retriesMapping = testItemRepository.selectRetries(updaterContent.getTestItems()
-				.stream()
-				.filter(TestItem::isHasRetries)
-				.map(TestItem::getItemId)
-				.collect(Collectors.toList())).stream().collect(groupingBy(TestItem::getRetryOf));
-		return RetriesUpdater.of(retriesMapping);
-	}
+public class RetriesUpdaterProvider implements
+    ResourceUpdaterProvider<TestItemUpdaterContent, TestItemResource> {
+
+  private final TestItemRepository testItemRepository;
+
+  @Autowired
+  public RetriesUpdaterProvider(TestItemRepository testItemRepository) {
+    this.testItemRepository = testItemRepository;
+  }
+
+  @Override
+  public ResourceUpdater<TestItemResource> retrieve(TestItemUpdaterContent updaterContent) {
+    Map<Long, List<TestItem>> retriesMapping = testItemRepository.selectRetries(
+        updaterContent.getTestItems()
+            .stream()
+            .filter(TestItem::isHasRetries)
+            .map(TestItem::getItemId)
+            .collect(Collectors.toList())).stream().collect(groupingBy(TestItem::getRetryOf));
+    return RetriesUpdater.of(retriesMapping);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/utils/item/updater/PathNameUpdater.java b/src/main/java/com/epam/ta/reportportal/ws/converter/utils/item/updater/PathNameUpdater.java
index 9452520a8a..5521cbb97c 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/utils/item/updater/PathNameUpdater.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/utils/item/updater/PathNameUpdater.java
@@ -16,33 +16,33 @@
 
 package com.epam.ta.reportportal.ws.converter.utils.item.updater;
 
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.entity.item.PathName;
 import com.epam.ta.reportportal.ws.converter.converters.TestItemConverter;
 import com.epam.ta.reportportal.ws.converter.utils.ResourceUpdater;
 import com.epam.ta.reportportal.ws.model.TestItemResource;
-
 import java.util.Map;
 
-import static java.util.Optional.ofNullable;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public class PathNameUpdater implements ResourceUpdater<TestItemResource> {
 
-	private final Map<Long, PathName> pathNamesMapping;
+  private final Map<Long, PathName> pathNamesMapping;
 
-	private PathNameUpdater(Map<Long, PathName> pathNamesMapping) {
-		this.pathNamesMapping = pathNamesMapping;
-	}
+  private PathNameUpdater(Map<Long, PathName> pathNamesMapping) {
+    this.pathNamesMapping = pathNamesMapping;
+  }
 
-	@Override
-	public void updateResource(TestItemResource resource) {
-		ofNullable(pathNamesMapping.get(resource.getItemId())).ifPresent(pathName -> resource.setPathNames(TestItemConverter.PATH_NAME_TO_RESOURCE
-				.apply(pathName)));
-	}
+  @Override
+  public void updateResource(TestItemResource resource) {
+    ofNullable(pathNamesMapping.get(resource.getItemId())).ifPresent(
+        pathName -> resource.setPathNames(TestItemConverter.PATH_NAME_TO_RESOURCE
+            .apply(pathName)));
+  }
 
-	public static PathNameUpdater of(Map<Long, PathName> pathNameMapping) {
-		return new PathNameUpdater(pathNameMapping);
-	}
+  public static PathNameUpdater of(Map<Long, PathName> pathNameMapping) {
+    return new PathNameUpdater(pathNameMapping);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/utils/item/updater/RetriesUpdater.java b/src/main/java/com/epam/ta/reportportal/ws/converter/utils/item/updater/RetriesUpdater.java
index 42a76ba47c..5b2d2bc442 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/converter/utils/item/updater/RetriesUpdater.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/converter/utils/item/updater/RetriesUpdater.java
@@ -16,36 +16,36 @@
 
 package com.epam.ta.reportportal.ws.converter.utils.item.updater;
 
+import static java.util.Optional.ofNullable;
+
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.ws.converter.converters.TestItemConverter;
 import com.epam.ta.reportportal.ws.converter.utils.ResourceUpdater;
 import com.epam.ta.reportportal.ws.model.TestItemResource;
-
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 
-import static java.util.Optional.ofNullable;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public class RetriesUpdater implements ResourceUpdater<TestItemResource> {
 
-	private final Map<Long, List<TestItem>> retriesMapping;
+  private final Map<Long, List<TestItem>> retriesMapping;
 
-	private RetriesUpdater(Map<Long, List<TestItem>> retriesMapping) {
-		this.retriesMapping = retriesMapping;
-	}
+  private RetriesUpdater(Map<Long, List<TestItem>> retriesMapping) {
+    this.retriesMapping = retriesMapping;
+  }
 
-	@Override
-	public void updateResource(TestItemResource resource) {
-		ofNullable(retriesMapping.get(resource.getItemId())).ifPresent(retries -> resource.setRetries(retries.stream()
-				.map(TestItemConverter.TO_RESOURCE)
-				.collect(Collectors.toList())));
-	}
+  @Override
+  public void updateResource(TestItemResource resource) {
+    ofNullable(retriesMapping.get(resource.getItemId())).ifPresent(
+        retries -> resource.setRetries(retries.stream()
+            .map(TestItemConverter.TO_RESOURCE)
+            .collect(Collectors.toList())));
+  }
 
-	public static RetriesUpdater of(Map<Long, List<TestItem>> retriesMapping) {
-		return new RetriesUpdater(retriesMapping);
-	}
+  public static RetriesUpdater of(Map<Long, List<TestItem>> retriesMapping) {
+    return new RetriesUpdater(retriesMapping);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/handler/QueryHandler.java b/src/main/java/com/epam/ta/reportportal/ws/handler/QueryHandler.java
index 9807f17b78..3dde7d4ed3 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/handler/QueryHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/handler/QueryHandler.java
@@ -23,5 +23,5 @@
  */
 public interface QueryHandler {
 
-	Object find(QueryRQ queryRQ);
+  Object find(QueryRQ queryRQ);
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/handler/impl/QueryHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/ws/handler/impl/QueryHandlerImpl.java
index 0cff6786ad..54ed9e187a 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/handler/impl/QueryHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/handler/impl/QueryHandlerImpl.java
@@ -16,7 +16,11 @@
 
 package com.epam.ta.reportportal.ws.handler.impl;
 
-import com.epam.ta.reportportal.dao.*;
+import com.epam.ta.reportportal.dao.FilterableRepository;
+import com.epam.ta.reportportal.dao.IntegrationRepository;
+import com.epam.ta.reportportal.dao.LogRepository;
+import com.epam.ta.reportportal.dao.ProjectRepository;
+import com.epam.ta.reportportal.dao.TestItemRepository;
 import com.epam.ta.reportportal.entity.integration.Integration;
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.log.Log;
@@ -25,10 +29,9 @@
 import com.epam.ta.reportportal.ws.handler.QueryHandler;
 import com.epam.ta.reportportal.ws.rabbit.QueryRQ;
 import com.google.common.collect.ImmutableMap;
-import org.springframework.stereotype.Service;
-
 import java.util.Map;
 import java.util.Optional;
+import org.springframework.stereotype.Service;
 
 /**
  * @author Yauheni_Martynau
@@ -36,34 +39,35 @@
 @Service
 public class QueryHandlerImpl implements QueryHandler {
 
-	private final ProjectRepository projectRepository;
-	private final IntegrationRepository integrationRepository;
-	private final TestItemRepository testItemRepository;
-	private final LogRepository logRepository;
+  private final ProjectRepository projectRepository;
+  private final IntegrationRepository integrationRepository;
+  private final TestItemRepository testItemRepository;
+  private final LogRepository logRepository;
 
-	private Map<String, FilterableRepository> repositories;
+  private Map<String, FilterableRepository> repositories;
 
-	public QueryHandlerImpl(ProjectRepository projectRepository, IntegrationRepository integrationRepository,
-			TestItemRepository testItemRepository, LogRepository logRepository) {
+  public QueryHandlerImpl(ProjectRepository projectRepository,
+      IntegrationRepository integrationRepository,
+      TestItemRepository testItemRepository, LogRepository logRepository) {
 
-		this.projectRepository = projectRepository;
-		this.integrationRepository = integrationRepository;
-		this.testItemRepository = testItemRepository;
-		this.logRepository = logRepository;
+    this.projectRepository = projectRepository;
+    this.integrationRepository = integrationRepository;
+    this.testItemRepository = testItemRepository;
+    this.logRepository = logRepository;
 
-		repositories = ImmutableMap.<String, FilterableRepository>builder()
-				.put(Project.class.getSimpleName(), projectRepository)
-				.put(Integration.class.getSimpleName(), integrationRepository)
-				.put(TestItem.class.getSimpleName(), testItemRepository)
-				.put(Log.class.getSimpleName(), logRepository)
-				.build();
-	}
+    repositories = ImmutableMap.<String, FilterableRepository>builder()
+        .put(Project.class.getSimpleName(), projectRepository)
+        .put(Integration.class.getSimpleName(), integrationRepository)
+        .put(TestItem.class.getSimpleName(), testItemRepository)
+        .put(Log.class.getSimpleName(), logRepository)
+        .build();
+  }
 
-	@Override
-	public Object find(QueryRQ queryRQ) {
+  @Override
+  public Object find(QueryRQ queryRQ) {
 
-		return Optional.ofNullable(repositories.get(queryRQ.getEntity()))
-				.map(repository -> repository.findByFilter(queryRQ.getFilter()))
-				.orElseThrow(() -> new ReportPortalException("Repository not found"));
-	}
+    return Optional.ofNullable(repositories.get(queryRQ.getEntity()))
+        .map(repository -> repository.findByFilter(queryRQ.getFilter()))
+        .orElseThrow(() -> new ReportPortalException("Repository not found"));
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/rabbit/AsyncReportingListener.java b/src/main/java/com/epam/ta/reportportal/ws/rabbit/AsyncReportingListener.java
index 574610eeef..54e9a9bfe3 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/rabbit/AsyncReportingListener.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/rabbit/AsyncReportingListener.java
@@ -16,6 +16,12 @@
 
 package com.epam.ta.reportportal.ws.rabbit;
 
+import static com.epam.ta.reportportal.commons.EntityUtils.normalizeId;
+import static com.epam.ta.reportportal.core.configs.rabbit.ReportingConfiguration.DEAD_LETTER_MAX_RETRY;
+import static com.epam.ta.reportportal.core.configs.rabbit.ReportingConfiguration.EXCHANGE_REPORTING_RETRY;
+import static com.epam.ta.reportportal.core.configs.rabbit.ReportingConfiguration.QUEUE_DLQ;
+import static com.epam.ta.reportportal.ws.converter.converters.LogConverter.LOG_FULL_TO_LOG;
+
 import com.epam.ta.reportportal.auth.basic.DatabaseUserDetailsService;
 import com.epam.ta.reportportal.binary.AttachmentBinaryDataService;
 import com.epam.ta.reportportal.commons.BinaryDataMetaInfo;
@@ -35,9 +41,10 @@
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.entity.log.Log;
+import com.epam.ta.reportportal.entity.log.LogFull;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.util.ProjectExtractor;
-import com.epam.ta.reportportal.ws.converter.builders.LogBuilder;
+import com.epam.ta.reportportal.ws.converter.builders.LogFullBuilder;
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.epam.ta.reportportal.ws.model.FinishExecutionRQ;
 import com.epam.ta.reportportal.ws.model.FinishTestItemRQ;
@@ -45,6 +52,12 @@
 import com.epam.ta.reportportal.ws.model.launch.StartLaunchRQ;
 import com.epam.ta.reportportal.ws.model.log.SaveLogRQ;
 import com.google.common.base.Strings;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -58,288 +71,294 @@
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.core.ParameterizedTypeReference;
 
-import java.time.LocalDateTime;
-import java.time.ZoneOffset;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-
-import static com.epam.ta.reportportal.commons.EntityUtils.normalizeId;
-import static com.epam.ta.reportportal.core.configs.rabbit.ReportingConfiguration.*;
-
 /**
  * @author Konstantin Antipin
  */
 public class AsyncReportingListener implements MessageListener {
-	private static final Logger LOGGER = LoggerFactory.getLogger(AsyncReportingListener.class);
-
-	@Autowired
-	private MessageConverter messageConverter;
-
-	@Autowired
-	@Qualifier("rabbitTemplate")
-	private AmqpTemplate amqpTemplate;
-
-	@Autowired
-	private StartLaunchHandler startLaunchHandler;
-
-	@Autowired
-	private FinishLaunchHandler finishLaunchHandler;
-
-	@Autowired
-	private StartTestItemHandler startTestItemHandler;
-
-	@Autowired
-	private FinishTestItemHandler finishTestItemHandler;
-
-	@Autowired
-	private DatabaseUserDetailsService userDetailsService;
-
-	@Autowired
-	private LogRepository logRepository;
-
-	@Autowired
-	private LaunchRepository launchRepository;
-
-	@Autowired
-	private TestItemRepository testItemRepository;
-
-	@Autowired
-	private TestItemService testItemService;
-
-	@Autowired
-	private AttachmentBinaryDataService attachmentBinaryDataService;
-
-	@Autowired
-	private ProjectExtractor projectExtractor;
-
-	@Autowired
-	private LogService logService;
-
-	@Override
-	@RabbitMessageLogging
-	public void onMessage(Message message) {
-
-		try {
-			if (breakRetrying(message)) {
-				return;
-			}
-
-			RequestType requestType = getRequestType(message);
-			Map<String, Object> headers = message.getMessageProperties().getHeaders();
-
-			switch (requestType) {
-				case START_LAUNCH:
-					onStartLaunch((StartLaunchRQ) messageConverter.fromMessage(message),
-							(String) headers.get(MessageHeaders.USERNAME),
-							(String) headers.get(MessageHeaders.PROJECT_NAME)
-					);
-					break;
-				case FINISH_LAUNCH:
-					onFinishLaunch((FinishExecutionRQ) messageConverter.fromMessage(message),
-							(String) headers.get(MessageHeaders.USERNAME),
-							(String) headers.get(MessageHeaders.PROJECT_NAME),
-							(String) headers.get(MessageHeaders.LAUNCH_ID),
-							(String) headers.get(MessageHeaders.BASE_URL)
-					);
-					break;
-				case START_TEST:
-					onStartItem((StartTestItemRQ) messageConverter.fromMessage(message),
-							(String) headers.get(MessageHeaders.USERNAME),
-							(String) headers.get(MessageHeaders.PROJECT_NAME),
-							(String) headers.get(MessageHeaders.PARENT_ITEM_ID)
-					);
-					break;
-				case FINISH_TEST:
-					onFinishItem((FinishTestItemRQ) messageConverter.fromMessage(message),
-							(String) headers.get(MessageHeaders.USERNAME),
-							(String) headers.get(MessageHeaders.PROJECT_NAME),
-							(String) headers.get(MessageHeaders.ITEM_ID)
-					);
-					break;
-				case LOG:
-					Jackson2JsonMessageConverter converter = (Jackson2JsonMessageConverter) messageConverter;
-					onLogCreate((DeserializablePair) converter.fromMessage(message,
-							new ParameterizedTypeReference<DeserializablePair<SaveLogRQ, BinaryDataMetaInfo>>() {
-							}
-					), (Long) headers.get(MessageHeaders.PROJECT_ID));
-					break;
-				default:
-					LOGGER.error("Unknown message type");
-					break;
-			}
-		} catch (Throwable e) {
-			if (e instanceof ReportPortalException && e.getMessage().startsWith("Test Item ")) {
-				LOGGER.debug("exception : {}, message : {},  cause : {}",
-						e.getClass().getName(),
-						e.getMessage(),
-						e.getCause() != null ? e.getCause().getMessage() : ""
-				);
-			} else {
-				LOGGER.error("exception : {}, message : {},  cause : {}",
-						e.getClass().getName(),
-						e.getMessage(),
-						e.getCause() != null ? e.getCause().getMessage() : ""
-				);
-			}
-			throw new AmqpRejectAndDontRequeueException(e);
-		}
 
-	}
-
-	public void onStartLaunch(StartLaunchRQ rq, String username, String projectName) {
-		ReportPortalUser user = (ReportPortalUser) userDetailsService.loadUserByUsername(username);
-		startLaunchHandler.startLaunch(user, extractProjectDetails(user, projectName), rq);
-	}
-
-	public void onFinishLaunch(FinishExecutionRQ rq, String username, String projectName, String launchId, String baseUrl) {
-		ReportPortalUser user = (ReportPortalUser) userDetailsService.loadUserByUsername(username);
-		finishLaunchHandler.finishLaunch(launchId, rq, extractProjectDetails(user, projectName), user, baseUrl);
-	}
+  private static final Logger LOGGER = LoggerFactory.getLogger(AsyncReportingListener.class);
+
+  @Autowired
+  private MessageConverter messageConverter;
+
+  @Autowired
+  @Qualifier("rabbitTemplate")
+  private AmqpTemplate amqpTemplate;
+
+  @Autowired
+  private StartLaunchHandler startLaunchHandler;
+
+  @Autowired
+  private FinishLaunchHandler finishLaunchHandler;
+
+  @Autowired
+  private StartTestItemHandler startTestItemHandler;
+
+  @Autowired
+  private FinishTestItemHandler finishTestItemHandler;
+
+  @Autowired
+  private DatabaseUserDetailsService userDetailsService;
+
+  @Autowired
+  private LogRepository logRepository;
+
+  @Autowired
+  private LaunchRepository launchRepository;
+
+  @Autowired
+  private TestItemRepository testItemRepository;
+
+  @Autowired
+  private TestItemService testItemService;
+
+  @Autowired
+  private AttachmentBinaryDataService attachmentBinaryDataService;
+
+  @Autowired
+  private ProjectExtractor projectExtractor;
+
+  @Autowired
+  private LogService logService;
+
+  @Override
+  @RabbitMessageLogging
+  public void onMessage(Message message) {
+
+    try {
+      if (breakRetrying(message)) {
+        return;
+      }
+
+      RequestType requestType = getRequestType(message);
+      Map<String, Object> headers = message.getMessageProperties().getHeaders();
+
+      switch (requestType) {
+        case START_LAUNCH:
+          onStartLaunch((StartLaunchRQ) messageConverter.fromMessage(message),
+              (String) headers.get(MessageHeaders.USERNAME),
+              (String) headers.get(MessageHeaders.PROJECT_NAME)
+          );
+          break;
+        case FINISH_LAUNCH:
+          onFinishLaunch((FinishExecutionRQ) messageConverter.fromMessage(message),
+              (String) headers.get(MessageHeaders.USERNAME),
+              (String) headers.get(MessageHeaders.PROJECT_NAME),
+              (String) headers.get(MessageHeaders.LAUNCH_ID),
+              (String) headers.get(MessageHeaders.BASE_URL)
+          );
+          break;
+        case START_TEST:
+          onStartItem((StartTestItemRQ) messageConverter.fromMessage(message),
+              (String) headers.get(MessageHeaders.USERNAME),
+              (String) headers.get(MessageHeaders.PROJECT_NAME),
+              (String) headers.get(MessageHeaders.PARENT_ITEM_ID)
+          );
+          break;
+        case FINISH_TEST:
+          onFinishItem((FinishTestItemRQ) messageConverter.fromMessage(message),
+              (String) headers.get(MessageHeaders.USERNAME),
+              (String) headers.get(MessageHeaders.PROJECT_NAME),
+              (String) headers.get(MessageHeaders.ITEM_ID)
+          );
+          break;
+        case LOG:
+          Jackson2JsonMessageConverter converter = (Jackson2JsonMessageConverter) messageConverter;
+          onLogCreate((DeserializablePair) converter.fromMessage(message,
+              new ParameterizedTypeReference<DeserializablePair<SaveLogRQ, BinaryDataMetaInfo>>() {
+              }
+          ), (Long) headers.get(MessageHeaders.PROJECT_ID));
+          break;
+        default:
+          LOGGER.error("Unknown message type");
+          break;
+      }
+    } catch (Throwable e) {
+      if (e instanceof ReportPortalException && e.getMessage().startsWith("Test Item ")) {
+        LOGGER.debug("exception : {}, message : {},  cause : {}",
+            e.getClass().getName(),
+            e.getMessage(),
+            e.getCause() != null ? e.getCause().getMessage() : ""
+        );
+      } else {
+        LOGGER.error("exception : {}, message : {},  cause : {}",
+            e.getClass().getName(),
+            e.getMessage(),
+            e.getCause() != null ? e.getCause().getMessage() : ""
+        );
+      }
+      throw new AmqpRejectAndDontRequeueException(e);
+    }
 
-	public void onStartItem(StartTestItemRQ rq, String username, String projectName, String parentId) {
-		ReportPortalUser user = (ReportPortalUser) userDetailsService.loadUserByUsername(username);
-		ReportPortalUser.ProjectDetails projectDetails = extractProjectDetails(user, normalizeId(projectName));
-		if (!Strings.isNullOrEmpty(parentId)) {
-			startTestItemHandler.startChildItem(user, projectDetails, rq, parentId);
-		} else {
-			startTestItemHandler.startRootItem(user, projectDetails, rq);
-		}
-	}
+  }
+
+  public void onStartLaunch(StartLaunchRQ rq, String username, String projectName) {
+    ReportPortalUser user = (ReportPortalUser) userDetailsService.loadUserByUsername(username);
+    startLaunchHandler.startLaunch(user, extractProjectDetails(user, projectName), rq);
+  }
+
+  public void onFinishLaunch(FinishExecutionRQ rq, String username, String projectName,
+      String launchId, String baseUrl) {
+    ReportPortalUser user = (ReportPortalUser) userDetailsService.loadUserByUsername(username);
+    finishLaunchHandler.finishLaunch(launchId, rq, extractProjectDetails(user, projectName), user,
+        baseUrl);
+  }
+
+  public void onStartItem(StartTestItemRQ rq, String username, String projectName,
+      String parentId) {
+    ReportPortalUser user = (ReportPortalUser) userDetailsService.loadUserByUsername(username);
+    ReportPortalUser.ProjectDetails projectDetails = extractProjectDetails(user,
+        normalizeId(projectName));
+    if (!Strings.isNullOrEmpty(parentId)) {
+      startTestItemHandler.startChildItem(user, projectDetails, rq, parentId);
+    } else {
+      startTestItemHandler.startRootItem(user, projectDetails, rq);
+    }
+  }
 
-	public void onFinishItem(FinishTestItemRQ rq, String username, String projectName, String itemId) {
-		ReportPortalUser user = (ReportPortalUser) userDetailsService.loadUserByUsername(username);
-		finishTestItemHandler.finishTestItem(user, extractProjectDetails(user, normalizeId(projectName)), itemId, rq);
-	}
+  public void onFinishItem(FinishTestItemRQ rq, String username, String projectName,
+      String itemId) {
+    ReportPortalUser user = (ReportPortalUser) userDetailsService.loadUserByUsername(username);
+    finishTestItemHandler.finishTestItem(user,
+        extractProjectDetails(user, normalizeId(projectName)), itemId, rq);
+  }
 
 	private ReportPortalUser.ProjectDetails extractProjectDetails(ReportPortalUser user, String projectName) {
     return projectExtractor.extractProjectDetails(user, projectName);
 	}
 
-	public void onLogCreate(DeserializablePair<SaveLogRQ, BinaryDataMetaInfo> payload, Long projectId) {
-		SaveLogRQ request = payload.getLeft();
-		BinaryDataMetaInfo metaInfo = payload.getRight();
+  public void onLogCreate(DeserializablePair<SaveLogRQ, BinaryDataMetaInfo> payload,
+      Long projectId) {
+    SaveLogRQ request = payload.getLeft();
+    BinaryDataMetaInfo metaInfo = payload.getRight();
 
-		Optional<TestItem> itemOptional = testItemRepository.findByUuid(request.getItemUuid());
-
-		if (StringUtils.isNotEmpty(payload.getLeft().getItemUuid()) && !itemOptional.isPresent()) {
-			throw new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND, payload.getLeft().getItemUuid());
-		}
-
-		if (itemOptional.isPresent()) {
-			createItemLog(request, itemOptional.get(), metaInfo, projectId);
-		} else {
-			Launch launch = launchRepository.findByUuid(request.getLaunchUuid())
-					.orElseThrow(() -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND, request.getLaunchUuid()));
-			createLaunchLog(request, launch, metaInfo, projectId);
-		}
-	}
+    Optional<TestItem> itemOptional = testItemRepository.findByUuid(request.getItemUuid());
 
-	/**
-	 * Process xdHeader of the message, breaking processing if maximum retry limit reached
-	 *
-	 * @param message
-	 * @return -
-	 */
-	private boolean breakRetrying(Message message) {
-		List<Map<String, ?>> xdHeader = (List<Map<String, ?>>) message.getMessageProperties().getHeaders().get(MessageHeaders.XD_HEADER);
-
-		if (xdHeader != null) {
-			long count = (Long) xdHeader.get(0).get("count");
-			if (count > DEAD_LETTER_MAX_RETRY) {
-				LOGGER.error("Dropping on maximum retry limit request of type = {}, for target id = {} ",
-						getRequestType(message),
-						getTargetId(message)
-				);
-
-				// log request : don't cleanup to not loose binary content of dropped DLQ message
-				// cleanup(payload);
-
-				amqpTemplate.send(EXCHANGE_REPORTING_RETRY, QUEUE_DLQ, message);
-				return true;
-			}
-		}
-		return false;
-	}
-
-	private String getTargetId(Message message) {
-		try {
-			switch (getRequestType(message)) {
-				case START_LAUNCH:
-					return ((StartLaunchRQ) messageConverter.fromMessage(message)).getUuid();
-				case FINISH_LAUNCH:
-					return (String) message.getMessageProperties().getHeaders().get(MessageHeaders.LAUNCH_ID);
-				case START_TEST:
-					return ((StartTestItemRQ) messageConverter.fromMessage(message)).getUuid();
-				case FINISH_TEST:
-					return (String) message.getMessageProperties().getHeaders().get(MessageHeaders.ITEM_ID);
-				case LOG:
-					Jackson2JsonMessageConverter converter = (Jackson2JsonMessageConverter) messageConverter;
-					return ((SaveLogRQ) ((DeserializablePair) converter.fromMessage(message,
-							new ParameterizedTypeReference<DeserializablePair<SaveLogRQ, BinaryDataMetaInfo>>() {
-							}
-					)).getLeft()).getUuid();
-				default:
-					return "";
-			}
-		} catch (Throwable e) {
-			return "";
-		}
-	}
-
-	private void createItemLog(SaveLogRQ request, TestItem item, BinaryDataMetaInfo metaInfo,
-			Long projectId) {
-		Log log = new LogBuilder().addSaveLogRq(request).addTestItem(item).addProjectId(projectId)
-				.get();
-		logRepository.save(log);
-		Launch effectiveLaunch = testItemService.getEffectiveLaunch(item);
-		logService.saveLogMessageToElasticSearch(log, effectiveLaunch.getId());
-
-    if (Objects.nonNull(request.getFile())) {
-      saveAttachment(request.getFile().getName(), metaInfo,
-          log.getId(),
-          projectId,
-          effectiveLaunch.getId(),
-          item.getItemId(),
-          effectiveLaunch.getUuid(),
-          log.getUuid()
-      );
+    if (StringUtils.isNotEmpty(payload.getLeft().getItemUuid()) && !itemOptional.isPresent()) {
+      throw new ReportPortalException(ErrorType.TEST_ITEM_NOT_FOUND,
+          payload.getLeft().getItemUuid());
     }
-	}
-
-	private void createLaunchLog(SaveLogRQ request, Launch launch, BinaryDataMetaInfo metaInfo,
-			Long projectId) {
-		Log log = new LogBuilder().addSaveLogRq(request).addLaunch(launch).addProjectId(projectId)
-				.get();
-		logRepository.save(log);
-		logService.saveLogMessageToElasticSearch(log, launch.getId());
-
-		saveAttachment(request.getFile().getName(), metaInfo, log.getId(), projectId, launch.getId(),
-				null, launch.getUuid(), log.getUuid());
-	}
 
-	private void saveAttachment(String fileName, BinaryDataMetaInfo metaInfo, Long logId,
-			Long projectId, Long launchId, Long itemId, String launchUuid,
-			String logUuid) {
-		if (!Objects.isNull(metaInfo)) {
-			attachmentBinaryDataService.attachToLog(metaInfo,
-					AttachmentMetaInfo.builder()
-							.withProjectId(projectId)
-							.withLaunchId(launchId)
-							.withItemId(itemId)
-							.withLogId(logId)
-							.withLaunchUuid(launchUuid)
-							.withLogUuid(logUuid)
+    if (itemOptional.isPresent()) {
+      createItemLog(request, itemOptional.get(), metaInfo, projectId);
+    } else {
+      Launch launch = launchRepository.findByUuid(request.getLaunchUuid())
+          .orElseThrow(
+              () -> new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND, request.getLaunchUuid()));
+      createLaunchLog(request, launch, metaInfo, projectId);
+    }
+  }
+
+  /**
+   * Process xdHeader of the message, breaking processing if maximum retry limit reached
+   *
+   * @param message
+   * @return -
+   */
+  private boolean breakRetrying(Message message) {
+    List<Map<String, ?>> xdHeader = (List<Map<String, ?>>) message.getMessageProperties()
+        .getHeaders().get(MessageHeaders.XD_HEADER);
+
+    if (xdHeader != null) {
+      long count = (Long) xdHeader.get(0).get("count");
+      if (count > DEAD_LETTER_MAX_RETRY) {
+        LOGGER.error("Dropping on maximum retry limit request of type = {}, for target id = {} ",
+            getRequestType(message),
+            getTargetId(message)
+        );
+
+        // log request : don't cleanup to not loose binary content of dropped DLQ message
+        // cleanup(payload);
+
+        amqpTemplate.send(EXCHANGE_REPORTING_RETRY, QUEUE_DLQ, message);
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private String getTargetId(Message message) {
+    try {
+      switch (getRequestType(message)) {
+        case START_LAUNCH:
+          return ((StartLaunchRQ) messageConverter.fromMessage(message)).getUuid();
+        case FINISH_LAUNCH:
+          return (String) message.getMessageProperties().getHeaders().get(MessageHeaders.LAUNCH_ID);
+        case START_TEST:
+          return ((StartTestItemRQ) messageConverter.fromMessage(message)).getUuid();
+        case FINISH_TEST:
+          return (String) message.getMessageProperties().getHeaders().get(MessageHeaders.ITEM_ID);
+        case LOG:
+          Jackson2JsonMessageConverter converter = (Jackson2JsonMessageConverter) messageConverter;
+          return ((SaveLogRQ) ((DeserializablePair) converter.fromMessage(message,
+              new ParameterizedTypeReference<DeserializablePair<SaveLogRQ, BinaryDataMetaInfo>>() {
+              }
+          )).getLeft()).getUuid();
+        default:
+          return "";
+      }
+    } catch (Throwable e) {
+      return "";
+    }
+  }
+
+  private void createItemLog(SaveLogRQ request, TestItem item, BinaryDataMetaInfo metaInfo,
+      Long projectId) {
+    LogFull logFull = new LogFullBuilder().addSaveLogRq(request).addTestItem(item)
+        .addProjectId(projectId).get();
+    Log log = LOG_FULL_TO_LOG.apply(logFull);
+    logRepository.save(log);
+    logFull.setId(log.getId());
+    Launch effectiveLaunch = testItemService.getEffectiveLaunch(item);
+    logService.saveLogMessage(logFull, effectiveLaunch.getId());
+
+    if (Objects.nonNull(request.getFile())) {saveAttachment(request.getFile().getName(), metaInfo,
+        logFull.getId(),
+        projectId,
+        effectiveLaunch.getId(),
+        item.getItemId(),
+        effectiveLaunch.getUuid(),
+        logFull.getUuid()
+    );
+  }}
+
+  private void createLaunchLog(SaveLogRQ request, Launch launch, BinaryDataMetaInfo metaInfo,
+      Long projectId) {
+    LogFull logFull = new LogFullBuilder().addSaveLogRq(request).addLaunch(launch)
+        .addProjectId(projectId).get();
+    Log log = LOG_FULL_TO_LOG.apply(logFull);
+    logRepository.save(log);
+    logFull.setId(log.getId());
+    logService.saveLogMessage(logFull, launch.getId());
+
+    saveAttachment(request.getFile().getName(), metaInfo, logFull.getId(), projectId, launch.getId(),
+				null, launch.getUuid(),
+        logFull.getUuid());
+  }
+
+  private void saveAttachment(String fileName, BinaryDataMetaInfo metaInfo, Long logId,
+			Long projectId,
+      Long launchId, Long itemId, String launchUuid,
+      String logUuid) {
+    if (!Objects.isNull(metaInfo)) {
+      attachmentBinaryDataService.attachToLog(metaInfo,
+          AttachmentMetaInfo.builder()
+              .withProjectId(projectId)
+              .withLaunchId(launchId)
+              .withItemId(itemId)
+              .withLogId(logId)
+              .withLaunchUuid(launchUuid)
+              .withLogUuid(logUuid)
 							.withFileName(fileName)
-							.withCreationDate(LocalDateTime.now(ZoneOffset.UTC))
-							.build()
-			);
-		}
-	}
+              .withCreationDate(LocalDateTime.now(ZoneOffset.UTC))
+              .build()
+      );
+    }
+  }
 
-	private RequestType getRequestType(Message message) {
-		return RequestType.valueOf((String) message.getMessageProperties().getHeaders().get(MessageHeaders.REQUEST_TYPE));
-	}
+  private RequestType getRequestType(Message message) {
+    return RequestType.valueOf(
+        (String) message.getMessageProperties().getHeaders().get(MessageHeaders.REQUEST_TYPE));
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/rabbit/ConsumerEventListener.java b/src/main/java/com/epam/ta/reportportal/ws/rabbit/ConsumerEventListener.java
index bd39012010..f0c802b9fd 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/rabbit/ConsumerEventListener.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/rabbit/ConsumerEventListener.java
@@ -20,6 +20,9 @@
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.rabbitmq.client.Channel;
 import com.rabbitmq.client.ShutdownSignalException;
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.TimeoutException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.amqp.core.Queue;
@@ -32,53 +35,50 @@
 import org.springframework.context.annotation.Conditional;
 import org.springframework.stereotype.Component;
 
-import java.io.IOException;
-import java.util.List;
-import java.util.concurrent.TimeoutException;
-
 /**
- * Finds a queue that doesn't have any connected consumers and set's it
- * to consumer that should be restarted, so it can be registered
- * with a different queue.
+ * Finds a queue that doesn't have any connected consumers and set's it to consumer that should be
+ * restarted, so it can be registered with a different queue.
  *
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
  */
 @Component
 @Conditional(Conditions.NotTestCondition.class)
-public class ConsumerEventListener implements ApplicationListener<ListenerContainerConsumerFailedEvent> {
+public class ConsumerEventListener implements
+    ApplicationListener<ListenerContainerConsumerFailedEvent> {
 
-	private static final Logger LOGGER = LoggerFactory.getLogger(ConsumerEventListener.class);
+  private static final Logger LOGGER = LoggerFactory.getLogger(ConsumerEventListener.class);
 
-	@Autowired
-	@Qualifier("queues")
-	private List<Queue> queues;
+  @Autowired
+  @Qualifier("queues")
+  private List<Queue> queues;
 
-	@Autowired
-	private ConnectionFactory connectionFactory;
+  @Autowired
+  private ConnectionFactory connectionFactory;
 
-	@Override
-	public void onApplicationEvent(ListenerContainerConsumerFailedEvent event) {
-		Object source = event.getSource();
-		if (source instanceof AbstractMessageListenerContainer) {
-			AbstractMessageListenerContainer listenerContainer = (AbstractMessageListenerContainer) source;
-			Throwable throwable = event.getThrowable();
-			if (throwable.getCause() instanceof IOException && throwable.getCause().getCause() instanceof ShutdownSignalException
-					&& throwable.getCause().getCause().getMessage().contains("in exclusive use")) {
-				for (Queue q : queues) {
-					if (getQueueConsumerCount(q) == 0) {
-						listenerContainer.setQueues(q);
-						LOGGER.info("Restarting consumer with a queue {}", q.getName());
-					}
-				}
-			}
-		}
-	}
+  @Override
+  public void onApplicationEvent(ListenerContainerConsumerFailedEvent event) {
+    Object source = event.getSource();
+    if (source instanceof AbstractMessageListenerContainer) {
+      AbstractMessageListenerContainer listenerContainer = (AbstractMessageListenerContainer) source;
+      Throwable throwable = event.getThrowable();
+      if (throwable.getCause() instanceof IOException && throwable.getCause()
+          .getCause() instanceof ShutdownSignalException
+          && throwable.getCause().getCause().getMessage().contains("in exclusive use")) {
+        for (Queue q : queues) {
+          if (getQueueConsumerCount(q) == 0) {
+            listenerContainer.setQueues(q);
+            LOGGER.info("Restarting consumer with a queue {}", q.getName());
+          }
+        }
+      }
+    }
+  }
 
-	private int getQueueConsumerCount(Queue queue) {
-		try (Channel channel = connectionFactory.createConnection().createChannel(false)) {
-			return channel.queueDeclarePassive(queue.getName()).getConsumerCount();
-		} catch (IOException | TimeoutException e) {
-			throw new ReportPortalException(e.getMessage());
-		}
-	}
+  private int getQueueConsumerCount(Queue queue) {
+    try (Channel channel = connectionFactory.createConnection().createChannel(false)) {
+      return channel.queueDeclarePassive(queue.getName()).getConsumerCount();
+    } catch (IOException | TimeoutException e) {
+      throw new ReportPortalException(e.getMessage());
+    }
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/rabbit/MessageHeaders.java b/src/main/java/com/epam/ta/reportportal/ws/rabbit/MessageHeaders.java
index a78e1e82c4..452885116d 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/rabbit/MessageHeaders.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/rabbit/MessageHeaders.java
@@ -21,22 +21,22 @@
  */
 public final class MessageHeaders {
 
-	public static final String REQUEST_TYPE = "requestType";
-	public static final String USERNAME = "username";
-	public static final String PROJECT_NAME = "projectName";
-	public static final String PROJECT_ID = "projectId";
-	public static final String LAUNCH_ID = "launchId";
-	public static final String ITEM_ID = "itemId";
-	public static final String PARENT_ITEM_ID = "parentItemId";
-	public static final String XD_HEADER = "x-death";
-	public static final String BASE_URL = "baseUrl";
+  public static final String REQUEST_TYPE = "requestType";
+  public static final String USERNAME = "username";
+  public static final String PROJECT_NAME = "projectName";
+  public static final String PROJECT_ID = "projectId";
+  public static final String LAUNCH_ID = "launchId";
+  public static final String ITEM_ID = "itemId";
+  public static final String PARENT_ITEM_ID = "parentItemId";
+  public static final String XD_HEADER = "x-death";
+  public static final String BASE_URL = "baseUrl";
 
-	public static final String ITEM_REF = "itemRef";
-	public static final String LIMIT = "limit";
-	public static final String IS_LOAD_BINARY_DATA = "isLoadBinaryData";
+  public static final String ITEM_REF = "itemRef";
+  public static final String LIMIT = "limit";
+  public static final String IS_LOAD_BINARY_DATA = "isLoadBinaryData";
 
-	private MessageHeaders() {
-		//static only
-	}
+  private MessageHeaders() {
+    //static only
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/rabbit/QueryConsumer.java b/src/main/java/com/epam/ta/reportportal/ws/rabbit/QueryConsumer.java
index af72c95088..da45a89fe7 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/rabbit/QueryConsumer.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/rabbit/QueryConsumer.java
@@ -16,23 +16,23 @@
 
 package com.epam.ta.reportportal.ws.rabbit;
 
+import static com.epam.ta.reportportal.core.configs.rabbit.InternalConfiguration.QUEUE_QUERY_RQ;
+
 import com.epam.ta.reportportal.ws.handler.QueryHandler;
 import org.springframework.amqp.rabbit.annotation.RabbitListener;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.messaging.handler.annotation.Payload;
 import org.springframework.stereotype.Component;
 
-import static com.epam.ta.reportportal.core.configs.rabbit.InternalConfiguration.QUEUE_QUERY_RQ;
-
 @Component
 public class QueryConsumer {
 
-	@Autowired
-	private QueryHandler queryHandler;
+  @Autowired
+  private QueryHandler queryHandler;
 
-	@RabbitListener(queues = QUEUE_QUERY_RQ)
-	public Object find(@Payload QueryRQ queryRQ) {
+  @RabbitListener(queues = QUEUE_QUERY_RQ)
+  public Object find(@Payload QueryRQ queryRQ) {
 
-		return queryHandler.find(queryRQ);
-	}
+    return queryHandler.find(queryRQ);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/rabbit/QueryRQ.java b/src/main/java/com/epam/ta/reportportal/ws/rabbit/QueryRQ.java
index 611d9575a3..93ea5d025c 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/rabbit/QueryRQ.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/rabbit/QueryRQ.java
@@ -23,23 +23,23 @@
  */
 public class QueryRQ {
 
-	private String entity;
+  private String entity;
 
-	private Filter filter;
+  private Filter filter;
 
-	public String getEntity() {
-		return entity;
-	}
+  public String getEntity() {
+    return entity;
+  }
 
-	public void setEntity(String entity) {
-		this.entity = entity;
-	}
+  public void setEntity(String entity) {
+    this.entity = entity;
+  }
 
-	public Filter getFilter() {
-		return filter;
-	}
+  public Filter getFilter() {
+    return filter;
+  }
 
-	public void setFilter(Filter filter) {
-		this.filter = filter;
-	}
+  public void setFilter(Filter filter) {
+    this.filter = filter;
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/rabbit/ReportingStartupService.java b/src/main/java/com/epam/ta/reportportal/ws/rabbit/ReportingStartupService.java
index 6798120239..23b459231c 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/rabbit/ReportingStartupService.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/rabbit/ReportingStartupService.java
@@ -17,16 +17,14 @@
 package com.epam.ta.reportportal.ws.rabbit;
 
 import com.epam.ta.reportportal.core.configs.Conditions;
+import java.util.List;
+import javax.annotation.PostConstruct;
 import org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.context.annotation.Conditional;
 import org.springframework.stereotype.Component;
 
-import javax.annotation.PostConstruct;
-
-import java.util.List;
-
 /**
  * @author Konstantin Antipin
  */
@@ -34,15 +32,15 @@
 @Conditional(Conditions.NotTestCondition.class)
 public class ReportingStartupService {
 
-    @Autowired
-    @Qualifier("reportingListenerContainers")
-    private List<AbstractMessageListenerContainer> listenerContainers;
+  @Autowired
+  @Qualifier("reportingListenerContainers")
+  private List<AbstractMessageListenerContainer> listenerContainers;
 
-    @PostConstruct
-    public void init() {
-        for (AbstractMessageListenerContainer listenerContainer : listenerContainers) {
-            listenerContainer.start();
-        }
+  @PostConstruct
+  public void init() {
+    for (AbstractMessageListenerContainer listenerContainer : listenerContainers) {
+      listenerContainer.start();
     }
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/rabbit/RequestType.java b/src/main/java/com/epam/ta/reportportal/ws/rabbit/RequestType.java
index 82f80386bf..3749c7d0a5 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/rabbit/RequestType.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/rabbit/RequestType.java
@@ -20,5 +20,5 @@
  * @author Konstantin Antipin
  */
 public enum RequestType {
-    START_LAUNCH, FINISH_LAUNCH, START_TEST, FINISH_TEST, LOG
+  START_LAUNCH, FINISH_LAUNCH, START_TEST, FINISH_TEST, LOG
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/resolver/ActiveRole.java b/src/main/java/com/epam/ta/reportportal/ws/resolver/ActiveRole.java
index f4d1e5251a..9dca62e094 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/resolver/ActiveRole.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/resolver/ActiveRole.java
@@ -16,11 +16,15 @@
 
 package com.epam.ta.reportportal.ws.resolver;
 
-import java.lang.annotation.*;
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
 
 /**
- * Annotation should be used as parameter in controllers to show that UserRole
- * should be resolved by Spring's resolvers
+ * Annotation should be used as parameter in controllers to show that UserRole should be resolved by
+ * Spring's resolvers
  *
  * @author Andrei Varabyeu
  */
@@ -28,4 +32,5 @@
 @Retention(RetentionPolicy.RUNTIME)
 @Documented
 public @interface ActiveRole {
+
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/ws/resolver/ActiveUserWebArgumentResolver.java b/src/main/java/com/epam/ta/reportportal/ws/resolver/ActiveUserWebArgumentResolver.java
index 966bafc9e3..0770d76537 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/resolver/ActiveUserWebArgumentResolver.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/resolver/ActiveUserWebArgumentResolver.java
@@ -17,6 +17,7 @@
 package com.epam.ta.reportportal.ws.resolver;
 
 import com.epam.ta.reportportal.entity.user.UserRole;
+import java.util.Optional;
 import org.springframework.core.MethodParameter;
 import org.springframework.security.core.Authentication;
 import org.springframework.web.bind.support.WebArgumentResolver;
@@ -25,47 +26,47 @@
 import org.springframework.web.method.support.HandlerMethodArgumentResolver;
 import org.springframework.web.method.support.ModelAndViewContainer;
 
-import java.util.Optional;
-
 /**
- * {@link org.springframework.web.bind.support.WebArgumentResolver} for
- * ReportPortal User Roles. Will resolve {@link UserRole} in case if method
- * parameter annotated by {@link ActiveRole} annotation
+ * {@link org.springframework.web.bind.support.WebArgumentResolver} for ReportPortal User Roles.
+ * Will resolve {@link UserRole} in case if method parameter annotated by {@link ActiveRole}
+ * annotation
  *
  * @author Andrei Varabyeu
  */
 public class ActiveUserWebArgumentResolver implements HandlerMethodArgumentResolver {
 
-	/**
-	 * Returns TRUE if method argument is {@link UserRole} and annotated by
-	 * {@link ActiveRole} annotation
-	 */
-	@Override
-	public boolean supportsParameter(MethodParameter methodParameter) {
-		return methodParameter.getParameterType().equals(UserRole.class) && null != methodParameter.getParameterAnnotation(
-				ActiveRole.class);
-	}
+  /**
+   * Returns TRUE if method argument is {@link UserRole} and annotated by {@link ActiveRole}
+   * annotation
+   */
+  @Override
+  public boolean supportsParameter(MethodParameter methodParameter) {
+    return methodParameter.getParameterType().equals(UserRole.class)
+        && null != methodParameter.getParameterAnnotation(
+        ActiveRole.class);
+  }
 
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see
-	 * org.springframework.web.method.support.HandlerMethodArgumentResolver#
-	 * resolveArgument(org.springframework.core.MethodParameter,
-	 * org.springframework.web.method.support.ModelAndViewContainer,
-	 * org.springframework.web.context.request.NativeWebRequest,
-	 * org.springframework.web.bind.support.WebDataBinderFactory)
-	 */
-	@Override
-	public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer paramModelAndViewContainer,
-			NativeWebRequest webRequest, WebDataBinderFactory paramWebDataBinderFactory) {
-		Authentication authentication = (Authentication) webRequest.getUserPrincipal();
-		if (!authentication.getAuthorities().isEmpty()) {
-			Optional<UserRole> userRole = UserRole.findByAuthority(
-					authentication.getAuthorities().iterator().next().getAuthority());
-			return userRole.isPresent() ? userRole.get() : WebArgumentResolver.UNRESOLVED;
-		}
-		return WebArgumentResolver.UNRESOLVED;
-	}
+  /*
+   * (non-Javadoc)
+   *
+   * @see
+   * org.springframework.web.method.support.HandlerMethodArgumentResolver#
+   * resolveArgument(org.springframework.core.MethodParameter,
+   * org.springframework.web.method.support.ModelAndViewContainer,
+   * org.springframework.web.context.request.NativeWebRequest,
+   * org.springframework.web.bind.support.WebDataBinderFactory)
+   */
+  @Override
+  public Object resolveArgument(MethodParameter methodParameter,
+      ModelAndViewContainer paramModelAndViewContainer,
+      NativeWebRequest webRequest, WebDataBinderFactory paramWebDataBinderFactory) {
+    Authentication authentication = (Authentication) webRequest.getUserPrincipal();
+    if (!authentication.getAuthorities().isEmpty()) {
+      Optional<UserRole> userRole = UserRole.findByAuthority(
+          authentication.getAuthorities().iterator().next().getAuthority());
+      return userRole.isPresent() ? userRole.get() : WebArgumentResolver.UNRESOLVED;
+    }
+    return WebArgumentResolver.UNRESOLVED;
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/resolver/FilterCriteriaResolver.java b/src/main/java/com/epam/ta/reportportal/ws/resolver/FilterCriteriaResolver.java
index 6391654ef6..ae8a5a5107 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/resolver/FilterCriteriaResolver.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/resolver/FilterCriteriaResolver.java
@@ -25,6 +25,8 @@
 import com.epam.ta.reportportal.commons.validation.Suppliers;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.List;
+import java.util.stream.Collectors;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.core.MethodParameter;
 import org.springframework.web.bind.support.WebDataBinderFactory;
@@ -32,90 +34,87 @@
 import org.springframework.web.method.support.HandlerMethodArgumentResolver;
 import org.springframework.web.method.support.ModelAndViewContainer;
 
-import java.util.List;
-import java.util.stream.Collectors;
-
 /**
  * Resolves filter parameters in GET requests. All Parameters should start with
  * <b>'filter.'</b> prefix. For example, if you would like to filter some
- * parameter with name 'age' you have to put in request the following:
- * '?filter.age=20'. Resolves parameter only in case argument marked with
- * annotation {@link FilterFor}. <br>
- * By FilterFor value resolves criterias/parameters to the given domain class
- * and resolves them if possible. If there are no criteria/parameter defined for
- * specified class than will throw exception
+ * parameter with name 'age' you have to put in request the following: '?filter.age=20'. Resolves
+ * parameter only in case argument marked with annotation {@link FilterFor}. <br> By FilterFor value
+ * resolves criterias/parameters to the given domain class and resolves them if possible. If there
+ * are no criteria/parameter defined for specified class than will throw exception
  *
  * @author Andrei Varabyeu
  */
 public class FilterCriteriaResolver implements HandlerMethodArgumentResolver {
 
-	/**
-	 * Default prefix for filter conditions. Since Request contains a lot of
-	 * parameters (some of them may not be related to filtering), we have to
-	 * introduce this
-	 */
-	public static final String DEFAULT_FILTER_PREFIX = "filter.";
+  /**
+   * Default prefix for filter conditions. Since Request contains a lot of parameters (some of them
+   * may not be related to filtering), we have to introduce this
+   */
+  public static final String DEFAULT_FILTER_PREFIX = "filter.";
 
-	/**
-	 * Prefix before condition type. 'NOT' filter condition may be marked with
-	 * this prefix
-	 */
-	public static final String NOT_FILTER_MARKER = "!";
+  /**
+   * Prefix before condition type. 'NOT' filter condition may be marked with this prefix
+   */
+  public static final String NOT_FILTER_MARKER = "!";
 
-	/**
-	 * Returns TRUE only for {@link java.util.List} marked with {@link FilterFor}
-	 * annotations
-	 */
-	@Override
-	public boolean supportsParameter(MethodParameter methodParameter) {
-		return methodParameter.getParameterType().equals(Filter.class) && null != methodParameter.getParameterAnnotation(FilterFor.class);
-	}
+  /**
+   * Returns TRUE only for {@link java.util.List} marked with {@link FilterFor} annotations
+   */
+  @Override
+  public boolean supportsParameter(MethodParameter methodParameter) {
+    return methodParameter.getParameterType().equals(Filter.class)
+        && null != methodParameter.getParameterAnnotation(FilterFor.class);
+  }
 
-	@Override
-	public Filter resolveArgument(MethodParameter methodParameter, ModelAndViewContainer paramModelAndViewContainer,
-			NativeWebRequest webRequest, WebDataBinderFactory paramWebDataBinderFactory) {
-		return resolveAsList(methodParameter, webRequest);
-	}
+  @Override
+  public Filter resolveArgument(MethodParameter methodParameter,
+      ModelAndViewContainer paramModelAndViewContainer,
+      NativeWebRequest webRequest, WebDataBinderFactory paramWebDataBinderFactory) {
+    return resolveAsList(methodParameter, webRequest);
+  }
 
-	@SuppressWarnings("unchecked")
-	private <T> Filter resolveAsList(MethodParameter methodParameter, NativeWebRequest webRequest) {
-		Class<T> domainModelType = (Class<T>) methodParameter.getParameterAnnotation(FilterFor.class).value();
+  @SuppressWarnings("unchecked")
+  private <T> Filter resolveAsList(MethodParameter methodParameter, NativeWebRequest webRequest) {
+    Class<T> domainModelType = (Class<T>) methodParameter.getParameterAnnotation(FilterFor.class)
+        .value();
 
-		List<ConvertibleCondition> filterConditions = webRequest.getParameterMap()
-				.entrySet()
-				.stream()
-				.filter(parameter -> parameter.getKey().startsWith(DEFAULT_FILTER_PREFIX) && parameter.getValue().length > 0)
-				.map(parameter -> {
-					final String[] tokens = parameter.getKey().split("\\.");
-					checkTokens(tokens);
-					String stringCondition = tokens[1];
-					boolean isNegative = stringCondition.startsWith(NOT_FILTER_MARKER);
+    List<ConvertibleCondition> filterConditions = webRequest.getParameterMap()
+        .entrySet()
+        .stream()
+        .filter(parameter -> parameter.getKey().startsWith(DEFAULT_FILTER_PREFIX)
+            && parameter.getValue().length > 0)
+        .map(parameter -> {
+          final String[] tokens = parameter.getKey().split("\\.");
+          checkTokens(tokens);
+          String stringCondition = tokens[1];
+          boolean isNegative = stringCondition.startsWith(NOT_FILTER_MARKER);
 
-					Condition condition = getCondition(isNegative ?
-							StringUtils.substringAfter(stringCondition, NOT_FILTER_MARKER) :
-							stringCondition);
-					String criteria = tokens[2];
-					BusinessRule.expect(parameter.getValue()[0], StringUtils::isNotBlank)
-							.verify(ErrorType.BAD_REQUEST_ERROR,
-									Suppliers.formattedSupplier("Filter criteria - '{}' value should be not empty", parameter.getKey())
-											.get()
-							);
-					return new FilterCondition(condition, isNegative, parameter.getValue()[0], criteria);
+          Condition condition = getCondition(isNegative ?
+              StringUtils.substringAfter(stringCondition, NOT_FILTER_MARKER) :
+              stringCondition);
+          String criteria = tokens[2];
+          BusinessRule.expect(parameter.getValue()[0], StringUtils::isNotBlank)
+              .verify(ErrorType.BAD_REQUEST_ERROR,
+                  Suppliers.formattedSupplier("Filter criteria - '{}' value should be not empty",
+                          parameter.getKey())
+                      .get()
+              );
+          return new FilterCondition(condition, isNegative, parameter.getValue()[0], criteria);
 
-				})
-				.collect(Collectors.toList());
-		return new Filter(domainModelType, filterConditions);
-	}
+        })
+        .collect(Collectors.toList());
+    return new Filter(domainModelType, filterConditions);
+  }
 
-	private void checkTokens(String[] tokens) {
-		BusinessRule.expect(tokens.length, Predicates.equalTo(3))
-				.verify(ErrorType.INCORRECT_FILTER_PARAMETERS, "Incorrect format of filtering parameters");
-	}
+  private void checkTokens(String[] tokens) {
+    BusinessRule.expect(tokens.length, Predicates.equalTo(3))
+        .verify(ErrorType.INCORRECT_FILTER_PARAMETERS, "Incorrect format of filtering parameters");
+  }
 
-	private Condition getCondition(String marker) {
-		return Condition.findByMarker(marker)
-				.orElseThrow(() -> new ReportPortalException(ErrorType.INCORRECT_FILTER_PARAMETERS,
-						"Unable to find condition with marker '" + marker + "'"
-				));
-	}
+  private Condition getCondition(String marker) {
+    return Condition.findByMarker(marker)
+        .orElseThrow(() -> new ReportPortalException(ErrorType.INCORRECT_FILTER_PARAMETERS,
+            "Unable to find condition with marker '" + marker + "'"
+        ));
+  }
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/ws/resolver/FilterFor.java b/src/main/java/com/epam/ta/reportportal/ws/resolver/FilterFor.java
index 31aa7bf2ad..2954b3c891 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/resolver/FilterFor.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/resolver/FilterFor.java
@@ -16,11 +16,15 @@
 
 package com.epam.ta.reportportal.ws.resolver;
 
-import java.lang.annotation.*;
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
 
 /**
- * Annotation to show that method parameter should be resolved as map of
- * parameters for specified class. Should be used in controllers
+ * Annotation to show that method parameter should be resolved as map of parameters for specified
+ * class. Should be used in controllers
  *
  * @author Andrei Varabyeu
  */
@@ -29,10 +33,10 @@
 @Documented
 public @interface FilterFor {
 
-	/**
-	 * Domain Object class queries and parameters will be applied to
-	 *
-	 * @return
-	 */
-	Class<?> value();
+  /**
+   * Domain Object class queries and parameters will be applied to
+   *
+   * @return class of filter
+   */
+  Class<?> value();
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/ws/resolver/JacksonViewAware.java b/src/main/java/com/epam/ta/reportportal/ws/resolver/JacksonViewAware.java
index b8086181ef..550dcf1255 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/resolver/JacksonViewAware.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/resolver/JacksonViewAware.java
@@ -23,27 +23,27 @@
  */
 public class JacksonViewAware {
 
-	/*
-	 * Java bean to be wrapped
-	 */
-	private final Object pojo;
-
-	/*
-	 * Jackson's JSON View
-	 */
-	private final Class<?> view;
-
-	public JacksonViewAware(Object pojo, Class<?> view) {
-		this.pojo = pojo;
-		this.view = view;
-	}
-
-	public Object getPojo() {
-		return pojo;
-	}
-
-	public Class<?> getView() {
-		return view;
-	}
+  /*
+   * Java bean to be wrapped
+   */
+  private final Object pojo;
+
+  /*
+   * Jackson's JSON View
+   */
+  private final Class<?> view;
+
+  public JacksonViewAware(Object pojo, Class<?> view) {
+    this.pojo = pojo;
+    this.view = view;
+  }
+
+  public Object getPojo() {
+    return pojo;
+  }
+
+  public Class<?> getView() {
+    return view;
+  }
 
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/ws/resolver/JacksonViewAwareModule.java b/src/main/java/com/epam/ta/reportportal/ws/resolver/JacksonViewAwareModule.java
index 048f877cf7..0c1eac419b 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/resolver/JacksonViewAwareModule.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/resolver/JacksonViewAwareModule.java
@@ -21,7 +21,6 @@
 import com.fasterxml.jackson.databind.SerializerProvider;
 import com.fasterxml.jackson.databind.module.SimpleModule;
 import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer;
-
 import java.io.IOException;
 
 /**
@@ -31,39 +30,38 @@
  */
 public class JacksonViewAwareModule extends SimpleModule {
 
-	private static final long serialVersionUID = 1L;
+  private static final long serialVersionUID = 1L;
 
-	/**
-	 * @param objectMapper - We need to provide ObjectMapper here since it's impossible
-	 *                     to serialize using JSON Views without mapper. It's little bit
-	 *                     unusual from Jackson point of view, but this is only one way
-	 *                     to avoid 'instaceOf' and classcast on http message converters
-	 *                     level
-	 * @see <a
-	 * href="http://wiki.fasterxml.com/JacksonHowToCustomSerializers">Jackson
-	 * - HowTo - CustomSerializers</a>
-	 */
-	public JacksonViewAwareModule(ObjectMapper objectMapper) {
-		addSerializer(JacksonViewAware.class, new JacksonViewAwareSerializer(objectMapper));
-	}
+  /**
+   * @param objectMapper - We need to provide ObjectMapper here since it's impossible to serialize
+   *                     using JSON Views without mapper. It's little bit unusual from Jackson point
+   *                     of view, but this is only one way to avoid 'instaceOf' and classcast on
+   *                     http message converters level
+   * @see <a href="http://wiki.fasterxml.com/JacksonHowToCustomSerializers">Jackson - HowTo -
+   * CustomSerializers</a>
+   */
+  public JacksonViewAwareModule(ObjectMapper objectMapper) {
+    addSerializer(JacksonViewAware.class, new JacksonViewAwareSerializer(objectMapper));
+  }
 
-	public static class JacksonViewAwareSerializer extends StdScalarSerializer<JacksonViewAware> {
+  public static class JacksonViewAwareSerializer extends StdScalarSerializer<JacksonViewAware> {
 
-		private ObjectMapper objectMapper;
+    private ObjectMapper objectMapper;
 
-		protected JacksonViewAwareSerializer(ObjectMapper objectMapper) {
-			super(JacksonViewAware.class);
-			this.objectMapper = objectMapper;
-		}
+    protected JacksonViewAwareSerializer(ObjectMapper objectMapper) {
+      super(JacksonViewAware.class);
+      this.objectMapper = objectMapper;
+    }
 
-		@Override
-		public void serialize(JacksonViewAware value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
-			/*
-			 * Writes bean with specified view
-			 */
-			objectMapper.writerWithView(value.getView()).writeValue(jgen, value.getPojo());
-		}
+    @Override
+    public void serialize(JacksonViewAware value, JsonGenerator jgen, SerializerProvider provider)
+        throws IOException {
+      /*
+       * Writes bean with specified view
+       */
+      objectMapper.writerWithView(value.getView()).writeValue(jgen, value.getPojo());
+    }
 
-	}
+  }
 
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/ws/resolver/JacksonViewReturnValueHandler.java b/src/main/java/com/epam/ta/reportportal/ws/resolver/JacksonViewReturnValueHandler.java
index da45ba2686..b7c269faa3 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/resolver/JacksonViewReturnValueHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/resolver/JacksonViewReturnValueHandler.java
@@ -22,62 +22,62 @@
 import org.springframework.web.method.support.ModelAndViewContainer;
 
 /**
- * Wraps {@link HandlerMethodReturnValueHandler}. Checks if {@link ResponseView}
- * annotation present, and if yes wraps bean to be serialized with view mapped
- * to it on controller's level class
+ * Wraps {@link HandlerMethodReturnValueHandler}. Checks if {@link ResponseView} annotation present,
+ * and if yes wraps bean to be serialized with view mapped to it on controller's level class
  *
  * @author Andrei Varabyeu
  */
 class JacksonViewReturnValueHandler implements HandlerMethodReturnValueHandler {
 
-	private final HandlerMethodReturnValueHandler delegate;
+  private final HandlerMethodReturnValueHandler delegate;
 
-	public JacksonViewReturnValueHandler(HandlerMethodReturnValueHandler delegate) {
-		this.delegate = delegate;
-	}
+  public JacksonViewReturnValueHandler(HandlerMethodReturnValueHandler delegate) {
+    this.delegate = delegate;
+  }
 
-	@Override
-	public boolean supportsReturnType(MethodParameter returnType) {
-		return delegate.supportsReturnType(returnType);
-	}
+  @Override
+  public boolean supportsReturnType(MethodParameter returnType) {
+    return delegate.supportsReturnType(returnType);
+  }
 
-	@Override
-	public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer,
-			NativeWebRequest webRequest) throws Exception {
+  @Override
+  public void handleReturnValue(Object returnValue, MethodParameter returnType,
+      ModelAndViewContainer mavContainer,
+      NativeWebRequest webRequest) throws Exception {
 
-		/*
-		 * Wraps bean to be serialized if there is some view assigned to it on
-		 * controller level
-		 */
-		Class<?> viewClass = getDeclaredViewClass(returnType);
-		if (viewClass != null) {
-			returnValue = wrapResult(returnValue, viewClass);
-		}
+    /*
+     * Wraps bean to be serialized if there is some view assigned to it on
+     * controller level
+     */
+    Class<?> viewClass = getDeclaredViewClass(returnType);
+    if (viewClass != null) {
+      returnValue = wrapResult(returnValue, viewClass);
+    }
 
-		delegate.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
+    delegate.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
 
-	}
+  }
 
-	/**
-	 * Returns assigned view or null
-	 *
-	 * @param returnType
-	 * @return
-	 */
-	private Class<?> getDeclaredViewClass(MethodParameter returnType) {
-		ResponseView annotation = returnType.getMethodAnnotation(ResponseView.class);
-		if (annotation != null) {
-			return annotation.value();
-		} else {
-			return null;
-		}
-	}
+  /**
+   * Returns assigned view or null
+   *
+   * @param returnType
+   * @return
+   */
+  private Class<?> getDeclaredViewClass(MethodParameter returnType) {
+    ResponseView annotation = returnType.getMethodAnnotation(ResponseView.class);
+    if (annotation != null) {
+      return annotation.value();
+    } else {
+      return null;
+    }
+  }
 
-	/**
-	 * Wraps bean and view into one object
-	 */
-	private Object wrapResult(Object result, Class<?> viewClass) {
-		return new JacksonViewAware(result, viewClass);
-	}
+  /**
+   * Wraps bean and view into one object
+   */
+  private Object wrapResult(Object result, Class<?> viewClass) {
+    return new JacksonViewAware(result, viewClass);
+  }
 
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/ws/resolver/JsonViewSupportFactoryBean.java b/src/main/java/com/epam/ta/reportportal/ws/resolver/JsonViewSupportFactoryBean.java
index 9c69db4a62..6b7ee82be6 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/resolver/JsonViewSupportFactoryBean.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/resolver/JsonViewSupportFactoryBean.java
@@ -16,47 +16,46 @@
 
 package com.epam.ta.reportportal.ws.resolver;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 import org.springframework.beans.factory.InitializingBean;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
 import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
 import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
 /**
- * Initializing bean for wrapping {@link HandlerMethodReturnValueHandler} with
- * JSON view decorators
+ * Initializing bean for wrapping {@link HandlerMethodReturnValueHandler} with JSON view decorators
  *
  * @author Andrei Varabyeu
  */
 public class JsonViewSupportFactoryBean implements InitializingBean {
 
-	@Autowired
-	private RequestMappingHandlerAdapter adapter;
-
-	@Override
-	public void afterPropertiesSet() {
-		List<HandlerMethodReturnValueHandler> handlers = adapter.getReturnValueHandlers();
-		adapter.setReturnValueHandlers(decorateHandlers(handlers));
-	}
-
-	private List<HandlerMethodReturnValueHandler> decorateHandlers(List<HandlerMethodReturnValueHandler> handlers) {
-
-		/*
-		 * We have to create new collection here, because initial list is
-		 * unmodifiable
-		 */
-		List<HandlerMethodReturnValueHandler> updatedHandlers = new ArrayList<>(handlers.size());
-		for (HandlerMethodReturnValueHandler handler : handlers) {
-			if (handler instanceof RequestResponseBodyMethodProcessor) {
-				updatedHandlers.add(new JacksonViewReturnValueHandler(handler));
-			} else {
-				updatedHandlers.add(handler);
-			}
-		}
-		return Collections.unmodifiableList(updatedHandlers);
-	}
+  @Autowired
+  private RequestMappingHandlerAdapter adapter;
+
+  @Override
+  public void afterPropertiesSet() {
+    List<HandlerMethodReturnValueHandler> handlers = adapter.getReturnValueHandlers();
+    adapter.setReturnValueHandlers(decorateHandlers(handlers));
+  }
+
+  private List<HandlerMethodReturnValueHandler> decorateHandlers(
+      List<HandlerMethodReturnValueHandler> handlers) {
+
+    /*
+     * We have to create new collection here, because initial list is
+     * unmodifiable
+     */
+    List<HandlerMethodReturnValueHandler> updatedHandlers = new ArrayList<>(handlers.size());
+    for (HandlerMethodReturnValueHandler handler : handlers) {
+      if (handler instanceof RequestResponseBodyMethodProcessor) {
+        updatedHandlers.add(new JacksonViewReturnValueHandler(handler));
+      } else {
+        updatedHandlers.add(handler);
+      }
+    }
+    return Collections.unmodifiableList(updatedHandlers);
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/resolver/PagingHandlerMethodArgumentResolver.java b/src/main/java/com/epam/ta/reportportal/ws/resolver/PagingHandlerMethodArgumentResolver.java
index 0dd27bb586..93589e1b69 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/resolver/PagingHandlerMethodArgumentResolver.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/resolver/PagingHandlerMethodArgumentResolver.java
@@ -16,6 +16,7 @@
 
 package com.epam.ta.reportportal.ws.resolver;
 
+import javax.annotation.Nonnull;
 import org.springframework.core.MethodParameter;
 import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.Pageable;
@@ -25,45 +26,48 @@
 import org.springframework.web.context.request.NativeWebRequest;
 import org.springframework.web.method.support.ModelAndViewContainer;
 
-import javax.annotation.Nonnull;
-
 /**
- * Added to avoid issue with page size == 0 (in this case repository layer tries
- * to retrieve all results from database) and page size greater than 300.
+ * Added to avoid issue with page size == 0 (in this case repository layer tries to retrieve all
+ * results from database) and page size greater than 300.
  *
  * @author Andrei Varabyeu
  */
-public class PagingHandlerMethodArgumentResolver extends org.springframework.data.web.PageableHandlerMethodArgumentResolver {
+public class PagingHandlerMethodArgumentResolver extends
+    org.springframework.data.web.PageableHandlerMethodArgumentResolver {
 
-	public PagingHandlerMethodArgumentResolver() {
-		super();
-	}
+  public PagingHandlerMethodArgumentResolver() {
+    super();
+  }
 
-	public PagingHandlerMethodArgumentResolver(SortHandlerMethodArgumentResolver sortResolver) {
-		super(sortResolver);
-	}
+  public PagingHandlerMethodArgumentResolver(SortHandlerMethodArgumentResolver sortResolver) {
+    super(sortResolver);
+  }
 
-	public static final int DEFAULT_PAGE_SIZE = 50;
-	public static final int MAX_PAGE_SIZE = 300000;
+  public static final int DEFAULT_PAGE_SIZE = 50;
+  public static final int MAX_PAGE_SIZE = 300000;
 
-	@Override
-	@Nonnull
-	public Pageable resolveArgument(MethodParameter methodParameter, @Nullable ModelAndViewContainer mavContainer,
-			NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) {
-		Pageable pageable = super.resolveArgument(methodParameter, mavContainer, webRequest, binderFactory);
+  @Override
+  @Nonnull
+  public Pageable resolveArgument(MethodParameter methodParameter,
+      @Nullable ModelAndViewContainer mavContainer,
+      NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) {
+    Pageable pageable = super.resolveArgument(methodParameter, mavContainer, webRequest,
+        binderFactory);
 
-		//overriding spring base limit for page size
-		String pageSize = webRequest.getParameter(getParameterNameToUse(getSizeParameterName(), methodParameter));
-		if (pageSize != null) {
-			pageable = PageRequest.of(pageable.getPageNumber(), Integer.parseInt(pageSize), pageable.getSort());
-		}
+    //overriding spring base limit for page size
+    String pageSize = webRequest.getParameter(
+        getParameterNameToUse(getSizeParameterName(), methodParameter));
+    if (pageSize != null) {
+      pageable = PageRequest.of(pageable.getPageNumber(), Integer.parseInt(pageSize),
+          pageable.getSort());
+    }
 
-		if (0 == pageable.getPageSize()) {
-			return PageRequest.of(pageable.getPageNumber(), DEFAULT_PAGE_SIZE, pageable.getSort());
-		} else if (MAX_PAGE_SIZE < pageable.getPageSize()) {
-			return PageRequest.of(pageable.getPageNumber(), MAX_PAGE_SIZE, pageable.getSort());
-		}
-		return pageable;
-	}
+    if (0 == pageable.getPageSize()) {
+      return PageRequest.of(pageable.getPageNumber(), DEFAULT_PAGE_SIZE, pageable.getSort());
+    } else if (MAX_PAGE_SIZE < pageable.getPageSize()) {
+      return PageRequest.of(pageable.getPageNumber(), MAX_PAGE_SIZE, pageable.getSort());
+    }
+    return pageable;
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/resolver/PredefinedFilterCriteriaResolver.java b/src/main/java/com/epam/ta/reportportal/ws/resolver/PredefinedFilterCriteriaResolver.java
index cb7af96822..479f56227e 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/resolver/PredefinedFilterCriteriaResolver.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/resolver/PredefinedFilterCriteriaResolver.java
@@ -23,6 +23,11 @@
 import com.epam.ta.reportportal.core.filter.predefined.PredefinedFilterType;
 import com.epam.ta.reportportal.core.filter.predefined.PredefinedFilters;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
 import org.jooq.Operator;
 import org.springframework.core.MethodParameter;
 import org.springframework.web.bind.support.WebDataBinderFactory;
@@ -30,76 +35,74 @@
 import org.springframework.web.method.support.HandlerMethodArgumentResolver;
 import org.springframework.web.method.support.ModelAndViewContainer;
 
-import java.util.Collections;
-import java.util.List;
-import java.util.Optional;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-
 /**
  * Resolves filter parameters in GET requests. All Parameters should start with
  * <b>'filter.'</b> prefix. For example, if you would like to filter some
- * parameter with name 'age' you have to put in request the following:
- * '?filter.age=20'. Resolves parameter only in case argument marked with
- * annotation {@link FilterFor}. <br>
- * By FilterFor value resolves criterias/parameters to the given domain class
- * and resolves them if possible. If there are no criteria/parameter defined for
- * specified class than will throw exception
+ * parameter with name 'age' you have to put in request the following: '?filter.age=20'. Resolves
+ * parameter only in case argument marked with annotation {@link FilterFor}. <br> By FilterFor value
+ * resolves criterias/parameters to the given domain class and resolves them if possible. If there
+ * are no criteria/parameter defined for specified class than will throw exception
  *
  * @author Andrei Varabyeu
  */
 public class PredefinedFilterCriteriaResolver implements HandlerMethodArgumentResolver {
 
-	/**
-	 * Default prefix for filter conditions. Since Request contains a lot of
-	 * parameters (some of them may not be related to filtering), we have to
-	 * introduce this
-	 */
-	public static final String PREDEFINED_FILTER_PREFIX = "predefinedFilter.";
+  /**
+   * Default prefix for filter conditions. Since Request contains a lot of parameters (some of them
+   * may not be related to filtering), we have to introduce this
+   */
+  public static final String PREDEFINED_FILTER_PREFIX = "predefinedFilter.";
 
-	/**
-	 * Returns TRUE only for {@link List} marked with {@link FilterFor}
-	 * annotations
-	 */
-	@Override
-	public boolean supportsParameter(MethodParameter methodParameter) {
-		return Queryable.class.isAssignableFrom(methodParameter.getParameterType()) && null != methodParameter.getParameterAnnotation(
-				FilterFor.class);
-	}
+  /**
+   * Returns TRUE only for {@link List} marked with {@link FilterFor} annotations
+   */
+  @Override
+  public boolean supportsParameter(MethodParameter methodParameter) {
+    return Queryable.class.isAssignableFrom(methodParameter.getParameterType())
+        && null != methodParameter.getParameterAnnotation(
+        FilterFor.class);
+  }
 
-	@Override
-	public Queryable resolveArgument(MethodParameter methodParameter, ModelAndViewContainer paramModelAndViewContainer,
-			NativeWebRequest webRequest, WebDataBinderFactory paramWebDataBinderFactory) {
-		Class<?> domainModelType = methodParameter.getParameterAnnotation(FilterFor.class).value();
+  @Override
+  public Queryable resolveArgument(MethodParameter methodParameter,
+      ModelAndViewContainer paramModelAndViewContainer,
+      NativeWebRequest webRequest, WebDataBinderFactory paramWebDataBinderFactory) {
+    Class<?> domainModelType = methodParameter.getParameterAnnotation(FilterFor.class).value();
 
-		List<Queryable> filterConditions = webRequest.getParameterMap()
-				.entrySet().stream().filter(parameter -> parameter.getKey().startsWith(PREDEFINED_FILTER_PREFIX))
-				.map(parameter -> {
-					BusinessRule.expect(parameter.getValue(), v -> null != v && v.length == 1)
-							.verify(ErrorType.INCORRECT_REQUEST, "Incorrect filter value");
+    List<Queryable> filterConditions = webRequest.getParameterMap()
+        .entrySet().stream()
+        .filter(parameter -> parameter.getKey().startsWith(PREDEFINED_FILTER_PREFIX))
+        .map(parameter -> {
+          BusinessRule.expect(parameter.getValue(), v -> null != v && v.length == 1)
+              .verify(ErrorType.INCORRECT_REQUEST, "Incorrect filter value");
 
-					String filterName = parameter.getKey().split("\\.")[1];
-					String[] filterParameters = parameter.getValue()[0].split(",");
+          String filterName = parameter.getKey().split("\\.")[1];
+          String[] filterParameters = parameter.getValue()[0].split(",");
 
-					Optional<PredefinedFilterType> predefinedFilterType = PredefinedFilterType.fromString(filterName);
-					BusinessRule.expect(predefinedFilterType, Optional::isPresent)
-							.verify(ErrorType.BAD_REQUEST_ERROR, "Incorrect predefined filter type " + filterName);
+          Optional<PredefinedFilterType> predefinedFilterType = PredefinedFilterType.fromString(
+              filterName);
+          BusinessRule.expect(predefinedFilterType, Optional::isPresent)
+              .verify(ErrorType.BAD_REQUEST_ERROR,
+                  "Incorrect predefined filter type " + filterName);
 
-					BusinessRule.expect(PredefinedFilters.hasFilter(predefinedFilterType.get()), Predicate.isEqual(true))
-							.verify(ErrorType.INCORRECT_REQUEST, "Unknown filter '" + filterName + "'");
+          BusinessRule.expect(PredefinedFilters.hasFilter(predefinedFilterType.get()),
+                  Predicate.isEqual(true))
+              .verify(ErrorType.INCORRECT_REQUEST, "Unknown filter '" + filterName + "'");
 
-					final Queryable queryable = PredefinedFilters.buildFilter(predefinedFilterType.get(), filterParameters);
-					BusinessRule.expect(queryable.getTarget().getClazz(), Predicate.isEqual(domainModelType))
-							.verify(ErrorType.INCORRECT_REQUEST, "Incorrect filter target class type");
+          final Queryable queryable = PredefinedFilters.buildFilter(predefinedFilterType.get(),
+              filterParameters);
+          BusinessRule.expect(queryable.getTarget().getClazz(), Predicate.isEqual(domainModelType))
+              .verify(ErrorType.INCORRECT_REQUEST, "Incorrect filter target class type");
 
-					return queryable;
+          return queryable;
 
-				})
-				.collect(Collectors.toList());
-		return filterConditions.isEmpty() ? nop(domainModelType) : new CompositeFilter(Operator.AND, filterConditions);
-	}
+        })
+        .collect(Collectors.toList());
+    return filterConditions.isEmpty() ? nop(domainModelType)
+        : new CompositeFilter(Operator.AND, filterConditions);
+  }
 
-	private Queryable nop(Class<?> type) {
-		return new Filter(type, Collections.emptyList());
-	}
+  private Queryable nop(Class<?> type) {
+    return new Filter(type, Collections.emptyList());
+  }
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/resolver/ResponseView.java b/src/main/java/com/epam/ta/reportportal/ws/resolver/ResponseView.java
index a1ba321674..1af8f3e2cd 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/resolver/ResponseView.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/resolver/ResponseView.java
@@ -31,8 +31,9 @@
 @Target(ElementType.METHOD)
 @Retention(RetentionPolicy.RUNTIME)
 public @interface ResponseView {
-	/**
-	 * View class
-	 */
-	Class<?> value();
+
+  /**
+   * View class
+   */
+  Class<?> value();
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/ws/resolver/SortArgumentResolver.java b/src/main/java/com/epam/ta/reportportal/ws/resolver/SortArgumentResolver.java
index b9e762c4a4..5841d34f05 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/resolver/SortArgumentResolver.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/resolver/SortArgumentResolver.java
@@ -16,11 +16,16 @@
 
 package com.epam.ta.reportportal.ws.resolver;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_ID;
+import static java.util.stream.Collectors.toList;
+
 import com.epam.ta.reportportal.commons.Preconditions;
 import com.epam.ta.reportportal.commons.querygen.CriteriaHolder;
 import com.epam.ta.reportportal.commons.querygen.FilterTarget;
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import java.util.Optional;
+import java.util.stream.StreamSupport;
 import org.springframework.core.MethodParameter;
 import org.springframework.data.domain.Sort;
 import org.springframework.data.web.SortHandlerMethodArgumentResolver;
@@ -28,56 +33,52 @@
 import org.springframework.web.context.request.NativeWebRequest;
 import org.springframework.web.method.support.ModelAndViewContainer;
 
-import java.util.Optional;
-import java.util.stream.StreamSupport;
-
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_ID;
-import static java.util.stream.Collectors.toList;
-
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
  */
 public class SortArgumentResolver extends SortHandlerMethodArgumentResolver {
 
-	@Override
-	public Sort resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest,
-			WebDataBinderFactory binderFactory) {
+  @Override
+  public Sort resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
+      NativeWebRequest webRequest,
+      WebDataBinderFactory binderFactory) {
 
-		/*
-		 * Resolve sort argument in default way
-		 */
-		Sort defaultSort = super.resolveArgument(parameter, mavContainer, webRequest, binderFactory);
+    /*
+     * Resolve sort argument in default way
+     */
+    Sort defaultSort = super.resolveArgument(parameter, mavContainer, webRequest, binderFactory);
 
-		/*
-		 * Try to find parameter to be sorted in internal-external mapping
-		 */
-		if (null != parameter.getParameterAnnotation(SortFor.class)) {
+    /*
+     * Try to find parameter to be sorted in internal-external mapping
+     */
+    if (null != parameter.getParameterAnnotation(SortFor.class)) {
 
-			Class<?> domainModelType = parameter.getParameterAnnotation(SortFor.class).value();
-			FilterTarget filterTarget = FilterTarget.findByClass(domainModelType);
+      Class<?> domainModelType = parameter.getParameterAnnotation(SortFor.class).value();
+      FilterTarget filterTarget = FilterTarget.findByClass(domainModelType);
 
-			/*
-			 * Hack. Adds sort by id to each query to avoid problems with
-			 * lost data while paging
-			 */
-			defaultSort = defaultSort.and(Sort.by(CRITERIA_ID));
+      /*
+       * Hack. Adds sort by id to each query to avoid problems with
+       * lost data while paging
+       */
+      defaultSort = defaultSort.and(Sort.by(CRITERIA_ID));
 
-			/*
-			 * Build Sort with search criteria from internal domain model
-			 */
-			return Sort.by(StreamSupport.stream(defaultSort.spliterator(), false).map(order -> {
-				Optional<CriteriaHolder> criteriaHolder = filterTarget.getCriteriaByFilter(order.getProperty());
-				BusinessRule.expect(criteriaHolder, Preconditions.IS_PRESENT)
-						.verify(ErrorType.INCORRECT_SORTING_PARAMETERS, order.getProperty());
-				return new Sort.Order(order.getDirection(), order.getProperty());
-			}).collect(toList()));
-		} else {
-			/*
-			 * Return default sort in case there are no SortFor annotation
-			 */
-			return defaultSort;
-		}
+      /*
+       * Build Sort with search criteria from internal domain model
+       */
+      return Sort.by(StreamSupport.stream(defaultSort.spliterator(), false).map(order -> {
+        Optional<CriteriaHolder> criteriaHolder = filterTarget.getCriteriaByFilter(
+            order.getProperty());
+        BusinessRule.expect(criteriaHolder, Preconditions.IS_PRESENT)
+            .verify(ErrorType.INCORRECT_SORTING_PARAMETERS, order.getProperty());
+        return new Sort.Order(order.getDirection(), order.getProperty());
+      }).collect(toList()));
+    } else {
+      /*
+       * Return default sort in case there are no SortFor annotation
+       */
+      return defaultSort;
+    }
 
-	}
+  }
 
 }
diff --git a/src/main/java/com/epam/ta/reportportal/ws/resolver/SortFor.java b/src/main/java/com/epam/ta/reportportal/ws/resolver/SortFor.java
index 9664c0aae1..e63de831b1 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/resolver/SortFor.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/resolver/SortFor.java
@@ -15,7 +15,11 @@
  */
 package com.epam.ta.reportportal.ws.resolver;
 
-import java.lang.annotation.*;
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
 
 /**
  * Remaps WS domain model to internal domain model in sorting request parameters
@@ -27,10 +31,10 @@
 @Documented
 public @interface SortFor {
 
-	/**
-	 * Domain Object class sorting parameters will be applied to
-	 *
-	 * @return Class
-	 */
-	Class<?> value();
+  /**
+   * Domain Object class sorting parameters will be applied to
+   *
+   * @return Class
+   */
+  Class<?> value();
 }
\ No newline at end of file
diff --git a/src/main/java/com/epam/ta/reportportal/ws/validation/JaskonRequiredPropertiesValidator.java b/src/main/java/com/epam/ta/reportportal/ws/validation/JaskonRequiredPropertiesValidator.java
index f487237949..7c39324df3 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/validation/JaskonRequiredPropertiesValidator.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/validation/JaskonRequiredPropertiesValidator.java
@@ -20,6 +20,10 @@
 import com.epam.ta.reportportal.commons.accessible.Accessible;
 import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.core.annotation.AnnotationUtils;
@@ -27,53 +31,51 @@
 import org.springframework.validation.ValidationUtils;
 import org.springframework.validation.Validator;
 
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
 public class JaskonRequiredPropertiesValidator implements Validator {
-	private static final Logger LOGGER = LoggerFactory.getLogger(JaskonRequiredPropertiesValidator.class);
 
-	@Override
-	public boolean supports(Class<?> clazz) {
-		return AnnotationUtils.isAnnotationDeclaredLocally(JsonInclude.class, clazz);
-	}
+  private static final Logger LOGGER = LoggerFactory.getLogger(
+      JaskonRequiredPropertiesValidator.class);
+
+  @Override
+  public boolean supports(Class<?> clazz) {
+    return AnnotationUtils.isAnnotationDeclaredLocally(JsonInclude.class, clazz);
+  }
 
-	@Override
-	public void validate(Object object, Errors errors) {
-		for (Field field : collectFields(object.getClass())) {
-			if (AnnotationUtils.isAnnotationDeclaredLocally(JsonInclude.class, field.getType())) {
-				try {
-					Object innerObject = Accessible.on(object).field(field).getValue();
-					if (null != innerObject) {
-						errors.pushNestedPath(field.getName());
-						validate(innerObject, errors);
-					}
-				} catch (Exception e) {
-					LOGGER.error("JaskonRequiredPropertiesValidator error: " + e.getMessage(), e);
-					// do nothing
-				}
+  @Override
+  public void validate(Object object, Errors errors) {
+    for (Field field : collectFields(object.getClass())) {
+      if (AnnotationUtils.isAnnotationDeclaredLocally(JsonInclude.class, field.getType())) {
+        try {
+          Object innerObject = Accessible.on(object).field(field).getValue();
+          if (null != innerObject) {
+            errors.pushNestedPath(field.getName());
+            validate(innerObject, errors);
+          }
+        } catch (Exception e) {
+          LOGGER.error("JaskonRequiredPropertiesValidator error: " + e.getMessage(), e);
+          // do nothing
+        }
 
-			}
-			if (field.isAnnotationPresent(JsonProperty.class) && field.getAnnotation(JsonProperty.class).required()) {
-				String errorCode = "NotNull." + field.getName();
-				ValidationUtils.rejectIfEmpty(errors, field.getName(), errorCode, new Object[] { errorCode });
-			}
-		}
-		if (errors.getNestedPath() != null && errors.getNestedPath().length() != 0) {
-			errors.popNestedPath();
-		}
-	}
+      }
+      if (field.isAnnotationPresent(JsonProperty.class) && field.getAnnotation(JsonProperty.class)
+          .required()) {
+        String errorCode = "NotNull." + field.getName();
+        ValidationUtils.rejectIfEmpty(errors, field.getName(), errorCode, new Object[]{errorCode});
+      }
+    }
+    if (errors.getNestedPath() != null && errors.getNestedPath().length() != 0) {
+      errors.popNestedPath();
+    }
+  }
 
-	private List<Field> collectFields(Class<?> clazz) {
-		List<Field> fields = null;
-		if (!Object.class.equals(clazz.getSuperclass())) {
-			fields = collectFields(clazz.getSuperclass());
-		}
+  private List<Field> collectFields(Class<?> clazz) {
+    List<Field> fields = null;
+    if (!Object.class.equals(clazz.getSuperclass())) {
+      fields = collectFields(clazz.getSuperclass());
+    }
 
-		fields = (fields == null) ? new ArrayList<>() : fields;
-		fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
-		return fields;
-	}
+    fields = (fields == null) ? new ArrayList<>() : fields;
+    fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
+    return fields;
+  }
 }
\ No newline at end of file
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 4056f615ae..7ff12905eb 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -14,26 +14,23 @@
 # limitations under the License.
 #
 spring.main.allow-bean-definition-overriding=true
-spring.batch.initialize-schema=always
-
+spring.batch.jdbc.initialize-schema=always
 info.build.name=API Service
 info.build.description=ReportPortal API Service
 info.build.version=${version}${buildNumber}
 info.build.branch=${branch}
 info.build.repo=${repo}
-
 management.endpoints.web.base-path=/
+management.endpoint.health.show-details=always
 #security.sessions=never
 #security.basic.enabled=false
-management.server.servlet.context-path=/admin
-
+management.server.base-path=/admin
 ## Supported period format details
 ## https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html#parse-java.lang.CharSequence-
-com.ta.reportportal.job.load.plugins.cron=PT1M
-com.ta.reportportal.job.clean.outdated.plugins.cron=PT1M
+com.ta.reportportal.job.load.plugins.cron=PT10S
+com.ta.reportportal.job.clean.outdated.plugins.cron=PT10S
 com.ta.reportportal.job.interrupt.broken.launches.cron=PT1H
 com.ta.reportportal.job.clean.bids.cron=PT1H
-
 spring.jooq.sql-dialect=POSTGRES
 
 
@@ -57,4 +54,4 @@ com.ta.reportportal.rp.flushing.time.cron=\${rp.environment.variable.flushing.ti
 ## Profiles list
 spring.profiles.active=\${rp.profiles:default}
 
-rp.feature.flags=
\ No newline at end of file
+rp.feature.flags=
diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml
index 641973021c..6cbd6f282e 100644
--- a/src/main/resources/application.yaml
+++ b/src/main/resources/application.yaml
@@ -2,7 +2,7 @@ spring:
   application:
     name: api
     quartz:
-#      org.quartz.jobStore.class: org.quartz.impl.jdbcjobstore.JobStoreTX
+      #      org.quartz.jobStore.class: org.quartz.impl.jdbcjobstore.JobStoreTX
       org.quartz.jobStore.driverDelegateClass: org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
       org.quartz.jobStore.dataSource: dataSource
       org.quartz.jobStore.tablePrefix: quartz.scheduler_
@@ -70,6 +70,11 @@ rp:
         batch-size: 20
       pattern-analysis:
         batch-size: 100
+        consumers-count: 2
+        prefetch-count: 0
+        single-item: true
+      elements-counter:
+        batch-size: 50
       history:
         old: false
       demo:
@@ -94,10 +99,6 @@ rp:
             core: 10
             max: 30
             queue: 500
-          pattern-analyze:
-            core: 20
-            max: 30
-            queue: 500
           demo-data:
             core: 10
             max: 20
@@ -110,6 +111,10 @@ rp:
             core: 10
             max: 20
             queue: 1000
+          user-email:
+            core: 5
+            max: 20
+            queue: 500
 
   amqp:
     addresses: amqp://${rp.amqp.user}:${rp.amqp.pass}@${rp.amqp.host}:${rp.amqp.port}
@@ -136,6 +141,10 @@ rp:
   jwt:
     signing-key:
 
+
+  jobs:
+    baseUrl: http://jobs:8686
+
   datasource:
     type: com.zaxxer.hikari.HikariDataSource
     driverClassName: org.postgresql.Driver
@@ -162,6 +171,7 @@ rp:
     path: ${rp.plugins.rootDir}/resolved
     resources:
       path: ${rp.plugins.rootDir}/resources
+      public: public
     temp:
       path: ${rp.plugins.rootDir}/temp
   binarystore:
diff --git a/src/main/resources/bug_template.ftl b/src/main/resources/bug_template.ftl
index aff122189c..6f973628d8 100644
--- a/src/main/resources/bug_template.ftl
+++ b/src/main/resources/bug_template.ftl
@@ -3,53 +3,55 @@
         ${description}
     </#if>
 
-<#--if RP contains some comments for test item-->
+    <#--if RP contains some comments for test item-->
     <#if comments??>
-		<h3>Test Item comments:</h3>
+      <h3>Test Item comments:</h3>
         ${comments}
     </#if>
 
-<#--##  if backlinks are present-->
+    <#--##  if backlinks are present-->
     <#if backLinks??>
-        <h3>Back link to Report Portal:</h3>
-        <ul type="square">
-        <#list backLinks as key,value>
+      <h3>Back link to Report Portal:</h3>
+      <ul type="square">
+          <#list backLinks as key,value>
             <li><a href="${value}" rel="nofollow" title="Follow link">Link to defect</a></li>
-        </#list>
-        </ul>
-        <br>
+          </#list>
+      </ul>
+      <br>
     </#if>
 
-<#--Complex block with logic in velocity. Consider to move all logic in JAVA code.-->
-        <#if logs?? && logs?size != 0>
-        <div class="panel">
-            <div class="panelHeader"
-                 style="border-bottom-width: 1px;border-bottom-style: solid;border-bottom-color: #ccc;background-color: #6DB33F;color: #34302D;">
-                <b>Test execution log</b>
-            </div>
-            <div class="panelContent">
-                <#list logs as logEntry>
-                    <#if logEntry.message??>
-                        <div style="border-width: 1px;">
-                            <pre style="white-space: pre-wrap; display: block;font-family: monospace;max-height: 30em;text-align: left;">${logEntry.message}</pre>
-                        </div>
-                    </#if>
-                <#--##    if URL provided to screen source-->
-                    <#if logEntry.decodedFileName??>
-                        <#if (logEntry.image)!false>
-                         <p><img src="${logEntry.decodedFileName}" align="absmiddle" border="0" height="366"><br class="atl-forced-newline">
-                         </p>
-                        <#else>
-                        <p>
-                            <a href="${logEntry.decodedFileName}">
-                                "${logEntry.decodedFileName}"
-                            </a>
-                            <br class="atl-forced-newline">
-                        </p>
-                        </#if>
+    <#--Complex block with logic in velocity. Consider to move all logic in JAVA code.-->
+    <#if logs?? && logs?size != 0>
+      <div class="panel">
+        <div class="panelHeader"
+             style="border-bottom-width: 1px;border-bottom-style: solid;border-bottom-color: #ccc;background-color: #6DB33F;color: #34302D;">
+          <b>Test execution log</b>
+        </div>
+        <div class="panelContent">
+            <#list logs as logEntry>
+                <#if logEntry.message??>
+                  <div style="border-width: 1px;">
+                    <pre
+                        style="white-space: pre-wrap; display: block;font-family: monospace;max-height: 30em;text-align: left;">${logEntry.message}</pre>
+                  </div>
+                </#if>
+            <#--##    if URL provided to screen source-->
+                <#if logEntry.decodedFileName??>
+                    <#if (logEntry.image)!false>
+                      <p><img src="${logEntry.decodedFileName}" align="absmiddle" border="0"
+                              height="366"><br class="atl-forced-newline">
+                      </p>
+                    <#else>
+                      <p>
+                        <a href="${logEntry.decodedFileName}">
+                          "${logEntry.decodedFileName}"
+                        </a>
+                        <br class="atl-forced-newline">
+                      </p>
                     </#if>
-                </#list>
-            </div>
+                </#if>
+            </#list>
         </div>
-        </#if>
+      </div>
+    </#if>
 </div>
diff --git a/src/main/resources/demo/attachments/css.css b/src/main/resources/demo/attachments/css.css
index fce80e34c3..67f6d90a09 100644
--- a/src/main/resources/demo/attachments/css.css
+++ b/src/main/resources/demo/attachments/css.css
@@ -1,31 +1,31 @@
 p {
-    font-family: arial, helvetica, sans-serif;
+  font-family: arial, helvetica, sans-serif;
 }
 
 h2 {
-    font-size: 20pt;
-    color: red;
-    background: white;
+  font-size: 20pt;
+  color: red;
+  background: white;
 }
 
 .note {
-    color: red;
-    background-color: yellow;
-    font-weight: bold;
+  color: red;
+  background-color: yellow;
+  font-weight: bold;
 }
 
 p#paragraph1 {
-    padding-left: 10px;
+  padding-left: 10px;
 }
 
 a:hover {
-    text-decoration: none;
+  text-decoration: none;
 }
 
 #news p {
-    color: blue;
+  color: blue;
 }
 
 [type="button"] {
-    background-color: green;
+  background-color: green;
 }
\ No newline at end of file
diff --git a/src/main/resources/demo/attachments/html.html b/src/main/resources/demo/attachments/html.html
index fca8088680..a2e5c1dde6 100644
--- a/src/main/resources/demo/attachments/html.html
+++ b/src/main/resources/demo/attachments/html.html
@@ -1,16 +1,16 @@
 <!DOCTYPE html>
 <html>
 <head>
-    <title>Sample "Hello, World" Application</title>
+  <title>Sample "Hello, World" Application</title>
 </head>
 <body bgcolor=white>
 
 <table border="0" cellpadding="10">
-    <tr>
-        <td>
-            <h1>Sample "Hello, World" Application</h1>
-        </td>
-    </tr>
+  <tr>
+    <td>
+      <h1>Sample "Hello, World" Application</h1>
+    </td>
+  </tr>
 </table>
 </body>
 </html>
\ No newline at end of file
diff --git a/src/main/resources/demo/attachments/javascript.js b/src/main/resources/demo/attachments/javascript.js
index de5361602b..e3e51f1831 100644
--- a/src/main/resources/demo/attachments/javascript.js
+++ b/src/main/resources/demo/attachments/javascript.js
@@ -1,62 +1,62 @@
 var APP = APP || {};
 APP.Views.People = Backbone.View.extend({
-    template: APP.getTemplate('people-list-template'),
-    initialize: function () {
-        this.render();
-        var peopleControls = new APP.Views.PeopleControls({
-            el: '#controls'
-        });
-        var peopleInfo = new APP.Views.PeopleInfo({
-            el: '#summary'
-        });
-        this.showPeopleCount();
-        this.listenTo(this.collection, 'reset', this.renderPeopleList);
-        this.listenTo(this.collection, 'all', this.showPeopleCount);
-    },
-    events: {
-        'click .toJSON': 'convertToJSON',
-        'click .deleteAll': 'deleteAll',
-        'click .addPerson': 'addPerson'
-    },
-    convertToJSON: function () {
-        this.$('#JSON-output').html(JSON.stringify(this.collection.toJSON()));
-    },
-    renderPerson: function (person) {
-        var personView = new APP.Views.Person({
-            model: person,
-            //el: '#peopleList' затирает el при каждом вызове
-        });
-        this.$el.find('#peopleList').append(personView.render().el);
-    },
-    deleteAll: function () {
-        if (confirm('Delete all data?')) {
-            this.collection.reset();
-        }
-    },
-    addPerson: function () {
-        var personModel = new APP.Models.Person({
-            'name': this.$el.find('#name').val().trim(),
-            'age': +this.$el.find('#age').val().trim(),
-            'profession': this.$el.find('#profession > option:selected').text(),
-        }, {
-            validate: true
-        });
-        if (!personModel.validationError) {
-            this.collection.add(personModel);
-            this.renderPerson(personModel);
-        } else {
-            alert(personModel.validationError);
-        }
-    },
-    renderPeopleList: function () {
-        this.$el.find('#peopleList').html('');
-        this.collection.each(this.renderCollection, this);
-    },
-    showPeopleCount: function () {
-        this.$el.find('#peopleCount').html(this.collection.length);
-    },
-    render: function () {
-        this.$el.html(this.template);
-        this.collection.each(this.renderPerson, this);
+  template: APP.getTemplate('people-list-template'),
+  initialize: function () {
+    this.render();
+    var peopleControls = new APP.Views.PeopleControls({
+      el: '#controls'
+    });
+    var peopleInfo = new APP.Views.PeopleInfo({
+      el: '#summary'
+    });
+    this.showPeopleCount();
+    this.listenTo(this.collection, 'reset', this.renderPeopleList);
+    this.listenTo(this.collection, 'all', this.showPeopleCount);
+  },
+  events: {
+    'click .toJSON': 'convertToJSON',
+    'click .deleteAll': 'deleteAll',
+    'click .addPerson': 'addPerson'
+  },
+  convertToJSON: function () {
+    this.$('#JSON-output').html(JSON.stringify(this.collection.toJSON()));
+  },
+  renderPerson: function (person) {
+    var personView = new APP.Views.Person({
+      model: person,
+      //el: '#peopleList' затирает el при каждом вызове
+    });
+    this.$el.find('#peopleList').append(personView.render().el);
+  },
+  deleteAll: function () {
+    if (confirm('Delete all data?')) {
+      this.collection.reset();
     }
+  },
+  addPerson: function () {
+    var personModel = new APP.Models.Person({
+      'name': this.$el.find('#name').val().trim(),
+      'age': +this.$el.find('#age').val().trim(),
+      'profession': this.$el.find('#profession > option:selected').text(),
+    }, {
+      validate: true
+    });
+    if (!personModel.validationError) {
+      this.collection.add(personModel);
+      this.renderPerson(personModel);
+    } else {
+      alert(personModel.validationError);
+    }
+  },
+  renderPeopleList: function () {
+    this.$el.find('#peopleList').html('');
+    this.collection.each(this.renderCollection, this);
+  },
+  showPeopleCount: function () {
+    this.$el.find('#peopleCount').html(this.collection.length);
+  },
+  render: function () {
+    this.$el.html(this.template);
+    this.collection.each(this.renderPerson, this);
+  }
 });
diff --git a/src/main/resources/demo/attachments/xml.xml b/src/main/resources/demo/attachments/xml.xml
index e727599fea..7ba28131c4 100644
--- a/src/main/resources/demo/attachments/xml.xml
+++ b/src/main/resources/demo/attachments/xml.xml
@@ -1,17 +1,17 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <configuration>
-    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
-        <layout class="ch.qos.logback.classic.PatternLayout">
-            <Pattern>
-                %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
-            </Pattern>
-        </layout>
-    </appender>
-    <logger name="com.mkyong.web" level="debug"
-            additivity="false">
-        <appender-ref ref="STDOUT"/>
-    </logger>
-    <root level="error">
-        <appender-ref ref="STDOUT"/>
-    </root>
+  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+    <layout class="ch.qos.logback.classic.PatternLayout">
+      <Pattern>
+        %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
+      </Pattern>
+    </layout>
+  </appender>
+  <logger name="com.mkyong.web" level="debug"
+    additivity="false">
+    <appender-ref ref="STDOUT"/>
+  </logger>
+  <root level="error">
+    <appender-ref ref="STDOUT"/>
+  </root>
 </configuration>
diff --git a/src/main/resources/demo/launch/002_launch.json b/src/main/resources/demo/launch/002_launch.json
index 2566579c44..0fa5122fc3 100644
--- a/src/main/resources/demo/launch/002_launch.json
+++ b/src/main/resources/demo/launch/002_launch.json
@@ -1,175 +1,175 @@
- {
-    "suites": [
-      {
-        "type": "RETRY",
-        "name": "Suite with retries",
-        "status": "FAILED",
-        "tests": [
-          {
-            "name": "First test case",
-            "status": "FAILED",
-            "steps": [
-              {
-                "name": "first test",
-                "status": "FAILED",
-                "issue": "SYSTEM_ISSUE"
-              }
-            ]
-          }
-        ]
-      },
-      {
-        "type": "NESTED",
-        "name": "Suite with nested steps",
-        "status": "FAILED",
-        "tests": [
-          {
-            "name": "History table. Extended functionality. Permissions. Edit defect",
-            "status": "FAILED",
-            "issue": "AUTOMATION_BUG",
-            "steps": [
-              {
-                "name": "Launch was executed 11 times",
-                "status": "PASSED"
-              },
-              {
-                "name": "**Step 1:** Login to https://localhost:8080/ with password *** <br />**Expected Result:** User is in RP",
-                "status": "PASSED"
-              },
-              {
-                "name": "**Step 2:** Open 'All launches' <br />**Expected Result:** All launches page is presented",
-                "status": "PASSED"
-              },
-              {
-                "name": "**Step 3:** Click on Total statistics <br />**Expected Result:** Launch list view is displayed, refines contains criteria **Method type: Test**; **Status: Passed, Failed, Skipped, Interrupted**",
-                "status": "PASSED"
-              },
-              {
-                "name": "**Step 4:** Click on 'History view' icon <br />**Expected Result:** 10 latest executions for the first 20 items (from the latest executions to the eldest) displayed by default**",
-                "status": "PASSED"
-              },
-              {
-                "name": "**Step 5:** Check several items **(own and not own)** <br />**Expected Result:** Items are added to the header",
-                "status": "PASSED"
-              },
-              {
-                "name": "**Step 6:** Click 'Actions'> 'Edit Defects' <br />**Expected Result:** Edit modal for bulk operation is opened",
-                "status": "PASSED"
-              },
-              {
-                "name": "**Step 7:** Update defect type <br />**Expected Result:** Value(s) are in the fields",
-                "status": "PASSED"
-              },
-              {
-                "name": "**Step 8:** Click 'Save'<br />**Expected Result:** Updates are saved for the last launch and all chosen items",
-                "status": "FAILED"
-              }
-            ]
-          }
-        ]
-      },
-      {
-        "type": "DEFAULT",
-        "name": "Filtering Launch Tests",
-        "status": "FAILED",
-        "hasBefore": true,
-        "tests": [
-          {
-            "name": "FilteringLaunchGtePassedTest",
-            "status": "PASSED",
-            "hasBefore": true,
-            "steps": [
-              {
-                "name": "testFilterLaunchGreaterThanEqualsNegativeValue",
-                "status": "PASSED",
-                "hasBefore": true
-              },
-              {
-                "name": "testFilterLaunchGreaterThanEqualsNotNumber",
-                "status": "PASSED",
-                "hasAfter": true
-              },
-              {
-                "name": "testFilterLaunchGreaterThanEqualsPositive",
-                "status": "PASSED"
-              },
-              {
-                "name": "testFilterLaunchGreaterThanEqualsZero",
-                "status": "PASSED"
-              },
-              {
-                "name": "testFilterLaunchLowerThanEqualsNegativeValue",
-                "status": "PASSED"
-              }
-            ]
-          },
-          {
-            "name": "FilteringLaunchInTagsTest",
-            "status": "FAILED",
-            "hasAfter": true,
-            "steps": [
-              {
-                "name": "testFilterPositive",
-                "status": "FAILED",
-                "hasBefore": true,
-                "issue": "SYSTEM_ISSUE"
-              },
-              {
-                "name": "testFilterNegative",
-                "status": "FAILED",
-                "hasAfter": true,
-                "issue": "SYSTEM_ISSUE"
-              },
-              {
-                "name": "testFilterSpecialSymbols",
-                "status": "FAILED",
-                "issue": "SYSTEM_ISSUE"
-              }
-            ]
-          }
-        ]
-      },
-      {
-        "type": "DEFAULT",
-        "name": "Launch Tests",
-        "status": "FAILED",
-        "hasBefore": true,
-        "tests": [
-          {
-            "name": "LaunchStatusTest",
-            "status": "FAILED",
-            "hasBefore": true,
-            "steps": [
-              {
-                "name": "launchMixedItemsStatusText",
-                "status": "SKIPPED",
-                "issue": "PRODUCT_BUG",
-                "hasBefore": true
-              },
-              {
-                "name": "launchStatusTest",
-                "status": "FAILED",
-                "hasAfter": true,
-                "issue": "AUTOMATION_BUG"
-              },
-              {
-                "name": "testLaunchStatusAfterDeletingTest",
-                "status": "FAILED",
-                "issue": "AUTOMATION_BUG"
-              },
-              {
-                "name": "testMixedItemsStatusAfterDeletingStep",
-                "status": "FAILED",
-                "issue": "AUTOMATION_BUG"
-              },
-              {
-                "name": "mixedItemStatus",
-                "status": "FAILED",
-                "issue": "AUTOMATION_BUG"
-              }
-            ]
-          }
-        ]
-      }
-    ]
-  }
\ No newline at end of file
+{
+  "suites": [
+    {
+      "type": "RETRY",
+      "name": "Suite with retries",
+      "status": "FAILED",
+      "tests": [
+        {
+          "name": "First test case",
+          "status": "FAILED",
+          "steps": [
+            {
+              "name": "first test",
+              "status": "FAILED",
+              "issue": "SYSTEM_ISSUE"
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "type": "NESTED",
+      "name": "Suite with nested steps",
+      "status": "FAILED",
+      "tests": [
+        {
+          "name": "History table. Extended functionality. Permissions. Edit defect",
+          "status": "FAILED",
+          "issue": "AUTOMATION_BUG",
+          "steps": [
+            {
+              "name": "Launch was executed 11 times",
+              "status": "PASSED"
+            },
+            {
+              "name": "**Step 1:** Login to https://localhost:8080/ with password *** <br />**Expected Result:** User is in RP",
+              "status": "PASSED"
+            },
+            {
+              "name": "**Step 2:** Open 'All launches' <br />**Expected Result:** All launches page is presented",
+              "status": "PASSED"
+            },
+            {
+              "name": "**Step 3:** Click on Total statistics <br />**Expected Result:** Launch list view is displayed, refines contains criteria **Method type: Test**; **Status: Passed, Failed, Skipped, Interrupted**",
+              "status": "PASSED"
+            },
+            {
+              "name": "**Step 4:** Click on 'History view' icon <br />**Expected Result:** 10 latest executions for the first 20 items (from the latest executions to the eldest) displayed by default**",
+              "status": "PASSED"
+            },
+            {
+              "name": "**Step 5:** Check several items **(own and not own)** <br />**Expected Result:** Items are added to the header",
+              "status": "PASSED"
+            },
+            {
+              "name": "**Step 6:** Click 'Actions'> 'Edit Defects' <br />**Expected Result:** Edit modal for bulk operation is opened",
+              "status": "PASSED"
+            },
+            {
+              "name": "**Step 7:** Update defect type <br />**Expected Result:** Value(s) are in the fields",
+              "status": "PASSED"
+            },
+            {
+              "name": "**Step 8:** Click 'Save'<br />**Expected Result:** Updates are saved for the last launch and all chosen items",
+              "status": "FAILED"
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "type": "DEFAULT",
+      "name": "Filtering Launch Tests",
+      "status": "FAILED",
+      "hasBefore": true,
+      "tests": [
+        {
+          "name": "FilteringLaunchGtePassedTest",
+          "status": "PASSED",
+          "hasBefore": true,
+          "steps": [
+            {
+              "name": "testFilterLaunchGreaterThanEqualsNegativeValue",
+              "status": "PASSED",
+              "hasBefore": true
+            },
+            {
+              "name": "testFilterLaunchGreaterThanEqualsNotNumber",
+              "status": "PASSED",
+              "hasAfter": true
+            },
+            {
+              "name": "testFilterLaunchGreaterThanEqualsPositive",
+              "status": "PASSED"
+            },
+            {
+              "name": "testFilterLaunchGreaterThanEqualsZero",
+              "status": "PASSED"
+            },
+            {
+              "name": "testFilterLaunchLowerThanEqualsNegativeValue",
+              "status": "PASSED"
+            }
+          ]
+        },
+        {
+          "name": "FilteringLaunchInTagsTest",
+          "status": "FAILED",
+          "hasAfter": true,
+          "steps": [
+            {
+              "name": "testFilterPositive",
+              "status": "FAILED",
+              "hasBefore": true,
+              "issue": "SYSTEM_ISSUE"
+            },
+            {
+              "name": "testFilterNegative",
+              "status": "FAILED",
+              "hasAfter": true,
+              "issue": "SYSTEM_ISSUE"
+            },
+            {
+              "name": "testFilterSpecialSymbols",
+              "status": "FAILED",
+              "issue": "SYSTEM_ISSUE"
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "type": "DEFAULT",
+      "name": "Launch Tests",
+      "status": "FAILED",
+      "hasBefore": true,
+      "tests": [
+        {
+          "name": "LaunchStatusTest",
+          "status": "FAILED",
+          "hasBefore": true,
+          "steps": [
+            {
+              "name": "launchMixedItemsStatusText",
+              "status": "SKIPPED",
+              "issue": "PRODUCT_BUG",
+              "hasBefore": true
+            },
+            {
+              "name": "launchStatusTest",
+              "status": "FAILED",
+              "hasAfter": true,
+              "issue": "AUTOMATION_BUG"
+            },
+            {
+              "name": "testLaunchStatusAfterDeletingTest",
+              "status": "FAILED",
+              "issue": "AUTOMATION_BUG"
+            },
+            {
+              "name": "testMixedItemsStatusAfterDeletingStep",
+              "status": "FAILED",
+              "issue": "AUTOMATION_BUG"
+            },
+            {
+              "name": "mixedItemStatus",
+              "status": "FAILED",
+              "issue": "AUTOMATION_BUG"
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/src/main/resources/templates/email/change-password-template.ftl b/src/main/resources/templates/email/change-password-template.ftl
index 84d95445df..a0140181e8 100644
--- a/src/main/resources/templates/email/change-password-template.ftl
+++ b/src/main/resources/templates/email/change-password-template.ftl
@@ -1,146 +1,171 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-    <title>ReportPortal</title>
-    <link href='http://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'>
-    <style>
-        body {
-            margin: 0;
-            padding: 0;
-        }
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+  <title>ReportPortal</title>
+  <link href='http://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'>
+  <style>
+    body {
+      margin: 0;
+      padding: 0;
+    }
 
-        a, a:active, a:visited {
-            color: #39c2d7;
-            text-decoration: underline;
-        }
+    a, a:active, a:visited {
+      color: #39c2d7;
+      text-decoration: underline;
+    }
 
-        a:hover {
-            text-decoration: none;
-        }
+    a:hover {
+      text-decoration: none;
+    }
 
-        .rplogo, .rplogo:hover, .rplogo:active, .rplogo:visited {
-            display: inline-block;
-            text-decoration: none;
-        }
+    .rplogo, .rplogo:hover, .rplogo:active, .rplogo:visited {
+      display: inline-block;
+      text-decoration: none;
+    }
 
-        @media only screen and (max-width: 540px) {
-            body {
-                margin: 0;
-                padding: 0;
-            }
+    @media only screen and (max-width: 540px) {
+      body {
+        margin: 0;
+        padding: 0;
+      }
 
-            table[class="mainwrapper"] {
-                width: 100% !important;
-            }
+      table[class="mainwrapper"] {
+        width: 100% !important;
+      }
 
-            .rplogo {
-                margin-left: 15px;
-            }
+      .rplogo {
+        margin-left: 15px;
+      }
 
-            table[class="mainimgwrapper"] {
-                height: 130px;
-                background-image: url("illustration.png");
-                background-size: cover;
-                background-position: center;
-            }
+      table[class="mainimgwrapper"] {
+        height: 130px;
+        background-image: url("images/illustration.png");
+        background-size: cover;
+        background-position: center;
+      }
 
-            .mainimg {
-                display: none;
-            }
-        }
-    </style>
+      .mainimg {
+        display: none;
+      }
+    }
+  </style>
 </head>
-<body bgcolor="#f9f9f9" topmargin="0" bottommargin="0" leftmargin="0" rightmargin="0" link="#39c2d7" alink="#39c2d7" vlink="#39c2d7"
+<body bgcolor="#f9f9f9" topmargin="0" bottommargin="0" leftmargin="0" rightmargin="0" link="#39c2d7"
+      alink="#39c2d7" vlink="#39c2d7"
       style="font-family: OpenSans, sans-serif;">
 <table width="540" border="0" cellspacing="0" cellpadding="0" align="center" class="mainwrapper">
-    <tbody>
-    <tr>
-        <td>
-            <table width="100%" border="0" cellspacing="0" cellpadding="0" class="logowrapper">
-                <tbody>
-                <tr>
-                    <td height="48">
-                        <a class="rplogo" href="http://reportportal.io" target="_blank"
-                           style="font-size: 15px; color: #595c5c; font-weight: bold; font-family: 'Roboto', sans-serif;">
-                            ReportPortal.io
-                        </a>
-                    </td>
-                </tr>
-                </tbody>
+  <tbody>
+  <tr>
+    <td>
+      <table width="100%" border="0" cellspacing="0" cellpadding="0" class="logowrapper">
+        <tbody>
+        <tr>
+          <td height="48">
+            <a class="rplogo" href="http://reportportal.io" target="_blank"
+               style="font-size: 15px; color: #595c5c; font-weight: bold; font-family: 'Roboto', sans-serif;">
+              ReportPortal.io
+            </a>
+          </td>
+        </tr>
+        </tbody>
+      </table>
+      <table width="100%" border="0" cellspacing="0" cellpadding="0" class="mainimgwrapper">
+        <tbody>
+        <tr>
+          <td height="130">
+            <img class="mainimg" src="cid:illustration.png" border="0" width="540" height="130"
+                 alt="Your password has been changed">
+          </td>
+        </tr>
+        </tbody>
+      </table>
+      <table width="100%" border="0" cellspacing="0" cellpadding="30" class="contentwrapper"
+             bgcolor="#ffffff">
+        <tbody>
+        <tr>
+          <td align="left" height="170">
+            <h2 align="center" style="font-size: 20px; color: #777777;">Your password has been
+              changed</h2>
+            <p style="font-size: 14px; color: #777777">The password for user
+              <b>${user_name}</b> has been successfully changed.</p>
+            <p style="font-size: 14px; color: #777777">If you didn’t change your password,
+              please <a href="mailto:support@reportportal.io?subject=A change password issue">Contact
+                us</a>.</p>
+          </td>
+        </tr>
+        </tbody>
+      </table>
+      <table width="100%" height="82" border="0" cellspacing="0" cellpadding="0"
+             class="linkswrapper">
+        <tbody>
+        <tr>
+          <td height="82" align="center">
+            <table border="0" cellspacing="0" cellpadding="12" class="linksline" align="center">
+              <tbody>
+              <tr>
+                <td>
+                  <p style="font-size: 13px; color: #464547;">Keep in touch with us:</p>
+                </td>
+                <td>
+                  <a href="http://twitter.com/ReportPortal_io" target="_blank">
+                    <img src="cid:ic-twitter.png" alt="twitter">
+                  </a>
+                </td>
+                <td>
+                  <a href="https://slack.epmrpp.reportportal.io" target="_blank">
+                    <img src="cid:ic-slack.png" alt="slack">
+                  </a>
+                </td>
+                <td>
+                  <a href="https://www.youtube.com/c/ReportPortal" target="_blank">
+                    <img src="cid:ic-youtube.png" alt="youtube">
+                  </a>
+                </td>
+                <td>
+                  <a href="https://www.linkedin.com/company/reportportal/" target="_blank">
+                    <img src="cid:ic-linkedin.png" alt="linkedin">
+                  </a>
+                </td>
+                <td>
+                  <a href="https://www.facebook.com/ReportPortal.io" target="_blank">
+                    <img src="cid:ic-facebook.png" alt="facebook">
+                  </a>
+                </td>
+                <td>
+                  <a href="https://github.com/reportportal" target="_blank">
+                    <img src="cid:ic-github.png" alt="github">
+                  </a>
+                </td>
+              </tr>
+              </tbody>
             </table>
-            <table width="100%" border="0" cellspacing="0" cellpadding="0" class="mainimgwrapper">
-                <tbody>
-                <tr>
-                    <td height="130">
-                        <img class="mainimg" src="cid:illustration.png" border="0" width="540" height="130"
-                             alt="Your password has been changed">
-                    </td>
-                </tr>
-                </tbody>
-            </table>
-            <table width="100%" border="0" cellspacing="0" cellpadding="30" class="contentwrapper" bgcolor="#ffffff">
-                <tbody>
-                <tr>
-                    <td align="left" height="170">
-                        <h2 align="center" style="font-size: 20px; color: #777777;">Your password has been changed</h2>
-                        <p style="font-size: 14px; color: #777777">The password for user
-                            <b>${user_name}</b> has been successfully changed.</p>
-                        <p style="font-size: 14px; color: #777777">If you didn’t change your password,
-                            please <a href="mailto:support@reportportal.io?subject=A change password issue">Contact us</a>.</p>
-                    </td>
-                </tr>
-                </tbody>
-            </table>
-            <table width="100%" height="82" border="0" cellspacing="0" cellpadding="0" class="linkswrapper">
-                <tbody>
-                <tr>
-                    <td height="82" align="center">
-                        <table border="0" cellspacing="0" cellpadding="12" class="linksline" align="center">
-                            <tbody>
-                            <tr>
-                                <td><p style="font-size: 13px; color: #464547;">Keep in touch with us:</p></td>
-                                <td><a href="https://github.com/reportportal" target="_blank"><img src="cid:ic-github.png" border="0"
-                                                                                                   width="20" height="21" alt="github"></a>
-                                </td>
-                                <td><a href="http://twitter.com/ReportPortal_io" target="_blank"><img src="cid:ic-twitter.png" border="0"
-                                                                                                      width="20" height="16" alt="twitter"></a>
-                                </td>
-                                <td><a href="https://www.youtube.com/c/ReportPortal" target="_blank"><img src="cid:ic-youtube.png"
-                                                                                                              border="0" width="20"
-                                                                                                              height="15" alt="youtube"></a>
-                                </td>
-                                <td><a href="https://slack.epmrpp.reportportal.io" target="_blank"><img src="cid:ic-slack.png"
-                                                                                                                 border="0" width="18"
-                                                                                                                 height="18"
-                                                                                                                 alt="slack"></a></td>
-                            </tr>
-                            </tbody>
-                        </table>
-                    </td>
-                </tr>
-                </tbody>
-            </table>
-            <table width="100%" border="0" cellspacing="0" cellpadding="0" bgcolor="#bdc7cc" class="footerline">
-                <tbody>
-                <tr>
-                    <td height="1"><!-- --></td>
-                </tr>
-                </tbody>
-            </table>
-            <table width="100%" border="0" cellspacing="0" cellpadding="0" class="footerwrapper">
-                <tbody>
-                <tr>
-                    <td align="center" height="52" class="footercontent">
-                        <p style="font-size: 11px; line-height: 1.5; color: #6d6d6d"><b>ReportPortal Notification Center</b><br>
-                            This notification was created automatically. Please don't reply to this e-mail.</p>
-                    </td>
-                </tr>
-                </tbody>
-            </table>
-        </td>
-    </tr>
-    </tbody>
+          </td>
+        </tr>
+        </tbody>
+      </table>
+      <table width="100%" border="0" cellspacing="0" cellpadding="0" bgcolor="#bdc7cc"
+             class="footerline">
+        <tbody>
+        <tr>
+          <td height="1"><!-- --></td>
+        </tr>
+        </tbody>
+      </table>
+      <table width="100%" border="0" cellspacing="0" cellpadding="0" class="footerwrapper">
+        <tbody>
+        <tr>
+          <td align="center" height="52" class="footercontent">
+            <p style="font-size: 11px; line-height: 1.5; color: #6d6d6d"><b>ReportPortal
+                Notification Center</b><br>
+              This notification was created automatically. Please don't reply to this e-mail.</p>
+          </td>
+        </tr>
+        </tbody>
+      </table>
+    </td>
+  </tr>
+  </tbody>
 </table>
 </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/src/main/resources/templates/email/create-user-template.ftl b/src/main/resources/templates/email/create-user-template.ftl
index 62d3356e4e..36e7199fd8 100644
--- a/src/main/resources/templates/email/create-user-template.ftl
+++ b/src/main/resources/templates/email/create-user-template.ftl
@@ -1,167 +1,195 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-    <title>ReportPortal</title>
-    <link href='http://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'>
-    <style>
-        body {
-            margin: 0;
-            padding: 0;
-        }
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+  <title>ReportPortal</title>
+  <link href='http://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'>
+  <style>
+    body {
+      margin: 0;
+      padding: 0;
+    }
 
-        a, a:active, a:visited {
-            color: #39c2d7;
-            text-decoration: underline;
-        }
+    a, a:active, a:visited {
+      color: #39c2d7;
+      text-decoration: underline;
+    }
 
-        a:hover {
-            text-decoration: none;
-        }
+    a:hover {
+      text-decoration: none;
+    }
 
-        .rplogo, .rplogo:hover, .rplogo:active, .rplogo:visited {
-            display: inline-block;
-            text-decoration: none;
-        }
+    .rplogo, .rplogo:hover, .rplogo:active, .rplogo:visited {
+      display: inline-block;
+      text-decoration: none;
+    }
 
-        @media only screen and (max-width: 540px) {
-            body {
-                margin: 0;
-                padding: 0;
-            }
+    @media only screen and (max-width: 540px) {
+      body {
+        margin: 0;
+        padding: 0;
+      }
 
-            table[class="mainwrapper"] {
-                width: 100% !important;
-            }
+      table[class="mainwrapper"] {
+        width: 100% !important;
+      }
 
-            .rplogo {
-                margin-left: 15px;
-            }
+      .rplogo {
+        margin-left: 15px;
+      }
 
-            table[class="mainimgwrapper"] {
-                height: 130px;
-                background-image: url("create-user.png");
-                background-size: cover;
-                background-position: center;
-            }
+      table[class="mainimgwrapper"] {
+        height: 130px;
+        background-image: url("images/create-user.png");
+        background-size: cover;
+        background-position: center;
+      }
 
-            .mainimg {
-                display: none;
-            }
-        }
-    </style>
+      .mainimg {
+        display: none;
+      }
+    }
+  </style>
 </head>
-<body bgcolor="#f9f9f9" topmargin="0" bottommargin="0" leftmargin="0" rightmargin="0" link="#39c2d7" alink="#39c2d7" vlink="#39c2d7"
+<body bgcolor="#f9f9f9" topmargin="0" bottommargin="0" leftmargin="0" rightmargin="0" link="#39c2d7"
+      alink="#39c2d7" vlink="#39c2d7"
       style="font-family: OpenSans, sans-serif;">
 <table width="540" border="0" cellspacing="0" cellpadding="0" align="center" class="mainwrapper">
-    <tbody>
-    <tr>
-        <td>
-            <table width="100%" border="0" cellspacing="0" cellpadding="0" class="logowrapper">
-                <tbody>
-                <tr>
-                    <td height="48">
-                        <a class="rplogo" href="http://reportportal.io" target="_blank"
-                           style="font-size: 15px; color: #595c5c; font-weight: bold; font-family: 'Roboto', sans-serif;">
-                            ReportPortal.io
-                        </a>
-                    </td>
-                </tr>
-                </tbody>
+  <tbody>
+  <tr>
+    <td>
+      <table width="100%" border="0" cellspacing="0" cellpadding="0" class="logowrapper">
+        <tbody>
+        <tr>
+          <td height="48">
+            <a class="rplogo" href="http://reportportal.io" target="_blank"
+               style="font-size: 15px; color: #595c5c; font-weight: bold; font-family: 'Roboto', sans-serif;">
+              ReportPortal.io
+            </a>
+          </td>
+        </tr>
+        </tbody>
+      </table>
+      <table width="100%" border="0" cellspacing="0" cellpadding="0" class="mainimgwrapper">
+        <tbody>
+        <tr>
+          <td height="130">
+            <img class="mainimg" src="cid:create-user.png" border="0" width="540" height="130"
+                 alt="You have been successfully registered on ReportPortal">
+          </td>
+        </tr>
+        </tbody>
+      </table>
+      <table width="100%" border="0" cellspacing="0" cellpadding="30" class="contentwrapper"
+             bgcolor="#ffffff">
+        <tbody>
+        <tr>
+          <td align="left" height="170">
+            <h2 style="font-size: 20px; color: #777777;" align="center">Welcome to
+              ReportPortal!</h2>
+            <p style="font-size: 14px; color: #777777;">You have been successfully registered on
+              ReportPortal.</p>
+            <p style="font-size: 14px; line-height: 1.7; color: #777777">Please, use the following
+              information to login:<br>
+              Login: <b>${login}</b><br>
+              Password: <b>${password}</b></p>
+            <table border="0" cellspacing="8" cellpadding="0" align="center">
+              <tbody>
+              <tr>
+                <td width="130" height="35" align="center" bgcolor="#a3c644">
+                  <a href="${url}"
+                     style="font-size: 14px; text-decoration: none; color: #ffffff; display: inline-block; padding: 10px 15px; width: 100px;">
+                    Login
+                  </a>
+                </td>
+              </tr>
+              </tbody>
             </table>
-            <table width="100%" border="0" cellspacing="0" cellpadding="0" class="mainimgwrapper">
-                <tbody>
-                <tr>
-                    <td height="130">
-                        <img class="mainimg" src="cid:create-user.png" border="0" width="540" height="130"
-                             alt="You have been successfully registered on ReportPortal">
-                    </td>
-                </tr>
-                </tbody>
+            <p style="font-size: 14px; color: #777777;">New to ReportPortal? Check out the <a
+                  href="https://reportportal.io/docs/reportportal-tutorial/?utm_source=trigger&utm_medium=email&utm_campaign=tutorial&utm_content=invitation"
+                  target="_blank">ReportPortal Tutorial</a>.</p>
+            <br>
+            <p style="font-size: 14px; line-height: 1.7; color: #777777;">Thanks,<br>
+              ReportPortal.io Team</p>
+          </td>
+        </tr>
+        </tbody>
+      </table>
+      <table width="100%" height="82" border="0" cellspacing="0" cellpadding="0"
+             class="linkswrapper">
+        <tbody>
+        <tr>
+          <td height="82" align="center">
+            <table border="0" cellspacing="0" cellpadding="12" class="linksline" align="center">
+              <tbody>
+              <tr>
+                <td>
+                  <p style="font-size: 13px; color: #464547;">Keep in touch with us:</p>
+                </td>
+                <td>
+                  <a href="http://twitter.com/ReportPortal_io" target="_blank">
+                    <img src="cid:ic-twitter.png" alt="twitter">
+                  </a>
+                </td>
+                <td>
+                  <a href="https://slack.epmrpp.reportportal.io" target="_blank">
+                    <img src="cid:ic-slack.png" alt="slack">
+                  </a>
+                </td>
+                <td>
+                  <a href="https://www.youtube.com/c/ReportPortal" target="_blank">
+                    <img src="cid:ic-youtube.png" alt="youtube">
+                  </a>
+                </td>
+                <td>
+                  <a href="https://www.linkedin.com/company/reportportal/" target="_blank">
+                    <img src="cid:ic-linkedin.png" alt="linkedin">
+                  </a>
+                </td>
+                <td>
+                  <a href="https://www.facebook.com/ReportPortal.io" target="_blank">
+                    <img src="cid:ic-facebook.png" alt="facebook">
+                  </a>
+                </td>
+                <td>
+                  <a href="https://github.com/reportportal" target="_blank">
+                    <img src="cid:ic-github.png" alt="github">
+                  </a>
+                </td>
+              </tr>
+              </tbody>
             </table>
-            <table width="100%" border="0" cellspacing="0" cellpadding="30" class="contentwrapper" bgcolor="#ffffff">
-                <tbody>
-                <tr>
-                    <td align="left" height="170">
-                        <h2 style="font-size: 20px; color: #777777;" align="center">Welcome to ReportPortal!</h2>
-                        <p style="font-size: 14px; color: #777777;">You have been successfully registered on ReportPortal.</p>
-                        <p style="font-size: 14px; line-height: 1.7; color: #777777">Please, use the following information to login:<br>
-                            Login: <b>${login}</b><br>
-                            Password: <b>${password}</b></p>
-                        <table border="0" cellspacing="8" cellpadding="0" align="center">
-                            <tbody>
-                            <tr>
-                                <td width="130" height="35" align="center" bgcolor="#a3c644">
-                                    <a href="${url}"
-                                       style="font-size: 14px; text-decoration: none; color: #ffffff; display: inline-block; padding: 10px 15px; width: 100px;">
-                                        Login
-                                    </a>
-                                </td>
-                            </tr>
-                            </tbody>
-                        </table>
-                        <p style="font-size: 14px; color: #777777;">New to ReportPortal? Check out the <a
-                                href="https://reportportal.io/docs/reportportal-tutorial/?utm_source=trigger&utm_medium=email&utm_campaign=tutorial&utm_content=invitation" target="_blank">ReportPortal Tutorial</a>.</p>
-                        <br>
-                        <p style="font-size: 14px; line-height: 1.7; color: #777777;">Thanks,<br>
-                            ReportPortal.io Team</p>
-                    </td>
-                </tr>
-                </tbody>
-            </table>
-            <table width="100%" height="82" border="0" cellspacing="0" cellpadding="0" class="linkswrapper">
-                <tbody>
-                <tr>
-                    <td height="82" align="center">
-                        <table border="0" cellspacing="0" cellpadding="12" class="linksline" align="center">
-                            <tbody>
-                            <tr>
-                                <td><p style="font-size: 13px; color: #464547;">Keep in touch with us:</p></td>
-                                <td><a href="https://github.com/reportportal" target="_blank"><img src="cid:ic-github.png" border="0"
-                                                                                                   width="20" height="21" alt="github"></a>
-                                </td>
-                                <td><a href="http://twitter.com/ReportPortal_io" target="_blank"><img src="cid:ic-twitter.png" border="0"
-                                                                                                      width="20" height="16" alt="twitter"></a>
-                                </td>
-                                <td><a href="https://www.youtube.com/c/ReportPortal" target="_blank"><img src="cid:ic-youtube.png"
-                                                                                                              border="0" width="20"
-                                                                                                              height="15" alt="youtube"></a>
-                                </td>
-                                <td><a href="https://slack.epmrpp.reportportal.io" target="_blank"><img src="cid:ic-slack.png"
-                                                                                                                 border="0" width="18"
-                                                                                                                 height="18"
-                                                                                                                 alt="slack"></a></td>
-                            </tr>
-                            </tbody>
-                        </table>
-                    </td>
-                </tr>
-                </tbody>
-            </table>
-            <table width="100%" border="0" cellspacing="0" cellpadding="0" bgcolor="#bdc7cc" class="footerline">
-                <tbody>
-                <tr>
-                    <td height="1"><!-- --></td>
-                </tr>
-                </tbody>
-            </table>
-            <table width="100%" border="0" cellspacing="0" cellpadding="0" class="footerwrapper">
-                <tbody>
-                <tr>
-                    <td align="center" height="85" class="footercontent" style="padding: 4px;">
-                        <p style="font-size: 11px; line-height: 1.5; color: #6d6d6d">
-                            <b>ReportPortal Notification Center</b><br>
-                            This is an automatically generated notification - please do not reply to this message. You are receiving this
-                            email to complete the registration initiated on the ReportPortal application; if you are not waiting
-                            for the ReportPortal's invitation then just ignore this message.
-                        </p>
-                    </td>
-                </tr>
-                </tbody>
-            </table>
-        </td>
-    </tr>
-    </tbody>
+          </td>
+        </tr>
+        </tbody>
+      </table>
+      <table width="100%" border="0" cellspacing="0" cellpadding="0" bgcolor="#bdc7cc"
+             class="footerline">
+        <tbody>
+        <tr>
+          <td height="1"><!-- --></td>
+        </tr>
+        </tbody>
+      </table>
+      <table width="100%" border="0" cellspacing="0" cellpadding="0" class="footerwrapper">
+        <tbody>
+        <tr>
+          <td align="center" height="85" class="footercontent" style="padding: 4px;">
+            <p style="font-size: 11px; line-height: 1.5; color: #6d6d6d">
+              <b>ReportPortal Notification Center</b><br>
+              This is an automatically generated notification - please do not reply to this message.
+              You are receiving this
+              email to complete the registration initiated on the ReportPortal application; if you
+              are not waiting
+              for the ReportPortal's invitation then just ignore this message.
+            </p>
+          </td>
+        </tr>
+        </tbody>
+      </table>
+    </td>
+  </tr>
+  </tbody>
 </table>
 </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/src/main/resources/templates/email/delete-account-notification-template.ftl b/src/main/resources/templates/email/delete-account-notification-template.ftl
index 1f6f33f36d..a156437854 100644
--- a/src/main/resources/templates/email/delete-account-notification-template.ftl
+++ b/src/main/resources/templates/email/delete-account-notification-template.ftl
@@ -1,75 +1,81 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
-  <head>
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-    <!-- [if mso ]>
-    <xml
-      ><o:OfficeDocumentSettings
-        ><o:PixelsPerInch>96</o:PixelsPerInch
-        ><o:AllowPNG /></o:OfficeDocumentSettings
-    ></xml>
-    <![endif] -->
-    <link
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+  <!-- [if mso ]>
+  <xml
+  >
+    <o:OfficeDocumentSettings
+    >
+      <o:PixelsPerInch>96
+      </o:PixelsPerInch
+      >
+      <o:AllowPNG/>
+    </o:OfficeDocumentSettings
+    >
+  </xml>
+  <![endif] -->
+  <link
       href="http://fonts.googleapis.com/css?family=Roboto:wght@100;400;500;&display=swap"
       rel="stylesheet"
       type="text/css"
-    />
-    <style>
-      .heading {
-        font-family: Arial, Helvetica, sans-serif;
-        margin-top: 0;
-        margin-bottom: 0;
-        color: #454a4f;
-        font-size: 36px;
-        font-style: normal;
-        font-weight: 700;
-        line-height: 48px;
-        text-align: left;
-      }
+  />
+  <style>
+    .heading {
+      font-family: Arial, Helvetica, sans-serif;
+      margin-top: 0;
+      margin-bottom: 0;
+      color: #454a4f;
+      font-size: 36px;
+      font-style: normal;
+      font-weight: 700;
+      line-height: 48px;
+      text-align: left;
+    }
 
-      .main-content {
-        margin-top: 0;
-        margin-bottom: 0;
-        margin-left: 0;
-        margin-right: 0;
-        font-family: Arial, Helvetica, sans-serif;
-        color: #545454;
-        font-size: 14px;
-        font-style: normal;
-        font-weight: 400;
-        line-height: 22px;
-      }
+    .main-content {
+      margin-top: 0;
+      margin-bottom: 0;
+      margin-left: 0;
+      margin-right: 0;
+      font-family: Arial, Helvetica, sans-serif;
+      color: #545454;
+      font-size: 14px;
+      font-style: normal;
+      font-weight: 400;
+      line-height: 22px;
+    }
 
-      .footer-content-heading {
-        margin-top: 0;
-        margin-bottom: 0;
-        margin-left: 0;
-        margin-right: 0;
-        color: #a2aab5;
-        font-family: 'Roboto', sans-serif;
-        font-size: 13px;
-        font-style: normal;
-        font-weight: 500;
-        line-height: 20px;
-      }
+    .footer-content-heading {
+      margin-top: 0;
+      margin-bottom: 0;
+      margin-left: 0;
+      margin-right: 0;
+      color: #a2aab5;
+      font-family: 'Roboto', sans-serif;
+      font-size: 13px;
+      font-style: normal;
+      font-weight: 500;
+      line-height: 20px;
+    }
 
-      .footer-content {
-        margin-top: 0;
-        margin-bottom: 0;
-        margin-left: 0;
-        margin-right: 0;
-        color: #a2aab5;
-        font-family: 'Roboto', sans-serif;
-        font-size: 11px;
-        font-style: normal;
-        font-weight: 400;
-        line-height: 16px;
-      }
-    </style>
+    .footer-content {
+      margin-top: 0;
+      margin-bottom: 0;
+      margin-left: 0;
+      margin-right: 0;
+      color: #a2aab5;
+      font-family: 'Roboto', sans-serif;
+      font-size: 11px;
+      font-style: normal;
+      font-weight: 400;
+      line-height: 16px;
+    }
+  </style>
 
-    <title>Report Portal</title>
-  </head>
-  <body
+  <title>Report Portal</title>
+</head>
+<body
     style="
       font-family: Arial, Helvetica, sans-serif;
       margin-top: 0;
@@ -81,217 +87,219 @@
       padding-top: 0;
       padding-bottom: 0px;
     "
+>
+<center>
+  <table
+      width="630"
+      border="0"
+      cellspacing="0"
+      cellpadding="0"
+      align="center"
   >
-    <center>
-      <table
-        width="630"
-        border="0"
-        cellspacing="0"
-        cellpadding="0"
-        align="center"
-      >
-        <tbody>
+    <tbody>
+    <tr>
+      <td>
+        <table
+            width="100%"
+            border="0"
+            cellspacing="0"
+            cellpadding="0"
+            bgcolor="#f4fbfb"
+        >
+          <tbody>
           <tr>
-            <td>
-              <table
-                width="100%"
-                border="0"
-                cellspacing="0"
-                cellpadding="0"
-                bgcolor="#f4fbfb"
-              >
-                <tbody>
-                  <tr>
-                    <td align="center" style="padding-top: 48px">
-                      <a
-                        href="http://reportportal.io"
-                        target="_blank"
-                        rel="noopener noreferrer"
-                        ><img src="cid:new-logo.png" alt="Report Portal logo"
-                      /></a>
-                    </td>
-                  </tr>
-                  <tr>
-                    <td
-                      align="center"
-                      style="
+            <td align="center" style="padding-top: 48px">
+              <a
+                  href="http://reportportal.io"
+                  target="_blank"
+                  rel="noopener noreferrer"
+              ><img src="cid:new-logo.png" alt="Report Portal logo"
+                /></a>
+            </td>
+          </tr>
+          <tr>
+            <td
+                align="center"
+                style="
                         padding-top: 37px;
                         padding-bottom: 38px;
                         background-color: rgb(244, 251, 251);
                         border-spacing: 0;
                       "
-                    >
-                      <img
-                        src="cid:delete-account-notification.png"
-                        alt="Calendar"
-                      />
-                    </td>
-                  </tr>
-                </tbody>
-              </table>
+            >
+              <img
+                  src="cid:delete-account-notification.png"
+                  alt="Calendar"
+              />
             </td>
           </tr>
-          <tr>
-            <td
-              align="center"
-              style="
+          </tbody>
+        </table>
+      </td>
+    </tr>
+    <tr>
+      <td
+          align="center"
+          style="
                 padding-left: 50px;
                 padding-right: 50px;
                 padding-bottom: 40px;
                 padding-top: 32px;
                 background-color: #ffffff;
               "
-            >
-              <table width="100%" border="0" cellspacing="0" cellpadding="0">
-                <thead>
-                  <th>
-                    <h1 class="heading">
-                      Your account will be <br />
-                      deleted soon
-                    </h1>
-                  </th>
-                </thead>
-                <tbody>
-                  <tr>
-                    <td style="padding-bottom: 12px; padding-top: 24px">
-                      <p class="main-content">
-                        We are writing to inform you that according to our data
-                        retention procedure your account and all your personal
-                        data (your account name, email and photo) will be
-                        deleted from ReportPortal database
-                        <b>${remainingTime}</b>. As it has already been inactive
-                        for ${inactivityPeriod}.
-                      </p>
-                    </td>
-                  </tr>
-                  <tr>
-                    <td style="padding-bottom: 12px">
-                      <p class="main-content">
-                        If you would like to keep your account, please log in to
-                        our platform ${deadlineDate} and your
-                        account will not be deleted. If you do not log in before
-                        this date, your account and all associated data will be
-                        erased from our platform, while all the previously
-                        reported and created in ReportPortal data (launches,
-                        filters, widgets, dashboards, etc.) will remain in the
-                        app.
-                      </p>
-                    </td>
-                  </tr>
-                  <tr>
-                    <td style="padding-bottom: 12px">
-                      <p class="main-content">
-                        If you have any questions or concerns about this
-                        process, please contact our support team for assistance.
-                      </p>
-                    </td>
-                  </tr>
-                  <tr>
-                    <td>
-                      <p class="main-content">
-                        <br>Kind regards,<br>ReportPortal team
-                      </p>
-                    </td>
-                  </tr>
-                </tbody>
-              </table>
+      >
+        <table width="100%" border="0" cellspacing="0" cellpadding="0">
+          <thead>
+          <th>
+            <h1 class="heading">
+              Your account will be <br/>
+              deleted soon
+            </h1>
+          </th>
+          </thead>
+          <tbody>
+          <tr>
+            <td style="padding-bottom: 12px; padding-top: 24px">
+              <p class="main-content">
+                We are writing to inform you that according to our data
+                retention procedure your account and all your personal
+                data (your account name, email and photo) will be
+                deleted from ReportPortal database
+                <b>${remainingTime}</b>. As it has already been inactive
+                for ${inactivityPeriod}.
+              </p>
             </td>
           </tr>
           <tr>
-            <td align="center">
+            <td style="padding-bottom: 12px">
+              <p class="main-content">
+                If you would like to keep your account, please log in to
+                our platform ${deadlineDate} and your
+                account will not be deleted. If you do not log in before
+                this date, your account and all associated data will be
+                erased from our platform, while all the previously
+                reported and created in ReportPortal data (launches,
+                filters, widgets, dashboards, etc.) will remain in the
+                app.
+              </p>
+            </td>
+          </tr>
+          <tr>
+            <td style="padding-bottom: 12px">
+              <p class="main-content">
+                If you have any questions or concerns about this
+                process, please contact our support team for assistance.
+              </p>
+            </td>
+          </tr>
+          <tr>
+            <td>
+              <p class="main-content">
+                <br>Kind regards,<br>ReportPortal team
+              </p>
+            </td>
+          </tr>
+          </tbody>
+        </table>
+      </td>
+    </tr>
+    <tr>
+      <td align="center">
+        <table
+            width="100%"
+            border="0"
+            cellspacing="0"
+            cellpadding="0"
+            bgcolor="#f4fbfb"
+        >
+          <tbody>
+          <tr>
+            <td align="center"
+                style="padding-top: 32px;
+                padding-bottom: 24px">
               <table
-                width="100%"
-                border="0"
-                cellspacing="0"
-                cellpadding="0"
-                bgcolor="#f4fbfb"
+                  border="0"
+                  cellspacing="0"
+                  cellpadding="0"
+                  bgcolor="#f4fbfb"
               >
-                <tbody>
-                  <tr>
-                    <td
-                      align="center"
-                      style="padding-top: 32px; padding-bottom: 24px"
+                <tr>
+                  <td style="padding-right: 22px">
+                    <a href="https://twitter.com/i/flow/login?redirect_after_login=%2FReportPortal_io"
+                       target="_blank"
+                       rel="noopener noreferrer">
+                      <img src="cid:new-ic-twitter.png"
+                           alt="Twitter icon"
+                      />
+                    </a>
+                  </td>
+                  <td style="padding-right: 22px">
+                    <a href="https://slack.epmrpp.reportportal.io/"
+                       target="_blank"
+                       rel="noopener noreferrer"
+                    >
+                      <img src="cid:new-ic-slack.png"
+                           alt="Slack icon"/>
+                    </a>
+                  </td>
+                  <td style="padding-right: 22px">
+                    <a href="https://www.youtube.com/c/ReportPortal"
+                       target="_blank"
+                       rel="noopener noreferrer"
                     >
-                      <table
-                        border="0"
-                        cellspacing="0"
-                        cellpadding="0"
-                        bgcolor="#f4fbfb"
-                      >
-                        <tr>
-                          <td style="padding-right: 22px">
-                            <a
-                              href="https://twitter.com/i/flow/login?redirect_after_login=%2FReportPortal_io"
-                              target="_blank"
-                              rel="noopener noreferrer"
-                              ><img
-                                src="cid:new-ic-twitter.png"
-                                alt="Twitter icon"
-                            /></a>
-                          </td>
-                          <td style="padding-right: 22px">
-                            <a
-                              href="https://slack.epmrpp.reportportal.io/"
-                              target="_blank"
-                              rel="noopener noreferrer"
-                              ><img src="cid:new-ic-slack.png" alt="Slack icon"
-                            /></a>
-                          </td>
-                          <td style="padding-right: 22px">
-                            <a
-                              href="https://www.youtube.com/c/ReportPortal"
-                              target="_blank"
-                              rel="noopener noreferrer"
-                              ><img
-                                src="cid:new-ic-youtube.png"
-                                alt="YouTube icon"
-                            /></a>
-                          </td>
-                          <td style="padding-right: 10px">
-                            <a
-                              href="https://www.linkedin.com/company/reportportal/"
-                              target="_blank"
-                              rel="noopener noreferrer"
-                              ><img
-                                src="cid:new-ic-linkedin.png"
-                                alt="Linkedin icon"
-                            /></a>
-                          </td>
-                          <td>
-                            <a
-                              href="https://github.com/reportportal"
-                              target="_blank"
-                              rel="noopener noreferrer"
-                              ><img
-                                src="cid:new-ic-github.png"
-                                alt="Github icon"
-                            /></a>
-                          </td>
-                        </tr>
-                      </table>
-                    </td>
-                  </tr>
-                  <tr>
-                    <td align="center">
-                      <h4 class="footer-content-heading">
-                        ReportPortal Notification Center
-                      </h4>
-                    </td>
-                  </tr>
-                  <tr>
-                    <td align="center" style="padding-bottom: 32px">
-                      <p class="footer-content">
-                        This notification was created automatically. Please
-                        don't reply to this e-mail.
-                      </p>
-                    </td>
-                  </tr>
-                </tbody>
+                      <img src="cid:new-ic-youtube.png"
+                           alt="YouTube icon">
+                    </a>
+                  </td>
+                  <td style="padding-right: 22px">
+                    <a href="https://www.linkedin.com/company/reportportal/"
+                       target="_blank"
+                       rel="noopener noreferrer">
+                      <img src="cid:new-ic-linkedin.png"
+                           alt="Linkedin icon">
+                    </a>
+                  </td>
+                  <td style="padding-right: 22px">
+                    <a href="https://www.facebook.com/ReportPortal.io"
+                       target="_blank"
+                       rel="noopener noreferrer">
+                      <img src="cid:new-ic-facebook.png"
+                           alt="Facebook icon">
+                    </a>
+                  </td>
+                  <td>
+                    <a href="https://github.com/reportportal"
+                       target="_blank"
+                       rel="noopener noreferrer">
+                      <img src="cid:new-ic-github.png"
+                           alt="Github icon">
+                    </a>
+                  </td>
+                </tr>
               </table>
             </td>
           </tr>
-        </tbody>
-      </table>
-    </center>
-  </body>
+          <tr>
+            <td align="center">
+              <h4 class="footer-content-heading">
+                ReportPortal Notification Center
+              </h4>
+            </td>
+          </tr>
+          <tr>
+            <td align="center" style="padding-bottom: 32px">
+              <p class="footer-content">
+                This notification was created automatically. Please
+                don't reply to this e-mail.
+              </p>
+            </td>
+          </tr>
+          </tbody>
+        </table>
+      </td>
+    </tr>
+    </tbody>
+  </table>
+</center>
+</body>
 </html>
diff --git a/src/main/resources/templates/email/delete-account-template.ftl b/src/main/resources/templates/email/delete-account-template.ftl
index 0a9e8308e7..efeadaf7dd 100644
--- a/src/main/resources/templates/email/delete-account-template.ftl
+++ b/src/main/resources/templates/email/delete-account-template.ftl
@@ -1,73 +1,80 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
-  <head>
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-    <link
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+  <link
       href="http://fonts.googleapis.com/css?family=Roboto:wght@100;400;500;&display=swap"
       rel="stylesheet"
       type="text/css"
-    />
-    <!--[if mso
-      ]><xml
-        ><o:OfficeDocumentSettings
-          ><o:PixelsPerInch>96</o:PixelsPerInch
-          ><o:AllowPNG /></o:OfficeDocumentSettings></xml
-    ><![endif]-->
-    <style>
-      .heading {
-        font-family: Arial, Helvetica, sans-serif;
-        margin-top: 0;
-        margin-bottom: 0;
-        color: #454a4f;
-        font-size: 36px;
-        font-style: normal;
-        font-weight: 700;
-        line-height: 48px;
-      }
+  />
+  <!--[if mso
+      ]>
+  <xml
+  >
+    <o:OfficeDocumentSettings
+    >
+      <o:PixelsPerInch>96
+      </o:PixelsPerInch
+      >
+      <o:AllowPNG/>
+    </o:OfficeDocumentSettings>
+  </xml
+  ><![endif]-->
+  <style>
+    .heading {
+      font-family: Arial, Helvetica, sans-serif;
+      margin-top: 0;
+      margin-bottom: 0;
+      color: #454a4f;
+      font-size: 36px;
+      font-style: normal;
+      font-weight: 700;
+      line-height: 48px;
+    }
 
-      .main-content {
-        margin-top: 0;
-        margin-bottom: 0;
-        margin-left: 0;
-        margin-right: 0;
-        font-family: Arial, Helvetica, sans-serif;
-        color: #545454;
-        font-size: 14px;
-        font-style: normal;
-        font-weight: 400;
-        line-height: 22px;
-      }
+    .main-content {
+      margin-top: 0;
+      margin-bottom: 0;
+      margin-left: 0;
+      margin-right: 0;
+      font-family: Arial, Helvetica, sans-serif;
+      color: #545454;
+      font-size: 14px;
+      font-style: normal;
+      font-weight: 400;
+      line-height: 22px;
+    }
 
-      .footer-content-heading {
-        margin-top: 0;
-        margin-bottom: 0;
-        margin-left: 0;
-        margin-right: 0;
-        color: #a2aab5;
-        font-family: 'Roboto', sans-serif;
-        font-size: 13px;
-        font-style: normal;
-        font-weight: 500;
-        line-height: 20px;
-      }
+    .footer-content-heading {
+      margin-top: 0;
+      margin-bottom: 0;
+      margin-left: 0;
+      margin-right: 0;
+      color: #a2aab5;
+      font-family: 'Roboto', sans-serif;
+      font-size: 13px;
+      font-style: normal;
+      font-weight: 500;
+      line-height: 20px;
+    }
 
-      .footer-content {
-        margin-top: 0;
-        margin-bottom: 0;
-        margin-left: 0;
-        margin-right: 0;
-        color: #a2aab5;
-        font-family: 'Roboto', sans-serif;
-        font-size: 11px;
-        font-style: normal;
-        font-weight: 400;
-        line-height: 16px;
-      }
-    </style>
+    .footer-content {
+      margin-top: 0;
+      margin-bottom: 0;
+      margin-left: 0;
+      margin-right: 0;
+      color: #a2aab5;
+      font-family: 'Roboto', sans-serif;
+      font-size: 11px;
+      font-style: normal;
+      font-weight: 400;
+      line-height: 16px;
+    }
+  </style>
 
-    <title>Report Portal</title>
-  </head>
-  <body
+  <title>Report Portal</title>
+</head>
+<body
     style="
       font-family: Arial, Helvetica, sans-serif;
       margin-top: 0;
@@ -79,212 +86,213 @@
       padding-top: 0;
       padding-bottom: 0px;
     "
+>
+<center>
+  <table
+      width="630"
+      border="0"
+      cellspacing="0"
+      cellpadding="0"
+      align="center"
   >
-    <center>
-      <table
-        width="630"
-        border="0"
-        cellspacing="0"
-        cellpadding="0"
-        align="center"
-      >
-        <tbody>
+    <tbody>
+    <tr>
+      <td>
+        <table
+            width="100%"
+            border="0"
+            cellspacing="0"
+            cellpadding="0"
+            bgcolor="#f4fbfb"
+        >
+          <tbody>
           <tr>
-            <td>
-              <table
-                width="100%"
-                border="0"
-                cellspacing="0"
-                cellpadding="0"
-                bgcolor="#f4fbfb"
-              >
-                <tbody>
-                  <tr>
-                    <td align="center" style="padding-top: 48px">
-                      <a
-                        href="http://reportportal.io"
-                        target="_blank"
-                        rel="noopener noreferrer"
-                        ><img src="cid:new-logo.png" alt="Report Portal logo"
-                      /></a>
-                    </td>
-                  </tr>
-                  <tr>
-                    <td
-                      align="center"
-                      style="
+            <td align="center" style="padding-top: 48px">
+              <a
+                  href="http://reportportal.io"
+                  target="_blank"
+                  rel="noopener noreferrer"
+              ><img src="cid:new-logo.png" alt="Report Portal logo"
+                /></a>
+            </td>
+          </tr>
+          <tr>
+            <td
+                align="center"
+                style="
                         padding-top: 37px;
                         padding-bottom: 38px;
                         background-color: rgb(244, 251, 251);
                         border-spacing: 0;
                       "
-                    >
-                      <img
-                        src="cid:deleted-account.png"
-                        alt="Deleted account img"
-                      />
-                    </td>
-                  </tr>
-                </tbody>
-              </table>
+            >
+              <img
+                  src="cid:deleted-account.png"
+                  alt="Deleted account img"
+              />
             </td>
           </tr>
-          <tr>
-            <td
-              align="center"
-              style="
+          </tbody>
+        </table>
+      </td>
+    </tr>
+    <tr>
+      <td
+          align="center"
+          style="
                 padding-left: 50px;
                 padding-right: 50px;
                 padding-bottom: 40px;
                 padding-top: 38px;
                 background-color: #ffffff;
               "
-            >
-              <table width="100%" border="0" cellspacing="0" cellpadding="0">
-                <thead>
-                  <th>
-                    <h1 class="heading">Your account has been deleted</h1>
-                  </th>
-                </thead>
-                <tbody>
-                  <tr>
-                    <td style="padding-bottom: 12px; padding-top: 24px">
-                      <p class="main-content">
-                        We regret to inform you that your account has been
-                        deleted.
-                      </p>
-                    </td>
-                  </tr>
-                  <tr>
-                    <td style="padding-bottom: 12px">
-                      <p class="main-content">
-                        Please note that all the associated personal data has
-                        been deleted from our database in a safe and secure
-                        manner.
-                      </p>
-                    </td>
-                  </tr>
-                  <tr>
-                    <td style="padding-bottom: 12px">
-                      <p class="main-content">
-                        If you have any questions or concerns about this
-                        process, please contact our support team for assistance.
-                      </p>
-                    </td>
-                  </tr>
-                  <tr>
-                    <td style="padding-bottom: 12px">
-                      <p class="main-content">
-                        Thank you for using ReportPortal.
-                      </p>
-                    </td>
-                  </tr>
-                  <tr>
-                    <td>
-                      <p class="main-content">
-                        <br>Kind regards,<br>ReportPortal team
-                      </p>
-                    </td>
-                  </tr>
-                </tbody>
-              </table>
+      >
+        <table width="100%" border="0" cellspacing="0" cellpadding="0">
+          <thead>
+          <th>
+            <h1 class="heading">Your account has been deleted</h1>
+          </th>
+          </thead>
+          <tbody>
+          <tr>
+            <td style="padding-bottom: 12px; padding-top: 24px">
+              <p class="main-content">
+                We regret to inform you that your account has been
+                deleted.
+              </p>
             </td>
           </tr>
           <tr>
-            <td align="center">
+            <td style="padding-bottom: 12px">
+              <p class="main-content">
+                Please note that all the associated personal data has
+                been deleted from our database in a safe and secure
+                manner.
+              </p>
+            </td>
+          </tr>
+          <tr>
+            <td style="padding-bottom: 12px">
+              <p class="main-content">
+                If you have any questions or concerns about this
+                process, please contact our support team for assistance.
+              </p>
+            </td>
+          </tr>
+          <tr>
+            <td style="padding-bottom: 12px">
+              <p class="main-content">
+                Thank you for using ReportPortal.
+              </p>
+            </td>
+          </tr>
+          <tr>
+            <td>
+              <p class="main-content">
+                <br>Kind regards,<br>ReportPortal team
+              </p>
+            </td>
+          </tr>
+          </tbody>
+        </table>
+      </td>
+    </tr>
+    <tr>
+      <td align="center">
+        <table
+            width="100%"
+            border="0"
+            cellspacing="0"
+            cellpadding="0"
+            bgcolor="#f4fbfb"
+        >
+          <tbody>
+          <tr>
+            <td
+                align="center"
+                style="padding-top: 32px; padding-bottom: 24px"
+            >
               <table
-                width="100%"
-                border="0"
-                cellspacing="0"
-                cellpadding="0"
-                bgcolor="#f4fbfb"
+                  border="0"
+                  cellspacing="0"
+                  cellpadding="0"
+                  bgcolor="#f4fbfb"
               >
-                <tbody>
-                  <tr>
-                    <td
-                      align="center"
-                      style="padding-top: 32px; padding-bottom: 24px"
-                    >
-                      <table
-                        border="0"
-                        cellspacing="0"
-                        cellpadding="0"
-                        bgcolor="#f4fbfb"
-                      >
-                        <tr>
-                          <td style="padding-right: 22px">
-                            <a
-                              href="https://twitter.com/i/flow/login?redirect_after_login=%2FReportPortal_io"
-                              target="_blank"
-                              rel="noopener noreferrer"
-                              ><img
-                                src="cid:new-ic-twitter.png"
-                                alt="Twitter icon"
-                            /></a>
-                          </td>
-                          <td style="padding-right: 22px">
-                            <a
-                              href="https://slack.epmrpp.reportportal.io/"
-                              target="_blank"
-                              rel="noopener noreferrer"
-                              ><img src="cid:new-ic-slack.png" alt="Slack icon"
-                            /></a>
-                          </td>
-                          <td style="padding-right: 22px">
-                            <a
-                              href="https://www.youtube.com/c/ReportPortal"
-                              target="_blank"
-                              rel="noopener noreferrer"
-                              ><img
-                                src="cid:new-ic-youtube.png"
-                                alt="YouTube icon"
-                            /></a>
-                          </td>
-                          <td style="padding-right: 10px">
-                            <a
-                              href="https://www.linkedin.com/company/reportportal/"
-                              target="_blank"
-                              rel="noopener noreferrer"
-                              ><img
-                                src="cid:new-ic-linkedin.png"
-                                alt="Linkedin icon"
-                            /></a>
-                          </td>
-                          <td>
-                            <a
-                              href="https://github.com/reportportal"
-                              target="_blank"
-                              rel="noopener noreferrer"
-                              ><img
-                                src="cid:new-ic-github.png"
-                                alt="Github icon"
-                            /></a>
-                          </td>
-                        </tr>
-                      </table>
-                    </td>
-                  </tr>
-                  <tr>
-                    <td align="center">
-                      <h4 class="footer-content-heading">
-                        ReportPortal Notification Center
-                      </h4>
-                    </td>
-                  </tr>
-                  <tr>
-                    <td align="center" style="padding-bottom: 32px">
-                      <p class="footer-content">
-                        This notification was created automatically. Please
-                        don't reply to this e-mail.
-                      </p>
-                    </td>
-                  </tr>
-                </tbody>
+                <tr>
+                  <td style="padding-right: 22px">
+                    <a
+                        href="https://twitter.com/i/flow/login?redirect_after_login=%2FReportPortal_io"
+                        target="_blank"
+                        rel="noopener noreferrer">
+                      <img src="cid:new-ic-twitter.png"
+                           alt="Twitter icon">
+                    </a>
+                  </td>
+                  <td style="padding-right: 22px">
+                    <a href="https://slack.epmrpp.reportportal.io/"
+                       target="_blank"
+                       rel="noopener noreferrer">
+                      <img src="cid:new-ic-slack.png"
+                           alt="Slack icon">
+                    </a>
+                  </td>
+                  <td style="padding-right: 22px">
+                    <a href="https://www.youtube.com/c/ReportPortal"
+                       target="_blank"
+                       rel="noopener noreferrer">
+                      <img src="cid:new-ic-youtube.png"
+                           alt="YouTube icon">
+                    </a>
+                  </td>
+                  <td style="padding-right: 22px">
+                    <a href="https://www.linkedin.com/company/reportportal/"
+                       target="_blank"
+                       rel="noopener noreferrer">
+                      <img src="cid:new-ic-linkedin.png"
+                           alt="Linkedin icon">
+                    </a>
+                  </td>
+                  <td style="padding-right: 22px">
+                    <a href="https://www.facebook.com/ReportPortal.io"
+                       target="_blank"
+                       rel="noopener noreferrer">
+                      <img src="cid:new-ic-facebook.png"
+                           alt="Facebook icon">
+                    </a>
+                  </td>
+                  <td>
+                    <a href="https://github.com/reportportal"
+                       target="_blank"
+                       rel="noopener noreferrer">
+                      <img src="cid:new-ic-github.png"
+                           alt="Github icon">
+                    </a>
+                  </td>
+                </tr>
               </table>
             </td>
           </tr>
-        </tbody>
-      </table>
-    </center>
-  </body>
+          <tr>
+            <td align="center">
+              <h4 class="footer-content-heading">
+                ReportPortal Notification Center
+              </h4>
+            </td>
+          </tr>
+          <tr>
+            <td align="center" style="padding-bottom: 32px">
+              <p class="footer-content">
+                This notification was created automatically. Please
+                don't reply to this e-mail.
+              </p>
+            </td>
+          </tr>
+          </tbody>
+        </table>
+      </td>
+    </tr>
+    </tbody>
+  </table>
+</center>
+</body>
 </html>
diff --git a/src/main/resources/templates/email/email-connection.ftl b/src/main/resources/templates/email/email-connection.ftl
index da90d0c4b4..9290534e47 100644
--- a/src/main/resources/templates/email/email-connection.ftl
+++ b/src/main/resources/templates/email/email-connection.ftl
@@ -1,134 +1,156 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-    <title>ReportPortal</title>
-    <link href='http://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'>
-    <style>
-        body {
-            margin: 0;
-            padding: 0;
-        }
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+  <title>ReportPortal</title>
+  <link href='http://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'>
+  <style>
+    body {
+      margin: 0;
+      padding: 0;
+    }
 
-        a, a:active, a:visited {
-            color: #39c2d7;
-            text-decoration: underline;
-        }
+    a, a:active, a:visited {
+      color: #39c2d7;
+      text-decoration: underline;
+    }
 
-        a:hover {
-            text-decoration: none;
-        }
+    a:hover {
+      text-decoration: none;
+    }
 
-        .rplogo, .rplogo:hover, .rplogo:active, .rplogo:visited {
-            display: inline-block;
-            text-decoration: none;
-        }
+    .rplogo, .rplogo:hover, .rplogo:active, .rplogo:visited {
+      display: inline-block;
+      text-decoration: none;
+    }
 
-        @media only screen and (max-width: 540px) {
-            body {
-                margin: 0;
-                padding: 0;
-            }
+    @media only screen and (max-width: 540px) {
+      body {
+        margin: 0;
+        padding: 0;
+      }
 
-            table[class="mainwrapper"] {
-                width: 100% !important;
-            }
+      table[class="mainwrapper"] {
+        width: 100% !important;
+      }
 
-            .rplogo {
-                margin-left: 15px;
-            }
+      .rplogo {
+        margin-left: 15px;
+      }
 
-            table[class="mainimgwrapper"] {
-                height: 130px;
-                background-size: cover;
-                background-position: center;
-            }
+      table[class="mainimgwrapper"] {
+        height: 130px;
+        background-size: cover;
+        background-position: center;
+      }
 
-            .mainimg {
-                display: none;
-            }
-        }
-    </style>
+      .mainimg {
+        display: none;
+      }
+    }
+  </style>
 </head>
-<body bgcolor="#f9f9f9" topmargin="0" bottommargin="0" leftmargin="0" rightmargin="0" link="#39c2d7" alink="#39c2d7" vlink="#39c2d7"
+<body bgcolor="#f9f9f9" topmargin="0" bottommargin="0" leftmargin="0" rightmargin="0" link="#39c2d7"
+      alink="#39c2d7" vlink="#39c2d7"
       style="font-family: OpenSans, sans-serif;">
 <table width="540" border="0" cellspacing="0" cellpadding="0" align="center" class="mainwrapper">
-    <tbody>
-    <tr>
-        <td>
-            <table width="100%" border="0" cellspacing="0" cellpadding="0" class="logowrapper">
-                <tbody>
-                <tr>
-                    <td height="48">
-                        <a class="rplogo" href="http://reportportal.io" target="_blank"
-                           style="font-size: 15px; color: #595c5c; font-weight: bold; font-family: 'Roboto', sans-serif;">
-                            ReportPortal.io
-                        </a>
-                    </td>
-                </tr>
-                </tbody>
+  <tbody>
+  <tr>
+    <td>
+      <table width="100%" border="0" cellspacing="0" cellpadding="0" class="logowrapper">
+        <tbody>
+        <tr>
+          <td height="48">
+            <a class="rplogo" href="http://reportportal.io" target="_blank"
+               style="font-size: 15px; color: #595c5c; font-weight: bold; font-family: 'Roboto', sans-serif;">
+              ReportPortal.io
+            </a>
+          </td>
+        </tr>
+        </tbody>
+      </table>
+      <table width="100%" border="0" cellspacing="0" cellpadding="30" class="contentwrapper"
+             bgcolor="#ffffff">
+        <tbody>
+        <tr>
+          <td align="left" height="170">
+            <h2 style="font-size: 20px; color: #777777;" align="center">Email server integration has
+              been successfully
+              created</h2>
+          </td>
+        </tr>
+        </tbody>
+      </table>
+      <table width="100%" height="82" border="0" cellspacing="0" cellpadding="0"
+             class="linkswrapper">
+        <tbody>
+        <tr>
+          <td height="82" align="center">
+            <table border="0" cellspacing="0" cellpadding="12" class="linksline" align="center">
+              <tbody>
+              <tr>
+                <td>
+                  <p style="font-size: 13px; color: #464547;">Keep in touch with us:</p>
+                </td>
+                <td>
+                  <a href="http://twitter.com/ReportPortal_io" target="_blank">
+                    <img src="cid:ic-twitter.png" alt="twitter">
+                  </a>
+                </td>
+                <td><a href="https://slack.epmrpp.reportportal.io" target="_blank">
+                    <img src="cid:ic-slack.png" alt="slack">
+                  </a>
+                </td>
+                <td>
+                  <a href="https://www.youtube.com/c/ReportPortal" target="_blank">
+                    <img src="cid:ic-youtube.png" alt="youtube">
+                  </a>
+                </td>
+                <td>
+                  <a href="https://www.linkedin.com/company/reportportal/" target="_blank">
+                    <img src="cid:ic-linkedin.png" alt="linkedin">
+                  </a>
+                </td>
+                <td>
+                  <a href="https://www.facebook.com/ReportPortal.io" target="_blank">
+                    <img src="cid:ic-facebook.png" alt="facebook">
+                  </a>
+                </td>
+                <td>
+                  <a href="https://github.com/reportportal" target="_blank">
+                    <img src="cid:ic-github.png" alt="github">
+                  </a>
+                </td>
+              </tr>
+              </tbody>
             </table>
-            <table width="100%" border="0" cellspacing="0" cellpadding="30" class="contentwrapper" bgcolor="#ffffff">
-                <tbody>
-                <tr>
-                    <td align="left" height="170">
-                        <h2 style="font-size: 20px; color: #777777;" align="center">Email server integration has been successfully
-                            created</h2>
-                    </td>
-                </tr>
-                </tbody>
-            </table>
-            <table width="100%" height="82" border="0" cellspacing="0" cellpadding="0" class="linkswrapper">
-                <tbody>
-                <tr>
-                    <td height="82" align="center">
-                        <table border="0" cellspacing="0" cellpadding="12" class="linksline" align="center">
-                            <tbody>
-                            <tr>
-                                <td><p style="font-size: 13px; color: #464547;">Keep in touch with us:</p></td>
-                                <td><a href="https://github.com/reportportal" target="_blank"><img src="cid:ic-github.png" border="0"
-                                                                                                   width="20" height="21" alt="github"></a>
-                                </td>
-                                <td><a href="http://twitter.com/ReportPortal_io" target="_blank"><img src="cid:ic-twitter.png" border="0"
-                                                                                                      width="20" height="16" alt="twitter"></a>
-                                </td>
-                                <td><a href="https://www.youtube.com/c/ReportPortal" target="_blank"><img src="cid:ic-youtube.png"
-                                                                                                              border="0" width="20"
-                                                                                                              height="15" alt="youtube"></a>
-                                </td>
-                                <td><a href="https://slack.epmrpp.reportportal.io" target="_blank"><img src="cid:ic-slack.png"
-                                                                                                                 border="0" width="18"
-                                                                                                                 height="18"
-                                                                                                                 alt="slack"></a></td>
-                            </tr>
-                            </tbody>
-                        </table>
-                    </td>
-                </tr>
-                </tbody>
-            </table>
-            <table width="100%" border="0" cellspacing="0" cellpadding="0" bgcolor="#bdc7cc" class="footerline">
-                <tbody>
-                <tr>
-                    <td height="1"><!-- --></td>
-                </tr>
-                </tbody>
-            </table>
-            <table width="100%" border="0" cellspacing="0" cellpadding="0" class="footerwrapper">
-                <tbody>
-                <tr>
-                    <td align="center" height="85" class="footercontent" style="padding: 4px;">
-                        <p style="font-size: 11px; line-height: 1.5; color: #6d6d6d">
-                            <b>ReportPortal Notification Center</b><br>
-                            This notification was created automatically. Please don't reply to this e-mail.
-                        </p>
-                    </td>
-                </tr>
-                </tbody>
-            </table>
-        </td>
-    </tr>
-    </tbody>
+          </td>
+        </tr>
+        </tbody>
+      </table>
+      <table width="100%" border="0" cellspacing="0" cellpadding="0" bgcolor="#bdc7cc"
+             class="footerline">
+        <tbody>
+        <tr>
+          <td height="1"><!-- --></td>
+        </tr>
+        </tbody>
+      </table>
+      <table width="100%" border="0" cellspacing="0" cellpadding="0" class="footerwrapper">
+        <tbody>
+        <tr>
+          <td align="center" height="85" class="footercontent" style="padding: 4px;">
+            <p style="font-size: 11px; line-height: 1.5; color: #6d6d6d">
+              <b>ReportPortal Notification Center</b><br>
+              This notification was created automatically. Please don't reply to this e-mail.
+            </p>
+          </td>
+        </tr>
+        </tbody>
+      </table>
+    </td>
+  </tr>
+  </tbody>
 </table>
 </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/src/main/resources/templates/email/finish-launch-template.ftl b/src/main/resources/templates/email/finish-launch-template.ftl
index 47d79ab982..bb63fcde32 100644
--- a/src/main/resources/templates/email/finish-launch-template.ftl
+++ b/src/main/resources/templates/email/finish-launch-template.ftl
@@ -1,264 +1,306 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-    <title>ReportPortal</title>
-    <link href='http://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'>
-    <style>
-        body {
-            margin: 0;
-            padding: 0;
-            font-family: OpenSans, sans-serif;
-        }
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+  <title>ReportPortal</title>
+  <link href='http://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'>
+  <style>
+    body {
+      margin: 0;
+      padding: 0;
+      font-family: OpenSans, sans-serif;
+    }
 
-        a, a:active, a:visited {
-            color: #39c2d7;
-            text-decoration: underline;
-        }
+    a, a:active, a:visited {
+      color: #39c2d7;
+      text-decoration: underline;
+    }
 
-        a:hover {
-            text-decoration: none;
-        }
+    a:hover {
+      text-decoration: none;
+    }
 
-        .rplogo, .rplogo:hover, .rplogo:active, .rplogo:visited {
-            display: inline-block;
-            text-decoration: none;
-        }
+    .rplogo, .rplogo:hover, .rplogo:active, .rplogo:visited {
+      display: inline-block;
+      text-decoration: none;
+    }
 
-        @media only screen and (max-width: 540px) {
-            body {
-                margin: 0;
-                padding: 0;
-            }
+    @media only screen and (max-width: 540px) {
+      body {
+        margin: 0;
+        padding: 0;
+      }
 
-            table[class="mainwrapper"] {
-                width: 100% !important;
-            }
+      table[class="mainwrapper"] {
+        width: 100% !important;
+      }
 
-            .rplogo {
-                margin-left: 15px;
-            }
-        }
-    </style>
+      .rplogo {
+        margin-left: 15px;
+      }
+    }
+  </style>
 </head>
-<body bgcolor="#f9f9f9" topmargin="0" bottommargin="0" leftmargin="0" rightmargin="0" link="#39c2d7" alink="#39c2d7"
+<body bgcolor="#f9f9f9" topmargin="0" bottommargin="0" leftmargin="0" rightmargin="0" link="#39c2d7"
+      alink="#39c2d7"
       vlink="#39c2d7"
       style="font-family: OpenSans, sans-serif;">
 <table width="540" border="0" cellspacing="0" cellpadding="0" align="center" class="mainwrapper">
-    <tbody>
-    <tr>
-        <td>
-            <table width="100%" border="0" cellspacing="0" cellpadding="0" class="logowrapper">
-                <tbody>
-                <tr>
-                    <td height="48">
-                        <a class="rplogo" href="http://reportportal.io" target="_blank"
-                           style="font-size: 15px; color: #595c5c; font-weight: bold; font-family: 'Roboto', sans-serif;">
-                            ReportPortal.io
-                        </a>
-                    </td>
-                </tr>
-                </tbody>
-            </table>
-            <table width="100%" border="0" cellspacing="0" cellpadding="30" class="contentwrapper" bgcolor="#ffffff">
-                <tbody>
-                <tr>
-                    <td align="left" height="170">
-                        <table class="content" width="100%" border="0" cellspacing="0" cellpadding="0" style="border-collapse:collapse;">
-                        <#assign rowCounter = 1>
-                        <#macro subtypes sbt>
-                            <#list sbt as key,value>
-                                <#if rowCounter % 2 == 0>
-                                <tr bgcolor="#ffffff" style="background-color:#ffffff;">
-                                <#else>
-                                <tr bgcolor="#f9f9f9" style="background-color:#f9f9f9;">
-                                </#if>
-                                <td height="25"
-                                    style="font-size: 14px; color: #464547; padding-left: 38px; border-width: 0px;">${key}</td>
-                                <td width="40" style="font-size: 14px; color: #464547; border-width: 0px;">${value}</td>
-                            </tr>
-                                <#assign rowCounter++>
-
+  <tbody>
+  <tr>
+    <td>
+      <table width="100%" border="0" cellspacing="0" cellpadding="0" class="logowrapper">
+        <tbody>
+        <tr>
+          <td height="48">
+            <a class="rplogo" href="http://reportportal.io" target="_blank"
+               style="font-size: 15px; color: #595c5c; font-weight: bold; font-family: 'Roboto', sans-serif;">
+              ReportPortal.io
+            </a>
+          </td>
+        </tr>
+        </tbody>
+      </table>
+      <table width="100%" border="0" cellspacing="0" cellpadding="30" class="contentwrapper"
+             bgcolor="#ffffff">
+        <tbody>
+        <tr>
+          <td align="left" height="170">
+            <table class="content" width="100%" border="0" cellspacing="0" cellpadding="0"
+                   style="border-collapse:collapse;">
+                <#assign rowCounter = 1>
+                <#macro subtypes sbt>
+                    <#list sbt as key,value>
+                        <#if rowCounter % 2 == 0>
+                          <tr bgcolor="#ffffff" style="background-color:#ffffff;">
+                        <#else>
+                          <tr bgcolor="#f9f9f9" style="background-color:#f9f9f9;">
+                        </#if>
+                      <td height="25"
+                          style="font-size: 14px; color: #464547; padding-left: 38px; border-width: 0px;">${key}</td>
+                      <td width="40"
+                          style="font-size: 14px; color: #464547; border-width: 0px;">${value}</td>
+                      </tr>
+                        <#assign rowCounter++>
 
-                            </#list>
-                        </#macro>
 
-                        <#macro maintype name counter>
-                            <#if rowCounter % 2 == 0>
-                            <tr bg="#ffffff" style="background-color:#ffffff;">
-                            <#else>
-                            <tr bgcolor="#f9f9f9" style="background-color:#f9f9f9;">
-                            </#if>
-                            <td height="40" style="font-size: 14px; color: #464547; padding-left: 20px; border-width: 0px;"><b>${name}</b>
-                            </td>
-                            <td style="font-size: 14px; color: #464547; border-width: 0px;"><b>${counter}</b></td>
-                        </tr>
-                            <#assign rowCounter++>
+                    </#list>
+                </#macro>
 
-                        </#macro>
-                        </table>
-                        <!-- Launch name and link to ReportPortal instance -->
-                        <h2 style="font-size: 20px; color: #777777;" align="center">Launch "${name}" #${number} has been
-                            finished</h2>
-                        <p style="font-size: 14px; color: #777777;">To view it on ReportPortal just visit this <a
-                                href="${url}" target="_blank">link</a>.</p>
-                        <#if attributes??>
-                            <p style="font-size: 14px; color: #777777;">Attributes to launch:
-                                <#list attributes as name, link>
-                                <a href="${link}" target="_blank" style="padding-left:5px;">${name}</a>
-                            </#list>
-                        </p>
+                <#macro maintype name counter>
+                    <#if rowCounter % 2 == 0>
+                      <tr bg="#ffffff" style="background-color:#ffffff;">
+                    <#else>
+                      <tr bgcolor="#f9f9f9" style="background-color:#f9f9f9;">
                     </#if>
-                        <!-- Launch name, link and description (if exists) -->
-                    <#if description??>
-                        <p style="font-size: 14px; color: #777777;">Description of launch:<br>${description}</p>
+                  <td height="40"
+                      style="font-size: 14px; color: #464547; padding-left: 20px; border-width: 0px;">
+                    <b>${name}</b>
+                  </td>
+                  <td style="font-size: 14px; color: #464547; border-width: 0px;"><b>${counter}</b>
+                  </td>
+                  </tr>
+                    <#assign rowCounter++>
+
+                </#macro>
+            </table>
+            <!-- Launch name and link to ReportPortal instance -->
+            <h2 style="font-size: 20px; color: #777777;" align="center">Launch "${name}" #${number}
+              has been
+              finished</h2>
+            <p style="font-size: 14px; color: #777777;">To view it on ReportPortal just visit this
+              <a
+                  href="${url}" target="_blank">link</a>.</p>
+              <#if attributes??>
+                <p style="font-size: 14px; color: #777777;">Attributes to launch:
+                    <#list attributes as name, link>
+                      <a href="${link}" target="_blank" style="padding-left:5px;">${name}</a>
+                    </#list>
+                </p>
+              </#if>
+            <!-- Launch name, link and description (if exists) -->
+              <#if description??>
+                <p style="font-size: 14px; color: #777777;">Description of launch:<br>${description}
+                </p>
+              </#if>
+            <table width="300" cellspacing="0" cellpadding="0" style="border: 1px solid #e9e9e9;">
+              <tr>
+                <td>
+                  <table width="300" border="0" cellspacing="0" cellpadding="6"
+                         style="border: none; border-collapse: collapse;">
+                    <tbody>
+                    <tr bgcolor="#f5f5f5" style="background: #f5f5f5;">
+                      <td height="40"
+                          style="font-size: 12px; color: #777777; border-bottom: 1px solid #e9e9e9; padding-left: 20px;">
+                        <b>LAUNCH STATISTICS</b></td>
+                      <td width="40"
+                          style="font-size: 12px; color: #777777; border-bottom: 1px solid #e9e9e9;"></td>
+                    </tr>
+                    <tr bgcolor="#ffffff" style="background: #ffffff;">
+                      <td height="40"
+                          style="font-size: 14px; color: #464547; padding-left: 20px; border-width: 0px;">
+                        <b>TOTAL</b>
+                      </td>
+                      <td width="40" style="font-size: 14px; color: #464547; border-width: 0px;">
+                        <b>${total}</b></td>
+                    </tr>
+                    <tr bgcolor="#f9f9f9" style="background: #f9f9f9;">
+                      <td height="25"
+                          style="font-size: 14px; color: #464547; padding-left: 38px; border-width: 0px;">
+                        Passed
+                      </td>
+                      <td width="40"
+                          style="font-size: 14px; color: #464547; border-width: 0px;">${passed}</td>
+                    </tr>
+                    <tr bgcolor="#ffffff" style="background: #ffffff;">
+                      <td height="25"
+                          style="font-size: 14px; color: #464547; padding-left: 38px; border-width: 0px;">
+                        Failed
+                      </td>
+                      <td width="40"
+                          style="font-size: 14px; color: #464547; border-width: 0px;">${failed}</td>
+                    </tr>
+                    <tr bgcolor="#f9f9f9" style="background: #f9f9f9;">
+                      <td height="25"
+                          style="font-size: 14px; color: #464547; padding-left: 38px; border-width: 0px;">
+                        Skipped
+                      </td>
+                      <td width="40"
+                          style="font-size: 14px; color: #464547; border-width: 0px;">${skipped}</td>
+                    </tr>
+                    </tbody>
+                  </table>
+                </td>
+              </tr>
+            </table>
+            <br>
+            <table width="100%" cellspacing="0" cellpadding="0" style="border: 1px solid #e9e9e9;">
+              <tr>
+                <td>
+                  <table width="100%" border="0" cellspacing="0" cellpadding="6"
+                         style="border: none; border-collapse: collapse;">
+                    <tbody>
+                    <tr bgcolor="#f5f5f5" style="background: #f5f5f5;">
+                      <td height="40"
+                          style="font-size: 12px; color: #777777; border-bottom: 1px solid #e9e9e9; padding-left: 20px;">
+                        <b>LAUNCH DEFECTS</b></td>
+                      <td width="40"
+                          style="font-size: 12px; color: #777777;  border-bottom: 1px solid #e9e9e9;"></td>
+                    </tr>
+                    <!-- PRODUCT BUG bugs section -->
+                    <#assign name="Product Bugs">
+                    <@maintype name="${name}" counter="${productBugTotal}" />
+                    <#if pbInfo??>
+                        <@subtypes sbt=pbInfo/>
                     </#if>
-                        <table width="300" cellspacing="0" cellpadding="0"  style="border: 1px solid #e9e9e9;">
-                            <tr>
-                                <td>
-                                    <table width="300" border="0" cellspacing="0" cellpadding="6" style="border: none; border-collapse: collapse;">
-                                        <tbody>
-                                        <tr bgcolor="#f5f5f5" style="background: #f5f5f5;">
-                                            <td height="40"
-                                                style="font-size: 12px; color: #777777; border-bottom: 1px solid #e9e9e9; padding-left: 20px;">
-                                                <b>LAUNCH STATISTICS</b></td>
-                                            <td width="40"
-                                                style="font-size: 12px; color: #777777; border-bottom: 1px solid #e9e9e9;"></td>
-                                        </tr>
-                                        <tr bgcolor="#ffffff" style="background: #ffffff;">
-                                            <td height="40" style="font-size: 14px; color: #464547; padding-left: 20px; border-width: 0px;">
-                                                <b>TOTAL</b>
-                                            </td>
-                                            <td width="40" style="font-size: 14px; color: #464547; border-width: 0px;"><b>${total}</b></td>
-                                        </tr>
-                                        <tr bgcolor="#f9f9f9" style="background: #f9f9f9;">
-                                            <td height="25" style="font-size: 14px; color: #464547; padding-left: 38px; border-width: 0px;">Passed
-                                            </td>
-                                            <td width="40" style="font-size: 14px; color: #464547; border-width: 0px;">${passed}</td>
-                                        </tr>
-                                        <tr bgcolor="#ffffff" style="background: #ffffff;">
-                                            <td height="25" style="font-size: 14px; color: #464547; padding-left: 38px; border-width: 0px;">Failed
-                                            </td>
-                                            <td width="40" style="font-size: 14px; color: #464547; border-width: 0px;">${failed}</td>
-                                        </tr>
-                                        <tr bgcolor="#f9f9f9" style="background: #f9f9f9;">
-                                            <td height="25" style="font-size: 14px; color: #464547; padding-left: 38px; border-width: 0px;">
-                                                Skipped
-                                            </td>
-                                            <td width="40" style="font-size: 14px; color: #464547; border-width: 0px;">${skipped}</td>
-                                        </tr>
-                                        </tbody>
-                                    </table>
-                                </td>
-                            </tr>
-                        </table>
-                        <br>
-                        <table width="100%" cellspacing="0" cellpadding="0"  style="border: 1px solid #e9e9e9;">
-                            <tr>
-                                <td>
-                                    <table width="100%" border="0" cellspacing="0" cellpadding="6" style="border: none; border-collapse: collapse;">
-                                        <tbody>
-                                        <tr bgcolor="#f5f5f5" style="background: #f5f5f5;">
-                                            <td height="40"
-                                                style="font-size: 12px; color: #777777; border-bottom: 1px solid #e9e9e9; padding-left: 20px;">
-                                                <b>LAUNCH DEFECTS</b></td>
-                                            <td width="40"
-                                                style="font-size: 12px; color: #777777;  border-bottom: 1px solid #e9e9e9;"></td>
-                                        </tr>
-                                        <!-- PRODUCT BUG bugs section -->
-                                        <#assign name="Product Bugs">
-                                        <@maintype name="${name}" counter="${productBugTotal}" />
-                                        <#if pbInfo??>
-                                            <@subtypes sbt=pbInfo/>
-                                        </#if>
 
-                                        <!-- AUTOMATION BUG bugs section -->
-                                        <#assign name="Automation Bugs">
-                                        <@maintype name="${name}" counter="${automationBugTotal}" />
-                                        <#if abInfo??>
-                                            <@subtypes sbt=abInfo/>
-                                        </#if>
+                    <!-- AUTOMATION BUG bugs section -->
+                    <#assign name="Automation Bugs">
+                    <@maintype name="${name}" counter="${automationBugTotal}" />
+                    <#if abInfo??>
+                        <@subtypes sbt=abInfo/>
+                    </#if>
 
-                                        <!-- SYSTEM ISSUE bugs section -->
-                                        <#assign name="System Issues">
-                                        <@maintype name="${name}" counter="${systemIssueTotal}" />
-                                        <#if siInfo??>
-                                            <@subtypes sbt=siInfo/>
-                                        </#if>
+                    <!-- SYSTEM ISSUE bugs section -->
+                    <#assign name="System Issues">
+                    <@maintype name="${name}" counter="${systemIssueTotal}" />
+                    <#if siInfo??>
+                        <@subtypes sbt=siInfo/>
+                    </#if>
 
-                                        <!-- NO DEFECT bugs section -->
-                                        <#assign name="No Defects">
-                                        <@maintype name="${name}" counter="${noDefectTotal}" />
-                                        <#if ndInfo??>
-                                            <@subtypes sbt=ndInfo/>
-                                        </#if>
+                    <!-- NO DEFECT bugs section -->
+                    <#assign name="No Defects">
+                    <@maintype name="${name}" counter="${noDefectTotal}" />
+                    <#if ndInfo??>
+                        <@subtypes sbt=ndInfo/>
+                    </#if>
 
-                                        <!-- TO INVESTIGATE bugs section -->
-                                        <#assign name="To Investigate">
-                                        <@maintype name="${name}" counter="${toInvestigateTotal}" />
-                                        <#if tiInfo??>
-                                            <@subtypes sbt=tiInfo/>
-                                        </#if>
-                                        </tbody>
-                                    </table>
-                                </td>
-                            </tr>
-                        </table>
-                    </td>
-                </tr>
-                </tbody>
-            </table>
-            <table width="100%" height="82" border="0" cellspacing="0" cellpadding="0" class="linkswrapper">
-                <tbody>
-                <tr>
-                    <td height="82" align="center">
-                        <table border="0" cellspacing="0" cellpadding="12" class="linksline" align="center">
-                            <tbody>
-                            <tr>
-                                <td><p style="font-size: 13px; color: #464547;">Keep in touch with us:</p></td>
-                                <td><a href="https://github.com/reportportal" target="_blank"><img src="cid:ic-github.png"
-                                                                                                   border="0" width="20"
-                                                                                                   height="21"
-                                                                                                   alt="github"></a>
-                                </td>
-                                <td><a href="http://twitter.com/ReportPortal_io" target="_blank"><img
-                                        src="cid:ic-twitter.png" border="0" width="20" height="16" alt="twitter"></a></td>
-                                <td><a href="https://www.youtube.com/c/ReportPortal"
-                                       target="_blank"><img src="cid:ic-youtube.png" border="0" width="20" height="15"
-                                                            alt="youtube"></a></td>
-                                <td><a href="https://slack.epmrpp.reportportal.io/" target="_blank"><img src="cid:ic-slack.png"
-                                                                                                                  border="0" width="18"
-                                                                                                                  height="18"
-                                                                                                                  alt="slack"></a>
-                                </td>
-                            </tr>
-                            </tbody>
-                        </table>
-                    </td>
-                </tr>
-                </tbody>
-            </table>
-            <table width="100%" border="0" cellspacing="0" cellpadding="0" bgcolor="#bdc7cc" class="footerline">
-                <tbody>
-                <tr>
-                    <td height="1"><!-- --></td>
-                </tr>
-                </tbody>
+                    <!-- TO INVESTIGATE bugs section -->
+                    <#assign name="To Investigate">
+                    <@maintype name="${name}" counter="${toInvestigateTotal}" />
+                    <#if tiInfo??>
+                        <@subtypes sbt=tiInfo/>
+                    </#if>
+                    </tbody>
+                  </table>
+                </td>
+              </tr>
             </table>
-            <table width="100%" border="0" cellspacing="0" cellpadding="0" class="footerwrapper">
-                <tbody>
-                <tr>
-                    <td align="center" height="52" class="footercontent">
-                        <p style="font-size: 11px; line-height: 1.5; color: #6d6d6d"><b>ReportPortal Notification
-                            Center</b><br>
-                            This notification was created automatically. Please don't reply to this e-mail.</p>
-                    </td>
-                </tr>
-                </tbody>
+          </td>
+        </tr>
+        </tbody>
+      </table>
+      <table width="100%" height="82" border="0" cellspacing="0" cellpadding="0"
+             class="linkswrapper">
+        <tbody>
+        <tr>
+          <td height="82" align="center">
+            <table border="0" cellspacing="0" cellpadding="12" class="linksline" align="center">
+              <tbody>
+              <tr>
+                <td>
+                  <p style="font-size: 13px; color: #464547;">Keep in touch with us:</p>
+                </td>
+                <td>
+                  <a href="http://twitter.com/ReportPortal_io" target="_blank">
+                    <img src="cid:ic-twitter.png" alt="twitter">
+                  </a>
+                </td>
+                <td>
+                  <a href="https://slack.epmrpp.reportportal.io/" target="_blank">
+                    <img src="cid:ic-slack.png" alt="slack">
+                  </a>
+                </td>
+                <td>
+                  <a href="https://www.youtube.com/c/ReportPortal" target="_blank">
+                    <img src="cid:ic-youtube.png" alt="youtube">
+                  </a>
+                </td>
+                <td>
+                  <a href="https://www.linkedin.com/company/reportportal/" target="_blank">
+                    <img src="cid:ic-linkedin.png" alt="linkedin">
+                  </a>
+                </td>
+                <td>
+                  <a href="https://www.facebook.com/ReportPortal.io" target="_blank">
+                    <img src="cid:ic-facebook.png" alt="facebook">
+                  </a>
+                </td>
+                <td>
+                  <a href="https://github.com/reportportal" target="_blank">
+                    <img src="cid:ic-github.png" alt="github">
+                  </a>
+                </td>
+              </tr>
+              </tbody>
             </table>
-        </td>
-    </tr>
-    </tbody>
+          </td>
+        </tr>
+        </tbody>
+      </table>
+      <table width="100%" border="0" cellspacing="0" cellpadding="0" bgcolor="#bdc7cc"
+             class="footerline">
+        <tbody>
+        <tr>
+          <td height="1"><!-- --></td>
+        </tr>
+        </tbody>
+      </table>
+      <table width="100%" border="0" cellspacing="0" cellpadding="0" class="footerwrapper">
+        <tbody>
+        <tr>
+          <td align="center" height="52" class="footercontent">
+            <p style="font-size: 11px; line-height: 1.5; color: #6d6d6d"><b>ReportPortal
+                Notification
+                Center</b><br>
+              This notification was created automatically. Please don't reply to this e-mail.</p>
+          </td>
+        </tr>
+        </tbody>
+      </table>
+    </td>
+  </tr>
+  </tbody>
 </table>
 </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/src/main/resources/templates/email/ic-github.png b/src/main/resources/templates/email/ic-github.png
deleted file mode 100644
index b03969a75aaa5ed0ce2469f86e594c35834b4932..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 816
zcmV-01JC@4P)<h;3K|Lk000e1NJLTq000yK000#T1^@s6M%B)!00001b5ch_0Itp)
z=>Px%>PbXFR5%fpR82@!Q4~JszURQiKp|1kWF#hyjYUC_<v5IiS_^{~E)0SQB3uTR
zLD3&>ln825ND*yX=%$@Ukv7w41V(6?HW7gsxax-yotby<>D)KHH*frz>cV^XJKs6y
zd*|JI?nPK-5D`Wb(@}}o1PHrHsm(eJg_s9|NrUKFyde}vL|UGX%ZY|~YL|sp7dyhs
zeZ@9TA<CX)B>ch47YQCprkY9SZt#~)Z_rwp|HR_DuZ~4)o;oqEU?h=>DX?xjj{liW
zffwTSp%*$w=vULL=`D(^YZ@cq7q0Lw!(ZB7a}f6HSnanITsb^C6V%uiTp;LRrGO@Y
z@Le(zda%y#I}QqmIO37v_qW;)iEj2!2!vas(NHgc_^q7-6j+kfp|KeoPHoMSY+*rr
z5GkJq&-YjT<ms|a7G6&n>c<|Wz~|)g?l;F?r|yZYA!C4KS87KI<c0pXK}gb#WR0wp
zF~O}==aAe~*7`Ezj${9A4wjeS=9rutr{JLA9^T;)2qHaLS6zBDoM4^@!kf~(QfZeW
zs1jWE2A2Tk!3DMyB0x7sYw_B7*9@tR$S5V?^{tFWOK=-}F9Z?Jjeg!<uuG%)H#6IG
zpSe-2B@Cn~mterhz13@%!nq|l=JjhWfrMjTl9X)M$I#2Ih9ilOF+@1w^=U0^o1OK~
zeO(yj%2LWSdr-=A0O|nOI%JUXI1#Nb`h!?<sy0X1P6RDpF>dU1urhE|3{+Gsa+!U+
zL;HlXF8VCrB^I0DwK*ce>McrQBO|eMg&6ZfK%cFp6U_QhKU3p;9qrASnYvp4&a<Xz
zoD3Lcr?uZZP{2m7oyTH4ukq({7(ukSvMzR}5U6`{>C=77g7b^gy1pV=i9#diohhBG
zHMHrT;gQD5A3;l<VQvIT@og>lNTh{)PT@_UzBv}J`>@W@xeix!GY>R|_18P~4oZSk
uye?TM(3$z_$|!>OocJ&it$FG2&iotoOdO<%($3NV0000<MNUMnLSTYu$%9}3

diff --git a/src/main/resources/templates/email/ic-slack.png b/src/main/resources/templates/email/ic-slack.png
deleted file mode 100644
index e343de86155b2b04b8c5f1ad6cf9d7b19ee0d1a9..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 686
zcmV;f0#W^mP)<h;3K|Lk000e1NJLTq000sI000sQ1^@s6R?d!B00001b5ch_0Itp)
z=>Px%Xh}ptR5%fRR8MPDK@gwWB=uhoeh0C>+=L1qlGNBHu}HyF#gkt^JXP^%1QA6&
ziO_=|K=dR?C~2tmB@qO@c<{X>C&8n~B2@c!oZlw<cqz35Z)bL9_P4Y1=P?~YEB*Lf
zV(FT?l!<9xNGub@Z1`oT9BgNgs(zLlVT?m-Byv@V&dyq=J7zIV_d1o}skf&<E4`?e
z5Iqy21#di(D_EXnX|r0|fuF(B?8kTaiMJ02;a_xe?liG!!8aul#>IZm%|X0mEp_!N
zljxZKs<5M=4e!)lEIC^}jD(p!67eY!xd1y8SGE>|fe|aWQV<v<-`J{_nwo<L9>{Y5
zs;wp_6CLuYWHh0HcLZnNzYN}~mRdOIqk#_8>_sg~lJ}FHu38kxdNI2^IRo=U062NN
zEPozW>%Gw%uhWZbUIs^H(Ix;Hr-l=SG<nc1_u>uSvmr^ccIDIXCUiNX7PuzohvT}S
z*Nj5;y@G!K`H6%!!to{Oj?EQb>01R~lJF{YC^w#4EFM3P{glckXXu^ZDKA3S!nVNM
z7tefQYhI8|7P{5>>(F`H-Q8RFGP<6zX@t=TZ}kRL>|n0E4IBx#LibZ0)AvcDncJx{
zms>pug6HCM6;nr%{D;&Zf^amAC@$+jx?E|)y=FGwthJAP=>g&os%>4!KGxh8oDOqm
zsO};{XDYx~2QG92Ads73blW+Tj>(in?DH8A46ptPTtx7}&|==QUG5Jb#&NN>!W}=f
zDG;17yqd%({{vI!v9>~6BYKNhWG|Qja$q{dm_JQQ;JRLDr1}BcWU~?svxl?tKXH=v
U|7RsVMF0Q*07*qoM6N<$f=T8&NdN!<

diff --git a/src/main/resources/templates/email/ic-twitter.png b/src/main/resources/templates/email/ic-twitter.png
deleted file mode 100644
index b0d3d1c094eae75d7ecaa818dd62ba8441cddc7a..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 593
zcmV-X0<QguP)<h;3K|Lk000e1NJLTq000yK000mO1^@s678qX}00001b5ch_0Itp)
z=>Px%3rR#lR5%fpQ_o9OQ4~JszSrnR3R($?AdJ4LHW7u6PjTlW5Xy%B0f`p5h&Huq
z)mGfpe-JGU-6^ih`AKbxN*Hl!Wfnw16f%x)?&-UCyu<i(WahxT=iKky^PPL{JBO(Y
zNf#=YsUAHQlIu()L|jyg7yVu;?^pGFDNH@_Gn<n5_G|0e*?#Z-S~9ucj(<GAJ*xG=
z2K)(g25e@Xt!sRHFqw>x)X$5gk#X+N_j=CWz@R6H=x6~fmh1#KAg+w%${F>BIRbkP
zq}Nc+hjhODeDYmoARZ*lm*QCKo=J8}6TuRmf+(FWzXIWG^8mA{XoHEDnCTM=`K@*I
zx#^D?Ac=~TsWS%l&64QrnXCP+_JZYx*^`J#G=(HnVjoLexZQ%=n^&}A32XnVUjd#2
zk;A*xvf~1jHH5Q=w{mz_8s+3&K!ecp9s>B`z;3l7UU4y&usELlqLhCVnch1`$C~+L
zE*x2R=j|Js4gTUis4LFVsaDL7xzQCiq){@=3+IEoXpxtl5;e~8Vj&z^ZH+PQaYWFQ
zw~6Hue)!cRj`)UYxhD+n*uiM=HE);^@y3c<0enMf!}cSF@=(dbbQomfWQLc`(2LYx
zU`_|o$X-jbV<yTeDfS-ZCx+i1a~=Y=WQ>D<P}rUkt#4tjM?u_=;nT2pg?Lv9zxI5+
fl1-;DhNsJad-J#YtB}Z=00000NkvXXu0mjf5ilJ}

diff --git a/src/main/resources/templates/email/ic-youtube.png b/src/main/resources/templates/email/ic-youtube.png
deleted file mode 100644
index 2e92439291a3f9e6d1ada2917c6bb5444993e290..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 297
zcmV+^0oMMBP)<h;3K|Lk000e1NJLTq000yK000jN1^@s6<e2YO00001b5ch_0Itp)
z=>Px#<4Ht8R5%f1v^sPnhJlfx_y7O@Vhj`jMn=Y0jEoFLj8=zlyrk4Hm^(m*GEvJg
zkf9*6m|&(;iza9wFkI4sVf>3&3ke!{%vN(2BNK}QBLl;8Vhkl{Ajpto)~d&uxj2o1
zh8`zmC{YH23^{C~@LXD0!vPosv+x;8w1FT)p1->-1Ei$z8OVZ95+>(x|31gBC%?-7
z{r^|-pMik`CXS6}v^;bjs0I&UWcFob_%{)l#+2}=f=dy0;s3vz@!JSD3(O!X3{kaW
v=P`luA9g9yMZtNQ;Xgw$H4Fur0V-_(>}5QQoiqvp00000NkvXXu0mjfxgK-s

diff --git a/src/main/resources/templates/email/create-user.png b/src/main/resources/templates/email/images/create-user.png
similarity index 100%
rename from src/main/resources/templates/email/create-user.png
rename to src/main/resources/templates/email/images/create-user.png
diff --git a/src/main/resources/templates/email/delete-account-notification.png b/src/main/resources/templates/email/images/delete-account-notification.png
similarity index 100%
rename from src/main/resources/templates/email/delete-account-notification.png
rename to src/main/resources/templates/email/images/delete-account-notification.png
diff --git a/src/main/resources/templates/email/deleted-account.png b/src/main/resources/templates/email/images/deleted-account.png
similarity index 100%
rename from src/main/resources/templates/email/deleted-account.png
rename to src/main/resources/templates/email/images/deleted-account.png
diff --git a/src/main/resources/templates/email/images/ic-facebook.png b/src/main/resources/templates/email/images/ic-facebook.png
new file mode 100644
index 0000000000000000000000000000000000000000..de08b4da48f90e6b5be2cde1849438f61efddf95
GIT binary patch
literal 896
zcmV-`1AqL9P)<h;3K|Lk000e1NJLTq000yK000yS1^@s6jfou%0004lX+uL$Nkc;*
zaB^>EX>4Tx04R}tkv&MmKpe$iQ>9WW3T6=LkfAzR5EXIMDionYs1;guFuC*#ni!H4
z7e~Rh;NZt%)xpJCR|i)?5c~jfb#YR3krMxx7Fxu3aNLh~_a1le0HI!Cy4^Jf=!RpZ
zlL;xCTaiMq2t!0aqJY9|b5@p9@Eu?G2=MhT&a?c_{W*HIyv=}sL_EVx%OPGTp4xOw
z&ilk7D=8ZBIq|4P7bJe<y4vJ7&P9&}o+(<H^c=BBEEPLg?O;~2bmB?kn5G+)FJzmn
zao*yrSE{UaPyWJ4-dJAZI?X7OSimA=NKjEl85KB)(`t}nBTf4WAODc&m&v7)s|-et
zd2B$3;`zb<;CHunVPd?Q6iEQxFRuGB41{)pM$L7<k6pKM0tBCdE2Hh-r~}iVq}SS7
z><H-F1}?7Knz{#E?f`>NreZ0c6r?E>3c&jreNzq?xCO$i&E8u3IDG&z)K%&RI5-4G
zij=+P^X{I`-u^w)>hA|D7IKQ}?mZ9y000JJOGiWi{{a60|De66lK=n!32;bRa{vGh
z*8l(w*8xH(n|J^K00(qQO+^Ri3KS3=F9Y71hX4Qpen~_@R5;7klrc<GQ51&1|2`aW
zav@G8CdSl4nDr5gI5Lnpn3%A1aWln^E*KUEH99!DIOqTa3xg82zBbQ9Czd`KbZ{ah
zY!X63-p^1Zgp}7dF$C{+@BPnz&pF@Cfy=(sQ(@~~vNacit2Q@*2-u4h9=0l_UuWf^
zm)}Hl>x1OaHrIq2LO+1<Ls9CcA1X9UHXj*3k^DTZjJ^W6+i2eo(&O`D3Jr~`hK+BN
z<=1he{S>Jtbk!Ky?iSOdWZwe5BN^!puxtCP#oPQ!ln$IBXb7`^ycw3XoKD?&Ulh^R
zFmANJAeDd{3MZx6_KP^lo&kTNkk7Uz$A0&hp)>=e;Pr^;W9LY9=N_X&_r8gS`~IA9
zl6j)JIe*UGyEw^qur){z|CU!1UPz}#mrk|ex?v5ef69{Tm=$0ox8hT6*am-+^Oplb
zNh=+aagsea^U!iyDHl=>|9Uw5=Y|4HRO2N3d5k{qWmr5M#3DJ<9UvTpkgs0&#6AMS
W;Egm{vtn8R0000<MNUMnLSTXd9g$K1

literal 0
HcmV?d00001

diff --git a/src/main/resources/templates/email/images/ic-github.png b/src/main/resources/templates/email/images/ic-github.png
new file mode 100644
index 0000000000000000000000000000000000000000..e5fd9694a3bf9ebc24541b05303cc4be9e1e4db6
GIT binary patch
literal 1125
zcmV-r1e*JaP)<h;3K|Lk000e1NJLTq000yK000yS1^@s6jfou%0004lX+uL$Nkc;*
zaB^>EX>4Tx04R}tkv&MmKpe$iQ>9WW3T6=LkfAzR5EXIMDionYs1;guFuC*#ni!H4
z7e~Rh;NZt%)xpJCR|i)?5c~jfb#YR3krMxx7Fxu3aNLh~_a1le0HI!Cy4^Jf=!RpZ
zlL;xCTaiMq2t!0aqJY9|b5@p9@Eu?G2=MhT&a?c_{W*HIyv=}sL_EVx%OPGTp4xOw
z&ilk7D=8ZBIq|4P7bJe<y4vJ7&P9&}o+(<H^c=BBEEPLg?O;~2bmB?kn5G+)FJzmn
zao*yrSE{UaPyWJ4-dJAZI?X7OSimA=NKjEl85KB)(`t}nBTf4WAODc&m&v7)s|-et
zd2B$3;`zb<;CHunVPd?Q6iEQxFRuGB41{)pM$L7<k6pKM0tBCdE2Hh-r~}iVq}SS7
z><H-F1}?7Knz{#E?f`>NreZ0c6r?E>3c&jreNzq?xCO$i&E8u3IDG&z)K%&RI5-4G
zij=+P^X{I`-u^w)>hA|D7IKQ}?mZ9y000JJOGiWi{{a60|De66lK=n!32;bRa{vGh
z*8l(w*8xH(n|J^K00(qQO+^Ri3KS3=HfOamM*si<V@X6oR5;7Mlut<0VHn3h-=E8&
z2_aOMqDzFE6Ot0rxsAL8Mu#p19fA%)w+Mq0!Y&1p1=77Bf=)$XVRR|jW}Ai{n~D`=
zR37@X2%T>G{hkh`Z8>8`^xU48_x<ob&-490@Q*{KN%x}}f3~4;&ZK#tyn7>&&}^kg
zd&kE&)aL3Bndj`2bUz(ydR`IO8P6Q_q+y@{n86(hKgKpQ{79cAZwAvrU>A^=h^L~#
z1IrAj6zGZ;V8QP$ZZ+9}pc^BA_$2XGSS_X_pjpSU4#71uLZu8}Y2u(S26aVWjYgx*
zeL&xz`V~%0o&vJvjFRxgG2mUUF27XO1Wd1hKzkyyXB9B~>_w}LE~K7`wzh?8cwaZW
z1Hc=h)2n~z*0cb)OZK!{iM$Af@}LnxOU04_YW)Roz1lO(T?I6=*8ukOr|ZDA7<#=5
z==bKH19M)DbEaBUdvbC=&?@6$MPY}Nnd4@<Ex08|7oJ4|@7Hq5hWUo0l3fR0Zl4Qu
z-aRUJ1sF}tY{{#*V=Nk+XisEL3g;@=Cd9N%4^pwfd4O;{6EmqFXa(xQhVpLB$%(F}
zk7XqnR6On&<Ke{AmC;!94SdC&f>RhxhVA?1e5VlzV?6OhTRPT!xD>Vm9E}79L6;0W
z*AbuWO?QN{1uH%VBs92uITZ^GfxSY!9E%1gDz)Q>^(0Hf#c*PBqlx~G<Wvv(=}Pmy
zl&>dcfyT84Ri?vKEO^#)oG9X^VEAwLq3`#Du}IShFcL{l?{>{QAu}seona=dYT$C@
r>b_<Cx%%G4hFn>%BwYr5;D5z;yesKU98iu*00000NkvXXu0mjf^$h^X

literal 0
HcmV?d00001

diff --git a/src/main/resources/templates/email/images/ic-linkedin.png b/src/main/resources/templates/email/images/ic-linkedin.png
new file mode 100644
index 0000000000000000000000000000000000000000..523755e1bf802ee23c9248d70d08f266af3b0c9c
GIT binary patch
literal 1015
zcmV<T0|@+yP)<h;3K|Lk000e1NJLTq000yK000yS1^@s6jfou%0004lX+uL$Nkc;*
zaB^>EX>4Tx04R}tkv&MmKpe$iQ>9WW3T6=LkfAzR5EXIMDionYs1;guFuC*#ni!H4
z7e~Rh;NZt%)xpJCR|i)?5c~jfb#YR3krMxx7Fxu3aNLh~_a1le0HI!Cy4^Jf=!RpZ
zlL;xCTaiMq2t!0aqJY9|b5@p9@Eu?G2=MhT&a?c_{W*HIyv=}sL_EVx%OPGTp4xOw
z&ilk7D=8ZBIq|4P7bJe<y4vJ7&P9&}o+(<H^c=BBEEPLg?O;~2bmB?kn5G+)FJzmn
zao*yrSE{UaPyWJ4-dJAZI?X7OSimA=NKjEl85KB)(`t}nBTf4WAODc&m&v7)s|-et
zd2B$3;`zb<;CHunVPd?Q6iEQxFRuGB41{)pM$L7<k6pKM0tBCdE2Hh-r~}iVq}SS7
z><H-F1}?7Knz{#E?f`>NreZ0c6r?E>3c&jreNzq?xCO$i&E8u3IDG&z)K%&RI5-4G
zij=+P^X{I`-u^w)>hA|D7IKQ}?mZ9y000JJOGiWi{{a60|De66lK=n!32;bRa{vGh
z*8l(w*8xH(n|J^K00(qQO+^Ri3KS3>0I?L7p8x;>^+`lQR5;7!(m!ZZQ547V@40!2
z_K(3qTB)LFQ4<U8P(%{iY9~REQU@g{PIk@U;NsFnr*<;p>>vo@>OX`^(lkUW_y_wM
zEh2)TU@fE+8sB^OI3$gQDAr~X{7v`5xgYMi_Xz8fm?`bTvwOF%IL{xPJWyd1F?B3A
zH;QlHBjlIb{bKK<mu*dfYUQ$^&p<~7`r5WeMw$XeSX5*WZ~{Q!Yg1q#Tmrs;q*R!k
zITnAs8BqSFIGJDQ(7=luqm{7N^5W_6zSZA?iJY6la=g}l#TYv=J<#(J;OLXrohIUB
zfYa-`S_UR|e~w+fdq#pa$EnN8xC))XqQd^bnzulvf2y>@gn~TKfpSHSozg&}CS=Z{
zI{s<r{6XM+<1d4#a;q>D@2=ib3_v(!uYq(KV-qW@->-``-NuM148|@3X@zsi?EFXr
z_^b5K&V~h20ym@O$U<vNB#&?#c$mz(lZC<94NzA_FKh_hQfci1+O10QThtyA=tDRK
zWE92_Q9+6*hc*NTJ`n&yvMjI-z*;Sd$UD~dN*QW(e*&8t?0*(?elFD)k#r*KrfYBG
zDaHpyti4~KS1X<sJOL6}S8He822e3$Mzp7jsddD=H$Bw5l+4bh5Q$ccv|JcI{9z#X
l>W;6DXKJ%*)x6>V%?}a`yMJFvf|URO002ovPDHLkV1g)&&ujny

literal 0
HcmV?d00001

diff --git a/src/main/resources/templates/email/images/ic-slack.png b/src/main/resources/templates/email/images/ic-slack.png
new file mode 100644
index 0000000000000000000000000000000000000000..28976ec8fa0a9d5d433b8ff18105dc720cf9000c
GIT binary patch
literal 1285
zcmV+g1^W7lP)<h;3K|Lk000e1NJLTq000yK000yS1^@s6jfou%0004lX+uL$Nkc;*
zaB^>EX>4Tx04R}tkv&MmKpe$iQ>9WW3T6=LkfAzR5EXIMDionYs1;guFuC*#ni!H4
z7e~Rh;NZt%)xpJCR|i)?5c~jfb#YR3krMxx7Fxu3aNLh~_a1le0HI!Cy4^Jf=!RpZ
zlL;xCTaiMq2t!0aqJY9|b5@p9@Eu?G2=MhT&a?c_{W*HIyv=}sL_EVx%OPGTp4xOw
z&ilk7D=8ZBIq|4P7bJe<y4vJ7&P9&}o+(<H^c=BBEEPLg?O;~2bmB?kn5G+)FJzmn
zao*yrSE{UaPyWJ4-dJAZI?X7OSimA=NKjEl85KB)(`t}nBTf4WAODc&m&v7)s|-et
zd2B$3;`zb<;CHunVPd?Q6iEQxFRuGB41{)pM$L7<k6pKM0tBCdE2Hh-r~}iVq}SS7
z><H-F1}?7Knz{#E?f`>NreZ0c6r?E>3c&jreNzq?xCO$i&E8u3IDG&z)K%&RI5-4G
zij=+P^X{I`-u^w)>hA|D7IKQ}?mZ9y000JJOGiWi{{a60|De66lK=n!32;bRa{vGh
z*8l(w*8xH(n|J^K00(qQO+^Ri3KS3>1;Kt|5C8xJ14%?dR5;7MlwWAoWgNyo&wGAn
z^QhH?(!#pif&HN}a5?9;8dA}&x@eMi(?Up!QPf=_QLtjLn{JFC?axJOjp!m!NU?2g
zr=buw+C-%Yt)v1gHuvZJe(%$Tay)|x4x;z+`|^JHKJW8<zwjR)EmwT_#80aha`U^v
z>tdGwV4|ydam%sE4WTA^4sov3(Rgr0z_yVyhm3oGIpA__78@6G;V7^PSc9~q)Y0(S
za&N<OMdNOvK`U+t?w(J=W}sE(b>L@A+l@L*Zcv{v-Xn+ht2#mf#~eXr>_yvQMZkn)
zS4#G(<Yrr6Waad`B)62&F>>yXl<XjQi{Z<4Gs!bYx{C`HVC(Ri9g;gRHL25U(m5UF
zLnphMFKr!}UII*2ehq6g_+6n_{=TI=3hYY&wvJBk#QsF+g5`3RW48wL{I+k-6l3%p
zc0EuBnj`u?#A(P4L43j1?bjunB5(yUD44G@rwQvtr`o6xKQ!tCW<_?G5Q><`Ax;1n
zNy7e0Y}&@ouXjv`u-kxKm9ja+fl_-z-&G}NTN1Jhqn%B^Z8<i%LAAMiWtC^=7EgWu
z*!{DW*o<$h|GhTNx`FMMA4#)#SE;j6A*ddQkFWEy-W2_~b!6J1Cb=Z*E8zIrLjGvm
z*!lI94qJvN?@35Xh>h1i@AC+61v3JywzW^vM-V5F-w~RsnvGSq-v$OsosDlM0J)Gn
zi>Xr#4?4s_q6;GQAkPZ+BkvA@{usF;>uJM3RmSCk)xu{hrYQPPq=G}%1KNbb0qg?s
z7t(p`!dQF5udO3f9l%pqw^fXj7lnq$I~#{8z`EJ|`<K_I?LvEi(qg9meDL1t+_jwe
z;Z70uN?v1mDsjGlw6plfvXgS8ySM=CtiEU+UK-?FK6!u`pRgGR^=3+&fJbj?IRHqC
zKn>A(Aj_qmzbY}l41Uk1btTIIo07y!7H=Sp=bfEgaQH=p<3Is8eADX-;M<29K1J*T
v4=5y0e%;kP6Jyc}9+2EuH<R@8f1G~-jKWE_G^3Y400000NkvXXu0mjfM^9i%

literal 0
HcmV?d00001

diff --git a/src/main/resources/templates/email/images/ic-twitter.png b/src/main/resources/templates/email/images/ic-twitter.png
new file mode 100644
index 0000000000000000000000000000000000000000..5974ab542b228eb7e31f9435a9d257a7715da78f
GIT binary patch
literal 1233
zcmV;?1TOoDP)<h;3K|Lk000e1NJLTq000yK000yS1^@s6jfou%0004lX+uL$Nkc;*
zaB^>EX>4Tx04R}tkv&MmKpe$iQ>9WW3T6=LkfAzR5EXIMDionYs1;guFuC*#ni!H4
z7e~Rh;NZt%)xpJCR|i)?5c~jfb#YR3krMxx7Fxu3aNLh~_a1le0HI!Cy4^Jf=!RpZ
zlL;xCTaiMq2t!0aqJY9|b5@p9@Eu?G2=MhT&a?c_{W*HIyv=}sL_EVx%OPGTp4xOw
z&ilk7D=8ZBIq|4P7bJe<y4vJ7&P9&}o+(<H^c=BBEEPLg?O;~2bmB?kn5G+)FJzmn
zao*yrSE{UaPyWJ4-dJAZI?X7OSimA=NKjEl85KB)(`t}nBTf4WAODc&m&v7)s|-et
zd2B$3;`zb<;CHunVPd?Q6iEQxFRuGB41{)pM$L7<k6pKM0tBCdE2Hh-r~}iVq}SS7
z><H-F1}?7Knz{#E?f`>NreZ0c6r?E>3c&jreNzq?xCO$i&E8u3IDG&z)K%&RI5-4G
zij=+P^X{I`-u^w)>hA|D7IKQ}?mZ9y000JJOGiWi{{a60|De66lK=n!32;bRa{vGh
z*8l(w*8xH(n|J^K00(qQO+^Ri3KS3>3Q@s-fdBvk&q+i<R5;7clwXL{RTRfR=gzph
zsA2llf<?keGqXw$;x@l&W@nZLWGzBuOYzTxh;9%RMY%!{1VNDz^&nDUf|Owpp^1WQ
z%+Bw(<BaQok+#3zKCKY7_Mj2&Htp>E?&-m{WOv4go;*+Yp6~sBIEQmN@SsJ$IMs!!
zEZqM+q`ZlOQF&is_1%nK3mdY3ypXun4wmx#yeQu(d{ymB90V{6qCpNRtV0<=83B`v
zbjay^u^4RybKJ>ZQO*J@4f6YcoPR<s-vDbs$1AzSkQ&(qnxBhwA6Wt``5VEW2OdKC
zwj-Q=Ye~y@A5I)cWUsOInR33zb4vbUg!d5HU&+Ql2XKnlV?-h@&<$LCcqaP%g{|x7
zS_1RMsjj(5y#(@@4WpYc=VQO5yx^3;HZVCGnqN(%=>d-e<=J{;%a2>0oV}MJi`&V%
z6WvXu2HYgNG6NvZ8Bc|^sNMmIfsPwv3gt}v&SJk=obdXR)7F?Bzy@v39Id1ut=o`6
zRM&vS5Uvxo1Fc{!fdH2?PmC$@s=&UK7ravKPuws>hCx(A{h^ZHaQlCKTBkH|JmvcK
zX?OB9fVAho?zq0D+~B2l9@9?PRI4phctk)f_DF9jSa&I#_(<V|pr1T7HkoPVla@49
zlk$Qu1$HX(hp7Dvk>6(PjdZv+I=||ce6K3&n>06H$!+}k{uQc<;|9kBb^^1&v!DY&
zY{l}9lRqVs^Yfv;05qc#J+rA+TYg`l;{_ie90ckrJXh_Dmn*rRtAY%nY<JvX_)34z
zO%u^UAldoniqF~t9oK&ccmtS6c(IyIj4o)G`r==Je2nmJYHV_#oJm$ueOY0*Q}TzF
z0Ml-;2Y4F@Rb@{ln>e?)`p$6rO^{KsddeyJpMvxPw-L52T@GqHfrf}2sOI8dx0=;x
ve}6M<=nk+YgaSfAU<&Mqw43e&x557g*Nz{tB)=jw00000NkvXXu0mjfPLD#b

literal 0
HcmV?d00001

diff --git a/src/main/resources/templates/email/images/ic-youtube.png b/src/main/resources/templates/email/images/ic-youtube.png
new file mode 100644
index 0000000000000000000000000000000000000000..6aa386b1eca7ef36b54702346f94a46a6185e1d8
GIT binary patch
literal 1076
zcmV-41k3x0P)<h;3K|Lk000e1NJLTq000yK000yS1^@s6jfou%0004lX+uL$Nkc;*
zaB^>EX>4Tx04R}tkv&MmKpe$iQ>9WW3T6=LkfAzR5EXIMDionYs1;guFuC*#ni!H4
z7e~Rh;NZt%)xpJCR|i)?5c~jfb#YR3krMxx7Fxu3aNLh~_a1le0HI!Cy4^Jf=!RpZ
zlL;xCTaiMq2t!0aqJY9|b5@p9@Eu?G2=MhT&a?c_{W*HIyv=}sL_EVx%OPGTp4xOw
z&ilk7D=8ZBIq|4P7bJe<y4vJ7&P9&}o+(<H^c=BBEEPLg?O;~2bmB?kn5G+)FJzmn
zao*yrSE{UaPyWJ4-dJAZI?X7OSimA=NKjEl85KB)(`t}nBTf4WAODc&m&v7)s|-et
zd2B$3;`zb<;CHunVPd?Q6iEQxFRuGB41{)pM$L7<k6pKM0tBCdE2Hh-r~}iVq}SS7
z><H-F1}?7Knz{#E?f`>NreZ0c6r?E>3c&jreNzq?xCO$i&E8u3IDG&z)K%&RI5-4G
zij=+P^X{I`-u^w)>hA|D7IKQ}?mZ9y000JJOGiWi{{a60|De66lK=n!32;bRa{vGh
z*8l(w*8xH(n|J^K00(qQO+^Ri3KS3>5Uity`v3p}GD$>1R5;7!lTAp}K^Vq=@9g>)
zUEK-~N>m$Sp-6^l)M{7@LAMT}-a2&%f=<!d=pLPdI&`Z`UAvS;yN1<4u?%&S3Z*aX
zgEe#g-2XgXEFxEtPC@TwnBke<JoC&u@UNHsJ~?pzMYRipge;8XEpE;t@|bhl41hEv
zb0L86IppRQMkaTBuKReq+rnSKw!Unq&}CrTU)d5<!p=QCTz}J&nXx?>gTOsQH}Ezo
zxts;zyz_;bV*3}pRYbj&Dr!}RZN=M3jN=yZtx-93n_PaTDm*dL*toPoPq~%x6+p|t
zz@1<&HbucYos-)oDO(KIp3bJ)GGiB7dS7o^k3QJix(tlVtk!ucfiY1u8t1!Y^aQ0#
z<H^j}>8@Lfto^z+0VJFmm4>F*3H&|KhjH~?O?K$uqtT;9Wzsi{xC6?;Ev(&Gnt9UE
z(B-`E04hz^o9xS;U#+t_M7aYBlH7V3we^oCLg&r^31HN`rHdR~Vo-<*=FC}ao!(C<
zWXwTc(%Di!buFDr6;|_z3Gz|Hz93bv0h<S+z?C3exR_2gPp=&{HNdB+&>MsHVxl1Q
zJ<BDLOZ|uHKWyL+*Mc56upwY~GBeWrrzo9joZSelE&X!8pboQV)^zuIELIjg1{w^8
zg}uf2iZm}-zNi~h46`ysm7(o|CS)T^vDtP5IP!3$V$nrTf%akSG>8edtXw57_}S0}
u;QPvYPLM}Tn6tszxy9?l$M)v=|LO;$80;8TZvSuq0000<MNUMnLSTaKl=gc7

literal 0
HcmV?d00001

diff --git a/src/main/resources/templates/email/illustration.png b/src/main/resources/templates/email/images/illustration.png
similarity index 100%
rename from src/main/resources/templates/email/illustration.png
rename to src/main/resources/templates/email/images/illustration.png
diff --git a/src/main/resources/templates/email/logo.png b/src/main/resources/templates/email/images/logo.png
similarity index 100%
rename from src/main/resources/templates/email/logo.png
rename to src/main/resources/templates/email/images/logo.png
diff --git a/src/main/resources/templates/email/images/new-ic-facebook.png b/src/main/resources/templates/email/images/new-ic-facebook.png
new file mode 100644
index 0000000000000000000000000000000000000000..a0e162be75f4f31b3dbe954795d4e941476eeaf5
GIT binary patch
literal 976
zcmV;>126oEP)<h;3K|Lk000e1NJLTq001Ze001Zm1^@s6jQ+T70004mX+uL$Nkc;*
zaB^>EX>4Tx04R}tkv&MmKpe$iTWh7XIJAR^Lx$>PK~%(1t5Adrp;l<s!Q|2}XktiG
zTpR`0f`cE6RR<SmT^(EnLGS~_)x}BCMN0f%QfLw5!Ery{-Fw`<1N_YzQ_Y?+K-DZG
zn@$P&!io@jMHn#z5k;@WOnp`qGw>W=_we!cF3GdJ&;2=~O3`G1PavLQx?vHo6Hjeg
zI_G`jIIBns@j3CRK^G)`<htzg8|Sjaex4aOa@jfJII&RfV!4Z1#ZZYSi4%&dQNBO#
zvch?bvs$aO_C5IvBSmd_iR(0nkj4TQAwqzRI;yC_LXuXE6cbt6PkHzU9luB}nOs#c
za?E1`DkR4b{s+IiHA@rYZc-!#1Yd0XV;BhS0<DH^e;?a+>jVfq16NwdztIGyKS^(N
zw8Rn6zYSbmcQknqxZD8-o^;8O94SE4Un&9bXY@@4Aa)CcSKZ#)`#607a@1Ak1~@nb
zM#_}E=JD>n?%w`A)9&vF_I7f0@Al3}00006VoOIv0RI600RN!9r;`8x010qNS#tmY
z4c7nw4c7reD4Tcy000McNliru=L!=BDKbZu(~|%I0nJH7K~z}7?Uuhw8(|oLpZ9XK
zgFoodu}e26TSXL0+oe-UGGxd>3yDTC{uSN(C)6&16fzukskv??h(Sb<wtqpOW(eru
zAXaE{ufv@hC0%kyF2nas_x<Gg-tT?64-5u_!7$cHTpKkS4g1gO#kwd(&{>el+fi*6
zoy@CY_O;`XtJQWMAD{gFCa^sC-12hRy{)KnuIr|Hw)GWs8E7Hu{Cn7)E;?x`I_bza
z6gh&IOuPqP1MMEXDCIMqICC(vprR`hT<M3BlkQZucV<$)^-<tSFrKiWAoBoS!~;nA
zRt=cDC)Q3(5O@So%D+8b3);^Ce01S@LKnN0q@VzZi1xQvoy<{UIaqb;>tHQjXW`&E
z-?wf~AbL>9rz<0jpnL-DTdU`Hzhx4%eAA=614bzrtP^w-K>XCtzN&s>g?XsL0xBDz
zzZ1#9f|L1tzi-9K9s-BKHG5A3YuQUg@QYh7hZXxP6r;NBEs3ws!f0lLnz5Rr7VHAH
zB3ohEo&!?^wm%e^=%3qraJfHHK~>olVJU2t@4j3J<s`g*-7V#EXNkSns;;M1*VF&C
yqhc}U7(pYLG<KZTJf;!UL4S!o3<iV25DQnF6q51Xt4BZp0000<MNUMnLSTX%r?_JP

literal 0
HcmV?d00001

diff --git a/src/main/resources/templates/email/new-ic-github.png b/src/main/resources/templates/email/images/new-ic-github.png
similarity index 100%
rename from src/main/resources/templates/email/new-ic-github.png
rename to src/main/resources/templates/email/images/new-ic-github.png
diff --git a/src/main/resources/templates/email/new-ic-linkedin.png b/src/main/resources/templates/email/images/new-ic-linkedin.png
similarity index 100%
rename from src/main/resources/templates/email/new-ic-linkedin.png
rename to src/main/resources/templates/email/images/new-ic-linkedin.png
diff --git a/src/main/resources/templates/email/new-ic-slack.png b/src/main/resources/templates/email/images/new-ic-slack.png
similarity index 100%
rename from src/main/resources/templates/email/new-ic-slack.png
rename to src/main/resources/templates/email/images/new-ic-slack.png
diff --git a/src/main/resources/templates/email/images/new-ic-twitter.png b/src/main/resources/templates/email/images/new-ic-twitter.png
new file mode 100644
index 0000000000000000000000000000000000000000..a1e4d788c8c7d4df182949dbb5bd8cfed2bd647a
GIT binary patch
literal 1593
zcmV-92FCe`P)<h;3K|Lk000e1NJLTq001Ze001Zm1^@s6jQ+T70004mX+uL$Nkc;*
zaB^>EX>4Tx04R}tkv&MmKpe$iTWh7XIJAR^Lx$>PK~%(1t5Adrp;l<s!Q|2}XktiG
zTpR`0f`cE6RR<SmT^(EnLGS~_)x}BCMN0f%QfLw5!Ery{-Fw`<1N_YzQ_Y?+K-DZG
zn@$P&!io@jMHn#z5k;@WOnp`qGw>W=_we!cF3GdJ&;2=~O3`G1PavLQx?vHo6Hjeg
zI_G`jIIBns@j3CRK^G)`<htzg8|Sjaex4aOa@jfJII&RfV!4Z1#ZZYSi4%&dQNBO#
zvch?bvs$aO_C5IvBSmd_iR(0nkj4TQAwqzRI;yC_LXuXE6cbt6PkHzU9luB}nOs#c
za?E1`DkR4b{s+IiHA@rYZc-!#1Yd0XV;BhS0<DH^e;?a+>jVfq16NwdztIGyKS^(N
zw8Rn6zYSbmcQknqxZD8-o^;8O94SE4Un&9bXY@@4Aa)CcSKZ#)`#607a@1Ak1~@nb
zM#_}E=JD>n?%w`A)9&vF_I7f0@Al3}00006VoOIv0RI600RN!9r;`8x010qNS#tmY
z4c7nw4c7reD4Tcy000McNliru=L!=BC?u*{SAzfm1U5-TK~z}7?U!wclvNbRf9ILi
zeJwF9i(<usJ_x2P8d_!;NV+qtf$g)4>&%jAOOh30nh?}LV7L?_y)B9D%xv4vom_Bd
zXUqgwD0*@IVx&c}iGm+Q@}+inX4{#2`Y<DDh>o?cADaKC=Q;PBdw=)d=bZaoD5|KU
ziu!*`#(O|x`l?14UQo)=SFY=(uIFD;NT*?wd>k|cO#j=egQ)ZI!13>14hDm^kbXkl
z-BZ$;;XYtiimD!9#r0yG0w=!hN;m+iLUh9eGar7lkPbRJlDA8ybRRG)w{<$TkhlT?
zwG2RnHv+C#0<Kq7^$8$@@M<KQaId|srd%g#9GI7%+;3QI88bkEEkIV4*CWy7Qvl5k
zzCIP*2#5;1BVF;?SBq_HJ2D|nWlUjF-t@a;Wm%xn_rsVbNysE#5!enoh-Ja00YcHl
zM<T2RPG*pKYuwtim#v&9P30#*L*A4Uv9<pCx<iGITj)1Pv+HdI+Ci#tq^GkpJ{2H+
zVcL4&OJI5lw%Zsp5kOTXrIjCE1~)2b{f)rg5FkKysN#8`ADEFTaXO7Lo|cxmqgil)
z(;y4eQrQX+F^Sgv$^v8+@%vq0;-=TZu!&cL(+}Jw(CT-+n*lnylJl*jhk#Ongo5`{
zhKcZ;zuvoR+zNGjH2J6_dJvchGzDC5CqN{Y45-@B72S$#3e?xWJ?<w-DAv1PRNe#9
zj&&BTZd}$65RN6jM{~6fWqY8(yXC)}JkGxjY_9jcugWf<%sTe7$ez#d0Z5&jHXq?a
ze)<b{CX=PN1Q6ijZSn%}HBhbD?6J1CBNZ(zbB9MXTLYW~9+~uqzI)36U#zVi!RihX
z6qsCg$C+;c*15}1h_x$#AraPwV!i8c31HalTZkj=s=04jl!wA*-?ISz#=4`TtOHb3
zcC<$mi^df&ceL3apdyzKdMwvsKZwM79|Q0=ct1sH1tvHm-C@%+V_X13U5N+ParOg~
zb8viHPUU=roxlWDF&%r7_W=wXKfDz*2|7jabhpLh6*m<yY~t18Z~&N=Hyte*)mqnG
zJXoef8$tF1ciSv`jWOlHV9<I-S*`Gk!kqGy6INBZDS#mpzZaZ7pgM2*xg?W$vZ={;
z9>8_o?4LNRfC12&G?i@tO-;V@*0IZhi@?foEV*gS0XsY6Qw8S>;QqYn6xb!JR;@U5
zx!+oM={d1>B`^f|L$Tfs0M9&K_mc|EfC_Ajn8cDX12pEqq)drtKQJ?II_+_EaloxR
zbv6Hd2CvCy@H?Ss@8Vo>_wE%T2zV5EtB|n^x|5`2WV5K$<X_KXbxD)!`}JBe{sylJ
zM-y`pwu;EXu*v<%s9y50!(+CB4ss&@cwVes8ff(WSV-K!@x!m>GFu1#(R4zrzBH!S
r#Yk6t_HL8Bvv^Z4s;Huh8ejbdXOyDwoU_2-00000NkvXXu0mjfMAYR}

literal 0
HcmV?d00001

diff --git a/src/main/resources/templates/email/new-ic-youtube.png b/src/main/resources/templates/email/images/new-ic-youtube.png
similarity index 100%
rename from src/main/resources/templates/email/new-ic-youtube.png
rename to src/main/resources/templates/email/images/new-ic-youtube.png
diff --git a/src/main/resources/templates/email/new-logo.png b/src/main/resources/templates/email/images/new-logo.png
similarity index 100%
rename from src/main/resources/templates/email/new-logo.png
rename to src/main/resources/templates/email/images/new-logo.png
diff --git a/src/main/resources/templates/email/restore-password.png b/src/main/resources/templates/email/images/restore-password.png
similarity index 100%
rename from src/main/resources/templates/email/restore-password.png
rename to src/main/resources/templates/email/images/restore-password.png
diff --git a/src/main/resources/templates/email/index-finished-template.ftl b/src/main/resources/templates/email/index-finished-template.ftl
index cc168b5d4c..132eec19f4 100644
--- a/src/main/resources/templates/email/index-finished-template.ftl
+++ b/src/main/resources/templates/email/index-finished-template.ftl
@@ -70,7 +70,7 @@
                             You can start to use Auto-Analyzer on your project.
                         </p>
                         <p height='34' style="margin: 5px 0 0 0;font-size: 14px;color: #777777;">
-                            ElasticSearch Index contains <b>${indexedLogsCount}</b> record(s) now.
+                            The search engine Index contains <b>${indexedLogsCount}</b> record(s) now.
                         </p>
                         <h3 style="margin:25px 0 0 0;font-size: 14px;font-weight: bold;color: #777777;">Your ReportPortal.io Team</h3>
                     </td>
diff --git a/src/main/resources/templates/email/new-ic-twitter.png b/src/main/resources/templates/email/new-ic-twitter.png
deleted file mode 100644
index 1101c16d5b293ffefebc6683048c43ec2b5ac3c2..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 690
zcmV;j0!{siP)<h;3K|Lk000e1NJLTq001Ze001Zm1^@s6jQ+T700009a7bBm000XU
z000XU0RWnu7ytkO0drDELIAGL9O(c600d`2O+f$vv5yP<VFdsH0!K+iK~#7F?Uqq)
z(?Af0XEsj70}nZZxj{KW!wV9MBH;&uDioTWfO3M86VRT(lz=KFNGU=gkK_h*Z{Q>3
zp)b_y9cD{gMN#b?JBic>f0Cs{`7`@_W@mQ*Dk>@}DjqcmTVyz%H3?{!3^f#B^mOO%
zJP3ltvgT|u^Y?>SF|1>7GMO}11Lt8E)tW*gYOeeg^D}tgX??Ng0q6*bF1wx9VOA^!
z0<Ls@@_jVjm1ynDBnka_z?{YBCmfEZ7ewYpqf>R97td+XW`hWuDX(omyYyH3$p_9%
zu8sh1UY1P``uo}C6&ciNa+f(jNzBF9(X^NU5AzyC;Q7JZ_9vIhX^_bCm%cXm3BUcA
zhFRGp0?}6B@?J`Go-+`4Ag;8MG0-!{^oHZ#b1v6U<POyy#Qh+@TxD<?%;UBZ>`?->
z1c1vg{x1@WP6cO)QK9&FDFRm|mgw9DA&p=QX!K%<&fUeHj(DGKI*W0?^HTKUPJ?}W
zgAkm+W|>QcqMO9*Tpw>Ti-_h_sudZuSyX5O*Z_z)@4jizrFxM;%Wcp;tcfD}SV&()
zY^RVkRnIsNF_ggGz3)1$LZ?FMdC=a;ye~iF|Lae(P{d=^b0|om4BlbyVWnWNh&f%q
zegP#AXE0<_wZt@elOJTvdKn9tlWwPd2qnoiI2`|K0@RM!keyIO*}4zR-3pKnigfIQ
zaU>#Z)EMj`sy)Xry5LQ7j$}^PHCD*rGU3_G_dLy0w({?TsC1!g^=KR8Rz*ccMa3iM
YA5GBjPjzfvwEzGB07*qoM6N<$g4NbCo&W#<

diff --git a/src/main/resources/templates/email/registration-template.ftl b/src/main/resources/templates/email/registration-template.ftl
index 8501ed695a..6b731360c8 100644
--- a/src/main/resources/templates/email/registration-template.ftl
+++ b/src/main/resources/templates/email/registration-template.ftl
@@ -1,167 +1,194 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-    <title>ReportPortal</title>
-    <link href='http://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'>
-    <style>
-        body {
-            margin: 0;
-            padding: 0;
-        }
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+  <title>ReportPortal</title>
+  <link href='http://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'>
+  <style>
+    body {
+      margin: 0;
+      padding: 0;
+    }
 
-        a, a:active, a:visited {
-            color: #39c2d7;
-            text-decoration: underline;
-        }
+    a, a:active, a:visited {
+      color: #39c2d7;
+      text-decoration: underline;
+    }
 
-        a:hover {
-            text-decoration: none;
-        }
+    a:hover {
+      text-decoration: none;
+    }
 
-        .rplogo, .rplogo:hover, .rplogo:active, .rplogo:visited {
-            display: inline-block;
-            text-decoration: none;
-        }
+    .rplogo, .rplogo:hover, .rplogo:active, .rplogo:visited {
+      display: inline-block;
+      text-decoration: none;
+    }
 
-        @media only screen and (max-width: 540px) {
-            body {
-                margin: 0;
-                padding: 0;
-            }
+    @media only screen and (max-width: 540px) {
+      body {
+        margin: 0;
+        padding: 0;
+      }
 
-            table[class="mainwrapper"] {
-                width: 100% !important;
-            }
+      table[class="mainwrapper"] {
+        width: 100% !important;
+      }
 
-            .rplogo {
-                margin-left: 15px;
-            }
+      .rplogo {
+        margin-left: 15px;
+      }
 
-            table[class="mainimgwrapper"] {
-                height: 130px;
-                background-image: url("create-user.png");
-                background-size: cover;
-                background-position: center;
-            }
+      table[class="mainimgwrapper"] {
+        height: 130px;
+        background-image: url("images/create-user.png");
+        background-size: cover;
+        background-position: center;
+      }
 
-            .mainimg {
-                display: none;
-            }
-        }
-    </style>
+      .mainimg {
+        display: none;
+      }
+    }
+  </style>
 </head>
-<body bgcolor="#f9f9f9" topmargin="0" bottommargin="0" leftmargin="0" rightmargin="0" link="#39c2d7" alink="#39c2d7" vlink="#39c2d7"
+<body bgcolor="#f9f9f9" topmargin="0" bottommargin="0" leftmargin="0" rightmargin="0" link="#39c2d7"
+      alink="#39c2d7" vlink="#39c2d7"
       style="font-family: OpenSans, sans-serif;">
 <table width="540" border="0" cellspacing="0" cellpadding="0" align="center" class="mainwrapper">
-    <tbody>
-    <tr>
-        <td>
-            <table width="100%" border="0" cellspacing="0" cellpadding="0" class="logowrapper">
-                <tbody>
-                <tr>
-                    <td height="48">
-                        <a class="rplogo" href="http://reportportal.io" target="_blank"
-                           style="font-size: 15px; color: #595c5c; font-weight: bold; font-family: 'Roboto', sans-serif;">
-                            ReportPortal.io
-                        </a>
-                    </td>
-                </tr>
-                </tbody>
+  <tbody>
+  <tr>
+    <td>
+      <table width="100%" border="0" cellspacing="0" cellpadding="0" class="logowrapper">
+        <tbody>
+        <tr>
+          <td height="48">
+            <a class="rplogo" href="http://reportportal.io" target="_blank"
+               style="font-size: 15px; color: #595c5c; font-weight: bold; font-family: 'Roboto', sans-serif;">
+              ReportPortal.io
+            </a>
+          </td>
+        </tr>
+        </tbody>
+      </table>
+      <table width="100%" border="0" cellspacing="0" cellpadding="0" class="mainimgwrapper">
+        <tbody>
+        <tr>
+          <td height="130">
+            <img class="mainimg" src="cid:create-user.png" border="0" width="540" height="130"
+                 alt="You’ve been invited to join ReportPortal">
+          </td>
+        </tr>
+        </tbody>
+      </table>
+      <table width="100%" border="0" cellspacing="0" cellpadding="30" class="contentwrapper"
+             bgcolor="#ffffff">
+        <tbody>
+        <tr>
+          <td align="left" height="170">
+            <h2 style="font-size: 20px; color: #777777;" align="center">Welcome to
+              ReportPortal!</h2>
+            <p style="font-size: 14px; color: #777777;">You’ve been invited to join
+              ReportPortal.</p>
+            <p style="font-size: 14px; line-height: 1.7; color: #777777">Click the link below to
+              create your account and get
+              started.</p>
+            <table border="0" cellspacing="8" cellpadding="0" align="center">
+              <tbody>
+              <tr>
+                <td width="130" height="35" align="center" bgcolor="#a3c644">
+                  <a href="${url}"
+                     style="font-size: 14px; text-decoration: none; color: #ffffff; display: inline-block; padding: 10px 15px; width: 100px;">
+                    Get Started
+                  </a>
+                </td>
+              </tr>
+              </tbody>
             </table>
-            <table width="100%" border="0" cellspacing="0" cellpadding="0" class="mainimgwrapper">
-                <tbody>
-                <tr>
-                    <td height="130">
-                        <img class="mainimg" src="cid:create-user.png" border="0" width="540" height="130"
-                             alt="You’ve been invited to join ReportPortal">
-                    </td>
-                </tr>
-                </tbody>
+            <p style="font-size: 14px; color: #777777;">New to ReportPortal? Check out the <a
+                  href="https://reportportal.io/docs/reportportal-tutorial/?utm_source=trigger&utm_medium=email&utm_campaign=tutorial&utm_content=invitation"
+                  target="_blank">ReportPortal Tutorial</a>.</p>
+            <br>
+            <p style="font-size: 14px; line-height: 1.7; color: #777777;">Thanks,<br>
+              ReportPortal.io Team</p>
+          </td>
+        </tr>
+        </tbody>
+      </table>
+      <table width="100%" height="82" border="0" cellspacing="0" cellpadding="0"
+             class="linkswrapper">
+        <tbody>
+        <tr>
+          <td height="82" align="center">
+            <table border="0" cellspacing="0" cellpadding="12" class="linksline" align="center">
+              <tbody>
+              <tr>
+                <td>
+                  <p style="font-size: 13px; color: #464547;">Keep in touch with us:</p>
+                </td>
+                <td>
+                  <a href="http://twitter.com/ReportPortal_io" target="_blank">
+                    <img src="cid:ic-twitter.png" alt="twitter">
+                  </a>
+                </td>
+                <td>
+                  <a href="https://slack.epmrpp.reportportal.io" target="_blank">
+                    <img src="cid:ic-slack.png" alt="slack">
+                  </a>
+                </td>
+                <td>
+                  <a href="https://www.youtube.com/c/ReportPortal" target="_blank">
+                    <img src="cid:ic-youtube.png" alt="youtube">
+                  </a>
+                </td>
+                <td>
+                  <a href="https://www.linkedin.com/company/reportportal/" target="_blank">
+                    <img src="cid:ic-linkedin.png" alt="linkedin">
+                  </a>
+                </td>
+                <td>
+                  <a href="https://www.facebook.com/ReportPortal.io" target="_blank">
+                    <img src="cid:ic-facebook.png" alt="facebook">
+                  </a>
+                </td>
+                <td>
+                  <a href="https://github.com/reportportal" target="_blank">
+                    <img src="cid:ic-github.png" alt="github">
+                  </a>
+                </td>
+              </tr>
+              </tbody>
             </table>
-            <table width="100%" border="0" cellspacing="0" cellpadding="30" class="contentwrapper" bgcolor="#ffffff">
-                <tbody>
-                <tr>
-                    <td align="left" height="170">
-                        <h2 style="font-size: 20px; color: #777777;" align="center">Welcome to ReportPortal!</h2>
-                        <p style="font-size: 14px; color: #777777;">You’ve been invited to join ReportPortal.</p>
-                        <p style="font-size: 14px; line-height: 1.7; color: #777777">Click the link below to create your account and get
-                            started.</p>
-                        <table border="0" cellspacing="8" cellpadding="0" align="center">
-                            <tbody>
-                            <tr>
-                                <td width="130" height="35" align="center" bgcolor="#a3c644">
-                                    <a href="${url}"
-                                       style="font-size: 14px; text-decoration: none; color: #ffffff; display: inline-block; padding: 10px 15px; width: 100px;">
-                                        Get Started
-                                    </a>
-                                </td>
-                            </tr>
-                            </tbody>
-                        </table>
-                        <p style="font-size: 14px; color: #777777;">New to ReportPortal? Check out the <a
-                                href="https://reportportal.io/docs/reportportal-tutorial/?utm_source=trigger&utm_medium=email&utm_campaign=tutorial&utm_content=invitation"
-                                target="_blank">ReportPortal Tutorial</a>.</p>
-                        <br>
-                        <p style="font-size: 14px; line-height: 1.7; color: #777777;">Thanks,<br>
-                            ReportPortal.io Team</p>
-                    </td>
-                </tr>
-                </tbody>
-            </table>
-            <table width="100%" height="82" border="0" cellspacing="0" cellpadding="0" class="linkswrapper">
-                <tbody>
-                <tr>
-                    <td height="82" align="center">
-                        <table border="0" cellspacing="0" cellpadding="12" class="linksline" align="center">
-                            <tbody>
-                            <tr>
-                                <td><p style="font-size: 13px; color: #464547;">Keep in touch with us:</p></td>
-                                <td><a href="https://github.com/reportportal" target="_blank"><img src="cid:ic-github.png" border="0"
-                                                                                                   width="20" height="21" alt="github"></a>
-                                </td>
-                                <td><a href="http://twitter.com/ReportPortal_io" target="_blank"><img src="cid:ic-twitter.png" border="0"
-                                                                                                      width="20" height="16" alt="twitter"></a>
-                                </td>
-                                <td><a href="https://www.youtube.com/c/ReportPortal" target="_blank"><img src="cid:ic-youtube.png"
-                                                                                                              border="0" width="20"
-                                                                                                              height="15" alt="youtube"></a>
-                                </td>
-                                <td><a href="https://slack.epmrpp.reportportal.io" target="_blank"><img src="cid:ic-slack.png"
-                                                                                                                 border="0" width="18"
-                                                                                                                 height="18"
-                                                                                                                 alt="slack"></a></td>
-                            </tr>
-                            </tbody>
-                        </table>
-                    </td>
-                </tr>
-                </tbody>
-            </table>
-            <table width="100%" border="0" cellspacing="0" cellpadding="0" bgcolor="#bdc7cc" class="footerline">
-                <tbody>
-                <tr>
-                    <td height="1"><!-- --></td>
-                </tr>
-                </tbody>
-            </table>
-            <table width="100%" border="0" cellspacing="0" cellpadding="0" class="footerwrapper">
-                <tbody>
-                <tr>
-                    <td align="center" height="52" class="footercontent" style="padding: 4px;">
-                        <p style="font-size: 11px; line-height: 1.5; color: #6d6d6d">
-                            <b>ReportPortal Notification Center</b><br>
-                            This is an automatically generated notification - please do not reply to this message. You are receiving this
-                            email to complete the registration initiated on the ReportPortal application; if you are not waiting
-                            for the ReportPortal's invitation then just ignore this message.
-                        </p>
-                    </td>
-                </tr>
-                </tbody>
-            </table>
-        </td>
-    </tr>
-    </tbody>
+          </td>
+        </tr>
+        </tbody>
+      </table>
+      <table width="100%" border="0" cellspacing="0" cellpadding="0" bgcolor="#bdc7cc"
+             class="footerline">
+        <tbody>
+        <tr>
+          <td height="1"><!-- --></td>
+        </tr>
+        </tbody>
+      </table>
+      <table width="100%" border="0" cellspacing="0" cellpadding="0" class="footerwrapper">
+        <tbody>
+        <tr>
+          <td align="center" height="52" class="footercontent" style="padding: 4px;">
+            <p style="font-size: 11px; line-height: 1.5; color: #6d6d6d">
+              <b>ReportPortal Notification Center</b><br>
+              This is an automatically generated notification - please do not reply to this message.
+              You are receiving this
+              email to complete the registration initiated on the ReportPortal application; if you
+              are not waiting
+              for the ReportPortal's invitation then just ignore this message.
+            </p>
+          </td>
+        </tr>
+        </tbody>
+      </table>
+    </td>
+  </tr>
+  </tbody>
 </table>
 </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/src/main/resources/templates/email/restore-password-template.ftl b/src/main/resources/templates/email/restore-password-template.ftl
index b54d40756b..818531fa57 100644
--- a/src/main/resources/templates/email/restore-password-template.ftl
+++ b/src/main/resources/templates/email/restore-password-template.ftl
@@ -1,161 +1,188 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-    <title>ReportPortal</title>
-    <link href='http://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'>
-    <style>
-        body {
-            margin: 0;
-            padding: 0;
-            font-family: OpenSans, sans-serif;
-        }
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+  <title>ReportPortal</title>
+  <link href='http://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'>
+  <style>
+    body {
+      margin: 0;
+      padding: 0;
+      font-family: OpenSans, sans-serif;
+    }
 
-        a, a:active, a:visited {
-            color: #39c2d7;
-            text-decoration: underline;
-        }
+    a, a:active, a:visited {
+      color: #39c2d7;
+      text-decoration: underline;
+    }
 
-        a:hover {
-            text-decoration: none;
-        }
+    a:hover {
+      text-decoration: none;
+    }
 
-        .rplogo, .rplogo:hover, .rplogo:active, .rplogo:visited {
-            display: inline-block;
-            text-decoration: none;
-        }
+    .rplogo, .rplogo:hover, .rplogo:active, .rplogo:visited {
+      display: inline-block;
+      text-decoration: none;
+    }
 
-        @media only screen and (max-width: 540px) {
-            body {
-                margin: 0;
-                padding: 0;
-            }
+    @media only screen and (max-width: 540px) {
+      body {
+        margin: 0;
+        padding: 0;
+      }
 
-            table[class="mainwrapper"] {
-                width: 100% !important;
-            }
+      table[class="mainwrapper"] {
+        width: 100% !important;
+      }
 
-            .rplogo {
-                margin-left: 15px;
-            }
+      .rplogo {
+        margin-left: 15px;
+      }
 
-            table[class="mainimgwrapper"] {
-                height: 130px;
-                background-image: url("restore-password.png");
-                background-size: cover;
-                background-position: center;
-            }
+      table[class="mainimgwrapper"] {
+        height: 130px;
+        background-image: url("images/restore-password.png");
+        background-size: cover;
+        background-position: center;
+      }
 
-            .mainimg {
-                display: none;
-            }
-        }
-    </style>
+      .mainimg {
+        display: none;
+      }
+    }
+  </style>
 </head>
-<body bgcolor="#f9f9f9" topmargin="0" bottommargin="0" leftmargin="0" rightmargin="0" link="#39c2d7" alink="#39c2d7" vlink="#39c2d7"
+<body bgcolor="#f9f9f9" topmargin="0" bottommargin="0" leftmargin="0" rightmargin="0" link="#39c2d7"
+      alink="#39c2d7" vlink="#39c2d7"
       style="font-family: OpenSans, sans-serif;">
 <table width="540" border="0" cellspacing="0" cellpadding="0" align="center" class="mainwrapper">
-    <tbody>
-    <tr>
-        <td>
-            <table width="100%" border="0" cellspacing="0" cellpadding="0" class="logowrapper">
-                <tbody>
-                <tr>
-                    <td height="48">
-                        <a class="rplogo" href="http://reportportal.io" target="_blank"
-                           style="font-size: 15px; color: #595c5c; font-weight: bold; font-family: 'Roboto', sans-serif;">
-                            ReportPortal.io
-                        </a>
-                    </td>
-                </tr>
-                </tbody>
+  <tbody>
+  <tr>
+    <td>
+      <table width="100%" border="0" cellspacing="0" cellpadding="0" class="logowrapper">
+        <tbody>
+        <tr>
+          <td height="48">
+            <a class="rplogo" href="http://reportportal.io" target="_blank"
+               style="font-size: 15px; color: #595c5c; font-weight: bold; font-family: 'Roboto', sans-serif;">
+              ReportPortal.io
+            </a>
+          </td>
+        </tr>
+        </tbody>
+      </table>
+      <table width="100%" border="0" cellspacing="0" cellpadding="0" class="mainimgwrapper">
+        <tbody>
+        <tr>
+          <td height="130">
+            <img class="mainimg" src="cid:restore-password.png" border="0" width="540" height="130"
+                 alt="Restore your password to ReportPortal">
+          </td>
+        </tr>
+        </tbody>
+      </table>
+      <table width="100%" border="0" cellspacing="0" cellpadding="30" class="contentwrapper"
+             bgcolor="#ffffff">
+        <tbody>
+        <tr>
+          <td align="left" height="170">
+            <h2 style="font-size: 20px; color: #777777;" align="center">Forgot your password to
+              ReportPortal?</h2>
+            <p style="font-size: 14px; color: #777777;">Click the link below to choose a new
+              one.</p>
+            <table border="0" cellspacing="8" cellpadding="0" align="center">
+              <tbody>
+              <tr>
+                <td width="150" height="35" align="center" bgcolor="#a3c644">
+                  <a href="${url}"
+                     style="font-size: 14px; text-decoration: none; color: #ffffff; display: inline-block; padding: 10px 15px; width: 120px;">
+                    Reset Password
+                  </a>
+                </td>
+              </tr>
+              </tbody>
             </table>
-            <table width="100%" border="0" cellspacing="0" cellpadding="0" class="mainimgwrapper">
-                <tbody>
-                <tr>
-                    <td height="130">
-                        <img class="mainimg" src="cid:restore-password.png" border="0" width="540" height="130"
-                             alt="Restore your password to ReportPortal">
-                    </td>
-                </tr>
-                </tbody>
+            <p style="font-size: 14px; color: #777777;">P.S. If you didn’t request this email, you
+              can just ignore it.</p>
+          </td>
+        </tr>
+        </tbody>
+      </table>
+      <table width="100%" height="82" border="0" cellspacing="0" cellpadding="0"
+             class="linkswrapper">
+        <tbody>
+        <tr>
+          <td height="82" align="center">
+            <table border="0" cellspacing="0" cellpadding="12" class="linksline" align="center">
+              <tbody>
+              <tr>
+                <td>
+                  <p style="font-size: 13px; color: #464547;">Keep in touch with us:</p>
+                </td>
+                <td>
+                  <a href="http://twitter.com/ReportPortal_io" target="_blank">
+                    <img src="cid:ic-twitter.png" alt="twitter">
+                  </a>
+                </td>
+                <td>
+                  <a href="https://slack.epmrpp.reportportal.io" target="_blank">
+                    <img src="cid:ic-slack.png" alt="slack">
+                  </a>
+                </td>
+                <td>
+                  <a href="https://www.youtube.com/c/ReportPortal" target="_blank">
+                    <img src="cid:ic-youtube.png" alt="youtube">
+                  </a>
+                </td>
+                <td>
+                  <a href="https://www.linkedin.com/company/reportportal/" target="_blank">
+                    <img src="cid:ic-linkedin.png" alt="linkedin">
+                  </a>
+                </td>
+                <td>
+                  <a href="https://www.facebook.com/ReportPortal.io" target="_blank">
+                    <img src="cid:ic-facebook.png" alt="facebook">
+                  </a>
+                </td>
+                <td>
+                  <a href="https://github.com/reportportal" target="_blank">
+                    <img src="cid:ic-github.png" alt="github">
+                  </a>
+                </td>
+              </tr>
+              </tbody>
             </table>
-            <table width="100%" border="0" cellspacing="0" cellpadding="30" class="contentwrapper" bgcolor="#ffffff">
-                <tbody>
-                <tr>
-                    <td align="left" height="170">
-                        <h2 style="font-size: 20px; color: #777777;" align="center">Forgot your password to ReportPortal?</h2>
-                        <p style="font-size: 14px; color: #777777;">Click the link below to choose a new one.</p>
-                        <table border="0" cellspacing="8" cellpadding="0" align="center">
-                            <tbody>
-                            <tr>
-                                <td width="150" height="35" align="center" bgcolor="#a3c644">
-                                    <a href="${url}"
-                                       style="font-size: 14px; text-decoration: none; color: #ffffff; display: inline-block; padding: 10px 15px; width: 120px;">
-                                        Reset Password
-                                    </a>
-                                </td>
-                            </tr>
-                            </tbody>
-                        </table>
-                        <p style="font-size: 14px; color: #777777;">P.S. If you didn’t request this email, you can just ignore it.</p>
-                    </td>
-                </tr>
-                </tbody>
-            </table>
-            <table width="100%" height="82" border="0" cellspacing="0" cellpadding="0" class="linkswrapper">
-                <tbody>
-                <tr>
-                    <td height="82" align="center">
-                        <table border="0" cellspacing="0" cellpadding="12" class="linksline" align="center">
-                            <tbody>
-                            <tr>
-                                <td><p style="font-size: 13px; color: #464547;">Keep in touch with us:</p></td>
-                                <td><a href="https://github.com/reportportal" target="_blank"><img src="cid:ic-github.png" border="0"
-                                                                                                   width="20" height="21" alt="github"></a>
-                                </td>
-                                <td><a href="http://twitter.com/ReportPortal_io" target="_blank"><img src="cid:ic-twitter.png" border="0"
-                                                                                                      width="20" height="16" alt="twitter"></a>
-                                </td>
-                                <td><a href="https://www.youtube.com/c/ReportPortal" target="_blank"><img src="cid:ic-youtube.png"
-                                                                                                              border="0" width="20"
-                                                                                                              height="15" alt="youtube"></a>
-                                </td>
-                                <td><a href="https://slack.epmrpp.reportportal.io" target="_blank"><img src="cid:ic-slack.png"
-                                                                                                                  border="0" width="18"
-                                                                                                                  height="18"
-                                                                                                                  alt="slack"></a></td>
-                            </tr>
-                            </tbody>
-                        </table>
-                    </td>
-                </tr>
-                </tbody>
-            </table>
-            <table width="100%" border="0" cellspacing="0" cellpadding="0" bgcolor="#bdc7cc" class="footerline">
-                <tbody>
-                <tr>
-                    <td height="1"><!-- --></td>
-                </tr>
-                </tbody>
-            </table>
-            <table width="100%" border="0" cellspacing="0" cellpadding="0" class="footerwrapper">
-                <tbody>
-                <tr>
-                    <td align="center" height="52" class="footercontent" style="padding: 4px;">
-                        <p style="font-size: 11px; line-height: 1.5; color: #6d6d6d">
-                            <b>ReportPortal Notification Center</b><br>
-                            This is an automatically generated notification - please do not reply to this message. You are receiving this
-                            email to complete the registration initiated on the ReportPortal application; if you are not waiting
-                            for the ReportPortal's invitation then just ignore this message.
-                        </p>
-                    </td>
-                </tr>
-                </tbody>
-            </table>
-        </td>
-    </tr>
-    </tbody>
+          </td>
+        </tr>
+        </tbody>
+      </table>
+      <table width="100%" border="0" cellspacing="0" cellpadding="0" bgcolor="#bdc7cc"
+             class="footerline">
+        <tbody>
+        <tr>
+          <td height="1"><!-- --></td>
+        </tr>
+        </tbody>
+      </table>
+      <table width="100%" border="0" cellspacing="0" cellpadding="0" class="footerwrapper">
+        <tbody>
+        <tr>
+          <td align="center" height="52" class="footercontent" style="padding: 4px;">
+            <p style="font-size: 11px; line-height: 1.5; color: #6d6d6d">
+              <b>ReportPortal Notification Center</b><br>
+              This is an automatically generated notification - please do not reply to this message.
+              You are receiving this
+              email to complete the registration initiated on the ReportPortal application; if you
+              are not waiting
+              for the ReportPortal's invitation then just ignore this message.
+            </p>
+          </td>
+        </tr>
+        </tbody>
+      </table>
+    </td>
+  </tr>
+  </tbody>
 </table>
 </body>
 </html>
diff --git a/src/main/resources/templates/email/self-delete-account-template.ftl b/src/main/resources/templates/email/self-delete-account-template.ftl
index cc5f32aa57..c1b0d2afa5 100644
--- a/src/main/resources/templates/email/self-delete-account-template.ftl
+++ b/src/main/resources/templates/email/self-delete-account-template.ftl
@@ -1,73 +1,75 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
-  <head>
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-    <link
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+  <link
       href="http://fonts.googleapis.com/css?family=Roboto:wght@100;400;500;&display=swap"
       rel="stylesheet"
       type="text/css"
-    />
-    <!--[if mso
-      ]><xml
-        ><o:OfficeDocumentSettings
-          ><o:PixelsPerInch>96</o:PixelsPerInch
-          ><o:AllowPNG /></o:OfficeDocumentSettings></xml
-    ><![endif]-->
-    <style>
-      .heading {
-        font-family: Arial, Helvetica, sans-serif;
-        margin-top: 0;
-        margin-bottom: 0;
-        color: #454a4f;
-        font-size: 36px;
-        font-style: normal;
-        font-weight: 700;
-        line-height: 48px;
-      }
+  />
+  <!--[if mso]>
+  <xml>
+    <o:OfficeDocumentSettings>
+      <o:PixelsPerInch>96</o:PixelsPerInch>
+      <o:AllowPNG/>
+    </o:OfficeDocumentSettings>
+  </xml>
+  <![endif]-->
+  <style>
+    .heading {
+      font-family: Arial, Helvetica, sans-serif;
+      margin-top: 0;
+      margin-bottom: 0;
+      color: #454a4f;
+      font-size: 36px;
+      font-style: normal;
+      font-weight: 700;
+      line-height: 48px;
+    }
 
-      .main-content {
-        margin-top: 0;
-        margin-bottom: 0;
-        margin-left: 0;
-        margin-right: 0;
-        font-family: Arial, Helvetica, sans-serif;
-        color: #545454;
-        font-size: 14px;
-        font-style: normal;
-        font-weight: 400;
-        line-height: 22px;
-      }
+    .main-content {
+      margin-top: 0;
+      margin-bottom: 0;
+      margin-left: 0;
+      margin-right: 0;
+      font-family: Arial, Helvetica, sans-serif;
+      color: #545454;
+      font-size: 14px;
+      font-style: normal;
+      font-weight: 400;
+      line-height: 22px;
+    }
 
-      .footer-content-heading {
-        margin-top: 0;
-        margin-bottom: 0;
-        margin-left: 0;
-        margin-right: 0;
-        color: #a2aab5;
-        font-family: 'Roboto', sans-serif;
-        font-size: 13px;
-        font-style: normal;
-        font-weight: 500;
-        line-height: 20px;
-      }
+    .footer-content-heading {
+      margin-top: 0;
+      margin-bottom: 0;
+      margin-left: 0;
+      margin-right: 0;
+      color: #a2aab5;
+      font-family: 'Roboto', sans-serif;
+      font-size: 13px;
+      font-style: normal;
+      font-weight: 500;
+      line-height: 20px;
+    }
 
-      .footer-content {
-        margin-top: 0;
-        margin-bottom: 0;
-        margin-left: 0;
-        margin-right: 0;
-        color: #a2aab5;
-        font-family: 'Roboto', sans-serif;
-        font-size: 11px;
-        font-style: normal;
-        font-weight: 400;
-        line-height: 16px;
-      }
-    </style>
+    .footer-content {
+      margin-top: 0;
+      margin-bottom: 0;
+      margin-left: 0;
+      margin-right: 0;
+      color: #a2aab5;
+      font-family: 'Roboto', sans-serif;
+      font-size: 11px;
+      font-style: normal;
+      font-weight: 400;
+      line-height: 16px;
+    }
+  </style>
 
-    <title>Report Portal</title>
-  </head>
-  <body
+  <title>Report Portal</title>
+</head>
+<body
     style="
       font-family: Arial, Helvetica, sans-serif;
       margin-top: 0;
@@ -79,215 +81,214 @@
       padding-top: 0;
       padding-bottom: 0px;
     "
+>
+<center>
+  <table
+      width="630"
+      border="0"
+      cellspacing="0"
+      cellpadding="0"
+      align="center"
   >
-    <center>
-      <table
-        width="630"
-        border="0"
-        cellspacing="0"
-        cellpadding="0"
-        align="center"
-      >
-        <tbody>
+    <tbody>
+    <tr>
+      <td>
+        <table
+            width="100%"
+            border="0"
+            cellspacing="0"
+            cellpadding="0"
+            bgcolor="#f4fbfb"
+        >
+          <tbody>
           <tr>
-            <td>
-              <table
-                width="100%"
-                border="0"
-                cellspacing="0"
-                cellpadding="0"
-                bgcolor="#f4fbfb"
-              >
-                <tbody>
-                  <tr>
-                    <td align="center" style="padding-top: 48px">
-                      <a
-                        href="http://reportportal.io"
-                        target="_blank"
-                        rel="noopener noreferrer"
-                        ><img src="cid:new-logo.png" alt="Report Portal logo"
-                      /></a>
-                    </td>
-                  </tr>
-                  <tr>
-                    <td
-                      align="center"
-                      style="
+            <td align="center" style="padding-top: 48px">
+              <a
+                  href="http://reportportal.io"
+                  target="_blank"
+                  rel="noopener noreferrer"
+              ><img src="cid:new-logo.png" alt="Report Portal logo"
+                /></a>
+            </td>
+          </tr>
+          <tr>
+            <td
+                align="center"
+                style="
                         padding-top: 37px;
                         padding-bottom: 38px;
                         background-color: rgb(244, 251, 251);
                         border-spacing: 0;
                       "
-                    >
-                      <img
-                        src="cid:deleted-account.png"
-                        alt="Deleted account img"
-                      />
-                    </td>
-                  </tr>
-                </tbody>
-              </table>
+            >
+              <img
+                  src="cid:deleted-account.png"
+                  alt="Deleted account img"
+              />
             </td>
           </tr>
-          <tr>
-            <td
-              align="center"
-              style="
+          </tbody>
+        </table>
+      </td>
+    </tr>
+    <tr>
+      <td
+          align="center"
+          style="
                 padding-left: 50px;
                 padding-right: 50px;
                 padding-bottom: 40px;
                 padding-top: 38px;
                 background-color: #ffffff;
               "
+      >
+        <table width="100%" border="0" cellspacing="0" cellpadding="0">
+          <thead>
+          <th>
+            <h1 class="heading">Your account has been deleted</h1>
+          </th>
+          </thead>
+          <tbody>
+          <tr>
+            <td style="padding-bottom: 12px; padding-top: 24px">
+              <p class="main-content">
+                This email is to confirm that your account and personal
+                data have been successfully deleted from ReportPortal
+                database. We're sorry to see you go, and we hope you had
+                a positive experience using our app.
+              </p>
+            </td>
+          </tr>
+          <tr>
+            <td style="padding-bottom: 12px">
+              <p class="main-content">
+                Please note that any data that you have reported to
+                ReportPortal or created there will remain in the app.
+              </p>
+            </td>
+          </tr>
+          <tr>
+            <td style="padding-bottom: 12px">
+              <p class="main-content">
+                If you haven't deleted your account or if you have any
+                questions or concerns, please contact our support team
+                for assistance.
+              </p>
+            </td>
+          </tr>
+          <tr>
+            <td style="padding-bottom: 12px">
+              <p class="main-content">
+                Thank you for your time and we wish you all the best in
+                your future testing endeavors.
+              </p>
+            </td>
+          </tr>
+          <tr>
+            <td>
+              <p class="main-content">
+                <br>Kind regards,<br>ReportPortal team
+              </p>
+            </td>
+          </tr>
+          </tbody>
+        </table>
+      </td>
+    </tr>
+    <tr>
+      <td align="center">
+        <table
+            width="100%"
+            border="0"
+            cellspacing="0"
+            cellpadding="0"
+            bgcolor="#f4fbfb"
+        >
+          <tbody>
+          <tr>
+            <td
+                align="center"
+                style="padding-top: 32px; padding-bottom: 24px"
             >
-              <table width="100%" border="0" cellspacing="0" cellpadding="0">
-                <thead>
-                  <th>
-                    <h1 class="heading">Your account has been deleted</h1>
-                  </th>
-                </thead>
-                <tbody>
-                  <tr>
-                    <td style="padding-bottom: 12px; padding-top: 24px">
-                      <p class="main-content">
-                        This email is to confirm that your account and personal
-                        data have been successfully deleted from ReportPortal
-                        database. We're sorry to see you go, and we hope you had
-                        a positive experience using our app.
-                      </p>
-                    </td>
-                  </tr>
-                  <tr>
-                    <td style="padding-bottom: 12px">
-                      <p class="main-content">
-                        Please note that any data that you have reported to
-                        ReportPortal or created there will remain in the app.
-                      </p>
-                    </td>
-                  </tr>
-                  <tr>
-                    <td style="padding-bottom: 12px">
-                      <p class="main-content">
-                        If you haven't deleted your account or if you have any
-                        questions or concerns, please contact our support team
-                        for assistance.
-                      </p>
-                    </td>
-                  </tr>
-                  <tr>
-                    <td style="padding-bottom: 12px">
-                      <p class="main-content">
-                        Thank you for your time and we wish you all the best in
-                        your future testing endeavors.
-                      </p>
-                    </td>
-                  </tr>
-                  <tr>
-                    <td>
-                      <p class="main-content">
-                        <br>Kind regards,<br>ReportPortal team
-                      </p>
-                    </td>
-                  </tr>
-                </tbody>
+              <table border="0"
+                     cellspacing="0"
+                     cellpadding="0"
+                     bgcolor="#f4fbfb"
+              >
+                <tr>
+                  <td style="padding-right: 22px">
+                    <a href="https://twitter.com/i/flow/login?redirect_after_login=%2FReportPortal_io"
+                       target="_blank"
+                       rel="noopener noreferrer">
+                      <img src="cid:new-ic-twitter.png"
+                           alt="Twitter icon">
+                    </a>
+                  </td>
+                  <td style="padding-right: 22px">
+                    <a href="https://slack.epmrpp.reportportal.io/"
+                       target="_blank"
+                       rel="noopener noreferrer">
+                      <img src="cid:new-ic-slack.png"
+                           alt="Slack icon">
+                    </a>
+                  </td>
+                  <td style="padding-right: 22px">
+                    <a href="https://www.youtube.com/c/ReportPortal"
+                       target="_blank"
+                       rel="noopener noreferrer">
+                      <img src="cid:new-ic-youtube.png"
+                           alt="YouTube icon">
+                    </a>
+                  </td>
+                  <td style="padding-right: 22px">
+                    <a href="https://www.linkedin.com/company/reportportal/"
+                       target="_blank"
+                       rel="noopener noreferrer">
+                      <img src="cid:new-ic-linkedin.png"
+                           alt="Linkedin icon">
+                    </a>
+                  </td>
+                  <td style="padding-right: 22px">
+                    <a href="https://www.facebook.com/ReportPortal.io"
+                       target="_blank"
+                       rel="noopener noreferrer">
+                      <img src="cid:new-ic-facebook.png"
+                           alt="Facebook icon">
+                    </a>
+                  </td>
+                  <td>
+                    <a href="https://github.com/reportportal"
+                       target="_blank"
+                       rel="noopener noreferrer">
+                      <img src="cid:new-ic-github.png"
+                           alt="Github icon">
+                    </a>
+                  </td>
+                </tr>
               </table>
             </td>
           </tr>
           <tr>
             <td align="center">
-              <table
-                width="100%"
-                border="0"
-                cellspacing="0"
-                cellpadding="0"
-                bgcolor="#f4fbfb"
-              >
-                <tbody>
-                  <tr>
-                    <td
-                      align="center"
-                      style="padding-top: 32px; padding-bottom: 24px"
-                    >
-                      <table
-                        border="0"
-                        cellspacing="0"
-                        cellpadding="0"
-                        bgcolor="#f4fbfb"
-                      >
-                        <tr>
-                          <td style="padding-right: 22px">
-                            <a
-                              href="https://twitter.com/i/flow/login?redirect_after_login=%2FReportPortal_io"
-                              target="_blank"
-                              rel="noopener noreferrer"
-                              ><img
-                                src="cid:new-ic-twitter.png"
-                                alt="Twitter icon"
-                            /></a>
-                          </td>
-                          <td style="padding-right: 22px">
-                            <a
-                              href="https://slack.epmrpp.reportportal.io/"
-                              target="_blank"
-                              rel="noopener noreferrer"
-                              ><img src="cid:new-ic-slack.png" alt="Slack icon"
-                            /></a>
-                          </td>
-                          <td style="padding-right: 22px">
-                            <a
-                              href="https://www.youtube.com/c/ReportPortal"
-                              target="_blank"
-                              rel="noopener noreferrer"
-                              ><img
-                                src="cid:new-ic-youtube.png"
-                                alt="YouTube icon"
-                            /></a>
-                          </td>
-                          <td style="padding-right: 10px">
-                            <a
-                              href="https://www.linkedin.com/company/reportportal/"
-                              target="_blank"
-                              rel="noopener noreferrer"
-                              ><img
-                                src="cid:new-ic-linkedin.png"
-                                alt="Linkedin icon"
-                            /></a>
-                          </td>
-                          <td>
-                            <a
-                              href="https://github.com/reportportal"
-                              target="_blank"
-                              rel="noopener noreferrer"
-                              ><img
-                                src="cid:new-ic-github.png"
-                                alt="Github icon"
-                            /></a>
-                          </td>
-                        </tr>
-                      </table>
-                    </td>
-                  </tr>
-                  <tr>
-                    <td align="center">
-                      <h4 class="footer-content-heading">
-                        ReportPortal Notification Center
-                      </h4>
-                    </td>
-                  </tr>
-                  <tr>
-                    <td align="center" style="padding-bottom: 32px">
-                      <p class="footer-content">
-                        This notification was created automatically. Please
-                        don't reply to this e-mail.
-                      </p>
-                    </td>
-                  </tr>
-                </tbody>
-              </table>
+              <h4 class="footer-content-heading">
+                ReportPortal Notification Center
+              </h4>
+            </td>
+          </tr>
+          <tr>
+            <td align="center" style="padding-bottom: 32px">
+              <p class="footer-content">
+                This notification was created automatically. Please
+                don't reply to this e-mail.
+              </p>
             </td>
           </tr>
-        </tbody>
-      </table>
-    </center>
-  </body>
+          </tbody>
+        </table>
+      </td>
+    </tr>
+    </tbody>
+  </table>
+</center>
+</body>
 </html>
diff --git a/src/main/resources/templates/report/projects.jrxml b/src/main/resources/templates/report/projects.jrxml
index 13e8b202a9..abf539ad3a 100644
--- a/src/main/resources/templates/report/projects.jrxml
+++ b/src/main/resources/templates/report/projects.jrxml
@@ -16,130 +16,158 @@
   -->
 
 <!-- Created with Jaspersoft Studio version 6.6.0.final using JasperReports Library version 6.6.0  -->
-<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-              xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd"
-              name="test" pageWidth="842" pageHeight="595" orientation="Landscape" columnWidth="802" leftMargin="20" rightMargin="20"
-              topMargin="20" bottomMargin="20" uuid="7a5c9b49-9dc5-422a-ac69-e92cf61ef530" isIgnorePagination="true">
-    <style name="Title" forecolor="#FFFFFF" fontName="Noto Sans" fontSize="50" isBold="false"/>
-    <style name="SubTitle" forecolor="#CCCCCC" fontName="Noto Sans" fontSize="18" isBold="false"/>
-    <style name="Column header" forecolor="#666666" fontName="Noto Sans" fontSize="14" isBold="true"/>
-    <style name="Detail" mode="Transparent" fontName="Noto Sans"/>
-    <style name="Row" mode="Transparent" fontName="Noto Sans" pdfFontName="Times-Roman">
-        <conditionalStyle>
-            <conditionExpression><![CDATA[$V{REPORT_COUNT}%2 == 0]]></conditionExpression>
-            <style mode="Opaque" backcolor="#F0EFEF"/>
-        </conditionalStyle>
-    </style>
-    <queryString>
-        <![CDATA[]]>
-    </queryString>
-    <field name="Project name" class="java.lang.String"/>
-    <field name="Project type" class="java.lang.String"/>
-    <field name="Organization" class="java.lang.String"/>
-    <field name="Members" class="java.lang.Integer"/>
-    <field name="Launches" class="java.lang.Integer"/>
-    <field name="Last launch date" class="java.lang.String"/>
-    <background>
-        <band splitType="Stretch"/>
-    </background>
-    <columnHeader>
-        <band height="19" splitType="Stretch">
-            <staticText>
-                <reportElement x="0" y="0" width="217" height="18" uuid="1e0d3905-6d0e-4660-ac0a-9b6ca6b47b93">
-                    <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="f172f0b8-1df3-4c59-bec2-45f6582696e3"/>
-                </reportElement>
-                <textElement textAlignment="Center"/>
-                <text><![CDATA[Project name]]></text>
-            </staticText>
-            <staticText>
-                <reportElement x="217" y="0" width="100" height="18" uuid="64cc94b9-8766-49b1-8b9f-e45296c5c9c7">
-                    <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="3ebec559-1ba4-4dc0-978b-ff46d0298c59"/>
-                </reportElement>
-                <textElement textAlignment="Center"/>
-                <text><![CDATA[Project type]]></text>
-            </staticText>
-            <staticText>
-                <reportElement x="317" y="0" width="150" height="18" uuid="b0549432-b1b4-41af-931e-7e25e63d738c">
-                    <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="0eca9f7f-619a-44d6-9cf6-46dc79e5e251"/>
-                </reportElement>
-                <textElement textAlignment="Center"/>
-                <text><![CDATA[Organization]]></text>
-            </staticText>
-            <staticText>
-                <reportElement x="467" y="0" width="100" height="18" uuid="e0ddb3e8-ddc4-41af-b0bb-5299862be558">
-                    <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="7d2a698e-beb1-4dbb-b059-0654b305955e"/>
-                </reportElement>
-                <textElement textAlignment="Center"/>
-                <text><![CDATA[Members]]></text>
-            </staticText>
-            <staticText>
-                <reportElement x="567" y="0" width="100" height="18" uuid="ac60d496-d8c7-4543-b8da-1112cde3fc2c">
-                    <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="d4571106-56c2-445d-a317-a38effb2595b"/>
-                </reportElement>
-                <textElement textAlignment="Center"/>
-                <text><![CDATA[Launches]]></text>
-            </staticText>
-            <staticText>
-                <reportElement x="667" y="0" width="130" height="18" uuid="c171c5b6-8de5-4c4e-8bcf-e00a8d4c4e04">
-                    <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="2f7dc42d-b03f-4000-b7c3-4143e6e1f44d"/>
-                </reportElement>
-                <textElement textAlignment="Center"/>
-                <text><![CDATA[Last launch date]]></text>
-            </staticText>
-        </band>
-    </columnHeader>
-    <detail>
-        <band height="18" splitType="Stretch">
-            <frame>
-                <reportElement style="Row" mode="Opaque" x="0" y="0" width="797" height="18" uuid="34a2ae4b-4055-476b-8676-d499f6af510b"/>
-                <textField>
-                    <reportElement x="0" y="0" width="217" height="30" uuid="42609d3f-7d28-44f2-b8ea-650fbbcf746f">
-                        <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="f172f0b8-1df3-4c59-bec2-45f6582696e3"/>
-                        <property name="net.sf.jasperreports.print.keep.full.text" value="true"/>
-                    </reportElement>
-                    <textElement textAlignment="Center"/>
-                    <textFieldExpression><![CDATA[$F{Project name}]]></textFieldExpression>
-                </textField>
-                <textField>
-                    <reportElement x="217" y="0" width="100" height="30" uuid="66d3c031-147d-40f1-a43b-d1d9a3a6e457">
-                        <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="3ebec559-1ba4-4dc0-978b-ff46d0298c59"/>
-                    </reportElement>
-                    <textElement textAlignment="Center"/>
-                    <textFieldExpression><![CDATA[$F{Project type}]]></textFieldExpression>
-                </textField>
-                <textField>
-                    <reportElement x="317" y="0" width="150" height="30" uuid="d4aa9cdc-f50c-4cb9-9246-f0f57250f17f">
-                        <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="0eca9f7f-619a-44d6-9cf6-46dc79e5e251"/>
-                        <property name="net.sf.jasperreports.print.keep.full.text" value="true"/>
-                    </reportElement>
-                    <textElement textAlignment="Center"/>
-                    <textFieldExpression><![CDATA[$F{Organization}]]></textFieldExpression>
-                </textField>
-                <textField>
-                    <reportElement x="467" y="0" width="100" height="30" uuid="47939077-bc56-4fc7-85b9-2942fcaddaa0">
-                        <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="7d2a698e-beb1-4dbb-b059-0654b305955e"/>
-                    </reportElement>
-                    <textElement textAlignment="Center"/>
-                    <textFieldExpression><![CDATA[$F{Members}]]></textFieldExpression>
-                </textField>
-                <textField>
-                    <reportElement x="567" y="0" width="100" height="30" uuid="5fc335bb-6c5a-46ac-b345-fbefa1deec6a">
-                        <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="d4571106-56c2-445d-a317-a38effb2595b"/>
-                    </reportElement>
-                    <textElement textAlignment="Center" verticalAlignment="Top"/>
-                    <textFieldExpression><![CDATA[$F{Launches}]]></textFieldExpression>
-                </textField>
-                <textField>
-                    <reportElement x="667" y="0" width="130" height="30" uuid="e2f3ad6a-109e-4eca-accc-eb0c7aa3bbb9">
-                        <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="2f7dc42d-b03f-4000-b7c3-4143e6e1f44d"/>
-                    </reportElement>
-                    <textElement textAlignment="Center"/>
-                    <textFieldExpression><![CDATA[$F{Last launch date}]]></textFieldExpression>
-                </textField>
-            </frame>
-        </band>
-    </detail>
-    <summary>
-        <band splitType="Stretch"/>
-    </summary>
+<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd"
+  name="test" pageWidth="842" pageHeight="595" orientation="Landscape" columnWidth="802"
+  leftMargin="20" rightMargin="20"
+  topMargin="20" bottomMargin="20" uuid="7a5c9b49-9dc5-422a-ac69-e92cf61ef530"
+  isIgnorePagination="true">
+  <style name="Title" forecolor="#FFFFFF" fontName="Noto Sans" fontSize="50" isBold="false"/>
+  <style name="SubTitle" forecolor="#CCCCCC" fontName="Noto Sans" fontSize="18" isBold="false"/>
+  <style name="Column header" forecolor="#666666" fontName="Noto Sans" fontSize="14" isBold="true"/>
+  <style name="Detail" mode="Transparent" fontName="Noto Sans"/>
+  <style name="Row" mode="Transparent" fontName="Noto Sans" pdfFontName="Times-Roman">
+    <conditionalStyle>
+      <conditionExpression><![CDATA[$V{REPORT_COUNT}%2 == 0]]></conditionExpression>
+      <style mode="Opaque" backcolor="#F0EFEF"/>
+    </conditionalStyle>
+  </style>
+  <queryString>
+    <![CDATA[]]>
+  </queryString>
+  <field name="Project name" class="java.lang.String"/>
+  <field name="Project type" class="java.lang.String"/>
+  <field name="Organization" class="java.lang.String"/>
+  <field name="Members" class="java.lang.Integer"/>
+  <field name="Launches" class="java.lang.Integer"/>
+  <field name="Last launch date" class="java.lang.String"/>
+  <background>
+    <band splitType="Stretch"/>
+  </background>
+  <columnHeader>
+    <band height="19" splitType="Stretch">
+      <staticText>
+        <reportElement x="0" y="0" width="217" height="18"
+          uuid="1e0d3905-6d0e-4660-ac0a-9b6ca6b47b93">
+          <property name="com.jaspersoft.studio.spreadsheet.connectionID"
+            value="f172f0b8-1df3-4c59-bec2-45f6582696e3"/>
+        </reportElement>
+        <textElement textAlignment="Center"/>
+        <text><![CDATA[Project name]]></text>
+      </staticText>
+      <staticText>
+        <reportElement x="217" y="0" width="100" height="18"
+          uuid="64cc94b9-8766-49b1-8b9f-e45296c5c9c7">
+          <property name="com.jaspersoft.studio.spreadsheet.connectionID"
+            value="3ebec559-1ba4-4dc0-978b-ff46d0298c59"/>
+        </reportElement>
+        <textElement textAlignment="Center"/>
+        <text><![CDATA[Project type]]></text>
+      </staticText>
+      <staticText>
+        <reportElement x="317" y="0" width="150" height="18"
+          uuid="b0549432-b1b4-41af-931e-7e25e63d738c">
+          <property name="com.jaspersoft.studio.spreadsheet.connectionID"
+            value="0eca9f7f-619a-44d6-9cf6-46dc79e5e251"/>
+        </reportElement>
+        <textElement textAlignment="Center"/>
+        <text><![CDATA[Organization]]></text>
+      </staticText>
+      <staticText>
+        <reportElement x="467" y="0" width="100" height="18"
+          uuid="e0ddb3e8-ddc4-41af-b0bb-5299862be558">
+          <property name="com.jaspersoft.studio.spreadsheet.connectionID"
+            value="7d2a698e-beb1-4dbb-b059-0654b305955e"/>
+        </reportElement>
+        <textElement textAlignment="Center"/>
+        <text><![CDATA[Members]]></text>
+      </staticText>
+      <staticText>
+        <reportElement x="567" y="0" width="100" height="18"
+          uuid="ac60d496-d8c7-4543-b8da-1112cde3fc2c">
+          <property name="com.jaspersoft.studio.spreadsheet.connectionID"
+            value="d4571106-56c2-445d-a317-a38effb2595b"/>
+        </reportElement>
+        <textElement textAlignment="Center"/>
+        <text><![CDATA[Launches]]></text>
+      </staticText>
+      <staticText>
+        <reportElement x="667" y="0" width="130" height="18"
+          uuid="c171c5b6-8de5-4c4e-8bcf-e00a8d4c4e04">
+          <property name="com.jaspersoft.studio.spreadsheet.connectionID"
+            value="2f7dc42d-b03f-4000-b7c3-4143e6e1f44d"/>
+        </reportElement>
+        <textElement textAlignment="Center"/>
+        <text><![CDATA[Last launch date]]></text>
+      </staticText>
+    </band>
+  </columnHeader>
+  <detail>
+    <band height="18" splitType="Stretch">
+      <frame>
+        <reportElement style="Row" mode="Opaque" x="0" y="0" width="797" height="18"
+          uuid="34a2ae4b-4055-476b-8676-d499f6af510b"/>
+        <textField>
+          <reportElement x="0" y="0" width="217" height="30"
+            uuid="42609d3f-7d28-44f2-b8ea-650fbbcf746f">
+            <property name="com.jaspersoft.studio.spreadsheet.connectionID"
+              value="f172f0b8-1df3-4c59-bec2-45f6582696e3"/>
+            <property name="net.sf.jasperreports.print.keep.full.text" value="true"/>
+          </reportElement>
+          <textElement textAlignment="Center"/>
+          <textFieldExpression><![CDATA[$F{Project name}]]></textFieldExpression>
+        </textField>
+        <textField>
+          <reportElement x="217" y="0" width="100" height="30"
+            uuid="66d3c031-147d-40f1-a43b-d1d9a3a6e457">
+            <property name="com.jaspersoft.studio.spreadsheet.connectionID"
+              value="3ebec559-1ba4-4dc0-978b-ff46d0298c59"/>
+          </reportElement>
+          <textElement textAlignment="Center"/>
+          <textFieldExpression><![CDATA[$F{Project type}]]></textFieldExpression>
+        </textField>
+        <textField>
+          <reportElement x="317" y="0" width="150" height="30"
+            uuid="d4aa9cdc-f50c-4cb9-9246-f0f57250f17f">
+            <property name="com.jaspersoft.studio.spreadsheet.connectionID"
+              value="0eca9f7f-619a-44d6-9cf6-46dc79e5e251"/>
+            <property name="net.sf.jasperreports.print.keep.full.text" value="true"/>
+          </reportElement>
+          <textElement textAlignment="Center"/>
+          <textFieldExpression><![CDATA[$F{Organization}]]></textFieldExpression>
+        </textField>
+        <textField>
+          <reportElement x="467" y="0" width="100" height="30"
+            uuid="47939077-bc56-4fc7-85b9-2942fcaddaa0">
+            <property name="com.jaspersoft.studio.spreadsheet.connectionID"
+              value="7d2a698e-beb1-4dbb-b059-0654b305955e"/>
+          </reportElement>
+          <textElement textAlignment="Center"/>
+          <textFieldExpression><![CDATA[$F{Members}]]></textFieldExpression>
+        </textField>
+        <textField>
+          <reportElement x="567" y="0" width="100" height="30"
+            uuid="5fc335bb-6c5a-46ac-b345-fbefa1deec6a">
+            <property name="com.jaspersoft.studio.spreadsheet.connectionID"
+              value="d4571106-56c2-445d-a317-a38effb2595b"/>
+          </reportElement>
+          <textElement textAlignment="Center" verticalAlignment="Top"/>
+          <textFieldExpression><![CDATA[$F{Launches}]]></textFieldExpression>
+        </textField>
+        <textField>
+          <reportElement x="667" y="0" width="130" height="30"
+            uuid="e2f3ad6a-109e-4eca-accc-eb0c7aa3bbb9">
+            <property name="com.jaspersoft.studio.spreadsheet.connectionID"
+              value="2f7dc42d-b03f-4000-b7c3-4143e6e1f44d"/>
+          </reportElement>
+          <textElement textAlignment="Center"/>
+          <textFieldExpression><![CDATA[$F{Last launch date}]]></textFieldExpression>
+        </textField>
+      </frame>
+    </band>
+  </detail>
+  <summary>
+    <band splitType="Stretch"/>
+  </summary>
 </jasperReport>
diff --git a/src/main/resources/templates/report/report.jrxml b/src/main/resources/templates/report/report.jrxml
index 2b49d853bf..459ff581d0 100644
--- a/src/main/resources/templates/report/report.jrxml
+++ b/src/main/resources/templates/report/report.jrxml
@@ -17,772 +17,838 @@
 
 <!-- Created with Jaspersoft Studio version 6.2.2.final using JasperReports Library version 6.2.2  -->
 <!-- 2016-07-25T16:43:03 -->
-<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-              xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd"
-              name="Blank_A4_Landscape" pageWidth="842" pageHeight="595" orientation="Landscape" columnWidth="802" leftMargin="20"
-              rightMargin="20" topMargin="20" bottomMargin="20" uuid="438bfacd-17a2-4c73-99de-5e4210041df7">
-    <property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/>
-    <style name="Table_TH" mode="Opaque" backcolor="#484866">
+<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd"
+  name="Blank_A4_Landscape" pageWidth="842" pageHeight="595" orientation="Landscape"
+  columnWidth="802" leftMargin="20"
+  rightMargin="20" topMargin="20" bottomMargin="20" uuid="438bfacd-17a2-4c73-99de-5e4210041df7">
+  <property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/>
+  <style name="Table_TH" mode="Opaque" backcolor="#484866">
+    <box>
+      <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/>
+      <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/>
+      <bottomPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/>
+      <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/>
+    </box>
+  </style>
+  <style name="Table_CH" mode="Opaque" backcolor="#CFCFE6">
+    <box>
+      <topPen lineWidth="0.5" lineStyle="Solid" lineColor="#000000"/>
+      <leftPen lineWidth="0.5" lineStyle="Solid" lineColor="#000000"/>
+      <bottomPen lineWidth="0.5" lineStyle="Solid" lineColor="#000000"/>
+      <rightPen lineWidth="0.5" lineStyle="Solid" lineColor="#000000"/>
+    </box>
+  </style>
+  <style name="Table_TD" mode="Opaque" backcolor="#FFFFFF">
+    <box>
+      <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/>
+      <leftPen lineWidth="0.5" lineStyle="Solid" lineColor="#000000"/>
+      <bottomPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/>
+      <rightPen lineWidth="0.5" lineStyle="Solid" lineColor="#000000"/>
+    </box>
+  </style>
+  <style name="Table 1_TH" mode="Opaque" backcolor="#F0F8FF">
+    <box>
+      <pen lineWidth="0.5" lineColor="#000000"/>
+      <topPen lineWidth="0.5" lineColor="#000000"/>
+      <leftPen lineWidth="0.5" lineColor="#000000"/>
+      <bottomPen lineWidth="0.5" lineColor="#000000"/>
+      <rightPen lineWidth="0.5" lineColor="#000000"/>
+    </box>
+  </style>
+  <subDataset name="TestItemsTableDS" whenResourceMissingType="Empty"
+    uuid="60da51c9-2b0f-4af5-8fe6-4544ac18aa83">
+    <queryString>
+      <![CDATA[]]>
+    </queryString>
+    <field name="type" class="java.lang.String"/>
+    <field name="name" class="java.lang.String">
+      <fieldDescription><![CDATA[]]></fieldDescription>
+    </field>
+    <field name="duration" class="java.lang.Double"/>
+    <field name="status" class="java.lang.String"/>
+    <field name="total" class="java.lang.Integer"/>
+    <field name="passed" class="java.lang.Integer"/>
+    <field name="failed" class="java.lang.Integer">
+      <fieldDescription><![CDATA[]]></fieldDescription>
+    </field>
+    <field name="skipped" class="java.lang.Integer"/>
+    <field name="automationBug" class="java.lang.Integer">
+      <fieldDescription><![CDATA[]]></fieldDescription>
+    </field>
+    <field name="productBug" class="java.lang.Integer">
+      <fieldDescription><![CDATA[]]></fieldDescription>
+    </field>
+    <field name="systemIssue" class="java.lang.Integer"/>
+    <field name="noDefect" class="java.lang.Integer">
+      <fieldDescription><![CDATA[]]></fieldDescription>
+    </field>
+    <field name="toInvestigate" class="java.lang.Integer">
+      <fieldDescription><![CDATA[]]></fieldDescription>
+    </field>
+  </subDataset>
+  <subDataset name="Dataset1" uuid="8b099eea-c143-479c-8970-4217b14379d7">
+    <queryString>
+      <![CDATA[]]>
+    </queryString>
+  </subDataset>
+  <parameter name="LAUNCH_NAME" class="java.lang.String"/>
+  <parameter name="LAUNCH_DURATION" class="java.lang.String">
+    <parameterDescription><![CDATA[]]></parameterDescription>
+  </parameter>
+  <parameter name="LAUNCH_DESCRIPTION" class="java.lang.String">
+    <parameterDescription><![CDATA[]]></parameterDescription>
+  </parameter>
+  <parameter name="LAUNCH_OWNER" class="java.lang.String"/>
+  <parameter name="LAUNCH_TAGS" class="java.lang.String"/>
+  <parameter name="TOTAL" class="java.lang.Integer">
+    <defaultValueExpression><![CDATA[0]]></defaultValueExpression>
+  </parameter>
+  <parameter name="PASSED" class="java.lang.Integer">
+    <defaultValueExpression><![CDATA[0]]></defaultValueExpression>
+  </parameter>
+  <parameter name="FAILED" class="java.lang.Integer">
+    <defaultValueExpression><![CDATA[0]]></defaultValueExpression>
+  </parameter>
+  <parameter name="SKIPPED" class="java.lang.Integer">
+    <defaultValueExpression><![CDATA[0]]></defaultValueExpression>
+  </parameter>
+  <parameter name="AB" class="java.lang.Integer">
+    <defaultValueExpression><![CDATA[0]]></defaultValueExpression>
+  </parameter>
+  <parameter name="PB" class="java.lang.Integer">
+    <defaultValueExpression><![CDATA[0]]></defaultValueExpression>
+  </parameter>
+  <parameter name="SI" class="java.lang.Integer">
+    <defaultValueExpression><![CDATA[0]]></defaultValueExpression>
+  </parameter>
+  <parameter name="ND" class="java.lang.Integer">
+    <defaultValueExpression><![CDATA[0]]></defaultValueExpression>
+  </parameter>
+  <parameter name="TI" class="java.lang.Integer">
+    <defaultValueExpression><![CDATA[0]]></defaultValueExpression>
+  </parameter>
+  <parameter name="TEST_ITEMS" class="java.util.Collection"/>
+  <queryString>
+    <![CDATA[]]>
+  </queryString>
+  <background>
+    <band splitType="Stretch"/>
+  </background>
+  <title>
+    <band height="85" splitType="Stretch">
+      <textField isBlankWhenNull="true">
+        <reportElement x="82" y="60" width="140" height="20"
+          uuid="f4f1aa0a-7460-4ec1-9568-6c2101c918de"/>
+        <textElement verticalAlignment="Top">
+          <font fontName="Noto Sans"/>
+        </textElement>
+        <textFieldExpression><![CDATA[$P{LAUNCH_DURATION}]]></textFieldExpression>
+      </textField>
+      <staticText>
+        <reportElement x="0" y="40" width="82" height="20"
+          uuid="bf3f95f3-b14a-492b-8b8b-fd8d9ba6d088"/>
+        <textElement verticalAlignment="Top">
+          <font fontName="Noto Sans" isBold="true"/>
+        </textElement>
+        <text><![CDATA[Owner:]]></text>
+      </staticText>
+      <staticText>
+        <reportElement x="0" y="60" width="82" height="20"
+          uuid="813174c3-f36a-4c64-b0d3-60726c2ea891"/>
+        <textElement verticalAlignment="Top">
+          <font fontName="Noto Sans" isBold="true"/>
+        </textElement>
+        <text><![CDATA[Duration:]]></text>
+      </staticText>
+      <textField isBlankWhenNull="true">
+        <reportElement x="82" y="40" width="388" height="20"
+          uuid="bafe2045-04c0-40b6-803e-03941dd6f77a"/>
+        <textElement verticalAlignment="Top">
+          <font fontName="Noto Sans"/>
+        </textElement>
+        <textFieldExpression><![CDATA[$P{LAUNCH_OWNER}]]></textFieldExpression>
+      </textField>
+      <staticText>
+        <reportElement x="0" y="0" width="82" height="20"
+          uuid="e15dcb90-a675-4b87-9a32-eaac213feea1"/>
+        <textElement>
+          <font fontName="Noto Sans" isBold="true"/>
+        </textElement>
+        <text><![CDATA[Launch name:]]></text>
+      </staticText>
+      <textField>
+        <reportElement x="82" y="0" width="388" height="20"
+          uuid="7661c90b-7b58-4292-8333-154705ff0701"/>
+        <textElement>
+          <font fontName="Noto Sans" isBold="true"/>
+        </textElement>
+        <textFieldExpression><![CDATA[$P{LAUNCH_NAME}]]></textFieldExpression>
+      </textField>
+      <staticText>
+        <reportElement x="0" y="20" width="82" height="20"
+          uuid="e4b2bcf3-cc0a-4156-a4aa-cddf2a16d5c0"/>
+        <textElement>
+          <font fontName="Noto Sans" isBold="true"/>
+        </textElement>
+        <text><![CDATA[Description:]]></text>
+      </staticText>
+      <textField>
+        <reportElement x="82" y="20" width="388" height="20"
+          uuid="b0b0090b-1fe2-4349-afd2-5f08bfa31187"/>
+        <textElement>
+          <font fontName="Noto Sans"/>
+        </textElement>
+        <textFieldExpression><![CDATA[$P{LAUNCH_DESCRIPTION}]]></textFieldExpression>
+      </textField>
+      <staticText>
+        <reportElement x="480" y="0" width="320" height="20"
+          uuid="fa79751f-81e6-40fb-b2aa-de1031768dc8"/>
         <box>
-            <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/>
-            <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/>
-            <bottomPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/>
-            <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/>
+          <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
         </box>
-    </style>
-    <style name="Table_CH" mode="Opaque" backcolor="#CFCFE6">
+        <textElement textAlignment="Center" verticalAlignment="Middle">
+          <font fontName="Noto Sans" isBold="true"/>
+        </textElement>
+        <text><![CDATA[Launch statistic]]></text>
+      </staticText>
+      <staticText>
+        <reportElement x="480" y="20" width="168" height="20"
+          uuid="d018d389-4a79-4095-b4f8-fbfaef41246d"/>
         <box>
-            <topPen lineWidth="0.5" lineStyle="Solid" lineColor="#000000"/>
-            <leftPen lineWidth="0.5" lineStyle="Solid" lineColor="#000000"/>
-            <bottomPen lineWidth="0.5" lineStyle="Solid" lineColor="#000000"/>
-            <rightPen lineWidth="0.5" lineStyle="Solid" lineColor="#000000"/>
+          <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
         </box>
-    </style>
-    <style name="Table_TD" mode="Opaque" backcolor="#FFFFFF">
+        <textElement textAlignment="Center" verticalAlignment="Middle">
+          <font fontName="Noto Sans" isBold="true"/>
+        </textElement>
+        <text><![CDATA[Execution statistic]]></text>
+      </staticText>
+      <staticText>
+        <reportElement x="648" y="20" width="152" height="20"
+          uuid="7fd8af2f-840f-4b1c-927b-18168bc9422c"/>
         <box>
-            <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/>
-            <leftPen lineWidth="0.5" lineStyle="Solid" lineColor="#000000"/>
-            <bottomPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/>
-            <rightPen lineWidth="0.5" lineStyle="Solid" lineColor="#000000"/>
+          <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
         </box>
-    </style>
-    <style name="Table 1_TH" mode="Opaque" backcolor="#F0F8FF">
+        <textElement textAlignment="Center" verticalAlignment="Middle">
+          <font fontName="Noto Sans" isBold="true"/>
+        </textElement>
+        <text><![CDATA[Issue statistic]]></text>
+      </staticText>
+      <staticText>
+        <reportElement mode="Opaque" x="480" y="40" width="30" height="20" backcolor="#489BEB"
+          uuid="364a016c-13cc-476e-a112-c293a2e4aa9c"/>
         <box>
-            <pen lineWidth="0.5" lineColor="#000000"/>
-            <topPen lineWidth="0.5" lineColor="#000000"/>
-            <leftPen lineWidth="0.5" lineColor="#000000"/>
-            <bottomPen lineWidth="0.5" lineColor="#000000"/>
-            <rightPen lineWidth="0.5" lineColor="#000000"/>
+          <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
         </box>
-    </style>
-    <subDataset name="TestItemsTableDS" whenResourceMissingType="Empty" uuid="60da51c9-2b0f-4af5-8fe6-4544ac18aa83">
-        <queryString>
-            <![CDATA[]]>
-        </queryString>
-        <field name="type" class="java.lang.String"/>
-        <field name="name" class="java.lang.String">
-            <fieldDescription><![CDATA[]]></fieldDescription>
-        </field>
-        <field name="duration" class="java.lang.Double"/>
-        <field name="status" class="java.lang.String"/>
-        <field name="total" class="java.lang.Integer"/>
-        <field name="passed" class="java.lang.Integer"/>
-        <field name="failed" class="java.lang.Integer">
-            <fieldDescription><![CDATA[]]></fieldDescription>
-        </field>
-        <field name="skipped" class="java.lang.Integer"/>
-        <field name="automationBug" class="java.lang.Integer">
-            <fieldDescription><![CDATA[]]></fieldDescription>
-        </field>
-        <field name="productBug" class="java.lang.Integer">
-            <fieldDescription><![CDATA[]]></fieldDescription>
-        </field>
-        <field name="systemIssue" class="java.lang.Integer"/>
-        <field name="noDefect" class="java.lang.Integer">
-            <fieldDescription><![CDATA[]]></fieldDescription>
-        </field>
-        <field name="toInvestigate" class="java.lang.Integer">
-            <fieldDescription><![CDATA[]]></fieldDescription>
-        </field>
-    </subDataset>
-    <subDataset name="Dataset1" uuid="8b099eea-c143-479c-8970-4217b14379d7">
-        <queryString>
-            <![CDATA[]]>
-        </queryString>
-    </subDataset>
-    <parameter name="LAUNCH_NAME" class="java.lang.String"/>
-    <parameter name="LAUNCH_DURATION" class="java.lang.String">
-        <parameterDescription><![CDATA[]]></parameterDescription>
-    </parameter>
-    <parameter name="LAUNCH_DESCRIPTION" class="java.lang.String">
-        <parameterDescription><![CDATA[]]></parameterDescription>
-    </parameter>
-    <parameter name="LAUNCH_OWNER" class="java.lang.String"/>
-    <parameter name="LAUNCH_TAGS" class="java.lang.String"/>
-    <parameter name="TOTAL" class="java.lang.Integer">
-        <defaultValueExpression><![CDATA[0]]></defaultValueExpression>
-    </parameter>
-    <parameter name="PASSED" class="java.lang.Integer">
-        <defaultValueExpression><![CDATA[0]]></defaultValueExpression>
-    </parameter>
-    <parameter name="FAILED" class="java.lang.Integer">
-        <defaultValueExpression><![CDATA[0]]></defaultValueExpression>
-    </parameter>
-    <parameter name="SKIPPED" class="java.lang.Integer">
-        <defaultValueExpression><![CDATA[0]]></defaultValueExpression>
-    </parameter>
-    <parameter name="AB" class="java.lang.Integer">
-        <defaultValueExpression><![CDATA[0]]></defaultValueExpression>
-    </parameter>
-    <parameter name="PB" class="java.lang.Integer">
-        <defaultValueExpression><![CDATA[0]]></defaultValueExpression>
-    </parameter>
-    <parameter name="SI" class="java.lang.Integer">
-        <defaultValueExpression><![CDATA[0]]></defaultValueExpression>
-    </parameter>
-    <parameter name="ND" class="java.lang.Integer">
-        <defaultValueExpression><![CDATA[0]]></defaultValueExpression>
-    </parameter>
-    <parameter name="TI" class="java.lang.Integer">
-        <defaultValueExpression><![CDATA[0]]></defaultValueExpression>
-    </parameter>
-    <parameter name="TEST_ITEMS" class="java.util.Collection"/>
-    <queryString>
-        <![CDATA[]]>
-    </queryString>
-    <background>
-        <band splitType="Stretch"/>
-    </background>
-    <title>
-        <band height="85" splitType="Stretch">
-            <textField isBlankWhenNull="true">
-                <reportElement x="82" y="60" width="140" height="20" uuid="f4f1aa0a-7460-4ec1-9568-6c2101c918de"/>
-                <textElement verticalAlignment="Top">
-                    <font fontName="Noto Sans"/>
-                </textElement>
-                <textFieldExpression><![CDATA[$P{LAUNCH_DURATION}]]></textFieldExpression>
-            </textField>
-            <staticText>
-                <reportElement x="0" y="40" width="82" height="20" uuid="bf3f95f3-b14a-492b-8b8b-fd8d9ba6d088"/>
-                <textElement verticalAlignment="Top">
-                    <font fontName="Noto Sans" isBold="true"/>
-                </textElement>
-                <text><![CDATA[Owner:]]></text>
-            </staticText>
-            <staticText>
-                <reportElement x="0" y="60" width="82" height="20" uuid="813174c3-f36a-4c64-b0d3-60726c2ea891"/>
-                <textElement verticalAlignment="Top">
-                    <font fontName="Noto Sans" isBold="true"/>
-                </textElement>
-                <text><![CDATA[Duration:]]></text>
-            </staticText>
-            <textField isBlankWhenNull="true">
-                <reportElement x="82" y="40" width="388" height="20" uuid="bafe2045-04c0-40b6-803e-03941dd6f77a"/>
-                <textElement verticalAlignment="Top">
-                    <font fontName="Noto Sans"/>
+        <textElement textAlignment="Center" verticalAlignment="Middle">
+          <font fontName="Noto Sans" size="9" isBold="true"/>
+          <paragraph lineSpacing="AtLeast"/>
+        </textElement>
+        <text><![CDATA[Total]]></text>
+      </staticText>
+      <staticText>
+        <reportElement mode="Opaque" x="510" y="40" width="50" height="20" backcolor="#87B77B"
+          uuid="1cb41bf6-b644-4dae-8e8e-690d8a9295a7"/>
+        <box>
+          <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+        </box>
+        <textElement textAlignment="Center" verticalAlignment="Middle">
+          <font fontName="Noto Sans" size="9" isBold="true"/>
+        </textElement>
+        <text><![CDATA[Passed]]></text>
+      </staticText>
+      <staticText>
+        <reportElement mode="Opaque" x="560" y="40" width="40" height="20" backcolor="#F36C4A"
+          uuid="9d8e885a-6c11-4500-a95e-b60c3eaf55c9"/>
+        <box>
+          <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+        </box>
+        <textElement textAlignment="Center" verticalAlignment="Middle">
+          <font fontName="Noto Sans" size="9" isBold="true"/>
+        </textElement>
+        <text><![CDATA[Failed]]></text>
+      </staticText>
+      <staticText>
+        <reportElement mode="Opaque" x="600" y="40" width="48" height="20" backcolor="#BDC7CC"
+          uuid="b85b72e9-4054-457b-bb42-b44bd3e4b858"/>
+        <box>
+          <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+        </box>
+        <textElement textAlignment="Center" verticalAlignment="Middle">
+          <font fontName="Noto Sans" size="9" isBold="true"/>
+        </textElement>
+        <text><![CDATA[Skipped]]></text>
+      </staticText>
+      <textField>
+        <reportElement x="480" y="60" width="30" height="20"
+          uuid="be0a5e88-b3b2-4bb2-881d-90ff51d7caf1"/>
+        <box>
+          <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+        </box>
+        <textElement textAlignment="Center" verticalAlignment="Middle">
+          <font fontName="Noto Sans" size="9"/>
+        </textElement>
+        <textFieldExpression><![CDATA[$P{TOTAL}]]></textFieldExpression>
+      </textField>
+      <textField>
+        <reportElement x="510" y="60" width="50" height="20"
+          uuid="3c0d9905-b60e-4c9b-80b4-d7d6b60e174e"/>
+        <box>
+          <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+        </box>
+        <textElement textAlignment="Center" verticalAlignment="Middle">
+          <font fontName="Noto Sans" size="9"/>
+        </textElement>
+        <textFieldExpression><![CDATA[$P{PASSED}]]></textFieldExpression>
+      </textField>
+      <textField>
+        <reportElement x="560" y="60" width="40" height="20"
+          uuid="c6fcfe12-2e78-44dd-b271-b16b191b3fc9"/>
+        <box>
+          <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+        </box>
+        <textElement textAlignment="Center" verticalAlignment="Middle">
+          <font fontName="Noto Sans" size="9"/>
+        </textElement>
+        <textFieldExpression><![CDATA[$P{FAILED}]]></textFieldExpression>
+      </textField>
+      <textField>
+        <reportElement x="600" y="60" width="48" height="20"
+          uuid="4272b431-fab3-40fd-92f5-1de979e56249"/>
+        <box>
+          <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+        </box>
+        <textElement textAlignment="Center" verticalAlignment="Middle">
+          <font fontName="Noto Sans" size="9"/>
+        </textElement>
+        <textFieldExpression><![CDATA[$P{SKIPPED}]]></textFieldExpression>
+      </textField>
+      <staticText>
+        <reportElement mode="Opaque" x="648" y="40" width="30" height="20" backcolor="#F7D63E"
+          uuid="10a4b295-cd29-4a96-8b83-2b8031a5f79e"/>
+        <box>
+          <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+        </box>
+        <textElement textAlignment="Center" verticalAlignment="Middle">
+          <font fontName="Noto Sans" size="9" isBold="true"/>
+        </textElement>
+        <text><![CDATA[AB]]></text>
+      </staticText>
+      <staticText>
+        <reportElement mode="Opaque" x="678" y="40" width="30" height="20" backcolor="#EC3900"
+          uuid="0fa281e5-f495-4c9b-8ead-0346399f7f89"/>
+        <box>
+          <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+        </box>
+        <textElement textAlignment="Center" verticalAlignment="Middle">
+          <font fontName="Noto Sans" size="9" isBold="true"/>
+        </textElement>
+        <text><![CDATA[PB]]></text>
+      </staticText>
+      <staticText>
+        <reportElement mode="Opaque" x="708" y="40" width="30" height="20" backcolor="#0274D1"
+          uuid="6aef0f86-27df-4967-9692-9b7dd7abb2fa"/>
+        <box>
+          <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+        </box>
+        <textElement textAlignment="Center" verticalAlignment="Middle">
+          <font fontName="Noto Sans" size="9" isBold="true"/>
+        </textElement>
+        <text><![CDATA[SI]]></text>
+      </staticText>
+      <staticText>
+        <reportElement mode="Opaque" x="738" y="40" width="30" height="20" backcolor="#BDC7CC"
+          uuid="b9208960-ff59-4de2-8059-9a607f220fbd"/>
+        <box>
+          <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+        </box>
+        <textElement textAlignment="Center" verticalAlignment="Middle">
+          <font fontName="Noto Sans" size="9" isBold="true"/>
+        </textElement>
+        <text><![CDATA[ND]]></text>
+      </staticText>
+      <staticText>
+        <reportElement mode="Opaque" x="768" y="40" width="32" height="20" backcolor="#FFB743"
+          uuid="c5c69ffe-8bf0-4290-bb2c-07ae27a82627"/>
+        <box>
+          <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+        </box>
+        <textElement textAlignment="Center" verticalAlignment="Middle">
+          <font fontName="Noto Sans" size="9" isBold="true"/>
+        </textElement>
+        <text><![CDATA[TI]]></text>
+      </staticText>
+      <textField>
+        <reportElement x="648" y="60" width="30" height="20"
+          uuid="2011a38d-2f02-43fa-8004-a0d49df5cd99"/>
+        <box>
+          <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+        </box>
+        <textElement textAlignment="Center" verticalAlignment="Middle">
+          <font fontName="Noto Sans" size="9"/>
+        </textElement>
+        <textFieldExpression><![CDATA[$P{AB}]]></textFieldExpression>
+      </textField>
+      <textField>
+        <reportElement x="678" y="60" width="30" height="20"
+          uuid="80d81588-1312-4554-8aa3-72d52c50ed83"/>
+        <box>
+          <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+        </box>
+        <textElement textAlignment="Center" verticalAlignment="Middle">
+          <font fontName="Noto Sans" size="9"/>
+        </textElement>
+        <textFieldExpression><![CDATA[$P{PB}]]></textFieldExpression>
+      </textField>
+      <textField>
+        <reportElement x="708" y="60" width="30" height="20"
+          uuid="2c8561e8-61af-4709-861e-d89b1be0cd6b"/>
+        <box>
+          <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+        </box>
+        <textElement textAlignment="Center" verticalAlignment="Middle">
+          <font fontName="Noto Sans" size="9"/>
+        </textElement>
+        <textFieldExpression><![CDATA[$P{SI}]]></textFieldExpression>
+      </textField>
+      <textField>
+        <reportElement x="738" y="60" width="30" height="20"
+          uuid="e348f9a4-6e6a-4815-b20e-0ebcfe8a3f40"/>
+        <box>
+          <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+        </box>
+        <textElement textAlignment="Center" verticalAlignment="Middle">
+          <font fontName="Noto Sans" size="9"/>
+        </textElement>
+        <textFieldExpression><![CDATA[$P{ND}]]></textFieldExpression>
+      </textField>
+      <textField>
+        <reportElement x="768" y="60" width="32" height="20"
+          uuid="7e2ef588-7105-4960-a393-44371e5652a2"/>
+        <box>
+          <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+          <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
+        </box>
+        <textElement textAlignment="Center" verticalAlignment="Middle">
+          <font fontName="Noto Sans" size="9"/>
+        </textElement>
+        <textFieldExpression><![CDATA[$P{TI}]]></textFieldExpression>
+      </textField>
+    </band>
+  </title>
+  <detail>
+    <band height="303" splitType="Stretch">
+      <componentElement>
+        <reportElement x="0" y="0" width="800" height="300"
+          uuid="854b8278-360a-4dba-9bd1-3a77189f6478">
+          <property name="com.jaspersoft.studio.layout"
+            value="com.jaspersoft.studio.editor.layout.VerticalRowLayout"/>
+          <property name="com.jaspersoft.studio.table.style.table_header" value="Table_TH"/>
+          <property name="com.jaspersoft.studio.table.style.column_header" value="Table_CH"/>
+          <property name="com.jaspersoft.studio.table.style.detail" value="Table_TD"/>
+        </reportElement>
+        <jr:table xmlns:jr="http://jasperreports.sourceforge.net/jasperreports/components"
+          xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/components http://jasperreports.sourceforge.net/xsd/components.xsd"
+          whenNoDataType="Blank">
+          <datasetRun subDataset="TestItemsTableDS" uuid="05506102-a762-4b4f-8c9f-0bb284545e94">
+            <dataSourceExpression>
+              <![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($P{TEST_ITEMS}, false)]]></dataSourceExpression>
+          </datasetRun>
+          <jr:column width="90" uuid="b2569992-2bd8-4ff9-a9b3-368d2ca026b7">
+            <property name="com.jaspersoft.studio.components.table.model.column.name"
+              value="Column1"/>
+            <property name="com.jaspersoft.studio.unit.height" value="pixel"/>
+            <jr:columnHeader style="Table_CH" height="30" rowSpan="1">
+              <staticText>
+                <reportElement x="0" y="0" width="90" height="30"
+                  uuid="6ac25c5d-aa07-4c0d-a578-53d2e0f96d42"/>
+                <textElement textAlignment="Center" verticalAlignment="Middle">
+                  <font fontName="Noto Sans" size="9" isBold="true"/>
                 </textElement>
-                <textFieldExpression><![CDATA[$P{LAUNCH_OWNER}]]></textFieldExpression>
-            </textField>
-            <staticText>
-                <reportElement x="0" y="0" width="82" height="20" uuid="e15dcb90-a675-4b87-9a32-eaac213feea1"/>
-                <textElement>
-                    <font fontName="Noto Sans" isBold="true"/>
+                <text><![CDATA[Type]]></text>
+              </staticText>
+            </jr:columnHeader>
+            <jr:detailCell style="Table_TD" height="20">
+              <property name="com.jaspersoft.studio.unit.height" value="px"/>
+              <textField>
+                <reportElement x="0" y="0" width="90" height="20"
+                  uuid="113268f0-68f2-4c5e-b580-ff200e7b853c"/>
+                <textElement textAlignment="Center" verticalAlignment="Middle">
+                  <font fontName="Noto Sans" size="9"/>
                 </textElement>
-                <text><![CDATA[Launch name:]]></text>
-            </staticText>
-            <textField>
-                <reportElement x="82" y="0" width="388" height="20" uuid="7661c90b-7b58-4292-8333-154705ff0701"/>
-                <textElement>
-                    <font fontName="Noto Sans" isBold="true"/>
+                <textFieldExpression><![CDATA[$F{type}]]></textFieldExpression>
+              </textField>
+            </jr:detailCell>
+          </jr:column>
+          <jr:column width="209" uuid="44a6a309-83bd-4546-b0cd-b10728e874dd">
+            <property name="com.jaspersoft.studio.components.table.model.column.name"
+              value="Column2"/>
+            <jr:columnHeader style="Table_CH" height="30" rowSpan="1">
+              <staticText>
+                <reportElement x="0" y="0" width="209" height="30"
+                  uuid="ca534fe2-78f2-44f6-9b03-9bc32970c178"/>
+                <textElement textAlignment="Center" verticalAlignment="Middle">
+                  <font fontName="Noto Sans" size="9" isBold="true"/>
                 </textElement>
-                <textFieldExpression><![CDATA[$P{LAUNCH_NAME}]]></textFieldExpression>
-            </textField>
-            <staticText>
-                <reportElement x="0" y="20" width="82" height="20" uuid="e4b2bcf3-cc0a-4156-a4aa-cddf2a16d5c0"/>
-                <textElement>
-                    <font fontName="Noto Sans" isBold="true"/>
+                <text><![CDATA[Name]]></text>
+              </staticText>
+            </jr:columnHeader>
+            <jr:detailCell style="Table_TD" height="20">
+              <textField isStretchWithOverflow="true">
+                <reportElement x="0" y="0" width="209" height="20"
+                  uuid="1ed705a6-1478-4fa5-82d0-f626e5aa6f7e"/>
+                <textElement verticalAlignment="Middle">
+                  <font fontName="Noto Sans" size="9"/>
                 </textElement>
-                <text><![CDATA[Description:]]></text>
-            </staticText>
-            <textField>
-                <reportElement x="82" y="20" width="388" height="20" uuid="b0b0090b-1fe2-4349-afd2-5f08bfa31187"/>
-                <textElement>
-                    <font fontName="Noto Sans"/>
+                <textFieldExpression><![CDATA[$F{name}]]></textFieldExpression>
+              </textField>
+            </jr:detailCell>
+          </jr:column>
+          <jr:column width="50" uuid="4c3f0fac-1fb3-467d-81a7-36b9b2d84302">
+            <property name="com.jaspersoft.studio.components.table.model.column.name"
+              value="Column13"/>
+            <jr:columnHeader style="Table_CH" height="30" rowSpan="1">
+              <staticText>
+                <reportElement x="0" y="0" width="50" height="30"
+                  uuid="3fe70789-6869-4b8d-bf21-be0fc66b623e"/>
+                <textElement textAlignment="Center" verticalAlignment="Middle">
+                  <font fontName="Noto Sans" size="9" isBold="true"/>
                 </textElement>
-                <textFieldExpression><![CDATA[$P{LAUNCH_DESCRIPTION}]]></textFieldExpression>
-            </textField>
-            <staticText>
-                <reportElement x="480" y="0" width="320" height="20" uuid="fa79751f-81e6-40fb-b2aa-de1031768dc8"/>
-                <box>
-                    <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                </box>
+                <text><![CDATA[Duration (sec)]]></text>
+              </staticText>
+            </jr:columnHeader>
+            <jr:detailCell style="Table_TD" height="20">
+              <textField>
+                <reportElement x="0" y="0" width="50" height="20"
+                  uuid="ba201ea1-3041-4d50-b546-d3b9a4ce5543"/>
                 <textElement textAlignment="Center" verticalAlignment="Middle">
-                    <font fontName="Noto Sans" isBold="true"/>
+                  <font fontName="Noto Sans" size="9"/>
                 </textElement>
-                <text><![CDATA[Launch statistic]]></text>
-            </staticText>
-            <staticText>
-                <reportElement x="480" y="20" width="168" height="20" uuid="d018d389-4a79-4095-b4f8-fbfaef41246d"/>
-                <box>
-                    <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                </box>
+                <textFieldExpression><![CDATA[$F{duration}]]></textFieldExpression>
+              </textField>
+            </jr:detailCell>
+          </jr:column>
+          <jr:column width="70" uuid="4c3f0fac-1fb3-467d-81a7-36b9b2d84401">
+            <property name="com.jaspersoft.studio.components.table.model.column.name"
+              value="Column3"/>
+            <jr:columnHeader style="Table_CH" height="30" rowSpan="1">
+              <staticText>
+                <reportElement x="0" y="0" width="70" height="30"
+                  uuid="3fe70789-6869-4b8d-bf21-be0fc66b619e"/>
                 <textElement textAlignment="Center" verticalAlignment="Middle">
-                    <font fontName="Noto Sans" isBold="true"/>
+                  <font fontName="Noto Sans" size="9" isBold="true"/>
                 </textElement>
-                <text><![CDATA[Execution statistic]]></text>
-            </staticText>
-            <staticText>
-                <reportElement x="648" y="20" width="152" height="20" uuid="7fd8af2f-840f-4b1c-927b-18168bc9422c"/>
-                <box>
-                    <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                </box>
+                <text><![CDATA[Status]]></text>
+              </staticText>
+            </jr:columnHeader>
+            <jr:detailCell style="Table_TD" height="20">
+              <textField>
+                <reportElement x="0" y="0" width="70" height="20"
+                  uuid="ba201ea1-3041-4d50-b546-d3b9a4ce5433"/>
                 <textElement textAlignment="Center" verticalAlignment="Middle">
-                    <font fontName="Noto Sans" isBold="true"/>
+                  <font fontName="Noto Sans" size="9"/>
                 </textElement>
-                <text><![CDATA[Issue statistic]]></text>
-            </staticText>
-            <staticText>
-                <reportElement mode="Opaque" x="480" y="40" width="30" height="20" backcolor="#489BEB"
-                               uuid="364a016c-13cc-476e-a112-c293a2e4aa9c"/>
-                <box>
-                    <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                </box>
+                <textFieldExpression><![CDATA[$F{status}]]></textFieldExpression>
+              </textField>
+            </jr:detailCell>
+          </jr:column>
+          <jr:column width="40" uuid="299a618c-60b1-45ee-bfd3-dfee01b8a36c">
+            <property name="com.jaspersoft.studio.components.table.model.column.name"
+              value="Column4"/>
+            <jr:columnHeader style="Table_CH" height="30" rowSpan="1">
+              <staticText>
+                <reportElement x="0" y="0" width="40" height="30"
+                  uuid="c4fef87b-707e-4406-8821-a3690eaf04a9"/>
                 <textElement textAlignment="Center" verticalAlignment="Middle">
-                    <font fontName="Noto Sans" size="9" isBold="true"/>
-                    <paragraph lineSpacing="AtLeast"/>
+                  <font fontName="Noto Sans" size="9" isBold="true"/>
                 </textElement>
                 <text><![CDATA[Total]]></text>
-            </staticText>
-            <staticText>
-                <reportElement mode="Opaque" x="510" y="40" width="50" height="20" backcolor="#87B77B"
-                               uuid="1cb41bf6-b644-4dae-8e8e-690d8a9295a7"/>
-                <box>
-                    <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                </box>
+              </staticText>
+            </jr:columnHeader>
+            <jr:detailCell style="Table_TD" height="20">
+              <textField>
+                <reportElement x="0" y="0" width="40" height="20"
+                  uuid="ba96f816-5077-44a1-b820-76375d356550"/>
                 <textElement textAlignment="Center" verticalAlignment="Middle">
-                    <font fontName="Noto Sans" size="9" isBold="true"/>
+                  <font fontName="Noto Sans" size="9"/>
                 </textElement>
-                <text><![CDATA[Passed]]></text>
-            </staticText>
-            <staticText>
-                <reportElement mode="Opaque" x="560" y="40" width="40" height="20" backcolor="#F36C4A"
-                               uuid="9d8e885a-6c11-4500-a95e-b60c3eaf55c9"/>
-                <box>
-                    <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                </box>
+                <textFieldExpression><![CDATA[$F{total}.toString()]]></textFieldExpression>
+              </textField>
+            </jr:detailCell>
+          </jr:column>
+          <jr:column width="51" uuid="036301ab-1dbb-4ab1-a25b-206fc3871d54">
+            <property name="com.jaspersoft.studio.components.table.model.column.name"
+              value="Column5"/>
+            <jr:columnHeader style="Table_CH" height="30" rowSpan="1">
+              <staticText>
+                <reportElement x="0" y="0" width="51" height="30"
+                  uuid="a5bfbd41-ceb3-4cc0-a823-dbccdc163799"/>
                 <textElement textAlignment="Center" verticalAlignment="Middle">
-                    <font fontName="Noto Sans" size="9" isBold="true"/>
+                  <font fontName="Noto Sans" size="9" isBold="true"/>
                 </textElement>
-                <text><![CDATA[Failed]]></text>
-            </staticText>
-            <staticText>
-                <reportElement mode="Opaque" x="600" y="40" width="48" height="20" backcolor="#BDC7CC"
-                               uuid="b85b72e9-4054-457b-bb42-b44bd3e4b858"/>
-                <box>
-                    <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                </box>
+                <text><![CDATA[Passed]]></text>
+              </staticText>
+            </jr:columnHeader>
+            <jr:detailCell style="Table_TD" height="20">
+              <textField>
+                <reportElement x="0" y="0" width="51" height="20"
+                  uuid="c714fea4-aa63-4704-a36d-148cc6720185"/>
                 <textElement textAlignment="Center" verticalAlignment="Middle">
-                    <font fontName="Noto Sans" size="9" isBold="true"/>
+                  <font fontName="Noto Sans" size="9"/>
                 </textElement>
-                <text><![CDATA[Skipped]]></text>
-            </staticText>
-            <textField>
-                <reportElement x="480" y="60" width="30" height="20" uuid="be0a5e88-b3b2-4bb2-881d-90ff51d7caf1"/>
-                <box>
-                    <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                </box>
+                <textFieldExpression><![CDATA[$F{passed}.toString()]]></textFieldExpression>
+              </textField>
+            </jr:detailCell>
+          </jr:column>
+          <jr:column width="40" uuid="012751ee-ecd0-4259-aaaa-8bf219a2269a">
+            <property name="com.jaspersoft.studio.components.table.model.column.name"
+              value="Column6"/>
+            <jr:columnHeader style="Table_CH" height="30" rowSpan="1">
+              <staticText>
+                <reportElement x="0" y="0" width="40" height="30"
+                  uuid="e705346a-5e09-4d83-addd-1f514ec17b6d"/>
                 <textElement textAlignment="Center" verticalAlignment="Middle">
-                    <font fontName="Noto Sans" size="9"/>
+                  <font fontName="Noto Sans" size="9" isBold="true"/>
                 </textElement>
-                <textFieldExpression><![CDATA[$P{TOTAL}]]></textFieldExpression>
-            </textField>
-            <textField>
-                <reportElement x="510" y="60" width="50" height="20" uuid="3c0d9905-b60e-4c9b-80b4-d7d6b60e174e"/>
-                <box>
-                    <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                </box>
+                <text><![CDATA[Failed]]></text>
+              </staticText>
+            </jr:columnHeader>
+            <jr:detailCell style="Table_TD" height="20">
+              <textField>
+                <reportElement x="0" y="0" width="40" height="20"
+                  uuid="258d73ee-ddef-4902-bbce-a424d2c4f130"/>
                 <textElement textAlignment="Center" verticalAlignment="Middle">
-                    <font fontName="Noto Sans" size="9"/>
+                  <font fontName="Noto Sans" size="9"/>
                 </textElement>
-                <textFieldExpression><![CDATA[$P{PASSED}]]></textFieldExpression>
-            </textField>
-            <textField>
-                <reportElement x="560" y="60" width="40" height="20" uuid="c6fcfe12-2e78-44dd-b271-b16b191b3fc9"/>
-                <box>
-                    <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                </box>
+                <textFieldExpression><![CDATA[$F{failed}.toString()]]></textFieldExpression>
+              </textField>
+            </jr:detailCell>
+          </jr:column>
+          <jr:column width="50" uuid="08db46ac-76eb-416c-97e7-c3748e6671fa">
+            <property name="com.jaspersoft.studio.components.table.model.column.name"
+              value="Column7"/>
+            <jr:columnHeader style="Table_CH" height="30" rowSpan="1">
+              <staticText>
+                <reportElement x="0" y="0" width="50" height="30"
+                  uuid="1ae2a81b-db01-49f0-b25c-89cfc989eb41"/>
                 <textElement textAlignment="Center" verticalAlignment="Middle">
-                    <font fontName="Noto Sans" size="9"/>
+                  <font fontName="Noto Sans" size="9" isBold="true"/>
                 </textElement>
-                <textFieldExpression><![CDATA[$P{FAILED}]]></textFieldExpression>
-            </textField>
-            <textField>
-                <reportElement x="600" y="60" width="48" height="20" uuid="4272b431-fab3-40fd-92f5-1de979e56249"/>
-                <box>
-                    <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                </box>
+                <text><![CDATA[Skipped]]></text>
+              </staticText>
+            </jr:columnHeader>
+            <jr:detailCell style="Table_TD" height="20">
+              <textField>
+                <reportElement x="0" y="0" width="50" height="20"
+                  uuid="508d7d97-04ff-4734-b0e9-826fdc2b30f6"/>
                 <textElement textAlignment="Center" verticalAlignment="Middle">
-                    <font fontName="Noto Sans" size="9"/>
+                  <font fontName="Noto Sans" size="9"/>
                 </textElement>
-                <textFieldExpression><![CDATA[$P{SKIPPED}]]></textFieldExpression>
-            </textField>
-            <staticText>
-                <reportElement mode="Opaque" x="648" y="40" width="30" height="20" backcolor="#F7D63E"
-                               uuid="10a4b295-cd29-4a96-8b83-2b8031a5f79e"/>
-                <box>
-                    <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                </box>
+                <textFieldExpression><![CDATA[$F{skipped}.toString()]]></textFieldExpression>
+              </textField>
+            </jr:detailCell>
+          </jr:column>
+          <jr:column width="40" uuid="6fe1d4d9-e98e-408a-bbfd-9217632c4248">
+            <property name="com.jaspersoft.studio.components.table.model.column.name"
+              value="Column8"/>
+            <jr:columnHeader style="Table_CH" height="30" rowSpan="1">
+              <staticText>
+                <reportElement x="0" y="0" width="40" height="30"
+                  uuid="ed1bfe30-4c47-4fc2-9902-7e98261b56b0"/>
                 <textElement textAlignment="Center" verticalAlignment="Middle">
-                    <font fontName="Noto Sans" size="9" isBold="true"/>
+                  <font fontName="Noto Sans" size="9" isBold="true"/>
                 </textElement>
                 <text><![CDATA[AB]]></text>
-            </staticText>
-            <staticText>
-                <reportElement mode="Opaque" x="678" y="40" width="30" height="20" backcolor="#EC3900"
-                               uuid="0fa281e5-f495-4c9b-8ead-0346399f7f89"/>
-                <box>
-                    <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                </box>
+              </staticText>
+            </jr:columnHeader>
+            <jr:detailCell style="Table_TD" height="20">
+              <textField>
+                <reportElement x="0" y="0" width="40" height="20"
+                  uuid="568bf98d-a032-4242-8ea5-c509d07952a5"/>
                 <textElement textAlignment="Center" verticalAlignment="Middle">
-                    <font fontName="Noto Sans" size="9" isBold="true"/>
+                  <font fontName="Noto Sans" size="9"/>
                 </textElement>
-                <text><![CDATA[PB]]></text>
-            </staticText>
-            <staticText>
-                <reportElement mode="Opaque" x="708" y="40" width="30" height="20" backcolor="#0274D1"
-                               uuid="6aef0f86-27df-4967-9692-9b7dd7abb2fa"/>
-                <box>
-                    <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                </box>
+                <textFieldExpression><![CDATA[$F{automationBug}.toString()]]></textFieldExpression>
+              </textField>
+            </jr:detailCell>
+          </jr:column>
+          <jr:column width="40" uuid="64a44a55-7fd1-4937-977a-d393be83748a">
+            <property name="com.jaspersoft.studio.components.table.model.column.name"
+              value="Column9"/>
+            <jr:columnHeader style="Table_CH" height="30" rowSpan="1">
+              <staticText>
+                <reportElement x="0" y="0" width="40" height="30"
+                  uuid="3e6f717a-5f91-4db4-a849-4aeeac81ecb2"/>
                 <textElement textAlignment="Center" verticalAlignment="Middle">
-                    <font fontName="Noto Sans" size="9" isBold="true"/>
+                  <font fontName="Noto Sans" size="9" isBold="true"/>
                 </textElement>
-                <text><![CDATA[SI]]></text>
-            </staticText>
-            <staticText>
-                <reportElement mode="Opaque" x="738" y="40" width="30" height="20" backcolor="#BDC7CC"
-                               uuid="b9208960-ff59-4de2-8059-9a607f220fbd"/>
-                <box>
-                    <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                </box>
+                <text><![CDATA[PB]]></text>
+              </staticText>
+            </jr:columnHeader>
+            <jr:detailCell style="Table_TD" height="20">
+              <textField>
+                <reportElement x="0" y="0" width="40" height="20"
+                  uuid="65fe9d6e-8e44-46d6-a795-3298db9b40b2"/>
                 <textElement textAlignment="Center" verticalAlignment="Middle">
-                    <font fontName="Noto Sans" size="9" isBold="true"/>
+                  <font fontName="Noto Sans" size="9"/>
                 </textElement>
-                <text><![CDATA[ND]]></text>
-            </staticText>
-            <staticText>
-                <reportElement mode="Opaque" x="768" y="40" width="32" height="20" backcolor="#FFB743"
-                               uuid="c5c69ffe-8bf0-4290-bb2c-07ae27a82627"/>
-                <box>
-                    <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                </box>
+                <textFieldExpression><![CDATA[$F{productBug}.toString()]]></textFieldExpression>
+              </textField>
+            </jr:detailCell>
+          </jr:column>
+          <jr:column width="40" uuid="fbe03a89-85d3-489a-82bf-571bc9901603">
+            <property name="com.jaspersoft.studio.components.table.model.column.name"
+              value="Column10"/>
+            <jr:columnHeader style="Table_CH" height="30" rowSpan="1">
+              <staticText>
+                <reportElement x="0" y="0" width="40" height="30"
+                  uuid="9175f909-a932-455c-8719-00c20d39fd21"/>
                 <textElement textAlignment="Center" verticalAlignment="Middle">
-                    <font fontName="Noto Sans" size="9" isBold="true"/>
+                  <font fontName="Noto Sans" size="9" isBold="true"/>
                 </textElement>
-                <text><![CDATA[TI]]></text>
-            </staticText>
-            <textField>
-                <reportElement x="648" y="60" width="30" height="20" uuid="2011a38d-2f02-43fa-8004-a0d49df5cd99"/>
-                <box>
-                    <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                </box>
+                <text><![CDATA[SI]]></text>
+              </staticText>
+            </jr:columnHeader>
+            <jr:detailCell style="Table_TD" height="20">
+              <textField>
+                <reportElement x="0" y="0" width="40" height="20"
+                  uuid="f917ddc4-503b-4911-89ca-a8c1b63ce588"/>
                 <textElement textAlignment="Center" verticalAlignment="Middle">
-                    <font fontName="Noto Sans" size="9"/>
+                  <font fontName="Noto Sans" size="9"/>
                 </textElement>
-                <textFieldExpression><![CDATA[$P{AB}]]></textFieldExpression>
-            </textField>
-            <textField>
-                <reportElement x="678" y="60" width="30" height="20" uuid="80d81588-1312-4554-8aa3-72d52c50ed83"/>
-                <box>
-                    <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                </box>
+                <textFieldExpression><![CDATA[$F{systemIssue}.toString()]]></textFieldExpression>
+              </textField>
+            </jr:detailCell>
+          </jr:column>
+          <jr:column width="40" uuid="2ef87095-2dc4-4b56-9383-06bcca1017a6">
+            <property name="com.jaspersoft.studio.components.table.model.column.name"
+              value="Column11"/>
+            <jr:columnHeader style="Table_CH" height="30" rowSpan="1">
+              <staticText>
+                <reportElement x="0" y="0" width="40" height="30"
+                  uuid="b1c0a90a-1757-45fc-95cb-370a7d20b262"/>
                 <textElement textAlignment="Center" verticalAlignment="Middle">
-                    <font fontName="Noto Sans" size="9"/>
+                  <font fontName="Noto Sans" size="9" isBold="true"/>
                 </textElement>
-                <textFieldExpression><![CDATA[$P{PB}]]></textFieldExpression>
-            </textField>
-            <textField>
-                <reportElement x="708" y="60" width="30" height="20" uuid="2c8561e8-61af-4709-861e-d89b1be0cd6b"/>
-                <box>
-                    <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                </box>
+                <text><![CDATA[ND]]></text>
+              </staticText>
+            </jr:columnHeader>
+            <jr:detailCell style="Table_TD" height="20">
+              <textField>
+                <reportElement x="0" y="0" width="40" height="20"
+                  uuid="d18e6732-4b1b-4dbe-af93-53af34f8a530"/>
                 <textElement textAlignment="Center" verticalAlignment="Middle">
-                    <font fontName="Noto Sans" size="9"/>
+                  <font fontName="Noto Sans" size="9"/>
                 </textElement>
-                <textFieldExpression><![CDATA[$P{SI}]]></textFieldExpression>
-            </textField>
-            <textField>
-                <reportElement x="738" y="60" width="30" height="20" uuid="e348f9a4-6e6a-4815-b20e-0ebcfe8a3f40"/>
-                <box>
-                    <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                </box>
+                <textFieldExpression><![CDATA[$F{noDefect}.toString()]]></textFieldExpression>
+              </textField>
+            </jr:detailCell>
+          </jr:column>
+          <jr:column width="40" uuid="ea408a50-e25d-487f-aaa8-ce4686ce4d2f">
+            <property name="com.jaspersoft.studio.components.table.model.column.name"
+              value="Column12"/>
+            <jr:columnHeader style="Table_CH" height="30" rowSpan="1">
+              <staticText>
+                <reportElement x="0" y="0" width="40" height="30"
+                  uuid="03c2d2fb-cb4a-48fc-b18d-4a6b3ba2fabc"/>
                 <textElement textAlignment="Center" verticalAlignment="Middle">
-                    <font fontName="Noto Sans" size="9"/>
+                  <font fontName="Noto Sans" size="9" isBold="true"/>
                 </textElement>
-                <textFieldExpression><![CDATA[$P{ND}]]></textFieldExpression>
-            </textField>
-            <textField>
-                <reportElement x="768" y="60" width="32" height="20" uuid="7e2ef588-7105-4960-a393-44371e5652a2"/>
-                <box>
-                    <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                    <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
-                </box>
+                <text><![CDATA[TI]]></text>
+              </staticText>
+            </jr:columnHeader>
+            <jr:detailCell style="Table_TD" height="20">
+              <textField>
+                <reportElement x="0" y="0" width="40" height="20"
+                  uuid="798423a0-99ec-4bc6-a82a-e95235ffbdd7"/>
                 <textElement textAlignment="Center" verticalAlignment="Middle">
-                    <font fontName="Noto Sans" size="9"/>
+                  <font fontName="Noto Sans" size="9"/>
                 </textElement>
-                <textFieldExpression><![CDATA[$P{TI}]]></textFieldExpression>
-            </textField>
-        </band>
-    </title>
-    <detail>
-        <band height="303" splitType="Stretch">
-            <componentElement>
-                <reportElement x="0" y="0" width="800" height="300" uuid="854b8278-360a-4dba-9bd1-3a77189f6478">
-                    <property name="com.jaspersoft.studio.layout" value="com.jaspersoft.studio.editor.layout.VerticalRowLayout"/>
-                    <property name="com.jaspersoft.studio.table.style.table_header" value="Table_TH"/>
-                    <property name="com.jaspersoft.studio.table.style.column_header" value="Table_CH"/>
-                    <property name="com.jaspersoft.studio.table.style.detail" value="Table_TD"/>
-                </reportElement>
-                <jr:table xmlns:jr="http://jasperreports.sourceforge.net/jasperreports/components"
-                          xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/components http://jasperreports.sourceforge.net/xsd/components.xsd"
-                          whenNoDataType="Blank">
-                    <datasetRun subDataset="TestItemsTableDS" uuid="05506102-a762-4b4f-8c9f-0bb284545e94">
-                        <dataSourceExpression>
-                            <![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($P{TEST_ITEMS}, false)]]></dataSourceExpression>
-                    </datasetRun>
-                    <jr:column width="90" uuid="b2569992-2bd8-4ff9-a9b3-368d2ca026b7">
-                        <property name="com.jaspersoft.studio.components.table.model.column.name" value="Column1"/>
-                        <property name="com.jaspersoft.studio.unit.height" value="pixel"/>
-                        <jr:columnHeader style="Table_CH" height="30" rowSpan="1">
-                            <staticText>
-                                <reportElement x="0" y="0" width="90" height="30" uuid="6ac25c5d-aa07-4c0d-a578-53d2e0f96d42"/>
-                                <textElement textAlignment="Center" verticalAlignment="Middle">
-                                    <font fontName="Noto Sans" size="9" isBold="true"/>
-                                </textElement>
-                                <text><![CDATA[Type]]></text>
-                            </staticText>
-                        </jr:columnHeader>
-                        <jr:detailCell style="Table_TD" height="20">
-                            <property name="com.jaspersoft.studio.unit.height" value="px"/>
-                            <textField>
-                                <reportElement x="0" y="0" width="90" height="20" uuid="113268f0-68f2-4c5e-b580-ff200e7b853c"/>
-                                <textElement textAlignment="Center" verticalAlignment="Middle">
-                                    <font fontName="Noto Sans" size="9"/>
-                                </textElement>
-                                <textFieldExpression><![CDATA[$F{type}]]></textFieldExpression>
-                            </textField>
-                        </jr:detailCell>
-                    </jr:column>
-                    <jr:column width="209" uuid="44a6a309-83bd-4546-b0cd-b10728e874dd">
-                        <property name="com.jaspersoft.studio.components.table.model.column.name" value="Column2"/>
-                        <jr:columnHeader style="Table_CH" height="30" rowSpan="1">
-                            <staticText>
-                                <reportElement x="0" y="0" width="209" height="30" uuid="ca534fe2-78f2-44f6-9b03-9bc32970c178"/>
-                                <textElement textAlignment="Center" verticalAlignment="Middle">
-                                    <font fontName="Noto Sans" size="9" isBold="true"/>
-                                </textElement>
-                                <text><![CDATA[Name]]></text>
-                            </staticText>
-                        </jr:columnHeader>
-                        <jr:detailCell style="Table_TD" height="20">
-                            <textField isStretchWithOverflow="true">
-                                <reportElement x="0" y="0" width="209" height="20" uuid="1ed705a6-1478-4fa5-82d0-f626e5aa6f7e"/>
-                                <textElement verticalAlignment="Middle">
-                                    <font fontName="Noto Sans" size="9"/>
-                                </textElement>
-                                <textFieldExpression><![CDATA[$F{name}]]></textFieldExpression>
-                            </textField>
-                        </jr:detailCell>
-                    </jr:column>
-                    <jr:column width="50" uuid="4c3f0fac-1fb3-467d-81a7-36b9b2d84302">
-                        <property name="com.jaspersoft.studio.components.table.model.column.name" value="Column13"/>
-                        <jr:columnHeader style="Table_CH" height="30" rowSpan="1">
-                            <staticText>
-                                <reportElement x="0" y="0" width="50" height="30" uuid="3fe70789-6869-4b8d-bf21-be0fc66b623e"/>
-                                <textElement textAlignment="Center" verticalAlignment="Middle">
-                                    <font fontName="Noto Sans" size="9" isBold="true"/>
-                                </textElement>
-                                <text><![CDATA[Duration (sec)]]></text>
-                            </staticText>
-                        </jr:columnHeader>
-                        <jr:detailCell style="Table_TD" height="20">
-                            <textField>
-                                <reportElement x="0" y="0" width="50" height="20" uuid="ba201ea1-3041-4d50-b546-d3b9a4ce5543"/>
-                                <textElement textAlignment="Center" verticalAlignment="Middle">
-                                    <font fontName="Noto Sans" size="9"/>
-                                </textElement>
-                                <textFieldExpression><![CDATA[$F{duration}]]></textFieldExpression>
-                            </textField>
-                        </jr:detailCell>
-                    </jr:column>
-                    <jr:column width="70" uuid="4c3f0fac-1fb3-467d-81a7-36b9b2d84401">
-                        <property name="com.jaspersoft.studio.components.table.model.column.name" value="Column3"/>
-                        <jr:columnHeader style="Table_CH" height="30" rowSpan="1">
-                            <staticText>
-                                <reportElement x="0" y="0" width="70" height="30" uuid="3fe70789-6869-4b8d-bf21-be0fc66b619e"/>
-                                <textElement textAlignment="Center" verticalAlignment="Middle">
-                                    <font fontName="Noto Sans" size="9" isBold="true"/>
-                                </textElement>
-                                <text><![CDATA[Status]]></text>
-                            </staticText>
-                        </jr:columnHeader>
-                        <jr:detailCell style="Table_TD" height="20">
-                            <textField>
-                                <reportElement x="0" y="0" width="70" height="20" uuid="ba201ea1-3041-4d50-b546-d3b9a4ce5433"/>
-                                <textElement textAlignment="Center" verticalAlignment="Middle">
-                                    <font fontName="Noto Sans" size="9"/>
-                                </textElement>
-                                <textFieldExpression><![CDATA[$F{status}]]></textFieldExpression>
-                            </textField>
-                        </jr:detailCell>
-                    </jr:column>
-                    <jr:column width="40" uuid="299a618c-60b1-45ee-bfd3-dfee01b8a36c">
-                        <property name="com.jaspersoft.studio.components.table.model.column.name" value="Column4"/>
-                        <jr:columnHeader style="Table_CH" height="30" rowSpan="1">
-                            <staticText>
-                                <reportElement x="0" y="0" width="40" height="30" uuid="c4fef87b-707e-4406-8821-a3690eaf04a9"/>
-                                <textElement textAlignment="Center" verticalAlignment="Middle">
-                                    <font fontName="Noto Sans" size="9" isBold="true"/>
-                                </textElement>
-                                <text><![CDATA[Total]]></text>
-                            </staticText>
-                        </jr:columnHeader>
-                        <jr:detailCell style="Table_TD" height="20">
-                            <textField>
-                                <reportElement x="0" y="0" width="40" height="20" uuid="ba96f816-5077-44a1-b820-76375d356550"/>
-                                <textElement textAlignment="Center" verticalAlignment="Middle">
-                                    <font fontName="Noto Sans" size="9"/>
-                                </textElement>
-                                <textFieldExpression><![CDATA[$F{total}.toString()]]></textFieldExpression>
-                            </textField>
-                        </jr:detailCell>
-                    </jr:column>
-                    <jr:column width="51" uuid="036301ab-1dbb-4ab1-a25b-206fc3871d54">
-                        <property name="com.jaspersoft.studio.components.table.model.column.name" value="Column5"/>
-                        <jr:columnHeader style="Table_CH" height="30" rowSpan="1">
-                            <staticText>
-                                <reportElement x="0" y="0" width="51" height="30" uuid="a5bfbd41-ceb3-4cc0-a823-dbccdc163799"/>
-                                <textElement textAlignment="Center" verticalAlignment="Middle">
-                                    <font fontName="Noto Sans" size="9" isBold="true"/>
-                                </textElement>
-                                <text><![CDATA[Passed]]></text>
-                            </staticText>
-                        </jr:columnHeader>
-                        <jr:detailCell style="Table_TD" height="20">
-                            <textField>
-                                <reportElement x="0" y="0" width="51" height="20" uuid="c714fea4-aa63-4704-a36d-148cc6720185"/>
-                                <textElement textAlignment="Center" verticalAlignment="Middle">
-                                    <font fontName="Noto Sans" size="9"/>
-                                </textElement>
-                                <textFieldExpression><![CDATA[$F{passed}.toString()]]></textFieldExpression>
-                            </textField>
-                        </jr:detailCell>
-                    </jr:column>
-                    <jr:column width="40" uuid="012751ee-ecd0-4259-aaaa-8bf219a2269a">
-                        <property name="com.jaspersoft.studio.components.table.model.column.name" value="Column6"/>
-                        <jr:columnHeader style="Table_CH" height="30" rowSpan="1">
-                            <staticText>
-                                <reportElement x="0" y="0" width="40" height="30" uuid="e705346a-5e09-4d83-addd-1f514ec17b6d"/>
-                                <textElement textAlignment="Center" verticalAlignment="Middle">
-                                    <font fontName="Noto Sans" size="9" isBold="true"/>
-                                </textElement>
-                                <text><![CDATA[Failed]]></text>
-                            </staticText>
-                        </jr:columnHeader>
-                        <jr:detailCell style="Table_TD" height="20">
-                            <textField>
-                                <reportElement x="0" y="0" width="40" height="20" uuid="258d73ee-ddef-4902-bbce-a424d2c4f130"/>
-                                <textElement textAlignment="Center" verticalAlignment="Middle">
-                                    <font fontName="Noto Sans" size="9"/>
-                                </textElement>
-                                <textFieldExpression><![CDATA[$F{failed}.toString()]]></textFieldExpression>
-                            </textField>
-                        </jr:detailCell>
-                    </jr:column>
-                    <jr:column width="50" uuid="08db46ac-76eb-416c-97e7-c3748e6671fa">
-                        <property name="com.jaspersoft.studio.components.table.model.column.name" value="Column7"/>
-                        <jr:columnHeader style="Table_CH" height="30" rowSpan="1">
-                            <staticText>
-                                <reportElement x="0" y="0" width="50" height="30" uuid="1ae2a81b-db01-49f0-b25c-89cfc989eb41"/>
-                                <textElement textAlignment="Center" verticalAlignment="Middle">
-                                    <font fontName="Noto Sans" size="9" isBold="true"/>
-                                </textElement>
-                                <text><![CDATA[Skipped]]></text>
-                            </staticText>
-                        </jr:columnHeader>
-                        <jr:detailCell style="Table_TD" height="20">
-                            <textField>
-                                <reportElement x="0" y="0" width="50" height="20" uuid="508d7d97-04ff-4734-b0e9-826fdc2b30f6"/>
-                                <textElement textAlignment="Center" verticalAlignment="Middle">
-                                    <font fontName="Noto Sans" size="9"/>
-                                </textElement>
-                                <textFieldExpression><![CDATA[$F{skipped}.toString()]]></textFieldExpression>
-                            </textField>
-                        </jr:detailCell>
-                    </jr:column>
-                    <jr:column width="40" uuid="6fe1d4d9-e98e-408a-bbfd-9217632c4248">
-                        <property name="com.jaspersoft.studio.components.table.model.column.name" value="Column8"/>
-                        <jr:columnHeader style="Table_CH" height="30" rowSpan="1">
-                            <staticText>
-                                <reportElement x="0" y="0" width="40" height="30" uuid="ed1bfe30-4c47-4fc2-9902-7e98261b56b0"/>
-                                <textElement textAlignment="Center" verticalAlignment="Middle">
-                                    <font fontName="Noto Sans" size="9" isBold="true"/>
-                                </textElement>
-                                <text><![CDATA[AB]]></text>
-                            </staticText>
-                        </jr:columnHeader>
-                        <jr:detailCell style="Table_TD" height="20">
-                            <textField>
-                                <reportElement x="0" y="0" width="40" height="20" uuid="568bf98d-a032-4242-8ea5-c509d07952a5"/>
-                                <textElement textAlignment="Center" verticalAlignment="Middle">
-                                    <font fontName="Noto Sans" size="9"/>
-                                </textElement>
-                                <textFieldExpression><![CDATA[$F{automationBug}.toString()]]></textFieldExpression>
-                            </textField>
-                        </jr:detailCell>
-                    </jr:column>
-                    <jr:column width="40" uuid="64a44a55-7fd1-4937-977a-d393be83748a">
-                        <property name="com.jaspersoft.studio.components.table.model.column.name" value="Column9"/>
-                        <jr:columnHeader style="Table_CH" height="30" rowSpan="1">
-                            <staticText>
-                                <reportElement x="0" y="0" width="40" height="30" uuid="3e6f717a-5f91-4db4-a849-4aeeac81ecb2"/>
-                                <textElement textAlignment="Center" verticalAlignment="Middle">
-                                    <font fontName="Noto Sans" size="9" isBold="true"/>
-                                </textElement>
-                                <text><![CDATA[PB]]></text>
-                            </staticText>
-                        </jr:columnHeader>
-                        <jr:detailCell style="Table_TD" height="20">
-                            <textField>
-                                <reportElement x="0" y="0" width="40" height="20" uuid="65fe9d6e-8e44-46d6-a795-3298db9b40b2"/>
-                                <textElement textAlignment="Center" verticalAlignment="Middle">
-                                    <font fontName="Noto Sans" size="9"/>
-                                </textElement>
-                                <textFieldExpression><![CDATA[$F{productBug}.toString()]]></textFieldExpression>
-                            </textField>
-                        </jr:detailCell>
-                    </jr:column>
-                    <jr:column width="40" uuid="fbe03a89-85d3-489a-82bf-571bc9901603">
-                        <property name="com.jaspersoft.studio.components.table.model.column.name" value="Column10"/>
-                        <jr:columnHeader style="Table_CH" height="30" rowSpan="1">
-                            <staticText>
-                                <reportElement x="0" y="0" width="40" height="30" uuid="9175f909-a932-455c-8719-00c20d39fd21"/>
-                                <textElement textAlignment="Center" verticalAlignment="Middle">
-                                    <font fontName="Noto Sans" size="9" isBold="true"/>
-                                </textElement>
-                                <text><![CDATA[SI]]></text>
-                            </staticText>
-                        </jr:columnHeader>
-                        <jr:detailCell style="Table_TD" height="20">
-                            <textField>
-                                <reportElement x="0" y="0" width="40" height="20" uuid="f917ddc4-503b-4911-89ca-a8c1b63ce588"/>
-                                <textElement textAlignment="Center" verticalAlignment="Middle">
-                                    <font fontName="Noto Sans" size="9"/>
-                                </textElement>
-                                <textFieldExpression><![CDATA[$F{systemIssue}.toString()]]></textFieldExpression>
-                            </textField>
-                        </jr:detailCell>
-                    </jr:column>
-                    <jr:column width="40" uuid="2ef87095-2dc4-4b56-9383-06bcca1017a6">
-                        <property name="com.jaspersoft.studio.components.table.model.column.name" value="Column11"/>
-                        <jr:columnHeader style="Table_CH" height="30" rowSpan="1">
-                            <staticText>
-                                <reportElement x="0" y="0" width="40" height="30" uuid="b1c0a90a-1757-45fc-95cb-370a7d20b262"/>
-                                <textElement textAlignment="Center" verticalAlignment="Middle">
-                                    <font fontName="Noto Sans" size="9" isBold="true"/>
-                                </textElement>
-                                <text><![CDATA[ND]]></text>
-                            </staticText>
-                        </jr:columnHeader>
-                        <jr:detailCell style="Table_TD" height="20">
-                            <textField>
-                                <reportElement x="0" y="0" width="40" height="20" uuid="d18e6732-4b1b-4dbe-af93-53af34f8a530"/>
-                                <textElement textAlignment="Center" verticalAlignment="Middle">
-                                    <font fontName="Noto Sans" size="9"/>
-                                </textElement>
-                                <textFieldExpression><![CDATA[$F{noDefect}.toString()]]></textFieldExpression>
-                            </textField>
-                        </jr:detailCell>
-                    </jr:column>
-                    <jr:column width="40" uuid="ea408a50-e25d-487f-aaa8-ce4686ce4d2f">
-                        <property name="com.jaspersoft.studio.components.table.model.column.name" value="Column12"/>
-                        <jr:columnHeader style="Table_CH" height="30" rowSpan="1">
-                            <staticText>
-                                <reportElement x="0" y="0" width="40" height="30" uuid="03c2d2fb-cb4a-48fc-b18d-4a6b3ba2fabc"/>
-                                <textElement textAlignment="Center" verticalAlignment="Middle">
-                                    <font fontName="Noto Sans" size="9" isBold="true"/>
-                                </textElement>
-                                <text><![CDATA[TI]]></text>
-                            </staticText>
-                        </jr:columnHeader>
-                        <jr:detailCell style="Table_TD" height="20">
-                            <textField>
-                                <reportElement x="0" y="0" width="40" height="20" uuid="798423a0-99ec-4bc6-a82a-e95235ffbdd7"/>
-                                <textElement textAlignment="Center" verticalAlignment="Middle">
-                                    <font fontName="Noto Sans" size="9"/>
-                                </textElement>
-                                <textFieldExpression><![CDATA[$F{toInvestigate}.toString()]]></textFieldExpression>
-                            </textField>
-                        </jr:detailCell>
-                    </jr:column>
-                </jr:table>
-            </componentElement>
-        </band>
-    </detail>
-    <pageFooter>
-        <band height="22">
-            <textField>
-                <reportElement x="680" y="0" width="60" height="20" uuid="27912fc5-278f-4ede-aff7-d2bbe49124b8"/>
-                <textElement textAlignment="Right"/>
-                <textFieldExpression><![CDATA["Page " + $V{PAGE_NUMBER}]]></textFieldExpression>
-            </textField>
-            <textField evaluationTime="Report">
-                <reportElement x="740" y="0" width="60" height="20" uuid="1f1297e2-e72a-49b7-9220-7ae53baf1c09"/>
-                <textElement textAlignment="Left"/>
-                <textFieldExpression><![CDATA[" of " + $V{PAGE_NUMBER}]]></textFieldExpression>
-            </textField>
-        </band>
-    </pageFooter>
+                <textFieldExpression><![CDATA[$F{toInvestigate}.toString()]]></textFieldExpression>
+              </textField>
+            </jr:detailCell>
+          </jr:column>
+        </jr:table>
+      </componentElement>
+    </band>
+  </detail>
+  <pageFooter>
+    <band height="22">
+      <textField>
+        <reportElement x="680" y="0" width="60" height="20"
+          uuid="27912fc5-278f-4ede-aff7-d2bbe49124b8"/>
+        <textElement textAlignment="Right"/>
+        <textFieldExpression><![CDATA["Page " + $V{PAGE_NUMBER}]]></textFieldExpression>
+      </textField>
+      <textField evaluationTime="Report">
+        <reportElement x="740" y="0" width="60" height="20"
+          uuid="1f1297e2-e72a-49b7-9220-7ae53baf1c09"/>
+        <textElement textAlignment="Left"/>
+        <textFieldExpression><![CDATA[" of " + $V{PAGE_NUMBER}]]></textFieldExpression>
+      </textField>
+    </band>
+  </pageFooter>
 </jasperReport>
diff --git a/src/main/resources/templates/report/users.jrxml b/src/main/resources/templates/report/users.jrxml
index 43a0d2822f..b5802d2091 100644
--- a/src/main/resources/templates/report/users.jrxml
+++ b/src/main/resources/templates/report/users.jrxml
@@ -16,135 +16,163 @@
   -->
 
 <!-- Created with Jaspersoft Studio version 6.6.0.final using JasperReports Library version 6.6.0  -->
-<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-              xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd"
-              name="test" pageWidth="842" pageHeight="595" orientation="Landscape" columnWidth="802" leftMargin="20" rightMargin="20"
-              topMargin="20" bottomMargin="20" uuid="7a5c9b49-9dc5-422a-ac69-e92cf61ef530" isIgnorePagination="true">
-    <property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/>
-    <style name="Title" forecolor="#FFFFFF" fontName="Noto Sans" fontSize="50" isBold="false"/>
-    <style name="SubTitle" forecolor="#CCCCCC" fontName="Noto Sans" fontSize="18" isBold="false"/>
-    <style name="Column header" forecolor="#666666" fontName="Noto Sans" fontSize="14" isBold="true"/>
-    <style name="Detail" mode="Transparent" fontName="Noto Sans"/>
-    <style name="Row" mode="Transparent" fontName="Noto Sans" pdfFontName="Times-Roman">
-        <conditionalStyle>
-            <conditionExpression><![CDATA[$V{REPORT_COUNT}%2 == 0]]></conditionExpression>
-            <style mode="Opaque" backcolor="#F0EFEF"/>
-        </conditionalStyle>
-    </style>
-    <queryString>
-        <![CDATA[]]>
-    </queryString>
-    <field name="Full name" class="java.lang.String"/>
-    <field name="Type" class="java.lang.String"/>
-    <field name="Login" class="java.lang.String"/>
-    <field name="Email" class="java.lang.String"/>
-    <field name="Last login" class="java.lang.String"/>
-    <field name="Projects and Roles" class="java.lang.String"/>
-    <background>
-        <band splitType="Stretch"/>
-    </background>
-    <columnHeader>
-        <band height="23" splitType="Stretch">
-            <staticText>
-                <reportElement x="0" y="0" width="180" height="18" uuid="1e0d3905-6d0e-4660-ac0a-9b6ca6b47b93">
-                    <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="f172f0b8-1df3-4c59-bec2-45f6582696e3"/>
-                </reportElement>
-                <textElement textAlignment="Center"/>
-                <text><![CDATA[Full name]]></text>
-            </staticText>
-            <staticText>
-                <reportElement x="180" y="0" width="80" height="18" uuid="82d59e26-2731-4f85-b1ee-3179b20e6f07">
-                    <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="f172f0b8-1df3-4c59-bec2-45f6582696e3"/>
-                </reportElement>
-                <textElement textAlignment="Center"/>
-                <text><![CDATA[Type]]></text>
-            </staticText>
-            <staticText>
-                <reportElement x="260" y="0" width="150" height="18" uuid="64cc94b9-8766-49b1-8b9f-e45296c5c9c7">
-                    <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="3ebec559-1ba4-4dc0-978b-ff46d0298c59"/>
-                </reportElement>
-                <textElement textAlignment="Center"/>
-                <text><![CDATA[Login]]></text>
-            </staticText>
-            <staticText>
-                <reportElement x="410" y="0" width="150" height="18" uuid="b0549432-b1b4-41af-931e-7e25e63d738c">
-                    <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="0eca9f7f-619a-44d6-9cf6-46dc79e5e251"/>
-                </reportElement>
-                <textElement textAlignment="Center"/>
-                <text><![CDATA[Email]]></text>
-            </staticText>
-            <staticText>
-                <reportElement x="560" y="0" width="120" height="18" uuid="e0ddb3e8-ddc4-41af-b0bb-5299862be558">
-                    <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="7d2a698e-beb1-4dbb-b059-0654b305955e"/>
-                </reportElement>
-                <textElement textAlignment="Center"/>
-                <text><![CDATA[Last login]]></text>
-            </staticText>
-            <staticText>
-                <reportElement x="680" y="0" width="117" height="18" uuid="ac60d496-d8c7-4543-b8da-1112cde3fc2c">
-                    <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="d4571106-56c2-445d-a317-a38effb2595b"/>
-                </reportElement>
-                <textElement textAlignment="Center"/>
-                <text><![CDATA[Projects and Roles]]></text>
-            </staticText>
-        </band>
-    </columnHeader>
-    <detail>
-        <band height="18" splitType="Stretch">
-            <frame>
-                <reportElement style="Row" mode="Opaque" x="0" y="0" width="797" height="18" uuid="34a2ae4b-4055-476b-8676-d499f6af510b"/>
-                <textField>
-                    <reportElement x="0" y="0" width="180" height="30" uuid="42609d3f-7d28-44f2-b8ea-650fbbcf746f">
-                        <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="f172f0b8-1df3-4c59-bec2-45f6582696e3"/>
-                        <property name="net.sf.jasperreports.print.keep.full.text" value="true"/>
-                    </reportElement>
-                    <textElement textAlignment="Center"/>
-                    <textFieldExpression><![CDATA[$F{Full name}]]></textFieldExpression>
-                </textField>
-                <textField>
-                    <reportElement x="180" y="0" width="80" height="30" uuid="9d167ef4-d39b-4963-9d55-593d5a6e388a">
-                        <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="f172f0b8-1df3-4c59-bec2-45f6582696e3"/>
-                        <property name="net.sf.jasperreports.print.keep.full.text" value="true"/>
-                    </reportElement>
-                    <textElement textAlignment="Center"/>
-                    <textFieldExpression><![CDATA[$F{Type}]]></textFieldExpression>
-                </textField>
-                <textField>
-                    <reportElement x="260" y="0" width="150" height="30" uuid="66d3c031-147d-40f1-a43b-d1d9a3a6e457">
-                        <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="3ebec559-1ba4-4dc0-978b-ff46d0298c59"/>
-                        <property name="net.sf.jasperreports.print.keep.full.text" value="true"/>
-                    </reportElement>
-                    <textElement textAlignment="Center"/>
-                    <textFieldExpression><![CDATA[$F{Login}]]></textFieldExpression>
-                </textField>
-                <textField>
-                    <reportElement x="410" y="0" width="150" height="30" uuid="d4aa9cdc-f50c-4cb9-9246-f0f57250f17f">
-                        <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="0eca9f7f-619a-44d6-9cf6-46dc79e5e251"/>
-                        <property name="net.sf.jasperreports.print.keep.full.text" value="true"/>
-                    </reportElement>
-                    <textElement textAlignment="Center"/>
-                    <textFieldExpression><![CDATA[$F{Email}]]></textFieldExpression>
-                </textField>
-                <textField>
-                    <reportElement x="560" y="0" width="120" height="30" uuid="47939077-bc56-4fc7-85b9-2942fcaddaa0">
-                        <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="7d2a698e-beb1-4dbb-b059-0654b305955e"/>
-                        <property name="net.sf.jasperreports.print.keep.full.text" value="true"/>
-                    </reportElement>
-                    <textElement textAlignment="Center"/>
-                    <textFieldExpression><![CDATA[$F{Last login}]]></textFieldExpression>
-                </textField>
-                <textField>
-                    <reportElement x="680" y="0" width="117" height="30" uuid="5fc335bb-6c5a-46ac-b345-fbefa1deec6a">
-                        <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="d4571106-56c2-445d-a317-a38effb2595b"/>
-                        <property name="net.sf.jasperreports.print.keep.full.text" value="true"/>
-                    </reportElement>
-                    <textElement textAlignment="Center" verticalAlignment="Top"/>
-                    <textFieldExpression><![CDATA[$F{Projects and Roles}]]></textFieldExpression>
-                </textField>
-            </frame>
-        </band>
-    </detail>
-    <summary>
-        <band splitType="Stretch"/>
-    </summary>
+<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd"
+  name="test" pageWidth="842" pageHeight="595" orientation="Landscape" columnWidth="802"
+  leftMargin="20" rightMargin="20"
+  topMargin="20" bottomMargin="20" uuid="7a5c9b49-9dc5-422a-ac69-e92cf61ef530"
+  isIgnorePagination="true">
+  <property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/>
+  <style name="Title" forecolor="#FFFFFF" fontName="Noto Sans" fontSize="50" isBold="false"/>
+  <style name="SubTitle" forecolor="#CCCCCC" fontName="Noto Sans" fontSize="18" isBold="false"/>
+  <style name="Column header" forecolor="#666666" fontName="Noto Sans" fontSize="14" isBold="true"/>
+  <style name="Detail" mode="Transparent" fontName="Noto Sans"/>
+  <style name="Row" mode="Transparent" fontName="Noto Sans" pdfFontName="Times-Roman">
+    <conditionalStyle>
+      <conditionExpression><![CDATA[$V{REPORT_COUNT}%2 == 0]]></conditionExpression>
+      <style mode="Opaque" backcolor="#F0EFEF"/>
+    </conditionalStyle>
+  </style>
+  <queryString>
+    <![CDATA[]]>
+  </queryString>
+  <field name="Full name" class="java.lang.String"/>
+  <field name="Type" class="java.lang.String"/>
+  <field name="Login" class="java.lang.String"/>
+  <field name="Email" class="java.lang.String"/>
+  <field name="Last login" class="java.lang.String"/>
+  <field name="Projects and Roles" class="java.lang.String"/>
+  <background>
+    <band splitType="Stretch"/>
+  </background>
+  <columnHeader>
+    <band height="23" splitType="Stretch">
+      <staticText>
+        <reportElement x="0" y="0" width="180" height="18"
+          uuid="1e0d3905-6d0e-4660-ac0a-9b6ca6b47b93">
+          <property name="com.jaspersoft.studio.spreadsheet.connectionID"
+            value="f172f0b8-1df3-4c59-bec2-45f6582696e3"/>
+        </reportElement>
+        <textElement textAlignment="Center"/>
+        <text><![CDATA[Full name]]></text>
+      </staticText>
+      <staticText>
+        <reportElement x="180" y="0" width="80" height="18"
+          uuid="82d59e26-2731-4f85-b1ee-3179b20e6f07">
+          <property name="com.jaspersoft.studio.spreadsheet.connectionID"
+            value="f172f0b8-1df3-4c59-bec2-45f6582696e3"/>
+        </reportElement>
+        <textElement textAlignment="Center"/>
+        <text><![CDATA[Type]]></text>
+      </staticText>
+      <staticText>
+        <reportElement x="260" y="0" width="150" height="18"
+          uuid="64cc94b9-8766-49b1-8b9f-e45296c5c9c7">
+          <property name="com.jaspersoft.studio.spreadsheet.connectionID"
+            value="3ebec559-1ba4-4dc0-978b-ff46d0298c59"/>
+        </reportElement>
+        <textElement textAlignment="Center"/>
+        <text><![CDATA[Login]]></text>
+      </staticText>
+      <staticText>
+        <reportElement x="410" y="0" width="150" height="18"
+          uuid="b0549432-b1b4-41af-931e-7e25e63d738c">
+          <property name="com.jaspersoft.studio.spreadsheet.connectionID"
+            value="0eca9f7f-619a-44d6-9cf6-46dc79e5e251"/>
+        </reportElement>
+        <textElement textAlignment="Center"/>
+        <text><![CDATA[Email]]></text>
+      </staticText>
+      <staticText>
+        <reportElement x="560" y="0" width="120" height="18"
+          uuid="e0ddb3e8-ddc4-41af-b0bb-5299862be558">
+          <property name="com.jaspersoft.studio.spreadsheet.connectionID"
+            value="7d2a698e-beb1-4dbb-b059-0654b305955e"/>
+        </reportElement>
+        <textElement textAlignment="Center"/>
+        <text><![CDATA[Last login]]></text>
+      </staticText>
+      <staticText>
+        <reportElement x="680" y="0" width="117" height="18"
+          uuid="ac60d496-d8c7-4543-b8da-1112cde3fc2c">
+          <property name="com.jaspersoft.studio.spreadsheet.connectionID"
+            value="d4571106-56c2-445d-a317-a38effb2595b"/>
+        </reportElement>
+        <textElement textAlignment="Center"/>
+        <text><![CDATA[Projects and Roles]]></text>
+      </staticText>
+    </band>
+  </columnHeader>
+  <detail>
+    <band height="18" splitType="Stretch">
+      <frame>
+        <reportElement style="Row" mode="Opaque" x="0" y="0" width="797" height="18"
+          uuid="34a2ae4b-4055-476b-8676-d499f6af510b"/>
+        <textField>
+          <reportElement x="0" y="0" width="180" height="30"
+            uuid="42609d3f-7d28-44f2-b8ea-650fbbcf746f">
+            <property name="com.jaspersoft.studio.spreadsheet.connectionID"
+              value="f172f0b8-1df3-4c59-bec2-45f6582696e3"/>
+            <property name="net.sf.jasperreports.print.keep.full.text" value="true"/>
+          </reportElement>
+          <textElement textAlignment="Center"/>
+          <textFieldExpression><![CDATA[$F{Full name}]]></textFieldExpression>
+        </textField>
+        <textField>
+          <reportElement x="180" y="0" width="80" height="30"
+            uuid="9d167ef4-d39b-4963-9d55-593d5a6e388a">
+            <property name="com.jaspersoft.studio.spreadsheet.connectionID"
+              value="f172f0b8-1df3-4c59-bec2-45f6582696e3"/>
+            <property name="net.sf.jasperreports.print.keep.full.text" value="true"/>
+          </reportElement>
+          <textElement textAlignment="Center"/>
+          <textFieldExpression><![CDATA[$F{Type}]]></textFieldExpression>
+        </textField>
+        <textField>
+          <reportElement x="260" y="0" width="150" height="30"
+            uuid="66d3c031-147d-40f1-a43b-d1d9a3a6e457">
+            <property name="com.jaspersoft.studio.spreadsheet.connectionID"
+              value="3ebec559-1ba4-4dc0-978b-ff46d0298c59"/>
+            <property name="net.sf.jasperreports.print.keep.full.text" value="true"/>
+          </reportElement>
+          <textElement textAlignment="Center"/>
+          <textFieldExpression><![CDATA[$F{Login}]]></textFieldExpression>
+        </textField>
+        <textField>
+          <reportElement x="410" y="0" width="150" height="30"
+            uuid="d4aa9cdc-f50c-4cb9-9246-f0f57250f17f">
+            <property name="com.jaspersoft.studio.spreadsheet.connectionID"
+              value="0eca9f7f-619a-44d6-9cf6-46dc79e5e251"/>
+            <property name="net.sf.jasperreports.print.keep.full.text" value="true"/>
+          </reportElement>
+          <textElement textAlignment="Center"/>
+          <textFieldExpression><![CDATA[$F{Email}]]></textFieldExpression>
+        </textField>
+        <textField>
+          <reportElement x="560" y="0" width="120" height="30"
+            uuid="47939077-bc56-4fc7-85b9-2942fcaddaa0">
+            <property name="com.jaspersoft.studio.spreadsheet.connectionID"
+              value="7d2a698e-beb1-4dbb-b059-0654b305955e"/>
+            <property name="net.sf.jasperreports.print.keep.full.text" value="true"/>
+          </reportElement>
+          <textElement textAlignment="Center"/>
+          <textFieldExpression><![CDATA[$F{Last login}]]></textFieldExpression>
+        </textField>
+        <textField>
+          <reportElement x="680" y="0" width="117" height="30"
+            uuid="5fc335bb-6c5a-46ac-b345-fbefa1deec6a">
+            <property name="com.jaspersoft.studio.spreadsheet.connectionID"
+              value="d4571106-56c2-445d-a317-a38effb2595b"/>
+            <property name="net.sf.jasperreports.print.keep.full.text" value="true"/>
+          </reportElement>
+          <textElement textAlignment="Center" verticalAlignment="Top"/>
+          <textFieldExpression><![CDATA[$F{Projects and Roles}]]></textFieldExpression>
+        </textField>
+      </frame>
+    </band>
+  </detail>
+  <summary>
+    <band splitType="Stretch"/>
+  </summary>
 </jasperReport>
diff --git a/src/test/java/com/epam/ta/reportportal/ReportPortalUserUtil.java b/src/test/java/com/epam/ta/reportportal/ReportPortalUserUtil.java
index 2ce24d750f..1b72d998e8 100644
--- a/src/test/java/com/epam/ta/reportportal/ReportPortalUserUtil.java
+++ b/src/test/java/com/epam/ta/reportportal/ReportPortalUserUtil.java
@@ -28,23 +28,24 @@
  */
 public class ReportPortalUserUtil {
 
-	public static final String TEST_PROJECT_NAME = "test_project";
+  public static final String TEST_PROJECT_NAME = "test_project";
 
-	private ReportPortalUserUtil() {
-		//static only
-	}
+  private ReportPortalUserUtil() {
+    //static only
+  }
 
-	public static ReportPortalUser getRpUser(String login, UserRole userRole, ProjectRole projectRole, Long projectId) {
-		return ReportPortalUser.userBuilder()
-				.withUserName(login)
-				.withPassword("test")
-				.withAuthorities(Sets.newHashSet(new SimpleGrantedAuthority(userRole.getAuthority())))
-				.withUserId(1L)
-				.withEmail("test@email.com")
-				.withUserRole(userRole)
-				.withProjectDetails(Maps.newHashMap("test_project",
-						new ReportPortalUser.ProjectDetails(projectId, TEST_PROJECT_NAME, projectRole)
-				))
-				.build();
-	}
+  public static ReportPortalUser getRpUser(String login, UserRole userRole, ProjectRole projectRole,
+      Long projectId) {
+    return ReportPortalUser.userBuilder()
+        .withUserName(login)
+        .withPassword("test")
+        .withAuthorities(Sets.newHashSet(new SimpleGrantedAuthority(userRole.getAuthority())))
+        .withUserId(1L)
+        .withEmail("test@email.com")
+        .withUserRole(userRole)
+        .withProjectDetails(Maps.newHashMap("test_project",
+            new ReportPortalUser.ProjectDetails(projectId, TEST_PROJECT_NAME, projectRole)
+        ))
+        .build();
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/TestConfig.java b/src/test/java/com/epam/ta/reportportal/TestConfig.java
index 2975908dd5..0effafeacb 100644
--- a/src/test/java/com/epam/ta/reportportal/TestConfig.java
+++ b/src/test/java/com/epam/ta/reportportal/TestConfig.java
@@ -24,14 +24,20 @@
 import com.fasterxml.jackson.databind.SerializationFeature;
 import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
 import com.rabbitmq.http.client.Client;
+import org.springframework.amqp.rabbit.connection.ConnectionFactory;
 import org.springframework.amqp.rabbit.core.RabbitTemplate;
 import org.springframework.amqp.support.converter.MessageConverter;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
 import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;
+import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
 import org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration;
 import org.springframework.boot.test.mock.mockito.MockBean;
-import org.springframework.context.annotation.*;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.FilterType;
+import org.springframework.context.annotation.Profile;
 import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter;
 import org.springframework.security.oauth2.provider.token.DefaultUserAuthenticationConverter;
 import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
@@ -40,58 +46,65 @@
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @Configuration
-@EnableAutoConfiguration(exclude = { QuartzAutoConfiguration.class, RabbitAutoConfiguration.class })
-@ComponentScan(value = { "com.epam.ta.reportportal" }, excludeFilters = {
-		@ComponentScan.Filter(type = FilterType.REGEX, pattern = "com.epam.ta.reportportal.ws.rabbit.*"),
-		@ComponentScan.Filter(type = FilterType.REGEX, pattern = { "com.epam.ta.reportportal.job.*" }),
-		@ComponentScan.Filter(type = FilterType.REGEX, pattern = { "com.epam.ta.reportportal.core.integration.migration.*" }),
-		@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = ApplicationContextAwareFactoryBeanTest.TestConfig.class) })
+@EnableAutoConfiguration(exclude = {QuartzAutoConfiguration.class, RabbitAutoConfiguration.class})
+@ComponentScan(value = {"com.epam.ta.reportportal"}, excludeFilters = {
+    @ComponentScan.Filter(type = FilterType.REGEX, pattern = "com.epam.ta.reportportal.ws.rabbit.*"),
+    @ComponentScan.Filter(type = FilterType.REGEX, pattern = {"com.epam.ta.reportportal.job.*"}),
+    @ComponentScan.Filter(type = FilterType.REGEX, pattern = {
+        "com.epam.ta.reportportal.core.integration.migration.*"}),
+    @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = ApplicationContextAwareFactoryBeanTest.TestConfig.class)})
 public class TestConfig {
 
-	@MockBean
-	protected Client rabbitClient;
+  @MockBean
+  protected Client rabbitClient;
 
-	@MockBean(name = "analyzerRabbitTemplate")
-	protected RabbitTemplate analyzerRabbitTemplate;
+  @MockBean(name = "analyzerRabbitTemplate")
+  protected RabbitTemplate analyzerRabbitTemplate;
 
-	@MockBean(name = "rabbitTemplate")
-	protected RabbitTemplate rabbitTemplate;
+  @MockBean(name = "rabbitTemplate")
+  protected RabbitTemplate rabbitTemplate;
 
-	@MockBean
-	protected MessageConverter messageConverter;
+  @MockBean(name = "connectionFactory")
+  protected ConnectionFactory connectionFactory;
 
-	@Autowired
-	private DatabaseUserDetailsService userDetailsService;
+  @MockBean(name = "simpleRabbitListenerContainerFactoryConfigurer")
+  protected SimpleRabbitListenerContainerFactoryConfigurer simpleRabbitListenerContainerFactoryConfigurer;
 
-	@Bean
-	@Profile("unittest")
-	protected RabbitMqManagementClient managementTemplate() {
-		return new RabbitMqManagementClientTemplate(rabbitClient, "analyzer");
-	}
+  @MockBean
+  protected MessageConverter messageConverter;
 
-	@Bean
-	@Profile("unittest")
-	public JwtAccessTokenConverter accessTokenConverter() {
-		JwtAccessTokenConverter jwtConverter = new JwtAccessTokenConverter();
-		jwtConverter.setSigningKey("123");
+  @Autowired
+  private DatabaseUserDetailsService userDetailsService;
 
-		DefaultAccessTokenConverter accessTokenConverter = new DefaultAccessTokenConverter();
-		DefaultUserAuthenticationConverter defaultUserAuthenticationConverter = new DefaultUserAuthenticationConverter();
-		defaultUserAuthenticationConverter.setUserDetailsService(userDetailsService);
-		accessTokenConverter.setUserTokenConverter(defaultUserAuthenticationConverter);
+  @Bean
+  @Profile("unittest")
+  protected RabbitMqManagementClient managementTemplate() {
+    return new RabbitMqManagementClientTemplate(rabbitClient, "analyzer");
+  }
 
-		jwtConverter.setAccessTokenConverter(accessTokenConverter);
+  @Bean
+  @Profile("unittest")
+  public JwtAccessTokenConverter accessTokenConverter() {
+    JwtAccessTokenConverter jwtConverter = new JwtAccessTokenConverter();
+    jwtConverter.setSigningKey("123");
 
-		return jwtConverter;
-	}
+    DefaultAccessTokenConverter accessTokenConverter = new DefaultAccessTokenConverter();
+    DefaultUserAuthenticationConverter defaultUserAuthenticationConverter = new DefaultUserAuthenticationConverter();
+    defaultUserAuthenticationConverter.setUserDetailsService(userDetailsService);
+    accessTokenConverter.setUserTokenConverter(defaultUserAuthenticationConverter);
 
-	@Bean
-	public ObjectMapper testObjectMapper() {
-		ObjectMapper objectMapper = new ObjectMapper();
+    jwtConverter.setAccessTokenConverter(accessTokenConverter);
 
-		objectMapper.configure(SerializationFeature.WRAP_ROOT_VALUE, false);
-		objectMapper.registerModule(new JavaTimeModule());
+    return jwtConverter;
+  }
 
-		return objectMapper;
-	}
+  @Bean
+  public ObjectMapper testObjectMapper() {
+    ObjectMapper objectMapper = new ObjectMapper();
+
+    objectMapper.configure(SerializationFeature.WRAP_ROOT_VALUE, false);
+    objectMapper.registerModule(new JavaTimeModule());
+
+    return objectMapper;
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/auth/OAuthHelper.java b/src/test/java/com/epam/ta/reportportal/auth/OAuthHelper.java
index dfe60f28d6..407a7f4cdb 100644
--- a/src/test/java/com/epam/ta/reportportal/auth/OAuthHelper.java
+++ b/src/test/java/com/epam/ta/reportportal/auth/OAuthHelper.java
@@ -17,6 +17,13 @@
 package com.epam.ta.reportportal.auth;
 
 import com.epam.ta.reportportal.entity.user.UserRole;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.GrantedAuthority;
@@ -28,66 +35,66 @@
 import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
 import org.springframework.stereotype.Component;
 
-import java.util.*;
-import java.util.stream.Collectors;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @Component
 public class OAuthHelper {
 
-	@Autowired
-	private AuthorizationServerTokenServices tokenService;
+  @Autowired
+  private AuthorizationServerTokenServices tokenService;
 
-	private String defaultToken;
+  private String defaultToken;
 
-	private String superadminToken;
+  private String superadminToken;
 
-	private String customerToken;
+  private String customerToken;
 
-	public String getDefaultToken() {
-		return defaultToken == null ? defaultToken = createAccessToken("default", "1q2w3e", UserRole.USER).getValue() : defaultToken;
-	}
+  public String getDefaultToken() {
+    return defaultToken == null ? defaultToken = createAccessToken("default", "1q2w3e",
+        UserRole.USER).getValue() : defaultToken;
+  }
 
-	public String getSuperadminToken() {
-		return superadminToken == null ?
-				superadminToken = createAccessToken("superadmin", "erebus", UserRole.ADMINISTRATOR).getValue() :
-				superadminToken;
-	}
+  public String getSuperadminToken() {
+    return superadminToken == null ?
+        superadminToken = createAccessToken("superadmin", "erebus",
+            UserRole.ADMINISTRATOR).getValue() :
+        superadminToken;
+  }
 
-	public String getCustomerToken() {
-		return customerToken == null ?
-				customerToken = createAccessToken("default_customer", "erebus", UserRole.USER).getValue() :
-				customerToken;
-	}
+  public String getCustomerToken() {
+    return customerToken == null ?
+        customerToken = createAccessToken("default_customer", "erebus", UserRole.USER).getValue() :
+        customerToken;
+  }
 
-	private OAuth2AccessToken createAccessToken(String username, String password, UserRole... roles) {
-		Collection<GrantedAuthority> authorities = Arrays.stream(roles)
-				.map(it -> new SimpleGrantedAuthority(it.getAuthority()))
-				.collect(Collectors.toList());
+  private OAuth2AccessToken createAccessToken(String username, String password, UserRole... roles) {
+    Collection<GrantedAuthority> authorities = Arrays.stream(roles)
+        .map(it -> new SimpleGrantedAuthority(it.getAuthority()))
+        .collect(Collectors.toList());
 
-		Set<String> scopes = Collections.singleton("ui");
+    Set<String> scopes = Collections.singleton("ui");
 
-		Map<String, String> requestParameters = new HashMap<>();
-		requestParameters.put("password", password);
-		requestParameters.put("grand_type", "password");
-		requestParameters.put("username", username);
+    Map<String, String> requestParameters = new HashMap<>();
+    requestParameters.put("password", password);
+    requestParameters.put("grand_type", "password");
+    requestParameters.put("username", username);
 
-		OAuth2Request oAuth2Request = new OAuth2Request(
-				requestParameters,
-				"ui",
-				authorities,
-				true,
-				scopes,
-				Collections.emptySet(),
-				null,
-				Collections.emptySet(),
-				Collections.emptyMap()
-		);
-		User userPrincipal = new User(username, password, true, true, true, true, authorities);
-		UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userPrincipal, null, authorities);
-		OAuth2Authentication auth = new OAuth2Authentication(oAuth2Request, authenticationToken);
-		return tokenService.createAccessToken(auth);
-	}
+    OAuth2Request oAuth2Request = new OAuth2Request(
+        requestParameters,
+        "ui",
+        authorities,
+        true,
+        scopes,
+        Collections.emptySet(),
+        null,
+        Collections.emptySet(),
+        Collections.emptyMap()
+    );
+    User userPrincipal = new User(username, password, true, true, true, true, authorities);
+    UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
+        userPrincipal, null, authorities);
+    OAuth2Authentication auth = new OAuth2Authentication(oAuth2Request, authenticationToken);
+    return tokenService.createAccessToken(auth);
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/auth/UserRoleHierarchyTest.java b/src/test/java/com/epam/ta/reportportal/auth/UserRoleHierarchyTest.java
index e7bc03d8a3..dbc8717f8d 100644
--- a/src/test/java/com/epam/ta/reportportal/auth/UserRoleHierarchyTest.java
+++ b/src/test/java/com/epam/ta/reportportal/auth/UserRoleHierarchyTest.java
@@ -16,33 +16,33 @@
 
 package com.epam.ta.reportportal.auth;
 
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+import java.util.Collection;
 import org.junit.jupiter.api.Test;
 import org.mockito.InjectMocks;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.authority.AuthorityUtils;
 
-import java.util.Collection;
-
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-
 /**
  * Created by Andrey_Ivanov1 on 05-Jun-17.
  */
 class UserRoleHierarchyTest {
 
-	@InjectMocks
-	private UserRoleHierarchy userRoleHierarchy = new UserRoleHierarchy();
-
-	@Test
-	void getReachableGrantedAuthoritiesTest() {
-		String string_for_auth = "ROLE_1,ROLE_2,ROLE_3,ROLE_4";
-		Collection<GrantedAuthority> authorities = AuthorityUtils.commaSeparatedStringToAuthorityList(string_for_auth);
-		assertNotNull(userRoleHierarchy.getReachableGrantedAuthorities(authorities));
-	}
-
-	@Test
-	void nullAuthoritiesTest() {
-		Collection<GrantedAuthority> authorities = null;
-		assertNotNull(userRoleHierarchy.getReachableGrantedAuthorities(authorities));
-	}
+  @InjectMocks
+  private UserRoleHierarchy userRoleHierarchy = new UserRoleHierarchy();
+
+  @Test
+  void getReachableGrantedAuthoritiesTest() {
+    String string_for_auth = "ROLE_1,ROLE_2,ROLE_3,ROLE_4";
+    Collection<GrantedAuthority> authorities = AuthorityUtils.commaSeparatedStringToAuthorityList(
+        string_for_auth);
+    assertNotNull(userRoleHierarchy.getReachableGrantedAuthorities(authorities));
+  }
+
+  @Test
+  void nullAuthoritiesTest() {
+    Collection<GrantedAuthority> authorities = null;
+    assertNotNull(userRoleHierarchy.getReachableGrantedAuthorities(authorities));
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/auth/basic/DatabaseUserDetailsServiceTest.java b/src/test/java/com/epam/ta/reportportal/auth/basic/DatabaseUserDetailsServiceTest.java
index 704cbfd361..10f7797491 100644
--- a/src/test/java/com/epam/ta/reportportal/auth/basic/DatabaseUserDetailsServiceTest.java
+++ b/src/test/java/com/epam/ta/reportportal/auth/basic/DatabaseUserDetailsServiceTest.java
@@ -16,7 +16,12 @@
 
 package com.epam.ta.reportportal.auth.basic;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.dao.UserRepository;
+import java.util.Optional;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.InjectMocks;
@@ -24,32 +29,26 @@
 import org.mockito.junit.jupiter.MockitoExtension;
 import org.springframework.security.core.userdetails.UsernameNotFoundException;
 
-import java.util.Optional;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.Mockito.when;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @ExtendWith(MockitoExtension.class)
 class DatabaseUserDetailsServiceTest {
 
-	@Mock
-	private UserRepository userRepository;
+  @Mock
+  private UserRepository userRepository;
 
-	@InjectMocks
-	private DatabaseUserDetailsService userDetailsService;
+  @InjectMocks
+  private DatabaseUserDetailsService userDetailsService;
 
-	@Test
-	void userNotFoundTest() {
-		when(userRepository.findReportPortalUser("not_exist")).thenReturn(Optional.empty());
+  @Test
+  void userNotFoundTest() {
+    when(userRepository.findReportPortalUser("not_exist")).thenReturn(Optional.empty());
 
-		UsernameNotFoundException exception = assertThrows(UsernameNotFoundException.class,
-				() -> userDetailsService.loadUserByUsername("not_exist")
-		);
+    UsernameNotFoundException exception = assertThrows(UsernameNotFoundException.class,
+        () -> userDetailsService.loadUserByUsername("not_exist")
+    );
 
-		assertEquals("User not found", exception.getMessage());
-	}
+    assertEquals("User not found", exception.getMessage());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/client/impl/AnalyzerUtilsTest.java b/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/client/impl/AnalyzerUtilsTest.java
index 39a100fa5c..3c1e0d843e 100644
--- a/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/client/impl/AnalyzerUtilsTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/client/impl/AnalyzerUtilsTest.java
@@ -16,49 +16,55 @@
 
 package com.epam.ta.reportportal.core.analyzer.auto.client.impl;
 
+import static com.epam.ta.reportportal.core.analyzer.auto.client.impl.AnalyzerUtils.ANALYZER_INDEX;
+import static com.epam.ta.reportportal.core.analyzer.auto.client.impl.AnalyzerUtils.ANALYZER_LOG_SEARCH;
+import static com.epam.ta.reportportal.core.analyzer.auto.client.impl.AnalyzerUtils.ANALYZER_PRIORITY;
+import static com.epam.ta.reportportal.core.analyzer.auto.client.impl.AnalyzerUtils.DOES_SUPPORT_SEARCH;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import com.google.common.collect.ImmutableMap;
 import com.rabbitmq.http.client.domain.ExchangeInfo;
-import org.junit.jupiter.api.Test;
-
 import java.util.Collections;
-
-import static com.epam.ta.reportportal.core.analyzer.auto.client.impl.AnalyzerUtils.*;
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author Pavel Bortnik
  */
 class AnalyzerUtilsTest {
 
-	@Test
-	void testParsing() {
-		ExchangeInfo mock = mock(ExchangeInfo.class);
-		when(mock.getArguments()).thenReturn(ImmutableMap.<String, Object>builder().put(ANALYZER_PRIORITY, 1)
-				.put(ANALYZER_INDEX, true)
-				.build());
-		assertEquals(1, AnalyzerUtils.EXCHANGE_PRIORITY.applyAsInt(mock));
-		assertTrue(AnalyzerUtils.DOES_SUPPORT_INDEX.test(mock));
-	}
+  @Test
+  void testParsing() {
+    ExchangeInfo mock = mock(ExchangeInfo.class);
+    when(mock.getArguments()).thenReturn(
+        ImmutableMap.<String, Object>builder().put(ANALYZER_PRIORITY, 1)
+            .put(ANALYZER_INDEX, true)
+            .build());
+    assertEquals(1, AnalyzerUtils.EXCHANGE_PRIORITY.applyAsInt(mock));
+    assertTrue(AnalyzerUtils.DOES_SUPPORT_INDEX.test(mock));
+  }
 
-	@Test
-	void testDefaultValues() {
-		ExchangeInfo mock = mock(ExchangeInfo.class);
-		when(mock.getArguments()).thenReturn(Collections.emptyMap());
-		assertEquals(Integer.MAX_VALUE, AnalyzerUtils.EXCHANGE_PRIORITY.applyAsInt(mock));
-		assertFalse(AnalyzerUtils.DOES_SUPPORT_INDEX.test(mock));
-	}
+  @Test
+  void testDefaultValues() {
+    ExchangeInfo mock = mock(ExchangeInfo.class);
+    when(mock.getArguments()).thenReturn(Collections.emptyMap());
+    assertEquals(Integer.MAX_VALUE, AnalyzerUtils.EXCHANGE_PRIORITY.applyAsInt(mock));
+    assertFalse(AnalyzerUtils.DOES_SUPPORT_INDEX.test(mock));
+  }
 
-	@Test
-	void testBadValues() {
-		ExchangeInfo mock = mock(ExchangeInfo.class);
-		when(mock.getArguments()).thenReturn(ImmutableMap.<String, Object>builder().put(ANALYZER_PRIORITY, "abracadabra")
-				.put(ANALYZER_INDEX, "666")
-				.put(ANALYZER_LOG_SEARCH, "666")
-				.build());
-		assertEquals(Integer.MAX_VALUE, AnalyzerUtils.EXCHANGE_PRIORITY.applyAsInt(mock));
-		assertFalse(AnalyzerUtils.DOES_SUPPORT_INDEX.test(mock));
-		assertFalse(DOES_SUPPORT_SEARCH.test(mock));
-	}
+  @Test
+  void testBadValues() {
+    ExchangeInfo mock = mock(ExchangeInfo.class);
+    when(mock.getArguments()).thenReturn(
+        ImmutableMap.<String, Object>builder().put(ANALYZER_PRIORITY, "abracadabra")
+            .put(ANALYZER_INDEX, "666")
+            .put(ANALYZER_LOG_SEARCH, "666")
+            .build());
+    assertEquals(Integer.MAX_VALUE, AnalyzerUtils.EXCHANGE_PRIORITY.applyAsInt(mock));
+    assertFalse(AnalyzerUtils.DOES_SUPPORT_INDEX.test(mock));
+    assertFalse(DOES_SUPPORT_SEARCH.test(mock));
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/client/impl/IndexerServiceClientImplTest.java b/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/client/impl/IndexerServiceClientImplTest.java
index 314c8d9437..42fa363bff 100644
--- a/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/client/impl/IndexerServiceClientImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/client/impl/IndexerServiceClientImplTest.java
@@ -1,97 +1,108 @@
 package com.epam.ta.reportportal.core.analyzer.auto.client.impl;
 
+import static com.epam.ta.reportportal.core.analyzer.auto.client.impl.AnalyzerUtils.ANALYZER_INDEX;
+import static com.epam.ta.reportportal.core.analyzer.auto.client.impl.AnalyzerUtils.ANALYZER_PRIORITY;
+import static com.epam.ta.reportportal.core.analyzer.auto.client.impl.IndexerServiceClientImpl.DEFECT_UPDATE_ROUTE;
+import static com.epam.ta.reportportal.core.analyzer.auto.client.impl.IndexerServiceClientImpl.DELETE_ROUTE;
+import static com.epam.ta.reportportal.core.analyzer.auto.client.impl.IndexerServiceClientImpl.ITEM_REMOVE_ROUTE;
+import static com.epam.ta.reportportal.core.analyzer.auto.client.impl.IndexerServiceClientImpl.LAUNCH_REMOVE_ROUTE;
+import static com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerStatusCache.AUTO_ANALYZER_KEY;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.mockito.internal.verification.VerificationModeFactory.times;
+
 import com.epam.ta.reportportal.core.analyzer.auto.client.RabbitMqManagementClient;
 import com.epam.ta.reportportal.core.analyzer.auto.client.model.IndexDefectsUpdate;
 import com.epam.ta.reportportal.core.analyzer.auto.client.model.IndexItemsRemove;
 import com.epam.ta.reportportal.core.analyzer.auto.client.model.IndexLaunchRemove;
 import com.rabbitmq.http.client.domain.ExchangeInfo;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import org.assertj.core.util.Lists;
 import org.assertj.core.util.Maps;
 import org.junit.jupiter.api.Test;
 import org.springframework.amqp.rabbit.core.RabbitTemplate;
 import org.springframework.core.ParameterizedTypeReference;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.core.analyzer.auto.client.impl.AnalyzerUtils.ANALYZER_INDEX;
-import static com.epam.ta.reportportal.core.analyzer.auto.client.impl.AnalyzerUtils.ANALYZER_PRIORITY;
-import static com.epam.ta.reportportal.core.analyzer.auto.client.impl.IndexerServiceClientImpl.*;
-import static com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerStatusCache.AUTO_ANALYZER_KEY;
-import static org.mockito.Mockito.*;
-import static org.mockito.internal.verification.VerificationModeFactory.times;
-
 class IndexerServiceClientImplTest {
 
-	private RabbitTemplate rabbitTemplate = mock(RabbitTemplate.class);
+  private RabbitTemplate rabbitTemplate = mock(RabbitTemplate.class);
 
-	private RabbitMqManagementClient rabbitMqManagementClient = mock(RabbitMqManagementClient.class);
+  private RabbitMqManagementClient rabbitMqManagementClient = mock(RabbitMqManagementClient.class);
 
-	private IndexerServiceClientImpl indexerServiceClient = new IndexerServiceClientImpl(rabbitMqManagementClient, rabbitTemplate);
+  private IndexerServiceClientImpl indexerServiceClient = new IndexerServiceClientImpl(
+      rabbitMqManagementClient, rabbitTemplate);
 
-	@Test
-	void deleteIndex() {
-		when(rabbitMqManagementClient.getAnalyzerExchangesInfo()).thenReturn(getExchanges());
-		when(rabbitTemplate.convertSendAndReceiveAsType(AUTO_ANALYZER_KEY, DELETE_ROUTE, 1L, new ParameterizedTypeReference<Integer>() {
-		})).thenReturn(1);
-		indexerServiceClient.deleteIndex(1L);
-		verify(rabbitTemplate, times(1)).convertSendAndReceiveAsType(AUTO_ANALYZER_KEY,
-				DELETE_ROUTE,
-				1L,
-				new ParameterizedTypeReference<Integer>() {
-				}
-		);
-	}
+  @Test
+  void deleteIndex() {
+    when(rabbitMqManagementClient.getAnalyzerExchangesInfo()).thenReturn(getExchanges());
+    when(rabbitTemplate.convertSendAndReceiveAsType(AUTO_ANALYZER_KEY, DELETE_ROUTE, 1L,
+        new ParameterizedTypeReference<Integer>() {
+        })).thenReturn(1);
+    indexerServiceClient.deleteIndex(1L);
+    verify(rabbitTemplate, times(1)).convertSendAndReceiveAsType(AUTO_ANALYZER_KEY,
+        DELETE_ROUTE,
+        1L,
+        new ParameterizedTypeReference<Integer>() {
+        }
+    );
+  }
 
-	@Test
-	void indexDefectsUpdate() {
-		Map<Long, String> update = Maps.newHashMap(1L, "pb001");
-		IndexDefectsUpdate indexDefectsUpdate = new IndexDefectsUpdate(1L, update);
-		when(rabbitMqManagementClient.getAnalyzerExchangesInfo()).thenReturn(getExchanges());
-		when(rabbitTemplate.convertSendAndReceiveAsType(AUTO_ANALYZER_KEY,
-				DEFECT_UPDATE_ROUTE,
-				indexDefectsUpdate,
-				new ParameterizedTypeReference<List<Long>>() {
-				}
-		)).thenReturn(Lists.emptyList());
-		indexerServiceClient.indexDefectsUpdate(1L, update);
-		verify(rabbitTemplate, times(1)).convertSendAndReceiveAsType(AUTO_ANALYZER_KEY,
-				DEFECT_UPDATE_ROUTE,
-				indexDefectsUpdate,
-				new ParameterizedTypeReference<List<Long>>() {
-				}
-		);
-	}
+  @Test
+  void indexDefectsUpdate() {
+    Map<Long, String> update = Maps.newHashMap(1L, "pb001");
+    IndexDefectsUpdate indexDefectsUpdate = new IndexDefectsUpdate(1L, update);
+    when(rabbitMqManagementClient.getAnalyzerExchangesInfo()).thenReturn(getExchanges());
+    when(rabbitTemplate.convertSendAndReceiveAsType(AUTO_ANALYZER_KEY,
+        DEFECT_UPDATE_ROUTE,
+        indexDefectsUpdate,
+        new ParameterizedTypeReference<List<Long>>() {
+        }
+    )).thenReturn(Lists.emptyList());
+    indexerServiceClient.indexDefectsUpdate(1L, update);
+    verify(rabbitTemplate, times(1)).convertSendAndReceiveAsType(AUTO_ANALYZER_KEY,
+        DEFECT_UPDATE_ROUTE,
+        indexDefectsUpdate,
+        new ParameterizedTypeReference<List<Long>>() {
+        }
+    );
+  }
 
-	@Test
-	void indexItemsRemove() {
-		List<Long> list = Lists.newArrayList(1L);
-		IndexItemsRemove indexItemsRemove = new IndexItemsRemove(1L, list);
-		when(rabbitMqManagementClient.getAnalyzerExchangesInfo()).thenReturn(getExchanges());
-		doNothing().when(rabbitTemplate).convertAndSend(AUTO_ANALYZER_KEY, ITEM_REMOVE_ROUTE, indexItemsRemove);
-		indexerServiceClient.indexItemsRemoveAsync(1L, list);
-		verify(rabbitTemplate, times(1)).convertAndSend(AUTO_ANALYZER_KEY, ITEM_REMOVE_ROUTE, indexItemsRemove);
-	}
+  @Test
+  void indexItemsRemove() {
+    List<Long> list = Lists.newArrayList(1L);
+    IndexItemsRemove indexItemsRemove = new IndexItemsRemove(1L, list);
+    when(rabbitMqManagementClient.getAnalyzerExchangesInfo()).thenReturn(getExchanges());
+    doNothing().when(rabbitTemplate)
+        .convertAndSend(AUTO_ANALYZER_KEY, ITEM_REMOVE_ROUTE, indexItemsRemove);
+    indexerServiceClient.indexItemsRemoveAsync(1L, list);
+    verify(rabbitTemplate, times(1)).convertAndSend(AUTO_ANALYZER_KEY, ITEM_REMOVE_ROUTE,
+        indexItemsRemove);
+  }
 
-	@Test
-	void indexLaunchesRemove() {
-		List<Long> list = Lists.newArrayList(1L);
-		IndexLaunchRemove indexLaunchRemove = new IndexLaunchRemove(1L, list);
-		when(rabbitMqManagementClient.getAnalyzerExchangesInfo()).thenReturn(getExchanges());
-		doNothing().when(rabbitTemplate).convertAndSend(AUTO_ANALYZER_KEY, LAUNCH_REMOVE_ROUTE, indexLaunchRemove);
-		indexerServiceClient.indexLaunchesRemove(1L, list);
-		verify(rabbitTemplate, times(1)).convertAndSend(AUTO_ANALYZER_KEY, LAUNCH_REMOVE_ROUTE, indexLaunchRemove);
-	}
+  @Test
+  void indexLaunchesRemove() {
+    List<Long> list = Lists.newArrayList(1L);
+    IndexLaunchRemove indexLaunchRemove = new IndexLaunchRemove(1L, list);
+    when(rabbitMqManagementClient.getAnalyzerExchangesInfo()).thenReturn(getExchanges());
+    doNothing().when(rabbitTemplate)
+        .convertAndSend(AUTO_ANALYZER_KEY, LAUNCH_REMOVE_ROUTE, indexLaunchRemove);
+    indexerServiceClient.indexLaunchesRemove(1L, list);
+    verify(rabbitTemplate, times(1)).convertAndSend(AUTO_ANALYZER_KEY, LAUNCH_REMOVE_ROUTE,
+        indexLaunchRemove);
+  }
 
-	private List<ExchangeInfo> getExchanges() {
-		ExchangeInfo exchangeInfo = new ExchangeInfo();
-		Map<String, Object> params = new HashMap<>();
-		params.put(ANALYZER_PRIORITY, 0);
-		params.put(ANALYZER_INDEX, true);
-		exchangeInfo.setArguments(params);
-		exchangeInfo.setName(AUTO_ANALYZER_KEY);
-		return Lists.newArrayList(exchangeInfo);
-	}
+  private List<ExchangeInfo> getExchanges() {
+    ExchangeInfo exchangeInfo = new ExchangeInfo();
+    Map<String, Object> params = new HashMap<>();
+    params.put(ANALYZER_PRIORITY, 0);
+    params.put(ANALYZER_INDEX, true);
+    exchangeInfo.setArguments(params);
+    exchangeInfo.setName(AUTO_ANALYZER_KEY);
+    return Lists.newArrayList(exchangeInfo);
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/client/impl/RabbitMqManagementClientTemplateTest.java b/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/client/impl/RabbitMqManagementClientTemplateTest.java
index 282d7ed811..e465dfbcdc 100644
--- a/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/client/impl/RabbitMqManagementClientTemplateTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/client/impl/RabbitMqManagementClientTemplateTest.java
@@ -16,6 +16,9 @@
 
 package com.epam.ta.reportportal.core.analyzer.auto.client.impl;
 
+import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.rabbitmq.http.client.Client;
 import org.junit.jupiter.api.Test;
@@ -23,23 +26,21 @@
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 
-import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
-import static org.mockito.Mockito.when;
-
 @ExtendWith(MockitoExtension.class)
 public class RabbitMqManagementClientTemplateTest {
 
-    @Mock
-    private Client rabbitClient;
+  @Mock
+  private Client rabbitClient;
 
-    private RabbitMqManagementClientTemplate template;
+  private RabbitMqManagementClientTemplate template;
 
-    @Test
-    public void testReportPortalExceptionOnGetExchanges() {
-        template = new RabbitMqManagementClientTemplate(rabbitClient, "analyzer");
+  @Test
+  public void testReportPortalExceptionOnGetExchanges() {
+    template = new RabbitMqManagementClientTemplate(rabbitClient, "analyzer");
 
-        when(rabbitClient.getExchanges("analyzer")).thenReturn(null);
+    when(rabbitClient.getExchanges("analyzer")).thenReturn(null);
 
-        assertThatThrownBy(() -> template.getAnalyzerExchangesInfo()).isInstanceOf(ReportPortalException.class);
-    }
+    assertThatThrownBy(() -> template.getAnalyzerExchangesInfo()).isInstanceOf(
+        ReportPortalException.class);
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/impl/AnalyzerServiceServiceTest.java b/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/impl/AnalyzerServiceServiceTest.java
index 6dbd87acbe..ac87b36b49 100644
--- a/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/impl/AnalyzerServiceServiceTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/impl/AnalyzerServiceServiceTest.java
@@ -16,10 +16,23 @@
 
 package com.epam.ta.reportportal.core.analyzer.auto.impl;
 
+import static com.epam.ta.reportportal.entity.AnalyzeMode.ALL_LAUNCHES;
+import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.PRODUCT_BUG;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyList;
+import static org.mockito.Mockito.anyLong;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.mockito.internal.verification.VerificationModeFactory.times;
+
 import com.epam.ta.reportportal.core.analyzer.auto.client.AnalyzerServiceClient;
 import com.epam.ta.reportportal.core.analyzer.auto.impl.preparer.LaunchPreparerService;
 import com.epam.ta.reportportal.core.events.MessageBus;
 import com.epam.ta.reportportal.core.item.impl.IssueTypeHandler;
+import com.epam.ta.reportportal.dao.LaunchRepository;
 import com.epam.ta.reportportal.dao.TestItemRepository;
 import com.epam.ta.reportportal.entity.enums.LogLevel;
 import com.epam.ta.reportportal.entity.enums.StatusEnum;
@@ -34,153 +47,159 @@
 import com.epam.ta.reportportal.ws.model.analyzer.IndexLog;
 import com.epam.ta.reportportal.ws.model.analyzer.IndexTestItem;
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
-import org.junit.jupiter.api.Test;
-
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
 import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.entity.AnalyzeMode.ALL_LAUNCHES;
-import static com.epam.ta.reportportal.entity.enums.TestItemIssueGroup.PRODUCT_BUG;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.mockito.Mockito.*;
-import static org.mockito.internal.verification.VerificationModeFactory.times;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author Pavel Bortnik
  */
 class AnalyzerServiceServiceTest {
 
-	private AnalyzerServiceClient analyzerServiceClient = mock(AnalyzerServiceClient.class);
+  private AnalyzerServiceClient analyzerServiceClient = mock(AnalyzerServiceClient.class);
 
-	private IssueTypeHandler issueTypeHandler = mock(IssueTypeHandler.class);
+  private IssueTypeHandler issueTypeHandler = mock(IssueTypeHandler.class);
 
-	private TestItemRepository testItemRepository = mock(TestItemRepository.class);
+  private TestItemRepository testItemRepository = mock(TestItemRepository.class);
 
-	private MessageBus messageBus = mock(MessageBus.class);
-
-	private LaunchPreparerService launchPreparerService = mock(LaunchPreparerService.class);
+  private LaunchRepository launchRepository = mock(LaunchRepository.class);
+
+  private MessageBus messageBus = mock(MessageBus.class);
 
-	private AnalyzerStatusCache analyzerStatusCache = mock(AnalyzerStatusCache.class);
-
-	private AnalyzerServiceImpl issuesAnalyzer = new AnalyzerServiceImpl(100, analyzerStatusCache,
-			launchPreparerService,
-			analyzerServiceClient,
-			issueTypeHandler,
-			testItemRepository,
-			messageBus
-	);
-
-	@Test
-	void hasAnalyzers() {
-		when(analyzerServiceClient.hasClients()).thenReturn(true);
-		assertTrue(issuesAnalyzer.hasAnalyzers());
-	}
-
-	@Test
-	void analyze() {
-		int itemsCount = 2;
-
-		Launch launch = launch();
-
-		List<TestItem> items = testItemsTI(itemsCount);
-		items.forEach(item -> item.setLaunchId(launch.getId()));
-
-		AnalyzerConfig analyzerConfig = analyzerConfig();
-
-		final IndexLaunch indexLaunch = new IndexLaunch();
-		indexLaunch.setLaunchId(launch.getId());
-		indexLaunch.setAnalyzerConfig(analyzerConfig);
-
-		final List<IndexTestItem> indexTestItems = items.stream().map(AnalyzerUtils::fromTestItem).peek(item -> item.setLogs(errorLogs(2))).collect(Collectors.toList());
-		indexLaunch.setTestItems(indexTestItems);
-
-		when(testItemRepository.findAllById(anyList())).thenReturn(items);
-
-		when(launchPreparerService.prepare(any(Launch.class), anyList(), any(AnalyzerConfig.class))).thenReturn(Optional.of(indexLaunch));
-
-		when(analyzerServiceClient.analyze(any())).thenReturn(analyzedItems(itemsCount));
-
-		when(issueTypeHandler.defineIssueType(anyLong(), eq("pb001"))).thenReturn(issueProductBug().getIssueType());
-
-		issuesAnalyzer.runAnalyzers(launch, items.stream().map(TestItem::getItemId).collect(Collectors.toList()), analyzerConfig);
-
-		verify(analyzerServiceClient, times(1)).analyze(any());
-		verify(testItemRepository, times(itemsCount)).save(any());
-		verify(messageBus, times(4)).publishActivity(any());
-	}
-
-	private AnalyzerConfig analyzerConfig() {
-		AnalyzerConfig analyzerConfig = new AnalyzerConfig();
-		analyzerConfig.setAnalyzerMode(ALL_LAUNCHES.getValue());
-		return analyzerConfig;
-	}
-
-	private Project project() {
-		Project project = new Project();
-		project.setId(1L);
-		return project;
-	}
-
-	private Launch launch() {
-		Launch launch = new Launch();
-		launch.setId(1L);
-		launch.setName("launch");
-		launch.setProjectId(1L);
-		return launch;
-	}
-
-	private List<TestItem> testItemsTI(int count) {
-		List<TestItem> list = new ArrayList<>(count);
-		for (int i = 1; i <= count; i++) {
-			TestItem test = new TestItem();
-			test.setItemId((long) i);
-			test.setName("test" + i);
-			test.setUniqueId("unique" + i);
-			test.setItemResults(new TestItemResults());
-			test.getItemResults().setIssue(issueToInvestigate());
-			test.getItemResults().setStatus(StatusEnum.FAILED);
-			list.add(test);
-		}
-		return list;
-	}
-
-	private IssueEntity issueToInvestigate() {
-		IssueType issueType = new IssueType();
-		issueType.setLocator("ti001");
-		IssueEntity issueEntity = new IssueEntity();
-		issueEntity.setIssueType(issueType);
-		return issueEntity;
-	}
-
-	private IssueEntity issueProductBug() {
-		IssueType issueType = new IssueType();
-		issueType.setLocator("pb001");
-		IssueEntity issueEntity = new IssueEntity();
-		issueEntity.setIssueType(issueType);
-		return issueEntity;
-	}
-
-	private Set<IndexLog> errorLogs(int count) {
-		Set<IndexLog> logs = new HashSet<>(count);
-		for (int i = 1; i <= count; i++) {
-			IndexLog log = new IndexLog();
-			log.setMessage("Error message " + i);
-			log.setLogLevel(LogLevel.ERROR.toInt());
-			logs.add(log);
-		}
-		return logs;
-	}
-
-	private Map<String, List<AnalyzedItemRs>> analyzedItems(int itemsCount) {
-		Map<String, List<AnalyzedItemRs>> res = new HashMap<>();
-		List<AnalyzedItemRs> list = new ArrayList<>();
-		for (int i = 1; i <= itemsCount; i++) {
-			AnalyzedItemRs testItem = new AnalyzedItemRs();
-			testItem.setItemId((long) i);
-			testItem.setLocator(PRODUCT_BUG.getLocator());
-			list.add(testItem);
-		}
-		res.put("test", list);
-		return res;
-	}
+  private LaunchPreparerService launchPreparerService = mock(LaunchPreparerService.class);
+
+  private AnalyzerStatusCache analyzerStatusCache = mock(AnalyzerStatusCache.class);
+
+  private AnalyzerServiceImpl issuesAnalyzer = new AnalyzerServiceImpl(100, analyzerStatusCache,
+      launchPreparerService,
+      analyzerServiceClient,
+      issueTypeHandler,
+      testItemRepository,
+      messageBus,
+      launchRepository
+  );
+
+  @Test
+  void hasAnalyzers() {
+    when(analyzerServiceClient.hasClients()).thenReturn(true);
+    assertTrue(issuesAnalyzer.hasAnalyzers());
+  }
+
+  @Test
+  void analyze() {
+    int itemsCount = 2;
+
+    Launch launch = launch();
+
+    List<TestItem> items = testItemsTI(itemsCount);
+    items.forEach(item -> item.setLaunchId(launch.getId()));
+
+    AnalyzerConfig analyzerConfig = analyzerConfig();
+
+    final IndexLaunch indexLaunch = new IndexLaunch();
+    indexLaunch.setLaunchId(launch.getId());
+    indexLaunch.setAnalyzerConfig(analyzerConfig);
+
+    final List<IndexTestItem> indexTestItems = items.stream().map(AnalyzerUtils::fromTestItem)
+        .peek(item -> item.setLogs(errorLogs(2))).collect(Collectors.toList());
+    indexLaunch.setTestItems(indexTestItems);
+
+    when(testItemRepository.findAllById(anyList())).thenReturn(items);
+
+    when(launchPreparerService.prepare(any(Launch.class), anyList(),
+        any(AnalyzerConfig.class))).thenReturn(Optional.of(indexLaunch));
+
+    when(analyzerServiceClient.analyze(any())).thenReturn(analyzedItems(itemsCount));
+
+    when(issueTypeHandler.defineIssueType(anyLong(), eq("pb001"))).thenReturn(
+        issueProductBug().getIssueType());
+
+    issuesAnalyzer.runAnalyzers(launch,
+        items.stream().map(TestItem::getItemId).collect(Collectors.toList()), analyzerConfig);
+
+    verify(analyzerServiceClient, times(1)).analyze(any());
+    verify(testItemRepository, times(itemsCount)).save(any());
+    verify(messageBus, times(4)).publishActivity(any());
+  }
+
+  private AnalyzerConfig analyzerConfig() {
+    AnalyzerConfig analyzerConfig = new AnalyzerConfig();
+    analyzerConfig.setAnalyzerMode(ALL_LAUNCHES.getValue());
+    return analyzerConfig;
+  }
+
+  private Project project() {
+    Project project = new Project();
+    project.setId(1L);
+    return project;
+  }
+
+  private Launch launch() {
+    Launch launch = new Launch();
+    launch.setId(1L);
+    launch.setName("launch");
+    launch.setProjectId(1L);
+    return launch;
+  }
+
+  private List<TestItem> testItemsTI(int count) {
+    List<TestItem> list = new ArrayList<>(count);
+    for (int i = 1; i <= count; i++) {
+      TestItem test = new TestItem();
+      test.setItemId((long) i);
+      test.setName("test" + i);
+      test.setUniqueId("unique" + i);
+      test.setItemResults(new TestItemResults());
+      test.getItemResults().setIssue(issueToInvestigate());
+      test.getItemResults().setStatus(StatusEnum.FAILED);
+      list.add(test);
+    }
+    return list;
+  }
+
+  private IssueEntity issueToInvestigate() {
+    IssueType issueType = new IssueType();
+    issueType.setLocator("ti001");
+    IssueEntity issueEntity = new IssueEntity();
+    issueEntity.setIssueType(issueType);
+    return issueEntity;
+  }
+
+  private IssueEntity issueProductBug() {
+    IssueType issueType = new IssueType();
+    issueType.setLocator("pb001");
+    IssueEntity issueEntity = new IssueEntity();
+    issueEntity.setIssueType(issueType);
+    return issueEntity;
+  }
+
+  private Set<IndexLog> errorLogs(int count) {
+    Set<IndexLog> logs = new HashSet<>(count);
+    for (int i = 1; i <= count; i++) {
+      IndexLog log = new IndexLog();
+      log.setMessage("Error message " + i);
+      log.setLogLevel(LogLevel.ERROR.toInt());
+      logs.add(log);
+    }
+    return logs;
+  }
+
+  private Map<String, List<AnalyzedItemRs>> analyzedItems(int itemsCount) {
+    Map<String, List<AnalyzedItemRs>> res = new HashMap<>();
+    List<AnalyzedItemRs> list = new ArrayList<>();
+    for (int i = 1; i <= itemsCount; i++) {
+      AnalyzedItemRs testItem = new AnalyzedItemRs();
+      testItem.setItemId((long) i);
+      testItem.setLocator(PRODUCT_BUG.getLocator());
+      list.add(testItem);
+    }
+    res.put("test", list);
+    return res;
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/impl/AnalyzerUtilsTest.java b/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/impl/AnalyzerUtilsTest.java
index f1a8d1877e..79b91877e8 100644
--- a/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/impl/AnalyzerUtilsTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/impl/AnalyzerUtilsTest.java
@@ -16,6 +16,11 @@
 
 package com.epam.ta.reportportal.core.analyzer.auto.impl;
 
+import static com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerUtils.fromTestItem;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 import com.epam.ta.reportportal.entity.attribute.Attribute;
 import com.epam.ta.reportportal.entity.enums.LogLevel;
 import com.epam.ta.reportportal.entity.enums.ProjectAttributeEnum;
@@ -23,7 +28,7 @@
 import com.epam.ta.reportportal.entity.item.TestItemResults;
 import com.epam.ta.reportportal.entity.item.issue.IssueEntity;
 import com.epam.ta.reportportal.entity.item.issue.IssueType;
-import com.epam.ta.reportportal.entity.log.Log;
+import com.epam.ta.reportportal.entity.log.LogFull;
 import com.epam.ta.reportportal.entity.project.Project;
 import com.epam.ta.reportportal.entity.project.ProjectUtils;
 import com.epam.ta.reportportal.ws.model.analyzer.IndexLog;
@@ -31,131 +36,143 @@
 import com.epam.ta.reportportal.ws.model.analyzer.RelevantItemInfo;
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
 import com.epam.ta.reportportal.ws.model.project.UniqueErrorConfig;
-import org.junit.jupiter.api.Test;
-
 import java.time.LocalDateTime;
 import java.time.ZoneOffset;
-import java.util.*;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerUtils.fromTestItem;
-import static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author Pavel Bortnik
  */
 class AnalyzerUtilsTest {
 
-    @Test
-    void testConverting() {
-        TestItem testItem = createTest();
-        testItem.getItemResults().setIssue(createIssue(false));
-        IndexTestItem indexTestItem = fromTestItem(testItem);
-        indexTestItem.setLogs(createSameLogs(5));
-        assertEquals(testItem.getItemId(), indexTestItem.getTestItemId());
-        assertEquals(testItem.getUniqueId(), indexTestItem.getUniqueId());
-        assertEquals(testItem.getStartTime(), indexTestItem.getStartTime());
-        assertEquals(testItem.getItemResults().getIssue().getIssueType().getLocator(), indexTestItem.getIssueTypeLocator());
-        assertEquals(1, indexTestItem.getLogs().size());
-        assertFalse(indexTestItem.isAutoAnalyzed());
+  @Test
+  void testConverting() {
+    TestItem testItem = createTest();
+    testItem.getItemResults().setIssue(createIssue(false));
+    IndexTestItem indexTestItem = fromTestItem(testItem);
+    indexTestItem.setLogs(createSameLogs(5));
+    assertEquals(testItem.getItemId(), indexTestItem.getTestItemId());
+    assertEquals(testItem.getUniqueId(), indexTestItem.getUniqueId());
+    assertEquals(testItem.getStartTime(), indexTestItem.getStartTime());
+    assertEquals(testItem.getItemResults().getIssue().getIssueType().getLocator(),
+        indexTestItem.getIssueTypeLocator());
+    assertEquals(1, indexTestItem.getLogs().size());
+    assertFalse(indexTestItem.isAutoAnalyzed());
+  }
+
+  @Test
+  void testConvertingAnalyzed() {
+    TestItem test = createTest();
+    test.getItemResults().setIssue(createIssue(true));
+    IndexTestItem indexTestItem = fromTestItem(test);
+    indexTestItem.setLogs(createSameLogs(1));
+    assertTrue(indexTestItem.isAutoAnalyzed());
+  }
+
+  @Test
+  void testAnalyzerConfig() {
+    AnalyzerConfig config = AnalyzerUtils.getAnalyzerConfig(project());
+    assertEquals(String.valueOf(config.getIsAutoAnalyzerEnabled()),
+        ProjectAttributeEnum.AUTO_ANALYZER_ENABLED.getDefaultValue());
+    assertEquals(String.valueOf(config.getNumberOfLogLines()),
+        ProjectAttributeEnum.NUMBER_OF_LOG_LINES.getDefaultValue());
+    assertEquals(config.getAnalyzerMode(),
+        ProjectAttributeEnum.AUTO_ANALYZER_MODE.getDefaultValue());
+    assertEquals(String.valueOf(config.getMinShouldMatch()),
+        ProjectAttributeEnum.MIN_SHOULD_MATCH.getDefaultValue());
+    assertEquals(String.valueOf(config.getSearchLogsMinShouldMatch()),
+        ProjectAttributeEnum.SEARCH_LOGS_MIN_SHOULD_MATCH.getDefaultValue());
+    assertEquals(String.valueOf(config.isIndexingRunning()),
+        ProjectAttributeEnum.INDEXING_RUNNING.getDefaultValue());
+    assertEquals(String.valueOf(config.isAllMessagesShouldMatch()),
+        ProjectAttributeEnum.ALL_MESSAGES_SHOULD_MATCH.getDefaultValue());
+  }
+
+  @Test
+  void testUniqueErrorConfig() {
+    final Map<String, String> configParameters = ProjectUtils.getConfigParameters(
+        project().getProjectAttributes());
+    final UniqueErrorConfig config = AnalyzerUtils.getUniqueErrorConfig(configParameters);
+    assertEquals(ProjectAttributeEnum.AUTO_UNIQUE_ERROR_ANALYZER_ENABLED.getDefaultValue(),
+        String.valueOf(config.isEnabled()));
+    assertEquals(ProjectAttributeEnum.UNIQUE_ERROR_ANALYZER_REMOVE_NUMBERS.getDefaultValue(),
+        String.valueOf(config.isRemoveNumbers()));
+  }
+
+  @Test
+  void testFromLogs() {
+    final LogFull logFull = new LogFull();
+    logFull.setId(1L);
+    logFull.setLogMessage("Log message");
+    logFull.setLogLevel(40000);
+    logFull.setClusterId(2L);
+
+    final Set<IndexLog> indexLogs = AnalyzerUtils.fromLogs(List.of(logFull));
+    final IndexLog indexLog = indexLogs.stream().findFirst().get();
+    assertEquals(logFull.getId(), indexLog.getLogId());
+    assertEquals(logFull.getLogMessage(), indexLog.getMessage());
+    assertEquals(logFull.getLogLevel().intValue(), indexLog.getLogLevel());
+    assertEquals(logFull.getClusterId(), indexLog.getClusterId());
+  }
+
+  @Test
+  void testToRelevantItemInfo() {
+    final TestItem testItem = new TestItem();
+    testItem.setItemId(1L);
+    testItem.setLaunchId(2L);
+    testItem.setPath("1");
+
+    final RelevantItemInfo itemInfo = AnalyzerUtils.TO_RELEVANT_ITEM_INFO.apply(testItem);
+    assertEquals(String.valueOf(testItem.getItemId()), itemInfo.getItemId());
+    assertEquals(String.valueOf(testItem.getLaunchId()), itemInfo.getLaunchId());
+    assertEquals(testItem.getPath(), itemInfo.getPath());
+  }
+
+  private TestItem createTest() {
+    TestItem testItem = new TestItem();
+    testItem.setItemId(1L);
+    testItem.setStartTime(LocalDateTime.now(ZoneOffset.UTC));
+    testItem.setUniqueId("uniqueId");
+    testItem.setItemResults(new TestItemResults());
+    return testItem;
+  }
+
+  private IssueEntity createIssue(boolean isAutoAnalyzed) {
+    IssueType issueType = new IssueType();
+    issueType.setId(1L);
+    issueType.setLocator("locator");
+    IssueEntity issue = new IssueEntity();
+    issue.setAutoAnalyzed(isAutoAnalyzed);
+    issue.setIssueType(issueType);
+    return issue;
+  }
+
+  private Set<IndexLog> createSameLogs(int count) {
+    Set<IndexLog> logs = new HashSet<>();
+    for (int i = 0; i < count; i++) {
+      IndexLog log = new IndexLog();
+      log.setLogLevel(LogLevel.ERROR.toInt());
+      log.setMessage("Current message of the log");
+      logs.add(log);
     }
-
-    @Test
-    void testConvertingAnalyzed() {
-        TestItem test = createTest();
-        test.getItemResults().setIssue(createIssue(true));
-        IndexTestItem indexTestItem = fromTestItem(test);
-        indexTestItem.setLogs(createSameLogs(1));
-        assertTrue(indexTestItem.isAutoAnalyzed());
-    }
-
-    @Test
-    void testAnalyzerConfig() {
-        AnalyzerConfig config = AnalyzerUtils.getAnalyzerConfig(project());
-        assertEquals(String.valueOf(config.getIsAutoAnalyzerEnabled()), ProjectAttributeEnum.AUTO_ANALYZER_ENABLED.getDefaultValue());
-        assertEquals(String.valueOf(config.getNumberOfLogLines()), ProjectAttributeEnum.NUMBER_OF_LOG_LINES.getDefaultValue());
-        assertEquals(config.getAnalyzerMode(), ProjectAttributeEnum.AUTO_ANALYZER_MODE.getDefaultValue());
-        assertEquals(String.valueOf(config.getMinShouldMatch()), ProjectAttributeEnum.MIN_SHOULD_MATCH.getDefaultValue());
-        assertEquals(String.valueOf(config.getSearchLogsMinShouldMatch()), ProjectAttributeEnum.SEARCH_LOGS_MIN_SHOULD_MATCH.getDefaultValue());
-        assertEquals(String.valueOf(config.isIndexingRunning()), ProjectAttributeEnum.INDEXING_RUNNING.getDefaultValue());
-        assertEquals(String.valueOf(config.isAllMessagesShouldMatch()), ProjectAttributeEnum.ALL_MESSAGES_SHOULD_MATCH.getDefaultValue());
-    }
-
-	@Test
-	void testUniqueErrorConfig() {
-		final Map<String, String> configParameters = ProjectUtils.getConfigParameters(project().getProjectAttributes());
-		final UniqueErrorConfig config = AnalyzerUtils.getUniqueErrorConfig(configParameters);
-		assertEquals(ProjectAttributeEnum.AUTO_UNIQUE_ERROR_ANALYZER_ENABLED.getDefaultValue(), String.valueOf(config.isEnabled()));
-		assertEquals(ProjectAttributeEnum.UNIQUE_ERROR_ANALYZER_REMOVE_NUMBERS.getDefaultValue(), String.valueOf(config.isRemoveNumbers()));
-	}
-
-	@Test
-	void testFromLogs() {
-		final Log log = new Log();
-		log.setId(1L);
-		log.setLogMessage("Log message");
-		log.setLogLevel(40000);
-		log.setClusterId(2L);
-
-		final Set<IndexLog> indexLogs = AnalyzerUtils.fromLogs(List.of(log));
-		final IndexLog indexLog = indexLogs.stream().findFirst().get();
-		assertEquals(log.getId(), indexLog.getLogId());
-		assertEquals(log.getLogMessage(), indexLog.getMessage());
-		assertEquals(log.getLogLevel().intValue(), indexLog.getLogLevel());
-		assertEquals(log.getClusterId(), indexLog.getClusterId());
-	}
-
-	@Test
-	void testToRelevantItemInfo() {
-		final TestItem testItem = new TestItem();
-		testItem.setItemId(1L);
-		testItem.setLaunchId(2L);
-		testItem.setPath("1");
-
-		final RelevantItemInfo itemInfo = AnalyzerUtils.TO_RELEVANT_ITEM_INFO.apply(testItem);
-		assertEquals(String.valueOf(testItem.getItemId()), itemInfo.getItemId());
-		assertEquals(String.valueOf(testItem.getLaunchId()), itemInfo.getLaunchId());
-		assertEquals(testItem.getPath(), itemInfo.getPath());
-	}
-
-    private TestItem createTest() {
-        TestItem testItem = new TestItem();
-        testItem.setItemId(1L);
-        testItem.setStartTime(LocalDateTime.now(ZoneOffset.UTC));
-        testItem.setUniqueId("uniqueId");
-        testItem.setItemResults(new TestItemResults());
-        return testItem;
-    }
-
-    private IssueEntity createIssue(boolean isAutoAnalyzed) {
-        IssueType issueType = new IssueType();
-        issueType.setId(1L);
-        issueType.setLocator("locator");
-        IssueEntity issue = new IssueEntity();
-        issue.setAutoAnalyzed(isAutoAnalyzed);
-        issue.setIssueType(issueType);
-        return issue;
-    }
-
-    private Set<IndexLog> createSameLogs(int count) {
-        Set<IndexLog> logs = new HashSet<>();
-        for (int i = 0; i < count; i++) {
-            IndexLog log = new IndexLog();
-            log.setLogLevel(LogLevel.ERROR.toInt());
-            log.setMessage("Current message of the log");
-            logs.add(log);
-        }
-        return logs;
-    }
-
-    public static Project project() {
-        Project project = new Project();
-        project.setProjectAttributes(ProjectUtils.defaultProjectAttributes(project, Arrays.stream(ProjectAttributeEnum.values()).map(it -> {
-            Attribute attribute = new Attribute();
-            attribute.setName(it.getAttribute());
-            return attribute;
+    return logs;
+  }
+
+  public static Project project() {
+    Project project = new Project();
+    project.setProjectAttributes(ProjectUtils.defaultProjectAttributes(project,
+        Arrays.stream(ProjectAttributeEnum.values()).map(it -> {
+          Attribute attribute = new Attribute();
+          attribute.setName(it.getAttribute());
+          return attribute;
         }).collect(Collectors.toSet())));
-        return project;
-    }
+    return project;
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/impl/LogIndexerServiceTest.java b/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/impl/LogIndexerServiceTest.java
index 73b79085c2..13439ad2e1 100644
--- a/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/impl/LogIndexerServiceTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/impl/LogIndexerServiceTest.java
@@ -16,6 +16,16 @@
 
 package com.epam.ta.reportportal.core.analyzer.auto.impl;
 
+import static com.epam.ta.reportportal.entity.AnalyzeMode.ALL_LAUNCHES;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.core.analyzer.auto.client.IndexerServiceClient;
 import com.epam.ta.reportportal.core.analyzer.auto.impl.preparer.LaunchPreparerService;
 import com.epam.ta.reportportal.core.analyzer.auto.indexer.BatchLogIndexer;
@@ -37,21 +47,16 @@
 import com.epam.ta.reportportal.ws.model.analyzer.IndexRsIndex;
 import com.epam.ta.reportportal.ws.model.analyzer.IndexRsItem;
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
 import org.assertj.core.util.Lists;
 import org.assertj.core.util.Maps;
 import org.junit.jupiter.api.Test;
 import org.springframework.core.task.SyncTaskExecutor;
 import org.springframework.core.task.TaskExecutor;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import static com.epam.ta.reportportal.entity.AnalyzeMode.ALL_LAUNCHES;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.mockito.Mockito.*;
-
 /**
  * Tests for {@link LogIndexerService}
  *
@@ -59,118 +64,118 @@
  */
 class LogIndexerServiceTest {
 
-	private BatchLogIndexer batchLogIndexer = mock(BatchLogIndexer.class);
-
-	private TaskExecutor taskExecutor = new SyncTaskExecutor();
-
-	private IndexerServiceClient indexerServiceClient = mock(IndexerServiceClient.class);
-
-	private LaunchRepository launchRepository = mock(LaunchRepository.class);
-
-	private TestItemRepository testItemRepository = mock(TestItemRepository.class);
-
-	private LogRepository logRepository = mock(LogRepository.class);
-
-	private IndexerStatusCache indexerStatusCache = mock(IndexerStatusCache.class);
-
-	private LaunchPreparerService launchPreparerService = mock(LaunchPreparerService.class);
-
-	private LogIndexerService logIndexerService = new LogIndexerService(batchLogIndexer,
-			taskExecutor,
-			launchRepository,
-			testItemRepository,
-			indexerServiceClient,
-			launchPreparerService,
-			indexerStatusCache
-	);
-
-	@Test
-	void testIndexWithZeroCount() {
-		Long launchId = 2L;
-		final IndexLaunch indexLaunch = new IndexLaunch();
-		indexLaunch.setLaunchId(launchId);
-		when(batchLogIndexer.index(eq(1L), any(AnalyzerConfig.class))).thenReturn(0L);
-		Long result = logIndexerService.index(1L, analyzerConfig()).join();
-		assertThat(result, org.hamcrest.Matchers.equalTo(0L));
-		verify(indexerStatusCache, times(1)).indexingFinished(1L);
-	}
-
-	@Test
-	void testIndexDefectsUpdate() {
-		final Map<Long, String> toUpdate = Maps.newHashMap(1L, "pb001");
-		when(indexerServiceClient.indexDefectsUpdate(1L, toUpdate)).thenReturn(Collections.emptyList());
-		logIndexerService.indexDefectsUpdate(
-				1L,
-				new AnalyzerConfig(),
-				Lists.newArrayList(createTestItem(1L, TestItemIssueGroup.PRODUCT_BUG))
-		);
-		verify(indexerServiceClient, times(1)).indexDefectsUpdate(1L, toUpdate);
-	}
-
-	@Test
-	void testIndexItemsRemove() {
-		List<Long> list = Lists.newArrayList(1L);
-		doNothing().when(indexerServiceClient).indexItemsRemoveAsync(1L, list);
-		logIndexerService.indexItemsRemoveAsync(1L, list);
-		verify(indexerServiceClient, times(1)).indexItemsRemoveAsync(1L, list);
-	}
-
-	private AnalyzerConfig analyzerConfig() {
-		AnalyzerConfig analyzerConfig = new AnalyzerConfig();
-		analyzerConfig.setAnalyzerMode(ALL_LAUNCHES.getValue());
-		return analyzerConfig;
-	}
-
-	private Launch createLaunch(Long id) {
-		Launch l = new Launch();
-		l.setId(id);
-		l.setMode(LaunchModeEnum.DEFAULT);
-		l.setName("launch" + id);
-		return l;
-	}
-
-	private TestItem createTestItem(Long id, TestItemIssueGroup issueGroup) {
-		TestItem ti = new TestItem();
-		ti.setItemId(id);
-		ti.setLaunchId(id);
-		ti.setItemResults(new TestItemResults());
-		IssueType issueType = new IssueType();
-		issueType.setLocator(issueGroup.getLocator());
-		IssueEntity issueEntity = new IssueEntity();
-		issueEntity.setIssueType(issueType);
-		issueEntity.setIgnoreAnalyzer(false);
-		ti.getItemResults().setIssue(issueEntity);
-		return ti;
-	}
-
-	private Log createLog(Long id) {
-		Log l = new Log();
-		l.setId(id);
-		l.setTestItem(new TestItem(id));
-		l.setLogLevel(LogLevel.ERROR.toInt());
-		return l;
-	}
-
-	private List<TestItem> createTestItems(int count, TestItemIssueGroup issueGroup) {
-		List<TestItem> testItems = new ArrayList<>(count);
-		for (int i = 0; i < count; i++) {
-			testItems.add(createTestItem((long) i, issueGroup));
-		}
-		return testItems;
-	}
-
-	private IndexRs createIndexRs(int count) {
-		IndexRs rs = new IndexRs();
-		rs.setTook(100);
-		rs.setErrors(false);
-		List<IndexRsItem> rsItems = new ArrayList<>(count);
-		for (int i = 0; i < count; i++) {
-			IndexRsItem rsItem = new IndexRsItem();
-			rsItem.setIndex(new IndexRsIndex());
-			rsItems.add(rsItem);
-		}
-		rs.setItems(rsItems);
-		return rs;
-	}
+  private BatchLogIndexer batchLogIndexer = mock(BatchLogIndexer.class);
+
+  private TaskExecutor taskExecutor = new SyncTaskExecutor();
+
+  private IndexerServiceClient indexerServiceClient = mock(IndexerServiceClient.class);
+
+  private LaunchRepository launchRepository = mock(LaunchRepository.class);
+
+  private TestItemRepository testItemRepository = mock(TestItemRepository.class);
+
+  private LogRepository logRepository = mock(LogRepository.class);
+
+  private IndexerStatusCache indexerStatusCache = mock(IndexerStatusCache.class);
+
+  private LaunchPreparerService launchPreparerService = mock(LaunchPreparerService.class);
+
+  private LogIndexerService logIndexerService = new LogIndexerService(batchLogIndexer,
+      taskExecutor,
+      launchRepository,
+      testItemRepository,
+      indexerServiceClient,
+      launchPreparerService,
+      indexerStatusCache
+  );
+
+  @Test
+  void testIndexWithZeroCount() {
+    Long launchId = 2L;
+    final IndexLaunch indexLaunch = new IndexLaunch();
+    indexLaunch.setLaunchId(launchId);
+    when(batchLogIndexer.index(eq(1L), any(AnalyzerConfig.class))).thenReturn(0L);
+    Long result = logIndexerService.index(1L, analyzerConfig()).join();
+    assertThat(result, org.hamcrest.Matchers.equalTo(0L));
+    verify(indexerStatusCache, times(1)).indexingFinished(1L);
+  }
+
+  @Test
+  void testIndexDefectsUpdate() {
+    final Map<Long, String> toUpdate = Maps.newHashMap(1L, "pb001");
+    when(indexerServiceClient.indexDefectsUpdate(1L, toUpdate)).thenReturn(Collections.emptyList());
+    logIndexerService.indexDefectsUpdate(
+        1L,
+        new AnalyzerConfig(),
+        Lists.newArrayList(createTestItem(1L, TestItemIssueGroup.PRODUCT_BUG))
+    );
+    verify(indexerServiceClient, times(1)).indexDefectsUpdate(1L, toUpdate);
+  }
+
+  @Test
+  void testIndexItemsRemove() {
+    List<Long> list = Lists.newArrayList(1L);
+    doNothing().when(indexerServiceClient).indexItemsRemoveAsync(1L, list);
+    logIndexerService.indexItemsRemoveAsync(1L, list);
+    verify(indexerServiceClient, times(1)).indexItemsRemoveAsync(1L, list);
+  }
+
+  private AnalyzerConfig analyzerConfig() {
+    AnalyzerConfig analyzerConfig = new AnalyzerConfig();
+    analyzerConfig.setAnalyzerMode(ALL_LAUNCHES.getValue());
+    return analyzerConfig;
+  }
+
+  private Launch createLaunch(Long id) {
+    Launch l = new Launch();
+    l.setId(id);
+    l.setMode(LaunchModeEnum.DEFAULT);
+    l.setName("launch" + id);
+    return l;
+  }
+
+  private TestItem createTestItem(Long id, TestItemIssueGroup issueGroup) {
+    TestItem ti = new TestItem();
+    ti.setItemId(id);
+    ti.setLaunchId(id);
+    ti.setItemResults(new TestItemResults());
+    IssueType issueType = new IssueType();
+    issueType.setLocator(issueGroup.getLocator());
+    IssueEntity issueEntity = new IssueEntity();
+    issueEntity.setIssueType(issueType);
+    issueEntity.setIgnoreAnalyzer(false);
+    ti.getItemResults().setIssue(issueEntity);
+    return ti;
+  }
+
+  private Log createLog(Long id) {
+    Log l = new Log();
+    l.setId(id);
+    l.setTestItem(new TestItem(id));
+    l.setLogLevel(LogLevel.ERROR.toInt());
+    return l;
+  }
+
+  private List<TestItem> createTestItems(int count, TestItemIssueGroup issueGroup) {
+    List<TestItem> testItems = new ArrayList<>(count);
+    for (int i = 0; i < count; i++) {
+      testItems.add(createTestItem((long) i, issueGroup));
+    }
+    return testItems;
+  }
+
+  private IndexRs createIndexRs(int count) {
+    IndexRs rs = new IndexRs();
+    rs.setTook(100);
+    rs.setErrors(false);
+    List<IndexRsItem> rsItems = new ArrayList<>(count);
+    for (int i = 0; i < count; i++) {
+      IndexRsItem rsItem = new IndexRsItem();
+      rsItem.setIndex(new IndexRsIndex());
+      rsItems.add(rsItem);
+    }
+    rs.setItems(rsItems);
+    return rs;
+  }
 
 }
diff --git a/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/impl/SearchLogServiceImplTest.java b/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/impl/SearchLogServiceImplTest.java
index 64244ca51f..6472fb5151 100644
--- a/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/impl/SearchLogServiceImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/impl/SearchLogServiceImplTest.java
@@ -16,11 +16,20 @@
 
 package com.epam.ta.reportportal.core.analyzer.auto.impl;
 
+import static com.epam.ta.reportportal.core.analyzer.auto.strategy.search.SearchLogsMode.CURRENT_LAUNCH;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.analyzer.auto.client.AnalyzerServiceClient;
 import com.epam.ta.reportportal.core.analyzer.auto.strategy.search.CurrentLaunchCollector;
 import com.epam.ta.reportportal.core.analyzer.auto.strategy.search.SearchCollectorFactory;
-import com.epam.ta.reportportal.dao.*;
+import com.epam.ta.reportportal.core.log.LogService;
+import com.epam.ta.reportportal.dao.LaunchRepository;
+import com.epam.ta.reportportal.dao.ProjectRepository;
+import com.epam.ta.reportportal.dao.TestItemRepository;
+import com.epam.ta.reportportal.dao.UserFilterRepository;
 import com.epam.ta.reportportal.entity.enums.LogLevel;
 import com.epam.ta.reportportal.entity.enums.StatusEnum;
 import com.epam.ta.reportportal.entity.filter.ObjectType;
@@ -30,7 +39,7 @@
 import com.epam.ta.reportportal.entity.item.issue.IssueEntity;
 import com.epam.ta.reportportal.entity.item.issue.IssueType;
 import com.epam.ta.reportportal.entity.launch.Launch;
-import com.epam.ta.reportportal.entity.log.Log;
+import com.epam.ta.reportportal.entity.log.LogFull;
 import com.epam.ta.reportportal.entity.project.Project;
 import com.epam.ta.reportportal.entity.project.ProjectRole;
 import com.epam.ta.reportportal.ws.model.analyzer.SearchRq;
@@ -38,111 +47,107 @@
 import com.epam.ta.reportportal.ws.model.log.SearchLogRq;
 import com.epam.ta.reportportal.ws.model.log.SearchLogRs;
 import com.google.common.collect.Lists;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
 import java.util.Collections;
 import java.util.Optional;
-
-import static com.epam.ta.reportportal.core.analyzer.auto.strategy.search.SearchLogsMode.CURRENT_LAUNCH;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class SearchLogServiceImplTest {
 
-	private final Project project = mock(Project.class);
-	private final Launch launch = mock(Launch.class);
-	private final TestItem testItem = mock(TestItem.class);
-	private final TestItem testItemOfFoundLog = mock(TestItem.class);
-	private final TestItemResults testItemResults = mock(TestItemResults.class);
-	private final UserFilter userFilter = mock(UserFilter.class);
-
-	private final ProjectRepository projectRepository = mock(ProjectRepository.class);
-
-	private final LaunchRepository launchRepository = mock(LaunchRepository.class);
-
-	private final TestItemRepository testItemRepository = mock(TestItemRepository.class);
-
-	private final LogRepository logRepository = mock(LogRepository.class);
-
-	private final AnalyzerServiceClient analyzerServiceClient = mock(AnalyzerServiceClient.class);
-
-	private final UserFilterRepository userFilterRepository = mock(UserFilterRepository.class);
-
-	private SearchCollectorFactory searchCollectorFactory = mock(SearchCollectorFactory.class);
-
-	private CurrentLaunchCollector currentLaunchCollector = mock(CurrentLaunchCollector.class);
-
-	private final SearchLogServiceImpl searchLogService = new SearchLogServiceImpl(projectRepository,
-			launchRepository,
-			testItemRepository,
-			logRepository,
-			analyzerServiceClient,
-			searchCollectorFactory
-	);
-
-	@Test
-	void searchTest() {
-
-		ReportPortalUser.ProjectDetails projectDetails = new ReportPortalUser.ProjectDetails(1L, "project", ProjectRole.PROJECT_MANAGER);
-
-		when(projectRepository.findById(projectDetails.getProjectId())).thenReturn(Optional.of(project));
-		when(testItemRepository.findById(1L)).thenReturn(Optional.of(testItem));
-		when(testItemRepository.findAllById(any())).thenReturn(Lists.newArrayList(testItemOfFoundLog));
-		when(testItem.getLaunchId()).thenReturn(1L);
-		when(testItemOfFoundLog.getItemId()).thenReturn(2L);
-		when(testItemOfFoundLog.getLaunchId()).thenReturn(1L);
-		when(launchRepository.findById(1L)).thenReturn(Optional.of(launch));
-		when(launch.getId()).thenReturn(1L);
-		when(testItem.getPath()).thenReturn("1");
-		when(testItem.getItemResults()).thenReturn(testItemResults);
-		when(testItem.isHasStats()).thenReturn(true);
-		when(testItemOfFoundLog.getItemResults()).thenReturn(testItemResults);
-		when(testItemOfFoundLog.isHasStats()).thenReturn(true);
-
-		when(testItemResults.getStatus()).thenReturn(StatusEnum.FAILED);
-
-		IssueType issueType = new IssueType();
-		issueType.setLocator("locator");
-		IssueEntity issueEntity = new IssueEntity();
-		issueEntity.setIssueType(issueType);
-		issueEntity.setIgnoreAnalyzer(false);
-		when(testItemResults.getIssue()).thenReturn(issueEntity);
-
-		when(userFilterRepository.findByIdAndProjectId(1L, 1L)).thenReturn(Optional.of(userFilter));
-		when(userFilter.getTargetClass()).thenReturn(ObjectType.Launch);
-		when(userFilter.getFilterCondition()).thenReturn(Collections.emptySet());
-
-		when(logRepository.findMessagesByLaunchIdAndItemIdAndPathAndLevelGte(launch.getId(),
-				testItem.getItemId(),
-				testItem.getPath(),
-				LogLevel.ERROR_INT
-		)).thenReturn(Lists.newArrayList("message"));
-		SearchRs searchRs = new SearchRs();
-		searchRs.setLogId(1L);
-		searchRs.setTestItemId(2L);
-		when(analyzerServiceClient.searchLogs(any(SearchRq.class))).thenReturn(Lists.newArrayList(searchRs));
-		Log log = new Log();
-		log.setId(1L);
-		log.setTestItem(testItem);
-		log.setLogMessage("message");
-		log.setLogLevel(40000);
-		when(logRepository.findAllById(any())).thenReturn(Lists.newArrayList(log));
-
-		SearchLogRq searchLogRq = new SearchLogRq();
-		searchLogRq.setSearchMode(CURRENT_LAUNCH.getValue());
-		searchLogRq.setFilterId(1L);
-
-		when(searchCollectorFactory.getCollector(CURRENT_LAUNCH)).thenReturn(currentLaunchCollector);
-		when(currentLaunchCollector.collect(any(), any())).thenReturn(Collections.singletonList(1L));
-
-		Iterable<SearchLogRs> responses = searchLogService.search(1L, searchLogRq, projectDetails);
-		Assertions.assertNotNull(responses);
-		Assertions.assertEquals(1, Lists.newArrayList(responses).size());
-
-	}
+  private final Project project = mock(Project.class);
+  private final Launch launch = mock(Launch.class);
+  private final TestItem testItem = mock(TestItem.class);
+  private final TestItem testItemOfFoundLog = mock(TestItem.class);
+  private final TestItemResults testItemResults = mock(TestItemResults.class);
+  private final UserFilter userFilter = mock(UserFilter.class);
+
+  private final ProjectRepository projectRepository = mock(ProjectRepository.class);
+
+  private final LaunchRepository launchRepository = mock(LaunchRepository.class);
+
+  private final TestItemRepository testItemRepository = mock(TestItemRepository.class);
+
+  private final LogService logService = mock(LogService.class);
+
+  private final AnalyzerServiceClient analyzerServiceClient = mock(AnalyzerServiceClient.class);
+
+  private final UserFilterRepository userFilterRepository = mock(UserFilterRepository.class);
+
+  private SearchCollectorFactory searchCollectorFactory = mock(SearchCollectorFactory.class);
+
+  private CurrentLaunchCollector currentLaunchCollector = mock(CurrentLaunchCollector.class);
+
+  private final SearchLogServiceImpl searchLogService = new SearchLogServiceImpl(projectRepository,
+      launchRepository,
+      testItemRepository,
+      logService, analyzerServiceClient,
+      searchCollectorFactory
+  );
+
+  @Test
+  void searchTest() {
+
+    ReportPortalUser.ProjectDetails projectDetails = new ReportPortalUser.ProjectDetails(1L,
+        "project", ProjectRole.PROJECT_MANAGER);
+
+    when(projectRepository.findById(projectDetails.getProjectId())).thenReturn(
+        Optional.of(project));
+    when(testItemRepository.findById(1L)).thenReturn(Optional.of(testItem));
+    when(testItemRepository.findAllById(any())).thenReturn(Lists.newArrayList(testItemOfFoundLog));
+    when(testItem.getLaunchId()).thenReturn(1L);
+    when(testItemOfFoundLog.getItemId()).thenReturn(2L);
+    when(testItemOfFoundLog.getLaunchId()).thenReturn(1L);
+    when(launchRepository.findById(1L)).thenReturn(Optional.of(launch));
+    when(launch.getId()).thenReturn(1L);
+    when(testItem.getPath()).thenReturn("1");
+    when(testItem.getItemResults()).thenReturn(testItemResults);
+    when(testItem.isHasStats()).thenReturn(true);
+    when(testItemOfFoundLog.getItemResults()).thenReturn(testItemResults);
+    when(testItemOfFoundLog.isHasStats()).thenReturn(true);
+
+    when(testItemResults.getStatus()).thenReturn(StatusEnum.FAILED);
+
+    IssueType issueType = new IssueType();
+    issueType.setLocator("locator");
+    IssueEntity issueEntity = new IssueEntity();
+    issueEntity.setIssueType(issueType);
+    issueEntity.setIgnoreAnalyzer(false);
+    when(testItemResults.getIssue()).thenReturn(issueEntity);
+
+    when(userFilterRepository.findByIdAndProjectId(1L, 1L)).thenReturn(Optional.of(userFilter));
+    when(userFilter.getTargetClass()).thenReturn(ObjectType.Launch);
+    when(userFilter.getFilterCondition()).thenReturn(Collections.emptySet());
+
+    when(logService.findMessagesByLaunchIdAndItemIdAndPathAndLevelGte(launch.getId(),
+        testItem.getItemId(),
+        testItem.getPath(),
+        LogLevel.ERROR_INT
+    )).thenReturn(Lists.newArrayList("message"));
+    SearchRs searchRs = new SearchRs();
+    searchRs.setLogId(1L);
+    searchRs.setTestItemId(2L);
+    when(analyzerServiceClient.searchLogs(any(SearchRq.class))).thenReturn(
+        Lists.newArrayList(searchRs));
+    LogFull log = new LogFull();
+    log.setId(1L);
+    log.setTestItem(testItem);
+    log.setLogMessage("message");
+    log.setLogLevel(40000);
+    when(logService.findAllById(any())).thenReturn(Lists.newArrayList(log));
+
+    SearchLogRq searchLogRq = new SearchLogRq();
+    searchLogRq.setSearchMode(CURRENT_LAUNCH.getValue());
+    searchLogRq.setFilterId(1L);
+
+    when(searchCollectorFactory.getCollector(CURRENT_LAUNCH)).thenReturn(currentLaunchCollector);
+    when(currentLaunchCollector.collect(any(), any())).thenReturn(Collections.singletonList(1L));
+
+    Iterable<SearchLogRs> responses = searchLogService.search(1L, searchLogRq, projectDetails);
+    Assertions.assertNotNull(responses);
+    Assertions.assertEquals(1, Lists.newArrayList(responses).size());
+
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/impl/SuggestItemServiceTest.java b/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/impl/SuggestItemServiceTest.java
index bc1a73933e..59919308c1 100644
--- a/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/impl/SuggestItemServiceTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/impl/SuggestItemServiceTest.java
@@ -1,5 +1,14 @@
 package com.epam.ta.reportportal.core.analyzer.auto.impl;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static com.epam.ta.reportportal.entity.enums.LogLevel.ERROR_INT;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.anyList;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.analyzer.auto.client.AnalyzerServiceClient;
 import com.epam.ta.reportportal.core.analyzer.auto.client.model.SuggestInfo;
@@ -8,224 +17,231 @@
 import com.epam.ta.reportportal.core.item.validator.state.TestItemValidator;
 import com.epam.ta.reportportal.core.launch.GetLaunchHandler;
 import com.epam.ta.reportportal.core.launch.cluster.GetClusterHandler;
+import com.epam.ta.reportportal.core.log.LogService;
 import com.epam.ta.reportportal.core.project.GetProjectHandler;
-import com.epam.ta.reportportal.dao.LogRepository;
 import com.epam.ta.reportportal.dao.TestItemRepository;
 import com.epam.ta.reportportal.entity.cluster.Cluster;
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.item.TestItemResults;
 import com.epam.ta.reportportal.entity.launch.Launch;
-import com.epam.ta.reportportal.entity.log.Log;
+import com.epam.ta.reportportal.entity.log.LogFull;
 import com.epam.ta.reportportal.entity.project.Project;
 import com.epam.ta.reportportal.entity.project.ProjectRole;
 import com.epam.ta.reportportal.entity.user.UserRole;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
 import java.time.LocalDateTime;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static com.epam.ta.reportportal.entity.enums.LogLevel.ERROR_INT;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.*;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
 
 class SuggestItemServiceTest {
 
-	private final AnalyzerServiceClient analyzerServiceClient = mock(AnalyzerServiceClient.class);
+  private final AnalyzerServiceClient analyzerServiceClient = mock(AnalyzerServiceClient.class);
 
-	private final GetProjectHandler getProjectHandler = mock(GetProjectHandler.class);
-	private final GetLaunchHandler getLaunchHandler = mock(GetLaunchHandler.class);
-	private final GetClusterHandler getClusterHandler = mock(GetClusterHandler.class);
+  private final GetProjectHandler getProjectHandler = mock(GetProjectHandler.class);
+  private final GetLaunchHandler getLaunchHandler = mock(GetLaunchHandler.class);
+  private final GetClusterHandler getClusterHandler = mock(GetClusterHandler.class);
 
-	private final LaunchAccessValidator launchAccessValidator = mock(LaunchAccessValidator.class);
+  private final LaunchAccessValidator launchAccessValidator = mock(LaunchAccessValidator.class);
 
-	private final TestItemRepository testItemRepository = mock(TestItemRepository.class);
-	private final LogRepository logRepository = mock(LogRepository.class);
+  private final TestItemRepository testItemRepository = mock(TestItemRepository.class);
+  private final LogService logService = mock(LogService.class);
 
-	private final TestItemValidator testItemValidator = mock(TestItemValidator.class);
-	private final List<TestItemValidator> validators = List.of(testItemValidator);
+  private final TestItemValidator testItemValidator = mock(TestItemValidator.class);
+  private final List<TestItemValidator> validators = List.of(testItemValidator);
 
-	private final SuggestItemService suggestItemService = new SuggestItemService(analyzerServiceClient,
-			getProjectHandler,
-			getLaunchHandler,
-			getClusterHandler,
-			launchAccessValidator,
-			testItemRepository,
-			logRepository,
-			validators
-	);
+  private final SuggestItemService suggestItemService = new SuggestItemService(
+      analyzerServiceClient,
+      getProjectHandler,
+      getLaunchHandler,
+      getClusterHandler,
+      launchAccessValidator,
+      testItemRepository,
+      logService, validators
+  );
 
-	@Test
-	void suggestItems() {
-		final ReportPortalUser rpUser = getRpUser("owner", UserRole.USER, ProjectRole.MEMBER, 1L);
-		final Project project = new Project(1L, "default");
+  @Test
+  void suggestItems() {
+    final ReportPortalUser rpUser = getRpUser("owner", UserRole.USER, ProjectRole.MEMBER, 1L);
+    final Project project = new Project(1L, "default");
 
-		TestItem testItem = new TestItem();
-		testItem.setItemId(1L);
-		testItem.setLaunchId(1L);
+    TestItem testItem = new TestItem();
+    testItem.setItemId(1L);
+    testItem.setLaunchId(1L);
 
-		TestItem relevantItem = getRelevantItem();
+    TestItem relevantItem = getRelevantItem();
 
-		Launch launch = new Launch();
-		launch.setId(1L);
+    Launch launch = new Launch();
+    launch.setId(1L);
 
-		final Log log = new Log();
+    final LogFull logFull = new LogFull();
 
-		SuggestInfo suggestInfo = new SuggestInfo();
-		suggestInfo.setRelevantItem(2L);
+    SuggestInfo suggestInfo = new SuggestInfo();
+    suggestInfo.setRelevantItem(2L);
 
-		when(testItemRepository.findById(1L)).thenReturn(Optional.of(testItem));
-		when(testItemValidator.validate(any(TestItem.class))).thenReturn(true);
-		when(testItemRepository.findById(2L)).thenReturn(Optional.of(relevantItem));
-		when(getLaunchHandler.get(testItem.getLaunchId())).thenReturn(launch);
-		when(getProjectHandler.get(any(ReportPortalUser.ProjectDetails.class))).thenReturn(project);
-		when(logRepository.findAllUnderTestItemByLaunchIdAndTestItemIdsAndLogLevelGte(launch.getId(),
-				Collections.singletonList(testItem.getItemId()),
-				ERROR_INT
-		)).thenReturn(Collections.singletonList(log));
+    when(testItemRepository.findById(1L)).thenReturn(Optional.of(testItem));
+    when(testItemValidator.validate(any(TestItem.class))).thenReturn(true);
+    when(testItemRepository.findById(2L)).thenReturn(Optional.of(relevantItem));
+    when(getLaunchHandler.get(testItem.getLaunchId())).thenReturn(launch);
+    when(getProjectHandler.get(any(ReportPortalUser.ProjectDetails.class))).thenReturn(project);
+    when(logService.findAllUnderTestItemByLaunchIdAndTestItemIdsAndLogLevelGte(launch.getId(),
+        Collections.singletonList(testItem.getItemId()),
+        ERROR_INT
+    )).thenReturn(Collections.singletonList(logFull));
 
-		when(analyzerServiceClient.searchSuggests(any(SuggestRq.class))).thenReturn(Collections.singletonList(suggestInfo));
+    when(analyzerServiceClient.searchSuggests(any(SuggestRq.class))).thenReturn(
+        Collections.singletonList(suggestInfo));
 
-		final List<SuggestedItem> suggestedItems = suggestItemService.suggestItems(1L,
-				ReportPortalUser.ProjectDetails.builder().withProjectId(1L).withProjectRole(ProjectRole.MEMBER.name()).build(),
-				rpUser
-		);
+    final List<SuggestedItem> suggestedItems = suggestItemService.suggestItems(1L,
+        ReportPortalUser.ProjectDetails.builder().withProjectId(1L)
+            .withProjectRole(ProjectRole.MEMBER.name()).build(),
+        rpUser
+    );
 
-		Assertions.assertEquals(1, suggestedItems.size());
+    Assertions.assertEquals(1, suggestedItems.size());
 
-	}
+  }
 
-	@Test
-	void suggestRemovedItems() {
-		final ReportPortalUser rpUser = getRpUser("owner", UserRole.USER, ProjectRole.MEMBER, 1L);
-		final Project project = new Project(1L, "default");
+  @Test
+  void suggestRemovedItems() {
+    final ReportPortalUser rpUser = getRpUser("owner", UserRole.USER, ProjectRole.MEMBER, 1L);
+    final Project project = new Project(1L, "default");
 
-		TestItem testItem = new TestItem();
-		testItem.setItemId(1L);
-		testItem.setLaunchId(1L);
+    TestItem testItem = new TestItem();
+    testItem.setItemId(1L);
+    testItem.setLaunchId(1L);
 
-		Launch launch = new Launch();
-		launch.setId(1L);
+    Launch launch = new Launch();
+    launch.setId(1L);
 
-		SuggestInfo suggestInfo = new SuggestInfo();
-		suggestInfo.setRelevantItem(2L);
+    SuggestInfo suggestInfo = new SuggestInfo();
+    suggestInfo.setRelevantItem(2L);
 
-		when(testItemRepository.findById(1L)).thenReturn(Optional.of(testItem));
-		when(testItemValidator.validate(any(TestItem.class))).thenReturn(true);
-		when(getLaunchHandler.get(testItem.getLaunchId())).thenReturn(launch);
-		when(getProjectHandler.get(any(ReportPortalUser.ProjectDetails.class))).thenReturn(project);
-		when(testItemRepository.findById(2L)).thenReturn(Optional.empty());
+    when(testItemRepository.findById(1L)).thenReturn(Optional.of(testItem));
+    when(testItemValidator.validate(any(TestItem.class))).thenReturn(true);
+    when(getLaunchHandler.get(testItem.getLaunchId())).thenReturn(launch);
+    when(getProjectHandler.get(any(ReportPortalUser.ProjectDetails.class))).thenReturn(project);
+    when(testItemRepository.findById(2L)).thenReturn(Optional.empty());
 
-		when(analyzerServiceClient.searchSuggests(any(SuggestRq.class))).thenReturn(Collections.singletonList(suggestInfo));
+    when(analyzerServiceClient.searchSuggests(any(SuggestRq.class))).thenReturn(
+        Collections.singletonList(suggestInfo));
 
-		final List<SuggestedItem> suggestedItems = suggestItemService.suggestItems(1L,
-				ReportPortalUser.ProjectDetails.builder().withProjectId(1L).withProjectRole(ProjectRole.MEMBER.name()).build(),
-				rpUser
-		);
+    final List<SuggestedItem> suggestedItems = suggestItemService.suggestItems(1L,
+        ReportPortalUser.ProjectDetails.builder().withProjectId(1L)
+            .withProjectRole(ProjectRole.MEMBER.name()).build(),
+        rpUser
+    );
 
-		Assertions.assertTrue(suggestedItems.isEmpty());
+    Assertions.assertTrue(suggestedItems.isEmpty());
 
-	}
+  }
 
-	@Test
-	void showThrowExceptionWhenNotValid() {
-		final ReportPortalUser rpUser = getRpUser("owner", UserRole.USER, ProjectRole.MEMBER, 1L);
+  @Test
+  void showThrowExceptionWhenNotValid() {
+    final ReportPortalUser rpUser = getRpUser("owner", UserRole.USER, ProjectRole.MEMBER, 1L);
 
-		TestItem testItem = new TestItem();
-		testItem.setItemId(1L);
+    TestItem testItem = new TestItem();
+    testItem.setItemId(1L);
 
-		when(testItemRepository.findById(1L)).thenReturn(Optional.of(testItem));
-		when(testItemValidator.validate(testItem)).thenReturn(false);
-		when(testItemValidator.provide(testItem)).thenReturn("Test item = 1 is a nested step");
+    when(testItemRepository.findById(1L)).thenReturn(Optional.of(testItem));
+    when(testItemValidator.validate(testItem)).thenReturn(false);
+    when(testItemValidator.provide(testItem)).thenReturn("Test item = 1 is a nested step");
 
-		final ReportPortalException exception = Assertions.assertThrows(ReportPortalException.class,
-				() -> suggestItemService.suggestItems(1L,
-						ReportPortalUser.ProjectDetails.builder().withProjectId(1L).withProjectRole(ProjectRole.MEMBER.name()).build(),
-						rpUser
-				)
-		);
+    final ReportPortalException exception = Assertions.assertThrows(ReportPortalException.class,
+        () -> suggestItemService.suggestItems(1L,
+            ReportPortalUser.ProjectDetails.builder().withProjectId(1L)
+                .withProjectRole(ProjectRole.MEMBER.name()).build(),
+            rpUser
+        )
+    );
 
-		Assertions.assertEquals("Error in handled Request. Please, check specified parameters: 'Test item = 1 is a nested step'", exception.getMessage());
-	}
+    Assertions.assertEquals(
+        "Error in handled Request. Please, check specified parameters: 'Test item = 1 is a nested step'",
+        exception.getMessage());
+  }
 
-	@Test
-	void showThrowExceptionWhenNotFound() {
-		final ReportPortalUser rpUser = getRpUser("owner", UserRole.USER, ProjectRole.MEMBER, 1L);
+  @Test
+  void showThrowExceptionWhenNotFound() {
+    final ReportPortalUser rpUser = getRpUser("owner", UserRole.USER, ProjectRole.MEMBER, 1L);
 
-		when(testItemRepository.findById(1L)).thenReturn(Optional.empty());
+    when(testItemRepository.findById(1L)).thenReturn(Optional.empty());
 
-		final ReportPortalException exception = Assertions.assertThrows(ReportPortalException.class,
-				() -> suggestItemService.suggestItems(1L,
-						ReportPortalUser.ProjectDetails.builder().withProjectId(1L).withProjectRole(ProjectRole.MEMBER.name()).build(),
-						rpUser
-				)
-		);
+    final ReportPortalException exception = Assertions.assertThrows(ReportPortalException.class,
+        () -> suggestItemService.suggestItems(1L,
+            ReportPortalUser.ProjectDetails.builder().withProjectId(1L)
+                .withProjectRole(ProjectRole.MEMBER.name()).build(),
+            rpUser
+        )
+    );
 
-		Assertions.assertEquals("Test Item '1' not found. Did you use correct Test Item ID?", exception.getMessage());
-	}
+    Assertions.assertEquals("Test Item '1' not found. Did you use correct Test Item ID?",
+        exception.getMessage());
+  }
 
-	@Test
-	void suggestClusterItems() {
-		final ReportPortalUser rpUser = getRpUser("owner", UserRole.USER, ProjectRole.MEMBER, 1L);
-		final Project project = new Project(1L, "default");
+  @Test
+  void suggestClusterItems() {
+    final ReportPortalUser rpUser = getRpUser("owner", UserRole.USER, ProjectRole.MEMBER, 1L);
+    final Project project = new Project(1L, "default");
 
-		final Cluster cluster = new Cluster();
-		cluster.setId(1L);
-		cluster.setLaunchId(1L);
+    final Cluster cluster = new Cluster();
+    cluster.setId(1L);
+    cluster.setLaunchId(1L);
 
-		TestItem relevantItem = getRelevantItem();
+    TestItem relevantItem = getRelevantItem();
 
-		Launch launch = new Launch();
-		launch.setId(1L);
+    Launch launch = new Launch();
+    launch.setId(1L);
 
-		final Log log = new Log();
+    final LogFull logFull = new LogFull();
 
-		SuggestInfo suggestInfo = new SuggestInfo();
-		suggestInfo.setRelevantItem(2L);
+    SuggestInfo suggestInfo = new SuggestInfo();
+    suggestInfo.setRelevantItem(2L);
 
-		when(getClusterHandler.getById(1L)).thenReturn(cluster);
-		when(testItemRepository.findById(2L)).thenReturn(Optional.of(relevantItem));
-		when(getLaunchHandler.get(cluster.getLaunchId())).thenReturn(launch);
-		when(getProjectHandler.get(any(ReportPortalUser.ProjectDetails.class))).thenReturn(project);
-		when(logRepository.findAllUnderTestItemByLaunchIdAndTestItemIdsAndLogLevelGte(launch.getId(),
-				Collections.singletonList(relevantItem.getItemId()),
-				ERROR_INT
-		)).thenReturn(Collections.singletonList(log));
+    when(getClusterHandler.getById(1L)).thenReturn(cluster);
+    when(testItemRepository.findById(2L)).thenReturn(Optional.of(relevantItem));
+    when(getLaunchHandler.get(cluster.getLaunchId())).thenReturn(launch);
+    when(getProjectHandler.get(any(ReportPortalUser.ProjectDetails.class))).thenReturn(project);
+    when(logService.findAllUnderTestItemByLaunchIdAndTestItemIdsAndLogLevelGte(launch.getId(),
+        Collections.singletonList(relevantItem.getItemId()),
+        ERROR_INT
+    )).thenReturn(Collections.singletonList(logFull));
 
-		when(analyzerServiceClient.searchSuggests(any(SuggestRq.class))).thenReturn(Collections.singletonList(suggestInfo));
+    when(analyzerServiceClient.searchSuggests(any(SuggestRq.class))).thenReturn(
+        Collections.singletonList(suggestInfo));
 
-		final List<SuggestedItem> suggestedItems = suggestItemService.suggestClusterItems(1L,
-				ReportPortalUser.ProjectDetails.builder().withProjectId(1L).withProjectRole(ProjectRole.MEMBER.name()).build(),
-				rpUser
-		);
+    final List<SuggestedItem> suggestedItems = suggestItemService.suggestClusterItems(1L,
+        ReportPortalUser.ProjectDetails.builder().withProjectId(1L)
+            .withProjectRole(ProjectRole.MEMBER.name()).build(),
+        rpUser
+    );
 
-		Assertions.assertEquals(1, suggestedItems.size());
+    Assertions.assertEquals(1, suggestedItems.size());
 
-	}
+  }
 
-	@Test
-	void handleSuggestChoice() {
-		final OperationCompletionRS operationCompletionRS = suggestItemService.handleSuggestChoice(new ArrayList<>());
-		verify(analyzerServiceClient, times(1)).handleSuggestChoice(anyList());
-		Assertions.assertEquals("User choice of suggested item was sent for handling to ML", operationCompletionRS.getResultMessage());
-	}
+  @Test
+  void handleSuggestChoice() {
+    final OperationCompletionRS operationCompletionRS = suggestItemService.handleSuggestChoice(
+        new ArrayList<>());
+    verify(analyzerServiceClient, times(1)).handleSuggestChoice(anyList());
+    Assertions.assertEquals("User choice of suggested item was sent for handling to ML",
+        operationCompletionRS.getResultMessage());
+  }
 
-	private TestItem getRelevantItem() {
+  private TestItem getRelevantItem() {
 
-		TestItem relevantItem = new TestItem();
-		relevantItem.setItemId(2L);
+    TestItem relevantItem = new TestItem();
+    relevantItem.setItemId(2L);
 
-		TestItemResults relevantItemRes = new TestItemResults();
-		relevantItemRes.setEndTime(LocalDateTime.now());
+    TestItemResults relevantItemRes = new TestItemResults();
+    relevantItemRes.setEndTime(LocalDateTime.now());
 
-		relevantItem.setItemResults(relevantItemRes);
+    relevantItem.setItemResults(relevantItemRes);
 
-		return relevantItem;
-	}
+    return relevantItem;
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/impl/preparer/LaunchPreparerServiceImplTest.java b/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/impl/preparer/LaunchPreparerServiceImplTest.java
index 4b24920d18..d4ae30d995 100644
--- a/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/impl/preparer/LaunchPreparerServiceImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/impl/preparer/LaunchPreparerServiceImplTest.java
@@ -16,55 +16,58 @@
 
 package com.epam.ta.reportportal.core.analyzer.auto.impl.preparer;
 
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.dao.ClusterRepository;
 import com.epam.ta.reportportal.dao.LaunchRepository;
 import com.epam.ta.reportportal.entity.cluster.Cluster;
 import com.epam.ta.reportportal.ws.model.analyzer.IndexLaunch;
 import com.epam.ta.reportportal.ws.model.analyzer.IndexTestItem;
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
-import org.junit.jupiter.api.Test;
-
 import java.util.List;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class LaunchPreparerServiceImplTest {
 
-	private final LaunchRepository launchRepository = mock(LaunchRepository.class);
-	private final ClusterRepository clusterRepository = mock(ClusterRepository.class);
-	private final TestItemPreparerService testItemPreparerService = mock(TestItemPreparerService.class);
+  private final LaunchRepository launchRepository = mock(LaunchRepository.class);
+  private final ClusterRepository clusterRepository = mock(ClusterRepository.class);
+  private final TestItemPreparerService testItemPreparerService = mock(
+      TestItemPreparerService.class);
 
-	private final LaunchPreparerServiceImpl preparerService = new LaunchPreparerServiceImpl(launchRepository,
-			clusterRepository,
-			testItemPreparerService
-	);
+  private final LaunchPreparerServiceImpl preparerService = new LaunchPreparerServiceImpl(
+      launchRepository,
+      clusterRepository,
+      testItemPreparerService
+  );
 
-	@Test
-	void prepare() {
+  @Test
+  void prepare() {
 
-		final long launchId = 1L;
+    final long launchId = 1L;
 
-		final IndexLaunch indexLaunch = new IndexLaunch();
-		indexLaunch.setLaunchId(launchId);
-		indexLaunch.setLaunchName("name");
-		indexLaunch.setProjectId(1L);
+    final IndexLaunch indexLaunch = new IndexLaunch();
+    indexLaunch.setLaunchId(launchId);
+    indexLaunch.setLaunchName("name");
+    indexLaunch.setProjectId(1L);
 
-		when(launchRepository.findIndexLaunchByIds(List.of(launchId))).thenReturn(List.of(indexLaunch));
+    when(launchRepository.findIndexLaunchByIds(List.of(launchId))).thenReturn(List.of(indexLaunch));
 
-		final IndexTestItem indexTestItem = new IndexTestItem();
-		when(testItemPreparerService.prepare(indexLaunch.getLaunchId())).thenReturn(List.of(indexTestItem));
+    final IndexTestItem indexTestItem = new IndexTestItem();
+    when(testItemPreparerService.prepare(indexLaunch.getLaunchId())).thenReturn(
+        List.of(indexTestItem));
 
-		final Cluster cluster = new Cluster();
-		cluster.setIndexId(1L);
-		cluster.setMessage("hello");
-		when(clusterRepository.findAllByLaunchId(indexLaunch.getLaunchId())).thenReturn(List.of(cluster));
+    final Cluster cluster = new Cluster();
+    cluster.setIndexId(1L);
+    cluster.setMessage("hello");
+    when(clusterRepository.findAllByLaunchId(indexLaunch.getLaunchId())).thenReturn(
+        List.of(cluster));
 
-		final AnalyzerConfig analyzerConfig = new AnalyzerConfig();
-		preparerService.prepare(List.of(launchId), analyzerConfig);
-	}
+    final AnalyzerConfig analyzerConfig = new AnalyzerConfig();
+    preparerService.prepare(List.of(launchId), analyzerConfig);
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/indexer/BatchLogIndexerTest.java b/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/indexer/BatchLogIndexerTest.java
index 991f086d82..e1f94a535f 100644
--- a/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/indexer/BatchLogIndexerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/indexer/BatchLogIndexerTest.java
@@ -1,5 +1,15 @@
 package com.epam.ta.reportportal.core.analyzer.auto.indexer;
 
+import static com.epam.ta.reportportal.entity.AnalyzeMode.ALL_LAUNCHES;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyList;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.core.analyzer.auto.client.IndexerServiceClient;
 import com.epam.ta.reportportal.core.analyzer.auto.impl.preparer.LaunchPreparerService;
 import com.epam.ta.reportportal.dao.LaunchRepository;
@@ -9,106 +19,110 @@
 import com.epam.ta.reportportal.ws.model.analyzer.IndexLaunch;
 import com.epam.ta.reportportal.ws.model.analyzer.IndexTestItem;
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
-import org.junit.jupiter.api.Test;
-
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.util.Collection;
 import java.util.List;
 import java.util.stream.Stream;
-
-import static com.epam.ta.reportportal.entity.AnalyzeMode.ALL_LAUNCHES;
-import static org.mockito.ArgumentMatchers.*;
-import static org.mockito.Mockito.*;
+import org.junit.jupiter.api.Test;
 
 class BatchLogIndexerTest {
 
-	private Integer batchSize = 2;
-
-	private IndexerServiceClient indexerServiceClient = mock(IndexerServiceClient.class);
-	private LaunchRepository launchRepository = mock(LaunchRepository.class);
-	private TestItemRepository testItemRepository = mock(TestItemRepository.class);
-	private LaunchPreparerService launchPreparerService = mock(LaunchPreparerService.class);
-
-	private final BatchLogIndexer batchLogIndexer = new BatchLogIndexer(batchSize,
-			batchSize,
-			launchRepository,
-			testItemRepository,
-			launchPreparerService,
-			indexerServiceClient
-	);
-
-	@Test
-	void indexWhenHasErrorLogs() {
-
-		final List<Long> firstPortionIds = List.of(1L, 2L);
-		final List<Long> secondPortionIds = List.of(3L);
-		when(launchRepository.findIdsByProjectIdAndModeAndStatusNotEq(eq(1L),
-				any(JLaunchModeEnum.class),
-				any(JStatusEnum.class),
-				anyInt()
-		)).thenReturn(firstPortionIds);
-		when(launchRepository.hasItemsWithLogsWithLogLevel(eq(1L), anyList(), anyInt())).thenReturn(true);
-		when(launchRepository.hasItemsWithLogsWithLogLevel(eq(2L), anyList(), anyInt())).thenReturn(true);
-		when(launchRepository.hasItemsWithLogsWithLogLevel(eq(3L), anyList(), anyInt())).thenReturn(true);
-
-		final IndexLaunch firstIndex = new IndexLaunch();
-		final List<IndexTestItem> firstIndexItems = List.of(new IndexTestItem());
-		firstIndex.setTestItems(firstIndexItems);
-		final IndexLaunch secondIndex = new IndexLaunch();
-		final List<IndexTestItem> secondIndexItems = List.of(new IndexTestItem());
-		secondIndex.setTestItems(secondIndexItems);
-		when(launchPreparerService.prepare(eq(firstPortionIds), any(AnalyzerConfig.class))).thenReturn(List.of(firstIndex, secondIndex));
-
-		when(launchRepository.findIdsByProjectIdAndModeAndStatusNotEqAfterId(eq(1L),
-				any(JLaunchModeEnum.class),
-				any(JStatusEnum.class),
-				eq(2L),
-				anyInt()
-		)).thenReturn(secondPortionIds);
-
-		final IndexLaunch thirdIndex = new IndexLaunch();
-		final List<IndexTestItem> thirdIndexItems = List.of(new IndexTestItem(), new IndexTestItem(), new IndexTestItem());
-		thirdIndex.setTestItems(thirdIndexItems);
-		when(launchPreparerService.prepare(eq(secondPortionIds), any(AnalyzerConfig.class))).thenReturn(List.of(thirdIndex));
-
-		batchLogIndexer.index(1L, analyzerConfig());
-
-		final int expectedIndexedTimes = Stream.of(firstIndexItems, secondIndexItems, thirdIndexItems)
-				.map(Collection::size)
-				.mapToInt(this::getIndexedTimes)
-				.sum();
-
-		verify(indexerServiceClient, times(expectedIndexedTimes)).index(anyList());
-
-	}
-
-	private int getIndexedTimes(int expectedIndexedItems) {
-		return BigDecimal.valueOf(expectedIndexedItems).divide(BigDecimal.valueOf(batchSize), RoundingMode.CEILING).intValue();
-	}
-
-	@Test
-	void indexWhenLaunchHasNoErrorLogs() {
-
-		final List<Long> ids = List.of(1L, 2L);
-		when(launchRepository.findIdsByProjectIdAndModeAndStatusNotEq(eq(1L),
-				any(JLaunchModeEnum.class),
-				any(JStatusEnum.class),
-				anyInt()
-		)).thenReturn(ids);
-		when(launchRepository.hasItemsWithLogsWithLogLevel(eq(1L), anyList(), anyInt())).thenReturn(false);
-		when(launchRepository.hasItemsWithLogsWithLogLevel(eq(2L), anyList(), anyInt())).thenReturn(false);
-
-		batchLogIndexer.index(1L, analyzerConfig());
-
-		verify(launchPreparerService, times(0)).prepare(anyList(), any(AnalyzerConfig.class));
-		verify(indexerServiceClient, times(0)).index(anyList());
-
-	}
-
-	private AnalyzerConfig analyzerConfig() {
-		AnalyzerConfig analyzerConfig = new AnalyzerConfig();
-		analyzerConfig.setAnalyzerMode(ALL_LAUNCHES.getValue());
-		return analyzerConfig;
-	}
+  private Integer batchSize = 2;
+
+  private IndexerServiceClient indexerServiceClient = mock(IndexerServiceClient.class);
+  private LaunchRepository launchRepository = mock(LaunchRepository.class);
+  private TestItemRepository testItemRepository = mock(TestItemRepository.class);
+  private LaunchPreparerService launchPreparerService = mock(LaunchPreparerService.class);
+
+  private final BatchLogIndexer batchLogIndexer = new BatchLogIndexer(batchSize,
+      batchSize,
+      launchRepository,
+      testItemRepository,
+      launchPreparerService,
+      indexerServiceClient
+  );
+
+  @Test
+  void indexWhenHasErrorLogs() {
+
+    final List<Long> firstPortionIds = List.of(1L, 2L);
+    final List<Long> secondPortionIds = List.of(3L);
+    when(launchRepository.findIdsByProjectIdAndModeAndStatusNotEq(eq(1L),
+        any(JLaunchModeEnum.class),
+        any(JStatusEnum.class),
+        anyInt()
+    )).thenReturn(firstPortionIds);
+    when(launchRepository.hasItemsWithLogsWithLogLevel(eq(1L), anyList(), anyInt())).thenReturn(
+        true);
+    when(launchRepository.hasItemsWithLogsWithLogLevel(eq(2L), anyList(), anyInt())).thenReturn(
+        true);
+    when(launchRepository.hasItemsWithLogsWithLogLevel(eq(3L), anyList(), anyInt())).thenReturn(
+        true);
+
+    final IndexLaunch firstIndex = new IndexLaunch();
+    final List<IndexTestItem> firstIndexItems = List.of(new IndexTestItem());
+    firstIndex.setTestItems(firstIndexItems);
+    final IndexLaunch secondIndex = new IndexLaunch();
+    final List<IndexTestItem> secondIndexItems = List.of(new IndexTestItem());
+    secondIndex.setTestItems(secondIndexItems);
+    when(launchPreparerService.prepare(eq(firstPortionIds), any(AnalyzerConfig.class))).thenReturn(
+        List.of(firstIndex, secondIndex));
+
+    when(launchRepository.findIdsByProjectIdAndModeAndStatusNotEqAfterId(eq(1L),
+        any(JLaunchModeEnum.class),
+        any(JStatusEnum.class),
+        eq(2L),
+        anyInt()
+    )).thenReturn(secondPortionIds);
+
+    final IndexLaunch thirdIndex = new IndexLaunch();
+    final List<IndexTestItem> thirdIndexItems = List.of(new IndexTestItem(), new IndexTestItem(),
+        new IndexTestItem());
+    thirdIndex.setTestItems(thirdIndexItems);
+    when(launchPreparerService.prepare(eq(secondPortionIds), any(AnalyzerConfig.class))).thenReturn(
+        List.of(thirdIndex));
+
+    batchLogIndexer.index(1L, analyzerConfig());
+
+    final int expectedIndexedTimes = Stream.of(firstIndexItems, secondIndexItems, thirdIndexItems)
+        .map(Collection::size)
+        .mapToInt(this::getIndexedTimes)
+        .sum();
+
+    verify(indexerServiceClient, times(expectedIndexedTimes)).index(anyList());
+
+  }
+
+  private int getIndexedTimes(int expectedIndexedItems) {
+    return BigDecimal.valueOf(expectedIndexedItems)
+        .divide(BigDecimal.valueOf(batchSize), RoundingMode.CEILING).intValue();
+  }
+
+  @Test
+  void indexWhenLaunchHasNoErrorLogs() {
+
+    final List<Long> ids = List.of(1L, 2L);
+    when(launchRepository.findIdsByProjectIdAndModeAndStatusNotEq(eq(1L),
+        any(JLaunchModeEnum.class),
+        any(JStatusEnum.class),
+        anyInt()
+    )).thenReturn(ids);
+    when(launchRepository.hasItemsWithLogsWithLogLevel(eq(1L), anyList(), anyInt())).thenReturn(
+        false);
+    when(launchRepository.hasItemsWithLogsWithLogLevel(eq(2L), anyList(), anyInt())).thenReturn(
+        false);
+
+    batchLogIndexer.index(1L, analyzerConfig());
+
+    verify(launchPreparerService, times(0)).prepare(anyList(), any(AnalyzerConfig.class));
+    verify(indexerServiceClient, times(0)).index(anyList());
+
+  }
+
+  private AnalyzerConfig analyzerConfig() {
+    AnalyzerConfig analyzerConfig = new AnalyzerConfig();
+    analyzerConfig.setAnalyzerMode(ALL_LAUNCHES.getValue());
+    return analyzerConfig;
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/starter/CollectingAutoAnalysisStarterTest.java b/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/starter/CollectingAutoAnalysisStarterTest.java
index a74f97d54c..6bbeab1cbe 100644
--- a/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/starter/CollectingAutoAnalysisStarterTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/starter/CollectingAutoAnalysisStarterTest.java
@@ -16,6 +16,14 @@
 
 package com.epam.ta.reportportal.core.analyzer.auto.starter;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.analyzer.auto.AnalyzerService;
 import com.epam.ta.reportportal.core.analyzer.auto.LogIndexer;
@@ -33,63 +41,67 @@
 import com.epam.ta.reportportal.entity.user.UserRole;
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
 import com.google.common.collect.Lists;
-import org.junit.jupiter.api.Test;
-
 import java.util.List;
 import java.util.Set;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.*;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class CollectingAutoAnalysisStarterTest {
 
-	public static final Long INDEXED_LOG_COUNT = 5L;
-
-	private final GetLaunchHandler getLaunchHandler = mock(GetLaunchHandler.class);
-	private final AnalyzeCollectorFactory analyzeCollectorFactory = mock(AnalyzeCollectorFactory.class);
-	private final AnalyzeItemsCollector analyzeItemsCollector = mock(AnalyzeItemsCollector.class);
-	private final AnalyzerService analyzerService = mock(AnalyzerService.class);
-	private final LogIndexer logIndexer = mock(LogIndexer.class);
-
-	private final CollectingAutoAnalysisStarter starter = new CollectingAutoAnalysisStarter(getLaunchHandler,
-			analyzeCollectorFactory,
-			analyzerService,
-			logIndexer
-	);
-
-	@Test
-	void shouldAnalyze() {
-
-		final Launch launch = LaunchTestUtil.getLaunch(StatusEnum.FAILED, LaunchModeEnum.DEFAULT).get();
-		final ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, launch.getProjectId());
-		final LaunchFinishedEvent event = new LaunchFinishedEvent(launch, user, "baseUrl");
-
-		final AnalyzerConfig analyzerConfig = new AnalyzerConfig();
-		analyzerConfig.setIsAutoAnalyzerEnabled(true);
-		final StartLaunchAutoAnalysisConfig startLaunchAutoAnalysisConfig = StartLaunchAutoAnalysisConfig.of(launch.getId(),
-				analyzerConfig,
-				Set.of(AnalyzeItemsMode.TO_INVESTIGATE),
-				user
-		);
-
-		when(analyzerService.hasAnalyzers()).thenReturn(true);
-
-		when(getLaunchHandler.get(event.getId())).thenReturn(launch);
-		when(logIndexer.indexLaunchLogs(eq(launch), any(AnalyzerConfig.class))).thenReturn(INDEXED_LOG_COUNT);
-
-		when(analyzeCollectorFactory.getCollector(AnalyzeItemsMode.TO_INVESTIGATE)).thenReturn(analyzeItemsCollector);
-		final List<Long> itemIds = Lists.newArrayList(1L, 2L);
-		when(analyzeItemsCollector.collectItems(launch.getProjectId(), launch.getId(), user)).thenReturn(itemIds);
-
-		starter.start(startLaunchAutoAnalysisConfig);
-
-		verify(analyzerService, times(1)).runAnalyzers(eq(launch), eq(itemIds), any(AnalyzerConfig.class));
-		verify(logIndexer, times(1)).indexItemsLogs(eq(launch.getProjectId()), eq(launch.getId()), eq(itemIds), any(AnalyzerConfig.class));
-	}
+  public static final Long INDEXED_LOG_COUNT = 5L;
+
+  private final GetLaunchHandler getLaunchHandler = mock(GetLaunchHandler.class);
+  private final AnalyzeCollectorFactory analyzeCollectorFactory = mock(
+      AnalyzeCollectorFactory.class);
+  private final AnalyzeItemsCollector analyzeItemsCollector = mock(AnalyzeItemsCollector.class);
+  private final AnalyzerService analyzerService = mock(AnalyzerService.class);
+  private final LogIndexer logIndexer = mock(LogIndexer.class);
+
+  private final CollectingAutoAnalysisStarter starter = new CollectingAutoAnalysisStarter(
+      getLaunchHandler,
+      analyzeCollectorFactory,
+      analyzerService,
+      logIndexer
+  );
+
+  @Test
+  void shouldAnalyze() {
+
+    final Launch launch = LaunchTestUtil.getLaunch(StatusEnum.FAILED, LaunchModeEnum.DEFAULT).get();
+    final ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER,
+        launch.getProjectId());
+    final LaunchFinishedEvent event = new LaunchFinishedEvent(launch, user, "baseUrl");
+
+    final AnalyzerConfig analyzerConfig = new AnalyzerConfig();
+    analyzerConfig.setIsAutoAnalyzerEnabled(true);
+    final StartLaunchAutoAnalysisConfig startLaunchAutoAnalysisConfig = StartLaunchAutoAnalysisConfig.of(
+        launch.getId(),
+        analyzerConfig,
+        Set.of(AnalyzeItemsMode.TO_INVESTIGATE),
+        user
+    );
+
+    when(analyzerService.hasAnalyzers()).thenReturn(true);
+
+    when(getLaunchHandler.get(event.getId())).thenReturn(launch);
+    when(logIndexer.indexLaunchLogs(eq(launch), any(AnalyzerConfig.class))).thenReturn(
+        INDEXED_LOG_COUNT);
+
+    when(analyzeCollectorFactory.getCollector(AnalyzeItemsMode.TO_INVESTIGATE)).thenReturn(
+        analyzeItemsCollector);
+    final List<Long> itemIds = Lists.newArrayList(1L, 2L);
+    when(
+        analyzeItemsCollector.collectItems(launch.getProjectId(), launch.getId(), user)).thenReturn(
+        itemIds);
+
+    starter.start(startLaunchAutoAnalysisConfig);
+
+    verify(analyzerService, times(1)).runAnalyzers(eq(launch), eq(itemIds),
+        any(AnalyzerConfig.class));
+    verify(logIndexer, times(1)).indexItemsLogs(eq(launch.getProjectId()), eq(launch.getId()),
+        eq(itemIds), any(AnalyzerConfig.class));
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/AsyncAutoAnalysisStarterTest.java b/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/AsyncAutoAnalysisStarterTest.java
index 03fb8692a4..f108e9d353 100644
--- a/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/AsyncAutoAnalysisStarterTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/AsyncAutoAnalysisStarterTest.java
@@ -16,6 +16,13 @@
 
 package com.epam.ta.reportportal.core.analyzer.auto.starter.decorator;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doCallRealMethod;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.analyzer.auto.starter.LaunchAutoAnalysisStarter;
 import com.epam.ta.reportportal.core.analyzer.auto.strategy.analyze.AnalyzeItemsMode;
@@ -23,39 +30,35 @@
 import com.epam.ta.reportportal.entity.project.ProjectRole;
 import com.epam.ta.reportportal.entity.user.UserRole;
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
+import java.util.Set;
 import org.junit.jupiter.api.Test;
 import org.springframework.core.task.SyncTaskExecutor;
 
-import java.util.Set;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.*;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class AsyncAutoAnalysisStarterTest {
 
-	private final SyncTaskExecutor taskExecutor = mock(SyncTaskExecutor.class);
-	private final LaunchAutoAnalysisStarter delegate = mock(LaunchAutoAnalysisStarter.class);
+  private final SyncTaskExecutor taskExecutor = mock(SyncTaskExecutor.class);
+  private final LaunchAutoAnalysisStarter delegate = mock(LaunchAutoAnalysisStarter.class);
 
-	private final AsyncAutoAnalysisStarter asyncAutoAnalysisStarter = new AsyncAutoAnalysisStarter(taskExecutor, delegate);
+  private final AsyncAutoAnalysisStarter asyncAutoAnalysisStarter = new AsyncAutoAnalysisStarter(
+      taskExecutor, delegate);
 
-	@Test
-	void shouldExecute() {
-		final ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, 1L);
-		final StartLaunchAutoAnalysisConfig config = StartLaunchAutoAnalysisConfig.of(1L,
-				new AnalyzerConfig(),
-				Set.of(AnalyzeItemsMode.TO_INVESTIGATE),
-				user
-		);
+  @Test
+  void shouldExecute() {
+    final ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, 1L);
+    final StartLaunchAutoAnalysisConfig config = StartLaunchAutoAnalysisConfig.of(1L,
+        new AnalyzerConfig(),
+        Set.of(AnalyzeItemsMode.TO_INVESTIGATE),
+        user
+    );
 
-		doCallRealMethod().when(taskExecutor).execute(any());
+    doCallRealMethod().when(taskExecutor).execute(any());
 
-		asyncAutoAnalysisStarter.start(config);
+    asyncAutoAnalysisStarter.start(config);
 
-		verify(delegate, times(1)).start(config);
-	}
+    verify(delegate, times(1)).start(config);
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/AutoAnalysisEnabledStarterTest.java b/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/AutoAnalysisEnabledStarterTest.java
index f01bc612c7..e339b01ad7 100644
--- a/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/AutoAnalysisEnabledStarterTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/AutoAnalysisEnabledStarterTest.java
@@ -16,6 +16,11 @@
 
 package com.epam.ta.reportportal.core.analyzer.auto.starter.decorator;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.analyzer.auto.starter.LaunchAutoAnalysisStarter;
 import com.epam.ta.reportportal.core.analyzer.auto.strategy.analyze.AnalyzeItemsMode;
@@ -23,54 +28,51 @@
 import com.epam.ta.reportportal.entity.project.ProjectRole;
 import com.epam.ta.reportportal.entity.user.UserRole;
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
-import org.junit.jupiter.api.Test;
-
 import java.util.Set;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static org.mockito.Mockito.*;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class AutoAnalysisEnabledStarterTest {
 
-	private final LaunchAutoAnalysisStarter delegate = mock(LaunchAutoAnalysisStarter.class);
-	private final AutoAnalysisEnabledStarter autoAnalysisEnabledStarter = new AutoAnalysisEnabledStarter(delegate);
+  private final LaunchAutoAnalysisStarter delegate = mock(LaunchAutoAnalysisStarter.class);
+  private final AutoAnalysisEnabledStarter autoAnalysisEnabledStarter = new AutoAnalysisEnabledStarter(
+      delegate);
 
-	@Test
-	void shouldRunWhenAutoAnalysisEnabled() {
+  @Test
+  void shouldRunWhenAutoAnalysisEnabled() {
 
-		final ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, 1L);
-		final AnalyzerConfig analyzerConfig = new AnalyzerConfig();
-		analyzerConfig.setIsAutoAnalyzerEnabled(true);
+    final ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, 1L);
+    final AnalyzerConfig analyzerConfig = new AnalyzerConfig();
+    analyzerConfig.setIsAutoAnalyzerEnabled(true);
 
-		final StartLaunchAutoAnalysisConfig config = StartLaunchAutoAnalysisConfig.of(1L,
-				analyzerConfig,
-				Set.of(AnalyzeItemsMode.TO_INVESTIGATE),
-				user
-		);
+    final StartLaunchAutoAnalysisConfig config = StartLaunchAutoAnalysisConfig.of(1L,
+        analyzerConfig,
+        Set.of(AnalyzeItemsMode.TO_INVESTIGATE),
+        user
+    );
 
-		autoAnalysisEnabledStarter.start(config);
+    autoAnalysisEnabledStarter.start(config);
 
-		verify(delegate, times(1)).start(config);
-	}
+    verify(delegate, times(1)).start(config);
+  }
 
-	@Test
-	void shouldNotRunWhenAutoAnalysisDisabled() {
-		final ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, 1L);
-		final AnalyzerConfig analyzerConfig = new AnalyzerConfig();
-		analyzerConfig.setIsAutoAnalyzerEnabled(false);
+  @Test
+  void shouldNotRunWhenAutoAnalysisDisabled() {
+    final ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, 1L);
+    final AnalyzerConfig analyzerConfig = new AnalyzerConfig();
+    analyzerConfig.setIsAutoAnalyzerEnabled(false);
 
-		final StartLaunchAutoAnalysisConfig config = StartLaunchAutoAnalysisConfig.of(1L,
-				analyzerConfig,
-				Set.of(AnalyzeItemsMode.TO_INVESTIGATE),
-				user
-		);
+    final StartLaunchAutoAnalysisConfig config = StartLaunchAutoAnalysisConfig.of(1L,
+        analyzerConfig,
+        Set.of(AnalyzeItemsMode.TO_INVESTIGATE),
+        user
+    );
 
-		autoAnalysisEnabledStarter.start(config);
+    autoAnalysisEnabledStarter.start(config);
 
-		verify(delegate, times(0)).start(config);
-	}
+    verify(delegate, times(0)).start(config);
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/ExistingAnalyzerStarterTest.java b/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/ExistingAnalyzerStarterTest.java
index fbdec07075..c94030457a 100644
--- a/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/ExistingAnalyzerStarterTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/ExistingAnalyzerStarterTest.java
@@ -16,6 +16,14 @@
 
 package com.epam.ta.reportportal.core.analyzer.auto.starter.decorator;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.analyzer.auto.AnalyzerService;
 import com.epam.ta.reportportal.core.analyzer.auto.starter.LaunchAutoAnalysisStarter;
@@ -25,57 +33,56 @@
 import com.epam.ta.reportportal.entity.user.UserRole;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
-import org.junit.jupiter.api.Test;
-
 import java.util.Set;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.Mockito.*;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class ExistingAnalyzerStarterTest {
 
-	private final AnalyzerService analyzerService = mock(AnalyzerService.class);
-	private final LaunchAutoAnalysisStarter delegate = mock(LaunchAutoAnalysisStarter.class);
+  private final AnalyzerService analyzerService = mock(AnalyzerService.class);
+  private final LaunchAutoAnalysisStarter delegate = mock(LaunchAutoAnalysisStarter.class);
 
-	private final ExistingAnalyzerStarter existingAnalyzerStarter = new ExistingAnalyzerStarter(analyzerService, delegate);
+  private final ExistingAnalyzerStarter existingAnalyzerStarter = new ExistingAnalyzerStarter(
+      analyzerService, delegate);
 
-	@Test
-	void shouldRunWhenHasAnalyzers() {
+  @Test
+  void shouldRunWhenHasAnalyzers() {
 
-		final ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, 1L);
-		final StartLaunchAutoAnalysisConfig config = StartLaunchAutoAnalysisConfig.of(1L,
-				new AnalyzerConfig(),
-				Set.of(AnalyzeItemsMode.TO_INVESTIGATE),
-				user
-		);
+    final ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, 1L);
+    final StartLaunchAutoAnalysisConfig config = StartLaunchAutoAnalysisConfig.of(1L,
+        new AnalyzerConfig(),
+        Set.of(AnalyzeItemsMode.TO_INVESTIGATE),
+        user
+    );
 
-		when(analyzerService.hasAnalyzers()).thenReturn(Boolean.TRUE);
+    when(analyzerService.hasAnalyzers()).thenReturn(Boolean.TRUE);
 
-		existingAnalyzerStarter.start(config);
+    existingAnalyzerStarter.start(config);
 
-		verify(delegate, times(1)).start(config);
-	}
+    verify(delegate, times(1)).start(config);
+  }
 
-	@Test
-	void shouldThrowReportPortalExceptionWhenNoAnalyzers() {
-		final ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, 1L);
-		final StartLaunchAutoAnalysisConfig config = StartLaunchAutoAnalysisConfig.of(1L,
-				new AnalyzerConfig(),
-				Set.of(AnalyzeItemsMode.TO_INVESTIGATE),
-				user
-		);
+  @Test
+  void shouldThrowReportPortalExceptionWhenNoAnalyzers() {
+    final ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, 1L);
+    final StartLaunchAutoAnalysisConfig config = StartLaunchAutoAnalysisConfig.of(1L,
+        new AnalyzerConfig(),
+        Set.of(AnalyzeItemsMode.TO_INVESTIGATE),
+        user
+    );
 
-		when(analyzerService.hasAnalyzers()).thenReturn(Boolean.FALSE);
+    when(analyzerService.hasAnalyzers()).thenReturn(Boolean.FALSE);
 
-		final ReportPortalException exception = assertThrows(ReportPortalException.class, () -> existingAnalyzerStarter.start(config));
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> existingAnalyzerStarter.start(config));
 
-		assertEquals("Impossible interact with integration. There are no analyzer services are deployed.", exception.getMessage());
+    assertEquals(
+        "Impossible interact with integration. There are no analyzer services are deployed.",
+        exception.getMessage());
 
-		verify(delegate, times(0)).start(config);
-	}
+    verify(delegate, times(0)).start(config);
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/IndexingAutoAnalysisStarterTest.java b/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/IndexingAutoAnalysisStarterTest.java
index 3d28d4f798..a7229fbf56 100644
--- a/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/IndexingAutoAnalysisStarterTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/analyzer/auto/starter/decorator/IndexingAutoAnalysisStarterTest.java
@@ -16,6 +16,12 @@
 
 package com.epam.ta.reportportal.core.analyzer.auto.starter.decorator;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.analyzer.auto.LogIndexer;
 import com.epam.ta.reportportal.core.analyzer.auto.starter.LaunchAutoAnalysisStarter;
@@ -29,43 +35,40 @@
 import com.epam.ta.reportportal.entity.project.ProjectRole;
 import com.epam.ta.reportportal.entity.user.UserRole;
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
-import org.junit.jupiter.api.Test;
-
 import java.util.Set;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static org.mockito.Mockito.*;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class IndexingAutoAnalysisStarterTest {
 
-	private final GetLaunchHandler getLaunchHandler = mock(GetLaunchHandler.class);
-	private final LogIndexer logIndexer = mock(LogIndexer.class);
-	private final LaunchAutoAnalysisStarter delegate = mock(LaunchAutoAnalysisStarter.class);
+  private final GetLaunchHandler getLaunchHandler = mock(GetLaunchHandler.class);
+  private final LogIndexer logIndexer = mock(LogIndexer.class);
+  private final LaunchAutoAnalysisStarter delegate = mock(LaunchAutoAnalysisStarter.class);
 
-	private final IndexingAutoAnalysisStarter indexingAutoAnalysisStarter = new IndexingAutoAnalysisStarter(getLaunchHandler,
-			logIndexer,
-			delegate
-	);
+  private final IndexingAutoAnalysisStarter indexingAutoAnalysisStarter = new IndexingAutoAnalysisStarter(
+      getLaunchHandler,
+      logIndexer,
+      delegate
+  );
 
-	@Test
-	void shouldIndex() {
-		final Launch launch = LaunchTestUtil.getLaunch(StatusEnum.FAILED, LaunchModeEnum.DEFAULT).get();
+  @Test
+  void shouldIndex() {
+    final Launch launch = LaunchTestUtil.getLaunch(StatusEnum.FAILED, LaunchModeEnum.DEFAULT).get();
 
-		final ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, 1L);
-		final StartLaunchAutoAnalysisConfig config = StartLaunchAutoAnalysisConfig.of(launch.getId(),
-				new AnalyzerConfig(),
-				Set.of(AnalyzeItemsMode.TO_INVESTIGATE),
-				user
-		);
+    final ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, 1L);
+    final StartLaunchAutoAnalysisConfig config = StartLaunchAutoAnalysisConfig.of(launch.getId(),
+        new AnalyzerConfig(),
+        Set.of(AnalyzeItemsMode.TO_INVESTIGATE),
+        user
+    );
 
-		when(getLaunchHandler.get(config.getLaunchId())).thenReturn(launch);
+    when(getLaunchHandler.get(config.getLaunchId())).thenReturn(launch);
 
-		indexingAutoAnalysisStarter.start(config);
+    indexingAutoAnalysisStarter.start(config);
 
-		verify(logIndexer, times(1)).indexLaunchLogs(launch, config.getAnalyzerConfig());
-	}
+    verify(logIndexer, times(1)).indexLaunchLogs(launch, config.getAnalyzerConfig());
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/analyzer/config/AnalyzerTypeTest.java b/src/test/java/com/epam/ta/reportportal/core/analyzer/config/AnalyzerTypeTest.java
index 66222c2226..a2cc3ffd12 100644
--- a/src/test/java/com/epam/ta/reportportal/core/analyzer/config/AnalyzerTypeTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/analyzer/config/AnalyzerTypeTest.java
@@ -16,30 +16,34 @@
 
 package com.epam.ta.reportportal.core.analyzer.config;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import org.junit.jupiter.api.Test;
 
-import static org.junit.jupiter.api.Assertions.*;
-
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
  */
 class AnalyzerTypeTest {
 
-	@Test
-	void testFromStringPositive() {
-		String autoAnalyser = "autoAnalyzer";
-		AnalyzerType analyzer = AnalyzerType.fromString(autoAnalyser);
-		assertTrue(analyzer.getName().equalsIgnoreCase(autoAnalyser));
-	}
+  @Test
+  void testFromStringPositive() {
+    String autoAnalyser = "autoAnalyzer";
+    AnalyzerType analyzer = AnalyzerType.fromString(autoAnalyser);
+    assertTrue(analyzer.getName().equalsIgnoreCase(autoAnalyser));
+  }
 
-	@Test
-	void testFromStringNegative() {
-		String autoAnalyser = "incorrect";
-		ReportPortalException exception = assertThrows(ReportPortalException.class, () -> AnalyzerType.fromString(autoAnalyser));
-		assertEquals(exception.getErrorType(), ErrorType.INCORRECT_REQUEST);
-		assertEquals(exception.getMessage(), "Incorrect Request. Incorrect analyzer type. Allowed are: [autoAnalyzer, patternAnalyzer]");
-	}
+  @Test
+  void testFromStringNegative() {
+    String autoAnalyser = "incorrect";
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> AnalyzerType.fromString(autoAnalyser));
+    assertEquals(exception.getErrorType(), ErrorType.INCORRECT_REQUEST);
+    assertEquals(exception.getMessage(),
+        "Incorrect Request. Incorrect analyzer type. Allowed are: [autoAnalyzer, patternAnalyzer]");
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/analyzer/pattern/PatternAnalyzerTest.java b/src/test/java/com/epam/ta/reportportal/core/analyzer/pattern/PatternAnalyzerTest.java
deleted file mode 100644
index 398ec83b35..0000000000
--- a/src/test/java/com/epam/ta/reportportal/core/analyzer/pattern/PatternAnalyzerTest.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright 2019 EPAM Systems
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.epam.ta.reportportal.core.analyzer.pattern;
-
-import com.epam.ta.reportportal.commons.querygen.ConvertibleCondition;
-import com.epam.ta.reportportal.commons.querygen.FilterCondition;
-import com.epam.ta.reportportal.commons.querygen.Queryable;
-import com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerStatusCache;
-import com.epam.ta.reportportal.core.analyzer.pattern.impl.PatternAnalyzerImpl;
-import com.epam.ta.reportportal.core.analyzer.pattern.selector.PatternAnalysisSelector;
-import com.epam.ta.reportportal.core.analyzer.pattern.selector.condition.PatternConditionProviderChain;
-import com.epam.ta.reportportal.core.analyzer.pattern.selector.impl.RegexPatternAnalysisSelector;
-import com.epam.ta.reportportal.core.analyzer.pattern.selector.impl.StringPartPatternAnalysisSelector;
-import com.epam.ta.reportportal.core.events.MessageBus;
-import com.epam.ta.reportportal.dao.IssueGroupRepository;
-import com.epam.ta.reportportal.dao.PatternTemplateRepository;
-import com.epam.ta.reportportal.dao.TestItemRepository;
-import com.epam.ta.reportportal.entity.enums.TestItemIssueGroup;
-import com.epam.ta.reportportal.entity.item.issue.IssueGroup;
-import com.epam.ta.reportportal.entity.launch.Launch;
-import com.epam.ta.reportportal.entity.pattern.PatternTemplate;
-import com.epam.ta.reportportal.entity.pattern.PatternTemplateTestItemPojo;
-import com.epam.ta.reportportal.entity.pattern.PatternTemplateType;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-import org.mockito.ArgumentCaptor;
-import org.springframework.core.task.TaskExecutor;
-import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.stream.Collectors;
-
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_ID;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.*;
-
-/**
- * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
- */
-class PatternAnalyzerTest {
-
-	private final PatternAnalysisSelector stringSelector = mock(StringPartPatternAnalysisSelector.class);
-	private final PatternAnalysisSelector regexSelector = mock(RegexPatternAnalysisSelector.class);
-	private final MessageBus messageBus = mock(MessageBus.class);
-
-	private final TestItemRepository testItemRepository = mock(TestItemRepository.class);
-	private final IssueGroupRepository issueGroupRepository = mock(IssueGroupRepository.class);
-	private final PatternTemplateRepository patternTemplateRepository = mock(PatternTemplateRepository.class);
-	private final AnalyzerStatusCache analyzerStatusCache = mock(AnalyzerStatusCache.class);
-	private final PatternConditionProviderChain patternConditionProviderChain = mock(PatternConditionProviderChain.class);
-
-	private final TaskExecutor taskExecutor = new ThreadPoolTaskExecutor() {
-		@Override
-		public void execute(Runnable task) {
-			task.run();
-		}
-	};
-
-	private final IssueGroup issueGroup = mock(IssueGroup.class);
-	private final Launch launch = mock(Launch.class);
-
-	private final Map<PatternTemplateType, PatternAnalysisSelector> analysisSelectorMapping = mock(Map.class);
-
-	private final int batchSize = 100;
-
-	private final PatternAnalyzer patternAnalyzer = new PatternAnalyzerImpl(batchSize,
-			testItemRepository,
-			patternTemplateRepository,
-			analysisSelectorMapping,
-			taskExecutor,
-			patternConditionProviderChain,
-			analyzerStatusCache,
-			messageBus
-	);
-
-	@Test
-	void analyzeTestItems() {
-		when(issueGroupRepository.findByTestItemIssueGroup(any(TestItemIssueGroup.class))).thenReturn(issueGroup);
-		when(patternTemplateRepository.findAllByProjectIdAndEnabled(launch.getProjectId(), true)).thenReturn(getPatternTemplates());
-
-		when(launch.getId()).thenReturn(1L);
-
-		final List<Long> itemIds = List.of(10L, 11L, 12L);
-
-		when(patternConditionProviderChain.provideCondition(anySet())).thenReturn(Optional.of(getConvertibleCondition()));
-		when(testItemRepository.selectIdsByFilter(eq(launch.getId()), any(Queryable.class), eq(batchSize), eq(0))).thenReturn(itemIds);
-		when(analysisSelectorMapping.get(PatternTemplateType.STRING)).thenReturn(stringSelector);
-		when(analysisSelectorMapping.get(PatternTemplateType.REGEX)).thenReturn(regexSelector);
-
-		final List<Long> firstPatternMatch = List.of(10L, 11L);
-		final List<Long> secondPatternMatch = List.of(11L, 12L);
-		when(stringSelector.selectItemsByPattern(eq(launch.getId()), eq(itemIds), anyString())).thenReturn(firstPatternMatch);
-		when(regexSelector.selectItemsByPattern(eq(launch.getId()), eq(itemIds), anyString())).thenReturn(secondPatternMatch);
-
-		patternAnalyzer.analyzeTestItems(launch, Sets.newHashSet());
-
-		final ArgumentCaptor<List<PatternTemplateTestItemPojo>> pojoCaptor = ArgumentCaptor.forClass(List.class);
-		verify(patternTemplateRepository, times(2)).saveInBatch(pojoCaptor.capture());
-
-		final List<PatternTemplateTestItemPojo> stringPatternPojos = pojoCaptor.getAllValues().get(0);
-		final List<PatternTemplateTestItemPojo> regexPatternPojos = pojoCaptor.getAllValues().get(1);
-
-		Assertions.assertEquals(firstPatternMatch,
-				stringPatternPojos.stream().map(PatternTemplateTestItemPojo::getTestItemId).collect(Collectors.toList())
-		);
-		Assertions.assertEquals(secondPatternMatch,
-				regexPatternPojos.stream().map(PatternTemplateTestItemPojo::getTestItemId).collect(Collectors.toList())
-		);
-	}
-
-	private ConvertibleCondition getConvertibleCondition() {
-		return FilterCondition.builder().eq(CRITERIA_ID, String.valueOf(1L)).build();
-	}
-
-	private List<PatternTemplate> getPatternTemplates() {
-
-		return Lists.newArrayList(getPatternTemplate(1L, "name", "value", PatternTemplateType.STRING),
-				getPatternTemplate(2L, "name1", "value1", PatternTemplateType.REGEX)
-		);
-	}
-
-	private PatternTemplate getPatternTemplate(Long id, String name, String value, PatternTemplateType type) {
-		PatternTemplate patternTemplate = new PatternTemplate();
-		patternTemplate.setId(id);
-		patternTemplate.setName(name);
-		patternTemplate.setValue(value);
-		patternTemplate.setEnabled(true);
-		patternTemplate.setTemplateType(type);
-		patternTemplate.setProjectId(1L);
-		return patternTemplate;
-	}
-
-	private List<PatternTemplateTestItemPojo> getPatternTemplateTestItemPojos(Long patternId) {
-
-		return Lists.newArrayList(new PatternTemplateTestItemPojo(patternId, 1L), new PatternTemplateTestItemPojo(patternId, 2L));
-	}
-}
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/analyzer/strategy/LaunchAutoAnalysisStrategyTest.java b/src/test/java/com/epam/ta/reportportal/core/analyzer/strategy/LaunchAutoAnalysisStrategyTest.java
index 184aab0ec2..1e7c6134e5 100644
--- a/src/test/java/com/epam/ta/reportportal/core/analyzer/strategy/LaunchAutoAnalysisStrategyTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/analyzer/strategy/LaunchAutoAnalysisStrategyTest.java
@@ -16,6 +16,12 @@
 
 package com.epam.ta.reportportal.core.analyzer.strategy;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.analyzer.auto.starter.LaunchAutoAnalysisStarter;
 import com.epam.ta.reportportal.core.analyzer.auto.strategy.analyze.AnalyzeItemsMode;
@@ -30,58 +36,59 @@
 import com.epam.ta.reportportal.ws.model.launch.AnalyzeLaunchRQ;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
+import java.util.Optional;
+import java.util.Set;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import org.mockito.ArgumentCaptor;
 
-import java.util.Optional;
-import java.util.Set;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static org.mockito.Mockito.*;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class LaunchAutoAnalysisStrategyTest {
-	private final Launch launch = mock(Launch.class);
-	private final Project project = mock(Project.class);
 
-	private final ProjectRepository projectRepository = mock(ProjectRepository.class);
-	private final LaunchRepository launchRepository = mock(LaunchRepository.class);
-	private final LaunchAutoAnalysisStarter autoAnalysisStarter = mock(LaunchAutoAnalysisStarter.class);
-	private final LaunchAutoAnalysisStrategy launchAutoAnalysisStrategy = new LaunchAutoAnalysisStrategy(projectRepository,
-			launchRepository,
-			autoAnalysisStarter
-	);
+  private final Launch launch = mock(Launch.class);
+  private final Project project = mock(Project.class);
+
+  private final ProjectRepository projectRepository = mock(ProjectRepository.class);
+  private final LaunchRepository launchRepository = mock(LaunchRepository.class);
+  private final LaunchAutoAnalysisStarter autoAnalysisStarter = mock(
+      LaunchAutoAnalysisStarter.class);
+  private final LaunchAutoAnalysisStrategy launchAutoAnalysisStrategy = new LaunchAutoAnalysisStrategy(
+      projectRepository,
+      launchRepository,
+      autoAnalysisStarter
+  );
 
-	@Test
-	void analyzeTest() {
+  @Test
+  void analyzeTest() {
 
-		when(launchRepository.findById(1L)).thenReturn(Optional.of(launch));
-		when(launch.getId()).thenReturn(1L);
-		when(launch.getProjectId()).thenReturn(1L);
-		when(launch.getMode()).thenReturn(LaunchModeEnum.DEFAULT);
-		when(projectRepository.findById(1L)).thenReturn(Optional.of(project));
-		when(project.getId()).thenReturn(1L);
+    when(launchRepository.findById(1L)).thenReturn(Optional.of(launch));
+    when(launch.getId()).thenReturn(1L);
+    when(launch.getProjectId()).thenReturn(1L);
+    when(launch.getMode()).thenReturn(LaunchModeEnum.DEFAULT);
+    when(projectRepository.findById(1L)).thenReturn(Optional.of(project));
+    when(project.getId()).thenReturn(1L);
 
-		when(project.getProjectAttributes()).thenReturn(Sets.newHashSet());
-		ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER, 1L);
+    when(project.getProjectAttributes()).thenReturn(Sets.newHashSet());
+    ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER, 1L);
 
-		ReportPortalUser.ProjectDetails projectDetails = new ReportPortalUser.ProjectDetails(1L, "name", ProjectRole.PROJECT_MANAGER);
-		AnalyzeLaunchRQ analyzeLaunchRQ = new AnalyzeLaunchRQ();
-		analyzeLaunchRQ.setLaunchId(1L);
-		analyzeLaunchRQ.setAnalyzerHistoryMode("ALL");
-		analyzeLaunchRQ.setAnalyzeItemsModes(Lists.newArrayList("TO_INVESTIGATE"));
-		analyzeLaunchRQ.setAnalyzerTypeName("patternAnalyzer");
-		launchAutoAnalysisStrategy.analyze(analyzeLaunchRQ, projectDetails, user);
+    ReportPortalUser.ProjectDetails projectDetails = new ReportPortalUser.ProjectDetails(1L, "name",
+        ProjectRole.PROJECT_MANAGER);
+    AnalyzeLaunchRQ analyzeLaunchRQ = new AnalyzeLaunchRQ();
+    analyzeLaunchRQ.setLaunchId(1L);
+    analyzeLaunchRQ.setAnalyzerHistoryMode("ALL");
+    analyzeLaunchRQ.setAnalyzeItemsModes(Lists.newArrayList("TO_INVESTIGATE"));
+    analyzeLaunchRQ.setAnalyzerTypeName("patternAnalyzer");
+    launchAutoAnalysisStrategy.analyze(analyzeLaunchRQ, projectDetails, user);
 
-		final ArgumentCaptor<StartLaunchAutoAnalysisConfig> configArgumentCaptor = ArgumentCaptor.forClass(StartLaunchAutoAnalysisConfig.class);
-		verify(autoAnalysisStarter, times(1)).start(configArgumentCaptor.capture());
+    final ArgumentCaptor<StartLaunchAutoAnalysisConfig> configArgumentCaptor = ArgumentCaptor.forClass(
+        StartLaunchAutoAnalysisConfig.class);
+    verify(autoAnalysisStarter, times(1)).start(configArgumentCaptor.capture());
 
-		final StartLaunchAutoAnalysisConfig config = configArgumentCaptor.getValue();
-		Assertions.assertEquals(launch.getId(), config.getLaunchId());
-		Assertions.assertEquals(Set.of(AnalyzeItemsMode.TO_INVESTIGATE), config.getAnalyzeItemsModes());
-		Assertions.assertEquals(user, config.getUser());
-	}
+    final StartLaunchAutoAnalysisConfig config = configArgumentCaptor.getValue();
+    Assertions.assertEquals(launch.getId(), config.getLaunchId());
+    Assertions.assertEquals(Set.of(AnalyzeItemsMode.TO_INVESTIGATE), config.getAnalyzeItemsModes());
+    Assertions.assertEquals(user, config.getUser());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/analyzer/strategy/LaunchPatternAnalysisStrategyTest.java b/src/test/java/com/epam/ta/reportportal/core/analyzer/strategy/LaunchPatternAnalysisStrategyTest.java
index bcded18910..7f9b432aae 100644
--- a/src/test/java/com/epam/ta/reportportal/core/analyzer/strategy/LaunchPatternAnalysisStrategyTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/analyzer/strategy/LaunchPatternAnalysisStrategyTest.java
@@ -16,14 +16,19 @@
 
 package com.epam.ta.reportportal.core.analyzer.strategy;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.analyzer.auto.strategy.analyze.AnalyzeItemsMode;
-import com.epam.ta.reportportal.core.analyzer.pattern.PatternAnalyzer;
+import com.epam.ta.reportportal.core.analyzer.pattern.service.LaunchPatternAnalyzer;
 import com.epam.ta.reportportal.dao.LaunchRepository;
 import com.epam.ta.reportportal.dao.ProjectRepository;
 import com.epam.ta.reportportal.entity.attribute.Attribute;
 import com.epam.ta.reportportal.entity.enums.LaunchModeEnum;
-import com.epam.ta.reportportal.entity.enums.ProjectAttributeEnum;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.entity.project.Project;
 import com.epam.ta.reportportal.entity.project.ProjectAttribute;
@@ -32,54 +37,53 @@
 import com.epam.ta.reportportal.ws.model.launch.AnalyzeLaunchRQ;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
-import org.junit.jupiter.api.Test;
-
 import java.util.Optional;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static org.mockito.Mockito.*;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class LaunchPatternAnalysisStrategyTest {
 
-	private final Launch launch = mock(Launch.class);
-	private final Project project = mock(Project.class);
+  private final Launch launch = mock(Launch.class);
+  private final Project project = mock(Project.class);
 
-	private final ProjectRepository projectRepository = mock(ProjectRepository.class);
-	private final LaunchRepository launchRepository = mock(LaunchRepository.class);
-	private final PatternAnalyzer patternAnalyzer = mock(PatternAnalyzer.class);
+  private final ProjectRepository projectRepository = mock(ProjectRepository.class);
+  private final LaunchRepository launchRepository = mock(LaunchRepository.class);
+  private final LaunchPatternAnalyzer launchPatternAnalyzer = mock(LaunchPatternAnalyzer.class);
 
-	private final LaunchPatternAnalysisStrategy launchPatternAnalysisStrategy = new LaunchPatternAnalysisStrategy(projectRepository,
-			launchRepository,
-			patternAnalyzer
-	);
+  private final LaunchPatternAnalysisStrategy launchPatternAnalysisStrategy = new LaunchPatternAnalysisStrategy(
+      projectRepository,
+      launchRepository,
+      launchPatternAnalyzer
+  );
 
-	@Test
-	void analyzeTest() {
+  @Test
+  void analyzeTest() {
 
-		when(launchRepository.findById(1L)).thenReturn(Optional.of(launch));
-		when(launch.getProjectId()).thenReturn(1L);
-		when(launch.getMode()).thenReturn(LaunchModeEnum.DEFAULT);
-		when(projectRepository.findById(1L)).thenReturn(Optional.of(project));
+    when(launchRepository.findById(1L)).thenReturn(Optional.of(launch));
+    when(launch.getProjectId()).thenReturn(1L);
+    when(launch.getMode()).thenReturn(LaunchModeEnum.DEFAULT);
+    when(projectRepository.findById(1L)).thenReturn(Optional.of(project));
 
-		ProjectAttribute projectAttribute = new ProjectAttribute();
-		projectAttribute.setValue("true");
-		Attribute attribute = new Attribute();
-		projectAttribute.setAttribute(attribute);
+    ProjectAttribute projectAttribute = new ProjectAttribute();
+    projectAttribute.setValue("true");
+    Attribute attribute = new Attribute();
+    projectAttribute.setAttribute(attribute);
 
-		when(project.getProjectAttributes()).thenReturn(Sets.newHashSet(projectAttribute));
+    when(project.getProjectAttributes()).thenReturn(Sets.newHashSet(projectAttribute));
 
-		ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER, 1L);
-		ReportPortalUser.ProjectDetails projectDetails = new ReportPortalUser.ProjectDetails(1L, "name", ProjectRole.PROJECT_MANAGER);
-		AnalyzeLaunchRQ analyzeLaunchRQ = new AnalyzeLaunchRQ();
-		analyzeLaunchRQ.setLaunchId(1L);
-		analyzeLaunchRQ.setAnalyzeItemsModes(Lists.newArrayList("TO_INVESTIGATE"));
-		analyzeLaunchRQ.setAnalyzerTypeName("patternAnalyzer");
-		launchPatternAnalysisStrategy.analyze(analyzeLaunchRQ, projectDetails, user);
+    ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER, 1L);
+    ReportPortalUser.ProjectDetails projectDetails = new ReportPortalUser.ProjectDetails(1L, "name",
+        ProjectRole.PROJECT_MANAGER);
+    AnalyzeLaunchRQ analyzeLaunchRQ = new AnalyzeLaunchRQ();
+    analyzeLaunchRQ.setLaunchId(1L);
+    analyzeLaunchRQ.setAnalyzeItemsModes(Lists.newArrayList("TO_INVESTIGATE"));
+    analyzeLaunchRQ.setAnalyzerTypeName("patternAnalyzer");
+    launchPatternAnalysisStrategy.analyze(analyzeLaunchRQ, projectDetails, user);
 
-		verify(patternAnalyzer, times(1)).analyzeTestItems(launch, Sets.newHashSet(AnalyzeItemsMode.TO_INVESTIGATE));
+    verify(launchPatternAnalyzer, times(1)).analyzeLaunch(launch,
+        Sets.newHashSet(AnalyzeItemsMode.TO_INVESTIGATE));
 
-	}
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/configs/ReportPortalClassLoadHelperTest.java b/src/test/java/com/epam/ta/reportportal/core/configs/ReportPortalClassLoadHelperTest.java
index 7ed1a45aa2..b86151e212 100644
--- a/src/test/java/com/epam/ta/reportportal/core/configs/ReportPortalClassLoadHelperTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/configs/ReportPortalClassLoadHelperTest.java
@@ -1,33 +1,32 @@
 package com.epam.ta.reportportal.core.configs;
 
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import org.springframework.core.io.ResourceLoader;
 
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class ReportPortalClassLoadHelperTest {
 
-	private ResourceLoader resourceLoader = mock(ResourceLoader.class);
-	private ReportPortalClassLoadHelper classLoadHelper;
+  private ResourceLoader resourceLoader = mock(ResourceLoader.class);
+  private ReportPortalClassLoadHelper classLoadHelper;
 
-	@Test
-	void initializeTest() {
-		classLoadHelper = new ReportPortalClassLoadHelper();
-		classLoadHelper.initialize();
-		Assertions.assertNotNull(classLoadHelper.getClassLoader());
-	}
+  @Test
+  void initializeTest() {
+    classLoadHelper = new ReportPortalClassLoadHelper();
+    classLoadHelper.initialize();
+    Assertions.assertNotNull(classLoadHelper.getClassLoader());
+  }
 
-	@Test
-	void loadClassTest() throws ClassNotFoundException {
-		classLoadHelper = new ReportPortalClassLoadHelper(resourceLoader);
-		when(resourceLoader.getClassLoader()).thenReturn(this.getClass().getClassLoader());
-		Class<?> clazz = classLoadHelper.loadClass(this.getClass().getCanonicalName());
-		Assertions.assertEquals(this.getClass(), clazz);
-	}
+  @Test
+  void loadClassTest() throws ClassNotFoundException {
+    classLoadHelper = new ReportPortalClassLoadHelper(resourceLoader);
+    when(resourceLoader.getClassLoader()).thenReturn(this.getClass().getClassLoader());
+    Class<?> clazz = classLoadHelper.loadClass(this.getClass().getCanonicalName());
+    Assertions.assertEquals(this.getClass(), clazz);
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/dashboard/impl/CreateDashboardHandlerImplTest.java b/src/test/java/com/epam/ta/reportportal/core/dashboard/impl/CreateDashboardHandlerImplTest.java
index 46c38bc9aa..398175001f 100644
--- a/src/test/java/com/epam/ta/reportportal/core/dashboard/impl/CreateDashboardHandlerImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/dashboard/impl/CreateDashboardHandlerImplTest.java
@@ -16,6 +16,12 @@
 
 package com.epam.ta.reportportal.core.dashboard.impl;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static com.epam.ta.reportportal.util.TestProjectExtractor.extractProjectDetails;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.dao.DashboardRepository;
 import com.epam.ta.reportportal.entity.project.ProjectRole;
@@ -28,36 +34,33 @@
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static com.epam.ta.reportportal.util.TestProjectExtractor.extractProjectDetails;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.Mockito.when;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @ExtendWith(MockitoExtension.class)
 class CreateDashboardHandlerImplTest {
 
-	@Mock
-	private DashboardRepository dashboardRepository;
+  @Mock
+  private DashboardRepository dashboardRepository;
 
-	@InjectMocks
-	private CreateDashboardHandlerImpl handler;
+  @InjectMocks
+  private CreateDashboardHandlerImpl handler;
 
-	@Test
-	void createAlreadyExistDashboard() {
-		CreateDashboardRQ createDashboardRQ = new CreateDashboardRQ();
-		createDashboardRQ.setName("exist");
+  @Test
+  void createAlreadyExistDashboard() {
+    CreateDashboardRQ createDashboardRQ = new CreateDashboardRQ();
+    createDashboardRQ.setName("exist");
 
-		final ReportPortalUser rpUser = getRpUser("owner", UserRole.USER, ProjectRole.MEMBER, 1L);
+    final ReportPortalUser rpUser = getRpUser("owner", UserRole.USER, ProjectRole.MEMBER, 1L);
 
-		when(dashboardRepository.existsByNameAndOwnerAndProjectId("exist", "owner", 1L)).thenReturn(true);
-		final ReportPortalException exception = assertThrows(
-				ReportPortalException.class,
-				() -> handler.createDashboard(extractProjectDetails(rpUser, "test_project"), createDashboardRQ, rpUser)
-		);
-		assertEquals("Resource 'exist' already exists. You couldn't create the duplicate.", exception.getMessage());
-	}
+    when(dashboardRepository.existsByNameAndOwnerAndProjectId("exist", "owner", 1L)).thenReturn(
+        true);
+    final ReportPortalException exception = assertThrows(
+        ReportPortalException.class,
+        () -> handler.createDashboard(extractProjectDetails(rpUser, "test_project"),
+            createDashboardRQ, rpUser)
+    );
+    assertEquals("Resource 'exist' already exists. You couldn't create the duplicate.",
+        exception.getMessage());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/events/MessageBusImplTest.java b/src/test/java/com/epam/ta/reportportal/core/events/MessageBusImplTest.java
index e3c2ec4a8f..d474652b52 100644
--- a/src/test/java/com/epam/ta/reportportal/core/events/MessageBusImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/events/MessageBusImplTest.java
@@ -1,9 +1,6 @@
 package com.epam.ta.reportportal.core.events;
 
 import static com.epam.ta.reportportal.core.configs.rabbit.InternalConfiguration.EXCHANGE_ACTIVITY;
-import static com.epam.ta.reportportal.core.configs.rabbit.InternalConfiguration.EXCHANGE_ATTACHMENT;
-import static com.epam.ta.reportportal.core.configs.rabbit.InternalConfiguration.EXCHANGE_EVENTS;
-import static com.epam.ta.reportportal.core.configs.rabbit.InternalConfiguration.QUEUE_ATTACHMENT_DELETE;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.lenient;
 import static org.mockito.Mockito.mock;
@@ -11,7 +8,6 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import com.epam.ta.reportportal.core.events.attachment.DeleteAttachmentEvent;
 import com.epam.ta.reportportal.entity.activity.Activity;
 import com.epam.ta.reportportal.entity.activity.EventObject;
 import org.junit.jupiter.api.BeforeEach;
@@ -68,14 +64,7 @@ public void whenPublishWithExchange_thenCallConvertAndSend() {
   public void whenPublishWithoutExchange_thenCallConvertSendAndReceive() {
     messageBus.publish(ROUTE, MESSAGE);
 
-    verify(amqpTemplate).convertSendAndReceive(ROUTE, MESSAGE);
-  }
-
-  @Test
-  public void whenBroadcastEvent_thenCallConvertAndSendWithExchangeEvents() {
-    messageBus.broadcastEvent(MESSAGE);
-
-    verify(amqpTemplate).convertAndSend(EXCHANGE_EVENTS, "", MESSAGE);
+    verify(amqpTemplate).convertAndSend(ROUTE, MESSAGE);
   }
 
   @Test
@@ -104,12 +93,4 @@ public void whenPublishActivity_andActivityIsNotNull_andSavedEvent_thenCallConve
     verify(amqpTemplate).convertAndSend(EXCHANGE_ACTIVITY, activityKey, activity);
   }
 
-  @Test
-  public void whenPublishDeleteAttachmentEvent_thenCallConvertAndSendWithAttachmentExchange() {
-    DeleteAttachmentEvent deleteAttachmentEvent = mock(DeleteAttachmentEvent.class);
-    messageBus.publishDeleteAttachmentEvent(deleteAttachmentEvent);
-
-    verify(amqpTemplate).convertAndSend(
-        EXCHANGE_ATTACHMENT, QUEUE_ATTACHMENT_DELETE, deleteAttachmentEvent);
-  }
 }
diff --git a/src/test/java/com/epam/ta/reportportal/core/events/activity/LaunchEventsTest.java b/src/test/java/com/epam/ta/reportportal/core/events/activity/LaunchEventsTest.java
index aeca64ce28..d64974813b 100644
--- a/src/test/java/com/epam/ta/reportportal/core/events/activity/LaunchEventsTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/events/activity/LaunchEventsTest.java
@@ -68,7 +68,7 @@ void finished() {
     launch.setName(name);
     launch.setProjectId(3L);
     launch.setMode(LaunchModeEnum.DEFAULT);
-    final Activity actual = new LaunchFinishedEvent(launch, 1L, "user").toActivity();
+    final Activity actual = new LaunchFinishedEvent(launch, 1L, "user", false).toActivity();
     final Activity expected = getExpectedActivity(EventAction.FINISH, EventPriority.LOW);
     checkActivity(expected, actual);
   }
@@ -88,4 +88,4 @@ void deleted() {
     final Activity expected = getExpectedActivity(EventAction.DELETE, EventPriority.MEDIUM);
     checkActivity(expected, actual);
   }
-}
\ No newline at end of file
+}
diff --git a/src/test/java/com/epam/ta/reportportal/core/events/activity/UserCreatedEventTest.java b/src/test/java/com/epam/ta/reportportal/core/events/activity/UserCreatedEventTest.java
index 46e59c84cd..8467597593 100644
--- a/src/test/java/com/epam/ta/reportportal/core/events/activity/UserCreatedEventTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/events/activity/UserCreatedEventTest.java
@@ -59,7 +59,7 @@ private static UserActivityResource getUser() {
 
   @Test
   void toActivity() {
-    final Activity actual = new UserCreatedEvent(getUser(), 1L, "user").toActivity();
+    final Activity actual = new UserCreatedEvent(getUser(), 1L, "user", false).toActivity();
     final Activity expected = getExpectedActivity();
     checkActivity(expected, actual);
 
diff --git a/src/test/java/com/epam/ta/reportportal/core/events/handler/ComponentHealthCheckTableEventHandlerTest.java b/src/test/java/com/epam/ta/reportportal/core/events/handler/ComponentHealthCheckTableEventHandlerTest.java
index 8c7690a513..4631af88f3 100644
--- a/src/test/java/com/epam/ta/reportportal/core/events/handler/ComponentHealthCheckTableEventHandlerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/events/handler/ComponentHealthCheckTableEventHandlerTest.java
@@ -1,5 +1,15 @@
 package com.epam.ta.reportportal.core.events.handler;
 
+import static com.epam.ta.reportportal.core.widget.content.loader.materialized.handler.MaterializedWidgetStateHandler.REFRESH;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyBoolean;
+import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.querygen.FilterCondition;
 import com.epam.ta.reportportal.core.events.widget.GenerateWidgetViewEvent;
@@ -12,6 +22,10 @@
 import com.epam.ta.reportportal.entity.widget.WidgetType;
 import com.epam.ta.reportportal.ws.converter.builders.WidgetBuilder;
 import com.google.common.collect.ImmutableMap;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.springframework.data.domain.Sort;
@@ -19,93 +33,87 @@
 import org.springframework.util.LinkedMultiValueMap;
 import org.springframework.util.MultiValueMap;
 
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
-
-import static com.epam.ta.reportportal.core.widget.content.loader.materialized.handler.MaterializedWidgetStateHandler.REFRESH;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.Mockito.*;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class ComponentHealthCheckTableEventHandlerTest {
 
-	private final WidgetRepository widgetRepository = mock(WidgetRepository.class);
-	private final BuildFilterStrategy buildFilterStrategy = mock(BuildFilterStrategy.class);
-	private final MaterializedViewNameGenerator materializedViewNameGenerator = mock(MaterializedViewNameGenerator.class);
-	private final Map<WidgetType, BuildFilterStrategy> buildFilterStrategyMapping = ImmutableMap.<WidgetType, BuildFilterStrategy>builder()
-			.put(WidgetType.COMPONENT_HEALTH_CHECK_TABLE, buildFilterStrategy)
-			.build();
-	private ThreadPoolTaskExecutor healthCheckTableExecutor = new ThreadPoolTaskExecutor();
-
-	private final HealthCheckTableGenerator healthCheckTableGenerator = mock(HealthCheckTableGenerator.class);
-	private final Map<WidgetType, ViewGenerator> viewGeneratorMapping = new HashMap<>() {
-		{
-			put(WidgetType.COMPONENT_HEALTH_CHECK_TABLE, healthCheckTableGenerator);
-		}
-	};
-
-	private final GenerateWidgetViewEventHandler generateWidgetViewEventHandler;
-
-	{
-		healthCheckTableExecutor.setWaitForTasksToCompleteOnShutdown(true);
-		healthCheckTableExecutor.setAwaitTerminationSeconds(2);
-		generateWidgetViewEventHandler = new GenerateWidgetViewEventHandler(widgetRepository,
-				buildFilterStrategyMapping,
-				materializedViewNameGenerator,
-				healthCheckTableExecutor,
-				viewGeneratorMapping
-		);
-
-	}
-
-	@BeforeEach
-	public void init() {
-		healthCheckTableExecutor.initialize();
-	}
-
-	@Test
-	void shouldGenerate() {
-		Widget widget = getWidget();
-		when(widgetRepository.findById(anyLong())).thenReturn(Optional.of(widget));
-
-		Map<Filter, Sort> filterSortMap = new HashMap<>();
-		Filter filter = Filter.builder().withTarget(Widget.class).withCondition(FilterCondition.builder().eq("id", "1").build()).build();
-		Sort sort = Sort.unsorted();
-		filterSortMap.put(filter, sort);
-
-		when(buildFilterStrategy.buildFilter(widget)).thenReturn(filterSortMap);
-		when(materializedViewNameGenerator.generate(widget)).thenReturn("widget_1_1");
-
-		MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
-		params.put(REFRESH, Collections.singletonList(Boolean.FALSE.toString()));
-
-		GenerateWidgetViewEvent event = new GenerateWidgetViewEvent(1L, params);
-
-		generateWidgetViewEventHandler.onApplicationEvent(event);
-
-		healthCheckTableExecutor.shutdown();
-
-		verify(healthCheckTableGenerator, times(1)).generate(anyBoolean(),
-				anyString(),
-				any(Widget.class),
-				any(Filter.class),
-				any(Sort.class),
-				any(MultiValueMap.class)
-		);
-
-	}
-
-	private Widget getWidget() {
-
-		Widget widget = new Widget();
-		widget.setId(1L);
-		widget.setWidgetType("componentHealthCheckTable");
-
-		return new WidgetBuilder(widget).addProject(1L).get();
-	}
+  private final WidgetRepository widgetRepository = mock(WidgetRepository.class);
+  private final BuildFilterStrategy buildFilterStrategy = mock(BuildFilterStrategy.class);
+  private final MaterializedViewNameGenerator materializedViewNameGenerator = mock(
+      MaterializedViewNameGenerator.class);
+  private final Map<WidgetType, BuildFilterStrategy> buildFilterStrategyMapping = ImmutableMap.<WidgetType, BuildFilterStrategy>builder()
+      .put(WidgetType.COMPONENT_HEALTH_CHECK_TABLE, buildFilterStrategy)
+      .build();
+  private ThreadPoolTaskExecutor healthCheckTableExecutor = new ThreadPoolTaskExecutor();
+
+  private final HealthCheckTableGenerator healthCheckTableGenerator = mock(
+      HealthCheckTableGenerator.class);
+  private final Map<WidgetType, ViewGenerator> viewGeneratorMapping = new HashMap<>() {
+    {
+      put(WidgetType.COMPONENT_HEALTH_CHECK_TABLE, healthCheckTableGenerator);
+    }
+  };
+
+  private final GenerateWidgetViewEventHandler generateWidgetViewEventHandler;
+
+  {
+    healthCheckTableExecutor.setWaitForTasksToCompleteOnShutdown(true);
+    healthCheckTableExecutor.setAwaitTerminationSeconds(2);
+    generateWidgetViewEventHandler = new GenerateWidgetViewEventHandler(widgetRepository,
+        buildFilterStrategyMapping,
+        materializedViewNameGenerator,
+        healthCheckTableExecutor,
+        viewGeneratorMapping
+    );
+
+  }
+
+  @BeforeEach
+  public void init() {
+    healthCheckTableExecutor.initialize();
+  }
+
+  @Test
+  void shouldGenerate() {
+    Widget widget = getWidget();
+    when(widgetRepository.findById(anyLong())).thenReturn(Optional.of(widget));
+
+    Map<Filter, Sort> filterSortMap = new HashMap<>();
+    Filter filter = Filter.builder().withTarget(Widget.class)
+        .withCondition(FilterCondition.builder().eq("id", "1").build()).build();
+    Sort sort = Sort.unsorted();
+    filterSortMap.put(filter, sort);
+
+    when(buildFilterStrategy.buildFilter(widget)).thenReturn(filterSortMap);
+    when(materializedViewNameGenerator.generate(widget)).thenReturn("widget_1_1");
+
+    MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
+    params.put(REFRESH, Collections.singletonList(Boolean.FALSE.toString()));
+
+    GenerateWidgetViewEvent event = new GenerateWidgetViewEvent(1L, params);
+
+    generateWidgetViewEventHandler.onApplicationEvent(event);
+
+    healthCheckTableExecutor.shutdown();
+
+    verify(healthCheckTableGenerator, times(1)).generate(anyBoolean(),
+        anyString(),
+        any(Widget.class),
+        any(Filter.class),
+        any(Sort.class),
+        any(MultiValueMap.class)
+    );
+
+  }
+
+  private Widget getWidget() {
+
+    Widget widget = new Widget();
+    widget.setId(1L);
+    widget.setWidgetType("componentHealthCheckTable");
+
+    return new WidgetBuilder(widget).addProject(1L).get();
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/events/handler/DefectTypeDeletedHandlerTest.java b/src/test/java/com/epam/ta/reportportal/core/events/handler/DefectTypeDeletedHandlerTest.java
index 5b3ab25130..e8dbcf8f22 100644
--- a/src/test/java/com/epam/ta/reportportal/core/events/handler/DefectTypeDeletedHandlerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/events/handler/DefectTypeDeletedHandlerTest.java
@@ -16,6 +16,15 @@
 
 package com.epam.ta.reportportal.core.events.handler;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.core.analyzer.auto.LogIndexer;
 import com.epam.ta.reportportal.core.analyzer.auto.client.AnalyzerServiceClient;
 import com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerStatusCache;
@@ -31,122 +40,126 @@
 import com.google.common.cache.Cache;
 import com.google.common.cache.CacheBuilder;
 import com.google.common.collect.Sets;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 
-import java.util.Arrays;
-import java.util.List;
-import java.util.Optional;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.Mockito.*;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @ExtendWith(MockitoExtension.class)
 class DefectTypeDeletedHandlerTest {
 
-	@Mock
-	private AnalyzerStatusCache analyzerStatusCache;
-
-	@Mock
-	private AnalyzerServiceClient analyzerServiceClient;
-
-	@Mock
-	private LaunchRepository launchRepository;
-
-	@Mock
-	private LogIndexer logIndexer;
-
-	@Mock
-	private ProjectRepository projectRepository;
-
-	@InjectMocks
-	private DefectTypeDeletedHandler handler;
-
-	@Test
-	void deleteSubTypeOnNotExistProject() {
-		long projectId = 2L;
-
-		when(projectRepository.findById(projectId)).thenReturn(Optional.empty());
-
-		ReportPortalException exception = assertThrows(
-				ReportPortalException.class,
-				() -> handler.handleDefectTypeDeleted(new DefectTypeDeletedEvent(new IssueTypeActivityResource(), 1L, "user", projectId))
-		);
-
-		assertEquals("Project '2' not found. Did you use correct project name?", exception.getMessage());
-	}
-
-	@Test
-	void noClientsTest() {
-		long projectId = 2L;
-
-		when(projectRepository.findById(projectId)).thenReturn(Optional.of(new Project()));
-		when(analyzerServiceClient.hasClients()).thenReturn(false);
-
-		handler.handleDefectTypeDeleted(new DefectTypeDeletedEvent(new IssueTypeActivityResource(), 1L, "user", projectId));
-
-		verifyNoInteractions(logIndexer);
-	}
-
-	@Test
-	void analysisAlreadyRunningTest() {
-		long projectId = 2L;
-
-		when(projectRepository.findById(projectId)).thenReturn(Optional.of(new Project()));
-		when(analyzerServiceClient.hasClients()).thenReturn(true);
-		Cache<Long, Long> cache = CacheBuilder.newBuilder().build();
-		cache.put(2L, projectId);
-		when(analyzerStatusCache.getAnalyzeStatus(AnalyzerStatusCache.AUTO_ANALYZER_KEY)).thenReturn(Optional.of(cache));
-
-		ReportPortalException exception = assertThrows(
-				ReportPortalException.class,
-				() -> handler.handleDefectTypeDeleted(new DefectTypeDeletedEvent(new IssueTypeActivityResource(), 1L, "user", projectId))
-		);
-		assertEquals("Forbidden operation. Index can not be removed until auto-analysis proceeds.", exception.getMessage());
-	}
-
-	@Test
-	void successfullyReindex() {
-		long projectId = 2L;
-
-		when(projectRepository.findById(projectId)).thenReturn(Optional.of(getProjectWithAnalyzerAttributes(projectId)));
-		when(analyzerServiceClient.hasClients()).thenReturn(true);
-		when(analyzerStatusCache.getAnalyzeStatus(AnalyzerStatusCache.AUTO_ANALYZER_KEY)).thenReturn(Optional.of(CacheBuilder.newBuilder().build()));
-		List<Long> launchIds = Arrays.asList(1L, 2L, 3L);
-
-		handler.handleDefectTypeDeleted(new DefectTypeDeletedEvent(new IssueTypeActivityResource(), 1L, "user", projectId));
-
-		verify(logIndexer, times(1)).index(eq(projectId), any(AnalyzerConfig.class));
-	}
-
-	private Project getProjectWithAnalyzerAttributes(Long projectId) {
-		Project project = new Project();
-		project.setProjectAttributes(Sets.newHashSet(
-				getProjectAttribute(project, getAttribute("analyzer.isAutoAnalyzerEnabled"), "false"),
-				getProjectAttribute(project, getAttribute("analyzer.minDocFreq"), "7"),
-				getProjectAttribute(project, getAttribute("analyzer.minTermFreq"), "2"),
-				getProjectAttribute(project, getAttribute("analyzer.minShouldMatch"), "80"),
-				getProjectAttribute(project, getAttribute("analyzer.numberOfLogLines"), "5"),
-				getProjectAttribute(project, getAttribute("analyzer.indexingRunning"), "false")
-		));
-		project.setId(projectId);
-		return project;
-	}
-
-	private ProjectAttribute getProjectAttribute(Project project, Attribute attribute, String value) {
-		return new ProjectAttribute().withProject(project).withAttribute(attribute).withValue(value);
-	}
-
-	private Attribute getAttribute(String name) {
-		Attribute attribute = new Attribute();
-		attribute.setName(name);
-		return attribute;
-	}
+  @Mock
+  private AnalyzerStatusCache analyzerStatusCache;
+
+  @Mock
+  private AnalyzerServiceClient analyzerServiceClient;
+
+  @Mock
+  private LaunchRepository launchRepository;
+
+  @Mock
+  private LogIndexer logIndexer;
+
+  @Mock
+  private ProjectRepository projectRepository;
+
+  @InjectMocks
+  private DefectTypeDeletedHandler handler;
+
+  @Test
+  void deleteSubTypeOnNotExistProject() {
+    long projectId = 2L;
+
+    when(projectRepository.findById(projectId)).thenReturn(Optional.empty());
+
+    ReportPortalException exception = assertThrows(
+        ReportPortalException.class,
+        () -> handler.handleDefectTypeDeleted(
+            new DefectTypeDeletedEvent(new IssueTypeActivityResource(), 1L, "user", projectId))
+    );
+
+    assertEquals("Project '2' not found. Did you use correct project name?",
+        exception.getMessage());
+  }
+
+  @Test
+  void noClientsTest() {
+    long projectId = 2L;
+
+    when(projectRepository.findById(projectId)).thenReturn(Optional.of(new Project()));
+    when(analyzerServiceClient.hasClients()).thenReturn(false);
+
+    handler.handleDefectTypeDeleted(
+        new DefectTypeDeletedEvent(new IssueTypeActivityResource(), 1L, "user", projectId));
+
+    verifyNoInteractions(logIndexer);
+  }
+
+  @Test
+  void analysisAlreadyRunningTest() {
+    long projectId = 2L;
+
+    when(projectRepository.findById(projectId)).thenReturn(Optional.of(new Project()));
+    when(analyzerServiceClient.hasClients()).thenReturn(true);
+    Cache<Long, Long> cache = CacheBuilder.newBuilder().build();
+    cache.put(2L, projectId);
+    when(analyzerStatusCache.getAnalyzeStatus(AnalyzerStatusCache.AUTO_ANALYZER_KEY)).thenReturn(
+        Optional.of(cache));
+
+    ReportPortalException exception = assertThrows(
+        ReportPortalException.class,
+        () -> handler.handleDefectTypeDeleted(
+            new DefectTypeDeletedEvent(new IssueTypeActivityResource(), 1L, "user", projectId))
+    );
+    assertEquals("Forbidden operation. Index can not be removed until auto-analysis proceeds.",
+        exception.getMessage());
+  }
+
+  @Test
+  void successfullyReindex() {
+    long projectId = 2L;
+
+    when(projectRepository.findById(projectId)).thenReturn(
+        Optional.of(getProjectWithAnalyzerAttributes(projectId)));
+    when(analyzerServiceClient.hasClients()).thenReturn(true);
+    when(analyzerStatusCache.getAnalyzeStatus(AnalyzerStatusCache.AUTO_ANALYZER_KEY)).thenReturn(
+        Optional.of(CacheBuilder.newBuilder().build()));
+    List<Long> launchIds = Arrays.asList(1L, 2L, 3L);
+
+    handler.handleDefectTypeDeleted(
+        new DefectTypeDeletedEvent(new IssueTypeActivityResource(), 1L, "user", projectId));
+
+    verify(logIndexer, times(1)).index(eq(projectId), any(AnalyzerConfig.class));
+  }
+
+  private Project getProjectWithAnalyzerAttributes(Long projectId) {
+    Project project = new Project();
+    project.setProjectAttributes(Sets.newHashSet(
+        getProjectAttribute(project, getAttribute("analyzer.isAutoAnalyzerEnabled"), "false"),
+        getProjectAttribute(project, getAttribute("analyzer.minDocFreq"), "7"),
+        getProjectAttribute(project, getAttribute("analyzer.minTermFreq"), "2"),
+        getProjectAttribute(project, getAttribute("analyzer.minShouldMatch"), "80"),
+        getProjectAttribute(project, getAttribute("analyzer.numberOfLogLines"), "5"),
+        getProjectAttribute(project, getAttribute("analyzer.indexingRunning"), "false")
+    ));
+    project.setId(projectId);
+    return project;
+  }
+
+  private ProjectAttribute getProjectAttribute(Project project, Attribute attribute, String value) {
+    return new ProjectAttribute().withProject(project).withAttribute(attribute).withValue(value);
+  }
+
+  private Attribute getAttribute(String name) {
+    Attribute attribute = new Attribute();
+    attribute.setName(name);
+    return attribute;
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/events/handler/item/TestItemIndexRunnerTest.java b/src/test/java/com/epam/ta/reportportal/core/events/handler/item/TestItemIndexRunnerTest.java
index 347dc079d9..6407c8e38e 100644
--- a/src/test/java/com/epam/ta/reportportal/core/events/handler/item/TestItemIndexRunnerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/events/handler/item/TestItemIndexRunnerTest.java
@@ -16,46 +16,48 @@
 
 package com.epam.ta.reportportal.core.events.handler.item;
 
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
 import com.epam.ta.reportportal.core.analyzer.auto.LogIndexer;
-import com.epam.ta.reportportal.core.events.activity.item.ItemFinishedEvent;
+import com.epam.ta.reportportal.core.events.activity.item.IssueResolvedEvent;
 import com.epam.ta.reportportal.entity.enums.ProjectAttributeEnum;
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
 import com.google.common.collect.ImmutableMap;
-import org.junit.jupiter.api.Test;
-
 import java.util.List;
 import java.util.Map;
-
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.Mockito.*;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class TestItemIndexRunnerTest {
 
-	private final LogIndexer logIndexer = mock(LogIndexer.class);
+  private final LogIndexer logIndexer = mock(LogIndexer.class);
 
-	private final TestItemIndexRunner runner = new TestItemIndexRunner(logIndexer);
+  private final TestItemIndexRunner runner = new TestItemIndexRunner(logIndexer);
 
-	@Test
-	void shouldInvokeIndexer() {
+  @Test
+  void shouldInvokeIndexer() {
 
-		final ItemFinishedEvent event = new ItemFinishedEvent(3L, 2L, 1L);
+    final IssueResolvedEvent event = new IssueResolvedEvent(3L, 2L, 1L);
 
-		final Map<String, String> projectConfig = ImmutableMap.<String, String>builder()
-				.put(ProjectAttributeEnum.AUTO_ANALYZER_ENABLED.getAttribute(), "false")
-				.build();
+    final Map<String, String> projectConfig = ImmutableMap.<String, String>builder()
+        .put(ProjectAttributeEnum.AUTO_ANALYZER_ENABLED.getAttribute(), "false")
+        .build();
 
-		final List<Long> itemIds = List.of(event.getItemId());
+    final List<Long> itemIds = List.of(event.getItemId());
 
-		runner.handle(event, projectConfig);
+    runner.handle(event, projectConfig);
 
-		verify(logIndexer, times(1)).indexItemsLogs(eq(event.getProjectId()),
-				eq(event.getLaunchId()),
-				eq(itemIds),
-				any(AnalyzerConfig.class)
-		);
-	}
+    verify(logIndexer, times(1)).indexItemsLogs(eq(event.getProjectId()),
+        eq(event.getLaunchId()),
+        eq(itemIds),
+        any(AnalyzerConfig.class)
+    );
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/events/handler/item/TestItemPatternAnalysisRunnerTest.java b/src/test/java/com/epam/ta/reportportal/core/events/handler/item/TestItemPatternAnalysisRunnerTest.java
new file mode 100644
index 0000000000..0871cd40e6
--- /dev/null
+++ b/src/test/java/com/epam/ta/reportportal/core/events/handler/item/TestItemPatternAnalysisRunnerTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2023 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.epam.ta.reportportal.core.events.handler.item;
+
+import static com.epam.ta.reportportal.core.events.handler.item.TestItemPatternAnalysisRunner.IMMEDIATE_PATTERN_ANALYSIS;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
+
+import com.epam.ta.reportportal.core.analyzer.pattern.handler.proxy.ItemsPatternAnalyzeProducer;
+import com.epam.ta.reportportal.core.events.activity.item.TestItemFinishedEvent;
+import com.epam.ta.reportportal.entity.ItemAttribute;
+import com.epam.ta.reportportal.entity.item.TestItem;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import java.util.Collections;
+import org.junit.jupiter.api.Test;
+
+/**
+ * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
+ */
+public class TestItemPatternAnalysisRunnerTest {
+
+  private final ItemsPatternAnalyzeProducer itemsPatternAnalyzer = mock(
+      ItemsPatternAnalyzeProducer.class);
+  private final TestItemPatternAnalysisRunner runner = new TestItemPatternAnalysisRunner(
+      itemsPatternAnalyzer);
+
+  @Test
+  void shouldNotInvokePatternAnalyzer() {
+    TestItem testItem = new TestItem();
+    TestItemFinishedEvent event = new TestItemFinishedEvent(testItem, 1L);
+    runner.handle(event, Collections.emptyMap());
+    verifyNoInteractions(itemsPatternAnalyzer);
+  }
+
+  @Test
+  void shouldNotInvokeFalseFlagPatternAnalyzer() {
+    TestItem testItem = new TestItem();
+    testItem.setItemId(1L);
+    testItem.setLaunchId(1L);
+    testItem.setAttributes(
+        Sets.newHashSet(new ItemAttribute(IMMEDIATE_PATTERN_ANALYSIS, "false", true)));
+    TestItemFinishedEvent event = new TestItemFinishedEvent(testItem, 1L);
+    runner.handle(event, Collections.emptyMap());
+    verifyNoInteractions(itemsPatternAnalyzer);
+  }
+
+  @Test
+  void shouldInvokePatternAnalyzer() {
+    TestItem testItem = new TestItem();
+    testItem.setItemId(1L);
+    testItem.setLaunchId(1L);
+    testItem.setAttributes(
+        Sets.newHashSet(new ItemAttribute(IMMEDIATE_PATTERN_ANALYSIS, "true", true)));
+    TestItemFinishedEvent event = new TestItemFinishedEvent(testItem, 1L);
+    runner.handle(event, Collections.emptyMap());
+
+    verify(itemsPatternAnalyzer, times(1)).analyze(1L, 1L, Lists.newArrayList(1L));
+  }
+
+}
diff --git a/src/test/java/com/epam/ta/reportportal/core/events/handler/item/TestItemUniqueErrorAnalysisRunnerTest.java b/src/test/java/com/epam/ta/reportportal/core/events/handler/item/TestItemUniqueErrorAnalysisRunnerTest.java
index 30c224af04..82d0383443 100644
--- a/src/test/java/com/epam/ta/reportportal/core/events/handler/item/TestItemUniqueErrorAnalysisRunnerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/events/handler/item/TestItemUniqueErrorAnalysisRunnerTest.java
@@ -16,69 +16,70 @@
 
 package com.epam.ta.reportportal.core.events.handler.item;
 
-import com.epam.ta.reportportal.core.events.activity.item.ItemFinishedEvent;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import com.epam.ta.reportportal.core.events.activity.item.IssueResolvedEvent;
 import com.epam.ta.reportportal.core.launch.cluster.ClusterGenerator;
 import com.epam.ta.reportportal.core.launch.cluster.config.GenerateClustersConfig;
 import com.epam.ta.reportportal.entity.enums.ProjectAttributeEnum;
 import com.google.common.collect.ImmutableMap;
+import java.util.Map;
 import org.junit.jupiter.api.Test;
 import org.mockito.ArgumentCaptor;
-import org.springframework.context.ApplicationEventPublisher;
-
-import java.util.Map;
-
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.*;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class TestItemUniqueErrorAnalysisRunnerTest {
 
-	private final ClusterGenerator clusterGenerator = mock(ClusterGenerator.class);
-	private final ApplicationEventPublisher eventPublisher = mock(ApplicationEventPublisher.class);
-
-	private final TestItemUniqueErrorAnalysisRunner runner = new TestItemUniqueErrorAnalysisRunner(clusterGenerator, eventPublisher);
+  private final ClusterGenerator clusterGenerator = mock(ClusterGenerator.class);
+  private final TestItemUniqueErrorAnalysisRunner runner = new TestItemUniqueErrorAnalysisRunner(
+      clusterGenerator);
 
-	@Test
-	void shouldAnalyzeWhenEnabled() {
+  @Test
+  void shouldAnalyzeWhenEnabled() {
 
-		final ItemFinishedEvent event = new ItemFinishedEvent(3L, 2L, 1L);
+    final IssueResolvedEvent event = new IssueResolvedEvent(3L, 2L, 1L);
 
-		final Map<String, String> projectConfig = ImmutableMap.<String, String>builder()
-				.put(ProjectAttributeEnum.AUTO_UNIQUE_ERROR_ANALYZER_ENABLED.getAttribute(), "true")
-				.put(ProjectAttributeEnum.UNIQUE_ERROR_ANALYZER_REMOVE_NUMBERS.getAttribute(), "true")
-				.build();
+    final Map<String, String> projectConfig = ImmutableMap.<String, String>builder()
+        .put(ProjectAttributeEnum.AUTO_UNIQUE_ERROR_ANALYZER_ENABLED.getAttribute(), "true")
+        .put(ProjectAttributeEnum.UNIQUE_ERROR_ANALYZER_REMOVE_NUMBERS.getAttribute(), "true")
+        .build();
 
-		runner.handle(event, projectConfig);
+    runner.handle(event, projectConfig);
 
-		final ArgumentCaptor<GenerateClustersConfig> configArgumentCaptor = ArgumentCaptor.forClass(GenerateClustersConfig.class);
-		verify(clusterGenerator, times(1)).generate(configArgumentCaptor.capture());
+    final ArgumentCaptor<GenerateClustersConfig> configArgumentCaptor = ArgumentCaptor.forClass(
+        GenerateClustersConfig.class);
+    verify(clusterGenerator, times(1)).generate(configArgumentCaptor.capture());
 
-		final GenerateClustersConfig config = configArgumentCaptor.getValue();
+    final GenerateClustersConfig config = configArgumentCaptor.getValue();
 
-		assertEquals(event.getLaunchId(), config.getEntityContext().getLaunchId());
-		assertEquals(event.getProjectId(), config.getEntityContext().getProjectId());
-		assertEquals(event.getItemId(), config.getEntityContext().getItemIds().get(0));
-		assertTrue(config.isForUpdate());
-		assertTrue(config.isCleanNumbers());
-	}
+    assertEquals(event.getLaunchId(), config.getEntityContext().getLaunchId());
+    assertEquals(event.getProjectId(), config.getEntityContext().getProjectId());
+    assertEquals(event.getItemId(), config.getEntityContext().getItemIds().get(0));
+    assertTrue(config.isForUpdate());
+    assertTrue(config.isCleanNumbers());
+  }
 
-	@Test
-	void shouldNotAnalyzeWhenDisabled() {
+  @Test
+  void shouldNotAnalyzeWhenDisabled() {
 
-		final ItemFinishedEvent event = new ItemFinishedEvent(3L, 2L, 1L);
+    final IssueResolvedEvent event = new IssueResolvedEvent(3L, 2L, 1L);
 
-		final Map<String, String> projectConfig = ImmutableMap.<String, String>builder()
-				.put(ProjectAttributeEnum.AUTO_UNIQUE_ERROR_ANALYZER_ENABLED.getAttribute(), "false")
-				.put(ProjectAttributeEnum.UNIQUE_ERROR_ANALYZER_REMOVE_NUMBERS.getAttribute(), "true")
-				.build();
+    final Map<String, String> projectConfig = ImmutableMap.<String, String>builder()
+        .put(ProjectAttributeEnum.AUTO_UNIQUE_ERROR_ANALYZER_ENABLED.getAttribute(), "false")
+        .put(ProjectAttributeEnum.UNIQUE_ERROR_ANALYZER_REMOVE_NUMBERS.getAttribute(), "true")
+        .build();
 
-		runner.handle(event, projectConfig);
+    runner.handle(event, projectConfig);
 
-		verify(clusterGenerator, times(0)).generate(any(GenerateClustersConfig.class));
+    verify(clusterGenerator, times(0)).generate(any(GenerateClustersConfig.class));
 
-	}
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchAnalysisFinishEventPublisherTest.java b/src/test/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchAnalysisFinishEventPublisherTest.java
index 4ecb50e733..5236481437 100644
--- a/src/test/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchAnalysisFinishEventPublisherTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchAnalysisFinishEventPublisherTest.java
@@ -16,6 +16,12 @@
 
 package com.epam.ta.reportportal.core.events.handler.launch;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.events.activity.LaunchFinishedEvent;
 import com.epam.ta.reportportal.core.launch.impl.LaunchTestUtil;
@@ -26,39 +32,36 @@
 import com.epam.ta.reportportal.entity.project.ProjectRole;
 import com.epam.ta.reportportal.entity.user.UserRole;
 import com.google.common.collect.ImmutableMap;
+import java.util.Map;
 import org.junit.jupiter.api.Test;
 import org.springframework.context.ApplicationEventPublisher;
 
-import java.util.Map;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.*;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class LaunchAnalysisFinishEventPublisherTest {
 
-	private final ApplicationEventPublisher eventPublisher = mock(ApplicationEventPublisher.class);
+  private final ApplicationEventPublisher eventPublisher = mock(ApplicationEventPublisher.class);
 
-	private final LaunchAnalysisFinishEventPublisher publisher = new LaunchAnalysisFinishEventPublisher(eventPublisher);
+  private final LaunchAnalysisFinishEventPublisher publisher = new LaunchAnalysisFinishEventPublisher(
+      eventPublisher);
 
-	@Test
-	void shouldSendEvent() {
+  @Test
+  void shouldSendEvent() {
 
-		final Launch launch = LaunchTestUtil.getLaunch(StatusEnum.FAILED, LaunchModeEnum.DEFAULT).get();
-		final ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, launch.getProjectId());
-		final LaunchFinishedEvent event = new LaunchFinishedEvent(launch, user, "baseUrl");
+    final Launch launch = LaunchTestUtil.getLaunch(StatusEnum.FAILED, LaunchModeEnum.DEFAULT).get();
+    final ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER,
+        launch.getProjectId());
+    final LaunchFinishedEvent event = new LaunchFinishedEvent(launch, user, "baseUrl");
 
-		final Map<String, String> projectConfig = ImmutableMap.<String, String>builder()
-				.put(ProjectAttributeEnum.AUTO_ANALYZER_ENABLED.getAttribute(), "true")
-				.build();
+    final Map<String, String> projectConfig = ImmutableMap.<String, String>builder()
+        .put(ProjectAttributeEnum.AUTO_ANALYZER_ENABLED.getAttribute(), "true")
+        .build();
 
-		publisher.handle(event, projectConfig);
+    publisher.handle(event, projectConfig);
 
-		verify(eventPublisher, times(1)).publishEvent(any());
+    verify(eventPublisher, times(1)).publishEvent(any());
 
-	}
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchAutoAnalysisRunnerTest.java b/src/test/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchAutoAnalysisRunnerTest.java
index 58fcc9d12f..3e1cc48188 100644
--- a/src/test/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchAutoAnalysisRunnerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchAutoAnalysisRunnerTest.java
@@ -16,6 +16,12 @@
 
 package com.epam.ta.reportportal.core.events.handler.launch;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.analyzer.auto.starter.LaunchAutoAnalysisStarter;
 import com.epam.ta.reportportal.core.analyzer.config.StartLaunchAutoAnalysisConfig;
@@ -28,38 +34,34 @@
 import com.epam.ta.reportportal.entity.project.ProjectRole;
 import com.epam.ta.reportportal.entity.user.UserRole;
 import com.google.common.collect.ImmutableMap;
-import org.junit.jupiter.api.Test;
-
 import java.util.Map;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.*;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class LaunchAutoAnalysisRunnerTest {
 
-	private final LaunchAutoAnalysisStarter starter = mock(LaunchAutoAnalysisStarter.class);
+  private final LaunchAutoAnalysisStarter starter = mock(LaunchAutoAnalysisStarter.class);
 
-	private final LaunchAutoAnalysisRunner runner = new LaunchAutoAnalysisRunner(starter);
+  private final LaunchAutoAnalysisRunner runner = new LaunchAutoAnalysisRunner(starter);
 
-	@Test
-	void shouldAnalyzeWhenEnabled() {
+  @Test
+  void shouldAnalyzeWhenEnabled() {
 
-		final Launch launch = LaunchTestUtil.getLaunch(StatusEnum.FAILED, LaunchModeEnum.DEFAULT).get();
-		final ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, launch.getProjectId());
-		final LaunchFinishedEvent event = new LaunchFinishedEvent(launch, user, "baseUrl");
+    final Launch launch = LaunchTestUtil.getLaunch(StatusEnum.FAILED, LaunchModeEnum.DEFAULT).get();
+    final ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER,
+        launch.getProjectId());
+    final LaunchFinishedEvent event = new LaunchFinishedEvent(launch, user, "baseUrl");
 
-		final Map<String, String> projectConfig = ImmutableMap.<String, String>builder()
-				.put(ProjectAttributeEnum.AUTO_ANALYZER_ENABLED.getAttribute(), "true")
-				.build();
+    final Map<String, String> projectConfig = ImmutableMap.<String, String>builder()
+        .put(ProjectAttributeEnum.AUTO_ANALYZER_ENABLED.getAttribute(), "true")
+        .build();
 
-		runner.handle(event, projectConfig);
+    runner.handle(event, projectConfig);
 
-		verify(starter, times(1)).start(any(StartLaunchAutoAnalysisConfig.class));
+    verify(starter, times(1)).start(any(StartLaunchAutoAnalysisConfig.class));
 
-	}
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchNotificationRunnerTest.java b/src/test/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchNotificationRunnerTest.java
index 6cbe50e121..f1f94dcec9 100644
--- a/src/test/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchNotificationRunnerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchNotificationRunnerTest.java
@@ -16,6 +16,13 @@
 
 package com.epam.ta.reportportal.core.events.handler.launch;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.events.activity.LaunchFinishedEvent;
 import com.epam.ta.reportportal.core.events.handler.util.LaunchFinishedTestUtils;
@@ -36,86 +43,86 @@
 import com.epam.ta.reportportal.util.email.EmailService;
 import com.epam.ta.reportportal.util.email.MailServiceFactory;
 import com.google.common.collect.ImmutableMap;
-import org.junit.jupiter.api.Test;
-
 import java.util.Map;
 import java.util.Optional;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.*;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class LaunchNotificationRunnerTest {
 
-	private final GetProjectHandler getProjectHandler = mock(GetProjectHandler.class);
-	private final GetLaunchHandler getLaunchHandler = mock(GetLaunchHandler.class);
-	private final GetIntegrationHandler getIntegrationHandler = mock(GetIntegrationHandler.class);
-	private final MailServiceFactory mailServiceFactory = mock(MailServiceFactory.class);
-	private final UserRepository userRepository = mock(UserRepository.class);
+  private final GetProjectHandler getProjectHandler = mock(GetProjectHandler.class);
+  private final GetLaunchHandler getLaunchHandler = mock(GetLaunchHandler.class);
+  private final GetIntegrationHandler getIntegrationHandler = mock(GetIntegrationHandler.class);
+  private final MailServiceFactory mailServiceFactory = mock(MailServiceFactory.class);
+  private final UserRepository userRepository = mock(UserRepository.class);
 
-	private Integration emailIntegration = mock(Integration.class);
+  private Integration emailIntegration = mock(Integration.class);
 
-	private EmailService emailService = mock(EmailService.class);
+  private EmailService emailService = mock(EmailService.class);
 
-	private final LaunchNotificationRunner runner = new LaunchNotificationRunner(getProjectHandler,
-			getLaunchHandler,
-			getIntegrationHandler,
-			mailServiceFactory,
-			userRepository
-	);
+  private final LaunchNotificationRunner runner = new LaunchNotificationRunner(getProjectHandler,
+      getLaunchHandler,
+      getIntegrationHandler,
+      mailServiceFactory,
+      userRepository
+  );
 
-	@Test
-	void shouldNotSendWhenNotificationsDisabled() {
+  @Test
+  void shouldNotSendWhenNotificationsDisabled() {
 
-		final Launch launch = LaunchTestUtil.getLaunch(StatusEnum.FAILED, LaunchModeEnum.DEFAULT).get();
-		final ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, launch.getProjectId());
-		final LaunchFinishedEvent event = new LaunchFinishedEvent(launch, user, "baseUrl");
+    final Launch launch = LaunchTestUtil.getLaunch(StatusEnum.FAILED, LaunchModeEnum.DEFAULT).get();
+    final ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER,
+        launch.getProjectId());
+    final LaunchFinishedEvent event = new LaunchFinishedEvent(launch, user, "baseUrl");
 
-		final Map<String, String> mapping = ImmutableMap.<String, String>builder()
-				.put(ProjectAttributeEnum.NOTIFICATIONS_ENABLED.getAttribute(), "false")
-				.build();
+    final Map<String, String> mapping = ImmutableMap.<String, String>builder()
+        .put(ProjectAttributeEnum.NOTIFICATIONS_ENABLED.getAttribute(), "false")
+        .build();
 
-		runner.handle(event, mapping);
+    runner.handle(event, mapping);
 
-		verify(getIntegrationHandler, times(0)).getEnabledByProjectIdOrGlobalAndIntegrationGroup(event.getProjectId(),
-				IntegrationGroupEnum.NOTIFICATION
-		);
+    verify(getIntegrationHandler, times(0)).getEnabledByProjectIdOrGlobalAndIntegrationGroup(
+        event.getProjectId(),
+        IntegrationGroupEnum.NOTIFICATION
+    );
 
-	}
+  }
 
-	@Test
-	void shouldSendWhenNotificationsEnabled() {
+  @Test
+  void shouldSendWhenNotificationsEnabled() {
 
-		final Launch launch = LaunchTestUtil.getLaunch(StatusEnum.FAILED, LaunchModeEnum.DEFAULT).get();
-		launch.setName("name1");
-		final ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, launch.getProjectId());
-		final LaunchFinishedEvent event = new LaunchFinishedEvent(launch, user, "baseUrl");
+    final Launch launch = LaunchTestUtil.getLaunch(StatusEnum.FAILED, LaunchModeEnum.DEFAULT).get();
+    launch.setName("name1");
+    final ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER,
+        launch.getProjectId());
+    final LaunchFinishedEvent event = new LaunchFinishedEvent(launch, user, "baseUrl");
 
-		final Map<String, String> mapping = ImmutableMap.<String, String>builder()
-				.put(ProjectAttributeEnum.NOTIFICATIONS_ENABLED.getAttribute(), "true")
-				.build();
+    final Map<String, String> mapping = ImmutableMap.<String, String>builder()
+        .put(ProjectAttributeEnum.NOTIFICATIONS_ENABLED.getAttribute(), "true")
+        .build();
 
-		final Project project = new Project();
-		project.setId(1L);
-		project.setSenderCases(LaunchFinishedTestUtils.getSenderCases());
+    final Project project = new Project();
+    project.setId(1L);
+    project.setSenderCases(LaunchFinishedTestUtils.getSenderCases());
 
-		when(getIntegrationHandler.getEnabledByProjectIdOrGlobalAndIntegrationGroup(event.getProjectId(),
-				IntegrationGroupEnum.NOTIFICATION
-		)).thenReturn(Optional.ofNullable(emailIntegration));
+    when(
+        getIntegrationHandler.getEnabledByProjectIdOrGlobalAndIntegrationGroup(event.getProjectId(),
+            IntegrationGroupEnum.NOTIFICATION
+        )).thenReturn(Optional.ofNullable(emailIntegration));
 
-		when(userRepository.findLoginById(any())).thenReturn(Optional.of("owner"));
-		when(mailServiceFactory.getDefaultEmailService(emailIntegration)).thenReturn(Optional.ofNullable(emailService));
+    when(userRepository.findLoginById(any())).thenReturn(Optional.of("owner"));
+    when(mailServiceFactory.getDefaultEmailService(emailIntegration)).thenReturn(
+        Optional.ofNullable(emailService));
 
-		when(getLaunchHandler.get(event.getId())).thenReturn(launch);
-		when(getProjectHandler.get(event.getProjectId())).thenReturn(project);
-		when(getLaunchHandler.hasItemsWithIssues(launch)).thenReturn(Boolean.TRUE);
+    when(getLaunchHandler.get(event.getId())).thenReturn(launch);
+    when(getProjectHandler.get(event.getProjectId())).thenReturn(project);
+    when(getLaunchHandler.hasItemsWithIssues(launch)).thenReturn(Boolean.TRUE);
 
-		runner.handle(event, mapping);
-		verify(emailService, times(2)).sendLaunchFinishNotification(any(), any(), any(), any());
+    runner.handle(event, mapping);
+    verify(emailService, times(2)).sendLaunchFinishNotification(any(), any(), any(), any());
 
-	}
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchPatternAnalysisRunnerTest.java b/src/test/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchPatternAnalysisRunnerTest.java
index 3e72682cf3..6666c0f352 100644
--- a/src/test/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchPatternAnalysisRunnerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchPatternAnalysisRunnerTest.java
@@ -16,9 +16,15 @@
 
 package com.epam.ta.reportportal.core.events.handler.launch;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.analyzer.auto.strategy.analyze.AnalyzeItemsMode;
-import com.epam.ta.reportportal.core.analyzer.pattern.PatternAnalyzer;
+import com.epam.ta.reportportal.core.analyzer.pattern.service.LaunchPatternAnalyzer;
 import com.epam.ta.reportportal.core.events.activity.LaunchFinishedEvent;
 import com.epam.ta.reportportal.core.launch.GetLaunchHandler;
 import com.epam.ta.reportportal.core.launch.impl.LaunchTestUtil;
@@ -29,57 +35,59 @@
 import com.epam.ta.reportportal.entity.project.ProjectRole;
 import com.epam.ta.reportportal.entity.user.UserRole;
 import com.google.common.collect.ImmutableMap;
-import org.junit.jupiter.api.Test;
-
+import com.google.common.collect.Sets;
 import java.util.Collections;
 import java.util.Map;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static org.mockito.Mockito.*;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class LaunchPatternAnalysisRunnerTest {
 
-	private final GetLaunchHandler getLaunchHandler = mock(GetLaunchHandler.class);
-	private final PatternAnalyzer patternAnalyzer = mock(PatternAnalyzer.class);
+  private final GetLaunchHandler getLaunchHandler = mock(GetLaunchHandler.class);
+  private final LaunchPatternAnalyzer launchPatternAnalyzer = mock(LaunchPatternAnalyzer.class);
 
-	private final LaunchPatternAnalysisRunner runner = new LaunchPatternAnalysisRunner(getLaunchHandler, patternAnalyzer);
+  private final LaunchPatternAnalysisRunner runner = new LaunchPatternAnalysisRunner(
+      getLaunchHandler, launchPatternAnalyzer);
 
-	@Test
-	public void shouldAnalyzeWhenEnabled() {
+  @Test
+  public void shouldAnalyzeWhenEnabled() {
 
-		final Launch launch = LaunchTestUtil.getLaunch(StatusEnum.FAILED, LaunchModeEnum.DEFAULT).get();
-		final ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, launch.getProjectId());
-		final LaunchFinishedEvent event = new LaunchFinishedEvent(launch, user, "baseUrl");
+    final Launch launch = LaunchTestUtil.getLaunch(StatusEnum.FAILED, LaunchModeEnum.DEFAULT).get();
+    final ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER,
+        launch.getProjectId());
+    final LaunchFinishedEvent event = new LaunchFinishedEvent(launch, user, "baseUrl");
 
-		final Map<String, String> mapping = ImmutableMap.<String, String>builder()
-				.put(ProjectAttributeEnum.AUTO_PATTERN_ANALYZER_ENABLED.getAttribute(), "true")
-				.build();
+    final Map<String, String> mapping = ImmutableMap.<String, String>builder()
+        .put(ProjectAttributeEnum.AUTO_PATTERN_ANALYZER_ENABLED.getAttribute(), "true")
+        .build();
 
-		when(getLaunchHandler.get(event.getId())).thenReturn(launch);
-		runner.handle(event, mapping);
+    when(getLaunchHandler.get(event.getId())).thenReturn(launch);
+    runner.handle(event, mapping);
 
-		verify(patternAnalyzer, times(1)).analyzeTestItems(launch, Collections.singleton(AnalyzeItemsMode.TO_INVESTIGATE));
+    verify(launchPatternAnalyzer, times(1)).analyzeLaunch(launch,
+        Sets.newHashSet(AnalyzeItemsMode.TO_INVESTIGATE, AnalyzeItemsMode.IGNORE_IMMEDIATE));
 
-	}
+  }
 
-	@Test
-	public void shouldNotAnalyzeWhenDisabled() {
+  @Test
+  public void shouldNotAnalyzeWhenDisabled() {
 
-		final Launch launch = LaunchTestUtil.getLaunch(StatusEnum.FAILED, LaunchModeEnum.DEFAULT).get();
-		final ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, launch.getProjectId());
-		final LaunchFinishedEvent event = new LaunchFinishedEvent(launch, user, "baseUrl");
+    final Launch launch = LaunchTestUtil.getLaunch(StatusEnum.FAILED, LaunchModeEnum.DEFAULT).get();
+    final ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER,
+        launch.getProjectId());
+    final LaunchFinishedEvent event = new LaunchFinishedEvent(launch, user, "baseUrl");
 
-		final Map<String, String> mapping = ImmutableMap.<String, String>builder()
-				.put(ProjectAttributeEnum.AUTO_PATTERN_ANALYZER_ENABLED.getAttribute(), "false")
-				.build();
+    final Map<String, String> mapping = ImmutableMap.<String, String>builder()
+        .put(ProjectAttributeEnum.AUTO_PATTERN_ANALYZER_ENABLED.getAttribute(), "false")
+        .build();
 
-		runner.handle(event, mapping);
+    runner.handle(event, mapping);
 
-		verify(getLaunchHandler, times(0)).get(event.getId());
-		verify(patternAnalyzer, times(0)).analyzeTestItems(launch, Collections.singleton(AnalyzeItemsMode.TO_INVESTIGATE));
+    verify(getLaunchHandler, times(0)).get(event.getId());
+    verify(launchPatternAnalyzer, times(0)).analyzeLaunch(launch,
+        Collections.singleton(AnalyzeItemsMode.TO_INVESTIGATE));
 
-	}
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchUniqueErrorAnalysisRunnerTest.java b/src/test/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchUniqueErrorAnalysisRunnerTest.java
index d0b367bb90..4f2fa087b9 100644
--- a/src/test/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchUniqueErrorAnalysisRunnerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/events/handler/launch/LaunchUniqueErrorAnalysisRunnerTest.java
@@ -16,6 +16,14 @@
 
 package com.epam.ta.reportportal.core.events.handler.launch;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyMap;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.events.activity.LaunchFinishedEvent;
 import com.epam.ta.reportportal.core.launch.cluster.UniqueErrorAnalysisStarter;
@@ -28,63 +36,62 @@
 import com.epam.ta.reportportal.entity.project.ProjectRole;
 import com.epam.ta.reportportal.entity.user.UserRole;
 import com.google.common.collect.ImmutableMap;
+import java.util.Map;
 import org.junit.jupiter.api.Test;
 import org.mockito.ArgumentCaptor;
 
-import java.util.Map;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.mockito.Mockito.*;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class LaunchUniqueErrorAnalysisRunnerTest {
 
-	private final UniqueErrorAnalysisStarter starter = mock(UniqueErrorAnalysisStarter.class);
+  private final UniqueErrorAnalysisStarter starter = mock(UniqueErrorAnalysisStarter.class);
 
-	private final LaunchUniqueErrorAnalysisRunner runner = new LaunchUniqueErrorAnalysisRunner(starter);
+  private final LaunchUniqueErrorAnalysisRunner runner = new LaunchUniqueErrorAnalysisRunner(
+      starter);
 
-	@Test
-	void shouldStartWhenEnabled() {
+  @Test
+  void shouldStartWhenEnabled() {
 
-		final Launch launch = LaunchTestUtil.getLaunch(StatusEnum.FAILED, LaunchModeEnum.DEFAULT).get();
-		final ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, launch.getProjectId());
-		final LaunchFinishedEvent event = new LaunchFinishedEvent(launch, user, "baseUrl");
+    final Launch launch = LaunchTestUtil.getLaunch(StatusEnum.FAILED, LaunchModeEnum.DEFAULT).get();
+    final ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER,
+        launch.getProjectId());
+    final LaunchFinishedEvent event = new LaunchFinishedEvent(launch, user, "baseUrl");
 
-		final Map<String, String> projectConfig = ImmutableMap.<String, String>builder()
-				.put(ProjectAttributeEnum.AUTO_UNIQUE_ERROR_ANALYZER_ENABLED.getAttribute(), "true")
-				.put(ProjectAttributeEnum.UNIQUE_ERROR_ANALYZER_REMOVE_NUMBERS.getAttribute(), "true")
-				.build();
+    final Map<String, String> projectConfig = ImmutableMap.<String, String>builder()
+        .put(ProjectAttributeEnum.AUTO_UNIQUE_ERROR_ANALYZER_ENABLED.getAttribute(), "true")
+        .put(ProjectAttributeEnum.UNIQUE_ERROR_ANALYZER_REMOVE_NUMBERS.getAttribute(), "true")
+        .build();
 
-		runner.handle(event, projectConfig);
+    runner.handle(event, projectConfig);
 
-		final ArgumentCaptor<ClusterEntityContext> entityContextCaptor = ArgumentCaptor.forClass(ClusterEntityContext.class);
-		verify(starter, times(1)).start(entityContextCaptor.capture(), anyMap());
+    final ArgumentCaptor<ClusterEntityContext> entityContextCaptor = ArgumentCaptor.forClass(
+        ClusterEntityContext.class);
+    verify(starter, times(1)).start(entityContextCaptor.capture(), anyMap());
 
-		final ClusterEntityContext entityContext = entityContextCaptor.getValue();
+    final ClusterEntityContext entityContext = entityContextCaptor.getValue();
 
-		assertEquals(event.getId(), entityContext.getLaunchId());
-		assertEquals(event.getProjectId(), entityContext.getProjectId());
-	}
+    assertEquals(event.getId(), entityContext.getLaunchId());
+    assertEquals(event.getProjectId(), entityContext.getProjectId());
+  }
 
-	@Test
-	void shouldNotStartWhenDisabled() {
+  @Test
+  void shouldNotStartWhenDisabled() {
 
-		final Launch launch = LaunchTestUtil.getLaunch(StatusEnum.FAILED, LaunchModeEnum.DEFAULT).get();
-		final ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, launch.getProjectId());
-		final LaunchFinishedEvent event = new LaunchFinishedEvent(launch, user, "baseUrl");
+    final Launch launch = LaunchTestUtil.getLaunch(StatusEnum.FAILED, LaunchModeEnum.DEFAULT).get();
+    final ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER,
+        launch.getProjectId());
+    final LaunchFinishedEvent event = new LaunchFinishedEvent(launch, user, "baseUrl");
 
-		final Map<String, String> projectConfig = ImmutableMap.<String, String>builder()
-				.put(ProjectAttributeEnum.AUTO_UNIQUE_ERROR_ANALYZER_ENABLED.getAttribute(), "false")
-				.put(ProjectAttributeEnum.UNIQUE_ERROR_ANALYZER_REMOVE_NUMBERS.getAttribute(), "true")
-				.build();
+    final Map<String, String> projectConfig = ImmutableMap.<String, String>builder()
+        .put(ProjectAttributeEnum.AUTO_UNIQUE_ERROR_ANALYZER_ENABLED.getAttribute(), "false")
+        .put(ProjectAttributeEnum.UNIQUE_ERROR_ANALYZER_REMOVE_NUMBERS.getAttribute(), "true")
+        .build();
 
-		runner.handle(event, projectConfig);
+    runner.handle(event, projectConfig);
 
-		verify(starter, times(0)).start(any(ClusterEntityContext.class), anyMap());
+    verify(starter, times(0)).start(any(ClusterEntityContext.class), anyMap());
 
-	}
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/events/listener/StartLaunchUniqueErrorAnalysisEventListenerTest.java b/src/test/java/com/epam/ta/reportportal/core/events/listener/StartLaunchUniqueErrorAnalysisEventListenerTest.java
index b7273120a4..f437d39c4a 100644
--- a/src/test/java/com/epam/ta/reportportal/core/events/listener/StartLaunchUniqueErrorAnalysisEventListenerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/events/listener/StartLaunchUniqueErrorAnalysisEventListenerTest.java
@@ -1,47 +1,52 @@
 package com.epam.ta.reportportal.core.events.listener;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.reportportal.extension.event.LaunchStartUniqueErrorAnalysisEvent;
 import com.epam.ta.reportportal.core.launch.cluster.UniqueErrorAnalysisStarter;
 import com.epam.ta.reportportal.core.launch.cluster.config.ClusterEntityContext;
 import com.epam.ta.reportportal.core.project.config.ProjectConfigProvider;
-import org.junit.jupiter.api.Test;
-import org.mockito.ArgumentCaptor;
-
 import java.util.Collections;
 import java.util.Map;
-
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.Mockito.*;
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class StartLaunchUniqueErrorAnalysisEventListenerTest {
 
-	private final ProjectConfigProvider projectConfigProvider = mock(ProjectConfigProvider.class);
-	private final UniqueErrorAnalysisStarter starter = mock(UniqueErrorAnalysisStarter.class);
+  private final ProjectConfigProvider projectConfigProvider = mock(ProjectConfigProvider.class);
+  private final UniqueErrorAnalysisStarter starter = mock(UniqueErrorAnalysisStarter.class);
 
-	private final StartLaunchUniqueErrorAnalysisEventListener listener = new StartLaunchUniqueErrorAnalysisEventListener(
-			projectConfigProvider,
-			starter
-	);
+  private final StartLaunchUniqueErrorAnalysisEventListener listener = new StartLaunchUniqueErrorAnalysisEventListener(
+      projectConfigProvider,
+      starter
+  );
 
-	@Test
-	void shouldStart() {
-		final Map<String, String> projectConfig = Collections.emptyMap();
-		when(projectConfigProvider.provide(anyLong())).thenReturn(projectConfig);
+  @Test
+  void shouldStart() {
+    final Map<String, String> projectConfig = Collections.emptyMap();
+    when(projectConfigProvider.provide(anyLong())).thenReturn(projectConfig);
 
-		final LaunchStartUniqueErrorAnalysisEvent event = new LaunchStartUniqueErrorAnalysisEvent(1L, 1L);
-		listener.onApplicationEvent(event);
+    final LaunchStartUniqueErrorAnalysisEvent event = new LaunchStartUniqueErrorAnalysisEvent(1L,
+        1L);
+    listener.onApplicationEvent(event);
 
-		final ArgumentCaptor<ClusterEntityContext> contextArgumentCaptor = ArgumentCaptor.forClass(ClusterEntityContext.class);
-		verify(starter, times(1)).start(contextArgumentCaptor.capture(), eq(projectConfig));
+    final ArgumentCaptor<ClusterEntityContext> contextArgumentCaptor = ArgumentCaptor.forClass(
+        ClusterEntityContext.class);
+    verify(starter, times(1)).start(contextArgumentCaptor.capture(), eq(projectConfig));
 
-		final ClusterEntityContext entityContext = contextArgumentCaptor.getValue();
+    final ClusterEntityContext entityContext = contextArgumentCaptor.getValue();
 
-		assertEquals(event.getSource(), entityContext.getLaunchId());
-		assertEquals(event.getProjectId(), entityContext.getProjectId());
-	}
+    assertEquals(event.getSource(), entityContext.getLaunchId());
+    assertEquals(event.getProjectId(), entityContext.getProjectId());
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/events/listener/TestItemFinishedEventListenerTest.java b/src/test/java/com/epam/ta/reportportal/core/events/listener/TestIssueResolvedEventListenerTest.java
similarity index 52%
rename from src/test/java/com/epam/ta/reportportal/core/events/listener/TestItemFinishedEventListenerTest.java
rename to src/test/java/com/epam/ta/reportportal/core/events/listener/TestIssueResolvedEventListenerTest.java
index 3a3e67fe47..b2e8897f5a 100644
--- a/src/test/java/com/epam/ta/reportportal/core/events/listener/TestItemFinishedEventListenerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/events/listener/TestIssueResolvedEventListenerTest.java
@@ -16,31 +16,33 @@
 
 package com.epam.ta.reportportal.core.events.listener;
 
-import com.epam.ta.reportportal.core.events.activity.item.ItemFinishedEvent;
-import com.epam.ta.reportportal.core.events.subscriber.impl.delegate.ProjectConfigDelegatingSubscriber;
-import org.junit.jupiter.api.Test;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
 
+import com.epam.ta.reportportal.core.events.activity.item.IssueResolvedEvent;
+import com.epam.ta.reportportal.core.events.subscriber.impl.delegate.ProjectConfigDelegatingSubscriber;
 import java.util.List;
-
-import static org.mockito.Mockito.*;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
-class TestItemFinishedEventListenerTest {
+class TestIssueResolvedEventListenerTest {
 
-	private final ProjectConfigDelegatingSubscriber<ItemFinishedEvent> delegatingSubscriber = (ProjectConfigDelegatingSubscriber<ItemFinishedEvent>) mock(
-			ProjectConfigDelegatingSubscriber.class);
+  private final ProjectConfigDelegatingSubscriber<IssueResolvedEvent> delegatingSubscriber = (ProjectConfigDelegatingSubscriber<IssueResolvedEvent>) mock(
+      ProjectConfigDelegatingSubscriber.class);
 
-	private final TestItemFinishedEventListener eventListener = new TestItemFinishedEventListener(List.of(delegatingSubscriber));
+  private final TestItemIssueResolvedEventListener eventListener = new TestItemIssueResolvedEventListener(
+      List.of(delegatingSubscriber));
 
-	@Test
-	void shouldHandle() {
-		final ItemFinishedEvent event = new ItemFinishedEvent(3L, 2L, 1L);
+  @Test
+  void shouldHandle() {
+    final IssueResolvedEvent event = new IssueResolvedEvent(3L, 2L, 1L);
 
-		eventListener.onApplicationEvent(event);
+    eventListener.onApplicationEvent(event);
 
-		verify(delegatingSubscriber, times(1)).handleEvent(event);
-	}
+    verify(delegatingSubscriber, times(1)).handleEvent(event);
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/events/subscriber/impl/delegate/ProjectConfigDelegatingSubscriberTest.java b/src/test/java/com/epam/ta/reportportal/core/events/subscriber/impl/delegate/ProjectConfigDelegatingSubscriberTest.java
index cfe3905abb..a3a4e911f9 100644
--- a/src/test/java/com/epam/ta/reportportal/core/events/subscriber/impl/delegate/ProjectConfigDelegatingSubscriberTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/events/subscriber/impl/delegate/ProjectConfigDelegatingSubscriberTest.java
@@ -16,8 +16,6 @@
 
 package com.epam.ta.reportportal.core.events.subscriber.impl.delegate;
 
-import static org.junit.jupiter.api.Assertions.*;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
diff --git a/src/test/java/com/epam/ta/reportportal/core/events/subscriber/impl/launch/finish/LaunchFinishedMessagePublisherTest.java b/src/test/java/com/epam/ta/reportportal/core/events/subscriber/impl/launch/finish/LaunchFinishedMessagePublisherTest.java
index 33b540dc58..2d3d121e3b 100644
--- a/src/test/java/com/epam/ta/reportportal/core/events/subscriber/impl/launch/finish/LaunchFinishedMessagePublisherTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/events/subscriber/impl/launch/finish/LaunchFinishedMessagePublisherTest.java
@@ -16,8 +16,6 @@
 
 package com.epam.ta.reportportal.core.events.subscriber.impl.launch.finish;
 
-import static org.junit.jupiter.api.Assertions.*;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
diff --git a/src/test/java/com/epam/ta/reportportal/core/hierarchy/impl/FinishLaunchHierarchyHandlerTest.java b/src/test/java/com/epam/ta/reportportal/core/hierarchy/impl/FinishLaunchHierarchyHandlerTest.java
index 987bc9d530..b2b191e199 100644
--- a/src/test/java/com/epam/ta/reportportal/core/hierarchy/impl/FinishLaunchHierarchyHandlerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/hierarchy/impl/FinishLaunchHierarchyHandlerTest.java
@@ -1,5 +1,18 @@
 package com.epam.ta.reportportal.core.hierarchy.impl;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.TEST_PROJECT_NAME;
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static com.epam.ta.reportportal.core.item.impl.status.ToSkippedStatusChangingStrategy.SKIPPED_ISSUE_KEY;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.item.impl.IssueTypeHandler;
 import com.epam.ta.reportportal.core.item.impl.retry.RetryHandler;
@@ -20,196 +33,200 @@
 import com.epam.ta.reportportal.entity.project.ProjectRole;
 import com.epam.ta.reportportal.entity.user.UserRole;
 import com.google.common.collect.Lists;
-import org.junit.jupiter.api.Test;
-
 import java.time.LocalDate;
 import java.time.Month;
 import java.time.ZoneId;
 import java.util.Date;
 import java.util.List;
 import java.util.Optional;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.TEST_PROJECT_NAME;
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static com.epam.ta.reportportal.core.item.impl.status.ToSkippedStatusChangingStrategy.SKIPPED_ISSUE_KEY;
-import static org.mockito.ArgumentMatchers.*;
-import static org.mockito.Mockito.*;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class FinishLaunchHierarchyHandlerTest {
 
-	private final LaunchRepository launchRepository = mock(LaunchRepository.class);
-	private final TestItemRepository testItemRepository = mock(TestItemRepository.class);
-	private final ItemAttributeRepository itemAttributeRepository = mock(ItemAttributeRepository.class);
-	private final RetryHandler retryHandler = mock(RetryHandler.class);
-	private final IssueTypeHandler issueTypeHandler = mock(IssueTypeHandler.class);
-	private final IssueEntityRepository issueEntityRepository = mock(IssueEntityRepository.class);
-	private final ChangeStatusHandler changeStatusHandler = mock(ChangeStatusHandler.class);
-
-	private final FinishLaunchHierarchyHandler finishLaunchHierarchyHandler = new FinishLaunchHierarchyHandler(launchRepository,
-			testItemRepository,
-			itemAttributeRepository,
-			retryHandler,
-			issueTypeHandler,
-			issueEntityRepository,
-			changeStatusHandler
-	);
-
-	@Test
-	void finishWithPassedStatus() {
-
-		Launch launch = getLaunch();
-
-		List<Long> idsWithChildren = Lists.newArrayList(2L, 1L);
-		List<Long> idsWithoutChildren = Lists.newArrayList(3L, 4L);
-
-		when(testItemRepository.findIdsByHasChildrenAndLaunchIdAndStatusOrderedByPathLevel(eq(launch.getId()),
-				eq(StatusEnum.IN_PROGRESS),
-				anyInt(),
-				anyLong()
-		)).thenReturn(idsWithChildren);
-		when(testItemRepository.findIdsByNotHasChildrenAndLaunchIdAndStatus(eq(launch.getId()),
-				eq(StatusEnum.IN_PROGRESS),
-				anyInt(),
-				anyLong()
-		)).thenReturn(idsWithoutChildren);
-
-		Date endTime = Date.from(LocalDate.of(2020, Month.OCTOBER, 30).atStartOfDay(ZoneId.systemDefault()).toInstant());
-		ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
-
-		when(testItemRepository.findAllById(idsWithChildren)).thenReturn(getTestItemsWithChildren(launch));
-		when(testItemRepository.findAllById(idsWithoutChildren)).thenReturn(getTestItemsWithoutChildren(launch));
-
-		when(issueEntityRepository.findById(3L)).thenReturn(Optional.empty());
-		when(issueEntityRepository.findById(4L)).thenReturn(Optional.empty());
-
-		finishLaunchHierarchyHandler.finishDescendants(launch,
-				StatusEnum.PASSED,
-				endTime,
-				rpUser,
-				rpUser.getProjectDetails().get(TEST_PROJECT_NAME)
-		);
-
-		verify(changeStatusHandler, times(2)).changeParentStatus(any(TestItem.class), any(), any());
-		verify(issueEntityRepository, times(0)).save(any());
-	}
-
-	@Test
-	void finishWithSkippedStatus() {
-
-		Launch launch = getLaunch();
-
-		when(itemAttributeRepository.findByLaunchIdAndKeyAndSystem(launch.getId(),
-				SKIPPED_ISSUE_KEY,
-				true
-		)).thenReturn(java.util.Optional.of(new ItemAttribute(SKIPPED_ISSUE_KEY, "true", true)));
-
-		when(issueTypeHandler.defineIssueType(anyLong(), anyString())).thenReturn(getToInvestigateIssueType());
-
-		List<Long> idsWithChildren = Lists.newArrayList(2L, 1L);
-		List<Long> idsWithoutChildren = Lists.newArrayList(3L, 4L);
-		when(testItemRepository.findIdsByHasChildrenAndLaunchIdAndStatusOrderedByPathLevel(eq(launch.getId()),
-				eq(StatusEnum.IN_PROGRESS),
-				anyInt(),
-				anyLong()
-		)).thenReturn(idsWithChildren);
-		when(testItemRepository.findIdsByNotHasChildrenAndLaunchIdAndStatus(eq(launch.getId()),
-				eq(StatusEnum.IN_PROGRESS),
-				anyInt(),
-				anyLong()
-		)).thenReturn(idsWithoutChildren);
-
-		Date endTime = Date.from(LocalDate.of(2020, Month.OCTOBER, 30).atStartOfDay(ZoneId.systemDefault()).toInstant());
-		ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
-
-		when(testItemRepository.findAllById(idsWithChildren)).thenReturn(getTestItemsWithChildren(launch));
-		when(testItemRepository.findAllById(idsWithoutChildren)).thenReturn(getTestItemsWithoutChildren(launch));
-
-		finishLaunchHierarchyHandler.finishDescendants(launch,
-				StatusEnum.SKIPPED,
-				endTime,
-				rpUser,
-				rpUser.getProjectDetails().get(TEST_PROJECT_NAME)
-		);
-
-		verify(changeStatusHandler, times(2)).changeParentStatus(any(TestItem.class), any(), any());
-		verify(issueEntityRepository, times(2)).save(any());
-
-	}
-
-	private Launch getLaunch() {
-		Launch launch = new Launch();
-		launch.setId(1L);
-		return launch;
-	}
-
-	private IssueType getToInvestigateIssueType() {
-		IssueType issueType = new IssueType();
-		issueType.setId(1L);
-		issueType.setLocator(TestItemIssueGroup.TO_INVESTIGATE.getLocator());
-
-		IssueGroup issueGroup = new IssueGroup();
-		issueGroup.setId(1);
-		issueGroup.setTestItemIssueGroup(TestItemIssueGroup.TO_INVESTIGATE);
-		issueType.setIssueGroup(issueGroup);
-		return issueType;
-	}
-
-	private List<TestItem> getTestItemsWithChildren(Launch launch) {
-
-		TestItem parent = new TestItem();
-		parent.setItemId(1L);
-		parent.setType(TestItemTypeEnum.SUITE);
-		parent.setLaunchId(launch.getId());
-		parent.setPath("1");
-		parent.setHasStats(true);
-		parent.setHasChildren(true);
-		TestItemResults parentResults = new TestItemResults();
-		parentResults.setStatus(StatusEnum.IN_PROGRESS);
-		parent.setItemResults(parentResults);
-
-		TestItem child = new TestItem();
-		child.setItemId(2L);
-		child.setType(TestItemTypeEnum.TEST);
-		child.setLaunchId(launch.getId());
-		child.setPath("1.2");
-		child.setParentId(parent.getItemId());
-		child.setHasStats(true);
-		child.setHasChildren(true);
-		TestItemResults childResults = new TestItemResults();
-		childResults.setStatus(StatusEnum.IN_PROGRESS);
-		child.setItemResults(childResults);
-
-		return Lists.newArrayList(child, parent);
-	}
-
-	private List<TestItem> getTestItemsWithoutChildren(Launch launch) {
-
-		TestItem firstChild = new TestItem();
-		firstChild.setItemId(3L);
-		firstChild.setType(TestItemTypeEnum.STEP);
-		firstChild.setLaunchId(launch.getId());
-		firstChild.setPath("1.2.3");
-		firstChild.setHasStats(true);
-		firstChild.setHasChildren(false);
-		TestItemResults parentResults = new TestItemResults();
-		parentResults.setStatus(StatusEnum.IN_PROGRESS);
-		firstChild.setItemResults(parentResults);
-
-		TestItem secondChild = new TestItem();
-		secondChild.setItemId(4L);
-		secondChild.setType(TestItemTypeEnum.STEP);
-		secondChild.setLaunchId(launch.getId());
-		secondChild.setPath("1.2.4");
-		secondChild.setHasStats(true);
-		secondChild.setHasChildren(true);
-		TestItemResults childResults = new TestItemResults();
-		childResults.setStatus(StatusEnum.IN_PROGRESS);
-		secondChild.setItemResults(childResults);
-
-		return Lists.newArrayList(firstChild, secondChild);
-	}
+  private final LaunchRepository launchRepository = mock(LaunchRepository.class);
+  private final TestItemRepository testItemRepository = mock(TestItemRepository.class);
+  private final ItemAttributeRepository itemAttributeRepository = mock(
+      ItemAttributeRepository.class);
+  private final RetryHandler retryHandler = mock(RetryHandler.class);
+  private final IssueTypeHandler issueTypeHandler = mock(IssueTypeHandler.class);
+  private final IssueEntityRepository issueEntityRepository = mock(IssueEntityRepository.class);
+  private final ChangeStatusHandler changeStatusHandler = mock(ChangeStatusHandler.class);
+
+  private final FinishLaunchHierarchyHandler finishLaunchHierarchyHandler = new FinishLaunchHierarchyHandler(
+      launchRepository,
+      testItemRepository,
+      itemAttributeRepository,
+      retryHandler,
+      issueTypeHandler,
+      issueEntityRepository,
+      changeStatusHandler
+  );
+
+  @Test
+  void finishWithPassedStatus() {
+
+    Launch launch = getLaunch();
+
+    List<Long> idsWithChildren = Lists.newArrayList(2L, 1L);
+    List<Long> idsWithoutChildren = Lists.newArrayList(3L, 4L);
+
+    when(testItemRepository.findIdsByHasChildrenAndLaunchIdAndStatusOrderedByPathLevel(
+        eq(launch.getId()),
+        eq(StatusEnum.IN_PROGRESS),
+        anyInt(),
+        anyLong()
+    )).thenReturn(idsWithChildren);
+    when(testItemRepository.findIdsByNotHasChildrenAndLaunchIdAndStatus(eq(launch.getId()),
+        eq(StatusEnum.IN_PROGRESS),
+        anyInt(),
+        anyLong()
+    )).thenReturn(idsWithoutChildren);
+
+    Date endTime = Date.from(
+        LocalDate.of(2020, Month.OCTOBER, 30).atStartOfDay(ZoneId.systemDefault()).toInstant());
+    ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
+
+    when(testItemRepository.findAllById(idsWithChildren)).thenReturn(
+        getTestItemsWithChildren(launch));
+    when(testItemRepository.findAllById(idsWithoutChildren)).thenReturn(
+        getTestItemsWithoutChildren(launch));
+
+    when(issueEntityRepository.findById(3L)).thenReturn(Optional.empty());
+    when(issueEntityRepository.findById(4L)).thenReturn(Optional.empty());
+
+    finishLaunchHierarchyHandler.finishDescendants(launch,
+        StatusEnum.PASSED,
+        endTime,
+        rpUser,
+        rpUser.getProjectDetails().get(TEST_PROJECT_NAME)
+    );
+
+    verify(changeStatusHandler, times(2)).changeParentStatus(any(TestItem.class), any(), any());
+    verify(issueEntityRepository, times(0)).save(any());
+  }
+
+  @Test
+  void finishWithSkippedStatus() {
+
+    Launch launch = getLaunch();
+
+    when(itemAttributeRepository.findByLaunchIdAndKeyAndSystem(launch.getId(),
+        SKIPPED_ISSUE_KEY,
+        true
+    )).thenReturn(java.util.Optional.of(new ItemAttribute(SKIPPED_ISSUE_KEY, "true", true)));
+
+    when(issueTypeHandler.defineIssueType(anyLong(), anyString())).thenReturn(
+        getToInvestigateIssueType());
+
+    List<Long> idsWithChildren = Lists.newArrayList(2L, 1L);
+    List<Long> idsWithoutChildren = Lists.newArrayList(3L, 4L);
+    when(testItemRepository.findIdsByHasChildrenAndLaunchIdAndStatusOrderedByPathLevel(
+        eq(launch.getId()),
+        eq(StatusEnum.IN_PROGRESS),
+        anyInt(),
+        anyLong()
+    )).thenReturn(idsWithChildren);
+    when(testItemRepository.findIdsByNotHasChildrenAndLaunchIdAndStatus(eq(launch.getId()),
+        eq(StatusEnum.IN_PROGRESS),
+        anyInt(),
+        anyLong()
+    )).thenReturn(idsWithoutChildren);
+
+    Date endTime = Date.from(
+        LocalDate.of(2020, Month.OCTOBER, 30).atStartOfDay(ZoneId.systemDefault()).toInstant());
+    ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
+
+    when(testItemRepository.findAllById(idsWithChildren)).thenReturn(
+        getTestItemsWithChildren(launch));
+    when(testItemRepository.findAllById(idsWithoutChildren)).thenReturn(
+        getTestItemsWithoutChildren(launch));
+
+    finishLaunchHierarchyHandler.finishDescendants(launch,
+        StatusEnum.SKIPPED,
+        endTime,
+        rpUser,
+        rpUser.getProjectDetails().get(TEST_PROJECT_NAME)
+    );
+
+    verify(changeStatusHandler, times(2)).changeParentStatus(any(TestItem.class), any(), any());
+    verify(issueEntityRepository, times(2)).save(any());
+
+  }
+
+  private Launch getLaunch() {
+    Launch launch = new Launch();
+    launch.setId(1L);
+    return launch;
+  }
+
+  private IssueType getToInvestigateIssueType() {
+    IssueType issueType = new IssueType();
+    issueType.setId(1L);
+    issueType.setLocator(TestItemIssueGroup.TO_INVESTIGATE.getLocator());
+
+    IssueGroup issueGroup = new IssueGroup();
+    issueGroup.setId(1);
+    issueGroup.setTestItemIssueGroup(TestItemIssueGroup.TO_INVESTIGATE);
+    issueType.setIssueGroup(issueGroup);
+    return issueType;
+  }
+
+  private List<TestItem> getTestItemsWithChildren(Launch launch) {
+
+    TestItem parent = new TestItem();
+    parent.setItemId(1L);
+    parent.setType(TestItemTypeEnum.SUITE);
+    parent.setLaunchId(launch.getId());
+    parent.setPath("1");
+    parent.setHasStats(true);
+    parent.setHasChildren(true);
+    TestItemResults parentResults = new TestItemResults();
+    parentResults.setStatus(StatusEnum.IN_PROGRESS);
+    parent.setItemResults(parentResults);
+
+    TestItem child = new TestItem();
+    child.setItemId(2L);
+    child.setType(TestItemTypeEnum.TEST);
+    child.setLaunchId(launch.getId());
+    child.setPath("1.2");
+    child.setParentId(parent.getItemId());
+    child.setHasStats(true);
+    child.setHasChildren(true);
+    TestItemResults childResults = new TestItemResults();
+    childResults.setStatus(StatusEnum.IN_PROGRESS);
+    child.setItemResults(childResults);
+
+    return Lists.newArrayList(child, parent);
+  }
+
+  private List<TestItem> getTestItemsWithoutChildren(Launch launch) {
+
+    TestItem firstChild = new TestItem();
+    firstChild.setItemId(3L);
+    firstChild.setType(TestItemTypeEnum.STEP);
+    firstChild.setLaunchId(launch.getId());
+    firstChild.setPath("1.2.3");
+    firstChild.setHasStats(true);
+    firstChild.setHasChildren(false);
+    TestItemResults parentResults = new TestItemResults();
+    parentResults.setStatus(StatusEnum.IN_PROGRESS);
+    firstChild.setItemResults(parentResults);
+
+    TestItem secondChild = new TestItem();
+    secondChild.setItemId(4L);
+    secondChild.setType(TestItemTypeEnum.STEP);
+    secondChild.setLaunchId(launch.getId());
+    secondChild.setPath("1.2.4");
+    secondChild.setHasStats(true);
+    secondChild.setHasChildren(true);
+    TestItemResults childResults = new TestItemResults();
+    childResults.setStatus(StatusEnum.IN_PROGRESS);
+    secondChild.setItemResults(childResults);
+
+    return Lists.newArrayList(firstChild, secondChild);
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/imprt/ImportLaunchHandlerImplTest.java b/src/test/java/com/epam/ta/reportportal/core/imprt/ImportLaunchHandlerImplTest.java
index 8e875fb626..d7a2014334 100644
--- a/src/test/java/com/epam/ta/reportportal/core/imprt/ImportLaunchHandlerImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/imprt/ImportLaunchHandlerImplTest.java
@@ -14,10 +14,14 @@
 import com.epam.ta.reportportal.core.imprt.impl.ImportStrategyFactory;
 import com.epam.ta.reportportal.core.imprt.impl.ImportType;
 import com.epam.ta.reportportal.core.imprt.impl.XmlImportStrategy;
+import com.epam.ta.reportportal.dao.LaunchRepository;
 import com.epam.ta.reportportal.exception.ReportPortalException;
+import com.epam.ta.reportportal.util.sample.LaunchSampleUtil;
 import com.epam.ta.reportportal.ws.model.ErrorType;
+import com.epam.ta.reportportal.ws.model.LaunchImportCompletionRS;
+import com.epam.ta.reportportal.ws.model.launch.LaunchImportRQ;
 import java.io.File;
-import java.util.HashMap;
+import java.util.Optional;
 import org.apache.commons.io.FilenameUtils;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -43,6 +47,9 @@ public class ImportLaunchHandlerImplTest {
   @Mock
   private MessageBus messageBus;
 
+  @Mock
+  private LaunchRepository launchRepository;
+
   @Captor
   private ArgumentCaptor<ImportFinishedEvent> importFinishedEventCaptor;
 
@@ -84,7 +91,7 @@ public void setUp() {
   public void whenImportLaunch_AndFileNameIsNotValid_ThenThrowException() {
     ReportPortalException reportPortalException = assertThrows(ReportPortalException.class,
         () -> importLaunchHandlerImpl.importLaunch(projectDetails, reportPortalUser, FORMAT,
-            multipartFile, BASE_URL, new HashMap<>()
+            multipartFile, BASE_URL, new LaunchImportRQ()
         )
     );
 
@@ -98,7 +105,7 @@ public void whenImportLaunch_AndFileExtensionIsNotValid_ThenThrowException() {
     when(multipartFile.getOriginalFilename()).thenReturn(INCORRECT_FILE_NAME);
     ReportPortalException reportPortalException = assertThrows(ReportPortalException.class,
         () -> importLaunchHandlerImpl.importLaunch(projectDetails, reportPortalUser, FORMAT,
-            multipartFile, BASE_URL, new HashMap<>()
+            multipartFile, BASE_URL, new LaunchImportRQ()
         )
     );
 
@@ -115,7 +122,7 @@ public void whenImportLaunch_AndFileSizeIsTooHigh_ThenThrowException() {
     when(multipartFile.getSize()).thenReturn(MAX_FILE_SIZE + 1L);
     ReportPortalException reportPortalException = assertThrows(ReportPortalException.class,
         () -> importLaunchHandlerImpl.importLaunch(projectDetails, reportPortalUser, FORMAT,
-            multipartFile, BASE_URL, new HashMap<>()
+            multipartFile, BASE_URL, new LaunchImportRQ()
         )
     );
 
@@ -126,28 +133,39 @@ public void whenImportLaunch_AndFileSizeIsTooHigh_ThenThrowException() {
   }
 
   @Test
-  public void whenImportLaunch_AndFileIsValid_ThenCallImportLaunch() throws Exception {
+  public void whenImportLaunch_AndFileIsValid_ThenCallImportLaunch() {
     when(multipartFile.getOriginalFilename()).thenReturn(FILE_NAME);
     when(multipartFile.getSize()).thenReturn(FILE_SIZE);
 
     File tempFile = mock(File.class);
     try (MockedStatic<File> fileMockedStatic = Mockito.mockStatic(File.class)) {
-      fileMockedStatic.when(()->File.createTempFile(eq(FILE_NAME), eq("." + FilenameUtils.getExtension(FILE_NAME))))
+      fileMockedStatic.when(
+              () -> File.createTempFile(eq(FILE_NAME), eq("." + FilenameUtils.getExtension(FILE_NAME))))
           .thenReturn(tempFile);
       XmlImportStrategy xmlImportStrategy = mock(XmlImportStrategy.class);
+      LaunchImportRQ rq = new LaunchImportRQ();
       when(xmlImportStrategy.importLaunch(projectDetails, reportPortalUser, tempFile, BASE_URL,
-          new HashMap<>()
+          rq
       )).thenReturn(LAUNCH_ID);
       when(importStrategyFactory.getImportStrategy(ImportType.XUNIT, FILE_NAME)).thenReturn(
           xmlImportStrategy);
 
-      importLaunchHandlerImpl.importLaunch(projectDetails, reportPortalUser, FORMAT, multipartFile,
-          BASE_URL, new HashMap<>()
+      var sampleLaunch = LaunchSampleUtil.getSampleLaunch(LAUNCH_ID);
+      when(launchRepository.findByUuid(LAUNCH_ID)).thenReturn(Optional.of(sampleLaunch));
+
+      var response = (LaunchImportCompletionRS) importLaunchHandlerImpl.importLaunch(projectDetails,
+          reportPortalUser, FORMAT,
+          multipartFile,
+          BASE_URL, rq
       );
 
+      assertEquals(sampleLaunch.getUuid(), response.getData().getId());
+      assertEquals(sampleLaunch.getName(), response.getData().getName());
+      assertEquals(sampleLaunch.getNumber(), response.getData().getNumber());
+
       verify(importStrategyFactory).getImportStrategy(ImportType.XUNIT, FILE_NAME);
       verify(xmlImportStrategy).importLaunch(projectDetails, reportPortalUser, tempFile, BASE_URL,
-          new HashMap<>()
+          rq
       );
       verify(messageBus).publishActivity(importFinishedEventCaptor.capture());
       ImportFinishedEvent importFinishedEvent = importFinishedEventCaptor.getValue();
@@ -155,6 +173,7 @@ public void whenImportLaunch_AndFileIsValid_ThenCallImportLaunch() throws Except
       assertEquals(USER_NAME, importFinishedEvent.getUserLogin());
       assertEquals(ID, importFinishedEvent.getUserId());
       assertEquals(FILE_NAME, importFinishedEvent.getFileName());
+
     }
   }
 }
diff --git a/src/test/java/com/epam/ta/reportportal/core/imprt/XmlImportStrategyTest.java b/src/test/java/com/epam/ta/reportportal/core/imprt/XmlImportStrategyTest.java
index d22dfdc3ae..8dc2699d08 100644
--- a/src/test/java/com/epam/ta/reportportal/core/imprt/XmlImportStrategyTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/imprt/XmlImportStrategyTest.java
@@ -16,6 +16,8 @@
 import com.epam.ta.reportportal.core.launch.StartLaunchHandler;
 import com.epam.ta.reportportal.dao.LaunchRepository;
 import com.epam.ta.reportportal.entity.launch.Launch;
+import com.epam.ta.reportportal.ws.model.attribute.ItemAttributesRQ;
+import com.epam.ta.reportportal.ws.model.launch.LaunchImportRQ;
 import com.epam.ta.reportportal.ws.model.launch.StartLaunchRS;
 import java.io.BufferedWriter;
 import java.io.File;
@@ -24,8 +26,8 @@
 import java.nio.file.Path;
 import java.time.Instant;
 import java.util.Date;
-import java.util.HashMap;
 import java.util.Optional;
+import java.util.Set;
 import javax.inject.Provider;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -70,7 +72,7 @@ void setUp() {
 
   @Test
   void whenImportLaunch_thenProcessXmlFile(@TempDir Path tempDir) throws Exception {
-    HashMap<String, String> params = new HashMap<>();
+    LaunchImportRQ rq = new LaunchImportRQ();
 
     File xmlFile = createFile(tempDir);
 
@@ -91,7 +93,7 @@ void whenImportLaunch_thenProcessXmlFile(@TempDir Path tempDir) throws Exception
     when(launchRepository.findByUuid(any())).thenReturn(Optional.of(launch));
     when(xmlParseJobProvider.get()).thenReturn(xunitParseJob);
 
-    xmlImportStrategy.importLaunch(projectDetails, user, xmlFile, BASE_URL, params);
+    xmlImportStrategy.importLaunch(projectDetails, user, xmlFile, BASE_URL, rq);
 
     verify(startLaunchHandler, times(1)).startLaunch(any(), any(), any());
     verify(finishLaunchHandler, times(1)).finishLaunch(any(), any(), any(), any(), any());
@@ -103,8 +105,8 @@ void whenImportLaunch_thenProcessXmlFile(@TempDir Path tempDir) throws Exception
   @Test
   void whenImportLaunch_andIsSkippedIssue_thenProcessXmlFileWithSkippedTrue(@TempDir Path tempDir)
       throws Exception {
-    HashMap<String, String> params = new HashMap<>();
-    params.put(AbstractImportStrategy.SKIPPED_IS_NOT_ISSUE, "true");
+    LaunchImportRQ rq = new LaunchImportRQ();
+    rq.setAttributes(Set.of(new ItemAttributesRQ(AbstractImportStrategy.SKIPPED_IS_NOT_ISSUE, "true")));
 
     File xmlFile = createFile(tempDir);
 
@@ -125,7 +127,7 @@ void whenImportLaunch_andIsSkippedIssue_thenProcessXmlFileWithSkippedTrue(@TempD
     when(launchRepository.findByUuid(any())).thenReturn(Optional.of(launch));
     when(xmlParseJobProvider.get()).thenReturn(xunitParseJob);
 
-    xmlImportStrategy.importLaunch(projectDetails, user, xmlFile, BASE_URL, params);
+    xmlImportStrategy.importLaunch(projectDetails, user, xmlFile, BASE_URL, rq);
 
     verify(startLaunchHandler, times(1)).startLaunch(any(), any(), any());
     verify(finishLaunchHandler, times(1)).finishLaunch(any(), any(), any(), any(), any());
diff --git a/src/test/java/com/epam/ta/reportportal/core/imprt/impl/junit/XunitImportHandlerTest.java b/src/test/java/com/epam/ta/reportportal/core/imprt/impl/junit/XunitImportHandlerTest.java
index d5293d61a3..8434eef739 100644
--- a/src/test/java/com/epam/ta/reportportal/core/imprt/impl/junit/XunitImportHandlerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/imprt/impl/junit/XunitImportHandlerTest.java
@@ -18,6 +18,8 @@
 import com.epam.ta.reportportal.ws.model.item.ItemCreatedRS;
 import com.epam.ta.reportportal.ws.model.log.SaveLogRQ;
 import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.time.Instant;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
@@ -28,6 +30,8 @@
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
 import org.mockito.InjectMocks;
@@ -65,6 +69,8 @@ public class XunitImportHandlerTest {
 
   private static final String TEST_CASE = "testcase";
 
+  private static final ZoneId TEST_ZONE_ID = ZoneId.of("UTC");
+
   private static final String ATTR_NAME = "attribute";
 
   private static final String TIMESTAMP = "1690210345";
@@ -96,12 +102,12 @@ public void whenStartElement_andQnameIsTestSuite_andItemUuidsAreEmpty_andStartTi
 
     LocalDateTime startSuiteTime =
         LocalDateTime.ofInstant(Instant.ofEpochMilli(Long.parseLong(suiteTimestamp)),
-            ZoneId.systemDefault()
+            TEST_ZONE_ID
         );
 
     LocalDateTime startItemTime =
         LocalDateTime.ofInstant(Instant.ofEpochMilli(Long.parseLong(TIMESTAMP)),
-            ZoneId.systemDefault()
+            TEST_ZONE_ID
         );
 
     setStartSuiteTime(xunitImportHandler, startSuiteTime);
@@ -210,7 +216,7 @@ public void whenStartElement_andQnameIsTestCase_thenStartStepItem() {
 
     LocalDateTime startItemTime =
         LocalDateTime.ofInstant(Instant.ofEpochMilli(Long.parseLong(TIMESTAMP)),
-            ZoneId.systemDefault()
+            TEST_ZONE_ID
         );
 
     setStartItemTime(xunitImportHandler, startItemTime);
@@ -328,6 +334,29 @@ public void whenStartElement_andQnameIsWarning_thenStatusIsWarning() {
     );
   }
 
+  @ParameterizedTest
+  @CsvSource(
+      value = {
+          "2023-09-26T14:47:26+02:00",
+          "2023-09-26T07:47:26-05:00",
+          "2023-09-26T12:47:26+00:00",
+          "2023-09-26T12:47:26",
+          "2023-09-26T12:47:26 UTC",
+          "2023-09-26T12:47:26 GMT",
+          "2023-09-26T12:47:26+00:00 GMT",
+          "1695732446000"
+      }
+  )
+  public void parseTimeStampDifferentFormats(String timestamp)
+      throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+    Method method = XunitImportHandler.class.getDeclaredMethod("parseTimeStamp", String.class);
+    method.setAccessible(true);
+
+    LocalDateTime startDateTime = (LocalDateTime) method.invoke(xunitImportHandler, timestamp);
+
+    assertEquals("2023-09-26T12:47:26", startDateTime.toString());
+  }
+
   private void setStartSuiteTime(XunitImportHandler xunitImportHandler,
       LocalDateTime startSuiteTime) {
     try {
diff --git a/src/test/java/com/epam/ta/reportportal/core/integration/impl/ExecuteIntegrationHandlerTest.java b/src/test/java/com/epam/ta/reportportal/core/integration/impl/ExecuteIntegrationHandlerTest.java
new file mode 100644
index 0000000000..a8dc44cf02
--- /dev/null
+++ b/src/test/java/com/epam/ta/reportportal/core/integration/impl/ExecuteIntegrationHandlerTest.java
@@ -0,0 +1,112 @@
+package com.epam.ta.reportportal.core.integration.impl;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
+import static org.mockito.Mockito.when;
+
+import com.epam.reportportal.extension.CommonPluginCommand;
+import com.epam.reportportal.extension.ReportPortalExtensionPoint;
+import com.epam.ta.reportportal.core.integration.ExecuteIntegrationHandler;
+import com.epam.ta.reportportal.core.plugin.PluginBox;
+import com.epam.ta.reportportal.dao.IntegrationRepository;
+import com.epam.ta.reportportal.exception.ReportPortalException;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Optional;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+public class ExecuteIntegrationHandlerTest {
+
+  private static final String PUBLIC_COMMAND_PREFIX = "public_";
+
+  private final IntegrationRepository integrationRepository = mock(IntegrationRepository.class);
+  private final PluginBox pluginBox = mock(PluginBox.class);
+
+  private final ExecuteIntegrationHandler executeIntegrationHandler = new ExecuteIntegrationHandlerImpl(
+      integrationRepository, pluginBox);
+
+  @Test
+  @DisplayName("Positive Test. Everything is fine")
+  public void executePublicCommandPositiveTest() {
+    final String pluginName = "signup";
+    final String publicCommand = PUBLIC_COMMAND_PREFIX + "testCommand";
+    final Map<String, Object> params = Collections.emptyMap();
+
+    CommonPluginCommand<String> commonPluginCommand = mock(CommonPluginCommand.class);
+    when(commonPluginCommand.executeCommand(params)).thenReturn("Ok");
+
+    ReportPortalExtensionPoint pluginInstance = mock(ReportPortalExtensionPoint.class);
+    when(pluginInstance.getCommonCommand(publicCommand)).thenReturn(commonPluginCommand);
+
+    when(pluginBox.getInstance(pluginName, ReportPortalExtensionPoint.class)).thenReturn(
+        Optional.of(pluginInstance));
+
+    executeIntegrationHandler.executePublicCommand(pluginName, publicCommand, params);
+
+    verify(pluginBox).getInstance(eq(pluginName), eq(ReportPortalExtensionPoint.class));
+    verify(pluginInstance).getCommonCommand(eq(publicCommand));
+  }
+
+  @Test
+  @DisplayName("Negative Test. When command is not public")
+  public void executeNotPublicCommandTest() {
+    final String pluginName = "signup";
+    final String publicCommand = "testCommand";
+    final Map<String, Object> params = Collections.emptyMap();
+
+    assertThrows(ReportPortalException.class, () ->
+        executeIntegrationHandler.executePublicCommand(pluginName, publicCommand, params));
+
+    verifyNoInteractions(pluginBox);
+  }
+
+  @Test
+  @DisplayName("Negative Test. When Plugin not found")
+  public void executePublicCommandWOPluginTest() {
+    final String pluginName = "signup";
+    final String publicCommand = PUBLIC_COMMAND_PREFIX + "testCommand";
+    final Map<String, Object> params = Collections.emptyMap();
+
+    CommonPluginCommand<String> commonPluginCommand = mock(CommonPluginCommand.class);
+    when(commonPluginCommand.executeCommand(params)).thenReturn("Ok");
+
+    ReportPortalExtensionPoint pluginInstance = mock(ReportPortalExtensionPoint.class);
+
+    when(pluginBox.getInstance(pluginName, ReportPortalExtensionPoint.class)).thenReturn(
+        Optional.empty());
+
+    assertThrows(ReportPortalException.class, () ->
+        executeIntegrationHandler.executePublicCommand(pluginName, publicCommand, params));
+
+    verify(pluginBox).getInstance(eq(pluginName), eq(ReportPortalExtensionPoint.class));
+    verifyNoInteractions(pluginInstance);
+  }
+
+  @Test
+  @DisplayName("Negative Test. When Command not found")
+  public void executePublicCommandWOCommandTest() {
+    final String pluginName = "signup";
+    final String publicCommand = PUBLIC_COMMAND_PREFIX + "testCommand";
+    final Map<String, Object> params = Collections.emptyMap();
+
+    CommonPluginCommand<String> commonPluginCommand = mock(CommonPluginCommand.class);
+    when(commonPluginCommand.executeCommand(params)).thenReturn("Ok");
+
+    ReportPortalExtensionPoint pluginInstance = mock(ReportPortalExtensionPoint.class);
+    when(pluginInstance.getCommonCommand(publicCommand)).thenReturn(null);
+
+    when(pluginBox.getInstance(pluginName, ReportPortalExtensionPoint.class)).thenReturn(
+        Optional.of(pluginInstance));
+
+    assertThrows(ReportPortalException.class, () ->
+        executeIntegrationHandler.executePublicCommand(pluginName, publicCommand, params));
+
+    verify(pluginBox).getInstance(eq(pluginName), eq(ReportPortalExtensionPoint.class));
+    verify(pluginInstance).getCommonCommand(eq(publicCommand));
+  }
+
+}
diff --git a/src/test/java/com/epam/ta/reportportal/core/integration/impl/GetIntegrationHandlerTest.java b/src/test/java/com/epam/ta/reportportal/core/integration/impl/GetIntegrationHandlerTest.java
index c1714eb67c..0f4dead3bf 100644
--- a/src/test/java/com/epam/ta/reportportal/core/integration/impl/GetIntegrationHandlerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/integration/impl/GetIntegrationHandlerTest.java
@@ -16,6 +16,13 @@
 
 package com.epam.ta.reportportal.core.integration.impl;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.TEST_PROJECT_NAME;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.core.bts.handler.GetBugTrackingSystemHandler;
 import com.epam.ta.reportportal.core.integration.GetIntegrationHandler;
 import com.epam.ta.reportportal.core.integration.impl.util.IntegrationTestUtil;
@@ -25,81 +32,81 @@
 import com.epam.ta.reportportal.dao.ProjectRepository;
 import com.epam.ta.reportportal.entity.project.Project;
 import com.epam.ta.reportportal.ws.model.integration.IntegrationResource;
-import org.junit.jupiter.api.Test;
-
 import java.util.Map;
 import java.util.Optional;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.TEST_PROJECT_NAME;
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class GetIntegrationHandlerTest {
 
-	private final Map integrationServiceMapming = mock(Map.class);
-	private final IntegrationService basicIntegrationService = mock(IntegrationService.class);
-	private final IntegrationRepository integrationRepository = mock(IntegrationRepository.class);
-	private final IntegrationTypeRepository integrationTypeRepository = mock(IntegrationTypeRepository.class);
-	private final ProjectRepository projectRepository = mock(ProjectRepository.class);
-	private final GetBugTrackingSystemHandler getBugTrackingSystemHandler = mock(GetBugTrackingSystemHandler.class);
-
-	private final GetIntegrationHandler getIntegrationHandler = new GetIntegrationHandlerImpl(integrationServiceMapming,
-			basicIntegrationService,
-			integrationRepository,
-			integrationTypeRepository,
-			projectRepository,
-			getBugTrackingSystemHandler
-	);
-
-	@Test
-	void getProjectIntegrationById() {
-
-		final long emailIntegrationId = 1L;
-		final long projectId = 1L;
-
-		Project project = new Project();
-		project.setId(projectId);
-		project.setName(TEST_PROJECT_NAME);
-
-		when(projectRepository.findByName(TEST_PROJECT_NAME)).thenReturn(Optional.of(project));
-
-		when(integrationRepository.findByIdAndProjectId(emailIntegrationId,
-				projectId
-		)).thenReturn(Optional.of(IntegrationTestUtil.getProjectEmailIntegration(
-				emailIntegrationId,
-				projectId
-		)));
-
-		IntegrationResource integrationResource = getIntegrationHandler.getProjectIntegrationById(emailIntegrationId, TEST_PROJECT_NAME);
-
-		assertNotNull(integrationResource);
-		assertEquals(emailIntegrationId, (long) integrationResource.getId());
-		assertEquals("superadmin", integrationResource.getCreator());
-		assertEquals(false, integrationResource.getEnabled());
-		assertEquals(projectId, (long) integrationResource.getProjectId());
-		assertNotNull(integrationResource.getIntegrationParams());
-		assertNotNull(integrationResource.getIntegrationType());
-	}
-
-	@Test
-	void getGlobalIntegrationById() {
-
-		final long emailIntegrationId = 1L;
-		when(integrationRepository.findGlobalById(emailIntegrationId)).thenReturn(Optional.of(IntegrationTestUtil.getGlobalEmailIntegration(
-				emailIntegrationId)));
-
-		IntegrationResource integrationResource = getIntegrationHandler.getGlobalIntegrationById(emailIntegrationId);
-
-		assertNotNull(integrationResource);
-		assertEquals("superadmin", integrationResource.getCreator());
-		assertEquals(emailIntegrationId, (long) integrationResource.getId());
-		assertEquals(false, integrationResource.getEnabled());
-		assertNull(integrationResource.getProjectId());
-		assertNotNull(integrationResource.getIntegrationParams());
-		assertNotNull(integrationResource.getIntegrationType());
-	}
+  private final Map integrationServiceMapming = mock(Map.class);
+  private final IntegrationService basicIntegrationService = mock(IntegrationService.class);
+  private final IntegrationRepository integrationRepository = mock(IntegrationRepository.class);
+  private final IntegrationTypeRepository integrationTypeRepository = mock(
+      IntegrationTypeRepository.class);
+  private final ProjectRepository projectRepository = mock(ProjectRepository.class);
+  private final GetBugTrackingSystemHandler getBugTrackingSystemHandler = mock(
+      GetBugTrackingSystemHandler.class);
+
+  private final GetIntegrationHandler getIntegrationHandler = new GetIntegrationHandlerImpl(
+      integrationServiceMapming,
+      basicIntegrationService,
+      integrationRepository,
+      integrationTypeRepository,
+      projectRepository,
+      getBugTrackingSystemHandler
+  );
+
+  @Test
+  void getProjectIntegrationById() {
+
+    final long emailIntegrationId = 1L;
+    final long projectId = 1L;
+
+    Project project = new Project();
+    project.setId(projectId);
+    project.setName(TEST_PROJECT_NAME);
+
+    when(projectRepository.findByName(TEST_PROJECT_NAME)).thenReturn(Optional.of(project));
+
+    when(integrationRepository.findByIdAndProjectId(emailIntegrationId,
+        projectId
+    )).thenReturn(Optional.of(IntegrationTestUtil.getProjectEmailIntegration(
+        emailIntegrationId,
+        projectId
+    )));
+
+    IntegrationResource integrationResource = getIntegrationHandler.getProjectIntegrationById(
+        emailIntegrationId, TEST_PROJECT_NAME);
+
+    assertNotNull(integrationResource);
+    assertEquals(emailIntegrationId, (long) integrationResource.getId());
+    assertEquals("superadmin", integrationResource.getCreator());
+    assertEquals(false, integrationResource.getEnabled());
+    assertEquals(projectId, (long) integrationResource.getProjectId());
+    assertNotNull(integrationResource.getIntegrationParams());
+    assertNotNull(integrationResource.getIntegrationType());
+  }
+
+  @Test
+  void getGlobalIntegrationById() {
+
+    final long emailIntegrationId = 1L;
+    when(integrationRepository.findGlobalById(emailIntegrationId)).thenReturn(
+        Optional.of(IntegrationTestUtil.getGlobalEmailIntegration(
+            emailIntegrationId)));
+
+    IntegrationResource integrationResource = getIntegrationHandler.getGlobalIntegrationById(
+        emailIntegrationId);
+
+    assertNotNull(integrationResource);
+    assertEquals("superadmin", integrationResource.getCreator());
+    assertEquals(emailIntegrationId, (long) integrationResource.getId());
+    assertEquals(false, integrationResource.getEnabled());
+    assertNull(integrationResource.getProjectId());
+    assertNotNull(integrationResource.getIntegrationParams());
+    assertNotNull(integrationResource.getIntegrationType());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/integration/impl/util/IntegrationTestUtil.java b/src/test/java/com/epam/ta/reportportal/core/integration/impl/util/IntegrationTestUtil.java
index bba23ea3cd..99a5bcb692 100644
--- a/src/test/java/com/epam/ta/reportportal/core/integration/impl/util/IntegrationTestUtil.java
+++ b/src/test/java/com/epam/ta/reportportal/core/integration/impl/util/IntegrationTestUtil.java
@@ -23,7 +23,6 @@
 import com.epam.ta.reportportal.entity.integration.IntegrationTypeDetails;
 import com.epam.ta.reportportal.entity.project.Project;
 import com.google.common.collect.Maps;
-
 import java.time.LocalDateTime;
 import java.util.Map;
 import java.util.Optional;
@@ -33,95 +32,96 @@
  */
 public final class IntegrationTestUtil {
 
-	private IntegrationTestUtil() {
+  private IntegrationTestUtil() {
 
-		//static only
-	}
+    //static only
+  }
 
-	public static Integration getGlobalEmailIntegration(long emailIntegrationId) {
+  public static Integration getGlobalEmailIntegration(long emailIntegrationId) {
 
-		Integration integration = new Integration();
+    Integration integration = new Integration();
 
-		integration.setCreator("superadmin");
-		integration.setCreationDate(LocalDateTime.now());
-		integration.setType(getEmailIntegrationType());
-		integration.setParams(new IntegrationParams(getParams()));
-		integration.setId(emailIntegrationId);
+    integration.setCreator("superadmin");
+    integration.setCreationDate(LocalDateTime.now());
+    integration.setType(getEmailIntegrationType());
+    integration.setParams(new IntegrationParams(getParams()));
+    integration.setId(emailIntegrationId);
 
-		return integration;
-	}
+    return integration;
+  }
 
-	public static Integration getProjectEmailIntegration(long emailIntegrationId, long projectId) {
+  public static Integration getProjectEmailIntegration(long emailIntegrationId, long projectId) {
 
-		Integration integration = getGlobalEmailIntegration(emailIntegrationId);
+    Integration integration = getGlobalEmailIntegration(emailIntegrationId);
 
-		integration.setProject(getProjectWithId(projectId).get());
+    integration.setProject(getProjectWithId(projectId).get());
 
-		return integration;
-	}
+    return integration;
+  }
 
-	public static Integration getGlobalJiraIntegration(long id, Map<String, Object> params) {
+  public static Integration getGlobalJiraIntegration(long id, Map<String, Object> params) {
 
-		Integration integration = new Integration();
+    Integration integration = new Integration();
 
-		integration.setCreator("superadmin");
-		integration.setCreationDate(LocalDateTime.now());
-		integration.setType(getJiraIntegrationType());
-		integration.setParams(new IntegrationParams(params));
-		integration.setId(id);
+    integration.setCreator("superadmin");
+    integration.setCreationDate(LocalDateTime.now());
+    integration.setType(getJiraIntegrationType());
+    integration.setParams(new IntegrationParams(params));
+    integration.setId(id);
 
-		return integration;
-	}
+    return integration;
+  }
 
-	public static Integration getProjectJiraIntegration(long id, Map<String, Object> params, long projectId) {
+  public static Integration getProjectJiraIntegration(long id, Map<String, Object> params,
+      long projectId) {
 
-		Integration integration = getGlobalJiraIntegration(id, params);
+    Integration integration = getGlobalJiraIntegration(id, params);
 
-		integration.setProject(getProjectWithId(projectId).get());
+    integration.setProject(getProjectWithId(projectId).get());
 
-		return integration;
-	}
+    return integration;
+  }
 
-	public static Map<String, Object> getParams() {
+  public static Map<String, Object> getParams() {
 
-		Map<String, Object> map = Maps.newHashMap();
-		map.put("first", "first");
-		map.put("second", "second");
-		return map;
-	}
+    Map<String, Object> map = Maps.newHashMap();
+    map.put("first", "first");
+    map.put("second", "second");
+    return map;
+  }
 
-	public static Optional<Project> getProjectWithId(long projectId) {
-		Project project = new Project();
+  public static Optional<Project> getProjectWithId(long projectId) {
+    Project project = new Project();
 
-		project.setId(projectId);
+    project.setId(projectId);
 
-		return Optional.of(project);
-	}
+    return Optional.of(project);
+  }
 
-	public static IntegrationType getJiraIntegrationType() {
+  public static IntegrationType getJiraIntegrationType() {
 
-		IntegrationType integrationType = new IntegrationType();
+    IntegrationType integrationType = new IntegrationType();
 
-		integrationType.setName("jira");
-		integrationType.setCreationDate(LocalDateTime.now());
-		integrationType.setId(1L);
-		integrationType.setIntegrationGroup(IntegrationGroupEnum.BTS);
-		IntegrationTypeDetails details = new IntegrationTypeDetails();
-		details.setDetails(Maps.newHashMap());
-		integrationType.setDetails(details);
+    integrationType.setName("jira");
+    integrationType.setCreationDate(LocalDateTime.now());
+    integrationType.setId(1L);
+    integrationType.setIntegrationGroup(IntegrationGroupEnum.BTS);
+    IntegrationTypeDetails details = new IntegrationTypeDetails();
+    details.setDetails(Maps.newHashMap());
+    integrationType.setDetails(details);
 
-		return integrationType;
-	}
+    return integrationType;
+  }
 
-	public static IntegrationType getEmailIntegrationType() {
+  public static IntegrationType getEmailIntegrationType() {
 
-		IntegrationType integrationType = new IntegrationType();
+    IntegrationType integrationType = new IntegrationType();
 
-		integrationType.setName("EMAIL");
-		integrationType.setCreationDate(LocalDateTime.now());
-		integrationType.setId(1L);
-		integrationType.setIntegrationGroup(IntegrationGroupEnum.NOTIFICATION);
+    integrationType.setName("EMAIL");
+    integrationType.setCreationDate(LocalDateTime.now());
+    integrationType.setId(1L);
+    integrationType.setIntegrationGroup(IntegrationGroupEnum.NOTIFICATION);
 
-		return integrationType;
-	}
+    return integrationType;
+  }
 }
diff --git a/src/test/java/com/epam/ta/reportportal/core/integration/util/AzureIntegrationServiceTest.java b/src/test/java/com/epam/ta/reportportal/core/integration/util/AzureIntegrationServiceTest.java
index f5324b0296..dfd77065dc 100644
--- a/src/test/java/com/epam/ta/reportportal/core/integration/util/AzureIntegrationServiceTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/integration/util/AzureIntegrationServiceTest.java
@@ -16,9 +16,18 @@
 
 package com.epam.ta.reportportal.core.integration.util;
 
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasSize;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.core.integration.util.property.BtsProperties;
 import com.epam.ta.reportportal.entity.enums.AuthType;
 import com.epam.ta.reportportal.exception.ReportPortalException;
+import java.util.HashMap;
+import java.util.Map;
 import org.jasypt.util.text.BasicTextEncryptor;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
@@ -26,70 +35,64 @@
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.hasSize;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.when;
-
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
  */
 @ExtendWith(MockitoExtension.class)
 class AzureIntegrationServiceTest {
-	private static final String UNSUPPORTED_AUTH_TYPE_NAME = AuthType.NTLM.name();
-
-	@Mock
-	private BasicTextEncryptor encryptor;
-
-	@InjectMocks
-	private BtsIntegrationService btsIntegrationService;
-
-	@Test
-	void testParameters() {
-		when(encryptor.encrypt(any())).thenReturn("encrypted");
-		Map<String, Object> res = btsIntegrationService.retrieveCreateParams("azure", getCorrectRallyIntegrationParams());
-		assertThat(res.keySet(), hasSize(4));
-	}
-
-	@Test
-	void testParametersWithoutKey() {
-		Map<String, Object> params = getCorrectRallyIntegrationParams();
-		params.remove(BtsProperties.OAUTH_ACCESS_KEY.getName());
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> btsIntegrationService.retrieveCreateParams("azure",params)
-		);
-		assertEquals("Impossible interact with integration. AccessKey value is not specified", exception.getMessage());
-	}
-
-	@Test
-	void testParametersUnsupportedAuthType() {
-		Map<String, Object> params = getCorrectRallyIntegrationParams();
-		params.put(BtsProperties.AUTH_TYPE.getName(), UNSUPPORTED_AUTH_TYPE_NAME);
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> btsIntegrationService.retrieveCreateParams("azure", params)
-		);
-		assertEquals(
-				"Impossible interact with integration. Unsupported auth type for integration - " + UNSUPPORTED_AUTH_TYPE_NAME,
-				exception.getMessage()
-		);
-	}
-
-	private Map<String, Object> getCorrectRallyIntegrationParams() {
-
-		Map<String, Object> params = new HashMap<>();
-		params.put(BtsProperties.URL.getName(), "azure-url");
-		params.put(BtsProperties.PROJECT.getName(), "azure-project");
-		params.put(BtsProperties.AUTH_TYPE.getName(), AuthType.OAUTH.name());
-		params.put(BtsProperties.OAUTH_ACCESS_KEY.getName(), "KEY");
-
-		return params;
-	}
+
+  private static final String UNSUPPORTED_AUTH_TYPE_NAME = AuthType.NTLM.name();
+
+  @Mock
+  private BasicTextEncryptor encryptor;
+
+  @InjectMocks
+  private BtsIntegrationService btsIntegrationService;
+
+  @Test
+  void testParameters() {
+    when(encryptor.encrypt(any())).thenReturn("encrypted");
+    Map<String, Object> res = btsIntegrationService.retrieveCreateParams("azure",
+        getCorrectRallyIntegrationParams());
+    assertThat(res.keySet(), hasSize(4));
+  }
+
+  @Test
+  void testParametersWithoutKey() {
+    Map<String, Object> params = getCorrectRallyIntegrationParams();
+    params.remove(BtsProperties.OAUTH_ACCESS_KEY.getName());
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> btsIntegrationService.retrieveCreateParams("azure", params)
+    );
+    assertEquals("Impossible interact with integration. AccessKey value is not specified",
+        exception.getMessage());
+  }
+
+  @Test
+  void testParametersUnsupportedAuthType() {
+    Map<String, Object> params = getCorrectRallyIntegrationParams();
+    params.put(BtsProperties.AUTH_TYPE.getName(), UNSUPPORTED_AUTH_TYPE_NAME);
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> btsIntegrationService.retrieveCreateParams("azure", params)
+    );
+    assertEquals(
+        "Impossible interact with integration. Unsupported auth type for integration - "
+            + UNSUPPORTED_AUTH_TYPE_NAME,
+        exception.getMessage()
+    );
+  }
+
+  private Map<String, Object> getCorrectRallyIntegrationParams() {
+
+    Map<String, Object> params = new HashMap<>();
+    params.put(BtsProperties.URL.getName(), "azure-url");
+    params.put(BtsProperties.PROJECT.getName(), "azure-project");
+    params.put(BtsProperties.AUTH_TYPE.getName(), AuthType.OAUTH.name());
+    params.put(BtsProperties.OAUTH_ACCESS_KEY.getName(), "KEY");
+
+    return params;
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/integration/util/EmailServerIntegrationServiceTest.java b/src/test/java/com/epam/ta/reportportal/core/integration/util/EmailServerIntegrationServiceTest.java
index a8220e5fcd..84cacacea3 100644
--- a/src/test/java/com/epam/ta/reportportal/core/integration/util/EmailServerIntegrationServiceTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/integration/util/EmailServerIntegrationServiceTest.java
@@ -16,6 +16,12 @@
 
 package com.epam.ta.reportportal.core.integration.util;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.core.plugin.PluginBox;
 import com.epam.ta.reportportal.dao.IntegrationRepository;
 import com.epam.ta.reportportal.entity.integration.Integration;
@@ -25,97 +31,97 @@
 import com.epam.ta.reportportal.util.email.MailServiceFactory;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
-import org.jasypt.util.text.BasicTextEncryptor;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import javax.mail.MessagingException;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Optional;
-
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.Mockito.*;
+import javax.mail.MessagingException;
+import org.jasypt.util.text.BasicTextEncryptor;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
  */
 class EmailServerIntegrationServiceTest {
 
-	private static final String INTEGRATION_NAME = "email";
-
-	private IntegrationRepository integrationRepository = mock(IntegrationRepository.class);
-	private final PluginBox pluginBox = mock(PluginBox.class);
-	private MailServiceFactory mailServiceFactory = mock(MailServiceFactory.class);
-	private EmailService emailService = mock(EmailService.class);
-
-	private EmailServerIntegrationService emailServerIntegrationService;
-
-	@BeforeEach
-	void setUp() {
-		BasicTextEncryptor basicTextEncryptor = new BasicTextEncryptor();
-		basicTextEncryptor.setPassword("123");
-		emailServerIntegrationService = new EmailServerIntegrationService(integrationRepository,
-				pluginBox,
-				basicTextEncryptor,
-				mailServiceFactory
-		);
-	}
-
-	@Test
-	void validateGlobalIntegrationNegative() throws MessagingException {
-		//given
-		Integration integration = new Integration();
-		IntegrationType integrationType = new IntegrationType();
-		integrationType.setName("email");
-		integration.setType(integrationType);
-
-		//when
-		when(integrationRepository.findAllGlobalByType(integrationType)).thenReturn(Lists.newArrayList());
-		when(mailServiceFactory.getEmailService(integration)).thenReturn(Optional.of(emailService));
-		doThrow(MessagingException.class).when(emailService).testConnection();
-
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> emailServerIntegrationService.retrieveCreateParams("email", new HashMap<>())
-		);
-
-		//then
-		assertEquals("Error in handled Request. Please, check specified parameters: 'No integration params provided'",
-				exception.getMessage()
-		);
-	}
-
-	@Test
-	void retrieveIntegrationParams() {
-		Map<String, Object> map = emailServerIntegrationService.retrieveCreateParams("email", getParams());
-		assertEquals(defaultParams(), map);
-	}
-
-	@Test
-	void retrieveIntegrationParamsInvalidPort() {
-		Map<String, Object> params = Maps.newHashMap();
-		params.put("from", "from@mail.com");
-		params.put("port", "123456789");
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> emailServerIntegrationService.retrieveCreateParams("email", params)
-		);
-		assertEquals("Incorrect Request. Incorrect 'Port' value. Allowed value is [1..65535]", exception.getMessage());
-	}
-
-	private Map<String, Object> defaultParams() {
-		Map<String, Object> res = Maps.newHashMap();
-		res.put("protocol", "value2");
-		res.put("host", "value3");
-		res.put("from", "from@mail.com");
-		return res;
-	}
-
-	private Map<String, Object> getParams() {
-		Map<String, Object> params = Maps.newHashMap();
-		params.put("from", "from@mail.com");
-		params.put("protocol", "value2");
-		params.put("host", "value3");
-
-		return params;
-	}
+  private static final String INTEGRATION_NAME = "email";
+
+  private IntegrationRepository integrationRepository = mock(IntegrationRepository.class);
+  private final PluginBox pluginBox = mock(PluginBox.class);
+  private MailServiceFactory mailServiceFactory = mock(MailServiceFactory.class);
+  private EmailService emailService = mock(EmailService.class);
+
+  private EmailServerIntegrationService emailServerIntegrationService;
+
+  @BeforeEach
+  void setUp() {
+    BasicTextEncryptor basicTextEncryptor = new BasicTextEncryptor();
+    basicTextEncryptor.setPassword("123");
+    emailServerIntegrationService = new EmailServerIntegrationService(integrationRepository,
+        pluginBox,
+        basicTextEncryptor,
+        mailServiceFactory
+    );
+  }
+
+  @Test
+  void validateGlobalIntegrationNegative() throws MessagingException {
+    //given
+    Integration integration = new Integration();
+    IntegrationType integrationType = new IntegrationType();
+    integrationType.setName("email");
+    integration.setType(integrationType);
+
+    //when
+    when(integrationRepository.findAllGlobalByType(integrationType)).thenReturn(
+        Lists.newArrayList());
+    when(mailServiceFactory.getEmailService(integration)).thenReturn(Optional.of(emailService));
+    doThrow(MessagingException.class).when(emailService).testConnection();
+
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> emailServerIntegrationService.retrieveCreateParams("email", new HashMap<>())
+    );
+
+    //then
+    assertEquals(
+        "Error in handled Request. Please, check specified parameters: 'No integration params provided'",
+        exception.getMessage()
+    );
+  }
+
+  @Test
+  void retrieveIntegrationParams() {
+    Map<String, Object> map = emailServerIntegrationService.retrieveCreateParams("email",
+        getParams());
+    assertEquals(defaultParams(), map);
+  }
+
+  @Test
+  void retrieveIntegrationParamsInvalidPort() {
+    Map<String, Object> params = Maps.newHashMap();
+    params.put("from", "from@mail.com");
+    params.put("port", "123456789");
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> emailServerIntegrationService.retrieveCreateParams("email", params)
+    );
+    assertEquals("Incorrect Request. Incorrect 'Port' value. Allowed value is [1..65535]",
+        exception.getMessage());
+  }
+
+  private Map<String, Object> defaultParams() {
+    Map<String, Object> res = Maps.newHashMap();
+    res.put("protocol", "value2");
+    res.put("host", "value3");
+    res.put("from", "from@mail.com");
+    return res;
+  }
+
+  private Map<String, Object> getParams() {
+    Map<String, Object> params = Maps.newHashMap();
+    params.put("from", "from@mail.com");
+    params.put("protocol", "value2");
+    params.put("host", "value3");
+
+    return params;
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/integration/util/JiraIntegrationServiceTest.java b/src/test/java/com/epam/ta/reportportal/core/integration/util/JiraIntegrationServiceTest.java
index 73cc599b96..d4b64eb9df 100644
--- a/src/test/java/com/epam/ta/reportportal/core/integration/util/JiraIntegrationServiceTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/integration/util/JiraIntegrationServiceTest.java
@@ -16,105 +16,109 @@
 
 package com.epam.ta.reportportal.core.integration.util;
 
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasSize;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.mock;
+
 import com.epam.ta.reportportal.core.integration.util.property.BtsProperties;
 import com.epam.ta.reportportal.core.plugin.PluginBox;
 import com.epam.ta.reportportal.dao.IntegrationRepository;
 import com.epam.ta.reportportal.entity.enums.AuthType;
 import com.epam.ta.reportportal.exception.ReportPortalException;
+import java.util.HashMap;
+import java.util.Map;
 import org.jasypt.util.text.BasicTextEncryptor;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.hasSize;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.Mockito.mock;
-
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
  */
 class JiraIntegrationServiceTest {
 
-	private static final String UNSUPPORTED_AUTH_TYPE_NAME = AuthType.NTLM.name();
-	private IntegrationRepository integrationRepository = mock(IntegrationRepository.class);
-	private PluginBox pluginBox = mock(PluginBox.class);
-
-	private BtsIntegrationService btsService;
-
-	@BeforeEach
-	void setUp() {
-		BasicTextEncryptor basicTextEncryptor = new BasicTextEncryptor();
-		basicTextEncryptor.setPassword("123");
-		btsService = new BtsIntegrationService(integrationRepository, pluginBox, basicTextEncryptor);
-	}
-
-	@Test
-	void testParameters() {
-		Map<String, Object> res = btsService.retrieveCreateParams("jira", getCorrectJiraIntegrationParams());
-		assertThat(res.keySet(), hasSize(5));
-	}
-
-	@Test
-	void testParametersWithoutUsername() {
-		Map<String, Object> params = getCorrectJiraIntegrationParams();
-		params.remove(BtsProperties.USER_NAME.getName());
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> btsService.retrieveCreateParams("jira", params)
-		);
-		assertEquals("Impossible interact with integration. Username value is not specified", exception.getMessage());
-	}
-
-	@Test
-	void testParametersWithouPassword() {
-		Map<String, Object> params = getCorrectJiraIntegrationParams();
-		params.remove(BtsProperties.PASSWORD.getName());
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> btsService.retrieveCreateParams("jira", params)
-		);
-		assertEquals("Impossible interact with integration. Password value is not specified", exception.getMessage());
-	}
-
-	@Test
-	void testParametersWithouKey() {
-		Map<String, Object> params = getCorrectJiraIntegrationParams();
-		params.put(BtsProperties.AUTH_TYPE.getName(), AuthType.OAUTH.name());
-		params.remove(BtsProperties.OAUTH_ACCESS_KEY.getName());
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> btsService.retrieveCreateParams("jira", params)
-		);
-		assertEquals("Impossible interact with integration. AccessKey value is not specified", exception.getMessage());
-	}
-
-	@Test
-	void testParametersUnopportetAuthType() {
-		Map<String, Object> params = getCorrectJiraIntegrationParams();
-		params.put(BtsProperties.AUTH_TYPE.getName(), UNSUPPORTED_AUTH_TYPE_NAME);
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> btsService.retrieveCreateParams("jira", params)
-		);
-		assertEquals(
-				"Impossible interact with integration. Unsupported auth type for integration - " + UNSUPPORTED_AUTH_TYPE_NAME,
-				exception.getMessage()
-		);
-	}
-
-	private Map<String, Object> getCorrectJiraIntegrationParams() {
-
-		Map<String, Object> params = new HashMap<>();
-		params.put(BtsProperties.URL.getName(), "jira-url");
-		params.put(BtsProperties.PROJECT.getName(), "jira-project");
-		params.put(BtsProperties.AUTH_TYPE.getName(), AuthType.BASIC.name());
-		params.put(BtsProperties.USER_NAME.getName(), "USERNAME");
-		params.put(BtsProperties.PASSWORD.getName(), "PASSWORD");
-		params.put(BtsProperties.OAUTH_ACCESS_KEY.getName(), "KEY");
-
-		return params;
-	}
+  private static final String UNSUPPORTED_AUTH_TYPE_NAME = AuthType.NTLM.name();
+  private IntegrationRepository integrationRepository = mock(IntegrationRepository.class);
+  private PluginBox pluginBox = mock(PluginBox.class);
+
+  private BtsIntegrationService btsService;
+
+  @BeforeEach
+  void setUp() {
+    BasicTextEncryptor basicTextEncryptor = new BasicTextEncryptor();
+    basicTextEncryptor.setPassword("123");
+    btsService = new BtsIntegrationService(integrationRepository, pluginBox, basicTextEncryptor);
+  }
+
+  @Test
+  void testParameters() {
+    Map<String, Object> res = btsService.retrieveCreateParams("jira",
+        getCorrectJiraIntegrationParams());
+    assertThat(res.keySet(), hasSize(5));
+  }
+
+  @Test
+  void testParametersWithoutUsername() {
+    Map<String, Object> params = getCorrectJiraIntegrationParams();
+    params.remove(BtsProperties.USER_NAME.getName());
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> btsService.retrieveCreateParams("jira", params)
+    );
+    assertEquals("Impossible interact with integration. Username value is not specified",
+        exception.getMessage());
+  }
+
+  @Test
+  void testParametersWithouPassword() {
+    Map<String, Object> params = getCorrectJiraIntegrationParams();
+    params.remove(BtsProperties.PASSWORD.getName());
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> btsService.retrieveCreateParams("jira", params)
+    );
+    assertEquals("Impossible interact with integration. Password value is not specified",
+        exception.getMessage());
+  }
+
+  @Test
+  void testParametersWithouKey() {
+    Map<String, Object> params = getCorrectJiraIntegrationParams();
+    params.put(BtsProperties.AUTH_TYPE.getName(), AuthType.OAUTH.name());
+    params.remove(BtsProperties.OAUTH_ACCESS_KEY.getName());
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> btsService.retrieveCreateParams("jira", params)
+    );
+    assertEquals("Impossible interact with integration. AccessKey value is not specified",
+        exception.getMessage());
+  }
+
+  @Test
+  void testParametersUnopportetAuthType() {
+    Map<String, Object> params = getCorrectJiraIntegrationParams();
+    params.put(BtsProperties.AUTH_TYPE.getName(), UNSUPPORTED_AUTH_TYPE_NAME);
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> btsService.retrieveCreateParams("jira", params)
+    );
+    assertEquals(
+        "Impossible interact with integration. Unsupported auth type for integration - "
+            + UNSUPPORTED_AUTH_TYPE_NAME,
+        exception.getMessage()
+    );
+  }
+
+  private Map<String, Object> getCorrectJiraIntegrationParams() {
+
+    Map<String, Object> params = new HashMap<>();
+    params.put(BtsProperties.URL.getName(), "jira-url");
+    params.put(BtsProperties.PROJECT.getName(), "jira-project");
+    params.put(BtsProperties.AUTH_TYPE.getName(), AuthType.BASIC.name());
+    params.put(BtsProperties.USER_NAME.getName(), "USERNAME");
+    params.put(BtsProperties.PASSWORD.getName(), "PASSWORD");
+    params.put(BtsProperties.OAUTH_ACCESS_KEY.getName(), "KEY");
+
+    return params;
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/integration/util/RallyIntegrationServiceTest.java b/src/test/java/com/epam/ta/reportportal/core/integration/util/RallyIntegrationServiceTest.java
index c69e086135..c63ffb5640 100644
--- a/src/test/java/com/epam/ta/reportportal/core/integration/util/RallyIntegrationServiceTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/integration/util/RallyIntegrationServiceTest.java
@@ -16,9 +16,18 @@
 
 package com.epam.ta.reportportal.core.integration.util;
 
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasSize;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.core.integration.util.property.BtsProperties;
 import com.epam.ta.reportportal.entity.enums.AuthType;
 import com.epam.ta.reportportal.exception.ReportPortalException;
+import java.util.HashMap;
+import java.util.Map;
 import org.jasypt.util.text.BasicTextEncryptor;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
@@ -26,70 +35,64 @@
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.hasSize;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.when;
-
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
  */
 @ExtendWith(MockitoExtension.class)
 class RallyIntegrationServiceTest {
-	private static final String UNSUPPORTED_AUTH_TYPE_NAME = AuthType.NTLM.name();
-
-	@Mock
-	private BasicTextEncryptor encryptor;
-
-	@InjectMocks
-	private BtsIntegrationService btsIntegrationService;
-
-	@Test
-	void testParameters() {
-		when(encryptor.encrypt(any())).thenReturn("encrypted");
-		Map<String, Object> res = btsIntegrationService.retrieveCreateParams("rally", getCorrectRallyIntegrationParams());
-		assertThat(res.keySet(), hasSize(4));
-	}
-
-	@Test
-	void testParametersWithoutKey() {
-		Map<String, Object> params = getCorrectRallyIntegrationParams();
-		params.remove(BtsProperties.OAUTH_ACCESS_KEY.getName());
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> btsIntegrationService.retrieveCreateParams("rally", params)
-		);
-		assertEquals("Impossible interact with integration. AccessKey value is not specified", exception.getMessage());
-	}
-
-	@Test
-	void testParametersUnsupportedAuthType() {
-		Map<String, Object> params = getCorrectRallyIntegrationParams();
-		params.put(BtsProperties.AUTH_TYPE.getName(), UNSUPPORTED_AUTH_TYPE_NAME);
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> btsIntegrationService.retrieveCreateParams("rally", params)
-		);
-		assertEquals(
-				"Impossible interact with integration. Unsupported auth type for integration - " + UNSUPPORTED_AUTH_TYPE_NAME,
-				exception.getMessage()
-		);
-	}
-
-	private Map<String, Object> getCorrectRallyIntegrationParams() {
-
-		Map<String, Object> params = new HashMap<>();
-		params.put(BtsProperties.URL.getName(), "rally-url");
-		params.put(BtsProperties.PROJECT.getName(), "rally-project");
-		params.put(BtsProperties.AUTH_TYPE.getName(), AuthType.OAUTH.name());
-		params.put(BtsProperties.OAUTH_ACCESS_KEY.getName(), "KEY");
-
-		return params;
-	}
+
+  private static final String UNSUPPORTED_AUTH_TYPE_NAME = AuthType.NTLM.name();
+
+  @Mock
+  private BasicTextEncryptor encryptor;
+
+  @InjectMocks
+  private BtsIntegrationService btsIntegrationService;
+
+  @Test
+  void testParameters() {
+    when(encryptor.encrypt(any())).thenReturn("encrypted");
+    Map<String, Object> res = btsIntegrationService.retrieveCreateParams("rally",
+        getCorrectRallyIntegrationParams());
+    assertThat(res.keySet(), hasSize(4));
+  }
+
+  @Test
+  void testParametersWithoutKey() {
+    Map<String, Object> params = getCorrectRallyIntegrationParams();
+    params.remove(BtsProperties.OAUTH_ACCESS_KEY.getName());
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> btsIntegrationService.retrieveCreateParams("rally", params)
+    );
+    assertEquals("Impossible interact with integration. AccessKey value is not specified",
+        exception.getMessage());
+  }
+
+  @Test
+  void testParametersUnsupportedAuthType() {
+    Map<String, Object> params = getCorrectRallyIntegrationParams();
+    params.put(BtsProperties.AUTH_TYPE.getName(), UNSUPPORTED_AUTH_TYPE_NAME);
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> btsIntegrationService.retrieveCreateParams("rally", params)
+    );
+    assertEquals(
+        "Impossible interact with integration. Unsupported auth type for integration - "
+            + UNSUPPORTED_AUTH_TYPE_NAME,
+        exception.getMessage()
+    );
+  }
+
+  private Map<String, Object> getCorrectRallyIntegrationParams() {
+
+    Map<String, Object> params = new HashMap<>();
+    params.put(BtsProperties.URL.getName(), "rally-url");
+    params.put(BtsProperties.PROJECT.getName(), "rally-project");
+    params.put(BtsProperties.AUTH_TYPE.getName(), AuthType.OAUTH.name());
+    params.put(BtsProperties.OAUTH_ACCESS_KEY.getName(), "KEY");
+
+    return params;
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/integration/util/SauceLabsIntegrationServiceTest.java b/src/test/java/com/epam/ta/reportportal/core/integration/util/SauceLabsIntegrationServiceTest.java
index fcf95a8cab..a4a0097c4d 100644
--- a/src/test/java/com/epam/ta/reportportal/core/integration/util/SauceLabsIntegrationServiceTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/integration/util/SauceLabsIntegrationServiceTest.java
@@ -16,9 +16,18 @@
 
 package com.epam.ta.reportportal.core.integration.util;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.core.integration.util.property.SauceLabsProperties;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.google.common.collect.Maps;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
 import org.apache.commons.collections.MapUtils;
 import org.jasypt.util.text.BasicTextEncryptor;
 import org.junit.jupiter.api.Test;
@@ -27,72 +36,70 @@
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.Mockito.when;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @ExtendWith(MockitoExtension.class)
 class SauceLabsIntegrationServiceTest {
 
-	@Mock
-	private BasicTextEncryptor encryptor;
+  @Mock
+  private BasicTextEncryptor encryptor;
 
-	@InjectMocks
-	private SauceLabsIntegrationService sauceLabsIntegrationService;
+  @InjectMocks
+  private SauceLabsIntegrationService sauceLabsIntegrationService;
 
-	@Test
-	void retrieveEmptyParamsTest() {
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> sauceLabsIntegrationService.retrieveCreateParams("saucelabs", Collections.emptyMap())
-		);
-		assertEquals("Error in handled Request. Please, check specified parameters: 'No integration params provided'",
-				exception.getMessage()
-		);
-	}
+  @Test
+  void retrieveEmptyParamsTest() {
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> sauceLabsIntegrationService.retrieveCreateParams("saucelabs", Collections.emptyMap())
+    );
+    assertEquals(
+        "Error in handled Request. Please, check specified parameters: 'No integration params provided'",
+        exception.getMessage()
+    );
+  }
 
-	@Test
-	void retrieveParamsWithoutAccessKeyTest() {
-		HashMap<String, Object> integrationParams = Maps.newHashMap();
-		integrationParams.put(SauceLabsProperties.USERNAME.getName(), "user");
-		ReportPortalException exception = assertThrows(ReportPortalException.class, () -> {
-			sauceLabsIntegrationService.retrieveCreateParams("saucelabs", integrationParams);
-		});
-		assertEquals("Error in handled Request. Please, check specified parameters: 'Access token value is not specified'",
-				exception.getMessage()
-		);
-	}
+  @Test
+  void retrieveParamsWithoutAccessKeyTest() {
+    HashMap<String, Object> integrationParams = Maps.newHashMap();
+    integrationParams.put(SauceLabsProperties.USERNAME.getName(), "user");
+    ReportPortalException exception = assertThrows(ReportPortalException.class, () -> {
+      sauceLabsIntegrationService.retrieveCreateParams("saucelabs", integrationParams);
+    });
+    assertEquals(
+        "Error in handled Request. Please, check specified parameters: 'Access token value is not specified'",
+        exception.getMessage()
+    );
+  }
 
-	@Test
-	void retrieveParamsWithoutUsernameTest() {
-		HashMap<String, Object> integrationParams = Maps.newHashMap();
-		integrationParams.put(SauceLabsProperties.ACCESS_TOKEN.getName(), "token");
-		ReportPortalException exception = assertThrows(ReportPortalException.class, () -> {
-			sauceLabsIntegrationService.retrieveCreateParams("saucelabs", integrationParams);
-		});
-		assertEquals("Error in handled Request. Please, check specified parameters: 'Username value is not specified'", exception.getMessage());
-	}
+  @Test
+  void retrieveParamsWithoutUsernameTest() {
+    HashMap<String, Object> integrationParams = Maps.newHashMap();
+    integrationParams.put(SauceLabsProperties.ACCESS_TOKEN.getName(), "token");
+    ReportPortalException exception = assertThrows(ReportPortalException.class, () -> {
+      sauceLabsIntegrationService.retrieveCreateParams("saucelabs", integrationParams);
+    });
+    assertEquals(
+        "Error in handled Request. Please, check specified parameters: 'Username value is not specified'",
+        exception.getMessage());
+  }
 
-	@Test
-	void retrieveParamsPositiveTest() {
-		final HashMap<String, Object> integrationParams = Maps.newHashMap();
-		integrationParams.put(SauceLabsProperties.USERNAME.getName(), "username");
-		integrationParams.put(SauceLabsProperties.ACCESS_TOKEN.getName(), "token");
-		integrationParams.put("param", "value");
+  @Test
+  void retrieveParamsPositiveTest() {
+    final HashMap<String, Object> integrationParams = Maps.newHashMap();
+    integrationParams.put(SauceLabsProperties.USERNAME.getName(), "username");
+    integrationParams.put(SauceLabsProperties.ACCESS_TOKEN.getName(), "token");
+    integrationParams.put("param", "value");
 
-		final String encryptedToken = "encryptedToken";
-		when(encryptor.encrypt("token")).thenReturn(encryptedToken);
+    final String encryptedToken = "encryptedToken";
+    when(encryptor.encrypt("token")).thenReturn(encryptedToken);
 
-		final Map<String, Object> params = sauceLabsIntegrationService.retrieveCreateParams("saucelabs", integrationParams);
+    final Map<String, Object> params = sauceLabsIntegrationService.retrieveCreateParams("saucelabs",
+        integrationParams);
 
-		assertNotNull(params);
-		assertTrue(MapUtils.isNotEmpty(params));
-		assertEquals(3, params.size());
-		assertEquals(encryptedToken, params.get(SauceLabsProperties.ACCESS_TOKEN.getName()));
-	}
+    assertNotNull(params);
+    assertTrue(MapUtils.isNotEmpty(params));
+    assertEquals(3, params.size());
+    assertEquals(encryptedToken, params.get(SauceLabsProperties.ACCESS_TOKEN.getName()));
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/integration/util/validator/IntegrationValidatorTest.java b/src/test/java/com/epam/ta/reportportal/core/integration/util/validator/IntegrationValidatorTest.java
index 959b8dbd34..16a687238d 100644
--- a/src/test/java/com/epam/ta/reportportal/core/integration/util/validator/IntegrationValidatorTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/integration/util/validator/IntegrationValidatorTest.java
@@ -16,6 +16,9 @@
 
 package com.epam.ta.reportportal.core.integration.util.validator;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
 import com.epam.ta.reportportal.entity.enums.IntegrationGroupEnum;
 import com.epam.ta.reportportal.entity.integration.Integration;
 import com.epam.ta.reportportal.entity.integration.IntegrationType;
@@ -24,68 +27,67 @@
 import com.google.common.collect.Sets;
 import org.junit.jupiter.api.Test;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 class IntegrationValidatorTest {
 
-	@Test
-	void validateNonGlobalIntegration() {
-		Integration integration = new Integration();
-		integration.setId(1L);
-		integration.setProject(new Project());
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> IntegrationValidator.validateProjectLevelIntegrationConstraints(new Project(), integration)
-		);
-		assertEquals("Impossible interact with integration. Integration with ID = '1' is not global.", exception.getMessage());
-	}
+  @Test
+  void validateNonGlobalIntegration() {
+    Integration integration = new Integration();
+    integration.setId(1L);
+    integration.setProject(new Project());
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> IntegrationValidator.validateProjectLevelIntegrationConstraints(new Project(),
+            integration)
+    );
+    assertEquals("Impossible interact with integration. Integration with ID = '1' is not global.",
+        exception.getMessage());
+  }
 
-	@Test
-	void validateIntegrationGroups() {
-		Integration integration = new Integration();
-		integration.setId(1L);
-		IntegrationType type = new IntegrationType();
-		type.setName("jira");
-		type.setIntegrationGroup(IntegrationGroupEnum.BTS);
-		integration.setType(type);
+  @Test
+  void validateIntegrationGroups() {
+    Integration integration = new Integration();
+    integration.setId(1L);
+    IntegrationType type = new IntegrationType();
+    type.setName("jira");
+    type.setIntegrationGroup(IntegrationGroupEnum.BTS);
+    integration.setType(type);
 
-		Project project = new Project();
-		Integration projectIntegration = new Integration();
-		IntegrationType projectIntegrationType = new IntegrationType();
-		projectIntegrationType.setName("jira");
-		projectIntegrationType.setIntegrationGroup(IntegrationGroupEnum.BTS);
-		projectIntegration.setType(projectIntegrationType);
-		project.setIntegrations(Sets.newHashSet(projectIntegration));
+    Project project = new Project();
+    Integration projectIntegration = new Integration();
+    IntegrationType projectIntegrationType = new IntegrationType();
+    projectIntegrationType.setName("jira");
+    projectIntegrationType.setIntegrationGroup(IntegrationGroupEnum.BTS);
+    projectIntegration.setType(projectIntegrationType);
+    project.setIntegrations(Sets.newHashSet(projectIntegration));
 
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> IntegrationValidator.validateProjectLevelIntegrationConstraints(project, integration)
-		);
-		assertEquals(
-				"Impossible interact with integration. Global integration with ID = '1' has been found, but you cannot use it, because you have project-level integration(s) of that type",
-				exception.getMessage()
-		);
-	}
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> IntegrationValidator.validateProjectLevelIntegrationConstraints(project, integration)
+    );
+    assertEquals(
+        "Impossible interact with integration. Global integration with ID = '1' has been found, but you cannot use it, because you have project-level integration(s) of that type",
+        exception.getMessage()
+    );
+  }
 
-	@Test
-	void successfullyValidate() {
-		Integration integration = new Integration();
-		integration.setId(1L);
-		IntegrationType type = new IntegrationType();
-		type.setName("rally");
-		type.setIntegrationGroup(IntegrationGroupEnum.BTS);
-		integration.setType(type);
+  @Test
+  void successfullyValidate() {
+    Integration integration = new Integration();
+    integration.setId(1L);
+    IntegrationType type = new IntegrationType();
+    type.setName("rally");
+    type.setIntegrationGroup(IntegrationGroupEnum.BTS);
+    integration.setType(type);
 
-		Project project = new Project();
-		Integration projectIntegration = new Integration();
-		IntegrationType projectIntegrationType = new IntegrationType();
-		projectIntegrationType.setName("jira");
-		projectIntegrationType.setIntegrationGroup(IntegrationGroupEnum.BTS);
-		projectIntegration.setType(projectIntegrationType);
-		project.setIntegrations(Sets.newHashSet(projectIntegration));
+    Project project = new Project();
+    Integration projectIntegration = new Integration();
+    IntegrationType projectIntegrationType = new IntegrationType();
+    projectIntegrationType.setName("jira");
+    projectIntegrationType.setIntegrationGroup(IntegrationGroupEnum.BTS);
+    projectIntegration.setType(projectIntegrationType);
+    project.setIntegrations(Sets.newHashSet(projectIntegration));
 
-		IntegrationValidator.validateProjectLevelIntegrationConstraints(project, integration);
-	}
+    IntegrationValidator.validateProjectLevelIntegrationConstraints(project, integration);
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/item/impl/DeleteTestItemHandlerImplTest.java b/src/test/java/com/epam/ta/reportportal/core/item/impl/DeleteTestItemHandlerImplTest.java
index ba2d1d8ecb..c5ec0b630e 100644
--- a/src/test/java/com/epam/ta/reportportal/core/item/impl/DeleteTestItemHandlerImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/item/impl/DeleteTestItemHandlerImplTest.java
@@ -16,8 +16,21 @@
 
 package com.epam.ta.reportportal.core.item.impl;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static com.epam.ta.reportportal.util.TestProjectExtractor.extractProjectDetails;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.anyLong;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
+import com.epam.ta.reportportal.core.ElementsCounterService;
 import com.epam.ta.reportportal.core.analyzer.auto.LogIndexer;
+import com.epam.ta.reportportal.core.log.LogService;
 import com.epam.ta.reportportal.core.remover.ContentRemover;
 import com.epam.ta.reportportal.dao.AttachmentRepository;
 import com.epam.ta.reportportal.dao.LaunchRepository;
@@ -31,20 +44,14 @@
 import com.epam.ta.reportportal.entity.user.UserRole;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
+import java.util.Collection;
+import java.util.Optional;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
-
-import java.util.Collection;
-import java.util.Optional;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static com.epam.ta.reportportal.util.TestProjectExtractor.extractProjectDetails;
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.*;
+import org.springframework.context.ApplicationEventPublisher;
 
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
@@ -52,184 +59,203 @@
 @ExtendWith(MockitoExtension.class)
 class DeleteTestItemHandlerImplTest {
 
-	@Mock
-	private TestItemRepository testItemRepository;
-
-	@Mock
-	private ContentRemover<Long> itemContentRemover;
-
-	@Mock
-	private LogIndexer logIndexer;
-
-	@Mock
-	private LaunchRepository launchRepository;
-
-	@Mock
-	private AttachmentRepository attachmentRepository;
-
-	@InjectMocks
-	private DeleteTestItemHandlerImpl handler;
-
-	@Test
-	void testItemNotFound() {
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
-
-		when(testItemRepository.findById(1L)).thenReturn(Optional.empty());
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.deleteTestItem(1L, extractProjectDetails(rpUser, "test_project"), rpUser)
-		);
-		assertEquals("Test Item '1' not found. Did you use correct Test Item ID?", exception.getMessage());
-	}
-
-	@Test
-	void deleteInProgressItem() {
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
-
-		Launch launch = new Launch();
-		launch.setStatus(StatusEnum.PASSED);
-		launch.setProjectId(1L);
-		launch.setUserId(1L);
-
-		when(launchRepository.findById(any(Long.class))).thenReturn(Optional.of(launch));
-		when(testItemRepository.findById(1L)).thenReturn(Optional.of(getTestItem(StatusEnum.IN_PROGRESS,
-				StatusEnum.IN_PROGRESS,
-				1L,
-				"test"
-		)));
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.deleteTestItem(1L, extractProjectDetails(rpUser, "test_project"), rpUser)
-		);
-		assertEquals("Unable to perform operation for non-finished test item. Unable to delete test item ['1'] in progress state",
-				exception.getMessage()
-		);
-	}
-
-	@Test
-	void deleteTestItemWithInProgressLaunch() {
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
-
-		Launch launch = new Launch();
-		launch.setStatus(StatusEnum.IN_PROGRESS);
-		launch.setProjectId(1L);
-		launch.setUserId(1L);
-
-		when(launchRepository.findById(any(Long.class))).thenReturn(Optional.of(launch));
-		when(testItemRepository.findById(1L)).thenReturn(Optional.of(getTestItem(StatusEnum.PASSED, StatusEnum.IN_PROGRESS, 1L, "test")));
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.deleteTestItem(1L, extractProjectDetails(rpUser, "test_project"), rpUser)
-		);
-		assertEquals(
-				"Unable to perform operation for non-finished launch. Unable to delete test item ['1'] under launch ['null'] with 'In progress' state",
-				exception.getMessage()
-		);
-	}
-
-	@Test
-	void deleteTestItemFromAnotherProject() {
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
-
-		Launch launch = new Launch();
-		launch.setStatus(StatusEnum.PASSED);
-		launch.setProjectId(2L);
-		launch.setUserId(1L);
-
-		when(launchRepository.findById(any(Long.class))).thenReturn(Optional.of(launch));
-		when(testItemRepository.findById(1L)).thenReturn(Optional.of(getTestItem(StatusEnum.PASSED, StatusEnum.FAILED, 2L, "test")));
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.deleteTestItem(1L, extractProjectDetails(rpUser, "test_project"), rpUser)
-		);
-		assertEquals("Forbidden operation. Deleting testItem '1' is not under specified project '1'", exception.getMessage());
-	}
-
-	@Test
-	void deleteNotOwnTestItem() {
-		final ReportPortalUser rpUser = getRpUser("not owner", UserRole.USER, ProjectRole.MEMBER, 1L);
-		rpUser.setUserId(2L);
-
-		Launch launch = new Launch();
-		launch.setStatus(StatusEnum.PASSED);
-		launch.setProjectId(1L);
-		launch.setUserId(1L);
-
-		when(testItemRepository.findById(1L)).thenReturn(Optional.of(getTestItem(StatusEnum.PASSED, StatusEnum.FAILED, 1L, "owner")));
-		when(launchRepository.findById(any(Long.class))).thenReturn(Optional.of(launch));
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.deleteTestItem(1L, extractProjectDetails(rpUser, "test_project"), rpUser)
-		);
-		assertEquals("You do not have enough permissions. You are not a launch owner.", exception.getMessage());
-	}
-
-	@Test
-	void deleteTestItemWithParent() {
-		ReportPortalUser rpUser = getRpUser("owner", UserRole.ADMINISTRATOR, ProjectRole.MEMBER, 1L);
-
-		TestItem item = getTestItem(StatusEnum.PASSED, StatusEnum.PASSED, 1L, "owner");
-		item.setItemId(123123L);
-		TestItem parent = new TestItem();
-		long parentId = 35L;
-		parent.setItemId(parentId);
-		String path = "1.2.3";
-		parent.setPath(path);
-		item.setParentId(parent.getItemId());
-
-		Launch launch = new Launch();
-		launch.setStatus(StatusEnum.PASSED);
-		launch.setProjectId(1L);
-		launch.setUserId(1L);
-
-		item.setLaunchId(launch.getId());
-		when(launchRepository.findById(item.getLaunchId())).thenReturn(Optional.of(launch));
-		when(testItemRepository.findById(1L)).thenReturn(Optional.of(item));
-		when(testItemRepository.findById(parentId)).thenReturn(Optional.of(parent));
-		when(testItemRepository.hasChildren(parent.getItemId(), parent.getPath())).thenReturn(false);
-		when(launchRepository.hasRetries(any())).thenReturn(false);
-		when(attachmentRepository.moveForDeletionByItems(any(Collection.class))).thenReturn(1);
-		handler.deleteTestItem(1L, extractProjectDetails(rpUser, "test_project"), rpUser);
-
-		verify(itemContentRemover,times(1)).remove(anyLong());
-		assertFalse(parent.isHasChildren());
-	}
-
-	@Test
-	void deleteItemPositive() {
-		ReportPortalUser rpUser = getRpUser("owner", UserRole.ADMINISTRATOR, ProjectRole.MEMBER, 1L);
-		TestItem item = getTestItem(StatusEnum.FAILED, StatusEnum.FAILED, 1L, "owner");
-
-		Launch launch = new Launch();
-		launch.setStatus(StatusEnum.FAILED);
-		launch.setProjectId(1L);
-		launch.setUserId(1L);
-
-		when(testItemRepository.findById(item.getItemId())).thenReturn(Optional.of(item));
-		when(launchRepository.findById(any(Long.class))).thenReturn(Optional.of(launch));
-
-		OperationCompletionRS response = handler.deleteTestItem(1L, extractProjectDetails(rpUser, "test_project"), rpUser);
-
-		verify(itemContentRemover,times(1)).remove(anyLong());
-		assertEquals("Test Item with ID = '1' has been successfully deleted.", response.getResultMessage());
-
-	}
-
-	private TestItem getTestItem(StatusEnum itemStatus, StatusEnum launchStatus, Long projectId, String owner) {
-		TestItem item = new TestItem();
-		item.setItemId(1L);
-		TestItemResults results = new TestItemResults();
-		results.setStatus(itemStatus);
-		item.setItemResults(results);
-		Launch launch = new Launch();
-		launch.setId(1L);
-		launch.setStatus(launchStatus);
-		launch.setProjectId(projectId);
-		User user = new User();
-		user.setId(1L);
-		user.setLogin(owner);
-		launch.setUserId(user.getId());
-		item.setLaunchId(launch.getId());
-		return item;
-	}
+  @Mock
+  private TestItemRepository testItemRepository;
+
+  @Mock
+  private ContentRemover<Long> itemContentRemover;
+
+  @Mock
+  private LogIndexer logIndexer;
+
+  @Mock
+  private ElementsCounterService elementsCounterService;
+
+  @Mock
+  private ApplicationEventPublisher eventPublisher;
+
+  @Mock
+  private LaunchRepository launchRepository;
+
+  @Mock
+  private AttachmentRepository attachmentRepository;
+
+  @Mock
+  private LogService logService;
+
+  @InjectMocks
+  private DeleteTestItemHandlerImpl handler;
+
+  @Test
+  void testItemNotFound() {
+    final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
+
+    when(testItemRepository.findById(1L)).thenReturn(Optional.empty());
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.deleteTestItem(1L, extractProjectDetails(rpUser, "test_project"), rpUser)
+    );
+    assertEquals("Test Item '1' not found. Did you use correct Test Item ID?",
+        exception.getMessage());
+  }
+
+  @Test
+  void deleteInProgressItem() {
+    final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
+
+    Launch launch = new Launch();
+    launch.setStatus(StatusEnum.PASSED);
+    launch.setProjectId(1L);
+    launch.setUserId(1L);
+
+    when(launchRepository.findById(any(Long.class))).thenReturn(Optional.of(launch));
+    when(testItemRepository.findById(1L)).thenReturn(Optional.of(getTestItem(StatusEnum.IN_PROGRESS,
+        StatusEnum.IN_PROGRESS,
+        1L,
+        "test"
+    )));
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.deleteTestItem(1L, extractProjectDetails(rpUser, "test_project"), rpUser)
+    );
+    assertEquals(
+        "Unable to perform operation for non-finished test item. Unable to delete test item ['1'] in progress state",
+        exception.getMessage()
+    );
+  }
+
+  @Test
+  void deleteTestItemWithInProgressLaunch() {
+    final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
+
+    Launch launch = new Launch();
+    launch.setStatus(StatusEnum.IN_PROGRESS);
+    launch.setProjectId(1L);
+    launch.setUserId(1L);
+
+    when(launchRepository.findById(any(Long.class))).thenReturn(Optional.of(launch));
+    when(testItemRepository.findById(1L)).thenReturn(
+        Optional.of(getTestItem(StatusEnum.PASSED, StatusEnum.IN_PROGRESS, 1L, "test")));
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.deleteTestItem(1L, extractProjectDetails(rpUser, "test_project"), rpUser)
+    );
+    assertEquals(
+        "Unable to perform operation for non-finished launch. Unable to delete test item ['1'] under launch ['null'] with 'In progress' state",
+        exception.getMessage()
+    );
+  }
+
+  @Test
+  void deleteTestItemFromAnotherProject() {
+    final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
+
+    Launch launch = new Launch();
+    launch.setStatus(StatusEnum.PASSED);
+    launch.setProjectId(2L);
+    launch.setUserId(1L);
+
+    when(launchRepository.findById(any(Long.class))).thenReturn(Optional.of(launch));
+    when(testItemRepository.findById(1L)).thenReturn(
+        Optional.of(getTestItem(StatusEnum.PASSED, StatusEnum.FAILED, 2L, "test")));
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.deleteTestItem(1L, extractProjectDetails(rpUser, "test_project"), rpUser)
+    );
+    assertEquals("Forbidden operation. Deleting testItem '1' is not under specified project '1'",
+        exception.getMessage());
+  }
+
+  @Test
+  void deleteNotOwnTestItem() {
+    final ReportPortalUser rpUser = getRpUser("not owner", UserRole.USER, ProjectRole.MEMBER, 1L);
+    rpUser.setUserId(2L);
+
+    Launch launch = new Launch();
+    launch.setStatus(StatusEnum.PASSED);
+    launch.setProjectId(1L);
+    launch.setUserId(1L);
+
+    when(testItemRepository.findById(1L)).thenReturn(
+        Optional.of(getTestItem(StatusEnum.PASSED, StatusEnum.FAILED, 1L, "owner")));
+    when(launchRepository.findById(any(Long.class))).thenReturn(Optional.of(launch));
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.deleteTestItem(1L, extractProjectDetails(rpUser, "test_project"), rpUser)
+    );
+    assertEquals("You do not have enough permissions. You are not a launch owner.",
+        exception.getMessage());
+  }
+
+  @Test
+  void deleteTestItemWithParent() {
+    ReportPortalUser rpUser = getRpUser("owner", UserRole.ADMINISTRATOR, ProjectRole.MEMBER, 1L);
+
+    TestItem item = getTestItem(StatusEnum.PASSED, StatusEnum.PASSED, 1L, "owner");
+    item.setItemId(123123L);
+    TestItem parent = new TestItem();
+    long parentId = 35L;
+    parent.setItemId(parentId);
+    String path = "1.2.3";
+    parent.setPath(path);
+    item.setParentId(parent.getItemId());
+
+    Launch launch = new Launch();
+    launch.setStatus(StatusEnum.PASSED);
+    launch.setProjectId(1L);
+    launch.setUserId(1L);
+
+    item.setLaunchId(launch.getId());
+    when(launchRepository.findById(item.getLaunchId())).thenReturn(Optional.of(launch));
+    when(testItemRepository.findById(1L)).thenReturn(Optional.of(item));
+    when(testItemRepository.findById(parentId)).thenReturn(Optional.of(parent));
+    when(testItemRepository.hasChildren(parent.getItemId(), parent.getPath())).thenReturn(false);
+    when(launchRepository.hasRetries(any())).thenReturn(false);
+    when(attachmentRepository.moveForDeletionByItems(any(Collection.class))).thenReturn(1);
+    handler.deleteTestItem(1L, extractProjectDetails(rpUser, "test_project"), rpUser);
+
+    verify(itemContentRemover, times(1)).remove(anyLong());
+    assertFalse(parent.isHasChildren());
+  }
+
+  @Test
+  void deleteItemPositive() {
+    ReportPortalUser rpUser = getRpUser("owner", UserRole.ADMINISTRATOR, ProjectRole.MEMBER, 1L);
+    TestItem item = getTestItem(StatusEnum.FAILED, StatusEnum.FAILED, 1L, "owner");
+
+    Launch launch = new Launch();
+    launch.setStatus(StatusEnum.FAILED);
+    launch.setProjectId(1L);
+    launch.setUserId(1L);
+
+    when(testItemRepository.findById(item.getItemId())).thenReturn(Optional.of(item));
+    when(launchRepository.findById(any(Long.class))).thenReturn(Optional.of(launch));
+
+    OperationCompletionRS response = handler.deleteTestItem(1L,
+        extractProjectDetails(rpUser, "test_project"), rpUser);
+
+    verify(itemContentRemover, times(1)).remove(anyLong());
+    assertEquals("Test Item with ID = '1' has been successfully deleted.",
+        response.getResultMessage());
+
+  }
+
+  private TestItem getTestItem(StatusEnum itemStatus, StatusEnum launchStatus, Long projectId,
+      String owner) {
+    TestItem item = new TestItem();
+    item.setItemId(1L);
+    TestItemResults results = new TestItemResults();
+    results.setStatus(itemStatus);
+    item.setItemResults(results);
+    Launch launch = new Launch();
+    launch.setId(1L);
+    launch.setStatus(launchStatus);
+    launch.setProjectId(projectId);
+    User user = new User();
+    user.setId(1L);
+    user.setLogin(owner);
+    launch.setUserId(user.getId());
+    item.setLaunchId(launch.getId());
+    return item;
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/item/impl/FinishTestItemHandlerAsyncImplTest.java b/src/test/java/com/epam/ta/reportportal/core/item/impl/FinishTestItemHandlerAsyncImplTest.java
index cd84ff52d7..33f8e82dc5 100644
--- a/src/test/java/com/epam/ta/reportportal/core/item/impl/FinishTestItemHandlerAsyncImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/item/impl/FinishTestItemHandlerAsyncImplTest.java
@@ -16,12 +16,19 @@
 
 package com.epam.ta.reportportal.core.item.impl;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.verify;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.entity.project.ProjectRole;
 import com.epam.ta.reportportal.entity.user.UserRole;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.util.ReportingQueueService;
 import com.epam.ta.reportportal.ws.model.FinishTestItemRQ;
+import java.util.UUID;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.InjectMocks;
@@ -29,14 +36,6 @@
 import org.mockito.junit.jupiter.MockitoExtension;
 import org.springframework.amqp.core.AmqpTemplate;
 
-import java.util.UUID;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.verify;
-
 /**
  * @author Konstantin Antipin
  */
@@ -44,38 +43,42 @@
 @ExtendWith(MockitoExtension.class)
 class FinishTestItemHandlerAsyncImplTest {
 
-	@Mock
-	AmqpTemplate amqpTemplate;
+  @Mock
+  AmqpTemplate amqpTemplate;
 
-	@Mock
-	ReportingQueueService reportingQueueService;
+  @Mock
+  ReportingQueueService reportingQueueService;
 
-	@InjectMocks
-	FinishTestItemHandlerAsyncImpl finishTestItemHandlerAsync;
+  @InjectMocks
+  FinishTestItemHandlerAsyncImpl finishTestItemHandlerAsync;
 
-	@Test
-	void finishTestItem() {
-		FinishTestItemRQ request = new FinishTestItemRQ();
-		request.setLaunchUuid(UUID.randomUUID().toString());
-		ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
+  @Test
+  void finishTestItem() {
+    FinishTestItemRQ request = new FinishTestItemRQ();
+    request.setLaunchUuid(UUID.randomUUID().toString());
+    ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER,
+        1L);
 
-		finishTestItemHandlerAsync.finishTestItem(user, user.getProjectDetails().get("test_project"), "123", request);
-		verify(amqpTemplate).convertAndSend(any(), any(), any(), any());
-		verify(reportingQueueService).getReportingQueueKey(any());
-	}
+    finishTestItemHandlerAsync.finishTestItem(user, user.getProjectDetails().get("test_project"),
+        "123", request);
+    verify(amqpTemplate).convertAndSend(any(), any(), any(), any());
+    verify(reportingQueueService).getReportingQueueKey(any());
+  }
 
-	@Test
-	void finishTestItemWithoutLaunchUuid() {
-		FinishTestItemRQ request = new FinishTestItemRQ();
-		ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
+  @Test
+  void finishTestItemWithoutLaunchUuid() {
+    FinishTestItemRQ request = new FinishTestItemRQ();
+    ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER,
+        1L);
 
-		ReportPortalException exception = assertThrows(
-				ReportPortalException.class,
-				() -> finishTestItemHandlerAsync.finishTestItem(user, user.getProjectDetails().get("test_project"), "123", request)
-		);
-		assertEquals(
-				"Error in handled Request. Please, check specified parameters: 'Launch UUID should not be null or empty.'",
-				exception.getMessage()
-		);
-	}
+    ReportPortalException exception = assertThrows(
+        ReportPortalException.class,
+        () -> finishTestItemHandlerAsync.finishTestItem(user,
+            user.getProjectDetails().get("test_project"), "123", request)
+    );
+    assertEquals(
+        "Error in handled Request. Please, check specified parameters: 'Launch UUID should not be null or empty.'",
+        exception.getMessage()
+    );
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/item/impl/FinishTestItemHandlerImplTest.java b/src/test/java/com/epam/ta/reportportal/core/item/impl/FinishTestItemHandlerImplTest.java
index 7384da4ea3..6f7c209483 100644
--- a/src/test/java/com/epam/ta/reportportal/core/item/impl/FinishTestItemHandlerImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/item/impl/FinishTestItemHandlerImplTest.java
@@ -16,9 +16,19 @@
 
 package com.epam.ta.reportportal.core.item.impl;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static com.epam.ta.reportportal.util.TestProjectExtractor.extractProjectDetails;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.events.MessageBus;
-import com.epam.ta.reportportal.core.events.activity.item.ItemFinishedEvent;
+import com.epam.ta.reportportal.core.events.activity.item.IssueResolvedEvent;
 import com.epam.ta.reportportal.core.item.impl.status.StatusChangingStrategy;
 import com.epam.ta.reportportal.dao.IssueEntityRepository;
 import com.epam.ta.reportportal.dao.LaunchRepository;
@@ -36,6 +46,10 @@
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.FinishTestItemRQ;
 import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
+import java.time.LocalDateTime;
+import java.util.Date;
+import java.util.Map;
+import java.util.Optional;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.InjectMocks;
@@ -43,180 +57,175 @@
 import org.mockito.junit.jupiter.MockitoExtension;
 import org.springframework.context.ApplicationEventPublisher;
 
-import java.time.LocalDateTime;
-import java.util.Date;
-import java.util.Map;
-import java.util.Optional;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static com.epam.ta.reportportal.util.TestProjectExtractor.extractProjectDetails;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.*;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @ExtendWith(MockitoExtension.class)
 class FinishTestItemHandlerImplTest {
 
-	@Mock
-	private TestItemRepository repository;
-
-	@Mock
-	private LaunchRepository launchRepository;
-
-	@Mock
-	private IssueTypeHandler issueTypeHandler;
-
-	@Mock
-	private Map<StatusEnum, StatusChangingStrategy> statusChangingStrategyMapping;
-
-	@Mock
-	private StatusChangingStrategy statusChangingStrategy;
-
-	@Mock
-	private IssueEntityRepository issueEntityRepository;
-
-	@Mock
-	private MessageBus messageBus;
-
-	@Mock
-	private ApplicationEventPublisher eventPublisher;
-
-	@InjectMocks
-	private FinishTestItemHandlerImpl handler;
-
-	@Test
-	void finishNotExistedTestItem() {
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
-		when(repository.findByUuid("1")).thenReturn(Optional.empty());
-		final ReportPortalException exception = assertThrows(
-				ReportPortalException.class,
-				() -> handler.finishTestItem(rpUser, extractProjectDetails(rpUser, "test_project"), "1", new FinishTestItemRQ())
-		);
-		assertEquals("Test Item '1' not found. Did you use correct Test Item ID?", exception.getMessage());
-	}
-
-	@Test
-	void finishTestItemUnderNotExistedLaunch() {
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
-		TestItem item = new TestItem();
-		TestItemResults results = new TestItemResults();
-		results.setStatus(StatusEnum.IN_PROGRESS);
-		item.setItemResults(results);
-		item.setItemId(1L);
-		when(repository.findByUuid("1")).thenReturn(Optional.of(item));
-
-		final ReportPortalException exception = assertThrows(
-				ReportPortalException.class,
-				() -> handler.finishTestItem(rpUser, extractProjectDetails(rpUser, "test_project"), "1", new FinishTestItemRQ())
-		);
-		assertEquals("Launch '' not found. Did you use correct Launch ID?", exception.getMessage());
-	}
-
-	@Test
-	void finishTestItemByNotLaunchOwner() {
-		final ReportPortalUser rpUser = getRpUser("not owner", UserRole.USER, ProjectRole.MEMBER, 1L);
-		TestItem item = new TestItem();
-		Launch launch = new Launch();
-		launch.setId(1L);
-		launch.setProjectId(1L);
-		User user = new User();
-		user.setId(2L);
-		user.setLogin("owner");
-		launch.setUserId(user.getId());
-		item.setItemId(1L);
-		item.setLaunchId(launch.getId());
-		item.setHasChildren(false);
-		when(repository.findByUuid("1")).thenReturn(Optional.of(item));
-		TestItemResults results = new TestItemResults();
-		results.setStatus(StatusEnum.IN_PROGRESS);
-		item.setItemResults(results);
-		item.setItemId(1L);
-		when(launchRepository.findById(any())).thenReturn(Optional.of(launch));
-
-
-		final ReportPortalException exception = assertThrows(
-				ReportPortalException.class,
-				() -> handler.finishTestItem(rpUser, extractProjectDetails(rpUser, "test_project"), "1", new FinishTestItemRQ())
-		);
-		assertEquals("Finish test item is not allowed. You are not a launch owner.", exception.getMessage());
-	}
-
-	@Test
-	void finishStepItemWithoutProvidedStatus() {
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
-		TestItem item = new TestItem();
-		item.setItemId(1L);
-		TestItemResults results = new TestItemResults();
-		results.setStatus(StatusEnum.IN_PROGRESS);
-		item.setItemResults(results);
-		Launch launch = new Launch();
-		launch.setId(1L);
-		launch.setUserId(1L);
-		launch.setProjectId(1L);
-		item.setLaunchId(launch.getId());
-		item.setHasChildren(false);
-		when(repository.findByUuid("1")).thenReturn(Optional.of(item));
-		when(launchRepository.findById(any())).thenReturn(Optional.of(launch));
-
-		final ReportPortalException exception = assertThrows(
-				ReportPortalException.class,
-				() -> handler.finishTestItem(rpUser, extractProjectDetails(rpUser, "test_project"), "1", new FinishTestItemRQ())
-		);
-		assertEquals(
-				"Test item status is ambiguous. There is no status provided from request and there are no descendants to check statistics for test item id '1'",
-				exception.getMessage()
-		);
-	}
-
-	@Test
-	void updateFinishedItemTest() {
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
-		TestItem item = new TestItem();
-		item.setItemId(1L);
-		TestItemResults results = new TestItemResults();
-		results.setStatus(StatusEnum.PASSED);
-		item.setItemResults(results);
-		Launch launch = new Launch();
-		launch.setId(1L);
-		launch.setUserId(1L);
-		launch.setProjectId(1L);
-		item.setStartTime(LocalDateTime.now().minusSeconds(5L));
-		item.setLaunchId(launch.getId());
-		item.setType(TestItemTypeEnum.STEP);
-		item.setHasStats(true);
-		item.setHasChildren(false);
-		when(launchRepository.findById(any())).thenReturn(Optional.of(launch));
-		when(repository.findByUuid("1")).thenReturn(Optional.of(item));
-		when(repository.findIdByUuidForUpdate(any())).thenReturn(Optional.of(item.getItemId()));
-		when(repository.findById(item.getItemId())).thenReturn(Optional.of(item));
-
-		IssueType issueType = new IssueType();
-		issueType.setLocator("123");
-		issueType.setIssueGroup(new IssueGroup());
-		issueType.setLongName("123123");
-		issueType.setHexColor("#1232asd");
-		issueType.setShortName("short");
-
-		when(issueTypeHandler.defineIssueType(any(), any())).thenReturn(issueType);
-		when(statusChangingStrategyMapping.get(any(StatusEnum.class))).thenReturn(statusChangingStrategy);
-
-		FinishTestItemRQ finishExecutionRQ = new FinishTestItemRQ();
-		finishExecutionRQ.setStatus("FAILED");
-		finishExecutionRQ.setEndTime(new Date());
-
-		OperationCompletionRS operationCompletionRS = handler.finishTestItem(rpUser,
-				extractProjectDetails(rpUser, "test_project"),
-				"1",
-				finishExecutionRQ
-		);
-
-		verify(statusChangingStrategy, times(1)).changeStatus(any(), any(), any());
-		verify(issueEntityRepository, times(1)).save(any());
-		verify(messageBus, times(1)).publishActivity(any());
-		verify(eventPublisher, times(1)).publishEvent(any(ItemFinishedEvent.class));
-	}
+  @Mock
+  private TestItemRepository repository;
+
+  @Mock
+  private LaunchRepository launchRepository;
+
+  @Mock
+  private IssueTypeHandler issueTypeHandler;
+
+  @Mock
+  private Map<StatusEnum, StatusChangingStrategy> statusChangingStrategyMapping;
+
+  @Mock
+  private StatusChangingStrategy statusChangingStrategy;
+
+  @Mock
+  private IssueEntityRepository issueEntityRepository;
+
+  @Mock
+  private MessageBus messageBus;
+
+  @Mock
+  private ApplicationEventPublisher eventPublisher;
+
+  @InjectMocks
+  private FinishTestItemHandlerImpl handler;
+
+  @Test
+  void finishNotExistedTestItem() {
+    final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
+    when(repository.findByUuid("1")).thenReturn(Optional.empty());
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.finishTestItem(rpUser, extractProjectDetails(rpUser, "test_project"), "1",
+            new FinishTestItemRQ()
+        )
+    );
+    assertEquals("Test Item '1' not found. Did you use correct Test Item ID?",
+        exception.getMessage()
+    );
+  }
+
+  @Test
+  void finishTestItemUnderNotExistedLaunch() {
+    final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
+    TestItem item = new TestItem();
+    TestItemResults results = new TestItemResults();
+    results.setStatus(StatusEnum.IN_PROGRESS);
+    item.setItemResults(results);
+    item.setItemId(1L);
+    when(repository.findByUuid("1")).thenReturn(Optional.of(item));
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.finishTestItem(rpUser, extractProjectDetails(rpUser, "test_project"), "1",
+            new FinishTestItemRQ()
+        )
+    );
+    assertEquals("Launch '' not found. Did you use correct Launch ID?", exception.getMessage());
+  }
+
+  @Test
+  void finishTestItemByNotLaunchOwner() {
+    final ReportPortalUser rpUser = getRpUser("not owner", UserRole.USER, ProjectRole.MEMBER, 1L);
+    TestItem item = new TestItem();
+    Launch launch = new Launch();
+    launch.setId(1L);
+    launch.setProjectId(1L);
+    User user = new User();
+    user.setId(2L);
+    user.setLogin("owner");
+    launch.setUserId(user.getId());
+    item.setItemId(1L);
+    item.setLaunchId(launch.getId());
+    item.setHasChildren(false);
+    when(repository.findByUuid("1")).thenReturn(Optional.of(item));
+    TestItemResults results = new TestItemResults();
+    results.setStatus(StatusEnum.IN_PROGRESS);
+    item.setItemResults(results);
+    item.setItemId(1L);
+    when(launchRepository.findById(any())).thenReturn(Optional.of(launch));
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.finishTestItem(rpUser, extractProjectDetails(rpUser, "test_project"), "1",
+            new FinishTestItemRQ()
+        )
+    );
+    assertEquals("Finish test item is not allowed. You are not a launch owner.",
+        exception.getMessage()
+    );
+  }
+
+  @Test
+  void finishStepItemWithoutProvidedStatus() {
+    final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
+    TestItem item = new TestItem();
+    item.setItemId(1L);
+    TestItemResults results = new TestItemResults();
+    results.setStatus(StatusEnum.IN_PROGRESS);
+    item.setItemResults(results);
+    Launch launch = new Launch();
+    launch.setId(1L);
+    launch.setUserId(1L);
+    launch.setProjectId(1L);
+    item.setLaunchId(launch.getId());
+    item.setHasChildren(false);
+    when(repository.findByUuid("1")).thenReturn(Optional.of(item));
+    when(launchRepository.findById(any())).thenReturn(Optional.of(launch));
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.finishTestItem(rpUser, extractProjectDetails(rpUser, "test_project"), "1",
+            new FinishTestItemRQ()
+        )
+    );
+    assertEquals(
+        "Test item status is ambiguous. There is no status provided from request and there are no descendants to check statistics for test item id '1'",
+        exception.getMessage()
+    );
+  }
+
+  @Test
+  void updateFinishedItemTest() {
+    final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
+    TestItem item = new TestItem();
+    item.setItemId(1L);
+    TestItemResults results = new TestItemResults();
+    results.setStatus(StatusEnum.PASSED);
+    item.setItemResults(results);
+    Launch launch = new Launch();
+    launch.setId(1L);
+    launch.setUserId(1L);
+    launch.setProjectId(1L);
+    item.setStartTime(LocalDateTime.now().minusSeconds(5L));
+    item.setLaunchId(launch.getId());
+    item.setType(TestItemTypeEnum.STEP);
+    item.setHasStats(true);
+    item.setHasChildren(false);
+    when(launchRepository.findById(any())).thenReturn(Optional.of(launch));
+    when(repository.findByUuid("1")).thenReturn(Optional.of(item));
+    when(repository.findIdByUuidForUpdate(any())).thenReturn(Optional.of(item.getItemId()));
+    when(repository.findById(item.getItemId())).thenReturn(Optional.of(item));
+
+    IssueType issueType = new IssueType();
+    issueType.setLocator("123");
+    issueType.setIssueGroup(new IssueGroup());
+    issueType.setLongName("123123");
+    issueType.setHexColor("#1232asd");
+    issueType.setShortName("short");
+
+    when(issueTypeHandler.defineIssueType(any(), any())).thenReturn(issueType);
+    when(statusChangingStrategyMapping.get(any(StatusEnum.class))).thenReturn(
+        statusChangingStrategy);
+
+    FinishTestItemRQ finishExecutionRQ = new FinishTestItemRQ();
+    finishExecutionRQ.setStatus("FAILED");
+    finishExecutionRQ.setEndTime(new Date());
+
+    OperationCompletionRS operationCompletionRS =
+        handler.finishTestItem(rpUser, extractProjectDetails(rpUser, "test_project"), "1",
+            finishExecutionRQ
+        );
+
+    verify(statusChangingStrategy, times(1)).changeStatus(any(), any(), any(), eq(false));
+    verify(issueEntityRepository, times(1)).save(any());
+    verify(messageBus, times(1)).publishActivity(any());
+    verify(eventPublisher, times(1)).publishEvent(any(IssueResolvedEvent.class));
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/item/impl/IssueTypeHandlerTest.java b/src/test/java/com/epam/ta/reportportal/core/item/impl/IssueTypeHandlerTest.java
index 3e3495d63a..70ea7275b1 100644
--- a/src/test/java/com/epam/ta/reportportal/core/item/impl/IssueTypeHandlerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/item/impl/IssueTypeHandlerTest.java
@@ -16,53 +16,54 @@
 
 package com.epam.ta.reportportal.core.item.impl;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.dao.TestItemRepository;
 import com.epam.ta.reportportal.entity.item.issue.IssueType;
 import com.epam.ta.reportportal.exception.ReportPortalException;
+import java.util.Collections;
+import java.util.Optional;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 
-import java.util.Collections;
-import java.util.Optional;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.Mockito.when;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @ExtendWith(MockitoExtension.class)
 class IssueTypeHandlerTest {
 
-	@Mock
-	private TestItemRepository testItemRepository;
+  @Mock
+  private TestItemRepository testItemRepository;
 
-	@InjectMocks
-	private IssueTypeHandler issueTypeHandler;
+  @InjectMocks
+  private IssueTypeHandler issueTypeHandler;
 
-	@Test
-	void defineIssueTypeWithNullLocator() {
-		ReportPortalException exception = assertThrows(ReportPortalException.class, () -> issueTypeHandler.defineIssueType(1L, null));
-		assertEquals("Locator should not be null", exception.getMessage());
-	}
+  @Test
+  void defineIssueTypeWithNullLocator() {
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> issueTypeHandler.defineIssueType(1L, null));
+    assertEquals("Locator should not be null", exception.getMessage());
+  }
 
-	@Test
-	void defineNotExistIssueType() {
-		when(testItemRepository.selectIssueTypeByLocator(2L, "not_exist")).thenReturn(Optional.empty());
-		IssueType issueType = new IssueType();
-		issueType.setLocator("exists");
-		when(testItemRepository.selectIssueLocatorsByProject(2L)).thenReturn(Collections.singletonList(issueType));
+  @Test
+  void defineNotExistIssueType() {
+    when(testItemRepository.selectIssueTypeByLocator(2L, "not_exist")).thenReturn(Optional.empty());
+    IssueType issueType = new IssueType();
+    issueType.setLocator("exists");
+    when(testItemRepository.selectIssueLocatorsByProject(2L)).thenReturn(
+        Collections.singletonList(issueType));
 
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> issueTypeHandler.defineIssueType(2L, "not_exist")
-		);
-		assertEquals(
-				"Test items issue type cannot be resolved. Invalid test item issue type definition 'not_exist' is requested. Valid issue types' locators are: [exists]",
-				exception.getMessage()
-		);
-	}
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> issueTypeHandler.defineIssueType(2L, "not_exist")
+    );
+    assertEquals(
+        "Test items issue type cannot be resolved. Invalid test item issue type definition 'not_exist' is requested. Valid issue types' locators are: [exists]",
+        exception.getMessage()
+    );
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/item/impl/LaunchAccessValidatorImplTest.java b/src/test/java/com/epam/ta/reportportal/core/item/impl/LaunchAccessValidatorImplTest.java
index a19a809773..429b0271d9 100644
--- a/src/test/java/com/epam/ta/reportportal/core/item/impl/LaunchAccessValidatorImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/item/impl/LaunchAccessValidatorImplTest.java
@@ -16,6 +16,12 @@
 
 package com.epam.ta.reportportal.core.item.impl;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static com.epam.ta.reportportal.util.TestProjectExtractor.extractProjectDetails;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.dao.LaunchRepository;
 import com.epam.ta.reportportal.entity.enums.LaunchModeEnum;
@@ -24,6 +30,7 @@
 import com.epam.ta.reportportal.entity.project.ProjectRole;
 import com.epam.ta.reportportal.entity.user.UserRole;
 import com.epam.ta.reportportal.exception.ReportPortalException;
+import java.util.Optional;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.junit.jupiter.api.function.Executable;
@@ -31,73 +38,69 @@
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 
-import java.util.Optional;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static com.epam.ta.reportportal.util.TestProjectExtractor.extractProjectDetails;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.Mockito.when;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @ExtendWith(MockitoExtension.class)
 class LaunchAccessValidatorImplTest {
 
-	@Mock
-	private LaunchRepository launchRepository;
-
-	@InjectMocks
-	private LaunchAccessValidatorImpl launchAccessValidator;
-
-	@Test
-	void validateNotExistingLaunch() {
-
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
-		Launch launch = new Launch();
-		launch.setId(1L);
-		when(launchRepository.findById(1L)).thenReturn(Optional.empty());
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> launchAccessValidator.validate(1L, extractProjectDetails(rpUser, "test_project"), rpUser)
-		);
-		assertEquals("Launch '1' not found. Did you use correct Launch ID?", exception.getMessage());
-	}
-
-	@Test
-	void validateLaunchUnderAnotherProject() {
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
-
-		TestItem item = new TestItem();
-		Launch launch = new Launch();
-		launch.setId(1L);
-		launch.setProjectId(2L);
-		item.setLaunchId(launch.getId());
-		when(launchRepository.findById(1L)).thenReturn(Optional.of(launch));
-
-		final Executable executable = () -> launchAccessValidator.validate(1L, extractProjectDetails(rpUser, "test_project"), rpUser);
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class, executable);
-		assertEquals("Forbidden operation. Specified launch with id '1' not referenced to specified project with id '1'",
-				exception.getMessage()
-		);
-	}
-
-	@Test
-	void validateLaunchWithOperatorRole() {
-		ReportPortalUser operator = getRpUser("operator", UserRole.USER, ProjectRole.OPERATOR, 1L);
-
-		Launch launch = new Launch();
-		launch.setId(1L);
-		launch.setMode(LaunchModeEnum.DEBUG);
-		launch.setProjectId(1L);
-
-		when(launchRepository.findById(1L)).thenReturn(Optional.of(launch));
-
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> launchAccessValidator.validate(1L, extractProjectDetails(operator, "test_project"), operator)
-		);
-		assertEquals("You do not have enough permissions.", exception.getMessage());
-	}
+  @Mock
+  private LaunchRepository launchRepository;
+
+  @InjectMocks
+  private LaunchAccessValidatorImpl launchAccessValidator;
+
+  @Test
+  void validateNotExistingLaunch() {
+
+    final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
+    Launch launch = new Launch();
+    launch.setId(1L);
+    when(launchRepository.findById(1L)).thenReturn(Optional.empty());
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> launchAccessValidator.validate(1L, extractProjectDetails(rpUser, "test_project"),
+            rpUser)
+    );
+    assertEquals("Launch '1' not found. Did you use correct Launch ID?", exception.getMessage());
+  }
+
+  @Test
+  void validateLaunchUnderAnotherProject() {
+    final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
+
+    TestItem item = new TestItem();
+    Launch launch = new Launch();
+    launch.setId(1L);
+    launch.setProjectId(2L);
+    item.setLaunchId(launch.getId());
+    when(launchRepository.findById(1L)).thenReturn(Optional.of(launch));
+
+    final Executable executable = () -> launchAccessValidator.validate(1L,
+        extractProjectDetails(rpUser, "test_project"), rpUser);
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class, executable);
+    assertEquals(
+        "Forbidden operation. Specified launch with id '1' not referenced to specified project with id '1'",
+        exception.getMessage()
+    );
+  }
+
+  @Test
+  void validateLaunchWithOperatorRole() {
+    ReportPortalUser operator = getRpUser("operator", UserRole.USER, ProjectRole.OPERATOR, 1L);
+
+    Launch launch = new Launch();
+    launch.setId(1L);
+    launch.setMode(LaunchModeEnum.DEBUG);
+    launch.setProjectId(1L);
+
+    when(launchRepository.findById(1L)).thenReturn(Optional.of(launch));
+
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> launchAccessValidator.validate(1L, extractProjectDetails(operator, "test_project"),
+            operator)
+    );
+    assertEquals("You do not have enough permissions.", exception.getMessage());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/item/impl/StartTestItemHandlerAsyncImplTest.java b/src/test/java/com/epam/ta/reportportal/core/item/impl/StartTestItemHandlerAsyncImplTest.java
index 1418221198..b1264242fb 100644
--- a/src/test/java/com/epam/ta/reportportal/core/item/impl/StartTestItemHandlerAsyncImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/item/impl/StartTestItemHandlerAsyncImplTest.java
@@ -16,6 +16,10 @@
 
 package com.epam.ta.reportportal.core.item.impl;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.verify;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.entity.project.ProjectRole;
 import com.epam.ta.reportportal.entity.user.UserRole;
@@ -28,10 +32,6 @@
 import org.mockito.junit.jupiter.MockitoExtension;
 import org.springframework.amqp.core.AmqpTemplate;
 
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.verify;
-
 /**
  * @author Konstantin Antipin
  */
@@ -39,32 +39,36 @@
 @ExtendWith(MockitoExtension.class)
 class StartTestItemHandlerAsyncImplTest {
 
-    @Mock
-    AmqpTemplate amqpTemplate;
+  @Mock
+  AmqpTemplate amqpTemplate;
 
-    @Mock
-    ReportingQueueService reportingQueueService;
+  @Mock
+  ReportingQueueService reportingQueueService;
 
-    @InjectMocks
-    StartTestItemHandlerAsyncImpl startTestItemHandlerAsync;
+  @InjectMocks
+  StartTestItemHandlerAsyncImpl startTestItemHandlerAsync;
 
-    @Test
-    void startRootItem() {
-        StartTestItemRQ request = new StartTestItemRQ();
-        ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
+  @Test
+  void startRootItem() {
+    StartTestItemRQ request = new StartTestItemRQ();
+    ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER,
+        1L);
 
-        startTestItemHandlerAsync.startRootItem(user, user.getProjectDetails().get("test_project"), request);
-        verify(amqpTemplate).convertAndSend(any(), any(), any(), any());
-        verify(reportingQueueService).getReportingQueueKey(any());
-    }
+    startTestItemHandlerAsync.startRootItem(user, user.getProjectDetails().get("test_project"),
+        request);
+    verify(amqpTemplate).convertAndSend(any(), any(), any(), any());
+    verify(reportingQueueService).getReportingQueueKey(any());
+  }
 
-    @Test
-    void startChildItem() {
-        StartTestItemRQ request = new StartTestItemRQ();
-        ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
+  @Test
+  void startChildItem() {
+    StartTestItemRQ request = new StartTestItemRQ();
+    ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER,
+        1L);
 
-        startTestItemHandlerAsync.startChildItem(user, user.getProjectDetails().get("test_project"), request, "123");
-        verify(amqpTemplate).convertAndSend(any(), any(), any(), any());
-        verify(reportingQueueService).getReportingQueueKey(any());
-    }
+    startTestItemHandlerAsync.startChildItem(user, user.getProjectDetails().get("test_project"),
+        request, "123");
+    verify(amqpTemplate).convertAndSend(any(), any(), any(), any());
+    verify(reportingQueueService).getReportingQueueKey(any());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/item/impl/StartTestItemHandlerImplTest.java b/src/test/java/com/epam/ta/reportportal/core/item/impl/StartTestItemHandlerImplTest.java
index 797e826f8d..4db2058cdc 100644
--- a/src/test/java/com/epam/ta/reportportal/core/item/impl/StartTestItemHandlerImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/item/impl/StartTestItemHandlerImplTest.java
@@ -16,6 +16,15 @@
 
 package com.epam.ta.reportportal.core.item.impl;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static com.epam.ta.reportportal.util.TestProjectExtractor.extractProjectDetails;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.validation.Suppliers;
 import com.epam.ta.reportportal.core.item.validator.parent.ParentItemValidator;
@@ -30,6 +39,11 @@
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import com.epam.ta.reportportal.ws.model.StartTestItemRQ;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Optional;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
@@ -39,191 +53,198 @@
 import org.mockito.Spy;
 import org.mockito.junit.jupiter.MockitoExtension;
 
-import java.time.LocalDateTime;
-import java.time.ZoneId;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.Optional;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static com.epam.ta.reportportal.util.TestProjectExtractor.extractProjectDetails;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.*;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @ExtendWith(MockitoExtension.class)
 class StartTestItemHandlerImplTest {
 
-	private final ParentItemValidator validator = mock(ParentItemValidator.class);
-
-	@Mock
-	private LaunchRepository launchRepository;
-
-	@Mock
-	private TestItemRepository testItemRepository;
-
-	@InjectMocks
-	private StartTestItemHandlerImpl handler;
-
-	@Spy
-	private ArrayList<ParentItemValidator> parentItemValidators = new ArrayList<>();
-
-	@BeforeEach
-	public void setup() throws Exception {
-		parentItemValidators.clear();
-		parentItemValidators.add(validator);
-	}
-
-	@Test
-	void startRootItemUnderNotExistedLaunch() {
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
-
-		when(launchRepository.findByUuid("1")).thenReturn(Optional.empty());
-		final StartTestItemRQ rq = new StartTestItemRQ();
-		rq.setLaunchUuid("1");
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.startRootItem(rpUser, extractProjectDetails(rpUser, "test_project"), rq)
-		);
-		assertEquals("Launch '1' not found. Did you use correct Launch ID?", exception.getMessage());
-	}
-
-	@Test
-	void startRootItemUnderLaunchFromAnotherProject() {
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
-		StartTestItemRQ startTestItemRQ = new StartTestItemRQ();
-		startTestItemRQ.setLaunchUuid("1");
-		startTestItemRQ.setStartTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
-
-		final Launch launch = getLaunch(2L, StatusEnum.IN_PROGRESS);
-		launch.setStartTime(LocalDateTime.now().minusHours(1));
-		when(launchRepository.findByUuid("1")).thenReturn(Optional.of(launch));
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.startRootItem(rpUser, extractProjectDetails(rpUser, "test_project"), startTestItemRQ)
-		);
-		assertEquals("You do not have enough permissions.", exception.getMessage());
-	}
-
-	@Test
-	@Disabled
-	void startRootItemUnderFinishedLaunch() {
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
-		StartTestItemRQ startTestItemRQ = new StartTestItemRQ();
-		startTestItemRQ.setLaunchUuid("1");
-
-		when(launchRepository.findByUuid("1")).thenReturn(Optional.of(getLaunch(1L, StatusEnum.PASSED)));
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.startRootItem(rpUser, extractProjectDetails(rpUser, "test_project"), startTestItemRQ)
-		);
-		assertEquals("Start test item is not allowed. Launch '1' is not in progress", exception.getMessage());
-	}
-
-	@Test
-	void startRootItemEarlierThanLaunch() {
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
-		StartTestItemRQ startTestItemRQ = new StartTestItemRQ();
-		startTestItemRQ.setLaunchUuid("1");
-		startTestItemRQ.setStartTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
-
-		final Launch launch = getLaunch(1L, StatusEnum.IN_PROGRESS);
-		launch.setStartTime(LocalDateTime.now().plusHours(1));
-		when(launchRepository.findByUuid("1")).thenReturn(Optional.of(launch));
-
-		assertThrows(ReportPortalException.class,
-				() -> handler.startRootItem(rpUser, extractProjectDetails(rpUser, "test_project"), startTestItemRQ)
-		);
-	}
-
-	@Test
-	void startChildItemUnderNotExistedParent() {
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
-
-		StartTestItemRQ rq = new StartTestItemRQ();
-		rq.setLaunchUuid("1");
-
-		when(launchRepository.findByUuid("1")).thenReturn(Optional.of(getLaunch(1L, StatusEnum.IN_PROGRESS)));
-		when(testItemRepository.findByUuid("1")).thenReturn(Optional.empty());
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.startChildItem(rpUser, extractProjectDetails(rpUser, "test_project"), rq, "1")
-		);
-		assertEquals("Test Item '1' not found. Did you use correct Test Item ID?", exception.getMessage());
-	}
-
-	@Test
-	void startChildItemEarlierThanParent() {
-
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
-		StartTestItemRQ startTestItemRQ = new StartTestItemRQ();
-		startTestItemRQ.setLaunchUuid("1");
-		startTestItemRQ.setStartTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
-
-		TestItem item = new TestItem();
-		item.setStartTime(LocalDateTime.now().plusHours(1));
-		when(launchRepository.findByUuid("1")).thenReturn(Optional.of(getLaunch(1L, StatusEnum.IN_PROGRESS)));
-		when(testItemRepository.findByUuid("1")).thenReturn(Optional.of(item));
-		doThrow(new ReportPortalException(ErrorType.BAD_REQUEST_ERROR)).when(validator)
-				.validate(any(StartTestItemRQ.class), any(TestItem.class));
-
-		assertThrows(ReportPortalException.class,
-				() -> handler.startChildItem(rpUser, extractProjectDetails(rpUser, "test_project"), startTestItemRQ, "1")
-		);
-	}
-
-	@Test
-	void startChildItemUnderFinishedParent() {
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
-		StartTestItemRQ startTestItemRQ = new StartTestItemRQ();
-		startTestItemRQ.setLaunchUuid("1");
-		startTestItemRQ.setStartTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
-
-		TestItem item = new TestItem();
-		item.setItemId(1L);
-		TestItemResults results = new TestItemResults();
-		results.setStatus(StatusEnum.FAILED);
-		item.setItemResults(results);
-		item.setStartTime(LocalDateTime.now().minusHours(1));
-		when(launchRepository.findByUuid("1")).thenReturn(Optional.of(getLaunch(1L, StatusEnum.IN_PROGRESS)));
-		when(testItemRepository.findByUuid("1")).thenReturn(Optional.of(item));
-		doThrow(new ReportPortalException(ErrorType.BAD_REQUEST_ERROR,
-				Suppliers.formattedSupplier("Unable to add a not nested step item, because parent item with ID = '{}' is a nested step", 1L)
-						.get()
-		)).when(validator).validate(any(StartTestItemRQ.class), any(TestItem.class));
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.startChildItem(rpUser, extractProjectDetails(rpUser, "test_project"), startTestItemRQ, "1")
-		);
-		assertEquals("Error in handled Request. Please, check specified parameters: "
-				+ "'Unable to add a not nested step item, because parent item with ID = '1' is a nested step'", exception.getMessage());
-	}
-
-	@Test
-	void startChildItemWithNotExistedLaunch() {
-		ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
-		StartTestItemRQ startTestItemRQ = new StartTestItemRQ();
-		startTestItemRQ.setLaunchUuid("1");
-		startTestItemRQ.setStartTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
-		startTestItemRQ.setLaunchUuid("1");
-
-		when(launchRepository.findByUuid("1")).thenReturn(Optional.empty());
-
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.startChildItem(rpUser, extractProjectDetails(rpUser, "test_project"), startTestItemRQ, "1")
-		);
-
-		assertEquals("Launch '1' not found. Did you use correct Launch ID?", exception.getMessage());
-	}
-
-	private Launch getLaunch(Long projectId, StatusEnum status) {
-		Launch launch = new Launch();
-		launch.setProjectId(projectId);
-		launch.setStatus(status);
-		return launch;
-	}
+  private final ParentItemValidator validator = mock(ParentItemValidator.class);
+
+  @Mock
+  private LaunchRepository launchRepository;
+
+  @Mock
+  private TestItemRepository testItemRepository;
+
+  @InjectMocks
+  private StartTestItemHandlerImpl handler;
+
+  @Spy
+  private ArrayList<ParentItemValidator> parentItemValidators = new ArrayList<>();
+
+  @BeforeEach
+  public void setup() throws Exception {
+    parentItemValidators.clear();
+    parentItemValidators.add(validator);
+  }
+
+  @Test
+  void startRootItemUnderNotExistedLaunch() {
+    final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
+
+    when(launchRepository.findByUuid("1")).thenReturn(Optional.empty());
+    final StartTestItemRQ rq = new StartTestItemRQ();
+    rq.setLaunchUuid("1");
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.startRootItem(rpUser, extractProjectDetails(rpUser, "test_project"), rq)
+    );
+    assertEquals("Launch '1' not found. Did you use correct Launch ID?", exception.getMessage());
+  }
+
+  @Test
+  void startRootItemUnderLaunchFromAnotherProject() {
+    final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
+    StartTestItemRQ startTestItemRQ = new StartTestItemRQ();
+    startTestItemRQ.setLaunchUuid("1");
+    startTestItemRQ.setStartTime(
+        Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+
+    final Launch launch = getLaunch(2L, StatusEnum.IN_PROGRESS);
+    launch.setStartTime(LocalDateTime.now().minusHours(1));
+    when(launchRepository.findByUuid("1")).thenReturn(Optional.of(launch));
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.startRootItem(rpUser, extractProjectDetails(rpUser, "test_project"),
+            startTestItemRQ)
+    );
+    assertEquals("You do not have enough permissions.", exception.getMessage());
+  }
+
+  @Test
+  @Disabled
+  void startRootItemUnderFinishedLaunch() {
+    final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
+    StartTestItemRQ startTestItemRQ = new StartTestItemRQ();
+    startTestItemRQ.setLaunchUuid("1");
+
+    when(launchRepository.findByUuid("1")).thenReturn(
+        Optional.of(getLaunch(1L, StatusEnum.PASSED)));
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.startRootItem(rpUser, extractProjectDetails(rpUser, "test_project"),
+            startTestItemRQ)
+    );
+    assertEquals("Start test item is not allowed. Launch '1' is not in progress",
+        exception.getMessage());
+  }
+
+  @Test
+  void startRootItemEarlierThanLaunch() {
+    final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
+    StartTestItemRQ startTestItemRQ = new StartTestItemRQ();
+    startTestItemRQ.setLaunchUuid("1");
+    startTestItemRQ.setStartTime(
+        Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+
+    final Launch launch = getLaunch(1L, StatusEnum.IN_PROGRESS);
+    launch.setStartTime(LocalDateTime.now().plusHours(1));
+    when(launchRepository.findByUuid("1")).thenReturn(Optional.of(launch));
+
+    assertThrows(ReportPortalException.class,
+        () -> handler.startRootItem(rpUser, extractProjectDetails(rpUser, "test_project"),
+            startTestItemRQ)
+    );
+  }
+
+  @Test
+  void startChildItemUnderNotExistedParent() {
+    final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
+
+    StartTestItemRQ rq = new StartTestItemRQ();
+    rq.setLaunchUuid("1");
+
+    when(launchRepository.findByUuid("1")).thenReturn(
+        Optional.of(getLaunch(1L, StatusEnum.IN_PROGRESS)));
+    when(testItemRepository.findByUuid("1")).thenReturn(Optional.empty());
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.startChildItem(rpUser, extractProjectDetails(rpUser, "test_project"), rq, "1")
+    );
+    assertEquals("Test Item '1' not found. Did you use correct Test Item ID?",
+        exception.getMessage());
+  }
+
+  @Test
+  void startChildItemEarlierThanParent() {
+
+    final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
+    StartTestItemRQ startTestItemRQ = new StartTestItemRQ();
+    startTestItemRQ.setLaunchUuid("1");
+    startTestItemRQ.setStartTime(
+        Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+
+    TestItem item = new TestItem();
+    item.setStartTime(LocalDateTime.now().plusHours(1));
+    when(launchRepository.findByUuid("1")).thenReturn(
+        Optional.of(getLaunch(1L, StatusEnum.IN_PROGRESS)));
+    when(testItemRepository.findByUuid("1")).thenReturn(Optional.of(item));
+    doThrow(new ReportPortalException(ErrorType.BAD_REQUEST_ERROR)).when(validator)
+        .validate(any(StartTestItemRQ.class), any(TestItem.class));
+
+    assertThrows(ReportPortalException.class,
+        () -> handler.startChildItem(rpUser, extractProjectDetails(rpUser, "test_project"),
+            startTestItemRQ, "1")
+    );
+  }
+
+  @Test
+  void startChildItemUnderFinishedParent() {
+    final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
+    StartTestItemRQ startTestItemRQ = new StartTestItemRQ();
+    startTestItemRQ.setLaunchUuid("1");
+    startTestItemRQ.setStartTime(
+        Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+
+    TestItem item = new TestItem();
+    item.setItemId(1L);
+    TestItemResults results = new TestItemResults();
+    results.setStatus(StatusEnum.FAILED);
+    item.setItemResults(results);
+    item.setStartTime(LocalDateTime.now().minusHours(1));
+    when(launchRepository.findByUuid("1")).thenReturn(
+        Optional.of(getLaunch(1L, StatusEnum.IN_PROGRESS)));
+    when(testItemRepository.findByUuid("1")).thenReturn(Optional.of(item));
+    doThrow(new ReportPortalException(ErrorType.BAD_REQUEST_ERROR,
+        Suppliers.formattedSupplier(
+                "Unable to add a not nested step item, because parent item with ID = '{}' is a nested step",
+                1L)
+            .get()
+    )).when(validator).validate(any(StartTestItemRQ.class), any(TestItem.class));
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.startChildItem(rpUser, extractProjectDetails(rpUser, "test_project"),
+            startTestItemRQ, "1")
+    );
+    assertEquals("Error in handled Request. Please, check specified parameters: "
+            + "'Unable to add a not nested step item, because parent item with ID = '1' is a nested step'",
+        exception.getMessage());
+  }
+
+  @Test
+  void startChildItemWithNotExistedLaunch() {
+    ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
+    StartTestItemRQ startTestItemRQ = new StartTestItemRQ();
+    startTestItemRQ.setLaunchUuid("1");
+    startTestItemRQ.setStartTime(
+        Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+    startTestItemRQ.setLaunchUuid("1");
+
+    when(launchRepository.findByUuid("1")).thenReturn(Optional.empty());
+
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.startChildItem(rpUser, extractProjectDetails(rpUser, "test_project"),
+            startTestItemRQ, "1")
+    );
+
+    assertEquals("Launch '1' not found. Did you use correct Launch ID?", exception.getMessage());
+  }
+
+  private Launch getLaunch(Long projectId, StatusEnum status) {
+    Launch launch = new Launch();
+    launch.setProjectId(projectId);
+    launch.setStatus(status);
+    return launch;
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/item/impl/TestCaseHashGeneratorImplTest.java b/src/test/java/com/epam/ta/reportportal/core/item/impl/TestCaseHashGeneratorImplTest.java
index a5b7eb3ac9..050052ef95 100644
--- a/src/test/java/com/epam/ta/reportportal/core/item/impl/TestCaseHashGeneratorImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/item/impl/TestCaseHashGeneratorImplTest.java
@@ -16,26 +16,25 @@
 
 package com.epam.ta.reportportal.core.item.impl;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.core.item.identity.IdentityUtil;
 import com.epam.ta.reportportal.core.item.identity.TestCaseHashGeneratorImpl;
 import com.epam.ta.reportportal.dao.TestItemRepository;
 import com.epam.ta.reportportal.entity.item.Parameter;
 import com.epam.ta.reportportal.entity.item.TestItem;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-
 import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.mockito.Mockito.when;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
 
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
@@ -43,52 +42,52 @@
 @ExtendWith(MockitoExtension.class)
 class TestCaseHashGeneratorImplTest {
 
-	@Mock
-	private TestItemRepository testItemRepository;
+  @Mock
+  private TestItemRepository testItemRepository;
 
-	@InjectMocks
-	private TestCaseHashGeneratorImpl testCaseHashGenerator;
+  @InjectMocks
+  private TestCaseHashGeneratorImpl testCaseHashGenerator;
 
-	@Test
-	void sameHashesForSameObjectsTest() {
-		TestItem item = getItem();
-		item.setItemId(3L);
-		item.setPath("1.2.3");
+  @Test
+  void sameHashesForSameObjectsTest() {
+    TestItem item = getItem();
+    item.setItemId(3L);
+    item.setPath("1.2.3");
 
-		Map<Long, String> pathNames = new LinkedHashMap<>();
-		pathNames.put(1L, "suite");
-		pathNames.put(2L, "test");
+    Map<Long, String> pathNames = new LinkedHashMap<>();
+    pathNames.put(1L, "suite");
+    pathNames.put(2L, "test");
 
-		List<TestItem> parents = pathNames.entrySet().stream().map(entry -> {
-			TestItem parent = new TestItem();
-			parent.setItemId(entry.getKey());
-			parent.setName(entry.getValue());
-			return parent;
-		}).collect(Collectors.toList());
+    List<TestItem> parents = pathNames.entrySet().stream().map(entry -> {
+      TestItem parent = new TestItem();
+      parent.setItemId(entry.getKey());
+      parent.setName(entry.getValue());
+      return parent;
+    }).collect(Collectors.toList());
 
-		final List<Long> parentIds = IdentityUtil.getParentIds(item);
+    final List<Long> parentIds = IdentityUtil.getParentIds(item);
 
-		when(testItemRepository.findAllById(parentIds)).thenReturn(parents);
+    when(testItemRepository.findAllById(parentIds)).thenReturn(parents);
 
-		Integer first = testCaseHashGenerator.generate(item, parentIds, 100L);
-		Integer second = testCaseHashGenerator.generate(item, parentIds, 100L);
+    Integer first = testCaseHashGenerator.generate(item, parentIds, 100L);
+    Integer second = testCaseHashGenerator.generate(item, parentIds, 100L);
 
-		assertNotNull(first);
-		assertNotNull(second);
-		assertEquals(first, second);
-	}
+    assertNotNull(first);
+    assertNotNull(second);
+    assertEquals(first, second);
+  }
 
-	private TestItem getItem() {
-		TestItem item = new TestItem();
-		item.setName("item");
-		HashSet<Parameter> parameters = new HashSet<>();
-		Parameter parameter = new Parameter();
-		parameter.setKey("key");
-		parameter.setValue("value");
-		parameters.add(parameter);
-		item.setParameters(parameters);
-		item.setPath("1.2.3");
-		item.setLaunchId(1L);
-		return item;
-	}
+  private TestItem getItem() {
+    TestItem item = new TestItem();
+    item.setName("item");
+    HashSet<Parameter> parameters = new HashSet<>();
+    Parameter parameter = new Parameter();
+    parameter.setKey("key");
+    parameter.setValue("value");
+    parameters.add(parameter);
+    item.setParameters(parameters);
+    item.setPath("1.2.3");
+    item.setLaunchId(1L);
+    return item;
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/item/impl/TestItemUniqueIdGeneratorTest.java b/src/test/java/com/epam/ta/reportportal/core/item/impl/TestItemUniqueIdGeneratorTest.java
index 8dc97e0c35..00fe84fb72 100644
--- a/src/test/java/com/epam/ta/reportportal/core/item/impl/TestItemUniqueIdGeneratorTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/item/impl/TestItemUniqueIdGeneratorTest.java
@@ -16,6 +16,11 @@
 
 package com.epam.ta.reportportal.core.item.impl;
 
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.core.item.identity.IdentityUtil;
 import com.epam.ta.reportportal.core.item.identity.TestItemUniqueIdGenerator;
 import com.epam.ta.reportportal.dao.TestItemRepository;
@@ -23,20 +28,16 @@
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.google.common.collect.Sets;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
-
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.Mockito.when;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
 
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
@@ -44,63 +45,63 @@
 @ExtendWith(MockitoExtension.class)
 class TestItemUniqueIdGeneratorTest {
 
-	@Mock
-	private TestItemRepository testItemRepository;
-
-	@InjectMocks
-	private TestItemUniqueIdGenerator uniqueIdGenerator;
-
-	@Test
-	void validateTest() {
-		assertFalse(uniqueIdGenerator.validate(""));
-		assertFalse(uniqueIdGenerator.validate(null));
-		assertFalse(uniqueIdGenerator.validate("qwerty"));
-		assertTrue(uniqueIdGenerator.validate("auto: 123456789"));
-	}
-
-	@Test
-	void generateTest() {
-		Launch launch = new Launch();
-		launch.setId(1L);
-		launch.setProjectId(1L);
-		launch.setName("launchName");
-
-		TestItem testItem = new TestItem();
-		testItem.setItemId(3L);
-		testItem.setName("itemName");
-		testItem.setPath("1.2.3");
-
-		HashMap<Long, String> pathNamesMap = new HashMap<>();
-		pathNamesMap.put(1L, "first");
-		pathNamesMap.put(2L, "second");
-		pathNamesMap.put(3L, "third");
-
-		Parameter param1 = new Parameter();
-		param1.setKey("key1");
-		param1.setValue("val1");
-		Parameter param2 = new Parameter();
-		param1.setKey("key2");
-		param1.setValue("val2");
-		testItem.setParameters(Sets.newHashSet(param1, param2));
-		testItem.setLaunchId(1L);
-
-		Map<Long, String> pathNames = new LinkedHashMap<>();
-		pathNames.put(1L, "suite");
-		pathNames.put(2L, "test");
-
-		List<TestItem> parents = pathNames.entrySet().stream().map(entry -> {
-			TestItem parent = new TestItem();
-			parent.setItemId(entry.getKey());
-			parent.setName(entry.getValue());
-			return parent;
-		}).collect(Collectors.toList());
-
-		final List<Long> parentIds = IdentityUtil.getParentIds(testItem);
-
-		when(testItemRepository.findAllById(parentIds)).thenReturn(parents);
-		String generated = uniqueIdGenerator.generate(testItem, parentIds, launch);
-
-		assertNotNull(generated);
-		assertTrue(generated.startsWith("auto:"));
-	}
+  @Mock
+  private TestItemRepository testItemRepository;
+
+  @InjectMocks
+  private TestItemUniqueIdGenerator uniqueIdGenerator;
+
+  @Test
+  void validateTest() {
+    assertFalse(uniqueIdGenerator.validate(""));
+    assertFalse(uniqueIdGenerator.validate(null));
+    assertFalse(uniqueIdGenerator.validate("qwerty"));
+    assertTrue(uniqueIdGenerator.validate("auto: 123456789"));
+  }
+
+  @Test
+  void generateTest() {
+    Launch launch = new Launch();
+    launch.setId(1L);
+    launch.setProjectId(1L);
+    launch.setName("launchName");
+
+    TestItem testItem = new TestItem();
+    testItem.setItemId(3L);
+    testItem.setName("itemName");
+    testItem.setPath("1.2.3");
+
+    HashMap<Long, String> pathNamesMap = new HashMap<>();
+    pathNamesMap.put(1L, "first");
+    pathNamesMap.put(2L, "second");
+    pathNamesMap.put(3L, "third");
+
+    Parameter param1 = new Parameter();
+    param1.setKey("key1");
+    param1.setValue("val1");
+    Parameter param2 = new Parameter();
+    param1.setKey("key2");
+    param1.setValue("val2");
+    testItem.setParameters(Sets.newHashSet(param1, param2));
+    testItem.setLaunchId(1L);
+
+    Map<Long, String> pathNames = new LinkedHashMap<>();
+    pathNames.put(1L, "suite");
+    pathNames.put(2L, "test");
+
+    List<TestItem> parents = pathNames.entrySet().stream().map(entry -> {
+      TestItem parent = new TestItem();
+      parent.setItemId(entry.getKey());
+      parent.setName(entry.getValue());
+      return parent;
+    }).collect(Collectors.toList());
+
+    final List<Long> parentIds = IdentityUtil.getParentIds(testItem);
+
+    when(testItemRepository.findAllById(parentIds)).thenReturn(parents);
+    String generated = uniqueIdGenerator.generate(testItem, parentIds, launch);
+
+    assertNotNull(generated);
+    assertTrue(generated.startsWith("auto:"));
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/item/impl/UpdateTestItemHandlerImplTest.java b/src/test/java/com/epam/ta/reportportal/core/item/impl/UpdateTestItemHandlerImplTest.java
index d3886c4962..d7b4a69dba 100644
--- a/src/test/java/com/epam/ta/reportportal/core/item/impl/UpdateTestItemHandlerImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/item/impl/UpdateTestItemHandlerImplTest.java
@@ -16,6 +16,17 @@
 
 package com.epam.ta.reportportal.core.item.impl;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static com.epam.ta.reportportal.core.item.impl.UpdateTestItemHandlerImpl.INITIAL_STATUS_ATTRIBUTE_KEY;
+import static com.epam.ta.reportportal.util.TestProjectExtractor.extractProjectDetails;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.events.MessageBus;
 import com.epam.ta.reportportal.core.item.TestItemService;
@@ -37,248 +48,267 @@
 import com.epam.ta.reportportal.ws.model.issue.DefineIssueRQ;
 import com.epam.ta.reportportal.ws.model.item.UpdateTestItemRQ;
 import com.google.common.collect.Sets;
+import java.util.Map;
+import java.util.Optional;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 
-import java.util.Map;
-import java.util.Optional;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static com.epam.ta.reportportal.core.item.impl.UpdateTestItemHandlerImpl.INITIAL_STATUS_ATTRIBUTE_KEY;
-import static com.epam.ta.reportportal.util.TestProjectExtractor.extractProjectDetails;
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.*;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @ExtendWith(MockitoExtension.class)
 class UpdateTestItemHandlerImplTest {
 
-	private final StatusChangingStrategy statusChangingStrategy = mock(StatusChangingStrategy.class);
-
-	@Mock
-	private Map<StatusEnum, StatusChangingStrategy> statusChangingStrategyMapping;
-
-	@Mock
-	private TestItemRepository itemRepository;
-
-	@Mock
-	private ProjectRepository projectRepository;
-
-	@Mock
-	private TestItemService testItemService;
-
-	@Mock
-	private MessageBus messageBus;
-
-	@InjectMocks
-	private UpdateTestItemHandlerImpl handler;
-
-	@Test
-	void updateNotExistedTestItem() {
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.PROJECT_MANAGER, 1L);
-		when(itemRepository.findById(1L)).thenReturn(Optional.empty());
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.updateTestItem(extractProjectDetails(rpUser, "test_project"), 1L, new UpdateTestItemRQ(), rpUser)
-		);
-		assertEquals("Test Item '1' not found. Did you use correct Test Item ID?", exception.getMessage());
-	}
-
-	@Test
-	void updateTestItemUnderNotExistedLaunch() {
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.PROJECT_MANAGER, 1L);
-
-		TestItem testItem = new TestItem();
-		testItem.setLaunchId(2L);
-		when(itemRepository.findById(1L)).thenReturn(Optional.of(testItem));
-		when(testItemService.getEffectiveLaunch(testItem)).thenThrow(new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND));
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.updateTestItem(extractProjectDetails(rpUser, "test_project"), 1L, new UpdateTestItemRQ(), rpUser)
-		);
-		assertEquals("Launch '' not found. Did you use correct Launch ID?", exception.getMessage());
-	}
-
-	@Test
-	void updateTestItemUnderNotOwnLaunch() {
-		final ReportPortalUser rpUser = getRpUser("not owner", UserRole.USER, ProjectRole.MEMBER, 1L);
-
-		TestItem item = new TestItem();
-		Launch launch = new Launch();
-		launch.setId(1L);
-		User user = new User();
-		user.setId(1L);
-		user.setLogin("owner");
-		launch.setUserId(2L);
-		launch.setProjectId(1L);
-		item.setLaunchId(launch.getId());
-		when(testItemService.getEffectiveLaunch(item)).thenReturn(launch);
-		when(itemRepository.findById(1L)).thenReturn(Optional.of(item));
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.updateTestItem(extractProjectDetails(rpUser, "test_project"), 1L, new UpdateTestItemRQ(), rpUser)
-		);
-		assertEquals("You do not have enough permissions. You are not a launch owner.", exception.getMessage());
-	}
-
-	@Test
-	void updateTestItemFromAnotherProject() {
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
-		TestItem item = new TestItem();
-		Launch launch = new Launch();
-		launch.setId(1L);
-		User user = new User();
-		user.setId(1L);
-		user.setLogin("owner");
-		launch.setUserId(user.getId());
-		launch.setProjectId(2L);
-		item.setLaunchId(launch.getId());
-		when(testItemService.getEffectiveLaunch(item)).thenReturn(launch);
-		when(itemRepository.findById(1L)).thenReturn(Optional.of(item));
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.updateTestItem(extractProjectDetails(rpUser, "test_project"), 1L, new UpdateTestItemRQ(), rpUser)
-		);
-		assertEquals("You do not have enough permissions. Launch is not under the specified project.", exception.getMessage());
-	}
-
-	@Test
-	void defineIssuesOnNotExistProject() {
-		ReportPortalUser rpUser = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, 1L);
-
-		when(projectRepository.findById(1L)).thenReturn(Optional.empty());
-
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.defineTestItemsIssues(extractProjectDetails(rpUser, "test_project"), new DefineIssueRQ(), rpUser)
-		);
-
-		assertEquals("Project '1' not found. Did you use correct project name?", exception.getMessage());
-	}
-
-	@Test
-	void changeNotStepItemStatus() {
-		ReportPortalUser user = getRpUser("user", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
-
-		UpdateTestItemRQ rq = new UpdateTestItemRQ();
-		rq.setStatus("FAILED");
-
-		long itemId = 1L;
-		TestItem item = new TestItem();
-		item.setItemId(itemId);
-		item.setHasChildren(true);
-		item.setType(TestItemTypeEnum.TEST);
-		TestItemResults itemResults = new TestItemResults();
-		itemResults.setStatus(StatusEnum.PASSED);
-		item.setItemResults(itemResults);
-		Launch launch = new Launch();
-		launch.setId(2L);
-		item.setLaunchId(launch.getId());
-
-		when(testItemService.getEffectiveLaunch(item)).thenReturn(launch);
-		when(itemRepository.findById(itemId)).thenReturn(Optional.of(item));
-
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.updateTestItem(extractProjectDetails(user, "test_project"), itemId, rq, user)
-		);
-		assertEquals("Incorrect Request. Unable to change status on test item with children", exception.getMessage());
-	}
-
-	@Test
-	void shouldCreateInitialStatusAttribute() {
-		ReportPortalUser user = getRpUser("user", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
-
-		UpdateTestItemRQ rq = new UpdateTestItemRQ();
-		rq.setStatus("PASSED");
-
-		long itemId = 1L;
-		TestItem item = new TestItem();
-		item.setItemId(itemId);
-		item.setHasChildren(false);
-		item.setType(TestItemTypeEnum.STEP);
-		TestItemResults itemResults = new TestItemResults();
-		itemResults.setStatus(StatusEnum.FAILED);
-		item.setItemResults(itemResults);
-		Launch launch = new Launch();
-		launch.setId(2L);
-		item.setLaunchId(launch.getId());
-
-		when(testItemService.getEffectiveLaunch(item)).thenReturn(launch);
-		when(itemRepository.findById(itemId)).thenReturn(Optional.of(item));
-		doNothing().when(messageBus).publishActivity(any());
-		when(statusChangingStrategyMapping.get(StatusEnum.PASSED)).thenReturn(statusChangingStrategy);
-		doNothing().when(statusChangingStrategy).changeStatus(item, StatusEnum.PASSED, user);
-
-		handler.updateTestItem(extractProjectDetails(user, "test_project"), itemId, rq, user);
-		assertTrue(item.getAttributes()
-				.stream()
-				.anyMatch(attribute -> INITIAL_STATUS_ATTRIBUTE_KEY.equalsIgnoreCase(attribute.getKey())
-						&& StatusEnum.FAILED.getExecutionCounterField().equalsIgnoreCase("failed")));
-	}
-
-	@Test
-	void shouldNotCreateInitialStatusAttribute() {
-		ReportPortalUser user = getRpUser("user", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
-
-		UpdateTestItemRQ rq = new UpdateTestItemRQ();
-		rq.setStatus("PASSED");
-
-		long itemId = 1L;
-		TestItem item = new TestItem();
-		item.setItemId(itemId);
-		item.setHasChildren(false);
-		item.setType(TestItemTypeEnum.STEP);
-		item.setAttributes(Sets.newHashSet(new ItemAttribute(INITIAL_STATUS_ATTRIBUTE_KEY, "passed", true)));
-		TestItemResults itemResults = new TestItemResults();
-		itemResults.setStatus(StatusEnum.FAILED);
-		item.setItemResults(itemResults);
-		Launch launch = new Launch();
-		launch.setId(2L);
-		item.setLaunchId(launch.getId());
-
-		when(testItemService.getEffectiveLaunch(item)).thenReturn(launch);
-		when(itemRepository.findById(itemId)).thenReturn(Optional.of(item));
-		doNothing().when(messageBus).publishActivity(any());
-		when(statusChangingStrategyMapping.get(StatusEnum.PASSED)).thenReturn(statusChangingStrategy);
-		doNothing().when(statusChangingStrategy).changeStatus(item, StatusEnum.PASSED, user);
-
-		handler.updateTestItem(extractProjectDetails(user, "test_project"), itemId, rq, user);
-		assertTrue(item.getAttributes()
-				.stream()
-				.anyMatch(attribute -> INITIAL_STATUS_ATTRIBUTE_KEY.equalsIgnoreCase(attribute.getKey())
-						&& StatusEnum.PASSED.getExecutionCounterField().equalsIgnoreCase("passed")));
-	}
-
-	@Test
-	void updateItemPositive() {
-		ReportPortalUser user = getRpUser("user", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
-
-		UpdateTestItemRQ rq = new UpdateTestItemRQ();
-		rq.setDescription("new description");
-
-		long itemId = 1L;
-		TestItem item = new TestItem();
-		item.setItemId(itemId);
-		item.setDescription("old description");
-		item.setHasChildren(false);
-		item.setType(TestItemTypeEnum.STEP);
-		TestItemResults itemResults = new TestItemResults();
-		itemResults.setStatus(StatusEnum.FAILED);
-		item.setItemResults(itemResults);
-		Launch launch = new Launch();
-		launch.setId(2L);
-		item.setLaunchId(launch.getId());
-
-		when(testItemService.getEffectiveLaunch(item)).thenReturn(launch);
-		when(itemRepository.findById(itemId)).thenReturn(Optional.of(item));
-
-		OperationCompletionRS response = handler.updateTestItem(extractProjectDetails(user, "test_project"), itemId, rq, user);
-
-		assertEquals("TestItem with ID = '1' successfully updated.", response.getResultMessage());
-		assertEquals(rq.getDescription(), item.getDescription());
-	}
+  private final StatusChangingStrategy statusChangingStrategy = mock(StatusChangingStrategy.class);
+
+  @Mock
+  private Map<StatusEnum, StatusChangingStrategy> statusChangingStrategyMapping;
+
+  @Mock
+  private TestItemRepository itemRepository;
+
+  @Mock
+  private ProjectRepository projectRepository;
+
+  @Mock
+  private TestItemService testItemService;
+
+  @Mock
+  private MessageBus messageBus;
+
+  @InjectMocks
+  private UpdateTestItemHandlerImpl handler;
+
+  @Test
+  void updateNotExistedTestItem() {
+    final ReportPortalUser rpUser =
+        getRpUser("test", UserRole.USER, ProjectRole.PROJECT_MANAGER, 1L);
+    when(itemRepository.findById(1L)).thenReturn(Optional.empty());
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.updateTestItem(extractProjectDetails(rpUser, "test_project"), 1L,
+            new UpdateTestItemRQ(), rpUser
+        )
+    );
+    assertEquals("Test Item '1' not found. Did you use correct Test Item ID?",
+        exception.getMessage()
+    );
+  }
+
+  @Test
+  void updateTestItemUnderNotExistedLaunch() {
+    final ReportPortalUser rpUser =
+        getRpUser("test", UserRole.USER, ProjectRole.PROJECT_MANAGER, 1L);
+
+    TestItem testItem = new TestItem();
+    testItem.setLaunchId(2L);
+    when(itemRepository.findById(1L)).thenReturn(Optional.of(testItem));
+    when(testItemService.getEffectiveLaunch(testItem)).thenThrow(
+        new ReportPortalException(ErrorType.LAUNCH_NOT_FOUND));
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.updateTestItem(extractProjectDetails(rpUser, "test_project"), 1L,
+            new UpdateTestItemRQ(), rpUser
+        )
+    );
+    assertEquals("Launch '' not found. Did you use correct Launch ID?", exception.getMessage());
+  }
+
+  @Test
+  void updateTestItemUnderNotOwnLaunch() {
+    final ReportPortalUser rpUser = getRpUser("not owner", UserRole.USER, ProjectRole.MEMBER, 1L);
+
+    TestItem item = new TestItem();
+    Launch launch = new Launch();
+    launch.setId(1L);
+    User user = new User();
+    user.setId(1L);
+    user.setLogin("owner");
+    launch.setUserId(2L);
+    launch.setProjectId(1L);
+    item.setLaunchId(launch.getId());
+    when(testItemService.getEffectiveLaunch(item)).thenReturn(launch);
+    when(itemRepository.findById(1L)).thenReturn(Optional.of(item));
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.updateTestItem(extractProjectDetails(rpUser, "test_project"), 1L,
+            new UpdateTestItemRQ(), rpUser
+        )
+    );
+    assertEquals("You do not have enough permissions. You are not a launch owner.",
+        exception.getMessage()
+    );
+  }
+
+  @Test
+  void updateTestItemFromAnotherProject() {
+    final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
+    TestItem item = new TestItem();
+    Launch launch = new Launch();
+    launch.setId(1L);
+    User user = new User();
+    user.setId(1L);
+    user.setLogin("owner");
+    launch.setUserId(user.getId());
+    launch.setProjectId(2L);
+    item.setLaunchId(launch.getId());
+    when(testItemService.getEffectiveLaunch(item)).thenReturn(launch);
+    when(itemRepository.findById(1L)).thenReturn(Optional.of(item));
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.updateTestItem(extractProjectDetails(rpUser, "test_project"), 1L,
+            new UpdateTestItemRQ(), rpUser
+        )
+    );
+    assertEquals("You do not have enough permissions. Launch is not under the specified project.",
+        exception.getMessage()
+    );
+  }
+
+  @Test
+  void defineIssuesOnNotExistProject() {
+    ReportPortalUser rpUser = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, 1L);
+
+    when(projectRepository.findById(1L)).thenReturn(Optional.empty());
+
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.defineTestItemsIssues(extractProjectDetails(rpUser, "test_project"),
+            new DefineIssueRQ(), rpUser
+        )
+    );
+
+    assertEquals("Project '1' not found. Did you use correct project name?",
+        exception.getMessage()
+    );
+  }
+
+  @Test
+  void changeNotStepItemStatus() {
+    ReportPortalUser user =
+        getRpUser("user", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
+
+    UpdateTestItemRQ rq = new UpdateTestItemRQ();
+    rq.setStatus("FAILED");
+
+    long itemId = 1L;
+    TestItem item = new TestItem();
+    item.setItemId(itemId);
+    item.setHasChildren(true);
+    item.setType(TestItemTypeEnum.TEST);
+    TestItemResults itemResults = new TestItemResults();
+    itemResults.setStatus(StatusEnum.PASSED);
+    item.setItemResults(itemResults);
+    Launch launch = new Launch();
+    launch.setId(2L);
+    item.setLaunchId(launch.getId());
+
+    when(testItemService.getEffectiveLaunch(item)).thenReturn(launch);
+    when(itemRepository.findById(itemId)).thenReturn(Optional.of(item));
+
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.updateTestItem(extractProjectDetails(user, "test_project"), itemId, rq, user)
+    );
+    assertEquals("Incorrect Request. Unable to change status on test item with children",
+        exception.getMessage()
+    );
+  }
+
+  @Test
+  void shouldCreateInitialStatusAttribute() {
+    ReportPortalUser user =
+        getRpUser("user", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
+
+    UpdateTestItemRQ rq = new UpdateTestItemRQ();
+    rq.setStatus("PASSED");
+
+    long itemId = 1L;
+    TestItem item = new TestItem();
+    item.setItemId(itemId);
+    item.setHasChildren(false);
+    item.setType(TestItemTypeEnum.STEP);
+    TestItemResults itemResults = new TestItemResults();
+    itemResults.setStatus(StatusEnum.FAILED);
+    item.setItemResults(itemResults);
+    Launch launch = new Launch();
+    launch.setId(2L);
+    item.setLaunchId(launch.getId());
+
+    when(testItemService.getEffectiveLaunch(item)).thenReturn(launch);
+    when(itemRepository.findById(itemId)).thenReturn(Optional.of(item));
+    doNothing().when(messageBus).publishActivity(any());
+    when(statusChangingStrategyMapping.get(StatusEnum.PASSED)).thenReturn(statusChangingStrategy);
+    doNothing().when(statusChangingStrategy).changeStatus(item, StatusEnum.PASSED, user, true);
+
+    handler.updateTestItem(extractProjectDetails(user, "test_project"), itemId, rq, user);
+    assertTrue(item.getAttributes().stream().anyMatch(
+        attribute -> INITIAL_STATUS_ATTRIBUTE_KEY.equalsIgnoreCase(attribute.getKey())
+            && StatusEnum.FAILED.getExecutionCounterField().equalsIgnoreCase("failed")));
+  }
+
+  @Test
+  void shouldNotCreateInitialStatusAttribute() {
+    ReportPortalUser user =
+        getRpUser("user", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
+
+    UpdateTestItemRQ rq = new UpdateTestItemRQ();
+    rq.setStatus("PASSED");
+
+    long itemId = 1L;
+    TestItem item = new TestItem();
+    item.setItemId(itemId);
+    item.setHasChildren(false);
+    item.setType(TestItemTypeEnum.STEP);
+    item.setAttributes(
+        Sets.newHashSet(new ItemAttribute(INITIAL_STATUS_ATTRIBUTE_KEY, "passed", true)));
+    TestItemResults itemResults = new TestItemResults();
+    itemResults.setStatus(StatusEnum.FAILED);
+    item.setItemResults(itemResults);
+    Launch launch = new Launch();
+    launch.setId(2L);
+    item.setLaunchId(launch.getId());
+
+    when(testItemService.getEffectiveLaunch(item)).thenReturn(launch);
+    when(itemRepository.findById(itemId)).thenReturn(Optional.of(item));
+    doNothing().when(messageBus).publishActivity(any());
+    when(statusChangingStrategyMapping.get(StatusEnum.PASSED)).thenReturn(statusChangingStrategy);
+    doNothing().when(statusChangingStrategy).changeStatus(item, StatusEnum.PASSED, user, true);
+
+    handler.updateTestItem(extractProjectDetails(user, "test_project"), itemId, rq, user);
+    assertTrue(item.getAttributes().stream().anyMatch(
+        attribute -> INITIAL_STATUS_ATTRIBUTE_KEY.equalsIgnoreCase(attribute.getKey())
+            && StatusEnum.PASSED.getExecutionCounterField().equalsIgnoreCase("passed")));
+  }
+
+  @Test
+  void updateItemPositive() {
+    ReportPortalUser user =
+        getRpUser("user", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
+
+    UpdateTestItemRQ rq = new UpdateTestItemRQ();
+    rq.setDescription("new description");
+
+    long itemId = 1L;
+    TestItem item = new TestItem();
+    item.setItemId(itemId);
+    item.setDescription("old description");
+    item.setHasChildren(false);
+    item.setType(TestItemTypeEnum.STEP);
+    TestItemResults itemResults = new TestItemResults();
+    itemResults.setStatus(StatusEnum.FAILED);
+    item.setItemResults(itemResults);
+    Launch launch = new Launch();
+    launch.setId(2L);
+    item.setLaunchId(launch.getId());
+
+    when(testItemService.getEffectiveLaunch(item)).thenReturn(launch);
+    when(itemRepository.findById(itemId)).thenReturn(Optional.of(item));
+
+    OperationCompletionRS response =
+        handler.updateTestItem(extractProjectDetails(user, "test_project"), itemId, rq, user);
+
+    assertEquals("TestItem with ID = '1' successfully updated.", response.getResultMessage());
+    assertEquals(rq.getDescription(), item.getDescription());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/item/impl/filter/updater/IssueTypeConditionReplacerTest.java b/src/test/java/com/epam/ta/reportportal/core/item/impl/filter/updater/IssueTypeConditionReplacerTest.java
index ac1268f6a3..260b912260 100644
--- a/src/test/java/com/epam/ta/reportportal/core/item/impl/filter/updater/IssueTypeConditionReplacerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/item/impl/filter/updater/IssueTypeConditionReplacerTest.java
@@ -16,58 +16,59 @@
 
 package com.epam.ta.reportportal.core.item.impl.filter.updater;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_ISSUE_TYPE;
+import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_ISSUE_TYPE_ID;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.querygen.Condition;
 import com.epam.ta.reportportal.commons.querygen.ConvertibleCondition;
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.querygen.FilterCondition;
 import com.epam.ta.reportportal.dao.IssueTypeRepository;
 import com.epam.ta.reportportal.entity.item.TestItem;
+import java.util.List;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
-import java.util.List;
-
-import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_ISSUE_TYPE;
-import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_ISSUE_TYPE_ID;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class IssueTypeConditionReplacerTest {
 
-	private final IssueTypeRepository issueTypeRepository = mock(IssueTypeRepository.class);
-	private final IssueTypeConditionReplacer replacer = new IssueTypeConditionReplacer(issueTypeRepository);
+  private final IssueTypeRepository issueTypeRepository = mock(IssueTypeRepository.class);
+  private final IssueTypeConditionReplacer replacer = new IssueTypeConditionReplacer(
+      issueTypeRepository);
 
-	@Test
-	void shouldReplace() {
+  @Test
+  void shouldReplace() {
 
-		final Filter filter = Filter.builder()
-				.withTarget(TestItem.class)
-				.withCondition(FilterCondition.builder()
-						.withCondition(Condition.IN)
-						.withSearchCriteria(CRITERIA_ISSUE_TYPE)
-						.withValue("ab001,pb001,ti001")
-						.build())
-				.build();
+    final Filter filter = Filter.builder()
+        .withTarget(TestItem.class)
+        .withCondition(FilterCondition.builder()
+            .withCondition(Condition.IN)
+            .withSearchCriteria(CRITERIA_ISSUE_TYPE)
+            .withValue("ab001,pb001,ti001")
+            .build())
+        .build();
 
-		final List<Long> ids = List.of(1L, 2L, 3L);
-		when(issueTypeRepository.getIssueTypeIdsByLocators(List.of("ab001", "pb001", "ti001"))).thenReturn(ids);
+    final List<Long> ids = List.of(1L, 2L, 3L);
+    when(issueTypeRepository.getIssueTypeIdsByLocators(
+        List.of("ab001", "pb001", "ti001"))).thenReturn(ids);
 
-		replacer.update(filter);
+    replacer.update(filter);
 
-		final List<ConvertibleCondition> rootConditions = filter.getFilterConditions();
-		final List<FilterCondition> nestedConditions = rootConditions.get(0).getAllConditions();
-		Assertions.assertEquals(1, rootConditions.size());
-		Assertions.assertEquals(1, nestedConditions.size());
+    final List<ConvertibleCondition> rootConditions = filter.getFilterConditions();
+    final List<FilterCondition> nestedConditions = rootConditions.get(0).getAllConditions();
+    Assertions.assertEquals(1, rootConditions.size());
+    Assertions.assertEquals(1, nestedConditions.size());
 
-		final FilterCondition filterCondition = nestedConditions.get(0);
+    final FilterCondition filterCondition = nestedConditions.get(0);
 
-		Assertions.assertEquals(CRITERIA_ISSUE_TYPE_ID, filterCondition.getSearchCriteria());
-		Assertions.assertEquals(Condition.IN, filterCondition.getCondition());
-		Assertions.assertEquals("1,2,3", filterCondition.getValue());
+    Assertions.assertEquals(CRITERIA_ISSUE_TYPE_ID, filterCondition.getSearchCriteria());
+    Assertions.assertEquals(Condition.IN, filterCondition.getCondition());
+    Assertions.assertEquals("1,2,3", filterCondition.getValue());
 
-	}
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/item/impl/history/TestItemsHistoryHandlerImplTest.java b/src/test/java/com/epam/ta/reportportal/core/item/impl/history/TestItemsHistoryHandlerImplTest.java
index 990b45a344..d1d8f8023d 100644
--- a/src/test/java/com/epam/ta/reportportal/core/item/impl/history/TestItemsHistoryHandlerImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/item/impl/history/TestItemsHistoryHandlerImplTest.java
@@ -16,16 +16,20 @@
 
 package com.epam.ta.reportportal.core.item.impl.history;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_ID;
+import static com.epam.ta.reportportal.util.TestProjectExtractor.extractProjectDetails;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
 import com.epam.ta.reportportal.ReportPortalUserUtil;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.querygen.FilterCondition;
+import com.epam.ta.reportportal.core.item.impl.history.param.HistoryRequestParams;
 import com.epam.ta.reportportal.dao.TestItemRepository;
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.project.ProjectRole;
 import com.epam.ta.reportportal.entity.user.UserRole;
 import com.epam.ta.reportportal.exception.ReportPortalException;
-import com.epam.ta.reportportal.core.item.impl.history.param.HistoryRequestParams;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.InjectMocks;
@@ -33,53 +37,51 @@
 import org.mockito.junit.jupiter.MockitoExtension;
 import org.springframework.data.domain.PageRequest;
 
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_ID;
-import static com.epam.ta.reportportal.util.TestProjectExtractor.extractProjectDetails;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @ExtendWith(MockitoExtension.class)
 class TestItemsHistoryHandlerImplTest {
 
-	@Mock
-	private TestItemRepository testItemRepository;
+  @Mock
+  private TestItemRepository testItemRepository;
 
-	@InjectMocks
-	private TestItemsHistoryHandlerImpl handler;
+  @InjectMocks
+  private TestItemsHistoryHandlerImpl handler;
 
-	@Test
-	void historyDepthLowerThanBoundTest() {
-		ReportPortalUser rpUser = ReportPortalUserUtil.getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
+  @Test
+  void historyDepthLowerThanBoundTest() {
+    ReportPortalUser rpUser = ReportPortalUserUtil.getRpUser("test", UserRole.USER,
+        ProjectRole.MEMBER, 1L);
 
-		assertThrows(ReportPortalException.class,
-				() -> handler.getItemsHistory(extractProjectDetails(rpUser, "test_project"),
-						Filter.builder()
-								.withTarget(TestItem.class)
-								.withCondition(FilterCondition.builder().eq(CRITERIA_ID, "1").build())
-								.build(),
-						PageRequest.of(0, 10),
-						HistoryRequestParams.of(0, 1L, 1L, 1L, null, 1L, 1, false),
-						rpUser
-				)
-		);
-	}
+    assertThrows(ReportPortalException.class,
+        () -> handler.getItemsHistory(extractProjectDetails(rpUser, "test_project"),
+            Filter.builder()
+                .withTarget(TestItem.class)
+                .withCondition(FilterCondition.builder().eq(CRITERIA_ID, "1").build())
+                .build(),
+            PageRequest.of(0, 10),
+            HistoryRequestParams.of(0, 1L, 1L, 1L, null, 1L, 1, false),
+            rpUser
+        )
+    );
+  }
 
-	@Test
-	void historyDepthGreaterThanBoundTest() {
-		ReportPortalUser rpUser = ReportPortalUserUtil.getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
+  @Test
+  void historyDepthGreaterThanBoundTest() {
+    ReportPortalUser rpUser = ReportPortalUserUtil.getRpUser("test", UserRole.USER,
+        ProjectRole.MEMBER, 1L);
 
-		assertThrows(ReportPortalException.class,
-				() -> handler.getItemsHistory(extractProjectDetails(rpUser, "test_project"),
-						Filter.builder()
-								.withTarget(TestItem.class)
-								.withCondition(FilterCondition.builder().eq(CRITERIA_ID, "1").build())
-								.build(),
-						PageRequest.of(0, 10),
-						HistoryRequestParams.of(31, 1L, 1L, 1L, "table", 1L, 1, false),
-						rpUser
-				)
-		);
-	}
+    assertThrows(ReportPortalException.class,
+        () -> handler.getItemsHistory(extractProjectDetails(rpUser, "test_project"),
+            Filter.builder()
+                .withTarget(TestItem.class)
+                .withCondition(FilterCondition.builder().eq(CRITERIA_ID, "1").build())
+                .build(),
+            PageRequest.of(0, 10),
+            HistoryRequestParams.of(31, 1L, 1L, 1L, "table", 1L, 1, false),
+            rpUser
+        )
+    );
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/item/impl/provider/impl/mock/ClusterItemDataProviderMockTest.java b/src/test/java/com/epam/ta/reportportal/core/item/impl/provider/impl/mock/ClusterItemDataProviderMockTest.java
index 65172d8301..c2d9f53c99 100644
--- a/src/test/java/com/epam/ta/reportportal/core/item/impl/provider/impl/mock/ClusterItemDataProviderMockTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/item/impl/provider/impl/mock/ClusterItemDataProviderMockTest.java
@@ -16,6 +16,8 @@
 
 package com.epam.ta.reportportal.core.item.impl.provider.impl.mock;
 
+import static java.util.stream.Collectors.groupingBy;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.querygen.Queryable;
 import com.epam.ta.reportportal.entity.ItemAttribute;
@@ -31,167 +33,170 @@
 import com.epam.ta.reportportal.entity.statistics.Statistics;
 import com.epam.ta.reportportal.entity.statistics.StatisticsField;
 import com.google.common.base.Suppliers;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageImpl;
-import org.springframework.data.domain.Pageable;
-
 import java.time.LocalDateTime;
 import java.time.ZoneOffset;
-import java.util.*;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
-
-import static java.util.stream.Collectors.groupingBy;
-import static org.junit.jupiter.api.Assertions.*;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageImpl;
+import org.springframework.data.domain.Pageable;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class ClusterItemDataProviderMockTest {
 
-	private final Supplier<List<TestItem>> itemSupplier = Suppliers.memoize(this::getItems);
-
-	public Page<TestItem> getTestItems(Queryable filter, Pageable pageable, ReportPortalUser.ProjectDetails projectDetails,
-			ReportPortalUser user, Map<String, String> params) {
-		final List<TestItem> testItems = itemSupplier.get();
-		final List<TestItem> content = testItems.stream()
-				.skip(pageable.getOffset())
-				.limit(pageable.getPageSize())
-				.collect(Collectors.toList());
-		return new PageImpl<>(content, pageable, testItems.size());
-	}
-
-	public Set<Statistics> accumulateStatistics(Queryable filter, ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user,
-			Map<String, String> params) {
-		final List<TestItem> testItems = itemSupplier.get();
-
-		return testItems.stream()
-				.map(TestItem::getItemResults)
-				.flatMap(r -> r.getStatistics().stream())
-				.collect(groupingBy(Statistics::getStatisticsField, LinkedHashMap::new, Collectors.summingInt(Statistics::getCounter)))
-				.entrySet()
-				.stream()
-				.map(entry -> new Statistics(entry.getKey(), entry.getValue()))
-				.collect(Collectors.toCollection(LinkedHashSet::new));
-	}
-
-	private List<TestItem> getItems() {
-		return IntStream.range(1, 21).mapToObj(this::getTestItem).collect(Collectors.toList());
-	}
-
-	private TestItem getTestItem(int index) {
-		final TestItem testItem = new TestItem();
-		testItem.setItemId((long) index);
-		testItem.setUuid(String.valueOf(index));
-		testItem.setUniqueId(String.valueOf(index));
-		testItem.setTestCaseId(String.valueOf(index));
-		testItem.setTestCaseHash(index);
-		testItem.setName("name " + index);
-		testItem.setCodeRef("ref" + index);
-		testItem.setDescription("description " + index);
-		testItem.setHasChildren(false);
-		testItem.setType(TestItemTypeEnum.STEP);
-		testItem.setHasRetries(false);
-		testItem.setHasStats(true);
-		testItem.setLastModified(LocalDateTime.now(ZoneOffset.UTC));
-		testItem.setPath(String.valueOf(index));
-		testItem.setStartTime(LocalDateTime.now(ZoneOffset.UTC));
-
-		final Set<Parameter> parameters = getParameters(index);
-		testItem.setParameters(parameters);
-
-		final Set<ItemAttribute> attributes = getItemAttributes(index);
-		testItem.setAttributes(attributes);
-
-		final TestItemResults testItemResults = getTestItemResults((long) index);
-
-		testItem.setItemResults(testItemResults);
-
-		return testItem;
-	}
-
-	private Set<Parameter> getParameters(int index) {
-		final Parameter parameter = new Parameter();
-		parameter.setKey("param key " + index);
-		parameter.setValue("param value " + index);
-		return Set.of(parameter);
-	}
-
-	private Set<ItemAttribute> getItemAttributes(int index) {
-		final ItemAttribute itemAttribute = new ItemAttribute();
-		itemAttribute.setKey("key" + index);
-		itemAttribute.setValue("value" + index);
-		itemAttribute.setSystem(false);
-
-		return Set.of(itemAttribute);
-	}
-
-	private TestItemResults getTestItemResults(Long index) {
-		final TestItemResults testItemResults = new TestItemResults();
-		testItemResults.setDuration(0.01);
-		testItemResults.setEndTime(LocalDateTime.now(ZoneOffset.UTC));
-		testItemResults.setStatus(StatusEnum.FAILED);
-
-		final IssueEntity issueEntity = getIssueEntity(index);
-
-		testItemResults.setIssue(issueEntity);
-
-		final LinkedHashSet<Statistics> statistics = getStatistics();
-
-		testItemResults.setStatistics(statistics);
-		return testItemResults;
-	}
-
-	private IssueEntity getIssueEntity(Long index) {
-		final IssueEntity issueEntity = new IssueEntity();
-		issueEntity.setIssueId(index);
-		issueEntity.setIssueDescription("description " + index);
-		issueEntity.setAutoAnalyzed(false);
-		issueEntity.setIgnoreAnalyzer(false);
-
-		final IssueType issueType = getIssueType();
-
-		issueEntity.setIssueType(issueType);
-		return issueEntity;
-	}
-
-	private IssueType getIssueType() {
-		final IssueType issueType = new IssueType();
-		issueType.setId(1L);
-		issueType.setLocator("ti001");
-		issueType.setHexColor("#ffb743");
-		issueType.setLongName("To Investigate");
-		issueType.setShortName("TI");
-
-		final IssueGroup issueGroup = getIssueGroup();
-		issueType.setIssueGroup(issueGroup);
-		return issueType;
-	}
-
-	private IssueGroup getIssueGroup() {
-		final IssueGroup issueGroup = new IssueGroup();
-		issueGroup.setId(1);
-		issueGroup.setTestItemIssueGroup(TestItemIssueGroup.TO_INVESTIGATE);
-		return issueGroup;
-	}
-
-	private LinkedHashSet<Statistics> getStatistics() {
-		return Map.of(1L,
-				"statistics$executions$total",
-				2L,
-				"statistics$executions$passed",
-				3L,
-				"statistics$executions$skipped",
-				4L,
-				"statistics$executions$failed",
-				12L,
-				"statistics$defects$to_investigate$ti001"
-		).entrySet().stream().map(entry -> {
-			final StatisticsField sf = new StatisticsField(entry.getValue());
-			sf.setId(entry.getKey());
-			return new Statistics(sf, 1);
-		}).collect(Collectors.toCollection(LinkedHashSet::new));
-	}
+  private final Supplier<List<TestItem>> itemSupplier = Suppliers.memoize(this::getItems);
+
+  public Page<TestItem> getTestItems(Queryable filter, Pageable pageable,
+      ReportPortalUser.ProjectDetails projectDetails,
+      ReportPortalUser user, Map<String, String> params) {
+    final List<TestItem> testItems = itemSupplier.get();
+    final List<TestItem> content = testItems.stream()
+        .skip(pageable.getOffset())
+        .limit(pageable.getPageSize())
+        .collect(Collectors.toList());
+    return new PageImpl<>(content, pageable, testItems.size());
+  }
+
+  public Set<Statistics> accumulateStatistics(Queryable filter,
+      ReportPortalUser.ProjectDetails projectDetails, ReportPortalUser user,
+      Map<String, String> params) {
+    final List<TestItem> testItems = itemSupplier.get();
+
+    return testItems.stream()
+        .map(TestItem::getItemResults)
+        .flatMap(r -> r.getStatistics().stream())
+        .collect(groupingBy(Statistics::getStatisticsField, LinkedHashMap::new,
+            Collectors.summingInt(Statistics::getCounter)))
+        .entrySet()
+        .stream()
+        .map(entry -> new Statistics(entry.getKey(), entry.getValue()))
+        .collect(Collectors.toCollection(LinkedHashSet::new));
+  }
+
+  private List<TestItem> getItems() {
+    return IntStream.range(1, 21).mapToObj(this::getTestItem).collect(Collectors.toList());
+  }
+
+  private TestItem getTestItem(int index) {
+    final TestItem testItem = new TestItem();
+    testItem.setItemId((long) index);
+    testItem.setUuid(String.valueOf(index));
+    testItem.setUniqueId(String.valueOf(index));
+    testItem.setTestCaseId(String.valueOf(index));
+    testItem.setTestCaseHash(index);
+    testItem.setName("name " + index);
+    testItem.setCodeRef("ref" + index);
+    testItem.setDescription("description " + index);
+    testItem.setHasChildren(false);
+    testItem.setType(TestItemTypeEnum.STEP);
+    testItem.setHasRetries(false);
+    testItem.setHasStats(true);
+    testItem.setLastModified(LocalDateTime.now(ZoneOffset.UTC));
+    testItem.setPath(String.valueOf(index));
+    testItem.setStartTime(LocalDateTime.now(ZoneOffset.UTC));
+
+    final Set<Parameter> parameters = getParameters(index);
+    testItem.setParameters(parameters);
+
+    final Set<ItemAttribute> attributes = getItemAttributes(index);
+    testItem.setAttributes(attributes);
+
+    final TestItemResults testItemResults = getTestItemResults((long) index);
+
+    testItem.setItemResults(testItemResults);
+
+    return testItem;
+  }
+
+  private Set<Parameter> getParameters(int index) {
+    final Parameter parameter = new Parameter();
+    parameter.setKey("param key " + index);
+    parameter.setValue("param value " + index);
+    return Set.of(parameter);
+  }
+
+  private Set<ItemAttribute> getItemAttributes(int index) {
+    final ItemAttribute itemAttribute = new ItemAttribute();
+    itemAttribute.setKey("key" + index);
+    itemAttribute.setValue("value" + index);
+    itemAttribute.setSystem(false);
+
+    return Set.of(itemAttribute);
+  }
+
+  private TestItemResults getTestItemResults(Long index) {
+    final TestItemResults testItemResults = new TestItemResults();
+    testItemResults.setDuration(0.01);
+    testItemResults.setEndTime(LocalDateTime.now(ZoneOffset.UTC));
+    testItemResults.setStatus(StatusEnum.FAILED);
+
+    final IssueEntity issueEntity = getIssueEntity(index);
+
+    testItemResults.setIssue(issueEntity);
+
+    final LinkedHashSet<Statistics> statistics = getStatistics();
+
+    testItemResults.setStatistics(statistics);
+    return testItemResults;
+  }
+
+  private IssueEntity getIssueEntity(Long index) {
+    final IssueEntity issueEntity = new IssueEntity();
+    issueEntity.setIssueId(index);
+    issueEntity.setIssueDescription("description " + index);
+    issueEntity.setAutoAnalyzed(false);
+    issueEntity.setIgnoreAnalyzer(false);
+
+    final IssueType issueType = getIssueType();
+
+    issueEntity.setIssueType(issueType);
+    return issueEntity;
+  }
+
+  private IssueType getIssueType() {
+    final IssueType issueType = new IssueType();
+    issueType.setId(1L);
+    issueType.setLocator("ti001");
+    issueType.setHexColor("#ffb743");
+    issueType.setLongName("To Investigate");
+    issueType.setShortName("TI");
+
+    final IssueGroup issueGroup = getIssueGroup();
+    issueType.setIssueGroup(issueGroup);
+    return issueType;
+  }
+
+  private IssueGroup getIssueGroup() {
+    final IssueGroup issueGroup = new IssueGroup();
+    issueGroup.setId(1);
+    issueGroup.setTestItemIssueGroup(TestItemIssueGroup.TO_INVESTIGATE);
+    return issueGroup;
+  }
+
+  private LinkedHashSet<Statistics> getStatistics() {
+    return Map.of(1L,
+        "statistics$executions$total",
+        2L,
+        "statistics$executions$passed",
+        3L,
+        "statistics$executions$skipped",
+        4L,
+        "statistics$executions$failed",
+        12L,
+        "statistics$defects$to_investigate$ti001"
+    ).entrySet().stream().map(entry -> {
+      final StatisticsField sf = new StatisticsField(entry.getValue());
+      sf.setId(entry.getKey());
+      return new Statistics(sf, 1);
+    }).collect(Collectors.toCollection(LinkedHashSet::new));
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/item/validator/state/NotNestedStepValidatorTest.java b/src/test/java/com/epam/ta/reportportal/core/item/validator/state/NotNestedStepValidatorTest.java
index ebb4c1de3f..479297051c 100644
--- a/src/test/java/com/epam/ta/reportportal/core/item/validator/state/NotNestedStepValidatorTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/item/validator/state/NotNestedStepValidatorTest.java
@@ -20,27 +20,25 @@
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
-import static org.junit.jupiter.api.Assertions.*;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class NotNestedStepValidatorTest {
 
-	private final NotNestedStepValidator validator = new NotNestedStepValidator();
-
-	@Test
-	void shouldReturnTrueWhenHasStats() {
-		final TestItem testItem = new TestItem();
-		testItem.setHasStats(true);
-		Assertions.assertTrue(validator.validate(testItem));
-	}
-
-	@Test
-	void shouldReturnFalseWhenNotHasStats() {
-		final TestItem testItem = new TestItem();
-		testItem.setHasStats(false);
-		Assertions.assertFalse(validator.validate(testItem));
-	}
+  private final NotNestedStepValidator validator = new NotNestedStepValidator();
+
+  @Test
+  void shouldReturnTrueWhenHasStats() {
+    final TestItem testItem = new TestItem();
+    testItem.setHasStats(true);
+    Assertions.assertTrue(validator.validate(testItem));
+  }
+
+  @Test
+  void shouldReturnFalseWhenNotHasStats() {
+    final TestItem testItem = new TestItem();
+    testItem.setHasStats(false);
+    Assertions.assertFalse(validator.validate(testItem));
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/item/validator/state/NotRetryValidatorTest.java b/src/test/java/com/epam/ta/reportportal/core/item/validator/state/NotRetryValidatorTest.java
index 75729a10c0..363ed3a0c2 100644
--- a/src/test/java/com/epam/ta/reportportal/core/item/validator/state/NotRetryValidatorTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/item/validator/state/NotRetryValidatorTest.java
@@ -20,33 +20,31 @@
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
-import static org.junit.jupiter.api.Assertions.*;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class NotRetryValidatorTest {
 
-	private final NotRetryValidator validator = new NotRetryValidator();
-
-	@Test
-	void shouldReturnTrueWhenRetryOfIsNullAndLaunchIdIsNotNull() {
-		final TestItem testItem = new TestItem();
-		testItem.setLaunchId(1L);
-		Assertions.assertTrue(validator.validate(testItem));
-	}
-
-	@Test
-	void shouldReturnFalseWhenRetryOfIsNotNull() {
-		final TestItem testItem = new TestItem();
-		testItem.setRetryOf(1L);
-		Assertions.assertFalse(validator.validate(testItem));
-	}
-
-	@Test
-	void shouldReturnFalseWhenLaunchIdIsNull() {
-		final TestItem testItem = new TestItem();
-		Assertions.assertFalse(validator.validate(testItem));
-	}
+  private final NotRetryValidator validator = new NotRetryValidator();
+
+  @Test
+  void shouldReturnTrueWhenRetryOfIsNullAndLaunchIdIsNotNull() {
+    final TestItem testItem = new TestItem();
+    testItem.setLaunchId(1L);
+    Assertions.assertTrue(validator.validate(testItem));
+  }
+
+  @Test
+  void shouldReturnFalseWhenRetryOfIsNotNull() {
+    final TestItem testItem = new TestItem();
+    testItem.setRetryOf(1L);
+    Assertions.assertFalse(validator.validate(testItem));
+  }
+
+  @Test
+  void shouldReturnFalseWhenLaunchIdIsNull() {
+    final TestItem testItem = new TestItem();
+    Assertions.assertFalse(validator.validate(testItem));
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/launch/cluster/CreateClusterHandlerImplTest.java b/src/test/java/com/epam/ta/reportportal/core/launch/cluster/CreateClusterHandlerImplTest.java
index 7f4c3c900f..1c274d8eb0 100644
--- a/src/test/java/com/epam/ta/reportportal/core/launch/cluster/CreateClusterHandlerImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/launch/cluster/CreateClusterHandlerImplTest.java
@@ -16,116 +16,124 @@
 
 package com.epam.ta.reportportal.core.launch.cluster;
 
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.anyLong;
+import static org.mockito.Mockito.anySet;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.core.analyzer.auto.client.model.cluster.ClusterData;
 import com.epam.ta.reportportal.core.analyzer.auto.client.model.cluster.ClusterInfoRs;
 import com.epam.ta.reportportal.dao.ClusterRepository;
 import com.epam.ta.reportportal.dao.LogRepository;
 import com.epam.ta.reportportal.entity.cluster.Cluster;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.*;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @ExtendWith(MockitoExtension.class)
 class CreateClusterHandlerImplTest {
 
-	@Mock
-	private ClusterRepository clusterRepository;
-
-	@Mock
-	private LogRepository logRepository;
-
-	@InjectMocks
-	private CreateClusterHandlerImpl createClusterHandler;
-
-	@Test
-	void updateCluster() {
-
-		final ClusterData clusterData = new ClusterData();
-		clusterData.setProject(1L);
-		clusterData.setLaunchId(1L);
-
-		final ClusterInfoRs first = new ClusterInfoRs();
-		first.setClusterId(1L);
-		first.setClusterMessage("first");
-		first.setLogIds(Set.of(1L, 2L));
-		first.setItemIds(Set.of(1L, 2L));
-
-		final ClusterInfoRs second = new ClusterInfoRs();
-		second.setClusterId(2L);
-		second.setClusterMessage("second");
-		second.setLogIds(Set.of(3L, 4L));
-		second.setItemIds(Set.of(3L, 4L));
-
-		clusterData.setClusters(List.of(first, second));
-
-		final Cluster firstCluster = new Cluster();
-		firstCluster.setIndexId(1L);
-		final Cluster secondCluster = new Cluster();
-		secondCluster.setIndexId(2L);
-		when(clusterRepository.findByIndexIdAndLaunchId(1L, clusterData.getLaunchId())).thenReturn(Optional.of(firstCluster));
-		when(clusterRepository.findByIndexIdAndLaunchId(2L, clusterData.getLaunchId())).thenReturn(Optional.of(secondCluster));
-
-		doAnswer(invocation -> {
-			Object[] args = invocation.getArguments();
-			Cluster cluster = ((Cluster) args[0]);
-			cluster.setId(cluster.getIndexId());
-			return cluster;
-		}).when(clusterRepository).save(any(Cluster.class));
-
-		createClusterHandler.create(clusterData);
-
-		verify(clusterRepository, times(2)).save(any(Cluster.class));
-		verify(clusterRepository, times(2)).saveClusterTestItems(any(Cluster.class), anySet());
-		verify(logRepository, times(2)).updateClusterIdByIdIn(any(Long.class), anySet());
-	}
-
-	@Test
-	void saveCluster() {
-
-		final ClusterData clusterData = new ClusterData();
-		clusterData.setProject(1L);
-		clusterData.setLaunchId(1L);
-
-		final ClusterInfoRs first = new ClusterInfoRs();
-		first.setClusterId(1L);
-		first.setClusterMessage("first");
-		first.setLogIds(Set.of(1L, 2L));
-		first.setItemIds(Set.of(1L, 2L));
-
-		final ClusterInfoRs second = new ClusterInfoRs();
-		second.setClusterId(2L);
-		second.setClusterMessage("second");
-		second.setLogIds(Set.of(3L, 4L));
-		second.setItemIds(Set.of(3L, 4L));
-
-		clusterData.setClusters(List.of(first, second));
-
-		when(clusterRepository.findByIndexIdAndLaunchId(anyLong(), eq(clusterData.getLaunchId()))).thenReturn(Optional.empty());
-
-		doAnswer(invocation -> {
-			Object[] args = invocation.getArguments();
-			Cluster cluster = ((Cluster) args[0]);
-			cluster.setId(cluster.getIndexId());
-			return cluster;
-		}).when(clusterRepository).save(any(Cluster.class));
-
-		createClusterHandler.create(clusterData);
-
-		verify(clusterRepository, times(2)).save(any(Cluster.class));
-		verify(clusterRepository, times(2)).saveClusterTestItems(any(Cluster.class), anySet());
-		verify(logRepository, times(2)).updateClusterIdByIdIn(any(Long.class), anySet());
-	}
+  @Mock
+  private ClusterRepository clusterRepository;
+
+  @Mock
+  private LogRepository logRepository;
+
+  @InjectMocks
+  private CreateClusterHandlerImpl createClusterHandler;
+
+  @Test
+  void updateCluster() {
+
+    final ClusterData clusterData = new ClusterData();
+    clusterData.setProject(1L);
+    clusterData.setLaunchId(1L);
+
+    final ClusterInfoRs first = new ClusterInfoRs();
+    first.setClusterId(1L);
+    first.setClusterMessage("first");
+    first.setLogIds(Set.of(1L, 2L));
+    first.setItemIds(Set.of(1L, 2L));
+
+    final ClusterInfoRs second = new ClusterInfoRs();
+    second.setClusterId(2L);
+    second.setClusterMessage("second");
+    second.setLogIds(Set.of(3L, 4L));
+    second.setItemIds(Set.of(3L, 4L));
+
+    clusterData.setClusters(List.of(first, second));
+
+    final Cluster firstCluster = new Cluster();
+    firstCluster.setIndexId(1L);
+    final Cluster secondCluster = new Cluster();
+    secondCluster.setIndexId(2L);
+    when(clusterRepository.findByIndexIdAndLaunchId(1L, clusterData.getLaunchId())).thenReturn(
+        Optional.of(firstCluster));
+    when(clusterRepository.findByIndexIdAndLaunchId(2L, clusterData.getLaunchId())).thenReturn(
+        Optional.of(secondCluster));
+
+    doAnswer(invocation -> {
+      Object[] args = invocation.getArguments();
+      Cluster cluster = ((Cluster) args[0]);
+      cluster.setId(cluster.getIndexId());
+      return cluster;
+    }).when(clusterRepository).save(any(Cluster.class));
+
+    createClusterHandler.create(clusterData);
+
+    verify(clusterRepository, times(2)).save(any(Cluster.class));
+    verify(clusterRepository, times(2)).saveClusterTestItems(any(Cluster.class), anySet());
+    verify(logRepository, times(2)).updateClusterIdByIdIn(any(Long.class), anySet());
+  }
+
+  @Test
+  void saveCluster() {
+
+    final ClusterData clusterData = new ClusterData();
+    clusterData.setProject(1L);
+    clusterData.setLaunchId(1L);
+
+    final ClusterInfoRs first = new ClusterInfoRs();
+    first.setClusterId(1L);
+    first.setClusterMessage("first");
+    first.setLogIds(Set.of(1L, 2L));
+    first.setItemIds(Set.of(1L, 2L));
+
+    final ClusterInfoRs second = new ClusterInfoRs();
+    second.setClusterId(2L);
+    second.setClusterMessage("second");
+    second.setLogIds(Set.of(3L, 4L));
+    second.setItemIds(Set.of(3L, 4L));
+
+    clusterData.setClusters(List.of(first, second));
+
+    when(clusterRepository.findByIndexIdAndLaunchId(anyLong(),
+        eq(clusterData.getLaunchId()))).thenReturn(Optional.empty());
+
+    doAnswer(invocation -> {
+      Object[] args = invocation.getArguments();
+      Cluster cluster = ((Cluster) args[0]);
+      cluster.setId(cluster.getIndexId());
+      return cluster;
+    }).when(clusterRepository).save(any(Cluster.class));
+
+    createClusterHandler.create(clusterData);
+
+    verify(clusterRepository, times(2)).save(any(Cluster.class));
+    verify(clusterRepository, times(2)).saveClusterTestItems(any(Cluster.class), anySet());
+    verify(logRepository, times(2)).updateClusterIdByIdIn(any(Long.class), anySet());
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/launch/cluster/UniqueErrorAnalysisStarterTest.java b/src/test/java/com/epam/ta/reportportal/core/launch/cluster/UniqueErrorAnalysisStarterTest.java
index 49140f3501..9bc2eca9da 100644
--- a/src/test/java/com/epam/ta/reportportal/core/launch/cluster/UniqueErrorAnalysisStarterTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/launch/cluster/UniqueErrorAnalysisStarterTest.java
@@ -1,58 +1,70 @@
 package com.epam.ta.reportportal.core.launch.cluster;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
 import com.epam.ta.reportportal.core.launch.cluster.config.ClusterEntityContext;
 import com.epam.ta.reportportal.core.launch.cluster.config.GenerateClustersConfig;
-import org.junit.jupiter.api.Test;
-import org.mockito.ArgumentCaptor;
-
 import java.util.HashMap;
 import java.util.List;
-
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.Mockito.*;
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class UniqueErrorAnalysisStarterTest {
 
-	private final ClusterGenerator clusterGenerator = mock(ClusterGenerator.class);
+  private final ClusterGenerator clusterGenerator = mock(ClusterGenerator.class);
 
-	private final UniqueErrorAnalysisStarter starter = new UniqueErrorAnalysisStarter(clusterGenerator);
+  private final UniqueErrorAnalysisStarter starter = new UniqueErrorAnalysisStarter(
+      clusterGenerator);
 
-	@Test
-	void shouldGenerateNotForUpdateWhenNoItemIds() {
+  @Test
+  void shouldGenerateNotForUpdateWhenNoItemIds() {
 
-		final ClusterEntityContext entityContext = ClusterEntityContext.of(1L, 1L);
+    final ClusterEntityContext entityContext = ClusterEntityContext.of(1L, 1L);
 
-		starter.start(entityContext, new HashMap<>());
+    starter.start(entityContext, new HashMap<>());
 
-		final ArgumentCaptor<GenerateClustersConfig> configArgumentCaptor = ArgumentCaptor.forClass(GenerateClustersConfig.class);
-		verify(clusterGenerator, times(1)).generate(configArgumentCaptor.capture());
+    final ArgumentCaptor<GenerateClustersConfig> configArgumentCaptor = ArgumentCaptor.forClass(
+        GenerateClustersConfig.class);
+    verify(clusterGenerator, times(1)).generate(configArgumentCaptor.capture());
 
-		final GenerateClustersConfig generateClustersConfig = configArgumentCaptor.getValue();
+    final GenerateClustersConfig generateClustersConfig = configArgumentCaptor.getValue();
 
-		assertFalse(generateClustersConfig.isForUpdate());
-		assertEquals(entityContext.getLaunchId(), generateClustersConfig.getEntityContext().getLaunchId());
-		assertEquals(entityContext.getProjectId(), generateClustersConfig.getEntityContext().getProjectId());
-		assertEquals(entityContext.getItemIds(), generateClustersConfig.getEntityContext().getItemIds());
-	}
+    assertFalse(generateClustersConfig.isForUpdate());
+    assertEquals(entityContext.getLaunchId(),
+        generateClustersConfig.getEntityContext().getLaunchId());
+    assertEquals(entityContext.getProjectId(),
+        generateClustersConfig.getEntityContext().getProjectId());
+    assertEquals(entityContext.getItemIds(),
+        generateClustersConfig.getEntityContext().getItemIds());
+  }
 
-	@Test
-	void shouldGenerateForUpdateWhenItemIdsExist() {
-		final ClusterEntityContext entityContext = ClusterEntityContext.of(1L, 1L, List.of(1L, 2L));
+  @Test
+  void shouldGenerateForUpdateWhenItemIdsExist() {
+    final ClusterEntityContext entityContext = ClusterEntityContext.of(1L, 1L, List.of(1L, 2L));
 
-		starter.start(entityContext, new HashMap<>());
+    starter.start(entityContext, new HashMap<>());
 
-		final ArgumentCaptor<GenerateClustersConfig> configArgumentCaptor = ArgumentCaptor.forClass(GenerateClustersConfig.class);
-		verify(clusterGenerator, times(1)).generate(configArgumentCaptor.capture());
+    final ArgumentCaptor<GenerateClustersConfig> configArgumentCaptor = ArgumentCaptor.forClass(
+        GenerateClustersConfig.class);
+    verify(clusterGenerator, times(1)).generate(configArgumentCaptor.capture());
 
-		final GenerateClustersConfig generateClustersConfig = configArgumentCaptor.getValue();
+    final GenerateClustersConfig generateClustersConfig = configArgumentCaptor.getValue();
 
-		assertTrue(generateClustersConfig.isForUpdate());
-		assertEquals(entityContext.getLaunchId(), generateClustersConfig.getEntityContext().getLaunchId());
-		assertEquals(entityContext.getProjectId(), generateClustersConfig.getEntityContext().getProjectId());
-		assertEquals(entityContext.getItemIds(), generateClustersConfig.getEntityContext().getItemIds());
-	}
+    assertTrue(generateClustersConfig.isForUpdate());
+    assertEquals(entityContext.getLaunchId(),
+        generateClustersConfig.getEntityContext().getLaunchId());
+    assertEquals(entityContext.getProjectId(),
+        generateClustersConfig.getEntityContext().getProjectId());
+    assertEquals(entityContext.getItemIds(),
+        generateClustersConfig.getEntityContext().getItemIds());
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/launch/cluster/UniqueErrorGeneratorAsyncTest.java b/src/test/java/com/epam/ta/reportportal/core/launch/cluster/UniqueErrorGeneratorAsyncTest.java
index f014db5ce7..682b4d7ebd 100644
--- a/src/test/java/com/epam/ta/reportportal/core/launch/cluster/UniqueErrorGeneratorAsyncTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/launch/cluster/UniqueErrorGeneratorAsyncTest.java
@@ -16,6 +16,20 @@
 
 package com.epam.ta.reportportal.core.launch.cluster;
 
+import static com.epam.ta.reportportal.core.launch.cluster.utils.ConfigProvider.getConfig;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.anyList;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.doCallRealMethod;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerStatusCache;
 import com.epam.ta.reportportal.core.launch.cluster.config.ClusterEntityContext;
 import com.epam.ta.reportportal.core.launch.cluster.config.GenerateClustersConfig;
@@ -25,107 +39,108 @@
 import org.junit.jupiter.api.Test;
 import org.springframework.core.task.SyncTaskExecutor;
 
-import static com.epam.ta.reportportal.core.launch.cluster.utils.ConfigProvider.getConfig;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.ArgumentMatchers.*;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.*;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class UniqueErrorGeneratorAsyncTest {
 
-	private final SyncTaskExecutor logClusterExecutor = mock(SyncTaskExecutor.class);
-
-	private final AnalyzerStatusCache analyzerStatusCache = mock(AnalyzerStatusCache.class);
-
-	private final PipelineConstructor<GenerateClustersConfig> pipelineConstructor = (PipelineConstructor<GenerateClustersConfig>) mock(
-			PipelineConstructor.class);
-
-	private final TransactionalPipeline transactionalPipeline = mock(TransactionalPipeline.class);
-
-	private final UniqueErrorGeneratorAsync clusterGenerator = new UniqueErrorGeneratorAsync(analyzerStatusCache,
-			pipelineConstructor,
-			transactionalPipeline,
-			logClusterExecutor
-	);
-
-	@Test
-	void shouldFailWhenCacheContainsLaunchId() {
-		when(analyzerStatusCache.containsLaunchId(anyString(), anyLong())).thenReturn(true);
-
-		final GenerateClustersConfig config = getConfig(false);
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class, () -> clusterGenerator.generate(config));
-		assertEquals("Impossible interact with integration. Clusters creation is in progress.", exception.getMessage());
-
-		final ClusterEntityContext entityContext = config.getEntityContext();
-		verify(analyzerStatusCache, times(0)).analyzeStarted(AnalyzerStatusCache.CLUSTER_KEY,
-				entityContext.getLaunchId(),
-				entityContext.getProjectId()
-		);
-	}
-
-	@Test
-	void shouldGenerate() {
-		when(analyzerStatusCache.containsLaunchId(anyString(), anyLong())).thenReturn(false);
-		doCallRealMethod().when(logClusterExecutor).execute(any(Runnable.class));
-
-		final GenerateClustersConfig config = getConfig(false);
-
-		clusterGenerator.generate(config);
-
-		final ClusterEntityContext entityContext = config.getEntityContext();
-		verify(analyzerStatusCache, times(1)).analyzeStarted(AnalyzerStatusCache.CLUSTER_KEY,
-				entityContext.getLaunchId(),
-				entityContext.getProjectId()
-		);
-		verify(pipelineConstructor, times(1)).construct(config);
-		verify(transactionalPipeline, times(1)).run(anyList());
-		verify(analyzerStatusCache, times(1)).analyzeFinished(AnalyzerStatusCache.CLUSTER_KEY, entityContext.getLaunchId());
-	}
-
-	@Test
-	void shouldCleanCacheWhenExceptionThrown() {
-		when(analyzerStatusCache.containsLaunchId(anyString(), anyLong())).thenReturn(false);
-		doCallRealMethod().when(logClusterExecutor).execute(any(Runnable.class));
-
-		final GenerateClustersConfig config = getConfig(false);
-
-		doThrow(new RuntimeException("Exception during generation")).when(transactionalPipeline).run(anyList());
-
-		clusterGenerator.generate(config);
-
-		final ClusterEntityContext entityContext = config.getEntityContext();
-		verify(analyzerStatusCache, times(1)).analyzeStarted(AnalyzerStatusCache.CLUSTER_KEY,
-				entityContext.getLaunchId(),
-				entityContext.getProjectId()
-		);
-		verify(pipelineConstructor, times(1)).construct(config);
-		verify(transactionalPipeline, times(1)).run(anyList());
-		verify(analyzerStatusCache, times(1)).analyzeFinished(AnalyzerStatusCache.CLUSTER_KEY, entityContext.getLaunchId());
-	}
-
-	@Test
-	void shouldCleanCacheWhenExceptionThrownDuringTaskSubmit() {
-		when(analyzerStatusCache.containsLaunchId(anyString(), anyLong())).thenReturn(false);
-
-		final GenerateClustersConfig config = getConfig(false);
-
-		doThrow(new RuntimeException("Exception during generation")).when(logClusterExecutor).execute(any(Runnable.class));
-
-		clusterGenerator.generate(config);
-
-		final ClusterEntityContext entityContext = config.getEntityContext();
-		verify(analyzerStatusCache, times(1)).analyzeStarted(AnalyzerStatusCache.CLUSTER_KEY,
-				entityContext.getLaunchId(),
-				entityContext.getProjectId()
-		);
-		verify(pipelineConstructor, times(0)).construct(any(GenerateClustersConfig.class));
-		verify(transactionalPipeline, times(0)).run(anyList());
-		verify(analyzerStatusCache, times(1)).analyzeFinished(AnalyzerStatusCache.CLUSTER_KEY, entityContext.getLaunchId());
-	}
+  private final SyncTaskExecutor logClusterExecutor = mock(SyncTaskExecutor.class);
+
+  private final AnalyzerStatusCache analyzerStatusCache = mock(AnalyzerStatusCache.class);
+
+  private final PipelineConstructor<GenerateClustersConfig> pipelineConstructor = (PipelineConstructor<GenerateClustersConfig>) mock(
+      PipelineConstructor.class);
+
+  private final TransactionalPipeline transactionalPipeline = mock(TransactionalPipeline.class);
+
+  private final UniqueErrorGeneratorAsync clusterGenerator = new UniqueErrorGeneratorAsync(
+      analyzerStatusCache,
+      pipelineConstructor,
+      transactionalPipeline,
+      logClusterExecutor
+  );
+
+  @Test
+  void shouldFailWhenCacheContainsLaunchId() {
+    when(analyzerStatusCache.containsLaunchId(anyString(), anyLong())).thenReturn(true);
+
+    final GenerateClustersConfig config = getConfig(false);
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> clusterGenerator.generate(config));
+    assertEquals("Impossible interact with integration. Clusters creation is in progress.",
+        exception.getMessage());
+
+    final ClusterEntityContext entityContext = config.getEntityContext();
+    verify(analyzerStatusCache, times(0)).analyzeStarted(AnalyzerStatusCache.CLUSTER_KEY,
+        entityContext.getLaunchId(),
+        entityContext.getProjectId()
+    );
+  }
+
+  @Test
+  void shouldGenerate() {
+    when(analyzerStatusCache.containsLaunchId(anyString(), anyLong())).thenReturn(false);
+    doCallRealMethod().when(logClusterExecutor).execute(any(Runnable.class));
+
+    final GenerateClustersConfig config = getConfig(false);
+
+    clusterGenerator.generate(config);
+
+    final ClusterEntityContext entityContext = config.getEntityContext();
+    verify(analyzerStatusCache, times(1)).analyzeStarted(AnalyzerStatusCache.CLUSTER_KEY,
+        entityContext.getLaunchId(),
+        entityContext.getProjectId()
+    );
+    verify(pipelineConstructor, times(1)).construct(config);
+    verify(transactionalPipeline, times(1)).run(anyList());
+    verify(analyzerStatusCache, times(1)).analyzeFinished(AnalyzerStatusCache.CLUSTER_KEY,
+        entityContext.getLaunchId());
+  }
+
+  @Test
+  void shouldCleanCacheWhenExceptionThrown() {
+    when(analyzerStatusCache.containsLaunchId(anyString(), anyLong())).thenReturn(false);
+    doCallRealMethod().when(logClusterExecutor).execute(any(Runnable.class));
+
+    final GenerateClustersConfig config = getConfig(false);
+
+    doThrow(new RuntimeException("Exception during generation")).when(transactionalPipeline)
+        .run(anyList());
+
+    clusterGenerator.generate(config);
+
+    final ClusterEntityContext entityContext = config.getEntityContext();
+    verify(analyzerStatusCache, times(1)).analyzeStarted(AnalyzerStatusCache.CLUSTER_KEY,
+        entityContext.getLaunchId(),
+        entityContext.getProjectId()
+    );
+    verify(pipelineConstructor, times(1)).construct(config);
+    verify(transactionalPipeline, times(1)).run(anyList());
+    verify(analyzerStatusCache, times(1)).analyzeFinished(AnalyzerStatusCache.CLUSTER_KEY,
+        entityContext.getLaunchId());
+  }
+
+  @Test
+  void shouldCleanCacheWhenExceptionThrownDuringTaskSubmit() {
+    when(analyzerStatusCache.containsLaunchId(anyString(), anyLong())).thenReturn(false);
+
+    final GenerateClustersConfig config = getConfig(false);
+
+    doThrow(new RuntimeException("Exception during generation")).when(logClusterExecutor)
+        .execute(any(Runnable.class));
+
+    clusterGenerator.generate(config);
+
+    final ClusterEntityContext entityContext = config.getEntityContext();
+    verify(analyzerStatusCache, times(1)).analyzeStarted(AnalyzerStatusCache.CLUSTER_KEY,
+        entityContext.getLaunchId(),
+        entityContext.getProjectId()
+    );
+    verify(pipelineConstructor, times(0)).construct(any(GenerateClustersConfig.class));
+    verify(transactionalPipeline, times(0)).run(anyList());
+    verify(analyzerStatusCache, times(1)).analyzeFinished(AnalyzerStatusCache.CLUSTER_KEY,
+        entityContext.getLaunchId());
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/launch/cluster/UniqueErrorGeneratorTest.java b/src/test/java/com/epam/ta/reportportal/core/launch/cluster/UniqueErrorGeneratorTest.java
index fb189153d5..dc5c5911d0 100644
--- a/src/test/java/com/epam/ta/reportportal/core/launch/cluster/UniqueErrorGeneratorTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/launch/cluster/UniqueErrorGeneratorTest.java
@@ -16,6 +16,18 @@
 
 package com.epam.ta.reportportal.core.launch.cluster;
 
+import static com.epam.ta.reportportal.core.launch.cluster.utils.ConfigProvider.getConfig;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.anyList;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.core.analyzer.auto.impl.AnalyzerStatusCache;
 import com.epam.ta.reportportal.core.launch.cluster.config.ClusterEntityContext;
 import com.epam.ta.reportportal.core.launch.cluster.config.GenerateClustersConfig;
@@ -24,82 +36,81 @@
 import com.epam.ta.reportportal.pipeline.TransactionalPipeline;
 import org.junit.jupiter.api.Test;
 
-import static com.epam.ta.reportportal.core.launch.cluster.utils.ConfigProvider.getConfig;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.*;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class UniqueErrorGeneratorTest {
 
-	private final AnalyzerStatusCache analyzerStatusCache = mock(AnalyzerStatusCache.class);
-
-	private final PipelineConstructor<GenerateClustersConfig> pipelineConstructor = (PipelineConstructor<GenerateClustersConfig>) mock(
-			PipelineConstructor.class);
-
-	private final TransactionalPipeline transactionalPipeline = mock(TransactionalPipeline.class);
-
-	private final UniqueErrorGenerator clusterGenerator = new UniqueErrorGenerator(analyzerStatusCache,
-			pipelineConstructor,
-			transactionalPipeline
-	);
-
-	@Test
-	void shouldFailWhenCacheContainsLaunchId() {
-		when(analyzerStatusCache.containsLaunchId(anyString(), anyLong())).thenReturn(true);
-
-		final GenerateClustersConfig config = getConfig(false);
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class, () -> clusterGenerator.generate(config));
-		assertEquals("Impossible interact with integration. Clusters creation is in progress.", exception.getMessage());
-
-		final ClusterEntityContext entityContext = config.getEntityContext();
-		verify(analyzerStatusCache, times(0)).analyzeStarted(AnalyzerStatusCache.CLUSTER_KEY,
-				entityContext.getLaunchId(),
-				entityContext.getProjectId()
-		);
-	}
-
-	@Test
-	void shouldGenerate() {
-		when(analyzerStatusCache.containsLaunchId(anyString(), anyLong())).thenReturn(false);
-
-		final GenerateClustersConfig config = getConfig(false);
-
-		clusterGenerator.generate(config);
-
-		final ClusterEntityContext entityContext = config.getEntityContext();
-		verify(analyzerStatusCache, times(1)).analyzeStarted(AnalyzerStatusCache.CLUSTER_KEY,
-				entityContext.getLaunchId(),
-				entityContext.getProjectId()
-		);
-		verify(pipelineConstructor, times(1)).construct(config);
-		verify(transactionalPipeline, times(1)).run(anyList());
-		verify(analyzerStatusCache, times(1)).analyzeFinished(AnalyzerStatusCache.CLUSTER_KEY, entityContext.getLaunchId());
-	}
-
-	@Test
-	void shouldCleanCacheWhenExceptionThrown() {
-		when(analyzerStatusCache.containsLaunchId(anyString(), anyLong())).thenReturn(false);
-
-		final GenerateClustersConfig config = getConfig(false);
-
-		doThrow(new RuntimeException("Exception during generation")).when(transactionalPipeline).run(anyList());
-
-		clusterGenerator.generate(config);
-
-		final ClusterEntityContext entityContext = config.getEntityContext();
-		verify(analyzerStatusCache, times(1)).analyzeStarted(AnalyzerStatusCache.CLUSTER_KEY,
-				entityContext.getLaunchId(),
-				entityContext.getProjectId()
-		);
-		verify(pipelineConstructor, times(1)).construct(config);
-		verify(transactionalPipeline, times(1)).run(anyList());
-		verify(analyzerStatusCache, times(1)).analyzeFinished(AnalyzerStatusCache.CLUSTER_KEY, entityContext.getLaunchId());
-	}
+  private final AnalyzerStatusCache analyzerStatusCache = mock(AnalyzerStatusCache.class);
+
+  private final PipelineConstructor<GenerateClustersConfig> pipelineConstructor = (PipelineConstructor<GenerateClustersConfig>) mock(
+      PipelineConstructor.class);
+
+  private final TransactionalPipeline transactionalPipeline = mock(TransactionalPipeline.class);
+
+  private final UniqueErrorGenerator clusterGenerator = new UniqueErrorGenerator(
+      analyzerStatusCache,
+      pipelineConstructor,
+      transactionalPipeline
+  );
+
+  @Test
+  void shouldFailWhenCacheContainsLaunchId() {
+    when(analyzerStatusCache.containsLaunchId(anyString(), anyLong())).thenReturn(true);
+
+    final GenerateClustersConfig config = getConfig(false);
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> clusterGenerator.generate(config));
+    assertEquals("Impossible interact with integration. Clusters creation is in progress.",
+        exception.getMessage());
+
+    final ClusterEntityContext entityContext = config.getEntityContext();
+    verify(analyzerStatusCache, times(0)).analyzeStarted(AnalyzerStatusCache.CLUSTER_KEY,
+        entityContext.getLaunchId(),
+        entityContext.getProjectId()
+    );
+  }
+
+  @Test
+  void shouldGenerate() {
+    when(analyzerStatusCache.containsLaunchId(anyString(), anyLong())).thenReturn(false);
+
+    final GenerateClustersConfig config = getConfig(false);
+
+    clusterGenerator.generate(config);
+
+    final ClusterEntityContext entityContext = config.getEntityContext();
+    verify(analyzerStatusCache, times(1)).analyzeStarted(AnalyzerStatusCache.CLUSTER_KEY,
+        entityContext.getLaunchId(),
+        entityContext.getProjectId()
+    );
+    verify(pipelineConstructor, times(1)).construct(config);
+    verify(transactionalPipeline, times(1)).run(anyList());
+    verify(analyzerStatusCache, times(1)).analyzeFinished(AnalyzerStatusCache.CLUSTER_KEY,
+        entityContext.getLaunchId());
+  }
+
+  @Test
+  void shouldCleanCacheWhenExceptionThrown() {
+    when(analyzerStatusCache.containsLaunchId(anyString(), anyLong())).thenReturn(false);
+
+    final GenerateClustersConfig config = getConfig(false);
+
+    doThrow(new RuntimeException("Exception during generation")).when(transactionalPipeline)
+        .run(anyList());
+
+    clusterGenerator.generate(config);
+
+    final ClusterEntityContext entityContext = config.getEntityContext();
+    verify(analyzerStatusCache, times(1)).analyzeStarted(AnalyzerStatusCache.CLUSTER_KEY,
+        entityContext.getLaunchId(),
+        entityContext.getProjectId()
+    );
+    verify(pipelineConstructor, times(1)).construct(config);
+    verify(transactionalPipeline, times(1)).run(anyList());
+    verify(analyzerStatusCache, times(1)).analyzeFinished(AnalyzerStatusCache.CLUSTER_KEY,
+        entityContext.getLaunchId());
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/DeleteClustersPartProviderTest.java b/src/test/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/DeleteClustersPartProviderTest.java
index ff921016a6..a1246f1cdc 100644
--- a/src/test/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/DeleteClustersPartProviderTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/DeleteClustersPartProviderTest.java
@@ -16,6 +16,11 @@
 
 package com.epam.ta.reportportal.core.launch.cluster.pipeline;
 
+import static com.epam.ta.reportportal.core.launch.cluster.utils.ConfigProvider.getConfig;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
 import com.epam.ta.reportportal.core.launch.cluster.config.ClusterEntityContext;
 import com.epam.ta.reportportal.core.launch.cluster.config.GenerateClustersConfig;
 import com.epam.ta.reportportal.dao.ClusterRepository;
@@ -23,41 +28,41 @@
 import com.epam.ta.reportportal.pipeline.PipelinePart;
 import org.junit.jupiter.api.Test;
 
-import static com.epam.ta.reportportal.core.launch.cluster.utils.ConfigProvider.getConfig;
-import static org.mockito.Mockito.*;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class DeleteClustersPartProviderTest {
 
-	private final ClusterRepository clusterRepository = mock(ClusterRepository.class);
-	private final LogRepository logRepository = mock(LogRepository.class);
-
-	private final DeleteClustersPartProvider provider = new DeleteClustersPartProvider(clusterRepository, logRepository);
-
-	@Test
-	void shouldDeleteWhenNotForUpdate() {
-		final GenerateClustersConfig config = getConfig(false);
-		final PipelinePart pipelinePart = provider.provide(config);
-		pipelinePart.handle();
-
-		final ClusterEntityContext entityContext = config.getEntityContext();
-		verify(logRepository, times(1)).updateClusterIdSetNullByLaunchId(entityContext.getLaunchId());
-		verify(clusterRepository, times(1)).deleteClusterTestItemsByLaunchId(entityContext.getLaunchId());
-		verify(clusterRepository, times(1)).deleteAllByLaunchId(entityContext.getLaunchId());
-	}
-
-	@Test
-	void shouldNotDeleteWhenForUpdate() {
-		final GenerateClustersConfig config = getConfig(true);
-		final PipelinePart pipelinePart = provider.provide(config);
-		pipelinePart.handle();
-
-		final ClusterEntityContext entityContext = config.getEntityContext();
-		verify(logRepository, times(0)).updateClusterIdSetNullByLaunchId(entityContext.getLaunchId());
-		verify(clusterRepository, times(0)).deleteClusterTestItemsByLaunchId(entityContext.getLaunchId());
-		verify(clusterRepository, times(0)).deleteAllByLaunchId(entityContext.getLaunchId());
-	}
+  private final ClusterRepository clusterRepository = mock(ClusterRepository.class);
+  private final LogRepository logRepository = mock(LogRepository.class);
+
+  private final DeleteClustersPartProvider provider = new DeleteClustersPartProvider(
+      clusterRepository, logRepository);
+
+  @Test
+  void shouldDeleteWhenNotForUpdate() {
+    final GenerateClustersConfig config = getConfig(false);
+    final PipelinePart pipelinePart = provider.provide(config);
+    pipelinePart.handle();
+
+    final ClusterEntityContext entityContext = config.getEntityContext();
+    verify(logRepository, times(1)).updateClusterIdSetNullByLaunchId(entityContext.getLaunchId());
+    verify(clusterRepository, times(1)).deleteClusterTestItemsByLaunchId(
+        entityContext.getLaunchId());
+    verify(clusterRepository, times(1)).deleteAllByLaunchId(entityContext.getLaunchId());
+  }
+
+  @Test
+  void shouldNotDeleteWhenForUpdate() {
+    final GenerateClustersConfig config = getConfig(true);
+    final PipelinePart pipelinePart = provider.provide(config);
+    pipelinePart.handle();
+
+    final ClusterEntityContext entityContext = config.getEntityContext();
+    verify(logRepository, times(0)).updateClusterIdSetNullByLaunchId(entityContext.getLaunchId());
+    verify(clusterRepository, times(0)).deleteClusterTestItemsByLaunchId(
+        entityContext.getLaunchId());
+    verify(clusterRepository, times(0)).deleteAllByLaunchId(entityContext.getLaunchId());
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/SaveClusterDataPartProviderTest.java b/src/test/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/SaveClusterDataPartProviderTest.java
index 73ac9d4731..6ebe945af5 100644
--- a/src/test/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/SaveClusterDataPartProviderTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/SaveClusterDataPartProviderTest.java
@@ -16,69 +16,72 @@
 
 package com.epam.ta.reportportal.core.launch.cluster.pipeline;
 
+import static com.epam.ta.reportportal.core.launch.cluster.utils.ConfigProvider.getConfig;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.core.analyzer.auto.client.model.cluster.ClusterData;
 import com.epam.ta.reportportal.core.launch.cluster.CreateClusterHandler;
 import com.epam.ta.reportportal.core.launch.cluster.config.GenerateClustersConfig;
 import com.epam.ta.reportportal.core.launch.cluster.pipeline.data.ClusterDataProvider;
 import com.epam.ta.reportportal.core.launch.cluster.pipeline.data.resolver.ClusterDataProviderResolver;
 import com.epam.ta.reportportal.pipeline.PipelinePart;
-import org.junit.jupiter.api.Test;
-
 import java.util.Optional;
-
-import static com.epam.ta.reportportal.core.launch.cluster.utils.ConfigProvider.getConfig;
-import static org.mockito.Mockito.*;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class SaveClusterDataPartProviderTest {
 
-	private final ClusterDataProvider dataProvider = mock(ClusterDataProvider.class);
-	private final ClusterDataProviderResolver resolver = mock(ClusterDataProviderResolver.class);
-	private final CreateClusterHandler createClusterHandler = mock(CreateClusterHandler.class);
+  private final ClusterDataProvider dataProvider = mock(ClusterDataProvider.class);
+  private final ClusterDataProviderResolver resolver = mock(ClusterDataProviderResolver.class);
+  private final CreateClusterHandler createClusterHandler = mock(CreateClusterHandler.class);
 
-	private final SaveClusterDataPartProvider provider = new SaveClusterDataPartProvider(resolver, createClusterHandler);
+  private final SaveClusterDataPartProvider provider = new SaveClusterDataPartProvider(resolver,
+      createClusterHandler);
 
-	@Test
-	void shouldSaveWhenProviderAndDataExists() {
-		final GenerateClustersConfig config = getConfig(false);
+  @Test
+  void shouldSaveWhenProviderAndDataExists() {
+    final GenerateClustersConfig config = getConfig(false);
 
-		final ClusterData clusterData = new ClusterData();
-		when(dataProvider.provide(config)).thenReturn(Optional.of(clusterData));
-		when(resolver.resolve(config)).thenReturn(Optional.of(dataProvider));
+    final ClusterData clusterData = new ClusterData();
+    when(dataProvider.provide(config)).thenReturn(Optional.of(clusterData));
+    when(resolver.resolve(config)).thenReturn(Optional.of(dataProvider));
 
-		final PipelinePart pipelinePart = provider.provide(config);
-		pipelinePart.handle();
+    final PipelinePart pipelinePart = provider.provide(config);
+    pipelinePart.handle();
 
-		verify(createClusterHandler, times(1)).create(clusterData);
-	}
+    verify(createClusterHandler, times(1)).create(clusterData);
+  }
 
-	@Test
-	void shouldSaveWhenProviderNotExists() {
-		final GenerateClustersConfig config = getConfig(false);
+  @Test
+  void shouldSaveWhenProviderNotExists() {
+    final GenerateClustersConfig config = getConfig(false);
 
-		final ClusterData clusterData = new ClusterData();
-		when(resolver.resolve(config)).thenReturn(Optional.empty());
+    final ClusterData clusterData = new ClusterData();
+    when(resolver.resolve(config)).thenReturn(Optional.empty());
 
-		final PipelinePart pipelinePart = provider.provide(config);
-		pipelinePart.handle();
+    final PipelinePart pipelinePart = provider.provide(config);
+    pipelinePart.handle();
 
-		verify(createClusterHandler, times(0)).create(clusterData);
-	}
+    verify(createClusterHandler, times(0)).create(clusterData);
+  }
 
-	@Test
-	void shouldNotSaveWhenProviderExistsAndNoDataExists() {
-		final GenerateClustersConfig config = getConfig(false);
+  @Test
+  void shouldNotSaveWhenProviderExistsAndNoDataExists() {
+    final GenerateClustersConfig config = getConfig(false);
 
-		final ClusterData clusterData = new ClusterData();
-		when(dataProvider.provide(config)).thenReturn(Optional.of(clusterData));
-		when(resolver.resolve(config)).thenReturn(Optional.empty());
+    final ClusterData clusterData = new ClusterData();
+    when(dataProvider.provide(config)).thenReturn(Optional.of(clusterData));
+    when(resolver.resolve(config)).thenReturn(Optional.empty());
 
-		final PipelinePart pipelinePart = provider.provide(config);
-		pipelinePart.handle();
+    final PipelinePart pipelinePart = provider.provide(config);
+    pipelinePart.handle();
 
-		verify(createClusterHandler, times(0)).create(clusterData);
-	}
+    verify(createClusterHandler, times(0)).create(clusterData);
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/SaveLastRunAttributePartProviderTest.java b/src/test/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/SaveLastRunAttributePartProviderTest.java
index 66713afdc1..4c1c230c70 100644
--- a/src/test/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/SaveLastRunAttributePartProviderTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/SaveLastRunAttributePartProviderTest.java
@@ -16,60 +16,71 @@
 
 package com.epam.ta.reportportal.core.launch.cluster.pipeline;
 
+import static com.epam.ta.reportportal.core.launch.cluster.pipeline.SaveLastRunAttributePartProvider.RP_CLUSTER_LAST_RUN_KEY;
+import static com.epam.ta.reportportal.core.launch.cluster.utils.ConfigProvider.getConfig;
+import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
 import com.epam.ta.reportportal.core.launch.cluster.config.GenerateClustersConfig;
 import com.epam.ta.reportportal.dao.ItemAttributeRepository;
-import com.epam.ta.reportportal.entity.ItemAttribute;
 import com.epam.ta.reportportal.pipeline.PipelinePart;
 import org.junit.jupiter.api.Test;
 
-import java.util.Optional;
-
-import static com.epam.ta.reportportal.core.launch.cluster.pipeline.SaveLastRunAttributePartProvider.RP_CLUSTER_LAST_RUN_KEY;
-import static com.epam.ta.reportportal.core.launch.cluster.utils.ConfigProvider.getConfig;
-import static org.mockito.Mockito.*;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class SaveLastRunAttributePartProviderTest {
 
-	private final ItemAttributeRepository itemAttributeRepository = mock(ItemAttributeRepository.class);
+  private final ItemAttributeRepository itemAttributeRepository = mock(
+      ItemAttributeRepository.class);
+
+  private final SaveLastRunAttributePartProvider provider = new SaveLastRunAttributePartProvider(
+      itemAttributeRepository);
 
-	private final SaveLastRunAttributePartProvider provider = new SaveLastRunAttributePartProvider(itemAttributeRepository);
+  @Test
+  void shouldDeletePreviousAndSaveNew() {
+    final GenerateClustersConfig config = getConfig(false);
 
-	@Test
-	void shouldSaveWhenNotExists() {
-		final GenerateClustersConfig config = getConfig(false);
-		when(itemAttributeRepository.findByLaunchIdAndKeyAndSystem(config.getEntityContext().getLaunchId(),
-				RP_CLUSTER_LAST_RUN_KEY,
-				true
-		)).thenReturn(Optional.empty());
+    final PipelinePart pipelinePart = provider.provide(config);
 
-		final PipelinePart pipelinePart = provider.provide(config);
+    pipelinePart.handle();
 
-		pipelinePart.handle();
+    verify(itemAttributeRepository, times(1)).deleteAllByLaunchIdAndKeyAndSystem(
+        eq(config.getEntityContext().getLaunchId()),
+        eq(RP_CLUSTER_LAST_RUN_KEY),
+        eq(true)
+    );
 
-		verify(itemAttributeRepository, times(1)).saveByLaunchId(eq(config.getEntityContext().getLaunchId()),
-				eq(RP_CLUSTER_LAST_RUN_KEY),
-				anyString(),
-				eq(true)
-		);
-	}
+    verify(itemAttributeRepository, times(1)).saveByLaunchId(
+        eq(config.getEntityContext().getLaunchId()),
+        eq(RP_CLUSTER_LAST_RUN_KEY),
+        anyString(),
+        eq(true)
+    );
+  }
 
-	@Test
-	void shouldUpdateWhenExists() {
-		final GenerateClustersConfig config = getConfig(false);
-		final ItemAttribute itemAttribute = new ItemAttribute();
-		when(itemAttributeRepository.findByLaunchIdAndKeyAndSystem(config.getEntityContext().getLaunchId(),
-				RP_CLUSTER_LAST_RUN_KEY,
-				true
-		)).thenReturn(Optional.of(itemAttribute));
+  @Test
+  void shouldNotSaveLastRunWhenForUpdate() {
+    final GenerateClustersConfig config = getConfig(true);
 
-		final PipelinePart pipelinePart = provider.provide(config);
+    final PipelinePart pipelinePart = provider.provide(config);
 
-		pipelinePart.handle();
+    pipelinePart.handle();
 
-		verify(itemAttributeRepository, times(1)).save(itemAttribute);
-	}
+    verify(itemAttributeRepository, times(0)).deleteAllByLaunchIdAndKeyAndSystem(
+        eq(config.getEntityContext().getLaunchId()),
+        eq(RP_CLUSTER_LAST_RUN_KEY),
+        eq(true)
+    );
+    verify(itemAttributeRepository, times(0)).saveByLaunchId(
+        eq(config.getEntityContext().getLaunchId()),
+        eq(RP_CLUSTER_LAST_RUN_KEY),
+        anyString(),
+        eq(true)
+    );
+  }
 
-}
\ No newline at end of file
+}
diff --git a/src/test/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/AnalyzerItemClusterDataProviderTest.java b/src/test/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/AnalyzerItemClusterDataProviderTest.java
index 22e272327d..4be7ffe95a 100644
--- a/src/test/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/AnalyzerItemClusterDataProviderTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/AnalyzerItemClusterDataProviderTest.java
@@ -16,6 +16,18 @@
 
 package com.epam.ta.reportportal.core.launch.cluster.pipeline.data;
 
+import static com.epam.ta.reportportal.core.launch.cluster.utils.ConfigProvider.getConfig;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.anyList;
+import static org.mockito.Mockito.anyLong;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.core.analyzer.auto.client.AnalyzerServiceClient;
 import com.epam.ta.reportportal.core.analyzer.auto.client.model.cluster.ClusterData;
 import com.epam.ta.reportportal.core.analyzer.auto.client.model.cluster.GenerateClustersRq;
@@ -29,96 +41,102 @@
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.analyzer.IndexLaunch;
 import com.epam.ta.reportportal.ws.model.project.AnalyzerConfig;
-import org.junit.jupiter.api.Test;
-
 import java.util.List;
 import java.util.Optional;
-
-import static com.epam.ta.reportportal.core.launch.cluster.utils.ConfigProvider.getConfig;
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.*;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class AnalyzerItemClusterDataProviderTest {
 
-	private final LaunchPreparerService launchPreparerService = mock(LaunchPreparerService.class);
-	private final GetLaunchHandler getLaunchHandler = mock(GetLaunchHandler.class);
-	private final TestItemRepository testItemRepository = mock(TestItemRepository.class);
-	private final AnalyzerServiceClient analyzerServiceClient = mock(AnalyzerServiceClient.class);
-
-	private final AnalyzerItemClusterDataProvider provider = new AnalyzerItemClusterDataProvider(analyzerServiceClient,
-			getLaunchHandler,
-			testItemRepository,
-			launchPreparerService
-	);
-
-	@Test
-	void shouldFailWhenNoAnalyzer() {
-		when(analyzerServiceClient.hasClients()).thenReturn(false);
-
-		final GenerateClustersConfig config = getConfig(false);
-		final ReportPortalException exception = assertThrows(ReportPortalException.class, () -> provider.provide(config));
-		assertEquals("Impossible interact with integration. There are no analyzer services are deployed.", exception.getMessage());
-	}
-
-	@Test
-	void shouldReturnDataWhenIndexLaunchExists() {
-		when(analyzerServiceClient.hasClients()).thenReturn(true);
-
-		final GenerateClustersConfig config = getConfig(false);
-		addItemIds(config);
-
-		final Launch launch = new Launch();
-		when(getLaunchHandler.get(config.getEntityContext().getLaunchId())).thenReturn(launch);
-
-		final List<TestItem> testItems = List.of(new TestItem(), new TestItem());
-		when(testItemRepository.findAllById(config.getEntityContext().getItemIds())).thenReturn(testItems);
-
-		when(launchPreparerService.prepare(launch, testItems, config.getAnalyzerConfig())).thenReturn(Optional.of(new IndexLaunch()));
-		when(analyzerServiceClient.generateClusters(any(GenerateClustersRq.class))).thenReturn(new ClusterData());
-		final Optional<ClusterData> data = provider.provide(config);
-		assertTrue(data.isPresent());
-	}
-
-	@Test
-	void shouldNotReturnDataWhenNoItemIds() {
-		when(analyzerServiceClient.hasClients()).thenReturn(true);
-
-		final GenerateClustersConfig config = getConfig(false);
-
-		final Optional<ClusterData> data = provider.provide(config);
-		assertTrue(data.isEmpty());
-
-		verify(getLaunchHandler, times(0)).get(anyLong());
-		verify(testItemRepository, times(0)).findAllById(anyList());
-		verify(launchPreparerService, times(0)).prepare(any(Launch.class), anyList(), any(AnalyzerConfig.class));
-	}
-
-	@Test
-	void shouldNotReturnDataWhenNoIndexLaunch() {
-		when(analyzerServiceClient.hasClients()).thenReturn(true);
-
-		final GenerateClustersConfig config = getConfig(false);
-		addItemIds(config);
-
-		final Launch launch = new Launch();
-		when(getLaunchHandler.get(config.getEntityContext().getLaunchId())).thenReturn(launch);
-
-		final List<TestItem> testItems = List.of(new TestItem(), new TestItem());
-		when(testItemRepository.findAllById(config.getEntityContext().getItemIds())).thenReturn(testItems);
-
-		when(launchPreparerService.prepare(launch, testItems, config.getAnalyzerConfig())).thenReturn(Optional.of(new IndexLaunch()));
-
-		final Optional<ClusterData> data = provider.provide(config);
-		assertTrue(data.isEmpty());
-	}
-
-	private void addItemIds(GenerateClustersConfig config) {
-		final ClusterEntityContext entityContext = config.getEntityContext();
-		config.setEntityContext(ClusterEntityContext.of(entityContext.getLaunchId(), entityContext.getProjectId(), List.of(1L, 2L)));
-	}
+  private final LaunchPreparerService launchPreparerService = mock(LaunchPreparerService.class);
+  private final GetLaunchHandler getLaunchHandler = mock(GetLaunchHandler.class);
+  private final TestItemRepository testItemRepository = mock(TestItemRepository.class);
+  private final AnalyzerServiceClient analyzerServiceClient = mock(AnalyzerServiceClient.class);
+
+  private final AnalyzerItemClusterDataProvider provider = new AnalyzerItemClusterDataProvider(
+      analyzerServiceClient,
+      getLaunchHandler,
+      testItemRepository,
+      launchPreparerService
+  );
+
+  @Test
+  void shouldFailWhenNoAnalyzer() {
+    when(analyzerServiceClient.hasClients()).thenReturn(false);
+
+    final GenerateClustersConfig config = getConfig(false);
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> provider.provide(config));
+    assertEquals(
+        "Impossible interact with integration. There are no analyzer services are deployed.",
+        exception.getMessage());
+  }
+
+  @Test
+  void shouldReturnDataWhenIndexLaunchExists() {
+    when(analyzerServiceClient.hasClients()).thenReturn(true);
+
+    final GenerateClustersConfig config = getConfig(false);
+    addItemIds(config);
+
+    final Launch launch = new Launch();
+    when(getLaunchHandler.get(config.getEntityContext().getLaunchId())).thenReturn(launch);
+
+    final List<TestItem> testItems = List.of(new TestItem(), new TestItem());
+    when(testItemRepository.findAllById(config.getEntityContext().getItemIds())).thenReturn(
+        testItems);
+
+    when(launchPreparerService.prepare(launch, testItems, config.getAnalyzerConfig())).thenReturn(
+        Optional.of(new IndexLaunch()));
+    when(analyzerServiceClient.generateClusters(any(GenerateClustersRq.class))).thenReturn(
+        new ClusterData());
+    final Optional<ClusterData> data = provider.provide(config);
+    assertTrue(data.isPresent());
+  }
+
+  @Test
+  void shouldNotReturnDataWhenNoItemIds() {
+    when(analyzerServiceClient.hasClients()).thenReturn(true);
+
+    final GenerateClustersConfig config = getConfig(false);
+
+    final Optional<ClusterData> data = provider.provide(config);
+    assertTrue(data.isEmpty());
+
+    verify(getLaunchHandler, times(0)).get(anyLong());
+    verify(testItemRepository, times(0)).findAllById(anyList());
+    verify(launchPreparerService, times(0)).prepare(any(Launch.class), anyList(),
+        any(AnalyzerConfig.class));
+  }
+
+  @Test
+  void shouldNotReturnDataWhenNoIndexLaunch() {
+    when(analyzerServiceClient.hasClients()).thenReturn(true);
+
+    final GenerateClustersConfig config = getConfig(false);
+    addItemIds(config);
+
+    final Launch launch = new Launch();
+    when(getLaunchHandler.get(config.getEntityContext().getLaunchId())).thenReturn(launch);
+
+    final List<TestItem> testItems = List.of(new TestItem(), new TestItem());
+    when(testItemRepository.findAllById(config.getEntityContext().getItemIds())).thenReturn(
+        testItems);
+
+    when(launchPreparerService.prepare(launch, testItems, config.getAnalyzerConfig())).thenReturn(
+        Optional.of(new IndexLaunch()));
+
+    final Optional<ClusterData> data = provider.provide(config);
+    assertTrue(data.isEmpty());
+  }
+
+  private void addItemIds(GenerateClustersConfig config) {
+    final ClusterEntityContext entityContext = config.getEntityContext();
+    config.setEntityContext(
+        ClusterEntityContext.of(entityContext.getLaunchId(), entityContext.getProjectId(),
+            List.of(1L, 2L)));
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/AnalyzerLaunchClusterDataProviderTest.java b/src/test/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/AnalyzerLaunchClusterDataProviderTest.java
index 0dd5527263..fd71e278c7 100644
--- a/src/test/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/AnalyzerLaunchClusterDataProviderTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/AnalyzerLaunchClusterDataProviderTest.java
@@ -16,6 +16,14 @@
 
 package com.epam.ta.reportportal.core.launch.cluster.pipeline.data;
 
+import static com.epam.ta.reportportal.core.launch.cluster.utils.ConfigProvider.getConfig;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.core.analyzer.auto.client.AnalyzerServiceClient;
 import com.epam.ta.reportportal.core.analyzer.auto.client.model.cluster.ClusterData;
 import com.epam.ta.reportportal.core.analyzer.auto.client.model.cluster.GenerateClustersRq;
@@ -23,60 +31,59 @@
 import com.epam.ta.reportportal.core.launch.cluster.config.GenerateClustersConfig;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.analyzer.IndexLaunch;
-import org.junit.jupiter.api.Test;
-
 import java.util.Optional;
-
-import static com.epam.ta.reportportal.core.launch.cluster.utils.ConfigProvider.getConfig;
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class AnalyzerLaunchClusterDataProviderTest {
-	private final LaunchPreparerService launchPreparerService = mock(LaunchPreparerService.class);
-	private final AnalyzerServiceClient analyzerServiceClient = mock(AnalyzerServiceClient.class);
 
-	private final AnalyzerLaunchClusterDataProvider provider = new AnalyzerLaunchClusterDataProvider(analyzerServiceClient,
-			launchPreparerService
-	);
+  private final LaunchPreparerService launchPreparerService = mock(LaunchPreparerService.class);
+  private final AnalyzerServiceClient analyzerServiceClient = mock(AnalyzerServiceClient.class);
+
+  private final AnalyzerLaunchClusterDataProvider provider = new AnalyzerLaunchClusterDataProvider(
+      analyzerServiceClient,
+      launchPreparerService
+  );
 
-	@Test
-	void shouldFailWhenNoAnalyzer() {
-		when(analyzerServiceClient.hasClients()).thenReturn(false);
+  @Test
+  void shouldFailWhenNoAnalyzer() {
+    when(analyzerServiceClient.hasClients()).thenReturn(false);
 
-		final GenerateClustersConfig config = getConfig(false);
-		final ReportPortalException exception = assertThrows(ReportPortalException.class, () -> provider.provide(config));
-		assertEquals("Impossible interact with integration. There are no analyzer services are deployed.", exception.getMessage());
-	}
+    final GenerateClustersConfig config = getConfig(false);
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> provider.provide(config));
+    assertEquals(
+        "Impossible interact with integration. There are no analyzer services are deployed.",
+        exception.getMessage());
+  }
 
-	@Test
-	void shouldReturnDataWhenIndexLaunchExists() {
-		when(analyzerServiceClient.hasClients()).thenReturn(true);
+  @Test
+  void shouldReturnDataWhenIndexLaunchExists() {
+    when(analyzerServiceClient.hasClients()).thenReturn(true);
 
-		final GenerateClustersConfig config = getConfig(false);
+    final GenerateClustersConfig config = getConfig(false);
 
-		when(launchPreparerService.prepare(config.getEntityContext().getLaunchId(),
-				config.getAnalyzerConfig()
-		)).thenReturn(Optional.of(new IndexLaunch()));
-		when(analyzerServiceClient.generateClusters(any(GenerateClustersRq.class))).thenReturn(new ClusterData());
-		final Optional<ClusterData> data = provider.provide(config);
-		assertTrue(data.isPresent());
-	}
+    when(launchPreparerService.prepare(config.getEntityContext().getLaunchId(),
+        config.getAnalyzerConfig()
+    )).thenReturn(Optional.of(new IndexLaunch()));
+    when(analyzerServiceClient.generateClusters(any(GenerateClustersRq.class))).thenReturn(
+        new ClusterData());
+    final Optional<ClusterData> data = provider.provide(config);
+    assertTrue(data.isPresent());
+  }
 
-	@Test
-	void shouldNotReturnDataWhenNoIndexLaunch() {
-		when(analyzerServiceClient.hasClients()).thenReturn(true);
+  @Test
+  void shouldNotReturnDataWhenNoIndexLaunch() {
+    when(analyzerServiceClient.hasClients()).thenReturn(true);
 
-		final GenerateClustersConfig config = getConfig(false);
+    final GenerateClustersConfig config = getConfig(false);
 
-		when(launchPreparerService.prepare(config.getEntityContext().getLaunchId(),
-				config.getAnalyzerConfig()
-		)).thenReturn(Optional.empty());
-		final Optional<ClusterData> data = provider.provide(config);
-		assertTrue(data.isEmpty());
-	}
+    when(launchPreparerService.prepare(config.getEntityContext().getLaunchId(),
+        config.getAnalyzerConfig()
+    )).thenReturn(Optional.empty());
+    final Optional<ClusterData> data = provider.provide(config);
+    assertTrue(data.isEmpty());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/resolver/ClusterDataProviderResolverTest.java b/src/test/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/resolver/ClusterDataProviderResolverTest.java
index 64d1b35071..48f46d26ad 100644
--- a/src/test/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/resolver/ClusterDataProviderResolverTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/resolver/ClusterDataProviderResolverTest.java
@@ -16,45 +16,45 @@
 
 package com.epam.ta.reportportal.core.launch.cluster.pipeline.data.resolver;
 
-import com.epam.ta.reportportal.core.launch.cluster.config.GenerateClustersConfig;
-import com.epam.ta.reportportal.core.launch.cluster.pipeline.data.ClusterDataProvider;
-import com.epam.ta.reportportal.core.launch.cluster.pipeline.data.resolver.evaluator.ClusterDataProviderEvaluator;
-import org.junit.jupiter.api.Test;
-
-import java.util.List;
-import java.util.Optional;
-
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import com.epam.ta.reportportal.core.launch.cluster.config.GenerateClustersConfig;
+import com.epam.ta.reportportal.core.launch.cluster.pipeline.data.ClusterDataProvider;
+import com.epam.ta.reportportal.core.launch.cluster.pipeline.data.resolver.evaluator.ClusterDataProviderEvaluator;
+import java.util.List;
+import java.util.Optional;
+import org.junit.jupiter.api.Test;
+
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class ClusterDataProviderResolverTest {
 
-	private final ClusterDataProvider dataProvider = mock(ClusterDataProvider.class);
-	private final ClusterDataProviderEvaluator evaluator = mock(ClusterDataProviderEvaluator.class);
-	private final ClusterDataProviderResolver resolver = new ClusterDataProviderResolver(List.of(evaluator));
+  private final ClusterDataProvider dataProvider = mock(ClusterDataProvider.class);
+  private final ClusterDataProviderEvaluator evaluator = mock(ClusterDataProviderEvaluator.class);
+  private final ClusterDataProviderResolver resolver = new ClusterDataProviderResolver(
+      List.of(evaluator));
 
-	@Test
-	void shouldReturnProviderWhenSupports() {
-		when(evaluator.supports(any(GenerateClustersConfig.class))).thenReturn(true);
-		when(evaluator.getProvider()).thenReturn(dataProvider);
+  @Test
+  void shouldReturnProviderWhenSupports() {
+    when(evaluator.supports(any(GenerateClustersConfig.class))).thenReturn(true);
+    when(evaluator.getProvider()).thenReturn(dataProvider);
 
-		final Optional<ClusterDataProvider> provider = resolver.resolve(new GenerateClustersConfig());
+    final Optional<ClusterDataProvider> provider = resolver.resolve(new GenerateClustersConfig());
 
-		assertTrue(provider.isPresent());
-		assertEquals(dataProvider, provider.get());
-	}
+    assertTrue(provider.isPresent());
+    assertEquals(dataProvider, provider.get());
+  }
 
-	@Test
-	void shouldNotReturnProviderWhenSupports() {
-		when(evaluator.supports(any(GenerateClustersConfig.class))).thenReturn(false);
-		final Optional<ClusterDataProvider> provider = resolver.resolve(new GenerateClustersConfig());
-		assertTrue(provider.isEmpty());
-	}
+  @Test
+  void shouldNotReturnProviderWhenSupports() {
+    when(evaluator.supports(any(GenerateClustersConfig.class))).thenReturn(false);
+    final Optional<ClusterDataProvider> provider = resolver.resolve(new GenerateClustersConfig());
+    assertTrue(provider.isEmpty());
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/resolver/evaluator/ClusterDataProviderEvaluatorTest.java b/src/test/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/resolver/evaluator/ClusterDataProviderEvaluatorTest.java
index 8223f18b83..d83c2a4eda 100644
--- a/src/test/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/resolver/evaluator/ClusterDataProviderEvaluatorTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/launch/cluster/pipeline/data/resolver/evaluator/ClusterDataProviderEvaluatorTest.java
@@ -16,42 +16,45 @@
 
 package com.epam.ta.reportportal.core.launch.cluster.pipeline.data.resolver.evaluator;
 
-import com.epam.ta.reportportal.core.launch.cluster.config.GenerateClustersConfig;
-import com.epam.ta.reportportal.core.launch.cluster.pipeline.data.ClusterDataProvider;
-import org.junit.jupiter.api.Test;
-
-import java.util.function.Predicate;
-
-import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import com.epam.ta.reportportal.core.launch.cluster.config.GenerateClustersConfig;
+import com.epam.ta.reportportal.core.launch.cluster.pipeline.data.ClusterDataProvider;
+import java.util.function.Predicate;
+import org.junit.jupiter.api.Test;
+
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class ClusterDataProviderEvaluatorTest {
 
-	private final Predicate<GenerateClustersConfig> predicate = (Predicate<GenerateClustersConfig>) mock(Predicate.class);
-	private final ClusterDataProvider clusterDataProvider = mock(ClusterDataProvider.class);
-
-	private final ClusterDataProviderEvaluator evaluator = new ClusterDataProviderEvaluator(predicate, clusterDataProvider);
-
-	@Test
-	void shouldReturnTrueWhenPredicateIsTrue() {
-		when(predicate.test(any(GenerateClustersConfig.class))).thenReturn(true);
-		assertTrue(evaluator.supports(new GenerateClustersConfig()));
-	}
-
-	@Test
-	void shouldReturnFalseWhenPredicateIsFalse() {
-		when(predicate.test(any(GenerateClustersConfig.class))).thenReturn(false);
-		assertFalse(evaluator.supports(new GenerateClustersConfig()));
-	}
-
-	@Test
-	void providerShouldBeEqual() {
-		assertEquals(clusterDataProvider, evaluator.getProvider());
-	}
+  private final Predicate<GenerateClustersConfig> predicate = (Predicate<GenerateClustersConfig>) mock(
+      Predicate.class);
+  private final ClusterDataProvider clusterDataProvider = mock(ClusterDataProvider.class);
+
+  private final ClusterDataProviderEvaluator evaluator = new ClusterDataProviderEvaluator(predicate,
+      clusterDataProvider);
+
+  @Test
+  void shouldReturnTrueWhenPredicateIsTrue() {
+    when(predicate.test(any(GenerateClustersConfig.class))).thenReturn(true);
+    assertTrue(evaluator.supports(new GenerateClustersConfig()));
+  }
+
+  @Test
+  void shouldReturnFalseWhenPredicateIsFalse() {
+    when(predicate.test(any(GenerateClustersConfig.class))).thenReturn(false);
+    assertFalse(evaluator.supports(new GenerateClustersConfig()));
+  }
+
+  @Test
+  void providerShouldBeEqual() {
+    assertEquals(clusterDataProvider, evaluator.getProvider());
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/launch/cluster/utils/ConfigProvider.java b/src/test/java/com/epam/ta/reportportal/core/launch/cluster/utils/ConfigProvider.java
index 507f9fbe7e..a0ccd90536 100644
--- a/src/test/java/com/epam/ta/reportportal/core/launch/cluster/utils/ConfigProvider.java
+++ b/src/test/java/com/epam/ta/reportportal/core/launch/cluster/utils/ConfigProvider.java
@@ -25,19 +25,19 @@
  */
 public class ConfigProvider {
 
-	private ConfigProvider() {
+  private ConfigProvider() {
 
-	}
+  }
 
-	public static final GenerateClustersConfig getConfig(boolean forUpdate) {
-		final GenerateClustersConfig config = new GenerateClustersConfig();
-		final AnalyzerConfig analyzerConfig = new AnalyzerConfig();
-		analyzerConfig.setNumberOfLogLines(1);
-		config.setAnalyzerConfig(analyzerConfig);
-		final ClusterEntityContext entityContext = ClusterEntityContext.of(1L, 1L);
-		config.setEntityContext(entityContext);
-		config.setForUpdate(forUpdate);
-		config.setCleanNumbers(false);
-		return config;
-	}
+  public static final GenerateClustersConfig getConfig(boolean forUpdate) {
+    final GenerateClustersConfig config = new GenerateClustersConfig();
+    final AnalyzerConfig analyzerConfig = new AnalyzerConfig();
+    analyzerConfig.setNumberOfLogLines(1);
+    config.setAnalyzerConfig(analyzerConfig);
+    final ClusterEntityContext entityContext = ClusterEntityContext.of(1L, 1L);
+    config.setEntityContext(entityContext);
+    config.setForUpdate(forUpdate);
+    config.setCleanNumbers(false);
+    return config;
+  }
 }
diff --git a/src/test/java/com/epam/ta/reportportal/core/launch/impl/DeleteLaunchHandlerImplTest.java b/src/test/java/com/epam/ta/reportportal/core/launch/impl/DeleteLaunchHandlerImplTest.java
index f097a089dc..9d0d6c8172 100644
--- a/src/test/java/com/epam/ta/reportportal/core/launch/impl/DeleteLaunchHandlerImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/launch/impl/DeleteLaunchHandlerImplTest.java
@@ -16,6 +16,13 @@
 
 package com.epam.ta.reportportal.core.launch.impl;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static com.epam.ta.reportportal.core.launch.impl.LaunchTestUtil.getLaunch;
+import static com.epam.ta.reportportal.util.TestProjectExtractor.extractProjectDetails;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.dao.AttachmentRepository;
 import com.epam.ta.reportportal.dao.LaunchRepository;
@@ -30,58 +37,57 @@
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static com.epam.ta.reportportal.core.launch.impl.LaunchTestUtil.getLaunch;
-import static com.epam.ta.reportportal.util.TestProjectExtractor.extractProjectDetails;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.Mockito.when;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @ExtendWith(MockitoExtension.class)
 class DeleteLaunchHandlerImplTest {
 
-	@Mock
-	private LaunchRepository launchRepository;
+  @Mock
+  private LaunchRepository launchRepository;
 
-	@Mock
-	private AttachmentRepository attachmentRepository;
+  @Mock
+  private AttachmentRepository attachmentRepository;
 
-	@InjectMocks
-	private DeleteLaunchHandlerImpl handler;
+  @InjectMocks
+  private DeleteLaunchHandlerImpl handler;
 
-	@Test
-	void deleteNotOwnLaunch() {
-		final ReportPortalUser rpUser = getRpUser("not owner", UserRole.USER, ProjectRole.MEMBER, 1L);
-		rpUser.setUserId(2L);
-		when(launchRepository.findById(1L)).thenReturn(getLaunch(StatusEnum.PASSED, LaunchModeEnum.DEFAULT));
+  @Test
+  void deleteNotOwnLaunch() {
+    final ReportPortalUser rpUser = getRpUser("not owner", UserRole.USER, ProjectRole.MEMBER, 1L);
+    rpUser.setUserId(2L);
+    when(launchRepository.findById(1L)).thenReturn(
+        getLaunch(StatusEnum.PASSED, LaunchModeEnum.DEFAULT));
 
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.deleteLaunch(1L, extractProjectDetails(rpUser, "test_project"), rpUser)
-		);
-		assertEquals("You do not have enough permissions. You are not launch owner.", exception.getMessage());
-	}
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.deleteLaunch(1L, extractProjectDetails(rpUser, "test_project"), rpUser)
+    );
+    assertEquals("You do not have enough permissions. You are not launch owner.",
+        exception.getMessage());
+  }
 
-	@Test
-	void deleteLaunchFromAnotherProject() {
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 2L);
-		when(launchRepository.findById(1L)).thenReturn(getLaunch(StatusEnum.PASSED, LaunchModeEnum.DEFAULT));
+  @Test
+  void deleteLaunchFromAnotherProject() {
+    final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 2L);
+    when(launchRepository.findById(1L)).thenReturn(
+        getLaunch(StatusEnum.PASSED, LaunchModeEnum.DEFAULT));
 
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.deleteLaunch(1L, extractProjectDetails(rpUser, "test_project"), rpUser)
-		);
-		assertEquals("Forbidden operation. Target launch '1' not under specified project '2'", exception.getMessage());
-	}
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.deleteLaunch(1L, extractProjectDetails(rpUser, "test_project"), rpUser)
+    );
+    assertEquals("Forbidden operation. Target launch '1' not under specified project '2'",
+        exception.getMessage());
+  }
 
-	@Test
-	void deleteLaunchInProgressStatus() {
+  @Test
+  void deleteLaunchInProgressStatus() {
 
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
-		when(launchRepository.findById(1L)).thenReturn(getLaunch(StatusEnum.IN_PROGRESS, LaunchModeEnum.DEFAULT));
+    final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
+    when(launchRepository.findById(1L)).thenReturn(
+        getLaunch(StatusEnum.IN_PROGRESS, LaunchModeEnum.DEFAULT));
 
-		assertThrows(ReportPortalException.class, () -> handler.deleteLaunch(1L, extractProjectDetails(rpUser, "test_project"), rpUser));
-	}
+    assertThrows(ReportPortalException.class,
+        () -> handler.deleteLaunch(1L, extractProjectDetails(rpUser, "test_project"), rpUser));
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/launch/impl/FinishLaunchHandlerAsyncImplTest.java b/src/test/java/com/epam/ta/reportportal/core/launch/impl/FinishLaunchHandlerAsyncImplTest.java
index 4a3f793c78..7a76a64e33 100644
--- a/src/test/java/com/epam/ta/reportportal/core/launch/impl/FinishLaunchHandlerAsyncImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/launch/impl/FinishLaunchHandlerAsyncImplTest.java
@@ -16,6 +16,10 @@
 
 package com.epam.ta.reportportal.core.launch.impl;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.verify;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.entity.project.ProjectRole;
 import com.epam.ta.reportportal.entity.user.UserRole;
@@ -28,10 +32,6 @@
 import org.mockito.junit.jupiter.MockitoExtension;
 import org.springframework.amqp.core.AmqpTemplate;
 
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.verify;
-
 /**
  * @author Konstantin Antipin
  */
@@ -39,22 +39,24 @@
 @ExtendWith(MockitoExtension.class)
 class FinishLaunchHandlerAsyncImplTest {
 
-    @Mock
-    AmqpTemplate amqpTemplate;
+  @Mock
+  AmqpTemplate amqpTemplate;
 
-    @Mock
-    ReportingQueueService reportingQueueService;
+  @Mock
+  ReportingQueueService reportingQueueService;
 
-    @InjectMocks
-    FinishLaunchHandlerAsyncImpl finishLaunchHandlerAsync;
+  @InjectMocks
+  FinishLaunchHandlerAsyncImpl finishLaunchHandlerAsync;
 
-    @Test
-    void finishLaunch() {
-        FinishExecutionRQ request = new FinishExecutionRQ();
-        ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
+  @Test
+  void finishLaunch() {
+    FinishExecutionRQ request = new FinishExecutionRQ();
+    ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER,
+        1L);
 
-        finishLaunchHandlerAsync.finishLaunch("0", request, user.getProjectDetails().get("test_project"), user, "http://base");
-        verify(amqpTemplate).convertAndSend(any(), any(), any(), any());
-        verify(reportingQueueService).getReportingQueueKey(any());
-    }
+    finishLaunchHandlerAsync.finishLaunch("0", request,
+        user.getProjectDetails().get("test_project"), user, "http://base");
+    verify(amqpTemplate).convertAndSend(any(), any(), any(), any());
+    verify(reportingQueueService).getReportingQueueKey(any());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/launch/impl/FinishLaunchHandlerImplTest.java b/src/test/java/com/epam/ta/reportportal/core/launch/impl/FinishLaunchHandlerImplTest.java
index 86d7ee3be4..bc93573082 100644
--- a/src/test/java/com/epam/ta/reportportal/core/launch/impl/FinishLaunchHandlerImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/launch/impl/FinishLaunchHandlerImplTest.java
@@ -16,6 +16,17 @@
 
 package com.epam.ta.reportportal.core.launch.impl;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static com.epam.ta.reportportal.core.launch.impl.LaunchTestUtil.getLaunch;
+import static com.epam.ta.reportportal.util.TestProjectExtractor.extractProjectDetails;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.events.MessageBus;
 import com.epam.ta.reportportal.core.hierarchy.FinishHierarchyHandler;
@@ -31,25 +42,18 @@
 import com.epam.ta.reportportal.ws.model.FinishExecutionRQ;
 import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
 import com.epam.ta.reportportal.ws.model.launch.FinishLaunchRS;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-import org.springframework.context.ApplicationEventPublisher;
-
 import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static com.epam.ta.reportportal.core.launch.impl.LaunchTestUtil.getLaunch;
-import static com.epam.ta.reportportal.util.TestProjectExtractor.extractProjectDetails;
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.Mockito.*;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.context.ApplicationEventPublisher;
 
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
@@ -57,147 +61,172 @@
 @ExtendWith(MockitoExtension.class)
 class FinishLaunchHandlerImplTest {
 
-	@Mock
-	private LaunchRepository launchRepository;
-
-	@Mock
-	private FinishHierarchyHandler<Launch> finishHierarchyHandler;
-
-	@Mock
-	private TestItemRepository testItemRepository;
-
-	@Mock
-	private MessageBus messageBus;
-
-	@Mock
-	private ApplicationEventPublisher publisher;
-
-	@InjectMocks
-	private FinishLaunchHandlerImpl handler;
-
-	@InjectMocks
-	private StopLaunchHandlerImpl stopLaunchHandler;
-
-	@Test
-	void finishLaunch() {
-		FinishExecutionRQ finishExecutionRQ = new FinishExecutionRQ();
-		finishExecutionRQ.setEndTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
-
-		ReportPortalUser rpUser = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
-
-		when(launchRepository.findByUuid("1")).thenReturn(getLaunch(StatusEnum.IN_PROGRESS, LaunchModeEnum.DEFAULT));
-
-		FinishLaunchRS response = handler.finishLaunch("1", finishExecutionRQ, extractProjectDetails(rpUser, "test_project"), rpUser, null);
-
-		verify(finishHierarchyHandler,times(1)).finishDescendants(any(), any(),any(),any(),any());
-
-		assertNotNull(response);
-	}
-
-	@Test
-	void finishLaunchWithLink() {
-		FinishExecutionRQ finishExecutionRQ = new FinishExecutionRQ();
-		finishExecutionRQ.setEndTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
-
-		ReportPortalUser rpUser = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
-
-		when(launchRepository.findByUuid("1")).thenReturn(getLaunch(StatusEnum.IN_PROGRESS, LaunchModeEnum.DEFAULT));
-
-		final FinishLaunchRS finishLaunchRS = handler.finishLaunch("1",
-				finishExecutionRQ,
-				extractProjectDetails(rpUser, "test_project"),
-				rpUser,
-				"http://example.com"
-		);
-
-		verify(finishHierarchyHandler,times(1)).finishDescendants(any(), any(),any(),any(),any());
-
-		assertNotNull(finishLaunchRS);
-		assertEquals("http://example.com/ui/#test_project/launches/all/1", finishLaunchRS.getLink());
-	}
-
-	@Test
-	void stopLaunch() {
-		FinishExecutionRQ finishExecutionRQ = new FinishExecutionRQ();
-		finishExecutionRQ.setEndTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
-
-		ReportPortalUser rpUser = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
-
-		when(launchRepository.findById(1L)).thenReturn(getLaunch(StatusEnum.IN_PROGRESS, LaunchModeEnum.DEFAULT));
+  @Mock
+  private LaunchRepository launchRepository;
 
-		final OperationCompletionRS response = stopLaunchHandler.stopLaunch(1L,
-				finishExecutionRQ,
-				extractProjectDetails(rpUser, "test_project"),
-				rpUser
-		);
-		assertNotNull(response);
-		assertEquals("Launch with ID = '1' successfully stopped.", response.getResultMessage());
-	}
+  @Mock
+  private FinishHierarchyHandler<Launch> finishHierarchyHandler;
 
-	@Test
-	void bulkStopLaunch() {
-		FinishExecutionRQ finishExecutionRQ = new FinishExecutionRQ();
-		finishExecutionRQ.setEndTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+  @Mock
+  private TestItemRepository testItemRepository;
 
-		Map<Long, FinishExecutionRQ> entities = new HashMap<>();
-		entities.put(1L, finishExecutionRQ);
+  @Mock
+  private MessageBus messageBus;
 
-		BulkRQ<Long, FinishExecutionRQ> bulkRq = new BulkRQ<>();
-		bulkRq.setEntities(entities);
+  @Mock
+  private ApplicationEventPublisher publisher;
 
-		ReportPortalUser rpUser = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
+  @InjectMocks
+  private FinishLaunchHandlerImpl handler;
 
-		when(launchRepository.findById(1L)).thenReturn(getLaunch(StatusEnum.IN_PROGRESS, LaunchModeEnum.DEFAULT));
+  @InjectMocks
+  private StopLaunchHandlerImpl stopLaunchHandler;
 
-		final List<OperationCompletionRS> response = stopLaunchHandler.stopLaunch(bulkRq,
-				extractProjectDetails(rpUser, "test_project"),
-				rpUser
-		);
-		assertNotNull(response);
-		assertEquals(1, response.size());
-	}
+  @Test
+  void finishLaunch() {
+    FinishExecutionRQ finishExecutionRQ = new FinishExecutionRQ();
+    finishExecutionRQ.setEndTime(
+        Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
 
-	@Test
-	void finishWithIncorrectStatus() {
-		FinishExecutionRQ finishExecutionRQ = new FinishExecutionRQ();
-		finishExecutionRQ.setEndTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+    ReportPortalUser rpUser = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER,
+        1L);
 
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
+    when(launchRepository.findByUuid("1")).thenReturn(
+        getLaunch(StatusEnum.IN_PROGRESS, LaunchModeEnum.DEFAULT));
 
-		when(launchRepository.findByUuid("1")).thenReturn(getLaunch(StatusEnum.PASSED, LaunchModeEnum.DEFAULT));
+    FinishLaunchRS response = handler.finishLaunch("1", finishExecutionRQ,
+        extractProjectDetails(rpUser, "test_project"), rpUser, null);
 
-		assertThrows(ReportPortalException.class,
-				() -> handler.finishLaunch("1", finishExecutionRQ, extractProjectDetails(rpUser, "test_project"), rpUser, null)
-		);
-	}
+    verify(finishHierarchyHandler, times(1)).finishDescendants(any(), any(), any(), any(), any());
 
-	@Test
-	void finishWithIncorrectEndTime() {
-		FinishExecutionRQ finishExecutionRQ = new FinishExecutionRQ();
-		finishExecutionRQ.setEndTime(Date.from(LocalDateTime.now().minusHours(5).atZone(ZoneId.of("UTC")).toInstant()));
+    assertNotNull(response);
+  }
 
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
+  @Test
+  void finishLaunchWithLink() {
+    FinishExecutionRQ finishExecutionRQ = new FinishExecutionRQ();
+    finishExecutionRQ.setEndTime(
+        Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
 
-		when(launchRepository.findByUuid("1")).thenReturn(getLaunch(StatusEnum.IN_PROGRESS, LaunchModeEnum.DEFAULT));
+    ReportPortalUser rpUser = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER,
+        1L);
 
-		assertThrows(ReportPortalException.class,
-				() -> handler.finishLaunch("1", finishExecutionRQ, extractProjectDetails(rpUser, "test_project"), rpUser, null)
-		);
-	}
+    when(launchRepository.findByUuid("1")).thenReturn(
+        getLaunch(StatusEnum.IN_PROGRESS, LaunchModeEnum.DEFAULT));
 
-	@Test
-	void finishNotOwnLaunch() {
-		FinishExecutionRQ finishExecutionRQ = new FinishExecutionRQ();
-		finishExecutionRQ.setEndTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+    final FinishLaunchRS finishLaunchRS = handler.finishLaunch("1",
+        finishExecutionRQ,
+        extractProjectDetails(rpUser, "test_project"),
+        rpUser,
+        "http://example.com"
+    );
 
-		final ReportPortalUser rpUser = getRpUser("not owner", UserRole.USER, ProjectRole.MEMBER, 1L);
-		rpUser.setUserId(2L);
+    verify(finishHierarchyHandler, times(1)).finishDescendants(any(), any(), any(), any(), any());
 
-		when(launchRepository.findByUuid("1")).thenReturn(getLaunch(StatusEnum.IN_PROGRESS, LaunchModeEnum.DEFAULT));
+    assertNotNull(finishLaunchRS);
+    assertEquals("http://example.com/ui/#test_project/launches/all/1", finishLaunchRS.getLink());
+  }
 
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.finishLaunch("1", finishExecutionRQ, extractProjectDetails(rpUser, "test_project"), rpUser, null)
-		);
-		assertEquals("You do not have enough permissions. You are not launch owner.", exception.getMessage());
-	}
+  @Test
+  void stopLaunch() {
+    FinishExecutionRQ finishExecutionRQ = new FinishExecutionRQ();
+    finishExecutionRQ.setEndTime(
+        Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+
+    ReportPortalUser rpUser = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER,
+        1L);
+
+    when(launchRepository.findById(1L)).thenReturn(
+        getLaunch(StatusEnum.IN_PROGRESS, LaunchModeEnum.DEFAULT));
+
+    final OperationCompletionRS response = stopLaunchHandler.stopLaunch(1L,
+        finishExecutionRQ,
+        extractProjectDetails(rpUser, "test_project"),
+        rpUser
+    );
+    assertNotNull(response);
+    assertEquals("Launch with ID = '1' successfully stopped.", response.getResultMessage());
+  }
+
+  @Test
+  void bulkStopLaunch() {
+    FinishExecutionRQ finishExecutionRQ = new FinishExecutionRQ();
+    finishExecutionRQ.setEndTime(
+        Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+
+    Map<Long, FinishExecutionRQ> entities = new HashMap<>();
+    entities.put(1L, finishExecutionRQ);
+
+    BulkRQ<Long, FinishExecutionRQ> bulkRq = new BulkRQ<>();
+    bulkRq.setEntities(entities);
+
+    ReportPortalUser rpUser = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER,
+        1L);
+
+    when(launchRepository.findById(1L)).thenReturn(
+        getLaunch(StatusEnum.IN_PROGRESS, LaunchModeEnum.DEFAULT));
+
+    final List<OperationCompletionRS> response = stopLaunchHandler.stopLaunch(bulkRq,
+        extractProjectDetails(rpUser, "test_project"),
+        rpUser
+    );
+    assertNotNull(response);
+    assertEquals(1, response.size());
+  }
+
+  @Test
+  void finishWithIncorrectStatus() {
+    FinishExecutionRQ finishExecutionRQ = new FinishExecutionRQ();
+    finishExecutionRQ.setEndTime(
+        Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+
+    final ReportPortalUser rpUser = getRpUser("test", UserRole.ADMINISTRATOR,
+        ProjectRole.PROJECT_MANAGER, 1L);
+
+    when(launchRepository.findByUuid("1")).thenReturn(
+        getLaunch(StatusEnum.PASSED, LaunchModeEnum.DEFAULT));
+
+    assertThrows(ReportPortalException.class,
+        () -> handler.finishLaunch("1", finishExecutionRQ,
+            extractProjectDetails(rpUser, "test_project"), rpUser, null)
+    );
+  }
+
+  @Test
+  void finishWithIncorrectEndTime() {
+    FinishExecutionRQ finishExecutionRQ = new FinishExecutionRQ();
+    finishExecutionRQ.setEndTime(
+        Date.from(LocalDateTime.now().minusHours(5).atZone(ZoneId.of("UTC")).toInstant()));
+
+    final ReportPortalUser rpUser = getRpUser("test", UserRole.ADMINISTRATOR,
+        ProjectRole.PROJECT_MANAGER, 1L);
+
+    when(launchRepository.findByUuid("1")).thenReturn(
+        getLaunch(StatusEnum.IN_PROGRESS, LaunchModeEnum.DEFAULT));
+
+    assertThrows(ReportPortalException.class,
+        () -> handler.finishLaunch("1", finishExecutionRQ,
+            extractProjectDetails(rpUser, "test_project"), rpUser, null)
+    );
+  }
+
+  @Test
+  void finishNotOwnLaunch() {
+    FinishExecutionRQ finishExecutionRQ = new FinishExecutionRQ();
+    finishExecutionRQ.setEndTime(
+        Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+
+    final ReportPortalUser rpUser = getRpUser("not owner", UserRole.USER, ProjectRole.MEMBER, 1L);
+    rpUser.setUserId(2L);
+
+    when(launchRepository.findByUuid("1")).thenReturn(
+        getLaunch(StatusEnum.IN_PROGRESS, LaunchModeEnum.DEFAULT));
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.finishLaunch("1", finishExecutionRQ,
+            extractProjectDetails(rpUser, "test_project"), rpUser, null)
+    );
+    assertEquals("You do not have enough permissions. You are not launch owner.",
+        exception.getMessage());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/launch/impl/GetLaunchHandlerImplTest.java b/src/test/java/com/epam/ta/reportportal/core/launch/impl/GetLaunchHandlerImplTest.java
index 255265e96f..ecb75b6190 100644
--- a/src/test/java/com/epam/ta/reportportal/core/launch/impl/GetLaunchHandlerImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/launch/impl/GetLaunchHandlerImplTest.java
@@ -16,13 +16,26 @@
 
 package com.epam.ta.reportportal.core.launch.impl;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static com.epam.ta.reportportal.commons.querygen.constant.LaunchCriteriaConstant.CRITERIA_LAUNCH_STATUS;
+import static com.epam.ta.reportportal.core.launch.impl.LaunchTestUtil.getLaunch;
+import static com.epam.ta.reportportal.util.TestProjectExtractor.extractProjectDetails;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.querygen.FilterCondition;
 import com.epam.ta.reportportal.core.jasper.GetJasperReportHandler;
 import com.epam.ta.reportportal.core.jasper.util.JasperDataProvider;
 import com.epam.ta.reportportal.core.launch.cluster.GetClusterHandler;
-import com.epam.ta.reportportal.dao.*;
+import com.epam.ta.reportportal.dao.ItemAttributeRepository;
+import com.epam.ta.reportportal.dao.LaunchRepository;
+import com.epam.ta.reportportal.dao.ProjectRepository;
+import com.epam.ta.reportportal.dao.UserRepository;
+import com.epam.ta.reportportal.dao.WidgetContentRepository;
 import com.epam.ta.reportportal.entity.enums.LaunchModeEnum;
 import com.epam.ta.reportportal.entity.enums.StatusEnum;
 import com.epam.ta.reportportal.entity.jasper.ReportFormat;
@@ -34,6 +47,8 @@
 import com.epam.ta.reportportal.ws.converter.converters.LaunchConverter;
 import com.epam.ta.reportportal.ws.model.Page;
 import com.epam.ta.reportportal.ws.model.launch.cluster.ClusterInfoResource;
+import java.util.List;
+import java.util.Optional;
 import org.apache.commons.lang3.RandomStringUtils;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
@@ -43,258 +58,265 @@
 import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.Pageable;
 
-import java.util.List;
-import java.util.Optional;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static com.epam.ta.reportportal.commons.querygen.constant.LaunchCriteriaConstant.CRITERIA_LAUNCH_STATUS;
-import static com.epam.ta.reportportal.core.launch.impl.LaunchTestUtil.getLaunch;
-import static com.epam.ta.reportportal.util.TestProjectExtractor.extractProjectDetails;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.when;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @ExtendWith(MockitoExtension.class)
 class GetLaunchHandlerImplTest {
 
-	@Mock
-	private GetClusterHandler getClusterHandler;
-
-	@Mock
-	private LaunchRepository launchRepository;
-
-	@Mock
-	private ItemAttributeRepository itemAttributeRepository;
-
-	@Mock
-	private ProjectRepository projectRepository;
-
-	@Mock
-	private WidgetContentRepository widgetContentRepository;
-
-	@Mock
-	private UserRepository userRepository;
-
-	@Mock
-	private JasperDataProvider jasperDataProvider;
-
-	@Mock
-	private GetJasperReportHandler<Launch> getJasperReportHandler;
-
-	@Mock
-	private LaunchConverter launchConverter;
-
-	@InjectMocks
-	private GetLaunchHandlerImpl handler;
+  @Mock
+  private GetClusterHandler getClusterHandler;
+
+  @Mock
+  private LaunchRepository launchRepository;
 
-	@Test
-	void getLaunchFromOtherProject() {
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 2L);
-		when(launchRepository.findById(1L)).thenReturn(getLaunch(StatusEnum.FAILED, LaunchModeEnum.DEFAULT));
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.getLaunch("1", extractProjectDetails(rpUser, "test_project"))
-		);
-		assertEquals("You do not have enough permissions.", exception.getMessage());
-	}
-
-	@Test
-	void getDebugLaunchWithCustomerRole() {
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.CUSTOMER, 1L);
-		when(launchRepository.findById(1L)).thenReturn(getLaunch(StatusEnum.PASSED, LaunchModeEnum.DEBUG));
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.getLaunch("1", extractProjectDetails(rpUser, "test_project"))
-		);
-		assertEquals("You do not have enough permissions.", exception.getMessage());
-	}
-
-	@Test
-	void getLaunchNamesIncorrectInput() {
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
-
-		assertThrows(ReportPortalException.class, () -> handler.getLaunchNames(extractProjectDetails(rpUser, "test_project"), ""));
-		assertThrows(ReportPortalException.class,
-				() -> handler.getLaunchNames(extractProjectDetails(rpUser, "test_project"), RandomStringUtils.random(257))
-		);
-	}
-
-	@Test
-	void getNotExistLaunch() {
-		ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, 1L);
-		String launchId = "1";
-
-		when(launchRepository.findById(Long.parseLong(launchId))).thenReturn(Optional.empty());
-
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.getLaunch(launchId, extractProjectDetails(user, "test_project"))
-		);
-		assertEquals("Launch '1' not found. Did you use correct Launch ID?", exception.getMessage());
-	}
-
-	@Test
-	void getLaunchByNotExistProjectName() {
-		String projectName = "not_exist";
-
-		when(projectRepository.findByName(projectName)).thenReturn(Optional.empty());
-
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.getLaunchByProjectName(projectName, PageRequest.of(0, 10), getDefaultFilter(), "user")
-		);
-		assertEquals("Project 'not_exist' not found. Did you use correct project name?", exception.getMessage());
-	}
-
-	@Test
-	void getLaunchByProjectNameNotFound() {
-		String projectName = "not_exist";
-
-		when(projectRepository.findByName(projectName)).thenReturn(Optional.of(new Project()));
-		when(launchRepository.findByFilter(any(), any())).thenReturn(null);
-
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.getLaunchByProjectName(projectName, PageRequest.of(0, 10), getDefaultFilter(), "user")
-		);
-		assertEquals("Launch '' not found. Did you use correct Launch ID?", exception.getMessage());
-	}
-
-	@Test
-	void getLaunchesByNotExistProject() {
-		long projectId = 1L;
-		ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER, projectId);
-
-		when(projectRepository.findById(projectId)).thenReturn(Optional.empty());
-
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.getProjectLaunches(extractProjectDetails(user, "test_project"),
-						getDefaultFilter(),
-						PageRequest.of(0, 10),
-						"user"
-				)
-		);
-		assertEquals("Project '1' not found. Did you use correct project name?", exception.getMessage());
-	}
-
-	@Test
-	void getLatestLaunchesOnNotExistProject() {
-		long projectId = 1L;
-		ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER, projectId);
-
-		when(projectRepository.findById(projectId)).thenReturn(Optional.empty());
-
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.getLatestLaunches(extractProjectDetails(user, "test_project"), getDefaultFilter(), PageRequest.of(0, 10))
-		);
-		assertEquals("Project '1' not found. Did you use correct project name?", exception.getMessage());
-	}
-
-	@Test
-	void getOwnersWrongTerm() {
-		long projectId = 1L;
-		ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER, projectId);
-
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.getOwners(extractProjectDetails(user, "test_project"), "qw", LaunchModeEnum.DEFAULT.name())
-		);
-		assertEquals("Incorrect filtering parameters. Length of the filtering string 'qw' is less than 3 symbols", exception.getMessage());
-	}
-
-	@Test
-	void getOwnersWrongMode() {
-		long projectId = 1L;
-		ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER, projectId);
-
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.getOwners(extractProjectDetails(user, "test_project"), "qwe", "incorrectMode")
-		);
-		assertEquals("Incorrect filtering parameters. Mode - incorrectMode doesn't exist.", exception.getMessage());
-	}
-
-	@Test
-	void exportLaunchNotFound() {
-		long launchId = 1L;
-		ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, 1L);
-
-		when(launchRepository.findById(launchId)).thenReturn(Optional.empty());
-
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.exportLaunch(launchId, ReportFormat.PDF, null, user)
-		);
-		assertEquals("Launch '1' not found. Did you use correct Launch ID?", exception.getMessage());
-	}
-
-	@Test
-	void exportLaunchUserNotFound() {
-		long launchId = 1L;
-		ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, 1L);
-
-		Launch launch = new Launch();
-		launch.setStatus(StatusEnum.FAILED);
-		when(launchRepository.findById(launchId)).thenReturn(Optional.of(launch));
-		when(userRepository.findById(1L)).thenReturn(Optional.empty());
-
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.exportLaunch(launchId, ReportFormat.PDF, null, user)
-		);
-		assertEquals("User '1' not found.", exception.getMessage());
-	}
-
-	@Test
-	void getLaunchInDebugModeByCustomer() {
-		long projectId = 1L;
-		ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.CUSTOMER, projectId);
-		String launchId = "1";
-
-		Launch launch = new Launch();
-		launch.setProjectId(projectId);
-		launch.setMode(LaunchModeEnum.DEBUG);
-		when(launchRepository.findById(Long.parseLong(launchId))).thenReturn(Optional.of(launch));
-
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.getLaunch(launchId, extractProjectDetails(user, "test_project"))
-		);
-		assertEquals("You do not have enough permissions.", exception.getMessage());
-	}
-
-	@Test
-	void getClusterInfo() {
-		long projectId = 1L;
-		ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, projectId);
-		String launchId = "1";
-
-		Launch launch = new Launch();
-		launch.setProjectId(projectId);
-		launch.setMode(LaunchModeEnum.DEBUG);
-		when(launchRepository.findById(Long.parseLong(launchId))).thenReturn(Optional.of(launch));
-
-		final Pageable pageable = PageRequest.of(1, 2);
-
-		final Page<ClusterInfoResource> expected = new Page<>(List.of(new ClusterInfoResource(), new ClusterInfoResource()), 2, 1, 10);
-
-		when(getClusterHandler.getResources(launch, pageable)).thenReturn(expected);
-
-		final Iterable<ClusterInfoResource> result = handler.getClusters(launchId, extractProjectDetails(user, "test_project"), pageable);
-
-		final Page<ClusterInfoResource> castedResult = (Page<ClusterInfoResource>) result;
-
-		assertEquals(expected.getPage().getNumber(), castedResult.getPage().getNumber());
-		assertEquals(expected.getPage().getSize(), castedResult.getPage().getSize());
-		assertEquals(expected.getPage().getTotalElements(), castedResult.getPage().getTotalElements());
-
-		assertEquals(10, castedResult.getPage().getTotalElements());
-		assertEquals(1, castedResult.getPage().getNumber());
-		assertEquals(2, castedResult.getPage().getSize());
-
-		assertEquals(2, castedResult.getContent().size());
-	}
-
-	private Filter getDefaultFilter() {
-		return Filter.builder()
-				.withTarget(Launch.class)
-				.withCondition(FilterCondition.builder().eq(CRITERIA_LAUNCH_STATUS, "PASSED").build())
-				.build();
-	}
+  @Mock
+  private ItemAttributeRepository itemAttributeRepository;
+
+  @Mock
+  private ProjectRepository projectRepository;
+
+  @Mock
+  private WidgetContentRepository widgetContentRepository;
+
+  @Mock
+  private UserRepository userRepository;
+
+  @Mock
+  private JasperDataProvider jasperDataProvider;
+
+  @Mock
+  private GetJasperReportHandler<Launch> getJasperReportHandler;
+
+  @Mock
+  private LaunchConverter launchConverter;
+
+  @InjectMocks
+  private GetLaunchHandlerImpl handler;
+
+  @Test
+  void getLaunchFromOtherProject() {
+    final ReportPortalUser rpUser = getRpUser("test", UserRole.ADMINISTRATOR,
+        ProjectRole.PROJECT_MANAGER, 2L);
+    when(launchRepository.findById(1L)).thenReturn(
+        getLaunch(StatusEnum.FAILED, LaunchModeEnum.DEFAULT));
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.getLaunch("1", extractProjectDetails(rpUser, "test_project"))
+    );
+    assertEquals("You do not have enough permissions.", exception.getMessage());
+  }
+
+  @Test
+  void getDebugLaunchWithCustomerRole() {
+    final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.CUSTOMER, 1L);
+    when(launchRepository.findById(1L)).thenReturn(
+        getLaunch(StatusEnum.PASSED, LaunchModeEnum.DEBUG));
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.getLaunch("1", extractProjectDetails(rpUser, "test_project"))
+    );
+    assertEquals("You do not have enough permissions.", exception.getMessage());
+  }
+
+  @Test
+  void getLaunchNamesIncorrectInput() {
+    final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
+
+    assertThrows(ReportPortalException.class,
+        () -> handler.getLaunchNames(extractProjectDetails(rpUser, "test_project"),
+            RandomStringUtils.random(257))
+    );
+  }
+
+  @Test
+  void getNotExistLaunch() {
+    ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, 1L);
+    String launchId = "1";
+
+    when(launchRepository.findById(Long.parseLong(launchId))).thenReturn(Optional.empty());
+
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.getLaunch(launchId, extractProjectDetails(user, "test_project"))
+    );
+    assertEquals("Launch '1' not found. Did you use correct Launch ID?", exception.getMessage());
+  }
+
+  @Test
+  void getLaunchByNotExistProjectName() {
+    String projectName = "not_exist";
+
+    when(projectRepository.findByName(projectName)).thenReturn(Optional.empty());
+
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.getLaunchByProjectName(projectName, PageRequest.of(0, 10), getDefaultFilter(),
+            "user")
+    );
+    assertEquals("Project 'not_exist' not found. Did you use correct project name?",
+        exception.getMessage());
+  }
+
+  @Test
+  void getLaunchByProjectNameNotFound() {
+    String projectName = "not_exist";
+
+    when(projectRepository.findByName(projectName)).thenReturn(Optional.of(new Project()));
+    when(launchRepository.findByFilter(any(), any())).thenReturn(null);
+
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.getLaunchByProjectName(projectName, PageRequest.of(0, 10), getDefaultFilter(),
+            "user")
+    );
+    assertEquals("Launch '' not found. Did you use correct Launch ID?", exception.getMessage());
+  }
+
+  @Test
+  void getLaunchesByNotExistProject() {
+    long projectId = 1L;
+    ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER,
+        projectId);
+
+    when(projectRepository.findById(projectId)).thenReturn(Optional.empty());
+
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.getProjectLaunches(extractProjectDetails(user, "test_project"),
+            getDefaultFilter(),
+            PageRequest.of(0, 10),
+            "user"
+        )
+    );
+    assertEquals("Project '1' not found. Did you use correct project name?",
+        exception.getMessage());
+  }
+
+  @Test
+  void getLatestLaunchesOnNotExistProject() {
+    long projectId = 1L;
+    ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER,
+        projectId);
+
+    when(projectRepository.findById(projectId)).thenReturn(Optional.empty());
+
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.getLatestLaunches(extractProjectDetails(user, "test_project"),
+            getDefaultFilter(), PageRequest.of(0, 10))
+    );
+    assertEquals("Project '1' not found. Did you use correct project name?",
+        exception.getMessage());
+  }
+
+  @Test
+  void getOwnersWrongTerm() {
+    long projectId = 1L;
+    ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER,
+        projectId);
+
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.getOwners(extractProjectDetails(user, "test_project"), "qw",
+            LaunchModeEnum.DEFAULT.name())
+    );
+    assertEquals(
+        "Incorrect filtering parameters. Length of the filtering string 'qw' is less than 3 symbols",
+        exception.getMessage());
+  }
+
+  @Test
+  void getOwnersWrongMode() {
+    long projectId = 1L;
+    ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER,
+        projectId);
+
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.getOwners(extractProjectDetails(user, "test_project"), "qwe", "incorrectMode")
+    );
+    assertEquals("Incorrect filtering parameters. Mode - incorrectMode doesn't exist.",
+        exception.getMessage());
+  }
+
+  @Test
+  void exportLaunchNotFound() {
+    long launchId = 1L;
+    ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, 1L);
+
+    when(launchRepository.findById(launchId)).thenReturn(Optional.empty());
+
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.exportLaunch(launchId, ReportFormat.PDF, null, user)
+    );
+    assertEquals("Launch '1' not found. Did you use correct Launch ID?", exception.getMessage());
+  }
+
+  @Test
+  void exportLaunchUserNotFound() {
+    long launchId = 1L;
+    ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, 1L);
+
+    Launch launch = new Launch();
+    launch.setStatus(StatusEnum.FAILED);
+    when(launchRepository.findById(launchId)).thenReturn(Optional.of(launch));
+    when(userRepository.findById(1L)).thenReturn(Optional.empty());
+
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.exportLaunch(launchId, ReportFormat.PDF, null, user)
+    );
+    assertEquals("User '1' not found.", exception.getMessage());
+  }
+
+  @Test
+  void getLaunchInDebugModeByCustomer() {
+    long projectId = 1L;
+    ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.CUSTOMER, projectId);
+    String launchId = "1";
+
+    Launch launch = new Launch();
+    launch.setProjectId(projectId);
+    launch.setMode(LaunchModeEnum.DEBUG);
+    when(launchRepository.findById(Long.parseLong(launchId))).thenReturn(Optional.of(launch));
+
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.getLaunch(launchId, extractProjectDetails(user, "test_project"))
+    );
+    assertEquals("You do not have enough permissions.", exception.getMessage());
+  }
+
+  @Test
+  void getClusterInfo() {
+    long projectId = 1L;
+    ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, projectId);
+    String launchId = "1";
+
+    Launch launch = new Launch();
+    launch.setProjectId(projectId);
+    launch.setMode(LaunchModeEnum.DEBUG);
+    when(launchRepository.findById(Long.parseLong(launchId))).thenReturn(Optional.of(launch));
+
+    final Pageable pageable = PageRequest.of(1, 2);
+
+    final Page<ClusterInfoResource> expected = new Page<>(
+        List.of(new ClusterInfoResource(), new ClusterInfoResource()), 2, 1, 10);
+
+    when(getClusterHandler.getResources(launch, pageable)).thenReturn(expected);
+
+    final Iterable<ClusterInfoResource> result = handler.getClusters(launchId,
+        extractProjectDetails(user, "test_project"), pageable);
+
+    final Page<ClusterInfoResource> castedResult = (Page<ClusterInfoResource>) result;
+
+    assertEquals(expected.getPage().getNumber(), castedResult.getPage().getNumber());
+    assertEquals(expected.getPage().getSize(), castedResult.getPage().getSize());
+    assertEquals(expected.getPage().getTotalElements(), castedResult.getPage().getTotalElements());
+
+    assertEquals(10, castedResult.getPage().getTotalElements());
+    assertEquals(1, castedResult.getPage().getNumber());
+    assertEquals(2, castedResult.getPage().getSize());
+
+    assertEquals(2, castedResult.getContent().size());
+  }
+
+  private Filter getDefaultFilter() {
+    return Filter.builder()
+        .withTarget(Launch.class)
+        .withCondition(FilterCondition.builder().eq(CRITERIA_LAUNCH_STATUS, "PASSED").build())
+        .build();
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/launch/impl/LaunchTestUtil.java b/src/test/java/com/epam/ta/reportportal/core/launch/impl/LaunchTestUtil.java
index 47102da1c1..cb4fe5a08d 100644
--- a/src/test/java/com/epam/ta/reportportal/core/launch/impl/LaunchTestUtil.java
+++ b/src/test/java/com/epam/ta/reportportal/core/launch/impl/LaunchTestUtil.java
@@ -20,7 +20,6 @@
 import com.epam.ta.reportportal.entity.enums.StatusEnum;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.entity.user.User;
-
 import java.time.LocalDateTime;
 import java.util.Optional;
 
@@ -29,25 +28,25 @@
  */
 public class LaunchTestUtil {
 
-	private LaunchTestUtil() {
-		//static only
-	}
+  private LaunchTestUtil() {
+    //static only
+  }
 
-	public static Optional<Launch> getLaunch(StatusEnum status, LaunchModeEnum mode) {
-		Launch launch = new Launch();
-		launch.setId(1L);
-		launch.setNumber(1L);
-		launch.setProjectId(1L);
-		launch.setStatus(status);
-		launch.setStartTime(LocalDateTime.now().minusHours(3));
-		User user = new User();
-		user.setId(1L);
-		user.setLogin("owner");
-		launch.setUserId(user.getId());
-		launch.setMode(mode);
-		launch.setUuid("uuid");
-		launch.setDescription("description");
-		launch.setName("launch name");
-		return Optional.of(launch);
-	}
+  public static Optional<Launch> getLaunch(StatusEnum status, LaunchModeEnum mode) {
+    Launch launch = new Launch();
+    launch.setId(1L);
+    launch.setNumber(1L);
+    launch.setProjectId(1L);
+    launch.setStatus(status);
+    launch.setStartTime(LocalDateTime.now().minusHours(3));
+    User user = new User();
+    user.setId(1L);
+    user.setLogin("owner");
+    launch.setUserId(user.getId());
+    launch.setMode(mode);
+    launch.setUuid("uuid");
+    launch.setDescription("description");
+    launch.setName("launch name");
+    return Optional.of(launch);
+  }
 }
diff --git a/src/test/java/com/epam/ta/reportportal/core/launch/impl/StartLaunchHandlerAsyncImplTest.java b/src/test/java/com/epam/ta/reportportal/core/launch/impl/StartLaunchHandlerAsyncImplTest.java
index 2a053b10a8..ca463f709d 100644
--- a/src/test/java/com/epam/ta/reportportal/core/launch/impl/StartLaunchHandlerAsyncImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/launch/impl/StartLaunchHandlerAsyncImplTest.java
@@ -16,6 +16,10 @@
 
 package com.epam.ta.reportportal.core.launch.impl;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.verify;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.entity.project.ProjectRole;
 import com.epam.ta.reportportal.entity.user.UserRole;
@@ -28,10 +32,6 @@
 import org.mockito.junit.jupiter.MockitoExtension;
 import org.springframework.amqp.core.AmqpTemplate;
 
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.verify;
-
 /**
  * @author Konstantin Antipin
  */
@@ -39,22 +39,24 @@
 @ExtendWith(MockitoExtension.class)
 class StartLaunchHandlerAsyncImplTest {
 
-    @Mock
-    AmqpTemplate amqpTemplate;
+  @Mock
+  AmqpTemplate amqpTemplate;
 
-    @Mock
-    ReportingQueueService reportingQueueService;
+  @Mock
+  ReportingQueueService reportingQueueService;
 
-    @InjectMocks
-    StartLaunchHandlerAsyncImpl startLaunchHandlerAsync;
+  @InjectMocks
+  StartLaunchHandlerAsyncImpl startLaunchHandlerAsync;
 
-    @Test
-    void starLaunch() {
-        StartLaunchRQ request = new StartLaunchRQ();
-        ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
+  @Test
+  void starLaunch() {
+    StartLaunchRQ request = new StartLaunchRQ();
+    ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER,
+        1L);
 
-        startLaunchHandlerAsync.startLaunch(user, user.getProjectDetails().get("test_project"), request);
-        verify(amqpTemplate).convertAndSend(any(), any(), any(), any());
-        verify(reportingQueueService).getReportingQueueKey(any());
-    }
+    startLaunchHandlerAsync.startLaunch(user, user.getProjectDetails().get("test_project"),
+        request);
+    verify(amqpTemplate).convertAndSend(any(), any(), any(), any());
+    verify(reportingQueueService).getReportingQueueKey(any());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/launch/impl/StartLaunchHandlerImplTest.java b/src/test/java/com/epam/ta/reportportal/core/launch/impl/StartLaunchHandlerImplTest.java
index 95caae5bc4..8d074cf6cb 100644
--- a/src/test/java/com/epam/ta/reportportal/core/launch/impl/StartLaunchHandlerImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/launch/impl/StartLaunchHandlerImplTest.java
@@ -16,6 +16,16 @@
 
 package com.epam.ta.reportportal.core.launch.impl;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static com.epam.ta.reportportal.util.TestProjectExtractor.extractProjectDetails;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.events.MessageBus;
 import com.epam.ta.reportportal.core.launch.rerun.RerunHandler;
@@ -28,6 +38,7 @@
 import com.epam.ta.reportportal.ws.model.launch.Mode;
 import com.epam.ta.reportportal.ws.model.launch.StartLaunchRQ;
 import com.epam.ta.reportportal.ws.model.launch.StartLaunchRS;
+import java.util.Date;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.InjectMocks;
@@ -35,75 +46,70 @@
 import org.mockito.junit.jupiter.MockitoExtension;
 import org.springframework.context.ApplicationEventPublisher;
 
-import java.util.Date;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static com.epam.ta.reportportal.util.TestProjectExtractor.extractProjectDetails;
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.Mockito.*;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @ExtendWith(MockitoExtension.class)
 class StartLaunchHandlerImplTest {
 
-	@Mock
-	private UserRepository userRepository;
+  @Mock
+  private UserRepository userRepository;
 
-	@Mock
-	private LaunchRepository launchRepository;
+  @Mock
+  private LaunchRepository launchRepository;
 
-	@Mock
-	private MessageBus messageBus;
+  @Mock
+  private MessageBus messageBus;
 
-	@Mock
-	private RerunHandler rerunHandler;
+  @Mock
+  private RerunHandler rerunHandler;
 
-	@Mock
-	private ApplicationEventPublisher eventPublisher;
+  @Mock
+  private ApplicationEventPublisher eventPublisher;
 
-	@InjectMocks
-	private StartLaunchHandlerImpl startLaunchHandlerImpl;
+  @InjectMocks
+  private StartLaunchHandlerImpl startLaunchHandlerImpl;
 
-	@Test
-	void startLaunch() {
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
+  @Test
+  void startLaunch() {
+    final ReportPortalUser rpUser = getRpUser("test", UserRole.ADMINISTRATOR,
+        ProjectRole.PROJECT_MANAGER, 1L);
 
-		StartLaunchRQ startLaunchRQ = new StartLaunchRQ();
-		startLaunchRQ.setStartTime(new Date());
-		startLaunchRQ.setName("test");
+    StartLaunchRQ startLaunchRQ = new StartLaunchRQ();
+    startLaunchRQ.setStartTime(new Date());
+    startLaunchRQ.setName("test");
 
-		Launch launch = new Launch();
-		launch.setId(1L);
+    Launch launch = new Launch();
+    launch.setId(1L);
 
-		when(launchRepository.save(any(Launch.class))).then(a -> {
-			Launch l = a.getArgument(0);
-			l.setId(1L);
-			return l;
-		}).thenReturn(launch);
+    when(launchRepository.save(any(Launch.class))).then(a -> {
+      Launch l = a.getArgument(0);
+      l.setId(1L);
+      return l;
+    }).thenReturn(launch);
 
-		final StartLaunchRS startLaunchRS = startLaunchHandlerImpl.startLaunch(rpUser,
-				extractProjectDetails(rpUser, "test_project"),
-				startLaunchRQ
-		);
+    final StartLaunchRS startLaunchRS = startLaunchHandlerImpl.startLaunch(rpUser,
+        extractProjectDetails(rpUser, "test_project"),
+        startLaunchRQ
+    );
 
-		verify(launchRepository, times(1)).refresh(any(Launch.class));
-		verify(eventPublisher, times(1)).publishEvent(any());
-		assertNotNull(startLaunchRS);
-	}
+    verify(launchRepository, times(1)).refresh(any(Launch.class));
+    verify(eventPublisher, times(1)).publishEvent(any());
+    assertNotNull(startLaunchRS);
+  }
 
-	@Test
-	void accessDeniedForCustomerRoleAndDebugMode() {
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.CUSTOMER, 1L);
+  @Test
+  void accessDeniedForCustomerRoleAndDebugMode() {
+    final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.CUSTOMER, 1L);
 
-		StartLaunchRQ startLaunchRQ = new StartLaunchRQ();
-		startLaunchRQ.setStartTime(new Date());
-		startLaunchRQ.setMode(Mode.DEBUG);
+    StartLaunchRQ startLaunchRQ = new StartLaunchRQ();
+    startLaunchRQ.setStartTime(new Date());
+    startLaunchRQ.setMode(Mode.DEBUG);
 
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> startLaunchHandlerImpl.startLaunch(rpUser, extractProjectDetails(rpUser, "test_project"), startLaunchRQ)
-		);
-		assertEquals("Forbidden operation.", exception.getMessage());
-	}
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> startLaunchHandlerImpl.startLaunch(rpUser,
+            extractProjectDetails(rpUser, "test_project"), startLaunchRQ)
+    );
+    assertEquals("Forbidden operation.", exception.getMessage());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/launch/impl/UpdateLaunchHandlerImplTest.java b/src/test/java/com/epam/ta/reportportal/core/launch/impl/UpdateLaunchHandlerImplTest.java
index 39c06f0ccf..e6ee281289 100644
--- a/src/test/java/com/epam/ta/reportportal/core/launch/impl/UpdateLaunchHandlerImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/launch/impl/UpdateLaunchHandlerImplTest.java
@@ -16,6 +16,18 @@
 
 package com.epam.ta.reportportal.core.launch.impl;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static com.epam.ta.reportportal.core.launch.impl.LaunchTestUtil.getLaunch;
+import static com.epam.ta.reportportal.util.TestProjectExtractor.extractProjectDetails;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.item.impl.LaunchAccessValidator;
 import com.epam.ta.reportportal.core.launch.GetLaunchHandler;
@@ -35,6 +47,7 @@
 import com.epam.ta.reportportal.ws.model.launch.Mode;
 import com.epam.ta.reportportal.ws.model.launch.UpdateLaunchRQ;
 import com.epam.ta.reportportal.ws.model.launch.cluster.CreateClustersRQ;
+import java.util.Map;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.ArgumentCaptor;
@@ -42,120 +55,124 @@
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 
-import java.util.Map;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static com.epam.ta.reportportal.core.launch.impl.LaunchTestUtil.getLaunch;
-import static com.epam.ta.reportportal.util.TestProjectExtractor.extractProjectDetails;
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.*;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @ExtendWith(MockitoExtension.class)
 class UpdateLaunchHandlerImplTest {
 
-	@Mock
-	private LaunchAccessValidator launchAccessValidator;
-
-	@Mock
-	private LaunchRepository launchRepository;
-
-	@Mock
-	private GetProjectHandler getProjectHandler;
-
-	@Mock
-	private GetLaunchHandler getLaunchHandler;
-
-	@Mock
-	private TestItemRepository testItemRepository;
-
-	@Mock
-	private UniqueErrorAnalysisStarter starter;
-
-	@InjectMocks
-	private UpdateLaunchHandlerImpl handler;
-
-	@Test
-	void updateNotOwnLaunch() {
-		final ReportPortalUser rpUser = getRpUser("not owner", UserRole.USER, ProjectRole.MEMBER, 1L);
-		rpUser.setUserId(2L);
-		when(getProjectHandler.get(any(ReportPortalUser.ProjectDetails.class))).thenReturn(new Project());
-		when(launchRepository.findById(1L)).thenReturn(getLaunch(StatusEnum.PASSED, LaunchModeEnum.DEFAULT));
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.updateLaunch(1L, extractProjectDetails(rpUser, "test_project"), rpUser, new UpdateLaunchRQ())
-		);
-		assertEquals("You do not have enough permissions.", exception.getMessage());
-	}
-
-	@Test
-	void updateDebugLaunchByCustomer() {
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.CUSTOMER, 1L);
-
-		when(getProjectHandler.get(any(ReportPortalUser.ProjectDetails.class))).thenReturn(new Project());
-		when(launchRepository.findById(1L)).thenReturn(getLaunch(StatusEnum.PASSED, LaunchModeEnum.DEFAULT));
-		final UpdateLaunchRQ updateLaunchRQ = new UpdateLaunchRQ();
-		updateLaunchRQ.setMode(Mode.DEBUG);
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.updateLaunch(1L, extractProjectDetails(rpUser, "test_project"), rpUser, updateLaunchRQ)
-		);
-		assertEquals("You do not have enough permissions.", exception.getMessage());
-	}
-
-	@Test
-	void createClustersLaunchInProgress() {
-
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.CUSTOMER, 1L);
-
-		when(getLaunchHandler.get(1L)).thenReturn(getLaunch(StatusEnum.IN_PROGRESS, LaunchModeEnum.DEFAULT).get());
-		final CreateClustersRQ createClustersRQ = new CreateClustersRQ();
-		createClustersRQ.setLaunchId(1L);
-		createClustersRQ.setRemoveNumbers(false);
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.createClusters(createClustersRQ, extractProjectDetails(rpUser, "test_project"), rpUser)
-		);
-		assertEquals("Incorrect Request. Cannot analyze launch in progress.", exception.getMessage());
-		verify(launchAccessValidator, times(1)).validate(any(Launch.class), any(ReportPortalUser.ProjectDetails.class), eq(rpUser));
-	}
-
-	@Test
-	void createClusters() {
-
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.CUSTOMER, 1L);
-
-		final Project project = new Project();
-		project.setId(1L);
-
-		final Launch launch = getLaunch(StatusEnum.PASSED, LaunchModeEnum.DEFAULT).get();
-		when(getLaunchHandler.get(1L)).thenReturn(launch);
-		when(getProjectHandler.get(launch.getProjectId())).thenReturn(project);
-
-		final CreateClustersRQ createClustersRQ = new CreateClustersRQ();
-		createClustersRQ.setLaunchId(1L);
-		final boolean defaultRemoveNumbers = Boolean.parseBoolean(ProjectAttributeEnum.UNIQUE_ERROR_ANALYZER_REMOVE_NUMBERS.getDefaultValue());
-		createClustersRQ.setRemoveNumbers(!defaultRemoveNumbers);
-
-		handler.createClusters(createClustersRQ, extractProjectDetails(rpUser, "test_project"), rpUser);
-
-		verify(launchAccessValidator, times(1)).validate(any(Launch.class), any(ReportPortalUser.ProjectDetails.class), eq(rpUser));
-
-		final ArgumentCaptor<ClusterEntityContext> contextCaptor = ArgumentCaptor.forClass(ClusterEntityContext.class);
-		final ArgumentCaptor<Map<String, String>> mapCaptor = ArgumentCaptor.forClass(Map.class);
-		verify(starter, times(1)).start(contextCaptor.capture(), mapCaptor.capture());
-
-		final ClusterEntityContext entityContext = contextCaptor.getValue();
-
-		assertEquals(1L, entityContext.getProjectId().longValue());
-		assertEquals(1L, entityContext.getLaunchId().longValue());
-
-		final Map<String, String> providedConfig = mapCaptor.getValue();
+  @Mock
+  private LaunchAccessValidator launchAccessValidator;
+
+  @Mock
+  private LaunchRepository launchRepository;
+
+  @Mock
+  private GetProjectHandler getProjectHandler;
 
-		final boolean providedRemoveNumbers = Boolean.parseBoolean(providedConfig.get(ProjectAttributeEnum.UNIQUE_ERROR_ANALYZER_REMOVE_NUMBERS.getAttribute()));
-		assertNotEquals(providedRemoveNumbers, defaultRemoveNumbers);
-		assertEquals(createClustersRQ.isRemoveNumbers(), providedRemoveNumbers);
-	}
+  @Mock
+  private GetLaunchHandler getLaunchHandler;
+
+  @Mock
+  private TestItemRepository testItemRepository;
+
+  @Mock
+  private UniqueErrorAnalysisStarter starter;
+
+  @InjectMocks
+  private UpdateLaunchHandlerImpl handler;
+
+  @Test
+  void updateNotOwnLaunch() {
+    final ReportPortalUser rpUser = getRpUser("not owner", UserRole.USER, ProjectRole.MEMBER, 1L);
+    rpUser.setUserId(2L);
+    when(getProjectHandler.get(any(ReportPortalUser.ProjectDetails.class))).thenReturn(
+        new Project());
+    when(launchRepository.findById(1L)).thenReturn(
+        getLaunch(StatusEnum.PASSED, LaunchModeEnum.DEFAULT));
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.updateLaunch(1L, extractProjectDetails(rpUser, "test_project"), rpUser,
+            new UpdateLaunchRQ())
+    );
+    assertEquals("You do not have enough permissions.", exception.getMessage());
+  }
+
+  @Test
+  void updateDebugLaunchByCustomer() {
+    final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.CUSTOMER, 1L);
+
+    when(getProjectHandler.get(any(ReportPortalUser.ProjectDetails.class))).thenReturn(
+        new Project());
+    when(launchRepository.findById(1L)).thenReturn(
+        getLaunch(StatusEnum.PASSED, LaunchModeEnum.DEFAULT));
+    final UpdateLaunchRQ updateLaunchRQ = new UpdateLaunchRQ();
+    updateLaunchRQ.setMode(Mode.DEBUG);
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.updateLaunch(1L, extractProjectDetails(rpUser, "test_project"), rpUser,
+            updateLaunchRQ)
+    );
+    assertEquals("You do not have enough permissions.", exception.getMessage());
+  }
+
+  @Test
+  void createClustersLaunchInProgress() {
+
+    final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.CUSTOMER, 1L);
+
+    when(getLaunchHandler.get(1L)).thenReturn(
+        getLaunch(StatusEnum.IN_PROGRESS, LaunchModeEnum.DEFAULT).get());
+    final CreateClustersRQ createClustersRQ = new CreateClustersRQ();
+    createClustersRQ.setLaunchId(1L);
+    createClustersRQ.setRemoveNumbers(false);
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.createClusters(createClustersRQ,
+            extractProjectDetails(rpUser, "test_project"), rpUser)
+    );
+    assertEquals("Incorrect Request. Cannot analyze launch in progress.", exception.getMessage());
+    verify(launchAccessValidator, times(1)).validate(any(Launch.class),
+        any(ReportPortalUser.ProjectDetails.class), eq(rpUser));
+  }
+
+  @Test
+  void createClusters() {
+
+    final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.CUSTOMER, 1L);
+
+    final Project project = new Project();
+    project.setId(1L);
+
+    final Launch launch = getLaunch(StatusEnum.PASSED, LaunchModeEnum.DEFAULT).get();
+    when(getLaunchHandler.get(1L)).thenReturn(launch);
+    when(getProjectHandler.get(launch.getProjectId())).thenReturn(project);
+
+    final CreateClustersRQ createClustersRQ = new CreateClustersRQ();
+    createClustersRQ.setLaunchId(1L);
+    final boolean defaultRemoveNumbers = Boolean.parseBoolean(
+        ProjectAttributeEnum.UNIQUE_ERROR_ANALYZER_REMOVE_NUMBERS.getDefaultValue());
+    createClustersRQ.setRemoveNumbers(!defaultRemoveNumbers);
+
+    handler.createClusters(createClustersRQ, extractProjectDetails(rpUser, "test_project"), rpUser);
+
+    verify(launchAccessValidator, times(1)).validate(any(Launch.class),
+        any(ReportPortalUser.ProjectDetails.class), eq(rpUser));
+
+    final ArgumentCaptor<ClusterEntityContext> contextCaptor = ArgumentCaptor.forClass(
+        ClusterEntityContext.class);
+    final ArgumentCaptor<Map<String, String>> mapCaptor = ArgumentCaptor.forClass(Map.class);
+    verify(starter, times(1)).start(contextCaptor.capture(), mapCaptor.capture());
+
+    final ClusterEntityContext entityContext = contextCaptor.getValue();
+
+    assertEquals(1L, entityContext.getProjectId().longValue());
+    assertEquals(1L, entityContext.getLaunchId().longValue());
+
+    final Map<String, String> providedConfig = mapCaptor.getValue();
+
+    final boolean providedRemoveNumbers = Boolean.parseBoolean(providedConfig.get(
+        ProjectAttributeEnum.UNIQUE_ERROR_ANALYZER_REMOVE_NUMBERS.getAttribute()));
+    assertNotEquals(providedRemoveNumbers, defaultRemoveNumbers);
+    assertEquals(createClustersRQ.isRemoveNumbers(), providedRemoveNumbers);
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/launch/rerun/RerunHandlerImplTest.java b/src/test/java/com/epam/ta/reportportal/core/launch/rerun/RerunHandlerImplTest.java
index 4d21f94642..3baeffaca3 100644
--- a/src/test/java/com/epam/ta/reportportal/core/launch/rerun/RerunHandlerImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/launch/rerun/RerunHandlerImplTest.java
@@ -16,6 +16,17 @@
 
 package com.epam.ta.reportportal.core.launch.rerun;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.commons.querygen.Queryable;
 import com.epam.ta.reportportal.core.item.identity.TestCaseHashGenerator;
@@ -39,6 +50,8 @@
 import com.epam.ta.reportportal.ws.model.launch.Mode;
 import com.epam.ta.reportportal.ws.model.launch.StartLaunchRQ;
 import com.google.common.collect.Sets;
+import java.util.ArrayList;
+import java.util.Optional;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.InjectMocks;
@@ -48,209 +61,211 @@
 import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.data.util.Pair;
 
-import java.util.ArrayList;
-import java.util.Optional;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.Mockito.*;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @ExtendWith(MockitoExtension.class)
 class RerunHandlerImplTest {
 
-	@Spy
-	private ArrayList<ParentItemValidator> parentItemValidators;
-
-	@Mock
-	private TestItemRepository testItemRepository;
-
-	@Mock
-	private LaunchRepository launchRepository;
-
-	@Mock
-	private UniqueIdGenerator uniqueIdGenerator;
-
-	@Mock
-	private TestCaseHashGenerator testCaseHashGenerator;
-
-	@Mock
-	private ApplicationEventPublisher eventPublisher;
-
-	@Mock
-	private RerunSearcher rerunSearcher;
-
-	@Mock
-	private RetryHandler retryHandler;
-
-	@InjectMocks
-	private RerunHandlerImpl rerunHandler;
-
-	@Test
-	void exceptionWhenLaunchIsNotStoredInDbByName() {
-		StartLaunchRQ request = new StartLaunchRQ();
-		String launchName = "launch";
-		long projectId = 1L;
-		request.setRerun(true);
-		request.setName(launchName);
-		ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.PROJECT_MANAGER, projectId);
-
-		when(launchRepository.findLatestByNameAndProjectId(launchName, projectId)).thenReturn(Optional.empty());
-
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> rerunHandler.handleLaunch(request, projectId, rpUser)
-		);
-		assertEquals("Launch 'launch' not found. Did you use correct Launch ID?", exception.getMessage());
-	}
-
-	@Test
-	void exceptionWhenLaunchIsNotStoredInDbByUuid() {
-		StartLaunchRQ request = new StartLaunchRQ();
-		String launchName = "launch";
-		String uuid = "uuid";
-		long projectId = 1L;
-		request.setRerun(true);
-		request.setRerunOf(uuid);
-		request.setName(launchName);
-		ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.PROJECT_MANAGER, projectId);
-
-		when(launchRepository.findByUuid(uuid)).thenReturn(Optional.empty());
-
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> rerunHandler.handleLaunch(request, projectId, rpUser)
-		);
-		assertEquals("Launch 'uuid' not found. Did you use correct Launch ID?", exception.getMessage());
-	}
-
-	@Test
-	void happyRerunLaunch() {
-		StartLaunchRQ request = new StartLaunchRQ();
-		String launchName = "launch";
-		long projectId = 1L;
-		request.setRerun(true);
-		request.setName(launchName);
-		request.setMode(Mode.DEFAULT);
-		request.setDescription("desc");
-		request.setAttributes(Sets.newHashSet(new ItemAttributesRQ("test", "test")));
-		ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.PROJECT_MANAGER, projectId);
-
-		when(launchRepository.findLatestByNameAndProjectId("launch", projectId)).thenReturn(Optional.of(getLaunch("uuid")));
-
-		final Launch launch = rerunHandler.handleLaunch(request, projectId, rpUser);
-
-		assertNotNull(launch.getNumber());
-		assertNotNull(launch.getId());
-
-	}
-
-	@Test
-	void returnEmptyOptionalWhenRootItemNotFound() {
-		StartTestItemRQ request = new StartTestItemRQ();
-		request.setLaunchUuid("launch_uuid");
-		request.setType("STEP");
-		String itemName = "name";
-		request.setName(itemName);
-		final String testCaseId = "caseId";
-		request.setTestCaseId(testCaseId);
-		Launch launch = getLaunch("uuid");
-
-		when(rerunSearcher.findItem(any(Queryable.class))).thenReturn(Optional.empty());
-
-		Optional<ItemCreatedRS> rerunCreatedRS = rerunHandler.handleRootItem(request, launch);
-
-		assertFalse(rerunCreatedRS.isPresent());
-	}
-
-	@Test
-	void happyRerunRootItem() {
-		StartTestItemRQ request = new StartTestItemRQ();
-		request.setLaunchUuid("launch_uuid");
-		request.setType("STEP");
-		String itemName = "name";
-		request.setName(itemName);
-		final String testCaseId = "caseId";
-		request.setTestCaseId(testCaseId);
-		Launch launch = getLaunch("uuid");
-
-		final TestItem item = getItem(itemName, launch);
-		when(rerunSearcher.findItem(any(Queryable.class))).thenReturn(Optional.of(item.getItemId()));
-		when(testItemRepository.findById(item.getItemId())).thenReturn(Optional.of(item));
-
-		Optional<ItemCreatedRS> rerunCreatedRS = rerunHandler.handleRootItem(request, launch);
-
-		assertTrue(rerunCreatedRS.isPresent());
-	}
-
-	@Test
-	void returnEmptyOptionalWhenChildItemNotFound() {
-		StartTestItemRQ request = new StartTestItemRQ();
-		request.setLaunchUuid("launch_uuid");
-		request.setType("STEP");
-		String itemName = "name";
-		request.setName(itemName);
-		final String testCaseId = "caseId";
-		request.setTestCaseId(testCaseId);
-		Launch launch = getLaunch("uuid");
-		TestItem parent = new TestItem();
-		parent.setItemId(2L);
-		parent.setPath("1.2");
-
-		when(rerunSearcher.findItem(any(Queryable.class))).thenReturn(Optional.empty());
-		when(testItemRepository.selectPath("uuid")).thenReturn(Optional.of(Pair.of(parent.getItemId(), parent.getPath())));
-
-		Optional<ItemCreatedRS> rerunCreatedRS = rerunHandler.handleChildItem(request, launch, "uuid");
-
-		assertFalse(rerunCreatedRS.isPresent());
-	}
-
-	@Test
-	void happyRerunChildItem() {
-		StartTestItemRQ request = new StartTestItemRQ();
-		request.setLaunchUuid("launch_uuid");
-		request.setType("STEP");
-		String itemName = "name";
-		request.setName(itemName);
-		final String testCaseId = "caseId";
-		request.setTestCaseId(testCaseId);
-		Launch launch = getLaunch("uuid");
-		TestItem parent = new TestItem();
-		parent.setItemId(2L);
-		parent.setPath("1.2");
-
-		final TestItem item = getItem(itemName, launch);
-		when(rerunSearcher.findItem(any(Queryable.class))).thenReturn(Optional.of(item.getItemId()));
-		when(testItemRepository.findById(item.getItemId())).thenReturn(Optional.of(item));
-		when(testItemRepository.selectPath("uuid")).thenReturn(Optional.of(Pair.of(parent.getItemId(), parent.getPath())));
-		when(testItemRepository.findIdByUuidForUpdate("uuid")).thenReturn(Optional.of(parent.getItemId()));
-		when(testItemRepository.getOne(parent.getItemId())).thenReturn(parent);
-
-		Optional<ItemCreatedRS> rerunCreatedRS = rerunHandler.handleChildItem(request, launch, "uuid");
-
-		verify(retryHandler, times(1)).handleRetries(any(), any(), any());
-
-		assertTrue(rerunCreatedRS.isPresent());
-	}
-
-	private TestItem getItem(String name, Launch launch) {
-		TestItem item = new TestItem();
-		item.setItemId(1L);
-		item.setName(name);
-		item.setLaunchId(launch.getId());
-		item.setDescription("desc");
-		item.setType(TestItemTypeEnum.STEP);
-		TestItemResults itemResults = new TestItemResults();
-		itemResults.setStatus(StatusEnum.PASSED);
-		item.setItemResults(itemResults);
-		return item;
-	}
-
-	private Launch getLaunch(String uuid) {
-		Launch launch = new Launch();
-		launch.setUuid(uuid);
-		launch.setNumber(1L);
-		launch.setId(1L);
-		return launch;
-	}
+  @Spy
+  private ArrayList<ParentItemValidator> parentItemValidators;
+
+  @Mock
+  private TestItemRepository testItemRepository;
+
+  @Mock
+  private LaunchRepository launchRepository;
+
+  @Mock
+  private UniqueIdGenerator uniqueIdGenerator;
+
+  @Mock
+  private TestCaseHashGenerator testCaseHashGenerator;
+
+  @Mock
+  private ApplicationEventPublisher eventPublisher;
+
+  @Mock
+  private RerunSearcher rerunSearcher;
+
+  @Mock
+  private RetryHandler retryHandler;
+
+  @InjectMocks
+  private RerunHandlerImpl rerunHandler;
+
+  @Test
+  void exceptionWhenLaunchIsNotStoredInDbByName() {
+    StartLaunchRQ request = new StartLaunchRQ();
+    String launchName = "launch";
+    long projectId = 1L;
+    request.setRerun(true);
+    request.setName(launchName);
+    ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.PROJECT_MANAGER,
+        projectId);
+
+    when(launchRepository.findLatestByNameAndProjectId(launchName, projectId)).thenReturn(
+        Optional.empty());
+
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> rerunHandler.handleLaunch(request, projectId, rpUser)
+    );
+    assertEquals("Launch 'launch' not found. Did you use correct Launch ID?",
+        exception.getMessage());
+  }
+
+  @Test
+  void exceptionWhenLaunchIsNotStoredInDbByUuid() {
+    StartLaunchRQ request = new StartLaunchRQ();
+    String launchName = "launch";
+    String uuid = "uuid";
+    long projectId = 1L;
+    request.setRerun(true);
+    request.setRerunOf(uuid);
+    request.setName(launchName);
+    ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.PROJECT_MANAGER,
+        projectId);
+
+    when(launchRepository.findByUuid(uuid)).thenReturn(Optional.empty());
+
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> rerunHandler.handleLaunch(request, projectId, rpUser)
+    );
+    assertEquals("Launch 'uuid' not found. Did you use correct Launch ID?", exception.getMessage());
+  }
+
+  @Test
+  void happyRerunLaunch() {
+    StartLaunchRQ request = new StartLaunchRQ();
+    String launchName = "launch";
+    long projectId = 1L;
+    request.setRerun(true);
+    request.setName(launchName);
+    request.setMode(Mode.DEFAULT);
+    request.setDescription("desc");
+    request.setAttributes(Sets.newHashSet(new ItemAttributesRQ("test", "test")));
+    ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.PROJECT_MANAGER,
+        projectId);
+
+    when(launchRepository.findLatestByNameAndProjectId("launch", projectId)).thenReturn(
+        Optional.of(getLaunch("uuid")));
+
+    final Launch launch = rerunHandler.handleLaunch(request, projectId, rpUser);
+
+    assertNotNull(launch.getNumber());
+    assertNotNull(launch.getId());
+
+  }
+
+  @Test
+  void returnEmptyOptionalWhenRootItemNotFound() {
+    StartTestItemRQ request = new StartTestItemRQ();
+    request.setLaunchUuid("launch_uuid");
+    request.setType("STEP");
+    String itemName = "name";
+    request.setName(itemName);
+    final String testCaseId = "caseId";
+    request.setTestCaseId(testCaseId);
+    Launch launch = getLaunch("uuid");
+
+    when(rerunSearcher.findItem(any(Queryable.class))).thenReturn(Optional.empty());
+
+    Optional<ItemCreatedRS> rerunCreatedRS = rerunHandler.handleRootItem(request, launch);
+
+    assertFalse(rerunCreatedRS.isPresent());
+  }
+
+  @Test
+  void happyRerunRootItem() {
+    StartTestItemRQ request = new StartTestItemRQ();
+    request.setLaunchUuid("launch_uuid");
+    request.setType("STEP");
+    String itemName = "name";
+    request.setName(itemName);
+    final String testCaseId = "caseId";
+    request.setTestCaseId(testCaseId);
+    Launch launch = getLaunch("uuid");
+
+    final TestItem item = getItem(itemName, launch);
+    when(rerunSearcher.findItem(any(Queryable.class))).thenReturn(Optional.of(item.getItemId()));
+    when(testItemRepository.findById(item.getItemId())).thenReturn(Optional.of(item));
+
+    Optional<ItemCreatedRS> rerunCreatedRS = rerunHandler.handleRootItem(request, launch);
+
+    assertTrue(rerunCreatedRS.isPresent());
+  }
+
+  @Test
+  void returnEmptyOptionalWhenChildItemNotFound() {
+    StartTestItemRQ request = new StartTestItemRQ();
+    request.setLaunchUuid("launch_uuid");
+    request.setType("STEP");
+    String itemName = "name";
+    request.setName(itemName);
+    final String testCaseId = "caseId";
+    request.setTestCaseId(testCaseId);
+    Launch launch = getLaunch("uuid");
+    TestItem parent = new TestItem();
+    parent.setItemId(2L);
+    parent.setPath("1.2");
+
+    when(rerunSearcher.findItem(any(Queryable.class))).thenReturn(Optional.empty());
+    when(testItemRepository.selectPath("uuid")).thenReturn(
+        Optional.of(Pair.of(parent.getItemId(), parent.getPath())));
+
+    Optional<ItemCreatedRS> rerunCreatedRS = rerunHandler.handleChildItem(request, launch, "uuid");
+
+    assertFalse(rerunCreatedRS.isPresent());
+  }
+
+  @Test
+  void happyRerunChildItem() {
+    StartTestItemRQ request = new StartTestItemRQ();
+    request.setLaunchUuid("launch_uuid");
+    request.setType("STEP");
+    String itemName = "name";
+    request.setName(itemName);
+    final String testCaseId = "caseId";
+    request.setTestCaseId(testCaseId);
+    Launch launch = getLaunch("uuid");
+    TestItem parent = new TestItem();
+    parent.setItemId(2L);
+    parent.setPath("1.2");
+
+    final TestItem item = getItem(itemName, launch);
+    when(rerunSearcher.findItem(any(Queryable.class))).thenReturn(Optional.of(item.getItemId()));
+    when(testItemRepository.findById(item.getItemId())).thenReturn(Optional.of(item));
+    when(testItemRepository.selectPath("uuid")).thenReturn(
+        Optional.of(Pair.of(parent.getItemId(), parent.getPath())));
+    when(testItemRepository.findIdByUuidForUpdate("uuid")).thenReturn(
+        Optional.of(parent.getItemId()));
+    when(testItemRepository.getOne(parent.getItemId())).thenReturn(parent);
+
+    Optional<ItemCreatedRS> rerunCreatedRS = rerunHandler.handleChildItem(request, launch, "uuid");
+
+    verify(retryHandler, times(1)).handleRetries(any(), any(), any());
+
+    assertTrue(rerunCreatedRS.isPresent());
+  }
+
+  private TestItem getItem(String name, Launch launch) {
+    TestItem item = new TestItem();
+    item.setItemId(1L);
+    item.setName(name);
+    item.setLaunchId(launch.getId());
+    item.setDescription("desc");
+    item.setType(TestItemTypeEnum.STEP);
+    TestItemResults itemResults = new TestItemResults();
+    itemResults.setStatus(StatusEnum.PASSED);
+    item.setItemResults(itemResults);
+    return item;
+  }
+
+  private Launch getLaunch(String uuid) {
+    Launch launch = new Launch();
+    launch.setUuid(uuid);
+    launch.setNumber(1L);
+    launch.setId(1L);
+    return launch;
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/launch/util/LaunchValidatorTest.java b/src/test/java/com/epam/ta/reportportal/core/launch/util/LaunchValidatorTest.java
index e0934c711a..02ad7ed9e3 100644
--- a/src/test/java/com/epam/ta/reportportal/core/launch/util/LaunchValidatorTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/launch/util/LaunchValidatorTest.java
@@ -16,46 +16,47 @@
 
 package com.epam.ta.reportportal.core.launch.util;
 
+import static com.epam.ta.reportportal.commons.EntityUtils.TO_DATE;
+import static com.epam.ta.reportportal.commons.EntityUtils.TO_LOCAL_DATE_TIME;
+import static com.epam.ta.reportportal.ws.model.ErrorType.FINISH_TIME_EARLIER_THAN_START_TIME;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
 import com.epam.ta.reportportal.commons.validation.Suppliers;
 import com.epam.ta.reportportal.entity.enums.StatusEnum;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.FinishExecutionRQ;
-import org.junit.jupiter.api.Test;
-
 import java.time.Instant;
 import java.time.LocalDateTime;
 import java.time.ZoneOffset;
-
-import static com.epam.ta.reportportal.commons.EntityUtils.TO_DATE;
-import static com.epam.ta.reportportal.commons.EntityUtils.TO_LOCAL_DATE_TIME;
-import static com.epam.ta.reportportal.ws.model.ErrorType.FINISH_TIME_EARLIER_THAN_START_TIME;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
  */
 class LaunchValidatorTest {
 
-	@Test
-	void validate() {
-		Launch launch = new Launch();
-		launch.setStatus(StatusEnum.IN_PROGRESS);
-		launch.setStartTime(LocalDateTime.ofInstant(Instant.ofEpochMilli(1575551458336L), ZoneOffset.UTC));
-
-		FinishExecutionRQ finishExecutionRQ = new FinishExecutionRQ();
-		finishExecutionRQ.setEndTime(TO_DATE.apply(LocalDateTime.ofInstant(Instant.ofEpochMilli(1575551458334L), ZoneOffset.UTC)));
-
-		ReportPortalException reportPortalException = assertThrows(ReportPortalException.class,
-				() -> LaunchValidator.validate(launch, finishExecutionRQ)
-		);
-
-		assertEquals(Suppliers.formattedSupplier(FINISH_TIME_EARLIER_THAN_START_TIME.getDescription(),
-				TO_LOCAL_DATE_TIME.apply(finishExecutionRQ.getEndTime()),
-				launch.getStartTime(),
-				launch.getId()
-		).get(), reportPortalException.getMessage());
-	}
+  @Test
+  void validate() {
+    Launch launch = new Launch();
+    launch.setStatus(StatusEnum.IN_PROGRESS);
+    launch.setStartTime(
+        LocalDateTime.ofInstant(Instant.ofEpochMilli(1575551458336L), ZoneOffset.UTC));
+
+    FinishExecutionRQ finishExecutionRQ = new FinishExecutionRQ();
+    finishExecutionRQ.setEndTime(TO_DATE.apply(
+        LocalDateTime.ofInstant(Instant.ofEpochMilli(1575551458334L), ZoneOffset.UTC)));
+
+    ReportPortalException reportPortalException = assertThrows(ReportPortalException.class,
+        () -> LaunchValidator.validate(launch, finishExecutionRQ)
+    );
+
+    assertEquals(Suppliers.formattedSupplier(FINISH_TIME_EARLIER_THAN_START_TIME.getDescription(),
+        TO_LOCAL_DATE_TIME.apply(finishExecutionRQ.getEndTime()),
+        launch.getStartTime(),
+        launch.getId()
+    ).get(), reportPortalException.getMessage());
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/log/ElasticLogServiceTest.java b/src/test/java/com/epam/ta/reportportal/core/log/ElasticLogServiceTest.java
new file mode 100644
index 0000000000..ea6bc7cbaf
--- /dev/null
+++ b/src/test/java/com/epam/ta/reportportal/core/log/ElasticLogServiceTest.java
@@ -0,0 +1,62 @@
+package com.epam.ta.reportportal.core.log;
+
+import static com.epam.ta.reportportal.core.configs.rabbit.BackgroundProcessingConfiguration.LOG_MESSAGE_SAVING_ROUTING_KEY;
+import static com.epam.ta.reportportal.core.configs.rabbit.BackgroundProcessingConfiguration.PROCESSING_EXCHANGE_NAME;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import com.epam.ta.reportportal.entity.item.TestItem;
+import com.epam.ta.reportportal.entity.launch.Launch;
+import com.epam.ta.reportportal.entity.log.LogFull;
+import com.epam.ta.reportportal.entity.log.LogMessage;
+import java.util.List;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.amqp.core.AmqpTemplate;
+
+@ExtendWith(MockitoExtension.class)
+class ElasticLogServiceTest {
+
+  @Mock
+  private AmqpTemplate amqpTemplate;
+
+  @InjectMocks
+  private ElasticLogService elasticLogService;
+
+  private LogFull logFull;
+
+  private LogMessage logMessage;
+
+  @BeforeEach
+  public void setUp() {
+    Long itemId = 1L;
+    Long launchId = 1L;
+    logFull = new LogFull();
+    logFull.setTestItem(new TestItem(itemId));
+    logFull.setLaunch(new Launch(launchId));
+
+    logMessage = new LogMessage(logFull.getId(), logFull.getLogTime(), logFull.getLogMessage(),
+        itemId, launchId, logFull.getProjectId());
+  }
+
+  @Test
+  void saveLogMessage() {
+    elasticLogService.saveLogMessage(logFull, logFull.getLaunch().getId());
+
+    verify(amqpTemplate, times(1)).convertAndSend(eq(PROCESSING_EXCHANGE_NAME),
+        eq(LOG_MESSAGE_SAVING_ROUTING_KEY), eq(logMessage));
+  }
+
+  @Test
+  void saveLogMessageList() {
+    elasticLogService.saveLogMessageList(List.of(logFull), logFull.getLaunch().getId());
+
+    verify(amqpTemplate, times(1)).convertAndSend(eq(PROCESSING_EXCHANGE_NAME),
+        eq(LOG_MESSAGE_SAVING_ROUTING_KEY), eq(logMessage));
+  }
+}
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/log/impl/CreateLogHandlerAsyncImplTest.java b/src/test/java/com/epam/ta/reportportal/core/log/impl/CreateLogHandlerAsyncImplTest.java
index 822a09e880..bcf4eb3512 100644
--- a/src/test/java/com/epam/ta/reportportal/core/log/impl/CreateLogHandlerAsyncImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/log/impl/CreateLogHandlerAsyncImplTest.java
@@ -16,12 +16,18 @@
 
 package com.epam.ta.reportportal.core.log.impl;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.BinaryDataMetaInfo;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.entity.project.ProjectRole;
 import com.epam.ta.reportportal.entity.user.UserRole;
 import com.epam.ta.reportportal.util.ReportingQueueService;
 import com.epam.ta.reportportal.ws.model.log.SaveLogRQ;
+import javax.inject.Provider;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.InjectMocks;
@@ -31,13 +37,6 @@
 import org.springframework.core.task.TaskExecutor;
 import org.springframework.web.multipart.MultipartFile;
 
-import javax.inject.Provider;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
 /**
  * @author Konstantin Antipin
  */
@@ -45,55 +44,58 @@
 @ExtendWith(MockitoExtension.class)
 class CreateLogHandlerAsyncImplTest {
 
-    @Mock
-    Provider<SaveLogBinaryDataTaskAsync> provider;
+  @Mock
+  Provider<SaveLogBinaryDataTaskAsync> provider;
 
-    @Mock
-    ReportingQueueService reportingQueueService;
+  @Mock
+  ReportingQueueService reportingQueueService;
 
-    @Mock
-    AmqpTemplate amqpTemplate;
+  @Mock
+  AmqpTemplate amqpTemplate;
 
-    @Mock
-    TaskExecutor taskExecutor;
+  @Mock
+  TaskExecutor taskExecutor;
 
-    @InjectMocks
-    CreateLogHandlerAsyncImpl createLogHandlerAsync;
+  @InjectMocks
+  CreateLogHandlerAsyncImpl createLogHandlerAsync;
 
-    @Mock
-    MultipartFile multipartFile;
+  @Mock
+  MultipartFile multipartFile;
 
-    @Mock
-    SaveLogBinaryDataTaskAsync saveLogBinaryDataTask;
+  @Mock
+  SaveLogBinaryDataTaskAsync saveLogBinaryDataTask;
 
-    @Mock
-    BinaryDataMetaInfo binaryDataMetaInfo;
+  @Mock
+  BinaryDataMetaInfo binaryDataMetaInfo;
 
-    @Test
-    void createLog() {
-        SaveLogRQ request = new SaveLogRQ();
-        ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
+  @Test
+  void createLog() {
+    SaveLogRQ request = new SaveLogRQ();
+    ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER,
+        1L);
 
-        when(provider.get()).thenReturn(saveLogBinaryDataTask);
-        when(saveLogBinaryDataTask.withRequest(any())).thenReturn(saveLogBinaryDataTask);
-        when(saveLogBinaryDataTask.withFile(any())).thenReturn(saveLogBinaryDataTask);
-        when(saveLogBinaryDataTask.withProjectId(any())).thenReturn(saveLogBinaryDataTask);
+    when(provider.get()).thenReturn(saveLogBinaryDataTask);
+    when(saveLogBinaryDataTask.withRequest(any())).thenReturn(saveLogBinaryDataTask);
+    when(saveLogBinaryDataTask.withFile(any())).thenReturn(saveLogBinaryDataTask);
+    when(saveLogBinaryDataTask.withProjectId(any())).thenReturn(saveLogBinaryDataTask);
 
-        createLogHandlerAsync.createLog(request, multipartFile, user.getProjectDetails().get("test_project"));
+    createLogHandlerAsync.createLog(request, multipartFile,
+        user.getProjectDetails().get("test_project"));
 
-        verify(provider).get();
-        verify(saveLogBinaryDataTask).withRequest(request);
-        verify(saveLogBinaryDataTask).withFile(multipartFile);
-        verify(saveLogBinaryDataTask).withProjectId(user.getProjectDetails().get("test_project").getProjectId());
-    }
+    verify(provider).get();
+    verify(saveLogBinaryDataTask).withRequest(request);
+    verify(saveLogBinaryDataTask).withFile(multipartFile);
+    verify(saveLogBinaryDataTask).withProjectId(
+        user.getProjectDetails().get("test_project").getProjectId());
+  }
 
-    @Test
-    void sendMessage() {
-        SaveLogRQ request = new SaveLogRQ();
+  @Test
+  void sendMessage() {
+    SaveLogRQ request = new SaveLogRQ();
 
-        createLogHandlerAsync.sendMessage(request, binaryDataMetaInfo, 0L);
-        verify(amqpTemplate).convertAndSend(any(), any(), any(), any());
-        verify(reportingQueueService).getReportingQueueKey(any());
-    }
+    createLogHandlerAsync.sendMessage(request, binaryDataMetaInfo, 0L);
+    verify(amqpTemplate).convertAndSend(any(), any(), any(), any());
+    verify(reportingQueueService).getReportingQueueKey(any());
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/log/impl/DeleteLogHandlerTest.java b/src/test/java/com/epam/ta/reportportal/core/log/impl/DeleteLogHandlerTest.java
index 963d1fe88a..61018dfb9f 100644
--- a/src/test/java/com/epam/ta/reportportal/core/log/impl/DeleteLogHandlerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/log/impl/DeleteLogHandlerTest.java
@@ -16,9 +16,20 @@
 
 package com.epam.ta.reportportal.core.log.impl;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static com.epam.ta.reportportal.util.TestProjectExtractor.extractProjectDetails;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.analyzer.auto.LogIndexer;
 import com.epam.ta.reportportal.core.item.TestItemService;
+import com.epam.ta.reportportal.core.log.LogService;
 import com.epam.ta.reportportal.dao.AttachmentRepository;
 import com.epam.ta.reportportal.dao.LogRepository;
 import com.epam.ta.reportportal.dao.ProjectRepository;
@@ -33,175 +44,174 @@
 import com.epam.ta.reportportal.entity.user.UserRole;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.google.common.collect.Sets;
+import java.util.Collections;
+import java.util.Optional;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 
-import java.util.Collections;
-import java.util.Optional;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static com.epam.ta.reportportal.util.TestProjectExtractor.extractProjectDetails;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.Mockito.*;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @ExtendWith(MockitoExtension.class)
 class DeleteLogHandlerTest {
 
-	@Mock
-	private ProjectRepository projectRepository;
-
-	@Mock
-	private LogRepository logRepository;
-
-	@Mock
-	private AttachmentRepository attachmentRepository;
-
-	@Mock
-	private TestItemService testItemService;
-
-	@Mock
-	private LogIndexer logIndexer;
-
-	@InjectMocks
-	private DeleteLogHandlerImpl handler;
-
-	@Test
-	void deleteLogOnNotExistProject() {
-		long projectId = 1L;
-		ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER, projectId);
-
-		when(projectRepository.existsById(projectId)).thenReturn(false);
-
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.deleteLog(1L, extractProjectDetails(user, "test_project"), user)
-		);
-		assertEquals("Project '1' not found. Did you use correct project name?", exception.getMessage());
-	}
-
-	@Test
-	void deleteNotExistLog() {
-		long projectId = 1L;
-		long logId = 2L;
-		ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER, projectId);
-
-		when(projectRepository.existsById(projectId)).thenReturn(true);
-		when(logRepository.findById(logId)).thenReturn(Optional.empty());
-
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.deleteLog(logId, extractProjectDetails(user, "test_project"), user)
-		);
-		assertEquals("Log '2' not found. Did you use correct Log ID?", exception.getMessage());
-	}
-
-	@Test
-	void deleteLogByNotOwner() {
-		long projectId = 1L;
-		long logId = 2L;
-		ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, projectId);
-
-		Log log = new Log();
-		TestItem testItem = new TestItem();
-		TestItemResults itemResults = new TestItemResults();
-		itemResults.setStatistics(Sets.newHashSet(new Statistics()));
-		testItem.setItemResults(itemResults);
-		Launch launch = new Launch();
-		launch.setId(1L);
-		launch.setProjectId(projectId);
-		User user1 = new User();
-		user1.setId(1L);
-		user1.setLogin("owner");
-		launch.setUserId(2L);
-		testItem.setLaunchId(launch.getId());
-		log.setTestItem(testItem);
-
-		when(testItemService.getEffectiveLaunch(any(TestItem.class))).thenReturn(launch);
-		when(projectRepository.existsById(projectId)).thenReturn(true);
-		when(logRepository.findById(logId)).thenReturn(Optional.of(log));
-
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.deleteLog(logId, extractProjectDetails(user, "test_project"), user)
-		);
-		assertEquals("You do not have enough permissions.", exception.getMessage());
-	}
-
-	@Test
-	void cleanUpLogDataTest() {
-		long projectId = 1L;
-		long logId = 2L;
-		ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, projectId);
-
-		Log log = new Log();
-		TestItem testItem = new TestItem();
-		TestItemResults itemResults = new TestItemResults();
-		itemResults.setStatistics(Sets.newHashSet(new Statistics()));
-		testItem.setItemResults(itemResults);
-		Launch launch = new Launch();
-		launch.setId(1L);
-		launch.setProjectId(projectId);
-		User user1 = new User();
-		user1.setId(1L);
-		user1.setLogin("owner");
-		launch.setUserId(user1.getId());
-		testItem.setLaunchId(launch.getId());
-		log.setTestItem(testItem);
-		Attachment attachment = new Attachment();
-		String attachmentPath = "attachmentPath";
-		attachment.setFileId(attachmentPath);
-		String attachmentThumbnailPath = "attachmentThumbnail";
-		attachment.setThumbnailId(attachmentThumbnailPath);
-		log.setAttachment(attachment);
-
-		when(testItemService.getEffectiveLaunch(any(TestItem.class))).thenReturn(launch);
-		when(projectRepository.existsById(projectId)).thenReturn(true);
-		when(logRepository.findById(logId)).thenReturn(Optional.of(log));
-
-		handler.deleteLog(logId, extractProjectDetails(user, "test_project"), user);
-
-		verify(logRepository, times(1)).delete(log);
-		verify(logIndexer, times(1)).cleanIndex(projectId, Collections.singletonList(logId));
-	}
-
-	@Test
-	void cleanUpLogDataNegative() {
-		long projectId = 1L;
-		long logId = 2L;
-		ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, projectId);
-
-		Log log = new Log();
-		TestItem testItem = new TestItem();
-		TestItemResults itemResults = new TestItemResults();
-		itemResults.setStatistics(Sets.newHashSet(new Statistics()));
-		testItem.setItemResults(itemResults);
-		Launch launch = new Launch();
-		launch.setId(1L);
-		launch.setProjectId(projectId);
-		User user1 = new User();
-		user1.setId(1L);
-		user1.setLogin("owner");
-		launch.setUserId(user1.getId());
-		testItem.setLaunchId(launch.getId());
-		log.setTestItem(testItem);
-		Attachment attachment = new Attachment();
-		String attachmentPath = "attachmentPath";
-		attachment.setFileId(attachmentPath);
-		String attachmentThumbnailPath = "attachmentThumbnail";
-		attachment.setThumbnailId(attachmentThumbnailPath);
-		log.setAttachment(attachment);
-		when(testItemService.getEffectiveLaunch(any(TestItem.class))).thenReturn(launch);
-		when(projectRepository.existsById(projectId)).thenReturn(true);
-		when(logRepository.findById(logId)).thenReturn(Optional.of(log));
-		doThrow(IllegalArgumentException.class).when(logRepository).delete(log);
-
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.deleteLog(logId, extractProjectDetails(user, "test_project"), user)
-		);
-		assertEquals("Error while Log instance deleting.", exception.getMessage());
-	}
+  @Mock
+  private ProjectRepository projectRepository;
+
+  @Mock
+  private LogRepository logRepository;
+
+  @Mock
+  private AttachmentRepository attachmentRepository;
+
+  @Mock
+  private TestItemService testItemService;
+
+  @Mock
+  private LogIndexer logIndexer;
+
+  @Mock
+  private LogService logService;
+
+  @InjectMocks
+  private DeleteLogHandlerImpl handler;
+
+  @Test
+  void deleteLogOnNotExistProject() {
+    long projectId = 1L;
+    ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER,
+        projectId);
+
+    when(projectRepository.existsById(projectId)).thenReturn(false);
+
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.deleteLog(1L, extractProjectDetails(user, "test_project"), user)
+    );
+    assertEquals("Project '1' not found. Did you use correct project name?",
+        exception.getMessage());
+  }
+
+  @Test
+  void deleteNotExistLog() {
+    long projectId = 1L;
+    long logId = 2L;
+    ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER,
+        projectId);
+
+    when(projectRepository.existsById(projectId)).thenReturn(true);
+    when(logRepository.findById(logId)).thenReturn(Optional.empty());
+
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.deleteLog(logId, extractProjectDetails(user, "test_project"), user)
+    );
+    assertEquals("Log '2' not found. Did you use correct Log ID?", exception.getMessage());
+  }
+
+  @Test
+  void deleteLogByNotOwner() {
+    long projectId = 1L;
+    long logId = 2L;
+    ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, projectId);
+
+    Log log = new Log();
+    TestItem testItem = new TestItem();
+    TestItemResults itemResults = new TestItemResults();
+    itemResults.setStatistics(Sets.newHashSet(new Statistics()));
+    testItem.setItemResults(itemResults);
+    Launch launch = new Launch();
+    launch.setId(1L);
+    launch.setProjectId(projectId);
+    User user1 = new User();
+    user1.setId(1L);
+    user1.setLogin("owner");
+    launch.setUserId(2L);
+    testItem.setLaunchId(launch.getId());
+    log.setTestItem(testItem);
+
+    when(testItemService.getEffectiveLaunch(any(TestItem.class))).thenReturn(launch);
+    when(projectRepository.existsById(projectId)).thenReturn(true);
+    when(logRepository.findById(logId)).thenReturn(Optional.of(log));
+
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.deleteLog(logId, extractProjectDetails(user, "test_project"), user)
+    );
+    assertEquals("You do not have enough permissions.", exception.getMessage());
+  }
+
+  @Test
+  void cleanUpLogDataTest() {
+    long projectId = 1L;
+    long logId = 2L;
+    ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, projectId);
+
+    Log log = new Log();
+    TestItem testItem = new TestItem();
+    TestItemResults itemResults = new TestItemResults();
+    itemResults.setStatistics(Sets.newHashSet(new Statistics()));
+    testItem.setItemResults(itemResults);
+    Launch launch = new Launch();
+    launch.setId(1L);
+    launch.setProjectId(projectId);
+    User user1 = new User();
+    user1.setId(1L);
+    user1.setLogin("owner");
+    launch.setUserId(user1.getId());
+    testItem.setLaunchId(launch.getId());
+    log.setTestItem(testItem);
+    Attachment attachment = new Attachment();
+    String attachmentPath = "attachmentPath";
+    attachment.setFileId(attachmentPath);
+    String attachmentThumbnailPath = "attachmentThumbnail";
+    attachment.setThumbnailId(attachmentThumbnailPath);
+    log.setAttachment(attachment);
+
+    when(testItemService.getEffectiveLaunch(any(TestItem.class))).thenReturn(launch);
+    when(projectRepository.existsById(projectId)).thenReturn(true);
+    when(logRepository.findById(logId)).thenReturn(Optional.of(log));
+
+    handler.deleteLog(logId, extractProjectDetails(user, "test_project"), user);
+
+    verify(logRepository, times(1)).delete(log);
+    verify(logIndexer, times(1)).cleanIndex(projectId, Collections.singletonList(logId));
+  }
+
+  @Test
+  void cleanUpLogDataNegative() {
+    long projectId = 1L;
+    long logId = 2L;
+    ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.MEMBER, projectId);
+
+    Log log = new Log();
+    TestItem testItem = new TestItem();
+    TestItemResults itemResults = new TestItemResults();
+    itemResults.setStatistics(Sets.newHashSet(new Statistics()));
+    testItem.setItemResults(itemResults);
+    Launch launch = new Launch();
+    launch.setId(1L);
+    launch.setProjectId(projectId);
+    User user1 = new User();
+    user1.setId(1L);
+    user1.setLogin("owner");
+    launch.setUserId(user1.getId());
+    testItem.setLaunchId(launch.getId());
+    log.setTestItem(testItem);
+    Attachment attachment = new Attachment();
+    String attachmentPath = "attachmentPath";
+    attachment.setFileId(attachmentPath);
+    String attachmentThumbnailPath = "attachmentThumbnail";
+    attachment.setThumbnailId(attachmentThumbnailPath);
+    log.setAttachment(attachment);
+    when(testItemService.getEffectiveLaunch(any(TestItem.class))).thenReturn(launch);
+    when(projectRepository.existsById(projectId)).thenReturn(true);
+    when(logRepository.findById(logId)).thenReturn(Optional.of(log));
+    doThrow(IllegalArgumentException.class).when(logRepository).delete(log);
+
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.deleteLog(logId, extractProjectDetails(user, "test_project"), user)
+    );
+    assertEquals("Error while Log instance deleting.", exception.getMessage());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/log/impl/GetLogHandlerImplTest.java b/src/test/java/com/epam/ta/reportportal/core/log/impl/GetLogHandlerImplTest.java
index 10e04185b8..22994eb417 100644
--- a/src/test/java/com/epam/ta/reportportal/core/log/impl/GetLogHandlerImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/log/impl/GetLogHandlerImplTest.java
@@ -1,9 +1,22 @@
 package com.epam.ta.reportportal.core.log.impl;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static com.epam.ta.reportportal.commons.querygen.constant.LogCriteriaConstant.CRITERIA_ITEM_LAUNCH_ID;
+import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_PATH;
+import static com.epam.ta.reportportal.util.TestProjectExtractor.extractProjectDetails;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
-import com.epam.ta.reportportal.commons.querygen.*;
+import com.epam.ta.reportportal.commons.querygen.Condition;
+import com.epam.ta.reportportal.commons.querygen.ConvertibleCondition;
+import com.epam.ta.reportportal.commons.querygen.Filter;
+import com.epam.ta.reportportal.commons.querygen.FilterCondition;
+import com.epam.ta.reportportal.commons.querygen.Queryable;
 import com.epam.ta.reportportal.core.item.TestItemService;
 import com.epam.ta.reportportal.core.log.GetLogHandler;
+import com.epam.ta.reportportal.core.log.LogService;
 import com.epam.ta.reportportal.dao.LogRepository;
 import com.epam.ta.reportportal.dao.TestItemRepository;
 import com.epam.ta.reportportal.entity.item.TestItem;
@@ -11,6 +24,8 @@
 import com.epam.ta.reportportal.entity.log.Log;
 import com.epam.ta.reportportal.entity.project.ProjectRole;
 import com.epam.ta.reportportal.entity.user.UserRole;
+import java.util.List;
+import java.util.Optional;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import org.mockito.ArgumentCaptor;
@@ -18,83 +33,80 @@
 import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.Pageable;
 
-import java.util.List;
-import java.util.Optional;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static com.epam.ta.reportportal.commons.querygen.constant.LogCriteriaConstant.CRITERIA_ITEM_LAUNCH_ID;
-import static com.epam.ta.reportportal.commons.querygen.constant.TestItemCriteriaConstant.CRITERIA_PATH;
-import static com.epam.ta.reportportal.util.TestProjectExtractor.extractProjectDetails;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class GetLogHandlerTest {
 
-	private final LogRepository logRepository = mock(LogRepository.class);
+  private final LogRepository logRepository = mock(LogRepository.class);
+
+  private final LogService logService = mock(LogService.class);
 
-	private final TestItemRepository testItemRepository = mock(TestItemRepository.class);
+  private final TestItemRepository testItemRepository = mock(TestItemRepository.class);
 
-	private final TestItemService testItemService = mock(TestItemService.class);
+  private final TestItemService testItemService = mock(TestItemService.class);
 
-	private final GetLogHandler getLogHandler = new GetLogHandlerImpl(logRepository, testItemRepository, testItemService);
+  private final GetLogHandler getLogHandler = new GetLogHandlerImpl(logRepository, logService,
+      testItemRepository, testItemService);
 
-	@Test
-	void getLogs() {
+  @Test
+  void getLogs() {
 
-		Long projectId = 1L;
-		ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER, projectId);
+    Long projectId = 1L;
+    ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER,
+        projectId);
 
-		String wrongPath = "1";
-		Filter idFilter = Filter.builder()
-				.withTarget(Log.class)
-				.withCondition(FilterCondition.builder()
-						.withSearchCriteria(CRITERIA_PATH)
-						.withValue(wrongPath)
-						.withCondition(Condition.UNDER)
-						.build())
-				.build();
-		Pageable pageable = PageRequest.of(1, 5);
+    String wrongPath = "1";
+    Filter idFilter = Filter.builder()
+        .withTarget(Log.class)
+        .withCondition(FilterCondition.builder()
+            .withSearchCriteria(CRITERIA_PATH)
+            .withValue(wrongPath)
+            .withCondition(Condition.UNDER)
+            .build())
+        .build();
+    Pageable pageable = PageRequest.of(1, 5);
 
-		TestItem testItem = new TestItem();
-		testItem.setItemId(3L);
-		String correctPath = "1.2.3";
-		testItem.setPath(correctPath);
-		testItem.setLaunchId(1L);
+    TestItem testItem = new TestItem();
+    testItem.setItemId(3L);
+    String correctPath = "1.2.3";
+    testItem.setPath(correctPath);
+    testItem.setLaunchId(1L);
 
-		Launch launch = new Launch();
-		launch.setId(1L);
+    Launch launch = new Launch();
+    launch.setId(1L);
 
-		when(testItemRepository.findByPath(correctPath)).thenReturn(Optional.of(testItem));
-		when(testItemService.getEffectiveLaunch(testItem)).thenReturn(launch);
+    when(testItemRepository.findByPath(correctPath)).thenReturn(Optional.of(testItem));
+    when(testItemService.getEffectiveLaunch(testItem)).thenReturn(launch);
 
-		ArgumentCaptor<Queryable> queryableArgumentCaptor = ArgumentCaptor.forClass(Queryable.class);
-		when(logRepository.findByFilter(queryableArgumentCaptor.capture(), any(Pageable.class))).thenReturn(Page.empty(pageable));
+    ArgumentCaptor<Queryable> queryableArgumentCaptor = ArgumentCaptor.forClass(Queryable.class);
+    when(
+        logService.findByFilter(queryableArgumentCaptor.capture(), any(Pageable.class))).thenReturn(
+        Page.empty(pageable));
 
-		getLogHandler.getLogs(correctPath, extractProjectDetails(user, "test_project"), idFilter, pageable);
+    getLogHandler.getLogs(correctPath, extractProjectDetails(user, "test_project"), idFilter,
+        pageable);
 
-		Queryable updatedFilter = queryableArgumentCaptor.getValue();
+    Queryable updatedFilter = queryableArgumentCaptor.getValue();
 
-		List<ConvertibleCondition> filterConditions = updatedFilter.getFilterConditions();
+    List<ConvertibleCondition> filterConditions = updatedFilter.getFilterConditions();
 
-		Optional<FilterCondition> launchIdCondition = filterConditions.stream()
-				.flatMap(convertibleCondition -> convertibleCondition.getAllConditions().stream())
-				.filter(c -> CRITERIA_ITEM_LAUNCH_ID.equals(c.getSearchCriteria()))
-				.findFirst();
+    Optional<FilterCondition> launchIdCondition = filterConditions.stream()
+        .flatMap(convertibleCondition -> convertibleCondition.getAllConditions().stream())
+        .filter(c -> CRITERIA_ITEM_LAUNCH_ID.equals(c.getSearchCriteria()))
+        .findFirst();
 
-		Assertions.assertTrue(launchIdCondition.isPresent());
-		Assertions.assertEquals(String.valueOf(launch.getId()), launchIdCondition.get().getValue());
+    Assertions.assertTrue(launchIdCondition.isPresent());
+    Assertions.assertEquals(String.valueOf(launch.getId()), launchIdCondition.get().getValue());
 
-		Optional<FilterCondition> underPathCondition = filterConditions.stream()
-				.flatMap(convertibleCondition -> convertibleCondition.getAllConditions().stream())
-				.filter(c -> CRITERIA_PATH.equals(c.getSearchCriteria()) && Condition.UNDER.equals(c.getCondition()))
-				.findFirst();
+    Optional<FilterCondition> underPathCondition = filterConditions.stream()
+        .flatMap(convertibleCondition -> convertibleCondition.getAllConditions().stream())
+        .filter(c -> CRITERIA_PATH.equals(c.getSearchCriteria()) && Condition.UNDER.equals(
+            c.getCondition()))
+        .findFirst();
 
-		Assertions.assertTrue(underPathCondition.isPresent());
-		Assertions.assertNotEquals(wrongPath, underPathCondition.get().getValue());
-		Assertions.assertEquals(correctPath, underPathCondition.get().getValue());
-	}
+    Assertions.assertTrue(underPathCondition.isPresent());
+    Assertions.assertNotEquals(wrongPath, underPathCondition.get().getValue());
+    Assertions.assertEquals(correctPath, underPathCondition.get().getValue());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/logging/HelperController.java b/src/test/java/com/epam/ta/reportportal/core/logging/HelperController.java
index f28caa9604..c3a275b97d 100644
--- a/src/test/java/com/epam/ta/reportportal/core/logging/HelperController.java
+++ b/src/test/java/com/epam/ta/reportportal/core/logging/HelperController.java
@@ -16,37 +16,38 @@
 
 package com.epam.ta.reportportal.core.logging;
 
+import java.util.Map;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.RequestBody;
-import java.util.Map;
 
 public class HelperController {
-	private static final Logger logger = LoggerFactory.getLogger(HelperController.class);
-
-	private static final HttpHeaders responseHeaders;
-
-	static {
-		responseHeaders = new HttpHeaders();
-		responseHeaders.set("Cotent-Type", "text/plain");
-		responseHeaders.set("Server", "Apache");
-	}
-
-	@HttpLogging(logExecutionTime = false)
-	public ResponseEntity<Map<String, Object>> logFull(@RequestBody Object payload) {
-		return new ResponseEntity(payload, responseHeaders, HttpStatus.OK);
-	}
-
-	@HttpLogging(logExecutionTime = false, logHeaders = false)
-	public ResponseEntity<Map<String, Object>> logWithoutHeaders(@RequestBody Object payload) {
-		return new ResponseEntity(payload, responseHeaders, HttpStatus.OK);
-	}
-
-	@HttpLogging(logExecutionTime = false, logResponseBody = false, logRequestBody = false)
-	public ResponseEntity<Map<String, Object>> logWithoutBody(@RequestBody Object payload) {
-		return new ResponseEntity(payload, responseHeaders, HttpStatus.OK);
-	}
+
+  private static final Logger logger = LoggerFactory.getLogger(HelperController.class);
+
+  private static final HttpHeaders responseHeaders;
+
+  static {
+    responseHeaders = new HttpHeaders();
+    responseHeaders.set("Cotent-Type", "text/plain");
+    responseHeaders.set("Server", "Apache");
+  }
+
+  @HttpLogging(logExecutionTime = false)
+  public ResponseEntity<Map<String, Object>> logFull(@RequestBody Object payload) {
+    return new ResponseEntity(payload, responseHeaders, HttpStatus.OK);
+  }
+
+  @HttpLogging(logExecutionTime = false, logHeaders = false)
+  public ResponseEntity<Map<String, Object>> logWithoutHeaders(@RequestBody Object payload) {
+    return new ResponseEntity(payload, responseHeaders, HttpStatus.OK);
+  }
+
+  @HttpLogging(logExecutionTime = false, logResponseBody = false, logRequestBody = false)
+  public ResponseEntity<Map<String, Object>> logWithoutBody(@RequestBody Object payload) {
+    return new ResponseEntity(payload, responseHeaders, HttpStatus.OK);
+  }
 }
diff --git a/src/test/java/com/epam/ta/reportportal/core/logging/HelperListener.java b/src/test/java/com/epam/ta/reportportal/core/logging/HelperListener.java
index 8bce4ce462..6d2ebba4d0 100644
--- a/src/test/java/com/epam/ta/reportportal/core/logging/HelperListener.java
+++ b/src/test/java/com/epam/ta/reportportal/core/logging/HelperListener.java
@@ -20,15 +20,15 @@
 
 public class HelperListener {
 
-	@RabbitMessageLogging
-	public void onMessageFull(Message message) {
-	}
+  @RabbitMessageLogging
+  public void onMessageFull(Message message) {
+  }
 
-	@RabbitMessageLogging(logHeaders = false)
-	public void onMessageWithoutHeaders(Message message) {
-	}
+  @RabbitMessageLogging(logHeaders = false)
+  public void onMessageWithoutHeaders(Message message) {
+  }
 
-	@RabbitMessageLogging(logBody = false)
-	public void onMessageWithoutBody(Message message) {
-	}
+  @RabbitMessageLogging(logBody = false)
+  public void onMessageWithoutBody(Message message) {
+  }
 }
diff --git a/src/test/java/com/epam/ta/reportportal/core/logging/HelperUtil.java b/src/test/java/com/epam/ta/reportportal/core/logging/HelperUtil.java
index 0f482f434f..45c1afb771 100644
--- a/src/test/java/com/epam/ta/reportportal/core/logging/HelperUtil.java
+++ b/src/test/java/com/epam/ta/reportportal/core/logging/HelperUtil.java
@@ -16,37 +16,38 @@
 
 package com.epam.ta.reportportal.core.logging;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.verify;
+import static org.mockito.internal.verification.VerificationModeFactory.times;
+
 import ch.qos.logback.classic.Level;
 import ch.qos.logback.classic.spi.ILoggingEvent;
 import ch.qos.logback.classic.spi.LoggingEvent;
 import ch.qos.logback.core.Appender;
-import org.mockito.ArgumentCaptor;
-
 import java.util.Arrays;
 import java.util.List;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.mockito.Mockito.verify;
-import static org.mockito.internal.verification.VerificationModeFactory.times;
+import org.mockito.ArgumentCaptor;
 
 public class HelperUtil {
 
-	public static void checkLoggingRecords(Appender<ILoggingEvent> appender, int numberOfRecords, Level[] levels, String ... records) {
-		ArgumentCaptor<LoggingEvent> argument = ArgumentCaptor.forClass(LoggingEvent.class);
-		verify(appender, times(numberOfRecords)).doAppend(argument.capture());
-
-		List<LoggingEvent> events = argument.getAllValues();
-		for (int i = 0; i < events.size(); i++) {
-			assertEquals(levels[i], events.get(i).getLevel());
-			assertEquals(orderedMultilineString(records[i]), orderedMultilineString(events.get(i).getMessage()));
-		}
-	}
-
-	public static String orderedMultilineString(String input) {
-		String[] lines = input.split("\n");
-		Arrays.sort(lines);
-		return Stream.of(lines).collect(Collectors.joining("\n"));
-	}
+  public static void checkLoggingRecords(Appender<ILoggingEvent> appender, int numberOfRecords,
+      Level[] levels, String... records) {
+    ArgumentCaptor<LoggingEvent> argument = ArgumentCaptor.forClass(LoggingEvent.class);
+    verify(appender, times(numberOfRecords)).doAppend(argument.capture());
+
+    List<LoggingEvent> events = argument.getAllValues();
+    for (int i = 0; i < events.size(); i++) {
+      assertEquals(levels[i], events.get(i).getLevel());
+      assertEquals(orderedMultilineString(records[i]),
+          orderedMultilineString(events.get(i).getMessage()));
+    }
+  }
+
+  public static String orderedMultilineString(String input) {
+    String[] lines = input.split("\n");
+    Arrays.sort(lines);
+    return Stream.of(lines).collect(Collectors.joining("\n"));
+  }
 }
diff --git a/src/test/java/com/epam/ta/reportportal/core/logging/HttpLoggingAspectTest.java b/src/test/java/com/epam/ta/reportportal/core/logging/HttpLoggingAspectTest.java
index 331f466798..3556c67911 100644
--- a/src/test/java/com/epam/ta/reportportal/core/logging/HttpLoggingAspectTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/logging/HttpLoggingAspectTest.java
@@ -16,11 +16,18 @@
 
 package com.epam.ta.reportportal.core.logging;
 
+import static com.epam.ta.reportportal.core.logging.HelperUtil.checkLoggingRecords;
+import static org.mockito.Mockito.when;
+
 import ch.qos.logback.classic.Level;
 import ch.qos.logback.classic.Logger;
 import ch.qos.logback.classic.spi.ILoggingEvent;
 import ch.qos.logback.core.Appender;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicLong;
+import javax.servlet.http.HttpServletRequest;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -35,121 +42,118 @@
 import org.springframework.web.context.request.RequestContextHolder;
 import org.springframework.web.context.request.ServletRequestAttributes;
 
-import javax.servlet.http.HttpServletRequest;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicLong;
-
-import static com.epam.ta.reportportal.core.logging.HelperUtil.checkLoggingRecords;
-import static org.mockito.Mockito.when;
-
 @ExtendWith(MockitoExtension.class)
 class HttpLoggingAspectTest {
-	private static HelperController proxy;
 
-	private static HttpLoggingAspect aspect;
+  private static HelperController proxy;
+
+  private static HttpLoggingAspect aspect;
 
-	private static MockHttpServletRequest request;
+  private static MockHttpServletRequest request;
 
-	private static Map<Object, Object> payload;
+  private static Map<Object, Object> payload;
 
-	private static Logger logger;
+  private static Logger logger;
 
-	@Mock
-	private static Appender<ILoggingEvent> appender;
+  @Mock
+  private static Appender<ILoggingEvent> appender;
 
-	@Mock
-	private static HttpLogging annotation;
+  @Mock
+  private static HttpLogging annotation;
 
-	private static String requestLog;
+  private static String requestLog;
 
-	private static String responseLog;
+  private static String responseLog;
 
-	private static AtomicLong COUNT = new AtomicLong();
+  private static AtomicLong COUNT = new AtomicLong();
 
-	@BeforeAll
-	static void beforeAll() {
-		aspect = new HttpLoggingAspect();
-		ReflectionTestUtils.setField(aspect, "objectMapper", new ObjectMapper());
+  @BeforeAll
+  static void beforeAll() {
+    aspect = new HttpLoggingAspect();
+    ReflectionTestUtils.setField(aspect, "objectMapper", new ObjectMapper());
 
-		HelperController controller = new HelperController();
-		AspectJProxyFactory factory = new AspectJProxyFactory(controller);
-		factory.addAspect(aspect);
-		proxy = factory.getProxy();
+    HelperController controller = new HelperController();
+    AspectJProxyFactory factory = new AspectJProxyFactory(controller);
+    factory.addAspect(aspect);
+    proxy = factory.getProxy();
 
-		request = new MockHttpServletRequest("GET", "/request/path/is/here");
-		request.setQueryString("ddd=qwerty");
-		request.addHeader("Content-Type", "application/json");
-		request.addHeader("Host", "localhost");
-		RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request));
+    request = new MockHttpServletRequest("GET", "/request/path/is/here");
+    request.setQueryString("ddd=qwerty");
+    request.addHeader("Content-Type", "application/json");
+    request.addHeader("Host", "localhost");
+    RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request));
 
-		payload = new HashMap<>();
-		payload.put("key1", "one");
-		payload.put("key2", "two");
-		payload.put("key3", "three");
+    payload = new HashMap<>();
+    payload.put("key1", "one");
+    payload.put("key2", "two");
+    payload.put("key3", "three");
 
-		logger = (Logger) LoggerFactory.getLogger(HelperController.class);
-		logger.setLevel(Level.DEBUG);
-		logger.setAdditive(false);
-	}
+    logger = (Logger) LoggerFactory.getLogger(HelperController.class);
+    logger.setLevel(Level.DEBUG);
+    logger.setAdditive(false);
+  }
 
-	@BeforeEach
-	void setup() {
-		logger.detachAndStopAllAppenders();
-		logger.addAppender(appender);
-	}
+  @BeforeEach
+  void setup() {
+    logger.detachAndStopAllAppenders();
+    logger.addAppender(appender);
+  }
 
-	@Test
-	void testFull() throws Exception {
+  @Test
+  void testFull() throws Exception {
 
-		when(annotation.logHeaders()).thenReturn(true);
-		when(annotation.logRequestBody()).thenReturn(true);
-		when(annotation.logResponseBody()).thenReturn(true);
-		when(annotation.logExecutionTime()).thenReturn(false);
+    when(annotation.logHeaders()).thenReturn(true);
+    when(annotation.logRequestBody()).thenReturn(true);
+    when(annotation.logResponseBody()).thenReturn(true);
+    when(annotation.logExecutionTime()).thenReturn(false);
 
-		long count = COUNT.incrementAndGet();
-		ResponseEntity<Map<String, Object>> response = proxy.logFull(payload);
-		formatRequestResponseAndPrint(count, "logFull", request, response);
+    long count = COUNT.incrementAndGet();
+    ResponseEntity<Map<String, Object>> response = proxy.logFull(payload);
+    formatRequestResponseAndPrint(count, "logFull", request, response);
 
-		checkLoggingRecords(appender, 2, new Level[] { Level.DEBUG, Level.DEBUG }, requestLog, responseLog);
-	}
+    checkLoggingRecords(appender, 2, new Level[]{Level.DEBUG, Level.DEBUG}, requestLog,
+        responseLog);
+  }
 
-	@Test
-	void testWithoutHeaders() throws Exception {
+  @Test
+  void testWithoutHeaders() throws Exception {
 
-		when(annotation.logHeaders()).thenReturn(false);
-		when(annotation.logRequestBody()).thenReturn(true);
-		when(annotation.logResponseBody()).thenReturn(true);
-		when(annotation.logExecutionTime()).thenReturn(false);
+    when(annotation.logHeaders()).thenReturn(false);
+    when(annotation.logRequestBody()).thenReturn(true);
+    when(annotation.logResponseBody()).thenReturn(true);
+    when(annotation.logExecutionTime()).thenReturn(false);
 
-		long count = COUNT.incrementAndGet();
-		ResponseEntity<Map<String, Object>> response = proxy.logWithoutHeaders(payload);
-		formatRequestResponseAndPrint(count, "logWithoutHeaders", request, response);
+    long count = COUNT.incrementAndGet();
+    ResponseEntity<Map<String, Object>> response = proxy.logWithoutHeaders(payload);
+    formatRequestResponseAndPrint(count, "logWithoutHeaders", request, response);
 
-		checkLoggingRecords(appender, 2, new Level[] { Level.DEBUG, Level.DEBUG }, requestLog, responseLog);
-	}
+    checkLoggingRecords(appender, 2, new Level[]{Level.DEBUG, Level.DEBUG}, requestLog,
+        responseLog);
+  }
 
-	@Test
-	void testWithoutBody() throws Exception {
+  @Test
+  void testWithoutBody() throws Exception {
 
-		when(annotation.logHeaders()).thenReturn(true);
-		when(annotation.logRequestBody()).thenReturn(false);
-		when(annotation.logResponseBody()).thenReturn(false);
-		when(annotation.logExecutionTime()).thenReturn(false);
+    when(annotation.logHeaders()).thenReturn(true);
+    when(annotation.logRequestBody()).thenReturn(false);
+    when(annotation.logResponseBody()).thenReturn(false);
+    when(annotation.logExecutionTime()).thenReturn(false);
 
-		long count = COUNT.incrementAndGet();
-		ResponseEntity<Map<String, Object>> response = proxy.logWithoutBody(payload);
-		formatRequestResponseAndPrint(count, "logWithoutBody", request, response);
+    long count = COUNT.incrementAndGet();
+    ResponseEntity<Map<String, Object>> response = proxy.logWithoutBody(payload);
+    formatRequestResponseAndPrint(count, "logWithoutBody", request, response);
 
-		checkLoggingRecords(appender, 2, new Level[] { Level.DEBUG, Level.DEBUG }, requestLog, responseLog);
-	}
+    checkLoggingRecords(appender, 2, new Level[]{Level.DEBUG, Level.DEBUG}, requestLog,
+        responseLog);
+  }
 
-	private void formatRequestResponseAndPrint(long count, String prefix, HttpServletRequest request, ResponseEntity response)
-			throws Exception {
-		requestLog = aspect.formatRequestRecord(count, prefix, request, payload, annotation);
-		responseLog = aspect.formatResponseRecord(count, prefix, response, annotation, 0L);
-		System.out.println(requestLog);
-		System.out.println(responseLog);
-	}
+  private void formatRequestResponseAndPrint(long count, String prefix, HttpServletRequest request,
+      ResponseEntity response)
+      throws Exception {
+    requestLog = aspect.formatRequestRecord(count, prefix, request, payload, annotation);
+    responseLog = aspect.formatResponseRecord(count, prefix, response, annotation, 0L);
+    System.out.println(requestLog);
+    System.out.println(responseLog);
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/logging/RabbitMessageLoggingAspectTest.java b/src/test/java/com/epam/ta/reportportal/core/logging/RabbitMessageLoggingAspectTest.java
index 5b3e09be79..85e09069a6 100644
--- a/src/test/java/com/epam/ta/reportportal/core/logging/RabbitMessageLoggingAspectTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/logging/RabbitMessageLoggingAspectTest.java
@@ -16,11 +16,18 @@
 
 package com.epam.ta.reportportal.core.logging;
 
+import static com.epam.ta.reportportal.core.logging.HelperUtil.checkLoggingRecords;
+import static org.mockito.Mockito.when;
+
 import ch.qos.logback.classic.Level;
 import ch.qos.logback.classic.Logger;
 import ch.qos.logback.classic.spi.ILoggingEvent;
 import ch.qos.logback.core.Appender;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.UUID;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -35,122 +42,114 @@
 import org.springframework.aop.aspectj.annotation.AspectJProxyFactory;
 import org.springframework.test.util.ReflectionTestUtils;
 
-import java.util.HashMap;
-import java.util.Map;
-import java.util.TreeMap;
-import java.util.UUID;
-
-import static com.epam.ta.reportportal.core.logging.HelperUtil.checkLoggingRecords;
-import static org.mockito.Mockito.when;
-
 @ExtendWith(MockitoExtension.class)
 class RabbitMessageLoggingAspectTest {
 
-	private static HelperListener proxy;
+  private static HelperListener proxy;
 
-	private static RabbitMessageLoggingAspect aspect;
+  private static RabbitMessageLoggingAspect aspect;
 
-	private static Message message;
+  private static Message message;
 
-	private static Map<Object, Object> payload;
+  private static Map<Object, Object> payload;
 
-	private static Logger logger;
+  private static Logger logger;
 
-	@Mock
-	private static Appender<ILoggingEvent> appender;
+  @Mock
+  private static Appender<ILoggingEvent> appender;
 
-	@Mock
-	private static RabbitMessageLogging annotation;
+  @Mock
+  private static RabbitMessageLogging annotation;
 
-	private String log;
+  private String log;
 
-	private static ObjectMapper objectMapper;
+  private static ObjectMapper objectMapper;
 
-	private static MessageConverter messageConverter;
+  private static MessageConverter messageConverter;
 
-	private static Map<String, Object> headers;
+  private static Map<String, Object> headers;
 
-	@BeforeAll
-	static void beforeAll() throws Exception {
-		aspect = new RabbitMessageLoggingAspect();
+  @BeforeAll
+  static void beforeAll() throws Exception {
+    aspect = new RabbitMessageLoggingAspect();
 
-		objectMapper = new ObjectMapper();
-		messageConverter = new Jackson2JsonMessageConverter();
+    objectMapper = new ObjectMapper();
+    messageConverter = new Jackson2JsonMessageConverter();
 
-		ReflectionTestUtils.setField(aspect, "objectMapper", objectMapper);
-		ReflectionTestUtils.setField(aspect, "messageConverter", messageConverter);
+    ReflectionTestUtils.setField(aspect, "objectMapper", objectMapper);
+    ReflectionTestUtils.setField(aspect, "messageConverter", messageConverter);
 
-		HelperListener listener = new HelperListener();
-		AspectJProxyFactory factory = new AspectJProxyFactory(listener);
-		factory.addAspect(aspect);
-		proxy = factory.getProxy();
+    HelperListener listener = new HelperListener();
+    AspectJProxyFactory factory = new AspectJProxyFactory(listener);
+    factory.addAspect(aspect);
+    proxy = factory.getProxy();
 
-		payload = new HashMap<>();
-		payload.put("key1", "one");
-		payload.put("key2", "two");
-		payload.put("key3", "three");
+    payload = new HashMap<>();
+    payload.put("key1", "one");
+    payload.put("key2", "two");
+    payload.put("key3", "three");
 
-		headers = new TreeMap<>();
-		headers.put("header1", "one");
-		headers.put("header2", UUID.randomUUID());
-		headers.put("__ContentTypeId__", "java.lang.Object");
-		headers.put("__TypeId__", "java.util.HashMap");
-		headers.put("__KeyTypeId__", "java.lang.Object");
+    headers = new TreeMap<>();
+    headers.put("header1", "one");
+    headers.put("header2", UUID.randomUUID());
+    headers.put("__ContentTypeId__", "java.lang.Object");
+    headers.put("__TypeId__", "java.util.HashMap");
+    headers.put("__KeyTypeId__", "java.lang.Object");
 
-		MessagePropertiesBuilder properties = MessagePropertiesBuilder.newInstance();
-		for (Map.Entry<String, Object> entry : headers.entrySet()) {
-			properties.setHeader(entry.getKey(), entry.getValue());
-		}
-		message = messageConverter.toMessage(payload, properties.build());
+    MessagePropertiesBuilder properties = MessagePropertiesBuilder.newInstance();
+    for (Map.Entry<String, Object> entry : headers.entrySet()) {
+      properties.setHeader(entry.getKey(), entry.getValue());
+    }
+    message = messageConverter.toMessage(payload, properties.build());
 
-		logger = (Logger) LoggerFactory.getLogger(HelperListener.class);
-		logger.setLevel(Level.DEBUG);
-		logger.setAdditive(false);
-	}
+    logger = (Logger) LoggerFactory.getLogger(HelperListener.class);
+    logger.setLevel(Level.DEBUG);
+    logger.setAdditive(false);
+  }
 
-	@BeforeEach
-	void setup() {
-		logger.detachAndStopAllAppenders();
-		logger.addAppender(appender);
-	}
+  @BeforeEach
+  void setup() {
+    logger.detachAndStopAllAppenders();
+    logger.addAppender(appender);
+  }
 
-	@Test
-	void testMessageFull() throws Exception {
+  @Test
+  void testMessageFull() throws Exception {
 
-		when(annotation.logHeaders()).thenReturn(true);
-		when(annotation.logBody()).thenReturn(true);
+    when(annotation.logHeaders()).thenReturn(true);
+    when(annotation.logBody()).thenReturn(true);
 
-		proxy.onMessageFull(message);
-		log = aspect.formatMessageRecord("onMessageFull", headers, payload, annotation);
-		System.out.println(log);
+    proxy.onMessageFull(message);
+    log = aspect.formatMessageRecord("onMessageFull", headers, payload, annotation);
+    System.out.println(log);
 
-		checkLoggingRecords(appender, 1, new Level[] { Level.DEBUG }, log);
-	}
+    checkLoggingRecords(appender, 1, new Level[]{Level.DEBUG}, log);
+  }
 
-	@Test
-	void testMessageWithoutHeader() throws Exception {
+  @Test
+  void testMessageWithoutHeader() throws Exception {
 
-		when(annotation.logHeaders()).thenReturn(false);
-		when(annotation.logBody()).thenReturn(true);
+    when(annotation.logHeaders()).thenReturn(false);
+    when(annotation.logBody()).thenReturn(true);
 
-		proxy.onMessageWithoutHeaders(message);
-		log = aspect.formatMessageRecord("onMessageWithoutHeaders", headers, payload, annotation);
-		System.out.println(log);
+    proxy.onMessageWithoutHeaders(message);
+    log = aspect.formatMessageRecord("onMessageWithoutHeaders", headers, payload, annotation);
+    System.out.println(log);
 
-		checkLoggingRecords(appender, 1, new Level[] { Level.DEBUG }, log);
-	}
+    checkLoggingRecords(appender, 1, new Level[]{Level.DEBUG}, log);
+  }
 
-	@Test
-	void testMessageWithoutBody() throws Exception {
+  @Test
+  void testMessageWithoutBody() throws Exception {
 
-		when(annotation.logHeaders()).thenReturn(true);
-		when(annotation.logBody()).thenReturn(false);
+    when(annotation.logHeaders()).thenReturn(true);
+    when(annotation.logBody()).thenReturn(false);
 
-		proxy.onMessageWithoutBody(message);
-		log = aspect.formatMessageRecord("onMessageWithoutBody", headers, payload, annotation);
-		System.out.println(log);
+    proxy.onMessageWithoutBody(message);
+    log = aspect.formatMessageRecord("onMessageWithoutBody", headers, payload, annotation);
+    System.out.println(log);
 
-		checkLoggingRecords(appender, 1, new Level[] { Level.DEBUG }, log);
-	}
+    checkLoggingRecords(appender, 1, new Level[]{Level.DEBUG}, log);
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/project/config/ProjectConfigProviderTest.java b/src/test/java/com/epam/ta/reportportal/core/project/config/ProjectConfigProviderTest.java
index 0e61724e30..601e4a87c8 100644
--- a/src/test/java/com/epam/ta/reportportal/core/project/config/ProjectConfigProviderTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/project/config/ProjectConfigProviderTest.java
@@ -16,50 +16,49 @@
 
 package com.epam.ta.reportportal.core.project.config;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.core.project.GetProjectHandler;
 import com.epam.ta.reportportal.entity.attribute.Attribute;
 import com.epam.ta.reportportal.entity.project.Project;
 import com.epam.ta.reportportal.entity.project.ProjectAttribute;
-import org.junit.jupiter.api.Test;
-
 import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
 import java.util.stream.LongStream;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class ProjectConfigProviderTest {
 
-	private final GetProjectHandler getProjectHandler = mock(GetProjectHandler.class);
-	private final ProjectConfigProvider provider = new ProjectConfigProvider(getProjectHandler);
+  private final GetProjectHandler getProjectHandler = mock(GetProjectHandler.class);
+  private final ProjectConfigProvider provider = new ProjectConfigProvider(getProjectHandler);
 
-	@Test
-	void shouldReturnConfig() {
+  @Test
+  void shouldReturnConfig() {
 
-		final long projectId = 1L;
-		final Project project = new Project();
-		project.setId(projectId);
-		final Set<ProjectAttribute> projectAttributes = LongStream.range(1, 10).mapToObj(it -> {
-			final Attribute attribute = new Attribute(it, String.valueOf(it));
-			return new ProjectAttribute(attribute, "Value " + it, project);
-		}).collect(Collectors.toSet());
-		project.setProjectAttributes(projectAttributes);
+    final long projectId = 1L;
+    final Project project = new Project();
+    project.setId(projectId);
+    final Set<ProjectAttribute> projectAttributes = LongStream.range(1, 10).mapToObj(it -> {
+      final Attribute attribute = new Attribute(it, String.valueOf(it));
+      return new ProjectAttribute(attribute, "Value " + it, project);
+    }).collect(Collectors.toSet());
+    project.setProjectAttributes(projectAttributes);
 
-		when(getProjectHandler.get(projectId)).thenReturn(project);
+    when(getProjectHandler.get(projectId)).thenReturn(project);
 
-		final Map<String, String> attributesMapping = provider.provide(projectId);
+    final Map<String, String> attributesMapping = provider.provide(projectId);
 
-		assertEquals(projectAttributes.size(), attributesMapping.size());
-		projectAttributes.forEach(a -> {
-			final String value = attributesMapping.get(a.getAttribute().getName());
-			assertEquals(a.getValue(), value);
-		});
-	}
+    assertEquals(projectAttributes.size(), attributesMapping.size());
+    projectAttributes.forEach(a -> {
+      final String value = attributesMapping.get(a.getAttribute().getName());
+      assertEquals(a.getValue(), value);
+    });
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/project/impl/CreateProjectHandlerImplTest.java b/src/test/java/com/epam/ta/reportportal/core/project/impl/CreateProjectHandlerImplTest.java
index ce79e09b07..2dd97504e0 100644
--- a/src/test/java/com/epam/ta/reportportal/core/project/impl/CreateProjectHandlerImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/project/impl/CreateProjectHandlerImplTest.java
@@ -16,6 +16,11 @@
 
 package com.epam.ta.reportportal.core.project.impl;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.dao.ProjectRepository;
 import com.epam.ta.reportportal.dao.UserRepository;
@@ -23,64 +28,65 @@
 import com.epam.ta.reportportal.entity.user.UserRole;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.project.CreateProjectRQ;
+import java.util.Optional;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 
-import java.util.Optional;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.Mockito.when;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @ExtendWith(MockitoExtension.class)
 class CreateProjectHandlerImplTest {
 
-	@Mock
-	private ProjectRepository projectRepository;
+  @Mock
+  private ProjectRepository projectRepository;
 
-	@Mock
-	private UserRepository userRepository;
+  @Mock
+  private UserRepository userRepository;
 
-	@InjectMocks
-	private CreateProjectHandlerImpl handler;
+  @InjectMocks
+  private CreateProjectHandlerImpl handler;
 
-	@Test
-	void createProjectWithWrongType() {
-		ReportPortalUser rpUser = getRpUser("user", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
+  @Test
+  void createProjectWithWrongType() {
+    ReportPortalUser rpUser = getRpUser("user", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER,
+        1L);
 
-		CreateProjectRQ createProjectRQ = new CreateProjectRQ();
-		String projectName = "projectName";
-		createProjectRQ.setProjectName(projectName);
-		createProjectRQ.setEntryType("wrongType");
+    CreateProjectRQ createProjectRQ = new CreateProjectRQ();
+    String projectName = "projectName";
+    createProjectRQ.setProjectName(projectName);
+    createProjectRQ.setEntryType("wrongType");
 
-		when(projectRepository.findByName(projectName.toLowerCase().trim())).thenReturn(Optional.empty());
+    when(projectRepository.findByName(projectName.toLowerCase().trim())).thenReturn(
+        Optional.empty());
 
-		ReportPortalException exception = assertThrows(ReportPortalException.class, () -> handler.createProject(createProjectRQ, rpUser));
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.createProject(createProjectRQ, rpUser));
 
-		assertEquals("Error in handled Request. Please, check specified parameters: 'wrongType'", exception.getMessage());
-	}
+    assertEquals("Error in handled Request. Please, check specified parameters: 'wrongType'",
+        exception.getMessage());
+  }
 
-	@Test
-	void createProjectByNotExistUser() {
-		ReportPortalUser rpUser = getRpUser("user", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
+  @Test
+  void createProjectByNotExistUser() {
+    ReportPortalUser rpUser = getRpUser("user", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER,
+        1L);
 
-		CreateProjectRQ createProjectRQ = new CreateProjectRQ();
-		String projectName = "projectName";
-		createProjectRQ.setProjectName(projectName);
-		createProjectRQ.setEntryType("internal");
+    CreateProjectRQ createProjectRQ = new CreateProjectRQ();
+    String projectName = "projectName";
+    createProjectRQ.setProjectName(projectName);
+    createProjectRQ.setEntryType("internal");
 
-		when(projectRepository.findByName(projectName.toLowerCase().trim())).thenReturn(Optional.empty());
-		when(userRepository.findRawById(rpUser.getUserId())).thenReturn(Optional.empty());
+    when(projectRepository.findByName(projectName.toLowerCase().trim())).thenReturn(
+        Optional.empty());
+    when(userRepository.findRawById(rpUser.getUserId())).thenReturn(Optional.empty());
 
-		ReportPortalException exception = assertThrows(ReportPortalException.class, () -> handler.createProject(createProjectRQ, rpUser));
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.createProject(createProjectRQ, rpUser));
 
-		assertEquals("User 'user' not found.", exception.getMessage());
-	}
+    assertEquals("User 'user' not found.", exception.getMessage());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/project/impl/DeleteProjectHandlerImplTest.java b/src/test/java/com/epam/ta/reportportal/core/project/impl/DeleteProjectHandlerImplTest.java
index 8af4ab38d7..54ed8ef79c 100644
--- a/src/test/java/com/epam/ta/reportportal/core/project/impl/DeleteProjectHandlerImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/project/impl/DeleteProjectHandlerImplTest.java
@@ -24,6 +24,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import com.epam.ta.reportportal.binary.AttachmentBinaryDataService;
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.analyzer.auto.LogIndexer;
 import com.epam.ta.reportportal.core.analyzer.auto.client.AnalyzerServiceClient;
@@ -67,9 +68,6 @@ class DeleteProjectHandlerImplTest {
 	@Mock
 	private UserRepository userRepository;
 
-	@Mock
-	private AttachmentRepository attachmentRepository;
-
 	@Mock
 	private LogIndexer logIndexer;
 
@@ -91,6 +89,9 @@ class DeleteProjectHandlerImplTest {
 	@Mock
 	private LogRepository logRepository;
 
+	@Mock
+	private AttachmentBinaryDataService attachmentBinaryDataService;
+
 	@InjectMocks
 	private DeleteProjectHandlerImpl handler;
 
diff --git a/src/test/java/com/epam/ta/reportportal/core/project/impl/ProjectInfoWidgetDataConverterTest.java b/src/test/java/com/epam/ta/reportportal/core/project/impl/ProjectInfoWidgetDataConverterTest.java
index 0a2191c967..71e7b91f3b 100644
--- a/src/test/java/com/epam/ta/reportportal/core/project/impl/ProjectInfoWidgetDataConverterTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/project/impl/ProjectInfoWidgetDataConverterTest.java
@@ -16,6 +16,16 @@
 
 package com.epam.ta.reportportal.core.project.impl;
 
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DEFECTS_AUTOMATION_BUG_TOTAL;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DEFECTS_PRODUCT_BUG_TOTAL;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DEFECTS_SYSTEM_ISSUE_TOTAL;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.DEFECTS_TO_INVESTIGATE_TOTAL;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.EXECUTIONS_FAILED;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.EXECUTIONS_PASSED;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.EXECUTIONS_SKIPPED;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.EXECUTIONS_TOTAL;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
 import com.epam.ta.reportportal.entity.enums.InfoInterval;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.entity.statistics.Statistics;
@@ -23,10 +33,11 @@
 import com.epam.ta.reportportal.ws.model.widget.ChartObject;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Sets;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import java.time.*;
+import java.time.DayOfWeek;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.ZoneOffset;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
 import java.time.temporal.IsoFields;
@@ -34,164 +45,185 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
-
-import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.*;
-import static org.junit.jupiter.api.Assertions.assertEquals;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 class ProjectInfoWidgetDataConverterTest {
 
-	private ProjectInfoWidgetDataConverter converter;
-
-	private String thisWeekFormattedDate;
-
-	private LocalDate today;
-	private LocalDate yesterday;
-
-	private String todayString;
-	private String yesterdayString;
-
-	@BeforeEach
-	void setUp() {
-		converter = new ProjectInfoWidgetDataConverter(ImmutableMap.<InfoInterval, ProjectInfoWidgetDataConverter.ProjectInfoGroup>builder()
-				.put(InfoInterval.ONE_MONTH, ProjectInfoWidgetDataConverter.ProjectInfoGroup.BY_DAY)
-				.put(InfoInterval.THREE_MONTHS, ProjectInfoWidgetDataConverter.ProjectInfoGroup.BY_WEEK)
-				.put(InfoInterval.SIX_MONTHS, ProjectInfoWidgetDataConverter.ProjectInfoGroup.BY_WEEK)
-				.build());
-
-		thisWeekFormattedDate = LocalDate.now(ZoneOffset.UTC)
-				.format(new DateTimeFormatterBuilder().appendValue(IsoFields.WEEK_BASED_YEAR, 4)
-						.appendLiteral("-W")
-						.appendValue(IsoFields.WEEK_OF_WEEK_BASED_YEAR, 2)
-						.toFormatter());
-
-		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
-
-		LocalDate now = LocalDate.now(ZoneOffset.UTC);
-		today = now.getDayOfWeek().equals(DayOfWeek.MONDAY) ? now.plusDays(2) : now;
-		yesterday = today.minusDays(1);
-
-		todayString = today.format(formatter);
-		yesterdayString = yesterday.format(formatter);
-	}
-
-	@Test
-	void getInvestigatedProjectInfo() {
-		Map<String, List<ChartObject>> investigatedProjectInfo = converter.getInvestigatedProjectInfo(getTestData(),
-				InfoInterval.ONE_MONTH
-		);
-
-		assertEquals("33.33", investigatedProjectInfo.get(yesterdayString).get(0).getValues().get("toInvestigate"));
-		assertEquals("66.67", investigatedProjectInfo.get(yesterdayString).get(0).getValues().get("investigated"));
-
-		assertEquals("38.46", investigatedProjectInfo.get(todayString).get(0).getValues().get("toInvestigate"));
-		assertEquals("61.54", investigatedProjectInfo.get(todayString).get(0).getValues().get("investigated"));
-	}
-
-	@Test
-	void getInvestigatedProjectInfoWithoutDefectsStatistics() {
-		Launch launch = new Launch();
-		launch.setName("test_launch");
-		launch.setId(1L);
-		launch.setNumber(1L);
-		launch.setStartTime(LocalDateTime.now(ZoneOffset.UTC));
-		launch.setStatistics(Sets.newHashSet(getStatistics(EXECUTIONS_TOTAL, 5), getStatistics(EXECUTIONS_PASSED, 5)));
-
-		Map<String, List<ChartObject>> investigatedProjectInfo = converter.getInvestigatedProjectInfo(Collections.singletonList(launch),
-				InfoInterval.THREE_MONTHS
-		);
-
-		assertEquals("0", investigatedProjectInfo.get(thisWeekFormattedDate).get(0).getValues().get("toInvestigate"));
-		assertEquals("0", investigatedProjectInfo.get(thisWeekFormattedDate).get(0).getValues().get("investigated"));
-	}
-
-	@Test
-	void getTestCasesStatisticsProjectInfo() {
-		Map<String, List<ChartObject>> testCasesStatisticsProjectInfo = converter.getTestCasesStatisticsProjectInfo(getTestData());
-
-		assertEquals("18.0", testCasesStatisticsProjectInfo.get("test_launch").get(0).getValues().get("min"));
-		assertEquals("19.5", testCasesStatisticsProjectInfo.get("test_launch").get(0).getValues().get("avg"));
-		assertEquals("21.0", testCasesStatisticsProjectInfo.get("test_launch").get(0).getValues().get("max"));
-	}
-
-	@Test
-	void getLaunchesQuantity() {
-		Map<String, List<ChartObject>> launchesQuantity = converter.getLaunchesQuantity(getTestData(), InfoInterval.ONE_MONTH);
-
-		assertEquals("1", launchesQuantity.get(yesterdayString).get(0).getValues().get("count"));
-		assertEquals("1", launchesQuantity.get(todayString).get(0).getValues().get("count"));
-	}
-
-	@Test
-	void getLaunchesQuantityByWeek() {
-		Map<String, List<ChartObject>> launchesQuantity = converter.getLaunchesQuantity(getTestData(), InfoInterval.THREE_MONTHS);
-
-		assertEquals("2", launchesQuantity.get(thisWeekFormattedDate).get(0).getValues().get("count"));
-	}
-
-	@Test
-	void getLaunchesIssues() {
-		Map<String, List<ChartObject>> launchesIssues = converter.getLaunchesIssues(getTestData(), InfoInterval.ONE_MONTH);
-
-		assertEquals("3", launchesIssues.get(yesterdayString).get(0).getValues().get("systemIssue"));
-		assertEquals("4", launchesIssues.get(yesterdayString).get(0).getValues().get("toInvestigate"));
-		assertEquals("2", launchesIssues.get(yesterdayString).get(0).getValues().get("productBug"));
-		assertEquals("3", launchesIssues.get(yesterdayString).get(0).getValues().get("automationBug"));
-
-		assertEquals("3", launchesIssues.get(todayString).get(0).getValues().get("systemIssue"));
-		assertEquals("5", launchesIssues.get(todayString).get(0).getValues().get("toInvestigate"));
-		assertEquals("1", launchesIssues.get(todayString).get(0).getValues().get("productBug"));
-		assertEquals("4", launchesIssues.get(todayString).get(0).getValues().get("automationBug"));
-	}
-
-	@Test
-	void getLaunchesIssuesByWeek() {
-		Map<String, List<ChartObject>> launchesIssues = converter.getLaunchesIssues(getTestData(), InfoInterval.THREE_MONTHS);
-
-		assertEquals("6", launchesIssues.get(thisWeekFormattedDate).get(0).getValues().get("systemIssue"));
-		assertEquals("9", launchesIssues.get(thisWeekFormattedDate).get(0).getValues().get("toInvestigate"));
-		assertEquals("3", launchesIssues.get(thisWeekFormattedDate).get(0).getValues().get("productBug"));
-		assertEquals("7", launchesIssues.get(thisWeekFormattedDate).get(0).getValues().get("automationBug"));
-	}
-
-	private List<Launch> getTestData() {
-		Launch launch1 = new Launch();
-		launch1.setName("test_launch");
-		launch1.setId(1L);
-		launch1.setNumber(1L);
-		launch1.setStartTime(LocalDateTime.of(yesterday, LocalTime.now(ZoneOffset.UTC)));
-		launch1.setStatistics(Sets.newHashSet(getStatistics(EXECUTIONS_TOTAL, 18),
-				getStatistics(EXECUTIONS_PASSED, 5),
-				getStatistics(EXECUTIONS_SKIPPED, 1),
-				getStatistics(EXECUTIONS_FAILED, 12),
-				getStatistics(DEFECTS_AUTOMATION_BUG_TOTAL, 3),
-				getStatistics(DEFECTS_PRODUCT_BUG_TOTAL, 2),
-				getStatistics(DEFECTS_SYSTEM_ISSUE_TOTAL, 3),
-				getStatistics(DEFECTS_TO_INVESTIGATE_TOTAL, 4)
-		));
-		Launch launch2 = new Launch();
-		launch2.setName("test_launch");
-		launch2.setId(2L);
-		launch2.setNumber(2L);
-		launch2.setStartTime(LocalDateTime.of(today, LocalTime.now(ZoneOffset.UTC)));
-		launch2.setStatistics(Sets.newHashSet(getStatistics(EXECUTIONS_TOTAL, 21),
-				getStatistics(EXECUTIONS_PASSED, 6),
-				getStatistics(EXECUTIONS_SKIPPED, 2),
-				getStatistics(EXECUTIONS_FAILED, 13),
-				getStatistics(DEFECTS_AUTOMATION_BUG_TOTAL, 4),
-				getStatistics(DEFECTS_PRODUCT_BUG_TOTAL, 1),
-				getStatistics(DEFECTS_SYSTEM_ISSUE_TOTAL, 3),
-				getStatistics(DEFECTS_TO_INVESTIGATE_TOTAL, 5)
-		));
-		return Arrays.asList(launch1, launch2);
-	}
-
-	private Statistics getStatistics(String statisticsFieldName, int counter) {
-		Statistics statistics = new Statistics();
-		statistics.setStatisticsField(new StatisticsField(statisticsFieldName));
-		statistics.setCounter(counter);
-		return statistics;
-	}
+  private ProjectInfoWidgetDataConverter converter;
+
+  private String thisWeekFormattedDate;
+
+  private LocalDate today;
+  private LocalDate yesterday;
+
+  private String todayString;
+  private String yesterdayString;
+
+  @BeforeEach
+  void setUp() {
+    converter = new ProjectInfoWidgetDataConverter(
+        ImmutableMap.<InfoInterval, ProjectInfoWidgetDataConverter.ProjectInfoGroup>builder()
+            .put(InfoInterval.ONE_MONTH, ProjectInfoWidgetDataConverter.ProjectInfoGroup.BY_DAY)
+            .put(InfoInterval.THREE_MONTHS, ProjectInfoWidgetDataConverter.ProjectInfoGroup.BY_WEEK)
+            .put(InfoInterval.SIX_MONTHS, ProjectInfoWidgetDataConverter.ProjectInfoGroup.BY_WEEK)
+            .build());
+
+    thisWeekFormattedDate = LocalDate.now(ZoneOffset.UTC)
+        .format(new DateTimeFormatterBuilder().appendValue(IsoFields.WEEK_BASED_YEAR, 4)
+            .appendLiteral("-W")
+            .appendValue(IsoFields.WEEK_OF_WEEK_BASED_YEAR, 2)
+            .toFormatter());
+
+    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+
+    LocalDate now = LocalDate.now(ZoneOffset.UTC);
+    today = now.getDayOfWeek().equals(DayOfWeek.MONDAY) ? now.plusDays(2) : now;
+    yesterday = today.minusDays(1);
+
+    todayString = today.format(formatter);
+    yesterdayString = yesterday.format(formatter);
+  }
+
+  @Test
+  void getInvestigatedProjectInfo() {
+    Map<String, List<ChartObject>> investigatedProjectInfo = converter.getInvestigatedProjectInfo(
+        getTestData(),
+        InfoInterval.ONE_MONTH
+    );
+
+    assertEquals("33.33",
+        investigatedProjectInfo.get(yesterdayString).get(0).getValues().get("toInvestigate"));
+    assertEquals("66.67",
+        investigatedProjectInfo.get(yesterdayString).get(0).getValues().get("investigated"));
+
+    assertEquals("38.46",
+        investigatedProjectInfo.get(todayString).get(0).getValues().get("toInvestigate"));
+    assertEquals("61.54",
+        investigatedProjectInfo.get(todayString).get(0).getValues().get("investigated"));
+  }
+
+  @Test
+  void getInvestigatedProjectInfoWithoutDefectsStatistics() {
+    Launch launch = new Launch();
+    launch.setName("test_launch");
+    launch.setId(1L);
+    launch.setNumber(1L);
+    launch.setStartTime(LocalDateTime.now(ZoneOffset.UTC));
+    launch.setStatistics(
+        Sets.newHashSet(getStatistics(EXECUTIONS_TOTAL, 5), getStatistics(EXECUTIONS_PASSED, 5)));
+
+    Map<String, List<ChartObject>> investigatedProjectInfo = converter.getInvestigatedProjectInfo(
+        Collections.singletonList(launch),
+        InfoInterval.THREE_MONTHS
+    );
+
+    assertEquals("0",
+        investigatedProjectInfo.get(thisWeekFormattedDate).get(0).getValues().get("toInvestigate"));
+    assertEquals("0",
+        investigatedProjectInfo.get(thisWeekFormattedDate).get(0).getValues().get("investigated"));
+  }
+
+  @Test
+  void getTestCasesStatisticsProjectInfo() {
+    Map<String, List<ChartObject>> testCasesStatisticsProjectInfo = converter.getTestCasesStatisticsProjectInfo(
+        getTestData());
+
+    assertEquals("18.0",
+        testCasesStatisticsProjectInfo.get("test_launch").get(0).getValues().get("min"));
+    assertEquals("19.5",
+        testCasesStatisticsProjectInfo.get("test_launch").get(0).getValues().get("avg"));
+    assertEquals("21.0",
+        testCasesStatisticsProjectInfo.get("test_launch").get(0).getValues().get("max"));
+  }
+
+  @Test
+  void getLaunchesQuantity() {
+    Map<String, List<ChartObject>> launchesQuantity = converter.getLaunchesQuantity(getTestData(),
+        InfoInterval.ONE_MONTH);
+
+    assertEquals("1", launchesQuantity.get(yesterdayString).get(0).getValues().get("count"));
+    assertEquals("1", launchesQuantity.get(todayString).get(0).getValues().get("count"));
+  }
+
+  @Test
+  void getLaunchesQuantityByWeek() {
+    Map<String, List<ChartObject>> launchesQuantity = converter.getLaunchesQuantity(getTestData(),
+        InfoInterval.THREE_MONTHS);
+
+    assertEquals("2", launchesQuantity.get(thisWeekFormattedDate).get(0).getValues().get("count"));
+  }
+
+  @Test
+  void getLaunchesIssues() {
+    Map<String, List<ChartObject>> launchesIssues = converter.getLaunchesIssues(getTestData(),
+        InfoInterval.ONE_MONTH);
+
+    assertEquals("3", launchesIssues.get(yesterdayString).get(0).getValues().get("systemIssue"));
+    assertEquals("4", launchesIssues.get(yesterdayString).get(0).getValues().get("toInvestigate"));
+    assertEquals("2", launchesIssues.get(yesterdayString).get(0).getValues().get("productBug"));
+    assertEquals("3", launchesIssues.get(yesterdayString).get(0).getValues().get("automationBug"));
+
+    assertEquals("3", launchesIssues.get(todayString).get(0).getValues().get("systemIssue"));
+    assertEquals("5", launchesIssues.get(todayString).get(0).getValues().get("toInvestigate"));
+    assertEquals("1", launchesIssues.get(todayString).get(0).getValues().get("productBug"));
+    assertEquals("4", launchesIssues.get(todayString).get(0).getValues().get("automationBug"));
+  }
+
+  @Test
+  void getLaunchesIssuesByWeek() {
+    Map<String, List<ChartObject>> launchesIssues = converter.getLaunchesIssues(getTestData(),
+        InfoInterval.THREE_MONTHS);
+
+    assertEquals("6",
+        launchesIssues.get(thisWeekFormattedDate).get(0).getValues().get("systemIssue"));
+    assertEquals("9",
+        launchesIssues.get(thisWeekFormattedDate).get(0).getValues().get("toInvestigate"));
+    assertEquals("3",
+        launchesIssues.get(thisWeekFormattedDate).get(0).getValues().get("productBug"));
+    assertEquals("7",
+        launchesIssues.get(thisWeekFormattedDate).get(0).getValues().get("automationBug"));
+  }
+
+  private List<Launch> getTestData() {
+    Launch launch1 = new Launch();
+    launch1.setName("test_launch");
+    launch1.setId(1L);
+    launch1.setNumber(1L);
+    launch1.setStartTime(LocalDateTime.of(yesterday, LocalTime.now(ZoneOffset.UTC)));
+    launch1.setStatistics(Sets.newHashSet(getStatistics(EXECUTIONS_TOTAL, 18),
+        getStatistics(EXECUTIONS_PASSED, 5),
+        getStatistics(EXECUTIONS_SKIPPED, 1),
+        getStatistics(EXECUTIONS_FAILED, 12),
+        getStatistics(DEFECTS_AUTOMATION_BUG_TOTAL, 3),
+        getStatistics(DEFECTS_PRODUCT_BUG_TOTAL, 2),
+        getStatistics(DEFECTS_SYSTEM_ISSUE_TOTAL, 3),
+        getStatistics(DEFECTS_TO_INVESTIGATE_TOTAL, 4)
+    ));
+    Launch launch2 = new Launch();
+    launch2.setName("test_launch");
+    launch2.setId(2L);
+    launch2.setNumber(2L);
+    launch2.setStartTime(LocalDateTime.of(today, LocalTime.now(ZoneOffset.UTC)));
+    launch2.setStatistics(Sets.newHashSet(getStatistics(EXECUTIONS_TOTAL, 21),
+        getStatistics(EXECUTIONS_PASSED, 6),
+        getStatistics(EXECUTIONS_SKIPPED, 2),
+        getStatistics(EXECUTIONS_FAILED, 13),
+        getStatistics(DEFECTS_AUTOMATION_BUG_TOTAL, 4),
+        getStatistics(DEFECTS_PRODUCT_BUG_TOTAL, 1),
+        getStatistics(DEFECTS_SYSTEM_ISSUE_TOTAL, 3),
+        getStatistics(DEFECTS_TO_INVESTIGATE_TOTAL, 5)
+    ));
+    return Arrays.asList(launch1, launch2);
+  }
+
+  private Statistics getStatistics(String statisticsFieldName, int counter) {
+    Statistics statistics = new Statistics();
+    statistics.setStatisticsField(new StatisticsField(statisticsFieldName));
+    statistics.setCounter(counter);
+    return statistics;
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/project/settings/impl/CreateProjectSettingsHandlerImplTest.java b/src/test/java/com/epam/ta/reportportal/core/project/settings/impl/CreateProjectSettingsHandlerImplTest.java
index 47e24bb867..efa9b5b70c 100644
--- a/src/test/java/com/epam/ta/reportportal/core/project/settings/impl/CreateProjectSettingsHandlerImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/project/settings/impl/CreateProjectSettingsHandlerImplTest.java
@@ -1,121 +1,127 @@
-/*
- * Copyright 2019 EPAM Systems
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.epam.ta.reportportal.core.project.settings.impl;
-
-import com.epam.ta.reportportal.commons.ReportPortalUser;
-import com.epam.ta.reportportal.dao.ProjectRepository;
-import com.epam.ta.reportportal.entity.enums.TestItemIssueGroup;
-import com.epam.ta.reportportal.entity.item.issue.IssueGroup;
-import com.epam.ta.reportportal.entity.item.issue.IssueType;
-import com.epam.ta.reportportal.entity.project.Project;
-import com.epam.ta.reportportal.entity.project.ProjectIssueType;
-import com.epam.ta.reportportal.entity.project.ProjectRole;
-import com.epam.ta.reportportal.entity.user.UserRole;
-import com.epam.ta.reportportal.exception.ReportPortalException;
-import com.epam.ta.reportportal.ws.model.project.config.CreateIssueSubTypeRQ;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-
-import java.util.HashSet;
-import java.util.Optional;
-import java.util.Set;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.TEST_PROJECT_NAME;
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.Mockito.when;
-
-/**
- * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
- */
-@ExtendWith(MockitoExtension.class)
-class CreateProjectSettingsHandlerImplTest {
-
-	@Mock
-	private ProjectRepository projectRepository;
-
-	@InjectMocks
-	private CreateProjectSettingsHandlerImpl handler;
-
-	@Test
-	void createSubtypeOnNotExistProject() {
-		long projectId = 1L;
-		ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER, projectId);
-
-		when(projectRepository.findByName(TEST_PROJECT_NAME)).thenReturn(Optional.empty());
-
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.createProjectIssueSubType(TEST_PROJECT_NAME, user, new CreateIssueSubTypeRQ())
-		);
-
-		assertEquals("Project 'test_project' not found. Did you use correct project name?", exception.getMessage());
-	}
-
-	@Test
-	void createSubtypeWithWrongGroup() {
-		long projectId = 1L;
-		ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER, projectId);
-
-		when(projectRepository.findByName(TEST_PROJECT_NAME)).thenReturn(Optional.of(new Project()));
-
-		CreateIssueSubTypeRQ createIssueSubTypeRQ = new CreateIssueSubTypeRQ();
-		createIssueSubTypeRQ.setTypeRef("wrongType");
-
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.createProjectIssueSubType(TEST_PROJECT_NAME, user, createIssueSubTypeRQ)
-		);
-
-		assertEquals("Error in handled Request. Please, check specified parameters: 'wrongType'", exception.getMessage());
-	}
-
-	@Test
-	void maxSubtypesCount() {
-		Project project = new Project();
-		project.setProjectIssueTypes(getSubTypes());
-
-		long projectId = 1L;
-		ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER, projectId);
-
-		when(projectRepository.findByName(TEST_PROJECT_NAME)).thenReturn(Optional.of(project));
-
-		CreateIssueSubTypeRQ createIssueSubTypeRQ = new CreateIssueSubTypeRQ();
-		createIssueSubTypeRQ.setTypeRef("product_bug");
-
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.createProjectIssueSubType(TEST_PROJECT_NAME, user, createIssueSubTypeRQ)
-		);
-
-		assertEquals("Incorrect Request. Sub Issues count is bound of size limit", exception.getMessage());
-	}
-
-	private Set<ProjectIssueType> getSubTypes() {
-		HashSet<ProjectIssueType> subTypes = new HashSet<>();
-		for (int i = 1; i < 16; i++) {
-			IssueType issueType = new IssueType();
-			issueType.setId((long) i);
-			issueType.setIssueGroup(new IssueGroup(TestItemIssueGroup.PRODUCT_BUG));
-			ProjectIssueType projectIssueType = new ProjectIssueType();
-			projectIssueType.setIssueType(issueType);
-			subTypes.add(projectIssueType);
-		}
-		return subTypes;
-	}
+/*
+ * Copyright 2019 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.core.project.settings.impl;
+
+import static com.epam.ta.reportportal.ReportPortalUserUtil.TEST_PROJECT_NAME;
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.when;
+
+import com.epam.ta.reportportal.commons.ReportPortalUser;
+import com.epam.ta.reportportal.dao.ProjectRepository;
+import com.epam.ta.reportportal.entity.enums.TestItemIssueGroup;
+import com.epam.ta.reportportal.entity.item.issue.IssueGroup;
+import com.epam.ta.reportportal.entity.item.issue.IssueType;
+import com.epam.ta.reportportal.entity.project.Project;
+import com.epam.ta.reportportal.entity.project.ProjectIssueType;
+import com.epam.ta.reportportal.entity.project.ProjectRole;
+import com.epam.ta.reportportal.entity.user.UserRole;
+import com.epam.ta.reportportal.exception.ReportPortalException;
+import com.epam.ta.reportportal.ws.model.ValidationConstraints;
+import com.epam.ta.reportportal.ws.model.project.config.CreateIssueSubTypeRQ;
+import java.util.HashSet;
+import java.util.Optional;
+import java.util.Set;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+/**
+ * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
+ */
+@ExtendWith(MockitoExtension.class)
+class CreateProjectSettingsHandlerImplTest {
+
+  @Mock
+  private ProjectRepository projectRepository;
+
+  @InjectMocks
+  private CreateProjectSettingsHandlerImpl handler;
+
+  @Test
+  void createSubtypeOnNotExistProject() {
+    long projectId = 1L;
+    ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER,
+        projectId);
+
+    when(projectRepository.findByName(TEST_PROJECT_NAME)).thenReturn(Optional.empty());
+
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.createProjectIssueSubType(TEST_PROJECT_NAME, user, new CreateIssueSubTypeRQ())
+    );
+
+    assertEquals("Project 'test_project' not found. Did you use correct project name?",
+        exception.getMessage());
+  }
+
+  @Test
+  void createSubtypeWithWrongGroup() {
+    long projectId = 1L;
+    ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER,
+        projectId);
+
+    when(projectRepository.findByName(TEST_PROJECT_NAME)).thenReturn(Optional.of(new Project()));
+
+    CreateIssueSubTypeRQ createIssueSubTypeRQ = new CreateIssueSubTypeRQ();
+    createIssueSubTypeRQ.setTypeRef("wrongType");
+
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.createProjectIssueSubType(TEST_PROJECT_NAME, user, createIssueSubTypeRQ)
+    );
+
+    assertEquals("Error in handled Request. Please, check specified parameters: 'wrongType'",
+        exception.getMessage());
+  }
+
+  @Test
+  void maxSubtypesCount() {
+    Project project = new Project();
+    project.setProjectIssueTypes(getSubTypes());
+
+    long projectId = 1L;
+    ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER,
+        projectId);
+
+    when(projectRepository.findByName(TEST_PROJECT_NAME)).thenReturn(Optional.of(project));
+
+    CreateIssueSubTypeRQ createIssueSubTypeRQ = new CreateIssueSubTypeRQ();
+    createIssueSubTypeRQ.setTypeRef("product_bug");
+
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.createProjectIssueSubType(TEST_PROJECT_NAME, user, createIssueSubTypeRQ)
+    );
+
+    assertEquals("Incorrect Request. Sub Issues count is bound of size limit",
+        exception.getMessage());
+  }
+
+  private Set<ProjectIssueType> getSubTypes() {
+    HashSet<ProjectIssueType> subTypes = new HashSet<>();
+    for (int i = 1; i < ValidationConstraints.MAX_ISSUE_TYPES_AND_SUBTYPES + 1; i++) {
+      IssueType issueType = new IssueType();
+      issueType.setId((long) i);
+      issueType.setIssueGroup(new IssueGroup(TestItemIssueGroup.PRODUCT_BUG));
+      ProjectIssueType projectIssueType = new ProjectIssueType();
+      projectIssueType.setIssueType(issueType);
+      subTypes.add(projectIssueType);
+    }
+    return subTypes;
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/project/settings/impl/DeleteProjectSettingsHandlerImplTest.java b/src/test/java/com/epam/ta/reportportal/core/project/settings/impl/DeleteProjectSettingsHandlerImplTest.java
index 3a317a1ab9..1a1b02a4bc 100644
--- a/src/test/java/com/epam/ta/reportportal/core/project/settings/impl/DeleteProjectSettingsHandlerImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/project/settings/impl/DeleteProjectSettingsHandlerImplTest.java
@@ -16,64 +16,66 @@
 
 package com.epam.ta.reportportal.core.project.settings.impl;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.TEST_PROJECT_NAME;
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.dao.ProjectRepository;
 import com.epam.ta.reportportal.entity.project.Project;
 import com.epam.ta.reportportal.entity.project.ProjectRole;
 import com.epam.ta.reportportal.entity.user.UserRole;
 import com.epam.ta.reportportal.exception.ReportPortalException;
+import java.util.Optional;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 
-import java.util.Optional;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.TEST_PROJECT_NAME;
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.Mockito.when;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @ExtendWith(MockitoExtension.class)
 class DeleteProjectSettingsHandlerImplTest {
 
-	@Mock
-	private ProjectRepository projectRepository;
+  @Mock
+  private ProjectRepository projectRepository;
 
-	@InjectMocks
-	private DeleteProjectSettingsHandlerImpl handler;
+  @InjectMocks
+  private DeleteProjectSettingsHandlerImpl handler;
 
-	@Test
-	void deleteSubtypeOnNotExistProject() {
-		long projectId = 1L;
-		ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER, projectId);
+  @Test
+  void deleteSubtypeOnNotExistProject() {
+    long projectId = 1L;
+    ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER,
+        projectId);
 
-		when(projectRepository.findByName(TEST_PROJECT_NAME)).thenReturn(Optional.empty());
+    when(projectRepository.findByName(TEST_PROJECT_NAME)).thenReturn(Optional.empty());
 
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.deleteProjectIssueSubType(TEST_PROJECT_NAME, user, 1L)
-		);
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.deleteProjectIssueSubType(TEST_PROJECT_NAME, user, 1L)
+    );
 
-		assertEquals("Project 'test_project' not found. Did you use correct project name?", exception.getMessage());
-	}
+    assertEquals("Project 'test_project' not found. Did you use correct project name?",
+        exception.getMessage());
+  }
 
-	@Test
-	void deleteNotExistSubtype() {
-		long projectId = 1L;
-		ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER, projectId);
+  @Test
+  void deleteNotExistSubtype() {
+    long projectId = 1L;
+    ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER,
+        projectId);
 
-		when(projectRepository.findByName(TEST_PROJECT_NAME)).thenReturn(Optional.of(new Project()));
+    when(projectRepository.findByName(TEST_PROJECT_NAME)).thenReturn(Optional.of(new Project()));
 
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.deleteProjectIssueSubType(TEST_PROJECT_NAME, user, 1L)
-		);
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.deleteProjectIssueSubType(TEST_PROJECT_NAME, user, 1L)
+    );
 
-		assertEquals("Issue Type '1' not found.", exception.getMessage());
-	}
+    assertEquals("Issue Type '1' not found.", exception.getMessage());
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/project/settings/impl/GetProjectSettingsHandlerImplTest.java b/src/test/java/com/epam/ta/reportportal/core/project/settings/impl/GetProjectSettingsHandlerImplTest.java
index 7d06b5312a..8ad3cb5261 100644
--- a/src/test/java/com/epam/ta/reportportal/core/project/settings/impl/GetProjectSettingsHandlerImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/project/settings/impl/GetProjectSettingsHandlerImplTest.java
@@ -16,44 +16,41 @@
 
 package com.epam.ta.reportportal.core.project.settings.impl;
 
-import com.epam.ta.reportportal.commons.ReportPortalUser;
+import static com.epam.ta.reportportal.ReportPortalUserUtil.TEST_PROJECT_NAME;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.dao.ProjectRepository;
-import com.epam.ta.reportportal.entity.project.ProjectRole;
-import com.epam.ta.reportportal.entity.user.UserRole;
 import com.epam.ta.reportportal.exception.ReportPortalException;
+import java.util.Optional;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 
-import java.util.Optional;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.TEST_PROJECT_NAME;
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.Mockito.when;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @ExtendWith(MockitoExtension.class)
 class GetProjectSettingsHandlerImplTest {
 
-	@Mock
-	private ProjectRepository repository;
+  @Mock
+  private ProjectRepository repository;
 
-	@InjectMocks
-	private GetProjectSettingsHandlerImpl handler;
+  @InjectMocks
+  private GetProjectSettingsHandlerImpl handler;
 
-	@Test
-	void getProjectSettingOnNotExistProject() {
+  @Test
+  void getProjectSettingOnNotExistProject() {
 
-		when(repository.findByName(TEST_PROJECT_NAME)).thenReturn(Optional.empty());
+    when(repository.findByName(TEST_PROJECT_NAME)).thenReturn(Optional.empty());
 
-		ReportPortalException exception = assertThrows(ReportPortalException.class, () -> handler.getProjectSettings(TEST_PROJECT_NAME));
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.getProjectSettings(TEST_PROJECT_NAME));
 
-		assertEquals("Project 'test_project' not found. Did you use correct project name?", exception.getMessage());
-	}
+    assertEquals("Project 'test_project' not found. Did you use correct project name?",
+        exception.getMessage());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/project/settings/impl/UpdateProjectSettingsHandlerImplTest.java b/src/test/java/com/epam/ta/reportportal/core/project/settings/impl/UpdateProjectSettingsHandlerImplTest.java
index d674ad2094..1fc6cc5d61 100644
--- a/src/test/java/com/epam/ta/reportportal/core/project/settings/impl/UpdateProjectSettingsHandlerImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/project/settings/impl/UpdateProjectSettingsHandlerImplTest.java
@@ -16,6 +16,12 @@
 
 package com.epam.ta.reportportal.core.project.settings.impl;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.TEST_PROJECT_NAME;
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.dao.ProjectRepository;
 import com.epam.ta.reportportal.entity.project.Project;
@@ -24,96 +30,94 @@
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.project.config.UpdateIssueSubTypeRQ;
 import com.epam.ta.reportportal.ws.model.project.config.UpdateOneIssueSubTypeRQ;
+import java.util.Collections;
+import java.util.Optional;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 
-import java.util.Collections;
-import java.util.Optional;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.TEST_PROJECT_NAME;
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.Mockito.when;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @ExtendWith(MockitoExtension.class)
 class UpdateProjectSettingsHandlerImplTest {
 
-	@Mock
-	private ProjectRepository projectRepository;
-
-	@InjectMocks
-	private UpdateProjectSettingsHandlerImpl handler;
-
-	@Test
-	void emptyRequest() {
-		ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER, 1L);
-
-		UpdateIssueSubTypeRQ updateIssueSubTypeRQ = new UpdateIssueSubTypeRQ();
-		updateIssueSubTypeRQ.setIds(Collections.emptyList());
-
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.updateProjectIssueSubType("test_project", user, updateIssueSubTypeRQ)
-		);
-		assertEquals("Forbidden operation. Please specify at least one item data for update.", exception.getMessage());
-	}
-
-	@Test
-	void updateSubtypeOnNotExistProject() {
-		long projectId = 1L;
-		ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER, projectId);
-
-		UpdateIssueSubTypeRQ updateIssueSubTypeRQ = new UpdateIssueSubTypeRQ();
-		updateIssueSubTypeRQ.setIds(Collections.singletonList(new UpdateOneIssueSubTypeRQ()));
-
-		when(projectRepository.findByName(TEST_PROJECT_NAME)).thenReturn(Optional.empty());
-
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.updateProjectIssueSubType(TEST_PROJECT_NAME, user, updateIssueSubTypeRQ)
-		);
-		assertEquals("Project 'test_project' not found. Did you use correct project name?", exception.getMessage());
-	}
-
-	@Test
-	void updateSubtypeWithIncorrectGroup() {
-		long projectId = 1L;
-		ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER, projectId);
-
-		UpdateIssueSubTypeRQ updateIssueSubTypeRQ = new UpdateIssueSubTypeRQ();
-		UpdateOneIssueSubTypeRQ oneIssueSubTypeRQ = new UpdateOneIssueSubTypeRQ();
-		oneIssueSubTypeRQ.setTypeRef("wrongType");
-		updateIssueSubTypeRQ.setIds(Collections.singletonList(oneIssueSubTypeRQ));
-
-		when(projectRepository.findByName(TEST_PROJECT_NAME)).thenReturn(Optional.of(new Project()));
-
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.updateProjectIssueSubType(TEST_PROJECT_NAME, user, updateIssueSubTypeRQ)
-		);
-		assertEquals("Issue Type 'wrongType' not found.", exception.getMessage());
-	}
-
-	@Test
-	void updateNotExistSubtype() {
-		long projectId = 1L;
-		ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER, projectId);
-
-		UpdateIssueSubTypeRQ updateIssueSubTypeRQ = new UpdateIssueSubTypeRQ();
-		UpdateOneIssueSubTypeRQ oneIssueSubTypeRQ = new UpdateOneIssueSubTypeRQ();
-		oneIssueSubTypeRQ.setTypeRef("product_bug");
-		oneIssueSubTypeRQ.setLocator("locator");
-		updateIssueSubTypeRQ.setIds(Collections.singletonList(oneIssueSubTypeRQ));
-
-		when(projectRepository.findByName(TEST_PROJECT_NAME)).thenReturn(Optional.of(new Project()));
-
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.updateProjectIssueSubType(TEST_PROJECT_NAME, user, updateIssueSubTypeRQ)
-		);
-		assertEquals("Issue Type 'locator' not found.", exception.getMessage());
-	}
+  @Mock
+  private ProjectRepository projectRepository;
+
+  @InjectMocks
+  private UpdateProjectSettingsHandlerImpl handler;
+
+  @Test
+  void emptyRequest() {
+    ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER, 1L);
+
+    UpdateIssueSubTypeRQ updateIssueSubTypeRQ = new UpdateIssueSubTypeRQ();
+    updateIssueSubTypeRQ.setIds(Collections.emptyList());
+
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.updateProjectIssueSubType("test_project", user, updateIssueSubTypeRQ)
+    );
+    assertEquals("Forbidden operation. Please specify at least one item data for update.",
+        exception.getMessage());
+  }
+
+  @Test
+  void updateSubtypeOnNotExistProject() {
+    long projectId = 1L;
+    ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER,
+        projectId);
+
+    UpdateIssueSubTypeRQ updateIssueSubTypeRQ = new UpdateIssueSubTypeRQ();
+    updateIssueSubTypeRQ.setIds(Collections.singletonList(new UpdateOneIssueSubTypeRQ()));
+
+    when(projectRepository.findByName(TEST_PROJECT_NAME)).thenReturn(Optional.empty());
+
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.updateProjectIssueSubType(TEST_PROJECT_NAME, user, updateIssueSubTypeRQ)
+    );
+    assertEquals("Project 'test_project' not found. Did you use correct project name?",
+        exception.getMessage());
+  }
+
+  @Test
+  void updateSubtypeWithIncorrectGroup() {
+    long projectId = 1L;
+    ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER,
+        projectId);
+
+    UpdateIssueSubTypeRQ updateIssueSubTypeRQ = new UpdateIssueSubTypeRQ();
+    UpdateOneIssueSubTypeRQ oneIssueSubTypeRQ = new UpdateOneIssueSubTypeRQ();
+    oneIssueSubTypeRQ.setTypeRef("wrongType");
+    updateIssueSubTypeRQ.setIds(Collections.singletonList(oneIssueSubTypeRQ));
+
+    when(projectRepository.findByName(TEST_PROJECT_NAME)).thenReturn(Optional.of(new Project()));
+
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.updateProjectIssueSubType(TEST_PROJECT_NAME, user, updateIssueSubTypeRQ)
+    );
+    assertEquals("Issue Type 'wrongType' not found.", exception.getMessage());
+  }
+
+  @Test
+  void updateNotExistSubtype() {
+    long projectId = 1L;
+    ReportPortalUser user = getRpUser("user", UserRole.USER, ProjectRole.PROJECT_MANAGER,
+        projectId);
+
+    UpdateIssueSubTypeRQ updateIssueSubTypeRQ = new UpdateIssueSubTypeRQ();
+    UpdateOneIssueSubTypeRQ oneIssueSubTypeRQ = new UpdateOneIssueSubTypeRQ();
+    oneIssueSubTypeRQ.setTypeRef("product_bug");
+    oneIssueSubTypeRQ.setLocator("locator");
+    updateIssueSubTypeRQ.setIds(Collections.singletonList(oneIssueSubTypeRQ));
+
+    when(projectRepository.findByName(TEST_PROJECT_NAME)).thenReturn(Optional.of(new Project()));
+
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.updateProjectIssueSubType(TEST_PROJECT_NAME, user, updateIssueSubTypeRQ)
+    );
+    assertEquals("Issue Type 'locator' not found.", exception.getMessage());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/project/settings/notification/CreateProjectNotificationHandlerImplTest.java b/src/test/java/com/epam/ta/reportportal/core/project/settings/notification/CreateProjectNotificationHandlerImplTest.java
new file mode 100644
index 0000000000..d9ef4bc959
--- /dev/null
+++ b/src/test/java/com/epam/ta/reportportal/core/project/settings/notification/CreateProjectNotificationHandlerImplTest.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2022 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.core.project.settings.notification;
+
+import static com.epam.ta.reportportal.commons.validation.Suppliers.formattedSupplier;
+import static com.epam.ta.reportportal.ws.model.ErrorType.BAD_REQUEST_ERROR;
+import static com.epam.ta.reportportal.ws.model.ErrorType.RESOURCE_ALREADY_EXISTS;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import com.epam.ta.reportportal.commons.ReportPortalUser;
+import com.epam.ta.reportportal.core.events.MessageBus;
+import com.epam.ta.reportportal.core.project.validator.notification.ProjectNotificationValidator;
+import com.epam.ta.reportportal.dao.SenderCaseRepository;
+import com.epam.ta.reportportal.entity.enums.LogicalOperator;
+import com.epam.ta.reportportal.entity.enums.SendCase;
+import com.epam.ta.reportportal.entity.project.Project;
+import com.epam.ta.reportportal.entity.project.email.LaunchAttributeRule;
+import com.epam.ta.reportportal.entity.project.email.SenderCase;
+import com.epam.ta.reportportal.exception.ReportPortalException;
+import com.epam.ta.reportportal.ws.converter.converters.ProjectConverter;
+import com.epam.ta.reportportal.ws.model.attribute.ItemAttributeResource;
+import com.epam.ta.reportportal.ws.model.project.email.SenderCaseDTO;
+import com.google.common.collect.Sets;
+import java.util.Collections;
+import java.util.Optional;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+/**
+ * @author <a href="mailto:chingiskhan_kalanov@epam.com">Chingiskhan Kalanov</a>
+ */
+class CreateProjectNotificationHandlerImplTest {
+
+  private static final long DEFAULT_PROJECT_ID = 1L;
+  private static final String DEFAULT_RULE_NAME = "Rule1";
+
+  private final SenderCaseRepository senderCaseRepository = mock(SenderCaseRepository.class);
+  private final MessageBus messageBus = mock(MessageBus.class);
+  private final ProjectConverter projectConverter = mock(ProjectConverter.class);
+  private final ProjectNotificationValidator projectNotificationValidator = new ProjectNotificationValidator(
+      senderCaseRepository);
+
+  private final CreateProjectNotificationHandlerImpl service = new CreateProjectNotificationHandlerImpl(
+      senderCaseRepository, messageBus,
+      projectConverter, projectNotificationValidator);
+
+  private SenderCaseDTO createNotificationRQ;
+  private Project project;
+  private ReportPortalUser rpUser;
+
+  @BeforeEach
+  public void beforeEach() {
+    createNotificationRQ = new SenderCaseDTO();
+    createNotificationRQ.setSendCase("always");
+    createNotificationRQ.setRuleName(DEFAULT_RULE_NAME);
+    createNotificationRQ.setAttributesOperator(LogicalOperator.AND.getOperator());
+    createNotificationRQ.setRecipients(Collections.singletonList("OWNER"));
+    createNotificationRQ.setLaunchNames(Collections.singletonList("test launch"));
+    createNotificationRQ.setEnabled(true);
+    ItemAttributeResource launchAttribute = new ItemAttributeResource();
+    launchAttribute.setKey("key");
+    launchAttribute.setValue("val");
+    createNotificationRQ.setAttributes(Sets.newHashSet(launchAttribute));
+
+    project = mock(Project.class);
+    when(project.getId()).thenReturn(DEFAULT_PROJECT_ID);
+
+    rpUser = mock(ReportPortalUser.class);
+  }
+
+  @Test
+  public void createNotificationWithExistingRuleNameTest() {
+    SenderCase existingSenderCase = mock(SenderCase.class);
+
+    when(senderCaseRepository.findByProjectIdAndRuleNameIgnoreCase(DEFAULT_PROJECT_ID,
+        DEFAULT_RULE_NAME))
+        .thenReturn(Optional.of(existingSenderCase));
+
+    assertEquals(
+        assertThrows(ReportPortalException.class,
+            () -> service.createNotification(project, createNotificationRQ, rpUser)
+        ).getMessage(),
+        formattedSupplier(RESOURCE_ALREADY_EXISTS.getDescription(),
+            createNotificationRQ.getRuleName()).get()
+    );
+  }
+
+  @Test
+  public void createNotificationWithNonExistingSendCaseTest() {
+    createNotificationRQ.setSendCase("NonExistingSendCase");
+
+    assertEquals(
+        assertThrows(ReportPortalException.class,
+            () -> service.createNotification(project, createNotificationRQ, rpUser)
+        ).getMessage(),
+        formattedSupplier(BAD_REQUEST_ERROR.getDescription(),
+            createNotificationRQ.getSendCase()).get()
+    );
+  }
+
+  @Test
+  public void createNotificationWithNullOrEmptyRecipientsTest() {
+    createNotificationRQ.setRecipients(null);
+
+    assertTrue(
+        assertThrows(ReportPortalException.class,
+            () -> service.createNotification(project, createNotificationRQ, rpUser))
+            .getMessage().contains("Recipients list should not be null")
+    );
+
+    createNotificationRQ.setRecipients(Collections.emptyList());
+
+    assertTrue(
+        assertThrows(ReportPortalException.class,
+            () -> service.createNotification(project, createNotificationRQ, rpUser))
+            .getMessage().contains("Empty recipients list for email case")
+    );
+  }
+
+  @Test
+  public void createNotificationWithDuplicateContentButWithDifferentRuleNameTest() {
+    SenderCase dupeCreateNotificationRQ = mock(SenderCase.class);
+    when(dupeCreateNotificationRQ.getSendCase()).thenReturn(SendCase.ALWAYS);
+    when(dupeCreateNotificationRQ.getRuleName()).thenReturn("Rule2");
+    when(dupeCreateNotificationRQ.getAttributesOperator()).thenReturn(LogicalOperator.AND);
+    when(dupeCreateNotificationRQ.getRecipients()).thenReturn(Collections.singleton("OWNER"));
+    when(dupeCreateNotificationRQ.getLaunchNames()).thenReturn(
+        Collections.singleton("test launch"));
+    when(dupeCreateNotificationRQ.isEnabled()).thenReturn(true);
+    when(dupeCreateNotificationRQ.getProject()).thenReturn(project);
+
+    LaunchAttributeRule launchAttribute = mock(LaunchAttributeRule.class);
+    when(launchAttribute.getKey()).thenReturn("key");
+    when(launchAttribute.getValue()).thenReturn("val");
+    when(dupeCreateNotificationRQ.getLaunchAttributeRules()).thenReturn(
+        Collections.singleton(launchAttribute));
+
+    when(senderCaseRepository.findAllByProjectId(DEFAULT_PROJECT_ID)).thenReturn(
+        Collections.singletonList(dupeCreateNotificationRQ));
+
+    assertTrue(
+        assertThrows(ReportPortalException.class,
+            () -> service.createNotification(project, createNotificationRQ, rpUser))
+            .getMessage().contains("Project email settings contain duplicate cases")
+    );
+  }
+
+}
diff --git a/src/test/java/com/epam/ta/reportportal/core/project/settings/notification/DeleteProjectNotificationHandlerImplTest.java b/src/test/java/com/epam/ta/reportportal/core/project/settings/notification/DeleteProjectNotificationHandlerImplTest.java
new file mode 100644
index 0000000000..36c1ca6eb8
--- /dev/null
+++ b/src/test/java/com/epam/ta/reportportal/core/project/settings/notification/DeleteProjectNotificationHandlerImplTest.java
@@ -0,0 +1,87 @@
+/*
+ *
+ * Copyright 2022 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.epam.ta.reportportal.core.project.settings.notification;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import com.epam.ta.reportportal.commons.ReportPortalUser;
+import com.epam.ta.reportportal.core.events.MessageBus;
+import com.epam.ta.reportportal.dao.SenderCaseRepository;
+import com.epam.ta.reportportal.entity.project.Project;
+import com.epam.ta.reportportal.entity.project.email.SenderCase;
+import com.epam.ta.reportportal.exception.ReportPortalException;
+import com.epam.ta.reportportal.ws.converter.converters.ProjectConverter;
+import java.util.Optional;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+/**
+ * @author <a href="mailto:chingiskhan_kalanov@epam.com">Chingiskhan Kalanov</a>
+ */
+class DeleteProjectNotificationHandlerImplTest {
+
+  private final SenderCaseRepository senderCaseRepository = mock(SenderCaseRepository.class);
+  private final MessageBus messageBus = mock(MessageBus.class);
+  private final ProjectConverter projectConverter = mock(ProjectConverter.class);
+
+  private final DeleteProjectNotificationHandlerImpl service = new DeleteProjectNotificationHandlerImpl(
+      senderCaseRepository, messageBus,
+      projectConverter);
+
+  private Project project;
+  private ReportPortalUser rpUser;
+
+  @BeforeEach
+  public void beforeEach() {
+    project = mock(Project.class);
+    when(project.getId()).thenReturn(1L);
+
+    rpUser = mock(ReportPortalUser.class);
+  }
+
+  @Test
+  public void deleteNonExistingNotificationTest() {
+    Assertions.assertTrue(
+        assertThrows(ReportPortalException.class,
+            () -> service.deleteNotification(project, 1L, rpUser))
+            .getMessage().contains("Did you use correct Notification ID?")
+    );
+  }
+
+  @Test
+  public void deleteNotificationButWithDifferentProjectTest() {
+    SenderCase sc = mock(SenderCase.class);
+    Project scProject = mock(Project.class);
+
+    when(scProject.getId()).thenReturn(2L);
+    when(sc.getProject()).thenReturn(scProject);
+    when(senderCaseRepository.findById(any())).thenReturn(Optional.of(sc));
+
+    Assertions.assertTrue(
+        assertThrows(ReportPortalException.class,
+            () -> service.deleteNotification(project, 1L, rpUser))
+            .getMessage().contains("Did you use correct Notification ID?")
+    );
+  }
+
+}
diff --git a/src/test/java/com/epam/ta/reportportal/core/project/settings/notification/GetProjectNotificationsHandlerImplTest.java b/src/test/java/com/epam/ta/reportportal/core/project/settings/notification/GetProjectNotificationsHandlerImplTest.java
new file mode 100644
index 0000000000..053a78687a
--- /dev/null
+++ b/src/test/java/com/epam/ta/reportportal/core/project/settings/notification/GetProjectNotificationsHandlerImplTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2022 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.core.project.settings.notification;
+
+import static com.epam.ta.reportportal.entity.enums.SendCase.ALWAYS;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import com.epam.ta.reportportal.dao.SenderCaseRepository;
+import com.epam.ta.reportportal.entity.enums.LogicalOperator;
+import com.epam.ta.reportportal.entity.project.email.SenderCase;
+import com.epam.ta.reportportal.ws.model.project.email.SenderCaseDTO;
+import java.util.List;
+import org.junit.jupiter.api.Test;
+
+/**
+ * @author <a href="mailto:chingiskhan_kalanov@epam.com">Chingiskhan Kalanov</a>
+ */
+class GetProjectNotificationsHandlerImplTest {
+
+  private static final Long DEFAULT_PROJECT_ID = 1L;
+  private static final Long DEFAULT_SENDER_CASE_1_ID = 1L;
+  private static final Long DEFAULT_SENDER_CASE_2_ID = 2L;
+  private static final String DEFAULT_SENDER_CASE_1_RULE_NAME = "rule #" + DEFAULT_SENDER_CASE_1_ID;
+  private static final String DEFAULT_SENDER_CASE_2_RULE_NAME = "rule #" + DEFAULT_SENDER_CASE_2_ID;
+
+  private final SenderCaseRepository senderCaseRepository = mock(SenderCaseRepository.class);
+  private final GetProjectNotificationsHandlerImpl getProjectNotificationsHandler =
+      new GetProjectNotificationsHandlerImpl(senderCaseRepository);
+
+  @Test
+  public void getProjectNotificationsTest() {
+    SenderCase senderCase1 = mock(SenderCase.class);
+    SenderCase senderCase2 = mock(SenderCase.class);
+
+    when(senderCase1.getId()).thenReturn(DEFAULT_SENDER_CASE_1_ID);
+    when(senderCase1.getRuleName()).thenReturn(DEFAULT_SENDER_CASE_1_RULE_NAME);
+    when(senderCase1.getSendCase()).thenReturn(ALWAYS);
+    when(senderCase2.getId()).thenReturn(DEFAULT_SENDER_CASE_2_ID);
+    when(senderCase2.getRuleName()).thenReturn(DEFAULT_SENDER_CASE_2_RULE_NAME);
+    when(senderCase2.getSendCase()).thenReturn(ALWAYS);
+    when(senderCase1.getAttributesOperator()).thenReturn(LogicalOperator.AND);
+    when(senderCase2.getAttributesOperator()).thenReturn(LogicalOperator.AND);
+
+    when(senderCaseRepository.findAllByProjectId(DEFAULT_PROJECT_ID)).thenReturn(
+        List.of(senderCase1, senderCase2));
+
+    List<SenderCaseDTO> result = getProjectNotificationsHandler.getProjectNotifications(
+        DEFAULT_PROJECT_ID);
+    assertEquals(2, result.size());
+  }
+}
diff --git a/src/test/java/com/epam/ta/reportportal/core/project/settings/notification/UpdateProjectNotificationHandlerImplTest.java b/src/test/java/com/epam/ta/reportportal/core/project/settings/notification/UpdateProjectNotificationHandlerImplTest.java
new file mode 100644
index 0000000000..6dc76d2921
--- /dev/null
+++ b/src/test/java/com/epam/ta/reportportal/core/project/settings/notification/UpdateProjectNotificationHandlerImplTest.java
@@ -0,0 +1,202 @@
+/*
+ *
+ * Copyright 2022 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.epam.ta.reportportal.core.project.settings.notification;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import com.epam.ta.reportportal.commons.ReportPortalUser;
+import com.epam.ta.reportportal.core.events.MessageBus;
+import com.epam.ta.reportportal.core.project.validator.notification.ProjectNotificationValidator;
+import com.epam.ta.reportportal.dao.SenderCaseRepository;
+import com.epam.ta.reportportal.entity.enums.LogicalOperator;
+import com.epam.ta.reportportal.entity.enums.SendCase;
+import com.epam.ta.reportportal.entity.project.Project;
+import com.epam.ta.reportportal.entity.project.email.LaunchAttributeRule;
+import com.epam.ta.reportportal.entity.project.email.SenderCase;
+import com.epam.ta.reportportal.exception.ReportPortalException;
+import com.epam.ta.reportportal.ws.converter.converters.ProjectConverter;
+import com.epam.ta.reportportal.ws.model.attribute.ItemAttributeResource;
+import com.epam.ta.reportportal.ws.model.project.email.SenderCaseDTO;
+import com.google.common.collect.Sets;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+/**
+ * @author <a href="mailto:chingiskhan_kalanov@epam.com">Chingiskhan Kalanov</a>
+ */
+class UpdateProjectNotificationHandlerImplTest {
+
+  private static final long DEFAULT_PROJECT_ID = 1L;
+  private static final String DEFAULT_RULE_NAME = "Rule1";
+
+  private final SenderCaseRepository senderCaseRepository = mock(SenderCaseRepository.class);
+  private final MessageBus messageBus = mock(MessageBus.class);
+  private final ProjectConverter projectConverter = mock(ProjectConverter.class);
+  private final ProjectNotificationValidator projectNotificationValidator = new ProjectNotificationValidator(
+      senderCaseRepository);
+
+  private final UpdateProjectNotificationHandlerImpl service = new UpdateProjectNotificationHandlerImpl(
+      senderCaseRepository, messageBus,
+      projectConverter, projectNotificationValidator);
+
+  private SenderCaseDTO updateNotificationRQ;
+  private Project project;
+  private ReportPortalUser rpUser;
+
+  @BeforeEach
+  public void beforeEach() {
+    updateNotificationRQ = new SenderCaseDTO();
+    updateNotificationRQ.setId(1L);
+    updateNotificationRQ.setSendCase("always");
+    updateNotificationRQ.setAttributesOperator(LogicalOperator.AND.getOperator());
+    updateNotificationRQ.setRuleName(DEFAULT_RULE_NAME);
+    updateNotificationRQ.setRecipients(Collections.singletonList("OWNER"));
+    updateNotificationRQ.setLaunchNames(Collections.singletonList("test launch"));
+    updateNotificationRQ.setEnabled(true);
+    ItemAttributeResource launchAttribute = new ItemAttributeResource();
+    launchAttribute.setKey("key");
+    launchAttribute.setValue("val");
+    updateNotificationRQ.setAttributes(Sets.newHashSet(launchAttribute));
+
+    project = mock(Project.class);
+    when(project.getId()).thenReturn(DEFAULT_PROJECT_ID);
+
+    rpUser = mock(ReportPortalUser.class);
+  }
+
+  @Test
+  public void updateNonExistingNotificationTest() {
+    Assertions.assertTrue(
+        assertThrows(ReportPortalException.class,
+            () -> service.updateNotification(project, updateNotificationRQ, rpUser))
+            .getMessage().contains("Did you use correct Notification ID?")
+    );
+  }
+
+  @Test
+  public void updateNotificationButWithDifferentProjectTest() {
+    SenderCase sc = mock(SenderCase.class);
+    Project scProject = mock(Project.class);
+
+    when(scProject.getId()).thenReturn(2L);
+    when(sc.getProject()).thenReturn(scProject);
+    when(senderCaseRepository.findById(any())).thenReturn(Optional.of(sc));
+
+    Assertions.assertTrue(
+        assertThrows(ReportPortalException.class,
+            () -> service.updateNotification(project, updateNotificationRQ, rpUser))
+            .getMessage().contains("Did you use correct Notification ID?")
+    );
+  }
+
+  @Test
+  public void updateNotificationWithNonExistingSendCaseTest() {
+    SenderCase sc = mock(SenderCase.class);
+    Project project = mock(Project.class);
+
+    when(project.getId()).thenReturn(1L);
+    when(sc.getProject()).thenReturn(project);
+    when(senderCaseRepository.findById(any())).thenReturn(Optional.of(sc));
+
+    updateNotificationRQ.setSendCase("NonExistingSendCase");
+    Assertions.assertTrue(
+        assertThrows(ReportPortalException.class,
+            () -> service.updateNotification(project, updateNotificationRQ, rpUser))
+            .getMessage().contains(updateNotificationRQ.getSendCase())
+    );
+  }
+
+  @Test
+  public void updateNotificationWithNullOrEmptyRecipientsTest() {
+    SenderCase sc = mock(SenderCase.class);
+    Project project = mock(Project.class);
+
+    when(project.getId()).thenReturn(DEFAULT_PROJECT_ID);
+    when(sc.getProject()).thenReturn(project);
+    when(senderCaseRepository.findById(any())).thenReturn(Optional.of(sc));
+
+    updateNotificationRQ.setRecipients(null);
+    String s = assertThrows(ReportPortalException.class,
+        () -> service.updateNotification(project, updateNotificationRQ, rpUser))
+        .getMessage();
+    Assertions.assertTrue(s.contains("Recipients list should not be null"));
+
+    updateNotificationRQ.setRecipients(Collections.emptyList());
+
+    Assertions.assertTrue(
+        assertThrows(ReportPortalException.class,
+            () -> service.updateNotification(project, updateNotificationRQ, rpUser))
+            .getMessage().contains("Empty recipients list for email case")
+    );
+  }
+
+  @Test
+  public void updateNotificationWithDuplicateContentButWithDifferentRuleNameTest() {
+    SenderCase sc = mock(SenderCase.class);
+    Project project = mock(Project.class);
+
+    when(project.getId()).thenReturn(DEFAULT_PROJECT_ID);
+    when(sc.getProject()).thenReturn(project);
+    when(senderCaseRepository.findById(any())).thenReturn(Optional.of(sc));
+
+    SenderCase modelForUpdate = mock(SenderCase.class);
+    when(modelForUpdate.getId()).thenReturn(1L);
+    when(modelForUpdate.getSendCase()).thenReturn(SendCase.ALWAYS);
+    when(modelForUpdate.getRuleName()).thenReturn("Rule2");
+    when(modelForUpdate.getAttributesOperator()).thenReturn(LogicalOperator.AND);
+    when(modelForUpdate.getRecipients()).thenReturn(Collections.singleton("OWNER"));
+    when(modelForUpdate.getLaunchNames()).thenReturn(Collections.singleton("test launch1"));
+    when(modelForUpdate.isEnabled()).thenReturn(true);
+    when(modelForUpdate.getProject()).thenReturn(project);
+
+    SenderCase dupeUpdateNotification = mock(SenderCase.class);
+    when(dupeUpdateNotification.getId()).thenReturn(2L);
+    when(dupeUpdateNotification.getSendCase()).thenReturn(SendCase.ALWAYS);
+    when(dupeUpdateNotification.getRuleName()).thenReturn("Rule3");
+    when(dupeUpdateNotification.getAttributesOperator()).thenReturn(LogicalOperator.AND);
+    when(dupeUpdateNotification.getRecipients()).thenReturn(Collections.singleton("OWNER"));
+    when(dupeUpdateNotification.getLaunchNames()).thenReturn(Collections.singleton("test launch"));
+    when(dupeUpdateNotification.isEnabled()).thenReturn(true);
+    when(dupeUpdateNotification.getProject()).thenReturn(project);
+
+    LaunchAttributeRule launchAttribute = mock(LaunchAttributeRule.class);
+    when(launchAttribute.getKey()).thenReturn("key");
+    when(launchAttribute.getValue()).thenReturn("val");
+    when(dupeUpdateNotification.getLaunchAttributeRules()).thenReturn(
+        Collections.singleton(launchAttribute));
+
+    when(senderCaseRepository.findAllByProjectId(DEFAULT_PROJECT_ID)).thenReturn(
+        List.of(modelForUpdate, dupeUpdateNotification));
+
+    assertTrue(
+        assertThrows(ReportPortalException.class,
+            () -> service.updateNotification(project, updateNotificationRQ, rpUser))
+            .getMessage().contains("Project email settings contain duplicate cases")
+    );
+  }
+
+}
diff --git a/src/test/java/com/epam/ta/reportportal/core/remover/user/UserContentRemoverTest.java b/src/test/java/com/epam/ta/reportportal/core/remover/user/UserContentRemoverTest.java
new file mode 100644
index 0000000000..b870c5b6dc
--- /dev/null
+++ b/src/test/java/com/epam/ta/reportportal/core/remover/user/UserContentRemoverTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2022 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.core.remover.user;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.internal.verification.VerificationModeFactory.times;
+
+import com.epam.ta.reportportal.core.remover.ContentRemover;
+import com.epam.ta.reportportal.entity.user.User;
+import java.util.List;
+import org.junit.jupiter.api.Test;
+
+/**
+ * @author <a href="mailto:chingiskhan_kalanov@epam.com">Chingiskhan Kalanov</a>
+ */
+class UserContentRemoverTest {
+
+  private final UserPhotoRemover userPhotoRemover = mock(UserPhotoRemover.class);
+  private final UserWidgetRemover userWidgetRemover = mock(UserWidgetRemover.class);
+  private final ContentRemover<User> userContentRemover = new UserContentRemover(
+      List.of(userWidgetRemover, userPhotoRemover));
+
+  @Test
+  public void removeTest() {
+    User user = mock(User.class);
+
+    userContentRemover.remove(user);
+
+    verify(userWidgetRemover, times(1)).remove(eq(user));
+    verify(userPhotoRemover, times(1)).remove(eq(user));
+  }
+
+}
diff --git a/src/test/java/com/epam/ta/reportportal/core/remover/user/UserPhotoRemoverTest.java b/src/test/java/com/epam/ta/reportportal/core/remover/user/UserPhotoRemoverTest.java
new file mode 100644
index 0000000000..4081ae4ff1
--- /dev/null
+++ b/src/test/java/com/epam/ta/reportportal/core/remover/user/UserPhotoRemoverTest.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2022 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.core.remover.user;
+
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.argThat;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
+import static org.mockito.Mockito.when;
+
+import com.epam.ta.reportportal.dao.AttachmentRepository;
+import com.epam.ta.reportportal.entity.attachment.Attachment;
+import com.epam.ta.reportportal.entity.user.User;
+import java.util.List;
+import org.junit.jupiter.api.Test;
+
+/**
+ * @author <a href="mailto:chingiskhan_kalanov@epam.com">Chingiskhan Kalanov</a>
+ */
+class UserPhotoRemoverTest {
+
+  private static final String USER_PHOTO_ID = "SOME_PHOTO_ID";
+  private static final String USER_THUMBNAIL_ID = "SOME_THUMBNAIL_ID";
+  private static final Long ATTACHMENT_PHOTO_ID = 1L;
+  private static final Long ATTACHMENT_THUMBNAIL_ID = 2L;
+
+  private final AttachmentRepository attachmentRepository = mock(AttachmentRepository.class);
+  private final UserPhotoRemover userPhotoRemover = new UserPhotoRemover(attachmentRepository);
+
+  @Test
+  public void removePhotoWithoutPhotoAttachmentTest() {
+    final User user = mock(User.class);
+
+    userPhotoRemover.remove(user);
+
+    verifyNoInteractions(attachmentRepository);
+  }
+
+  @Test
+  public void removePhotoWithoutThumbnailAttachmentTest() {
+    final User user = mock(User.class);
+    final Attachment userPhoto = mock(Attachment.class);
+
+    when(user.getAttachment()).thenReturn(USER_PHOTO_ID);
+
+    when(userPhoto.getId()).thenReturn(ATTACHMENT_PHOTO_ID);
+    when(userPhoto.getFileId()).thenReturn(USER_PHOTO_ID);
+
+    doReturn(userPhoto).when(attachmentRepository)
+        .save(argThat(argument -> argument.getFileId().equals(USER_PHOTO_ID)));
+
+    userPhotoRemover.remove(user);
+
+    verify(attachmentRepository, times(1)).save(any(Attachment.class));
+    verify(attachmentRepository, times(1)).moveForDeletion(eq(List.of(ATTACHMENT_PHOTO_ID)));
+  }
+
+  @Test
+  public void removePhotoTest() {
+    final User user = mock(User.class);
+    final Attachment userPhoto = mock(Attachment.class);
+    final Attachment userThumbnail = mock(Attachment.class);
+
+    when(user.getAttachment()).thenReturn(USER_PHOTO_ID);
+    when(user.getAttachmentThumbnail()).thenReturn(USER_THUMBNAIL_ID);
+
+    when(userPhoto.getId()).thenReturn(ATTACHMENT_PHOTO_ID);
+    when(userPhoto.getFileId()).thenReturn(USER_PHOTO_ID);
+    when(userThumbnail.getId()).thenReturn(ATTACHMENT_THUMBNAIL_ID);
+    when(userThumbnail.getFileId()).thenReturn(USER_THUMBNAIL_ID);
+
+    doReturn(userPhoto).when(attachmentRepository)
+        .save(argThat(argument -> argument.getFileId().equals(USER_PHOTO_ID)));
+    doReturn(userThumbnail).when(attachmentRepository)
+        .save(argThat(argument -> argument.getFileId().equals(USER_THUMBNAIL_ID)));
+
+    userPhotoRemover.remove(user);
+
+    verify(attachmentRepository, times(2)).save(any(Attachment.class));
+    verify(attachmentRepository, times(1)).moveForDeletion(
+        eq(List.of(ATTACHMENT_PHOTO_ID, ATTACHMENT_THUMBNAIL_ID)));
+  }
+}
diff --git a/src/test/java/com/epam/ta/reportportal/core/statistics/StatisticsHelperTest.java b/src/test/java/com/epam/ta/reportportal/core/statistics/StatisticsHelperTest.java
index 22f3ce33fd..4001bdc333 100644
--- a/src/test/java/com/epam/ta/reportportal/core/statistics/StatisticsHelperTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/statistics/StatisticsHelperTest.java
@@ -16,97 +16,102 @@
 
 package com.epam.ta.reportportal.core.statistics;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
 import com.epam.ta.reportportal.entity.enums.StatusEnum;
 import com.epam.ta.reportportal.entity.statistics.Statistics;
 import com.epam.ta.reportportal.entity.statistics.StatisticsField;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.google.common.collect.Sets;
-import org.junit.jupiter.api.Test;
-
 import java.util.List;
 import java.util.stream.Collectors;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 class StatisticsHelperTest {
 
-	@Test
-	void emptyStatisticsTest() {
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> StatisticsHelper.getStatusFromStatistics(Sets.newHashSet(new Statistics()))
-		);
-		assertEquals("Error in handled Request. Please, check specified parameters: 'Statistics should contain a name field.'",
-				exception.getMessage()
-		);
-	}
+  @Test
+  void emptyStatisticsTest() {
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> StatisticsHelper.getStatusFromStatistics(Sets.newHashSet(new Statistics()))
+    );
+    assertEquals(
+        "Error in handled Request. Please, check specified parameters: 'Statistics should contain a name field.'",
+        exception.getMessage()
+    );
+  }
 
-	@Test
-	void passedTest() {
-		StatusEnum statusFromStatistics = StatisticsHelper.getStatusFromStatistics(Sets.newHashSet(getStatistics("statistics$executions$passed",
-				4
-				),
-				getStatistics("statistics$executions$total", 4),
-				getStatistics("statistics$executions$failed", 0),
-				getStatistics("statistics$executions$skipped", 0)
-		));
-		assertEquals(StatusEnum.PASSED, statusFromStatistics);
-	}
+  @Test
+  void passedTest() {
+    StatusEnum statusFromStatistics = StatisticsHelper.getStatusFromStatistics(
+        Sets.newHashSet(getStatistics("statistics$executions$passed",
+                4
+            ),
+            getStatistics("statistics$executions$total", 4),
+            getStatistics("statistics$executions$failed", 0),
+            getStatistics("statistics$executions$skipped", 0)
+        ));
+    assertEquals(StatusEnum.PASSED, statusFromStatistics);
+  }
 
-	@Test
-	void failedTest() {
-		StatusEnum statusFromStatistics = StatisticsHelper.getStatusFromStatistics(Sets.newHashSet(getStatistics("statistics$executions$passed",
-				4
-				),
-				getStatistics("statistics$executions$failed", 2),
-				getStatistics("statistics$executions$total", 6)
-		));
-		assertEquals(StatusEnum.FAILED, statusFromStatistics);
-	}
+  @Test
+  void failedTest() {
+    StatusEnum statusFromStatistics = StatisticsHelper.getStatusFromStatistics(
+        Sets.newHashSet(getStatistics("statistics$executions$passed",
+                4
+            ),
+            getStatistics("statistics$executions$failed", 2),
+            getStatistics("statistics$executions$total", 6)
+        ));
+    assertEquals(StatusEnum.FAILED, statusFromStatistics);
+  }
 
-	@Test
-	void skippedTest() {
-		StatusEnum statusFromStatistics = StatisticsHelper.getStatusFromStatistics(Sets.newHashSet(getStatistics("statistics$executions$passed",
-				4
-				),
-				getStatistics("statistics$executions$skipped", 1),
-				getStatistics("statistics$executions$total", 5)
-		));
-		assertEquals(StatusEnum.FAILED, statusFromStatistics);
-	}
+  @Test
+  void skippedTest() {
+    StatusEnum statusFromStatistics = StatisticsHelper.getStatusFromStatistics(
+        Sets.newHashSet(getStatistics("statistics$executions$passed",
+                4
+            ),
+            getStatistics("statistics$executions$skipped", 1),
+            getStatistics("statistics$executions$total", 5)
+        ));
+    assertEquals(StatusEnum.FAILED, statusFromStatistics);
+  }
 
-	@Test
-	void toInvestigateTest() {
-		StatusEnum statusFromStatistics = StatisticsHelper.getStatusFromStatistics(Sets.newHashSet(getStatistics("statistics$executions$passed",
-				4
-				),
-				getStatistics("statistics$defects$to_investigate$total", 1),
-				getStatistics("statistics$executions$total", 5)
-		));
-		assertEquals(StatusEnum.FAILED, statusFromStatistics);
-	}
+  @Test
+  void toInvestigateTest() {
+    StatusEnum statusFromStatistics = StatisticsHelper.getStatusFromStatistics(
+        Sets.newHashSet(getStatistics("statistics$executions$passed",
+                4
+            ),
+            getStatistics("statistics$defects$to_investigate$total", 1),
+            getStatistics("statistics$executions$total", 5)
+        ));
+    assertEquals(StatusEnum.FAILED, statusFromStatistics);
+  }
 
-	private Statistics getStatistics(String statisticsFieldName, int counter) {
-		Statistics statistics = new Statistics();
-		statistics.setStatisticsField(new StatisticsField(statisticsFieldName));
-		statistics.setCounter(counter);
-		return statistics;
-	}
+  private Statistics getStatistics(String statisticsFieldName, int counter) {
+    Statistics statistics = new Statistics();
+    statistics.setStatisticsField(new StatisticsField(statisticsFieldName));
+    statistics.setCounter(counter);
+    return statistics;
+  }
 
-	@Test
-	void extractStatisticsCount() {
-		assertEquals(5, (int) StatisticsHelper.extractStatisticsCount(
-				"statistics$executions$passed",
-				Sets.newHashSet(getStatistics("statistics$executions$passed", 5), getStatistics("statistics$executions$total", 5))
-		));
-	}
+  @Test
+  void extractStatisticsCount() {
+    assertEquals(5, (int) StatisticsHelper.extractStatisticsCount(
+        "statistics$executions$passed",
+        Sets.newHashSet(getStatistics("statistics$executions$passed", 5),
+            getStatistics("statistics$executions$total", 5))
+    ));
+  }
 
-	@Test
-	void defaultStatisticsFields() {
-		List<String> fields = StatisticsHelper.defaultStatisticsFields().collect(Collectors.toList());
-		assertEquals(9, fields.size());
-	}
+  @Test
+  void defaultStatisticsFields() {
+    List<String> fields = StatisticsHelper.defaultStatisticsFields().collect(Collectors.toList());
+    assertEquals(9, fields.size());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/user/impl/CreateUserHandlerImplTest.java b/src/test/java/com/epam/ta/reportportal/core/user/impl/CreateUserHandlerImplTest.java
index 7a52442d39..0029766b77 100644
--- a/src/test/java/com/epam/ta/reportportal/core/user/impl/CreateUserHandlerImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/user/impl/CreateUserHandlerImplTest.java
@@ -16,10 +16,29 @@
 
 package com.epam.ta.reportportal.core.user.impl;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static com.epam.ta.reportportal.core.user.impl.CreateUserHandlerImpl.BID_TYPE;
+import static com.epam.ta.reportportal.core.user.impl.CreateUserHandlerImpl.INTERNAL_BID_TYPE;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.isA;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
+import com.epam.ta.reportportal.core.events.activity.ChangeUserTypeEvent;
+import com.epam.ta.reportportal.core.events.activity.CreateInvitationLinkEvent;
+import com.epam.ta.reportportal.core.integration.GetIntegrationHandler;
 import com.epam.ta.reportportal.core.project.GetProjectHandler;
 import com.epam.ta.reportportal.dao.UserCreationBidRepository;
 import com.epam.ta.reportportal.dao.UserRepository;
+import com.epam.ta.reportportal.entity.enums.IntegrationGroupEnum;
+import com.epam.ta.reportportal.entity.integration.Integration;
 import com.epam.ta.reportportal.entity.project.Project;
 import com.epam.ta.reportportal.entity.project.ProjectRole;
 import com.epam.ta.reportportal.entity.user.User;
@@ -30,19 +49,15 @@
 import com.epam.ta.reportportal.ws.model.user.CreateUserRQ;
 import com.epam.ta.reportportal.ws.model.user.CreateUserRQConfirm;
 import com.epam.ta.reportportal.ws.model.user.CreateUserRQFull;
+import java.util.Optional;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.ArgumentCaptor;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
-
-import java.util.Optional;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.when;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
@@ -50,211 +65,293 @@
 @ExtendWith(MockitoExtension.class)
 class CreateUserHandlerImplTest {
 
-	@Mock
-	private UserRepository userRepository;
-
-	@Mock
-	private GetProjectHandler getProjectHandler;
-
-	@Mock
-	private UserCreationBidRepository userCreationBidRepository;
-
-	@InjectMocks
-	private CreateUserHandlerImpl handler;
-
-	@Test
-	void createByNotExistedAdmin() {
-
-		final ReportPortalUser rpUser = getRpUser("admin", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
-		when(userRepository.findRawById(rpUser.getUserId())).thenReturn(Optional.empty());
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.createUserByAdmin(new CreateUserRQFull(), rpUser, "url")
-		);
-		assertEquals("User 'admin' not found.", exception.getMessage());
-	}
-
-	@Test
-	void createByNotAdmin() {
-		final ReportPortalUser rpUser = getRpUser("admin", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
-		User user = new User();
-		user.setRole(UserRole.USER);
-		when(userRepository.findRawById(1L)).thenReturn(Optional.of(user));
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.createUserByAdmin(new CreateUserRQFull(), rpUser, "url")
-		);
-		assertEquals("You do not have enough permissions. Only administrator can create new user. Your role is - USER",
-				exception.getMessage()
-		);
-	}
-
-	@Test
-	void createByAdminUserAlreadyExists() {
-		final ReportPortalUser rpUser = getRpUser("admin", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
-		User creator = new User();
-		creator.setRole(UserRole.ADMINISTRATOR);
-
-		doReturn(Optional.of(creator)).when(userRepository).findRawById(rpUser.getUserId());
-		doReturn(Optional.of(new User())).when(userRepository).findByLogin("new_user");
-
-		final CreateUserRQFull request = new CreateUserRQFull();
-		request.setLogin("new_user");
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.createUserByAdmin(request, rpUser, "url")
-		);
-		assertEquals("User with 'login='new_user'' already exists. You couldn't create the duplicate.", exception.getMessage());
-	}
-
-	@Test
-	void createByAdminWithIncorrectName() {
-		final ReportPortalUser rpUser = getRpUser("admin", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
-		User creator = new User();
-		creator.setRole(UserRole.ADMINISTRATOR);
-		doReturn(Optional.of(creator)).when(userRepository).findRawById(rpUser.getUserId());
-		doReturn(Optional.empty()).when(userRepository).findByLogin("#$$/");
-
-		final CreateUserRQFull request = new CreateUserRQFull();
-		request.setLogin("#$$/");
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.createUserByAdmin(request, rpUser, "url")
-		);
-		assertEquals("Incorrect Request. Username '#$$/' consists only of special characters", exception.getMessage());
-	}
-
-	@Test
-	void createByAdminWithIncorrectEmail() {
-		final ReportPortalUser rpUser = getRpUser("admin", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
-		User creator = new User();
-		creator.setRole(UserRole.ADMINISTRATOR);
-		doReturn(Optional.of(creator)).when(userRepository).findRawById(rpUser.getUserId());
-		doReturn(Optional.empty()).when(userRepository).findByLogin("new_user");
-
-		final CreateUserRQFull request = new CreateUserRQFull();
-		request.setLogin("new_user");
-		request.setEmail("incorrect@email");
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.createUserByAdmin(request, rpUser, "url")
-		);
-		assertEquals("Error in handled Request. Please, check specified parameters: 'email='incorrect@email''", exception.getMessage());
-	}
-
-	@Test
-	void createByAdminWithExistedEmail() {
-		final ReportPortalUser rpUser = getRpUser("admin", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
-		User creator = new User();
-		creator.setRole(UserRole.ADMINISTRATOR);
-		doReturn(Optional.of(creator)).when(userRepository).findRawById(rpUser.getUserId());
-		doReturn(Optional.empty()).when(userRepository).findByLogin("new_user");
-		when(userRepository.findByEmail("correct@domain.com")).thenReturn(Optional.of(new User()));
-
-		final CreateUserRQFull request = new CreateUserRQFull();
-		request.setLogin("new_user");
-		request.setEmail("correct@domain.com");
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.createUserByAdmin(request, rpUser, "url")
-		);
-		assertEquals("User with 'email='correct@domain.com'' already exists. You couldn't create the duplicate.", exception.getMessage());
-	}
-
-	@Test
-	void createByAdminWithExistedEmailUppercase() {
-		final ReportPortalUser rpUser = getRpUser("admin", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
-		User creator = new User();
-		creator.setRole(UserRole.ADMINISTRATOR);
-		doReturn(Optional.of(creator)).when(userRepository).findRawById(rpUser.getUserId());
-		doReturn(Optional.empty()).when(userRepository).findByLogin("new_user");
-		when(userRepository.findByEmail("correct@domain.com")).thenReturn(Optional.of(new User()));
-
-		final CreateUserRQFull request = new CreateUserRQFull();
-		request.setLogin("new_user");
-		request.setEmail("CORRECT@domain.com");
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.createUserByAdmin(request, rpUser, "url")
-		);
-		assertEquals("User with 'email='CORRECT@domain.com'' already exists. You couldn't create the duplicate.", exception.getMessage());
-	}
-
-	@Test
-	void CreateUserBidOnNotExistedProject() {
-		final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
-
-		when(getProjectHandler.get("not_exists")).thenThrow(new ReportPortalException(ErrorType.PROJECT_NOT_FOUND, "not_exists"));
-
-		CreateUserRQ request = new CreateUserRQ();
-		request.setDefaultProject("not_exists");
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.createUserBid(request, rpUser, "emailUrl")
-		);
-		assertEquals("Project 'not_exists' not found. Did you use correct project name?", exception.getMessage());
-	}
-
-	@Test
-	void createUserWithoutBid() {
-		when(userCreationBidRepository.findById("uuid")).thenReturn(Optional.empty());
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.createUser(new CreateUserRQConfirm(), "uuid")
-		);
-		assertEquals("Incorrect Request. Impossible to register user. UUID expired or already registered.", exception.getMessage());
-	}
-
-	@Test
-	void createAlreadyExistedUser() {
-		final UserCreationBid creationBid = new UserCreationBid();
-		creationBid.setDefaultProject(new Project());
-		when(userCreationBidRepository.findById("uuid")).thenReturn(Optional.of(creationBid));
-		when(userRepository.findByLogin("test")).thenReturn(Optional.of(new User()));
-
-		final CreateUserRQConfirm request = new CreateUserRQConfirm();
-		request.setLogin("test");
-		final ReportPortalException exception = assertThrows(ReportPortalException.class, () -> handler.createUser(request, "uuid"));
-		assertEquals("User with 'login='test'' already exists. You couldn't create the duplicate.", exception.getMessage());
-	}
-
-	@Test
-	public void createUserWithIncorrectLogin() {
-		final UserCreationBid creationBid = new UserCreationBid();
-		creationBid.setDefaultProject(new Project());
-		when(userCreationBidRepository.findById("uuid")).thenReturn(Optional.of(creationBid));
-		when(userRepository.findByLogin("##$%/")).thenReturn(Optional.empty());
-
-		final CreateUserRQConfirm request = new CreateUserRQConfirm();
-		request.setLogin("##$%/");
-		final ReportPortalException exception = assertThrows(ReportPortalException.class, () -> handler.createUser(request, "uuid"));
-		assertEquals("Incorrect Request. Username '##$%/' consists only of special characters", exception.getMessage());
-	}
-
-	@Test
-	void createUserWithIncorrectEmail() {
-		final UserCreationBid bid = new UserCreationBid();
-		Project project = new Project();
-		project.setName("test_project");
-		bid.setDefaultProject(project);
-		when(userCreationBidRepository.findById("uuid")).thenReturn(Optional.of(bid));
-		when(userRepository.findByLogin("test")).thenReturn(Optional.empty());
-
-		final CreateUserRQConfirm request = new CreateUserRQConfirm();
-		request.setLogin("test");
-		request.setEmail("incorrect@domain");
-		final ReportPortalException exception = assertThrows(ReportPortalException.class, () -> handler.createUser(request, "uuid"));
-		assertEquals("Error in handled Request. Please, check specified parameters: 'email='incorrect@domain''", exception.getMessage());
-	}
-
-	@Test
-	void createUserWithExistedEmail() {
-		final UserCreationBid bid = new UserCreationBid();
-		Project project = new Project();
-		project.setName("test_project");
-		bid.setDefaultProject(project);
-		when(userCreationBidRepository.findById("uuid")).thenReturn(Optional.of(bid));
-		when(userRepository.findByLogin("test")).thenReturn(Optional.empty());
-		when(userRepository.findByEmail("email@domain.com")).thenReturn(Optional.of(new User()));
-
-		final CreateUserRQConfirm request = new CreateUserRQConfirm();
-		request.setLogin("test");
-		request.setEmail("email@domain.com");
-		final ReportPortalException exception = assertThrows(ReportPortalException.class, () -> handler.createUser(request, "uuid"));
-		assertEquals("User with 'email='email@domain.com'' already exists. You couldn't create the duplicate.", exception.getMessage());
-	}
+  @Mock
+  private UserRepository userRepository;
+
+  @Mock
+  private GetProjectHandler getProjectHandler;
+
+  @Mock
+  private UserCreationBidRepository userCreationBidRepository;
+
+  @Mock
+  private GetIntegrationHandler getIntegrationHandler;
+
+  @Mock
+  private ThreadPoolTaskExecutor emailExecutorService;
+
+  @Mock
+  private ApplicationEventPublisher eventPublisher;
+
+  @InjectMocks
+  private CreateUserHandlerImpl handler;
+
+  @Test
+  void createByNotExistedAdmin() {
+
+    final ReportPortalUser rpUser = getRpUser("admin", UserRole.ADMINISTRATOR,
+        ProjectRole.PROJECT_MANAGER, 1L);
+    when(userRepository.findRawById(rpUser.getUserId())).thenReturn(Optional.empty());
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.createUserByAdmin(new CreateUserRQFull(), rpUser, "url")
+    );
+    assertEquals("User 'admin' not found.", exception.getMessage());
+  }
+
+  @Test
+  void createByNotAdmin() {
+    final ReportPortalUser rpUser = getRpUser("admin", UserRole.ADMINISTRATOR,
+        ProjectRole.PROJECT_MANAGER, 1L);
+    User user = new User();
+    user.setRole(UserRole.USER);
+    when(userRepository.findRawById(1L)).thenReturn(Optional.of(user));
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.createUserByAdmin(new CreateUserRQFull(), rpUser, "url")
+    );
+    assertEquals(
+        "You do not have enough permissions. Only administrator can create new user. Your role is - USER",
+        exception.getMessage()
+    );
+  }
+
+  @Test
+  void createByAdminUserAlreadyExists() {
+    final ReportPortalUser rpUser = getRpUser("admin", UserRole.ADMINISTRATOR,
+        ProjectRole.PROJECT_MANAGER, 1L);
+    User creator = new User();
+    creator.setRole(UserRole.ADMINISTRATOR);
+
+    doReturn(Optional.of(creator)).when(userRepository).findRawById(rpUser.getUserId());
+    doReturn(Optional.of(new User())).when(userRepository).findByLogin("new_user");
+
+    final CreateUserRQFull request = new CreateUserRQFull();
+    request.setLogin("new_user");
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.createUserByAdmin(request, rpUser, "url")
+    );
+    assertEquals("User with 'login='new_user'' already exists. You couldn't create the duplicate.",
+        exception.getMessage());
+  }
+
+  @Test
+  void createByAdminWithIncorrectName() {
+    final ReportPortalUser rpUser = getRpUser("admin", UserRole.ADMINISTRATOR,
+        ProjectRole.PROJECT_MANAGER, 1L);
+    User creator = new User();
+    creator.setRole(UserRole.ADMINISTRATOR);
+    doReturn(Optional.of(creator)).when(userRepository).findRawById(rpUser.getUserId());
+    doReturn(Optional.empty()).when(userRepository).findByLogin("#$$/");
+
+    final CreateUserRQFull request = new CreateUserRQFull();
+    request.setLogin("#$$/");
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.createUserByAdmin(request, rpUser, "url")
+    );
+    assertEquals("Incorrect Request. Username '#$$/' consists only of special characters",
+        exception.getMessage());
+  }
+
+  @Test
+  void createByAdminWithIncorrectEmail() {
+    final ReportPortalUser rpUser = getRpUser("admin", UserRole.ADMINISTRATOR,
+        ProjectRole.PROJECT_MANAGER, 1L);
+    User creator = new User();
+    creator.setRole(UserRole.ADMINISTRATOR);
+    doReturn(Optional.of(creator)).when(userRepository).findRawById(rpUser.getUserId());
+    doReturn(Optional.empty()).when(userRepository).findByLogin("new_user");
+
+    final CreateUserRQFull request = new CreateUserRQFull();
+    request.setLogin("new_user");
+    request.setEmail("incorrect@email");
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.createUserByAdmin(request, rpUser, "url")
+    );
+    assertEquals(
+        "Error in handled Request. Please, check specified parameters: 'email='incorrect@email''",
+        exception.getMessage());
+  }
+
+  @Test
+  void createByAdminWithExistedEmail() {
+    final ReportPortalUser rpUser = getRpUser("admin", UserRole.ADMINISTRATOR,
+        ProjectRole.PROJECT_MANAGER, 1L);
+    User creator = new User();
+    creator.setRole(UserRole.ADMINISTRATOR);
+    doReturn(Optional.of(creator)).when(userRepository).findRawById(rpUser.getUserId());
+    doReturn(Optional.empty()).when(userRepository).findByLogin("new_user");
+    when(userRepository.findByEmail("correct@domain.com")).thenReturn(Optional.of(new User()));
+
+    final CreateUserRQFull request = new CreateUserRQFull();
+    request.setLogin("new_user");
+    request.setEmail("correct@domain.com");
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.createUserByAdmin(request, rpUser, "url")
+    );
+    assertEquals(
+        "User with 'email='correct@domain.com'' already exists. You couldn't create the duplicate.",
+        exception.getMessage());
+  }
+
+  @Test
+  void createByAdminWithExistedEmailUppercase() {
+    final ReportPortalUser rpUser = getRpUser("admin", UserRole.ADMINISTRATOR,
+        ProjectRole.PROJECT_MANAGER, 1L);
+    User creator = new User();
+    creator.setRole(UserRole.ADMINISTRATOR);
+    doReturn(Optional.of(creator)).when(userRepository).findRawById(rpUser.getUserId());
+    doReturn(Optional.empty()).when(userRepository).findByLogin("new_user");
+    when(userRepository.findByEmail("correct@domain.com")).thenReturn(Optional.of(new User()));
+
+    final CreateUserRQFull request = new CreateUserRQFull();
+    request.setLogin("new_user");
+    request.setEmail("CORRECT@domain.com");
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.createUserByAdmin(request, rpUser, "url")
+    );
+    assertEquals(
+        "User with 'email='CORRECT@domain.com'' already exists. You couldn't create the duplicate.",
+        exception.getMessage());
+  }
+
+  @Test
+  void createUserBid() {
+    final ReportPortalUser rpUser = getRpUser("admin", UserRole.ADMINISTRATOR, ProjectRole.MEMBER,
+        1L);
+    final String projectName = "test_project";
+    final String email = "email@mail.com";
+    final String role = ProjectRole.MEMBER.name();
+
+    final Project project = new Project();
+    project.setId(1L);
+    project.setName(projectName);
+
+    when(getProjectHandler.get(projectName)).thenReturn(project);
+    when(userRepository.existsById(rpUser.getUserId())).thenReturn(true);
+    when(getIntegrationHandler.getEnabledByProjectIdOrGlobalAndIntegrationGroup(project.getId(),
+        IntegrationGroupEnum.NOTIFICATION
+    )).thenReturn(Optional.of(new Integration()));
+    doNothing().when(emailExecutorService).execute(any());
+    doNothing().when(eventPublisher).publishEvent(isA(CreateInvitationLinkEvent.class));
+
+    CreateUserRQ request = new CreateUserRQ();
+    request.setDefaultProject(projectName);
+    request.setEmail(email);
+    request.setRole(role);
+
+    handler.createUserBid(request, rpUser, "emailUrl");
+
+    final ArgumentCaptor<UserCreationBid> bidCaptor = ArgumentCaptor.forClass(
+        UserCreationBid.class);
+    verify(userCreationBidRepository, times(1)).save(bidCaptor.capture());
+
+    final UserCreationBid bid = bidCaptor.getValue();
+
+    assertEquals(projectName, bid.getProjectName());
+    assertEquals(email, bid.getEmail());
+    assertEquals(role, bid.getRole());
+    assertNotNull(bid.getMetadata());
+
+    assertEquals(INTERNAL_BID_TYPE, String.valueOf(bid.getMetadata().getMetadata().get(BID_TYPE)));
+
+  }
+
+  @Test
+  void CreateUserBidOnNotExistedProject() {
+    final ReportPortalUser rpUser = getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L);
+
+    when(getProjectHandler.get("not_exists")).thenThrow(
+        new ReportPortalException(ErrorType.PROJECT_NOT_FOUND, "not_exists"));
+
+    CreateUserRQ request = new CreateUserRQ();
+    request.setDefaultProject("not_exists");
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.createUserBid(request, rpUser, "emailUrl")
+    );
+    assertEquals("Project 'not_exists' not found. Did you use correct project name?",
+        exception.getMessage());
+  }
+
+  @Test
+  void createUserWithoutBid() {
+    when(userCreationBidRepository.findByUuidAndType("uuid", INTERNAL_BID_TYPE)).thenReturn(
+        Optional.empty());
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.createUser(new CreateUserRQConfirm(), "uuid")
+    );
+    assertEquals(
+        "Incorrect Request. Impossible to register user. UUID expired or already registered.",
+        exception.getMessage());
+  }
+
+  @Test
+  void createAlreadyExistedUser() {
+    final UserCreationBid creationBid = new UserCreationBid();
+    creationBid.setProjectName("project");
+    when(userCreationBidRepository.findByUuidAndType("uuid", INTERNAL_BID_TYPE)).thenReturn(
+        Optional.of(creationBid));
+    when(userRepository.findByLogin("test")).thenReturn(Optional.of(new User()));
+
+    final CreateUserRQConfirm request = new CreateUserRQConfirm();
+    request.setLogin("test");
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.createUser(request, "uuid"));
+    assertEquals("User with 'login='test'' already exists. You couldn't create the duplicate.",
+        exception.getMessage());
+  }
+
+  @Test
+  public void createUserWithIncorrectLogin() {
+    final UserCreationBid creationBid = new UserCreationBid();
+    creationBid.setProjectName("project");
+    when(userCreationBidRepository.findByUuidAndType("uuid", INTERNAL_BID_TYPE)).thenReturn(
+        Optional.of(creationBid));
+    when(userRepository.findByLogin("##$%/")).thenReturn(Optional.empty());
+
+    final CreateUserRQConfirm request = new CreateUserRQConfirm();
+    request.setLogin("##$%/");
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.createUser(request, "uuid"));
+    assertEquals("Incorrect Request. Username '##$%/' consists only of special characters",
+        exception.getMessage());
+  }
+
+  @Test
+  void createUserWithIncorrectEmail() {
+    final UserCreationBid bid = new UserCreationBid();
+    bid.setProjectName("test_project");
+    when(userCreationBidRepository.findByUuidAndType("uuid", INTERNAL_BID_TYPE)).thenReturn(
+        Optional.of(bid));
+    when(userRepository.findByLogin("test")).thenReturn(Optional.empty());
+
+    final CreateUserRQConfirm request = new CreateUserRQConfirm();
+    request.setLogin("test");
+    request.setEmail("incorrect@domain");
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.createUser(request, "uuid"));
+    assertEquals(
+        "Error in handled Request. Please, check specified parameters: 'email='incorrect@domain''",
+        exception.getMessage());
+  }
+
+  @Test
+  void createUserWithExistedEmail() {
+    final UserCreationBid bid = new UserCreationBid();
+    bid.setProjectName("test_project");
+    when(userCreationBidRepository.findByUuidAndType("uuid", INTERNAL_BID_TYPE)).thenReturn(
+        Optional.of(bid));
+    when(userRepository.findByLogin("test")).thenReturn(Optional.empty());
+    when(userRepository.findByEmail("email@domain.com")).thenReturn(Optional.of(new User()));
+
+    final CreateUserRQConfirm request = new CreateUserRQConfirm();
+    request.setLogin("test");
+    request.setEmail("email@domain.com");
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.createUser(request, "uuid"));
+    assertEquals(
+        "User with 'email='email@domain.com'' already exists. You couldn't create the duplicate.",
+        exception.getMessage());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/user/impl/GetUserHandlerImplTest.java b/src/test/java/com/epam/ta/reportportal/core/user/impl/GetUserHandlerImplTest.java
index d354935ad1..ba43a833ee 100644
--- a/src/test/java/com/epam/ta/reportportal/core/user/impl/GetUserHandlerImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/user/impl/GetUserHandlerImplTest.java
@@ -16,6 +16,15 @@
 
 package com.epam.ta.reportportal.core.user.impl;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static com.epam.ta.reportportal.core.user.impl.CreateUserHandlerImpl.INTERNAL_BID_TYPE;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.dao.UserCreationBidRepository;
 import com.epam.ta.reportportal.dao.UserRepository;
 import com.epam.ta.reportportal.entity.project.ProjectRole;
@@ -24,97 +33,93 @@
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.YesNoRS;
 import com.epam.ta.reportportal.ws.model.user.UserBidRS;
+import java.util.Optional;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 
-import java.util.Optional;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.Mockito.when;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @ExtendWith(MockitoExtension.class)
 class GetUserHandlerImplTest {
 
-	@Mock
-	private UserRepository userRepository;
+  @Mock
+  private UserRepository userRepository;
 
-	@Mock
-	private UserCreationBidRepository userCreationBidRepository;
+  @Mock
+  private UserCreationBidRepository userCreationBidRepository;
 
-	@InjectMocks
-	private GetUserHandlerImpl handler;
+  @InjectMocks
+  private GetUserHandlerImpl handler;
 
-	@Test
-	void getNotExistedUserByUsername() {
-		when(userRepository.findByLogin("not_exist")).thenReturn(Optional.empty());
+  @Test
+  void getNotExistedUserByUsername() {
+    when(userRepository.findByLogin("not_exist")).thenReturn(Optional.empty());
 
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.getUser("not_exist", getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L))
-		);
-		assertEquals("User 'not_exist' not found.", exception.getMessage());
-	}
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.getUser("not_exist", getRpUser("test", UserRole.USER, ProjectRole.MEMBER, 1L))
+    );
+    assertEquals("User 'not_exist' not found.", exception.getMessage());
+  }
 
-	@Test
-	void getNotExistedUserByLoggedInUser() {
-		when(userRepository.findByLogin("not_exist")).thenReturn(Optional.empty());
+  @Test
+  void getNotExistedUserByLoggedInUser() {
+    when(userRepository.findByLogin("not_exist")).thenReturn(Optional.empty());
 
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> handler.getUser(getRpUser("not_exist", UserRole.USER, ProjectRole.MEMBER, 1L))
-		);
-		assertEquals("User 'not_exist' not found.", exception.getMessage());
-	}
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> handler.getUser(getRpUser("not_exist", UserRole.USER, ProjectRole.MEMBER, 1L))
+    );
+    assertEquals("User 'not_exist' not found.", exception.getMessage());
+  }
 
-	@Test
-	void getEmptyBidInfo() {
-		String uuid = "uuid";
+  @Test
+  void getEmptyBidInfo() {
+    String uuid = "uuid";
 
-		when(userCreationBidRepository.findById(uuid)).thenReturn(Optional.empty());
+    when(userCreationBidRepository.findByUuidAndType(uuid, INTERNAL_BID_TYPE)).thenReturn(
+        Optional.empty());
 
-		UserBidRS bidInformation = handler.getBidInformation(uuid);
-		assertFalse(bidInformation.getIsActive());
-		assertNull(bidInformation.getEmail());
-		assertNull(bidInformation.getUuid());
-	}
+    UserBidRS bidInformation = handler.getBidInformation(uuid);
+    assertFalse(bidInformation.getIsActive());
+    assertNull(bidInformation.getEmail());
+    assertNull(bidInformation.getUuid());
+  }
 
-	@Test
-	void validateInfoByNotExistUsername() {
-		String username = "not_exist";
-		when(userRepository.findByLogin(username)).thenReturn(Optional.empty());
+  @Test
+  void validateInfoByNotExistUsername() {
+    String username = "not_exist";
+    when(userRepository.findByLogin(username)).thenReturn(Optional.empty());
 
-		YesNoRS yesNoRS = handler.validateInfo(username, null);
+    YesNoRS yesNoRS = handler.validateInfo(username, null);
 
-		assertFalse(yesNoRS.getIs());
-	}
+    assertFalse(yesNoRS.getIs());
+  }
 
-	@Test
-	void validateInfoByExistEmail() {
-		String email = "exist@domain.com";
-		when(userRepository.findByEmail(email)).thenReturn(Optional.of(new User()));
+  @Test
+  void validateInfoByExistEmail() {
+    String email = "exist@domain.com";
+    when(userRepository.findByEmail(email)).thenReturn(Optional.of(new User()));
 
-		YesNoRS yesNoRS = handler.validateInfo(null, email);
+    YesNoRS yesNoRS = handler.validateInfo(null, email);
 
-		assertTrue(yesNoRS.getIs());
-	}
+    assertTrue(yesNoRS.getIs());
+  }
 
-	@Test
-	void validateInfoByNotExistEmail() {
-		String email = "not_exist@domain.com";
-		when(userRepository.findByEmail(email)).thenReturn(Optional.empty());
+  @Test
+  void validateInfoByNotExistEmail() {
+    String email = "not_exist@domain.com";
+    when(userRepository.findByEmail(email)).thenReturn(Optional.empty());
 
-		YesNoRS yesNoRS = handler.validateInfo(null, email);
+    YesNoRS yesNoRS = handler.validateInfo(null, email);
 
-		assertFalse(yesNoRS.getIs());
-	}
+    assertFalse(yesNoRS.getIs());
+  }
 
-	@Test
-	void validateInfoNullRequest() {
-		assertFalse(handler.validateInfo(null, null).getIs());
-	}
+  @Test
+  void validateInfoNullRequest() {
+    assertFalse(handler.validateInfo(null, null).getIs());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/generator/FailedViewStateGeneratorTest.java b/src/test/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/generator/FailedViewStateGeneratorTest.java
index 11aa4964ad..fc3bf86f5b 100644
--- a/src/test/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/generator/FailedViewStateGeneratorTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/widget/content/loader/materialized/generator/FailedViewStateGeneratorTest.java
@@ -16,6 +16,12 @@
 
 package com.epam.ta.reportportal.core.widget.content.loader.materialized.generator;
 
+import static com.epam.ta.reportportal.core.widget.content.updater.MaterializedWidgetStateUpdater.STATE;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.querygen.FilterCondition;
 import com.epam.ta.reportportal.core.widget.util.WidgetOptionUtil;
@@ -29,47 +35,49 @@
 import org.springframework.data.domain.Sort;
 import org.springframework.util.LinkedMultiValueMap;
 
-import static com.epam.ta.reportportal.core.widget.content.updater.MaterializedWidgetStateUpdater.STATE;
-import static org.mockito.Mockito.*;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class FailedViewStateGeneratorTest {
 
-	private final ViewGenerator delegate = mock(ViewGenerator.class);
-	private final WidgetRepository widgetRepository = mock(WidgetRepository.class);
+  private final ViewGenerator delegate = mock(ViewGenerator.class);
+  private final WidgetRepository widgetRepository = mock(WidgetRepository.class);
 
-	private final FailedViewStateGenerator generator = new FailedViewStateGenerator(delegate, widgetRepository);
+  private final FailedViewStateGenerator generator = new FailedViewStateGenerator(delegate,
+      widgetRepository);
 
-	@Test
-	void shouldCatchExceptionAndSetFailedState() {
+  @Test
+  void shouldCatchExceptionAndSetFailedState() {
 
-		final boolean refresh = false;
-		final String viewName = "viewName";
-		final Widget widget = getWidget();
-		Sort sort = Sort.unsorted();
-		final LinkedMultiValueMap<String, String> params = new LinkedMultiValueMap<>();
+    final boolean refresh = false;
+    final String viewName = "viewName";
+    final Widget widget = getWidget();
+    Sort sort = Sort.unsorted();
+    final LinkedMultiValueMap<String, String> params = new LinkedMultiValueMap<>();
 
-		Filter filter = Filter.builder().withTarget(Widget.class).withCondition(FilterCondition.builder().eq("id", "1").build()).build();
-		doThrow(RuntimeException.class).when(delegate).generate(refresh, viewName, widget, filter, sort, params);
+    Filter filter = Filter.builder().withTarget(Widget.class)
+        .withCondition(FilterCondition.builder().eq("id", "1").build()).build();
+    doThrow(RuntimeException.class).when(delegate)
+        .generate(refresh, viewName, widget, filter, sort, params);
 
-		generator.generate(refresh, viewName, widget, filter, sort, params);
+    generator.generate(refresh, viewName, widget, filter, sort, params);
 
-		final ArgumentCaptor<Widget> widgetArgumentCaptor = ArgumentCaptor.forClass(Widget.class);
-		verify(widgetRepository, times(1)).save(widgetArgumentCaptor.capture());
+    final ArgumentCaptor<Widget> widgetArgumentCaptor = ArgumentCaptor.forClass(Widget.class);
+    verify(widgetRepository, times(1)).save(widgetArgumentCaptor.capture());
 
-		final Widget failedWidget = widgetArgumentCaptor.getValue();
-		final String failedState = WidgetOptionUtil.getValueByKey(STATE, failedWidget.getWidgetOptions());
+    final Widget failedWidget = widgetArgumentCaptor.getValue();
+    final String failedState = WidgetOptionUtil.getValueByKey(STATE,
+        failedWidget.getWidgetOptions());
 
-		Assertions.assertEquals(WidgetState.FAILED.getValue(), failedState);
+    Assertions.assertEquals(WidgetState.FAILED.getValue(), failedState);
 
-	}
+  }
 
-	private Widget getWidget() {
-		Widget widget = new Widget();
-		widget.setId(1L);
-		widget.setWidgetType("componentHealthCheckTable");
-		return new WidgetBuilder(widget).addProject(1L).addOption(STATE, WidgetState.CREATED.getValue()).get();
-	}
+  private Widget getWidget() {
+    Widget widget = new Widget();
+    widget.setId(1L);
+    widget.setWidgetType("componentHealthCheckTable");
+    return new WidgetBuilder(widget).addProject(1L).addOption(STATE, WidgetState.CREATED.getValue())
+        .get();
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/widget/content/loader/util/healthcheck/HealthCheckTableReadyContentResolverTest.java b/src/test/java/com/epam/ta/reportportal/core/widget/content/loader/util/healthcheck/HealthCheckTableReadyContentResolverTest.java
index 1f949fa7f5..0eededc3c2 100644
--- a/src/test/java/com/epam/ta/reportportal/core/widget/content/loader/util/healthcheck/HealthCheckTableReadyContentResolverTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/widget/content/loader/util/healthcheck/HealthCheckTableReadyContentResolverTest.java
@@ -1,5 +1,14 @@
 package com.epam.ta.reportportal.core.widget.content.loader.util.healthcheck;
 
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.ATTRIBUTES;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.ATTRIBUTE_KEYS;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.EXECUTIONS_PASSED;
+import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.EXECUTIONS_TOTAL;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.core.widget.content.loader.materialized.HealthCheckTableReadyContentLoader;
 import com.epam.ta.reportportal.dao.WidgetContentRepository;
 import com.epam.ta.reportportal.entity.widget.Widget;
@@ -10,80 +19,77 @@
 import com.epam.ta.reportportal.ws.model.widget.WidgetRQ;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.collect.Lists;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import org.junit.jupiter.api.Test;
 import org.springframework.util.LinkedMultiValueMap;
 import org.springframework.util.MultiValueMap;
 
-import java.util.*;
-
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.ATTRIBUTES;
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.ATTRIBUTE_KEYS;
-import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.EXECUTIONS_PASSED;
-import static com.epam.ta.reportportal.dao.constant.WidgetContentRepositoryConstants.EXECUTIONS_TOTAL;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 public class HealthCheckTableReadyContentResolverTest {
 
-	private final WidgetContentRepository widgetContentRepository = mock(WidgetContentRepository.class);
-	private final ObjectMapper objectMapper = new ObjectMapper();
+  private final WidgetContentRepository widgetContentRepository = mock(
+      WidgetContentRepository.class);
+  private final ObjectMapper objectMapper = new ObjectMapper();
 
-	private final HealthCheckTableReadyContentLoader contentResolver = new HealthCheckTableReadyContentLoader(widgetContentRepository,
-			objectMapper
-	);
+  private final HealthCheckTableReadyContentLoader contentResolver = new HealthCheckTableReadyContentLoader(
+      widgetContentRepository,
+      objectMapper
+  );
 
-	@Test
-	void getContentTest() {
+  @Test
+  void getContentTest() {
 
-		WidgetRQ widgetRQ = new WidgetRQ();
-		widgetRQ.setName("name");
+    WidgetRQ widgetRQ = new WidgetRQ();
+    widgetRQ.setName("name");
 
-		widgetRQ.setWidgetType("componentHealthCheckTable");
-		ContentParameters contentParameters = new ContentParameters();
-		contentParameters.setContentFields(new ArrayList<>());
-		contentParameters.setItemsCount(600);
+    widgetRQ.setWidgetType("componentHealthCheckTable");
+    ContentParameters contentParameters = new ContentParameters();
+    contentParameters.setContentFields(new ArrayList<>());
+    contentParameters.setItemsCount(600);
 
-		Map<String, Object> options = new HashMap<>();
+    Map<String, Object> options = new HashMap<>();
 
-		contentParameters.setWidgetOptions(options);
-		widgetRQ.setContentParameters(contentParameters);
-		widgetRQ.setFilterIds(Collections.singletonList(1L));
-		widgetRQ.setDescription("descr");
+    contentParameters.setWidgetOptions(options);
+    widgetRQ.setContentParameters(contentParameters);
+    widgetRQ.setFilterIds(Collections.singletonList(1L));
+    widgetRQ.setDescription("descr");
 
-		SortEntry sortEntry = new SortEntry();
-		sortEntry.setSortingColumn("passingRate");
-		Widget widget = new WidgetBuilder().addWidgetRq(widgetRQ)
-				.addOption("viewName", "name")
-				.addOption("sort", sortEntry)
-				.addOption(ATTRIBUTE_KEYS, Lists.newArrayList("k1", "k2"))
-				.get();
+    SortEntry sortEntry = new SortEntry();
+    sortEntry.setSortingColumn("passingRate");
+    Widget widget = new WidgetBuilder().addWidgetRq(widgetRQ)
+        .addOption("viewName", "name")
+        .addOption("sort", sortEntry)
+        .addOption(ATTRIBUTE_KEYS, Lists.newArrayList("k1", "k2"))
+        .get();
 
-		HealthCheckTableContent content = new HealthCheckTableContent();
-		content.setAttributeValue("v2");
-		content.setPassingRate(50.00);
-		HashMap<String, Integer> statistics = new HashMap<>();
-		statistics.put(EXECUTIONS_PASSED, 5);
-		statistics.put(EXECUTIONS_TOTAL, 10);
-		content.setStatistics(statistics);
+    HealthCheckTableContent content = new HealthCheckTableContent();
+    content.setAttributeValue("v2");
+    content.setPassingRate(50.00);
+    HashMap<String, Integer> statistics = new HashMap<>();
+    statistics.put(EXECUTIONS_PASSED, 5);
+    statistics.put(EXECUTIONS_TOTAL, 10);
+    content.setStatistics(statistics);
 
-		when(widgetContentRepository.componentHealthCheckTable(any())).thenReturn(Lists.newArrayList(content));
+    when(widgetContentRepository.componentHealthCheckTable(any())).thenReturn(
+        Lists.newArrayList(content));
 
-		MultiValueMap<String, String> values = new LinkedMultiValueMap<>();
-		values.put(ATTRIBUTES, Lists.newArrayList("v1"));
+    MultiValueMap<String, String> values = new LinkedMultiValueMap<>();
+    values.put(ATTRIBUTES, Lists.newArrayList("v1"));
 
-		Map<String, Object> result = contentResolver.loadContent(widget, values);
+    Map<String, Object> result = contentResolver.loadContent(widget, values);
 
-		List<HealthCheckTableContent> resultList = (List<HealthCheckTableContent>) result.get("result");
+    List<HealthCheckTableContent> resultList = (List<HealthCheckTableContent>) result.get("result");
 
-		HealthCheckTableContent tableContent = resultList.get(0);
+    HealthCheckTableContent tableContent = resultList.get(0);
 
-		assertEquals(content.getPassingRate(), tableContent.getPassingRate());
-		assertEquals(content.getAttributeValue(), tableContent.getAttributeValue());
-	}
+    assertEquals(content.getPassingRate(), tableContent.getPassingRate());
+    assertEquals(content.getAttributeValue(), tableContent.getAttributeValue());
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/widget/content/materialized/generator/MaterializedViewNameGeneratorTest.java b/src/test/java/com/epam/ta/reportportal/core/widget/content/materialized/generator/MaterializedViewNameGeneratorTest.java
index d5468c9f1e..c4856b336d 100644
--- a/src/test/java/com/epam/ta/reportportal/core/widget/content/materialized/generator/MaterializedViewNameGeneratorTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/widget/content/materialized/generator/MaterializedViewNameGeneratorTest.java
@@ -18,40 +18,39 @@
 
 import com.epam.ta.reportportal.entity.project.Project;
 import com.epam.ta.reportportal.entity.widget.Widget;
+import java.util.stream.Stream;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
 
-import java.util.stream.Stream;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class MaterializedViewNameGeneratorTest {
 
-	private final MaterializedViewNameGenerator generator = new MaterializedViewNameGenerator();
-
-	private static Stream<Arguments> provideData() {
-		return Stream.of(Arguments.of("widget_1_1", getWidget(1L, 1L)),
-				Arguments.of("widget_1_2", getWidget(2L, 1L)),
-				Arguments.of("widget_2_1", getWidget(1L, 2L))
-		);
-	}
-
-	private static Widget getWidget(Long id, Long projectId) {
-		final Widget widget = new Widget();
-		widget.setId(id);
-		final Project project = new Project();
-		project.setId(projectId);
-		widget.setProject(project);
-		return widget;
-	}
-
-	@ParameterizedTest
-	@MethodSource("provideData")
-	void generate(String expectedName, Widget widget) {
-		Assertions.assertEquals(expectedName, generator.generate(widget));
-	}
+  private final MaterializedViewNameGenerator generator = new MaterializedViewNameGenerator();
+
+  private static Stream<Arguments> provideData() {
+    return Stream.of(Arguments.of("widget_1_1", getWidget(1L, 1L)),
+        Arguments.of("widget_1_2", getWidget(2L, 1L)),
+        Arguments.of("widget_2_1", getWidget(1L, 2L))
+    );
+  }
+
+  private static Widget getWidget(Long id, Long projectId) {
+    final Widget widget = new Widget();
+    widget.setId(id);
+    final Project project = new Project();
+    project.setId(projectId);
+    widget.setProject(project);
+    return widget;
+  }
+
+  @ParameterizedTest
+  @MethodSource("provideData")
+  void generate(String expectedName, Widget widget) {
+    Assertions.assertEquals(expectedName, generator.generate(widget));
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/widget/content/remover/DelegatingStateContentRemoverTest.java b/src/test/java/com/epam/ta/reportportal/core/widget/content/remover/DelegatingStateContentRemoverTest.java
index 4ac37d772a..29fc705a56 100644
--- a/src/test/java/com/epam/ta/reportportal/core/widget/content/remover/DelegatingStateContentRemoverTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/widget/content/remover/DelegatingStateContentRemoverTest.java
@@ -16,50 +16,55 @@
 
 package com.epam.ta.reportportal.core.widget.content.remover;
 
+import static com.epam.ta.reportportal.entity.widget.WidgetType.COMPONENT_HEALTH_CHECK;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.core.widget.content.materialized.state.WidgetStateResolver;
 import com.epam.ta.reportportal.entity.widget.Widget;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.entity.widget.WidgetState;
+import java.util.Map;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.ValueSource;
 
-import java.util.Map;
-
-import static com.epam.ta.reportportal.entity.widget.WidgetType.*;
-import static org.mockito.Mockito.*;
-
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
  */
 class DelegatingStateContentRemoverTest {
 
-	private final WidgetStateResolver widgetStateResolver = mock(WidgetStateResolver.class);
+  private final WidgetStateResolver widgetStateResolver = mock(WidgetStateResolver.class);
 
-	private final WidgetContentRemover remover = mock(WidgetContentRemover.class);
-	private final Map<WidgetState, WidgetContentRemover> removerMapping = Map.of(WidgetState.RENDERING, remover);
+  private final WidgetContentRemover remover = mock(WidgetContentRemover.class);
+  private final Map<WidgetState, WidgetContentRemover> removerMapping = Map.of(
+      WidgetState.RENDERING, remover);
 
-	private final DelegatingStateContentRemover delegatingStateContentRemover = new DelegatingStateContentRemover(widgetStateResolver,
-			removerMapping
-	);
+  private final DelegatingStateContentRemover delegatingStateContentRemover = new DelegatingStateContentRemover(
+      widgetStateResolver,
+      removerMapping
+  );
 
-	@ParameterizedTest
-	@ValueSource(strings = { "cumulative", "componentHealthCheckTable" })
-	void supports(String type) {
-		final Widget widget = new Widget();
-		widget.setWidgetType(type);
+  @ParameterizedTest
+  @ValueSource(strings = {"cumulative", "componentHealthCheckTable"})
+  void supports(String type) {
+    final Widget widget = new Widget();
+    widget.setWidgetType(type);
 
-		when(widgetStateResolver.resolve(widget.getWidgetOptions())).thenReturn(WidgetState.RENDERING);
+    when(widgetStateResolver.resolve(widget.getWidgetOptions())).thenReturn(WidgetState.RENDERING);
 
-		delegatingStateContentRemover.removeContent(widget);
-		verify(remover, times(1)).removeContent(widget);
-	}
+    delegatingStateContentRemover.removeContent(widget);
+    verify(remover, times(1)).removeContent(widget);
+  }
 
-	@Test
-	void supportsHealthNegative() {
-		final Widget widget = new Widget();
-		widget.setWidgetType(COMPONENT_HEALTH_CHECK.getType());
-		delegatingStateContentRemover.removeContent(widget);
-		verify(widgetStateResolver, times(0)).resolve(any(WidgetOptions.class));
-	}
+  @Test
+  void supportsHealthNegative() {
+    final Widget widget = new Widget();
+    widget.setWidgetType(COMPONENT_HEALTH_CHECK.getType());
+    delegatingStateContentRemover.removeContent(widget);
+    verify(widgetStateResolver, times(0)).resolve(any(WidgetOptions.class));
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/widget/content/remover/MaterializedViewRemoverTest.java b/src/test/java/com/epam/ta/reportportal/core/widget/content/remover/MaterializedViewRemoverTest.java
index 4c042f5b77..61747243d0 100644
--- a/src/test/java/com/epam/ta/reportportal/core/widget/content/remover/MaterializedViewRemoverTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/widget/content/remover/MaterializedViewRemoverTest.java
@@ -16,33 +16,36 @@
 
 package com.epam.ta.reportportal.core.widget.content.remover;
 
+import static com.epam.ta.reportportal.core.widget.content.loader.materialized.handler.MaterializedWidgetStateHandler.VIEW_NAME;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
 import com.epam.ta.reportportal.dao.WidgetContentRepository;
 import com.epam.ta.reportportal.entity.widget.Widget;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
-import org.junit.jupiter.api.Test;
-
 import java.util.Map;
-
-import static com.epam.ta.reportportal.core.widget.content.loader.materialized.handler.MaterializedWidgetStateHandler.VIEW_NAME;
-import static org.mockito.Mockito.*;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class MaterializedViewRemoverTest {
 
-	private final WidgetContentRepository widgetContentRepository = mock(WidgetContentRepository.class);
-	private final MaterializedViewRemover materializedViewRemover = new MaterializedViewRemover(widgetContentRepository);
+  private final WidgetContentRepository widgetContentRepository = mock(
+      WidgetContentRepository.class);
+  private final MaterializedViewRemover materializedViewRemover = new MaterializedViewRemover(
+      widgetContentRepository);
 
-	@Test
-	void shouldRemove() {
-		final Widget widget = new Widget();
-		final String viewName = "name";
-		widget.setWidgetOptions(new WidgetOptions(Map.of(VIEW_NAME, viewName)));
+  @Test
+  void shouldRemove() {
+    final Widget widget = new Widget();
+    final String viewName = "name";
+    widget.setWidgetOptions(new WidgetOptions(Map.of(VIEW_NAME, viewName)));
 
-		materializedViewRemover.removeContent(widget);
+    materializedViewRemover.removeContent(widget);
 
-		verify(widgetContentRepository, times(1)).removeWidgetView(viewName);
-	}
+    verify(widgetContentRepository, times(1)).removeWidgetView(viewName);
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/widget/content/remover/StaleMaterializedViewRemoverTest.java b/src/test/java/com/epam/ta/reportportal/core/widget/content/remover/StaleMaterializedViewRemoverTest.java
index 722982f284..12550c6e83 100644
--- a/src/test/java/com/epam/ta/reportportal/core/widget/content/remover/StaleMaterializedViewRemoverTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/widget/content/remover/StaleMaterializedViewRemoverTest.java
@@ -16,6 +16,11 @@
 
 package com.epam.ta.reportportal.core.widget.content.remover;
 
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.core.widget.content.materialized.generator.MaterializedViewNameGenerator;
 import com.epam.ta.reportportal.dao.StaleMaterializedViewRepository;
 import com.epam.ta.reportportal.entity.materialized.StaleMaterializedView;
@@ -24,35 +29,37 @@
 import org.junit.jupiter.api.Test;
 import org.mockito.ArgumentCaptor;
 
-import static org.mockito.Mockito.*;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class StaleMaterializedViewRemoverTest {
 
-	private final MaterializedViewNameGenerator nameGenerator = mock(MaterializedViewNameGenerator.class);
-	private final StaleMaterializedViewRepository staleMaterializedViewRepository = mock(StaleMaterializedViewRepository.class);
-	private final StaleMaterializedViewRemover staleMaterializedViewRemover = new StaleMaterializedViewRemover(nameGenerator,
-			staleMaterializedViewRepository
-	);
+  private final MaterializedViewNameGenerator nameGenerator = mock(
+      MaterializedViewNameGenerator.class);
+  private final StaleMaterializedViewRepository staleMaterializedViewRepository = mock(
+      StaleMaterializedViewRepository.class);
+  private final StaleMaterializedViewRemover staleMaterializedViewRemover = new StaleMaterializedViewRemover(
+      nameGenerator,
+      staleMaterializedViewRepository
+  );
 
-	@Test
-	void shouldSaveStaleView() {
-		final Widget widget = new Widget();
+  @Test
+  void shouldSaveStaleView() {
+    final Widget widget = new Widget();
 
-		final String viewName = "widget_1_1";
-		when(nameGenerator.generate(widget)).thenReturn(viewName);
+    final String viewName = "widget_1_1";
+    when(nameGenerator.generate(widget)).thenReturn(viewName);
 
-		staleMaterializedViewRemover.removeContent(widget);
+    staleMaterializedViewRemover.removeContent(widget);
 
-		final ArgumentCaptor<StaleMaterializedView> viewArgumentCaptor = ArgumentCaptor.forClass(StaleMaterializedView.class);
-		verify(staleMaterializedViewRepository, times(1)).insert(viewArgumentCaptor.capture());
+    final ArgumentCaptor<StaleMaterializedView> viewArgumentCaptor = ArgumentCaptor.forClass(
+        StaleMaterializedView.class);
+    verify(staleMaterializedViewRepository, times(1)).insert(viewArgumentCaptor.capture());
 
-		final StaleMaterializedView view = viewArgumentCaptor.getValue();
+    final StaleMaterializedView view = viewArgumentCaptor.getValue();
 
-		Assertions.assertEquals(viewName, view.getName());
-		Assertions.assertNotNull(view.getCreationDate());
-	}
+    Assertions.assertEquals(viewName, view.getName());
+    Assertions.assertNotNull(view.getCreationDate());
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/ActivityContentValidatorTest.java b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/ActivityContentValidatorTest.java
index f79ab45cce..850d6443c0 100644
--- a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/ActivityContentValidatorTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/ActivityContentValidatorTest.java
@@ -1,34 +1,34 @@
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.exception.ReportPortalException;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
 import java.util.Collections;
 import java.util.HashMap;
-
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 
 public class ActivityContentValidatorTest {
 
-	private WidgetValidatorStrategy activityContentValidator;
+  private WidgetValidatorStrategy activityContentValidator;
 
-	@BeforeEach
-	public void setUp() {
-		activityContentValidator = new ActivityContentValidator();
-	}
+  @BeforeEach
+  public void setUp() {
+    activityContentValidator = new ActivityContentValidator();
+  }
 
-	@Test
-	public void testValidateWithException() {
-		Exception exception = assertThrows(ReportPortalException.class, () -> {
-			activityContentValidator.validate(Collections.singletonList("test"), new HashMap<>(), new WidgetOptions(), 5);
-		});
+  @Test
+  public void testValidateWithException() {
+    Exception exception = assertThrows(ReportPortalException.class, () -> {
+      activityContentValidator.validate(Collections.singletonList("test"), new HashMap<>(),
+          new WidgetOptions(), 5);
+    });
 
-		String expectedMessage = "Filter-Sort mapping should not be empty";
-		String actualMessage = exception.getMessage();
-		assertTrue(actualMessage.contains(expectedMessage));
-	}
+    String expectedMessage = "Filter-Sort mapping should not be empty";
+    String actualMessage = exception.getMessage();
+    assertTrue(actualMessage.contains(expectedMessage));
+  }
 
 }
diff --git a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/BugTrendChartContentValidatorTest.java b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/BugTrendChartContentValidatorTest.java
index be91486589..60c4ed99e9 100644
--- a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/BugTrendChartContentValidatorTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/BugTrendChartContentValidatorTest.java
@@ -1,44 +1,46 @@
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.querygen.FilterCondition;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.exception.ReportPortalException;
+import java.util.Collections;
+import java.util.HashMap;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.springframework.data.domain.Sort;
 
-import java.util.Collections;
-import java.util.HashMap;
-
-import static org.junit.jupiter.api.Assertions.*;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class BugTrendChartContentValidatorTest {
 
-	private WidgetValidatorStrategy bugTrendChartContentValidator;
-
-	@BeforeEach
-	public void setUp() {
-		bugTrendChartContentValidator = new BugTrendChartContentValidator();
-	}
-
-	@Test
-	public void testValidateWithException() {
-		Exception exception = assertThrows(ReportPortalException.class, () -> {
-			HashMap<Filter, Sort> filterSortMap = new HashMap<>();
-			filterSortMap.put(Filter.builder()
-					.withTarget(Launch.class)
-					.withCondition(FilterCondition.builder().eq("id", "1").build())
-					.build(), Sort.unsorted());
-			bugTrendChartContentValidator.validate(Collections.singletonList("statistics$defects$automation_bug$total'"), filterSortMap, new WidgetOptions(), 5);
-		});
-
-		String expectedMessage = "Bad content fields format";
-		String actualMessage = exception.getMessage();
-		assertTrue(actualMessage.contains(expectedMessage));
-	}
+  private WidgetValidatorStrategy bugTrendChartContentValidator;
+
+  @BeforeEach
+  public void setUp() {
+    bugTrendChartContentValidator = new BugTrendChartContentValidator();
+  }
+
+  @Test
+  public void testValidateWithException() {
+    Exception exception = assertThrows(ReportPortalException.class, () -> {
+      HashMap<Filter, Sort> filterSortMap = new HashMap<>();
+      filterSortMap.put(Filter.builder()
+          .withTarget(Launch.class)
+          .withCondition(FilterCondition.builder().eq("id", "1").build())
+          .build(), Sort.unsorted());
+      bugTrendChartContentValidator.validate(
+          Collections.singletonList("statistics$defects$automation_bug$total'"), filterSortMap,
+          new WidgetOptions(), 5);
+    });
+
+    String expectedMessage = "Bad content fields format";
+    String actualMessage = exception.getMessage();
+    assertTrue(actualMessage.contains(expectedMessage));
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/CasesTrendContentValidatorTest.java b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/CasesTrendContentValidatorTest.java
index 13d180a7c1..7ccdfd089b 100644
--- a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/CasesTrendContentValidatorTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/CasesTrendContentValidatorTest.java
@@ -1,45 +1,45 @@
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.querygen.FilterCondition;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.exception.ReportPortalException;
+import java.util.Collections;
+import java.util.HashMap;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.springframework.data.domain.Sort;
 
-import java.util.Collections;
-import java.util.HashMap;
-
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class CasesTrendContentValidatorTest {
 
-	private WidgetValidatorStrategy casesTrendContentValidator;
-
-	@BeforeEach
-	public void setUp() {
-		casesTrendContentValidator = new CasesTrendContentValidator();
-	}
-
-	@Test
-	public void testValidateWithException() {
-		Exception exception = assertThrows(ReportPortalException.class, () -> {
-			HashMap<Filter, Sort> filterSortMap = new HashMap<>();
-			filterSortMap.put(Filter.builder()
-					.withTarget(Launch.class)
-					.withCondition(FilterCondition.builder().eq("id", "1").build())
-					.build(), Sort.unsorted());
-			casesTrendContentValidator.validate(Collections.singletonList("test"), filterSortMap, new WidgetOptions(), 5);
-		});
-
-		String expectedMessage = "Bad content fields format";
-		String actualMessage = exception.getMessage();
-		assertTrue(actualMessage.contains(expectedMessage));
-	}
+  private WidgetValidatorStrategy casesTrendContentValidator;
+
+  @BeforeEach
+  public void setUp() {
+    casesTrendContentValidator = new CasesTrendContentValidator();
+  }
+
+  @Test
+  public void testValidateWithException() {
+    Exception exception = assertThrows(ReportPortalException.class, () -> {
+      HashMap<Filter, Sort> filterSortMap = new HashMap<>();
+      filterSortMap.put(Filter.builder()
+          .withTarget(Launch.class)
+          .withCondition(FilterCondition.builder().eq("id", "1").build())
+          .build(), Sort.unsorted());
+      casesTrendContentValidator.validate(Collections.singletonList("test"), filterSortMap,
+          new WidgetOptions(), 5);
+    });
+
+    String expectedMessage = "Bad content fields format";
+    String actualMessage = exception.getMessage();
+    assertTrue(actualMessage.contains(expectedMessage));
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/ChartInvestigatedContentValidatorTest.java b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/ChartInvestigatedContentValidatorTest.java
index 2b73b0fb22..b989b56794 100644
--- a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/ChartInvestigatedContentValidatorTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/ChartInvestigatedContentValidatorTest.java
@@ -1,37 +1,37 @@
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.exception.ReportPortalException;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
 import java.util.Collections;
 import java.util.HashMap;
-
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class ChartInvestigatedContentValidatorTest {
 
-	private WidgetValidatorStrategy chartInvestigatedContentValidator;
+  private WidgetValidatorStrategy chartInvestigatedContentValidator;
 
-	@BeforeEach
-	public void setUp() {
-		chartInvestigatedContentValidator = new ChartInvestigatedContentValidator();
-	}
+  @BeforeEach
+  public void setUp() {
+    chartInvestigatedContentValidator = new ChartInvestigatedContentValidator();
+  }
 
-	@Test
-	public void testValidateWithException() {
-		Exception exception = assertThrows(ReportPortalException.class, () -> {
-			chartInvestigatedContentValidator.validate(Collections.singletonList("test"), new HashMap<>(), new WidgetOptions(), 5);
-		});
+  @Test
+  public void testValidateWithException() {
+    Exception exception = assertThrows(ReportPortalException.class, () -> {
+      chartInvestigatedContentValidator.validate(Collections.singletonList("test"), new HashMap<>(),
+          new WidgetOptions(), 5);
+    });
 
-		String expectedMessage = "Filter-Sort mapping should not be empty";
-		String actualMessage = exception.getMessage();
-		assertTrue(actualMessage.contains(expectedMessage));
-	}
+    String expectedMessage = "Filter-Sort mapping should not be empty";
+    String actualMessage = exception.getMessage();
+    assertTrue(actualMessage.contains(expectedMessage));
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/ComponentHealthCheckContentValidatorTest.java b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/ComponentHealthCheckContentValidatorTest.java
index 302e099221..6de71ce07f 100644
--- a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/ComponentHealthCheckContentValidatorTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/ComponentHealthCheckContentValidatorTest.java
@@ -1,76 +1,75 @@
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.ATTRIBUTE_KEYS;
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.MIN_PASSING_RATE;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.google.common.collect.Lists;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
-
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.ATTRIBUTE_KEYS;
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.MIN_PASSING_RATE;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class ComponentHealthCheckContentValidatorTest {
 
-	private MultilevelValidatorStrategy сomponentHealthCheckContentValidator;
+  private MultilevelValidatorStrategy сomponentHealthCheckContentValidator;
 
-	@BeforeEach
-	public void setUp() {
-		сomponentHealthCheckContentValidator = new ComponentHealthCheckContentValidator();
-	}
+  @BeforeEach
+  public void setUp() {
+    сomponentHealthCheckContentValidator = new ComponentHealthCheckContentValidator();
+  }
 
-	@Test
-	public void testValidateWithException() {
-		WidgetOptions widgetOptions = new WidgetOptions(getWidgetOptionsContentWithBlankKey());
-		Exception exception = assertThrows(ReportPortalException.class,
-				() -> сomponentHealthCheckContentValidator.validate(Collections.singletonList("test"),
-						new HashMap<>(),
-						widgetOptions,
-						new String[] { "v1" },
-						new HashMap<>(),
-						100
-				)
-		);
+  @Test
+  public void testValidateWithException() {
+    WidgetOptions widgetOptions = new WidgetOptions(getWidgetOptionsContentWithBlankKey());
+    Exception exception = assertThrows(ReportPortalException.class,
+        () -> сomponentHealthCheckContentValidator.validate(Collections.singletonList("test"),
+            new HashMap<>(),
+            widgetOptions,
+            new String[]{"v1"},
+            new HashMap<>(),
+            100
+        )
+    );
 
-		String expectedMessage = "Current level key should be not blank";
-		String actualMessage = exception.getMessage();
-		assertTrue(actualMessage.contains(expectedMessage));
+    String expectedMessage = "Current level key should be not blank";
+    String actualMessage = exception.getMessage();
+    assertTrue(actualMessage.contains(expectedMessage));
 
-		WidgetOptions wo = new WidgetOptions(getWidgetOptionsContent());
-		сomponentHealthCheckContentValidator.validate(Collections.singletonList("test"),
-				new HashMap<>(),
-				wo,
-				new String[] { "v1" },
-				new HashMap<>(),
-				100
-		);
-	}
+    WidgetOptions wo = new WidgetOptions(getWidgetOptionsContent());
+    сomponentHealthCheckContentValidator.validate(Collections.singletonList("test"),
+        new HashMap<>(),
+        wo,
+        new String[]{"v1"},
+        new HashMap<>(),
+        100
+    );
+  }
 
-	private Map<String, Object> getWidgetOptionsContent() {
-		Map<String, Object> content = new HashMap<>();
+  private Map<String, Object> getWidgetOptionsContent() {
+    Map<String, Object> content = new HashMap<>();
 
-		content.put(ATTRIBUTE_KEYS, Lists.newArrayList("k1", "k2"));
-		content.put(MIN_PASSING_RATE, 50);
+    content.put(ATTRIBUTE_KEYS, Lists.newArrayList("k1", "k2"));
+    content.put(MIN_PASSING_RATE, 50);
 
-		return content;
+    return content;
 
-	}
+  }
 
-	private Map<String, Object> getWidgetOptionsContentWithBlankKey() {
-		Map<String, Object> content = new HashMap<>();
+  private Map<String, Object> getWidgetOptionsContentWithBlankKey() {
+    Map<String, Object> content = new HashMap<>();
 
-		content.put(ATTRIBUTE_KEYS, Lists.newArrayList("k1", ""));
-		content.put(MIN_PASSING_RATE, 50);
+    content.put(ATTRIBUTE_KEYS, Lists.newArrayList("k1", ""));
+    content.put(MIN_PASSING_RATE, 50);
 
-		return content;
+    return content;
 
-	}
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/CumulativeTrendChartValidatorTest.java b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/CumulativeTrendChartValidatorTest.java
index c8eca151e3..41c33277a9 100644
--- a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/CumulativeTrendChartValidatorTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/CumulativeTrendChartValidatorTest.java
@@ -1,7 +1,5 @@
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
-import static org.junit.jupiter.api.Assertions.*;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
diff --git a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/FlakyCasesTableContentValidatorTest.java b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/FlakyCasesTableContentValidatorTest.java
index a28705dfd7..c4fc0a9fc2 100644
--- a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/FlakyCasesTableContentValidatorTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/FlakyCasesTableContentValidatorTest.java
@@ -4,7 +4,6 @@
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-
 import java.util.HashMap;
 import java.util.Map;
 
diff --git a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchExecutionAndIssueStatisticsContentValidatorTest.java b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchExecutionAndIssueStatisticsContentValidatorTest.java
index b4d4bd0dd5..0249e9a58b 100644
--- a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchExecutionAndIssueStatisticsContentValidatorTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchExecutionAndIssueStatisticsContentValidatorTest.java
@@ -1,44 +1,45 @@
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.querygen.FilterCondition;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.exception.ReportPortalException;
+import java.util.Collections;
+import java.util.HashMap;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.springframework.data.domain.Sort;
 
-import java.util.Collections;
-import java.util.HashMap;
-
-import static org.junit.jupiter.api.Assertions.*;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class LaunchExecutionAndIssueStatisticsContentValidatorTest {
 
-	private WidgetValidatorStrategy launchExecutionAndIssueStatisticsContentValidator;
-
-	@BeforeEach
-	public void setUp() {
-		launchExecutionAndIssueStatisticsContentValidator = new LaunchExecutionAndIssueStatisticsContentValidator();
-	}
-
-	@Test
-	public void testValidateWithException() {
-		Exception exception = assertThrows(ReportPortalException.class, () -> {
-			HashMap<Filter, Sort> filterSortMap = new HashMap<>();
-			filterSortMap.put(Filter.builder()
-					.withTarget(Launch.class)
-					.withCondition(FilterCondition.builder().eq("id", "1").build())
-					.build(), Sort.unsorted());
-			launchExecutionAndIssueStatisticsContentValidator.validate(Collections.singletonList("test"), filterSortMap, new WidgetOptions(), 5);
-		});
-
-		String expectedMessage = "Bad content fields format";
-		String actualMessage = exception.getMessage();
-		assertTrue(actualMessage.contains(expectedMessage));
-	}
+  private WidgetValidatorStrategy launchExecutionAndIssueStatisticsContentValidator;
+
+  @BeforeEach
+  public void setUp() {
+    launchExecutionAndIssueStatisticsContentValidator = new LaunchExecutionAndIssueStatisticsContentValidator();
+  }
+
+  @Test
+  public void testValidateWithException() {
+    Exception exception = assertThrows(ReportPortalException.class, () -> {
+      HashMap<Filter, Sort> filterSortMap = new HashMap<>();
+      filterSortMap.put(Filter.builder()
+          .withTarget(Launch.class)
+          .withCondition(FilterCondition.builder().eq("id", "1").build())
+          .build(), Sort.unsorted());
+      launchExecutionAndIssueStatisticsContentValidator.validate(Collections.singletonList("test"),
+          filterSortMap, new WidgetOptions(), 5);
+    });
+
+    String expectedMessage = "Bad content fields format";
+    String actualMessage = exception.getMessage();
+    assertTrue(actualMessage.contains(expectedMessage));
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchesComparisonContentValidatorTest.java b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchesComparisonContentValidatorTest.java
index 7dd0f4879c..b3d0ca58e1 100644
--- a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchesComparisonContentValidatorTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchesComparisonContentValidatorTest.java
@@ -1,44 +1,45 @@
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.querygen.FilterCondition;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.exception.ReportPortalException;
+import java.util.Collections;
+import java.util.HashMap;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.springframework.data.domain.Sort;
 
-import java.util.Collections;
-import java.util.HashMap;
-
-import static org.junit.jupiter.api.Assertions.*;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class LaunchesComparisonContentValidatorTest {
 
-	private WidgetValidatorStrategy launchesComparisonContentValidator;
-
-	@BeforeEach
-	public void setUp() {
-		launchesComparisonContentValidator = new LaunchesComparisonContentValidator();
-	}
-
-	@Test
-	public void testValidateWithException() {
-		Exception exception = assertThrows(ReportPortalException.class, () -> {
-			HashMap<Filter, Sort> filterSortMap = new HashMap<>();
-			filterSortMap.put(Filter.builder()
-					.withTarget(Launch.class)
-					.withCondition(FilterCondition.builder().eq("id", "1").build())
-					.build(), Sort.unsorted());
-			launchesComparisonContentValidator.validate(Collections.singletonList("test"), filterSortMap, new WidgetOptions(), 5);
-		});
-
-		String expectedMessage = "Bad content fields format";
-		String actualMessage = exception.getMessage();
-		assertTrue(actualMessage.contains(expectedMessage));
-	}
+  private WidgetValidatorStrategy launchesComparisonContentValidator;
+
+  @BeforeEach
+  public void setUp() {
+    launchesComparisonContentValidator = new LaunchesComparisonContentValidator();
+  }
+
+  @Test
+  public void testValidateWithException() {
+    Exception exception = assertThrows(ReportPortalException.class, () -> {
+      HashMap<Filter, Sort> filterSortMap = new HashMap<>();
+      filterSortMap.put(Filter.builder()
+          .withTarget(Launch.class)
+          .withCondition(FilterCondition.builder().eq("id", "1").build())
+          .build(), Sort.unsorted());
+      launchesComparisonContentValidator.validate(Collections.singletonList("test"), filterSortMap,
+          new WidgetOptions(), 5);
+    });
+
+    String expectedMessage = "Bad content fields format";
+    String actualMessage = exception.getMessage();
+    assertTrue(actualMessage.contains(expectedMessage));
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchesDurationContentValidatorTest.java b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchesDurationContentValidatorTest.java
index d505151392..dec6a1a18d 100644
--- a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchesDurationContentValidatorTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchesDurationContentValidatorTest.java
@@ -1,36 +1,36 @@
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.exception.ReportPortalException;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
 import java.util.Collections;
 import java.util.HashMap;
-
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class LaunchesDurationContentValidatorTest {
 
-	private WidgetValidatorStrategy launchesDurationContentValidator;
+  private WidgetValidatorStrategy launchesDurationContentValidator;
 
-	@BeforeEach
-	public void setUp() {
-		launchesDurationContentValidator = new LaunchesDurationContentValidator();
-	}
+  @BeforeEach
+  public void setUp() {
+    launchesDurationContentValidator = new LaunchesDurationContentValidator();
+  }
 
-	@Test
-	public void testValidateWithException() {
-		Exception exception = assertThrows(ReportPortalException.class, () -> {
-			launchesDurationContentValidator.validate(Collections.singletonList("test"), new HashMap<>(), new WidgetOptions(), 5);
-		});
+  @Test
+  public void testValidateWithException() {
+    Exception exception = assertThrows(ReportPortalException.class, () -> {
+      launchesDurationContentValidator.validate(Collections.singletonList("test"), new HashMap<>(),
+          new WidgetOptions(), 5);
+    });
 
-		String expectedMessage = "Filter-Sort mapping should not be empty";
-		String actualMessage = exception.getMessage();
-		assertTrue(actualMessage.contains(expectedMessage));
-	}
+    String expectedMessage = "Filter-Sort mapping should not be empty";
+    String actualMessage = exception.getMessage();
+    assertTrue(actualMessage.contains(expectedMessage));
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchesTableContentValidatorTest.java b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchesTableContentValidatorTest.java
index 5b4f68ab43..f464796a57 100644
--- a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchesTableContentValidatorTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/LaunchesTableContentValidatorTest.java
@@ -1,45 +1,45 @@
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.querygen.FilterCondition;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.exception.ReportPortalException;
+import java.util.ArrayList;
+import java.util.HashMap;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.springframework.data.domain.Sort;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class LaunchesTableContentValidatorTest {
 
-	private WidgetValidatorStrategy launchesTableContentValidator;
-
-	@BeforeEach
-	public void setUp() {
-		launchesTableContentValidator = new LaunchesTableContentValidator();
-	}
-
-	@Test
-	public void testValidateWithException() {
-		Exception exception = assertThrows(ReportPortalException.class, () -> {
-			HashMap<Filter, Sort> filterSortMap = new HashMap<>();
-			filterSortMap.put(Filter.builder()
-					.withTarget(Launch.class)
-					.withCondition(FilterCondition.builder().eq("id", "1").build())
-					.build(), Sort.unsorted());
-			launchesTableContentValidator.validate(new ArrayList<>(), filterSortMap, new WidgetOptions(), 5);
-		});
-
-		String expectedMessage = "Content fields should not be empty";
-		String actualMessage = exception.getMessage();
-		assertTrue(actualMessage.contains(expectedMessage));
-	}
+  private WidgetValidatorStrategy launchesTableContentValidator;
+
+  @BeforeEach
+  public void setUp() {
+    launchesTableContentValidator = new LaunchesTableContentValidator();
+  }
+
+  @Test
+  public void testValidateWithException() {
+    Exception exception = assertThrows(ReportPortalException.class, () -> {
+      HashMap<Filter, Sort> filterSortMap = new HashMap<>();
+      filterSortMap.put(Filter.builder()
+          .withTarget(Launch.class)
+          .withCondition(FilterCondition.builder().eq("id", "1").build())
+          .build(), Sort.unsorted());
+      launchesTableContentValidator.validate(new ArrayList<>(), filterSortMap, new WidgetOptions(),
+          5);
+    });
+
+    String expectedMessage = "Content fields should not be empty";
+    String actualMessage = exception.getMessage();
+    assertTrue(actualMessage.contains(expectedMessage));
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/MostTimeConsumingContentValidatorTest.java b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/MostTimeConsumingContentValidatorTest.java
index 83053d5119..5f349548b3 100644
--- a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/MostTimeConsumingContentValidatorTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/MostTimeConsumingContentValidatorTest.java
@@ -1,52 +1,51 @@
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LAUNCH_NAME_FIELD;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.querygen.FilterCondition;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.exception.ReportPortalException;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.springframework.data.domain.Sort;
-
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
-
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LAUNCH_NAME_FIELD;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.data.domain.Sort;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class MostTimeConsumingContentValidatorTest {
 
-	private WidgetValidatorStrategy mostTimeConsumingContentValidator;
-
-	@BeforeEach
-	public void setUp() {
-		mostTimeConsumingContentValidator = new MostTimeConsumingContentValidator();
-	}
-
-	@Test
-	public void testValidateWithException() {
-		Exception exception = assertThrows(ReportPortalException.class, () -> {
-			HashMap<Filter, Sort> filterSortMap = new HashMap<>();
-			filterSortMap.put(Filter.builder()
-					.withTarget(Launch.class)
-					.withCondition(FilterCondition.builder().eq("id", "1").build())
-					.build(), Sort.unsorted());
-			Map<String, Object> params = new HashMap<>();
-			params.put(LAUNCH_NAME_FIELD, "");
-			WidgetOptions widgetOptions = new WidgetOptions();
-			mostTimeConsumingContentValidator.validate(Collections.singletonList("test"), filterSortMap,
-					widgetOptions, 5);
-		});
-
-		String expectedMessage = LAUNCH_NAME_FIELD + " should be specified for widget.";
-		String actualMessage = exception.getMessage();
-		assertTrue(actualMessage.contains(expectedMessage));
-	}
+  private WidgetValidatorStrategy mostTimeConsumingContentValidator;
+
+  @BeforeEach
+  public void setUp() {
+    mostTimeConsumingContentValidator = new MostTimeConsumingContentValidator();
+  }
+
+  @Test
+  public void testValidateWithException() {
+    Exception exception = assertThrows(ReportPortalException.class, () -> {
+      HashMap<Filter, Sort> filterSortMap = new HashMap<>();
+      filterSortMap.put(Filter.builder()
+          .withTarget(Launch.class)
+          .withCondition(FilterCondition.builder().eq("id", "1").build())
+          .build(), Sort.unsorted());
+      Map<String, Object> params = new HashMap<>();
+      params.put(LAUNCH_NAME_FIELD, "");
+      WidgetOptions widgetOptions = new WidgetOptions();
+      mostTimeConsumingContentValidator.validate(Collections.singletonList("test"), filterSortMap,
+          widgetOptions, 5);
+    });
+
+    String expectedMessage = LAUNCH_NAME_FIELD + " should be specified for widget.";
+    String actualMessage = exception.getMessage();
+    assertTrue(actualMessage.contains(expectedMessage));
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/NotPassedTestsContentValidatorTest.java b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/NotPassedTestsContentValidatorTest.java
index d783562439..b712f2cafe 100644
--- a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/NotPassedTestsContentValidatorTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/NotPassedTestsContentValidatorTest.java
@@ -1,36 +1,36 @@
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.exception.ReportPortalException;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
 import java.util.Collections;
 import java.util.HashMap;
-
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class NotPassedTestsContentValidatorTest {
 
-	private WidgetValidatorStrategy notPassedTestsContentValidator;
+  private WidgetValidatorStrategy notPassedTestsContentValidator;
 
-	@BeforeEach
-	public void setUp() {
-		notPassedTestsContentValidator = new NotPassedTestsContentValidator();
-	}
+  @BeforeEach
+  public void setUp() {
+    notPassedTestsContentValidator = new NotPassedTestsContentValidator();
+  }
 
-	@Test
-	public void testValidateWithException() {
-		Exception exception = assertThrows(ReportPortalException.class, () -> {
-			notPassedTestsContentValidator.validate(Collections.singletonList("test"), new HashMap<>(), new WidgetOptions(), 5);
-		});
+  @Test
+  public void testValidateWithException() {
+    Exception exception = assertThrows(ReportPortalException.class, () -> {
+      notPassedTestsContentValidator.validate(Collections.singletonList("test"), new HashMap<>(),
+          new WidgetOptions(), 5);
+    });
 
-		String expectedMessage = "Filter-Sort mapping should not be empty";
-		String actualMessage = exception.getMessage();
-		assertTrue(actualMessage.contains(expectedMessage));
-	}
+    String expectedMessage = "Filter-Sort mapping should not be empty";
+    String actualMessage = exception.getMessage();
+    assertTrue(actualMessage.contains(expectedMessage));
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/PassingRatePerLaunchContentValidatorTest.java b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/PassingRatePerLaunchContentValidatorTest.java
index ddfb84888a..5e2453fb86 100644
--- a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/PassingRatePerLaunchContentValidatorTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/PassingRatePerLaunchContentValidatorTest.java
@@ -1,50 +1,50 @@
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LAUNCH_NAME_FIELD;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.querygen.FilterCondition;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.exception.ReportPortalException;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.springframework.data.domain.Sort;
-
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
-
-import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.LAUNCH_NAME_FIELD;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.data.domain.Sort;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class PassingRatePerLaunchContentValidatorTest {
 
-	private WidgetValidatorStrategy passingRatePerLaunchContentValidator;
-
-	@BeforeEach
-	public void setUp() {
-		passingRatePerLaunchContentValidator = new PassingRatePerLaunchContentValidator();
-	}
-
-	@Test
-	public void testValidateWithException() {
-		Exception exception = assertThrows(ReportPortalException.class, () -> {
-			HashMap<Filter, Sort> filterSortMap = new HashMap<>();
-			filterSortMap.put(Filter.builder()
-					.withTarget(Launch.class)
-					.withCondition(FilterCondition.builder().eq("id", "1").build())
-					.build(), Sort.unsorted());
-			Map<String, Object> params = new HashMap<>();
-			params.put(LAUNCH_NAME_FIELD, "");
-			WidgetOptions widgetOptions = new WidgetOptions();
-			passingRatePerLaunchContentValidator.validate(Collections.singletonList("test"), filterSortMap, widgetOptions, 5);
-		});
-
-		String expectedMessage = LAUNCH_NAME_FIELD + " should be specified for widget.";
-		String actualMessage = exception.getMessage();
-		assertTrue(actualMessage.contains(expectedMessage));
-	}
+  private WidgetValidatorStrategy passingRatePerLaunchContentValidator;
+
+  @BeforeEach
+  public void setUp() {
+    passingRatePerLaunchContentValidator = new PassingRatePerLaunchContentValidator();
+  }
+
+  @Test
+  public void testValidateWithException() {
+    Exception exception = assertThrows(ReportPortalException.class, () -> {
+      HashMap<Filter, Sort> filterSortMap = new HashMap<>();
+      filterSortMap.put(Filter.builder()
+          .withTarget(Launch.class)
+          .withCondition(FilterCondition.builder().eq("id", "1").build())
+          .build(), Sort.unsorted());
+      Map<String, Object> params = new HashMap<>();
+      params.put(LAUNCH_NAME_FIELD, "");
+      WidgetOptions widgetOptions = new WidgetOptions();
+      passingRatePerLaunchContentValidator.validate(Collections.singletonList("test"),
+          filterSortMap, widgetOptions, 5);
+    });
+
+    String expectedMessage = LAUNCH_NAME_FIELD + " should be specified for widget.";
+    String actualMessage = exception.getMessage();
+    assertTrue(actualMessage.contains(expectedMessage));
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/PassingRateSummaryContentValidatorTest.java b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/PassingRateSummaryContentValidatorTest.java
index cef939e864..628ca15c2f 100644
--- a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/PassingRateSummaryContentValidatorTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/PassingRateSummaryContentValidatorTest.java
@@ -1,40 +1,39 @@
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.exception.ReportPortalException;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
 import java.util.Collections;
 import java.util.HashMap;
-
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class PassingRateSummaryContentValidatorTest {
 
-	private WidgetValidatorStrategy passingRateSummaryContentValidator;
-
-	@BeforeEach
-	public void setUp() {
-		passingRateSummaryContentValidator = new PassingRateSummaryContentValidator();
-	}
-
-	@Test
-	public void testValidateWithException() {
-		Exception exception = assertThrows(ReportPortalException.class,
-				() -> passingRateSummaryContentValidator.validate(Collections.singletonList("test"),
-						new HashMap<>(),
-						new WidgetOptions(),
-						5
-				)
-		);
-
-		String expectedMessage = "Filter-Sort mapping should not be empty";
-		String actualMessage = exception.getMessage();
-		assertTrue(actualMessage.contains(expectedMessage));
-	}
+  private WidgetValidatorStrategy passingRateSummaryContentValidator;
+
+  @BeforeEach
+  public void setUp() {
+    passingRateSummaryContentValidator = new PassingRateSummaryContentValidator();
+  }
+
+  @Test
+  public void testValidateWithException() {
+    Exception exception = assertThrows(ReportPortalException.class,
+        () -> passingRateSummaryContentValidator.validate(Collections.singletonList("test"),
+            new HashMap<>(),
+            new WidgetOptions(),
+            5
+        )
+    );
+
+    String expectedMessage = "Filter-Sort mapping should not be empty";
+    String actualMessage = exception.getMessage();
+    assertTrue(actualMessage.contains(expectedMessage));
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/TopPatternContentValidatorTest.java b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/TopPatternContentValidatorTest.java
index 386700abc7..280ac05740 100644
--- a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/TopPatternContentValidatorTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/TopPatternContentValidatorTest.java
@@ -1,42 +1,41 @@
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.exception.ReportPortalException;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
 import java.util.Collections;
 import java.util.HashMap;
-
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class TopPatternContentValidatorTest {
 
-	private MultilevelValidatorStrategy topPatternContentValidator;
-
-	@BeforeEach
-	public void setUp() {
-		topPatternContentValidator = new TopPatternContentValidator();
-	}
-
-	@Test
-	public void testValidateWithException() {
-		Exception exception = assertThrows(ReportPortalException.class, () -> {
-			topPatternContentValidator.validate(Collections.singletonList("test"),
-					new HashMap<>(),
-					new WidgetOptions(),
-					new String[] {},
-					new HashMap<>(),
-					5
-			);
-		});
-
-		String expectedMessage = "Filter-Sort mapping should not be empty";
-		String actualMessage = exception.getMessage();
-		assertTrue(actualMessage.contains(expectedMessage));
-	}
+  private MultilevelValidatorStrategy topPatternContentValidator;
+
+  @BeforeEach
+  public void setUp() {
+    topPatternContentValidator = new TopPatternContentValidator();
+  }
+
+  @Test
+  public void testValidateWithException() {
+    Exception exception = assertThrows(ReportPortalException.class, () -> {
+      topPatternContentValidator.validate(Collections.singletonList("test"),
+          new HashMap<>(),
+          new WidgetOptions(),
+          new String[]{},
+          new HashMap<>(),
+          5
+      );
+    });
+
+    String expectedMessage = "Filter-Sort mapping should not be empty";
+    String actualMessage = exception.getMessage();
+    assertTrue(actualMessage.contains(expectedMessage));
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/UniqueBugContentValidatorTest.java b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/UniqueBugContentValidatorTest.java
index de6965f412..34ba8d0df6 100644
--- a/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/UniqueBugContentValidatorTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/widget/content/updater/validator/UniqueBugContentValidatorTest.java
@@ -1,36 +1,36 @@
 package com.epam.ta.reportportal.core.widget.content.updater.validator;
 
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.exception.ReportPortalException;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
 import java.util.Collections;
 import java.util.HashMap;
-
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class UniqueBugContentValidatorTest {
 
-	private WidgetValidatorStrategy uniqueBugContentValidator;
+  private WidgetValidatorStrategy uniqueBugContentValidator;
 
-	@BeforeEach
-	public void setUp() {
-		uniqueBugContentValidator = new UniqueBugContentValidator();
-	}
+  @BeforeEach
+  public void setUp() {
+    uniqueBugContentValidator = new UniqueBugContentValidator();
+  }
 
-	@Test
-	public void testValidateWithException() {
-		Exception exception = assertThrows(ReportPortalException.class, () -> {
-			uniqueBugContentValidator.validate(Collections.singletonList("test"), new HashMap<>(), new WidgetOptions(), 5);
-		});
+  @Test
+  public void testValidateWithException() {
+    Exception exception = assertThrows(ReportPortalException.class, () -> {
+      uniqueBugContentValidator.validate(Collections.singletonList("test"), new HashMap<>(),
+          new WidgetOptions(), 5);
+    });
 
-		String expectedMessage = "Filter-Sort mapping should not be empty";
-		String actualMessage = exception.getMessage();
-		assertTrue(actualMessage.contains(expectedMessage));
-	}
+    String expectedMessage = "Filter-Sort mapping should not be empty";
+    String actualMessage = exception.getMessage();
+    assertTrue(actualMessage.contains(expectedMessage));
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/widget/util/ContentFieldMatcherUtilTest.java b/src/test/java/com/epam/ta/reportportal/core/widget/util/ContentFieldMatcherUtilTest.java
index 3cc221f89d..334ed2f79f 100644
--- a/src/test/java/com/epam/ta/reportportal/core/widget/util/ContentFieldMatcherUtilTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/widget/util/ContentFieldMatcherUtilTest.java
@@ -16,15 +16,16 @@
 
 package com.epam.ta.reportportal.core.widget.util;
 
-import com.google.common.collect.Lists;
-import org.junit.jupiter.api.Test;
+import static com.epam.ta.reportportal.core.widget.util.ContentFieldPatternConstants.COMBINED_CONTENT_FIELDS_REGEX;
+import static com.epam.ta.reportportal.core.widget.util.ContentFieldPatternConstants.DEFECTS_REGEX;
+import static com.epam.ta.reportportal.core.widget.util.ContentFieldPatternConstants.EXECUTIONS_REGEX;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
+import com.google.common.collect.Lists;
 import java.util.List;
 import java.util.Random;
-
-import static com.epam.ta.reportportal.core.widget.util.ContentFieldPatternConstants.*;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
@@ -32,128 +33,131 @@
 //TODO replace random wrong content field generation with the specified loop
 public class ContentFieldMatcherUtilTest {
 
-	@Test
-	void whenCorrectDefectsContentFieldsFormatThenTrue() {
-
-		boolean match = ContentFieldMatcherUtil.match(DEFECTS_REGEX, buildCorrectDefectContentFields());
+  @Test
+  void whenCorrectDefectsContentFieldsFormatThenTrue() {
 
-		assertTrue(match);
-	}
+    boolean match = ContentFieldMatcherUtil.match(DEFECTS_REGEX, buildCorrectDefectContentFields());
 
-	@Test
-	void whenWrongDefectsContentFieldsFormatThenFalse() {
+    assertTrue(match);
+  }
 
-		boolean match = ContentFieldMatcherUtil.match(DEFECTS_REGEX, buildWrongDefectContentFields());
+  @Test
+  void whenWrongDefectsContentFieldsFormatThenFalse() {
 
-		assertFalse(match);
-	}
+    boolean match = ContentFieldMatcherUtil.match(DEFECTS_REGEX, buildWrongDefectContentFields());
 
-	@Test
-	void whenCorrectExecutionsContentFieldsFormatThenTrue() {
+    assertFalse(match);
+  }
 
-		boolean match = ContentFieldMatcherUtil.match(EXECUTIONS_REGEX, buildCorrectExecutionContentFields());
+  @Test
+  void whenCorrectExecutionsContentFieldsFormatThenTrue() {
 
-		assertTrue(match);
-	}
+    boolean match = ContentFieldMatcherUtil.match(EXECUTIONS_REGEX,
+        buildCorrectExecutionContentFields());
 
-	@Test
-	void whenWrongExecutionsContentFieldsFormatThenFalse() {
+    assertTrue(match);
+  }
 
-		List<String> contentFields = buildWrongExecutionContentFields();
-		boolean match = ContentFieldMatcherUtil.match(DEFECTS_REGEX, contentFields);
+  @Test
+  void whenWrongExecutionsContentFieldsFormatThenFalse() {
 
-		assertFalse(match);
-	}
+    List<String> contentFields = buildWrongExecutionContentFields();
+    boolean match = ContentFieldMatcherUtil.match(DEFECTS_REGEX, contentFields);
 
-	@Test
-	void whenCorrectCombinedContentFieldsFormatThenTrue() {
+    assertFalse(match);
+  }
 
-		boolean match = ContentFieldMatcherUtil.match(COMBINED_CONTENT_FIELDS_REGEX, buildCorrectCombinedContentFields());
+  @Test
+  void whenCorrectCombinedContentFieldsFormatThenTrue() {
 
-		assertTrue(match);
-	}
+    boolean match = ContentFieldMatcherUtil.match(COMBINED_CONTENT_FIELDS_REGEX,
+        buildCorrectCombinedContentFields());
 
-	@Test
-	void whenWrongCombinedContentFieldsFormatThenFalse() {
+    assertTrue(match);
+  }
 
-		boolean match = ContentFieldMatcherUtil.match(COMBINED_CONTENT_FIELDS_REGEX, buildWrongCombinedContentFields());
+  @Test
+  void whenWrongCombinedContentFieldsFormatThenFalse() {
 
-		assertFalse(match);
-	}
+    boolean match = ContentFieldMatcherUtil.match(COMBINED_CONTENT_FIELDS_REGEX,
+        buildWrongCombinedContentFields());
 
-	private List<String> buildCorrectDefectContentFields() {
-		return Lists.newArrayList(
-				"statistics$defects$automation_bug$AB001",
-				"statistics$defects$product_bug$PB001",
-				"statistics$defects$to_investigate$TI001",
-				"statistics$defects$system_issue$SI001",
-				"statistics$defects$no_defect$ND001",
-				"statistics$defects$no_defect$total",
-				"statistics$defects$product_bug$total",
-				"statistics$defects$to_investigate$total",
-				"statistics$defects$system_issue$total"
+    assertFalse(match);
+  }
 
-		);
-	}
+  private List<String> buildCorrectDefectContentFields() {
+    return Lists.newArrayList(
+        "statistics$defects$automation_bug$AB001",
+        "statistics$defects$product_bug$PB001",
+        "statistics$defects$to_investigate$TI001",
+        "statistics$defects$system_issue$SI001",
+        "statistics$defects$no_defect$ND001",
+        "statistics$defects$no_defect$total",
+        "statistics$defects$product_bug$total",
+        "statistics$defects$to_investigate$total",
+        "statistics$defects$system_issue$total"
 
-	private List<String> buildWrongDefectContentFields() {
-		List<String> contentFields = buildCorrectDefectContentFields();
-		Random random = new Random();
-		int index = random.nextInt(contentFields.size());
+    );
+  }
 
-		contentFields.set(index, "statistics$wrong$format");
+  private List<String> buildWrongDefectContentFields() {
+    List<String> contentFields = buildCorrectDefectContentFields();
+    Random random = new Random();
+    int index = random.nextInt(contentFields.size());
 
-		return contentFields;
-	}
+    contentFields.set(index, "statistics$wrong$format");
 
-	private List<String> buildCorrectExecutionContentFields() {
-		return Lists.newArrayList(
-				"statistics$executions$passed",
-				"statistics$executions$failed",
-				"statistics$executions$skipped",
-				"statistics$executions$total"
-		);
-	}
+    return contentFields;
+  }
 
-	private List<String> buildWrongExecutionContentFields() {
-		List<String> contentFields = buildCorrectExecutionContentFields();
+  private List<String> buildCorrectExecutionContentFields() {
+    return Lists.newArrayList(
+        "statistics$executions$passed",
+        "statistics$executions$failed",
+        "statistics$executions$skipped",
+        "statistics$executions$total"
+    );
+  }
 
-		Random random = new Random();
-		int index = random.nextInt(contentFields.size());
+  private List<String> buildWrongExecutionContentFields() {
+    List<String> contentFields = buildCorrectExecutionContentFields();
 
-		contentFields.set(index, "statistics$wrong$format");
+    Random random = new Random();
+    int index = random.nextInt(contentFields.size());
 
-		return contentFields;
-	}
+    contentFields.set(index, "statistics$wrong$format");
 
-	private List<String> buildCorrectCombinedContentFields() {
-		return Lists.newArrayList(
-				"statistics$executions$passed",
-				"statistics$executions$failed",
-				"statistics$executions$skipped",
-				"statistics$executions$total",
-				"statistics$defects$automation_bug$AB001",
-				"statistics$defects$product_bug$PB001",
-				"statistics$defects$to_investigate$TI001",
-				"statistics$defects$system_issue$SI001",
-				"statistics$defects$no_defect$ND001",
-				"statistics$defects$no_defect$total"
-		);
-	}
+    return contentFields;
+  }
 
-	private List<String> buildWrongCombinedContentFields() {
-		List<String> contentFields = buildCorrectCombinedContentFields();
+  private List<String> buildCorrectCombinedContentFields() {
+    return Lists.newArrayList(
+        "statistics$executions$passed",
+        "statistics$executions$failed",
+        "statistics$executions$skipped",
+        "statistics$executions$total",
+        "statistics$defects$automation_bug$AB001",
+        "statistics$defects$product_bug$PB001",
+        "statistics$defects$to_investigate$TI001",
+        "statistics$defects$system_issue$SI001",
+        "statistics$defects$no_defect$ND001",
+        "statistics$defects$no_defect$total"
+    );
+  }
 
-		Random random = new Random();
-		int index = random.nextInt(contentFields.size());
+  private List<String> buildWrongCombinedContentFields() {
+    List<String> contentFields = buildCorrectCombinedContentFields();
 
-		contentFields.set(index, "statistics$wrong$format");
+    Random random = new Random();
+    int index = random.nextInt(contentFields.size());
 
-		return contentFields;
-	}
+    contentFields.set(index, "statistics$wrong$format");
 
-	public static Object[][] data() {
-		return new Object[1][0];
-	}
+    return contentFields;
+  }
+
+  public static Object[][] data() {
+    return new Object[1][0];
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/core/widget/util/WidgetOptionUtilTest.java b/src/test/java/com/epam/ta/reportportal/core/widget/util/WidgetOptionUtilTest.java
index c1a17b52e2..d3531fc486 100644
--- a/src/test/java/com/epam/ta/reportportal/core/widget/util/WidgetOptionUtilTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/widget/util/WidgetOptionUtilTest.java
@@ -16,82 +16,86 @@
 
 package com.epam.ta.reportportal.core.widget.util;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
 import com.epam.ta.reportportal.entity.widget.WidgetOptions;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Maps;
-import org.junit.jupiter.api.Test;
-
 import java.util.Map;
-
-import static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class WidgetOptionUtilTest {
 
-	private static final String FIRST_KEY = "KEY1";
-	private static final String SECOND_KEY = "KEY2";
-	private static final String FIRST_STRING_VALUE = "VALUE1";
-	private static final String SECOND_STRING_VALUE = "VALUE2";
+  private static final String FIRST_KEY = "KEY1";
+  private static final String SECOND_KEY = "KEY2";
+  private static final String FIRST_STRING_VALUE = "VALUE1";
+  private static final String SECOND_STRING_VALUE = "VALUE2";
 
-	@Test
-	void getStringValueWhenCorrectTypeTest() {
+  @Test
+  void getStringValueWhenCorrectTypeTest() {
 
-		//given
-		WidgetOptions widgetOptions = new WidgetOptions(getMapWithStringValues());
+    //given
+    WidgetOptions widgetOptions = new WidgetOptions(getMapWithStringValues());
 
-		//when
-		String value = WidgetOptionUtil.getValueByKey(FIRST_KEY, widgetOptions);
+    //when
+    String value = WidgetOptionUtil.getValueByKey(FIRST_KEY, widgetOptions);
 
-		//then
-		assertNotNull(value);
-		assertEquals(FIRST_STRING_VALUE, value);
-	}
+    //then
+    assertNotNull(value);
+    assertEquals(FIRST_STRING_VALUE, value);
+  }
 
-	@Test
-	void throwExceptionWhenGetStringValueWithInCorrectTypeTest() {
+  @Test
+  void throwExceptionWhenGetStringValueWithInCorrectTypeTest() {
 
-		//given
-		WidgetOptions widgetOptions = new WidgetOptions(getMapWithNonStringValues());
+    //given
+    WidgetOptions widgetOptions = new WidgetOptions(getMapWithNonStringValues());
 
-		//when //then throw exception
-		assertThrows(ReportPortalException.class, () -> WidgetOptionUtil.getValueByKey(FIRST_KEY, widgetOptions));
-	}
+    //when //then throw exception
+    assertThrows(ReportPortalException.class,
+        () -> WidgetOptionUtil.getValueByKey(FIRST_KEY, widgetOptions));
+  }
 
-	@Test
-	void getMapValueWhenCorrectTypeTest() {
+  @Test
+  void getMapValueWhenCorrectTypeTest() {
 
-		//given
-		WidgetOptions widgetOptions = new WidgetOptions(getMapWithNonStringValues());
+    //given
+    WidgetOptions widgetOptions = new WidgetOptions(getMapWithNonStringValues());
 
-		//when
-		Map<String, String> mapByKey = WidgetOptionUtil.getMapByKey(FIRST_KEY, widgetOptions);
+    //when
+    Map<String, String> mapByKey = WidgetOptionUtil.getMapByKey(FIRST_KEY, widgetOptions);
 
-		//then
-		assertNotNull(mapByKey);
-	}
+    //then
+    assertNotNull(mapByKey);
+  }
 
-	@Test
-	void throwExceptionWhenGetMapValueWithInCorrectTypeTest() {
+  @Test
+  void throwExceptionWhenGetMapValueWithInCorrectTypeTest() {
 
-		//given
-		WidgetOptions widgetOptions = new WidgetOptions(getMapWithStringValues());
+    //given
+    WidgetOptions widgetOptions = new WidgetOptions(getMapWithStringValues());
 
-		//when //then throw exception
-		assertThrows(ReportPortalException.class, () -> WidgetOptionUtil.getMapByKey(FIRST_KEY, widgetOptions));
-	}
+    //when //then throw exception
+    assertThrows(ReportPortalException.class,
+        () -> WidgetOptionUtil.getMapByKey(FIRST_KEY, widgetOptions));
+  }
 
-	private Map<String, Object> getMapWithStringValues() {
-		return ImmutableMap.<String, Object>builder().put(FIRST_KEY, FIRST_STRING_VALUE).put(SECOND_KEY, SECOND_STRING_VALUE).build();
-	}
+  private Map<String, Object> getMapWithStringValues() {
+    return ImmutableMap.<String, Object>builder().put(FIRST_KEY, FIRST_STRING_VALUE)
+        .put(SECOND_KEY, SECOND_STRING_VALUE).build();
+  }
 
-	private Map<String, Object> getMapWithNonStringValues() {
-		Map<String, Object> mapValue = Maps.newHashMap();
-		mapValue.put(FIRST_KEY, ImmutableList.<String>builder().add(FIRST_STRING_VALUE).build());
+  private Map<String, Object> getMapWithNonStringValues() {
+    Map<String, Object> mapValue = Maps.newHashMap();
+    mapValue.put(FIRST_KEY, ImmutableList.<String>builder().add(FIRST_STRING_VALUE).build());
 
-		return ImmutableMap.<String, Object>builder().put(FIRST_KEY, mapValue).build();
-	}
+    return ImmutableMap.<String, Object>builder().put(FIRST_KEY, mapValue).build();
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/job/CleanOutdatedPluginsJobTest.java b/src/test/java/com/epam/ta/reportportal/job/CleanOutdatedPluginsJobTest.java
index 8d5dcaa3a7..d478b9f6e3 100644
--- a/src/test/java/com/epam/ta/reportportal/job/CleanOutdatedPluginsJobTest.java
+++ b/src/test/java/com/epam/ta/reportportal/job/CleanOutdatedPluginsJobTest.java
@@ -16,6 +16,14 @@
 
 package com.epam.ta.reportportal.job;
 
+import static java.util.Optional.ofNullable;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.mockito.internal.verification.VerificationModeFactory.times;
+
 import com.epam.reportportal.extension.common.ExtensionPoint;
 import com.epam.ta.reportportal.core.plugin.Pf4jPluginBox;
 import com.epam.ta.reportportal.core.plugin.Plugin;
@@ -24,129 +32,129 @@
 import com.epam.ta.reportportal.entity.integration.IntegrationTypeDetails;
 import com.epam.ta.reportportal.job.service.PluginLoaderService;
 import com.google.common.collect.Lists;
-import org.junit.jupiter.api.Test;
-import org.pf4j.PluginWrapper;
-
 import java.io.File;
 import java.io.IOException;
 import java.nio.file.Paths;
 import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
-
-import static java.util.Optional.ofNullable;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.*;
-import static org.mockito.internal.verification.VerificationModeFactory.times;
+import org.junit.jupiter.api.Test;
+import org.pf4j.PluginWrapper;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  **/
 class CleanOutdatedPluginsJobTest {
 
-	private static final String PLUGIN_TEMP_DIRECTORY = "/temp/";
+  private static final String PLUGIN_TEMP_DIRECTORY = "/temp/";
 
-	private String pluginsRootPath = System.getProperty("java.io.tmpdir") + "/plugins";
+  private String pluginsRootPath = System.getProperty("java.io.tmpdir") + "/plugins";
 
-	private IntegrationTypeRepository integrationTypeRepository = mock(IntegrationTypeRepository.class);
+  private IntegrationTypeRepository integrationTypeRepository = mock(
+      IntegrationTypeRepository.class);
 
-	private Pf4jPluginBox pluginBox = mock(Pf4jPluginBox.class);
+  private Pf4jPluginBox pluginBox = mock(Pf4jPluginBox.class);
 
-	private PluginLoaderService pluginLoaderService = mock(PluginLoaderService.class);
+  private PluginLoaderService pluginLoaderService = mock(PluginLoaderService.class);
 
-	private PluginWrapper jiraPlugin = mock(PluginWrapper.class);
-	private IntegrationType jiraIntegrationType = mock(IntegrationType.class);
-	private PluginWrapper rallyPlugin = mock(PluginWrapper.class);
-	private IntegrationType rallyIntegrationType = mock(IntegrationType.class);
+  private PluginWrapper jiraPlugin = mock(PluginWrapper.class);
+  private IntegrationType jiraIntegrationType = mock(IntegrationType.class);
+  private PluginWrapper rallyPlugin = mock(PluginWrapper.class);
+  private IntegrationType rallyIntegrationType = mock(IntegrationType.class);
 
-	private CleanOutdatedPluginsJob cleanOutdatedPluginsJob = new CleanOutdatedPluginsJob(pluginsRootPath + PLUGIN_TEMP_DIRECTORY,
-			integrationTypeRepository,
-			pluginBox,
-			pluginLoaderService
-	);
+  private CleanOutdatedPluginsJob cleanOutdatedPluginsJob = new CleanOutdatedPluginsJob(
+      pluginsRootPath + PLUGIN_TEMP_DIRECTORY,
+      integrationTypeRepository,
+      pluginBox,
+      pluginLoaderService
+  );
 
-	@Test
-	void testExecutionWithoutPluginInCache() throws IOException {
+  @Test
+  void testExecutionWithoutPluginInCache() throws IOException {
 
-		File dir = new File(pluginsRootPath + PLUGIN_TEMP_DIRECTORY);
-		if (!dir.exists()) {
-			assertTrue(dir.mkdirs());
-		}
+    File dir = new File(pluginsRootPath + PLUGIN_TEMP_DIRECTORY);
+    if (!dir.exists()) {
+      assertTrue(dir.mkdirs());
+    }
 
-		File file = new File(dir, "qwe.jar");
+    File file = new File(dir, "qwe.jar");
 
-		assertTrue(file.createNewFile());
+    assertTrue(file.createNewFile());
 
-		when(pluginBox.isInUploadingState(any(String.class))).thenReturn(false);
+    when(pluginBox.isInUploadingState(any(String.class))).thenReturn(false);
 
-		cleanOutdatedPluginsJob.execute();
-	}
+    cleanOutdatedPluginsJob.execute();
+  }
 
-	@Test
-	void testExecutionWithPluginInCache() throws IOException {
+  @Test
+  void testExecutionWithPluginInCache() throws IOException {
 
-		File dir = new File(pluginsRootPath + PLUGIN_TEMP_DIRECTORY);
-		if (!dir.exists()) {
-			assertTrue(dir.mkdirs());
-		}
+    File dir = new File(pluginsRootPath + PLUGIN_TEMP_DIRECTORY);
+    if (!dir.exists()) {
+      assertTrue(dir.mkdirs());
+    }
 
-		File file = File.createTempFile("test", ".jar", dir);
+    File file = File.createTempFile("test", ".jar", dir);
 
-		file.deleteOnExit();
+    file.deleteOnExit();
 
-		when(pluginBox.isInUploadingState(any(String.class))).thenReturn(true);
+    when(pluginBox.isInUploadingState(any(String.class))).thenReturn(true);
 
-		cleanOutdatedPluginsJob.execute();
-	}
+    cleanOutdatedPluginsJob.execute();
+  }
 
-	@Test
-	void testBrokenIntegrationTypeRemoving() {
+  @Test
+  void testBrokenIntegrationTypeRemoving() {
 
-		when(integrationTypeRepository.findAll()).thenReturn(getBrokenIntegrationType());
+    when(integrationTypeRepository.findAll()).thenReturn(getBrokenIntegrationType());
 
-		cleanOutdatedPluginsJob.execute();
-		verify(pluginLoaderService, times(2)).checkAndDeleteIntegrationType(any(IntegrationType.class));
-	}
+    cleanOutdatedPluginsJob.execute();
+    verify(pluginLoaderService, times(2)).checkAndDeleteIntegrationType(any(IntegrationType.class));
+  }
 
-	@Test
-	void testTemporaryPluginRemoving() {
-		List<Plugin> plugins = getPlugins();
-		when(integrationTypeRepository.findAll()).thenReturn(Collections.emptyList());
+  @Test
+  void testTemporaryPluginRemoving() {
+    List<Plugin> plugins = getPlugins();
+    when(integrationTypeRepository.findAll()).thenReturn(Collections.emptyList());
 
-		when(pluginBox.getPlugins()).thenReturn(plugins);
-		when(pluginBox.getPluginById(plugins.get(0).getId())).thenReturn(ofNullable(jiraPlugin));
-		when(jiraPlugin.getPluginPath()).thenReturn(Paths.get(pluginsRootPath, "qwe.jar"));
+    when(pluginBox.getPlugins()).thenReturn(plugins);
+    when(pluginBox.getPluginById(plugins.get(0).getId())).thenReturn(ofNullable(jiraPlugin));
+    when(jiraPlugin.getPluginPath()).thenReturn(Paths.get(pluginsRootPath, "qwe.jar"));
 
-		when(pluginBox.isInUploadingState(jiraPlugin.getPluginPath().getFileName().toString())).thenReturn(false);
-		when(integrationTypeRepository.findByName(jiraPlugin.getPluginId())).thenReturn(Optional.of(jiraIntegrationType));
-		when(pluginBox.unloadPlugin(jiraIntegrationType)).thenReturn(true);
+    when(pluginBox.isInUploadingState(
+        jiraPlugin.getPluginPath().getFileName().toString())).thenReturn(false);
+    when(integrationTypeRepository.findByName(jiraPlugin.getPluginId())).thenReturn(
+        Optional.of(jiraIntegrationType));
+    when(pluginBox.unloadPlugin(jiraIntegrationType)).thenReturn(true);
 
-		when(pluginBox.getPluginById(plugins.get(1).getId())).thenReturn(ofNullable(rallyPlugin));
-		when(rallyPlugin.getPluginPath()).thenReturn(Paths.get(pluginsRootPath, "qwe1.jar"));
+    when(pluginBox.getPluginById(plugins.get(1).getId())).thenReturn(ofNullable(rallyPlugin));
+    when(rallyPlugin.getPluginPath()).thenReturn(Paths.get(pluginsRootPath, "qwe1.jar"));
 
-		when(pluginBox.isInUploadingState(rallyPlugin.getPluginPath().getFileName().toString())).thenReturn(false);
-		when(integrationTypeRepository.findByName(rallyPlugin.getPluginId())).thenReturn(Optional.of(rallyIntegrationType));
-		when(pluginBox.unloadPlugin(rallyIntegrationType)).thenReturn(false);
+    when(pluginBox.isInUploadingState(
+        rallyPlugin.getPluginPath().getFileName().toString())).thenReturn(false);
+    when(integrationTypeRepository.findByName(rallyPlugin.getPluginId())).thenReturn(
+        Optional.of(rallyIntegrationType));
+    when(pluginBox.unloadPlugin(rallyIntegrationType)).thenReturn(false);
 
-		cleanOutdatedPluginsJob.execute();
+    cleanOutdatedPluginsJob.execute();
 
-	}
+  }
 
-	private List<IntegrationType> getBrokenIntegrationType() {
+  private List<IntegrationType> getBrokenIntegrationType() {
 
-		IntegrationType jira = new IntegrationType();
-		jira.setName("jira");
-		jira.setDetails(new IntegrationTypeDetails());
+    IntegrationType jira = new IntegrationType();
+    jira.setName("jira");
+    jira.setDetails(new IntegrationTypeDetails());
 
-		IntegrationType rally = new IntegrationType();
-		rally.setName("rally");
+    IntegrationType rally = new IntegrationType();
+    rally.setName("rally");
 
-		return Lists.newArrayList(jira, rally);
-	}
+    return Lists.newArrayList(jira, rally);
+  }
 
-	private List<Plugin> getPlugins() {
-		return Lists.newArrayList(new Plugin("jira", ExtensionPoint.BTS), new Plugin("rally", ExtensionPoint.BTS));
-	}
+  private List<Plugin> getPlugins() {
+    return Lists.newArrayList(new Plugin("jira", ExtensionPoint.BTS),
+        new Plugin("rally", ExtensionPoint.BTS));
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/job/InterruptBrokenLaunchesJobTest.java b/src/test/java/com/epam/ta/reportportal/job/InterruptBrokenLaunchesJobTest.java
index 699221b806..0096bbae97 100644
--- a/src/test/java/com/epam/ta/reportportal/job/InterruptBrokenLaunchesJobTest.java
+++ b/src/test/java/com/epam/ta/reportportal/job/InterruptBrokenLaunchesJobTest.java
@@ -16,6 +16,11 @@
 
 package com.epam.ta.reportportal.job;
 
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.dao.LaunchRepository;
 import com.epam.ta.reportportal.dao.LogRepository;
 import com.epam.ta.reportportal.dao.ProjectRepository;
@@ -26,6 +31,10 @@
 import com.epam.ta.reportportal.entity.project.Project;
 import com.epam.ta.reportportal.entity.project.ProjectAttribute;
 import com.google.common.collect.Sets;
+import java.time.Duration;
+import java.util.Collections;
+import java.util.Optional;
+import java.util.stream.Stream;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.InjectMocks;
@@ -33,92 +42,93 @@
 import org.mockito.junit.jupiter.MockitoExtension;
 import org.springframework.data.domain.PageImpl;
 
-import java.time.Duration;
-import java.util.Collections;
-import java.util.Optional;
-import java.util.stream.Stream;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.*;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @ExtendWith(MockitoExtension.class)
 class InterruptBrokenLaunchesJobTest {
 
-	@Mock
-	private LaunchRepository launchRepository;
-
-	@Mock
-	private LogRepository logRepository;
-
-	@Mock
-	private TestItemRepository testItemRepository;
-
-	@Mock
-	private ProjectRepository projectRepository;
-
-	@InjectMocks
-	private InterruptBrokenLaunchesJob interruptBrokenLaunchesJob;
-
-	@Test
-	void noInProgressItemsTest() {
-		String name = "name";
-		Project project = new Project();
-		final ProjectAttribute projectAttribute = new ProjectAttribute();
-		final Attribute attribute = new Attribute();
-		attribute.setName("job.interruptJobTime");
-		projectAttribute.setAttribute(attribute);
-
-		//1 day in seconds
-		projectAttribute.setValue(String.valueOf(3600 * 24));
-		project.setProjectAttributes(Sets.newHashSet(projectAttribute));
-		project.setName(name);
-
-		long launchId = 1L;
-
-		when(projectRepository.findAllIdsAndProjectAttributes(any())).thenReturn(new PageImpl<>(Collections.singletonList(project)));
-		when(launchRepository.streamIdsWithStatusAndStartTimeBefore(any(), any(), any())).thenReturn(Stream.of(launchId));
-		when(testItemRepository.hasItemsInStatusByLaunch(launchId, StatusEnum.IN_PROGRESS)).thenReturn(false);
-		when(launchRepository.findById(launchId)).thenReturn(Optional.of(new Launch()));
-
-		interruptBrokenLaunchesJob.execute(null);
-
-		verify(launchRepository, times(1)).findById(launchId);
-		verify(launchRepository, times(1)).save(any());
-
-	}
-
-	@Test
-	void interruptLaunchWithInProgressItemsTest() {
-		String name = "name";
-		Project project = new Project();
-		final ProjectAttribute projectAttribute = new ProjectAttribute();
-		final Attribute attribute = new Attribute();
-		attribute.setName("job.interruptJobTime");
-		projectAttribute.setAttribute(attribute);
-
-		//1 day in seconds
-		projectAttribute.setValue(String.valueOf(3600 * 24));
-		project.setProjectAttributes(Sets.newHashSet(projectAttribute));
-		project.setName(name);
-
-		long launchId = 1L;
-
-		when(projectRepository.findAllIdsAndProjectAttributes(any())).thenReturn(new PageImpl<>(Collections.singletonList(project)));
-		when(launchRepository.streamIdsWithStatusAndStartTimeBefore(any(), any(), any())).thenReturn(Stream.of(launchId));
-		when(testItemRepository.hasItemsInStatusByLaunch(launchId, StatusEnum.IN_PROGRESS)).thenReturn(true);
-		when(testItemRepository.hasItemsInStatusAddedLately(launchId, Duration.ofSeconds(3600 * 24),StatusEnum.IN_PROGRESS)).thenReturn(false);
-		when(testItemRepository.hasLogs(launchId, Duration.ofSeconds(3600 * 24), StatusEnum.IN_PROGRESS)).thenReturn(true);
-		when(logRepository.hasLogsAddedLately(Duration.ofSeconds(3600 * 24), launchId, StatusEnum.IN_PROGRESS)).thenReturn(false);
-		when(launchRepository.findById(launchId)).thenReturn(Optional.of(new Launch()));
-
-		interruptBrokenLaunchesJob.execute(null);
-
-		verify(testItemRepository, times(1)).interruptInProgressItems(launchId);
-		verify(launchRepository, times(1)).findById(launchId);
-		verify(launchRepository, times(1)).save(any());
-
-	}
+  @Mock
+  private LaunchRepository launchRepository;
+
+  @Mock
+  private LogRepository logRepository;
+
+  @Mock
+  private TestItemRepository testItemRepository;
+
+  @Mock
+  private ProjectRepository projectRepository;
+
+  @InjectMocks
+  private InterruptBrokenLaunchesJob interruptBrokenLaunchesJob;
+
+  @Test
+  void noInProgressItemsTest() {
+    String name = "name";
+    Project project = new Project();
+    final ProjectAttribute projectAttribute = new ProjectAttribute();
+    final Attribute attribute = new Attribute();
+    attribute.setName("job.interruptJobTime");
+    projectAttribute.setAttribute(attribute);
+
+    //1 day in seconds
+    projectAttribute.setValue(String.valueOf(3600 * 24));
+    project.setProjectAttributes(Sets.newHashSet(projectAttribute));
+    project.setName(name);
+
+    long launchId = 1L;
+
+    when(projectRepository.findAllIdsAndProjectAttributes(any())).thenReturn(
+        new PageImpl<>(Collections.singletonList(project)));
+    when(launchRepository.streamIdsWithStatusAndStartTimeBefore(any(), any(), any())).thenReturn(
+        Stream.of(launchId));
+    when(testItemRepository.hasItemsInStatusByLaunch(launchId, StatusEnum.IN_PROGRESS)).thenReturn(
+        false);
+    when(launchRepository.findById(launchId)).thenReturn(Optional.of(new Launch()));
+
+    interruptBrokenLaunchesJob.execute(null);
+
+    verify(launchRepository, times(1)).findById(launchId);
+    verify(launchRepository, times(1)).save(any());
+
+  }
+
+  @Test
+  void interruptLaunchWithInProgressItemsTest() {
+    String name = "name";
+    Project project = new Project();
+    final ProjectAttribute projectAttribute = new ProjectAttribute();
+    final Attribute attribute = new Attribute();
+    attribute.setName("job.interruptJobTime");
+    projectAttribute.setAttribute(attribute);
+
+    //1 day in seconds
+    projectAttribute.setValue(String.valueOf(3600 * 24));
+    project.setProjectAttributes(Sets.newHashSet(projectAttribute));
+    project.setName(name);
+
+    long launchId = 1L;
+
+    when(projectRepository.findAllIdsAndProjectAttributes(any())).thenReturn(
+        new PageImpl<>(Collections.singletonList(project)));
+    when(launchRepository.streamIdsWithStatusAndStartTimeBefore(any(), any(), any())).thenReturn(
+        Stream.of(launchId));
+    when(testItemRepository.hasItemsInStatusByLaunch(launchId, StatusEnum.IN_PROGRESS)).thenReturn(
+        true);
+    when(testItemRepository.hasItemsInStatusAddedLately(launchId, Duration.ofSeconds(3600 * 24),
+        StatusEnum.IN_PROGRESS)).thenReturn(false);
+    when(testItemRepository.hasLogs(launchId, Duration.ofSeconds(3600 * 24),
+        StatusEnum.IN_PROGRESS)).thenReturn(true);
+    when(logRepository.hasLogsAddedLately(Duration.ofSeconds(3600 * 24), launchId,
+        StatusEnum.IN_PROGRESS)).thenReturn(false);
+    when(launchRepository.findById(launchId)).thenReturn(Optional.of(new Launch()));
+
+    interruptBrokenLaunchesJob.execute(null);
+
+    verify(testItemRepository, times(1)).interruptInProgressItems(launchId);
+    verify(launchRepository, times(1)).findById(launchId);
+    verify(launchRepository, times(1)).save(any());
+
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/job/JobExecutorDelegateTest.java b/src/test/java/com/epam/ta/reportportal/job/JobExecutorDelegateTest.java
index 0aab51d2c6..aa47ff9e57 100644
--- a/src/test/java/com/epam/ta/reportportal/job/JobExecutorDelegateTest.java
+++ b/src/test/java/com/epam/ta/reportportal/job/JobExecutorDelegateTest.java
@@ -16,6 +16,9 @@
 
 package com.epam.ta.reportportal.job;
 
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.InjectMocks;
@@ -23,9 +26,6 @@
 import org.mockito.junit.jupiter.MockitoExtension;
 import org.springframework.scheduling.TaskScheduler;
 
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
 /**
  * Created by Andrey_Ivanov1 on 31-May-17.
  */
@@ -33,17 +33,17 @@
 @ExtendWith(MockitoExtension.class)
 class JobExecutorDelegateTest {
 
-	@InjectMocks
-	private JobExecutorDelegate jobExecutorDelegate = new JobExecutorDelegate();
-	@Mock
-	private SelfCancelableJob selfCancalableJob;
-	@Mock
-	private TaskScheduler taskScheduler;
-
-	@Test
-	void submitJobTest() {
-		jobExecutorDelegate.submitJob(selfCancalableJob);
-		verify(taskScheduler, times(1)).schedule(selfCancalableJob, selfCancalableJob);
-	}
+  @InjectMocks
+  private JobExecutorDelegate jobExecutorDelegate = new JobExecutorDelegate();
+  @Mock
+  private SelfCancelableJob selfCancalableJob;
+  @Mock
+  private TaskScheduler taskScheduler;
+
+  @Test
+  void submitJobTest() {
+    jobExecutorDelegate.submitJob(selfCancalableJob);
+    verify(taskScheduler, times(1)).schedule(selfCancalableJob, selfCancalableJob);
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/job/LoadPluginsJobTest.java b/src/test/java/com/epam/ta/reportportal/job/LoadPluginsJobTest.java
index 5f89408591..099b1d4944 100644
--- a/src/test/java/com/epam/ta/reportportal/job/LoadPluginsJobTest.java
+++ b/src/test/java/com/epam/ta/reportportal/job/LoadPluginsJobTest.java
@@ -16,6 +16,10 @@
 
 package com.epam.ta.reportportal.job;
 
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.core.plugin.Pf4jPluginBox;
 import com.epam.ta.reportportal.core.plugin.PluginInfo;
 import com.epam.ta.reportportal.dao.IntegrationTypeRepository;
@@ -24,84 +28,83 @@
 import com.epam.ta.reportportal.filesystem.DataStore;
 import com.epam.ta.reportportal.job.service.PluginLoaderService;
 import com.google.common.collect.Lists;
-import org.apache.commons.io.FileUtils;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.Test;
-import org.pf4j.PluginWrapper;
-
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.util.List;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+import org.apache.commons.io.FileUtils;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Test;
+import org.pf4j.PluginWrapper;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class LoadPluginsJobTest {
 
-	private IntegrationTypeRepository integrationTypeRepository = mock(IntegrationTypeRepository.class);
+  private IntegrationTypeRepository integrationTypeRepository = mock(
+      IntegrationTypeRepository.class);
 
-	private PluginLoaderService pluginLoaderService = mock(PluginLoaderService.class);
+  private PluginLoaderService pluginLoaderService = mock(PluginLoaderService.class);
 
-	private String pluginsRootPath = "plugins";
+  private String pluginsRootPath = "plugins";
 
-	private Pf4jPluginBox pluginBox = mock(Pf4jPluginBox.class);
+  private Pf4jPluginBox pluginBox = mock(Pf4jPluginBox.class);
 
-	private DataStore dataStore = mock(DataStore.class);
+  private DataStore dataStore = mock(DataStore.class);
 
-	private PluginWrapper rallyPlugin = mock(PluginWrapper.class);
-	private IntegrationType rally = mock(IntegrationType.class);
+  private PluginWrapper rallyPlugin = mock(PluginWrapper.class);
+  private IntegrationType rally = mock(IntegrationType.class);
 
-	private LoadPluginsJob loadPluginsJob = new LoadPluginsJob(pluginsRootPath,
-			integrationTypeRepository,
-			pluginLoaderService,
-			pluginBox,
-			dataStore
-	);
+  private LoadPluginsJob loadPluginsJob = new LoadPluginsJob(pluginsRootPath,
+      integrationTypeRepository,
+      pluginLoaderService,
+      pluginBox,
+      dataStore
+  );
 
-	@AfterAll
-	public static void clearPluginDirectory() throws IOException {
-		FileUtils.deleteDirectory(new File(System.getProperty("user.dir") + "/plugins"));
-	}
+  @AfterAll
+  public static void clearPluginDirectory() throws IOException {
+    FileUtils.deleteDirectory(new File(System.getProperty("user.dir") + "/plugins"));
+  }
 
-	@Test
-	void loadDisabledPluginTest() throws IOException {
+  @Test
+  void loadDisabledPluginTest() throws IOException {
 
-		List<IntegrationType> integrationTypes = getIntegrationTypes();
-		when(integrationTypeRepository.findAll()).thenReturn(integrationTypes);
-		List<PluginInfo> pluginInfos = getPluginInfos();
+    List<IntegrationType> integrationTypes = getIntegrationTypes();
+    when(integrationTypeRepository.findAll()).thenReturn(integrationTypes);
+    List<PluginInfo> pluginInfos = getPluginInfos();
 
-		File tempFile = File.createTempFile("file", ".jar");
-		tempFile.deleteOnExit();
+    File tempFile = File.createTempFile("file", ".jar");
+    tempFile.deleteOnExit();
 
-		when(dataStore.load(any(String.class))).thenReturn(new FileInputStream(tempFile));
-		when(pluginBox.loadPlugin(any(String.class), any(IntegrationTypeDetails.class))).thenReturn(true);
-		when(pluginLoaderService.getNotLoadedPluginsInfo()).thenReturn(pluginInfos);
-		when(pluginBox.getPluginById(any(String.class))).thenReturn(java.util.Optional.ofNullable(rallyPlugin));
-		when(rallyPlugin.getPluginId()).thenReturn("rally");
-		when(integrationTypeRepository.findByName(any(String.class))).thenReturn(java.util.Optional.ofNullable(rally));
-		when(pluginBox.unloadPlugin(rally)).thenReturn(true);
+    when(dataStore.load(any(String.class))).thenReturn(new FileInputStream(tempFile));
+    when(pluginBox.loadPlugin(any(String.class), any(IntegrationTypeDetails.class))).thenReturn(
+        true);
+    when(pluginLoaderService.getNotLoadedPluginsInfo()).thenReturn(pluginInfos);
+    when(pluginBox.getPluginById(any(String.class))).thenReturn(
+        java.util.Optional.ofNullable(rallyPlugin));
+    when(rallyPlugin.getPluginId()).thenReturn("rally");
+    when(integrationTypeRepository.findByName(any(String.class))).thenReturn(
+        java.util.Optional.ofNullable(rally));
+    when(pluginBox.unloadPlugin(rally)).thenReturn(true);
 
-		loadPluginsJob.execute();
-	}
+    loadPluginsJob.execute();
+  }
 
-	private List<IntegrationType> getIntegrationTypes() {
-		IntegrationType jira = new IntegrationType();
-		jira.setName("jira");
-		IntegrationType rally = new IntegrationType();
-		rally.setName("rally");
-		return Lists.newArrayList(jira, rally);
-	}
+  private List<IntegrationType> getIntegrationTypes() {
+    IntegrationType jira = new IntegrationType();
+    jira.setName("jira");
+    IntegrationType rally = new IntegrationType();
+    rally.setName("rally");
+    return Lists.newArrayList(jira, rally);
+  }
 
-	private List<PluginInfo> getPluginInfos() {
+  private List<PluginInfo> getPluginInfos() {
 
-		return Lists.newArrayList(new PluginInfo("jira", "v1.0", "file Id", "jira file", true),
-				new PluginInfo("rally", "v2.0", "file Id", "rally file", false)
-		);
-	}
+    return Lists.newArrayList(new PluginInfo("jira", "v1.0", "file Id", "jira file", true),
+        new PluginInfo("rally", "v2.0", "file Id", "rally file", false)
+    );
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/job/PluginLoaderServiceTest.java b/src/test/java/com/epam/ta/reportportal/job/PluginLoaderServiceTest.java
index 3bb9244287..fbf4cab757 100644
--- a/src/test/java/com/epam/ta/reportportal/job/PluginLoaderServiceTest.java
+++ b/src/test/java/com/epam/ta/reportportal/job/PluginLoaderServiceTest.java
@@ -16,6 +16,11 @@
 
 package com.epam.ta.reportportal.job;
 
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.reportportal.extension.common.IntegrationTypeProperties;
 import com.epam.ta.reportportal.core.plugin.Pf4jPluginBox;
 import com.epam.ta.reportportal.core.plugin.PluginInfo;
@@ -26,128 +31,129 @@
 import com.epam.ta.reportportal.job.service.impl.PluginLoaderServiceImpl;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-import org.pf4j.PluginDescriptor;
-import org.pf4j.PluginWrapper;
-
 import java.nio.file.Paths;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
-
-import static org.mockito.Mockito.*;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.pf4j.PluginDescriptor;
+import org.pf4j.PluginWrapper;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class PluginLoaderServiceTest {
 
-	private IntegrationTypeRepository integrationTypeRepository = mock(IntegrationTypeRepository.class);
-
-	private Pf4jPluginBox pluginBox = mock(Pf4jPluginBox.class);
-
-	private PluginLoaderService pluginLoaderService = new PluginLoaderServiceImpl(integrationTypeRepository, pluginBox);
-
-	private PluginWrapper jiraPlugin = mock(PluginWrapper.class);
-	private PluginWrapper rallyPlugin = mock(PluginWrapper.class);
-
-	private PluginDescriptor jiraPluginDescriptor = mock(PluginDescriptor.class);
-	private PluginDescriptor rallyPluginDescriptor = mock(PluginDescriptor.class);
-
-	@Test
-	void getNotLoadedPluginsInfoTest() {
-
-		when(pluginBox.getPluginById("jira")).thenReturn(Optional.ofNullable(jiraPlugin));
-		when(pluginBox.getPluginById("rally")).thenReturn(Optional.ofNullable(rallyPlugin));
-		when(jiraPlugin.getDescriptor()).thenReturn(jiraPluginDescriptor);
-		when(jiraPluginDescriptor.getVersion()).thenReturn("v1");
-		when(rallyPlugin.getDescriptor()).thenReturn(rallyPluginDescriptor);
-		when(rallyPluginDescriptor.getVersion()).thenReturn("another version");
-		when(integrationTypeRepository.findAll()).thenReturn(getIntegrationTypes());
-		List<PluginInfo> notLoadedPluginsInfo = pluginLoaderService.getNotLoadedPluginsInfo();
-
-		Assertions.assertFalse(notLoadedPluginsInfo.isEmpty());
-		Assertions.assertEquals(1, notLoadedPluginsInfo.size());
-		Assertions.assertEquals("rally", notLoadedPluginsInfo.get(0).getId());
-	}
-
-	@Test
-	void checkAndDeleteIntegrationTypeWhenPluginPositive() {
-		IntegrationType integrationType = new IntegrationType();
-		integrationType.setId(1L);
-		integrationType.setName("jira");
-
-		when(pluginBox.getPluginById(integrationType.getName())).thenReturn(Optional.ofNullable(jiraPlugin));
-		when(jiraPlugin.getPluginId()).thenReturn("jira");
-		when(jiraPlugin.getPluginPath()).thenReturn(Paths.get("plugins", "file.jar"));
-		when(pluginBox.unloadPlugin(integrationType)).thenReturn(true);
-
-		pluginLoaderService.checkAndDeleteIntegrationType(integrationType);
-
-		verify(integrationTypeRepository, times(1)).deleteById(integrationType.getId());
-	}
-
-	@Test
-	void checkAndDeleteIntegrationTypeWhenPluginNegative() {
-		IntegrationType integrationType = new IntegrationType();
-		integrationType.setId(1L);
-		integrationType.setName("jira");
-
-		when(pluginBox.getPluginById(integrationType.getName())).thenReturn(Optional.ofNullable(jiraPlugin));
-		when(jiraPlugin.getPluginId()).thenReturn("jira");
-		when(pluginBox.unloadPlugin(integrationType)).thenReturn(false);
-
-		pluginLoaderService.checkAndDeleteIntegrationType(integrationType);
-
-		verify(integrationTypeRepository, times(0)).deleteById(integrationType.getId());
-	}
-
-	@Test
-	void checkAndDeleteIntegrationTypeWhenNotPluginTest() {
-		IntegrationType integrationType = new IntegrationType();
-		integrationType.setId(1L);
-		integrationType.setName("EMAIL");
-
-		pluginLoaderService.checkAndDeleteIntegrationType(integrationType);
-
-		verify(integrationTypeRepository, times(0)).deleteById(integrationType.getId());
-	}
-
-	private List<IntegrationType> getIntegrationTypes() {
-
-		IntegrationType jira = new IntegrationType();
-		jira.setName("jira");
-		IntegrationTypeDetails jiraDetails = new IntegrationTypeDetails();
-		Map<String, Object> jiraParams = Maps.newHashMap();
-		jiraParams.put(IntegrationTypeProperties.FILE_ID.getAttribute(), "f1");
-		jiraParams.put(IntegrationTypeProperties.FILE_NAME.getAttribute(), "fname1");
-		jiraParams.put(IntegrationTypeProperties.VERSION.getAttribute(), "v1");
-		jiraParams.put(IntegrationTypeProperties.COMMANDS.getAttribute(), "");
-		jiraDetails.setDetails(jiraParams);
-		jira.setEnabled(true);
-		jira.setDetails(jiraDetails);
-
-		IntegrationType rally = new IntegrationType();
-		rally.setEnabled(true);
-		Map<String, Object> rallyParams = Maps.newHashMap();
-		rallyParams.put(IntegrationTypeProperties.FILE_ID.getAttribute(), "f2");
-		rallyParams.put(IntegrationTypeProperties.FILE_NAME.getAttribute(), "fname2");
-		rallyParams.put(IntegrationTypeProperties.VERSION.getAttribute(), "v2");
-		rallyParams.put(IntegrationTypeProperties.COMMANDS.getAttribute(), "");
-		IntegrationTypeDetails rallyDetails = new IntegrationTypeDetails();
-		rallyDetails.setDetails(rallyParams);
-		rally.setName("rally");
-		rally.setDetails(rallyDetails);
-
-		IntegrationType noDetails = new IntegrationType();
-		noDetails.setName("NO DETAILS");
-
-		IntegrationType emptyParams = new IntegrationType();
-		emptyParams.setName("EMPTY PARAMS");
-		emptyParams.setDetails(new IntegrationTypeDetails());
-
-		return Lists.newArrayList(jira, rally, noDetails, emptyParams);
-	}
+  private IntegrationTypeRepository integrationTypeRepository = mock(
+      IntegrationTypeRepository.class);
+
+  private Pf4jPluginBox pluginBox = mock(Pf4jPluginBox.class);
+
+  private PluginLoaderService pluginLoaderService = new PluginLoaderServiceImpl(
+      integrationTypeRepository, pluginBox);
+
+  private PluginWrapper jiraPlugin = mock(PluginWrapper.class);
+  private PluginWrapper rallyPlugin = mock(PluginWrapper.class);
+
+  private PluginDescriptor jiraPluginDescriptor = mock(PluginDescriptor.class);
+  private PluginDescriptor rallyPluginDescriptor = mock(PluginDescriptor.class);
+
+  @Test
+  void getNotLoadedPluginsInfoTest() {
+
+    when(pluginBox.getPluginById("jira")).thenReturn(Optional.ofNullable(jiraPlugin));
+    when(pluginBox.getPluginById("rally")).thenReturn(Optional.ofNullable(rallyPlugin));
+    when(jiraPlugin.getDescriptor()).thenReturn(jiraPluginDescriptor);
+    when(jiraPluginDescriptor.getVersion()).thenReturn("v1");
+    when(rallyPlugin.getDescriptor()).thenReturn(rallyPluginDescriptor);
+    when(rallyPluginDescriptor.getVersion()).thenReturn("another version");
+    when(integrationTypeRepository.findAll()).thenReturn(getIntegrationTypes());
+    List<PluginInfo> notLoadedPluginsInfo = pluginLoaderService.getNotLoadedPluginsInfo();
+
+    Assertions.assertFalse(notLoadedPluginsInfo.isEmpty());
+    Assertions.assertEquals(1, notLoadedPluginsInfo.size());
+    Assertions.assertEquals("rally", notLoadedPluginsInfo.get(0).getId());
+  }
+
+  @Test
+  void checkAndDeleteIntegrationTypeWhenPluginPositive() {
+    IntegrationType integrationType = new IntegrationType();
+    integrationType.setId(1L);
+    integrationType.setName("jira");
+
+    when(pluginBox.getPluginById(integrationType.getName())).thenReturn(
+        Optional.ofNullable(jiraPlugin));
+    when(jiraPlugin.getPluginId()).thenReturn("jira");
+    when(jiraPlugin.getPluginPath()).thenReturn(Paths.get("plugins", "file.jar"));
+    when(pluginBox.unloadPlugin(integrationType)).thenReturn(true);
+
+    pluginLoaderService.checkAndDeleteIntegrationType(integrationType);
+
+    verify(integrationTypeRepository, times(1)).deleteById(integrationType.getId());
+  }
+
+  @Test
+  void checkAndDeleteIntegrationTypeWhenPluginNegative() {
+    IntegrationType integrationType = new IntegrationType();
+    integrationType.setId(1L);
+    integrationType.setName("jira");
+
+    when(pluginBox.getPluginById(integrationType.getName())).thenReturn(
+        Optional.ofNullable(jiraPlugin));
+    when(jiraPlugin.getPluginId()).thenReturn("jira");
+    when(pluginBox.unloadPlugin(integrationType)).thenReturn(false);
+
+    pluginLoaderService.checkAndDeleteIntegrationType(integrationType);
+
+    verify(integrationTypeRepository, times(0)).deleteById(integrationType.getId());
+  }
+
+  @Test
+  void checkAndDeleteIntegrationTypeWhenNotPluginTest() {
+    IntegrationType integrationType = new IntegrationType();
+    integrationType.setId(1L);
+    integrationType.setName("EMAIL");
+
+    pluginLoaderService.checkAndDeleteIntegrationType(integrationType);
+
+    verify(integrationTypeRepository, times(0)).deleteById(integrationType.getId());
+  }
+
+  private List<IntegrationType> getIntegrationTypes() {
+
+    IntegrationType jira = new IntegrationType();
+    jira.setName("jira");
+    IntegrationTypeDetails jiraDetails = new IntegrationTypeDetails();
+    Map<String, Object> jiraParams = Maps.newHashMap();
+    jiraParams.put(IntegrationTypeProperties.FILE_ID.getAttribute(), "f1");
+    jiraParams.put(IntegrationTypeProperties.FILE_NAME.getAttribute(), "fname1");
+    jiraParams.put(IntegrationTypeProperties.VERSION.getAttribute(), "v1");
+    jiraParams.put(IntegrationTypeProperties.COMMANDS.getAttribute(), "");
+    jiraDetails.setDetails(jiraParams);
+    jira.setEnabled(true);
+    jira.setDetails(jiraDetails);
+
+    IntegrationType rally = new IntegrationType();
+    rally.setEnabled(true);
+    Map<String, Object> rallyParams = Maps.newHashMap();
+    rallyParams.put(IntegrationTypeProperties.FILE_ID.getAttribute(), "f2");
+    rallyParams.put(IntegrationTypeProperties.FILE_NAME.getAttribute(), "fname2");
+    rallyParams.put(IntegrationTypeProperties.VERSION.getAttribute(), "v2");
+    rallyParams.put(IntegrationTypeProperties.COMMANDS.getAttribute(), "");
+    IntegrationTypeDetails rallyDetails = new IntegrationTypeDetails();
+    rallyDetails.setDetails(rallyParams);
+    rally.setName("rally");
+    rally.setDetails(rallyDetails);
+
+    IntegrationType noDetails = new IntegrationType();
+    noDetails.setName("NO DETAILS");
+
+    IntegrationType emptyParams = new IntegrationType();
+    emptyParams.setName("EMPTY PARAMS");
+    emptyParams.setDetails(new IntegrationTypeDetails());
+
+    return Lists.newArrayList(jira, rally, noDetails, emptyParams);
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/job/SaveLogBinaryDataTaskTest.java b/src/test/java/com/epam/ta/reportportal/job/SaveLogBinaryDataTaskTest.java
deleted file mode 100644
index 651eea4482..0000000000
--- a/src/test/java/com/epam/ta/reportportal/job/SaveLogBinaryDataTaskTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2019 EPAM Systems
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.epam.ta.reportportal.job;
-
-import com.epam.ta.reportportal.binary.AttachmentBinaryDataService;
-import com.epam.ta.reportportal.core.log.impl.SaveLogBinaryDataTask;
-import com.epam.ta.reportportal.entity.attachment.AttachmentMetaInfo;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-import org.springframework.mock.web.MockMultipartFile;
-
-import java.nio.charset.StandardCharsets;
-
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-/**
- * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
- */
-@ExtendWith(MockitoExtension.class)
-class SaveLogBinaryDataTaskTest {
-
-	@Mock
-	private AttachmentBinaryDataService attachmentBinaryDataService;
-
-	@InjectMocks
-	private SaveLogBinaryDataTask saveLogBinaryDataTask;
-
-	@Test
-	void saveBinaryDataPositive() {
-		long logId = 1L;
-		MockMultipartFile file = new MockMultipartFile("file", "filename", "text/plain", "some data".getBytes(StandardCharsets.UTF_8));
-		long projectId = 2L;
-		AttachmentMetaInfo attachmentMetaInfo = AttachmentMetaInfo.builder().withLogId(logId).withProjectId(projectId).build();
-		SaveLogBinaryDataTask saveLogBinaryDataTask = this.saveLogBinaryDataTask.withFile(file).withAttachmentMetaInfo(attachmentMetaInfo);
-
-		saveLogBinaryDataTask.run();
-
-		verify(attachmentBinaryDataService, times(1)).saveFileAndAttachToLog(file, attachmentMetaInfo);
-
-	}
-}
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/job/SelfCancalableJobTest.java b/src/test/java/com/epam/ta/reportportal/job/SelfCancalableJobTest.java
index 41ce2498f7..0e9ebbef99 100644
--- a/src/test/java/com/epam/ta/reportportal/job/SelfCancalableJobTest.java
+++ b/src/test/java/com/epam/ta/reportportal/job/SelfCancalableJobTest.java
@@ -16,6 +16,8 @@
 
 package com.epam.ta.reportportal.job;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.Mock;
@@ -24,8 +26,6 @@
 import org.springframework.scheduling.TriggerContext;
 import org.springframework.test.util.ReflectionTestUtils;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
 /**
  * Created by Andrey_Ivanov1 on 01-Jun-17.
  */
@@ -33,27 +33,28 @@
 @ExtendWith(MockitoExtension.class)
 class SelfCancelableJobTest {
 
-	@Mock
-	private Trigger triggerDelegate;
-	@Mock
-	private TriggerContext triggerContext;
-
-	@Test
-	void selfCancelableJobTest() {
-		SelfCancelableJob selfCancelableJob = new SelfCancelableJob(triggerDelegate) {
-			@Override
-			public void run() {
-			}
-		};
-
-		assertEquals(true, ReflectionTestUtils.getField(selfCancelableJob, "oneMoreTime"));
-		assertEquals(triggerDelegate, ReflectionTestUtils.getField(selfCancelableJob, "triggerDelegate"));
-		selfCancelableJob.oneMoreTime(true);
-		selfCancelableJob.nextExecutionTime(triggerContext);
-		assertEquals(true, ReflectionTestUtils.getField(selfCancelableJob, "oneMoreTime"));
-		selfCancelableJob.oneMoreTime(false);
-		selfCancelableJob.nextExecutionTime(triggerContext);
-		assertEquals(false, ReflectionTestUtils.getField(selfCancelableJob, "oneMoreTime"));
-	}
+  @Mock
+  private Trigger triggerDelegate;
+  @Mock
+  private TriggerContext triggerContext;
+
+  @Test
+  void selfCancelableJobTest() {
+    SelfCancelableJob selfCancelableJob = new SelfCancelableJob(triggerDelegate) {
+      @Override
+      public void run() {
+      }
+    };
+
+    assertEquals(true, ReflectionTestUtils.getField(selfCancelableJob, "oneMoreTime"));
+    assertEquals(triggerDelegate,
+        ReflectionTestUtils.getField(selfCancelableJob, "triggerDelegate"));
+    selfCancelableJob.oneMoreTime(true);
+    selfCancelableJob.nextExecutionTime(triggerContext);
+    assertEquals(true, ReflectionTestUtils.getField(selfCancelableJob, "oneMoreTime"));
+    selfCancelableJob.oneMoreTime(false);
+    selfCancelableJob.nextExecutionTime(triggerContext);
+    assertEquals(false, ReflectionTestUtils.getField(selfCancelableJob, "oneMoreTime"));
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/plugin/Pf4jPluginManagerTest.java b/src/test/java/com/epam/ta/reportportal/plugin/Pf4jPluginManagerTest.java
index f8f24e16bd..fd9aeef652 100644
--- a/src/test/java/com/epam/ta/reportportal/plugin/Pf4jPluginManagerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/plugin/Pf4jPluginManagerTest.java
@@ -16,6 +16,14 @@
 
 package com.epam.ta.reportportal.plugin;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import com.epam.reportportal.extension.bugtracking.BtsExtension;
 import com.epam.ta.reportportal.core.integration.impl.util.IntegrationTestUtil;
 import com.epam.ta.reportportal.core.integration.plugin.PluginLoader;
@@ -26,6 +34,13 @@
 import com.epam.ta.reportportal.entity.integration.IntegrationTypeDetails;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.google.common.collect.Lists;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.List;
 import org.apache.commons.io.FileUtils;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Test;
@@ -36,196 +51,207 @@
 import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
 import org.springframework.context.ApplicationEventPublisher;
 
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.file.FileSystems;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.List;
-
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.*;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class Pf4jPluginManagerTest {
 
-	public static final String PLUGINS_PATH = "plugins";
-	public static final String RESOURCES_PATH = "resources";
-	public static final String PLUGINS_TEMP_PATH = "plugins/temp";
-	public static final String NEW_PLUGIN_FILE_NAME = "plugin.jar";
-
-	public static final String NEW_JIRA_PLUGIN_ID = "new_jira";
-	public static final String NEW_JIRA_PLUGIN_VERSION = "1.0";
-
-	private final PluginLoader pluginLoader = mock(PluginLoader.class);
-	private final IntegrationTypeRepository integrationTypeRepository = mock(IntegrationTypeRepository.class);
-	private final AutowireCapableBeanFactory beanFactory = mock(AutowireCapableBeanFactory.class);
-	private final PluginManager pluginManager = mock(PluginManager.class);
-	private final PluginWrapper previousPlugin = mock(PluginWrapper.class);
-	private final PluginWrapper newPlugin = mock(PluginWrapper.class);
-	private final ApplicationEventPublisher applicationEventPublisher = mock(ApplicationEventPublisher.class);
-
-	private final Pf4jPluginManager pluginBox = new Pf4jPluginManager(PLUGINS_PATH,
-			PLUGINS_TEMP_PATH,
-			RESOURCES_PATH,
-			pluginLoader,
-			integrationTypeRepository,
-			pluginManager,
-			beanFactory,
-			applicationEventPublisher
-	);
-
-	private final InputStream fileStream = mock(InputStream.class);
-
-	Pf4jPluginManagerTest() throws IOException {
-	}
-
-	@AfterEach
-	void cleanUp() throws IOException {
-		File directory = new File("plugins");
-		if (directory.exists()) {
-			FileUtils.deleteDirectory(directory);
-		}
-	}
-
-	@Test
-	void uploadPlugin() throws PluginException, IOException {
-		PluginInfo pluginInfo = getPluginInfo();
-
-		when(pluginLoader.extractPluginInfo(Paths.get(PLUGINS_TEMP_PATH, NEW_PLUGIN_FILE_NAME))).thenReturn(pluginInfo);
-		IntegrationType jiraIntegrationType = IntegrationTestUtil.getJiraIntegrationType();
-		IntegrationTypeDetails jiraDetails = jiraIntegrationType.getDetails();
-		when(pluginLoader.resolvePluginDetails(pluginInfo)).thenReturn(jiraDetails);
-		when(pluginManager.getPlugin("old_jira")).then((i) -> {
-			pluginInfo.setId(NEW_JIRA_PLUGIN_ID);
-			return null;
-		});
-		when(pluginManager.loadPlugin(Paths.get(PLUGINS_TEMP_PATH, NEW_PLUGIN_FILE_NAME))).thenReturn(NEW_JIRA_PLUGIN_ID);
-		when(pluginManager.getPlugin(NEW_JIRA_PLUGIN_ID)).thenReturn(newPlugin);
-		when(pluginManager.getPluginsRoot()).thenReturn(FileSystems.getDefault().getPath(PLUGINS_PATH));
-		when(pluginLoader.validatePluginExtensionClasses(newPlugin)).thenReturn(true);
-		doNothing().when(pluginLoader).savePlugin(Paths.get(PLUGINS_PATH, NEW_PLUGIN_FILE_NAME), fileStream);
-
-		String pluginFileName = NEW_JIRA_PLUGIN_ID + "-" + NEW_JIRA_PLUGIN_VERSION + ".jar";
-		when(pluginLoader.saveToDataStore(pluginFileName, fileStream)).thenReturn(pluginFileName);
-		when(pluginManager.loadPlugin(Paths.get(PLUGINS_PATH, pluginFileName))).thenReturn(NEW_JIRA_PLUGIN_ID);
-		when(integrationTypeRepository.save(any(IntegrationType.class))).thenReturn(jiraIntegrationType);
-		Files.createFile(Paths.get(PLUGINS_TEMP_PATH, "plugin.jar"));
-		IntegrationType newIntegrationType = pluginBox.uploadPlugin(NEW_PLUGIN_FILE_NAME, fileStream);
-		assertEquals(1L, newIntegrationType.getId().longValue());
-	}
-
-	@Test
-	void uploadPluginWithExistingFile() throws PluginException, IOException {
-		File tempFile = File.createTempFile(NEW_PLUGIN_FILE_NAME, ".jar", new File(PLUGINS_TEMP_PATH));
-		tempFile.deleteOnExit();
-		PluginInfo pluginInfo = getPluginInfo();
-		when(pluginLoader.extractPluginInfo(Paths.get(PLUGINS_TEMP_PATH, tempFile.getName()))).thenReturn(pluginInfo);
-		IntegrationType jiraIntegrationType = IntegrationTestUtil.getJiraIntegrationType();
-		IntegrationTypeDetails jiraDetails = jiraIntegrationType.getDetails();
-		when(pluginLoader.resolvePluginDetails(pluginInfo)).thenReturn(jiraDetails);
-		when(pluginManager.getPlugin("old_jira")).then((i) -> {
-			pluginInfo.setId(NEW_JIRA_PLUGIN_ID);
-			return null;
-		});
-		when(pluginManager.loadPlugin(Paths.get(PLUGINS_TEMP_PATH, tempFile.getName()))).thenReturn(NEW_JIRA_PLUGIN_ID);
-		when(pluginManager.getPlugin(NEW_JIRA_PLUGIN_ID)).thenReturn(newPlugin);
-		when(pluginManager.getPluginsRoot()).thenReturn(FileSystems.getDefault().getPath(PLUGINS_PATH));
-		when(pluginLoader.validatePluginExtensionClasses(newPlugin)).thenReturn(true);
-		String pluginFileName = NEW_JIRA_PLUGIN_ID + "-" + NEW_JIRA_PLUGIN_VERSION + ".jar";
-		when(pluginManager.loadPlugin(Paths.get(PLUGINS_PATH, pluginFileName))).thenReturn(NEW_JIRA_PLUGIN_ID);
-		when(integrationTypeRepository.save(any(IntegrationType.class))).thenReturn(jiraIntegrationType);
-		IntegrationType newIntegrationType = pluginBox.uploadPlugin(tempFile.getName(), fileStream);
-		assertEquals(1L, newIntegrationType.getId().longValue());
-	}
-
-	@Test
-	void uploadPluginWithLoadingError() throws PluginException {
-
-		PluginInfo pluginInfo = getPluginInfo();
-		when(pluginLoader.extractPluginInfo(Paths.get(PLUGINS_TEMP_PATH, NEW_PLUGIN_FILE_NAME))).thenReturn(pluginInfo);
-		IntegrationType jiraIntegrationType = IntegrationTestUtil.getJiraIntegrationType();
-		IntegrationTypeDetails jiraDetails = jiraIntegrationType.getDetails();
-		when(pluginLoader.resolvePluginDetails(pluginInfo)).thenReturn(jiraDetails);
-		when(pluginManager.getPlugin("old_jira")).then((i) -> {
-			pluginInfo.setId(NEW_JIRA_PLUGIN_ID);
-			return null;
-		});
-		when(previousPlugin.getPluginState()).thenReturn(PluginState.STARTED);
-		when(pluginManager.getPluginsRoot()).thenReturn(FileSystems.getDefault().getPath(PLUGINS_PATH));
-		when(pluginManager.loadPlugin(Paths.get(PLUGINS_TEMP_PATH, NEW_PLUGIN_FILE_NAME))).thenReturn(null);
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> pluginBox.uploadPlugin(NEW_PLUGIN_FILE_NAME, fileStream)
-		);
-		assertEquals("Error during plugin uploading: 'Failed to load new plugin from file = 'plugin.jar''", exception.getMessage());
-	}
-
-	@Test
-	void uploadPluginWithoutExtensionClasses() throws PluginException {
-
-		PluginInfo pluginInfo = getPluginInfo();
-		when(pluginLoader.extractPluginInfo(Paths.get(PLUGINS_TEMP_PATH, NEW_PLUGIN_FILE_NAME))).thenReturn(pluginInfo);
-		IntegrationType jiraIntegrationType = IntegrationTestUtil.getJiraIntegrationType();
-		IntegrationTypeDetails jiraDetails = jiraIntegrationType.getDetails();
-		when(pluginLoader.resolvePluginDetails(pluginInfo)).thenReturn(jiraDetails);
-		when(pluginManager.getPlugin("old_jira")).then((i) -> {
-			pluginInfo.setId(NEW_JIRA_PLUGIN_ID);
-			return null;
-		});
-		when(pluginManager.loadPlugin(Paths.get(PLUGINS_TEMP_PATH, NEW_PLUGIN_FILE_NAME))).thenReturn(NEW_JIRA_PLUGIN_ID);
-		when(pluginManager.getPlugin(NEW_JIRA_PLUGIN_ID)).thenReturn(newPlugin);
-		when(pluginManager.getPluginsRoot()).thenReturn(FileSystems.getDefault().getPath(PLUGINS_PATH));
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> pluginBox.uploadPlugin(NEW_PLUGIN_FILE_NAME, fileStream)
-		);
-		assertEquals("Error during plugin uploading: 'New plugin with id = 'new_jira' doesn't have mandatory extension classes.'",
-				exception.getMessage()
-		);
-	}
-
-	@Test
-	void uploadPluginWithPluginException() throws PluginException {
-
-		when(pluginLoader.extractPluginInfo(Paths.get(PLUGINS_TEMP_PATH, NEW_PLUGIN_FILE_NAME))).thenThrow(new PluginException(
-				"Manifest not found"));
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> pluginBox.uploadPlugin(NEW_PLUGIN_FILE_NAME, fileStream)
-		);
-		assertEquals("Error during plugin uploading: 'Manifest not found'", exception.getMessage());
-	}
-
-	@Test
-	void uploadPluginWithoutVersion() throws PluginException {
-
-		when(pluginLoader.extractPluginInfo(Paths.get(PLUGINS_TEMP_PATH, NEW_PLUGIN_FILE_NAME))).thenReturn(getPluginInfoWithoutVersion());
-
-		final ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> pluginBox.uploadPlugin(NEW_PLUGIN_FILE_NAME, fileStream)
-		);
-		assertEquals("Error during plugin uploading: 'Plugin version should be specified.'", exception.getMessage());
-	}
-
-	@Test
-	void getPlugins() {
-		when(pluginManager.getPlugins()).thenReturn(Lists.newArrayList(newPlugin));
-		when(newPlugin.getPluginId()).thenReturn(NEW_JIRA_PLUGIN_ID);
-		when(pluginManager.getExtensionClasses(NEW_JIRA_PLUGIN_ID)).thenReturn(Lists.newArrayList(BtsExtension.class));
-		List<Plugin> plugins = pluginBox.getPlugins();
-		assertNotNull(plugins);
-		assertEquals(1L, plugins.size());
-	}
-
-	private PluginInfo getPluginInfo() {
-		return new PluginInfo("old_jira", NEW_JIRA_PLUGIN_VERSION);
-	}
-
-	private PluginInfo getPluginInfoWithoutVersion() {
-		return new PluginInfo("jira", null);
-	}
+  public static final String PLUGINS_PATH = "plugins";
+  public static final String RESOURCES_PATH = "resources";
+  public static final String PLUGINS_TEMP_PATH = "plugins/temp";
+  public static final String NEW_PLUGIN_FILE_NAME = "plugin.jar";
+
+  public static final String NEW_JIRA_PLUGIN_ID = "new_jira";
+  public static final String NEW_JIRA_PLUGIN_VERSION = "1.0";
+
+  private final PluginLoader pluginLoader = mock(PluginLoader.class);
+  private final IntegrationTypeRepository integrationTypeRepository = mock(
+      IntegrationTypeRepository.class);
+  private final AutowireCapableBeanFactory beanFactory = mock(AutowireCapableBeanFactory.class);
+  private final PluginManager pluginManager = mock(PluginManager.class);
+  private final PluginWrapper previousPlugin = mock(PluginWrapper.class);
+  private final PluginWrapper newPlugin = mock(PluginWrapper.class);
+  private final ApplicationEventPublisher applicationEventPublisher = mock(
+      ApplicationEventPublisher.class);
+
+  private final Pf4jPluginManager pluginBox = new Pf4jPluginManager(PLUGINS_PATH,
+      PLUGINS_TEMP_PATH,
+      RESOURCES_PATH,
+      pluginLoader,
+      integrationTypeRepository,
+      pluginManager,
+      beanFactory,
+      applicationEventPublisher
+  );
+
+  private final InputStream fileStream = mock(InputStream.class);
+
+  Pf4jPluginManagerTest() throws IOException {
+  }
+
+  @AfterEach
+  void cleanUp() throws IOException {
+    File directory = new File("plugins");
+    if (directory.exists()) {
+      FileUtils.deleteDirectory(directory);
+    }
+  }
+
+  @Test
+  void uploadPlugin() throws PluginException, IOException {
+    PluginInfo pluginInfo = getPluginInfo();
+
+    when(pluginLoader.extractPluginInfo(
+        Paths.get(PLUGINS_TEMP_PATH, NEW_PLUGIN_FILE_NAME))).thenReturn(pluginInfo);
+    IntegrationType jiraIntegrationType = IntegrationTestUtil.getJiraIntegrationType();
+    IntegrationTypeDetails jiraDetails = jiraIntegrationType.getDetails();
+    when(pluginLoader.resolvePluginDetails(pluginInfo)).thenReturn(jiraDetails);
+    when(pluginManager.getPlugin("old_jira")).then((i) -> {
+      pluginInfo.setId(NEW_JIRA_PLUGIN_ID);
+      return null;
+    });
+    when(pluginManager.loadPlugin(Paths.get(PLUGINS_TEMP_PATH, NEW_PLUGIN_FILE_NAME))).thenReturn(
+        NEW_JIRA_PLUGIN_ID);
+    when(pluginManager.getPlugin(NEW_JIRA_PLUGIN_ID)).thenReturn(newPlugin);
+    when(pluginManager.getPluginsRoot()).thenReturn(FileSystems.getDefault().getPath(PLUGINS_PATH));
+    when(pluginLoader.validatePluginExtensionClasses(newPlugin)).thenReturn(true);
+    doNothing().when(pluginLoader)
+        .savePlugin(Paths.get(PLUGINS_PATH, NEW_PLUGIN_FILE_NAME), fileStream);
+
+    String pluginFileName = NEW_JIRA_PLUGIN_ID + "-" + NEW_JIRA_PLUGIN_VERSION + ".jar";
+    when(pluginLoader.saveToDataStore(pluginFileName, fileStream)).thenReturn(pluginFileName);
+    when(pluginManager.loadPlugin(Paths.get(PLUGINS_PATH, pluginFileName))).thenReturn(
+        NEW_JIRA_PLUGIN_ID);
+    when(integrationTypeRepository.save(any(IntegrationType.class))).thenReturn(
+        jiraIntegrationType);
+    Files.createFile(Paths.get(PLUGINS_TEMP_PATH, "plugin.jar"));
+    IntegrationType newIntegrationType = pluginBox.uploadPlugin(NEW_PLUGIN_FILE_NAME, fileStream);
+    assertEquals(1L, newIntegrationType.getId().longValue());
+  }
+
+  @Test
+  void uploadPluginWithExistingFile() throws PluginException, IOException {
+    File tempFile = File.createTempFile(NEW_PLUGIN_FILE_NAME, ".jar", new File(PLUGINS_TEMP_PATH));
+    tempFile.deleteOnExit();
+    PluginInfo pluginInfo = getPluginInfo();
+    when(pluginLoader.extractPluginInfo(
+        Paths.get(PLUGINS_TEMP_PATH, tempFile.getName()))).thenReturn(pluginInfo);
+    IntegrationType jiraIntegrationType = IntegrationTestUtil.getJiraIntegrationType();
+    IntegrationTypeDetails jiraDetails = jiraIntegrationType.getDetails();
+    when(pluginLoader.resolvePluginDetails(pluginInfo)).thenReturn(jiraDetails);
+    when(pluginManager.getPlugin("old_jira")).then((i) -> {
+      pluginInfo.setId(NEW_JIRA_PLUGIN_ID);
+      return null;
+    });
+    when(pluginManager.loadPlugin(Paths.get(PLUGINS_TEMP_PATH, tempFile.getName()))).thenReturn(
+        NEW_JIRA_PLUGIN_ID);
+    when(pluginManager.getPlugin(NEW_JIRA_PLUGIN_ID)).thenReturn(newPlugin);
+    when(pluginManager.getPluginsRoot()).thenReturn(FileSystems.getDefault().getPath(PLUGINS_PATH));
+    when(pluginLoader.validatePluginExtensionClasses(newPlugin)).thenReturn(true);
+    String pluginFileName = NEW_JIRA_PLUGIN_ID + "-" + NEW_JIRA_PLUGIN_VERSION + ".jar";
+    when(pluginManager.loadPlugin(Paths.get(PLUGINS_PATH, pluginFileName))).thenReturn(
+        NEW_JIRA_PLUGIN_ID);
+    when(integrationTypeRepository.save(any(IntegrationType.class))).thenReturn(
+        jiraIntegrationType);
+    IntegrationType newIntegrationType = pluginBox.uploadPlugin(tempFile.getName(), fileStream);
+    assertEquals(1L, newIntegrationType.getId().longValue());
+  }
+
+  @Test
+  void uploadPluginWithLoadingError() throws PluginException {
+
+    PluginInfo pluginInfo = getPluginInfo();
+    when(pluginLoader.extractPluginInfo(
+        Paths.get(PLUGINS_TEMP_PATH, NEW_PLUGIN_FILE_NAME))).thenReturn(pluginInfo);
+    IntegrationType jiraIntegrationType = IntegrationTestUtil.getJiraIntegrationType();
+    IntegrationTypeDetails jiraDetails = jiraIntegrationType.getDetails();
+    when(pluginLoader.resolvePluginDetails(pluginInfo)).thenReturn(jiraDetails);
+    when(pluginManager.getPlugin("old_jira")).then((i) -> {
+      pluginInfo.setId(NEW_JIRA_PLUGIN_ID);
+      return null;
+    });
+    when(previousPlugin.getPluginState()).thenReturn(PluginState.STARTED);
+    when(pluginManager.getPluginsRoot()).thenReturn(FileSystems.getDefault().getPath(PLUGINS_PATH));
+    when(pluginManager.loadPlugin(Paths.get(PLUGINS_TEMP_PATH, NEW_PLUGIN_FILE_NAME))).thenReturn(
+        null);
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> pluginBox.uploadPlugin(NEW_PLUGIN_FILE_NAME, fileStream)
+    );
+    assertEquals(
+        "Error during plugin uploading: 'Failed to load new plugin from file = 'plugin.jar''",
+        exception.getMessage());
+  }
+
+  @Test
+  void uploadPluginWithoutExtensionClasses() throws PluginException {
+
+    PluginInfo pluginInfo = getPluginInfo();
+    when(pluginLoader.extractPluginInfo(
+        Paths.get(PLUGINS_TEMP_PATH, NEW_PLUGIN_FILE_NAME))).thenReturn(pluginInfo);
+    IntegrationType jiraIntegrationType = IntegrationTestUtil.getJiraIntegrationType();
+    IntegrationTypeDetails jiraDetails = jiraIntegrationType.getDetails();
+    when(pluginLoader.resolvePluginDetails(pluginInfo)).thenReturn(jiraDetails);
+    when(pluginManager.getPlugin("old_jira")).then((i) -> {
+      pluginInfo.setId(NEW_JIRA_PLUGIN_ID);
+      return null;
+    });
+    when(pluginManager.loadPlugin(Paths.get(PLUGINS_TEMP_PATH, NEW_PLUGIN_FILE_NAME))).thenReturn(
+        NEW_JIRA_PLUGIN_ID);
+    when(pluginManager.getPlugin(NEW_JIRA_PLUGIN_ID)).thenReturn(newPlugin);
+    when(pluginManager.getPluginsRoot()).thenReturn(FileSystems.getDefault().getPath(PLUGINS_PATH));
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> pluginBox.uploadPlugin(NEW_PLUGIN_FILE_NAME, fileStream)
+    );
+    assertEquals(
+        "Error during plugin uploading: 'New plugin with id = 'new_jira' doesn't have mandatory extension classes.'",
+        exception.getMessage()
+    );
+  }
+
+  @Test
+  void uploadPluginWithPluginException() throws PluginException {
+
+    when(pluginLoader.extractPluginInfo(
+        Paths.get(PLUGINS_TEMP_PATH, NEW_PLUGIN_FILE_NAME))).thenThrow(new PluginException(
+        "Manifest not found"));
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> pluginBox.uploadPlugin(NEW_PLUGIN_FILE_NAME, fileStream)
+    );
+    assertEquals("Error during plugin uploading: 'Manifest not found'", exception.getMessage());
+  }
+
+  @Test
+  void uploadPluginWithoutVersion() throws PluginException {
+
+    when(pluginLoader.extractPluginInfo(
+        Paths.get(PLUGINS_TEMP_PATH, NEW_PLUGIN_FILE_NAME))).thenReturn(
+        getPluginInfoWithoutVersion());
+
+    final ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> pluginBox.uploadPlugin(NEW_PLUGIN_FILE_NAME, fileStream)
+    );
+    assertEquals("Error during plugin uploading: 'Plugin version should be specified.'",
+        exception.getMessage());
+  }
+
+  @Test
+  void getPlugins() {
+    when(pluginManager.getPlugins()).thenReturn(Lists.newArrayList(newPlugin));
+    when(newPlugin.getPluginId()).thenReturn(NEW_JIRA_PLUGIN_ID);
+    when(pluginManager.getExtensionClasses(NEW_JIRA_PLUGIN_ID)).thenReturn(
+        Lists.newArrayList(BtsExtension.class));
+    List<Plugin> plugins = pluginBox.getPlugins();
+    assertNotNull(plugins);
+    assertEquals(1L, plugins.size());
+  }
+
+  private PluginInfo getPluginInfo() {
+    return new PluginInfo("old_jira", NEW_JIRA_PLUGIN_VERSION);
+  }
+
+  private PluginInfo getPluginInfoWithoutVersion() {
+    return new PluginInfo("jira", null);
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/store/service/DataStoreServiceTest.java b/src/test/java/com/epam/ta/reportportal/store/service/DataStoreServiceTest.java
index 577e6866da..0c8a49bb3d 100644
--- a/src/test/java/com/epam/ta/reportportal/store/service/DataStoreServiceTest.java
+++ b/src/test/java/com/epam/ta/reportportal/store/service/DataStoreServiceTest.java
@@ -16,10 +16,22 @@
 
 package com.epam.ta.reportportal.store.service;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.reportportal.commons.Thumbnailator;
 import com.epam.ta.reportportal.binary.impl.AttachmentDataStoreService;
 import com.epam.ta.reportportal.filesystem.DataEncoder;
 import com.epam.ta.reportportal.filesystem.DataStore;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Optional;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.InjectMocks;
@@ -27,84 +39,77 @@
 import org.mockito.junit.jupiter.MockitoExtension;
 import org.springframework.web.multipart.MultipartFile;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Optional;
-
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.Mockito.*;
-
 /**
  * @author Dzianis_Shybeka
  */
 @ExtendWith(MockitoExtension.class)
 class DataStoreServiceTest {
 
-	@Mock
-	private DataStore dataStore;
+  @Mock
+  private DataStore dataStore;
 
-	@Mock
-	private Thumbnailator thumbnailator;
+  @Mock
+  private Thumbnailator thumbnailator;
 
-	@Mock
-	private DataEncoder dataEncoder;
+  @Mock
+  private DataEncoder dataEncoder;
 
-	@InjectMocks
-	private AttachmentDataStoreService dataStoreService;
+  @InjectMocks
+  private AttachmentDataStoreService dataStoreService;
 
-	@Test
-	void saveTest() throws Exception {
-		//  given:
-		MultipartFile file = mock(MultipartFile.class);
+  @Test
+  void saveTest() throws Exception {
+    //  given:
+    MultipartFile file = mock(MultipartFile.class);
 
-		//  and: setups
-		when(dataStore.save("fileName", file.getInputStream())).thenReturn("filePath");
-		when(dataEncoder.encode("filePath")).thenReturn("fileId");
+    //  and: setups
+    when(dataStore.save("fileName", file.getInputStream())).thenReturn("filePath");
+    when(dataEncoder.encode("filePath")).thenReturn("fileId");
 
-		//  when:
-		String fileId = dataStoreService.save("fileName", file.getInputStream());
+    //  when:
+    String fileId = dataStoreService.save("fileName", file.getInputStream());
 
-		assertEquals("fileId", fileId);
-	}
+    assertEquals("fileId", fileId);
+  }
 
-	@Test
-	void saveThumbnailTest() throws IOException {
-		MultipartFile file = mock(MultipartFile.class);
+  @Test
+  void saveThumbnailTest() throws IOException {
+    MultipartFile file = mock(MultipartFile.class);
 
-		when(dataStore.save("fileName", file.getInputStream())).thenReturn("thumbnailPath");
-		when(dataEncoder.encode("thumbnailPath")).thenReturn("thumbnailId");
+    when(dataStore.save("fileName", file.getInputStream())).thenReturn("thumbnailPath");
+    when(dataEncoder.encode("thumbnailPath")).thenReturn("thumbnailId");
 
-		assertEquals("thumbnailId", dataStoreService.saveThumbnail("fileName", file.getInputStream()));
-	}
+    assertEquals("thumbnailId", dataStoreService.saveThumbnail("fileName", file.getInputStream()));
+  }
 
-	@Test
-	void saveThumbnailWithException() throws IOException {
-		MultipartFile file = mock(MultipartFile.class);
+  @Test
+  void saveThumbnailWithException() throws IOException {
+    MultipartFile file = mock(MultipartFile.class);
 
-		when(thumbnailator.createThumbnail(file.getInputStream())).thenThrow(IOException.class);
+    when(thumbnailator.createThumbnail(file.getInputStream())).thenThrow(IOException.class);
 
-		assertNull(dataStoreService.saveThumbnail("fileName", file.getInputStream()));
-	}
+    assertNull(dataStoreService.saveThumbnail("fileName", file.getInputStream()));
+  }
 
-	@Test
-	void deleteTest() {
-		when(dataEncoder.decode("fileId")).thenReturn("filePath");
+  @Test
+  void deleteTest() {
+    when(dataEncoder.decode("fileId")).thenReturn("filePath");
 
-		dataStoreService.delete("fileId");
+    dataStoreService.delete("fileId");
 
-		verify(dataStore, times(1)).delete("filePath");
-	}
+    verify(dataStore, times(1)).delete("filePath");
+  }
 
-	@Test
-	void loadTest() {
-		InputStream inputStream = mock(InputStream.class);
+  @Test
+  void loadTest() {
+    InputStream inputStream = mock(InputStream.class);
 
-		when(dataEncoder.decode("fileId")).thenReturn("filePath");
-		when(dataStore.load("filePath")).thenReturn(inputStream);
+    when(dataEncoder.decode("fileId")).thenReturn("filePath");
+    when(dataStore.load("filePath")).thenReturn(inputStream);
 
-		Optional<InputStream> content = dataStoreService.load("fileId");
+    Optional<InputStream> content = dataStoreService.load("fileId");
 
-		assertTrue(content.isPresent());
-		assertSame(inputStream, content.get());
-	}
+    assertTrue(content.isPresent());
+    assertSame(inputStream, content.get());
+  }
 }
diff --git a/src/test/java/com/epam/ta/reportportal/util/ApplicationContextAwareFactoryBeanTest.java b/src/test/java/com/epam/ta/reportportal/util/ApplicationContextAwareFactoryBeanTest.java
index bbf7cc84a6..afffaf5bfb 100644
--- a/src/test/java/com/epam/ta/reportportal/util/ApplicationContextAwareFactoryBeanTest.java
+++ b/src/test/java/com/epam/ta/reportportal/util/ApplicationContextAwareFactoryBeanTest.java
@@ -16,6 +16,9 @@
 
 package com.epam.ta.reportportal.util;
 
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.springframework.beans.factory.FactoryBean;
@@ -26,44 +29,41 @@
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
 
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.is;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @ExtendWith(SpringExtension.class)
-@ContextConfiguration(classes = { ApplicationContextAwareFactoryBeanTest.TestConfig.class })
+@ContextConfiguration(classes = {ApplicationContextAwareFactoryBeanTest.TestConfig.class})
 public class ApplicationContextAwareFactoryBeanTest {
 
-	@Autowired
-	private ApplicationContextAwareFactoryBeanTest testObject;
+  @Autowired
+  private ApplicationContextAwareFactoryBeanTest testObject;
 
-	@Autowired
-	private ApplicationContext context;
+  @Autowired
+  private ApplicationContext context;
 
-	@Test
-	void testSingleton() {
-		assertThat(testObject, is(context.getBean(ApplicationContextAwareFactoryBeanTest.class)));
-	}
+  @Test
+  void testSingleton() {
+    assertThat(testObject, is(context.getBean(ApplicationContextAwareFactoryBeanTest.class)));
+  }
 
-	@Configuration
-	public static class TestConfig {
+  @Configuration
+  public static class TestConfig {
 
-		@Bean
-		FactoryBean<ApplicationContextAwareFactoryBeanTest> resourceCopier() {
-			return new ApplicationContextAwareFactoryBean<ApplicationContextAwareFactoryBeanTest>() {
+    @Bean
+    FactoryBean<ApplicationContextAwareFactoryBeanTest> resourceCopier() {
+      return new ApplicationContextAwareFactoryBean<ApplicationContextAwareFactoryBeanTest>() {
 
-				@Override
-				public Class<?> getObjectType() {
-					return ApplicationContextAwareFactoryBeanTest.class;
-				}
+        @Override
+        public Class<?> getObjectType() {
+          return ApplicationContextAwareFactoryBeanTest.class;
+        }
 
-				@Override
-				protected ApplicationContextAwareFactoryBeanTest createInstance() {
-					return new ApplicationContextAwareFactoryBeanTest();
-				}
-			};
-		}
-	}
+        @Override
+        protected ApplicationContextAwareFactoryBeanTest createInstance() {
+          return new ApplicationContextAwareFactoryBeanTest();
+        }
+      };
+    }
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/util/ItemInfoUtilsTest.java b/src/test/java/com/epam/ta/reportportal/util/ItemInfoUtilsTest.java
index a62386a949..7efc44eb87 100644
--- a/src/test/java/com/epam/ta/reportportal/util/ItemInfoUtilsTest.java
+++ b/src/test/java/com/epam/ta/reportportal/util/ItemInfoUtilsTest.java
@@ -16,92 +16,99 @@
 
 package com.epam.ta.reportportal.util;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 import com.epam.ta.reportportal.entity.ItemAttribute;
 import com.epam.ta.reportportal.ws.model.attribute.ItemAttributeResource;
 import com.google.common.collect.Lists;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
 import org.junit.jupiter.api.Test;
 
-import java.util.*;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 class ItemInfoUtilsTest {
 
-	@Test
-	void nullAttributesCollectionTest() {
-		Optional<ItemAttribute> attribute = ItemInfoUtils.extractAttribute(null, "key");
-		assertTrue(attribute.isEmpty());
-	}
-
-	@Test
-	void emptyAttributesCollectionTest() {
-		Optional<ItemAttribute> attribute = ItemInfoUtils.extractAttribute(Collections.emptyList(), "key");
-		assertTrue(attribute.isEmpty());
-	}
-
-	@Test
-	void shouldFindNonSystemAttribute() {
-		String key = "key1";
-		Optional<ItemAttribute> attribute = ItemInfoUtils.extractAttribute(getAttributes(), key);
-		assertTrue(attribute.isPresent());
-		assertEquals(key, attribute.get().getKey());
-	}
-
-	@Test
-	void shouldFindSystemAttribute() {
-		String key = "key3";
-		Optional<ItemAttribute> attribute = ItemInfoUtils.extractAttribute(getAttributes(), key);
-		assertTrue(attribute.isPresent());
-		assertEquals(key, attribute.get().getKey());
-	}
-
-	@Test
-	void shouldNotFindAttribute() {
-		String key = "not-exist";
-		Optional<ItemAttribute> attribute = ItemInfoUtils.extractAttribute(getAttributes(), key);
-		assertTrue(attribute.isEmpty());
-	}
-
-	@Test
-	void nullAttributeResourceCollectionTest() {
-		Optional<ItemAttributeResource> itemAttributeResource = ItemInfoUtils.extractAttributeResource(null, "key");
-		assertTrue(itemAttributeResource.isEmpty());
-	}
-
-	@Test
-	void emptyAttributeResourcesCollectionTest() {
-		Optional<ItemAttributeResource> itemAttributeResource = ItemInfoUtils.extractAttributeResource(Collections.emptyList(), "key");
-		assertTrue(itemAttributeResource.isEmpty());
-	}
-
-	@Test
-	void shouldFindAttributeResource() {
-		String key = "key1";
-		Optional<ItemAttributeResource> itemAttributeResource = ItemInfoUtils.extractAttributeResource(getAttributeResources(), key);
-		assertTrue(itemAttributeResource.isPresent());
-		assertEquals(key, itemAttributeResource.get().getKey());
-	}
-
-	@Test
-	void shouldNotFindAttributeResource() {
-		String key = "not-exist";
-		Optional<ItemAttributeResource> itemAttributeResource = ItemInfoUtils.extractAttributeResource(getAttributeResources(), key);
-		assertTrue(itemAttributeResource.isEmpty());
-	}
-
-	private List<ItemAttribute> getAttributes() {
-		return Lists.newArrayList(
-				new ItemAttribute("key1", "value1", false),
-				new ItemAttribute("key2", "value2", false),
-				new ItemAttribute("key3", "value3", true)
-		);
-	}
-
-	private List<ItemAttributeResource> getAttributeResources() {
-		return Lists.newArrayList(new ItemAttributeResource("key1", "value1"), new ItemAttributeResource("key2", "value2"));
-	}
+  @Test
+  void nullAttributesCollectionTest() {
+    Optional<ItemAttribute> attribute = ItemInfoUtils.extractAttribute(null, "key");
+    assertTrue(attribute.isEmpty());
+  }
+
+  @Test
+  void emptyAttributesCollectionTest() {
+    Optional<ItemAttribute> attribute = ItemInfoUtils.extractAttribute(Collections.emptyList(),
+        "key");
+    assertTrue(attribute.isEmpty());
+  }
+
+  @Test
+  void shouldFindNonSystemAttribute() {
+    String key = "key1";
+    Optional<ItemAttribute> attribute = ItemInfoUtils.extractAttribute(getAttributes(), key);
+    assertTrue(attribute.isPresent());
+    assertEquals(key, attribute.get().getKey());
+  }
+
+  @Test
+  void shouldFindSystemAttribute() {
+    String key = "key3";
+    Optional<ItemAttribute> attribute = ItemInfoUtils.extractAttribute(getAttributes(), key);
+    assertTrue(attribute.isPresent());
+    assertEquals(key, attribute.get().getKey());
+  }
+
+  @Test
+  void shouldNotFindAttribute() {
+    String key = "not-exist";
+    Optional<ItemAttribute> attribute = ItemInfoUtils.extractAttribute(getAttributes(), key);
+    assertTrue(attribute.isEmpty());
+  }
+
+  @Test
+  void nullAttributeResourceCollectionTest() {
+    Optional<ItemAttributeResource> itemAttributeResource = ItemInfoUtils.extractAttributeResource(
+        null, "key");
+    assertTrue(itemAttributeResource.isEmpty());
+  }
+
+  @Test
+  void emptyAttributeResourcesCollectionTest() {
+    Optional<ItemAttributeResource> itemAttributeResource = ItemInfoUtils.extractAttributeResource(
+        Collections.emptyList(), "key");
+    assertTrue(itemAttributeResource.isEmpty());
+  }
+
+  @Test
+  void shouldFindAttributeResource() {
+    String key = "key1";
+    Optional<ItemAttributeResource> itemAttributeResource = ItemInfoUtils.extractAttributeResource(
+        getAttributeResources(), key);
+    assertTrue(itemAttributeResource.isPresent());
+    assertEquals(key, itemAttributeResource.get().getKey());
+  }
+
+  @Test
+  void shouldNotFindAttributeResource() {
+    String key = "not-exist";
+    Optional<ItemAttributeResource> itemAttributeResource = ItemInfoUtils.extractAttributeResource(
+        getAttributeResources(), key);
+    assertTrue(itemAttributeResource.isEmpty());
+  }
+
+  private List<ItemAttribute> getAttributes() {
+    return Lists.newArrayList(
+        new ItemAttribute("key1", "value1", false),
+        new ItemAttribute("key2", "value2", false),
+        new ItemAttribute("key3", "value3", true)
+    );
+  }
+
+  private List<ItemAttributeResource> getAttributeResources() {
+    return Lists.newArrayList(new ItemAttributeResource("key1", "value1"),
+        new ItemAttributeResource("key2", "value2"));
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/util/MultipartFileUtilsTest.java b/src/test/java/com/epam/ta/reportportal/util/MultipartFileUtilsTest.java
index 6f50ffa706..db5bf17ea9 100644
--- a/src/test/java/com/epam/ta/reportportal/util/MultipartFileUtilsTest.java
+++ b/src/test/java/com/epam/ta/reportportal/util/MultipartFileUtilsTest.java
@@ -16,33 +16,32 @@
 
 package com.epam.ta.reportportal.util;
 
-import org.apache.commons.io.IOUtils;
-import org.junit.jupiter.api.Test;
-import org.springframework.core.io.ClassPathResource;
-import org.springframework.web.multipart.commons.CommonsMultipartFile;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import org.apache.commons.io.IOUtils;
+import org.junit.jupiter.api.Test;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.web.multipart.commons.CommonsMultipartFile;
 
 /**
  * @author <a href="mailto:pavel_bortnik@epam.com">Pavel Bortnik</a>
  */
 class MultipartFileUtilsTest {
 
-	@Test
-	void getMultipartFile() throws IOException {
-		String path = "image/image.png";
-		File expected = new ClassPathResource(path).getFile();
-		CommonsMultipartFile file = MultipartFileUtils.getMultipartFile(path);
-		assertEquals(expected.length(), file.getSize());
-		assertEquals(expected.getName(), file.getFileItem().getName());
-		assertEquals("image/png", file.getContentType());
-		try (FileInputStream expectedStream = new FileInputStream(expected)) {
-			assertTrue(IOUtils.contentEquals(expectedStream, file.getInputStream()));
-		}
-	}
+  @Test
+  void getMultipartFile() throws IOException {
+    String path = "image/image.png";
+    File expected = new ClassPathResource(path).getFile();
+    CommonsMultipartFile file = MultipartFileUtils.getMultipartFile(path);
+    assertEquals(expected.length(), file.getSize());
+    assertEquals(expected.getName(), file.getFileItem().getName());
+    assertEquals("image/png", file.getContentType());
+    try (FileInputStream expectedStream = new FileInputStream(expected)) {
+      assertTrue(IOUtils.contentEquals(expectedStream, file.getInputStream()));
+    }
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/util/PredicatesTest.java b/src/test/java/com/epam/ta/reportportal/util/PredicatesTest.java
index 2891fe76c3..fd4108d73f 100644
--- a/src/test/java/com/epam/ta/reportportal/util/PredicatesTest.java
+++ b/src/test/java/com/epam/ta/reportportal/util/PredicatesTest.java
@@ -16,6 +16,11 @@
 
 package com.epam.ta.reportportal.util;
 
+import static com.epam.ta.reportportal.util.Predicates.ITEM_CAN_BE_INDEXED;
+import static com.epam.ta.reportportal.util.Predicates.LAUNCH_CAN_BE_INDEXED;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 import com.epam.ta.reportportal.entity.enums.LaunchModeEnum;
 import com.epam.ta.reportportal.entity.enums.TestItemIssueGroup;
 import com.epam.ta.reportportal.entity.enums.TestItemTypeEnum;
@@ -29,80 +34,80 @@
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.ValueSource;
 
-import static com.epam.ta.reportportal.util.Predicates.ITEM_CAN_BE_INDEXED;
-import static com.epam.ta.reportportal.util.Predicates.LAUNCH_CAN_BE_INDEXED;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
 /**
  * @author Andrei Varabyeu
  */
 class PredicatesTest {
 
-	@Test
-	void checkSpecialCharacters() {
-		assertTrue(Predicates.SPECIAL_CHARS_ONLY.test("_"), "Incorrect predicate behavior: only spec chars");
-		assertFalse(Predicates.SPECIAL_CHARS_ONLY.test("a_"), "Incorrect predicate behavior: spec chars after ASCII");
-		assertFalse(Predicates.SPECIAL_CHARS_ONLY.test("_a"), "Incorrect predicate behavior: spec chars before ASCII");
-	}
+  @Test
+  void checkSpecialCharacters() {
+    assertTrue(Predicates.SPECIAL_CHARS_ONLY.test("_"),
+        "Incorrect predicate behavior: only spec chars");
+    assertFalse(Predicates.SPECIAL_CHARS_ONLY.test("a_"),
+        "Incorrect predicate behavior: spec chars after ASCII");
+    assertFalse(Predicates.SPECIAL_CHARS_ONLY.test("_a"),
+        "Incorrect predicate behavior: spec chars before ASCII");
+  }
 
-	@ParameterizedTest
-	@ValueSource(strings = { "STEP", "BEFORE_METHOD", "AFTER_METHOD" })
-	void checkCanBeIndexed(String type) {
-		TestItem testItem = new TestItem();
-		testItem.setType(TestItemTypeEnum.fromValue(type).get());
-		final TestItemResults itemResults = new TestItemResults();
-		final IssueEntity issueEntity = new IssueEntity();
-		issueEntity.setIgnoreAnalyzer(false);
-		final IssueType issueType = new IssueType();
-		issueType.setIssueGroup(new IssueGroup(TestItemIssueGroup.PRODUCT_BUG));
-		issueEntity.setIssueType(issueType);
-		itemResults.setIssue(issueEntity);
-		testItem.setItemResults(itemResults);
-		assertTrue(ITEM_CAN_BE_INDEXED.test(testItem), "Item should be available for indexing");
-	}
+  @ParameterizedTest
+  @ValueSource(strings = {"STEP", "BEFORE_METHOD", "AFTER_METHOD"})
+  void checkCanBeIndexed(String type) {
+    TestItem testItem = new TestItem();
+    testItem.setType(TestItemTypeEnum.fromValue(type).get());
+    final TestItemResults itemResults = new TestItemResults();
+    final IssueEntity issueEntity = new IssueEntity();
+    issueEntity.setIgnoreAnalyzer(false);
+    final IssueType issueType = new IssueType();
+    issueType.setIssueGroup(new IssueGroup(TestItemIssueGroup.PRODUCT_BUG));
+    issueEntity.setIssueType(issueType);
+    itemResults.setIssue(issueEntity);
+    testItem.setItemResults(itemResults);
+    assertTrue(ITEM_CAN_BE_INDEXED.test(testItem), "Item should be available for indexing");
+  }
 
-	@Test
-	void checkTIIndexed() {
-		TestItem testItem = new TestItem();
-		final TestItemResults itemResults = new TestItemResults();
-		testItem.setType(TestItemTypeEnum.STEP);
-		final IssueEntity issue = new IssueEntity();
-		final IssueType issueType = new IssueType();
-		issueType.setIssueGroup(new IssueGroup(TestItemIssueGroup.TO_INVESTIGATE));
-		issueType.setLocator(TestItemIssueGroup.TO_INVESTIGATE.getLocator());
-		issue.setIssueType(issueType);
-		itemResults.setIssue(issue);
-		testItem.setItemResults(itemResults);
-		assertTrue(ITEM_CAN_BE_INDEXED.test(testItem), "Item with TI issue is available for indexing");
-	}
+  @Test
+  void checkTIIndexed() {
+    TestItem testItem = new TestItem();
+    final TestItemResults itemResults = new TestItemResults();
+    testItem.setType(TestItemTypeEnum.STEP);
+    final IssueEntity issue = new IssueEntity();
+    final IssueType issueType = new IssueType();
+    issueType.setIssueGroup(new IssueGroup(TestItemIssueGroup.TO_INVESTIGATE));
+    issueType.setLocator(TestItemIssueGroup.TO_INVESTIGATE.getLocator());
+    issue.setIssueType(issueType);
+    itemResults.setIssue(issue);
+    testItem.setItemResults(itemResults);
+    assertTrue(ITEM_CAN_BE_INDEXED.test(testItem), "Item with TI issue is available for indexing");
+  }
 
-	@Test
-	void checkIgnoreIndexed() {
-		TestItem testItem = new TestItem();
-		testItem.setType(TestItemTypeEnum.STEP);
-		final TestItemResults itemResults = new TestItemResults();
-		final IssueEntity issueEntity = new IssueEntity();
-		issueEntity.setIgnoreAnalyzer(true);
-		final IssueType issueType = new IssueType();
-		issueType.setIssueGroup(new IssueGroup(TestItemIssueGroup.PRODUCT_BUG));
-		issueEntity.setIssueType(issueType);
-		itemResults.setIssue(issueEntity);
-		testItem.setItemResults(itemResults);
-		assertFalse(ITEM_CAN_BE_INDEXED.test(testItem), "Item with ignore flag shouldn't be available for indexing");
-	}
+  @Test
+  void checkIgnoreIndexed() {
+    TestItem testItem = new TestItem();
+    testItem.setType(TestItemTypeEnum.STEP);
+    final TestItemResults itemResults = new TestItemResults();
+    final IssueEntity issueEntity = new IssueEntity();
+    issueEntity.setIgnoreAnalyzer(true);
+    final IssueType issueType = new IssueType();
+    issueType.setIssueGroup(new IssueGroup(TestItemIssueGroup.PRODUCT_BUG));
+    issueEntity.setIssueType(issueType);
+    itemResults.setIssue(issueEntity);
+    testItem.setItemResults(itemResults);
+    assertFalse(ITEM_CAN_BE_INDEXED.test(testItem),
+        "Item with ignore flag shouldn't be available for indexing");
+  }
 
-	@Test
-	void checkLaunchCanBeIndexed() {
-		Launch launch = new Launch();
-		launch.setMode(LaunchModeEnum.DEFAULT);
-		assertTrue(LAUNCH_CAN_BE_INDEXED.test(launch), "Launch should be available for indexing");
-	}
+  @Test
+  void checkLaunchCanBeIndexed() {
+    Launch launch = new Launch();
+    launch.setMode(LaunchModeEnum.DEFAULT);
+    assertTrue(LAUNCH_CAN_BE_INDEXED.test(launch), "Launch should be available for indexing");
+  }
 
-	@Test
-	void checkDebugLaunchCanBeIndexed() {
-		Launch launch = new Launch();
-		launch.setMode(LaunchModeEnum.DEFAULT);
-		assertTrue(LAUNCH_CAN_BE_INDEXED.test(launch), "Launch in debug mode should not be available for indexing");
-	}
+  @Test
+  void checkDebugLaunchCanBeIndexed() {
+    Launch launch = new Launch();
+    launch.setMode(LaunchModeEnum.DEFAULT);
+    assertTrue(LAUNCH_CAN_BE_INDEXED.test(launch),
+        "Launch in debug mode should not be available for indexing");
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/util/ReportingQueueServiceTest.java b/src/test/java/com/epam/ta/reportportal/util/ReportingQueueServiceTest.java
index 2040b2f41f..2f914865da 100755
--- a/src/test/java/com/epam/ta/reportportal/util/ReportingQueueServiceTest.java
+++ b/src/test/java/com/epam/ta/reportportal/util/ReportingQueueServiceTest.java
@@ -16,38 +16,37 @@
 
 package com.epam.ta.reportportal.util;
 
-import org.junit.jupiter.api.Test;
-
-import java.util.UUID;
-
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
-class ReportingQueueServiceTest {
-
-	private ReportingQueueService reportingQueueService = new ReportingQueueService();
+import java.util.UUID;
+import org.junit.jupiter.api.Test;
 
-	@Test
-	void getKeyFromUuid() {
-		String uuid = UUID.randomUUID().toString();
-		int queueAmount = 5;
-		reportingQueueService.setQueueAmount(queueAmount);
-		String reportingQueueKey = reportingQueueService.getReportingQueueKey(uuid);
-		System.out.println(reportingQueueKey);
-		assertNotNull(reportingQueueKey);
-		int integerKey = Integer.parseInt(reportingQueueKey);
-		assertTrue(integerKey <= queueAmount);
-	}
+class ReportingQueueServiceTest {
 
-	@Test
-	void getKeyFromCustomString() {
-		String customUuid = "cutom-uuid-kek";
-		int queueAmount = 5;
-		reportingQueueService.setQueueAmount(queueAmount);
-		String reportingQueueKey = reportingQueueService.getReportingQueueKey(customUuid);
-		System.out.println(reportingQueueKey);
-		assertNotNull(reportingQueueKey);
-		int integerKey = Integer.parseInt(reportingQueueKey);
-		assertTrue(integerKey <= queueAmount);
-	}
+  private ReportingQueueService reportingQueueService = new ReportingQueueService();
+
+  @Test
+  void getKeyFromUuid() {
+    String uuid = UUID.randomUUID().toString();
+    int queueAmount = 5;
+    reportingQueueService.setQueueAmount(queueAmount);
+    String reportingQueueKey = reportingQueueService.getReportingQueueKey(uuid);
+    System.out.println(reportingQueueKey);
+    assertNotNull(reportingQueueKey);
+    int integerKey = Integer.parseInt(reportingQueueKey);
+    assertTrue(integerKey <= queueAmount);
+  }
+
+  @Test
+  void getKeyFromCustomString() {
+    String customUuid = "cutom-uuid-kek";
+    int queueAmount = 5;
+    reportingQueueService.setQueueAmount(queueAmount);
+    String reportingQueueKey = reportingQueueService.getReportingQueueKey(customUuid);
+    System.out.println(reportingQueueKey);
+    assertNotNull(reportingQueueKey);
+    int integerKey = Integer.parseInt(reportingQueueKey);
+    assertTrue(integerKey <= queueAmount);
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/util/TestProjectExtractor.java b/src/test/java/com/epam/ta/reportportal/util/TestProjectExtractor.java
index ffec9e5bb0..25e803fdd6 100644
--- a/src/test/java/com/epam/ta/reportportal/util/TestProjectExtractor.java
+++ b/src/test/java/com/epam/ta/reportportal/util/TestProjectExtractor.java
@@ -1,21 +1,21 @@
 package com.epam.ta.reportportal.util;
 
+import static com.epam.ta.reportportal.commons.EntityUtils.normalizeId;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.model.ErrorType;
-
 import java.util.Optional;
 
-import static com.epam.ta.reportportal.commons.EntityUtils.normalizeId;
-
 public class TestProjectExtractor {
 
-	public static ReportPortalUser.ProjectDetails extractProjectDetails(ReportPortalUser user, String projectName) {
-		final String normalizedProjectName = normalizeId(projectName);
-			return Optional.ofNullable(user.getProjectDetails().get(normalizedProjectName))
-					.orElseThrow(() -> new ReportPortalException(ErrorType.ACCESS_DENIED,
-							"Please check the list of your available projects."
-					));
-	}
+  public static ReportPortalUser.ProjectDetails extractProjectDetails(ReportPortalUser user,
+      String projectName) {
+    final String normalizedProjectName = normalizeId(projectName);
+    return Optional.ofNullable(user.getProjectDetails().get(normalizedProjectName))
+        .orElseThrow(() -> new ReportPortalException(ErrorType.ACCESS_DENIED,
+            "Please check the list of your available projects."
+        ));
+  }
 
 }
diff --git a/src/test/java/com/epam/ta/reportportal/util/email/EmailRulesValidatorTest.java b/src/test/java/com/epam/ta/reportportal/util/email/EmailRulesValidatorTest.java
index 33d7923268..1624df0b57 100644
--- a/src/test/java/com/epam/ta/reportportal/util/email/EmailRulesValidatorTest.java
+++ b/src/test/java/com/epam/ta/reportportal/util/email/EmailRulesValidatorTest.java
@@ -16,6 +16,9 @@
 
 package com.epam.ta.reportportal.util.email;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
 import com.epam.ta.reportportal.entity.project.Project;
 import com.epam.ta.reportportal.entity.user.ProjectUser;
 import com.epam.ta.reportportal.entity.user.User;
@@ -25,156 +28,162 @@
 import org.apache.commons.lang3.RandomStringUtils;
 import org.junit.jupiter.api.Test;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 class EmailRulesValidatorTest {
 
-	@Test
-	void validateBlankLaunchName() {
-		ReportPortalException exception = assertThrows(ReportPortalException.class, () -> EmailRulesValidator.validateLaunchName(""));
-		assertEquals(
-				"Error in handled Request. Please, check specified parameters: 'Launch name values cannot be empty. Please specify it or not include in request.'",
-				exception.getMessage()
-		);
-	}
-
-	@Test
-	void validateNullLaunchName() {
-		ReportPortalException exception = assertThrows(ReportPortalException.class, () -> EmailRulesValidator.validateLaunchName(null));
-		assertEquals(
-				"Error in handled Request. Please, check specified parameters: 'Launch name values cannot be empty. Please specify it or not include in request.'",
-				exception.getMessage()
-		);
-	}
-
-	@Test
-	void validateLaunchNameLength() {
-		String largeString = RandomStringUtils.randomAlphabetic(257);
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> EmailRulesValidator.validateLaunchName(largeString)
-		);
-		assertEquals("Error in handled Request. Please, check specified parameters: 'One of provided launch names '" + largeString + "' is too long. Acceptable name length is [1..256]'",
-				exception.getMessage()
-		);
-	}
-
-	@Test
-	void successfullyValidateLaunchName() {
-		EmailRulesValidator.validateLaunchName("launch_name");
-	}
-
-	@Test
-	void validateEmptyLaunchAttributes() {
-		ItemAttributeResource attribute = new ItemAttributeResource();
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> EmailRulesValidator.validateLaunchAttribute(attribute)
-		);
-		assertEquals(
-				"Error in handled Request. Please, check specified parameters: 'Attribute' values cannot be empty. Please specify them or do not include in a request.'",
-				exception.getMessage()
-		);
-	}
-
-	@Test
-	void validateNullLaunchAttribute() {
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> EmailRulesValidator.validateLaunchAttribute(null)
-		);
-		assertEquals("Error in handled Request. Please, check specified parameters: 'Launch attribute cannot be null.'",
-				exception.getMessage()
-		);
-	}
-
-	@Test
-	void successfullyValidateLaunchAttribute() {
-		ItemAttributeResource attribute = new ItemAttributeResource();
-		attribute.setKey("key");
-		attribute.setValue("value");
-		EmailRulesValidator.validateLaunchAttribute(attribute);
-	}
-
-	@Test
-	void validateNullRecipientName() {
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> EmailRulesValidator.validateRecipient(new Project(), null)
-		);
-		assertEquals("Error in handled Request. Please, check specified parameters: 'Provided recipient email 'null' is invalid'",
-				exception.getMessage()
-		);
-	}
-
-	@Test
-	void validateInvalidRecipientEmail() {
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> EmailRulesValidator.validateRecipient(new Project(), "invalid@domain")
-		);
-		assertEquals(
-				"Error in handled Request. Please, check specified parameters: 'Provided recipient email 'invalid@domain' is invalid'",
-				exception.getMessage()
-		);
-	}
-
-	@Test
-	void successfullyValidateRecipientEmail() {
-		EmailRulesValidator.validateRecipient(new Project(), "valid.email@domain.com");
-	}
-
-	@Test
-	void successfullyValidateOwnerRecipient() {
-		EmailRulesValidator.validateRecipient(new Project(), "OWNER");
-	}
-
-	@Test
-	void validateShortLoginRecipient() {
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> EmailRulesValidator.validateRecipient(new Project(), "")
-		);
-		assertEquals("Error in handled Request. Please, check specified parameters: 'Acceptable login length  [1..128]'",
-				exception.getMessage()
-		);
-	}
-
-	@Test
-	void validateLongLoginRecipient() {
-		String largeLogin = RandomStringUtils.randomAlphabetic(129);
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> EmailRulesValidator.validateRecipient(new Project(), largeLogin)
-		);
-		assertEquals("Error in handled Request. Please, check specified parameters: 'Acceptable login length  [1..128]'",
-				exception.getMessage()
-		);
-	}
-
-	@Test
-	void validateNotAssignedUserLoginRecipient() {
-		Project project = new Project();
-		project.setId(1L);
-		ProjectUser projectUser = new ProjectUser();
-		projectUser.setProject(project);
-		User user = new User();
-		user.setLogin("exists");
-		projectUser.setUser(user);
-		project.setUsers(Sets.newHashSet(projectUser));
-		ReportPortalException exception = assertThrows(ReportPortalException.class,
-				() -> EmailRulesValidator.validateRecipient(project, "not_exists")
-		);
-		assertEquals("User 'not_exists' not found. User not found in project 1", exception.getMessage());
-	}
-
-	@Test
-	void successfullyValidateLoginRecipient() {
-		Project project = new Project();
-		project.setId(1L);
-		ProjectUser projectUser = new ProjectUser();
-		projectUser.setProject(project);
-		User user = new User();
-		user.setLogin("exists");
-		projectUser.setUser(user);
-		project.setUsers(Sets.newHashSet(projectUser));
-		EmailRulesValidator.validateRecipient(project, "exists");
-	}
+  @Test
+  void validateBlankLaunchName() {
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> EmailRulesValidator.validateLaunchName(""));
+    assertEquals(
+        "Error in handled Request. Please, check specified parameters: 'Launch name values cannot be empty. Please specify it or not include in request.'",
+        exception.getMessage()
+    );
+  }
+
+  @Test
+  void validateNullLaunchName() {
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> EmailRulesValidator.validateLaunchName(null));
+    assertEquals(
+        "Error in handled Request. Please, check specified parameters: 'Launch name values cannot be empty. Please specify it or not include in request.'",
+        exception.getMessage()
+    );
+  }
+
+  @Test
+  void validateLaunchNameLength() {
+    String largeString = RandomStringUtils.randomAlphabetic(257);
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> EmailRulesValidator.validateLaunchName(largeString)
+    );
+    assertEquals(
+        "Error in handled Request. Please, check specified parameters: 'One of provided launch names '"
+            + largeString + "' is too long. Acceptable name length is [1..256]'",
+        exception.getMessage()
+    );
+  }
+
+  @Test
+  void successfullyValidateLaunchName() {
+    EmailRulesValidator.validateLaunchName("launch_name");
+  }
+
+  @Test
+  void validateEmptyLaunchAttributes() {
+    ItemAttributeResource attribute = new ItemAttributeResource();
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> EmailRulesValidator.validateLaunchAttribute(attribute)
+    );
+    assertEquals(
+        "Error in handled Request. Please, check specified parameters: 'Attribute' values cannot be empty. Please specify them or do not include in a request.'",
+        exception.getMessage()
+    );
+  }
+
+  @Test
+  void validateNullLaunchAttribute() {
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> EmailRulesValidator.validateLaunchAttribute(null)
+    );
+    assertEquals(
+        "Error in handled Request. Please, check specified parameters: 'Launch attribute cannot be null.'",
+        exception.getMessage()
+    );
+  }
+
+  @Test
+  void successfullyValidateLaunchAttribute() {
+    ItemAttributeResource attribute = new ItemAttributeResource();
+    attribute.setKey("key");
+    attribute.setValue("value");
+    EmailRulesValidator.validateLaunchAttribute(attribute);
+  }
+
+  @Test
+  void validateNullRecipientName() {
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> EmailRulesValidator.validateRecipient(new Project(), null)
+    );
+    assertEquals(
+        "Error in handled Request. Please, check specified parameters: 'Provided recipient email 'null' is invalid'",
+        exception.getMessage()
+    );
+  }
+
+  @Test
+  void validateInvalidRecipientEmail() {
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> EmailRulesValidator.validateRecipient(new Project(), "invalid@domain")
+    );
+    assertEquals(
+        "Error in handled Request. Please, check specified parameters: 'Provided recipient email 'invalid@domain' is invalid'",
+        exception.getMessage()
+    );
+  }
+
+  @Test
+  void successfullyValidateRecipientEmail() {
+    EmailRulesValidator.validateRecipient(new Project(), "valid.email@domain.com");
+  }
+
+  @Test
+  void successfullyValidateOwnerRecipient() {
+    EmailRulesValidator.validateRecipient(new Project(), "OWNER");
+  }
+
+  @Test
+  void validateShortLoginRecipient() {
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> EmailRulesValidator.validateRecipient(new Project(), "")
+    );
+    assertEquals(
+        "Error in handled Request. Please, check specified parameters: 'Acceptable login length  [1..128]'",
+        exception.getMessage()
+    );
+  }
+
+  @Test
+  void validateLongLoginRecipient() {
+    String largeLogin = RandomStringUtils.randomAlphabetic(129);
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> EmailRulesValidator.validateRecipient(new Project(), largeLogin)
+    );
+    assertEquals(
+        "Error in handled Request. Please, check specified parameters: 'Acceptable login length  [1..128]'",
+        exception.getMessage()
+    );
+  }
+
+  @Test
+  void validateNotAssignedUserLoginRecipient() {
+    Project project = new Project();
+    project.setId(1L);
+    ProjectUser projectUser = new ProjectUser();
+    projectUser.setProject(project);
+    User user = new User();
+    user.setLogin("exists");
+    projectUser.setUser(user);
+    project.setUsers(Sets.newHashSet(projectUser));
+    ReportPortalException exception = assertThrows(ReportPortalException.class,
+        () -> EmailRulesValidator.validateRecipient(project, "not_exists")
+    );
+    assertEquals("User 'not_exists' not found. User not found in project 1",
+        exception.getMessage());
+  }
+
+  @Test
+  void successfullyValidateLoginRecipient() {
+    Project project = new Project();
+    project.setId(1L);
+    ProjectUser projectUser = new ProjectUser();
+    projectUser.setProject(project);
+    User user = new User();
+    user.setLogin("exists");
+    projectUser.setUser(user);
+    project.setUsers(Sets.newHashSet(projectUser));
+    EmailRulesValidator.validateRecipient(project, "exists");
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/util/email/EmailServiceTest.java b/src/test/java/com/epam/ta/reportportal/util/email/EmailServiceTest.java
index f88bd950a8..00ceffb7bb 100644
--- a/src/test/java/com/epam/ta/reportportal/util/email/EmailServiceTest.java
+++ b/src/test/java/com/epam/ta/reportportal/util/email/EmailServiceTest.java
@@ -16,6 +16,10 @@
 
 package com.epam.ta.reportportal.util.email;
 
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import com.epam.reportportal.commons.template.TemplateEngine;
 import com.epam.ta.reportportal.entity.ItemAttribute;
 import com.epam.ta.reportportal.entity.enums.LaunchModeEnum;
@@ -26,64 +30,60 @@
 import com.epam.ta.reportportal.entity.statistics.Statistics;
 import com.epam.ta.reportportal.entity.statistics.StatisticsField;
 import com.google.common.collect.Sets;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
 import java.time.LocalDateTime;
 import java.util.Map;
 import java.util.Properties;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class EmailServiceTest {
 
-	private TemplateEngine templateEngine = mock(TemplateEngine.class);
+  private TemplateEngine templateEngine = mock(TemplateEngine.class);
 
-	private EmailService emailService = new EmailService(new Properties());
+  private EmailService emailService = new EmailService(new Properties());
 
-	@BeforeEach
-	void setUp() {
-		emailService.setTemplateEngine(templateEngine);
-	}
+  @BeforeEach
+  void setUp() {
+    emailService.setTemplateEngine(templateEngine);
+  }
 
-	@Test
-	void prepareLaunchTest() {
+  @Test
+  void prepareLaunchTest() {
 
-		when(templateEngine.merge(any(String.class), any(Map.class))).thenReturn("EMAIL MESSAGE");
+    when(templateEngine.merge(any(String.class), any(Map.class))).thenReturn("EMAIL MESSAGE");
 
-		ProjectIssueType projectIssueType = new ProjectIssueType();
-		IssueType issueType = new IssueType();
-		issueType.setLocator("pb001");
-		issueType.setLongName("ProductBug");
-		projectIssueType.setIssueType(issueType);
+    ProjectIssueType projectIssueType = new ProjectIssueType();
+    IssueType issueType = new IssueType();
+    issueType.setLocator("pb001");
+    issueType.setLongName("ProductBug");
+    projectIssueType.setIssueType(issueType);
 
-		String url = emailService.mergeFinishLaunchText("url", getLaunch(), Sets.newHashSet(projectIssueType));
+    String url = emailService.mergeFinishLaunchText("url", getLaunch(),
+        Sets.newHashSet(projectIssueType));
 
-		System.out.println(url);
-	}
+    System.out.println(url);
+  }
 
-	private Launch getLaunch() {
-		Launch launch = new Launch();
-		launch.setId(1L);
-		launch.setHasRetries(false);
-		launch.setStatus(StatusEnum.PASSED);
-		launch.setProjectId(1L);
-		launch.setStartTime(LocalDateTime.now());
-		launch.setEndTime(LocalDateTime.now().plusMinutes(5L));
-		launch.setName("Launch name");
-		launch.setMode(LaunchModeEnum.DEFAULT);
-		launch.setNumber(1L);
-		launch.setDescription("description");
-		launch.setAttributes(Sets.newHashSet(new ItemAttribute("key", "value", false)));
-		StatisticsField statisticsField = new StatisticsField("statistics$executions$total");
-		Statistics statistics = new Statistics(statisticsField, 1, 1L);
-		launch.setStatistics(Sets.newHashSet(statistics));
-		return launch;
-	}
+  private Launch getLaunch() {
+    Launch launch = new Launch();
+    launch.setId(1L);
+    launch.setHasRetries(false);
+    launch.setStatus(StatusEnum.PASSED);
+    launch.setProjectId(1L);
+    launch.setStartTime(LocalDateTime.now());
+    launch.setEndTime(LocalDateTime.now().plusMinutes(5L));
+    launch.setName("Launch name");
+    launch.setMode(LaunchModeEnum.DEFAULT);
+    launch.setNumber(1L);
+    launch.setDescription("description");
+    launch.setAttributes(Sets.newHashSet(new ItemAttribute("key", "value", false)));
+    StatisticsField statisticsField = new StatisticsField("statistics$executions$total");
+    Statistics statistics = new Statistics(statisticsField, 1, 1L);
+    launch.setStatistics(Sets.newHashSet(statistics));
+    return launch;
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/util/sample/LaunchSampleUtil.java b/src/test/java/com/epam/ta/reportportal/util/sample/LaunchSampleUtil.java
new file mode 100644
index 0000000000..9dc2aa2469
--- /dev/null
+++ b/src/test/java/com/epam/ta/reportportal/util/sample/LaunchSampleUtil.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2023 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.util.sample;
+
+import com.epam.ta.reportportal.entity.launch.Launch;
+import java.util.UUID;
+import java.util.concurrent.ThreadLocalRandom;
+import org.apache.commons.lang3.RandomStringUtils;
+
+/**
+ * Utility class for generating {@link Launch } samples.
+ *
+ * @author Siarhei Hrabko
+ */
+public final class LaunchSampleUtil {
+
+  private LaunchSampleUtil() {
+  }
+
+  /**
+   * Generates sample launch object for testing purposes.
+   *
+   * @param uuid {@link String} uuid of generated launch
+   * @return {@link Launch } generated launch object
+   */
+  public static Launch getSampleLaunch(String uuid) {
+    var launch = new Launch();
+    launch.setUuid(uuid);
+    launch.setName(RandomStringUtils.random(10));
+    launch.setNumber(ThreadLocalRandom.current().nextLong(100));
+    return launch;
+  }
+
+  public static Launch getSampleLaunch() {
+    return getSampleLaunch(UUID.randomUUID().toString());
+  }
+}
diff --git a/src/test/java/com/epam/ta/reportportal/ws/BaseMvcTest.java b/src/test/java/com/epam/ta/reportportal/ws/BaseMvcTest.java
index 12b0fac4cb..6f51bab15d 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/BaseMvcTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/BaseMvcTest.java
@@ -20,7 +20,10 @@
 import com.epam.ta.reportportal.TestConfig;
 import com.epam.ta.reportportal.auth.OAuthHelper;
 import com.epam.ta.reportportal.core.events.MessageBus;
+import com.epam.ta.reportportal.core.integration.ExecuteIntegrationHandler;
+import com.epam.ta.reportportal.core.integration.plugin.binary.PluginFilesProvider;
 import com.epam.ta.reportportal.core.plugin.Pf4jPluginBox;
+import com.epam.ta.reportportal.util.BinaryDataResponseWriter;
 import com.epam.ta.reportportal.util.email.EmailService;
 import com.epam.ta.reportportal.util.email.MailServiceFactory;
 import org.flywaydb.test.FlywayTestExecutionListener;
@@ -48,44 +51,57 @@
 @AutoConfigureMockMvc
 @ActiveProfiles("unittest")
 @ContextConfiguration(classes = TestConfig.class)
-@TestExecutionListeners(listeners = { FlywayTestExecutionListener.class }, mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS)
+@TestExecutionListeners(listeners = {
+    FlywayTestExecutionListener.class}, mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS)
 @Transactional
 public abstract class BaseMvcTest {
 
-	protected static final String DEFAULT_PROJECT_BASE_URL = "/v1/default_personal";
-	protected static final String SUPERADMIN_PROJECT_BASE_URL = "/v1/superadmin_personal";
+  protected static final String DEFAULT_PROJECT_BASE_URL = "/v1/default_personal";
+  protected static final String SUPERADMIN_PROJECT_BASE_URL = "/v1/superadmin_personal";
 
-	@Autowired
-	protected OAuthHelper oAuthHelper;
+  @Autowired
+  protected OAuthHelper oAuthHelper;
 
-	@Autowired
-	protected MockMvc mockMvc;
+  @Autowired
+  protected MockMvc mockMvc;
 
-	@MockBean
-	protected MessageBus messageBus;
+  @MockBean
+  protected MessageBus messageBus;
 
-	@MockBean
-	protected MailServiceFactory mailServiceFactory;
+  @MockBean
+  protected MailServiceFactory mailServiceFactory;
 
-	@MockBean
-	protected Pf4jPluginBox pluginBox;
+  @MockBean
+  protected Pf4jPluginBox pluginBox;
 
-	@Mock
-	protected BtsExtension extension;
+  @MockBean(name = "pluginFilesProvider")
+  protected PluginFilesProvider pluginFilesProvider;
 
-	@Mock
-	protected EmailService emailService;
+  @MockBean(name = "pluginPublicFilesProvider")
+  protected PluginFilesProvider pluginPublicFilesProvider;
 
-	@FlywayTest
-	@BeforeAll
-	public static void before() {
-	}
+  @MockBean
+  protected BinaryDataResponseWriter binaryDataResponseWriter;
 
-	protected RequestPostProcessor token(String tokenValue) {
-		return mockRequest -> {
-			mockRequest.addHeader("Authorization", "Bearer " + tokenValue);
-			return mockRequest;
-		};
-	}
+  @MockBean
+  protected ExecuteIntegrationHandler executeIntegrationHandler;
+
+  @Mock
+  protected BtsExtension extension;
+
+  @Mock
+  protected EmailService emailService;
+
+  @FlywayTest
+  @BeforeAll
+  public static void before() {
+  }
+
+  protected RequestPostProcessor token(String tokenValue) {
+    return mockRequest -> {
+      mockRequest.addHeader("Authorization", "Bearer " + tokenValue);
+      return mockRequest;
+    };
+  }
 
 }
diff --git a/src/test/java/com/epam/ta/reportportal/ws/controller/BugTrackingSystemControllerTest.java b/src/test/java/com/epam/ta/reportportal/ws/controller/BugTrackingSystemControllerTest.java
index d75a2c49d6..b10ae1db6c 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/controller/BugTrackingSystemControllerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/controller/BugTrackingSystemControllerTest.java
@@ -16,15 +16,34 @@
 
 package com.epam.ta.reportportal.ws.controller;
 
+import static com.epam.ta.reportportal.ws.controller.constants.ValidationTestsConstants.INCORRECT_REQUEST_MESSAGE;
+import static com.epam.ta.reportportal.ws.model.ErrorType.INCORRECT_REQUEST;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
 import com.epam.reportportal.extension.bugtracking.BtsExtension;
 import com.epam.ta.reportportal.entity.integration.Integration;
 import com.epam.ta.reportportal.ws.BaseMvcTest;
 import com.epam.ta.reportportal.ws.model.ErrorRS;
-import com.epam.ta.reportportal.ws.model.externalsystem.*;
+import com.epam.ta.reportportal.ws.model.externalsystem.AllowedValue;
+import com.epam.ta.reportportal.ws.model.externalsystem.BtsConnectionTestRQ;
+import com.epam.ta.reportportal.ws.model.externalsystem.PostFormField;
+import com.epam.ta.reportportal.ws.model.externalsystem.PostTicketRQ;
+import com.epam.ta.reportportal.ws.model.externalsystem.Ticket;
 import com.epam.ta.reportportal.ws.model.integration.IntegrationRQ;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.LongStream;
 import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -33,177 +52,179 @@
 import org.springframework.test.web.servlet.MvcResult;
 import org.springframework.util.CollectionUtils;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-import java.util.stream.LongStream;
-
-import static com.epam.ta.reportportal.ws.controller.constants.ValidationTestsConstants.INCORRECT_REQUEST_MESSAGE;
-import static com.epam.ta.reportportal.ws.model.ErrorType.INCORRECT_REQUEST;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.when;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 @Sql("/db/bts/bts-integration-fill.sql")
 class BugTrackingSystemControllerTest extends BaseMvcTest {
 
-	@Autowired
-	private ObjectMapper objectMapper;
-
-	@Test
-	@Disabled
-	void updateGlobalBtsIntegration() throws Exception {
-
-		when(pluginBox.getInstance("jira", BtsExtension.class)).thenReturn(java.util.Optional.ofNullable(extension));
-		when(extension.testConnection(any(Integration.class))).thenReturn(true);
-
-		IntegrationRQ request = getUpdateRQ();
-
-		mockMvc.perform(put("/v1/integration" + "/9").with(token(oAuthHelper.getSuperadminToken()))
-				.contentType(MediaType.APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
-	}
-
-	@Test
-	@Disabled
-	void updateProjectBtsIntegration() throws Exception {
-
-		when(pluginBox.getInstance("jira", BtsExtension.class)).thenReturn(java.util.Optional.ofNullable(extension));
-		when(extension.testConnection(any(Integration.class))).thenReturn(true);
-
-		IntegrationRQ request = getUpdateRQ();
-
-		mockMvc.perform(put("/v1/integration/superadmin_personal/10").with(token(oAuthHelper.getSuperadminToken()))
-				.contentType(MediaType.APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
-	}
-
-	@Test
-	@Disabled
-	void checkConnection() throws Exception {
-
-		when(pluginBox.getInstance("jira", BtsExtension.class)).thenReturn(java.util.Optional.ofNullable(extension));
-		when(extension.testConnection(any(Integration.class))).thenReturn(true);
-
-		mockMvc.perform(get(SUPERADMIN_PROJECT_BASE_URL + "/integration/10/connection/test").with(token(oAuthHelper.getSuperadminToken())));
-	}
-
-	@Test
-	void getSetOfIntegrationSystemFields() throws Exception {
-
-		Map<String, List<String>> params = Maps.newHashMap();
-		params.put("issueType", Lists.newArrayList("ISSUE01"));
-
-		when(pluginBox.getInstance("jira", BtsExtension.class)).thenReturn(java.util.Optional.ofNullable(extension));
-		when(extension.getTicketFields(any(String.class), any(Integration.class))).thenReturn(Lists.newArrayList(new PostFormField()));
-
-		mockMvc.perform(get("/v1/bts/superadmin_personal/10/fields-set").params(CollectionUtils.toMultiValueMap(params))
-				.with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isOk());
-	}
-
-	@Test
-	void getAllowableIssueTypes() throws Exception {
-
-		when(pluginBox.getInstance("jira", BtsExtension.class)).thenReturn(java.util.Optional.ofNullable(extension));
-		when(extension.getIssueTypes(any(Integration.class))).thenReturn(Lists.newArrayList("type1", "type2"));
-
-		mockMvc.perform(get("/v1/bts/superadmin_personal/10/issue_types").with(token(oAuthHelper.getSuperadminToken())))
-				.andExpect(status().isOk());
-	}
-
-	@Test
-	void createIssue() throws Exception {
-
-		PostTicketRQ request = getPostTicketRQ();
-
-		when(pluginBox.getInstance("jira", BtsExtension.class)).thenReturn(java.util.Optional.ofNullable(extension));
-		when(extension.submitTicket(any(PostTicketRQ.class), any(Integration.class))).thenReturn(new Ticket());
-
-		mockMvc.perform(post("/v1/bts/superadmin_personal/10/ticket").with(token(oAuthHelper.getSuperadminToken()))
-				.contentType(MediaType.APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().isCreated());
-	}
-
-	@Test
-	void shouldNotCreateIssueWhenMoreThen300BackLinks() throws Exception {
-
-		final PostTicketRQ request = new PostTicketRQ();
-		final Map<Long, String> backLinks = LongStream.range(1, 302).boxed().collect(Collectors.toMap(it -> it, String::valueOf));
-		request.setBackLinks(backLinks);
-
-		final MvcResult mvcResult = mockMvc.perform(post("/v1/bts/superadmin_personal/10/ticket").with(token(oAuthHelper.getSuperadminToken()))
-				.contentType(MediaType.APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().isBadRequest()).andReturn();
-
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[Field 'backLinks' should have size from '0' to '300'.] ",
-				error.getMessage()
-		);
-	}
-
-	@Test
-	void getTicket() throws Exception {
-
-		final String ticketId = "/ticket_id";
-
-		Map<String, List<String>> params = Maps.newHashMap();
-		params.put("btsUrl", Lists.newArrayList("jira.com"));
-		params.put("btsProject", Lists.newArrayList("project"));
-
-		when(pluginBox.getInstance("jira", BtsExtension.class)).thenReturn(java.util.Optional.ofNullable(extension));
-		when(extension.getTicket(any(String.class), any(Integration.class))).thenReturn(java.util.Optional.of(new Ticket()));
-
-		mockMvc.perform(get("/v1/bts/superadmin_personal/ticket" + ticketId).params(CollectionUtils.toMultiValueMap(params))
-				.with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isOk());
-	}
-
-	private IntegrationRQ getUpdateRQ() {
+  @Autowired
+  private ObjectMapper objectMapper;
 
-		IntegrationRQ integrationRQ = new IntegrationRQ();
-		integrationRQ.setEnabled(true);
-		integrationRQ.setName("jira1");
-		Map<String, Object> integrationParams = new HashMap<>();
-		integrationParams.put("defectFormFields", getPostFormFields());
-		integrationRQ.setIntegrationParams(integrationParams);
-		return integrationRQ;
-	}
+  @Test
+  @Disabled
+  void updateGlobalBtsIntegration() throws Exception {
 
-	private BtsConnectionTestRQ getConnectionRQ() {
-		BtsConnectionTestRQ connectionTestRQ = new BtsConnectionTestRQ();
-		connectionTestRQ.setUrl("url");
-		connectionTestRQ.setBtsProject("project");
+    when(pluginBox.getInstance("jira", BtsExtension.class)).thenReturn(
+        java.util.Optional.ofNullable(extension));
+    when(extension.testConnection(any(Integration.class))).thenReturn(true);
+
+    IntegrationRQ request = getUpdateRQ();
+
+    mockMvc.perform(put("/v1/integration" + "/9").with(token(oAuthHelper.getSuperadminToken()))
+        .contentType(MediaType.APPLICATION_JSON)
+        .content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
+  }
 
-		return connectionTestRQ;
-	}
+  @Test
+  @Disabled
+  void updateProjectBtsIntegration() throws Exception {
 
-	private PostTicketRQ getPostTicketRQ() {
-		PostTicketRQ postTicketRQ = new PostTicketRQ();
-		postTicketRQ.setFields(getPostFormFields());
-		postTicketRQ.setNumberOfLogs(10);
-		postTicketRQ.setIsIncludeScreenshots(false);
-		postTicketRQ.setIsIncludeComments(false);
-		postTicketRQ.setTestItemId(1L);
+    when(pluginBox.getInstance("jira", BtsExtension.class)).thenReturn(
+        java.util.Optional.ofNullable(extension));
+    when(extension.testConnection(any(Integration.class))).thenReturn(true);
 
-		return postTicketRQ;
-	}
+    IntegrationRQ request = getUpdateRQ();
 
-	private List<PostFormField> getPostFormFields() {
+    mockMvc.perform(
+        put("/v1/integration/superadmin_personal/10").with(token(oAuthHelper.getSuperadminToken()))
+            .contentType(MediaType.APPLICATION_JSON)
+            .content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
+  }
 
-		PostFormField field = new PostFormField("id",
-				"name",
-				"type",
-				true,
-				Lists.newArrayList("value"),
-				Lists.newArrayList(new AllowedValue("id", "name"))
-		);
+  @Test
+  @Disabled
+  void checkConnection() throws Exception {
 
-		return Lists.newArrayList(field);
-	}
+    when(pluginBox.getInstance("jira", BtsExtension.class)).thenReturn(
+        java.util.Optional.ofNullable(extension));
+    when(extension.testConnection(any(Integration.class))).thenReturn(true);
+
+    mockMvc.perform(get(SUPERADMIN_PROJECT_BASE_URL + "/integration/10/connection/test").with(
+        token(oAuthHelper.getSuperadminToken())));
+  }
+
+  @Test
+  void getSetOfIntegrationSystemFields() throws Exception {
+
+    Map<String, List<String>> params = Maps.newHashMap();
+    params.put("issueType", Lists.newArrayList("ISSUE01"));
+
+    when(pluginBox.getInstance("jira", BtsExtension.class)).thenReturn(
+        java.util.Optional.ofNullable(extension));
+    when(extension.getTicketFields(any(String.class), any(Integration.class))).thenReturn(
+        Lists.newArrayList(new PostFormField()));
+
+    mockMvc.perform(get("/v1/bts/superadmin_personal/10/fields-set").params(
+            CollectionUtils.toMultiValueMap(params))
+        .with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isOk());
+  }
+
+  @Test
+  void getAllowableIssueTypes() throws Exception {
+
+    when(pluginBox.getInstance("jira", BtsExtension.class)).thenReturn(
+        java.util.Optional.ofNullable(extension));
+    when(extension.getIssueTypes(any(Integration.class))).thenReturn(
+        Lists.newArrayList("type1", "type2"));
+
+    mockMvc.perform(get("/v1/bts/superadmin_personal/10/issue_types").with(
+            token(oAuthHelper.getSuperadminToken())))
+        .andExpect(status().isOk());
+  }
+
+  @Test
+  void createIssue() throws Exception {
+
+    PostTicketRQ request = getPostTicketRQ();
+
+    when(pluginBox.getInstance("jira", BtsExtension.class)).thenReturn(
+        java.util.Optional.ofNullable(extension));
+    when(extension.submitTicket(any(PostTicketRQ.class), any(Integration.class))).thenReturn(
+        new Ticket());
+
+    mockMvc.perform(
+        post("/v1/bts/superadmin_personal/10/ticket").with(token(oAuthHelper.getSuperadminToken()))
+            .contentType(MediaType.APPLICATION_JSON)
+            .content(objectMapper.writeValueAsBytes(request))).andExpect(status().isCreated());
+  }
+
+  @Test
+  void shouldNotCreateIssueWhenMoreThen300BackLinks() throws Exception {
+
+    final PostTicketRQ request = new PostTicketRQ();
+    final Map<Long, String> backLinks = LongStream.range(1, 302).boxed()
+        .collect(Collectors.toMap(it -> it, String::valueOf));
+    request.setBackLinks(backLinks);
+
+    final MvcResult mvcResult = mockMvc.perform(
+            post("/v1/bts/superadmin_personal/10/ticket").with(token(oAuthHelper.getSuperadminToken()))
+                .contentType(MediaType.APPLICATION_JSON)
+                .content(objectMapper.writeValueAsBytes(request))).andExpect(status().isBadRequest())
+        .andReturn();
+
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(
+        INCORRECT_REQUEST_MESSAGE + "[Field 'backLinks' should have size from '0' to '300'.] ",
+        error.getMessage()
+    );
+  }
+
+  @Test
+  void getTicket() throws Exception {
+
+    final String ticketId = "/ticket_id";
+
+    Map<String, List<String>> params = Maps.newHashMap();
+    params.put("btsUrl", Lists.newArrayList("jira.com"));
+    params.put("btsProject", Lists.newArrayList("project"));
+
+    when(pluginBox.getInstance("jira", BtsExtension.class)).thenReturn(
+        java.util.Optional.ofNullable(extension));
+    when(extension.getTicket(any(String.class), any(Integration.class))).thenReturn(
+        java.util.Optional.of(new Ticket()));
+
+    mockMvc.perform(get("/v1/bts/superadmin_personal/ticket" + ticketId).params(
+            CollectionUtils.toMultiValueMap(params))
+        .with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isOk());
+  }
+
+  private IntegrationRQ getUpdateRQ() {
+
+    IntegrationRQ integrationRQ = new IntegrationRQ();
+    integrationRQ.setEnabled(true);
+    integrationRQ.setName("jira1");
+    Map<String, Object> integrationParams = new HashMap<>();
+    integrationParams.put("defectFormFields", getPostFormFields());
+    integrationRQ.setIntegrationParams(integrationParams);
+    return integrationRQ;
+  }
+
+  private BtsConnectionTestRQ getConnectionRQ() {
+    BtsConnectionTestRQ connectionTestRQ = new BtsConnectionTestRQ();
+    connectionTestRQ.setUrl("url");
+    connectionTestRQ.setBtsProject("project");
+
+    return connectionTestRQ;
+  }
+
+  private PostTicketRQ getPostTicketRQ() {
+    PostTicketRQ postTicketRQ = new PostTicketRQ();
+    postTicketRQ.setFields(getPostFormFields());
+    postTicketRQ.setNumberOfLogs(10);
+    postTicketRQ.setIsIncludeScreenshots(false);
+    postTicketRQ.setIsIncludeComments(false);
+    postTicketRQ.setTestItemId(1L);
+
+    return postTicketRQ;
+  }
+
+  private List<PostFormField> getPostFormFields() {
+    PostFormField field = PostFormField.builder().id("id").fieldName("name")
+        .fieldType("type").isRequired(true)
+        .value(List.of("value")).definedValues(List.of(new AllowedValue("id", "name"))).build();
+    return Lists.newArrayList(field);
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/controller/DashboardControllerValidationTest.java b/src/test/java/com/epam/ta/reportportal/ws/controller/DashboardControllerValidationTest.java
index 72f3dc129e..e156cc1915 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/controller/DashboardControllerValidationTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/controller/DashboardControllerValidationTest.java
@@ -16,15 +16,14 @@
 
 package com.epam.ta.reportportal.ws.controller;
 
-import com.epam.ta.reportportal.ws.BaseMvcTest;
-import com.epam.ta.reportportal.ws.model.ErrorRS;
-import com.epam.ta.reportportal.ws.model.dashboard.CreateDashboardRQ;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.test.web.servlet.MvcResult;
-
-import static com.epam.ta.reportportal.ws.controller.constants.ValidationTestsConstants.*;
+import static com.epam.ta.reportportal.ws.controller.constants.ValidationTestsConstants.FIELD_NAME_IS_BLANK_MESSAGE;
+import static com.epam.ta.reportportal.ws.controller.constants.ValidationTestsConstants.FIELD_NAME_IS_NULL_MESSAGE;
+import static com.epam.ta.reportportal.ws.controller.constants.ValidationTestsConstants.FIELD_NAME_SIZE_MESSAGE_WITH_FORMAT;
+import static com.epam.ta.reportportal.ws.controller.constants.ValidationTestsConstants.ID_PATH;
+import static com.epam.ta.reportportal.ws.controller.constants.ValidationTestsConstants.INCORRECT_REQUEST_MESSAGE;
+import static com.epam.ta.reportportal.ws.controller.constants.ValidationTestsConstants.LONG_NAME_VALUE;
+import static com.epam.ta.reportportal.ws.controller.constants.ValidationTestsConstants.SHORT_NAME_VALUE;
+import static com.epam.ta.reportportal.ws.controller.constants.ValidationTestsConstants.WHITESPACES_NAME_VALUE;
 import static com.epam.ta.reportportal.ws.model.ErrorType.INCORRECT_REQUEST;
 import static org.apache.commons.lang3.StringUtils.EMPTY;
 import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -33,203 +32,232 @@
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
 
+import com.epam.ta.reportportal.ws.BaseMvcTest;
+import com.epam.ta.reportportal.ws.model.ErrorRS;
+import com.epam.ta.reportportal.ws.model.dashboard.CreateDashboardRQ;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.web.servlet.MvcResult;
+
 /**
  * @author <a href="mailto:tatyana_gladysheva@epam.com">Tatyana Gladysheva</a>
  */
 class DashboardControllerValidationTest extends BaseMvcTest {
 
-	private static final String DASHBOARD_PATH = "/dashboard";
-
-	private static final String FIELD_NAME_SIZE_MESSAGE = String.format(FIELD_NAME_SIZE_MESSAGE_WITH_FORMAT, 3, 128);
-
-	@Autowired
-	private ObjectMapper objectMapper;
-
-	@Test
-	public void createDashboardShouldReturnErrorWhenNameIsNull() throws Exception {
-		//GIVEN
-		CreateDashboardRQ createDashboardRQ = new CreateDashboardRQ();
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + DASHBOARD_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(createDashboardRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + FIELD_NAME_IS_NULL_MESSAGE, error.getMessage());
-	}
-
-	@Test
-	public void createDashboardShouldReturnErrorWhenNameIsEmpty() throws Exception {
-		//GIVEN
-		CreateDashboardRQ createDashboardRQ = new CreateDashboardRQ();
-		createDashboardRQ.setName(EMPTY);
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + DASHBOARD_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(createDashboardRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " " + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
-	}
-
-	@Test
-	public void createDashboardShouldReturnErrorWhenNameConsistsOfWhitespaces() throws Exception {
-		//GIVEN
-		CreateDashboardRQ createDashboardRQ = new CreateDashboardRQ();
-		createDashboardRQ.setName(WHITESPACES_NAME_VALUE);
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + DASHBOARD_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(createDashboardRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " " + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
-	}
-
-	@Test
-	public void createDashboardShouldReturnErrorWhenNameIsLessThanThreeCharacters() throws Exception {
-		//GIVEN
-		CreateDashboardRQ createDashboardRQ = new CreateDashboardRQ();
-		createDashboardRQ.setName(SHORT_NAME_VALUE);
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + DASHBOARD_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(createDashboardRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
-	}
-
-	@Test
-	public void createDashboardShouldReturnErrorWhenNameIsGreaterThanOneHundredAndTwentyEightCharacters() throws Exception {
-		//GIVEN
-		CreateDashboardRQ createDashboardRQ = new CreateDashboardRQ();
-		createDashboardRQ.setName(LONG_NAME_VALUE);
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + DASHBOARD_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(createDashboardRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
-	}
-
-	@Test
-	public void updateDashboardShouldReturnErrorWhenNameIsNull() throws Exception {
-		//GIVEN
-		CreateDashboardRQ createDashboardRQ = new CreateDashboardRQ();
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + DASHBOARD_PATH + ID_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(createDashboardRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + FIELD_NAME_IS_NULL_MESSAGE, error.getMessage());
-	}
-
-	@Test
-	public void updateDashboardShouldReturnErrorWhenNameIsEmpty() throws Exception {
-		//GIVEN
-		CreateDashboardRQ createDashboardRQ = new CreateDashboardRQ();
-		createDashboardRQ.setName(EMPTY);
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + DASHBOARD_PATH + ID_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(createDashboardRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " " + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
-	}
-
-	@Test
-	public void updateDashboardShouldReturnErrorWhenNameConsistsOfWhitespaces() throws Exception {
-		//GIVEN
-		CreateDashboardRQ createDashboardRQ = new CreateDashboardRQ();
-		createDashboardRQ.setName(WHITESPACES_NAME_VALUE);
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + DASHBOARD_PATH + ID_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(createDashboardRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " " + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
-	}
-
-	@Test
-	public void updateDashboardShouldReturnErrorWhenNameIsLessThanThreeCharacters() throws Exception {
-		//GIVEN
-		CreateDashboardRQ createDashboardRQ = new CreateDashboardRQ();
-		createDashboardRQ.setName(SHORT_NAME_VALUE);
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + DASHBOARD_PATH + ID_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(createDashboardRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
-	}
-
-	@Test
-	public void updateDashboardShouldReturnErrorWhenNameIsGreaterThanOneHundredAndTwentyEightCharacters() throws Exception {
-		//GIVEN
-		CreateDashboardRQ createDashboardRQ = new CreateDashboardRQ();
-		createDashboardRQ.setName(LONG_NAME_VALUE);
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + DASHBOARD_PATH + ID_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(createDashboardRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
-	}
+  private static final String DASHBOARD_PATH = "/dashboard";
+
+  private static final String FIELD_NAME_SIZE_MESSAGE = String.format(
+      FIELD_NAME_SIZE_MESSAGE_WITH_FORMAT, 3, 128);
+
+  @Autowired
+  private ObjectMapper objectMapper;
+
+  @Test
+  public void createDashboardShouldReturnErrorWhenNameIsNull() throws Exception {
+    //GIVEN
+    CreateDashboardRQ createDashboardRQ = new CreateDashboardRQ();
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + DASHBOARD_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(createDashboardRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + FIELD_NAME_IS_NULL_MESSAGE, error.getMessage());
+  }
+
+  @Test
+  public void createDashboardShouldReturnErrorWhenNameIsEmpty() throws Exception {
+    //GIVEN
+    CreateDashboardRQ createDashboardRQ = new CreateDashboardRQ();
+    createDashboardRQ.setName(EMPTY);
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + DASHBOARD_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(createDashboardRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " "
+        + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
+  }
+
+  @Test
+  public void createDashboardShouldReturnErrorWhenNameConsistsOfWhitespaces() throws Exception {
+    //GIVEN
+    CreateDashboardRQ createDashboardRQ = new CreateDashboardRQ();
+    createDashboardRQ.setName(WHITESPACES_NAME_VALUE);
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + DASHBOARD_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(createDashboardRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " "
+        + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
+  }
+
+  @Test
+  public void createDashboardShouldReturnErrorWhenNameIsLessThanThreeCharacters() throws Exception {
+    //GIVEN
+    CreateDashboardRQ createDashboardRQ = new CreateDashboardRQ();
+    createDashboardRQ.setName(SHORT_NAME_VALUE);
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + DASHBOARD_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(createDashboardRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_SIZE_MESSAGE + "] ",
+        error.getMessage());
+  }
+
+  @Test
+  public void createDashboardShouldReturnErrorWhenNameIsGreaterThanOneHundredAndTwentyEightCharacters()
+      throws Exception {
+    //GIVEN
+    CreateDashboardRQ createDashboardRQ = new CreateDashboardRQ();
+    createDashboardRQ.setName(LONG_NAME_VALUE);
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + DASHBOARD_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(createDashboardRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_SIZE_MESSAGE + "] ",
+        error.getMessage());
+  }
+
+  @Test
+  public void updateDashboardShouldReturnErrorWhenNameIsNull() throws Exception {
+    //GIVEN
+    CreateDashboardRQ createDashboardRQ = new CreateDashboardRQ();
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + DASHBOARD_PATH + ID_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(createDashboardRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + FIELD_NAME_IS_NULL_MESSAGE, error.getMessage());
+  }
+
+  @Test
+  public void updateDashboardShouldReturnErrorWhenNameIsEmpty() throws Exception {
+    //GIVEN
+    CreateDashboardRQ createDashboardRQ = new CreateDashboardRQ();
+    createDashboardRQ.setName(EMPTY);
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + DASHBOARD_PATH + ID_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(createDashboardRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " "
+        + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
+  }
+
+  @Test
+  public void updateDashboardShouldReturnErrorWhenNameConsistsOfWhitespaces() throws Exception {
+    //GIVEN
+    CreateDashboardRQ createDashboardRQ = new CreateDashboardRQ();
+    createDashboardRQ.setName(WHITESPACES_NAME_VALUE);
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + DASHBOARD_PATH + ID_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(createDashboardRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " "
+        + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
+  }
+
+  @Test
+  public void updateDashboardShouldReturnErrorWhenNameIsLessThanThreeCharacters() throws Exception {
+    //GIVEN
+    CreateDashboardRQ createDashboardRQ = new CreateDashboardRQ();
+    createDashboardRQ.setName(SHORT_NAME_VALUE);
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + DASHBOARD_PATH + ID_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(createDashboardRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_SIZE_MESSAGE + "] ",
+        error.getMessage());
+  }
+
+  @Test
+  public void updateDashboardShouldReturnErrorWhenNameIsGreaterThanOneHundredAndTwentyEightCharacters()
+      throws Exception {
+    //GIVEN
+    CreateDashboardRQ createDashboardRQ = new CreateDashboardRQ();
+    createDashboardRQ.setName(LONG_NAME_VALUE);
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + DASHBOARD_PATH + ID_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(createDashboardRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_SIZE_MESSAGE + "] ",
+        error.getMessage());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/controller/IntegrationControllerTest.java b/src/test/java/com/epam/ta/reportportal/ws/controller/IntegrationControllerTest.java
index e8a180d97a..29d87b1166 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/controller/IntegrationControllerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/controller/IntegrationControllerTest.java
@@ -16,239 +16,265 @@
 
 package com.epam.ta.reportportal.ws.controller;
 
+import static org.mockito.Mockito.doNothing;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
 import com.epam.ta.reportportal.ws.BaseMvcTest;
 import com.epam.ta.reportportal.ws.model.integration.IntegrationRQ;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import java.util.HashMap;
+import java.util.Map;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.MediaType;
 import org.springframework.test.context.jdbc.Sql;
 
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.mockito.Mockito.doNothing;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @Sql("/db/integration/integration-fill.sql")
 class IntegrationControllerTest extends BaseMvcTest {
 
-	@Autowired
-	private ObjectMapper objectMapper;
-
-	@Test
-	void createGlobalIntegration() throws Exception {
-		IntegrationRQ request = new IntegrationRQ();
-		request.setName("email");
-		Map<String, Object> params = new HashMap<>();
-		params.put("param1", "value");
-		params.put("param2", "lalala");
-		request.setIntegrationParams(params);
-		request.setEnabled(true);
-
-		doNothing().when(emailService).testConnection();
-
-		mockMvc.perform(post("/v1/integration/email").with(token(oAuthHelper.getSuperadminToken()))
-				.contentType(MediaType.APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().isCreated());
-
-		mockMvc.perform(post("/v1/integration/email").with(token(oAuthHelper.getSuperadminToken()))
-				.contentType(MediaType.APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().isConflict());
-	}
-
-	@Test
-	void createGlobalIntegrationNegative() throws Exception {
-		IntegrationRQ request = new IntegrationRQ();
-		request.setName("name");
-		Map<String, Object> params = new HashMap<>();
-		params.put("param1", "value");
-		params.put("param2", "lalala");
-		request.setIntegrationParams(params);
-		request.setEnabled(true);
-
-		mockMvc.perform(post("/v1/integration/unknown").with(token(oAuthHelper.getSuperadminToken()))
-				.contentType(MediaType.APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().isNotFound());
-	}
-
-	@Test
-	void createProjectIntegration() throws Exception {
-		IntegrationRQ request = new IntegrationRQ();
-		request.setName("email");
-		Map<String, Object> params = new HashMap<>();
-		params.put("param1", "value");
-		params.put("param2", "lalala");
-		request.setIntegrationParams(params);
-		request.setEnabled(true);
-
-		doNothing().when(emailService).testConnection();
-
-		mockMvc.perform(post("/v1/integration/default_personal/email").with(token(oAuthHelper.getDefaultToken()))
-				.contentType(MediaType.APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().isCreated());
-
-		mockMvc.perform(post("/v1/integration/default_personal/email").with(token(oAuthHelper.getDefaultToken()))
-				.contentType(MediaType.APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().isConflict());
-	}
-
-	@Test
-	void createProjectIntegrationNegative() throws Exception {
-		IntegrationRQ request = new IntegrationRQ();
-		Map<String, Object> params = new HashMap<>();
-		params.put("param1", "value");
-		params.put("param2", "lalala");
-		request.setIntegrationParams(params);
-		request.setEnabled(true);
-
-		mockMvc.perform(post("/v1/integration/default_personal/unknown").with(token(oAuthHelper.getDefaultToken()))
-				.contentType(MediaType.APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().isNotFound());
-	}
-
-	@Test
-	void updateGlobalIntegration() throws Exception {
-		IntegrationRQ request = new IntegrationRQ();
-		Map<String, Object> params = new HashMap<>();
-		params.put("param1", "value");
-		params.put("param2", "lalala");
-		request.setIntegrationParams(params);
-		request.setEnabled(true);
-
-		doNothing().when(emailService).testConnection();
-
-		mockMvc.perform(put("/v1/integration/7").with(token(oAuthHelper.getSuperadminToken()))
-				.contentType(MediaType.APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
-	}
-
-	@Test
-	void updateGlobalIntegrationNegative() throws Exception {
-		IntegrationRQ request = new IntegrationRQ();
-		Map<String, Object> params = new HashMap<>();
-		params.put("param1", "value");
-		params.put("param2", "lalala");
-		request.setIntegrationParams(params);
-		request.setEnabled(true);
-
-		mockMvc.perform(put("/v1/integration/77").with(token(oAuthHelper.getSuperadminToken()))
-				.contentType(MediaType.APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().isNotFound());
-	}
-
-	@Test
-	void updateProjectIntegration() throws Exception {
-		IntegrationRQ request = new IntegrationRQ();
-		Map<String, Object> params = new HashMap<>();
-		params.put("param1", "value");
-		params.put("param2", "lalala");
-		request.setIntegrationParams(params);
-		request.setEnabled(true);
-
-		doNothing().when(emailService).testConnection();
-
-		mockMvc.perform(put("/v1/integration/default_personal/8").with(token(oAuthHelper.getDefaultToken()))
-				.contentType(MediaType.APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
-	}
-
-	@Test
-	void updateProjectIntegrationNegative() throws Exception {
-		IntegrationRQ request = new IntegrationRQ();
-		Map<String, Object> params = new HashMap<>();
-		params.put("param1", "value");
-		params.put("param2", "lalala");
-		request.setIntegrationParams(params);
-		request.setEnabled(true);
-
-		mockMvc.perform(put("/v1/integration/default_personal/88").with(token(oAuthHelper.getDefaultToken()))
-				.contentType(MediaType.APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().isNotFound());
-	}
-
-	@Test
-	void getAllGlobal() throws Exception {
-		mockMvc.perform(get("/v1/integration/global/all").with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isOk());
-	}
-
-	@Test
-	void getAllGlobalByType() throws Exception {
-		mockMvc.perform(get("/v1/integration/global/all/jira").with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isOk());
-	}
-
-	@Test
-	void getAllProject() throws Exception {
-		mockMvc.perform(get("/v1/integration/project/superadmin_personal/all").with(token(oAuthHelper.getSuperadminToken())))
-				.andExpect(status().isOk());
-	}
-
-	@Test
-	void getAllProjectByType() throws Exception {
-		mockMvc.perform(get("/v1/integration/project/superadmin_personal/all/jira").with(token(oAuthHelper.getSuperadminToken())))
-				.andExpect(status().isOk());
-	}
-
-	@Test
-	void getGlobalIntegration() throws Exception {
-		mockMvc.perform(get("/v1/integration/7").with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isOk());
-	}
-
-
-	@Test
-	void getGlobalIntegrationNegative() throws Exception {
-		mockMvc.perform(get("/v1/integration/100").with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isNotFound());
-	}
-
-	@Test
-	void deleteGlobalIntegration() throws Exception {
-		mockMvc.perform(delete("/v1/integration/7").with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isOk());
-	}
-
-	@Test
-	void deleteGlobalIntegrationNegative() throws Exception {
-		mockMvc.perform(delete("/v1/integration/100").with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isNotFound());
-	}
-
-	@Test
-	void deleteAllIntegrations() throws Exception {
-		mockMvc.perform(delete("/v1/integration/all/email").with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isOk());
-	}
-
-	@Test
-	void getProjectIntegration() throws Exception {
-		mockMvc.perform(get("/v1/integration/default_personal/8").with(token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
-	}
-
-	@Test
-	void testProjectIntegrationConnection() throws Exception {
-		mockMvc.perform(get("/v1/integration/default_personal/8/connection/test").with(token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
-	}
-
-	@Test
-	void getProjectIntegrationNegative() throws Exception {
-		mockMvc.perform(get("/v1/integration/default_personal/100").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().isNotFound());
-	}
-
-	@Test
-	void deleteProjectIntegration() throws Exception {
-		mockMvc.perform(delete("/v1/integration/default_personal/8").with(token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
-	}
-
-	@Test
-	void deleteProjectIntegrationNegative() throws Exception {
-		mockMvc.perform(delete("/v1/integration/default_personal/100").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().isNotFound());
-	}
-
-	@Test
-	void deleteAllProjectIntegrations() throws Exception {
-		mockMvc.perform(delete("/v1/integration/default_personal/all/email").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().isOk());
-	}
+  @Autowired
+  private ObjectMapper objectMapper;
+
+  @Test
+  void createGlobalIntegration() throws Exception {
+    IntegrationRQ request = new IntegrationRQ();
+    request.setName("email");
+    Map<String, Object> params = new HashMap<>();
+    params.put("param1", "value");
+    params.put("param2", "lalala");
+    request.setIntegrationParams(params);
+    request.setEnabled(true);
+
+    doNothing().when(emailService).testConnection();
+
+    mockMvc.perform(post("/v1/integration/email").with(token(oAuthHelper.getSuperadminToken()))
+        .contentType(MediaType.APPLICATION_JSON)
+        .content(objectMapper.writeValueAsBytes(request))).andExpect(status().isCreated());
+
+    mockMvc.perform(post("/v1/integration/email").with(token(oAuthHelper.getSuperadminToken()))
+        .contentType(MediaType.APPLICATION_JSON)
+        .content(objectMapper.writeValueAsBytes(request))).andExpect(status().isConflict());
+  }
+
+  @Test
+  void createGlobalIntegrationNegative() throws Exception {
+    IntegrationRQ request = new IntegrationRQ();
+    request.setName("name");
+    Map<String, Object> params = new HashMap<>();
+    params.put("param1", "value");
+    params.put("param2", "lalala");
+    request.setIntegrationParams(params);
+    request.setEnabled(true);
+
+    mockMvc.perform(post("/v1/integration/unknown").with(token(oAuthHelper.getSuperadminToken()))
+        .contentType(MediaType.APPLICATION_JSON)
+        .content(objectMapper.writeValueAsBytes(request))).andExpect(status().isNotFound());
+  }
+
+  @Test
+  void createProjectIntegration() throws Exception {
+    IntegrationRQ request = new IntegrationRQ();
+    request.setName("email");
+    Map<String, Object> params = new HashMap<>();
+    params.put("param1", "value");
+    params.put("param2", "lalala");
+    request.setIntegrationParams(params);
+    request.setEnabled(true);
+
+    doNothing().when(emailService).testConnection();
+
+    mockMvc.perform(
+        post("/v1/integration/default_personal/email").with(token(oAuthHelper.getDefaultToken()))
+            .contentType(MediaType.APPLICATION_JSON)
+            .content(objectMapper.writeValueAsBytes(request))).andExpect(status().isCreated());
+
+    mockMvc.perform(
+        post("/v1/integration/default_personal/email").with(token(oAuthHelper.getDefaultToken()))
+            .contentType(MediaType.APPLICATION_JSON)
+            .content(objectMapper.writeValueAsBytes(request))).andExpect(status().isConflict());
+  }
+
+  @Test
+  void createProjectIntegrationNegative() throws Exception {
+    IntegrationRQ request = new IntegrationRQ();
+    Map<String, Object> params = new HashMap<>();
+    params.put("param1", "value");
+    params.put("param2", "lalala");
+    request.setIntegrationParams(params);
+    request.setEnabled(true);
+
+    mockMvc.perform(
+        post("/v1/integration/default_personal/unknown").with(token(oAuthHelper.getDefaultToken()))
+            .contentType(MediaType.APPLICATION_JSON)
+            .content(objectMapper.writeValueAsBytes(request))).andExpect(status().isNotFound());
+  }
+
+  @Test
+  void updateGlobalIntegration() throws Exception {
+    IntegrationRQ request = new IntegrationRQ();
+    Map<String, Object> params = new HashMap<>();
+    params.put("param1", "value");
+    params.put("param2", "lalala");
+    request.setIntegrationParams(params);
+    request.setEnabled(true);
+
+    doNothing().when(emailService).testConnection();
+
+    mockMvc.perform(put("/v1/integration/7").with(token(oAuthHelper.getSuperadminToken()))
+        .contentType(MediaType.APPLICATION_JSON)
+        .content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
+  }
+
+  @Test
+  void updateGlobalIntegrationNegative() throws Exception {
+    IntegrationRQ request = new IntegrationRQ();
+    Map<String, Object> params = new HashMap<>();
+    params.put("param1", "value");
+    params.put("param2", "lalala");
+    request.setIntegrationParams(params);
+    request.setEnabled(true);
+
+    mockMvc.perform(put("/v1/integration/77").with(token(oAuthHelper.getSuperadminToken()))
+        .contentType(MediaType.APPLICATION_JSON)
+        .content(objectMapper.writeValueAsBytes(request))).andExpect(status().isNotFound());
+  }
+
+  @Test
+  void updateProjectIntegration() throws Exception {
+    IntegrationRQ request = new IntegrationRQ();
+    Map<String, Object> params = new HashMap<>();
+    params.put("param1", "value");
+    params.put("param2", "lalala");
+    request.setIntegrationParams(params);
+    request.setEnabled(true);
+
+    doNothing().when(emailService).testConnection();
+
+    mockMvc.perform(
+        put("/v1/integration/default_personal/8").with(token(oAuthHelper.getDefaultToken()))
+            .contentType(MediaType.APPLICATION_JSON)
+            .content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
+  }
+
+  @Test
+  void updateProjectIntegrationNegative() throws Exception {
+    IntegrationRQ request = new IntegrationRQ();
+    Map<String, Object> params = new HashMap<>();
+    params.put("param1", "value");
+    params.put("param2", "lalala");
+    request.setIntegrationParams(params);
+    request.setEnabled(true);
+
+    mockMvc.perform(
+        put("/v1/integration/default_personal/88").with(token(oAuthHelper.getDefaultToken()))
+            .contentType(MediaType.APPLICATION_JSON)
+            .content(objectMapper.writeValueAsBytes(request))).andExpect(status().isNotFound());
+  }
+
+  @Test
+  void getAllGlobal() throws Exception {
+    mockMvc.perform(get("/v1/integration/global/all").with(token(oAuthHelper.getSuperadminToken())))
+        .andExpect(status().isOk());
+  }
+
+  @Test
+  void getAllGlobalByType() throws Exception {
+    mockMvc.perform(
+            get("/v1/integration/global/all/jira").with(token(oAuthHelper.getSuperadminToken())))
+        .andExpect(status().isOk());
+  }
+
+  @Test
+  void getAllProject() throws Exception {
+    mockMvc.perform(get("/v1/integration/project/superadmin_personal/all").with(
+            token(oAuthHelper.getSuperadminToken())))
+        .andExpect(status().isOk());
+  }
+
+  @Test
+  void getAllProjectByType() throws Exception {
+    mockMvc.perform(get("/v1/integration/project/superadmin_personal/all/jira").with(
+            token(oAuthHelper.getSuperadminToken())))
+        .andExpect(status().isOk());
+  }
+
+  @Test
+  void getGlobalIntegration() throws Exception {
+    mockMvc.perform(get("/v1/integration/7").with(token(oAuthHelper.getSuperadminToken())))
+        .andExpect(status().isOk());
+  }
+
+
+  @Test
+  void getGlobalIntegrationNegative() throws Exception {
+    mockMvc.perform(get("/v1/integration/100").with(token(oAuthHelper.getSuperadminToken())))
+        .andExpect(status().isNotFound());
+  }
+
+  @Test
+  void deleteGlobalIntegration() throws Exception {
+    mockMvc.perform(delete("/v1/integration/7").with(token(oAuthHelper.getSuperadminToken())))
+        .andExpect(status().isOk());
+  }
+
+  @Test
+  void deleteGlobalIntegrationNegative() throws Exception {
+    mockMvc.perform(delete("/v1/integration/100").with(token(oAuthHelper.getSuperadminToken())))
+        .andExpect(status().isNotFound());
+  }
+
+  @Test
+  void deleteAllIntegrations() throws Exception {
+    mockMvc.perform(
+            delete("/v1/integration/all/email").with(token(oAuthHelper.getSuperadminToken())))
+        .andExpect(status().isOk());
+  }
+
+  @Test
+  void getProjectIntegration() throws Exception {
+    mockMvc.perform(
+            get("/v1/integration/default_personal/8").with(token(oAuthHelper.getDefaultToken())))
+        .andExpect(status().isOk());
+  }
+
+  @Test
+  void testProjectIntegrationConnection() throws Exception {
+    mockMvc.perform(get("/v1/integration/default_personal/8/connection/test").with(
+        token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
+  }
+
+  @Test
+  void getProjectIntegrationNegative() throws Exception {
+    mockMvc.perform(
+            get("/v1/integration/default_personal/100").with(token(oAuthHelper.getDefaultToken())))
+        .andExpect(status().isNotFound());
+  }
+
+  @Test
+  void deleteProjectIntegration() throws Exception {
+    mockMvc.perform(
+            delete("/v1/integration/default_personal/8").with(token(oAuthHelper.getDefaultToken())))
+        .andExpect(status().isOk());
+  }
+
+  @Test
+  void deleteProjectIntegrationNegative() throws Exception {
+    mockMvc.perform(
+            delete("/v1/integration/default_personal/100").with(token(oAuthHelper.getDefaultToken())))
+        .andExpect(status().isNotFound());
+  }
+
+  @Test
+  void deleteAllProjectIntegrations() throws Exception {
+    mockMvc.perform(delete("/v1/integration/default_personal/all/email").with(
+            token(oAuthHelper.getDefaultToken())))
+        .andExpect(status().isOk());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/controller/LaunchAsyncControllerTest.java b/src/test/java/com/epam/ta/reportportal/ws/controller/LaunchAsyncControllerTest.java
index 35092dfa1a..2ef618bcbd 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/controller/LaunchAsyncControllerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/controller/LaunchAsyncControllerTest.java
@@ -16,6 +16,13 @@
 
 package com.epam.ta.reportportal.ws.controller;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.launch.FinishLaunchHandler;
 import com.epam.ta.reportportal.core.launch.MergeLaunchHandler;
@@ -27,6 +34,8 @@
 import com.epam.ta.reportportal.ws.model.launch.MergeLaunchesRQ;
 import com.epam.ta.reportportal.ws.model.launch.StartLaunchRQ;
 import com.google.common.collect.Lists;
+import java.util.UUID;
+import javax.servlet.http.HttpServletRequest;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.ArgumentCaptor;
@@ -35,108 +44,119 @@
 import org.mockito.junit.jupiter.MockitoExtension;
 import org.springframework.security.web.savedrequest.Enumerator;
 
-import javax.servlet.http.HttpServletRequest;
-import java.util.UUID;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
 /**
  * @author Konstantin Antipin
  */
 @ExtendWith(MockitoExtension.class)
 class LaunchAsyncControllerTest {
 
-    @Mock
-    ProjectExtractor projectExtractor;
-
-    @Mock
-    StartLaunchHandler startLaunchHandler;
-
-    @Mock
-    FinishLaunchHandler finishLaunchHandler;
-
-    @Mock
-    MergeLaunchHandler mergeLaunchHandler;
-
-    @InjectMocks
-    LaunchAsyncController launchAsyncController;
-
-    @Mock
-    HttpServletRequest httpServletRequest;
-
-    @Test
-    void startLaunch() {
-        ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
-
-        StartLaunchRQ startLaunchRQ = new StartLaunchRQ();
-
-        ArgumentCaptor<ReportPortalUser> userArgumentCaptor = ArgumentCaptor.forClass(ReportPortalUser.class);
-        ArgumentCaptor<ReportPortalUser.ProjectDetails> projectDetailsArgumentCaptor = ArgumentCaptor.forClass(ReportPortalUser.ProjectDetails.class);
-        ArgumentCaptor<StartLaunchRQ> requestArgumentCaptor = ArgumentCaptor.forClass(StartLaunchRQ.class);
-
-        when(projectExtractor.extractProjectDetails(any(ReportPortalUser.class), anyString())).thenReturn(user.getProjectDetails()
-                .get("test_project"));
-
-        launchAsyncController.startLaunch("test_project", startLaunchRQ, user);
-        verify(startLaunchHandler).startLaunch(userArgumentCaptor.capture(), projectDetailsArgumentCaptor.capture(), requestArgumentCaptor.capture());
-        assertEquals(user, userArgumentCaptor.getValue());
-        assertEquals(user.getProjectDetails().get("test_project"), projectDetailsArgumentCaptor.getValue());
-        assertEquals(startLaunchRQ, requestArgumentCaptor.getValue());
-    }
-
-    @Test
-    void finishLaunch() {
-        ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
-
-        FinishExecutionRQ finishExecutionRQ = new FinishExecutionRQ();
-
-        String launchId = UUID.randomUUID().toString();
-
-        ArgumentCaptor<String> launchIdArgumentCaptor = ArgumentCaptor.forClass(String.class);
-        ArgumentCaptor<FinishExecutionRQ> requestArgumentCaptor = ArgumentCaptor.forClass(FinishExecutionRQ.class);
-        ArgumentCaptor<ReportPortalUser.ProjectDetails> projectDetailsArgumentCaptor = ArgumentCaptor.forClass(ReportPortalUser.ProjectDetails.class);
-        ArgumentCaptor<ReportPortalUser> userArgumentCaptor = ArgumentCaptor.forClass(ReportPortalUser.class);
-        ArgumentCaptor<String> urlArgumentCaptor = ArgumentCaptor.forClass(String.class);
-
-        when(projectExtractor.extractProjectDetails(any(ReportPortalUser.class), anyString())).thenReturn(user.getProjectDetails()
-                .get("test_project"));
-
-        when(httpServletRequest.getRequestURL()).thenReturn(new StringBuffer("http://localhost:8080"));
-        when(httpServletRequest.getHeaderNames()).thenReturn(new Enumerator<>(Lists.newArrayList()));
-        launchAsyncController.finishLaunch("test_project", launchId, finishExecutionRQ, user, httpServletRequest);
-        verify(finishLaunchHandler).finishLaunch(
-                launchIdArgumentCaptor.capture(),
-                requestArgumentCaptor.capture(),
-                projectDetailsArgumentCaptor.capture(),
-                userArgumentCaptor.capture(),
-                urlArgumentCaptor.capture());
-        assertEquals(user, userArgumentCaptor.getValue());
-        assertEquals(user.getProjectDetails().get("test_project"), projectDetailsArgumentCaptor.getValue());
-        assertEquals(finishExecutionRQ, requestArgumentCaptor.getValue());
-    }
-
-    @Test
-    void mergeLaunch() {
-        ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
-
-        MergeLaunchesRQ mergeLaunchesRQ = new MergeLaunchesRQ();
-
-        ArgumentCaptor<ReportPortalUser.ProjectDetails> projectDetailsArgumentCaptor = ArgumentCaptor.forClass(ReportPortalUser.ProjectDetails.class);
-        ArgumentCaptor<ReportPortalUser> userArgumentCaptor = ArgumentCaptor.forClass(ReportPortalUser.class);
-        ArgumentCaptor<MergeLaunchesRQ> requestArgumentCaptor = ArgumentCaptor.forClass(MergeLaunchesRQ.class);
-
-        when(projectExtractor.extractProjectDetails(any(ReportPortalUser.class), anyString())).thenReturn(user.getProjectDetails()
-                .get("test_project"));
-
-        launchAsyncController.mergeLaunches("test_project", mergeLaunchesRQ, user);
-        verify(mergeLaunchHandler).mergeLaunches(projectDetailsArgumentCaptor.capture(), userArgumentCaptor.capture(), requestArgumentCaptor.capture());
-        assertEquals(user, userArgumentCaptor.getValue());
-        assertEquals(user.getProjectDetails().get("test_project"), projectDetailsArgumentCaptor.getValue());
-        assertEquals(mergeLaunchesRQ, requestArgumentCaptor.getValue());
-    }
+  @Mock
+  ProjectExtractor projectExtractor;
+
+  @Mock
+  StartLaunchHandler startLaunchHandler;
+
+  @Mock
+  FinishLaunchHandler finishLaunchHandler;
+
+  @Mock
+  MergeLaunchHandler mergeLaunchHandler;
+
+  @InjectMocks
+  LaunchAsyncController launchAsyncController;
+
+  @Mock
+  HttpServletRequest httpServletRequest;
+
+  @Test
+  void startLaunch() {
+    ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER,
+        1L);
+
+    StartLaunchRQ startLaunchRQ = new StartLaunchRQ();
+
+    ArgumentCaptor<ReportPortalUser> userArgumentCaptor = ArgumentCaptor.forClass(
+        ReportPortalUser.class);
+    ArgumentCaptor<ReportPortalUser.ProjectDetails> projectDetailsArgumentCaptor = ArgumentCaptor.forClass(
+        ReportPortalUser.ProjectDetails.class);
+    ArgumentCaptor<StartLaunchRQ> requestArgumentCaptor = ArgumentCaptor.forClass(
+        StartLaunchRQ.class);
+
+    when(projectExtractor.extractProjectDetails(any(ReportPortalUser.class),
+        anyString())).thenReturn(user.getProjectDetails()
+        .get("test_project"));
+
+    launchAsyncController.startLaunch("test_project", startLaunchRQ, user);
+    verify(startLaunchHandler).startLaunch(userArgumentCaptor.capture(),
+        projectDetailsArgumentCaptor.capture(), requestArgumentCaptor.capture());
+    assertEquals(user, userArgumentCaptor.getValue());
+    assertEquals(user.getProjectDetails().get("test_project"),
+        projectDetailsArgumentCaptor.getValue());
+    assertEquals(startLaunchRQ, requestArgumentCaptor.getValue());
+  }
+
+  @Test
+  void finishLaunch() {
+    ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER,
+        1L);
+
+    FinishExecutionRQ finishExecutionRQ = new FinishExecutionRQ();
+
+    String launchId = UUID.randomUUID().toString();
+
+    ArgumentCaptor<String> launchIdArgumentCaptor = ArgumentCaptor.forClass(String.class);
+    ArgumentCaptor<FinishExecutionRQ> requestArgumentCaptor = ArgumentCaptor.forClass(
+        FinishExecutionRQ.class);
+    ArgumentCaptor<ReportPortalUser.ProjectDetails> projectDetailsArgumentCaptor = ArgumentCaptor.forClass(
+        ReportPortalUser.ProjectDetails.class);
+    ArgumentCaptor<ReportPortalUser> userArgumentCaptor = ArgumentCaptor.forClass(
+        ReportPortalUser.class);
+    ArgumentCaptor<String> urlArgumentCaptor = ArgumentCaptor.forClass(String.class);
+
+    when(projectExtractor.extractProjectDetails(any(ReportPortalUser.class),
+        anyString())).thenReturn(user.getProjectDetails()
+        .get("test_project"));
+
+    when(httpServletRequest.getRequestURL()).thenReturn(new StringBuffer("http://localhost:8080"));
+    when(httpServletRequest.getHeaderNames()).thenReturn(new Enumerator<>(Lists.newArrayList()));
+    launchAsyncController.finishLaunch("test_project", launchId, finishExecutionRQ, user,
+        httpServletRequest);
+    verify(finishLaunchHandler).finishLaunch(
+        launchIdArgumentCaptor.capture(),
+        requestArgumentCaptor.capture(),
+        projectDetailsArgumentCaptor.capture(),
+        userArgumentCaptor.capture(),
+        urlArgumentCaptor.capture());
+    assertEquals(user, userArgumentCaptor.getValue());
+    assertEquals(user.getProjectDetails().get("test_project"),
+        projectDetailsArgumentCaptor.getValue());
+    assertEquals(finishExecutionRQ, requestArgumentCaptor.getValue());
+  }
+
+  @Test
+  void mergeLaunch() {
+    ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER,
+        1L);
+
+    MergeLaunchesRQ mergeLaunchesRQ = new MergeLaunchesRQ();
+
+    ArgumentCaptor<ReportPortalUser.ProjectDetails> projectDetailsArgumentCaptor = ArgumentCaptor.forClass(
+        ReportPortalUser.ProjectDetails.class);
+    ArgumentCaptor<ReportPortalUser> userArgumentCaptor = ArgumentCaptor.forClass(
+        ReportPortalUser.class);
+    ArgumentCaptor<MergeLaunchesRQ> requestArgumentCaptor = ArgumentCaptor.forClass(
+        MergeLaunchesRQ.class);
+
+    when(projectExtractor.extractProjectDetails(any(ReportPortalUser.class),
+        anyString())).thenReturn(user.getProjectDetails()
+        .get("test_project"));
+
+    launchAsyncController.mergeLaunches("test_project", mergeLaunchesRQ, user);
+    verify(mergeLaunchHandler).mergeLaunches(projectDetailsArgumentCaptor.capture(),
+        userArgumentCaptor.capture(), requestArgumentCaptor.capture());
+    assertEquals(user, userArgumentCaptor.getValue());
+    assertEquals(user.getProjectDetails().get("test_project"),
+        projectDetailsArgumentCaptor.getValue());
+    assertEquals(mergeLaunchesRQ, requestArgumentCaptor.getValue());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/controller/LaunchControllerTest.java b/src/test/java/com/epam/ta/reportportal/ws/controller/LaunchControllerTest.java
index 6b6e274e37..6b71d7fa7c 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/controller/LaunchControllerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/controller/LaunchControllerTest.java
@@ -16,6 +16,22 @@
 
 package com.epam.ta.reportportal.ws.controller;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_PROJECT_ID;
+import static com.epam.ta.reportportal.ws.model.launch.Mode.DEBUG;
+import static com.epam.ta.reportportal.ws.model.launch.Mode.DEFAULT;
+import static java.util.stream.Collectors.toMap;
+import static org.hamcrest.Matchers.hasSize;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.springframework.http.MediaType.APPLICATION_JSON;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.querygen.FilterCondition;
 import com.epam.ta.reportportal.dao.LaunchRepository;
@@ -38,26 +54,19 @@
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
-import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.test.context.jdbc.Sql;
-
 import java.time.LocalDateTime;
 import java.time.ZoneId;
-import java.util.*;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
-
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_PROJECT_ID;
-import static com.epam.ta.reportportal.ws.model.launch.Mode.DEBUG;
-import static com.epam.ta.reportportal.ws.model.launch.Mode.DEFAULT;
-import static java.util.stream.Collectors.toMap;
-import static org.hamcrest.Matchers.hasSize;
-import static org.junit.jupiter.api.Assertions.*;
-import static org.springframework.http.MediaType.APPLICATION_JSON;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.jdbc.Sql;
 
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
@@ -65,329 +74,370 @@
 @Sql("/db/launch/launch-fill.sql")
 class LaunchControllerTest extends BaseMvcTest {
 
-	@Autowired
-	private ObjectMapper objectMapper;
-
-	@Autowired
-	private LaunchRepository launchRepository;
-
-	@Test
-	void happyCreateLaunch() throws Exception {
-		String name = "some launch name";
-		StartLaunchRQ startLaunchRQ = new StartLaunchRQ();
-		startLaunchRQ.setDescription("some description");
-		startLaunchRQ.setName(name);
-		startLaunchRQ.setStartTime(new Date());
-		startLaunchRQ.setMode(DEFAULT);
-		startLaunchRQ.setAttributes(Sets.newHashSet(new ItemAttributesRQ("key", "value")));
-
-		mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + "/launch/").with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(startLaunchRQ))
-				.contentType(APPLICATION_JSON)).andExpect(status().isCreated());
-	}
-
-	@Test
-	void getSuggestedItemsAnalyzerNotDeployed() throws Exception {
-		AnalyzeLaunchRQ analyzeLaunchRQ = new AnalyzeLaunchRQ();
-		analyzeLaunchRQ.setLaunchId(1L);
-		analyzeLaunchRQ.setAnalyzeItemsModes(Collections.singletonList("TO_INVESTIGATE"));
-		analyzeLaunchRQ.setAnalyzerTypeName("autoAnalyzer");
-		analyzeLaunchRQ.setAnalyzerHistoryMode("ALL");
-		mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + "/launch/analyze").with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(analyzeLaunchRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(result -> assertTrue(result.getResolvedException() instanceof ReportPortalException))
-				.andExpect(result -> assertEquals(
-						"Impossible interact with integration. There are no analyzer services are deployed.",
-						result.getResolvedException().getMessage()
-				));
-	}
-
-	@Test
-	void updateLaunchPositive() throws Exception {
-		UpdateLaunchRQ rq = new UpdateLaunchRQ();
-		rq.setMode(DEFAULT);
-		rq.setDescription("description");
-		rq.setAttributes(Sets.newHashSet(new ItemAttributeResource("test", "test")));
-		mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/launch/3/update").with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(rq))
-				.contentType(APPLICATION_JSON)).andExpect(status().is(200));
-	}
-
-	@Test
-	void getLaunchPositive() throws Exception {
-		mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/launch/2").with(token(oAuthHelper.getDefaultToken()))).andExpect(status().is(200));
-	}
-
-	@Test
-	void getLaunchStringPositive() throws Exception {
-		mockMvc.perform(get(
-				DEFAULT_PROJECT_BASE_URL + "/launch/4850a659-ac26-4a65-8ea4-a6756a57fb92").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().is(200));
-	}
-
-	@Test
-	void getLaunchUuidPositive() throws Exception {
-		mockMvc.perform(get(
-				DEFAULT_PROJECT_BASE_URL + "/launch/uuid/4850a659-ac26-4a65-8ea4-a6756a57fb92").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().is(200));
-	}
-
-	@Test
-	void getDebugLaunches() throws Exception {
-		mockMvc.perform(get(SUPERADMIN_PROJECT_BASE_URL + "/launch/mode").with(token(oAuthHelper.getSuperadminToken())))
-				.andExpect(status().is(200));
-	}
-
-	@Test
-	void compareLaunches() throws Exception {
-		mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/launch/compare?ids=1,2").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().is(200));
-	}
-
-	@Test
-	void mergeLaunchesPositive() throws Exception {
-		MergeLaunchesRQ rq = new MergeLaunchesRQ();
-		HashSet<Long> set = new HashSet<>();
-		set.add(1L);
-		set.add(2L);
-		rq.setLaunches(set);
-		rq.setName("Merged");
-		rq.setMergeStrategyType("BASIC");
-		rq.setStartTime(new Date());
-		rq.setEndTime(new Date());
-		mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + "/launch/merge").contentType(APPLICATION_JSON)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(rq))).andExpect(status().is(200));
-	}
-
-	@Test
-	void deleteLaunchPositive() throws Exception {
-		mockMvc.perform(delete(DEFAULT_PROJECT_BASE_URL + "/launch/1").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().is(200));
-	}
-
-	@Test
-	void deleteLaunchNegative() throws Exception {
-		mockMvc.perform(delete(DEFAULT_PROJECT_BASE_URL + "/launch/3").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().is(406));
-	}
-
-	@Test
-	void getStatus() throws Exception {
-		mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/launch/status?ids=1").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().is(200));
-	}
-
-	@Test
-	void finishLaunch() throws Exception {
-		final FinishExecutionRQ finishExecutionRQ = new FinishExecutionRQ();
-		finishExecutionRQ.setEndTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
-		finishExecutionRQ.setStatus(StatusEnum.PASSED.name());
-		mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/launch/befef834-b2ef-4acf-aea3-b5a5b15fd93c/finish").contentType(APPLICATION_JSON)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(finishExecutionRQ))).andExpect(status().is(200));
-	}
-
-	@Test
-	void forceFinishLaunch() throws Exception {
-		final FinishExecutionRQ finishExecutionRQ = new FinishExecutionRQ();
-		finishExecutionRQ.setEndTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
-		finishExecutionRQ.setStatus(StatusEnum.PASSED.name());
-		mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/launch/3/stop").contentType(APPLICATION_JSON)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(finishExecutionRQ))).andExpect(status().is(200));
-	}
-
-	@Test
-	void bulkForceFinish() throws Exception {
-		final BulkRQ<Long, FinishExecutionRQ> bulkRQ = new BulkRQ<>();
-		bulkRQ.setEntities(Stream.of(3L, 5L).collect(toMap(it -> it, it -> {
-			FinishExecutionRQ finishExecutionRQ = new FinishExecutionRQ();
-			finishExecutionRQ.setStatus(StatusEnum.PASSED.name());
-			finishExecutionRQ.setEndTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
-			return finishExecutionRQ;
-		})));
-		mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/launch/stop").with(token(oAuthHelper.getDefaultToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(bulkRQ))).andExpect(status().isOk());
-	}
-
-	@Test
-	void getAllOwners() throws Exception {
-		mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/launch/owners?filter.cnt.user=def").contentType(APPLICATION_JSON)
-				.with(token(oAuthHelper.getDefaultToken()))).andExpect(status().is(200));
-	}
-
-	@Test
-	void getAllLaunchNames() throws Exception {
-		mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/launch/names?filter.cnt.name=test").contentType(APPLICATION_JSON)
-				.with(token(oAuthHelper.getDefaultToken()))).andExpect(status().is(200));
-	}
-
-	@Test
-	void bulkDeleteLaunches() throws Exception {
-		DeleteBulkRQ deleteBulkRQ = new DeleteBulkRQ();
-		List<Long> ids = Lists.newArrayList(1L, 2L);
-		deleteBulkRQ.setIds(ids);
-		mockMvc.perform(delete(DEFAULT_PROJECT_BASE_URL + "/launch").contentType(APPLICATION_JSON)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(deleteBulkRQ))).andExpect(status().is(200));
-		List<Launch> launches = launchRepository.findAllById(ids);
-		assertTrue(launches.isEmpty());
-	}
-
-	@Test
-	void bulkMoveToDebug() throws Exception {
-		final List<Long> ids = launchRepository.findByFilter(Filter.builder()
-				.withTarget(Launch.class)
-				.withCondition(FilterCondition.builder().eq(CRITERIA_PROJECT_ID, String.valueOf(2L)).build())
-				.build()).stream().filter(it -> it.getMode() == LaunchModeEnum.DEFAULT).map(Launch::getId).collect(Collectors.toList());
-		final Map<Long, UpdateLaunchRQ> entities = ids.stream().collect(toMap(it -> it, it -> {
-			final UpdateLaunchRQ updateLaunchRQ = new UpdateLaunchRQ();
-			updateLaunchRQ.setMode(DEBUG);
-			return updateLaunchRQ;
-		}));
-		final BulkRQ<Long, UpdateLaunchRQ> bulkRQ = new BulkRQ<>();
-		bulkRQ.setEntities(entities);
-		mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/launch/update").with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(bulkRQ))
-				.contentType(APPLICATION_JSON)).andExpect(status().is(200));
-		launchRepository.findAllById(ids).forEach(it -> assertSame(it.getMode(), LaunchModeEnum.DEBUG));
-	}
-
-	@Test
-	void getLaunches() throws Exception {
-		mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL
-				+ "/launch?page.page=1&page.size=50&page.sort=statistics$defects$product_bug$total,ASC").contentType(APPLICATION_JSON)
-				.with(token(oAuthHelper.getDefaultToken()))).andExpect(status().is(200));
-	}
-
-	@Test
-	void getLatestLaunches() throws Exception {
-		mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL
-				+ "/launch/latest?page.page=1&page.size=10&page.sort=name,ASC").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().is(200));
-	}
-
-	@Test
-	void getAttributeKeys() throws Exception {
-		mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL
-				+ "/launch/attribute/keys?filter.cnt.attributeKey=browser").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().isOk());
-	}
-
-	@Test
-	void getAttributeValues() throws Exception {
-		mockMvc.perform(get(
-				DEFAULT_PROJECT_BASE_URL + "/launch/attribute/values?filter.eq.attributeKey=browser&filter.cnt.attributeValue=ch").with(
-				token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
-	}
-
-	@Test
-	void getProjectLaunches() throws Exception {
-		mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/launch").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().isOk())
-				.andExpect(jsonPath("$.content", hasSize(4)));
-	}
-
-	@Test
-	void export() throws Exception {
-		mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/launch/1/report").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().isOk());
-	}
-
-	@Test
-	void bulkUpdateItemAttributes() throws Exception {
-		BulkInfoUpdateRQ request = new BulkInfoUpdateRQ();
-		List<Long> launchIds = Arrays.asList(1L, 2L, 3L, 4L);
-		request.setIds(launchIds);
-		BulkInfoUpdateRQ.Description description = new BulkInfoUpdateRQ.Description();
-		description.setAction(BulkInfoUpdateRQ.Action.CREATE);
-		String comment = "created";
-		description.setComment(comment);
-		request.setDescription(description);
-		UpdateItemAttributeRQ updateItemAttributeRQ = new UpdateItemAttributeRQ();
-		updateItemAttributeRQ.setAction(BulkInfoUpdateRQ.Action.UPDATE);
-		updateItemAttributeRQ.setFrom(new ItemAttributeResource("testKey", "testValue"));
-		updateItemAttributeRQ.setTo(new ItemAttributeResource("updatedKey", "updatedValue"));
-		request.setAttributes(Lists.newArrayList(updateItemAttributeRQ));
-
-		mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/launch/info").with(token(oAuthHelper.getDefaultToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
-
-		List<Launch> launches = launchRepository.findAllById(launchIds);
-		launches.forEach(it -> launchRepository.refresh(it));
-
-		launches.forEach(it -> {
-			assertTrue(it.getAttributes()
-					.stream()
-					.noneMatch(attr -> "testKey".equals(attr.getKey()) && attr.getValue().equals("testValue") && !attr.isSystem()));
-			assertTrue(it.getAttributes()
-					.stream()
-					.anyMatch(attr -> "updatedKey".equals(attr.getKey()) && attr.getValue().equals("updatedValue") && !attr.isSystem()));
-			assertEquals(comment, it.getDescription());
-		});
-	}
-
-	@Test
-	void bulkCreateAttributes() throws Exception {
-		BulkInfoUpdateRQ request = new BulkInfoUpdateRQ();
-		List<Long> launchIds = Arrays.asList(1L, 2L, 3L, 4L);
-		request.setIds(launchIds);
-		BulkInfoUpdateRQ.Description description = new BulkInfoUpdateRQ.Description();
-		description.setAction(BulkInfoUpdateRQ.Action.UPDATE);
-		String comment = "updated";
-		description.setComment(comment);
-		request.setDescription(description);
-		UpdateItemAttributeRQ updateItemAttributeRQ = new UpdateItemAttributeRQ();
-		updateItemAttributeRQ.setAction(BulkInfoUpdateRQ.Action.CREATE);
-		updateItemAttributeRQ.setTo(new ItemAttributeResource("createdKey", "createdValue"));
-		request.setAttributes(Lists.newArrayList(updateItemAttributeRQ));
-
-		mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/launch/info").with(token(oAuthHelper.getDefaultToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
-
-		List<Launch> launches = launchRepository.findAllById(launchIds);
-		launches.forEach(it -> launchRepository.refresh(it));
-
-		launches.forEach(it -> {
-			assertTrue(it.getAttributes()
-					.stream()
-					.anyMatch(attr -> "createdKey".equals(attr.getKey()) && attr.getValue().equals("createdValue") && !attr.isSystem()));
-			assertTrue(it.getDescription().length() > comment.length() && it.getDescription().contains(comment));
-		});
-	}
-
-	@Test
-	void bulkDeleteAttributes() throws Exception {
-		BulkInfoUpdateRQ request = new BulkInfoUpdateRQ();
-		List<Long> launchIds = Arrays.asList(1L, 2L, 3L, 4L);
-		request.setIds(launchIds);
-		BulkInfoUpdateRQ.Description description = new BulkInfoUpdateRQ.Description();
-		description.setAction(BulkInfoUpdateRQ.Action.CREATE);
-		String comment = "created";
-		description.setComment(comment);
-		request.setDescription(description);
-		UpdateItemAttributeRQ updateItemAttributeRQ = new UpdateItemAttributeRQ();
-		updateItemAttributeRQ.setAction(BulkInfoUpdateRQ.Action.DELETE);
-		updateItemAttributeRQ.setFrom(new ItemAttributeResource("testKey", "testValue"));
-		request.setAttributes(Lists.newArrayList(updateItemAttributeRQ));
-
-		mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/launch/info").with(token(oAuthHelper.getDefaultToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
-
-		List<Launch> launches = launchRepository.findAllById(launchIds);
-		launches.forEach(it -> launchRepository.refresh(it));
-
-		launches.forEach(it -> {
-			assertTrue(it.getAttributes()
-					.stream()
-					.noneMatch(attr -> "testKey".equals(attr.getKey()) && attr.getValue().equals("testValue") && !attr.isSystem()));
-			assertEquals(comment, it.getDescription());
-		});
-	}
+  @Autowired
+  private ObjectMapper objectMapper;
+
+  @Autowired
+  private LaunchRepository launchRepository;
+
+  @Test
+  void happyCreateLaunch() throws Exception {
+    String name = "some launch name";
+    StartLaunchRQ startLaunchRQ = new StartLaunchRQ();
+    startLaunchRQ.setDescription("some description");
+    startLaunchRQ.setName(name);
+    startLaunchRQ.setStartTime(new Date());
+    startLaunchRQ.setMode(DEFAULT);
+    startLaunchRQ.setAttributes(Sets.newHashSet(new ItemAttributesRQ("key", "value")));
+
+    mockMvc.perform(
+        post(DEFAULT_PROJECT_BASE_URL + "/launch/").with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(startLaunchRQ))
+            .contentType(APPLICATION_JSON)).andExpect(status().isCreated());
+  }
+
+  @Test
+  void getSuggestedItemsAnalyzerNotDeployed() throws Exception {
+    AnalyzeLaunchRQ analyzeLaunchRQ = new AnalyzeLaunchRQ();
+    analyzeLaunchRQ.setLaunchId(1L);
+    analyzeLaunchRQ.setAnalyzeItemsModes(Collections.singletonList("TO_INVESTIGATE"));
+    analyzeLaunchRQ.setAnalyzerTypeName("autoAnalyzer");
+    analyzeLaunchRQ.setAnalyzerHistoryMode("ALL");
+    mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + "/launch/analyze").with(
+                token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(analyzeLaunchRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(
+            result -> assertTrue(result.getResolvedException() instanceof ReportPortalException))
+        .andExpect(result -> assertEquals(
+            "Impossible interact with integration. There are no analyzer services are deployed.",
+            result.getResolvedException().getMessage()
+        ));
+  }
+
+  @Test
+  void updateLaunchPositive() throws Exception {
+    UpdateLaunchRQ rq = new UpdateLaunchRQ();
+    rq.setMode(DEFAULT);
+    rq.setDescription("description");
+    rq.setAttributes(Sets.newHashSet(new ItemAttributeResource("test", "test")));
+    mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/launch/3/update").with(
+            token(oAuthHelper.getDefaultToken()))
+        .content(objectMapper.writeValueAsBytes(rq))
+        .contentType(APPLICATION_JSON)).andExpect(status().is(200));
+  }
+
+  @Test
+  void getLaunchPositive() throws Exception {
+    mockMvc.perform(
+            get(DEFAULT_PROJECT_BASE_URL + "/launch/2").with(token(oAuthHelper.getDefaultToken())))
+        .andExpect(status().is(200));
+  }
+
+  @Test
+  void getLaunchStringPositive() throws Exception {
+    mockMvc.perform(get(
+            DEFAULT_PROJECT_BASE_URL + "/launch/4850a659-ac26-4a65-8ea4-a6756a57fb92").with(
+            token(oAuthHelper.getDefaultToken())))
+        .andExpect(status().is(200));
+  }
+
+  @Test
+  void getLaunchUuidPositive() throws Exception {
+    mockMvc.perform(get(
+            DEFAULT_PROJECT_BASE_URL + "/launch/uuid/4850a659-ac26-4a65-8ea4-a6756a57fb92").with(
+            token(oAuthHelper.getDefaultToken())))
+        .andExpect(status().is(200));
+  }
+
+  @Test
+  void getDebugLaunches() throws Exception {
+    mockMvc.perform(get(SUPERADMIN_PROJECT_BASE_URL + "/launch/mode").with(
+            token(oAuthHelper.getSuperadminToken())))
+        .andExpect(status().is(200));
+  }
+
+  @Test
+  void compareLaunches() throws Exception {
+    mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/launch/compare?ids=1,2").with(
+            token(oAuthHelper.getDefaultToken())))
+        .andExpect(status().is(200));
+  }
+
+  @Test
+  void mergeLaunchesPositive() throws Exception {
+    MergeLaunchesRQ rq = new MergeLaunchesRQ();
+    HashSet<Long> set = new HashSet<>();
+    set.add(1L);
+    set.add(2L);
+    rq.setLaunches(set);
+    rq.setName("Merged");
+    rq.setMergeStrategyType("BASIC");
+    rq.setStartTime(new Date());
+    rq.setEndTime(new Date());
+    mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + "/launch/merge").contentType(APPLICATION_JSON)
+        .with(token(oAuthHelper.getDefaultToken()))
+        .content(objectMapper.writeValueAsBytes(rq))).andExpect(status().is(200));
+  }
+
+  @Test
+  void deleteLaunchPositive() throws Exception {
+    mockMvc.perform(
+            delete(DEFAULT_PROJECT_BASE_URL + "/launch/1").with(token(oAuthHelper.getDefaultToken())))
+        .andExpect(status().is(200));
+  }
+
+  @Test
+  void deleteLaunchNegative() throws Exception {
+    mockMvc.perform(
+            delete(DEFAULT_PROJECT_BASE_URL + "/launch/3").with(token(oAuthHelper.getDefaultToken())))
+        .andExpect(status().is(406));
+  }
+
+  @Test
+  void getStatus() throws Exception {
+    mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/launch/status?ids=1").with(
+            token(oAuthHelper.getDefaultToken())))
+        .andExpect(status().is(200));
+  }
+
+  @Test
+  void finishLaunch() throws Exception {
+    final FinishExecutionRQ finishExecutionRQ = new FinishExecutionRQ();
+    finishExecutionRQ.setEndTime(
+        Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+    finishExecutionRQ.setStatus(StatusEnum.PASSED.name());
+    mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL
+        + "/launch/befef834-b2ef-4acf-aea3-b5a5b15fd93c/finish").contentType(APPLICATION_JSON)
+        .with(token(oAuthHelper.getDefaultToken()))
+        .content(objectMapper.writeValueAsBytes(finishExecutionRQ))).andExpect(status().is(200));
+  }
+
+  @Test
+  void forceFinishLaunch() throws Exception {
+    final FinishExecutionRQ finishExecutionRQ = new FinishExecutionRQ();
+    finishExecutionRQ.setEndTime(
+        Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+    finishExecutionRQ.setStatus(StatusEnum.PASSED.name());
+    mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/launch/3/stop").contentType(APPLICATION_JSON)
+        .with(token(oAuthHelper.getDefaultToken()))
+        .content(objectMapper.writeValueAsBytes(finishExecutionRQ))).andExpect(status().is(200));
+  }
+
+  @Test
+  void bulkForceFinish() throws Exception {
+    final BulkRQ<Long, FinishExecutionRQ> bulkRQ = new BulkRQ<>();
+    bulkRQ.setEntities(Stream.of(3L, 5L).collect(toMap(it -> it, it -> {
+      FinishExecutionRQ finishExecutionRQ = new FinishExecutionRQ();
+      finishExecutionRQ.setStatus(StatusEnum.PASSED.name());
+      finishExecutionRQ.setEndTime(
+          Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+      return finishExecutionRQ;
+    })));
+    mockMvc.perform(
+        put(DEFAULT_PROJECT_BASE_URL + "/launch/stop").with(token(oAuthHelper.getDefaultToken()))
+            .contentType(APPLICATION_JSON)
+            .content(objectMapper.writeValueAsBytes(bulkRQ))).andExpect(status().isOk());
+  }
+
+  @Test
+  void getAllOwners() throws Exception {
+    mockMvc.perform(
+        get(DEFAULT_PROJECT_BASE_URL + "/launch/owners?filter.cnt.user=def").contentType(
+                APPLICATION_JSON)
+            .with(token(oAuthHelper.getDefaultToken()))).andExpect(status().is(200));
+  }
+
+  @Test
+  void getAllLaunchNames() throws Exception {
+    mockMvc.perform(
+        get(DEFAULT_PROJECT_BASE_URL + "/launch/names?filter.cnt.name=test").contentType(
+                APPLICATION_JSON)
+            .with(token(oAuthHelper.getDefaultToken()))).andExpect(status().is(200));
+  }
+
+  @Test
+  void bulkDeleteLaunches() throws Exception {
+    DeleteBulkRQ deleteBulkRQ = new DeleteBulkRQ();
+    List<Long> ids = Lists.newArrayList(1L, 2L);
+    deleteBulkRQ.setIds(ids);
+    mockMvc.perform(delete(DEFAULT_PROJECT_BASE_URL + "/launch").contentType(APPLICATION_JSON)
+        .with(token(oAuthHelper.getDefaultToken()))
+        .content(objectMapper.writeValueAsBytes(deleteBulkRQ))).andExpect(status().is(200));
+    List<Launch> launches = launchRepository.findAllById(ids);
+    assertTrue(launches.isEmpty());
+  }
+
+  @Test
+  void bulkMoveToDebug() throws Exception {
+    final List<Long> ids = launchRepository.findByFilter(Filter.builder()
+            .withTarget(Launch.class)
+            .withCondition(
+                FilterCondition.builder().eq(CRITERIA_PROJECT_ID, String.valueOf(2L)).build())
+            .build()).stream().filter(it -> it.getMode() == LaunchModeEnum.DEFAULT).map(Launch::getId)
+        .collect(Collectors.toList());
+    final Map<Long, UpdateLaunchRQ> entities = ids.stream().collect(toMap(it -> it, it -> {
+      final UpdateLaunchRQ updateLaunchRQ = new UpdateLaunchRQ();
+      updateLaunchRQ.setMode(DEBUG);
+      return updateLaunchRQ;
+    }));
+    final BulkRQ<Long, UpdateLaunchRQ> bulkRQ = new BulkRQ<>();
+    bulkRQ.setEntities(entities);
+    mockMvc.perform(
+        put(DEFAULT_PROJECT_BASE_URL + "/launch/update").with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(bulkRQ))
+            .contentType(APPLICATION_JSON)).andExpect(status().is(200));
+    launchRepository.findAllById(ids).forEach(it -> assertSame(it.getMode(), LaunchModeEnum.DEBUG));
+  }
+
+  @Test
+  void getLaunches() throws Exception {
+    mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL
+        + "/launch?page.page=1&page.size=50&page.sort=statistics$defects$product_bug$total,ASC").contentType(
+            APPLICATION_JSON)
+        .with(token(oAuthHelper.getDefaultToken()))).andExpect(status().is(200));
+  }
+
+  @Test
+  void getLatestLaunches() throws Exception {
+    mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL
+            + "/launch/latest?page.page=1&page.size=10&page.sort=name,ASC").with(
+            token(oAuthHelper.getDefaultToken())))
+        .andExpect(status().is(200));
+  }
+
+  @Test
+  void getAttributeKeys() throws Exception {
+    mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL
+            + "/launch/attribute/keys?filter.cnt.attributeKey=browser").with(
+            token(oAuthHelper.getDefaultToken())))
+        .andExpect(status().isOk());
+  }
+
+  @Test
+  void getAttributeValues() throws Exception {
+    mockMvc.perform(get(
+        DEFAULT_PROJECT_BASE_URL
+            + "/launch/attribute/values?filter.eq.attributeKey=browser&filter.cnt.attributeValue=ch").with(
+        token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
+  }
+
+  @Test
+  void getProjectLaunches() throws Exception {
+    mockMvc.perform(
+            get(DEFAULT_PROJECT_BASE_URL + "/launch").with(token(oAuthHelper.getDefaultToken())))
+        .andExpect(status().isOk())
+        .andExpect(jsonPath("$.content", hasSize(4)));
+  }
+
+  @Test
+  void export() throws Exception {
+    mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/launch/1/report").with(
+            token(oAuthHelper.getDefaultToken())))
+        .andExpect(status().isOk());
+  }
+
+  @Test
+  void bulkUpdateItemAttributes() throws Exception {
+    BulkInfoUpdateRQ request = new BulkInfoUpdateRQ();
+    List<Long> launchIds = Arrays.asList(1L, 2L, 3L, 4L);
+    request.setIds(launchIds);
+    BulkInfoUpdateRQ.Description description = new BulkInfoUpdateRQ.Description();
+    description.setAction(BulkInfoUpdateRQ.Action.CREATE);
+    String comment = "created";
+    description.setComment(comment);
+    request.setDescription(description);
+    UpdateItemAttributeRQ updateItemAttributeRQ = new UpdateItemAttributeRQ();
+    updateItemAttributeRQ.setAction(BulkInfoUpdateRQ.Action.UPDATE);
+    updateItemAttributeRQ.setFrom(new ItemAttributeResource("testKey", "testValue"));
+    updateItemAttributeRQ.setTo(new ItemAttributeResource("updatedKey", "updatedValue"));
+    request.setAttributes(Lists.newArrayList(updateItemAttributeRQ));
+
+    mockMvc.perform(
+        put(DEFAULT_PROJECT_BASE_URL + "/launch/info").with(token(oAuthHelper.getDefaultToken()))
+            .contentType(APPLICATION_JSON)
+            .content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
+
+    List<Launch> launches = launchRepository.findAllById(launchIds);
+    launches.forEach(it -> launchRepository.refresh(it));
+
+    launches.forEach(it -> {
+      assertTrue(it.getAttributes()
+          .stream()
+          .noneMatch(attr -> "testKey".equals(attr.getKey()) && attr.getValue().equals("testValue")
+              && !attr.isSystem()));
+      assertTrue(it.getAttributes()
+          .stream()
+          .anyMatch(
+              attr -> "updatedKey".equals(attr.getKey()) && attr.getValue().equals("updatedValue")
+                  && !attr.isSystem()));
+      assertEquals(comment, it.getDescription());
+    });
+  }
+
+  @Test
+  void bulkCreateAttributes() throws Exception {
+    BulkInfoUpdateRQ request = new BulkInfoUpdateRQ();
+    List<Long> launchIds = Arrays.asList(1L, 2L, 3L, 4L);
+    request.setIds(launchIds);
+    BulkInfoUpdateRQ.Description description = new BulkInfoUpdateRQ.Description();
+    description.setAction(BulkInfoUpdateRQ.Action.UPDATE);
+    String comment = "updated";
+    description.setComment(comment);
+    request.setDescription(description);
+    UpdateItemAttributeRQ updateItemAttributeRQ = new UpdateItemAttributeRQ();
+    updateItemAttributeRQ.setAction(BulkInfoUpdateRQ.Action.CREATE);
+    updateItemAttributeRQ.setTo(new ItemAttributeResource("createdKey", "createdValue"));
+    request.setAttributes(Lists.newArrayList(updateItemAttributeRQ));
+
+    mockMvc.perform(
+        put(DEFAULT_PROJECT_BASE_URL + "/launch/info").with(token(oAuthHelper.getDefaultToken()))
+            .contentType(APPLICATION_JSON)
+            .content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
+
+    List<Launch> launches = launchRepository.findAllById(launchIds);
+    launches.forEach(it -> launchRepository.refresh(it));
+
+    launches.forEach(it -> {
+      assertTrue(it.getAttributes()
+          .stream()
+          .anyMatch(
+              attr -> "createdKey".equals(attr.getKey()) && attr.getValue().equals("createdValue")
+                  && !attr.isSystem()));
+      assertTrue(
+          it.getDescription().length() > comment.length() && it.getDescription().contains(comment));
+    });
+  }
+
+  @Test
+  void bulkDeleteAttributes() throws Exception {
+    BulkInfoUpdateRQ request = new BulkInfoUpdateRQ();
+    List<Long> launchIds = Arrays.asList(1L, 2L, 3L, 4L);
+    request.setIds(launchIds);
+    BulkInfoUpdateRQ.Description description = new BulkInfoUpdateRQ.Description();
+    description.setAction(BulkInfoUpdateRQ.Action.CREATE);
+    String comment = "created";
+    description.setComment(comment);
+    request.setDescription(description);
+    UpdateItemAttributeRQ updateItemAttributeRQ = new UpdateItemAttributeRQ();
+    updateItemAttributeRQ.setAction(BulkInfoUpdateRQ.Action.DELETE);
+    updateItemAttributeRQ.setFrom(new ItemAttributeResource("testKey", "testValue"));
+    request.setAttributes(Lists.newArrayList(updateItemAttributeRQ));
+
+    mockMvc.perform(
+        put(DEFAULT_PROJECT_BASE_URL + "/launch/info").with(token(oAuthHelper.getDefaultToken()))
+            .contentType(APPLICATION_JSON)
+            .content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
+
+    List<Launch> launches = launchRepository.findAllById(launchIds);
+    launches.forEach(it -> launchRepository.refresh(it));
+
+    launches.forEach(it -> {
+      assertTrue(it.getAttributes()
+          .stream()
+          .noneMatch(attr -> "testKey".equals(attr.getKey()) && attr.getValue().equals("testValue")
+              && !attr.isSystem()));
+      assertEquals(comment, it.getDescription());
+    });
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/controller/LaunchControllerValidationTest.java b/src/test/java/com/epam/ta/reportportal/ws/controller/LaunchControllerValidationTest.java
index b1e47da472..0b3070b83b 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/controller/LaunchControllerValidationTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/controller/LaunchControllerValidationTest.java
@@ -16,6 +16,19 @@
 
 package com.epam.ta.reportportal.ws.controller;
 
+import static com.epam.ta.reportportal.ws.controller.constants.ValidationTestsConstants.FIELD_NAME_IS_BLANK_MESSAGE;
+import static com.epam.ta.reportportal.ws.controller.constants.ValidationTestsConstants.FIELD_NAME_IS_NULL_MESSAGE;
+import static com.epam.ta.reportportal.ws.controller.constants.ValidationTestsConstants.FIELD_NAME_SIZE_MESSAGE_WITH_FORMAT;
+import static com.epam.ta.reportportal.ws.controller.constants.ValidationTestsConstants.INCORRECT_REQUEST_MESSAGE;
+import static com.epam.ta.reportportal.ws.controller.constants.ValidationTestsConstants.WHITESPACES_NAME_VALUE;
+import static com.epam.ta.reportportal.ws.model.ErrorType.INCORRECT_REQUEST;
+import static com.epam.ta.reportportal.ws.model.launch.Mode.DEFAULT;
+import static org.apache.commons.lang3.StringUtils.EMPTY;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.springframework.http.MediaType.APPLICATION_JSON;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
 import com.epam.ta.reportportal.ws.BaseMvcTest;
 import com.epam.ta.reportportal.ws.model.ErrorRS;
 import com.epam.ta.reportportal.ws.model.attribute.ItemAttributesRQ;
@@ -23,210 +36,218 @@
 import com.epam.ta.reportportal.ws.model.launch.StartLaunchRQ;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.collect.Sets;
+import java.util.Date;
+import java.util.HashSet;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.test.web.servlet.MvcResult;
 
-import java.util.Date;
-import java.util.HashSet;
-
-import static com.epam.ta.reportportal.ws.controller.constants.ValidationTestsConstants.*;
-import static com.epam.ta.reportportal.ws.model.ErrorType.INCORRECT_REQUEST;
-import static com.epam.ta.reportportal.ws.model.launch.Mode.DEFAULT;
-import static org.apache.commons.lang3.StringUtils.EMPTY;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.springframework.http.MediaType.APPLICATION_JSON;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
 /**
  * @author <a href="mailto:tatyana_gladysheva@epam.com">Tatyana Gladysheva</a>
  */
 public class LaunchControllerValidationTest extends BaseMvcTest {
 
-	private static final String LAUNCH_PATH = "/launch";
-	private static final String MERGE_PATH = "/merge";
-
-	private static final String FIELD_NAME_SIZE_MESSAGE = String.format(FIELD_NAME_SIZE_MESSAGE_WITH_FORMAT, 1, 256);
-
-	private static final String LONG_NAME_VALUE = "tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
-			+ "tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
-			+ "ttttttttttttttttttttttttttttttttttttttttttttt";
-
-	@Autowired
-	private ObjectMapper objectMapper;
-
-	@Test
-	public void createLaunchShouldReturnErrorWhenNameIsNull() throws Exception {
-		//GIVEN
-		StartLaunchRQ startLaunchRQ = prepareLaunch();
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + LAUNCH_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(startLaunchRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + FIELD_NAME_IS_NULL_MESSAGE, error.getMessage());
-	}
-
-	@Test
-	public void createLaunchShouldReturnErrorWhenNameIsEmpty() throws Exception {
-		//GIVEN
-		StartLaunchRQ startLaunchRQ = prepareLaunch();
-		startLaunchRQ.setName(EMPTY);
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + LAUNCH_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(startLaunchRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " " + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
-	}
-
-	@Test
-	public void createLaunchShouldReturnErrorWhenNameConsistsOfWhitespaces() throws Exception {
-		//GIVEN
-		StartLaunchRQ startLaunchRQ = prepareLaunch();
-		startLaunchRQ.setName(WHITESPACES_NAME_VALUE);
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + LAUNCH_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(startLaunchRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " " + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
-	}
-
-	@Test
-	public void createLaunchShouldReturnErrorWhenNameIsGreaterThanTwoHundredAndFiftySixCharacters() throws Exception {
-		//GIVEN
-		StartLaunchRQ startLaunchRQ = prepareLaunch();
-		startLaunchRQ.setName(LONG_NAME_VALUE);
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + LAUNCH_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(startLaunchRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
-	}
-
-	private StartLaunchRQ prepareLaunch() {
-		StartLaunchRQ startLaunchRQ = new StartLaunchRQ();
-		startLaunchRQ.setDescription("some description");
-		startLaunchRQ.setStartTime(new Date());
-		startLaunchRQ.setMode(DEFAULT);
-		startLaunchRQ.setAttributes(Sets.newHashSet(new ItemAttributesRQ("key", "value")));
-		return startLaunchRQ;
-	}
-
-	@Test
-	public void mergeLaunchShouldReturnErrorWhenNameIsNull() throws Exception {
-		//GIVEN
-		MergeLaunchesRQ mergeLaunchesRQ = prepareLaunchesMerge();
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + LAUNCH_PATH + MERGE_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(mergeLaunchesRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + FIELD_NAME_IS_NULL_MESSAGE, error.getMessage());
-	}
-
-	@Test
-	public void mergeLaunchShouldReturnErrorWhenNameIsEmpty() throws Exception {
-		//GIVEN
-		MergeLaunchesRQ mergeLaunchesRQ = prepareLaunchesMerge();
-		mergeLaunchesRQ.setName(EMPTY);
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + LAUNCH_PATH + MERGE_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(mergeLaunchesRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " " + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
-	}
-
-	@Test
-	public void mergeLaunchShouldReturnErrorWhenNameConsistsOfWhitespaces() throws Exception {
-		//GIVEN
-		MergeLaunchesRQ mergeLaunchesRQ = prepareLaunchesMerge();
-		mergeLaunchesRQ.setName(WHITESPACES_NAME_VALUE);
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + LAUNCH_PATH + MERGE_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(mergeLaunchesRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " " + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
-	}
-
-	@Test
-	public void mergeLaunchShouldReturnErrorWhenNameIsGreaterThanTwoHundredAndFiftySixCharacters() throws Exception {
-		//GIVEN
-		MergeLaunchesRQ mergeLaunchesRQ = prepareLaunchesMerge();
-		mergeLaunchesRQ.setName(LONG_NAME_VALUE);
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + LAUNCH_PATH + MERGE_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(mergeLaunchesRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
-	}
-
-	private MergeLaunchesRQ prepareLaunchesMerge() {
-		MergeLaunchesRQ mergeLaunchesRQ = new MergeLaunchesRQ();
-
-		HashSet<Long> set = new HashSet<>();
-		set.add(1L);
-		set.add(2L);
-
-		mergeLaunchesRQ.setLaunches(set);
-		mergeLaunchesRQ.setMergeStrategyType("BASIC");
-		mergeLaunchesRQ.setStartTime(new Date());
-		mergeLaunchesRQ.setEndTime(new Date());
-
-		return mergeLaunchesRQ;
-	}
+  private static final String LAUNCH_PATH = "/launch";
+  private static final String MERGE_PATH = "/merge";
+
+  private static final String FIELD_NAME_SIZE_MESSAGE = String.format(
+      FIELD_NAME_SIZE_MESSAGE_WITH_FORMAT, 1, 256);
+
+  private static final String LONG_NAME_VALUE =
+      "tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
+          + "tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
+          + "ttttttttttttttttttttttttttttttttttttttttttttt";
+
+  @Autowired
+  private ObjectMapper objectMapper;
+
+  @Test
+  public void createLaunchShouldReturnErrorWhenNameIsNull() throws Exception {
+    //GIVEN
+    StartLaunchRQ startLaunchRQ = prepareLaunch();
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + LAUNCH_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(startLaunchRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + FIELD_NAME_IS_NULL_MESSAGE, error.getMessage());
+  }
+
+  @Test
+  public void createLaunchShouldReturnErrorWhenNameIsEmpty() throws Exception {
+    //GIVEN
+    StartLaunchRQ startLaunchRQ = prepareLaunch();
+    startLaunchRQ.setName(EMPTY);
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + LAUNCH_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(startLaunchRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " "
+        + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
+  }
+
+  @Test
+  public void createLaunchShouldReturnErrorWhenNameConsistsOfWhitespaces() throws Exception {
+    //GIVEN
+    StartLaunchRQ startLaunchRQ = prepareLaunch();
+    startLaunchRQ.setName(WHITESPACES_NAME_VALUE);
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + LAUNCH_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(startLaunchRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " "
+        + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
+  }
+
+  @Test
+  public void createLaunchShouldReturnErrorWhenNameIsGreaterThanTwoHundredAndFiftySixCharacters()
+      throws Exception {
+    //GIVEN
+    StartLaunchRQ startLaunchRQ = prepareLaunch();
+    startLaunchRQ.setName(LONG_NAME_VALUE);
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + LAUNCH_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(startLaunchRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_SIZE_MESSAGE + "] ",
+        error.getMessage());
+  }
+
+  private StartLaunchRQ prepareLaunch() {
+    StartLaunchRQ startLaunchRQ = new StartLaunchRQ();
+    startLaunchRQ.setDescription("some description");
+    startLaunchRQ.setStartTime(new Date());
+    startLaunchRQ.setMode(DEFAULT);
+    startLaunchRQ.setAttributes(Sets.newHashSet(new ItemAttributesRQ("key", "value")));
+    return startLaunchRQ;
+  }
+
+  @Test
+  public void mergeLaunchShouldReturnErrorWhenNameIsNull() throws Exception {
+    //GIVEN
+    MergeLaunchesRQ mergeLaunchesRQ = prepareLaunchesMerge();
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + LAUNCH_PATH + MERGE_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(mergeLaunchesRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + FIELD_NAME_IS_NULL_MESSAGE, error.getMessage());
+  }
+
+  @Test
+  public void mergeLaunchShouldReturnErrorWhenNameIsEmpty() throws Exception {
+    //GIVEN
+    MergeLaunchesRQ mergeLaunchesRQ = prepareLaunchesMerge();
+    mergeLaunchesRQ.setName(EMPTY);
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + LAUNCH_PATH + MERGE_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(mergeLaunchesRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " "
+        + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
+  }
+
+  @Test
+  public void mergeLaunchShouldReturnErrorWhenNameConsistsOfWhitespaces() throws Exception {
+    //GIVEN
+    MergeLaunchesRQ mergeLaunchesRQ = prepareLaunchesMerge();
+    mergeLaunchesRQ.setName(WHITESPACES_NAME_VALUE);
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + LAUNCH_PATH + MERGE_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(mergeLaunchesRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " "
+        + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
+  }
+
+  @Test
+  public void mergeLaunchShouldReturnErrorWhenNameIsGreaterThanTwoHundredAndFiftySixCharacters()
+      throws Exception {
+    //GIVEN
+    MergeLaunchesRQ mergeLaunchesRQ = prepareLaunchesMerge();
+    mergeLaunchesRQ.setName(LONG_NAME_VALUE);
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + LAUNCH_PATH + MERGE_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(mergeLaunchesRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_SIZE_MESSAGE + "] ",
+        error.getMessage());
+  }
+
+  private MergeLaunchesRQ prepareLaunchesMerge() {
+    MergeLaunchesRQ mergeLaunchesRQ = new MergeLaunchesRQ();
+
+    HashSet<Long> set = new HashSet<>();
+    set.add(1L);
+    set.add(2L);
+
+    mergeLaunchesRQ.setLaunches(set);
+    mergeLaunchesRQ.setMergeStrategyType("BASIC");
+    mergeLaunchesRQ.setStartTime(new Date());
+    mergeLaunchesRQ.setEndTime(new Date());
+
+    return mergeLaunchesRQ;
+  }
 }
diff --git a/src/test/java/com/epam/ta/reportportal/ws/controller/LogAsyncControllerTest.java b/src/test/java/com/epam/ta/reportportal/ws/controller/LogAsyncControllerTest.java
index bec7d82a10..4edba9ed06 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/controller/LogAsyncControllerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/controller/LogAsyncControllerTest.java
@@ -16,12 +16,22 @@
 
 package com.epam.ta.reportportal.ws.controller;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.mockito.internal.verification.VerificationModeFactory.times;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.log.CreateLogHandler;
 import com.epam.ta.reportportal.entity.project.ProjectRole;
 import com.epam.ta.reportportal.entity.user.UserRole;
 import com.epam.ta.reportportal.util.ProjectExtractor;
 import com.epam.ta.reportportal.ws.model.log.SaveLogRQ;
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.Validator;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.ArgumentCaptor;
@@ -30,106 +40,110 @@
 import org.mockito.junit.jupiter.MockitoExtension;
 import org.springframework.web.multipart.MultipartFile;
 
-import javax.servlet.http.HttpServletRequest;
-import javax.validation.Validator;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.mockito.internal.verification.VerificationModeFactory.times;
-
 /**
  * @author Konstantin Antipin
  */
 @ExtendWith(MockitoExtension.class)
 class LogAsyncControllerTest {
 
-    @Mock
-    ProjectExtractor projectExtractor;
-
-    @Mock
-    CreateLogHandler createLogHandler;
-
-    @Mock
-    Validator validator;
-
-    @InjectMocks
-    LogAsyncController logAsyncController;
-
-    @Mock
-    HttpServletRequest httpServletRequest;
-
-    @Test
-    void createLog() {
-        ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
-
-        SaveLogRQ saveLogRQ = new SaveLogRQ();
-
-        ArgumentCaptor<SaveLogRQ> requestArgumentCaptor = ArgumentCaptor.forClass(SaveLogRQ.class);
-        ArgumentCaptor<MultipartFile> fileArgumentCaptor = ArgumentCaptor.forClass(MultipartFile.class);
-        ArgumentCaptor<ReportPortalUser.ProjectDetails> projectDetailsArgumentCaptor = ArgumentCaptor.forClass(ReportPortalUser.ProjectDetails.class);
-
-		when(projectExtractor.extractProjectDetails(any(ReportPortalUser.class), anyString())).thenReturn(user.getProjectDetails()
-				.get("test_project"));
-
-        logAsyncController.createLog("test_project", saveLogRQ, user);
-        verify(createLogHandler).createLog(requestArgumentCaptor.capture(), fileArgumentCaptor.capture(), projectDetailsArgumentCaptor.capture());
-        verify(validator).validate(requestArgumentCaptor.capture());
-
-        requestArgumentCaptor.getAllValues().forEach(rq -> assertEquals(saveLogRQ, rq));
-        assertEquals(null, fileArgumentCaptor.getValue());
-        assertEquals(user.getProjectDetails().get("test_project"), projectDetailsArgumentCaptor.getValue());
-    }
-
-    @Test
-    void createLogEntry() {
-        ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
-
-        SaveLogRQ saveLogRQ = new SaveLogRQ();
-
-        ArgumentCaptor<SaveLogRQ> requestArgumentCaptor = ArgumentCaptor.forClass(SaveLogRQ.class);
-        ArgumentCaptor<MultipartFile> fileArgumentCaptor = ArgumentCaptor.forClass(MultipartFile.class);
-        ArgumentCaptor<ReportPortalUser.ProjectDetails> projectDetailsArgumentCaptor = ArgumentCaptor.forClass(ReportPortalUser.ProjectDetails.class);
-
-		when(projectExtractor.extractProjectDetails(any(ReportPortalUser.class), anyString())).thenReturn(user.getProjectDetails()
-				.get("test_project"));
-
-        logAsyncController.createLogEntry("test_project", saveLogRQ, user);
-        verify(createLogHandler).createLog(requestArgumentCaptor.capture(), fileArgumentCaptor.capture(), projectDetailsArgumentCaptor.capture());
-        verify(validator).validate(requestArgumentCaptor.capture());
-
-        requestArgumentCaptor.getAllValues().forEach(rq -> assertEquals(saveLogRQ, rq));
-        assertEquals(null, fileArgumentCaptor.getValue());
-        assertEquals(user.getProjectDetails().get("test_project"), projectDetailsArgumentCaptor.getValue());
-    }
-
-    @Test
-    void createLogs() {
-        ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
-
-        SaveLogRQ saveLogRQ = new SaveLogRQ();
-        SaveLogRQ[] saveLogRQs = {saveLogRQ, saveLogRQ};
-
-        ArgumentCaptor<SaveLogRQ> requestArgumentCaptor = ArgumentCaptor.forClass(SaveLogRQ.class);
-        ArgumentCaptor<MultipartFile> fileArgumentCaptor = ArgumentCaptor.forClass(MultipartFile.class);
-        ArgumentCaptor<ReportPortalUser.ProjectDetails> projectDetailsArgumentCaptor = ArgumentCaptor.forClass(ReportPortalUser.ProjectDetails.class);
-
-		when(projectExtractor.extractProjectDetails(any(ReportPortalUser.class), anyString())).thenReturn(user.getProjectDetails()
-				.get("test_project"));
-
-        logAsyncController.createLog("test_project", saveLogRQs, httpServletRequest, user);
-        verify(validator, times(4)).validate(requestArgumentCaptor.capture());
-        verify(createLogHandler, times(2)).createLog(requestArgumentCaptor.capture(), fileArgumentCaptor.capture(), projectDetailsArgumentCaptor.capture());
-
-        assertEquals(6,requestArgumentCaptor.getAllValues().size());
-        assertEquals(2,fileArgumentCaptor.getAllValues().size());
-        assertEquals(2, projectDetailsArgumentCaptor.getAllValues().size());
-
-        requestArgumentCaptor.getAllValues().forEach(arg -> assertEquals(saveLogRQ, arg));
-        fileArgumentCaptor.getAllValues().forEach(arg -> assertEquals(null, arg));
-        projectDetailsArgumentCaptor.getAllValues().forEach(arg -> assertEquals(user.getProjectDetails().get("test_project"), arg));
-    }
+  @Mock
+  ProjectExtractor projectExtractor;
+
+  @Mock
+  CreateLogHandler createLogHandler;
+
+  @Mock
+  Validator validator;
+
+  @InjectMocks
+  LogAsyncController logAsyncController;
+
+  @Mock
+  HttpServletRequest httpServletRequest;
+
+  @Test
+  void createLog() {
+    ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER,
+        1L);
+
+    SaveLogRQ saveLogRQ = new SaveLogRQ();
+
+    ArgumentCaptor<SaveLogRQ> requestArgumentCaptor = ArgumentCaptor.forClass(SaveLogRQ.class);
+    ArgumentCaptor<MultipartFile> fileArgumentCaptor = ArgumentCaptor.forClass(MultipartFile.class);
+    ArgumentCaptor<ReportPortalUser.ProjectDetails> projectDetailsArgumentCaptor = ArgumentCaptor.forClass(
+        ReportPortalUser.ProjectDetails.class);
+
+    when(projectExtractor.extractProjectDetails(any(ReportPortalUser.class),
+        anyString())).thenReturn(user.getProjectDetails()
+        .get("test_project"));
+
+    logAsyncController.createLog("test_project", saveLogRQ, user);
+    verify(createLogHandler).createLog(requestArgumentCaptor.capture(),
+        fileArgumentCaptor.capture(), projectDetailsArgumentCaptor.capture());
+    verify(validator).validate(requestArgumentCaptor.capture());
+
+    requestArgumentCaptor.getAllValues().forEach(rq -> assertEquals(saveLogRQ, rq));
+    assertEquals(null, fileArgumentCaptor.getValue());
+    assertEquals(user.getProjectDetails().get("test_project"),
+        projectDetailsArgumentCaptor.getValue());
+  }
+
+  @Test
+  void createLogEntry() {
+    ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER,
+        1L);
+
+    SaveLogRQ saveLogRQ = new SaveLogRQ();
+
+    ArgumentCaptor<SaveLogRQ> requestArgumentCaptor = ArgumentCaptor.forClass(SaveLogRQ.class);
+    ArgumentCaptor<MultipartFile> fileArgumentCaptor = ArgumentCaptor.forClass(MultipartFile.class);
+    ArgumentCaptor<ReportPortalUser.ProjectDetails> projectDetailsArgumentCaptor = ArgumentCaptor.forClass(
+        ReportPortalUser.ProjectDetails.class);
+
+    when(projectExtractor.extractProjectDetails(any(ReportPortalUser.class),
+        anyString())).thenReturn(user.getProjectDetails()
+        .get("test_project"));
+
+    logAsyncController.createLogEntry("test_project", saveLogRQ, user);
+    verify(createLogHandler).createLog(requestArgumentCaptor.capture(),
+        fileArgumentCaptor.capture(), projectDetailsArgumentCaptor.capture());
+    verify(validator).validate(requestArgumentCaptor.capture());
+
+    requestArgumentCaptor.getAllValues().forEach(rq -> assertEquals(saveLogRQ, rq));
+    assertEquals(null, fileArgumentCaptor.getValue());
+    assertEquals(user.getProjectDetails().get("test_project"),
+        projectDetailsArgumentCaptor.getValue());
+  }
+
+  @Test
+  void createLogs() {
+    ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER,
+        1L);
+
+    SaveLogRQ saveLogRQ = new SaveLogRQ();
+    SaveLogRQ[] saveLogRQs = {saveLogRQ, saveLogRQ};
+
+    ArgumentCaptor<SaveLogRQ> requestArgumentCaptor = ArgumentCaptor.forClass(SaveLogRQ.class);
+    ArgumentCaptor<MultipartFile> fileArgumentCaptor = ArgumentCaptor.forClass(MultipartFile.class);
+    ArgumentCaptor<ReportPortalUser.ProjectDetails> projectDetailsArgumentCaptor = ArgumentCaptor.forClass(
+        ReportPortalUser.ProjectDetails.class);
+
+    when(projectExtractor.extractProjectDetails(any(ReportPortalUser.class),
+        anyString())).thenReturn(user.getProjectDetails()
+        .get("test_project"));
+
+    logAsyncController.createLog("test_project", saveLogRQs, httpServletRequest, user);
+    verify(validator, times(4)).validate(requestArgumentCaptor.capture());
+    verify(createLogHandler, times(2)).createLog(requestArgumentCaptor.capture(),
+        fileArgumentCaptor.capture(), projectDetailsArgumentCaptor.capture());
+
+    assertEquals(6, requestArgumentCaptor.getAllValues().size());
+    assertEquals(2, fileArgumentCaptor.getAllValues().size());
+    assertEquals(2, projectDetailsArgumentCaptor.getAllValues().size());
+
+    requestArgumentCaptor.getAllValues().forEach(arg -> assertEquals(saveLogRQ, arg));
+    fileArgumentCaptor.getAllValues().forEach(arg -> assertEquals(null, arg));
+    projectDetailsArgumentCaptor.getAllValues()
+        .forEach(arg -> assertEquals(user.getProjectDetails().get("test_project"), arg));
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/controller/LogControllerTest.java b/src/test/java/com/epam/ta/reportportal/ws/controller/LogControllerTest.java
index d7f278b425..7076cf8f98 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/controller/LogControllerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/controller/LogControllerTest.java
@@ -16,97 +16,109 @@
 
 package com.epam.ta.reportportal.ws.controller;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.BaseMvcTest;
 import com.epam.ta.reportportal.ws.model.log.SaveLogRQ;
 import com.epam.ta.reportportal.ws.model.log.SearchLogRq;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.MediaType;
-import org.springframework.test.context.jdbc.Sql;
-
 import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.util.Date;
 import java.util.UUID;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.jdbc.Sql;
 
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
-@Sql({ "/db/test-item/test-item-fill.sql", "/db/log/log-fill.sql" })
+@Sql({"/db/test-item/test-item-fill.sql", "/db/log/log-fill.sql"})
 class LogControllerTest extends BaseMvcTest {
 
-	@Autowired
-	private ObjectMapper objectMapper;
+  @Autowired
+  private ObjectMapper objectMapper;
 
-	@Test
-	void createLogPositive() throws Exception {
-		SaveLogRQ rq = new SaveLogRQ();
-		rq.setLaunchUuid(UUID.randomUUID().toString());
-		rq.setItemUuid("f3960757-1a06-405e-9eb7-607c34683154");
-		rq.setLevel("ERROR");
-		rq.setMessage("log message");
-		rq.setLogTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
-		mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + "/log").with(token(oAuthHelper.getDefaultToken()))
-				.contentType(MediaType.APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(rq))).andExpect(status().isCreated());
-	}
+  @Test
+  void createLogPositive() throws Exception {
+    SaveLogRQ rq = new SaveLogRQ();
+    rq.setLaunchUuid(UUID.randomUUID().toString());
+    rq.setItemUuid("f3960757-1a06-405e-9eb7-607c34683154");
+    rq.setLevel("ERROR");
+    rq.setMessage("log message");
+    rq.setLogTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+    mockMvc.perform(
+        post(DEFAULT_PROJECT_BASE_URL + "/log").with(token(oAuthHelper.getDefaultToken()))
+            .contentType(MediaType.APPLICATION_JSON)
+            .content(objectMapper.writeValueAsBytes(rq))).andExpect(status().isCreated());
+  }
 
-	@Test
-	void searchLogsNegative() throws Exception {
-		SearchLogRq rq = new SearchLogRq();
-		rq.setSearchMode("currentLaunch");
-		rq.setFilterId(1L);
-		mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + "/log/search/1").with(token(oAuthHelper.getDefaultToken()))
-				.contentType(MediaType.APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(rq)))
-				.andExpect(result -> assertTrue(result.getResolvedException() instanceof ReportPortalException))
-				.andExpect(result -> assertEquals(
-						"Unable to perform operation for non-finished test item.",
-						result.getResolvedException().getMessage()
-				));
-		;
-	}
+  @Test
+  void searchLogsNegative() throws Exception {
+    SearchLogRq rq = new SearchLogRq();
+    rq.setSearchMode("currentLaunch");
+    rq.setFilterId(1L);
+    mockMvc.perform(
+            post(DEFAULT_PROJECT_BASE_URL + "/log/search/1").with(token(oAuthHelper.getDefaultToken()))
+                .contentType(MediaType.APPLICATION_JSON)
+                .content(objectMapper.writeValueAsBytes(rq)))
+        .andExpect(
+            result -> assertTrue(result.getResolvedException() instanceof ReportPortalException))
+        .andExpect(result -> assertEquals(
+            "Unable to perform operation for non-finished test item.",
+            result.getResolvedException().getMessage()
+        ));
+    ;
+  }
 
-	@Test
-	void deleteLogPositive() throws Exception {
-		mockMvc.perform(delete(DEFAULT_PROJECT_BASE_URL + "/log/1").with(token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
-	}
+  @Test
+  void deleteLogPositive() throws Exception {
+    mockMvc.perform(
+            delete(DEFAULT_PROJECT_BASE_URL + "/log/1").with(token(oAuthHelper.getDefaultToken())))
+        .andExpect(status().isOk());
+  }
 
-	@Test
-	void getLogsPositive() throws Exception {
-		mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/log?filter.eq.item=2").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().isOk());
-	}
+  @Test
+  void getLogsPositive() throws Exception {
+    mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/log?filter.eq.item=2").with(
+            token(oAuthHelper.getDefaultToken())))
+        .andExpect(status().isOk());
+  }
 
-	@Test
-	void getLogPositive() throws Exception {
-		mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/log/2").with(token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
-	}
+  @Test
+  void getLogPositive() throws Exception {
+    mockMvc.perform(
+            get(DEFAULT_PROJECT_BASE_URL + "/log/2").with(token(oAuthHelper.getDefaultToken())))
+        .andExpect(status().isOk());
+  }
 
-	@Test
-	void getLogStringPositive() throws Exception {
-		mockMvc.perform(get(
-				DEFAULT_PROJECT_BASE_URL + "/log/9ba98f41-2cde-4510-8503-d8eda901cc71").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().isOk());
-	}
+  @Test
+  void getLogStringPositive() throws Exception {
+    mockMvc.perform(get(
+            DEFAULT_PROJECT_BASE_URL + "/log/9ba98f41-2cde-4510-8503-d8eda901cc71").with(
+            token(oAuthHelper.getDefaultToken())))
+        .andExpect(status().isOk());
+  }
 
-	@Test
-	void getLogUuidPositive() throws Exception {
-		mockMvc.perform(get(
-				DEFAULT_PROJECT_BASE_URL + "/log/uuid/9ba98f41-2cde-4510-8503-d8eda901cc71").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().isOk());
-	}
+  @Test
+  void getLogUuidPositive() throws Exception {
+    mockMvc.perform(get(
+            DEFAULT_PROJECT_BASE_URL + "/log/uuid/9ba98f41-2cde-4510-8503-d8eda901cc71").with(
+            token(oAuthHelper.getDefaultToken())))
+        .andExpect(status().isOk());
+  }
 
-	@Test
-	void getLogNegative() throws Exception {
-		mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/log/100").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().isNotFound());
-	}
+  @Test
+  void getLogNegative() throws Exception {
+    mockMvc.perform(
+            get(DEFAULT_PROJECT_BASE_URL + "/log/100").with(token(oAuthHelper.getDefaultToken())))
+        .andExpect(status().isNotFound());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/controller/PluginControllerTest.java b/src/test/java/com/epam/ta/reportportal/ws/controller/PluginControllerTest.java
index 628e2a9cf3..1e365e529f 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/controller/PluginControllerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/controller/PluginControllerTest.java
@@ -16,20 +16,27 @@
 
 package com.epam.ta.reportportal.ws.controller;
 
-import com.epam.ta.reportportal.ws.BaseMvcTest;
-import org.junit.jupiter.api.Test;
-
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
 
+import com.epam.ta.reportportal.ws.BaseMvcTest;
+import org.junit.jupiter.api.Test;
+
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class PluginControllerTest extends BaseMvcTest {
 
-	@Test
-	void getLaunchPositive() throws Exception {
-		mockMvc.perform(get("/v1/plugin").with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isOk());
-	}
+  @Test
+  void getLaunchPositive() throws Exception {
+    mockMvc.perform(get("/v1/plugin").with(token(oAuthHelper.getSuperadminToken())))
+        .andExpect(status().isOk());
+  }
+
+  @Test
+  void shouldNotGetFileWhenNotAuthenticated() throws Exception {
+    mockMvc.perform(get("/v1/plugin/pluginName/file/image.png"))
+        .andExpect(status().isUnauthorized());
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/controller/PluginPublicControllerTest.java b/src/test/java/com/epam/ta/reportportal/ws/controller/PluginPublicControllerTest.java
new file mode 100644
index 0000000000..b2e0c1a4a9
--- /dev/null
+++ b/src/test/java/com/epam/ta/reportportal/ws/controller/PluginPublicControllerTest.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2022 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.ws.controller;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+import com.epam.ta.reportportal.entity.attachment.BinaryData;
+import com.epam.ta.reportportal.ws.BaseMvcTest;
+import java.io.ByteArrayInputStream;
+import java.util.Collections;
+import java.util.Map;
+import javax.activation.MimetypesFileTypeMap;
+import javax.servlet.http.HttpServletResponse;
+import org.hamcrest.Matchers;
+import org.junit.jupiter.api.Test;
+import org.springframework.http.MediaType;
+
+/**
+ * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
+ */
+class PluginPublicControllerTest extends BaseMvcTest {
+
+  @Test
+  void shouldGetFileWhenAuthenticated() throws Exception {
+
+    final ByteArrayInputStream inputStream = new ByteArrayInputStream(new byte[]{});
+    final String contentType = MimetypesFileTypeMap.getDefaultFileTypeMap()
+        .getContentType("image.png");
+
+    final BinaryData binaryData = new BinaryData(contentType, (long) inputStream.available(),
+        inputStream);
+    when(pluginPublicFilesProvider.load("pluginName", "image.png")).thenReturn(binaryData);
+
+    mockMvc.perform(get("/v1/plugin/public/pluginName/file/image.png").with(
+            token(oAuthHelper.getSuperadminToken())))
+        .andExpect(status().isOk());
+
+    verify(binaryDataResponseWriter, times(1)).write(eq(binaryData),
+        any(HttpServletResponse.class));
+  }
+
+  @Test
+  void shouldGetFileWhenNotAuthenticated() throws Exception {
+    final ByteArrayInputStream inputStream = new ByteArrayInputStream(new byte[]{});
+    final String contentType = MimetypesFileTypeMap.getDefaultFileTypeMap()
+        .getContentType("image.png");
+
+    final BinaryData binaryData = new BinaryData(contentType, (long) inputStream.available(),
+        inputStream);
+    when(pluginPublicFilesProvider.load("pluginName", "image.png")).thenReturn(binaryData);
+
+    mockMvc.perform(get("/v1/plugin/public/pluginName/file/image.png")).andExpect(status().isOk());
+
+    verify(binaryDataResponseWriter, times(1)).write(eq(binaryData),
+        any(HttpServletResponse.class));
+  }
+
+  @Test
+  void shouldExecutePublicCommandWhenAuthenticated() throws Exception {
+    final String plugin = "signup";
+    final String command = "testCommand";
+    final Map<String, Object> params = Collections.emptyMap();
+    final String ok = "{'result': 'ok'}";
+    when(executeIntegrationHandler.executePublicCommand(plugin, command, params)).thenReturn(ok);
+
+    mockMvc.perform(put("/v1/plugin/public/{plugin}/{command}", plugin, command)
+            .with(token(oAuthHelper.getSuperadminToken()))
+            .contentType(MediaType.APPLICATION_JSON)
+            .content("{}"))
+        .andExpect(status().isOk())
+        .andExpect(content().string(Matchers.containsString(ok)));
+
+    verify(executeIntegrationHandler).executePublicCommand(eq(plugin), eq(command), eq(params));
+  }
+
+  @Test
+  void shouldExecutePublicCommandWhenNotAuthenticated() throws Exception {
+    final String plugin = "signup";
+    final String command = "testCommand";
+    final Map<String, Object> params = Collections.emptyMap();
+    final String ok = "{'result': 'ok'}";
+    when(executeIntegrationHandler.executePublicCommand(plugin, command, params)).thenReturn(ok);
+
+    mockMvc.perform(put("/v1/plugin/public/{plugin}/{command}", plugin, command)
+            .contentType(MediaType.APPLICATION_JSON)
+            .content("{}"))
+        .andExpect(status().isOk())
+        .andExpect(content().string(Matchers.containsString(ok)));
+
+    verify(executeIntegrationHandler).executePublicCommand(eq(plugin), eq(command), eq(params));
+  }
+
+}
diff --git a/src/test/java/com/epam/ta/reportportal/ws/controller/ProjectControllerTest.java b/src/test/java/com/epam/ta/reportportal/ws/controller/ProjectControllerTest.java
index 660c301c9c..7a08a2e65a 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/controller/ProjectControllerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/controller/ProjectControllerTest.java
@@ -510,6 +510,7 @@ void updateProjectNotificationConfig() throws Exception {
 		senderCaseDTO.setRecipients(Collections.singletonList("default"));
 		senderCaseDTO.setLaunchNames(Collections.singletonList("test launch"));
 		senderCaseDTO.setEnabled(true);
+		senderCaseDTO.setRuleName("rule #1");
 		ItemAttributeResource launchAttribute = new ItemAttributeResource();
 		launchAttribute.setKey("key");
 		launchAttribute.setValue("val");
@@ -531,7 +532,7 @@ void indexProjectData() throws Exception {
 		arguments.put("analyzer_index", true);
 		arguments.put("analyzer", "test_analyzer");
 		exchangeInfo.setArguments(arguments);
-		when(rabbitClient.getExchanges(any())).thenReturn(Collections.singletonList(exchangeInfo));
+		when(rabbitClient.getExchanges(any(String.class))).thenReturn(Collections.singletonList(exchangeInfo));
 
 		mockMvc.perform(put("/v1/project/default_personal/index").with(token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
 
@@ -546,7 +547,7 @@ void deleteIndex() throws Exception {
 		arguments.put("analyzer_index", true);
 		arguments.put("analyzer", "test_analyzer");
 		exchangeInfo.setArguments(arguments);
-		when(rabbitClient.getExchanges(any())).thenReturn(Collections.singletonList(exchangeInfo));
+		when(rabbitClient.getExchanges(any(String.class))).thenReturn(Collections.singletonList(exchangeInfo));
 
 		mockMvc.perform(delete("/v1/project/default_personal/index").with(token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
 
@@ -565,4 +566,4 @@ private void verifyProjectIndexEvent() {
 		assertEquals(2L, event.getUserId().longValue());
 		assertEquals("default", event.getUserLogin());
 	}
-}
\ No newline at end of file
+}
diff --git a/src/test/java/com/epam/ta/reportportal/ws/controller/ProjectSettingsControllerTest.java b/src/test/java/com/epam/ta/reportportal/ws/controller/ProjectSettingsControllerTest.java
index 910685e81e..4ba4c88e86 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/controller/ProjectSettingsControllerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/controller/ProjectSettingsControllerTest.java
@@ -1,179 +1,292 @@
-/*
- * Copyright 2019 EPAM Systems
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.epam.ta.reportportal.ws.controller;
-
-import com.epam.ta.reportportal.dao.IssueTypeRepository;
-import com.epam.ta.reportportal.entity.item.issue.IssueType;
-import com.epam.ta.reportportal.ws.BaseMvcTest;
-import com.epam.ta.reportportal.ws.model.project.config.CreateIssueSubTypeRQ;
-import com.epam.ta.reportportal.ws.model.project.config.ProjectSettingsResource;
-import com.epam.ta.reportportal.ws.model.project.config.UpdateIssueSubTypeRQ;
-import com.epam.ta.reportportal.ws.model.project.config.UpdateOneIssueSubTypeRQ;
-import com.epam.ta.reportportal.ws.model.project.config.pattern.CreatePatternTemplateRQ;
-import com.epam.ta.reportportal.ws.model.project.config.pattern.UpdatePatternTemplateRQ;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.test.context.jdbc.Sql;
-import org.springframework.test.web.servlet.MvcResult;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Optional;
-import java.util.stream.Collectors;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.springframework.http.MediaType.APPLICATION_JSON;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
-/**
- * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
- */
-@Sql("/db/project-settings/project-settings-fill.sql")
-class ProjectSettingsControllerTest extends BaseMvcTest {
-
-	@Autowired
-	private ObjectMapper objectMapper;
-
-	@Autowired
-	private IssueTypeRepository issueTypeRepository;
-
-	@Test
-	void createSubType() throws Exception {
-		CreateIssueSubTypeRQ rq = new CreateIssueSubTypeRQ();
-		rq.setTypeRef("PRODUCT_BUG");
-		rq.setColor("#eeeeee");
-		rq.setLongName("LongName");
-		rq.setShortName("name");
-		mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + "/settings/sub-type").contentType(APPLICATION_JSON)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(rq))).andExpect(status().isCreated());
-	}
-
-	@Test
-	void getProjectSettings() throws Exception {
-		final MvcResult mvcResult = mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/settings").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().isOk())
-				.andReturn();
-		final ProjectSettingsResource projectSettingsResource = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
-				ProjectSettingsResource.class
-		);
-		assertEquals(8,
-				projectSettingsResource.getSubTypes().values().stream().flatMap(Collection::stream).collect(Collectors.toList()).size()
-		);
-	}
-
-	@Test
-	void deleteSubType() throws Exception {
-		mockMvc.perform(delete(DEFAULT_PROJECT_BASE_URL + "/settings/sub-type/6").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().isOk());
-
-		Optional<IssueType> byId = issueTypeRepository.findById(6L);
-		assertFalse(byId.isPresent());
-
-	}
-
-	@Test
-	void updateSubType() throws Exception {
-		UpdateIssueSubTypeRQ request = new UpdateIssueSubTypeRQ();
-		final UpdateOneIssueSubTypeRQ updateOneIssueSubTypeRQ = new UpdateOneIssueSubTypeRQ();
-		updateOneIssueSubTypeRQ.setColor("#000000");
-		updateOneIssueSubTypeRQ.setLocator("custom_ti");
-		updateOneIssueSubTypeRQ.setLongName("updated");
-		updateOneIssueSubTypeRQ.setShortName("upd");
-		updateOneIssueSubTypeRQ.setTypeRef("TO_INVESTIGATE");
-		request.setIds(Collections.singletonList(updateOneIssueSubTypeRQ));
-		mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/settings/sub-type").with(token(oAuthHelper.getDefaultToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
-	}
-
-	@Test
-	void createPatternTemplate() throws Exception {
-		CreatePatternTemplateRQ createPatternTemplateRQ = new CreatePatternTemplateRQ();
-		createPatternTemplateRQ.setEnabled(true);
-		createPatternTemplateRQ.setName("another_name");
-		createPatternTemplateRQ.setType("string");
-		createPatternTemplateRQ.setValue("qwe");
-		mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + "/settings/pattern").with(token(oAuthHelper.getDefaultToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(createPatternTemplateRQ))).andExpect(status().isCreated());
-	}
-
-	@Test
-	void createPatternTemplateWithWrongType() throws Exception {
-		CreatePatternTemplateRQ createPatternTemplateRQ = new CreatePatternTemplateRQ();
-		createPatternTemplateRQ.setEnabled(true);
-		createPatternTemplateRQ.setName("name");
-		createPatternTemplateRQ.setType("dd");
-		createPatternTemplateRQ.setValue("qwe");
-		mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + "/settings/pattern").with(token(oAuthHelper.getDefaultToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(createPatternTemplateRQ))).andExpect(status().isBadRequest());
-	}
-
-	@Test
-	void createPatternTemplateWithDuplicateName() throws Exception {
-		CreatePatternTemplateRQ createPatternTemplateRQ = new CreatePatternTemplateRQ();
-		createPatternTemplateRQ.setEnabled(true);
-		createPatternTemplateRQ.setName("some_name");
-		createPatternTemplateRQ.setType("string");
-		createPatternTemplateRQ.setValue("qwe");
-
-		mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + "/settings/pattern").with(token(oAuthHelper.getDefaultToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(createPatternTemplateRQ))).andExpect(status().isConflict());
-	}
-
-	@Test
-	void updatePatternTemplate() throws Exception {
-
-		UpdatePatternTemplateRQ updatePatternTemplateRQ = new UpdatePatternTemplateRQ();
-		updatePatternTemplateRQ.setName("another_name");
-		updatePatternTemplateRQ.setEnabled(true);
-
-		mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/settings/pattern/1").with(token(oAuthHelper.getDefaultToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(updatePatternTemplateRQ))).andExpect(status().isOk());
-	}
-
-	@Test
-	void updatePatternTemplateWithTheSameName() throws Exception {
-
-		UpdatePatternTemplateRQ updatePatternTemplateRQ = new UpdatePatternTemplateRQ();
-		updatePatternTemplateRQ.setName("some_name");
-		updatePatternTemplateRQ.setEnabled(true);
-
-		mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/settings/pattern/1").with(token(oAuthHelper.getDefaultToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(updatePatternTemplateRQ))).andExpect(status().isOk());
-	}
-
-	@Test
-	void updatePatternTemplateWithDuplicateName() throws Exception {
-
-		UpdatePatternTemplateRQ updatePatternTemplateRQ = new UpdatePatternTemplateRQ();
-		updatePatternTemplateRQ.setName("some_name");
-		updatePatternTemplateRQ.setEnabled(true);
-
-		mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/settings/pattern/2").with(token(oAuthHelper.getDefaultToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(updatePatternTemplateRQ))).andExpect(status().isConflict());
-	}
+/*
+ * Copyright 2019 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.epam.ta.reportportal.ws.controller;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.springframework.http.MediaType.APPLICATION_JSON;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+import com.epam.ta.reportportal.dao.IssueTypeRepository;
+import com.epam.ta.reportportal.dao.SenderCaseRepository;
+import com.epam.ta.reportportal.entity.enums.LogicalOperator;
+import com.epam.ta.reportportal.entity.enums.SendCase;
+import com.epam.ta.reportportal.entity.item.issue.IssueType;
+import com.epam.ta.reportportal.entity.project.email.SenderCase;
+import com.epam.ta.reportportal.ws.BaseMvcTest;
+import com.epam.ta.reportportal.ws.model.project.config.CreateIssueSubTypeRQ;
+import com.epam.ta.reportportal.ws.model.project.config.ProjectSettingsResource;
+import com.epam.ta.reportportal.ws.model.project.config.UpdateIssueSubTypeRQ;
+import com.epam.ta.reportportal.ws.model.project.config.UpdateOneIssueSubTypeRQ;
+import com.epam.ta.reportportal.ws.model.project.config.pattern.CreatePatternTemplateRQ;
+import com.epam.ta.reportportal.ws.model.project.config.pattern.UpdatePatternTemplateRQ;
+import com.epam.ta.reportportal.ws.model.project.email.SenderCaseDTO;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.jdbc.Sql;
+import org.springframework.test.web.servlet.MvcResult;
+
+/**
+ * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
+ */
+@Sql("/db/project-settings/project-settings-fill.sql")
+class ProjectSettingsControllerTest extends BaseMvcTest {
+
+  @Autowired
+  private ObjectMapper objectMapper;
+
+  @Autowired
+  private IssueTypeRepository issueTypeRepository;
+
+  @Autowired
+  private SenderCaseRepository senderCaseRepository;
+
+  private static final String NOTIFICATION_URL = "/settings/notification/";
+
+  @Test
+  void createSubType() throws Exception {
+    CreateIssueSubTypeRQ rq = new CreateIssueSubTypeRQ();
+    rq.setTypeRef("PRODUCT_BUG");
+    rq.setColor("#eeeeee");
+    rq.setLongName("LongName");
+    rq.setShortName("name");
+    mockMvc.perform(
+        post(DEFAULT_PROJECT_BASE_URL + "/settings/sub-type").contentType(APPLICATION_JSON)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(rq))).andExpect(status().isCreated());
+  }
+
+  @Test
+  void getProjectSettings() throws Exception {
+    final MvcResult mvcResult = mockMvc.perform(
+            get(DEFAULT_PROJECT_BASE_URL + "/settings").with(token(oAuthHelper.getDefaultToken())))
+        .andExpect(status().isOk())
+        .andReturn();
+    final ProjectSettingsResource projectSettingsResource = objectMapper.readValue(
+        mvcResult.getResponse().getContentAsString(),
+        ProjectSettingsResource.class
+    );
+    assertEquals(8,
+        projectSettingsResource.getSubTypes().values().stream().flatMap(Collection::stream)
+            .collect(Collectors.toList()).size()
+    );
+  }
+
+  @Test
+  void deleteSubType() throws Exception {
+    mockMvc.perform(delete(DEFAULT_PROJECT_BASE_URL + "/settings/sub-type/6").with(
+            token(oAuthHelper.getDefaultToken())))
+        .andExpect(status().isOk());
+
+    Optional<IssueType> byId = issueTypeRepository.findById(6L);
+    assertFalse(byId.isPresent());
+
+  }
+
+  @Test
+  void updateSubType() throws Exception {
+    UpdateIssueSubTypeRQ request = new UpdateIssueSubTypeRQ();
+    final UpdateOneIssueSubTypeRQ updateOneIssueSubTypeRQ = new UpdateOneIssueSubTypeRQ();
+    updateOneIssueSubTypeRQ.setColor("#000000");
+    updateOneIssueSubTypeRQ.setLocator("custom_ti");
+    updateOneIssueSubTypeRQ.setLongName("updated");
+    updateOneIssueSubTypeRQ.setShortName("upd");
+    updateOneIssueSubTypeRQ.setTypeRef("TO_INVESTIGATE");
+    request.setIds(Collections.singletonList(updateOneIssueSubTypeRQ));
+    mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/settings/sub-type").with(
+            token(oAuthHelper.getDefaultToken()))
+        .contentType(APPLICATION_JSON)
+        .content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
+  }
+
+  @Test
+  void createPatternTemplate() throws Exception {
+    CreatePatternTemplateRQ createPatternTemplateRQ = new CreatePatternTemplateRQ();
+    createPatternTemplateRQ.setEnabled(true);
+    createPatternTemplateRQ.setName("another_name");
+    createPatternTemplateRQ.setType("string");
+    createPatternTemplateRQ.setValue("qwe");
+    mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + "/settings/pattern").with(
+                token(oAuthHelper.getDefaultToken()))
+            .contentType(APPLICATION_JSON)
+            .content(objectMapper.writeValueAsBytes(createPatternTemplateRQ)))
+        .andExpect(status().isCreated());
+  }
+
+  @Test
+  void createPatternTemplateWithWrongType() throws Exception {
+    CreatePatternTemplateRQ createPatternTemplateRQ = new CreatePatternTemplateRQ();
+    createPatternTemplateRQ.setEnabled(true);
+    createPatternTemplateRQ.setName("name");
+    createPatternTemplateRQ.setType("dd");
+    createPatternTemplateRQ.setValue("qwe");
+    mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + "/settings/pattern").with(
+                token(oAuthHelper.getDefaultToken()))
+            .contentType(APPLICATION_JSON)
+            .content(objectMapper.writeValueAsBytes(createPatternTemplateRQ)))
+        .andExpect(status().isBadRequest());
+  }
+
+  @Test
+  void createPatternTemplateWithDuplicateName() throws Exception {
+    CreatePatternTemplateRQ createPatternTemplateRQ = new CreatePatternTemplateRQ();
+    createPatternTemplateRQ.setEnabled(true);
+    createPatternTemplateRQ.setName("some_name");
+    createPatternTemplateRQ.setType("string");
+    createPatternTemplateRQ.setValue("qwe");
+
+    mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + "/settings/pattern").with(
+                token(oAuthHelper.getDefaultToken()))
+            .contentType(APPLICATION_JSON)
+            .content(objectMapper.writeValueAsBytes(createPatternTemplateRQ)))
+        .andExpect(status().isConflict());
+  }
+
+  @Test
+  void updatePatternTemplate() throws Exception {
+
+    UpdatePatternTemplateRQ updatePatternTemplateRQ = new UpdatePatternTemplateRQ();
+    updatePatternTemplateRQ.setName("another_name");
+    updatePatternTemplateRQ.setEnabled(true);
+
+    mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/settings/pattern/1").with(
+                token(oAuthHelper.getDefaultToken()))
+            .contentType(APPLICATION_JSON)
+            .content(objectMapper.writeValueAsBytes(updatePatternTemplateRQ)))
+        .andExpect(status().isOk());
+  }
+
+  @Test
+  void updatePatternTemplateWithTheSameName() throws Exception {
+
+    UpdatePatternTemplateRQ updatePatternTemplateRQ = new UpdatePatternTemplateRQ();
+    updatePatternTemplateRQ.setName("some_name");
+    updatePatternTemplateRQ.setEnabled(true);
+
+    mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/settings/pattern/1").with(
+                token(oAuthHelper.getDefaultToken()))
+            .contentType(APPLICATION_JSON)
+            .content(objectMapper.writeValueAsBytes(updatePatternTemplateRQ)))
+        .andExpect(status().isOk());
+  }
+
+  @Test
+  void updatePatternTemplateWithDuplicateName() throws Exception {
+
+    UpdatePatternTemplateRQ updatePatternTemplateRQ = new UpdatePatternTemplateRQ();
+    updatePatternTemplateRQ.setName("some_name");
+    updatePatternTemplateRQ.setEnabled(true);
+
+    mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/settings/pattern/2").with(
+                token(oAuthHelper.getDefaultToken()))
+            .contentType(APPLICATION_JSON)
+            .content(objectMapper.writeValueAsBytes(updatePatternTemplateRQ)))
+        .andExpect(status().isConflict());
+  }
+
+  @Test
+  void getNotifications() throws Exception {
+    final MvcResult mvcResult = mockMvc.perform(get(
+            DEFAULT_PROJECT_BASE_URL + NOTIFICATION_URL).with(token(oAuthHelper.getDefaultToken())))
+        .andExpect(status().isOk())
+        .andReturn();
+    final List<SenderCaseDTO> senderCaseDTOS = objectMapper.readValue(
+        mvcResult.getResponse().getContentAsString(),
+        new TypeReference<>() {
+        }
+    );
+    assertEquals(4, senderCaseDTOS.size());
+  }
+
+  @Test
+  void createNotification() throws Exception {
+
+    SenderCaseDTO senderCaseDTO = new SenderCaseDTO();
+    senderCaseDTO.setId(5L);
+    senderCaseDTO.setSendCase(SendCase.MORE_20.getCaseString());
+    senderCaseDTO.setEnabled(true);
+    senderCaseDTO.setRuleName("rule #5");
+    senderCaseDTO.setRecipients(List.of("test1@email.com", "test2@email.com"));
+    senderCaseDTO.setAttributesOperator(LogicalOperator.AND.getOperator());
+
+    mockMvc.perform(
+            post(DEFAULT_PROJECT_BASE_URL + NOTIFICATION_URL).with(token(oAuthHelper.getDefaultToken()))
+                .contentType(APPLICATION_JSON)
+                .content(objectMapper.writeValueAsBytes(senderCaseDTO)))
+        .andExpect(status().isCreated());
+  }
+
+  @Test
+  void createNotificationWithDuplicateRuleName() throws Exception {
+
+    SenderCaseDTO senderCaseDTO = new SenderCaseDTO();
+    senderCaseDTO.setId(5L);
+    senderCaseDTO.setSendCase(SendCase.MORE_20.getCaseString());
+    senderCaseDTO.setEnabled(true);
+    senderCaseDTO.setRuleName("rule #2");
+    senderCaseDTO.setRecipients(List.of("test1@email.com", "test2@email.com"));
+    senderCaseDTO.setAttributesOperator(LogicalOperator.AND.getOperator());
+
+    mockMvc.perform(
+            post(DEFAULT_PROJECT_BASE_URL + NOTIFICATION_URL).with(token(oAuthHelper.getDefaultToken()))
+                .contentType(APPLICATION_JSON)
+                .content(objectMapper.writeValueAsBytes(senderCaseDTO)))
+        .andExpect(status().isConflict());
+  }
+
+  @Test
+  void updateNotification() throws Exception {
+
+    SenderCaseDTO updateRq = new SenderCaseDTO();
+    updateRq.setId(1L);
+    updateRq.setRuleName("rule #5");
+    updateRq.setSendCase(SendCase.ALWAYS.getCaseString());
+    updateRq.setRecipients(List.of("test1@email.com", "test2@email.com"));
+    updateRq.setLaunchNames(List.of("launch"));
+    updateRq.setAttributesOperator(LogicalOperator.AND.getOperator());
+
+    mockMvc.perform(
+        put(DEFAULT_PROJECT_BASE_URL + NOTIFICATION_URL).with(token(oAuthHelper.getDefaultToken()))
+            .contentType(APPLICATION_JSON)
+            .content(objectMapper.writeValueAsBytes(updateRq))).andExpect(status().isCreated());
+  }
+
+  @Test
+  void deleteNotification() throws Exception {
+    Long id = 1L;
+
+    mockMvc.perform(delete(DEFAULT_PROJECT_BASE_URL + NOTIFICATION_URL + id).with(
+            token(oAuthHelper.getDefaultToken())))
+        .andExpect(status().isOk());
+
+    List<SenderCase> senderCases = senderCaseRepository.findAll();
+
+    assertFalse(senderCases.stream().anyMatch(s -> s.getId().equals(id)));
+  }
+
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/controller/SettingsControllerTest.java b/src/test/java/com/epam/ta/reportportal/ws/controller/SettingsControllerTest.java
index c6a8cc09c9..f674aa8b31 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/controller/SettingsControllerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/controller/SettingsControllerTest.java
@@ -16,6 +16,11 @@
 
 package com.epam.ta.reportportal.ws.controller;
 
+import static org.springframework.http.MediaType.APPLICATION_JSON;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
 import com.epam.ta.reportportal.ws.BaseMvcTest;
 import com.epam.ta.reportportal.ws.model.settings.AnalyticsResource;
 import com.fasterxml.jackson.databind.ObjectMapper;
@@ -23,41 +28,37 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.MediaType;
 
-import static org.springframework.http.MediaType.APPLICATION_JSON;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 class SettingsControllerTest extends BaseMvcTest {
 
-	@Autowired
-	private ObjectMapper objectMapper;
-
-	@Test
-	void getServerSettings() throws Exception {
-		mockMvc.perform(get("/v1/settings").with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isOk());
-	}
-
-	@Test
-	void updateAnalyticsSettings() throws Exception {
-		AnalyticsResource resource = new AnalyticsResource();
-		resource.setType("server.analytics.all");
-		resource.setEnabled(true);
-		mockMvc.perform(put("/v1/settings/analytics").with(token(oAuthHelper.getSuperadminToken()))
-				.contentType(MediaType.APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(resource))).andExpect(status().isOk());
-	}
-
-	@Test
-	void saveAnalyticsSettingsNegative() throws Exception {
-		AnalyticsResource resource = new AnalyticsResource();
-		resource.setEnabled(true);
-		resource.setType("");
-		mockMvc.perform(put("/v1/settings/analytics").with(token(oAuthHelper.getSuperadminToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(resource))).andExpect(status().isBadRequest());
-	}
+  @Autowired
+  private ObjectMapper objectMapper;
+
+  @Test
+  void getServerSettings() throws Exception {
+    mockMvc.perform(get("/v1/settings").with(token(oAuthHelper.getSuperadminToken())))
+        .andExpect(status().isOk());
+  }
+
+  @Test
+  void updateAnalyticsSettings() throws Exception {
+    AnalyticsResource resource = new AnalyticsResource();
+    resource.setType("server.analytics.all");
+    resource.setEnabled(true);
+    mockMvc.perform(put("/v1/settings/analytics").with(token(oAuthHelper.getSuperadminToken()))
+        .contentType(MediaType.APPLICATION_JSON)
+        .content(objectMapper.writeValueAsBytes(resource))).andExpect(status().isOk());
+  }
+
+  @Test
+  void saveAnalyticsSettingsNegative() throws Exception {
+    AnalyticsResource resource = new AnalyticsResource();
+    resource.setEnabled(true);
+    resource.setType("");
+    mockMvc.perform(put("/v1/settings/analytics").with(token(oAuthHelper.getSuperadminToken()))
+        .contentType(APPLICATION_JSON)
+        .content(objectMapper.writeValueAsBytes(resource))).andExpect(status().isBadRequest());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/controller/TestItemAsyncControllerTest.java b/src/test/java/com/epam/ta/reportportal/ws/controller/TestItemAsyncControllerTest.java
index e9d9d7e990..d0618eabc4 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/controller/TestItemAsyncControllerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/controller/TestItemAsyncControllerTest.java
@@ -16,6 +16,13 @@
 
 package com.epam.ta.reportportal.ws.controller;
 
+import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.ReportPortalUser;
 import com.epam.ta.reportportal.core.item.FinishTestItemHandler;
 import com.epam.ta.reportportal.core.item.StartTestItemHandler;
@@ -24,6 +31,7 @@
 import com.epam.ta.reportportal.util.ProjectExtractor;
 import com.epam.ta.reportportal.ws.model.FinishTestItemRQ;
 import com.epam.ta.reportportal.ws.model.StartTestItemRQ;
+import java.util.UUID;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.ArgumentCaptor;
@@ -31,106 +39,115 @@
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 
-import java.util.UUID;
-
-import static com.epam.ta.reportportal.ReportPortalUserUtil.getRpUser;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
 /**
  * @author Konstantin Antipin
  */
 @ExtendWith(MockitoExtension.class)
 class TestItemAsyncControllerTest {
 
-	@Mock
-	ProjectExtractor projectExtractor;
-
-	@Mock
-	StartTestItemHandler startTestItemHandler;
-
-	@Mock
-	FinishTestItemHandler finishTestItemHandler;
-
-	@InjectMocks
-	TestItemAsyncController testItemAsyncController;
-
-	@Test
-	void startRootItem() {
-		ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
-
-		StartTestItemRQ startTestItemRQ = new StartTestItemRQ();
-
-		ArgumentCaptor<ReportPortalUser> userArgumentCaptor = ArgumentCaptor.forClass(ReportPortalUser.class);
-		ArgumentCaptor<ReportPortalUser.ProjectDetails> projectDetailsArgumentCaptor = ArgumentCaptor.forClass(ReportPortalUser.ProjectDetails.class);
-		ArgumentCaptor<StartTestItemRQ> requestArgumentCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class);
-
-		when(projectExtractor.extractProjectDetails(any(ReportPortalUser.class), anyString())).thenReturn(user.getProjectDetails()
-				.get("test_project"));
-
-		testItemAsyncController.startRootItem("test_project", user, startTestItemRQ);
-		verify(startTestItemHandler).startRootItem(userArgumentCaptor.capture(),
-				projectDetailsArgumentCaptor.capture(),
-				requestArgumentCaptor.capture()
-		);
-		assertEquals(user, userArgumentCaptor.getValue());
-		assertEquals(user.getProjectDetails().get("test_project"), projectDetailsArgumentCaptor.getValue());
-		assertEquals(startTestItemRQ, requestArgumentCaptor.getValue());
-	}
-
-	@Test
-	void startChildItem() {
-		ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
-
-		StartTestItemRQ startTestItemRQ = new StartTestItemRQ();
-		String parentItem = "parent";
-
-		ArgumentCaptor<ReportPortalUser> userArgumentCaptor = ArgumentCaptor.forClass(ReportPortalUser.class);
-		ArgumentCaptor<ReportPortalUser.ProjectDetails> projectDetailsArgumentCaptor = ArgumentCaptor.forClass(ReportPortalUser.ProjectDetails.class);
-		ArgumentCaptor<StartTestItemRQ> requestArgumentCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class);
-		ArgumentCaptor<String> parentArgumentCaptor = ArgumentCaptor.forClass(String.class);
-
-		when(projectExtractor.extractProjectDetails(any(ReportPortalUser.class), anyString())).thenReturn(user.getProjectDetails()
-				.get("test_project"));
-
-		testItemAsyncController.startChildItem("test_project", user, parentItem, startTestItemRQ);
-		verify(startTestItemHandler).startChildItem(userArgumentCaptor.capture(),
-				projectDetailsArgumentCaptor.capture(),
-				requestArgumentCaptor.capture(),
-				parentArgumentCaptor.capture()
-		);
-		assertEquals(user, userArgumentCaptor.getValue());
-		assertEquals(user.getProjectDetails().get("test_project"), projectDetailsArgumentCaptor.getValue());
-		assertEquals(startTestItemRQ, requestArgumentCaptor.getValue());
-	}
-
-	@Test
-	void finishTestItem() {
-		ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER, 1L);
-
-		FinishTestItemRQ finishTestItemRQ = new FinishTestItemRQ();
-		String testItemId = UUID.randomUUID().toString();
-		finishTestItemRQ.setLaunchUuid(UUID.randomUUID().toString());
-
-		ArgumentCaptor<ReportPortalUser> userArgumentCaptor = ArgumentCaptor.forClass(ReportPortalUser.class);
-		ArgumentCaptor<ReportPortalUser.ProjectDetails> projectDetailsArgumentCaptor = ArgumentCaptor.forClass(ReportPortalUser.ProjectDetails.class);
-		ArgumentCaptor<String> testItemCaptor = ArgumentCaptor.forClass(String.class);
-		ArgumentCaptor<FinishTestItemRQ> requestArgumentCaptor = ArgumentCaptor.forClass(FinishTestItemRQ.class);
-
-		when(projectExtractor.extractProjectDetails(any(ReportPortalUser.class), anyString())).thenReturn(user.getProjectDetails()
-				.get("test_project"));
-
-		testItemAsyncController.finishTestItem("test_project", user, testItemId, finishTestItemRQ);
-		verify(finishTestItemHandler).finishTestItem(userArgumentCaptor.capture(),
-				projectDetailsArgumentCaptor.capture(),
-				testItemCaptor.capture(),
-				requestArgumentCaptor.capture()
-		);
-		assertEquals(user, userArgumentCaptor.getValue());
-		assertEquals(user.getProjectDetails().get("test_project"), projectDetailsArgumentCaptor.getValue());
-		assertEquals(finishTestItemRQ, requestArgumentCaptor.getValue());
-	}
+  @Mock
+  ProjectExtractor projectExtractor;
+
+  @Mock
+  StartTestItemHandler startTestItemHandler;
+
+  @Mock
+  FinishTestItemHandler finishTestItemHandler;
+
+  @InjectMocks
+  TestItemAsyncController testItemAsyncController;
+
+  @Test
+  void startRootItem() {
+    ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER,
+        1L);
+
+    StartTestItemRQ startTestItemRQ = new StartTestItemRQ();
+
+    ArgumentCaptor<ReportPortalUser> userArgumentCaptor = ArgumentCaptor.forClass(
+        ReportPortalUser.class);
+    ArgumentCaptor<ReportPortalUser.ProjectDetails> projectDetailsArgumentCaptor = ArgumentCaptor.forClass(
+        ReportPortalUser.ProjectDetails.class);
+    ArgumentCaptor<StartTestItemRQ> requestArgumentCaptor = ArgumentCaptor.forClass(
+        StartTestItemRQ.class);
+
+    when(projectExtractor.extractProjectDetails(any(ReportPortalUser.class),
+        anyString())).thenReturn(user.getProjectDetails()
+        .get("test_project"));
+
+    testItemAsyncController.startRootItem("test_project", user, startTestItemRQ);
+    verify(startTestItemHandler).startRootItem(userArgumentCaptor.capture(),
+        projectDetailsArgumentCaptor.capture(),
+        requestArgumentCaptor.capture()
+    );
+    assertEquals(user, userArgumentCaptor.getValue());
+    assertEquals(user.getProjectDetails().get("test_project"),
+        projectDetailsArgumentCaptor.getValue());
+    assertEquals(startTestItemRQ, requestArgumentCaptor.getValue());
+  }
+
+  @Test
+  void startChildItem() {
+    ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER,
+        1L);
+
+    StartTestItemRQ startTestItemRQ = new StartTestItemRQ();
+    String parentItem = "parent";
+
+    ArgumentCaptor<ReportPortalUser> userArgumentCaptor = ArgumentCaptor.forClass(
+        ReportPortalUser.class);
+    ArgumentCaptor<ReportPortalUser.ProjectDetails> projectDetailsArgumentCaptor = ArgumentCaptor.forClass(
+        ReportPortalUser.ProjectDetails.class);
+    ArgumentCaptor<StartTestItemRQ> requestArgumentCaptor = ArgumentCaptor.forClass(
+        StartTestItemRQ.class);
+    ArgumentCaptor<String> parentArgumentCaptor = ArgumentCaptor.forClass(String.class);
+
+    when(projectExtractor.extractProjectDetails(any(ReportPortalUser.class),
+        anyString())).thenReturn(user.getProjectDetails()
+        .get("test_project"));
+
+    testItemAsyncController.startChildItem("test_project", user, parentItem, startTestItemRQ);
+    verify(startTestItemHandler).startChildItem(userArgumentCaptor.capture(),
+        projectDetailsArgumentCaptor.capture(),
+        requestArgumentCaptor.capture(),
+        parentArgumentCaptor.capture()
+    );
+    assertEquals(user, userArgumentCaptor.getValue());
+    assertEquals(user.getProjectDetails().get("test_project"),
+        projectDetailsArgumentCaptor.getValue());
+    assertEquals(startTestItemRQ, requestArgumentCaptor.getValue());
+  }
+
+  @Test
+  void finishTestItem() {
+    ReportPortalUser user = getRpUser("test", UserRole.ADMINISTRATOR, ProjectRole.PROJECT_MANAGER,
+        1L);
+
+    FinishTestItemRQ finishTestItemRQ = new FinishTestItemRQ();
+    String testItemId = UUID.randomUUID().toString();
+    finishTestItemRQ.setLaunchUuid(UUID.randomUUID().toString());
+
+    ArgumentCaptor<ReportPortalUser> userArgumentCaptor = ArgumentCaptor.forClass(
+        ReportPortalUser.class);
+    ArgumentCaptor<ReportPortalUser.ProjectDetails> projectDetailsArgumentCaptor = ArgumentCaptor.forClass(
+        ReportPortalUser.ProjectDetails.class);
+    ArgumentCaptor<String> testItemCaptor = ArgumentCaptor.forClass(String.class);
+    ArgumentCaptor<FinishTestItemRQ> requestArgumentCaptor = ArgumentCaptor.forClass(
+        FinishTestItemRQ.class);
+
+    when(projectExtractor.extractProjectDetails(any(ReportPortalUser.class),
+        anyString())).thenReturn(user.getProjectDetails()
+        .get("test_project"));
+
+    testItemAsyncController.finishTestItem("test_project", user, testItemId, finishTestItemRQ);
+    verify(finishTestItemHandler).finishTestItem(userArgumentCaptor.capture(),
+        projectDetailsArgumentCaptor.capture(),
+        testItemCaptor.capture(),
+        requestArgumentCaptor.capture()
+    );
+    assertEquals(user, userArgumentCaptor.getValue());
+    assertEquals(user.getProjectDetails().get("test_project"),
+        projectDetailsArgumentCaptor.getValue());
+    assertEquals(finishTestItemRQ, requestArgumentCaptor.getValue());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/controller/TestItemControllerTest.java b/src/test/java/com/epam/ta/reportportal/ws/controller/TestItemControllerTest.java
index 56d96cb788..98a4098ce4 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/controller/TestItemControllerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/controller/TestItemControllerTest.java
@@ -16,6 +16,20 @@
 
 package com.epam.ta.reportportal.ws.controller;
 
+import static org.hamcrest.Matchers.hasSize;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.springframework.http.MediaType.APPLICATION_JSON;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
 import com.epam.ta.reportportal.core.analyzer.auto.client.model.SuggestInfo;
 import com.epam.ta.reportportal.dao.LaunchRepository;
 import com.epam.ta.reportportal.dao.TestItemRepository;
@@ -41,939 +55,1008 @@
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
 import org.junit.jupiter.api.Test;
 import org.mockito.ArgumentMatchers;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.test.context.jdbc.Sql;
 
-import java.time.LocalDateTime;
-import java.time.ZoneId;
-import java.util.*;
-
-import static org.hamcrest.Matchers.hasSize;
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.springframework.http.MediaType.APPLICATION_JSON;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @Sql("/db/test-item/test-item-fill.sql")
 class TestItemControllerTest extends BaseMvcTest {
 
-	@Autowired
-	private ObjectMapper objectMapper;
-
-	@Autowired
-	private TestItemRepository testItemRepository;
-
-	@Autowired
-	private LaunchRepository launchRepository;
-
-	@Test
-	void startRootItemPositive() throws Exception {
-		StartTestItemRQ rq = new StartTestItemRQ();
-		rq.setLaunchUuid("a7b66ef2-db30-4db7-94df-f5f7786b398a");
-		rq.setName("RootItem");
-		rq.setType("SUITE");
-		rq.setParameters(getParameters());
-		rq.setUniqueId(UUID.randomUUID().toString());
-		rq.setStartTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
-		mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + "/item").contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(rq))
-				.with(token(oAuthHelper.getDefaultToken()))).andExpect(status().isCreated());
-	}
-
-	@Test
-	void startRootItemWithoutUuid() throws Exception {
-		StartTestItemRQ rq = new StartTestItemRQ();
-		rq.setLaunchUuid("a7b66ef2-db30-4db7-94df-f5f7786b398a");
-		rq.setName("RootItem");
-		rq.setType("SUITE");
-		rq.setParameters(getParameters());
-		rq.setStartTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
-		mockMvc.perform(post(SUPERADMIN_PROJECT_BASE_URL + "/item").contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(rq))
-				.with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isCreated());
-	}
-
-	@Test
-	void startChildItemPositive() throws Exception {
-		StartTestItemRQ rq = new StartTestItemRQ();
-		rq.setLaunchUuid("a7b66ef2-db30-4db7-94df-f5f7786b398a");
-		rq.setName("ChildItem");
-		rq.setType("TEST");
-		rq.setUniqueId(UUID.randomUUID().toString());
-		rq.setParameters(getParameters());
-		rq.setStartTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
-		mockMvc.perform(post(
-				DEFAULT_PROJECT_BASE_URL + "/item/0f7ca5bc-cfae-4cc1-9682-e59c2860131e").content(objectMapper.writeValueAsBytes(rq))
-				.contentType(APPLICATION_JSON)
-				.with(token(oAuthHelper.getDefaultToken()))).andExpect(status().isCreated());
-	}
-
-	@Test
-	void startChildItemWithoutUuid() throws Exception {
-		StartTestItemRQ rq = new StartTestItemRQ();
-		rq.setLaunchUuid("a7b66ef2-db30-4db7-94df-f5f7786b398a");
-		rq.setName("ChildItem");
-		rq.setType("TEST");
-		rq.setParameters(getParameters());
-		rq.setStartTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
-		mockMvc.perform(post(
-				DEFAULT_PROJECT_BASE_URL + "/item/0f7ca5bc-cfae-4cc1-9682-e59c2860131e").content(objectMapper.writeValueAsBytes(rq))
-				.contentType(APPLICATION_JSON)
-				.with(token(oAuthHelper.getDefaultToken()))).andExpect(status().isCreated());
-	}
-
-	@Test
-	void finishTestItemPositive() throws Exception {
-		FinishTestItemRQ rq = new FinishTestItemRQ();
-		rq.setLaunchUuid(UUID.randomUUID().toString());
-		rq.setEndTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
-		rq.setStatus("PASSED");
-		mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/item/0f7ca5bc-cfae-4cc1-9682-e59c2860131e").content(objectMapper.writeValueAsBytes(
-				rq)).contentType(APPLICATION_JSON).with(token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
-	}
-
-	@Test
-	void finishRootTestItemWithoutStatus() throws Exception {
-		FinishTestItemRQ rq = new FinishTestItemRQ();
-		rq.setLaunchUuid(UUID.randomUUID().toString());
-		rq.setEndTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
-		mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/item/0f7ca5bc-cfae-4cc1-9682-e59c2860131e").content(objectMapper.writeValueAsBytes(
-				rq)).contentType(APPLICATION_JSON).with(token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
-	}
-
-	@Test
-	void finishTestItemWithFailedStatus() throws Exception {
-		FinishTestItemRQ rq = new FinishTestItemRQ();
-		rq.setLaunchUuid(UUID.randomUUID().toString());
-		rq.setEndTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
-		rq.setStatus("FAILED");
-		Issue issue = new Issue();
-		issue.setIssueType("pb001");
-		rq.setIssue(issue);
-		mockMvc.perform(put(
-				SUPERADMIN_PROJECT_BASE_URL + "/item/3ab067e5-537b-45ff-9605-843ab695c96a").content(objectMapper.writeValueAsBytes(rq))
-				.contentType(APPLICATION_JSON)
-				.with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isOk());
-	}
-
-	@Test
-	void finishTestItemWithoutIssueType() throws Exception {
-		FinishTestItemRQ rq = new FinishTestItemRQ();
-		rq.setLaunchUuid(UUID.randomUUID().toString());
-		rq.setEndTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
-		rq.setStatus("FAILED");
-		mockMvc.perform(put(
-				SUPERADMIN_PROJECT_BASE_URL + "/item/3ab067e5-537b-45ff-9605-843ab695c96a").content(objectMapper.writeValueAsBytes(rq))
-				.contentType(APPLICATION_JSON)
-				.with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isOk());
-	}
-
-	@Test
-	void getSuggestedItemsAnalyzerNotDeployed() throws Exception {
-		mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/item/suggest/1").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(result -> assertTrue(result.getResolvedException() instanceof ReportPortalException))
-				.andExpect(result -> assertEquals(
-						"Impossible interact with integration. There are no analyzer services with suggest items support deployed.",
-						result.getResolvedException().getMessage()
-				));
-	}
-
-	@Test
-	void getTestItemPositive() throws Exception {
-		mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/item/1").with(token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
-	}
-
-	@Test
-	void getTestItemStringPositive() throws Exception {
-		mockMvc.perform(get(
-				DEFAULT_PROJECT_BASE_URL + "/item/0f7ca5bc-cfae-4cc1-9682-e59c2860131e").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().isOk());
-	}
-
-	@Test
-	void getTestItemRetryPositive() throws Exception {
-		mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/item/7").with(token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
-	}
-
-	@Test
-	void getTestItemRetryStringPositive() throws Exception {
-		mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/item/3ab067e5-537b-45ff-9605-retry").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().isOk());
-	}
-
-	@Test
-	void getTestItemUuidPositive() throws Exception {
-		mockMvc.perform(get(
-				DEFAULT_PROJECT_BASE_URL + "/item/uuid/0f7ca5bc-cfae-4cc1-9682-e59c2860131e").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().isOk());
-	}
-
-	@Test
-	void getTestItemsPositive() throws Exception {
-		mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/item?filter.eq.launchId=1").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().isOk());
-	}
-
-	@Test
-	void getTestItemsBadProvider() throws Exception {
-		mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/item/v2?providerType=bad").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().isBadRequest());
-	}
-
-	@Test
-	void getTestItemsLaunchProvider() throws Exception {
-		mockMvc.perform(get(
-				DEFAULT_PROJECT_BASE_URL + "/item/v2?providerType=launch&launchId=1").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().isOk());
-	}
-
-	@Test
-	void getTestItemsLaunchProviderMissedParam() throws Exception {
-		mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/item/v2?providerType=launch").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().isBadRequest());
-	}
-
-	@Test
-	void getTestItemsFilterProvider() throws Exception {
-		mockMvc.perform(get(
-				DEFAULT_PROJECT_BASE_URL + "/item/v2?providerType=filter&filterId=1&launchesLimit=10").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().isOk());
-	}
-
-	@Test
-	void getTestItemsFilterProviderMissedParam() throws Exception {
-		mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/item/v2?providerType=filter").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().isBadRequest());
-	}
-
-	@Test
-	void getTestItemsWidgetProvider() throws Exception {
-		mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/item/v2?providerType=widget").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().isBadRequest());
-	}
-
-	@Test
-	void getTestItemBySpecifiedIds() throws Exception {
-		mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/item/items?ids=1,2,3").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().isOk());
-	}
-
-	@Test
-	void deleteTestItemPositive() throws Exception {
-		mockMvc.perform(delete(DEFAULT_PROJECT_BASE_URL + "/item/2").with(token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
-	}
-
-	@Test
-	void deleteTestItemBySpecifiedIds() throws Exception {
-		mockMvc.perform(delete(DEFAULT_PROJECT_BASE_URL + "/item?ids=2,3").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().isOk());
-	}
-
-	@Test
-	void getAccumulatedStatisticsByFilter() throws Exception {
-		mockMvc.perform(get(
-				DEFAULT_PROJECT_BASE_URL + "/item/statistics?providerType=launch&launchId=1").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().isOk());
-	}
-
-	@Test
-	void getItemHistoryByParentIdPositive() throws Exception {
-		mockMvc.perform(get(
-				DEFAULT_PROJECT_BASE_URL + "/item/history?filter.eq.parentId=1&historyDepth=3").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().isOk());
-	}
-
-	@Test
-	void getItemHistoryByLaunchIdPositive() throws Exception {
-		mockMvc.perform(get(SUPERADMIN_PROJECT_BASE_URL
-				+ "/item/history?filter.eq.launchId=1&historyDepth=3").with(token(oAuthHelper.getSuperadminToken())))
-				.andExpect(status().isOk());
-	}
-
-	@Test
-	void getItemHistoryByFilterIdPositive() throws Exception {
-		mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL
-				+ "/item/history?filterId=1&launchesLimit=10&historyDepth=3").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().isOk());
-	}
-
-	@Test
-	void updateTestItemPositive() throws Exception {
-		UpdateTestItemRQ rq = new UpdateTestItemRQ();
-		rq.setDescription("updated");
-		rq.setAttributes(Sets.newHashSet(new ItemAttributeResource("test", "test")));
-		mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/item/1/update").with(token(oAuthHelper.getDefaultToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(rq))).andExpect(status().isOk());
-	}
-
-	@Test
-	void handleSuggestChooseAnalyzerNotDeployed() throws Exception {
-		SuggestInfo suggestInfo = new SuggestInfo();
-		suggestInfo.setTestItem(1L);
-		mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/item/suggest/choice").with(token(oAuthHelper.getDefaultToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(Lists.newArrayList(suggestInfo))))
-				.andExpect(result -> assertTrue(result.getResolvedException() instanceof ReportPortalException))
-				.andExpect(result -> assertEquals(
-						"Impossible interact with integration. There are no analyzer services with suggest items support deployed.",
-						result.getResolvedException().getMessage()
-				));
-	}
-
-	@Test
-	void getTickets() throws Exception {
-		mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/item/ticket/ids?launch=1&term=ticket").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().isOk());
-	}
-
-	@Test
-	void getAttributeKeys() throws Exception {
-		mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL
-				+ "/item/attribute/keys?launch=1&filter.cnt.attributeKey=bro").with(token(oAuthHelper.getDefaultToken())))
-				.andExpect(status().isOk());
-	}
-
-	@Test
-	void getAttributeKeysForProject() throws Exception {
-		mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL
-				+ "/item/attribute/keys/all?filterId=1&launchesLimit=600&isLatest=false&filter.cnt.attributeKey=bro").with(token(oAuthHelper
-				.getDefaultToken()))).andExpect(status().isOk());
-	}
-
-	@Test
-	void getAttributeValues() throws Exception {
-		mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/item/attribute/values?launch=1&filter.cnt.attributeValue=lin").with(token(
-				oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
-	}
-
-	@Test
-	void getAttributeKeysByProjectId() throws Exception {
-		mockMvc.perform(get(
-				DEFAULT_PROJECT_BASE_URL + "/item/step/attribute/keys?filter.eq.name=test launch&filter.cnt.attributeKey=bro").with(token(
-				oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
-	}
-
-	@Test
-	void getAttributeValuesByKeyAndProjectId() throws Exception {
-		mockMvc.perform(get(
-				DEFAULT_PROJECT_BASE_URL + "/item/step/attribute/values?filter.eq.name=test launch&filter.cnt.attributeValue=lin").with(
-				token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
-	}
-
-	@Test
-	void defineTestItemIssue() throws Exception {
-		DefineIssueRQ rq = new DefineIssueRQ();
-		IssueDefinition issueDefinition = new IssueDefinition();
-		issueDefinition.setId(3L);
-		Issue issue = new Issue();
-		issue.setIssueType("pb001");
-		issue.setIgnoreAnalyzer(false);
-		issueDefinition.setIssue(issue);
-		rq.setIssues(Collections.singletonList(issueDefinition));
-		mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/item").with(token(oAuthHelper.getDefaultToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(rq))).andExpect(status().isOk());
-	}
-
-	@Test
-	void defineTestItemIssueNegative() throws Exception {
-		DefineIssueRQ rq = new DefineIssueRQ();
-		IssueDefinition issueDefinition = new IssueDefinition();
-		issueDefinition.setId(100L);
-		Issue issue = new Issue();
-		issue.setIssueType("pb001");
-		issue.setIgnoreAnalyzer(false);
-		issueDefinition.setIssue(issue);
-		rq.setIssues(Collections.singletonList(issueDefinition));
-		mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/item").with(token(oAuthHelper.getDefaultToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(rq))).andExpect(status().isBadRequest());
-	}
-
-	@Test
-	void finishTestItemWithLinkedTicketsBadTicketId() throws Exception {
-		FinishTestItemRQ rq = new FinishTestItemRQ();
-		rq.setLaunchUuid("334d153c-8f9c-4dff-8627-47dd003bee0f");
-		rq.setEndTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
-		rq.setStatus("FAILED");
-
-		Issue.ExternalSystemIssue ticket = new Issue.ExternalSystemIssue();
-		ticket.setBtsUrl("jira.com");
-		ticket.setBtsProject("project");
-		ticket.setUrl("https://example.com/NEWTICKET1");
-
-		Issue issue = new Issue();
-		issue.setIssueType("pb001");
-		issue.setIgnoreAnalyzer(false);
-		issue.setExternalSystemIssues(Sets.newHashSet(ticket));
-
-		rq.setIssue(issue);
-
-		mockMvc.perform(put(
-				SUPERADMIN_PROJECT_BASE_URL + "/item/3ab067e5-537b-45ff-9605-843ab695c96a").content(objectMapper.writeValueAsBytes(rq))
-				.contentType(APPLICATION_JSON)
-				.with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isBadRequest());
-	}
-
-	@Test
-	void finishTestItemWithLinkedTicketsBadBtsUrl() throws Exception {
-		FinishTestItemRQ rq = new FinishTestItemRQ();
-		rq.setLaunchUuid("334d153c-8f9c-4dff-8627-47dd003bee0f");
-		rq.setEndTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
-		rq.setStatus("FAILED");
-
-		Issue.ExternalSystemIssue ticket = new Issue.ExternalSystemIssue();
-		ticket.setBtsProject("project");
-		ticket.setTicketId("ticket1");
-		ticket.setUrl("https://example.com/NEWTICKET1");
-
-		Issue issue = new Issue();
-		issue.setIssueType("pb001");
-		issue.setIgnoreAnalyzer(false);
-		issue.setExternalSystemIssues(Sets.newHashSet(ticket));
-
-		rq.setIssue(issue);
-
-		mockMvc.perform(put(
-				SUPERADMIN_PROJECT_BASE_URL + "/item/3ab067e5-537b-45ff-9605-843ab695c96a").content(objectMapper.writeValueAsBytes(rq))
-				.contentType(APPLICATION_JSON)
-				.with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isBadRequest());
-	}
-
-	@Test
-	void finishTestItemWithLinkedTicketsBadBtsProject() throws Exception {
-		FinishTestItemRQ rq = new FinishTestItemRQ();
-		rq.setLaunchUuid("334d153c-8f9c-4dff-8627-47dd003bee0f");
-		rq.setEndTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
-		rq.setStatus("FAILED");
-
-		Issue.ExternalSystemIssue ticket = new Issue.ExternalSystemIssue();
-		ticket.setBtsUrl("jira.com");
-		ticket.setTicketId("ticket1");
-		ticket.setUrl("https://example.com/NEWTICKET1");
-
-		Issue issue = new Issue();
-		issue.setIssueType("pb001");
-		issue.setIgnoreAnalyzer(false);
-		issue.setExternalSystemIssues(Sets.newHashSet(ticket));
-
-		rq.setIssue(issue);
-
-		mockMvc.perform(put(
-				SUPERADMIN_PROJECT_BASE_URL + "/item/3ab067e5-537b-45ff-9605-843ab695c96a").content(objectMapper.writeValueAsBytes(rq))
-				.contentType(APPLICATION_JSON)
-				.with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isBadRequest());
-	}
-
-	@Test
-	void finishTestItemWithLinkedTicketsBadUrl() throws Exception {
-		FinishTestItemRQ rq = new FinishTestItemRQ();
-		rq.setLaunchUuid("334d153c-8f9c-4dff-8627-47dd003bee0f");
-		rq.setEndTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
-		rq.setStatus("FAILED");
-
-		Issue.ExternalSystemIssue ticket = new Issue.ExternalSystemIssue();
-		ticket.setBtsUrl("jira.com");
-		ticket.setBtsProject("project");
-		ticket.setTicketId("ticket1");
-
-		Issue issue = new Issue();
-		issue.setIssueType("pb001");
-		issue.setIgnoreAnalyzer(false);
-		issue.setExternalSystemIssues(Sets.newHashSet(ticket));
-
-		rq.setIssue(issue);
-
-		mockMvc.perform(put(
-				SUPERADMIN_PROJECT_BASE_URL + "/item/3ab067e5-537b-45ff-9605-843ab695c96a").content(objectMapper.writeValueAsBytes(rq))
-				.contentType(APPLICATION_JSON)
-				.with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isBadRequest());
-	}
-
-	@Test
-	void finishTestItemWithEmptyLinkedTickets() throws Exception {
-		FinishTestItemRQ rq = new FinishTestItemRQ();
-		rq.setLaunchUuid("334d153c-8f9c-4dff-8627-47dd003bee0f");
-		rq.setEndTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
-		rq.setStatus("FAILED");
-
-		Issue issue = new Issue();
-		issue.setIssueType("pb001");
-		issue.setIgnoreAnalyzer(false);
-		issue.setExternalSystemIssues(Sets.newHashSet());
-
-		rq.setIssue(issue);
-
-		mockMvc.perform(put(
-				SUPERADMIN_PROJECT_BASE_URL + "/item/3ab067e5-537b-45ff-9605-843ab695c96a").content(objectMapper.writeValueAsBytes(rq))
-				.contentType(APPLICATION_JSON)
-				.with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isOk());
-	}
-
-	@Test
-	void finishTestItemWithLinkedTickets() throws Exception {
-		FinishTestItemRQ rq = new FinishTestItemRQ();
-		rq.setLaunchUuid("334d153c-8f9c-4dff-8627-47dd003bee0f");
-		rq.setEndTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
-		rq.setStatus("FAILED");
-
-		Issue.ExternalSystemIssue ticket = new Issue.ExternalSystemIssue();
-		ticket.setBtsUrl("jira.com");
-		ticket.setBtsProject("project");
-		ticket.setTicketId("ticket1");
-		ticket.setUrl("https://example.com/NEWTICKET1");
-
-		Issue issue = new Issue();
-		issue.setIssueType("pb001");
-		issue.setIgnoreAnalyzer(false);
-		issue.setExternalSystemIssues(Sets.newHashSet(ticket));
-
-		rq.setIssue(issue);
-
-		mockMvc.perform(put(
-				SUPERADMIN_PROJECT_BASE_URL + "/item/3ab067e5-537b-45ff-9605-843ab695c96a").content(objectMapper.writeValueAsBytes(rq))
-				.contentType(APPLICATION_JSON)
-				.with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isOk());
-	}
-
-	@Test
-	void linkExternalIssues() throws Exception {
-		LinkExternalIssueRQ rq = new LinkExternalIssueRQ();
-		rq.setTestItemIds(Collections.singletonList(3L));
-		Issue.ExternalSystemIssue issue = new Issue.ExternalSystemIssue();
-		issue.setBtsUrl("jira.com");
-		issue.setBtsProject("project");
-		issue.setTicketId("ticket1");
-		issue.setUrl("https://example.com/NEWTICKET1");
-		rq.setIssues(Collections.singletonList(issue));
-		mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/item/issue/link").with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(rq))
-				.contentType(APPLICATION_JSON)).andExpect(status().isOk());
-	}
-
-	@Test
-	void linkExternalIssueNegative() throws Exception {
-		LinkExternalIssueRQ rq = new LinkExternalIssueRQ();
-		rq.setTestItemIds(Collections.singletonList(2L));
-		Issue.ExternalSystemIssue issue = new Issue.ExternalSystemIssue();
-		issue.setBtsUrl("jira.com");
-		issue.setBtsProject("project");
-		issue.setTicketId("ticket1");
-		issue.setUrl("https://example.com/NEWTICKET1");
-		rq.setIssues(Collections.singletonList(issue));
-		mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/item/issue/link").with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(rq))
-				.contentType(APPLICATION_JSON)).andExpect(status().isBadRequest());
-	}
-
-	@Test
-	void unlinkExternalIssues() throws Exception {
-		UnlinkExternalIssueRQ rq = new UnlinkExternalIssueRQ();
-		rq.setTestItemIds(Collections.singletonList(3L));
-		rq.setTicketIds(Collections.singletonList("ticket"));
-		mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/item/issue/unlink").with(token(oAuthHelper.getDefaultToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(rq))).andExpect(status().isOk());
-	}
-
-	@Test
-	void unlinkExternalIssuesNegative() throws Exception {
-		UnlinkExternalIssueRQ rq = new UnlinkExternalIssueRQ();
-		rq.setTestItemIds(Collections.singletonList(2L));
-		rq.setTicketIds(Collections.singletonList("ticket"));
-		mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/item/issue/unlink").with(token(oAuthHelper.getDefaultToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(rq))).andExpect(status().isBadRequest());
-	}
-
-	private List<ParameterResource> getParameters() {
-		ParameterResource parameters = new ParameterResource();
-		parameters.setKey("CardNumber");
-		parameters.setValue("4444333322221111");
-		ParameterResource parameters1 = new ParameterResource();
-		parameters1.setKey("Stars");
-		parameters1.setValue("2 stars");
-		return ImmutableList.<ParameterResource>builder().add(parameters).add(parameters1).build();
-	}
-
-	@Test
-	void getItemsByAdmin() throws Exception {
-		mockMvc.perform(get(SUPERADMIN_PROJECT_BASE_URL + "/item/items?ids=1,2,4").with(token(oAuthHelper.getSuperadminToken())))
-				.andExpect(status().isOk())
-				.andExpect(jsonPath("$", hasSize(3)));
-	}
-
-	@Sql("/db/test-item/item-change-status-from-passed.sql")
-	@Test
-	void changeStatusFromPassedToFailed() throws Exception {
-		UpdateTestItemRQ request = new UpdateTestItemRQ();
-		request.setStatus("failed");
-
-		mockMvc.perform(put(SUPERADMIN_PROJECT_BASE_URL + "/item/6/update").with(token(oAuthHelper.getSuperadminToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
-
-		Optional<TestItem> updatedItem = testItemRepository.findById(6L);
-
-		assertTrue(updatedItem.isPresent());
-		assertEquals(StatusEnum.FAILED, updatedItem.get().getItemResults().getStatus());
-		assertEquals(StatusEnum.FAILED, testItemRepository.findById(updatedItem.get().getParentId()).get().getItemResults().getStatus());
-
-		Launch launch = launchRepository.findById(updatedItem.get().getLaunchId()).get();
-		assertEquals(StatusEnum.FAILED, launch.getStatus());
-
-		verify(messageBus, times(2)).publishActivity(ArgumentMatchers.any());
-	}
-
-	@Sql("/db/test-item/item-change-status-from-passed.sql")
-	@Test
-	void changeStatusFromPassedToSkipped() throws Exception {
-		UpdateTestItemRQ request = new UpdateTestItemRQ();
-		request.setStatus("skipped");
-
-		mockMvc.perform(put(SUPERADMIN_PROJECT_BASE_URL + "/item/6/update").with(token(oAuthHelper.getSuperadminToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
-
-		Optional<TestItem> updatedItem = testItemRepository.findById(6L);
-		assertTrue(updatedItem.isPresent());
-		assertEquals(StatusEnum.SKIPPED, updatedItem.get().getItemResults().getStatus());
-		assertEquals(TestItemIssueGroup.TO_INVESTIGATE,
-				updatedItem.get().getItemResults().getIssue().getIssueType().getIssueGroup().getTestItemIssueGroup()
-		);
-		assertEquals(StatusEnum.FAILED, testItemRepository.findById(updatedItem.get().getParentId()).get().getItemResults().getStatus());
-
-		Launch launch = launchRepository.findById(updatedItem.get().getLaunchId()).get();
-		assertEquals(StatusEnum.FAILED, launch.getStatus());
-
-		verify(messageBus, times(2)).publishActivity(ArgumentMatchers.any());
-	}
-
-	@Sql("/db/test-item/item-change-status-from-passed.sql")
-	@Test
-	void changeStatusFromPassedToSkippedWithoutIssue() throws Exception {
-		UpdateTestItemRQ request = new UpdateTestItemRQ();
-		request.setStatus("skipped");
-
-		mockMvc.perform(put(SUPERADMIN_PROJECT_BASE_URL + "/item/9/update").with(token(oAuthHelper.getSuperadminToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
-
-		Optional<TestItem> updatedItem = testItemRepository.findById(9L);
-		assertTrue(updatedItem.isPresent());
-		assertEquals(StatusEnum.SKIPPED, updatedItem.get().getItemResults().getStatus());
-		assertNull(updatedItem.get().getItemResults().getIssue());
-		assertEquals(StatusEnum.FAILED, testItemRepository.findById(updatedItem.get().getParentId()).get().getItemResults().getStatus());
-
-		Launch launch = launchRepository.findById(updatedItem.get().getLaunchId()).get();
-		assertEquals(StatusEnum.FAILED, launch.getStatus());
-
-		verify(messageBus, times(2)).publishActivity(ArgumentMatchers.any());
-	}
-
-	@Sql("/db/test-item/item-change-status-from-passed.sql")
-	@Test
-	void finishTestItemWithFinishedParent() throws Exception {
-		FinishTestItemRQ rq = new FinishTestItemRQ();
-		rq.setLaunchUuid(UUID.randomUUID().toString());
-		rq.setEndTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
-		rq.setStatus("FAILED");
-		Issue issue = new Issue();
-		issue.setIssueType("pb001");
-		rq.setIssue(issue);
-
-		Optional<TestItem> updatedItem = testItemRepository.findById(11L);
-		assertTrue(updatedItem.isPresent());
-		assertEquals(StatusEnum.IN_PROGRESS, updatedItem.get().getItemResults().getStatus());
-
-		mockMvc.perform(put(SUPERADMIN_PROJECT_BASE_URL + "/item/uuid_s_2_9").content(objectMapper.writeValueAsBytes(rq))
-				.contentType(APPLICATION_JSON)
-				.with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isOk());
-
-		updatedItem = testItemRepository.findById(11L);
-		assertTrue(updatedItem.isPresent());
-		assertEquals(StatusEnum.FAILED, updatedItem.get().getItemResults().getStatus());
-		assertEquals(TestItemIssueGroup.PRODUCT_BUG,
-				updatedItem.get().getItemResults().getIssue().getIssueType().getIssueGroup().getTestItemIssueGroup()
-		);
-		assertEquals(StatusEnum.FAILED, testItemRepository.findById(updatedItem.get().getParentId()).get().getItemResults().getStatus());
-
-		Launch launch = launchRepository.findById(updatedItem.get().getLaunchId()).get();
-		assertEquals(StatusEnum.FAILED, launch.getStatus());
-	}
-
-	@Sql("/db/test-item/item-change-status-from-failed.sql")
-	@Test
-	void changeStatusFromFailedToPassed() throws Exception {
-		UpdateTestItemRQ request = new UpdateTestItemRQ();
-		request.setStatus("passed");
-
-		mockMvc.perform(put(SUPERADMIN_PROJECT_BASE_URL + "/item/6/update").with(token(oAuthHelper.getSuperadminToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
-
-		Optional<TestItem> updatedItem = testItemRepository.findById(6L);
-		assertTrue(updatedItem.isPresent());
-		assertEquals(StatusEnum.PASSED, updatedItem.get().getItemResults().getStatus());
-		assertNull(updatedItem.get().getItemResults().getIssue());
-		assertEquals(StatusEnum.PASSED, testItemRepository.findById(updatedItem.get().getParentId()).get().getItemResults().getStatus());
-
-		Launch launch = launchRepository.findById(updatedItem.get().getLaunchId()).get();
-		assertEquals(StatusEnum.PASSED, launch.getStatus());
-
-		verify(messageBus, times(2)).publishActivity(ArgumentMatchers.any());
-	}
-
-	@Sql("/db/test-item/item-change-status-from-failed.sql")
-	@Test
-	void changeStatusFromFailedToSkipped() throws Exception {
-		UpdateTestItemRQ request = new UpdateTestItemRQ();
-		request.setStatus("skipped");
-
-		mockMvc.perform(put(SUPERADMIN_PROJECT_BASE_URL + "/item/6/update").with(token(oAuthHelper.getSuperadminToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
-
-		Optional<TestItem> updatedItem = testItemRepository.findById(6L);
-		assertTrue(updatedItem.isPresent());
-		assertEquals(StatusEnum.SKIPPED, updatedItem.get().getItemResults().getStatus());
-		assertEquals(TestItemIssueGroup.AUTOMATION_BUG,
-				updatedItem.get().getItemResults().getIssue().getIssueType().getIssueGroup().getTestItemIssueGroup()
-		);
-		assertEquals(StatusEnum.FAILED, testItemRepository.findById(updatedItem.get().getParentId()).get().getItemResults().getStatus());
-
-		Launch launch = launchRepository.findById(updatedItem.get().getLaunchId()).get();
-		assertEquals(StatusEnum.FAILED, launch.getStatus());
-
-		verify(messageBus, times(1)).publishActivity(ArgumentMatchers.any());
-	}
-
-	@Sql("/db/test-item/item-change-status-from-skipped.sql")
-	@Test
-	void changeStatusFromSkippedToFailed() throws Exception {
-		UpdateTestItemRQ request = new UpdateTestItemRQ();
-		request.setStatus("failed");
-
-		mockMvc.perform(put(SUPERADMIN_PROJECT_BASE_URL + "/item/6/update").with(token(oAuthHelper.getSuperadminToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
-
-		Optional<TestItem> updatedItem = testItemRepository.findById(6L);
-		assertTrue(updatedItem.isPresent());
-		assertEquals(StatusEnum.FAILED, updatedItem.get().getItemResults().getStatus());
-		assertEquals(TestItemIssueGroup.TO_INVESTIGATE,
-				updatedItem.get().getItemResults().getIssue().getIssueType().getIssueGroup().getTestItemIssueGroup()
-		);
-		assertEquals(StatusEnum.FAILED, testItemRepository.findById(updatedItem.get().getParentId()).get().getItemResults().getStatus());
-
-		Launch launch = launchRepository.findById(updatedItem.get().getLaunchId()).get();
-		assertEquals(StatusEnum.FAILED, launch.getStatus());
-
-		verify(messageBus, times(1)).publishActivity(ArgumentMatchers.any());
-	}
-
-	@Sql("/db/test-item/item-change-status-from-skipped.sql")
-	@Test
-	void changeStatusFromSkippedToPassed() throws Exception {
-		UpdateTestItemRQ request = new UpdateTestItemRQ();
-		request.setStatus("passed");
-
-		mockMvc.perform(put(SUPERADMIN_PROJECT_BASE_URL + "/item/6/update").with(token(oAuthHelper.getSuperadminToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
-
-		Optional<TestItem> updatedItem = testItemRepository.findById(6L);
-		assertTrue(updatedItem.isPresent());
-		assertEquals(StatusEnum.PASSED, updatedItem.get().getItemResults().getStatus());
-		assertNull(updatedItem.get().getItemResults().getIssue());
-		assertEquals(StatusEnum.PASSED, testItemRepository.findById(updatedItem.get().getParentId()).get().getItemResults().getStatus());
-
-		Launch launch = launchRepository.findById(updatedItem.get().getLaunchId()).get();
-		assertEquals(StatusEnum.PASSED, launch.getStatus());
-
-		verify(messageBus, times(2)).publishActivity(ArgumentMatchers.any());
-	}
-
-	@Sql("/db/test-item/item-change-status-from-interrupted.sql")
-	@Test
-	void changeStatusFromInterruptedToPassed() throws Exception {
-		UpdateTestItemRQ request = new UpdateTestItemRQ();
-		request.setStatus("passed");
-
-		mockMvc.perform(put(SUPERADMIN_PROJECT_BASE_URL + "/item/6/update").with(token(oAuthHelper.getSuperadminToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
-
-		Optional<TestItem> updatedItem = testItemRepository.findById(6L);
-		assertTrue(updatedItem.isPresent());
-		assertEquals(StatusEnum.PASSED, updatedItem.get().getItemResults().getStatus());
-		assertNull(updatedItem.get().getItemResults().getIssue());
-		assertEquals(StatusEnum.PASSED, testItemRepository.findById(updatedItem.get().getParentId()).get().getItemResults().getStatus());
-
-		Launch launch = launchRepository.findById(updatedItem.get().getLaunchId()).get();
-		assertEquals(StatusEnum.PASSED, launch.getStatus());
-
-		verify(messageBus, times(2)).publishActivity(ArgumentMatchers.any());
-	}
-
-	@Sql("/db/test-item/item-change-status-from-interrupted.sql")
-	@Test
-	void changeStatusFromInterruptedToSkipped() throws Exception {
-		UpdateTestItemRQ request = new UpdateTestItemRQ();
-		request.setStatus("skipped");
-
-		mockMvc.perform(put(SUPERADMIN_PROJECT_BASE_URL + "/item/6/update").with(token(oAuthHelper.getSuperadminToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
-
-		Optional<TestItem> updatedItem = testItemRepository.findById(6L);
-		assertTrue(updatedItem.isPresent());
-		assertEquals(StatusEnum.SKIPPED, updatedItem.get().getItemResults().getStatus());
-		assertEquals(TestItemIssueGroup.TO_INVESTIGATE,
-				updatedItem.get().getItemResults().getIssue().getIssueType().getIssueGroup().getTestItemIssueGroup()
-		);
-		assertEquals(StatusEnum.FAILED, testItemRepository.findById(updatedItem.get().getParentId()).get().getItemResults().getStatus());
-
-		Launch launch = launchRepository.findById(updatedItem.get().getLaunchId()).get();
-		assertEquals(StatusEnum.FAILED, launch.getStatus());
-
-		verify(messageBus, times(1)).publishActivity(ArgumentMatchers.any());
-	}
-
-	@Sql("/db/test-item/item-change-status-from-interrupted.sql")
-	@Test
-	void changeStatusFromInterruptedToFailed() throws Exception {
-		UpdateTestItemRQ request = new UpdateTestItemRQ();
-		request.setStatus("failed");
-
-		mockMvc.perform(put(SUPERADMIN_PROJECT_BASE_URL + "/item/6/update").with(token(oAuthHelper.getSuperadminToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
-
-		Optional<TestItem> updatedItem = testItemRepository.findById(6L);
-		assertTrue(updatedItem.isPresent());
-		assertEquals(StatusEnum.FAILED, updatedItem.get().getItemResults().getStatus());
-		assertEquals(TestItemIssueGroup.TO_INVESTIGATE,
-				updatedItem.get().getItemResults().getIssue().getIssueType().getIssueGroup().getTestItemIssueGroup()
-		);
-		assertEquals(StatusEnum.FAILED, testItemRepository.findById(updatedItem.get().getParentId()).get().getItemResults().getStatus());
-
-		Launch launch = launchRepository.findById(updatedItem.get().getLaunchId()).get();
-		assertEquals(StatusEnum.FAILED, launch.getStatus());
-
-		verify(messageBus, times(1)).publishActivity(ArgumentMatchers.any());
-	}
-
-	@Test
-	void changeStatusNegative() throws Exception {
-		UpdateTestItemRQ request = new UpdateTestItemRQ();
-		request.setStatus("failed");
-
-		mockMvc.perform(put(SUPERADMIN_PROJECT_BASE_URL + "/item/5/update").with(token(oAuthHelper.getSuperadminToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().is(400));
-	}
-
-	@Test
-	void bulkUpdateItemAttributes() throws Exception {
-		BulkInfoUpdateRQ request = new BulkInfoUpdateRQ();
-		List<Long> launchIds = Arrays.asList(1L, 2L, 3L, 4L, 5L, 6L);
-		request.setIds(launchIds);
-		BulkInfoUpdateRQ.Description description = new BulkInfoUpdateRQ.Description();
-		description.setAction(BulkInfoUpdateRQ.Action.CREATE);
-		String comment = "created";
-		description.setComment(comment);
-		request.setDescription(description);
-		UpdateItemAttributeRQ updateItemAttributeRQ = new UpdateItemAttributeRQ();
-		updateItemAttributeRQ.setAction(BulkInfoUpdateRQ.Action.UPDATE);
-		updateItemAttributeRQ.setFrom(new ItemAttributeResource("testKey", "testValue"));
-		updateItemAttributeRQ.setTo(new ItemAttributeResource("updatedKey", "updatedValue"));
-		request.setAttributes(Lists.newArrayList(updateItemAttributeRQ));
-
-		mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/item/info").with(token(oAuthHelper.getDefaultToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
-
-		List<TestItem> items = testItemRepository.findAllById(launchIds);
-		items.forEach(it -> testItemRepository.refresh(it));
-
-		items.forEach(it -> {
-			assertTrue(it.getAttributes()
-					.stream()
-					.noneMatch(attr -> "testKey".equals(attr.getKey()) && attr.getValue().equals("testValue") && !attr.isSystem()));
-			assertTrue(it.getAttributes()
-					.stream()
-					.anyMatch(attr -> "updatedKey".equals(attr.getKey()) && attr.getValue().equals("updatedValue") && !attr.isSystem()));
-			assertEquals(comment, it.getDescription());
-		});
-	}
-
-	@Test
-	void bulkCreateAttributes() throws Exception {
-		BulkInfoUpdateRQ request = new BulkInfoUpdateRQ();
-		List<Long> launchIds = Arrays.asList(1L, 2L, 3L, 4L, 5L, 6L);
-		request.setIds(launchIds);
-		BulkInfoUpdateRQ.Description description = new BulkInfoUpdateRQ.Description();
-		description.setAction(BulkInfoUpdateRQ.Action.UPDATE);
-		String comment = "updated";
-		description.setComment(comment);
-		request.setDescription(description);
-		UpdateItemAttributeRQ updateItemAttributeRQ = new UpdateItemAttributeRQ();
-		updateItemAttributeRQ.setAction(BulkInfoUpdateRQ.Action.CREATE);
-		updateItemAttributeRQ.setTo(new ItemAttributeResource("createdKey", "createdValue"));
-		request.setAttributes(Lists.newArrayList(updateItemAttributeRQ));
-
-		mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/item/info").with(token(oAuthHelper.getDefaultToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
-
-		List<TestItem> items = testItemRepository.findAllById(launchIds);
-		items.forEach(it -> testItemRepository.refresh(it));
-
-		items.forEach(it -> {
-			assertTrue(it.getAttributes()
-					.stream()
-					.anyMatch(attr -> "createdKey".equals(attr.getKey()) && attr.getValue().equals("createdValue") && !attr.isSystem()));
-			assertTrue(it.getDescription().length() > comment.length() && it.getDescription().contains(comment));
-		});
-	}
-
-	@Test
-	void bulkDeleteAttributes() throws Exception {
-		BulkInfoUpdateRQ request = new BulkInfoUpdateRQ();
-		List<Long> launchIds = Arrays.asList(1L, 2L, 3L, 4L, 5L, 6L);
-		request.setIds(launchIds);
-		BulkInfoUpdateRQ.Description description = new BulkInfoUpdateRQ.Description();
-		description.setAction(BulkInfoUpdateRQ.Action.CREATE);
-		String comment = "created";
-		description.setComment(comment);
-		request.setDescription(description);
-		UpdateItemAttributeRQ updateItemAttributeRQ = new UpdateItemAttributeRQ();
-		updateItemAttributeRQ.setAction(BulkInfoUpdateRQ.Action.DELETE);
-		updateItemAttributeRQ.setFrom(new ItemAttributeResource("testKey", "testValue"));
-		request.setAttributes(Lists.newArrayList(updateItemAttributeRQ));
-
-		mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/item/info").with(token(oAuthHelper.getDefaultToken()))
-				.contentType(APPLICATION_JSON)
-				.content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
-
-		List<TestItem> items = testItemRepository.findAllById(launchIds);
-		items.forEach(it -> testItemRepository.refresh(it));
-
-		items.forEach(it -> {
-			assertTrue(it.getAttributes()
-					.stream()
-					.noneMatch(attr -> "testKey".equals(attr.getKey()) && attr.getValue().equals("testValue") && !attr.isSystem()));
-			assertEquals(comment, it.getDescription());
-		});
-	}
+  @Autowired
+  private ObjectMapper objectMapper;
+
+  @Autowired
+  private TestItemRepository testItemRepository;
+
+  @Autowired
+  private LaunchRepository launchRepository;
+
+  @Test
+  void startRootItemPositive() throws Exception {
+    StartTestItemRQ rq = new StartTestItemRQ();
+    rq.setLaunchUuid("a7b66ef2-db30-4db7-94df-f5f7786b398a");
+    rq.setName("RootItem");
+    rq.setType("SUITE");
+    rq.setParameters(getParameters());
+    rq.setUniqueId(UUID.randomUUID().toString());
+    rq.setStartTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+    mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + "/item").contentType(APPLICATION_JSON)
+            .content(objectMapper.writeValueAsBytes(rq)).with(token(oAuthHelper.getDefaultToken())))
+        .andExpect(status().isCreated());
+  }
+
+  @Test
+  void startRootItemWithoutUuid() throws Exception {
+    StartTestItemRQ rq = new StartTestItemRQ();
+    rq.setLaunchUuid("a7b66ef2-db30-4db7-94df-f5f7786b398a");
+    rq.setName("RootItem");
+    rq.setType("SUITE");
+    rq.setParameters(getParameters());
+    rq.setStartTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+    mockMvc.perform(post(SUPERADMIN_PROJECT_BASE_URL + "/item").contentType(APPLICATION_JSON)
+            .content(objectMapper.writeValueAsBytes(rq)).with(token(oAuthHelper.getSuperadminToken())))
+        .andExpect(status().isCreated());
+  }
+
+  @Test
+  void startChildItemPositive() throws Exception {
+    StartTestItemRQ rq = new StartTestItemRQ();
+    rq.setLaunchUuid("a7b66ef2-db30-4db7-94df-f5f7786b398a");
+    rq.setName("ChildItem");
+    rq.setType("TEST");
+    rq.setUniqueId(UUID.randomUUID().toString());
+    rq.setParameters(getParameters());
+    rq.setStartTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+    mockMvc.perform(
+        post(DEFAULT_PROJECT_BASE_URL + "/item/0f7ca5bc-cfae-4cc1-9682-e59c2860131e").content(
+                objectMapper.writeValueAsBytes(rq)).contentType(APPLICATION_JSON)
+            .with(token(oAuthHelper.getDefaultToken()))).andExpect(status().isCreated());
+  }
+
+  @Test
+  void startChildItemWithoutUuid() throws Exception {
+    StartTestItemRQ rq = new StartTestItemRQ();
+    rq.setLaunchUuid("a7b66ef2-db30-4db7-94df-f5f7786b398a");
+    rq.setName("ChildItem");
+    rq.setType("TEST");
+    rq.setParameters(getParameters());
+    rq.setStartTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+    mockMvc.perform(
+        post(DEFAULT_PROJECT_BASE_URL + "/item/0f7ca5bc-cfae-4cc1-9682-e59c2860131e").content(
+                objectMapper.writeValueAsBytes(rq)).contentType(APPLICATION_JSON)
+            .with(token(oAuthHelper.getDefaultToken()))).andExpect(status().isCreated());
+  }
+
+  @Test
+  void finishTestItemPositive() throws Exception {
+    FinishTestItemRQ rq = new FinishTestItemRQ();
+    rq.setLaunchUuid(UUID.randomUUID().toString());
+    rq.setEndTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+    rq.setStatus("PASSED");
+    mockMvc.perform(
+        put(DEFAULT_PROJECT_BASE_URL + "/item/0f7ca5bc-cfae-4cc1-9682-e59c2860131e").content(
+                objectMapper.writeValueAsBytes(rq)).contentType(APPLICATION_JSON)
+            .with(token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
+  }
+
+  @Test
+  void finishRootTestItemWithoutStatus() throws Exception {
+    FinishTestItemRQ rq = new FinishTestItemRQ();
+    rq.setLaunchUuid(UUID.randomUUID().toString());
+    rq.setEndTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+    mockMvc.perform(
+        put(DEFAULT_PROJECT_BASE_URL + "/item/0f7ca5bc-cfae-4cc1-9682-e59c2860131e").content(
+                objectMapper.writeValueAsBytes(rq)).contentType(APPLICATION_JSON)
+            .with(token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
+  }
+
+  @Test
+  void finishTestItemWithFailedStatus() throws Exception {
+    FinishTestItemRQ rq = new FinishTestItemRQ();
+    rq.setLaunchUuid(UUID.randomUUID().toString());
+    rq.setEndTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+    rq.setStatus("FAILED");
+    Issue issue = new Issue();
+    issue.setIssueType("pb001");
+    rq.setIssue(issue);
+    mockMvc.perform(
+        put(SUPERADMIN_PROJECT_BASE_URL + "/item/3ab067e5-537b-45ff-9605-843ab695c96a").content(
+                objectMapper.writeValueAsBytes(rq)).contentType(APPLICATION_JSON)
+            .with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isOk());
+  }
+
+  @Test
+  void finishTestItemWithoutIssueType() throws Exception {
+    FinishTestItemRQ rq = new FinishTestItemRQ();
+    rq.setLaunchUuid(UUID.randomUUID().toString());
+    rq.setEndTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+    rq.setStatus("FAILED");
+    mockMvc.perform(
+        put(SUPERADMIN_PROJECT_BASE_URL + "/item/3ab067e5-537b-45ff-9605-843ab695c96a").content(
+                objectMapper.writeValueAsBytes(rq)).contentType(APPLICATION_JSON)
+            .with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isOk());
+  }
+
+  @Test
+  void getSuggestedItemsAnalyzerNotDeployed() throws Exception {
+    mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/item/suggest/1").with(
+            token(oAuthHelper.getDefaultToken()))).andExpect(
+            result -> assertTrue(result.getResolvedException() instanceof ReportPortalException))
+        .andExpect(result -> assertEquals(
+            "Impossible interact with integration. There are no analyzer services with suggest items support deployed.",
+            result.getResolvedException().getMessage()
+        ));
+  }
+
+  @Test
+  void getTestItemPositive() throws Exception {
+    mockMvc.perform(
+            get(DEFAULT_PROJECT_BASE_URL + "/item/1").with(token(oAuthHelper.getDefaultToken())))
+        .andExpect(status().isOk());
+  }
+
+  @Test
+  void getTestItemStringPositive() throws Exception {
+    mockMvc.perform(
+        get(DEFAULT_PROJECT_BASE_URL + "/item/0f7ca5bc-cfae-4cc1-9682-e59c2860131e").with(
+            token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
+  }
+
+  @Test
+  void getTestItemRetryPositive() throws Exception {
+    mockMvc.perform(
+            get(DEFAULT_PROJECT_BASE_URL + "/item/7").with(token(oAuthHelper.getDefaultToken())))
+        .andExpect(status().isOk());
+  }
+
+  @Test
+  void getTestItemRetryStringPositive() throws Exception {
+    mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/item/3ab067e5-537b-45ff-9605-retry").with(
+        token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
+  }
+
+  @Test
+  void getTestItemUuidPositive() throws Exception {
+    mockMvc.perform(
+        get(DEFAULT_PROJECT_BASE_URL + "/item/uuid/0f7ca5bc-cfae-4cc1-9682-e59c2860131e").with(
+            token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
+  }
+
+  @Test
+  void getTestItemsPositive() throws Exception {
+    mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/item?filter.eq.launchId=1").with(
+        token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
+  }
+
+  @Test
+  void getTestItemsBadProvider() throws Exception {
+    mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/item/v2?providerType=bad").with(
+        token(oAuthHelper.getDefaultToken()))).andExpect(status().isBadRequest());
+  }
+
+  @Test
+  void getTestItemsLaunchProvider() throws Exception {
+    mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/item/v2?providerType=launch&launchId=1").with(
+        token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
+  }
+
+  @Test
+  void getTestItemsLaunchProviderMissedParam() throws Exception {
+    mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/item/v2?providerType=launch").with(
+        token(oAuthHelper.getDefaultToken()))).andExpect(status().isBadRequest());
+  }
+
+  @Test
+  void getTestItemsFilterProvider() throws Exception {
+    mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL
+        + "/item/v2?providerType=filter&filterId=1&launchesLimit=10").with(
+        token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
+  }
+
+  @Test
+  void getTestItemsFilterProviderMissedParam() throws Exception {
+    mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/item/v2?providerType=filter").with(
+        token(oAuthHelper.getDefaultToken()))).andExpect(status().isBadRequest());
+  }
+
+  @Test
+  void getTestItemsWidgetProvider() throws Exception {
+    mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/item/v2?providerType=widget").with(
+        token(oAuthHelper.getDefaultToken()))).andExpect(status().isBadRequest());
+  }
+
+  @Test
+  void getTestItemBySpecifiedIds() throws Exception {
+    mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/item/items?ids=1,2,3").with(
+        token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
+  }
+
+  @Test
+  void deleteTestItemPositive() throws Exception {
+    mockMvc.perform(
+            delete(DEFAULT_PROJECT_BASE_URL + "/item/2").with(token(oAuthHelper.getDefaultToken())))
+        .andExpect(status().isOk());
+  }
+
+  @Test
+  void deleteTestItemBySpecifiedIds() throws Exception {
+    mockMvc.perform(delete(DEFAULT_PROJECT_BASE_URL + "/item?ids=2,3").with(
+        token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
+  }
+
+  @Test
+  void getAccumulatedStatisticsByFilter() throws Exception {
+    mockMvc.perform(
+        get(DEFAULT_PROJECT_BASE_URL + "/item/statistics?providerType=launch&launchId=1").with(
+            token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
+  }
+
+  @Test
+  void getItemHistoryByParentIdPositive() throws Exception {
+    mockMvc.perform(
+        get(DEFAULT_PROJECT_BASE_URL + "/item/history?filter.eq.parentId=1&historyDepth=3").with(
+            token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
+  }
+
+  @Test
+  void getItemHistoryByLaunchIdPositive() throws Exception {
+    mockMvc.perform(
+        get(SUPERADMIN_PROJECT_BASE_URL + "/item/history?filter.eq.launchId=1&historyDepth=3").with(
+            token(oAuthHelper.getSuperadminToken()))).andExpect(status().isOk());
+  }
+
+  @Test
+  void getItemHistoryByFilterIdPositive() throws Exception {
+    mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL
+        + "/item/history?filterId=1&launchesLimit=10&historyDepth=3").with(
+        token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
+  }
+
+  @Test
+  void updateTestItemPositive() throws Exception {
+    UpdateTestItemRQ rq = new UpdateTestItemRQ();
+    rq.setDescription("updated");
+    rq.setAttributes(Sets.newHashSet(new ItemAttributeResource("test", "test")));
+    mockMvc.perform(
+            put(DEFAULT_PROJECT_BASE_URL + "/item/1/update").with(token(oAuthHelper.getDefaultToken()))
+                .contentType(APPLICATION_JSON).content(objectMapper.writeValueAsBytes(rq)))
+        .andExpect(status().isOk());
+  }
+
+  @Test
+  void handleSuggestChooseAnalyzerNotDeployed() throws Exception {
+    SuggestInfo suggestInfo = new SuggestInfo();
+    suggestInfo.setTestItem(1L);
+    mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/item/suggest/choice").with(
+                token(oAuthHelper.getDefaultToken())).contentType(APPLICATION_JSON)
+            .content(objectMapper.writeValueAsBytes(Lists.newArrayList(suggestInfo)))).andExpect(
+            result -> assertTrue(result.getResolvedException() instanceof ReportPortalException))
+        .andExpect(result -> assertEquals(
+            "Impossible interact with integration. There are no analyzer services with suggest items support deployed.",
+            result.getResolvedException().getMessage()
+        ));
+  }
+
+  @Test
+  void getTickets() throws Exception {
+    mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL + "/item/ticket/ids?launch=1&term=ticket").with(
+        token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
+  }
+
+  @Test
+  void getAttributeKeys() throws Exception {
+    mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL
+        + "/item/attribute/keys?launch=1&filter.cnt.attributeKey=bro").with(
+        token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
+  }
+
+  @Test
+  void getAttributeKeysForProject() throws Exception {
+    mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL
+        + "/item/attribute/keys/all?filterId=1&launchesLimit=600&isLatest=false&filter.cnt.attributeKey=bro").with(
+        token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
+  }
+
+  @Test
+  void getAttributeValues() throws Exception {
+    mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL
+        + "/item/attribute/values?launch=1&filter.cnt.attributeValue=lin").with(
+        token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
+  }
+
+  @Test
+  void getAttributeKeysByProjectId() throws Exception {
+    mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL
+        + "/item/step/attribute/keys?filter.eq.name=test launch&filter.cnt.attributeKey=bro").with(
+        token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
+  }
+
+  @Test
+  void getAttributeValuesByKeyAndProjectId() throws Exception {
+    mockMvc.perform(get(DEFAULT_PROJECT_BASE_URL
+        + "/item/step/attribute/values?filter.eq.name=test launch&filter.cnt.attributeValue=lin").with(
+        token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk());
+  }
+
+  @Test
+  void defineTestItemIssue() throws Exception {
+    DefineIssueRQ rq = new DefineIssueRQ();
+    IssueDefinition issueDefinition = new IssueDefinition();
+    issueDefinition.setId(3L);
+    Issue issue = new Issue();
+    issue.setIssueType("pb001");
+    issue.setIgnoreAnalyzer(false);
+    issueDefinition.setIssue(issue);
+    rq.setIssues(Collections.singletonList(issueDefinition));
+    mockMvc.perform(
+            put(DEFAULT_PROJECT_BASE_URL + "/item").with(token(oAuthHelper.getDefaultToken()))
+                .contentType(APPLICATION_JSON).content(objectMapper.writeValueAsBytes(rq)))
+        .andExpect(status().isOk());
+  }
+
+  @Test
+  void defineTestItemIssueNegative() throws Exception {
+    DefineIssueRQ rq = new DefineIssueRQ();
+    IssueDefinition issueDefinition = new IssueDefinition();
+    issueDefinition.setId(100L);
+    Issue issue = new Issue();
+    issue.setIssueType("pb001");
+    issue.setIgnoreAnalyzer(false);
+    issueDefinition.setIssue(issue);
+    rq.setIssues(Collections.singletonList(issueDefinition));
+    mockMvc.perform(
+            put(DEFAULT_PROJECT_BASE_URL + "/item").with(token(oAuthHelper.getDefaultToken()))
+                .contentType(APPLICATION_JSON).content(objectMapper.writeValueAsBytes(rq)))
+        .andExpect(status().isBadRequest());
+  }
+
+  @Test
+  void finishTestItemWithLinkedTicketsBadTicketId() throws Exception {
+    FinishTestItemRQ rq = new FinishTestItemRQ();
+    rq.setLaunchUuid("334d153c-8f9c-4dff-8627-47dd003bee0f");
+    rq.setEndTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+    rq.setStatus("FAILED");
+
+    Issue.ExternalSystemIssue ticket = new Issue.ExternalSystemIssue();
+    ticket.setBtsUrl("jira.com");
+    ticket.setBtsProject("project");
+    ticket.setUrl("https://example.com/NEWTICKET1");
+
+    Issue issue = new Issue();
+    issue.setIssueType("pb001");
+    issue.setIgnoreAnalyzer(false);
+    issue.setExternalSystemIssues(Sets.newHashSet(ticket));
+
+    rq.setIssue(issue);
+
+    mockMvc.perform(
+        put(SUPERADMIN_PROJECT_BASE_URL + "/item/3ab067e5-537b-45ff-9605-843ab695c96a").content(
+                objectMapper.writeValueAsBytes(rq)).contentType(APPLICATION_JSON)
+            .with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isBadRequest());
+  }
+
+  @Test
+  void finishTestItemWithLinkedTicketsBadBtsUrl() throws Exception {
+    FinishTestItemRQ rq = new FinishTestItemRQ();
+    rq.setLaunchUuid("334d153c-8f9c-4dff-8627-47dd003bee0f");
+    rq.setEndTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+    rq.setStatus("FAILED");
+
+    Issue.ExternalSystemIssue ticket = new Issue.ExternalSystemIssue();
+    ticket.setBtsProject("project");
+    ticket.setTicketId("ticket1");
+    ticket.setUrl("https://example.com/NEWTICKET1");
+
+    Issue issue = new Issue();
+    issue.setIssueType("pb001");
+    issue.setIgnoreAnalyzer(false);
+    issue.setExternalSystemIssues(Sets.newHashSet(ticket));
+
+    rq.setIssue(issue);
+
+    mockMvc.perform(
+        put(SUPERADMIN_PROJECT_BASE_URL + "/item/3ab067e5-537b-45ff-9605-843ab695c96a").content(
+                objectMapper.writeValueAsBytes(rq)).contentType(APPLICATION_JSON)
+            .with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isBadRequest());
+  }
+
+  @Test
+  void finishTestItemWithLinkedTicketsBadBtsProject() throws Exception {
+    FinishTestItemRQ rq = new FinishTestItemRQ();
+    rq.setLaunchUuid("334d153c-8f9c-4dff-8627-47dd003bee0f");
+    rq.setEndTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+    rq.setStatus("FAILED");
+
+    Issue.ExternalSystemIssue ticket = new Issue.ExternalSystemIssue();
+    ticket.setBtsUrl("jira.com");
+    ticket.setTicketId("ticket1");
+    ticket.setUrl("https://example.com/NEWTICKET1");
+
+    Issue issue = new Issue();
+    issue.setIssueType("pb001");
+    issue.setIgnoreAnalyzer(false);
+    issue.setExternalSystemIssues(Sets.newHashSet(ticket));
+
+    rq.setIssue(issue);
+
+    mockMvc.perform(
+        put(SUPERADMIN_PROJECT_BASE_URL + "/item/3ab067e5-537b-45ff-9605-843ab695c96a").content(
+                objectMapper.writeValueAsBytes(rq)).contentType(APPLICATION_JSON)
+            .with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isBadRequest());
+  }
+
+  @Test
+  void finishTestItemWithLinkedTicketsBadUrl() throws Exception {
+    FinishTestItemRQ rq = new FinishTestItemRQ();
+    rq.setLaunchUuid("334d153c-8f9c-4dff-8627-47dd003bee0f");
+    rq.setEndTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+    rq.setStatus("FAILED");
+
+    Issue.ExternalSystemIssue ticket = new Issue.ExternalSystemIssue();
+    ticket.setBtsUrl("jira.com");
+    ticket.setBtsProject("project");
+    ticket.setTicketId("ticket1");
+
+    Issue issue = new Issue();
+    issue.setIssueType("pb001");
+    issue.setIgnoreAnalyzer(false);
+    issue.setExternalSystemIssues(Sets.newHashSet(ticket));
+
+    rq.setIssue(issue);
+
+    mockMvc.perform(
+        put(SUPERADMIN_PROJECT_BASE_URL + "/item/3ab067e5-537b-45ff-9605-843ab695c96a").content(
+                objectMapper.writeValueAsBytes(rq)).contentType(APPLICATION_JSON)
+            .with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isBadRequest());
+  }
+
+  @Test
+  void finishTestItemWithEmptyLinkedTickets() throws Exception {
+    FinishTestItemRQ rq = new FinishTestItemRQ();
+    rq.setLaunchUuid("334d153c-8f9c-4dff-8627-47dd003bee0f");
+    rq.setEndTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+    rq.setStatus("FAILED");
+
+    Issue issue = new Issue();
+    issue.setIssueType("pb001");
+    issue.setIgnoreAnalyzer(false);
+    issue.setExternalSystemIssues(Sets.newHashSet());
+
+    rq.setIssue(issue);
+
+    mockMvc.perform(
+        put(SUPERADMIN_PROJECT_BASE_URL + "/item/3ab067e5-537b-45ff-9605-843ab695c96a").content(
+                objectMapper.writeValueAsBytes(rq)).contentType(APPLICATION_JSON)
+            .with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isOk());
+  }
+
+  @Test
+  void finishTestItemWithLinkedTickets() throws Exception {
+    FinishTestItemRQ rq = new FinishTestItemRQ();
+    rq.setLaunchUuid("334d153c-8f9c-4dff-8627-47dd003bee0f");
+    rq.setEndTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+    rq.setStatus("FAILED");
+
+    Issue.ExternalSystemIssue ticket = new Issue.ExternalSystemIssue();
+    ticket.setBtsUrl("jira.com");
+    ticket.setBtsProject("project");
+    ticket.setTicketId("ticket1");
+    ticket.setUrl("https://example.com/NEWTICKET1");
+
+    Issue issue = new Issue();
+    issue.setIssueType("pb001");
+    issue.setIgnoreAnalyzer(false);
+    issue.setExternalSystemIssues(Sets.newHashSet(ticket));
+
+    rq.setIssue(issue);
+
+    mockMvc.perform(
+        put(SUPERADMIN_PROJECT_BASE_URL + "/item/3ab067e5-537b-45ff-9605-843ab695c96a").content(
+                objectMapper.writeValueAsBytes(rq)).contentType(APPLICATION_JSON)
+            .with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isOk());
+  }
+
+  @Test
+  void linkExternalIssues() throws Exception {
+    LinkExternalIssueRQ rq = new LinkExternalIssueRQ();
+    rq.setTestItemIds(Collections.singletonList(3L));
+    Issue.ExternalSystemIssue issue = new Issue.ExternalSystemIssue();
+    issue.setBtsUrl("jira.com");
+    issue.setBtsProject("project");
+    issue.setTicketId("ticket1");
+    issue.setUrl("https://example.com/NEWTICKET1");
+    rq.setIssues(Collections.singletonList(issue));
+    mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/item/issue/link").with(
+            token(oAuthHelper.getDefaultToken())).content(objectMapper.writeValueAsBytes(rq))
+        .contentType(APPLICATION_JSON)).andExpect(status().isOk());
+  }
+
+  @Test
+  void linkExternalIssueNegative() throws Exception {
+    LinkExternalIssueRQ rq = new LinkExternalIssueRQ();
+    rq.setTestItemIds(Collections.singletonList(2L));
+    Issue.ExternalSystemIssue issue = new Issue.ExternalSystemIssue();
+    issue.setBtsUrl("jira.com");
+    issue.setBtsProject("project");
+    issue.setTicketId("ticket1");
+    issue.setUrl("https://example.com/NEWTICKET1");
+    rq.setIssues(Collections.singletonList(issue));
+    mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/item/issue/link").with(
+            token(oAuthHelper.getDefaultToken())).content(objectMapper.writeValueAsBytes(rq))
+        .contentType(APPLICATION_JSON)).andExpect(status().isBadRequest());
+  }
+
+  @Test
+  void unlinkExternalIssues() throws Exception {
+    UnlinkExternalIssueRQ rq = new UnlinkExternalIssueRQ();
+    rq.setTestItemIds(Collections.singletonList(3L));
+    rq.setTicketIds(Collections.singletonList("ticket"));
+    mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/item/issue/unlink").with(
+            token(oAuthHelper.getDefaultToken())).contentType(APPLICATION_JSON)
+        .content(objectMapper.writeValueAsBytes(rq))).andExpect(status().isOk());
+  }
+
+  @Test
+  void unlinkExternalIssuesNegative() throws Exception {
+    UnlinkExternalIssueRQ rq = new UnlinkExternalIssueRQ();
+    rq.setTestItemIds(Collections.singletonList(2L));
+    rq.setTicketIds(Collections.singletonList("ticket"));
+    mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + "/item/issue/unlink").with(
+            token(oAuthHelper.getDefaultToken())).contentType(APPLICATION_JSON)
+        .content(objectMapper.writeValueAsBytes(rq))).andExpect(status().isBadRequest());
+  }
+
+  private List<ParameterResource> getParameters() {
+    ParameterResource parameters = new ParameterResource();
+    parameters.setKey("CardNumber");
+    parameters.setValue("4444333322221111");
+    ParameterResource parameters1 = new ParameterResource();
+    parameters1.setKey("Stars");
+    parameters1.setValue("2 stars");
+    return ImmutableList.<ParameterResource>builder().add(parameters).add(parameters1).build();
+  }
+
+  @Test
+  void getItemsByAdmin() throws Exception {
+    mockMvc.perform(get(SUPERADMIN_PROJECT_BASE_URL + "/item/items?ids=1,2,4").with(
+            token(oAuthHelper.getSuperadminToken()))).andExpect(status().isOk())
+        .andExpect(jsonPath("$", hasSize(3)));
+  }
+
+  @Sql("/db/test-item/item-change-status-from-passed.sql")
+  @Test
+  void changeStatusFromPassedToFailed() throws Exception {
+    UpdateTestItemRQ request = new UpdateTestItemRQ();
+    request.setStatus("failed");
+
+    mockMvc.perform(put(SUPERADMIN_PROJECT_BASE_URL + "/item/6/update").with(
+            token(oAuthHelper.getSuperadminToken())).contentType(APPLICATION_JSON)
+        .content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
+
+    Optional<TestItem> updatedItem = testItemRepository.findById(6L);
+
+    assertTrue(updatedItem.isPresent());
+    assertEquals(StatusEnum.FAILED, updatedItem.get().getItemResults().getStatus());
+    assertEquals(
+        StatusEnum.FAILED,
+        testItemRepository.findById(updatedItem.get().getParentId()).get().getItemResults()
+            .getStatus()
+    );
+
+    Launch launch = launchRepository.findById(updatedItem.get().getLaunchId()).get();
+    assertEquals(StatusEnum.FAILED, launch.getStatus());
+
+    verify(messageBus, times(2)).publishActivity(ArgumentMatchers.any());
+  }
+
+  @Sql("/db/test-item/item-change-status-from-passed.sql")
+  @Test
+  void changeStatusFromPassedToSkipped() throws Exception {
+    UpdateTestItemRQ request = new UpdateTestItemRQ();
+    request.setStatus("skipped");
+
+    mockMvc.perform(put(SUPERADMIN_PROJECT_BASE_URL + "/item/6/update").with(
+            token(oAuthHelper.getSuperadminToken())).contentType(APPLICATION_JSON)
+        .content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
+
+    Optional<TestItem> updatedItem = testItemRepository.findById(6L);
+    assertTrue(updatedItem.isPresent());
+    assertEquals(StatusEnum.SKIPPED, updatedItem.get().getItemResults().getStatus());
+    assertEquals(
+        TestItemIssueGroup.TO_INVESTIGATE,
+        updatedItem.get().getItemResults().getIssue().getIssueType().getIssueGroup()
+            .getTestItemIssueGroup()
+    );
+    assertEquals(
+        StatusEnum.FAILED,
+        testItemRepository.findById(updatedItem.get().getParentId()).get().getItemResults()
+            .getStatus()
+    );
+
+    Launch launch = launchRepository.findById(updatedItem.get().getLaunchId()).get();
+    assertEquals(StatusEnum.FAILED, launch.getStatus());
+
+    verify(messageBus, times(2)).publishActivity(ArgumentMatchers.any());
+  }
+
+  @Sql("/db/test-item/item-change-status-from-passed.sql")
+  @Test
+  void changeStatusFromPassedToSkippedWithoutIssue() throws Exception {
+    UpdateTestItemRQ request = new UpdateTestItemRQ();
+    request.setStatus("skipped");
+
+    mockMvc.perform(put(SUPERADMIN_PROJECT_BASE_URL + "/item/9/update").with(
+            token(oAuthHelper.getSuperadminToken())).contentType(APPLICATION_JSON)
+        .content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
+
+    Optional<TestItem> updatedItem = testItemRepository.findById(9L);
+    assertTrue(updatedItem.isPresent());
+    assertEquals(StatusEnum.SKIPPED, updatedItem.get().getItemResults().getStatus());
+    assertNull(updatedItem.get().getItemResults().getIssue());
+    assertEquals(
+        StatusEnum.FAILED,
+        testItemRepository.findById(updatedItem.get().getParentId()).get().getItemResults()
+            .getStatus()
+    );
+
+    Launch launch = launchRepository.findById(updatedItem.get().getLaunchId()).get();
+    assertEquals(StatusEnum.FAILED, launch.getStatus());
+
+    verify(messageBus, times(2)).publishActivity(ArgumentMatchers.any());
+  }
+
+  @Sql("/db/test-item/item-change-status-from-passed.sql")
+  @Test
+  void finishChildTestItemWithFailedStatusWithFinishedParentWithPassedStatus() throws Exception {
+    FinishTestItemRQ rq = new FinishTestItemRQ();
+    rq.setLaunchUuid(UUID.randomUUID().toString());
+    rq.setEndTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+    rq.setStatus("FAILED");
+    Issue issue = new Issue();
+    issue.setIssueType("pb001");
+    rq.setIssue(issue);
+
+    Optional<TestItem> updatedItem = testItemRepository.findById(11L);
+    assertTrue(updatedItem.isPresent());
+    assertEquals(StatusEnum.IN_PROGRESS, updatedItem.get().getItemResults().getStatus());
+
+    mockMvc.perform(put(SUPERADMIN_PROJECT_BASE_URL + "/item/uuid_s_2_9").content(
+            objectMapper.writeValueAsBytes(rq)).contentType(APPLICATION_JSON)
+        .with(token(oAuthHelper.getSuperadminToken()))).andExpect(status().isOk());
+
+    updatedItem = testItemRepository.findById(11L);
+    assertTrue(updatedItem.isPresent());
+    assertEquals(StatusEnum.FAILED, updatedItem.get().getItemResults().getStatus());
+    assertEquals(
+        TestItemIssueGroup.PRODUCT_BUG,
+        updatedItem.get().getItemResults().getIssue().getIssueType().getIssueGroup()
+            .getTestItemIssueGroup()
+    );
+    assertEquals(
+        StatusEnum.PASSED,
+        testItemRepository.findById(updatedItem.get().getParentId()).get().getItemResults()
+            .getStatus()
+    );
+
+    Launch launch = launchRepository.findById(updatedItem.get().getLaunchId()).get();
+    assertEquals(StatusEnum.PASSED, launch.getStatus());
+  }
+
+  @Sql("/db/test-item/item-change-status-from-failed.sql")
+  @Test
+  void changeStatusFromFailedToPassed() throws Exception {
+    UpdateTestItemRQ request = new UpdateTestItemRQ();
+    request.setStatus("passed");
+
+    mockMvc.perform(put(SUPERADMIN_PROJECT_BASE_URL + "/item/6/update").with(
+            token(oAuthHelper.getSuperadminToken())).contentType(APPLICATION_JSON)
+        .content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
+
+    Optional<TestItem> updatedItem = testItemRepository.findById(6L);
+    assertTrue(updatedItem.isPresent());
+    assertEquals(StatusEnum.PASSED, updatedItem.get().getItemResults().getStatus());
+    assertNull(updatedItem.get().getItemResults().getIssue());
+    assertEquals(
+        StatusEnum.PASSED,
+        testItemRepository.findById(updatedItem.get().getParentId()).get().getItemResults()
+            .getStatus()
+    );
+
+    Launch launch = launchRepository.findById(updatedItem.get().getLaunchId()).get();
+    assertEquals(StatusEnum.PASSED, launch.getStatus());
+
+    verify(messageBus, times(2)).publishActivity(ArgumentMatchers.any());
+  }
+
+  @Sql("/db/test-item/item-change-status-from-failed.sql")
+  @Test
+  void changeStatusFromFailedToSkipped() throws Exception {
+    UpdateTestItemRQ request = new UpdateTestItemRQ();
+    request.setStatus("skipped");
+
+    mockMvc.perform(put(SUPERADMIN_PROJECT_BASE_URL + "/item/6/update").with(
+            token(oAuthHelper.getSuperadminToken())).contentType(APPLICATION_JSON)
+        .content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
+
+    Optional<TestItem> updatedItem = testItemRepository.findById(6L);
+    assertTrue(updatedItem.isPresent());
+    assertEquals(StatusEnum.SKIPPED, updatedItem.get().getItemResults().getStatus());
+    assertEquals(
+        TestItemIssueGroup.AUTOMATION_BUG,
+        updatedItem.get().getItemResults().getIssue().getIssueType().getIssueGroup()
+            .getTestItemIssueGroup()
+    );
+    assertEquals(
+        StatusEnum.FAILED,
+        testItemRepository.findById(updatedItem.get().getParentId()).get().getItemResults()
+            .getStatus()
+    );
+
+    Launch launch = launchRepository.findById(updatedItem.get().getLaunchId()).get();
+    assertEquals(StatusEnum.FAILED, launch.getStatus());
+
+    verify(messageBus, times(1)).publishActivity(ArgumentMatchers.any());
+  }
+
+  @Sql("/db/test-item/item-change-status-from-skipped.sql")
+  @Test
+  void changeStatusFromSkippedToFailed() throws Exception {
+    UpdateTestItemRQ request = new UpdateTestItemRQ();
+    request.setStatus("failed");
+
+    mockMvc.perform(put(SUPERADMIN_PROJECT_BASE_URL + "/item/6/update").with(
+            token(oAuthHelper.getSuperadminToken())).contentType(APPLICATION_JSON)
+        .content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
+
+    Optional<TestItem> updatedItem = testItemRepository.findById(6L);
+    assertTrue(updatedItem.isPresent());
+    assertEquals(StatusEnum.FAILED, updatedItem.get().getItemResults().getStatus());
+    assertEquals(
+        TestItemIssueGroup.TO_INVESTIGATE,
+        updatedItem.get().getItemResults().getIssue().getIssueType().getIssueGroup()
+            .getTestItemIssueGroup()
+    );
+    assertEquals(
+        StatusEnum.FAILED,
+        testItemRepository.findById(updatedItem.get().getParentId()).get().getItemResults()
+            .getStatus()
+    );
+
+    Launch launch = launchRepository.findById(updatedItem.get().getLaunchId()).get();
+    assertEquals(StatusEnum.FAILED, launch.getStatus());
+
+    verify(messageBus, times(1)).publishActivity(ArgumentMatchers.any());
+  }
+
+  @Sql("/db/test-item/item-change-status-from-skipped.sql")
+  @Test
+  void changeStatusFromSkippedToPassed() throws Exception {
+    UpdateTestItemRQ request = new UpdateTestItemRQ();
+    request.setStatus("passed");
+
+    mockMvc.perform(put(SUPERADMIN_PROJECT_BASE_URL + "/item/6/update").with(
+            token(oAuthHelper.getSuperadminToken())).contentType(APPLICATION_JSON)
+        .content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
+
+    Optional<TestItem> updatedItem = testItemRepository.findById(6L);
+    assertTrue(updatedItem.isPresent());
+    assertEquals(StatusEnum.PASSED, updatedItem.get().getItemResults().getStatus());
+    assertNull(updatedItem.get().getItemResults().getIssue());
+    assertEquals(
+        StatusEnum.PASSED,
+        testItemRepository.findById(updatedItem.get().getParentId()).get().getItemResults()
+            .getStatus()
+    );
+
+    Launch launch = launchRepository.findById(updatedItem.get().getLaunchId()).get();
+    assertEquals(StatusEnum.PASSED, launch.getStatus());
+
+    verify(messageBus, times(2)).publishActivity(ArgumentMatchers.any());
+  }
+
+  @Sql("/db/test-item/item-change-status-from-interrupted.sql")
+  @Test
+  void changeStatusFromInterruptedToPassed() throws Exception {
+    UpdateTestItemRQ request = new UpdateTestItemRQ();
+    request.setStatus("passed");
+
+    mockMvc.perform(put(SUPERADMIN_PROJECT_BASE_URL + "/item/6/update").with(
+            token(oAuthHelper.getSuperadminToken())).contentType(APPLICATION_JSON)
+        .content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
+
+    Optional<TestItem> updatedItem = testItemRepository.findById(6L);
+    assertTrue(updatedItem.isPresent());
+    assertEquals(StatusEnum.PASSED, updatedItem.get().getItemResults().getStatus());
+    assertNull(updatedItem.get().getItemResults().getIssue());
+    assertEquals(
+        StatusEnum.PASSED,
+        testItemRepository.findById(updatedItem.get().getParentId()).get().getItemResults()
+            .getStatus()
+    );
+
+    Launch launch = launchRepository.findById(updatedItem.get().getLaunchId()).get();
+    assertEquals(StatusEnum.PASSED, launch.getStatus());
+
+    verify(messageBus, times(2)).publishActivity(ArgumentMatchers.any());
+  }
+
+  @Sql("/db/test-item/item-change-status-from-interrupted.sql")
+  @Test
+  void changeStatusFromInterruptedToSkipped() throws Exception {
+    UpdateTestItemRQ request = new UpdateTestItemRQ();
+    request.setStatus("skipped");
+
+    mockMvc.perform(put(SUPERADMIN_PROJECT_BASE_URL + "/item/6/update").with(
+            token(oAuthHelper.getSuperadminToken())).contentType(APPLICATION_JSON)
+        .content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
+
+    Optional<TestItem> updatedItem = testItemRepository.findById(6L);
+    assertTrue(updatedItem.isPresent());
+    assertEquals(StatusEnum.SKIPPED, updatedItem.get().getItemResults().getStatus());
+    assertEquals(
+        TestItemIssueGroup.TO_INVESTIGATE,
+        updatedItem.get().getItemResults().getIssue().getIssueType().getIssueGroup()
+            .getTestItemIssueGroup()
+    );
+    assertEquals(
+        StatusEnum.FAILED,
+        testItemRepository.findById(updatedItem.get().getParentId()).get().getItemResults()
+            .getStatus()
+    );
+
+    Launch launch = launchRepository.findById(updatedItem.get().getLaunchId()).get();
+    assertEquals(StatusEnum.FAILED, launch.getStatus());
+
+    verify(messageBus, times(1)).publishActivity(ArgumentMatchers.any());
+  }
+
+  @Sql("/db/test-item/item-change-status-from-interrupted.sql")
+  @Test
+  void changeStatusFromInterruptedToFailed() throws Exception {
+    UpdateTestItemRQ request = new UpdateTestItemRQ();
+    request.setStatus("failed");
+
+    mockMvc.perform(put(SUPERADMIN_PROJECT_BASE_URL + "/item/6/update").with(
+            token(oAuthHelper.getSuperadminToken())).contentType(APPLICATION_JSON)
+        .content(objectMapper.writeValueAsBytes(request))).andExpect(status().isOk());
+
+    Optional<TestItem> updatedItem = testItemRepository.findById(6L);
+    assertTrue(updatedItem.isPresent());
+    assertEquals(StatusEnum.FAILED, updatedItem.get().getItemResults().getStatus());
+    assertEquals(
+        TestItemIssueGroup.TO_INVESTIGATE,
+        updatedItem.get().getItemResults().getIssue().getIssueType().getIssueGroup()
+            .getTestItemIssueGroup()
+    );
+    assertEquals(
+        StatusEnum.FAILED,
+        testItemRepository.findById(updatedItem.get().getParentId()).get().getItemResults()
+            .getStatus()
+    );
+
+    Launch launch = launchRepository.findById(updatedItem.get().getLaunchId()).get();
+    assertEquals(StatusEnum.FAILED, launch.getStatus());
+
+    verify(messageBus, times(1)).publishActivity(ArgumentMatchers.any());
+  }
+
+  @Test
+  void changeStatusNegative() throws Exception {
+    UpdateTestItemRQ request = new UpdateTestItemRQ();
+    request.setStatus("failed");
+
+    mockMvc.perform(put(SUPERADMIN_PROJECT_BASE_URL + "/item/5/update").with(
+            token(oAuthHelper.getSuperadminToken())).contentType(APPLICATION_JSON)
+        .content(objectMapper.writeValueAsBytes(request))).andExpect(status().is(400));
+  }
+
+  @Test
+  void bulkUpdateItemAttributes() throws Exception {
+    BulkInfoUpdateRQ request = new BulkInfoUpdateRQ();
+    List<Long> launchIds = Arrays.asList(1L, 2L, 3L, 4L, 5L, 6L);
+    request.setIds(launchIds);
+    BulkInfoUpdateRQ.Description description = new BulkInfoUpdateRQ.Description();
+    description.setAction(BulkInfoUpdateRQ.Action.CREATE);
+    String comment = "created";
+    description.setComment(comment);
+    request.setDescription(description);
+    UpdateItemAttributeRQ updateItemAttributeRQ = new UpdateItemAttributeRQ();
+    updateItemAttributeRQ.setAction(BulkInfoUpdateRQ.Action.UPDATE);
+    updateItemAttributeRQ.setFrom(new ItemAttributeResource("testKey", "testValue"));
+    updateItemAttributeRQ.setTo(new ItemAttributeResource("updatedKey", "updatedValue"));
+    request.setAttributes(Lists.newArrayList(updateItemAttributeRQ));
+
+    mockMvc.perform(
+            put(DEFAULT_PROJECT_BASE_URL + "/item/info").with(token(oAuthHelper.getDefaultToken()))
+                .contentType(APPLICATION_JSON).content(objectMapper.writeValueAsBytes(request)))
+        .andExpect(status().isOk());
+
+    List<TestItem> items = testItemRepository.findAllById(launchIds);
+    items.forEach(it -> testItemRepository.refresh(it));
+
+    items.forEach(it -> {
+      assertTrue(it.getAttributes().stream().noneMatch(
+          attr -> "testKey".equals(attr.getKey()) && attr.getValue().equals("testValue")
+              && !attr.isSystem()));
+      assertTrue(it.getAttributes().stream().anyMatch(
+          attr -> "updatedKey".equals(attr.getKey()) && attr.getValue().equals("updatedValue")
+              && !attr.isSystem()));
+      assertEquals(comment, it.getDescription());
+    });
+  }
+
+  @Test
+  void bulkCreateAttributes() throws Exception {
+    BulkInfoUpdateRQ request = new BulkInfoUpdateRQ();
+    List<Long> launchIds = Arrays.asList(1L, 2L, 3L, 4L, 5L, 6L);
+    request.setIds(launchIds);
+    BulkInfoUpdateRQ.Description description = new BulkInfoUpdateRQ.Description();
+    description.setAction(BulkInfoUpdateRQ.Action.UPDATE);
+    String comment = "updated";
+    description.setComment(comment);
+    request.setDescription(description);
+    UpdateItemAttributeRQ updateItemAttributeRQ = new UpdateItemAttributeRQ();
+    updateItemAttributeRQ.setAction(BulkInfoUpdateRQ.Action.CREATE);
+    updateItemAttributeRQ.setTo(new ItemAttributeResource("createdKey", "createdValue"));
+    request.setAttributes(Lists.newArrayList(updateItemAttributeRQ));
+
+    mockMvc.perform(
+            put(DEFAULT_PROJECT_BASE_URL + "/item/info").with(token(oAuthHelper.getDefaultToken()))
+                .contentType(APPLICATION_JSON).content(objectMapper.writeValueAsBytes(request)))
+        .andExpect(status().isOk());
+
+    List<TestItem> items = testItemRepository.findAllById(launchIds);
+    items.forEach(it -> testItemRepository.refresh(it));
+
+    items.forEach(it -> {
+      assertTrue(it.getAttributes().stream().anyMatch(
+          attr -> "createdKey".equals(attr.getKey()) && attr.getValue().equals("createdValue")
+              && !attr.isSystem()));
+      assertTrue(
+          it.getDescription().length() > comment.length() && it.getDescription().contains(comment));
+    });
+  }
+
+  @Test
+  void bulkDeleteAttributes() throws Exception {
+    BulkInfoUpdateRQ request = new BulkInfoUpdateRQ();
+    List<Long> launchIds = Arrays.asList(1L, 2L, 3L, 4L, 5L, 6L);
+    request.setIds(launchIds);
+    BulkInfoUpdateRQ.Description description = new BulkInfoUpdateRQ.Description();
+    description.setAction(BulkInfoUpdateRQ.Action.CREATE);
+    String comment = "created";
+    description.setComment(comment);
+    request.setDescription(description);
+    UpdateItemAttributeRQ updateItemAttributeRQ = new UpdateItemAttributeRQ();
+    updateItemAttributeRQ.setAction(BulkInfoUpdateRQ.Action.DELETE);
+    updateItemAttributeRQ.setFrom(new ItemAttributeResource("testKey", "testValue"));
+    request.setAttributes(Lists.newArrayList(updateItemAttributeRQ));
+
+    mockMvc.perform(
+            put(DEFAULT_PROJECT_BASE_URL + "/item/info").with(token(oAuthHelper.getDefaultToken()))
+                .contentType(APPLICATION_JSON).content(objectMapper.writeValueAsBytes(request)))
+        .andExpect(status().isOk());
+
+    List<TestItem> items = testItemRepository.findAllById(launchIds);
+    items.forEach(it -> testItemRepository.refresh(it));
+
+    items.forEach(it -> {
+      assertTrue(it.getAttributes().stream().noneMatch(
+          attr -> "testKey".equals(attr.getKey()) && attr.getValue().equals("testValue")
+              && !attr.isSystem()));
+      assertEquals(comment, it.getDescription());
+    });
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/controller/TestItemControllerValidationTest.java b/src/test/java/com/epam/ta/reportportal/ws/controller/TestItemControllerValidationTest.java
index 30c3dd001c..ac34e211de 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/controller/TestItemControllerValidationTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/controller/TestItemControllerValidationTest.java
@@ -16,6 +16,18 @@
 
 package com.epam.ta.reportportal.ws.controller;
 
+import static com.epam.ta.reportportal.ws.controller.constants.ValidationTestsConstants.FIELD_NAME_IS_BLANK_MESSAGE;
+import static com.epam.ta.reportportal.ws.controller.constants.ValidationTestsConstants.FIELD_NAME_IS_NULL_MESSAGE;
+import static com.epam.ta.reportportal.ws.controller.constants.ValidationTestsConstants.INCORRECT_REQUEST_MESSAGE;
+import static com.epam.ta.reportportal.ws.controller.constants.ValidationTestsConstants.WHITESPACES_NAME_VALUE;
+import static com.epam.ta.reportportal.ws.model.ErrorType.INCORRECT_REQUEST;
+import static org.apache.commons.lang3.StringUtils.EMPTY;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.springframework.http.MediaType.APPLICATION_JSON;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
 import com.epam.ta.reportportal.ws.BaseMvcTest;
 import com.epam.ta.reportportal.ws.model.ErrorRS;
 import com.epam.ta.reportportal.ws.model.StartTestItemRQ;
@@ -25,10 +37,6 @@
 import com.epam.ta.reportportal.ws.model.item.LinkExternalIssueRQ;
 import com.epam.ta.reportportal.ws.model.item.UnlinkExternalIssueRQ;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.test.web.servlet.MvcResult;
-
 import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.util.Date;
@@ -36,319 +44,353 @@
 import java.util.UUID;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
-
-import static com.epam.ta.reportportal.ws.controller.constants.ValidationTestsConstants.*;
-import static com.epam.ta.reportportal.ws.model.ErrorType.INCORRECT_REQUEST;
-import static org.apache.commons.lang3.StringUtils.EMPTY;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.springframework.http.MediaType.APPLICATION_JSON;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.web.servlet.MvcResult;
 
 /**
  * @author <a href="mailto:tatyana_gladysheva@epam.com">Tatyana Gladysheva</a>
  */
 public class TestItemControllerValidationTest extends BaseMvcTest {
 
-	private static final String ITEM_PATH = "/item";
-	private static final String PARENT_ID_PATH = "/555";
-
-	private static final String FIELD_NAME_SIZE_MESSAGE = "Field 'name' should have size from '1' to '1,024'.";
-
-	private static final String LONG_NAME_VALUE = "ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
-			+ "ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
-			+ "ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
-			+ "ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
-			+ "ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
-			+ "ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
-			+ "ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
-			+ "ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
-			+ "ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt";
-
-	@Autowired
-	private ObjectMapper objectMapper;
-
-	@Test
-	public void startRootTestItemShouldReturnErrorWhenNameIsNull() throws Exception {
-		//GIVEN
-		StartTestItemRQ startTestItemRQ = prepareTestItem();
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + ITEM_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(startTestItemRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + FIELD_NAME_IS_NULL_MESSAGE, error.getMessage());
-	}
-
-	@Test
-	public void startRootTestItemShouldReturnErrorWhenNameIsEmpty() throws Exception {
-		//GIVEN
-		StartTestItemRQ startTestItemRQ = prepareTestItem();
-		startTestItemRQ.setName(EMPTY);
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + ITEM_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(startTestItemRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " " + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
-	}
-
-	@Test
-	public void startRootTestItemShouldReturnErrorWhenNameConsistsOfWhitespaces() throws Exception {
-		//GIVEN
-		StartTestItemRQ startTestItemRQ = prepareTestItem();
-		startTestItemRQ.setName(WHITESPACES_NAME_VALUE);
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + ITEM_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(startTestItemRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " " + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
-	}
-
-	@Test
-	public void startRootTestItemShouldReturnErrorWhenNameIsGreaterThanOneThousandTwentyFourCharacters() throws Exception {
-		//GIVEN
-		StartTestItemRQ startTestItemRQ = prepareTestItem();
-		startTestItemRQ.setName(LONG_NAME_VALUE);
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + ITEM_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(startTestItemRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
-	}
-
-	@Test
-	public void startChildTestItemShouldReturnErrorWhenNameIsNull() throws Exception {
-		//GIVEN
-		StartTestItemRQ startTestItemRQ = prepareTestItem();
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + ITEM_PATH + PARENT_ID_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(startTestItemRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + FIELD_NAME_IS_NULL_MESSAGE, error.getMessage());
-	}
-
-	@Test
-	public void startChildTestItemShouldReturnErrorWhenNameIsEmpty() throws Exception {
-		//GIVEN
-		StartTestItemRQ startTestItemRQ = prepareTestItem();
-		startTestItemRQ.setName(EMPTY);
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + ITEM_PATH + PARENT_ID_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(startTestItemRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " " + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
-	}
-
-	@Test
-	public void startChildTestItemShouldReturnErrorWhenNameConsistsOfWhitespaces() throws Exception {
-		//GIVEN
-		StartTestItemRQ startTestItemRQ = prepareTestItem();
-		startTestItemRQ.setName(WHITESPACES_NAME_VALUE);
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + ITEM_PATH + PARENT_ID_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(startTestItemRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " " + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
-	}
-
-	@Test
-	public void startChildTestItemShouldReturnErrorWhenNameIsGreaterThanOneThousandTwentyFourCharacters() throws Exception {
-		//GIVEN
-		StartTestItemRQ startTestItemRQ = prepareTestItem();
-		startTestItemRQ.setName(LONG_NAME_VALUE);
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + ITEM_PATH + PARENT_ID_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(startTestItemRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
-	}
-
-	@Test
-	public void shouldReturnBadRequestWhenMoreThan300Issues() throws Exception {
-		//GIVEN
-		final DefineIssueRQ defineIssueRQ = new DefineIssueRQ();
-		defineIssueRQ.setIssues(Stream.generate(() -> {
-			final IssueDefinition issueDefinition = new IssueDefinition();
-			issueDefinition.setId(1L);
-			final Issue issue = new Issue();
-			issue.setComment("comment");
-			issue.setIssueType("ab001");
-			issueDefinition.setIssue(issue);
-			return issueDefinition;
-		}).limit(301).collect(Collectors.toList()));
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + ITEM_PATH).with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(defineIssueRQ))
-				.contentType(APPLICATION_JSON)).andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[Field 'issues' should have size from '0' to '300'.] ",
-				error.getMessage()
-		);
-	}
-
-	@Test
-	public void shouldReturnBadRequestWhenMoreThan300IssuesToLink() throws Exception {
-		//GIVEN
-		final LinkExternalIssueRQ linkExternalIssueRQ = new LinkExternalIssueRQ();
-		final Issue.ExternalSystemIssue externalSystemIssue = getExternalSystemIssue();
-		linkExternalIssueRQ.setIssues(Stream.generate(() -> externalSystemIssue).limit(301).collect(Collectors.toList()));
-		linkExternalIssueRQ.setTestItemIds(List.of(1L));
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(put(
-				DEFAULT_PROJECT_BASE_URL + ITEM_PATH + "/issue/link").with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(linkExternalIssueRQ))
-				.contentType(APPLICATION_JSON)).andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[Field 'issues' should have size from '0' to '300'.] ",
-				error.getMessage()
-		);
-	}
-
-	private Issue.ExternalSystemIssue getExternalSystemIssue() {
-		final Issue.ExternalSystemIssue externalSystemIssue = new Issue.ExternalSystemIssue();
-		externalSystemIssue.setBtsProject("prj");
-		externalSystemIssue.setUrl("url");
-		externalSystemIssue.setBtsUrl("btsUrl");
-		externalSystemIssue.setSubmitDate(123L);
-		externalSystemIssue.setTicketId("id");
-		return externalSystemIssue;
-	}
-
-	@Test
-	public void shouldReturnBadRequestWhenMoreThan300ItemIdsToLink() throws Exception {
-		//GIVEN
-		final LinkExternalIssueRQ linkExternalIssueRQ = new LinkExternalIssueRQ();
-		final Issue.ExternalSystemIssue externalSystemIssue = getExternalSystemIssue();
-		linkExternalIssueRQ.setIssues(List.of(externalSystemIssue));
-		final List<Long> itemIds = Stream.generate(() -> 1L).limit(301).collect(Collectors.toList());
-		linkExternalIssueRQ.setTestItemIds(itemIds);
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(put(
-				DEFAULT_PROJECT_BASE_URL + ITEM_PATH + "/issue/link").with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(linkExternalIssueRQ))
-				.contentType(APPLICATION_JSON)).andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[Field 'testItemIds' should have size from '0' to '300'.] ",
-				error.getMessage()
-		);
-	}
-
-	@Test
-	public void shouldReturnBadRequestWhenMoreThan300TicketsToUnlink() throws Exception {
-		//GIVEN
-		final UnlinkExternalIssueRQ unlinkExternalIssueRQ = new UnlinkExternalIssueRQ();
-		unlinkExternalIssueRQ.setTicketIds(Stream.generate(() -> "id").limit(301).collect(Collectors.toList()));
-		unlinkExternalIssueRQ.setTestItemIds(List.of(1L));
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(put(
-				DEFAULT_PROJECT_BASE_URL + ITEM_PATH + "/issue/unlink").with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(unlinkExternalIssueRQ))
-				.contentType(APPLICATION_JSON)).andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[Field 'ticketIds' should have size from '0' to '300'.] ",
-				error.getMessage()
-		);
-	}
-
-	@Test
-	public void shouldReturnBadRequestWhenMoreThan300ItemIdsToUnlink() throws Exception {
-		//GIVEN
-		final UnlinkExternalIssueRQ unlinkExternalIssueRQ = new UnlinkExternalIssueRQ();
-		unlinkExternalIssueRQ.setTicketIds(List.of("id"));
-		unlinkExternalIssueRQ.setTestItemIds(Stream.generate(() -> 1L).limit(301).collect(Collectors.toList()));
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(put(
-				DEFAULT_PROJECT_BASE_URL + ITEM_PATH + "/issue/unlink").with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(unlinkExternalIssueRQ))
-				.contentType(APPLICATION_JSON)).andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[Field 'testItemIds' should have size from '0' to '300'.] ",
-				error.getMessage()
-		);
-	}
-
-	private StartTestItemRQ prepareTestItem() {
-		StartTestItemRQ startTestItemRQ = new StartTestItemRQ();
-		startTestItemRQ.setLaunchUuid("a7b66ef2-db30-4db7-94df-f5f7786b398a");
-		startTestItemRQ.setType("SUITE");
-		startTestItemRQ.setUniqueId(UUID.randomUUID().toString());
-		startTestItemRQ.setStartTime(Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
-		return startTestItemRQ;
-	}
+  private static final String ITEM_PATH = "/item";
+  private static final String PARENT_ID_PATH = "/555";
+
+  private static final String FIELD_NAME_SIZE_MESSAGE = "Field 'name' should have size from '1' to '1,024'.";
+
+  private static final String LONG_NAME_VALUE =
+      "ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
+          + "ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
+          + "ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
+          + "ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
+          + "ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
+          + "ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
+          + "ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
+          + "ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
+          + "ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt";
+
+  @Autowired
+  private ObjectMapper objectMapper;
+
+  @Test
+  public void startRootTestItemShouldReturnErrorWhenNameIsNull() throws Exception {
+    //GIVEN
+    StartTestItemRQ startTestItemRQ = prepareTestItem();
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + ITEM_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(startTestItemRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + FIELD_NAME_IS_NULL_MESSAGE, error.getMessage());
+  }
+
+  @Test
+  public void startRootTestItemShouldReturnErrorWhenNameIsEmpty() throws Exception {
+    //GIVEN
+    StartTestItemRQ startTestItemRQ = prepareTestItem();
+    startTestItemRQ.setName(EMPTY);
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + ITEM_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(startTestItemRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " "
+        + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
+  }
+
+  @Test
+  public void startRootTestItemShouldReturnErrorWhenNameConsistsOfWhitespaces() throws Exception {
+    //GIVEN
+    StartTestItemRQ startTestItemRQ = prepareTestItem();
+    startTestItemRQ.setName(WHITESPACES_NAME_VALUE);
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + ITEM_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(startTestItemRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " "
+        + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
+  }
+
+  @Test
+  public void startRootTestItemShouldReturnErrorWhenNameIsGreaterThanOneThousandTwentyFourCharacters()
+      throws Exception {
+    //GIVEN
+    StartTestItemRQ startTestItemRQ = prepareTestItem();
+    startTestItemRQ.setName(LONG_NAME_VALUE);
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + ITEM_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(startTestItemRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_SIZE_MESSAGE + "] ",
+        error.getMessage());
+  }
+
+  @Test
+  public void startChildTestItemShouldReturnErrorWhenNameIsNull() throws Exception {
+    //GIVEN
+    StartTestItemRQ startTestItemRQ = prepareTestItem();
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(
+            post(DEFAULT_PROJECT_BASE_URL + ITEM_PATH + PARENT_ID_PATH)
+                .with(token(oAuthHelper.getDefaultToken()))
+                .content(objectMapper.writeValueAsBytes(startTestItemRQ))
+                .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + FIELD_NAME_IS_NULL_MESSAGE, error.getMessage());
+  }
+
+  @Test
+  public void startChildTestItemShouldReturnErrorWhenNameIsEmpty() throws Exception {
+    //GIVEN
+    StartTestItemRQ startTestItemRQ = prepareTestItem();
+    startTestItemRQ.setName(EMPTY);
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(
+            post(DEFAULT_PROJECT_BASE_URL + ITEM_PATH + PARENT_ID_PATH)
+                .with(token(oAuthHelper.getDefaultToken()))
+                .content(objectMapper.writeValueAsBytes(startTestItemRQ))
+                .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " "
+        + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
+  }
+
+  @Test
+  public void startChildTestItemShouldReturnErrorWhenNameConsistsOfWhitespaces() throws Exception {
+    //GIVEN
+    StartTestItemRQ startTestItemRQ = prepareTestItem();
+    startTestItemRQ.setName(WHITESPACES_NAME_VALUE);
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(
+            post(DEFAULT_PROJECT_BASE_URL + ITEM_PATH + PARENT_ID_PATH)
+                .with(token(oAuthHelper.getDefaultToken()))
+                .content(objectMapper.writeValueAsBytes(startTestItemRQ))
+                .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " "
+        + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
+  }
+
+  @Test
+  public void startChildTestItemShouldReturnErrorWhenNameIsGreaterThanOneThousandTwentyFourCharacters()
+      throws Exception {
+    //GIVEN
+    StartTestItemRQ startTestItemRQ = prepareTestItem();
+    startTestItemRQ.setName(LONG_NAME_VALUE);
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(
+            post(DEFAULT_PROJECT_BASE_URL + ITEM_PATH + PARENT_ID_PATH)
+                .with(token(oAuthHelper.getDefaultToken()))
+                .content(objectMapper.writeValueAsBytes(startTestItemRQ))
+                .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_SIZE_MESSAGE + "] ",
+        error.getMessage());
+  }
+
+  @Test
+  public void shouldReturnBadRequestWhenMoreThan300Issues() throws Exception {
+    //GIVEN
+    final DefineIssueRQ defineIssueRQ = new DefineIssueRQ();
+    defineIssueRQ.setIssues(Stream.generate(() -> {
+      final IssueDefinition issueDefinition = new IssueDefinition();
+      issueDefinition.setId(1L);
+      final Issue issue = new Issue();
+      issue.setComment("comment");
+      issue.setIssueType("ab001");
+      issueDefinition.setIssue(issue);
+      return issueDefinition;
+    }).limit(301).collect(Collectors.toList()));
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(
+        put(DEFAULT_PROJECT_BASE_URL + ITEM_PATH).with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(defineIssueRQ))
+            .contentType(APPLICATION_JSON)).andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(
+        INCORRECT_REQUEST_MESSAGE + "[Field 'issues' should have size from '0' to '300'.] ",
+        error.getMessage()
+    );
+  }
+
+  @Test
+  public void shouldReturnBadRequestWhenMoreThan300IssuesToLink() throws Exception {
+    //GIVEN
+    final LinkExternalIssueRQ linkExternalIssueRQ = new LinkExternalIssueRQ();
+    final Issue.ExternalSystemIssue externalSystemIssue = getExternalSystemIssue();
+    linkExternalIssueRQ.setIssues(
+        Stream.generate(() -> externalSystemIssue).limit(301).collect(Collectors.toList()));
+    linkExternalIssueRQ.setTestItemIds(List.of(1L));
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(put(
+        DEFAULT_PROJECT_BASE_URL + ITEM_PATH + "/issue/link").with(
+            token(oAuthHelper.getDefaultToken()))
+        .content(objectMapper.writeValueAsBytes(linkExternalIssueRQ))
+        .contentType(APPLICATION_JSON)).andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(
+        INCORRECT_REQUEST_MESSAGE + "[Field 'issues' should have size from '0' to '300'.] ",
+        error.getMessage()
+    );
+  }
+
+  private Issue.ExternalSystemIssue getExternalSystemIssue() {
+    final Issue.ExternalSystemIssue externalSystemIssue = new Issue.ExternalSystemIssue();
+    externalSystemIssue.setBtsProject("prj");
+    externalSystemIssue.setUrl("url");
+    externalSystemIssue.setBtsUrl("btsUrl");
+    externalSystemIssue.setSubmitDate(123L);
+    externalSystemIssue.setTicketId("id");
+    return externalSystemIssue;
+  }
+
+  @Test
+  public void shouldReturnBadRequestWhenMoreThan300ItemIdsToLink() throws Exception {
+    //GIVEN
+    final LinkExternalIssueRQ linkExternalIssueRQ = new LinkExternalIssueRQ();
+    final Issue.ExternalSystemIssue externalSystemIssue = getExternalSystemIssue();
+    linkExternalIssueRQ.setIssues(List.of(externalSystemIssue));
+    final List<Long> itemIds = Stream.generate(() -> 1L).limit(301).collect(Collectors.toList());
+    linkExternalIssueRQ.setTestItemIds(itemIds);
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(put(
+        DEFAULT_PROJECT_BASE_URL + ITEM_PATH + "/issue/link").with(
+            token(oAuthHelper.getDefaultToken()))
+        .content(objectMapper.writeValueAsBytes(linkExternalIssueRQ))
+        .contentType(APPLICATION_JSON)).andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(
+        INCORRECT_REQUEST_MESSAGE + "[Field 'testItemIds' should have size from '0' to '300'.] ",
+        error.getMessage()
+    );
+  }
+
+  @Test
+  public void shouldReturnBadRequestWhenMoreThan300TicketsToUnlink() throws Exception {
+    //GIVEN
+    final UnlinkExternalIssueRQ unlinkExternalIssueRQ = new UnlinkExternalIssueRQ();
+    unlinkExternalIssueRQ.setTicketIds(
+        Stream.generate(() -> "id").limit(301).collect(Collectors.toList()));
+    unlinkExternalIssueRQ.setTestItemIds(List.of(1L));
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(put(
+        DEFAULT_PROJECT_BASE_URL + ITEM_PATH + "/issue/unlink").with(
+            token(oAuthHelper.getDefaultToken()))
+        .content(objectMapper.writeValueAsBytes(unlinkExternalIssueRQ))
+        .contentType(APPLICATION_JSON)).andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(
+        INCORRECT_REQUEST_MESSAGE + "[Field 'ticketIds' should have size from '0' to '300'.] ",
+        error.getMessage()
+    );
+  }
+
+  @Test
+  public void shouldReturnBadRequestWhenMoreThan300ItemIdsToUnlink() throws Exception {
+    //GIVEN
+    final UnlinkExternalIssueRQ unlinkExternalIssueRQ = new UnlinkExternalIssueRQ();
+    unlinkExternalIssueRQ.setTicketIds(List.of("id"));
+    unlinkExternalIssueRQ.setTestItemIds(
+        Stream.generate(() -> 1L).limit(301).collect(Collectors.toList()));
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(put(
+        DEFAULT_PROJECT_BASE_URL + ITEM_PATH + "/issue/unlink").with(
+            token(oAuthHelper.getDefaultToken()))
+        .content(objectMapper.writeValueAsBytes(unlinkExternalIssueRQ))
+        .contentType(APPLICATION_JSON)).andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(
+        INCORRECT_REQUEST_MESSAGE + "[Field 'testItemIds' should have size from '0' to '300'.] ",
+        error.getMessage()
+    );
+  }
+
+  private StartTestItemRQ prepareTestItem() {
+    StartTestItemRQ startTestItemRQ = new StartTestItemRQ();
+    startTestItemRQ.setLaunchUuid("a7b66ef2-db30-4db7-94df-f5f7786b398a");
+    startTestItemRQ.setType("SUITE");
+    startTestItemRQ.setUniqueId(UUID.randomUUID().toString());
+    startTestItemRQ.setStartTime(
+        Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant()));
+    return startTestItemRQ;
+  }
 }
diff --git a/src/test/java/com/epam/ta/reportportal/ws/controller/UserFilterControllerValidationTest.java b/src/test/java/com/epam/ta/reportportal/ws/controller/UserFilterControllerValidationTest.java
index 209cdf62d4..def3e3e20b 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/controller/UserFilterControllerValidationTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/controller/UserFilterControllerValidationTest.java
@@ -16,6 +16,22 @@
 
 package com.epam.ta.reportportal.ws.controller;
 
+import static com.epam.ta.reportportal.ws.controller.constants.ValidationTestsConstants.FIELD_NAME_IS_BLANK_MESSAGE;
+import static com.epam.ta.reportportal.ws.controller.constants.ValidationTestsConstants.FIELD_NAME_IS_NULL_MESSAGE;
+import static com.epam.ta.reportportal.ws.controller.constants.ValidationTestsConstants.FIELD_NAME_SIZE_MESSAGE_WITH_FORMAT;
+import static com.epam.ta.reportportal.ws.controller.constants.ValidationTestsConstants.ID_PATH;
+import static com.epam.ta.reportportal.ws.controller.constants.ValidationTestsConstants.INCORRECT_REQUEST_MESSAGE;
+import static com.epam.ta.reportportal.ws.controller.constants.ValidationTestsConstants.LONG_NAME_VALUE;
+import static com.epam.ta.reportportal.ws.controller.constants.ValidationTestsConstants.SHORT_NAME_VALUE;
+import static com.epam.ta.reportportal.ws.controller.constants.ValidationTestsConstants.WHITESPACES_NAME_VALUE;
+import static com.epam.ta.reportportal.ws.model.ErrorType.INCORRECT_REQUEST;
+import static org.apache.commons.lang3.StringUtils.EMPTY;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.springframework.http.MediaType.APPLICATION_JSON;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
 import com.epam.ta.reportportal.ws.BaseMvcTest;
 import com.epam.ta.reportportal.ws.model.ErrorRS;
 import com.epam.ta.reportportal.ws.model.filter.Order;
@@ -28,228 +44,240 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.test.web.servlet.MvcResult;
 
-import static com.epam.ta.reportportal.ws.controller.constants.ValidationTestsConstants.*;
-import static com.epam.ta.reportportal.ws.model.ErrorType.INCORRECT_REQUEST;
-import static org.apache.commons.lang3.StringUtils.EMPTY;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.springframework.http.MediaType.APPLICATION_JSON;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
 /**
  * @author <a href="mailto:tatyana_gladysheva@epam.com">Tatyana Gladysheva</a>
  */
 public class UserFilterControllerValidationTest extends BaseMvcTest {
 
-	private static final String FILTER_PATH = "/filter";
-
-	private static final String FIELD_NAME_SIZE_MESSAGE = String.format(FIELD_NAME_SIZE_MESSAGE_WITH_FORMAT, 3, 128);
-
-	@Autowired
-	private ObjectMapper objectMapper;
-
-	@Test
-	public void createFilterShouldReturnErrorWhenNameIsNull() throws Exception {
-		//GIVEN
-		UpdateUserFilterRQ userFilterRQ = prepareFilter();
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + FILTER_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(userFilterRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + FIELD_NAME_IS_NULL_MESSAGE, error.getMessage());
-	}
-
-	@Test
-	public void createFilterShouldReturnErrorWhenNameIsEmpty() throws Exception {
-		//GIVEN
-		UpdateUserFilterRQ userFilterRQ = prepareFilter();
-		userFilterRQ.setName(EMPTY);
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + FILTER_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(userFilterRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " " + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
-	}
-
-	@Test
-	public void createFilterShouldReturnErrorWhenNameConsistsOfWhitespaces() throws Exception {
-		//GIVEN
-		UpdateUserFilterRQ userFilterRQ = prepareFilter();
-		userFilterRQ.setName(WHITESPACES_NAME_VALUE);
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + FILTER_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(userFilterRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " " + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
-	}
-
-	@Test
-	public void createFilterShouldReturnErrorWhenNameIsLessThanThreeCharacters() throws Exception {
-		//GIVEN
-		UpdateUserFilterRQ userFilterRQ = prepareFilter();
-		userFilterRQ.setName(SHORT_NAME_VALUE);
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + FILTER_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(userFilterRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
-	}
-
-	@Test
-	public void createFilterShouldReturnErrorWhenNameIsGreaterThanOneHundredAndTwentyEightCharacters() throws Exception {
-		//GIVEN
-		UpdateUserFilterRQ userFilterRQ = prepareFilter();
-		userFilterRQ.setName(LONG_NAME_VALUE);
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + FILTER_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(userFilterRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
-	}
-
-	@Test
-	public void updateFilterShouldReturnErrorWhenNameIsNull() throws Exception {
-		//GIVEN
-		UpdateUserFilterRQ userFilterRQ = prepareFilter();
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + FILTER_PATH + ID_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(userFilterRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + FIELD_NAME_IS_NULL_MESSAGE, error.getMessage());
-	}
-
-	@Test
-	public void updateFilterShouldReturnErrorWhenNameIsEmpty() throws Exception {
-		//GIVEN
-		UpdateUserFilterRQ userFilterRQ = prepareFilter();
-		userFilterRQ.setName(EMPTY);
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + FILTER_PATH + ID_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(userFilterRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " " + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
-	}
-
-	@Test
-	public void updateFilterShouldReturnErrorWhenNameConsistsOfWhitespaces() throws Exception {
-		//GIVEN
-		UpdateUserFilterRQ userFilterRQ = prepareFilter();
-		userFilterRQ.setName(WHITESPACES_NAME_VALUE);
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + FILTER_PATH + ID_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(userFilterRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " " + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
-	}
-
-	@Test
-	public void updateFilterShouldReturnErrorWhenNameIsLessThanThreeCharacters() throws Exception {
-		//GIVEN
-		UpdateUserFilterRQ userFilterRQ = prepareFilter();
-		userFilterRQ.setName(SHORT_NAME_VALUE);
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + FILTER_PATH + ID_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(userFilterRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
-	}
-
-	@Test
-	public void updateFilterShouldReturnErrorWhenNameIsGreaterThanOneHundredAndTwentyEightCharacters() throws Exception {
-		//GIVEN
-		UpdateUserFilterRQ userFilterRQ = prepareFilter();
-		userFilterRQ.setName(LONG_NAME_VALUE);
-
-		//WHEN
-		MvcResult mvcResult = mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + FILTER_PATH + ID_PATH)
-				.with(token(oAuthHelper.getDefaultToken()))
-				.content(objectMapper.writeValueAsBytes(userFilterRQ))
-				.contentType(APPLICATION_JSON))
-				.andExpect(status().isBadRequest()).andReturn();
-
-		//THEN
-		ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), ErrorRS.class);
-		assertEquals(INCORRECT_REQUEST, error.getErrorType());
-		assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
-	}
-
-	private UpdateUserFilterRQ prepareFilter() {
-		UpdateUserFilterRQ userFilterRQ = new UpdateUserFilterRQ();
-		userFilterRQ.setObjectType("Launch");
-
-		Order order = new Order();
-		order.setIsAsc(false);
-		order.setSortingColumnName("startTime");
-
-		userFilterRQ.setOrders(Lists.newArrayList(order));
-
-		userFilterRQ.setDescription("description");
-		userFilterRQ.setConditions(Sets.newHashSet(new UserFilterCondition("name", "cnt", "test")));
-
-		return userFilterRQ;
-	}
+  private static final String FILTER_PATH = "/filter";
+
+  private static final String FIELD_NAME_SIZE_MESSAGE = String.format(
+      FIELD_NAME_SIZE_MESSAGE_WITH_FORMAT, 3, 128);
+
+  @Autowired
+  private ObjectMapper objectMapper;
+
+  @Test
+  public void createFilterShouldReturnErrorWhenNameIsNull() throws Exception {
+    //GIVEN
+    UpdateUserFilterRQ userFilterRQ = prepareFilter();
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + FILTER_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(userFilterRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + FIELD_NAME_IS_NULL_MESSAGE, error.getMessage());
+  }
+
+  @Test
+  public void createFilterShouldReturnErrorWhenNameIsEmpty() throws Exception {
+    //GIVEN
+    UpdateUserFilterRQ userFilterRQ = prepareFilter();
+    userFilterRQ.setName(EMPTY);
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + FILTER_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(userFilterRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " "
+        + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
+  }
+
+  @Test
+  public void createFilterShouldReturnErrorWhenNameConsistsOfWhitespaces() throws Exception {
+    //GIVEN
+    UpdateUserFilterRQ userFilterRQ = prepareFilter();
+    userFilterRQ.setName(WHITESPACES_NAME_VALUE);
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + FILTER_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(userFilterRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " "
+        + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
+  }
+
+  @Test
+  public void createFilterShouldReturnErrorWhenNameIsLessThanThreeCharacters() throws Exception {
+    //GIVEN
+    UpdateUserFilterRQ userFilterRQ = prepareFilter();
+    userFilterRQ.setName(SHORT_NAME_VALUE);
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + FILTER_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(userFilterRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_SIZE_MESSAGE + "] ",
+        error.getMessage());
+  }
+
+  @Test
+  public void createFilterShouldReturnErrorWhenNameIsGreaterThanOneHundredAndTwentyEightCharacters()
+      throws Exception {
+    //GIVEN
+    UpdateUserFilterRQ userFilterRQ = prepareFilter();
+    userFilterRQ.setName(LONG_NAME_VALUE);
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(post(DEFAULT_PROJECT_BASE_URL + FILTER_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(userFilterRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_SIZE_MESSAGE + "] ",
+        error.getMessage());
+  }
+
+  @Test
+  public void updateFilterShouldReturnErrorWhenNameIsNull() throws Exception {
+    //GIVEN
+    UpdateUserFilterRQ userFilterRQ = prepareFilter();
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + FILTER_PATH + ID_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(userFilterRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + FIELD_NAME_IS_NULL_MESSAGE, error.getMessage());
+  }
+
+  @Test
+  public void updateFilterShouldReturnErrorWhenNameIsEmpty() throws Exception {
+    //GIVEN
+    UpdateUserFilterRQ userFilterRQ = prepareFilter();
+    userFilterRQ.setName(EMPTY);
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + FILTER_PATH + ID_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(userFilterRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " "
+        + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
+  }
+
+  @Test
+  public void updateFilterShouldReturnErrorWhenNameConsistsOfWhitespaces() throws Exception {
+    //GIVEN
+    UpdateUserFilterRQ userFilterRQ = prepareFilter();
+    userFilterRQ.setName(WHITESPACES_NAME_VALUE);
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + FILTER_PATH + ID_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(userFilterRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_IS_BLANK_MESSAGE + " "
+        + FIELD_NAME_SIZE_MESSAGE + "] ", error.getMessage());
+  }
+
+  @Test
+  public void updateFilterShouldReturnErrorWhenNameIsLessThanThreeCharacters() throws Exception {
+    //GIVEN
+    UpdateUserFilterRQ userFilterRQ = prepareFilter();
+    userFilterRQ.setName(SHORT_NAME_VALUE);
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + FILTER_PATH + ID_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(userFilterRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_SIZE_MESSAGE + "] ",
+        error.getMessage());
+  }
+
+  @Test
+  public void updateFilterShouldReturnErrorWhenNameIsGreaterThanOneHundredAndTwentyEightCharacters()
+      throws Exception {
+    //GIVEN
+    UpdateUserFilterRQ userFilterRQ = prepareFilter();
+    userFilterRQ.setName(LONG_NAME_VALUE);
+
+    //WHEN
+    MvcResult mvcResult = mockMvc.perform(put(DEFAULT_PROJECT_BASE_URL + FILTER_PATH + ID_PATH)
+            .with(token(oAuthHelper.getDefaultToken()))
+            .content(objectMapper.writeValueAsBytes(userFilterRQ))
+            .contentType(APPLICATION_JSON))
+        .andExpect(status().isBadRequest()).andReturn();
+
+    //THEN
+    ErrorRS error = objectMapper.readValue(mvcResult.getResponse().getContentAsString(),
+        ErrorRS.class);
+    assertEquals(INCORRECT_REQUEST, error.getErrorType());
+    assertEquals(INCORRECT_REQUEST_MESSAGE + "[" + FIELD_NAME_SIZE_MESSAGE + "] ",
+        error.getMessage());
+  }
+
+  private UpdateUserFilterRQ prepareFilter() {
+    UpdateUserFilterRQ userFilterRQ = new UpdateUserFilterRQ();
+    userFilterRQ.setObjectType("Launch");
+
+    Order order = new Order();
+    order.setIsAsc(false);
+    order.setSortingColumnName("startTime");
+
+    userFilterRQ.setOrders(Lists.newArrayList(order));
+
+    userFilterRQ.setDescription("description");
+    userFilterRQ.setConditions(Sets.newHashSet(new UserFilterCondition("name", "cnt", "test")));
+
+    return userFilterRQ;
+  }
 }
diff --git a/src/test/java/com/epam/ta/reportportal/ws/controller/constants/ValidationTestsConstants.java b/src/test/java/com/epam/ta/reportportal/ws/controller/constants/ValidationTestsConstants.java
index b168ffab57..2bc23bda71 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/controller/constants/ValidationTestsConstants.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/controller/constants/ValidationTestsConstants.java
@@ -21,16 +21,17 @@
  */
 public final class ValidationTestsConstants {
 
-	public static final String ID_PATH = "/555";
+  public static final String ID_PATH = "/555";
 
-	public static final String WHITESPACES_NAME_VALUE = "    ";
-	public static final String SHORT_NAME_VALUE = "cc";
-	public static final String LONG_NAME_VALUE = "ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt";
+  public static final String WHITESPACES_NAME_VALUE = "    ";
+  public static final String SHORT_NAME_VALUE = "cc";
+  public static final String LONG_NAME_VALUE = "ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt";
 
-	public static final String INCORRECT_REQUEST_MESSAGE = "Incorrect Request. ";
-	public static final String FIELD_NAME_IS_NULL_MESSAGE = "[Field 'name' should not be null.] ";
-	public static final String FIELD_NAME_IS_BLANK_MESSAGE = "Field 'name' should not contain only white spaces and shouldn't be empty.";
-	public static final String FIELD_NAME_SIZE_MESSAGE_WITH_FORMAT = "Field 'name' should have size from '%d' to '%d'.";
+  public static final String INCORRECT_REQUEST_MESSAGE = "Incorrect Request. ";
+  public static final String FIELD_NAME_IS_NULL_MESSAGE = "[Field 'name' should not be null.] ";
+  public static final String FIELD_NAME_IS_BLANK_MESSAGE = "Field 'name' should not contain only white spaces and shouldn't be empty.";
+  public static final String FIELD_NAME_SIZE_MESSAGE_WITH_FORMAT = "Field 'name' should have size from '%d' to '%d'.";
 
-	private ValidationTestsConstants() {}
+  private ValidationTestsConstants() {
+  }
 }
diff --git a/src/test/java/com/epam/ta/reportportal/ws/converter/LogResourceAssemblerTest.java b/src/test/java/com/epam/ta/reportportal/ws/converter/LogResourceAssemblerTest.java
index f376803ebe..8c7b6c7598 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/converter/LogResourceAssemblerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/converter/LogResourceAssemblerTest.java
@@ -16,66 +16,66 @@
 
 package com.epam.ta.reportportal.ws.converter;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
 import com.epam.ta.reportportal.entity.enums.LogLevel;
 import com.epam.ta.reportportal.entity.item.TestItem;
-import com.epam.ta.reportportal.entity.log.Log;
+import com.epam.ta.reportportal.entity.log.LogFull;
 import com.epam.ta.reportportal.ws.model.log.LogResource;
-import org.junit.jupiter.api.Test;
-
 import java.time.LocalDateTime;
 import java.util.Collections;
 import java.util.List;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 class LogResourceAssemblerTest {
 
-	@Test
-	void toResource() {
-		LogResourceAssembler resourceAssembler = new LogResourceAssembler();
-		Log log = getLog();
-		LogResource logResource = resourceAssembler.toResource(log);
+  @Test
+  void toResource() {
+    LogResourceAssembler resourceAssembler = new LogResourceAssembler();
+    LogFull logFull = getFullLog();
+    LogResource logResource = resourceAssembler.toResource(logFull);
 
-		assertEquals(logResource.getId(), log.getId());
-		assertEquals(logResource.getLevel(), LogLevel.toLevel(log.getLogLevel()).name());
-		assertEquals(logResource.getMessage(), log.getLogMessage());
-		assertEquals(logResource.getItemId(), log.getTestItem().getItemId());
-	}
+    assertEquals(logResource.getId(), logFull.getId());
+    assertEquals(logResource.getLevel(), LogLevel.toLevel(logFull.getLogLevel()).name());
+    assertEquals(logResource.getMessage(), logFull.getLogMessage());
+    assertEquals(logResource.getItemId(), logFull.getTestItem().getItemId());
+  }
 
-	@Test
-	void toResources() {
-		LogResourceAssembler resourceAssembler = new LogResourceAssembler();
-		List<LogResource> logResources = resourceAssembler.toResources(Collections.singleton(getLog()));
+  @Test
+  void toResources() {
+    LogResourceAssembler resourceAssembler = new LogResourceAssembler();
+    List<LogResource> logResources = resourceAssembler.toResources(
+        Collections.singleton(getFullLog()));
 
-		assertEquals(1, logResources.size());
-	}
+    assertEquals(1, logResources.size());
+  }
 
-	@Test
-	void apply() {
-		LogResourceAssembler resourceAssembler = new LogResourceAssembler();
-		Log log = getLog();
-		LogResource logResource = resourceAssembler.apply(log);
+  @Test
+  void apply() {
+    LogResourceAssembler resourceAssembler = new LogResourceAssembler();
+    LogFull logFull = getFullLog();
+    LogResource logResource = resourceAssembler.apply(logFull);
 
-		assertEquals(logResource.getId(), log.getId());
-		assertEquals(logResource.getLevel(), LogLevel.toLevel(log.getLogLevel()).name());
-		assertEquals(logResource.getMessage(), log.getLogMessage());
-		assertEquals(logResource.getItemId(), log.getTestItem().getItemId());
-	}
+    assertEquals(logResource.getId(), logFull.getId());
+    assertEquals(logResource.getLevel(), LogLevel.toLevel(logFull.getLogLevel()).name());
+    assertEquals(logResource.getMessage(), logFull.getLogMessage());
+    assertEquals(logResource.getItemId(), logFull.getTestItem().getItemId());
+  }
 
-	private Log getLog() {
-		Log log = new Log();
-		log.setId(1L);
-		log.setLogTime(LocalDateTime.now());
-		log.setLastModified(LocalDateTime.now());
-		log.setLogMessage("message");
-		log.setLogLevel(40000);
-		TestItem testItem = new TestItem();
-		testItem.setItemId(2L);
-		log.setTestItem(testItem);
+  private LogFull getFullLog() {
+    LogFull logFull = new LogFull();
+    logFull.setId(1L);
+    logFull.setLogTime(LocalDateTime.now());
+    logFull.setLastModified(LocalDateTime.now());
+    logFull.setLogMessage("message");
+    logFull.setLogLevel(40000);
+    TestItem testItem = new TestItem();
+    testItem.setItemId(2L);
+    logFull.setTestItem(testItem);
 
-		return log;
-	}
+    return logFull;
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/converter/builders/IntegrationBuilderTest.java b/src/test/java/com/epam/ta/reportportal/ws/converter/builders/IntegrationBuilderTest.java
index 37c1b359ea..28743fad3b 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/converter/builders/IntegrationBuilderTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/converter/builders/IntegrationBuilderTest.java
@@ -16,100 +16,99 @@
 
 package com.epam.ta.reportportal.ws.converter.builders;
 
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
 import com.epam.ta.reportportal.entity.integration.Integration;
 import com.epam.ta.reportportal.entity.integration.IntegrationParams;
 import com.epam.ta.reportportal.entity.integration.IntegrationType;
 import com.epam.ta.reportportal.entity.project.Project;
 import com.google.common.collect.Maps;
-import org.junit.jupiter.api.Test;
-
 import java.time.LocalDateTime;
 import java.util.HashMap;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 class IntegrationBuilderTest {
 
-	@Test
-	void integrationBuilderTest() {
-		final Project project = new Project();
-		project.setId(1L);
-		project.setName("project");
-		final IntegrationParams params = new IntegrationParams();
-		final HashMap<String, Object> parameters = Maps.newHashMap();
-		parameters.put("param1", "val1");
-		parameters.put("param2", "val2");
-		params.setParams(parameters);
-		final IntegrationType type = new IntegrationType();
-		type.setName("type");
+  @Test
+  void integrationBuilderTest() {
+    final Project project = new Project();
+    project.setId(1L);
+    project.setName("project");
+    final IntegrationParams params = new IntegrationParams();
+    final HashMap<String, Object> parameters = Maps.newHashMap();
+    parameters.put("param1", "val1");
+    parameters.put("param2", "val2");
+    params.setParams(parameters);
+    final IntegrationType type = new IntegrationType();
+    type.setName("type");
 
-		final String name = "name";
-		final boolean enabled = true;
-		final LocalDateTime creationDate = LocalDateTime.now();
-		final String creator = "creator";
+    final String name = "name";
+    final boolean enabled = true;
+    final LocalDateTime creationDate = LocalDateTime.now();
+    final String creator = "creator";
 
-		final Integration integration = new IntegrationBuilder().withName(name)
-				.withEnabled(enabled)
-				.withCreationDate(creationDate)
-				.withProject(project)
-				.withCreator(creator)
-				.withParams(params)
-				.withType(type)
-				.get();
+    final Integration integration = new IntegrationBuilder().withName(name)
+        .withEnabled(enabled)
+        .withCreationDate(creationDate)
+        .withProject(project)
+        .withCreator(creator)
+        .withParams(params)
+        .withType(type)
+        .get();
 
-		assertNotNull(integration);
-		assertEquals(name, integration.getName());
-		assertEquals(enabled, integration.isEnabled());
-		assertEquals(creationDate, integration.getCreationDate());
-		assertEquals(creator, integration.getCreator());
-		assertEquals(project, integration.getProject());
-		assertThat(integration.getType()).isEqualToComparingFieldByField(type);
-		assertEquals(params.getParams(), integration.getParams().getParams());
-	}
+    assertNotNull(integration);
+    assertEquals(name, integration.getName());
+    assertEquals(enabled, integration.isEnabled());
+    assertEquals(creationDate, integration.getCreationDate());
+    assertEquals(creator, integration.getCreator());
+    assertEquals(project, integration.getProject());
+    assertThat(integration.getType()).isEqualToComparingFieldByField(type);
+    assertEquals(params.getParams(), integration.getParams().getParams());
+  }
 
-	@Test
-	void updateExistIntegrationTest() {
-		final Integration integration = new Integration();
-		integration.setName("name");
-		integration.setEnabled(false);
+  @Test
+  void updateExistIntegrationTest() {
+    final Integration integration = new Integration();
+    integration.setName("name");
+    integration.setEnabled(false);
 
-		final Project project = new Project();
-		project.setId(1L);
-		project.setName("project");
-		final IntegrationParams params = new IntegrationParams();
-		final HashMap<String, Object> parameters = Maps.newHashMap();
-		parameters.put("param1", "val1");
-		parameters.put("param2", "val2");
-		params.setParams(parameters);
-		final IntegrationType type = new IntegrationType();
-		type.setName("type");
+    final Project project = new Project();
+    project.setId(1L);
+    project.setName("project");
+    final IntegrationParams params = new IntegrationParams();
+    final HashMap<String, Object> parameters = Maps.newHashMap();
+    parameters.put("param1", "val1");
+    parameters.put("param2", "val2");
+    params.setParams(parameters);
+    final IntegrationType type = new IntegrationType();
+    type.setName("type");
 
-		final String name = "name";
-		final boolean enabled = true;
-		final LocalDateTime creationDate = LocalDateTime.now();
-		final String creator = "creator";
+    final String name = "name";
+    final boolean enabled = true;
+    final LocalDateTime creationDate = LocalDateTime.now();
+    final String creator = "creator";
 
-		final Integration updatedIntegration = new IntegrationBuilder(integration).withName(name)
-				.withEnabled(enabled)
-				.withCreationDate(creationDate)
-				.withProject(project)
-				.withCreator(creator)
-				.withParams(params)
-				.withType(type)
-				.get();
+    final Integration updatedIntegration = new IntegrationBuilder(integration).withName(name)
+        .withEnabled(enabled)
+        .withCreationDate(creationDate)
+        .withProject(project)
+        .withCreator(creator)
+        .withParams(params)
+        .withType(type)
+        .get();
 
-		assertNotNull(updatedIntegration);
-		assertEquals(name, updatedIntegration.getName());
-		assertEquals(enabled, updatedIntegration.isEnabled());
-		assertEquals(creationDate, updatedIntegration.getCreationDate());
-		assertEquals(creator, updatedIntegration.getCreator());
-		assertEquals(project, updatedIntegration.getProject());
-		assertThat(integration.getType()).isEqualToComparingFieldByField(type);
-		assertEquals(params.getParams(), updatedIntegration.getParams().getParams());
-	}
+    assertNotNull(updatedIntegration);
+    assertEquals(name, updatedIntegration.getName());
+    assertEquals(enabled, updatedIntegration.isEnabled());
+    assertEquals(creationDate, updatedIntegration.getCreationDate());
+    assertEquals(creator, updatedIntegration.getCreator());
+    assertEquals(project, updatedIntegration.getProject());
+    assertThat(integration.getType()).isEqualToComparingFieldByField(type);
+    assertEquals(params.getParams(), updatedIntegration.getParams().getParams());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/converter/builders/IssueEntityBuilderTest.java b/src/test/java/com/epam/ta/reportportal/ws/converter/builders/IssueEntityBuilderTest.java
index 572f60d2c4..a255c06c8a 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/converter/builders/IssueEntityBuilderTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/converter/builders/IssueEntityBuilderTest.java
@@ -16,41 +16,41 @@
 
 package com.epam.ta.reportportal.ws.converter.builders;
 
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
 import com.epam.ta.reportportal.entity.enums.TestItemIssueGroup;
 import com.epam.ta.reportportal.entity.item.issue.IssueEntity;
 import com.epam.ta.reportportal.entity.item.issue.IssueGroup;
 import com.epam.ta.reportportal.entity.item.issue.IssueType;
 import org.junit.jupiter.api.Test;
 
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 class IssueEntityBuilderTest {
 
-	@Test
-	void issueEntityBuilder() {
-		final boolean autoAnalyzed = false;
-		final boolean ignoreAnalyzer = true;
-		final IssueType issueType = new IssueType(new IssueGroup(TestItemIssueGroup.PRODUCT_BUG),
-				"locator",
-				"longName",
-				"shortName",
-				"color"
-		);
-		final String description = "description";
+  @Test
+  void issueEntityBuilder() {
+    final boolean autoAnalyzed = false;
+    final boolean ignoreAnalyzer = true;
+    final IssueType issueType = new IssueType(new IssueGroup(TestItemIssueGroup.PRODUCT_BUG),
+        "locator",
+        "longName",
+        "shortName",
+        "color"
+    );
+    final String description = "description";
 
-		final IssueEntity issueEntity = new IssueEntityBuilder().addAutoAnalyzedFlag(autoAnalyzed)
-				.addIgnoreFlag(ignoreAnalyzer)
-				.addIssueType(issueType)
-				.addDescription(description)
-				.get();
+    final IssueEntity issueEntity = new IssueEntityBuilder().addAutoAnalyzedFlag(autoAnalyzed)
+        .addIgnoreFlag(ignoreAnalyzer)
+        .addIssueType(issueType)
+        .addDescription(description)
+        .get();
 
-		assertEquals(autoAnalyzed, issueEntity.getAutoAnalyzed());
-		assertEquals(ignoreAnalyzer, issueEntity.getIgnoreAnalyzer());
-		assertThat(issueEntity.getIssueType()).isEqualToComparingFieldByField(issueType);
-		assertEquals(description, issueEntity.getIssueDescription());
-	}
+    assertEquals(autoAnalyzed, issueEntity.getAutoAnalyzed());
+    assertEquals(ignoreAnalyzer, issueEntity.getIgnoreAnalyzer());
+    assertThat(issueEntity.getIssueType()).isEqualToComparingFieldByField(issueType);
+    assertEquals(description, issueEntity.getIssueDescription());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/converter/builders/IssueTypeBuilderTest.java b/src/test/java/com/epam/ta/reportportal/ws/converter/builders/IssueTypeBuilderTest.java
index 92723090a7..a565362707 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/converter/builders/IssueTypeBuilderTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/converter/builders/IssueTypeBuilderTest.java
@@ -16,38 +16,38 @@
 
 package com.epam.ta.reportportal.ws.converter.builders;
 
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
 import com.epam.ta.reportportal.entity.enums.TestItemIssueGroup;
 import com.epam.ta.reportportal.entity.item.issue.IssueGroup;
 import com.epam.ta.reportportal.entity.item.issue.IssueType;
 import org.junit.jupiter.api.Test;
 
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 class IssueTypeBuilderTest {
 
-	@Test
-	void issueTypeBuilderTest() {
-		final String color = "color";
-		final IssueGroup issueGroup = new IssueGroup(TestItemIssueGroup.PRODUCT_BUG);
-		final String locator = "locator";
-		final String longName = "longName";
-		final String shortName = "shortName";
+  @Test
+  void issueTypeBuilderTest() {
+    final String color = "color";
+    final IssueGroup issueGroup = new IssueGroup(TestItemIssueGroup.PRODUCT_BUG);
+    final String locator = "locator";
+    final String longName = "longName";
+    final String shortName = "shortName";
 
-		final IssueType issueType = new IssueTypeBuilder().addHexColor(color)
-				.addIssueGroup(issueGroup)
-				.addLocator(locator)
-				.addLongName(longName)
-				.addShortName(shortName)
-				.get();
+    final IssueType issueType = new IssueTypeBuilder().addHexColor(color)
+        .addIssueGroup(issueGroup)
+        .addLocator(locator)
+        .addLongName(longName)
+        .addShortName(shortName)
+        .get();
 
-		assertEquals(color, issueType.getHexColor());
-		assertThat(issueType.getIssueGroup()).isEqualToComparingFieldByField(issueGroup);
-		assertEquals(locator, issueType.getLocator());
-		assertEquals(longName, issueType.getLongName());
-		assertEquals(shortName.toUpperCase(), issueType.getShortName());
-	}
+    assertEquals(color, issueType.getHexColor());
+    assertThat(issueType.getIssueGroup()).isEqualToComparingFieldByField(issueGroup);
+    assertEquals(locator, issueType.getLocator());
+    assertEquals(longName, issueType.getLongName());
+    assertEquals(shortName.toUpperCase(), issueType.getShortName());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/converter/builders/LaunchBuilderTest.java b/src/test/java/com/epam/ta/reportportal/ws/converter/builders/LaunchBuilderTest.java
index 95a7f1eca7..2c2374bab9 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/converter/builders/LaunchBuilderTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/converter/builders/LaunchBuilderTest.java
@@ -16,6 +16,11 @@
 
 package com.epam.ta.reportportal.ws.converter.builders;
 
+import static com.epam.ta.reportportal.commons.EntityUtils.TO_DATE;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 import com.epam.ta.reportportal.entity.ItemAttribute;
 import com.epam.ta.reportportal.entity.enums.LaunchModeEnum;
 import com.epam.ta.reportportal.entity.launch.Launch;
@@ -24,86 +29,83 @@
 import com.epam.ta.reportportal.ws.model.launch.Mode;
 import com.epam.ta.reportportal.ws.model.launch.StartLaunchRQ;
 import com.google.common.collect.Sets;
-import org.junit.jupiter.api.Test;
-
 import java.time.LocalDateTime;
-import java.time.ZoneId;
 import java.time.temporal.ChronoUnit;
 import java.util.Date;
-
-import static com.epam.ta.reportportal.commons.EntityUtils.TO_DATE;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 class LaunchBuilderTest {
 
-    @Test
-    void launchBuilder() {
-        final String description = "description";
-        final LocalDateTime now = LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS);
-        final Date date = TO_DATE.apply(now);
-        final Long projectId = 1L;
-        final ItemAttributeResource attributeResource = new ItemAttributeResource("key", "value");
-        final Long userId = 2L;
-        final String passed = "PASSED";
-        final Mode mode = Mode.DEFAULT;
+  @Test
+  void launchBuilder() {
+    final String description = "description";
+    final LocalDateTime now = LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS);
+    final Date date = TO_DATE.apply(now);
+    final Long projectId = 1L;
+    final ItemAttributeResource attributeResource = new ItemAttributeResource("key", "value");
+    final Long userId = 2L;
+    final String passed = "PASSED";
+    final Mode mode = Mode.DEFAULT;
 
-        final Launch launch = new LaunchBuilder().addDescription(description)
-                .addEndTime(date)
-                .addProject(projectId)
-                .addAttribute(attributeResource)
-                .addUserId(userId)
-                .addStatus(passed)
-                .addMode(mode)
-                .get();
+    final Launch launch = new LaunchBuilder().addDescription(description)
+        .addEndTime(date)
+        .addProject(projectId)
+        .addAttribute(attributeResource)
+        .addUserId(userId)
+        .addStatus(passed)
+        .addMode(mode)
+        .get();
 
-        assertEquals(description, launch.getDescription());
-        assertEquals(now, launch.getEndTime());
-        assertEquals(projectId, launch.getProjectId());
-        assertTrue(launch.getAttributes().contains(new ItemAttribute("key", "value", false)));
-        assertEquals(userId, launch.getUserId());
-        assertEquals(passed, launch.getStatus().name());
-        assertEquals(LaunchModeEnum.DEFAULT, launch.getMode());
-    }
+    assertEquals(description, launch.getDescription());
+    assertEquals(now, launch.getEndTime());
+    assertEquals(projectId, launch.getProjectId());
+    assertTrue(launch.getAttributes().contains(new ItemAttribute("key", "value", false)));
+    assertEquals(userId, launch.getUserId());
+    assertEquals(passed, launch.getStatus().name());
+    assertEquals(LaunchModeEnum.DEFAULT, launch.getMode());
+  }
 
-    @Test
-    void addStartRqTest() {
-        final StartLaunchRQ request = new StartLaunchRQ();
-        final String uuid = "uuid";
-        request.setUuid(uuid);
-        request.setMode(Mode.DEFAULT);
-        final String description = "description";
-        request.setDescription(description);
-        final String name = "name";
-        request.setName(name);
-        final LocalDateTime now = LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS);
-        request.setStartTime(TO_DATE.apply(now));
-        request.setAttributes(Sets.newHashSet(new ItemAttributesRQ("key", "value")));
+  @Test
+  void addStartRqTest() {
+    final StartLaunchRQ request = new StartLaunchRQ();
+    final String uuid = "uuid";
+    request.setUuid(uuid);
+    request.setMode(Mode.DEFAULT);
+    final String description = "description";
+    request.setDescription(description);
+    final String name = "name";
+    request.setName(name);
+    final LocalDateTime now = LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS);
+    request.setStartTime(TO_DATE.apply(now));
+    request.setAttributes(Sets.newHashSet(new ItemAttributesRQ("key", "value")));
 
-        final Launch launch = new LaunchBuilder().addStartRQ(request).addAttributes(request.getAttributes()).get();
+    final Launch launch = new LaunchBuilder().addStartRQ(request)
+        .addAttributes(request.getAttributes()).get();
 
-        assertEquals(name, launch.getName());
-        assertEquals(uuid, launch.getUuid());
-        assertEquals(description, launch.getDescription());
-        assertEquals(now, launch.getStartTime());
-        assertTrue(launch.getAttributes().contains(new ItemAttribute("key", "value", false)));
-        assertEquals(LaunchModeEnum.DEFAULT, launch.getMode());
-    }
+    assertEquals(name, launch.getName());
+    assertEquals(uuid, launch.getUuid());
+    assertEquals(description, launch.getDescription());
+    assertEquals(now, launch.getStartTime());
+    assertTrue(launch.getAttributes().contains(new ItemAttribute("key", "value", false)));
+    assertEquals(LaunchModeEnum.DEFAULT, launch.getMode());
+  }
 
-    @Test
-    void overwriteAttributes() {
-        Launch launch = new Launch();
-        final ItemAttribute systemAttribute = new ItemAttribute("key", "value", true);
-        launch.setAttributes(Sets.newHashSet(new ItemAttribute("key", "value", false), systemAttribute));
+  @Test
+  void overwriteAttributes() {
+    Launch launch = new Launch();
+    final ItemAttribute systemAttribute = new ItemAttribute("key", "value", true);
+    launch.setAttributes(
+        Sets.newHashSet(new ItemAttribute("key", "value", false), systemAttribute));
 
-        final Launch buildLaunch = new LaunchBuilder(launch).overwriteAttributes(Sets.newHashSet(new ItemAttributeResource("newKey",
-                "newVal"
+    final Launch buildLaunch = new LaunchBuilder(launch).overwriteAttributes(
+        Sets.newHashSet(new ItemAttributeResource("newKey",
+            "newVal"
         ))).get();
 
-        assertThat(buildLaunch.getAttributes()).containsExactlyInAnyOrder(new ItemAttribute("newKey", "newVal", false), systemAttribute);
-    }
+    assertThat(buildLaunch.getAttributes()).containsExactlyInAnyOrder(
+        new ItemAttribute("newKey", "newVal", false), systemAttribute);
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/converter/builders/LogBuilderTest.java b/src/test/java/com/epam/ta/reportportal/ws/converter/builders/LogFullBuilderTest.java
similarity index 55%
rename from src/test/java/com/epam/ta/reportportal/ws/converter/builders/LogBuilderTest.java
rename to src/test/java/com/epam/ta/reportportal/ws/converter/builders/LogFullBuilderTest.java
index f384806541..1451a9bd37 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/converter/builders/LogBuilderTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/converter/builders/LogFullBuilderTest.java
@@ -16,44 +16,40 @@
 
 package com.epam.ta.reportportal.ws.converter.builders;
 
+import static com.epam.ta.reportportal.commons.EntityUtils.TO_DATE;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
 import com.epam.ta.reportportal.entity.item.TestItem;
-import com.epam.ta.reportportal.entity.log.Log;
+import com.epam.ta.reportportal.entity.log.LogFull;
 import com.epam.ta.reportportal.ws.model.log.SaveLogRQ;
-import org.junit.jupiter.api.Test;
-
 import java.time.LocalDateTime;
-import java.time.ZoneId;
 import java.time.temporal.ChronoUnit;
-import java.time.temporal.TemporalUnit;
-import java.util.Date;
-
-import static com.epam.ta.reportportal.commons.EntityUtils.TO_DATE;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.assertEquals;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
-class LogBuilderTest {
-
-    @Test
-    void logBuilder() {
-        final SaveLogRQ createLogRQ = new SaveLogRQ();
-        final String message = "message";
-        createLogRQ.setMessage(message);
-        createLogRQ.setLevel("ERROR");
-        final LocalDateTime now = LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS);
-
-        createLogRQ.setLogTime(TO_DATE.apply(now));
-        TestItem item = new TestItem();
-        item.setItemId(1L);
-        item.setUniqueId("uuid");
-
-        final Log log = new LogBuilder().addSaveLogRq(createLogRQ).addTestItem(item).get();
-
-        assertEquals(message, log.getLogMessage());
-        assertEquals(40000, (int) log.getLogLevel());
-        assertEquals(now, log.getLogTime());
-        assertThat(log.getTestItem()).isEqualToComparingFieldByField(item);
-    }
+class LogFullBuilderTest {
+
+  @Test
+  void logBuilder() {
+    final SaveLogRQ createLogRQ = new SaveLogRQ();
+    final String message = "message";
+    createLogRQ.setMessage(message);
+    createLogRQ.setLevel("ERROR");
+    final LocalDateTime now = LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS);
+
+    createLogRQ.setLogTime(TO_DATE.apply(now));
+    TestItem item = new TestItem();
+    item.setItemId(1L);
+    item.setUniqueId("uuid");
+
+    final LogFull logFull = new LogFullBuilder().addSaveLogRq(createLogRQ).addTestItem(item).get();
+
+    assertEquals(message, logFull.getLogMessage());
+    assertEquals(40000, (int) logFull.getLogLevel());
+    assertEquals(now, logFull.getLogTime());
+    assertThat(logFull.getTestItem()).isEqualToComparingFieldByField(item);
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/converter/builders/PatternTemplateBuilderTest.java b/src/test/java/com/epam/ta/reportportal/ws/converter/builders/PatternTemplateBuilderTest.java
index 5d1b81b721..bfb72f7c32 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/converter/builders/PatternTemplateBuilderTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/converter/builders/PatternTemplateBuilderTest.java
@@ -16,34 +16,35 @@
 
 package com.epam.ta.reportportal.ws.converter.builders;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
 import com.epam.ta.reportportal.entity.pattern.PatternTemplate;
 import com.epam.ta.reportportal.ws.model.project.config.pattern.CreatePatternTemplateRQ;
 import org.junit.jupiter.api.Test;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class PatternTemplateBuilderTest {
 
-	@Test
-	void patternTemplateBuilder() {
-		CreatePatternTemplateRQ createPatternTemplateRQ = new CreatePatternTemplateRQ();
-		String name = "name";
-		String type = "STRING";
-		boolean enabled = true;
-		String value = "qwe";
-		createPatternTemplateRQ.setName(name);
-		createPatternTemplateRQ.setType(type);
-		createPatternTemplateRQ.setEnabled(enabled);
-		createPatternTemplateRQ.setValue(value);
+  @Test
+  void patternTemplateBuilder() {
+    CreatePatternTemplateRQ createPatternTemplateRQ = new CreatePatternTemplateRQ();
+    String name = "name";
+    String type = "STRING";
+    boolean enabled = true;
+    String value = "qwe";
+    createPatternTemplateRQ.setName(name);
+    createPatternTemplateRQ.setType(type);
+    createPatternTemplateRQ.setEnabled(enabled);
+    createPatternTemplateRQ.setValue(value);
 
-		PatternTemplate patternTemplate = new PatternTemplateBuilder().withCreateRequest(createPatternTemplateRQ).get();
+    PatternTemplate patternTemplate = new PatternTemplateBuilder().withCreateRequest(
+        createPatternTemplateRQ).get();
 
-		assertEquals(name, patternTemplate.getName());
-		assertEquals(type, patternTemplate.getTemplateType().name());
-		assertEquals(enabled, patternTemplate.isEnabled());
-		assertEquals(value, patternTemplate.getValue());
-	}
+    assertEquals(name, patternTemplate.getName());
+    assertEquals(type, patternTemplate.getTemplateType().name());
+    assertEquals(enabled, patternTemplate.isEnabled());
+    assertEquals(value, patternTemplate.getValue());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/converter/builders/TestItemBuilderTest.java b/src/test/java/com/epam/ta/reportportal/ws/converter/builders/TestItemBuilderTest.java
index aa47a7e27a..bcd8e4de3c 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/converter/builders/TestItemBuilderTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/converter/builders/TestItemBuilderTest.java
@@ -16,6 +16,12 @@
 
 package com.epam.ta.reportportal.ws.converter.builders;
 
+import static com.epam.ta.reportportal.commons.EntityUtils.TO_DATE;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 import com.epam.ta.reportportal.entity.ItemAttribute;
 import com.epam.ta.reportportal.entity.enums.StatusEnum;
 import com.epam.ta.reportportal.entity.enums.TestItemTypeEnum;
@@ -29,170 +35,189 @@
 import com.epam.ta.reportportal.ws.model.attribute.ItemAttributesRQ;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
-import org.apache.commons.lang3.RandomStringUtils;
-import org.junit.jupiter.api.Test;
-
 import java.time.LocalDateTime;
 import java.time.temporal.ChronoUnit;
 import java.util.Collections;
-
-import static com.epam.ta.reportportal.commons.EntityUtils.TO_DATE;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.*;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 class TestItemBuilderTest {
 
-	@Test
-	void testItemBuilder() {
-		final Launch launch = new Launch();
-		launch.setId(1L);
-		launch.setName("name");
-		final ParameterResource parameterResource = new ParameterResource();
-		parameterResource.setKey("key");
-		parameterResource.setValue("value");
-		final String description = "description";
-		final String typeValue = "step";
-
-		final TestItem testItem = new TestItemBuilder().addDescription(description)
-				.addType(typeValue)
-				.addLaunchId(launch.getId())
-				.addParameters(Collections.singletonList(parameterResource))
-				.addAttributes(Sets.newHashSet(new ItemAttributesRQ("key", "value")))
-				.addParentId(1L)
-				.get();
-
-		assertThat(testItem.getLaunchId()).isEqualToComparingFieldByField(launch.getId());
-		assertEquals(description, testItem.getDescription());
-		assertEquals(TestItemTypeEnum.STEP, testItem.getType());
-		final Parameter param = new Parameter();
-		param.setKey("key");
-		param.setValue("value");
-		assertTrue(testItem.getParameters().contains(param));
-		assertThat(testItem.getAttributes()).containsExactly(new ItemAttribute("key", "value", false));
-		assertNotNull(testItem.getParentId());
-	}
-
-	@Test
-	void addStartRqTest() {
-		final StartTestItemRQ rq = new StartTestItemRQ();
-		rq.setType("step");
-		final ParameterResource parameterResource = new ParameterResource();
-		parameterResource.setKey("key");
-		parameterResource.setValue("value");
-		rq.setParameters(Collections.singletonList(parameterResource));
-		final String uuid = "uuid";
-		rq.setUniqueId(uuid);
-		final String description = "description";
-		rq.setDescription(description);
-		final LocalDateTime now = LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS);
-		rq.setStartTime(TO_DATE.apply(now));
-		final String name = "name";
-		rq.setName(name);
-
-		final TestItem testItem = new TestItemBuilder().addStartItemRequest(rq).get();
-
-		assertEquals(TestItemTypeEnum.STEP, testItem.getType());
-		final Parameter param = new Parameter();
-		param.setKey("key");
-		param.setValue("value");
-		assertTrue(testItem.getParameters().contains(param));
-		assertEquals(uuid, testItem.getUniqueId());
-		assertEquals(description, testItem.getDescription());
-		assertEquals(now, testItem.getStartTime());
-		assertEquals(name, testItem.getName());
-	}
-
-	@Test
-	void addResultsTest() {
-		TestItem item = new TestItem();
-		final LocalDateTime now = LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS);
-		item.setStartTime(now);
-		final TestItemResults itemResults = new TestItemResults();
-		itemResults.setEndTime(now.plusSeconds(120));
-		item.setItemResults(itemResults);
-		final ItemAttribute systemAttribute = new ItemAttribute("key", "val", true);
-		item.setAttributes(Sets.newHashSet(new ItemAttribute("key", "val", false), systemAttribute));
-
-		final TestItem resultItem = new TestItemBuilder(item).addTestItemResults(itemResults)
-				.addStatus(StatusEnum.PASSED)
-				.overwriteAttributes(Sets.newHashSet(new ItemAttributeResource("k", "v")))
-				.get();
-
-		assertEquals(120, resultItem.getItemResults().getDuration(), 0.1);
-		assertEquals(StatusEnum.PASSED, resultItem.getItemResults().getStatus());
-		assertThat(resultItem.getAttributes()).containsExactlyInAnyOrder(systemAttribute, new ItemAttribute("k", "v", false));
-	}
-
-	@Test
-	void providedTestCaseIdTest() {
-		StartTestItemRQ request = new StartTestItemRQ();
-        request.setName("item");
-        request.setType("step");
-		String testCaseId = "my-test-case-id";
-		request.setTestCaseId(testCaseId);
-
-		TestItem testItem = new TestItemBuilder().addStartItemRequest(request).get();
-
-		assertEquals(testCaseId, testItem.getTestCaseId());
-		assertEquals(testCaseId.hashCode(), testItem.getTestCaseHash().intValue());
-	}
-
-	@Test
-	void providedTestCaseIdWith1025SymbolsTest() {
-		StartTestItemRQ request = new StartTestItemRQ();
-		request.setName("item");
-		request.setType("step");
-		String testCaseId = RandomStringUtils.random(1025, true, true);
-		request.setTestCaseId(testCaseId);
-
-		TestItem item = new TestItemBuilder().addStartItemRequest(request).get();
-
-		assertTrue(item.getTestCaseId().length() <= 1024);
-		assertEquals(testCaseId.substring(0, 1010), item.getTestCaseId().substring(0, 1010));
-		assertEquals("[" + testCaseId.substring(1011).hashCode() + "]", item.getTestCaseId().substring(1011));
-		assertEquals(testCaseId.hashCode(), item.getTestCaseHash().intValue());
-	}
-
-	@Test
-	void testCaseIdGeneratedFromCodeRefTest() {
-		StartTestItemRQ request = new StartTestItemRQ();
-        request.setName("item");
-        request.setType("step");
-		String codeRef = "com.epam.ta.reportportal.core.item.identity.TestCaseIdHandlerImplTest";
-		request.setCodeRef(codeRef);
-
-		TestItem item = new TestItemBuilder().addStartItemRequest(request).get();
-
-		assertEquals(codeRef, item.getTestCaseId());
-		assertEquals(codeRef.hashCode(), item.getTestCaseHash().intValue());
-	}
-
-    @Test
-    void testCaseIdGeneratedFromCodeRefAndParamsTest() {
-        StartTestItemRQ request = new StartTestItemRQ();
-        request.setName("item");
-        request.setType("step");
-        String codeRef = "com.epam.ta.reportportal.core.item.identity.TestCaseIdHandlerImplTest";
-        request.setCodeRef(codeRef);
-        ParameterResource param1 = new ParameterResource();
-        param1.setKey("key1");
-        String value1 = "value1";
-        param1.setValue(value1);
-        ParameterResource param2 = new ParameterResource();
-        param2.setKey("key2");
-        String value2 = "value2";
-        param2.setValue(value2);
-        ParameterResource param3 = new ParameterResource();
-        param1.setKey("key3");
-        request.setParameters(Lists.newArrayList(param1, param2, param3));
-
-        TestItem item = new TestItemBuilder().addStartItemRequest(request).get();
-
-        String expected = codeRef + "[" + value1 + "," + value2 + ",null]";
-        assertEquals(expected, item.getTestCaseId());
-        assertEquals(expected.hashCode(), item.getTestCaseHash().intValue());
-    }
+  @Test
+  void testItemBuilder() {
+    final Launch launch = new Launch();
+    launch.setId(1L);
+    launch.setName("name");
+    final ParameterResource parameterResource = new ParameterResource();
+    parameterResource.setKey("key");
+    parameterResource.setValue("value");
+    final String description = "description";
+    final String typeValue = "step";
+
+    final TestItem testItem = new TestItemBuilder().addDescription(description)
+        .addType(typeValue)
+        .addLaunchId(launch.getId())
+        .addParameters(Collections.singletonList(parameterResource))
+        .addAttributes(Sets.newHashSet(new ItemAttributesRQ("key", "value")))
+        .addParentId(1L)
+        .get();
+
+    assertEquals(testItem.getLaunchId(), launch.getId());
+    assertEquals(description, testItem.getDescription());
+    assertEquals(TestItemTypeEnum.STEP, testItem.getType());
+    final Parameter param = new Parameter();
+    param.setKey("key");
+    param.setValue("value");
+    assertTrue(testItem.getParameters().contains(param));
+    assertThat(testItem.getAttributes()).containsExactly(new ItemAttribute("key", "value", false));
+    assertNotNull(testItem.getParentId());
+  }
+
+  @Test
+  void addStartRqTest() {
+    final StartTestItemRQ rq = new StartTestItemRQ();
+    rq.setType("step");
+    final ParameterResource parameterResource = new ParameterResource();
+    parameterResource.setKey("key");
+    parameterResource.setValue("value");
+    rq.setParameters(Collections.singletonList(parameterResource));
+    final String uuid = "uuid";
+    rq.setUniqueId(uuid);
+    final String description = "description";
+    rq.setDescription(description);
+    final LocalDateTime now = LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS);
+    rq.setStartTime(TO_DATE.apply(now));
+    final String name = "name";
+    rq.setName(name);
+
+    final TestItem testItem = new TestItemBuilder().addStartItemRequest(rq).get();
+
+    assertEquals(TestItemTypeEnum.STEP, testItem.getType());
+    final Parameter param = new Parameter();
+    param.setKey("key");
+    param.setValue("value");
+    assertTrue(testItem.getParameters().contains(param));
+    assertEquals(uuid, testItem.getUniqueId());
+    assertEquals(description, testItem.getDescription());
+    assertEquals(now, testItem.getStartTime());
+    assertEquals(name, testItem.getName());
+  }
+
+  @Test
+  void addResultsTest() {
+    TestItem item = new TestItem();
+    final LocalDateTime now = LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS);
+    item.setStartTime(now);
+    final TestItemResults itemResults = new TestItemResults();
+    itemResults.setEndTime(now.plusSeconds(120));
+    item.setItemResults(itemResults);
+    final ItemAttribute systemAttribute = new ItemAttribute("key", "val", true);
+    item.setAttributes(Sets.newHashSet(new ItemAttribute("key", "val", false), systemAttribute));
+
+    final TestItem resultItem = new TestItemBuilder(item).addTestItemResults(itemResults)
+        .addStatus(StatusEnum.PASSED)
+        .overwriteAttributes(Sets.newHashSet(new ItemAttributeResource("k", "v")))
+        .get();
+
+    assertEquals(120, resultItem.getItemResults().getDuration(), 0.1);
+    assertEquals(StatusEnum.PASSED, resultItem.getItemResults().getStatus());
+    assertThat(resultItem.getAttributes()).containsExactlyInAnyOrder(systemAttribute,
+        new ItemAttribute("k", "v", false));
+  }
+
+  @Test
+  void overwriteAttributesValuesTest() {
+    TestItem item = new TestItem();
+    final LocalDateTime now = LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS);
+    item.setStartTime(now);
+    final TestItemResults itemResults = new TestItemResults();
+    itemResults.setEndTime(now.plusSeconds(120));
+    item.setItemResults(itemResults);
+    final ItemAttribute systemAttribute = new ItemAttribute("key", "val", true);
+    item.setAttributes(Sets.newHashSet(new ItemAttribute("someKey", "val", false), systemAttribute));
+
+    final TestItem resultItem = new TestItemBuilder(item).addTestItemResults(itemResults)
+        .addStatus(StatusEnum.PASSED)
+        .overwriteAttributesValues(Sets.newHashSet(new ItemAttributeResource("someKey", "newVal")))
+        .get();
+
+    assertEquals(120, resultItem.getItemResults().getDuration(), 0.1);
+    assertEquals(StatusEnum.PASSED, resultItem.getItemResults().getStatus());
+    assertThat(resultItem.getAttributes()).containsExactlyInAnyOrder(systemAttribute,
+        new ItemAttribute("someKey", "newVal", false));
+  }
+
+  @Test
+  void providedTestCaseIdTest() {
+    StartTestItemRQ request = new StartTestItemRQ();
+    request.setName("item");
+    request.setType("step");
+    String testCaseId = "my-test-case-id";
+    request.setTestCaseId(testCaseId);
+
+    TestItem testItem = new TestItemBuilder().addStartItemRequest(request).get();
+
+    assertEquals(testCaseId, testItem.getTestCaseId());
+    assertEquals(testCaseId.hashCode(), testItem.getTestCaseHash().intValue());
+  }
+
+  @Test
+  void providedTestCaseIdWith1025SymbolsTest() {
+    StartTestItemRQ request = new StartTestItemRQ();
+    request.setName("item");
+    request.setType("step");
+    String testCaseId = RandomStringUtils.random(1025, true, true);
+    request.setTestCaseId(testCaseId);
+
+    TestItem item = new TestItemBuilder().addStartItemRequest(request).get();
+
+    assertTrue(item.getTestCaseId().length() <= 1024);
+    assertEquals(testCaseId.substring(0, 1010), item.getTestCaseId().substring(0, 1010));
+    assertEquals("[" + testCaseId.substring(1011).hashCode() + "]",
+        item.getTestCaseId().substring(1011));
+    assertEquals(testCaseId.hashCode(), item.getTestCaseHash().intValue());
+  }
+
+  @Test
+  void testCaseIdGeneratedFromCodeRefTest() {
+    StartTestItemRQ request = new StartTestItemRQ();
+    request.setName("item");
+    request.setType("step");
+    String codeRef = "com.epam.ta.reportportal.core.item.identity.TestCaseIdHandlerImplTest";
+    request.setCodeRef(codeRef);
+
+    TestItem item = new TestItemBuilder().addStartItemRequest(request).get();
+
+    assertEquals(codeRef, item.getTestCaseId());
+    assertEquals(codeRef.hashCode(), item.getTestCaseHash().intValue());
+  }
+
+  @Test
+  void testCaseIdGeneratedFromCodeRefAndParamsTest() {
+    StartTestItemRQ request = new StartTestItemRQ();
+    request.setName("item");
+    request.setType("step");
+    String codeRef = "com.epam.ta.reportportal.core.item.identity.TestCaseIdHandlerImplTest";
+    request.setCodeRef(codeRef);
+    ParameterResource param1 = new ParameterResource();
+    param1.setKey("key1");
+    String value1 = "value1";
+    param1.setValue(value1);
+    ParameterResource param2 = new ParameterResource();
+    param2.setKey("key2");
+    String value2 = "value2";
+    param2.setValue(value2);
+    ParameterResource param3 = new ParameterResource();
+    param1.setKey("key3");
+    request.setParameters(Lists.newArrayList(param1, param2, param3));
+
+    TestItem item = new TestItemBuilder().addStartItemRequest(request).get();
+
+    String expected = codeRef + "[" + value1 + "," + value2 + ",null]";
+    assertEquals(expected, item.getTestCaseId());
+    assertEquals(expected.hashCode(), item.getTestCaseHash().intValue());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/converter/builders/UserBuilderTest.java b/src/test/java/com/epam/ta/reportportal/ws/converter/builders/UserBuilderTest.java
index eaa5a29910..7cfb8a0fd3 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/converter/builders/UserBuilderTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/converter/builders/UserBuilderTest.java
@@ -16,40 +16,43 @@
 
 package com.epam.ta.reportportal.ws.converter.builders;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
 import com.epam.ta.reportportal.entity.user.User;
 import com.epam.ta.reportportal.entity.user.UserRole;
 import com.epam.ta.reportportal.entity.user.UserType;
 import com.epam.ta.reportportal.ws.model.user.CreateUserRQConfirm;
 import org.junit.jupiter.api.Test;
 
-import static org.junit.jupiter.api.Assertions.*;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 class UserBuilderTest {
 
-	@Test
-	void userBuilder() {
-		final CreateUserRQConfirm request = new CreateUserRQConfirm();
-		final String login = "login";
-		request.setLogin(login);
-		final String email = "email@domain.com";
-		request.setEmail(email);
-		final String fullName = "full name";
-		request.setFullName(fullName);
-		request.setPassword("password");
-		final UserRole role = UserRole.USER;
+  @Test
+  void userBuilder() {
+    final CreateUserRQConfirm request = new CreateUserRQConfirm();
+    final String login = "login";
+    request.setLogin(login);
+    final String email = "email@domain.com";
+    request.setEmail(email);
+    final String fullName = "full name";
+    request.setFullName(fullName);
+    request.setPassword("password");
+    final UserRole role = UserRole.USER;
 
-		final User user = new UserBuilder().addCreateUserRQ(request).addUserRole(role).addPassword(request.getPassword()).get();
+    final User user = new UserBuilder().addCreateUserRQ(request).addUserRole(role)
+        .addPassword(request.getPassword()).get();
 
-		assertEquals(login, user.getLogin());
-		assertEquals(email, user.getEmail());
-		assertEquals(fullName, user.getFullName());
-		assertNotNull(user.getPassword());
-		assertEquals(role, user.getRole());
-		assertEquals(UserType.INTERNAL, user.getUserType());
-		assertNotNull(user.getMetadata());
-		assertFalse(user.isExpired());
-	}
+    assertEquals(login, user.getLogin());
+    assertEquals(email, user.getEmail());
+    assertEquals(fullName, user.getFullName());
+    assertNotNull(user.getPassword());
+    assertEquals(role, user.getRole());
+    assertEquals(UserType.INTERNAL, user.getUserType());
+    assertNotNull(user.getMetadata());
+    assertFalse(user.isExpired());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/converter/builders/UserPreferenceBuilderTest.java b/src/test/java/com/epam/ta/reportportal/ws/converter/builders/UserPreferenceBuilderTest.java
index b38baaf1ec..d5827b169f 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/converter/builders/UserPreferenceBuilderTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/converter/builders/UserPreferenceBuilderTest.java
@@ -16,30 +16,31 @@
 
 package com.epam.ta.reportportal.ws.converter.builders;
 
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
 import com.epam.ta.reportportal.entity.filter.UserFilter;
 import com.epam.ta.reportportal.entity.preference.UserPreference;
 import org.junit.jupiter.api.Test;
 
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 class UserPreferenceBuilderTest {
 
-	@Test
-	void userPreferenceBuilder() {
-		final UserFilter filter = new UserFilter();
-		filter.setName("name");
-		filter.setOwner("owner");
-		final Long projectId = 1L;
-		final Long userId = 2L;
+  @Test
+  void userPreferenceBuilder() {
+    final UserFilter filter = new UserFilter();
+    filter.setName("name");
+    filter.setOwner("owner");
+    final Long projectId = 1L;
+    final Long userId = 2L;
 
-		final UserPreference userPreference = new UserPreferenceBuilder().withFilter(filter).withProject(projectId).withUser(userId).get();
+    final UserPreference userPreference = new UserPreferenceBuilder().withFilter(filter)
+        .withProject(projectId).withUser(userId).get();
 
-		assertThat(userPreference.getFilter()).isEqualToComparingFieldByField(filter);
-		assertEquals(projectId, userPreference.getProject().getId());
-		assertEquals(userId, userPreference.getUser().getId());
-	}
+    assertThat(userPreference.getFilter()).isEqualToComparingFieldByField(filter);
+    assertEquals(projectId, userPreference.getProject().getId());
+    assertEquals(userId, userPreference.getUser().getId());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/converter/converters/IntegrationConverterTest.java b/src/test/java/com/epam/ta/reportportal/ws/converter/converters/IntegrationConverterTest.java
index b2739cde92..114abaebb4 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/converter/converters/IntegrationConverterTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/converter/converters/IntegrationConverterTest.java
@@ -16,6 +16,9 @@
 
 package com.epam.ta.reportportal.ws.converter.converters;
 
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
 import com.epam.ta.reportportal.entity.enums.IntegrationAuthFlowEnum;
 import com.epam.ta.reportportal.entity.enums.IntegrationGroupEnum;
 import com.epam.ta.reportportal.entity.integration.Integration;
@@ -26,81 +29,83 @@
 import com.epam.ta.reportportal.ws.model.integration.IntegrationResource;
 import com.epam.ta.reportportal.ws.model.integration.IntegrationTypeResource;
 import com.google.common.collect.Sets;
-import org.junit.jupiter.api.Test;
-
 import java.sql.Date;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.util.HashMap;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.assertEquals;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 class IntegrationConverterTest {
 
-	@Test
-	void toResource() {
-		final Integration integration = getIntegration();
-		final IntegrationResource resource = IntegrationConverter.TO_INTEGRATION_RESOURCE.apply(integration);
+  @Test
+  void toResource() {
+    final Integration integration = getIntegration();
+    final IntegrationResource resource = IntegrationConverter.TO_INTEGRATION_RESOURCE.apply(
+        integration);
 
-		assertEquals(resource.getCreationDate(), Date.from(integration.getCreationDate().atZone(ZoneId.of("UTC")).toInstant()));
-		assertEquals(resource.getEnabled(), integration.isEnabled());
-		assertEquals(resource.getId(), integration.getId());
-		assertEquals(resource.getProjectId(), integration.getProject().getId());
+    assertEquals(resource.getCreationDate(),
+        Date.from(integration.getCreationDate().atZone(ZoneId.of("UTC")).toInstant()));
+    assertEquals(resource.getEnabled(), integration.isEnabled());
+    assertEquals(resource.getId(), integration.getId());
+    assertEquals(resource.getProjectId(), integration.getProject().getId());
 
-		assertThat(resource.getIntegrationParams()).containsOnlyKeys("param1", "param2", "nullParam", null);
-		assertThat(resource.getIntegrationParams()).doesNotContainKey("accessToken");
-		assertThat(resource.getIntegrationParams()).containsValues("qwerty", "asdfgh", "value", null);
+    assertThat(resource.getIntegrationParams()).containsOnlyKeys("param1", "param2", "nullParam",
+        null);
+    assertThat(resource.getIntegrationParams()).doesNotContainKey("accessToken");
+    assertThat(resource.getIntegrationParams()).containsValues("qwerty", "asdfgh", "value", null);
 
-		final IntegrationTypeResource integrationTypeResource = resource.getIntegrationType();
+    final IntegrationTypeResource integrationTypeResource = resource.getIntegrationType();
 
-		assertEquals(integrationTypeResource.getAuthFlow().name(), integration.getType().getAuthFlow().name());
-		assertEquals(integrationTypeResource.getId(), integration.getType().getId());
-		assertEquals(integrationTypeResource.getName(), integration.getType().getName());
-		assertEquals(integrationTypeResource.getGroupType(), integration.getType().getIntegrationGroup().name());
-	}
+    assertEquals(integrationTypeResource.getAuthFlow().name(),
+        integration.getType().getAuthFlow().name());
+    assertEquals(integrationTypeResource.getId(), integration.getType().getId());
+    assertEquals(integrationTypeResource.getName(), integration.getType().getName());
+    assertEquals(integrationTypeResource.getGroupType(),
+        integration.getType().getIntegrationGroup().name());
+  }
 
-	@Test
-	void toActivityResource() {
-		final Integration integration = getIntegration();
-		final IntegrationActivityResource resource = IntegrationConverter.TO_ACTIVITY_RESOURCE.apply(integration);
+  @Test
+  void toActivityResource() {
+    final Integration integration = getIntegration();
+    final IntegrationActivityResource resource = IntegrationConverter.TO_ACTIVITY_RESOURCE.apply(
+        integration);
 
-		assertEquals(resource.getId(), integration.getId());
-		assertEquals(resource.getProjectId(), integration.getProject().getId());
-		assertEquals(resource.getProjectName(), integration.getProject().getName());
-		assertEquals(resource.getTypeName(), integration.getType().getName());
-	}
+    assertEquals(resource.getId(), integration.getId());
+    assertEquals(resource.getProjectId(), integration.getProject().getId());
+    assertEquals(resource.getProjectName(), integration.getProject().getName());
+    assertEquals(resource.getTypeName(), integration.getType().getName());
+  }
 
-	private static Integration getIntegration() {
-		Integration integration = new Integration();
-		final IntegrationType type = new IntegrationType();
-		type.setCreationDate(LocalDateTime.now());
-		type.setIntegrationGroup(IntegrationGroupEnum.NOTIFICATION);
-		type.setName("typeName");
-		type.setAuthFlow(IntegrationAuthFlowEnum.BASIC);
-		type.setEnabled(true);
-		type.setId(1L);
-		type.setIntegrations(Sets.newHashSet(integration));
-		integration.setType(type);
-		final IntegrationParams params = new IntegrationParams();
-		final HashMap<String, Object> paramMap = new HashMap<>();
-		paramMap.put("param1", "qwerty");
-		paramMap.put("param2", "asdfgh");
-		paramMap.put("nullParam", null);
-		paramMap.put(null, "value");
-		paramMap.put("accessToken", "asdfgh");
-		params.setParams(paramMap);
-		integration.setParams(params);
-		integration.setEnabled(true);
-		final Project project = new Project();
-		project.setId(2L);
-		project.setName("projectName");
-		integration.setProject(project);
-		integration.setId(3L);
-		integration.setCreationDate(LocalDateTime.now());
-		return integration;
-	}
+  private static Integration getIntegration() {
+    Integration integration = new Integration();
+    final IntegrationType type = new IntegrationType();
+    type.setCreationDate(LocalDateTime.now());
+    type.setIntegrationGroup(IntegrationGroupEnum.NOTIFICATION);
+    type.setName("typeName");
+    type.setAuthFlow(IntegrationAuthFlowEnum.BASIC);
+    type.setEnabled(true);
+    type.setId(1L);
+    type.setIntegrations(Sets.newHashSet(integration));
+    integration.setType(type);
+    final IntegrationParams params = new IntegrationParams();
+    final HashMap<String, Object> paramMap = new HashMap<>();
+    paramMap.put("param1", "qwerty");
+    paramMap.put("param2", "asdfgh");
+    paramMap.put("nullParam", null);
+    paramMap.put(null, "value");
+    paramMap.put("accessToken", "asdfgh");
+    params.setParams(paramMap);
+    integration.setParams(params);
+    integration.setEnabled(true);
+    final Project project = new Project();
+    project.setId(2L);
+    project.setName("projectName");
+    integration.setProject(project);
+    integration.setId(3L);
+    integration.setCreationDate(LocalDateTime.now());
+    return integration;
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/converter/converters/IntegrationFieldsConverterTest.java b/src/test/java/com/epam/ta/reportportal/ws/converter/converters/IntegrationFieldsConverterTest.java
index de380e7965..e572322fa8 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/converter/converters/IntegrationFieldsConverterTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/converter/converters/IntegrationFieldsConverterTest.java
@@ -16,70 +16,72 @@
 
 package com.epam.ta.reportportal.ws.converter.converters;
 
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
 import com.epam.ta.reportportal.entity.bts.DefectFieldAllowedValue;
 import com.epam.ta.reportportal.entity.bts.DefectFormField;
 import com.epam.ta.reportportal.ws.model.externalsystem.AllowedValue;
 import com.epam.ta.reportportal.ws.model.externalsystem.PostFormField;
 import com.google.common.collect.Sets;
-import org.junit.jupiter.api.Test;
-
 import java.util.Collections;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.assertEquals;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 class IntegrationFieldsConverterTest {
 
-	@Test
-	void fieldToDb() {
-		final PostFormField field = getField();
-		final DefectFormField defectFormField = IntegrationFieldsConverter.FIELD_TO_DB.apply(field);
+  @Test
+  void fieldToDb() {
+    final PostFormField field = getField();
+    final DefectFormField defectFormField = IntegrationFieldsConverter.FIELD_TO_DB.apply(field);
 
-		assertEquals(defectFormField.getFieldId(), field.getId());
-		assertEquals(defectFormField.getType(), field.getFieldType());
-		assertEquals(defectFormField.isRequired(), field.getIsRequired());
-		assertThat(defectFormField.getValues()).containsExactlyElementsOf(field.getValue());
-		assertThat(defectFormField.getDefectFieldAllowedValues()).hasSameSizeAs(field.getDefinedValues());
-	}
+    assertEquals(defectFormField.getFieldId(), field.getId());
+    assertEquals(defectFormField.getType(), field.getFieldType());
+    assertEquals(defectFormField.isRequired(), field.getIsRequired());
+    assertThat(defectFormField.getValues()).containsExactlyElementsOf(field.getValue());
+    assertThat(defectFormField.getDefectFieldAllowedValues()).hasSameSizeAs(
+        field.getDefinedValues());
+  }
 
-	@Test
-	void fieldToModel() {
-		final DefectFormField defectFormField = getDefectFormField();
-		final PostFormField postFormField = IntegrationFieldsConverter.FIELD_TO_MODEL.apply(defectFormField);
+  @Test
+  void fieldToModel() {
+    final DefectFormField defectFormField = getDefectFormField();
+    final PostFormField postFormField = IntegrationFieldsConverter.FIELD_TO_MODEL.apply(
+        defectFormField);
 
-		assertEquals(postFormField.getFieldType(), defectFormField.getType());
-		assertEquals(postFormField.getIsRequired(), defectFormField.isRequired());
-		assertThat(postFormField.getValue()).containsExactlyInAnyOrder("value1", "value2");
-		assertThat(postFormField.getDefinedValues()).hasSameSizeAs(defectFormField.getDefectFieldAllowedValues());
-	}
+    assertEquals(postFormField.getFieldType(), defectFormField.getType());
+    assertEquals(postFormField.getIsRequired(), defectFormField.isRequired());
+    assertThat(postFormField.getValue()).containsExactlyInAnyOrder("value1", "value2");
+    assertThat(postFormField.getDefinedValues()).hasSameSizeAs(
+        defectFormField.getDefectFieldAllowedValues());
+  }
 
-	private static PostFormField getField() {
-		final PostFormField postFormField = new PostFormField();
-		postFormField.setFieldType("type");
-		postFormField.setId("id");
-		postFormField.setIsRequired(true);
-		postFormField.setFieldName("name");
-		final AllowedValue allowedValue = new AllowedValue();
-		allowedValue.setValueId("valueId");
-		allowedValue.setValueName("valueName");
-		postFormField.setDefinedValues(Collections.singletonList(allowedValue));
-		postFormField.setValue(Collections.singletonList("value"));
-		return postFormField;
-	}
+  private static PostFormField getField() {
+    final PostFormField postFormField = new PostFormField();
+    postFormField.setFieldType("type");
+    postFormField.setId("id");
+    postFormField.setIsRequired(true);
+    postFormField.setFieldName("name");
+    final AllowedValue allowedValue = new AllowedValue();
+    allowedValue.setValueId("valueId");
+    allowedValue.setValueName("valueName");
+    postFormField.setDefinedValues(Collections.singletonList(allowedValue));
+    postFormField.setValue(Collections.singletonList("value"));
+    return postFormField;
+  }
 
-	private static DefectFormField getDefectFormField() {
-		final DefectFormField defectFormField = new DefectFormField();
-		defectFormField.setFieldId("fieldId");
-		defectFormField.setRequired(true);
-		defectFormField.setType("type");
-		defectFormField.setValues(Sets.newHashSet("value1", "value2"));
-		final DefectFieldAllowedValue defectFieldAllowedValue = new DefectFieldAllowedValue();
-		defectFieldAllowedValue.setValueId("id");
-		defectFieldAllowedValue.setValueName("name");
-		defectFormField.setDefectFieldAllowedValues(Sets.newHashSet(defectFieldAllowedValue));
-		return defectFormField;
-	}
+  private static DefectFormField getDefectFormField() {
+    final DefectFormField defectFormField = new DefectFormField();
+    defectFormField.setFieldId("fieldId");
+    defectFormField.setRequired(true);
+    defectFormField.setType("type");
+    defectFormField.setValues(Sets.newHashSet("value1", "value2"));
+    final DefectFieldAllowedValue defectFieldAllowedValue = new DefectFieldAllowedValue();
+    defectFieldAllowedValue.setValueId("id");
+    defectFieldAllowedValue.setValueName("name");
+    defectFormField.setDefectFieldAllowedValues(Sets.newHashSet(defectFieldAllowedValue));
+    return defectFormField;
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/converter/converters/IssueConverterTest.java b/src/test/java/com/epam/ta/reportportal/ws/converter/converters/IssueConverterTest.java
index c459775b51..eb5e34dab8 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/converter/converters/IssueConverterTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/converter/converters/IssueConverterTest.java
@@ -16,6 +16,8 @@
 
 package com.epam.ta.reportportal.ws.converter.converters;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
 import com.epam.ta.reportportal.entity.enums.TestItemIssueGroup;
 import com.epam.ta.reportportal.entity.item.issue.IssueEntity;
 import com.epam.ta.reportportal.entity.item.issue.IssueGroup;
@@ -23,48 +25,48 @@
 import com.epam.ta.reportportal.ws.model.issue.Issue;
 import org.junit.jupiter.api.Test;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 class IssueConverterTest {
 
-	@Test
-	void toModel() {
-		final IssueEntity issueEntity = getIssueEntity();
-		final Issue resource = IssueConverter.TO_MODEL.apply(issueEntity);
+  @Test
+  void toModel() {
+    final IssueEntity issueEntity = getIssueEntity();
+    final Issue resource = IssueConverter.TO_MODEL.apply(issueEntity);
 
-		assertEquals(resource.getAutoAnalyzed(), issueEntity.getAutoAnalyzed());
-		assertEquals(resource.getComment(), issueEntity.getIssueDescription());
-		assertEquals(resource.getIgnoreAnalyzer(), issueEntity.getIgnoreAnalyzer());
-		assertEquals(resource.getIssueType(), issueEntity.getIssueType().getLocator());
-	}
+    assertEquals(resource.getAutoAnalyzed(), issueEntity.getAutoAnalyzed());
+    assertEquals(resource.getComment(), issueEntity.getIssueDescription());
+    assertEquals(resource.getIgnoreAnalyzer(), issueEntity.getIgnoreAnalyzer());
+    assertEquals(resource.getIssueType(), issueEntity.getIssueType().getLocator());
+  }
 
-	@Test
-	void toResource() {
-		final Issue issue = getIssue();
-		final IssueEntity issueEntity = IssueConverter.TO_ISSUE.apply(issue);
+  @Test
+  void toResource() {
+    final Issue issue = getIssue();
+    final IssueEntity issueEntity = IssueConverter.TO_ISSUE.apply(issue);
 
-		assertEquals(issueEntity.getIgnoreAnalyzer(), issue.getIgnoreAnalyzer());
-		assertEquals(issueEntity.getAutoAnalyzed(), issue.getAutoAnalyzed());
-		assertEquals(issue.getComment(), issue.getComment());
-	}
+    assertEquals(issueEntity.getIgnoreAnalyzer(), issue.getIgnoreAnalyzer());
+    assertEquals(issueEntity.getAutoAnalyzed(), issue.getAutoAnalyzed());
+    assertEquals(issue.getComment(), issue.getComment());
+  }
 
-	private static IssueEntity getIssueEntity() {
-		final IssueEntity issue = new IssueEntity();
-		issue.setIssueType(new IssueType(new IssueGroup(TestItemIssueGroup.PRODUCT_BUG), "locator", "long name", "SNA", "color"));
-		issue.setIgnoreAnalyzer(false);
-		issue.setAutoAnalyzed(false);
-		issue.setIssueDescription("issue description");
-		return issue;
-	}
+  private static IssueEntity getIssueEntity() {
+    final IssueEntity issue = new IssueEntity();
+    issue.setIssueType(
+        new IssueType(new IssueGroup(TestItemIssueGroup.PRODUCT_BUG), "locator", "long name", "SNA",
+            "color"));
+    issue.setIgnoreAnalyzer(false);
+    issue.setAutoAnalyzed(false);
+    issue.setIssueDescription("issue description");
+    return issue;
+  }
 
-	private static Issue getIssue() {
-		Issue issue = new Issue();
-		issue.setComment("comment");
-		issue.setIgnoreAnalyzer(false);
-		issue.setAutoAnalyzed(false);
-		return issue;
-	}
+  private static Issue getIssue() {
+    Issue issue = new Issue();
+    issue.setComment("comment");
+    issue.setIgnoreAnalyzer(false);
+    issue.setAutoAnalyzed(false);
+    return issue;
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/converter/converters/ItemAttributeConverterTest.java b/src/test/java/com/epam/ta/reportportal/ws/converter/converters/ItemAttributeConverterTest.java
index 2042e33277..acf039c71f 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/converter/converters/ItemAttributeConverterTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/converter/converters/ItemAttributeConverterTest.java
@@ -16,24 +16,24 @@
 
 package com.epam.ta.reportportal.ws.converter.converters;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
 import com.epam.ta.reportportal.entity.ItemAttribute;
 import com.epam.ta.reportportal.ws.model.attribute.ItemAttributeResource;
 import org.junit.jupiter.api.Test;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 class ItemAttributeConverterTest {
 
-	@Test
-	void fromResource() {
-		ItemAttributeResource resource = new ItemAttributeResource("key", "val");
-		final ItemAttribute itemAttribute = ItemAttributeConverter.FROM_RESOURCE.apply(resource);
+  @Test
+  void fromResource() {
+    ItemAttributeResource resource = new ItemAttributeResource("key", "val");
+    final ItemAttribute itemAttribute = ItemAttributeConverter.FROM_RESOURCE.apply(resource);
 
-		assertEquals(itemAttribute.getKey(), resource.getKey());
-		assertEquals(itemAttribute.getValue(), resource.getValue());
-		assertEquals(itemAttribute.isSystem(), false);
-	}
+    assertEquals(itemAttribute.getKey(), resource.getKey());
+    assertEquals(itemAttribute.getValue(), resource.getValue());
+    assertEquals(itemAttribute.isSystem(), false);
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/converter/converters/LogConverterTest.java b/src/test/java/com/epam/ta/reportportal/ws/converter/converters/LogConverterTest.java
index 5264651a8e..33d700039e 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/converter/converters/LogConverterTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/converter/converters/LogConverterTest.java
@@ -16,60 +16,60 @@
 
 package com.epam.ta.reportportal.ws.converter.converters;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
 import com.epam.ta.reportportal.entity.attachment.Attachment;
 import com.epam.ta.reportportal.entity.enums.LogLevel;
 import com.epam.ta.reportportal.entity.item.TestItem;
-import com.epam.ta.reportportal.entity.log.Log;
+import com.epam.ta.reportportal.entity.log.LogFull;
 import com.epam.ta.reportportal.ws.model.log.LogResource;
-import org.junit.jupiter.api.Test;
-
 import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.util.Date;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 class LogConverterTest {
 
-	private static Log getLog() {
-		Log log = new Log();
-		log.setLogLevel(50000);
-		log.setLogMessage("message");
-		final TestItem testItem = new TestItem();
-		testItem.setItemId(1L);
-		log.setTestItem(testItem);
-		Attachment attachment = new Attachment();
-		attachment.setId(1L);
-		attachment.setFileId("attachId");
-		attachment.setContentType("contentType");
-		attachment.setThumbnailId("thumbnailId");
-		log.setAttachment(attachment);
-		log.setLogTime(LocalDateTime.now());
-		log.setId(2L);
-		log.setUuid("uuid");
-		log.setLastModified(LocalDateTime.now());
-		return log;
-	}
+  private static LogFull getLogFull() {
+    LogFull logFull = new LogFull();
+    logFull.setLogLevel(50000);
+    logFull.setLogMessage("message");
+    final TestItem testItem = new TestItem();
+    testItem.setItemId(1L);
+    logFull.setTestItem(testItem);
+    Attachment attachment = new Attachment();
+    attachment.setId(1L);
+    attachment.setFileId("attachId");
+    attachment.setContentType("contentType");
+    attachment.setThumbnailId("thumbnailId");
+    logFull.setAttachment(attachment);
+    logFull.setLogTime(LocalDateTime.now());
+    logFull.setId(2L);
+    logFull.setUuid("uuid");
+    logFull.setLastModified(LocalDateTime.now());
+    return logFull;
+  }
 
-	@Test
-	void toResource() {
-		final Log log = getLog();
-		final LogResource resource = LogConverter.TO_RESOURCE.apply(log);
+  @Test
+  void toResource() {
+    final LogFull logFull = getLogFull();
+    final LogResource resource = LogConverter.TO_RESOURCE.apply(logFull);
 
-		assertEquals(resource.getId(), log.getId());
-		assertEquals(resource.getUuid(), log.getUuid());
-		assertEquals(resource.getMessage(), log.getLogMessage());
-		assertEquals(resource.getLevel(), LogLevel.toLevel(log.getLogLevel()).toString());
-		assertEquals(resource.getLogTime(), Date.from(log.getLogTime().atZone(ZoneId.of("UTC")).toInstant()));
-		assertEquals(resource.getItemId(), log.getTestItem().getItemId());
+    assertEquals(resource.getId(), logFull.getId());
+    assertEquals(resource.getUuid(), logFull.getUuid());
+    assertEquals(resource.getMessage(), logFull.getLogMessage());
+    assertEquals(resource.getLevel(), LogLevel.toLevel(logFull.getLogLevel()).toString());
+    assertEquals(resource.getLogTime(),
+        Date.from(logFull.getLogTime().atZone(ZoneId.of("UTC")).toInstant()));
+    assertEquals(resource.getItemId(), logFull.getTestItem().getItemId());
 
-		final LogResource.BinaryContent binaryContent = resource.getBinaryContent();
+    final LogResource.BinaryContent binaryContent = resource.getBinaryContent();
 
-		assertEquals(binaryContent.getContentType(), log.getAttachment().getContentType());
-		assertEquals(binaryContent.getBinaryDataId(), String.valueOf(log.getAttachment().getId()));
-		assertEquals(binaryContent.getThumbnailId(), log.getAttachment().getThumbnailId());
-	}
+    assertEquals(binaryContent.getContentType(), logFull.getAttachment().getContentType());
+    assertEquals(binaryContent.getBinaryDataId(), String.valueOf(logFull.getAttachment().getId()));
+    assertEquals(binaryContent.getThumbnailId(), logFull.getAttachment().getThumbnailId());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/converter/converters/ParametersConverterTest.java b/src/test/java/com/epam/ta/reportportal/ws/converter/converters/ParametersConverterTest.java
index 2085389af5..a71e99c26a 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/converter/converters/ParametersConverterTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/converter/converters/ParametersConverterTest.java
@@ -16,46 +16,46 @@
 
 package com.epam.ta.reportportal.ws.converter.converters;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
 import com.epam.ta.reportportal.entity.item.Parameter;
 import com.epam.ta.reportportal.ws.model.ParameterResource;
 import org.junit.jupiter.api.Test;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 class ParametersConverterTest {
 
-	@Test
-	void toResource() {
-		final Parameter parameter = getParameter();
-		final ParameterResource resource = ParametersConverter.TO_RESOURCE.apply(parameter);
-
-		assertEquals(resource.getKey(), parameter.getKey());
-		assertEquals(resource.getValue(), parameter.getValue());
-	}
-
-	@Test
-	void toModel() {
-		final ParameterResource resource = getResource();
-		final Parameter parameter = ParametersConverter.TO_MODEL.apply(resource);
-
-		assertEquals(parameter.getKey(), resource.getKey());
-		assertEquals(parameter.getValue(), resource.getValue());
-	}
-
-	private static Parameter getParameter() {
-		Parameter parameter = new Parameter();
-		parameter.setKey("key");
-		parameter.setValue("value");
-		return parameter;
-	}
-
-	private static ParameterResource getResource() {
-		ParameterResource resource = new ParameterResource();
-		resource.setKey("key");
-		resource.setValue("value");
-		return resource;
-	}
+  @Test
+  void toResource() {
+    final Parameter parameter = getParameter();
+    final ParameterResource resource = ParametersConverter.TO_RESOURCE.apply(parameter);
+
+    assertEquals(resource.getKey(), parameter.getKey());
+    assertEquals(resource.getValue(), parameter.getValue());
+  }
+
+  @Test
+  void toModel() {
+    final ParameterResource resource = getResource();
+    final Parameter parameter = ParametersConverter.TO_MODEL.apply(resource);
+
+    assertEquals(parameter.getKey(), resource.getKey());
+    assertEquals(parameter.getValue(), resource.getValue());
+  }
+
+  private static Parameter getParameter() {
+    Parameter parameter = new Parameter();
+    parameter.setKey("key");
+    parameter.setValue("value");
+    return parameter;
+  }
+
+  private static ParameterResource getResource() {
+    ParameterResource resource = new ParameterResource();
+    resource.setKey("key");
+    resource.setValue("value");
+    return resource;
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/converter/converters/PatternTemplateConverterTest.java b/src/test/java/com/epam/ta/reportportal/ws/converter/converters/PatternTemplateConverterTest.java
index d329c12fc2..f97b2dbb7e 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/converter/converters/PatternTemplateConverterTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/converter/converters/PatternTemplateConverterTest.java
@@ -16,54 +16,55 @@
 
 package com.epam.ta.reportportal.ws.converter.converters;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
 import com.epam.ta.reportportal.entity.pattern.PatternTemplate;
 import com.epam.ta.reportportal.entity.pattern.PatternTemplateType;
 import com.epam.ta.reportportal.ws.model.activity.PatternTemplateActivityResource;
 import com.epam.ta.reportportal.ws.model.project.config.pattern.PatternTemplateResource;
 import org.junit.jupiter.api.Test;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class PatternTemplateConverterTest {
 
-	@Test
-	public void toResourceTest() {
+  @Test
+  public void toResourceTest() {
 
-		PatternTemplate patternTemplate = get();
+    PatternTemplate patternTemplate = get();
 
-		PatternTemplateResource resource = PatternTemplateConverter.TO_RESOURCE.apply(patternTemplate);
+    PatternTemplateResource resource = PatternTemplateConverter.TO_RESOURCE.apply(patternTemplate);
 
-		assertEquals(patternTemplate.getId(), resource.getId());
-		assertEquals(patternTemplate.getTemplateType().name(), resource.getType());
-		assertEquals(patternTemplate.getName(), resource.getName());
-		assertEquals(patternTemplate.getValue(), resource.getValue());
-		assertEquals(patternTemplate.isEnabled(), resource.getEnabled());
-	}
+    assertEquals(patternTemplate.getId(), resource.getId());
+    assertEquals(patternTemplate.getTemplateType().name(), resource.getType());
+    assertEquals(patternTemplate.getName(), resource.getName());
+    assertEquals(patternTemplate.getValue(), resource.getValue());
+    assertEquals(patternTemplate.isEnabled(), resource.getEnabled());
+  }
 
-	@Test
-	public void toActivityResourceTest() {
+  @Test
+  public void toActivityResourceTest() {
 
-		PatternTemplate patternTemplate = get();
+    PatternTemplate patternTemplate = get();
 
-		PatternTemplateActivityResource resource = PatternTemplateConverter.TO_ACTIVITY_RESOURCE.apply(patternTemplate);
+    PatternTemplateActivityResource resource = PatternTemplateConverter.TO_ACTIVITY_RESOURCE.apply(
+        patternTemplate);
 
-		assertEquals(patternTemplate.getId(), resource.getId());
-		assertEquals(patternTemplate.getProjectId(), resource.getProjectId());
-		assertEquals(patternTemplate.getName(), resource.getName());
-	}
+    assertEquals(patternTemplate.getId(), resource.getId());
+    assertEquals(patternTemplate.getProjectId(), resource.getProjectId());
+    assertEquals(patternTemplate.getName(), resource.getName());
+  }
 
-	private PatternTemplate get() {
-		PatternTemplate patternTemplate = new PatternTemplate();
-		patternTemplate.setId(1L);
-		patternTemplate.setProjectId(1L);
-		patternTemplate.setTemplateType(PatternTemplateType.STRING);
-		patternTemplate.setEnabled(true);
-		patternTemplate.setValue("qwe");
-		patternTemplate.setName("name");
-		return patternTemplate;
-	}
+  private PatternTemplate get() {
+    PatternTemplate patternTemplate = new PatternTemplate();
+    patternTemplate.setId(1L);
+    patternTemplate.setProjectId(1L);
+    patternTemplate.setTemplateType(PatternTemplateType.STRING);
+    patternTemplate.setEnabled(true);
+    patternTemplate.setValue("qwe");
+    patternTemplate.setName("name");
+    return patternTemplate;
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/converter/converters/ProjectActivityConverterTest.java b/src/test/java/com/epam/ta/reportportal/ws/converter/converters/ProjectActivityConverterTest.java
index abbfc0ecd3..05a4dfb394 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/converter/converters/ProjectActivityConverterTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/converter/converters/ProjectActivityConverterTest.java
@@ -16,6 +16,9 @@
 
 package com.epam.ta.reportportal.ws.converter.converters;
 
+import static org.assertj.core.api.Java6Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
 import com.epam.ta.reportportal.entity.attribute.Attribute;
 import com.epam.ta.reportportal.entity.project.Project;
 import com.epam.ta.reportportal.entity.project.ProjectAttribute;
@@ -23,35 +26,34 @@
 import com.google.common.collect.Sets;
 import org.junit.jupiter.api.Test;
 
-import static org.assertj.core.api.Java6Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 class ProjectActivityConverterTest {
 
-	@Test
-	void toActivityResource() {
-		final Project project = getProject();
-		final ProjectAttributesActivityResource resource = ProjectActivityConverter.TO_ACTIVITY_RESOURCE.apply(project);
-
-		assertEquals(resource.getProjectId(), project.getId());
-		assertEquals(resource.getProjectName(), project.getName());
-		assertThat(resource.getConfig()).containsOnlyKeys("attr.lol");
-		assertThat(resource.getConfig()).containsValue("value");
-
-	}
-
-	private static Project getProject() {
-		Project project = new Project();
-		project.setId(1L);
-		project.setName("name");
-		final Attribute attribute = new Attribute();
-		attribute.setId(2L);
-		attribute.setName("attr.lol");
-		final ProjectAttribute projectAttribute = new ProjectAttribute().withProject(project).withValue("value").withAttribute(attribute);
-		project.setProjectAttributes(Sets.newHashSet(projectAttribute));
-		return project;
-	}
+  @Test
+  void toActivityResource() {
+    final Project project = getProject();
+    final ProjectAttributesActivityResource resource = ProjectActivityConverter.TO_ACTIVITY_RESOURCE.apply(
+        project);
+
+    assertEquals(resource.getProjectId(), project.getId());
+    assertEquals(resource.getProjectName(), project.getName());
+    assertThat(resource.getConfig()).containsOnlyKeys("attr.lol");
+    assertThat(resource.getConfig()).containsValue("value");
+
+  }
+
+  private static Project getProject() {
+    Project project = new Project();
+    project.setId(1L);
+    project.setName("name");
+    final Attribute attribute = new Attribute();
+    attribute.setId(2L);
+    attribute.setName("attr.lol");
+    final ProjectAttribute projectAttribute = new ProjectAttribute().withProject(project)
+        .withValue("value").withAttribute(attribute);
+    project.setProjectAttributes(Sets.newHashSet(projectAttribute));
+    return project;
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/converter/converters/RestorePasswordBidConverterTest.java b/src/test/java/com/epam/ta/reportportal/ws/converter/converters/RestorePasswordBidConverterTest.java
index 94f82f3f14..6d4bdd0f36 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/converter/converters/RestorePasswordBidConverterTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/converter/converters/RestorePasswordBidConverterTest.java
@@ -16,26 +16,26 @@
 
 package com.epam.ta.reportportal.ws.converter.converters;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
 import com.epam.ta.reportportal.entity.user.RestorePasswordBid;
 import com.epam.ta.reportportal.ws.model.user.RestorePasswordRQ;
 import org.junit.jupiter.api.Test;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 class RestorePasswordBidConverterTest {
 
-	@Test
-	void toBid() {
-		final RestorePasswordRQ request = new RestorePasswordRQ();
-		request.setEmail("email@example.com");
+  @Test
+  void toBid() {
+    final RestorePasswordRQ request = new RestorePasswordRQ();
+    request.setEmail("email@example.com");
 
-		final RestorePasswordBid bid = RestorePasswordBidConverter.TO_BID.apply(request);
+    final RestorePasswordBid bid = RestorePasswordBidConverter.TO_BID.apply(request);
 
-		assertEquals(bid.getEmail(), request.getEmail());
-		assertNotNull(bid.getUuid());
-	}
+    assertEquals(bid.getEmail(), request.getEmail());
+    assertNotNull(bid.getUuid());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/converter/converters/TestItemConverterTest.java b/src/test/java/com/epam/ta/reportportal/ws/converter/converters/TestItemConverterTest.java
index 73b4e49f93..3d1a8139c6 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/converter/converters/TestItemConverterTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/converter/converters/TestItemConverterTest.java
@@ -16,6 +16,11 @@
 
 package com.epam.ta.reportportal.ws.converter.converters;
 
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
 import com.epam.ta.reportportal.entity.ItemAttribute;
 import com.epam.ta.reportportal.entity.bts.Ticket;
 import com.epam.ta.reportportal.entity.enums.StatusEnum;
@@ -33,163 +38,179 @@
 import com.epam.ta.reportportal.ws.model.TestItemResource;
 import com.epam.ta.reportportal.ws.model.activity.TestItemActivityResource;
 import com.google.common.collect.Sets;
-import org.junit.jupiter.api.Test;
-
 import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.util.Date;
 import java.util.stream.Collectors;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 class TestItemConverterTest {
 
-	@Test
-	void toActivityResourceNullTest() {
-		assertThrows(NullPointerException.class, () -> TestItemConverter.TO_ACTIVITY_RESOURCE.apply(null, null));
-	}
+  @Test
+  void toActivityResourceNullTest() {
+    assertThrows(NullPointerException.class,
+        () -> TestItemConverter.TO_ACTIVITY_RESOURCE.apply(null, null));
+  }
 
-	@Test
-	void toResourceNullTest() {
-		assertThrows(NullPointerException.class, () -> TestItemConverter.TO_RESOURCE.apply(null));
-	}
+  @Test
+  void toResourceNullTest() {
+    assertThrows(NullPointerException.class, () -> TestItemConverter.TO_RESOURCE.apply(null));
+  }
 
-	@Test
-	void toActivityResource() {
-		final TestItem item = getItem(true);
-		final TestItemActivityResource activityResource = TestItemConverter.TO_ACTIVITY_RESOURCE.apply(item, 4L);
+  @Test
+  void toActivityResource() {
+    final TestItem item = getItem(true);
+    final TestItemActivityResource activityResource = TestItemConverter.TO_ACTIVITY_RESOURCE.apply(
+        item, 4L);
 
-		assertEquals(activityResource.getId(), item.getItemId());
-		assertEquals(activityResource.getName(), item.getName());
-		assertEquals((long) activityResource.getProjectId(), 4L);
-		assertEquals(activityResource.getIssueDescription(), item.getItemResults().getIssue().getIssueDescription());
-		assertEquals(activityResource.getIssueTypeLongName(), item.getItemResults().getIssue().getIssueType().getLongName());
-		assertEquals(activityResource.getStatus(), item.getItemResults().getStatus().name());
-		assertEquals(
-				activityResource.getTickets(),
-				item.getItemResults()
-						.getIssue()
-						.getTickets()
-						.stream()
-						.map(it -> it.getTicketId().concat(":").concat(it.getUrl()))
-						.collect(Collectors.joining(", "))
-		);
-		assertEquals(activityResource.isIgnoreAnalyzer(), item.getItemResults().getIssue().getIgnoreAnalyzer());
-		assertEquals(activityResource.isAutoAnalyzed(), item.getItemResults().getIssue().getAutoAnalyzed());
-	}
+    assertEquals(activityResource.getId(), item.getItemId());
+    assertEquals(activityResource.getName(), item.getName());
+    assertEquals((long) activityResource.getProjectId(), 4L);
+    assertEquals(activityResource.getIssueDescription(),
+        item.getItemResults().getIssue().getIssueDescription());
+    assertEquals(activityResource.getIssueTypeLongName(),
+        item.getItemResults().getIssue().getIssueType().getLongName());
+    assertEquals(activityResource.getStatus(), item.getItemResults().getStatus().name());
+    assertEquals(
+        activityResource.getTickets(),
+        item.getItemResults()
+            .getIssue()
+            .getTickets()
+            .stream()
+            .map(it -> it.getTicketId().concat(":").concat(it.getUrl()))
+            .collect(Collectors.joining(", "))
+    );
+    assertEquals(activityResource.isIgnoreAnalyzer(),
+        item.getItemResults().getIssue().getIgnoreAnalyzer());
+    assertEquals(activityResource.isAutoAnalyzed(),
+        item.getItemResults().getIssue().getAutoAnalyzed());
+  }
 
-	@Test
-	void toResource() {
-		final TestItem item = getItem(true);
-		final TestItemResource resource = TestItemConverter.TO_RESOURCE.apply(item);
+  @Test
+  void toResource() {
+    final TestItem item = getItem(true);
+    final TestItemResource resource = TestItemConverter.TO_RESOURCE.apply(item);
 
-		assertEquals(resource.getName(), item.getName());
-		assertEquals(resource.getDescription(), item.getDescription());
-		assertEquals(resource.getLaunchId(), item.getLaunchId());
-		assertEquals(resource.getUuid(), item.getUuid());
-		assertEquals(resource.getItemId(), item.getItemId());
-		assertEquals(resource.getParent(), item.getParentId());
-		assertEquals(resource.getPath(), item.getPath());
-		assertEquals(resource.getStatus(), item.getItemResults().getStatus().name());
-		assertEquals(resource.getType(), item.getType().name());
-		assertEquals(resource.getStartTime(), Date.from(item.getStartTime().atZone(ZoneId.of("UTC")).toInstant()));
-		assertEquals(resource.getEndTime(), Date.from(item.getItemResults().getEndTime().atZone(ZoneId.of("UTC")).toInstant()));
-		assertEquals(resource.getUniqueId(), item.getUniqueId());
-		assertThat(resource.getAttributes()
-				.stream()
-				.map(ItemAttributeConverter.FROM_RESOURCE)
-				.collect(Collectors.toSet())).containsExactlyElementsOf(item.getAttributes());
-		assertThat(resource.getParameters()
-				.stream()
-				.map(ParametersConverter.TO_MODEL)
-				.collect(Collectors.toSet())).containsExactlyElementsOf(item.getParameters());
-		assertThat(resource.getStatisticsResource()).isEqualToComparingFieldByField(StatisticsConverter.TO_RESOURCE.apply(item.getItemResults()
-				.getStatistics()));
-		assertEquals(resource.getIssue().getComment(), item.getItemResults().getIssue().getIssueDescription());
-		assertEquals(resource.getIssue().getAutoAnalyzed(), item.getItemResults().getIssue().getAutoAnalyzed());
-		assertEquals(resource.getIssue().getIssueType(), item.getItemResults().getIssue().getIssueType().getLocator());
-		assertEquals(resource.getIssue().getIgnoreAnalyzer(), item.getItemResults().getIssue().getIgnoreAnalyzer());
-	}
+    assertEquals(resource.getName(), item.getName());
+    assertEquals(resource.getDescription(), item.getDescription());
+    assertEquals(resource.getLaunchId(), item.getLaunchId());
+    assertEquals(resource.getUuid(), item.getUuid());
+    assertEquals(resource.getItemId(), item.getItemId());
+    assertEquals(resource.getParent(), item.getParentId());
+    assertEquals(resource.getPath(), item.getPath());
+    assertEquals(resource.getStatus(), item.getItemResults().getStatus().name());
+    assertEquals(resource.getType(), item.getType().name());
+    assertEquals(resource.getStartTime(),
+        Date.from(item.getStartTime().atZone(ZoneId.of("UTC")).toInstant()));
+    assertEquals(resource.getEndTime(),
+        Date.from(item.getItemResults().getEndTime().atZone(ZoneId.of("UTC")).toInstant()));
+    assertEquals(resource.getUniqueId(), item.getUniqueId());
+    assertThat(resource.getAttributes()
+        .stream()
+        .map(ItemAttributeConverter.FROM_RESOURCE)
+        .collect(Collectors.toSet())).containsExactlyElementsOf(item.getAttributes());
+    assertThat(resource.getParameters()
+        .stream()
+        .map(ParametersConverter.TO_MODEL)
+        .collect(Collectors.toSet())).containsExactlyElementsOf(item.getParameters());
+    assertThat(resource.getStatisticsResource()).isEqualToComparingFieldByField(
+        StatisticsConverter.TO_RESOURCE.apply(item.getItemResults()
+            .getStatistics()));
+    assertEquals(resource.getIssue().getComment(),
+        item.getItemResults().getIssue().getIssueDescription());
+    assertEquals(resource.getIssue().getAutoAnalyzed(),
+        item.getItemResults().getIssue().getAutoAnalyzed());
+    assertEquals(resource.getIssue().getIssueType(),
+        item.getItemResults().getIssue().getIssueType().getLocator());
+    assertEquals(resource.getIssue().getIgnoreAnalyzer(),
+        item.getItemResults().getIssue().getIgnoreAnalyzer());
+  }
 
-	@Test
-	void toResourceWithoutIssue() {
-		final TestItem item = getItem(false);
-		final TestItemResource resource = TestItemConverter.TO_RESOURCE.apply(item);
+  @Test
+  void toResourceWithoutIssue() {
+    final TestItem item = getItem(false);
+    final TestItemResource resource = TestItemConverter.TO_RESOURCE.apply(item);
 
-		assertEquals(resource.getName(), item.getName());
-		assertEquals(resource.getDescription(), item.getDescription());
-		assertEquals(resource.getLaunchId(), item.getLaunchId());
-		assertEquals(resource.getUuid(), item.getUuid());
-		assertEquals(resource.getItemId(), item.getItemId());
-		assertEquals(resource.getParent(), item.getParentId());
-		assertEquals(resource.getPath(), item.getPath());
-		assertEquals(resource.getStatus(), item.getItemResults().getStatus().name());
-		assertEquals(resource.getType(), item.getType().name());
-		assertEquals(resource.getStartTime(), Date.from(item.getStartTime().atZone(ZoneId.of("UTC")).toInstant()));
-		assertEquals(resource.getEndTime(), Date.from(item.getItemResults().getEndTime().atZone(ZoneId.of("UTC")).toInstant()));
-		assertEquals(resource.getUniqueId(), item.getUniqueId());
-		assertThat(resource.getAttributes()
-				.stream()
-				.map(ItemAttributeConverter.FROM_RESOURCE)
-				.collect(Collectors.toSet())).containsExactlyElementsOf(item.getAttributes());
-		assertThat(resource.getParameters()
-				.stream()
-				.map(ParametersConverter.TO_MODEL)
-				.collect(Collectors.toSet())).containsExactlyElementsOf(item.getParameters());
-		assertThat(resource.getStatisticsResource()).isEqualToComparingFieldByField(StatisticsConverter.TO_RESOURCE.apply(item.getItemResults()
-				.getStatistics()));
-		assertNull(resource.getIssue());
-	}
+    assertEquals(resource.getName(), item.getName());
+    assertEquals(resource.getDescription(), item.getDescription());
+    assertEquals(resource.getLaunchId(), item.getLaunchId());
+    assertEquals(resource.getUuid(), item.getUuid());
+    assertEquals(resource.getItemId(), item.getItemId());
+    assertEquals(resource.getParent(), item.getParentId());
+    assertEquals(resource.getPath(), item.getPath());
+    assertEquals(resource.getStatus(), item.getItemResults().getStatus().name());
+    assertEquals(resource.getType(), item.getType().name());
+    assertEquals(resource.getStartTime(),
+        Date.from(item.getStartTime().atZone(ZoneId.of("UTC")).toInstant()));
+    assertEquals(resource.getEndTime(),
+        Date.from(item.getItemResults().getEndTime().atZone(ZoneId.of("UTC")).toInstant()));
+    assertEquals(resource.getUniqueId(), item.getUniqueId());
+    assertThat(resource.getAttributes()
+        .stream()
+        .map(ItemAttributeConverter.FROM_RESOURCE)
+        .collect(Collectors.toSet())).containsExactlyElementsOf(item.getAttributes());
+    assertThat(resource.getParameters()
+        .stream()
+        .map(ParametersConverter.TO_MODEL)
+        .collect(Collectors.toSet())).containsExactlyElementsOf(item.getParameters());
+    assertThat(resource.getStatisticsResource()).isEqualToComparingFieldByField(
+        StatisticsConverter.TO_RESOURCE.apply(item.getItemResults()
+            .getStatistics()));
+    assertNull(resource.getIssue());
+  }
 
-	private TestItem getItem(boolean hasIssue) {
-		TestItem item = new TestItem();
-		item.setName("name");
-		item.setDescription("description");
-		item.setStartTime(LocalDateTime.now());
-		item.setUniqueId("uniqueId");
-		item.setUuid("uuid");
-		item.setItemId(1L);
-		item.setType(TestItemTypeEnum.STEP);
-		item.setPath("1.2.3");
-		final Parameter parameter = new Parameter();
-		parameter.setKey("key");
-		parameter.setValue("value");
-		item.setParameters(Sets.newHashSet(parameter));
-		item.setAttributes(Sets.newHashSet(new ItemAttribute("key1", "value1", false), new ItemAttribute("key2", "value2", false)));
-		final Launch launch = new Launch();
-		launch.setProjectId(4L);
-		launch.setId(2L);
-		item.setLaunchId(launch.getId());
-		item.setHasChildren(false);
-		final TestItem parent = new TestItem();
-		parent.setItemId(3L);
-		item.setParentId(parent.getItemId());
-		final TestItemResults itemResults = new TestItemResults();
-		itemResults.setStatus(StatusEnum.FAILED);
-		itemResults.setEndTime(LocalDateTime.now());
-		if (hasIssue) {
-			final IssueEntity issue = new IssueEntity();
-			issue.setIssueId(3L);
-			issue.setIssueType(new IssueType(new IssueGroup(TestItemIssueGroup.PRODUCT_BUG), "locator", "long name", "SNA", "color"));
-			issue.setIgnoreAnalyzer(false);
-			issue.setAutoAnalyzed(false);
-			issue.setIssueDescription("issue description");
-			final Ticket ticket = new Ticket();
-			ticket.setTicketId("ticketId1");
-			ticket.setUrl("http:/example.com/ticketId1");
-			final Ticket ticket1 = new Ticket();
-			ticket1.setTicketId("ticketId2");
-			ticket1.setUrl("http:/example.com/ticketId2");
-			issue.setTickets(Sets.newHashSet(ticket, ticket1));
-			itemResults.setIssue(issue);
-		}
-		itemResults.setStatistics(Sets.newHashSet(new Statistics(new StatisticsField("statistics$defects$automation_bug$total"), 1, 2L)));
-		item.setItemResults(itemResults);
-		return item;
-	}
+  private TestItem getItem(boolean hasIssue) {
+    TestItem item = new TestItem();
+    item.setName("name");
+    item.setDescription("description");
+    item.setStartTime(LocalDateTime.now());
+    item.setUniqueId("uniqueId");
+    item.setUuid("uuid");
+    item.setItemId(1L);
+    item.setType(TestItemTypeEnum.STEP);
+    item.setPath("1.2.3");
+    final Parameter parameter = new Parameter();
+    parameter.setKey("key");
+    parameter.setValue("value");
+    item.setParameters(Sets.newHashSet(parameter));
+    item.setAttributes(Sets.newHashSet(new ItemAttribute("key1", "value1", false),
+        new ItemAttribute("key2", "value2", false)));
+    final Launch launch = new Launch();
+    launch.setProjectId(4L);
+    launch.setId(2L);
+    item.setLaunchId(launch.getId());
+    item.setHasChildren(false);
+    final TestItem parent = new TestItem();
+    parent.setItemId(3L);
+    item.setParentId(parent.getItemId());
+    final TestItemResults itemResults = new TestItemResults();
+    itemResults.setStatus(StatusEnum.FAILED);
+    itemResults.setEndTime(LocalDateTime.now());
+    if (hasIssue) {
+      final IssueEntity issue = new IssueEntity();
+      issue.setIssueId(3L);
+      issue.setIssueType(
+          new IssueType(new IssueGroup(TestItemIssueGroup.PRODUCT_BUG), "locator", "long name",
+              "SNA", "color"));
+      issue.setIgnoreAnalyzer(false);
+      issue.setAutoAnalyzed(false);
+      issue.setIssueDescription("issue description");
+      final Ticket ticket = new Ticket();
+      ticket.setTicketId("ticketId1");
+      ticket.setUrl("http:/example.com/ticketId1");
+      final Ticket ticket1 = new Ticket();
+      ticket1.setTicketId("ticketId2");
+      ticket1.setUrl("http:/example.com/ticketId2");
+      issue.setTickets(Sets.newHashSet(ticket, ticket1));
+      itemResults.setIssue(issue);
+    }
+    itemResults.setStatistics(Sets.newHashSet(
+        new Statistics(new StatisticsField("statistics$defects$automation_bug$total"), 1, 2L)));
+    item.setItemResults(itemResults);
+    return item;
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/converter/converters/TicketConverterTest.java b/src/test/java/com/epam/ta/reportportal/ws/converter/converters/TicketConverterTest.java
index ce89064856..c286ef43e2 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/converter/converters/TicketConverterTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/converter/converters/TicketConverterTest.java
@@ -16,34 +16,34 @@
 
 package com.epam.ta.reportportal.ws.converter.converters;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
 import com.epam.ta.reportportal.entity.bts.Ticket;
 import com.epam.ta.reportportal.ws.model.issue.Issue;
 import org.junit.jupiter.api.Test;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 class TicketConverterTest {
 
-	@Test
-	void toTicket() {
-		final Issue.ExternalSystemIssue issue = getIssue();
-		final Ticket resource = TicketConverter.TO_TICKET.apply(issue);
+  @Test
+  void toTicket() {
+    final Issue.ExternalSystemIssue issue = getIssue();
+    final Ticket resource = TicketConverter.TO_TICKET.apply(issue);
 
-		assertEquals(resource.getTicketId(), issue.getTicketId());
-		assertEquals(resource.getUrl(), issue.getUrl());
-		assertEquals(resource.getBtsUrl(), issue.getBtsUrl());
-		assertEquals(resource.getBtsProject(), issue.getBtsProject());
-	}
+    assertEquals(resource.getTicketId(), issue.getTicketId());
+    assertEquals(resource.getUrl(), issue.getUrl());
+    assertEquals(resource.getBtsUrl(), issue.getBtsUrl());
+    assertEquals(resource.getBtsProject(), issue.getBtsProject());
+  }
 
-	private static Issue.ExternalSystemIssue getIssue() {
-		Issue.ExternalSystemIssue issue = new Issue.ExternalSystemIssue();
-		issue.setBtsUrl("jira.com");
-		issue.setBtsUrl("project");
-		issue.setTicketId("ticketId");
-		issue.setUrl("https:/example.com/ticketId");
-		return issue;
-	}
+  private static Issue.ExternalSystemIssue getIssue() {
+    Issue.ExternalSystemIssue issue = new Issue.ExternalSystemIssue();
+    issue.setBtsUrl("jira.com");
+    issue.setBtsUrl("project");
+    issue.setTicketId("ticketId");
+    issue.setUrl("https:/example.com/ticketId");
+    return issue;
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/converter/converters/UserCreationBidConverterTest.java b/src/test/java/com/epam/ta/reportportal/ws/converter/converters/UserCreationBidConverterTest.java
index ef5c66853b..b1b0935fdc 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/converter/converters/UserCreationBidConverterTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/converter/converters/UserCreationBidConverterTest.java
@@ -16,40 +16,39 @@
 
 package com.epam.ta.reportportal.ws.converter.converters;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
 import com.epam.ta.reportportal.entity.project.Project;
 import com.epam.ta.reportportal.entity.user.UserCreationBid;
 import com.epam.ta.reportportal.ws.model.user.CreateUserRQ;
-import org.junit.jupiter.api.Test;
-
 import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.util.Date;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 class UserCreationBidConverterTest {
 
-	@Test
-	void toUser() {
-		CreateUserRQ request = new CreateUserRQ();
-		final String email = "email@example.com";
-		request.setEmail(email);
-		final String role = "role";
-		request.setRole(role);
-		final Project project = new Project();
-		project.setName("projectName");
-		final Date creationDate = Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant());
-		project.setCreationDate(creationDate);
-
-		final UserCreationBid bid = UserCreationBidConverter.TO_USER.apply(request, project);
-
-		assertNotNull(bid.getUuid());
-		assertEquals(bid.getEmail(), email);
-		assertEquals(bid.getRole(), role);
-		assertEquals(bid.getDefaultProject(), project);
-	}
+  @Test
+  void toUser() {
+    CreateUserRQ request = new CreateUserRQ();
+    final String email = "email@example.com";
+    request.setEmail(email);
+    final String role = "role";
+    request.setRole(role);
+    final Project project = new Project();
+    project.setName("projectName");
+    final Date creationDate = Date.from(LocalDateTime.now().atZone(ZoneId.of("UTC")).toInstant());
+    project.setCreationDate(creationDate);
+
+    final UserCreationBid bid = UserCreationBidConverter.TO_USER.apply(request, project);
+
+    assertNotNull(bid.getUuid());
+    assertEquals(bid.getEmail(), email);
+    assertEquals(bid.getRole(), role);
+    assertEquals(bid.getProjectName(), project.getName());
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/launch/LaunchResourceAttributeUpdaterTest.java b/src/test/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/launch/LaunchResourceAttributeUpdaterTest.java
index 8d18fc62ed..f58d7b5c7a 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/launch/LaunchResourceAttributeUpdaterTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/launch/LaunchResourceAttributeUpdaterTest.java
@@ -16,51 +16,51 @@
 
 package com.epam.ta.reportportal.ws.converter.resource.handler.attribute.launch;
 
+import static java.util.stream.Collectors.groupingBy;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
 import com.epam.ta.reportportal.entity.ItemAttribute;
 import com.epam.ta.reportportal.ws.model.attribute.ItemAttributeResource;
 import com.epam.ta.reportportal.ws.model.launch.LaunchResource;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-
-import static java.util.stream.Collectors.groupingBy;
-import static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class LaunchResourceAttributeUpdaterTest {
 
-	private final LaunchResourceAttributeUpdater launchResourceAttributeUpdater = new LaunchResourceAttributeUpdater();
+  private final LaunchResourceAttributeUpdater launchResourceAttributeUpdater = new LaunchResourceAttributeUpdater();
 
-	@Test
-	void shouldUpdate() {
-		final LaunchResource launchResource = new LaunchResource();
-		final List<ItemAttribute> attributes = List.of(new ItemAttribute("k1", "v1", false), new ItemAttribute("k2", "v2", false));
-		launchResourceAttributeUpdater.handle(launchResource, attributes);
+  @Test
+  void shouldUpdate() {
+    final LaunchResource launchResource = new LaunchResource();
+    final List<ItemAttribute> attributes = List.of(new ItemAttribute("k1", "v1", false),
+        new ItemAttribute("k2", "v2", false));
+    launchResourceAttributeUpdater.handle(launchResource, attributes);
 
-		final Set<ItemAttributeResource> resourceAttributes = launchResource.getAttributes();
-		Assertions.assertEquals(2, resourceAttributes.size());
+    final Set<ItemAttributeResource> resourceAttributes = launchResource.getAttributes();
+    Assertions.assertEquals(2, resourceAttributes.size());
 
-		final Map<String, List<ItemAttributeResource>> mapping = resourceAttributes.stream()
-				.collect(groupingBy(ItemAttributeResource::getKey));
+    final Map<String, List<ItemAttributeResource>> mapping = resourceAttributes.stream()
+        .collect(groupingBy(ItemAttributeResource::getKey));
 
-		final ItemAttributeResource firstResource = mapping.get("k1").get(0);
-		final ItemAttributeResource secondResource = mapping.get("k2").get(0);
+    final ItemAttributeResource firstResource = mapping.get("k1").get(0);
+    final ItemAttributeResource secondResource = mapping.get("k2").get(0);
 
-		final ItemAttribute firstAttribute = attributes.get(0);
-		final ItemAttribute secondAttribute = attributes.get(1);
-		shouldEqual(firstAttribute, firstResource);
-		shouldEqual(secondAttribute, secondResource);
+    final ItemAttribute firstAttribute = attributes.get(0);
+    final ItemAttribute secondAttribute = attributes.get(1);
+    shouldEqual(firstAttribute, firstResource);
+    shouldEqual(secondAttribute, secondResource);
 
-	}
+  }
 
-	private void shouldEqual(ItemAttribute itemAttribute, ItemAttributeResource resource) {
-		assertEquals(itemAttribute.getKey(), resource.getKey());
-		assertEquals(itemAttribute.getValue(), resource.getValue());
-	}
+  private void shouldEqual(ItemAttribute itemAttribute, ItemAttributeResource resource) {
+    assertEquals(itemAttribute.getKey(), resource.getKey());
+    assertEquals(itemAttribute.getValue(), resource.getValue());
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/launch/LaunchResourceMetadataAttributeUpdaterTest.java b/src/test/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/launch/LaunchResourceMetadataAttributeUpdaterTest.java
index 735963e040..f09dadb2fe 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/launch/LaunchResourceMetadataAttributeUpdaterTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/launch/LaunchResourceMetadataAttributeUpdaterTest.java
@@ -16,47 +16,48 @@
 
 package com.epam.ta.reportportal.ws.converter.resource.handler.attribute.launch;
 
+import static com.epam.ta.reportportal.core.launch.cluster.pipeline.SaveLastRunAttributePartProvider.RP_CLUSTER_LAST_RUN_KEY;
+
 import com.epam.ta.reportportal.entity.ItemAttribute;
 import com.epam.ta.reportportal.ws.model.launch.LaunchResource;
-import org.apache.commons.collections4.MapUtils;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-
-import static com.epam.ta.reportportal.core.launch.cluster.pipeline.SaveLastRunAttributePartProvider.RP_CLUSTER_LAST_RUN_KEY;
+import org.apache.commons.collections4.MapUtils;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
 
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class LaunchResourceMetadataAttributeUpdaterTest {
 
-	private final LaunchResourceMetadataAttributeUpdater updater = new LaunchResourceMetadataAttributeUpdater(Set.of(RP_CLUSTER_LAST_RUN_KEY));
-
-	@Test
-	void shouldUpdateMetadataWhenAttributeMatches() {
-		final LaunchResource launchResource = new LaunchResource();
-		final List<ItemAttribute> attributes = List.of(new ItemAttribute(RP_CLUSTER_LAST_RUN_KEY, "v1", false),
-				new ItemAttribute("k2", "v2", false)
-		);
-		updater.handle(launchResource, attributes);
-
-		final Map<String, Object> metadata = launchResource.getMetadata();
-		Assertions.assertFalse(metadata.isEmpty());
-		Assertions.assertEquals("v1", metadata.get(RP_CLUSTER_LAST_RUN_KEY));
-	}
-
-	@Test
-	void shouldNotUpdateMetadataWhenAttributeMatches() {
-		final LaunchResource launchResource = new LaunchResource();
-		final List<ItemAttribute> attributes = List.of(new ItemAttribute("k1", "v1", false),
-				new ItemAttribute("k2", "v2", false)
-		);
-		updater.handle(launchResource, attributes);
-
-		Assertions.assertTrue(MapUtils.isEmpty(launchResource.getMetadata()));
-	}
+  private final LaunchResourceMetadataAttributeUpdater updater = new LaunchResourceMetadataAttributeUpdater(
+      Set.of(RP_CLUSTER_LAST_RUN_KEY));
+
+  @Test
+  void shouldUpdateMetadataWhenAttributeMatches() {
+    final LaunchResource launchResource = new LaunchResource();
+    final List<ItemAttribute> attributes = List.of(
+        new ItemAttribute(RP_CLUSTER_LAST_RUN_KEY, "v1", false),
+        new ItemAttribute("k2", "v2", false)
+    );
+    updater.handle(launchResource, attributes);
+
+    final Map<String, Object> metadata = launchResource.getMetadata();
+    Assertions.assertFalse(metadata.isEmpty());
+    Assertions.assertEquals("v1", metadata.get(RP_CLUSTER_LAST_RUN_KEY));
+  }
+
+  @Test
+  void shouldNotUpdateMetadataWhenAttributeMatches() {
+    final LaunchResource launchResource = new LaunchResource();
+    final List<ItemAttribute> attributes = List.of(new ItemAttribute("k1", "v1", false),
+        new ItemAttribute("k2", "v2", false)
+    );
+    updater.handle(launchResource, attributes);
+
+    Assertions.assertTrue(MapUtils.isEmpty(launchResource.getMetadata()));
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/matcher/PredicateItemAttributeTypeMatcherTest.java b/src/test/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/matcher/PredicateItemAttributeTypeMatcherTest.java
index 27b2c956a9..f247e82583 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/matcher/PredicateItemAttributeTypeMatcherTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/converter/resource/handler/attribute/matcher/PredicateItemAttributeTypeMatcherTest.java
@@ -21,38 +21,38 @@
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
-import static org.junit.jupiter.api.Assertions.*;
-
 /**
  * @author <a href="mailto:ivan_budayeu@epam.com">Ivan Budayeu</a>
  */
 class PredicateItemAttributeTypeMatcherTest {
 
-	private final PredicateItemAttributeTypeMatcher systemAttributeMatcher = new PredicateItemAttributeTypeMatcher(ItemAttribute::isSystem, ItemAttributeType.SYSTEM);
-	private final PredicateItemAttributeTypeMatcher publicAttributeMatcher = new PredicateItemAttributeTypeMatcher(it -> !it.isSystem(), ItemAttributeType.PUBLIC);
-
-	@Test
-	void publicShouldReturnTrue() {
-		final ItemAttribute publicAttribute = new ItemAttribute("k1", "v1", false);
-		Assertions.assertTrue(publicAttributeMatcher.matches(publicAttribute));
-	}
-
-	@Test
-	void publicShouldReturnFalse() {
-		final ItemAttribute systemAttribute = new ItemAttribute("k1", "v1", true);
-		Assertions.assertFalse(publicAttributeMatcher.matches(systemAttribute));
-	}
-
-	@Test
-	void systemShouldReturnTrue() {
-		final ItemAttribute systemAttribute = new ItemAttribute("k1", "v1", true);
-		Assertions.assertTrue(systemAttributeMatcher.matches(systemAttribute));
-	}
-
-	@Test
-	void systemShouldReturnFalse() {
-		final ItemAttribute publicAttribute = new ItemAttribute("k1", "v1", false);
-		Assertions.assertFalse(systemAttributeMatcher.matches(publicAttribute));
-	}
+  private final PredicateItemAttributeTypeMatcher systemAttributeMatcher = new PredicateItemAttributeTypeMatcher(
+      ItemAttribute::isSystem, ItemAttributeType.SYSTEM);
+  private final PredicateItemAttributeTypeMatcher publicAttributeMatcher = new PredicateItemAttributeTypeMatcher(
+      it -> !it.isSystem(), ItemAttributeType.PUBLIC);
+
+  @Test
+  void publicShouldReturnTrue() {
+    final ItemAttribute publicAttribute = new ItemAttribute("k1", "v1", false);
+    Assertions.assertTrue(publicAttributeMatcher.matches(publicAttribute));
+  }
+
+  @Test
+  void publicShouldReturnFalse() {
+    final ItemAttribute systemAttribute = new ItemAttribute("k1", "v1", true);
+    Assertions.assertFalse(publicAttributeMatcher.matches(systemAttribute));
+  }
+
+  @Test
+  void systemShouldReturnTrue() {
+    final ItemAttribute systemAttribute = new ItemAttribute("k1", "v1", true);
+    Assertions.assertTrue(systemAttributeMatcher.matches(systemAttribute));
+  }
+
+  @Test
+  void systemShouldReturnFalse() {
+    final ItemAttribute publicAttribute = new ItemAttribute("k1", "v1", false);
+    Assertions.assertFalse(systemAttributeMatcher.matches(publicAttribute));
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/handler/impl/QueryHandlerImplTest.java b/src/test/java/com/epam/ta/reportportal/ws/handler/impl/QueryHandlerImplTest.java
index 007c1ba223..7653576593 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/handler/impl/QueryHandlerImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/handler/impl/QueryHandlerImplTest.java
@@ -16,6 +16,11 @@
 
 package com.epam.ta.reportportal.ws.handler.impl;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.querygen.FilterCondition;
 import com.epam.ta.reportportal.dao.IntegrationRepository;
@@ -34,72 +39,68 @@
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
 /**
  * @author Yauheni_Martynau
  */
 @ExtendWith(MockitoExtension.class)
 class QueryHandlerImplTest {
 
-	@Mock
-	private ProjectRepository projectRepository;
+  @Mock
+  private ProjectRepository projectRepository;
 
-	@Mock
-	private IntegrationRepository integrationRepository;
+  @Mock
+  private IntegrationRepository integrationRepository;
 
-	@Mock
-	private TestItemRepository testItemRepository;
+  @Mock
+  private TestItemRepository testItemRepository;
 
-	@Mock
-	private LogRepository logRepository;
+  @Mock
+  private LogRepository logRepository;
 
-	@InjectMocks
-	private QueryHandlerImpl queryHandler;
+  @InjectMocks
+  private QueryHandlerImpl queryHandler;
 
-	@Test
-	void testFind_withLogRepositoryRequest() {
+  @Test
+  void testFind_withLogRepositoryRequest() {
 
-		//given:
-		Filter requestFilter = Filter.builder()
-				.withTarget(Log.class).withCondition(FilterCondition.builder().eq("id", "2").build())
-				.build();
+    //given:
+    Filter requestFilter = Filter.builder()
+        .withTarget(Log.class).withCondition(FilterCondition.builder().eq("id", "2").build())
+        .build();
 
-		QueryRQ queryRQ = new QueryRQ();
-		queryRQ.setEntity(Log.class.getSimpleName());
-		queryRQ.setFilter(requestFilter);
+    QueryRQ queryRQ = new QueryRQ();
+    queryRQ.setEntity(Log.class.getSimpleName());
+    queryRQ.setFilter(requestFilter);
 
-		//setup:
-		when(logRepository.findByFilter(requestFilter)).thenReturn(Lists.newArrayList());
+    //setup:
+    when(logRepository.findByFilter(requestFilter)).thenReturn(Lists.newArrayList());
 
-		//when:
-		queryHandler.find(queryRQ);
+    //when:
+    queryHandler.find(queryRQ);
 
-		//then:
-		ArgumentCaptor<Filter> captor = ArgumentCaptor.forClass(Filter.class);
-		verify(logRepository).findByFilter(captor.capture());
+    //then:
+    ArgumentCaptor<Filter> captor = ArgumentCaptor.forClass(Filter.class);
+    verify(logRepository).findByFilter(captor.capture());
 
-		Filter capturedFilter = captor.getValue();
+    Filter capturedFilter = captor.getValue();
 
-		assertEquals(requestFilter, capturedFilter);
-	}
+    assertEquals(requestFilter, capturedFilter);
+  }
 
-	@Test
-	void testFind_withNotFoundRepository() {
+  @Test
+  void testFind_withNotFoundRepository() {
 
-		//given:
-		Filter requestFilter = Filter.builder()
-				.withTarget(Launch.class).withCondition(FilterCondition.builder().eq("name", "name").build())
-				.build();
+    //given:
+    Filter requestFilter = Filter.builder()
+        .withTarget(Launch.class)
+        .withCondition(FilterCondition.builder().eq("name", "name").build())
+        .build();
 
-		QueryRQ queryRQ = new QueryRQ();
-		queryRQ.setEntity(Launch.class.getSimpleName());
-		queryRQ.setFilter(requestFilter);
+    QueryRQ queryRQ = new QueryRQ();
+    queryRQ.setEntity(Launch.class.getSimpleName());
+    queryRQ.setFilter(requestFilter);
 
-		//when:
-		assertThrows(ReportPortalException.class, () -> queryHandler.find(queryRQ));
-	}
+    //when:
+    assertThrows(ReportPortalException.class, () -> queryHandler.find(queryRQ));
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/rabbit/AsyncReportingListenerTest.java b/src/test/java/com/epam/ta/reportportal/ws/rabbit/AsyncReportingListenerTest.java
index c540bb3554..e86e86e793 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/rabbit/AsyncReportingListenerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/rabbit/AsyncReportingListenerTest.java
@@ -1,5 +1,6 @@
 package com.epam.ta.reportportal.ws.rabbit;
 
+import static com.epam.ta.reportportal.ws.converter.converters.LogConverter.LOG_FULL_TO_LOG;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.argThat;
 import static org.mockito.ArgumentMatchers.eq;
@@ -29,8 +30,9 @@
 import com.epam.ta.reportportal.entity.item.TestItem;
 import com.epam.ta.reportportal.entity.launch.Launch;
 import com.epam.ta.reportportal.entity.log.Log;
+import com.epam.ta.reportportal.entity.log.LogFull;
 import com.epam.ta.reportportal.util.ProjectExtractor;
-import com.epam.ta.reportportal.ws.converter.builders.LogBuilder;
+import com.epam.ta.reportportal.ws.converter.builders.LogFullBuilder;
 import com.epam.ta.reportportal.ws.model.FinishExecutionRQ;
 import com.epam.ta.reportportal.ws.model.FinishTestItemRQ;
 import com.epam.ta.reportportal.ws.model.StartTestItemRQ;
@@ -239,12 +241,13 @@ void whenMessageReceived_andItemIsNotPresent_thenCreateLaunchLog() {
     when(launch.getId()).thenReturn(ID);
     when(launchRepository.findByUuid(LAUNCH_ID)).thenReturn(Optional.of(launch));
 
-    Log log = new LogBuilder().addSaveLogRq(saveLogRQ).addLaunch(launch).addProjectId(ID).get();
+    LogFull logFull = new LogFullBuilder().addSaveLogRq(saveLogRQ).addLaunch(launch).addProjectId(ID).get();
+    final Log log = LOG_FULL_TO_LOG.apply(logFull);
 
     asyncReportingListener.onMessage(message);
 
     verify(logRepository).save(log);
-    verify(logService).saveLogMessageToElasticSearch(log, ID);
+    verify(logService).saveLogMessage(logFull, ID);
     verify(attachmentBinaryDataService).attachToLog(
         eq(binaryDataMetaInfo), any(AttachmentMetaInfo.class));
   }
@@ -277,7 +280,8 @@ void whenMessageReceived_andItemIsPresent_thenCreateItemLog() {
     TestItem testItem = mock(TestItem.class);
     when(testItemRepository.findByUuid(ITEM_ID)).thenReturn(Optional.of(testItem));
 
-    Log log = new LogBuilder().addSaveLogRq(saveLogRQ).addTestItem(testItem).addProjectId(ID).get();
+    LogFull logFull = new LogFullBuilder().addSaveLogRq(saveLogRQ).addTestItem(testItem).addProjectId(ID).get();
+    final Log log = LOG_FULL_TO_LOG.apply(logFull);
 
     Launch launch = mock(Launch.class);
     when(launch.getId()).thenReturn(ID);
@@ -286,7 +290,7 @@ void whenMessageReceived_andItemIsPresent_thenCreateItemLog() {
     asyncReportingListener.onMessage(message);
 
     verify(logRepository).save(log);
-    verify(logService).saveLogMessageToElasticSearch(log, ID);
+    verify(logService).saveLogMessage(logFull, ID);
     verify(attachmentBinaryDataService).attachToLog(
         eq(binaryDataMetaInfo), any(AttachmentMetaInfo.class));
   }
diff --git a/src/test/java/com/epam/ta/reportportal/ws/rabbit/QueryConsumerTest.java b/src/test/java/com/epam/ta/reportportal/ws/rabbit/QueryConsumerTest.java
index a2c4a298d2..4410e8ea01 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/rabbit/QueryConsumerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/rabbit/QueryConsumerTest.java
@@ -16,6 +16,10 @@
 
 package com.epam.ta.reportportal.ws.rabbit;
 
+import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_ID;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
 import com.epam.ta.reportportal.commons.querygen.Filter;
 import com.epam.ta.reportportal.commons.querygen.FilterCondition;
 import com.epam.ta.reportportal.entity.launch.Launch;
@@ -26,33 +30,29 @@
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 
-import static com.epam.ta.reportportal.commons.querygen.constant.GeneralCriteriaConstant.CRITERIA_ID;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @ExtendWith(MockitoExtension.class)
 class QueryConsumerTest {
 
-	@Mock
-	private QueryHandler queryHandler;
+  @Mock
+  private QueryHandler queryHandler;
 
-	@InjectMocks
-	private QueryConsumer queryConsumer;
+  @InjectMocks
+  private QueryConsumer queryConsumer;
 
-	@Test
-	void find() {
-		QueryRQ queryRQ = new QueryRQ();
-		queryRQ.setEntity("launch");
-		queryRQ.setFilter(Filter.builder()
-				.withTarget(Launch.class)
-				.withCondition(FilterCondition.builder().eq(CRITERIA_ID, "100").build())
-				.build());
+  @Test
+  void find() {
+    QueryRQ queryRQ = new QueryRQ();
+    queryRQ.setEntity("launch");
+    queryRQ.setFilter(Filter.builder()
+        .withTarget(Launch.class)
+        .withCondition(FilterCondition.builder().eq(CRITERIA_ID, "100").build())
+        .build());
 
-		queryConsumer.find(queryRQ);
+    queryConsumer.find(queryRQ);
 
-		verify(queryHandler, times(1)).find(queryRQ);
-	}
+    verify(queryHandler, times(1)).find(queryRQ);
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/validation/BusinessRuleTest.java b/src/test/java/com/epam/ta/reportportal/ws/validation/BusinessRuleTest.java
index 6581451117..8671cc0bb8 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/validation/BusinessRuleTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/validation/BusinessRuleTest.java
@@ -17,6 +17,8 @@
 
 package com.epam.ta.reportportal.ws.validation;
 
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
 import com.epam.ta.reportportal.commons.Predicates;
 import com.epam.ta.reportportal.commons.validation.BusinessRule;
 import com.epam.ta.reportportal.commons.validation.BusinessRuleViolationException;
@@ -25,8 +27,6 @@
 import com.epam.ta.reportportal.ws.model.ErrorType;
 import org.junit.jupiter.api.Test;
 
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
 /**
  * Unit test for business rule logic
  *
@@ -34,19 +34,21 @@
  */
 class BusinessRuleTest {
 
-	@Test
-	void testVerifyCustomError() {
-		assertThrows(
-				ReportPortalException.class,
-				() -> BusinessRule.expect("", Predicates.isNull()).verify(ErrorType.FINISH_TIME_EARLIER_THAN_START_TIME, "")
-		);
-	}
+  @Test
+  void testVerifyCustomError() {
+    assertThrows(
+        ReportPortalException.class,
+        () -> BusinessRule.expect("", Predicates.isNull())
+            .verify(ErrorType.FINISH_TIME_EARLIER_THAN_START_TIME, "")
+    );
+  }
 
-	@Test
-	void testVerifyBusinessError() {
-		assertThrows(
-				BusinessRuleViolationException.class,
-				() -> BusinessRule.expect("", Predicates.alwaysFalse(), Suppliers.stringSupplier("error")).verify()
-		);
-	}
+  @Test
+  void testVerifyBusinessError() {
+    assertThrows(
+        BusinessRuleViolationException.class,
+        () -> BusinessRule.expect("", Predicates.alwaysFalse(), Suppliers.stringSupplier("error"))
+            .verify()
+    );
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/com/epam/ta/reportportal/ws/validation/JaskonRequiredPropertiesValidatorTest.java b/src/test/java/com/epam/ta/reportportal/ws/validation/JaskonRequiredPropertiesValidatorTest.java
index 5a564c09cc..2d5b6e21c4 100644
--- a/src/test/java/com/epam/ta/reportportal/ws/validation/JaskonRequiredPropertiesValidatorTest.java
+++ b/src/test/java/com/epam/ta/reportportal/ws/validation/JaskonRequiredPropertiesValidatorTest.java
@@ -16,71 +16,72 @@
 
 package com.epam.ta.reportportal.ws.validation;
 
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.nullValue;
+
 import com.epam.ta.reportportal.ws.model.FinishTestItemRQ;
 import com.epam.ta.reportportal.ws.model.issue.Issue;
 import com.epam.ta.reportportal.ws.model.issue.IssueDefinition;
 import com.epam.ta.reportportal.ws.model.launch.StartLaunchRQ;
-import org.junit.jupiter.api.Test;
-import org.springframework.validation.BeanPropertyBindingResult;
-import org.springframework.validation.Errors;
-
 import java.util.Calendar;
 import java.util.Collections;
 import java.util.UUID;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.*;
+import org.junit.jupiter.api.Test;
+import org.springframework.validation.BeanPropertyBindingResult;
+import org.springframework.validation.Errors;
 
 /**
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 public class JaskonRequiredPropertiesValidatorTest {
 
-	@Test
-	public void testRequiredFields() {
-		StartLaunchRQ startLaunchRQ = new StartLaunchRQ();
-		startLaunchRQ.setDescription("some description");
-		startLaunchRQ.setName("some launch name");
-		startLaunchRQ.setAttributes(Collections.emptySet());
-		JaskonRequiredPropertiesValidator validator = new JaskonRequiredPropertiesValidator();
-		Errors errors = new BeanPropertyBindingResult(startLaunchRQ, "startLaunchRq");
-		validator.validate(startLaunchRQ, errors);
-		assertThat(errors.getAllErrors(), not(empty()));
-		assertThat(errors.getFieldError("startTime"), not(nullValue()));
-	}
+  @Test
+  public void testRequiredFields() {
+    StartLaunchRQ startLaunchRQ = new StartLaunchRQ();
+    startLaunchRQ.setDescription("some description");
+    startLaunchRQ.setName("some launch name");
+    startLaunchRQ.setAttributes(Collections.emptySet());
+    JaskonRequiredPropertiesValidator validator = new JaskonRequiredPropertiesValidator();
+    Errors errors = new BeanPropertyBindingResult(startLaunchRQ, "startLaunchRq");
+    validator.validate(startLaunchRQ, errors);
+    assertThat(errors.getAllErrors(), not(empty()));
+    assertThat(errors.getFieldError("startTime"), not(nullValue()));
+  }
 
-	@Test
-	public void testInnerRequiredFields() {
-		IssueDefinition issueRQ = new IssueDefinition();
-		JaskonRequiredPropertiesValidator validator = new JaskonRequiredPropertiesValidator();
-		Errors errors = new BeanPropertyBindingResult(issueRQ, "issueRQ");
-		validator.validate(issueRQ, errors);
-		assertThat(errors.getAllErrors(), not(empty()));
-		assertThat(errors.getFieldError("issue"), not(nullValue()));
-	}
+  @Test
+  public void testInnerRequiredFields() {
+    IssueDefinition issueRQ = new IssueDefinition();
+    JaskonRequiredPropertiesValidator validator = new JaskonRequiredPropertiesValidator();
+    Errors errors = new BeanPropertyBindingResult(issueRQ, "issueRQ");
+    validator.validate(issueRQ, errors);
+    assertThat(errors.getAllErrors(), not(empty()));
+    assertThat(errors.getFieldError("issue"), not(nullValue()));
+  }
 
-	@Test
-	public void testInnerRequiredFields1() {
-		FinishTestItemRQ issueRQ = new FinishTestItemRQ();
-		issueRQ.setLaunchUuid(UUID.randomUUID().toString());
-		issueRQ.setEndTime(Calendar.getInstance().getTime());
-		issueRQ.setStatus("PASSED");
-		JaskonRequiredPropertiesValidator validator = new JaskonRequiredPropertiesValidator();
-		Errors errors = new BeanPropertyBindingResult(issueRQ, "issueRQ");
-		validator.validate(issueRQ, errors);
-		assertThat(errors.getAllErrors(), empty());
-	}
+  @Test
+  public void testInnerRequiredFields1() {
+    FinishTestItemRQ issueRQ = new FinishTestItemRQ();
+    issueRQ.setLaunchUuid(UUID.randomUUID().toString());
+    issueRQ.setEndTime(Calendar.getInstance().getTime());
+    issueRQ.setStatus("PASSED");
+    JaskonRequiredPropertiesValidator validator = new JaskonRequiredPropertiesValidator();
+    Errors errors = new BeanPropertyBindingResult(issueRQ, "issueRQ");
+    validator.validate(issueRQ, errors);
+    assertThat(errors.getAllErrors(), empty());
+  }
 
-	@Test
-	public void testInnerRequiredFields2() {
-		FinishTestItemRQ issueRQ = new FinishTestItemRQ();
-		issueRQ.setEndTime(Calendar.getInstance().getTime());
-		issueRQ.setStatus("PASSED");
-		issueRQ.setIssue(new Issue());
-		JaskonRequiredPropertiesValidator validator = new JaskonRequiredPropertiesValidator();
-		Errors errors = new BeanPropertyBindingResult(issueRQ, "issueRQ");
-		validator.validate(issueRQ, errors);
-		assertThat(errors.getAllErrors(), not(empty()));
-	}
+  @Test
+  public void testInnerRequiredFields2() {
+    FinishTestItemRQ issueRQ = new FinishTestItemRQ();
+    issueRQ.setEndTime(Calendar.getInstance().getTime());
+    issueRQ.setStatus("PASSED");
+    issueRQ.setIssue(new Issue());
+    JaskonRequiredPropertiesValidator validator = new JaskonRequiredPropertiesValidator();
+    Errors errors = new BeanPropertyBindingResult(issueRQ, "issueRQ");
+    validator.validate(issueRQ, errors);
+    assertThat(errors.getAllErrors(), not(empty()));
+  }
 
 }
\ No newline at end of file
diff --git a/src/test/resources/db/data-store/data-store-fill.sql b/src/test/resources/db/data-store/data-store-fill.sql
index d062fc1f9f..c3c892cad4 100644
--- a/src/test/resources/db/data-store/data-store-fill.sql
+++ b/src/test/resources/db/data-store/data-store-fill.sql
@@ -1,10 +1,14 @@
-INSERT INTO launch(id, uuid, project_id, user_id, name, description, start_time, end_time, last_modified, mode, status, has_retries,
+INSERT INTO launch(id, uuid, project_id, user_id, name, description, start_time, end_time,
+                   last_modified, mode, status, has_retries,
                    rerun, approximate_duration)
-VALUES (1, 'uuid', 1, 1, 'launch', 'launch', now(), now(), now(), 'DEFAULT', 'FAILED', FALSE, FALSE, 0);
+VALUES (1, 'uuid', 1, 1, 'launch', 'launch', now(), now(), now(), 'DEFAULT', 'FAILED', FALSE, FALSE,
+        0);
 
-INSERT INTO test_item(test_case_hash, item_id, uuid, name, type, start_time, description, last_modified, path, unique_id, has_children,
+INSERT INTO test_item(test_case_hash, item_id, uuid, name, type, start_time, description,
+                      last_modified, path, unique_id, has_children,
                       has_retries, has_stats, parent_id, retry_of, launch_id)
-VALUES (1, 1, 'uuid', 'item', 'STEP', now(), 'desc', now(), '1', 'uniqueId', FALSE, FALSE, TRUE, NULL, NULL, 1);
+VALUES (1, 1, 'uuid', 'item', 'STEP', now(), 'desc', now(), '1', 'uniqueId', FALSE, FALSE, TRUE,
+        NULL, NULL, 1);
 
 INSERT INTO log(id, uuid, log_time, log_message, item_id, last_modified, log_level, project_id)
 VALUES (1, 'uuid', now(), 'msg', 1, now(), 40000, 1);
\ No newline at end of file
diff --git a/src/test/resources/db/launch/launch-fill.sql b/src/test/resources/db/launch/launch-fill.sql
index 2687f0ea2f..29530f9417 100644
--- a/src/test/resources/db/launch/launch-fill.sql
+++ b/src/test/resources/db/launch/launch-fill.sql
@@ -1,4 +1,5 @@
-INSERT INTO launch (id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode,
+INSERT INTO launch (id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                    last_modified, mode,
                     status)
 VALUES (1,
         '4b02ef3a-56d6-443b-8cf7-27014bd53497',
@@ -24,11 +25,14 @@ VALUES (1,
         now(),
         'DEFAULT',
         'FAILED'),
-       (3, 'befef834-b2ef-4acf-aea3-b5a5b15fd93c', 2, 2, 'empty launch', 'postman', now(), null, 1, now(), 'DEFAULT',
+       (3, 'befef834-b2ef-4acf-aea3-b5a5b15fd93c', 2, 2, 'empty launch', 'postman', now(), null, 1,
+        now(), 'DEFAULT',
         'IN_PROGRESS'),
-       (4, '2e13b3df-298b-4052-beb8-426eedbc38ee', 1, 1, 'empty debug launch', 'postman', now(), null, 1, now(),
+       (4, '2e13b3df-298b-4052-beb8-426eedbc38ee', 1, 1, 'empty debug launch', 'postman', now(),
+        null, 1, now(),
         'DEBUG', 'IN_PROGRESS'),
-       (5, 'e3adc64e-87cc-4781-b2d3-faa4ef1679dc', 2, 2, 'empty launch 2', 'postman', now(), null, 1, now(), 'DEFAULT',
+       (5, 'e3adc64e-87cc-4781-b2d3-faa4ef1679dc', 2, 2, 'empty launch 2', 'postman', now(), null,
+        1, now(), 'DEFAULT',
         'IN_PROGRESS');
 
 INSERT INTO public.test_item (test_case_hash, item_id,
diff --git a/src/test/resources/db/migration/V001003__integration_type.sql b/src/test/resources/db/migration/V001003__integration_type.sql
index 1a5993323e..e88d88245a 100644
--- a/src/test/resources/db/migration/V001003__integration_type.sql
+++ b/src/test/resources/db/migration/V001003__integration_type.sql
@@ -1,3 +1,5 @@
-INSERT INTO integration_type (enabled, name, auth_flow, creation_date, group_type) VALUES (TRUE, 'rally', 'OAUTH', now(), 'BTS') ;
+INSERT INTO integration_type (enabled, name, auth_flow, creation_date, group_type)
+VALUES (TRUE, 'rally', 'OAUTH', now(), 'BTS');
 
-INSERT INTO integration_type (enabled, name, auth_flow, creation_date, group_type) VALUES (TRUE, 'jira', 'BASIC', now(), 'BTS');
\ No newline at end of file
+INSERT INTO integration_type (enabled, name, auth_flow, creation_date, group_type)
+VALUES (TRUE, 'jira', 'BASIC', now(), 'BTS');
\ No newline at end of file
diff --git a/src/test/resources/db/migration/V0027__attachment_creation_date.up.sql b/src/test/resources/db/migration/V0027__attachment_creation_date.up.sql
index 09ae930faa..cfc17b8475 100644
--- a/src/test/resources/db/migration/V0027__attachment_creation_date.up.sql
+++ b/src/test/resources/db/migration/V0027__attachment_creation_date.up.sql
@@ -1 +1,2 @@
-ALTER TABLE attachment ADD COLUMN creation_date TIMESTAMP;
\ No newline at end of file
+ALTER TABLE attachment
+    ADD COLUMN creation_date TIMESTAMP;
\ No newline at end of file
diff --git a/src/test/resources/db/migration/V0030__log_project_id.up.sql b/src/test/resources/db/migration/V0030__log_project_id.up.sql
index e4c7a6bf9c..a19259e2fb 100644
--- a/src/test/resources/db/migration/V0030__log_project_id.up.sql
+++ b/src/test/resources/db/migration/V0030__log_project_id.up.sql
@@ -1 +1,2 @@
-ALTER TABLE log ADD COLUMN project_id BIGINT;
\ No newline at end of file
+ALTER TABLE log
+    ADD COLUMN project_id BIGINT;
\ No newline at end of file
diff --git a/src/test/resources/db/project-settings/project-settings-fill.sql b/src/test/resources/db/project-settings/project-settings-fill.sql
index b719fd5816..5f39f3d259 100644
--- a/src/test/resources/db/project-settings/project-settings-fill.sql
+++ b/src/test/resources/db/project-settings/project-settings-fill.sql
@@ -1,10 +1,10 @@
-insert into issue_type (id, issue_group_id, locator, issue_name, abbreviation, hex_color)
-values (6, 1, 'custom_ti', 'Custom to investigate', 'CTI', '#2f39bf'),
+INSERT INTO issue_type (id, issue_group_id, locator, issue_name, abbreviation, hex_color)
+VALUES (6, 1, 'custom_ti', 'Custom to investigate', 'CTI', '#2f39bf'),
        (7, 2, 'custom_ab', 'Custom automation bug', 'CAB', '#ccac39'),
        (8, 5, 'custom si', 'Custom system issue', 'CSI', '#08af2a');
 
-insert into issue_type_project(project_id, issue_type_id)
-values (2, 6),
+INSERT INTO issue_type_project(project_id, issue_type_id)
+VALUES (2, 6),
        (2, 7),
        (2, 8);
 
@@ -15,20 +15,20 @@ VALUES (1, 'default', 2),
 
 
 INSERT INTO public.filter (id, name, target, description)
-VALUES (1, 'filter', 'Launch', null);
+VALUES (1, 'filter', 'Launch', NULL);
 
 INSERT INTO public.filter_sort (id, filter_id, field, direction)
 VALUES (1, 1, 'name', 'ASC');
 
 INSERT INTO public.filter_condition (id, filter_id, condition, value, search_criteria, negative)
-VALUES (1, 1, 'CONTAINS', 'test', 'name', false);
+VALUES (1, 1, 'CONTAINS', 'test', 'name', FALSE);
 
 INSERT INTO public.widget (id, name, description, widget_type, items_count, widget_options)
-VALUES (2, 'overall statistics', null, 'overallStatistics', 20, '{"options": {}}'),
-       (3, 'launches table', null, 'launchesTable', 20, '{"options": {}}');
+VALUES (2, 'overall statistics', NULL, 'overallStatistics', 20, '{"options": {}}'),
+       (3, 'launches table', NULL, 'launchesTable', 20, '{"options": {}}');
 
-insert into content_field(id, field)
-values (2, 'statistics$executions$total'),
+INSERT INTO content_field(id, field)
+VALUES (2, 'statistics$executions$total'),
        (2, 'statistics$executions$passed'),
        (2, 'statistics$executions$failed'),
        (2, 'statistics$executions$skipped'),
@@ -62,4 +62,15 @@ insert into pattern_template(id, name, "value", type, enabled, project_id)
 values (1, 'some_name', 'value', 'STRING', true, 2),
        (2, 'simple_name', 'value', 'STRING', true, 2),
        (3, 'another_name', 'value', 'STRING', true, 1);
-alter sequence pattern_template_id_seq restart with 4;
\ No newline at end of file
+alter sequence pattern_template_id_seq restart with 4;
+
+INSERT INTO public.sender_case (id, send_case, project_id, enabled, rule_name)
+VALUES (1, 'ALWAYS', 2, TRUE, 'rule #1'),
+       (2, 'FAILED', 2, FALSE, 'rule #2'),
+       (3, 'TO_INVESTIGATE', 2, FALSE, 'rule #3'),
+       (4, 'MORE_10', 2, TRUE, 'rule #4');
+
+ALTER SEQUENCE sender_case_id_seq RESTART WITH 5;
+
+INSERT INTO public.launch_names (sender_case_id, launch_name)
+VALUES (1, 1);
\ No newline at end of file
diff --git a/src/test/resources/db/shareable/shareable-fill.sql b/src/test/resources/db/shareable/shareable-fill.sql
index ad0f031691..3f9af7062c 100644
--- a/src/test/resources/db/shareable/shareable-fill.sql
+++ b/src/test/resources/db/shareable/shareable-fill.sql
@@ -1,7 +1,10 @@
-INSERT INTO public.users (id, login, password, email, attachment, attachment_thumbnail, role, type, expired, full_name, metadata)
-VALUES (3, 'jaja_user', '7c381f9d81b0e438af4e7094c6cae203', 'jaja@mail.com', null, null, 'USER', 'INTERNAL', false, 'Jaja Juja', '{"metadata": {"last_login": 1546605767372}}');
+INSERT INTO public.users (id, login, password, email, attachment, attachment_thumbnail, role, type,
+                          expired, full_name, metadata)
+VALUES (3, 'jaja_user', '7c381f9d81b0e438af4e7094c6cae203', 'jaja@mail.com', null, null, 'USER',
+        'INTERNAL', false, 'Jaja Juja', '{"metadata": {"last_login": 1546605767372}}');
 
-INSERT INTO public.project_user (user_id, project_id, project_role) VALUES (3, 1, 'MEMBER');
+INSERT INTO public.project_user (user_id, project_id, project_role)
+VALUES (3, 1, 'MEMBER');
 
 INSERT INTO public.owned_entity (id, owner, project_id)
 VALUES (1, 'superadmin', 1),
@@ -23,53 +26,57 @@ VALUES (1, 'superadmin', 1),
        (17, 'default', 2),
        (18, 'default', 2);
 
-INSERT INTO public.filter (id, name, target, description) VALUES
-(1, 'Admin Filter', 'Launch', null),
-(2, 'Admin Shared Filter', 'Launch', null),
-(3, 'Default Filter', 'Launch', null),
-(4, 'Default Shared Filter', 'Launch', null);
+INSERT INTO public.filter (id, name, target, description)
+VALUES (1, 'Admin Filter', 'Launch', null),
+       (2, 'Admin Shared Filter', 'Launch', null),
+       (3, 'Default Filter', 'Launch', null),
+       (4, 'Default Shared Filter', 'Launch', null);
 
-INSERT INTO public.filter_sort (id, filter_id, field, direction) VALUES
-(1, 1, 'name', 'ASC'),
-(2, 2, 'name', 'DESC'),
-(3, 3, 'name', 'ASC'),
-(4, 4, 'name', 'DESC');
+INSERT INTO public.filter_sort (id, filter_id, field, direction)
+VALUES (1, 1, 'name', 'ASC'),
+       (2, 2, 'name', 'DESC'),
+       (3, 3, 'name', 'ASC'),
+       (4, 4, 'name', 'DESC');
 
-INSERT INTO public.filter_condition (id, filter_id, condition, value, search_criteria, negative) VALUES
-(1, 1, 'CONTAINS', 'asdf', 'name', false),
-(2, 2, 'EQUALS', 'test', 'description', false),
-(3, 3, 'EQUALS', 'juja', 'name', false),
-(4, 4, 'EQUALS', 'qwerty', 'name', false);
+INSERT INTO public.filter_condition (id, filter_id, condition, value, search_criteria, negative)
+VALUES (1, 1, 'CONTAINS', 'asdf', 'name', false),
+       (2, 2, 'EQUALS', 'test', 'description', false),
+       (3, 3, 'EQUALS', 'juja', 'name', false),
+       (4, 4, 'EQUALS', 'qwerty', 'name', false);
 
-INSERT INTO public.widget (id, name, description, widget_type, items_count, widget_options) VALUES
-(5, 'activity stream12', null, 'activityStream', 50, '{"options": {"user": "superadmin", "actionType": ["startLaunch", "finishLaunch"]}}'),
-(7, 'INVESTIGATED PERCENTAGE OF LAUNCHES', null, 'investigatedTrend', 10, '{"options": {"timeline": "DAY"}}'),
-(6, 'LAUNCH STATISTICS', null, 'launchStatistics', 10, '{"options": {"timeline": "WEEK"}}'),
-(8, 'TEST CASES GROWTH TREND CHART', null, 'casesTrend', 10, '{"options": {}}'),
-(9, 'LAUNCHES DURATION CHART', null, 'launchesDurationChart', 10, '{"options": {}}'),
-(12, 'ACTIVITY STREAM', null, 'activityStream', 10, '{"options": {"user": "default", "actionType": ["startLaunch", "finishLaunch", "deleteLaunch"]}}'),
-(10, 'FAILED CASES TREND CHART', null, 'bugTrend', 10, '{"options": {}}'),
-(11, 'LAUNCH STATISTICS', null, 'launchStatistics', 10, '{"options": {"timeline": "WEEK"}}');
+INSERT INTO public.widget (id, name, description, widget_type, items_count, widget_options)
+VALUES (5, 'activity stream12', null, 'activityStream', 50,
+        '{"options": {"user": "superadmin", "actionType": ["startLaunch", "finishLaunch"]}}'),
+       (7, 'INVESTIGATED PERCENTAGE OF LAUNCHES', null, 'investigatedTrend', 10,
+        '{"options": {"timeline": "DAY"}}'),
+       (6, 'LAUNCH STATISTICS', null, 'launchStatistics', 10, '{"options": {"timeline": "WEEK"}}'),
+       (8, 'TEST CASES GROWTH TREND CHART', null, 'casesTrend', 10, '{"options": {}}'),
+       (9, 'LAUNCHES DURATION CHART', null, 'launchesDurationChart', 10, '{"options": {}}'),
+       (12, 'ACTIVITY STREAM', null, 'activityStream', 10,
+        '{"options": {"user": "default", "actionType": ["startLaunch", "finishLaunch", "deleteLaunch"]}}'),
+       (10, 'FAILED CASES TREND CHART', null, 'bugTrend', 10, '{"options": {}}'),
+       (11, 'LAUNCH STATISTICS', null, 'launchStatistics', 10, '{"options": {"timeline": "WEEK"}}');
 
 insert into content_field(id, field)
 values (10, 'statistics$executions$failed');
 
-INSERT INTO public.widget_filter (widget_id, filter_id) VALUES
-(6, 1),
-(7, 2),
-(8, 2),
-(10, 3),
-(11, 3);
+INSERT INTO public.widget_filter (widget_id, filter_id)
+VALUES (6, 1),
+       (7, 2),
+       (8, 2),
+       (10, 3),
+       (11, 3);
 
-INSERT INTO public.dashboard (id, name, description, creation_date) VALUES
-(13, 'test admin dashboard', 'admin shared dashboard', '2019-01-10 13:01:06.083000'),
-(14, 'test admin private dashboard', 'admin dashboard', '2019-01-10 13:01:19.259000'),
-(15, 'test jaja shared dashboard', 'jaja dashboard', '2019-01-10 13:01:51.417000'),
-(16, 'test jaja private dashboard', 'jaja dashboard', '2019-01-10 13:01:59.015000'),
-(17, 'test default shared dashboard', 'default dashboard', '2019-01-10 13:02:20.397000'),
-(18, 'test default private dashboard', 'default dashboard', '2019-01-10 13:02:27.659000');
+INSERT INTO public.dashboard (id, name, description, creation_date)
+VALUES (13, 'test admin dashboard', 'admin shared dashboard', '2019-01-10 13:01:06.083000'),
+       (14, 'test admin private dashboard', 'admin dashboard', '2019-01-10 13:01:19.259000'),
+       (15, 'test jaja shared dashboard', 'jaja dashboard', '2019-01-10 13:01:51.417000'),
+       (16, 'test jaja private dashboard', 'jaja dashboard', '2019-01-10 13:01:59.015000'),
+       (17, 'test default shared dashboard', 'default dashboard', '2019-01-10 13:02:20.397000'),
+       (18, 'test default private dashboard', 'default dashboard', '2019-01-10 13:02:27.659000');
 
-INSERT INTO public.dashboard_widget (dashboard_id, widget_id, widget_name, widget_owner, widget_type, widget_width, widget_height,
+INSERT INTO public.dashboard_widget (dashboard_id, widget_id, widget_name, widget_owner,
+                                     widget_type, widget_width, widget_height,
                                      widget_position_x,
                                      widget_position_y)
 VALUES (13, 5, 'activity stream12', 'superadmin', 'activityStream', 5, 5, 0, 0),
diff --git a/src/test/resources/db/test-item/item-change-status-from-failed.sql b/src/test/resources/db/test-item/item-change-status-from-failed.sql
index 553c308079..92f31233f9 100644
--- a/src/test/resources/db/test-item/item-change-status-from-failed.sql
+++ b/src/test/resources/db/test-item/item-change-status-from-failed.sql
@@ -1,17 +1,21 @@
 -- Passed launch with 4 step items
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
 values (1, 'uuid', 1, 1, 'test launch', 'desc', now(), null, 1, now(), 'DEFAULT', 'FAILED', false);
 
-insert into item_attribute(id, key, value, item_id, launch_id, system) values (1, 'skippedIssue', 'true', null, 1, true);
+insert into item_attribute(id, key, value, item_id, launch_id, system)
+values (1, 'skippedIssue', 'true', null, 1, true);
 
 -- Test level item with 2 step items
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (1, 1, 'uuid2', 'test item 1', 'TEST', now(), 'desc', 'uuid1', now(), '1', null, 1);
 insert into test_item_results(result_id, status)
 values (1, 'IN_PROGRESS');
 
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (2, 2, 'uuid3', 'step item 1', 'STEP', now(), 'desc', 'uuid1', now(), '1.2', 1, 1);
 insert into test_item_results(result_id, status)
 values (2, 'IN_PROGRESS');
@@ -20,7 +24,8 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 2;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (3, 3, 'uuid4', 'step item 2', 'STEP', now(), 'desc', 'uuid3', now(), '1.3', 1, 1);
 insert into test_item_results(result_id, status)
 values (3, 'IN_PROGRESS');
@@ -35,12 +40,14 @@ set status   = 'PASSED',
 where result_id = 1;
 
 -- Test level item with 2 step items
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (4, 4,'uuid5', 'test item 1', 'TEST', now(), 'desc', 'uuid4', now(), '4', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (4, 4, 'uuid5', 'test item 1', 'TEST', now(), 'desc', 'uuid4', now(), '4', null, 1);
 insert into test_item_results(result_id, status)
 values (4, 'IN_PROGRESS');
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (5, 5, 'uuid6', 'step item 3', 'STEP', now(), 'desc', 'uuid5', now(), '4.5', 4, 1);
 insert into test_item_results(result_id, status)
 values (5, 'IN_PROGRESS');
@@ -49,8 +56,9 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 5;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (6, 6,'uuid8', 'step item 4', 'STEP', now(), 'desc', 'uuid6', now(), '4.6', 4, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (6, 6, 'uuid8', 'step item 4', 'STEP', now(), 'desc', 'uuid6', now(), '4.6', 4, 1);
 insert into test_item_results(result_id, status)
 values (6, 'IN_PROGRESS');
 update test_item_results
@@ -60,7 +68,8 @@ where result_id = 6;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (6, 2, 'automation bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (7, 7, 'uuid9', 'step item 7', 'STEP', now(), 'desc', 'uuid7', now(), '4.7', 4, 1);
 insert into test_item_results(result_id, status)
 values (7, 'IN_PROGRESS');
diff --git a/src/test/resources/db/test-item/item-change-status-from-interrupted.sql b/src/test/resources/db/test-item/item-change-status-from-interrupted.sql
index 1754a78b0f..5b0a31da87 100644
--- a/src/test/resources/db/test-item/item-change-status-from-interrupted.sql
+++ b/src/test/resources/db/test-item/item-change-status-from-interrupted.sql
@@ -1,17 +1,21 @@
 -- Passed launch with 4 step items
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
 values (1, 'uuid1', 1, 1, 'test launch', 'desc', now(), null, 1, now(), 'DEFAULT', 'FAILED', false);
 
-insert into item_attribute(id, key, value, item_id, launch_id, system) values (1, 'skippedIssue', 'true', null, 1, true);
+insert into item_attribute(id, key, value, item_id, launch_id, system)
+values (1, 'skippedIssue', 'true', null, 1, true);
 
 -- Test level item with 2 step items
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (1, 1, 'uuid', 'test item 1', 'TEST', now(), 'desc', 'uuid1', now(), '1', null, 1);
 insert into test_item_results(result_id, status)
 values (1, 'IN_PROGRESS');
 
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (2, 2, 'uuid2', 'step item 1', 'STEP', now(), 'desc', 'uuid1', now(), '1.2', 1, 1);
 insert into test_item_results(result_id, status)
 values (2, 'IN_PROGRESS');
@@ -20,7 +24,8 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 2;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (3, 3, 'uuid3', 'step item 2', 'STEP', now(), 'desc', 'uuid3', now(), '1.3', 1, 1);
 insert into test_item_results(result_id, status)
 values (3, 'IN_PROGRESS');
@@ -35,12 +40,14 @@ set status   = 'PASSED',
 where result_id = 1;
 
 -- Test level item with 2 step items
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (4, 4, 'uuid4', 'test item 1', 'TEST', now(), 'desc', 'uuid4', now(), '4', null, 1);
 insert into test_item_results(result_id, status)
 values (4, 'IN_PROGRESS');
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (5, 5, 'uuid5', 'step item 3', 'STEP', now(), 'desc', 'uuid5', now(), '4.5', 4, 1);
 insert into test_item_results(result_id, status)
 values (5, 'IN_PROGRESS');
@@ -49,7 +56,8 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 5;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (6, 6, 'uuid6', 'step item 4', 'STEP', now(), 'desc', 'uuid6', now(), '4.6', 4, 1);
 insert into test_item_results(result_id, status)
 values (6, 'IN_PROGRESS');
@@ -58,7 +66,8 @@ set status   = 'INTERRUPTED',
     end_time = now()
 where result_id = 6;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (7, 7, 'uuid7', 'step item 7', 'STEP', now(), 'desc', 'uuid7', now(), '4.7', 4, 1);
 insert into test_item_results(result_id, status)
 values (7, 'IN_PROGRESS');
diff --git a/src/test/resources/db/test-item/item-change-status-from-passed.sql b/src/test/resources/db/test-item/item-change-status-from-passed.sql
index 33352e9cd5..154417bb43 100644
--- a/src/test/resources/db/test-item/item-change-status-from-passed.sql
+++ b/src/test/resources/db/test-item/item-change-status-from-passed.sql
@@ -1,17 +1,21 @@
 -- Passed launch with 4 step items
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
 values (1, 'uuid', 1, 1, 'test launch', 'desc', now(), null, 1, now(), 'DEFAULT', 'PASSED', false);
 
-insert into item_attribute(id, key, value, item_id, launch_id, system) values (1, 'skippedIssue', 'true', null, 1, true);
+insert into item_attribute(id, key, value, item_id, launch_id, system)
+values (1, 'skippedIssue', 'true', null, 1, true);
 
 -- Test level item with 2 step items
-insert into test_item(test_case_hash, item_id, uuid,name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (1, 1, 'uuid1', 'test item 1', 'TEST', now(), 'desc', 'uuid1', now(), '1', null, 1);
 insert into test_item_results(result_id, status)
 values (1, 'IN_PROGRESS');
 
 
-insert into test_item(test_case_hash, item_id, uuid,name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (2, 2, 'uuid2', 'step item 1', 'STEP', now(), 'desc', 'uuid1', now(), '1.2', 1, 1);
 insert into test_item_results(result_id, status)
 values (2, 'IN_PROGRESS');
@@ -20,7 +24,8 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 2;
 
-insert into test_item(test_case_hash, item_id, uuid,name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (3, 3, 'uuid3', 'step item 2', 'STEP', now(), 'desc', 'uuid3', now(), '1.3', 1, 1);
 insert into test_item_results(result_id, status)
 values (3, 'IN_PROGRESS');
@@ -35,12 +40,14 @@ set status   = 'PASSED',
 where result_id = 1;
 
 -- Test level item with 2 step items
-insert into test_item(test_case_hash, item_id, uuid,name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (4, 4, 'uuid4', 'test item 1', 'TEST', now(), 'desc', 'uuid4', now(), '4', null, 1);
 insert into test_item_results(result_id, status)
 values (4, 'IN_PROGRESS');
 
-insert into test_item(test_case_hash, item_id, uuid,name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (5, 5, 'uuid5', 'step item 3', 'STEP', now(), 'desc', 'uuid5', now(), '4.5', 4, 1);
 insert into test_item_results(result_id, status)
 values (5, 'IN_PROGRESS');
@@ -49,7 +56,8 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 5;
 
-insert into test_item(test_case_hash, item_id, uuid,name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (6, 6, 'uuid6', 'step item 4', 'STEP', now(), 'desc', 'uuid6', now(), '4.6', 4, 1);
 insert into test_item_results(result_id, status)
 values (6, 'IN_PROGRESS');
@@ -58,7 +66,8 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 6;
 
-insert into test_item(test_case_hash, item_id, uuid,name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (7, 7, 'uuid7', 'step item 7', 'STEP', now(), 'desc', 'uuid7', now(), '4.7', 4, 1);
 insert into test_item_results(result_id, status)
 values (7, 'IN_PROGRESS');
@@ -73,16 +82,21 @@ set status   = 'PASSED',
 where result_id = 4;
 
 
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
-values (2, 'l2_uuid', 1, 1, 'test launch without skipped issue', 'desc', now(), null, 1, now(), 'DEFAULT', 'PASSED', false);
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
+values (2, 'l2_uuid', 1, 1, 'test launch without skipped issue', 'desc', now(), null, 1, now(),
+        'DEFAULT', 'PASSED', false);
 
-insert into test_item(test_case_hash, item_id, uuid,name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (8, 8, 'uuid_s_8', 'test suite 1', 'SUITE', now(), 'desc', 'uuid4', now(), '8', null, 2);
 insert into test_item_results(result_id, status)
 values (8, 'IN_PROGRESS');
 
-insert into test_item(test_case_hash, item_id, uuid,name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (9, 9, 'uuid_s_9', 'step item under suite', 'STEP', now(), 'desc', 'uuid7', now(), '8.9', 8, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (9, 9, 'uuid_s_9', 'step item under suite', 'STEP', now(), 'desc', 'uuid7', now(), '8.9', 8,
+        2);
 insert into test_item_results(result_id, status)
 values (9, 'IN_PROGRESS');
 update test_item_results
@@ -96,11 +110,15 @@ set status   = 'PASSED',
 where result_id = 8;
 
 
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
-values (3, 'l3_uuid', 1, 1, 'test launch to finish', 'desc', now(), null, 1, now(), 'DEFAULT', 'PASSED', false);
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
+values (3, 'l3_uuid', 1, 1, 'test launch to finish', 'desc', now(), null, 1, now(), 'DEFAULT',
+        'PASSED', false);
 
-insert into test_item(test_case_hash, item_id, uuid,name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (10, 10, 'uuid_s_2_8', 'test suite 2_1', 'SUITE', now(), 'desc', 'uuid4', now(), '10', null, 3);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (10, 10, 'uuid_s_2_8', 'test suite 2_1', 'SUITE', now(), 'desc', 'uuid4', now(), '10', null,
+        3);
 insert into test_item_results(result_id, status)
 values (10, 'IN_PROGRESS');
 update test_item_results
@@ -108,7 +126,9 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 10;
 
-insert into test_item(test_case_hash, item_id, uuid,name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (11, 11, 'uuid_s_2_9', 'step item under suite 2_1', 'STEP', now(), 'desc', 'uuid7', now(), '10.11', 10, 3);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (11, 11, 'uuid_s_2_9', 'step item under suite 2_1', 'STEP', now(), 'desc', 'uuid7', now(),
+        '10.11', 10, 3);
 insert into test_item_results(result_id, status)
 values (11, 'IN_PROGRESS');
\ No newline at end of file
diff --git a/src/test/resources/db/test-item/item-change-status-from-skipped.sql b/src/test/resources/db/test-item/item-change-status-from-skipped.sql
index 44a3b45758..3fd4e60e19 100644
--- a/src/test/resources/db/test-item/item-change-status-from-skipped.sql
+++ b/src/test/resources/db/test-item/item-change-status-from-skipped.sql
@@ -1,17 +1,21 @@
 -- Passed launch with 4 step items
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
 values (1, 'uuid', 1, 1, 'test launch', 'desc', now(), null, 1, now(), 'DEFAULT', 'FAILED', false);
 
-insert into item_attribute(id, key, value, item_id, launch_id, system) values (1, 'skippedIssue', 'true', null, 1, true);
+insert into item_attribute(id, key, value, item_id, launch_id, system)
+values (1, 'skippedIssue', 'true', null, 1, true);
 
 -- Test level item with 2 step items
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (1, 1, 'uuid1', 'test item 1', 'TEST', now(), 'desc', 'uuid1', now(), '1', null, 1);
 insert into test_item_results(result_id, status)
 values (1, 'IN_PROGRESS');
 
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (2, 2, 'uuid2', 'step item 1', 'STEP', now(), 'desc', 'uuid1', now(), '1.2', 1, 1);
 insert into test_item_results(result_id, status)
 values (2, 'IN_PROGRESS');
@@ -20,8 +24,9 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 2;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (3, 3,'uuid3',  'step item 2', 'STEP', now(), 'desc', 'uuid3', now(), '1.3', 1, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (3, 3, 'uuid3', 'step item 2', 'STEP', now(), 'desc', 'uuid3', now(), '1.3', 1, 1);
 insert into test_item_results(result_id, status)
 values (3, 'IN_PROGRESS');
 update test_item_results
@@ -35,13 +40,15 @@ set status   = 'PASSED',
 where result_id = 1;
 
 -- Test level item with 2 step items
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (4, 4,'uuid4',  'test item 1', 'TEST', now(), 'desc', 'uuid4', now(), '4', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (4, 4, 'uuid4', 'test item 1', 'TEST', now(), 'desc', 'uuid4', now(), '4', null, 1);
 insert into test_item_results(result_id, status)
 values (4, 'IN_PROGRESS');
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (5, 5,'uuid5',  'step item 3', 'STEP', now(), 'desc', 'uuid5', now(), '4.5', 4, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (5, 5, 'uuid5', 'step item 3', 'STEP', now(), 'desc', 'uuid5', now(), '4.5', 4, 1);
 insert into test_item_results(result_id, status)
 values (5, 'IN_PROGRESS');
 update test_item_results
@@ -49,8 +56,9 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 5;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (6, 6,'uuid6',  'step item 4', 'STEP', now(), 'desc', 'uuid6', now(), '4.6', 4, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (6, 6, 'uuid6', 'step item 4', 'STEP', now(), 'desc', 'uuid6', now(), '4.6', 4, 1);
 insert into test_item_results(result_id, status)
 values (6, 'IN_PROGRESS');
 update test_item_results
@@ -58,7 +66,8 @@ set status   = 'SKIPPED',
     end_time = now()
 where result_id = 6;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (7, 7, 'uuid7', 'step item 7', 'STEP', now(), 'desc', 'uuid7', now(), '4.7', 4, 1);
 insert into test_item_results(result_id, status)
 values (7, 'IN_PROGRESS');
diff --git a/src/test/resources/db/user/user-customer.sql b/src/test/resources/db/user/user-customer.sql
index dddbedc617..a4c23e1951 100644
--- a/src/test/resources/db/user/user-customer.sql
+++ b/src/test/resources/db/user/user-customer.sql
@@ -1,5 +1,7 @@
 INSERT INTO users (login, password, email, role, type, full_name, expired, metadata)
-VALUES ('default_customer', '5d39d85bddde885f6579f8121e11eba2', 'customeremail@domain.com', 'USER', 'INTERNAL', 'tester', FALSE,
+VALUES ('default_customer', '5d39d85bddde885f6579f8121e11eba2', 'customeremail@domain.com', 'USER',
+        'INTERNAL', 'tester', FALSE,
         '{"metadata": {"last_login": 0}}');
 
-INSERT INTO project_user (user_id, project_id, project_role) VALUES ((SELECT currval(pg_get_serial_sequence('users', 'id'))), 2, 'CUSTOMER');
+INSERT INTO project_user (user_id, project_id, project_role)
+VALUES ((SELECT currval(pg_get_serial_sequence('users', 'id'))), 2, 'CUSTOMER');
diff --git a/src/test/resources/db/user/user-fill.sql b/src/test/resources/db/user/user-fill.sql
index d55fb2798e..2dceea1356 100644
--- a/src/test/resources/db/user/user-fill.sql
+++ b/src/test/resources/db/user/user-fill.sql
@@ -1,5 +1,10 @@
-INSERT INTO user_creation_bid (uuid, email, default_project_id, role, inviting_user_id)
-VALUES ('e5f98deb-8966-4b2d-ba2f-35bc69d30c06', 'test@domain.com', 2, 'MEMBER', 1);
+INSERT INTO user_creation_bid (uuid, email, project_name, role, metadata, inviting_user_id)
+VALUES ('e5f98deb-8966-4b2d-ba2f-35bc69d30c06', 'test@domain.com', 'default_personal', 'MEMBER',
+'{
+   "metadata": {
+     "type": "internal"
+   }
+ }', 1);
 
 INSERT INTO restore_password_bid (uuid, last_modified, email)
 VALUES ('e5f98deb-8966-4b2d-ba2f-35bc69d30c06', now(), 'defaultemail@domain.com');
@@ -7,13 +12,6 @@ VALUES ('e5f98deb-8966-4b2d-ba2f-35bc69d30c06', now(), 'defaultemail@domain.com'
 INSERT INTO integration (project_id, type, enabled, params, creator, creation_date, name)
 VALUES (2, 2, TRUE, NULL, 'superadmin', now(), 'integration name');
 
-INSERT INTO public.oauth_access_token (id, token_id, token, authentication_id, username, user_id, client_id, authentication, refresh_token)
-VALUES (3, '1089a992-a931-4b5c-8194-09c925168b37',
-        E'\\xACED0005737200436F72672E737072696E676672616D65776F726B2E73656375726974792E6F61757468322E636F6D6D6F6E2E44656661756C744F4175746832416363657373546F6B656E0CB29E361B24FACE0200064C00156164646974696F6E616C496E666F726D6174696F6E74000F4C6A6176612F7574696C2F4D61703B4C000A65787069726174696F6E7400104C6A6176612F7574696C2F446174653B4C000C72656672657368546F6B656E74003F4C6F72672F737072696E676672616D65776F726B2F73656375726974792F6F61757468322F636F6D6D6F6E2F4F417574683252656672657368546F6B656E3B4C000573636F706574000F4C6A6176612F7574696C2F5365743B4C0009746F6B656E547970657400124C6A6176612F6C616E672F537472696E673B4C000576616C756571007E000578707372001E6A6176612E7574696C2E436F6C6C656374696F6E7324456D7074794D6170593614855ADCE7D002000078707070737200256A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C65536574801D92D18F9B80550200007872002C6A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C65436F6C6C656374696F6E19420080CB5EF71E0200014C0001637400164C6A6176612F7574696C2F436F6C6C656374696F6E3B7870737200176A6176612E7574696C2E4C696E6B656448617368536574D86CD75A95DD2A1E020000787200116A6176612E7574696C2E48617368536574BA44859596B8B7340300007870770C000000103F400000000000017400036170697874000662656172657274002431303839613939322D613933312D346235632D383139342D303963393235313638623337',
-        'ec119aafb40d36d6757f5b3ffccf8b32', 'default', 2, 'api',
-        E'\\xACED0005737200416F72672E737072696E676672616D65776F726B2E73656375726974792E6F61757468322E70726F76696465722E4F417574683241757468656E7469636174696F6EBD400B02166252130200024C000D73746F7265645265717565737474003C4C6F72672F737072696E676672616D65776F726B2F73656375726974792F6F61757468322F70726F76696465722F4F4175746832526571756573743B4C00127573657241757468656E7469636174696F6E7400324C6F72672F737072696E676672616D65776F726B2F73656375726974792F636F72652F41757468656E7469636174696F6E3B787200476F72672E737072696E676672616D65776F726B2E73656375726974792E61757468656E7469636174696F6E2E416273747261637441757468656E7469636174696F6E546F6B656ED3AA287E6E47640E0200035A000D61757468656E746963617465644C000B617574686F7269746965737400164C6A6176612F7574696C2F436F6C6C656374696F6E3B4C000764657461696C737400124C6A6176612F6C616E672F4F626A6563743B787000737200266A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C654C697374FC0F2531B5EC8E100200014C00046C6973747400104C6A6176612F7574696C2F4C6973743B7872002C6A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C65436F6C6C656374696F6E19420080CB5EF71E0200014C00016371007E00047870737200136A6176612E7574696C2E41727261794C6973747881D21D99C7619D03000149000473697A65787000000001770400000001737200426F72672E737072696E676672616D65776F726B2E73656375726974792E636F72652E617574686F726974792E53696D706C654772616E746564417574686F7269747900000000000002080200014C0004726F6C657400124C6A6176612F6C616E672F537472696E673B7870740009524F4C455F555345527871007E000C707372003A6F72672E737072696E676672616D65776F726B2E73656375726974792E6F61757468322E70726F76696465722E4F41757468325265717565737400000000000000010200075A0008617070726F7665644C000B617574686F72697469657371007E00044C000A657874656E73696F6E7374000F4C6A6176612F7574696C2F4D61703B4C000B726564697265637455726971007E000E4C00077265667265736874003B4C6F72672F737072696E676672616D65776F726B2F73656375726974792F6F61757468322F70726F76696465722F546F6B656E526571756573743B4C000B7265736F7572636549647374000F4C6A6176612F7574696C2F5365743B4C000D726573706F6E7365547970657371007E0014787200386F72672E737072696E676672616D65776F726B2E73656375726974792E6F61757468322E70726F76696465722E426173655265717565737436287A3EA37169BD0200034C0008636C69656E74496471007E000E4C001172657175657374506172616D657465727371007E00124C000573636F706571007E00147870740003617069737200256A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C654D6170F1A5A8FE74F507420200014C00016D71007E00127870737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F40000000000006770800000008000000047400056772616E7474000870617373776F726474000A6772616E745F7479706570740009636C69656E745F696471007E0017740008757365726E616D6574000764656661756C7478737200256A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C65536574801D92D18F9B80550200007871007E0009737200176A6176612E7574696C2E4C696E6B656448617368536574D86CD75A95DD2A1E020000787200116A6176612E7574696C2E48617368536574BA44859596B8B7340300007870770C000000103F4000000000000171007E001778017371007E0025770C000000103F40000000000000787371007E001A3F40000000000000770800000010000000007870707371007E0025770C000000103F40000000000000787371007E0025770C000000103F40000000000000787372004F6F72672E737072696E676672616D65776F726B2E73656375726974792E61757468656E7469636174696F6E2E557365726E616D6550617373776F726441757468656E7469636174696F6E546F6B656E00000000000002080200024C000B63726564656E7469616C7371007E00054C00097072696E636970616C71007E00057871007E0003017371007E00077371007E000B0000000177040000000171007E000F7871007E002E707400034E2F4173720031636F6D2E6570616D2E74612E7265706F7274706F7274616C2E636F6D6D6F6E732E5265706F7274506F7274616C557365729177CA61D787FB2E0200044C0005656D61696C71007E000E4C000E70726F6A65637444657461696C7371007E00124C00067573657249647400104C6A6176612F6C616E672F4C6F6E673B4C000875736572526F6C6574002F4C636F6D2F6570616D2F74612F7265706F7274706F7274616C2F656E746974792F757365722F55736572526F6C653B787200326F72672E737072696E676672616D65776F726B2E73656375726974792E636F72652E7573657264657461696C732E5573657200000000000002080200075A00116163636F756E744E6F6E457870697265645A00106163636F756E744E6F6E4C6F636B65645A001563726564656E7469616C734E6F6E457870697265645A0007656E61626C65644C000B617574686F72697469657371007E00144C000870617373776F726471007E000E4C0008757365726E616D6571007E000E7870010101017371007E0022737200116A6176612E7574696C2E54726565536574DD98509395ED875B0300007870737200466F72672E737072696E676672616D65776F726B2E73656375726974792E636F72652E7573657264657461696C732E5573657224417574686F72697479436F6D70617261746F720000000000000208020000787077040000000171007E000F78740020336664653662623035343133383765346562646164663763326666333131323371007E002174001764656661756C74656D61696C40646F6D61696E2E636F6D7371007E001A3F400000000000017708000000020000000174001064656661756C745F706572736F6E616C73720040636F6D2E6570616D2E74612E7265706F7274706F7274616C2E636F6D6D6F6E732E5265706F7274506F7274616C557365722450726F6A65637444657461696C731F175AB834A625AD0200034C000970726F6A656374496471007E00314C000B70726F6A6563744E616D6571007E000E4C000B70726F6A656374526F6C657400354C636F6D2F6570616D2F74612F7265706F7274706F7274616C2F656E746974792F70726F6A6563742F50726F6A656374526F6C653B78707372000E6A6176612E6C616E672E4C6F6E673B8BE490CC8F23DF0200014A000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B0200007870000000000000000571007E003D7E720033636F6D2E6570616D2E74612E7265706F7274706F7274616C2E656E746974792E70726F6A6563742E50726F6A656374526F6C6500000000000000001200007872000E6A6176612E6C616E672E456E756D0000000000000000120000787074000F50524F4A4543545F4D414E41474552787371007E004100000000000000027E72002D636F6D2E6570616D2E74612E7265706F7274706F7274616C2E656E746974792E757365722E55736572526F6C6500000000000000001200007871007E004574000455534552',
-        NULL);
-
 INSERT INTO api_keys(
 	id, name, hash, created_at, user_id)
 	VALUES (1, 'test', '1E2CEACB608044C8C900C7A5FB43ED593BC97DBC559D0F03D6FC59D5EB58303F', now(), 1);
\ No newline at end of file
diff --git a/src/test/resources/db/widget/bug-trend.sql b/src/test/resources/db/widget/bug-trend.sql
index fc520d13e1..8e390e533d 100644
--- a/src/test/resources/db/widget/bug-trend.sql
+++ b/src/test/resources/db/widget/bug-trend.sql
@@ -1,8 +1,10 @@
 -- First launch
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
 values (1, 'uuid', 1, 1, 'test launch', 'desc', now(), null, 1, now(), 'DEFAULT', 'FAILED', false);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (1, 1, 'uuid1', 'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '1', null, 1);
 insert into test_item_results(result_id, status)
 values (1, 'IN_PROGRESS');
@@ -11,8 +13,9 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 1;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (2, 2,'uuid2',  'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '2', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (2, 2, 'uuid2', 'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '2', null, 1);
 insert into test_item_results(result_id, status)
 values (2, 'IN_PROGRESS');
 update test_item_results
@@ -22,7 +25,8 @@ where result_id = 2;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (2, 2, 'automation bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (3, 3, 'uuid3', 'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '3', null, 1);
 insert into test_item_results(result_id, status)
 values (3, 'IN_PROGRESS');
@@ -33,8 +37,9 @@ where result_id = 3;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (3, 3, 'product bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (4, 4,'uuid4',  'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '4', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (4, 4, 'uuid4', 'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '4', null, 1);
 insert into test_item_results(result_id, status)
 values (4, 'IN_PROGRESS');
 update test_item_results
@@ -42,8 +47,9 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 4;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (5, 5,'uuid5',  'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '5', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (5, 5, 'uuid5', 'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '5', null, 1);
 insert into test_item_results(result_id, status)
 values (5, 'IN_PROGRESS');
 update test_item_results
@@ -54,11 +60,13 @@ insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore
 values (5, 1, 'to investigate', false, true);
 
 -- Second launch
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
 values (2, 'uuid2', 1, 1, 'test launch', 'desc', now(), null, 2, now(), 'DEFAULT', 'FAILED', false);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (6, 6, 'uuid6',  'test item 1', 'STEP', now(), 'desc', 'uuid6', now(), '6', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (6, 6, 'uuid6', 'test item 1', 'STEP', now(), 'desc', 'uuid6', now(), '6', null, 2);
 insert into test_item_results(result_id, status)
 values (6, 'IN_PROGRESS');
 update test_item_results
@@ -66,8 +74,9 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 6;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (7, 7, 'uuid7',  'test item 2', 'STEP', now(), 'desc', 'uuid7', now(), '7', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (7, 7, 'uuid7', 'test item 2', 'STEP', now(), 'desc', 'uuid7', now(), '7', null, 2);
 insert into test_item_results(result_id, status)
 values (7, 'IN_PROGRESS');
 update test_item_results
@@ -77,8 +86,9 @@ where result_id = 7;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (7, 1, 'unknown bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (8, 8, 'uuid8',  'test item 3', 'STEP', now(), 'desc', 'uuid8', now(), '8', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (8, 8, 'uuid8', 'test item 3', 'STEP', now(), 'desc', 'uuid8', now(), '8', null, 2);
 insert into test_item_results(result_id, status)
 values (8, 'IN_PROGRESS');
 update test_item_results
@@ -88,8 +98,9 @@ where result_id = 8;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (8, 3, 'product bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (9, 9, 'uuid9',  'test item 4', 'STEP', now(), 'desc', 'uuid9', now(), '9', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (9, 9, 'uuid9', 'test item 4', 'STEP', now(), 'desc', 'uuid9', now(), '9', null, 2);
 insert into test_item_results(result_id, status)
 values (9, 'IN_PROGRESS');
 update test_item_results
@@ -97,8 +108,9 @@ set status   = 'SKIPPED',
     end_time = now()
 where result_id = 9;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (10, 10, 'uuid10',  'test item 5', 'STEP', now(), 'desc', 'uuid10', now(), '10', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (10, 10, 'uuid10', 'test item 5', 'STEP', now(), 'desc', 'uuid10', now(), '10', null, 2);
 insert into test_item_results(result_id, status)
 values (10, 'IN_PROGRESS');
 update test_item_results
diff --git a/src/test/resources/db/widget/cases-trend.sql b/src/test/resources/db/widget/cases-trend.sql
index 6f6e97518a..6570a2ba35 100644
--- a/src/test/resources/db/widget/cases-trend.sql
+++ b/src/test/resources/db/widget/cases-trend.sql
@@ -1,9 +1,11 @@
 -- First launch
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
 values (1, 'uuid', 1, 1, 'test launch', 'desc', now(), null, 1, now(), 'DEFAULT', 'FAILED', false);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (1, 1,'uuid1',  'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '1', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (1, 1, 'uuid1', 'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '1', null, 1);
 insert into test_item_results(result_id, status)
 values (1, 'IN_PROGRESS');
 update test_item_results
@@ -11,8 +13,9 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 1;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (2, 2,'uuid2',  'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '2', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (2, 2, 'uuid2', 'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '2', null, 1);
 insert into test_item_results(result_id, status)
 values (2, 'IN_PROGRESS');
 update test_item_results
@@ -22,8 +25,9 @@ where result_id = 2;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (2, 2, 'automation bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (3, 3,'uuid3',  'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '3', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (3, 3, 'uuid3', 'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '3', null, 1);
 insert into test_item_results(result_id, status)
 values (3, 'IN_PROGRESS');
 update test_item_results
@@ -33,8 +37,9 @@ where result_id = 3;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (3, 3, 'product bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (4, 4,'uuid4',  'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '4', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (4, 4, 'uuid4', 'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '4', null, 1);
 insert into test_item_results(result_id, status)
 values (4, 'IN_PROGRESS');
 update test_item_results
@@ -42,8 +47,9 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 4;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (5, 5,'uuid5',  'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '5', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (5, 5, 'uuid5', 'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '5', null, 1);
 insert into test_item_results(result_id, status)
 values (5, 'IN_PROGRESS');
 update test_item_results
@@ -54,11 +60,13 @@ insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore
 values (5, 1, 'to investigate', false, true);
 
 -- Second launch
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
 values (2, 'uuid2', 1, 1, 'test launch', 'desc', now(), null, 2, now(), 'DEFAULT', 'FAILED', false);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (6, 6,'uuid6',  'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '6', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (6, 6, 'uuid6', 'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '6', null, 2);
 insert into test_item_results(result_id, status)
 values (6, 'IN_PROGRESS');
 update test_item_results
@@ -66,7 +74,8 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 6;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (7, 7, 'uuid7', 'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '7', null, 2);
 insert into test_item_results(result_id, status)
 values (7, 'IN_PROGRESS');
@@ -77,8 +86,9 @@ where result_id = 7;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (7, 1, 'unknown bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (8, 8,'uuid8',  'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '8', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (8, 8, 'uuid8', 'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '8', null, 2);
 insert into test_item_results(result_id, status)
 values (8, 'IN_PROGRESS');
 update test_item_results
@@ -88,8 +98,9 @@ where result_id = 8;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (8, 3, 'product bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (9, 9,'uuid9',  'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '9', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (9, 9, 'uuid9', 'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '9', null, 2);
 insert into test_item_results(result_id, status)
 values (9, 'IN_PROGRESS');
 update test_item_results
@@ -97,8 +108,9 @@ set status   = 'SKIPPED',
     end_time = now()
 where result_id = 9;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (10, 10,'uuid10',  'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '10', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (10, 10, 'uuid10', 'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '10', null, 2);
 insert into test_item_results(result_id, status)
 values (10, 'IN_PROGRESS');
 update test_item_results
diff --git a/src/test/resources/db/widget/flaky-test-cases.sql b/src/test/resources/db/widget/flaky-test-cases.sql
index baaab8788a..563c79e13f 100644
--- a/src/test/resources/db/widget/flaky-test-cases.sql
+++ b/src/test/resources/db/widget/flaky-test-cases.sql
@@ -1,9 +1,11 @@
 -- First launch
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
 values (1, 'uuid', 1, 1, 'test launch', 'desc', now(), null, 1, now(), 'DEFAULT', 'FAILED', false);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (1, 1,'uuid1',  'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '1', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (1, 1, 'uuid1', 'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '1', null, 1);
 insert into test_item_results(result_id, status)
 values (1, 'IN_PROGRESS');
 update test_item_results
@@ -11,8 +13,9 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 1;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (2, 2,'uuid2',  'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '2', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (2, 2, 'uuid2', 'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '2', null, 1);
 insert into test_item_results(result_id, status)
 values (2, 'IN_PROGRESS');
 update test_item_results
@@ -22,8 +25,9 @@ where result_id = 2;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (2, 2, 'automation bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (3, 3,'uuid3',  'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '3', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (3, 3, 'uuid3', 'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '3', null, 1);
 insert into test_item_results(result_id, status)
 values (3, 'IN_PROGRESS');
 update test_item_results
@@ -33,8 +37,9 @@ where result_id = 3;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (3, 3, 'product bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (4, 4,'uuid4',  'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '4', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (4, 4, 'uuid4', 'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '4', null, 1);
 insert into test_item_results(result_id, status)
 values (4, 'IN_PROGRESS');
 update test_item_results
@@ -42,8 +47,9 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 4;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (5, 5,'uuid5',  'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '5', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (5, 5, 'uuid5', 'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '5', null, 1);
 insert into test_item_results(result_id, status)
 values (5, 'IN_PROGRESS');
 update test_item_results
@@ -54,11 +60,13 @@ insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore
 values (5, 1, 'to investigate', false, true);
 
 -- Second launch
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
 values (2, 'uuid2', 1, 1, 'test launch', 'desc', now(), null, 2, now(), 'DEFAULT', 'FAILED', false);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (6, 6,'uuid6',  'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '6', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (6, 6, 'uuid6', 'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '6', null, 2);
 insert into test_item_results(result_id, status)
 values (6, 'IN_PROGRESS');
 update test_item_results
@@ -66,8 +74,9 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 6;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (7, 7,'uuid7',  'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '7', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (7, 7, 'uuid7', 'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '7', null, 2);
 insert into test_item_results(result_id, status)
 values (7, 'IN_PROGRESS');
 update test_item_results
@@ -77,8 +86,9 @@ where result_id = 7;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (7, 1, 'unknown bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (8, 8, 'uuid8',  'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '8', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (8, 8, 'uuid8', 'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '8', null, 2);
 insert into test_item_results(result_id, status)
 values (8, 'IN_PROGRESS');
 update test_item_results
@@ -88,8 +98,9 @@ where result_id = 8;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (8, 3, 'product bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (9, 9, 'uuid9',  'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '9', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (9, 9, 'uuid9', 'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '9', null, 2);
 insert into test_item_results(result_id, status)
 values (9, 'IN_PROGRESS');
 update test_item_results
@@ -97,20 +108,34 @@ set status   = 'SKIPPED',
     end_time = now()
 where result_id = 9;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (10, 10, 'uuid10',  'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '10', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (10, 10, 'uuid10', 'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '10', null, 2);
 insert into test_item_results(result_id, status)
 values (10, 'IN_PROGRESS');
 update test_item_results
 set status   = 'FAILED',
     end_time = now()
 where result_id = 10;
+
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (11, 11, 'uuid11', 'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '11', null, 2);
+insert into test_item_results(result_id, status)
+values (11, 'IN_PROGRESS');
+update test_item_results
+set status   = 'FAILED',
+    end_time = now()
+where result_id = 11;
+
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (10, 1, 'to investigate', false, true);
 
 -- Third launch
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
-values (3, 'uuid3', 1, 1, 'empty launch', 'desc', now(), null, 2, now(), 'DEFAULT', 'FAILED', false);
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
+values (3, 'uuid3', 1, 1, 'empty launch', 'desc', now(), null, 2, now(), 'DEFAULT', 'FAILED',
+        false);
 
 -- Filter and widget
 INSERT INTO public.owned_entity (id, owner, project_id)
@@ -120,7 +145,11 @@ VALUES (1, 'superadmin', 1),
        (4, 'superadmin', 1);
 
 INSERT INTO public.widget (id, name, description, widget_type, items_count, widget_options)
-VALUES (1, 'flaky test cases', null, 'flakyTestCases', 10, '{"options": {"launchNameFilter": "test launch"}}'),
-       (2, 'flaky test cases', null, 'flakyTestCases', 10, '{"options": {"launchNameFilter": "not_exist"}}'),
-       (3, 'flaky test cases', null, 'flakyTestCases', 10, '{"options": {"launchNameFilter": "empty launch"}}'),
-       (4, 'flaky test cases', null, 'flakyTestCases', 10, '{"options": {"launchNameFilter": "test launch", "includeMethods": true}}');
+VALUES (1, 'flaky test cases', null, 'flakyTestCases', 10,
+        '{"options": {"launchNameFilter": "test launch"}}'),
+       (2, 'flaky test cases', null, 'flakyTestCases', 10,
+        '{"options": {"launchNameFilter": "not_exist"}}'),
+       (3, 'flaky test cases', null, 'flakyTestCases', 10,
+        '{"options": {"launchNameFilter": "empty launch"}}'),
+       (4, 'flaky test cases', null, 'flakyTestCases', 10,
+        '{"options": {"launchNameFilter": "test launch", "includeMethods": true}}');
diff --git a/src/test/resources/db/widget/investigated-trend.sql b/src/test/resources/db/widget/investigated-trend.sql
index f972dc1273..7cd1493e98 100644
--- a/src/test/resources/db/widget/investigated-trend.sql
+++ b/src/test/resources/db/widget/investigated-trend.sql
@@ -1,9 +1,11 @@
 -- First launch
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
 values (1, 'uuid', 1, 1, 'test launch', 'desc', now(), null, 1, now(), 'DEFAULT', 'FAILED', false);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (1, 1,'uuid1',  'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '1', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (1, 1, 'uuid1', 'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '1', null, 1);
 insert into test_item_results(result_id, status)
 values (1, 'IN_PROGRESS');
 update test_item_results
@@ -11,7 +13,8 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 1;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (2, 2, 'uuid2', 'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '2', null, 1);
 insert into test_item_results(result_id, status)
 values (2, 'IN_PROGRESS');
@@ -22,7 +25,8 @@ where result_id = 2;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (2, 2, 'automation bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (3, 3, 'uuid3', 'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '3', null, 1);
 insert into test_item_results(result_id, status)
 values (3, 'IN_PROGRESS');
@@ -33,7 +37,8 @@ where result_id = 3;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (3, 3, 'product bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (4, 4, 'uuid4', 'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '4', null, 1);
 insert into test_item_results(result_id, status)
 values (4, 'IN_PROGRESS');
@@ -42,7 +47,8 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 4;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (5, 5, 'uuid5', 'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '5', null, 1);
 insert into test_item_results(result_id, status)
 values (5, 'IN_PROGRESS');
@@ -54,10 +60,12 @@ insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore
 values (5, 1, 'to investigate', false, true);
 
 -- Second launch
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
 values (2, 'uuid2', 1, 1, 'test launch', 'desc', now(), null, 2, now(), 'DEFAULT', 'FAILED', false);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (6, 6, 'uuid6', 'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '6', null, 2);
 insert into test_item_results(result_id, status)
 values (6, 'IN_PROGRESS');
@@ -66,7 +74,8 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 6;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (7, 7, 'uuid7', 'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '7', null, 2);
 insert into test_item_results(result_id, status)
 values (7, 'IN_PROGRESS');
@@ -77,7 +86,8 @@ where result_id = 7;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (7, 1, 'unknown bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (8, 8, 'uuid8', 'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '8', null, 2);
 insert into test_item_results(result_id, status)
 values (8, 'IN_PROGRESS');
@@ -88,7 +98,8 @@ where result_id = 8;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (8, 3, 'product bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (9, 9, 'uuid9', 'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '9', null, 2);
 insert into test_item_results(result_id, status)
 values (9, 'IN_PROGRESS');
@@ -97,7 +108,8 @@ set status   = 'SKIPPED',
     end_time = now()
 where result_id = 9;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (10, 10, 'uuid10', 'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '10', null, 2);
 insert into test_item_results(result_id, status)
 values (10, 'IN_PROGRESS');
@@ -125,7 +137,8 @@ VALUES (1, 1, 'CONTAINS', 'test', 'name', false);
 
 INSERT INTO public.widget (id, name, description, widget_type, items_count, widget_options)
 VALUES (2, 'investigated trend', null, 'investigatedTrend', 10, '{"options": {}}'),
-       (3, 'investigated trend', null, 'investigatedTrend', 10, '{"options": {"timeline":  "WEEK"}}');
+       (3, 'investigated trend', null, 'investigatedTrend', 10,
+        '{"options": {"timeline":  "WEEK"}}');
 
 insert into widget_filter(widget_id, filter_id)
 values (2, 1),
diff --git a/src/test/resources/db/widget/launch-statistics.sql b/src/test/resources/db/widget/launch-statistics.sql
index 2c5b2aaf21..60d2cbd2c0 100644
--- a/src/test/resources/db/widget/launch-statistics.sql
+++ b/src/test/resources/db/widget/launch-statistics.sql
@@ -1,8 +1,10 @@
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
 values (1, 'uuid', 1, 1, 'test launch', 'desc', now(), null, 1, now(), 'DEFAULT', 'FAILED', false);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (1, 1,'uuid1',  'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '1', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (1, 1, 'uuid1', 'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '1', null, 1);
 insert into test_item_results(result_id, status)
 values (1, 'IN_PROGRESS');
 update test_item_results
@@ -10,7 +12,8 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 1;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (2, 2, 'uuid2', 'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '2', null, 1);
 insert into test_item_results(result_id, status)
 values (2, 'IN_PROGRESS');
@@ -21,8 +24,9 @@ where result_id = 2;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (2, 2, 'automation bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (3, 3,'uuid3',  'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '3', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (3, 3, 'uuid3', 'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '3', null, 1);
 insert into test_item_results(result_id, status)
 values (3, 'IN_PROGRESS');
 update test_item_results
@@ -32,8 +36,9 @@ where result_id = 3;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (3, 3, 'product bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (4, 4,'uuid4',  'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '4', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (4, 4, 'uuid4', 'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '4', null, 1);
 insert into test_item_results(result_id, status)
 values (4, 'IN_PROGRESS');
 update test_item_results
@@ -41,8 +46,9 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 4;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (5, 5,'uuid5',  'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '5', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (5, 5, 'uuid5', 'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '5', null, 1);
 insert into test_item_results(result_id, status)
 values (5, 'IN_PROGRESS');
 update test_item_results
diff --git a/src/test/resources/db/widget/launches-comparison-chart.sql b/src/test/resources/db/widget/launches-comparison-chart.sql
index 3f4d028ad9..e7e1dcf603 100644
--- a/src/test/resources/db/widget/launches-comparison-chart.sql
+++ b/src/test/resources/db/widget/launches-comparison-chart.sql
@@ -1,9 +1,11 @@
 -- First launch
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
 values (1, 'uuid', 1, 1, 'test launch', 'desc', now(), null, 1, now(), 'DEFAULT', 'FAILED', false);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (1, 1,'uuid1',  'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '1', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (1, 1, 'uuid1', 'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '1', null, 1);
 insert into test_item_results(result_id, status)
 values (1, 'IN_PROGRESS');
 update test_item_results
@@ -11,8 +13,9 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 1;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (2, 2,'uuid2',  'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '2', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (2, 2, 'uuid2', 'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '2', null, 1);
 insert into test_item_results(result_id, status)
 values (2, 'IN_PROGRESS');
 update test_item_results
@@ -22,8 +25,9 @@ where result_id = 2;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (2, 2, 'automation bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (3, 3,'uuid3',  'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '3', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (3, 3, 'uuid3', 'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '3', null, 1);
 insert into test_item_results(result_id, status)
 values (3, 'IN_PROGRESS');
 update test_item_results
@@ -33,7 +37,8 @@ where result_id = 3;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (3, 3, 'product bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (4, 4, 'uuid4', 'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '4', null, 1);
 insert into test_item_results(result_id, status)
 values (4, 'IN_PROGRESS');
@@ -42,8 +47,9 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 4;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (5, 5,'uuid5',  'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '5', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (5, 5, 'uuid5', 'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '5', null, 1);
 insert into test_item_results(result_id, status)
 values (5, 'IN_PROGRESS');
 update test_item_results
@@ -54,11 +60,13 @@ insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore
 values (5, 1, 'to investigate', false, true);
 
 -- Second launch
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
 values (2, 'uuid2', 1, 1, 'test launch', 'desc', now(), null, 2, now(), 'DEFAULT', 'FAILED', false);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (6, 6,'uuid6',  'test item 1', 'STEP', now(), 'desc', 'uuid6', now(), '6', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (6, 6, 'uuid6', 'test item 1', 'STEP', now(), 'desc', 'uuid6', now(), '6', null, 2);
 insert into test_item_results(result_id, status)
 values (6, 'IN_PROGRESS');
 update test_item_results
@@ -66,8 +74,9 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 6;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (7, 7,'uuid7',  'test item 2', 'STEP', now(), 'desc', 'uuid7', now(), '7', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (7, 7, 'uuid7', 'test item 2', 'STEP', now(), 'desc', 'uuid7', now(), '7', null, 2);
 insert into test_item_results(result_id, status)
 values (7, 'IN_PROGRESS');
 update test_item_results
@@ -77,7 +86,8 @@ where result_id = 7;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (7, 1, 'unknown bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (8, 8, 'uuid8', 'test item 3', 'STEP', now(), 'desc', 'uuid8', now(), '8', null, 2);
 insert into test_item_results(result_id, status)
 values (8, 'IN_PROGRESS');
@@ -88,8 +98,9 @@ where result_id = 8;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (8, 3, 'product bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (9, 9,'uuid9',  'test item 4', 'STEP', now(), 'desc', 'uuid9', now(), '9', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (9, 9, 'uuid9', 'test item 4', 'STEP', now(), 'desc', 'uuid9', now(), '9', null, 2);
 insert into test_item_results(result_id, status)
 values (9, 'IN_PROGRESS');
 update test_item_results
@@ -97,7 +108,8 @@ set status   = 'SKIPPED',
     end_time = now()
 where result_id = 9;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (10, 10, 'uuid10', 'test item 5', 'STEP', now(), 'desc', 'uuid10', now(), '10', null, 2);
 insert into test_item_results(result_id, status)
 values (10, 'IN_PROGRESS');
@@ -128,8 +140,10 @@ VALUES (1, 1, 'CONTAINS', 'test', 'name', false),
        (4, 4, 'EQUALS', 'mot_exist', 'name', false);
 
 INSERT INTO public.widget (id, name, description, widget_type, items_count, widget_options)
-VALUES (2, 'launch comparison', null, 'launchesComparisonChart', 20, '{"options": {"launchNameFilter": "test launch"}}'),
-       (3, 'launch comparison', null, 'launchesComparisonChart', 20, '{"options": {"launchNameFilter": "test launch"}}');
+VALUES (2, 'launch comparison', null, 'launchesComparisonChart', 20,
+        '{"options": {"launchNameFilter": "test launch"}}'),
+       (3, 'launch comparison', null, 'launchesComparisonChart', 20,
+        '{"options": {"launchNameFilter": "test launch"}}');
 
 insert into content_field(id, field)
 values (2, 'statistics$executions$total'),
diff --git a/src/test/resources/db/widget/launches-duration-chart.sql b/src/test/resources/db/widget/launches-duration-chart.sql
index c59ca8f7ad..7ce324da0a 100644
--- a/src/test/resources/db/widget/launches-duration-chart.sql
+++ b/src/test/resources/db/widget/launches-duration-chart.sql
@@ -1,10 +1,14 @@
 -- First launch
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
-values (1, 'uuid', 1, 1, 'test launch', 'desc', now() - interval '9 minute', now(), 1, now(), 'DEFAULT', 'FAILED', false);
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
+values (1, 'uuid', 1, 1, 'test launch', 'desc', now() - interval '9 minute', now(), 1, now(),
+        'DEFAULT', 'FAILED', false);
 
 -- Second launch
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
-values (2, 'uuid2', 1, 1, 'test launch', 'desc', now() - interval '11 minute', now(), 2, now(), 'DEFAULT', 'FAILED', false);
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
+values (2, 'uuid2', 1, 1, 'test launch', 'desc', now() - interval '11 minute', now(), 2, now(),
+        'DEFAULT', 'FAILED', false);
 
 -- Filters and widgets
 INSERT INTO public.owned_entity (id, owner, project_id)
diff --git a/src/test/resources/db/widget/launches-table.sql b/src/test/resources/db/widget/launches-table.sql
index 1d59fbcec5..6b2935539d 100644
--- a/src/test/resources/db/widget/launches-table.sql
+++ b/src/test/resources/db/widget/launches-table.sql
@@ -1,12 +1,16 @@
 -- First launch
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
 values (2, 'uuid2', 1, 1, 'test launch', 'desc', now(), null, 2, now(), 'DEFAULT', 'FAILED', false);
 
-insert into item_attribute(key, value, launch_id) VALUES ('key', 'value', 2);
-insert into item_attribute(key, value, launch_id) VALUES ('key1', 'value1', 2);
+insert into item_attribute(key, value, launch_id)
+VALUES ('key', 'value', 2);
+insert into item_attribute(key, value, launch_id)
+VALUES ('key1', 'value1', 2);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (6, 6,'uuid6',  'test item 1', 'STEP', now(), 'desc', 'uuid6', now(), '6', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (6, 6, 'uuid6', 'test item 1', 'STEP', now(), 'desc', 'uuid6', now(), '6', null, 2);
 insert into test_item_results(result_id, status)
 values (6, 'IN_PROGRESS');
 update test_item_results
@@ -14,8 +18,9 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 6;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (7, 7,'uuid7',  'test item 2', 'STEP', now(), 'desc', 'uuid7', now(), '7', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (7, 7, 'uuid7', 'test item 2', 'STEP', now(), 'desc', 'uuid7', now(), '7', null, 2);
 insert into test_item_results(result_id, status)
 values (7, 'IN_PROGRESS');
 update test_item_results
@@ -25,8 +30,9 @@ where result_id = 7;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (7, 1, 'unknown bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (8, 8,'uuid8',  'test item 3', 'STEP', now(), 'desc', 'uuid8', now(), '8', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (8, 8, 'uuid8', 'test item 3', 'STEP', now(), 'desc', 'uuid8', now(), '8', null, 2);
 insert into test_item_results(result_id, status)
 values (8, 'IN_PROGRESS');
 update test_item_results
@@ -36,8 +42,9 @@ where result_id = 8;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (8, 3, 'product bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (9, 9,'uuid9',  'test item 4', 'STEP', now(), 'desc', 'uuid9', now(), '9', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (9, 9, 'uuid9', 'test item 4', 'STEP', now(), 'desc', 'uuid9', now(), '9', null, 2);
 insert into test_item_results(result_id, status)
 values (9, 'IN_PROGRESS');
 update test_item_results
@@ -45,8 +52,9 @@ set status   = 'SKIPPED',
     end_time = now()
 where result_id = 9;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (10, 10,'uuid10',  'test item 5', 'STEP', now(), 'desc', 'uuid10', now(), '10', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (10, 10, 'uuid10', 'test item 5', 'STEP', now(), 'desc', 'uuid10', now(), '10', null, 2);
 insert into test_item_results(result_id, status)
 values (10, 'IN_PROGRESS');
 update test_item_results
diff --git a/src/test/resources/db/widget/most-time-consuming.sql b/src/test/resources/db/widget/most-time-consuming.sql
index 35ce4a3440..d746ef9ddd 100644
--- a/src/test/resources/db/widget/most-time-consuming.sql
+++ b/src/test/resources/db/widget/most-time-consuming.sql
@@ -1,9 +1,11 @@
 -- First launch
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
 values (1, 'uuid', 1, 1, 'test launch', 'desc', now(), null, 1, now(), 'DEFAULT', 'FAILED', false);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (1, 1,'uuid1',  'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '1', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (1, 1, 'uuid1', 'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '1', null, 1);
 insert into test_item_results(result_id, status)
 values (1, 'IN_PROGRESS');
 update test_item_results
@@ -12,8 +14,9 @@ set status   = 'PASSED',
     duration = 165.0
 where result_id = 1;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (2, 2,'uuid2',  'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '2', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (2, 2, 'uuid2', 'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '2', null, 1);
 insert into test_item_results(result_id, status)
 values (2, 'IN_PROGRESS');
 update test_item_results
@@ -24,8 +27,9 @@ where result_id = 2;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (2, 2, 'automation bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (3, 3,'uuid3',  'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '3', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (3, 3, 'uuid3', 'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '3', null, 1);
 insert into test_item_results(result_id, status)
 values (3, 'IN_PROGRESS');
 update test_item_results
@@ -36,8 +40,9 @@ where result_id = 3;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (3, 3, 'product bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (4, 4,'uuid4',  'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '4', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (4, 4, 'uuid4', 'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '4', null, 1);
 insert into test_item_results(result_id, status)
 values (4, 'IN_PROGRESS');
 update test_item_results
@@ -46,8 +51,9 @@ set status   = 'PASSED',
     duration = 87.0
 where result_id = 4;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (5, 5,'uuid5',  'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '5', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (5, 5, 'uuid5', 'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '5', null, 1);
 insert into test_item_results(result_id, status)
 values (5, 'IN_PROGRESS');
 update test_item_results
@@ -59,8 +65,10 @@ insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore
 values (5, 1, 'to investigate', false, true);
 
 -- Second launch
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
-values (2, 'uuid1', 1, 1, 'empty launch', 'desc', now(), null, 1, now(), 'DEFAULT', 'FAILED', false);
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
+values (2, 'uuid1', 1, 1, 'empty launch', 'desc', now(), null, 1, now(), 'DEFAULT', 'FAILED',
+        false);
 
 -- Filter and widgets
 INSERT INTO public.owned_entity (id, owner, project_id)
@@ -84,9 +92,12 @@ VALUES (1, 1, 'CONTAINS', 'test', 'name', false),
        (2, 2, 'EQUALS', 'mot_exist', 'name', false);
 
 INSERT INTO public.widget (id, name, description, widget_type, items_count, widget_options)
-VALUES (3, 'most time consuming', null, 'mostTimeConsuming', 20, '{"options": {"launchNameFilter": "test launch"}}'),
-       (4, 'most time consuming', null, 'mostTimeConsuming', 20, '{"options": {"launchNameFilter": "empty launch"}}'),
-       (5, 'most time consuming', null, 'mostTimeConsuming', 20, '{"options": {"launchNameFilter": "not exist"}}'),
+VALUES (3, 'most time consuming', null, 'mostTimeConsuming', 20,
+        '{"options": {"launchNameFilter": "test launch"}}'),
+       (4, 'most time consuming', null, 'mostTimeConsuming', 20,
+        '{"options": {"launchNameFilter": "empty launch"}}'),
+       (5, 'most time consuming', null, 'mostTimeConsuming', 20,
+        '{"options": {"launchNameFilter": "not exist"}}'),
        (6, 'most time consuming', null, 'mostTimeConsuming', 20,
         '{"options": {"launchNameFilter": "test launch", "includeMethods": true}}');
 
diff --git a/src/test/resources/db/widget/not-passed.sql b/src/test/resources/db/widget/not-passed.sql
index 7b812928b4..4946da68c5 100644
--- a/src/test/resources/db/widget/not-passed.sql
+++ b/src/test/resources/db/widget/not-passed.sql
@@ -1,8 +1,10 @@
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
 values (1, 'uuid', 1, 1, 'test launch', 'desc', now(), null, 1, now(), 'DEFAULT', 'FAILED', false);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (1, 1,'uuid1',  'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '1', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (1, 1, 'uuid1', 'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '1', null, 1);
 insert into test_item_results(result_id, status)
 values (1, 'IN_PROGRESS');
 update test_item_results
@@ -10,7 +12,8 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 1;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (2, 2, 'uuid2', 'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '2', null, 1);
 insert into test_item_results(result_id, status)
 values (2, 'IN_PROGRESS');
@@ -21,8 +24,9 @@ where result_id = 2;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (2, 2, 'automation bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (3, 3,'uuid3',  'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '3', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (3, 3, 'uuid3', 'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '3', null, 1);
 insert into test_item_results(result_id, status)
 values (3, 'IN_PROGRESS');
 update test_item_results
@@ -32,7 +36,8 @@ where result_id = 3;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (3, 3, 'product bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (4, 4, 'uuid4', 'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '4', null, 1);
 insert into test_item_results(result_id, status)
 values (4, 'IN_PROGRESS');
@@ -41,8 +46,9 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 4;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (5, 5,'uuid5',  'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '5', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (5, 5, 'uuid5', 'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '5', null, 1);
 insert into test_item_results(result_id, status)
 values (5, 'IN_PROGRESS');
 update test_item_results
diff --git a/src/test/resources/db/widget/old-line-chart.sql b/src/test/resources/db/widget/old-line-chart.sql
index 3be685f012..4095bac6ef 100644
--- a/src/test/resources/db/widget/old-line-chart.sql
+++ b/src/test/resources/db/widget/old-line-chart.sql
@@ -1,9 +1,11 @@
 -- First launch
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
 values (1, 'uuid', 1, 1, 'test launch', 'desc', now(), null, 1, now(), 'DEFAULT', 'FAILED', false);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (1, 1, 'uuid1',  'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '1', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (1, 1, 'uuid1', 'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '1', null, 1);
 insert into test_item_results(result_id, status)
 values (1, 'IN_PROGRESS');
 update test_item_results
@@ -11,7 +13,8 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 1;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (2, 2, 'uuid2', 'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '2', null, 1);
 insert into test_item_results(result_id, status)
 values (2, 'IN_PROGRESS');
@@ -22,8 +25,9 @@ where result_id = 2;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (2, 2, 'automation bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (3, 3,'uuid3',  'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '3', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (3, 3, 'uuid3', 'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '3', null, 1);
 insert into test_item_results(result_id, status)
 values (3, 'IN_PROGRESS');
 update test_item_results
@@ -33,7 +37,8 @@ where result_id = 3;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (3, 3, 'product bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (4, 4, 'uuid4', 'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '4', null, 1);
 insert into test_item_results(result_id, status)
 values (4, 'IN_PROGRESS');
@@ -42,8 +47,9 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 4;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (5, 5,'uuid5',  'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '5', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (5, 5, 'uuid5', 'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '5', null, 1);
 insert into test_item_results(result_id, status)
 values (5, 'IN_PROGRESS');
 update test_item_results
diff --git a/src/test/resources/db/widget/overall-statistics.sql b/src/test/resources/db/widget/overall-statistics.sql
index 3efec2045b..16fc8ea1ad 100644
--- a/src/test/resources/db/widget/overall-statistics.sql
+++ b/src/test/resources/db/widget/overall-statistics.sql
@@ -1,8 +1,10 @@
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
 values (1, 'uuid', 1, 1, 'test launch', 'desc', now(), null, 1, now(), 'DEFAULT', 'FAILED', false);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (1, 1,'uuid1',  'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '1', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (1, 1, 'uuid1', 'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '1', null, 1);
 insert into test_item_results(result_id, status)
 values (1, 'IN_PROGRESS');
 update test_item_results
@@ -10,7 +12,8 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 1;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (2, 2, 'uuid2', 'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '2', null, 1);
 insert into test_item_results(result_id, status)
 values (2, 'IN_PROGRESS');
@@ -21,8 +24,9 @@ where result_id = 2;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (2, 2, 'automation bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (3, 3,'uuid3',  'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '3', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (3, 3, 'uuid3', 'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '3', null, 1);
 insert into test_item_results(result_id, status)
 values (3, 'IN_PROGRESS');
 update test_item_results
@@ -32,8 +36,9 @@ where result_id = 3;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (3, 3, 'product bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (4, 4,'uuid4',  'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '4', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (4, 4, 'uuid4', 'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '4', null, 1);
 insert into test_item_results(result_id, status)
 values (4, 'IN_PROGRESS');
 update test_item_results
@@ -41,8 +46,9 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 4;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (5, 5,'uuid5',  'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '5', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (5, 5, 'uuid5', 'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '5', null, 1);
 insert into test_item_results(result_id, status)
 values (5, 'IN_PROGRESS');
 update test_item_results
diff --git a/src/test/resources/db/widget/passing-rate-per-launch.sql b/src/test/resources/db/widget/passing-rate-per-launch.sql
index 6db0eaec2c..d21c0cb9f8 100644
--- a/src/test/resources/db/widget/passing-rate-per-launch.sql
+++ b/src/test/resources/db/widget/passing-rate-per-launch.sql
@@ -1,9 +1,11 @@
 -- First launch
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
 values (1, 'uuid', 1, 1, 'test launch', 'desc', now(), null, 1, now(), 'DEFAULT', 'FAILED', false);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (1, 1, 'uuid1',  'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '1', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (1, 1, 'uuid1', 'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '1', null, 1);
 insert into test_item_results(result_id, status)
 values (1, 'IN_PROGRESS');
 update test_item_results
@@ -11,8 +13,9 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 1;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (2, 2,'uuid2',  'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '2', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (2, 2, 'uuid2', 'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '2', null, 1);
 insert into test_item_results(result_id, status)
 values (2, 'IN_PROGRESS');
 update test_item_results
@@ -22,8 +25,9 @@ where result_id = 2;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (2, 2, 'automation bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (3, 3,'uuid3',  'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '3', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (3, 3, 'uuid3', 'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '3', null, 1);
 insert into test_item_results(result_id, status)
 values (3, 'IN_PROGRESS');
 update test_item_results
@@ -33,8 +37,9 @@ where result_id = 3;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (3, 3, 'product bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (4, 4,'uuid4',  'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '4', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (4, 4, 'uuid4', 'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '4', null, 1);
 insert into test_item_results(result_id, status)
 values (4, 'IN_PROGRESS');
 update test_item_results
@@ -42,8 +47,9 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 4;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (5, 5,'uuid5',  'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '5', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (5, 5, 'uuid5', 'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '5', null, 1);
 insert into test_item_results(result_id, status)
 values (5, 'IN_PROGRESS');
 update test_item_results
@@ -54,10 +60,12 @@ insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore
 values (5, 1, 'to investigate', false, true);
 
 -- Second launch
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
 values (2, 'uuid2', 1, 1, 'test launch', 'desc', now(), null, 2, now(), 'DEFAULT', 'FAILED', false);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (6, 6, 'uuid6', 'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '6', null, 2);
 insert into test_item_results(result_id, status)
 values (6, 'IN_PROGRESS');
@@ -66,8 +74,9 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 6;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (7, 7,'uuid7',  'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '7', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (7, 7, 'uuid7', 'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '7', null, 2);
 insert into test_item_results(result_id, status)
 values (7, 'IN_PROGRESS');
 update test_item_results
@@ -77,8 +86,9 @@ where result_id = 7;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (7, 1, 'unknown bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (8, 8,'uuid8',  'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '8', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (8, 8, 'uuid8', 'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '8', null, 2);
 insert into test_item_results(result_id, status)
 values (8, 'IN_PROGRESS');
 update test_item_results
@@ -88,7 +98,8 @@ where result_id = 8;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (8, 3, 'product bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (9, 9, 'uuid9', 'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '9', null, 2);
 insert into test_item_results(result_id, status)
 values (9, 'IN_PROGRESS');
@@ -97,8 +108,9 @@ set status   = 'SKIPPED',
     end_time = now()
 where result_id = 9;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (10, 10,'uuid10',  'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '10', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (10, 10, 'uuid10', 'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '10', null, 2);
 insert into test_item_results(result_id, status)
 values (10, 'IN_PROGRESS');
 update test_item_results
@@ -109,8 +121,10 @@ insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore
 values (10, 1, 'to investigate', false, true);
 
 -- Third launch
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
-values (3, 'uuid3', 1, 1, 'empty launch', 'desc', now(), null, 2, now(), 'DEFAULT', 'FAILED', false);
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
+values (3, 'uuid3', 1, 1, 'empty launch', 'desc', now(), null, 2, now(), 'DEFAULT', 'FAILED',
+        false);
 
 -- Filter and widget
 INSERT INTO public.owned_entity (id, owner, project_id)
diff --git a/src/test/resources/db/widget/passing-rate-summary.sql b/src/test/resources/db/widget/passing-rate-summary.sql
index bba8808a15..63cb3e8e78 100644
--- a/src/test/resources/db/widget/passing-rate-summary.sql
+++ b/src/test/resources/db/widget/passing-rate-summary.sql
@@ -1,8 +1,10 @@
 -- First launch
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
 values (1, 'uuid', 1, 1, 'test launch', 'desc', now(), null, 1, now(), 'DEFAULT', 'FAILED', false);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (1, 1, 'uuid1', 'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '1', null, 1);
 insert into test_item_results(result_id, status)
 values (1, 'IN_PROGRESS');
@@ -11,8 +13,9 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 1;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (2, 2,'uuid2',  'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '2', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (2, 2, 'uuid2', 'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '2', null, 1);
 insert into test_item_results(result_id, status)
 values (2, 'IN_PROGRESS');
 update test_item_results
@@ -22,8 +25,9 @@ where result_id = 2;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (2, 2, 'automation bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (3, 3,'uuid3',  'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '3', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (3, 3, 'uuid3', 'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '3', null, 1);
 insert into test_item_results(result_id, status)
 values (3, 'IN_PROGRESS');
 update test_item_results
@@ -33,8 +37,9 @@ where result_id = 3;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (3, 3, 'product bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (4, 4,'uuid4',  'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '4', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (4, 4, 'uuid4', 'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '4', null, 1);
 insert into test_item_results(result_id, status)
 values (4, 'IN_PROGRESS');
 update test_item_results
@@ -42,8 +47,9 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 4;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (5, 5, 'uuid5',  'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '5', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (5, 5, 'uuid5', 'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '5', null, 1);
 insert into test_item_results(result_id, status)
 values (5, 'IN_PROGRESS');
 update test_item_results
@@ -54,11 +60,13 @@ insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore
 values (5, 1, 'to investigate', false, true);
 
 -- Second launch
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
 values (2, 'uuid2', 1, 1, 'test launch', 'desc', now(), null, 2, now(), 'DEFAULT', 'FAILED', false);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (6, 6,'uuid6',  'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '6', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (6, 6, 'uuid6', 'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '6', null, 2);
 insert into test_item_results(result_id, status)
 values (6, 'IN_PROGRESS');
 update test_item_results
@@ -66,8 +74,9 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 6;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (7, 7, 'uuid7',  'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '7', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (7, 7, 'uuid7', 'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '7', null, 2);
 insert into test_item_results(result_id, status)
 values (7, 'IN_PROGRESS');
 update test_item_results
@@ -77,7 +86,8 @@ where result_id = 7;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (7, 1, 'unknown bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (8, 8, 'uuid8', 'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '8', null, 2);
 insert into test_item_results(result_id, status)
 values (8, 'IN_PROGRESS');
@@ -88,7 +98,8 @@ where result_id = 8;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (8, 3, 'product bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (9, 9, 'uuid9', 'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '9', null, 2);
 insert into test_item_results(result_id, status)
 values (9, 'IN_PROGRESS');
@@ -97,8 +108,9 @@ set status   = 'SKIPPED',
     end_time = now()
 where result_id = 9;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (10, 10, 'uuid10',  'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '10', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (10, 10, 'uuid10', 'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '10', null, 2);
 insert into test_item_results(result_id, status)
 values (10, 'IN_PROGRESS');
 update test_item_results
diff --git a/src/test/resources/db/widget/product-status.sql b/src/test/resources/db/widget/product-status.sql
index f06b0eff35..e554a5fe8b 100644
--- a/src/test/resources/db/widget/product-status.sql
+++ b/src/test/resources/db/widget/product-status.sql
@@ -1,11 +1,13 @@
 -- First launch
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
 values (1, 'uuid', 1, 1, 'test launch', 'desc', now(), null, 1, now(), 'DEFAULT', 'FAILED', false);
 
 insert into item_attribute(id, key, value, item_id, launch_id, system)
 values (1, 'key', 'val', null, 1, false);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (1, 1, 'uuid1', 'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '1', null, 1);
 insert into test_item_results(result_id, status)
 values (1, 'IN_PROGRESS');
@@ -14,7 +16,8 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 1;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (2, 2, 'uuid2', 'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '2', null, 1);
 insert into test_item_results(result_id, status)
 values (2, 'IN_PROGRESS');
@@ -25,7 +28,8 @@ where result_id = 2;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (2, 2, 'automation bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (3, 3, 'uuid3', 'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '3', null, 1);
 insert into test_item_results(result_id, status)
 values (3, 'IN_PROGRESS');
@@ -36,7 +40,8 @@ where result_id = 3;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (3, 3, 'product bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (4, 4, 'uuid4', 'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '4', null, 1);
 insert into test_item_results(result_id, status)
 values (4, 'IN_PROGRESS');
@@ -45,7 +50,8 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 4;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (5, 5, 'uuid5', 'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '5', null, 1);
 insert into test_item_results(result_id, status)
 values (5, 'IN_PROGRESS');
@@ -57,10 +63,12 @@ insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore
 values (5, 1, 'to investigate', false, true);
 
 -- Second launch
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
 values (2, 'uuid2', 1, 1, 'test launch', 'desc', now(), null, 2, now(), 'DEFAULT', 'FAILED', false);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (6, 6, 'uuid6', 'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '6', null, 2);
 insert into test_item_results(result_id, status)
 values (6, 'IN_PROGRESS');
@@ -69,7 +77,8 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 6;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (7, 7, 'uuid7', 'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '7', null, 2);
 insert into test_item_results(result_id, status)
 values (7, 'IN_PROGRESS');
@@ -80,7 +89,8 @@ where result_id = 7;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (7, 1, 'unknown bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (8, 8, 'uuid8', 'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '8', null, 2);
 insert into test_item_results(result_id, status)
 values (8, 'IN_PROGRESS');
@@ -91,7 +101,8 @@ where result_id = 8;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (8, 3, 'product bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (9, 9, 'uuid9', 'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '9', null, 2);
 insert into test_item_results(result_id, status)
 values (9, 'IN_PROGRESS');
@@ -100,7 +111,8 @@ set status   = 'SKIPPED',
     end_time = now()
 where result_id = 9;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 values (10, 10, 'uuid10', 'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '10', null, 2);
 insert into test_item_results(result_id, status)
 values (10, 'IN_PROGRESS');
@@ -138,8 +150,10 @@ VALUES (1, 1, 'CONTAINS', 'test', 'name', false),
        (3, 1, 'CONTAINS', 'test', 'name', false);
 
 INSERT INTO public.widget (id, name, description, widget_type, items_count, widget_options)
-VALUES (4, 'product status', null, 'productStatus', 10, '{"options": {"strategy": "launch", "customColumns": {"column": "key"}}}'),
-       (5, 'product status', null, 'productStatus', 10, '{"options": {"strategy": "launch", "customColumns": {"column": "key"}}}'),
+VALUES (4, 'product status', null, 'productStatus', 10,
+        '{"options": {"strategy": "launch", "customColumns": {"column": "key"}}}'),
+       (5, 'product status', null, 'productStatus', 10,
+        '{"options": {"strategy": "launch", "customColumns": {"column": "key"}}}'),
        (6, 'cases trend', null, 'casesTrend', 10, '{"options": {}}'),
        (7, 'cases trend', null, 'casesTrend', 10, '{"options": {"timeline":  "notPresent"}}'),
        (8, 'cases trend', null, 'casesTrend', 10, '{"options": {"timeline":  "WEEK"}}');
diff --git a/src/test/resources/db/widget/top-test-cases.sql b/src/test/resources/db/widget/top-test-cases.sql
index 4fec70f950..bdb02b5326 100644
--- a/src/test/resources/db/widget/top-test-cases.sql
+++ b/src/test/resources/db/widget/top-test-cases.sql
@@ -1,9 +1,11 @@
 -- First launch
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
 values (1, 'uuid', 1, 1, 'test launch', 'desc', now(), null, 1, now(), 'DEFAULT', 'FAILED', false);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (1, 1,'uuid1',  'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '1', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (1, 1, 'uuid1', 'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '1', null, 1);
 insert into test_item_results(result_id, status)
 values (1, 'IN_PROGRESS');
 update test_item_results
@@ -11,8 +13,9 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 1;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (2, 2,'uuid2',  'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '2', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (2, 2, 'uuid2', 'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '2', null, 1);
 insert into test_item_results(result_id, status)
 values (2, 'IN_PROGRESS');
 update test_item_results
@@ -22,8 +25,9 @@ where result_id = 2;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (2, 2, 'automation bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (3, 3,'uuid3',  'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '3', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (3, 3, 'uuid3', 'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '3', null, 1);
 insert into test_item_results(result_id, status)
 values (3, 'IN_PROGRESS');
 update test_item_results
@@ -33,8 +37,9 @@ where result_id = 3;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (3, 3, 'product bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (4, 4,'uuid4',  'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '4', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (4, 4, 'uuid4', 'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '4', null, 1);
 insert into test_item_results(result_id, status)
 values (4, 'IN_PROGRESS');
 update test_item_results
@@ -42,8 +47,9 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 4;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (5, 5,'uuid5',  'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '5', null, 1);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (5, 5, 'uuid5', 'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '5', null, 1);
 insert into test_item_results(result_id, status)
 values (5, 'IN_PROGRESS');
 update test_item_results
@@ -54,11 +60,13 @@ insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore
 values (5, 1, 'to investigate', false, true);
 
 -- Second launch
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
 values (2, 'uuid2', 1, 1, 'test launch', 'desc', now(), null, 2, now(), 'DEFAULT', 'FAILED', false);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (6, 6,'uuid6',  'test item 1', 'STEP', now(), 'desc', 'uuid6', now(), '6', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (6, 6, 'uuid6', 'test item 1', 'STEP', now(), 'desc', 'uuid6', now(), '6', null, 2);
 insert into test_item_results(result_id, status)
 values (6, 'IN_PROGRESS');
 update test_item_results
@@ -66,8 +74,9 @@ set status   = 'PASSED',
     end_time = now()
 where result_id = 6;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (7, 7,'uuid7',  'test item 2', 'STEP', now(), 'desc', 'uuid7', now(), '7', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (7, 7, 'uuid7', 'test item 2', 'STEP', now(), 'desc', 'uuid7', now(), '7', null, 2);
 insert into test_item_results(result_id, status)
 values (7, 'IN_PROGRESS');
 update test_item_results
@@ -77,8 +86,9 @@ where result_id = 7;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (7, 1, 'unknown bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (8, 8,'uuid8',  'test item 3', 'STEP', now(), 'desc', 'uuid8', now(), '8', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (8, 8, 'uuid8', 'test item 3', 'STEP', now(), 'desc', 'uuid8', now(), '8', null, 2);
 insert into test_item_results(result_id, status)
 values (8, 'IN_PROGRESS');
 update test_item_results
@@ -88,8 +98,9 @@ where result_id = 8;
 insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 values (8, 3, 'product bug', false, true);
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (9, 9,'uuid9',  'test item 4', 'STEP', now(), 'desc', 'uuid9', now(), '9', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (9, 9, 'uuid9', 'test item 4', 'STEP', now(), 'desc', 'uuid9', now(), '9', null, 2);
 insert into test_item_results(result_id, status)
 values (9, 'IN_PROGRESS');
 update test_item_results
@@ -97,8 +108,9 @@ set status   = 'SKIPPED',
     end_time = now()
 where result_id = 9;
 
-insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
-values (10, 10,'uuid10',  'test item 5', 'STEP', now(), 'desc', 'uuid10', now(), '10', null, 2);
+insert into test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
+values (10, 10, 'uuid10', 'test item 5', 'STEP', now(), 'desc', 'uuid10', now(), '10', null, 2);
 insert into test_item_results(result_id, status)
 values (10, 'IN_PROGRESS');
 update test_item_results
@@ -109,8 +121,10 @@ insert into issue(issue_id, issue_type, issue_description, auto_analyzed, ignore
 values (10, 1, 'to investigate', false, true);
 
 -- Third launch
-insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
-values (3, 'uuid3', 1, 1, 'empty launch', 'desc', now(), null, 2, now(), 'DEFAULT', 'FAILED', false);
+insert into launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
+values (3, 'uuid3', 1, 1, 'empty launch', 'desc', now(), null, 2, now(), 'DEFAULT', 'FAILED',
+        false);
 
 -- Filter and widget
 INSERT INTO public.owned_entity (id, owner, project_id)
@@ -121,10 +135,14 @@ VALUES (1, 'superadmin', 1),
 
 
 INSERT INTO public.widget (id, name, description, widget_type, items_count, widget_options)
-VALUES (1, 'top test cases', null, 'topTestCases', 20, '{"options": {"launchNameFilter": "test launch"}}'),
-       (2, 'top test cases', null, 'topTestCases', 20, '{"options": {"launchNameFilter": "empty launch"}}'),
-       (3, 'top test cases', null, 'topTestCases', 20, '{"options": {"launchNameFilter": "not exist launch"}}'),
-       (4, 'top test cases', null, 'topTestCases', 20, '{"options": {"launchNameFilter": "test launch", "includeMethods": true}}');
+VALUES (1, 'top test cases', null, 'topTestCases', 20,
+        '{"options": {"launchNameFilter": "test launch"}}'),
+       (2, 'top test cases', null, 'topTestCases', 20,
+        '{"options": {"launchNameFilter": "empty launch"}}'),
+       (3, 'top test cases', null, 'topTestCases', 20,
+        '{"options": {"launchNameFilter": "not exist launch"}}'),
+       (4, 'top test cases', null, 'topTestCases', 20,
+        '{"options": {"launchNameFilter": "test launch", "includeMethods": true}}');
 
 insert into content_field(id, field)
 values (1, 'statistics$executions$failed'),
diff --git a/src/test/resources/db/widget/unique-bug-table.sql b/src/test/resources/db/widget/unique-bug-table.sql
index 753761e23a..7b6ae02a77 100644
--- a/src/test/resources/db/widget/unique-bug-table.sql
+++ b/src/test/resources/db/widget/unique-bug-table.sql
@@ -1,8 +1,10 @@
 -- First launch
-INSERT INTO launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
+INSERT INTO launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
 VALUES (1, 'uuid', 1, 1, 'test launch', 'desc', now(), NULL, 1, now(), 'DEFAULT', 'FAILED', FALSE);
 
-INSERT INTO test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+INSERT INTO test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 VALUES (1, 1, 'uuid1', 'test item 1', 'STEP', now(), 'desc', 'uuid1', now(), '1', NULL, 1);
 INSERT INTO test_item_results(result_id, status)
 VALUES (1, 'IN_PROGRESS');
@@ -11,7 +13,8 @@ SET status   = 'PASSED',
     end_time = now()
 WHERE result_id = 1;
 
-INSERT INTO test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+INSERT INTO test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 VALUES (2, 2, 'uuid2', 'test item 2', 'STEP', now(), 'desc', 'uuid2', now(), '2', NULL, 1);
 INSERT INTO test_item_results(result_id, status)
 VALUES (2, 'IN_PROGRESS');
@@ -22,14 +25,16 @@ WHERE result_id = 2;
 INSERT INTO issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 VALUES (2, 2, 'automation bug', FALSE, TRUE);
 INSERT INTO ticket(id, ticket_id, submitter, bts_url, submit_date, url, bts_project)
-VALUES (1, 'ticket1', 'superadmin', 'http:/example.com', now(), 'http:/example.com/ticket1', 'superadmin_bts');
+VALUES (1, 'ticket1', 'superadmin', 'http:/example.com', now(), 'http:/example.com/ticket1',
+        'superadmin_bts');
 INSERT INTO issue_ticket(issue_id, ticket_id)
 VALUES (2, 1);
 INSERT INTO item_attribute(key, value, item_id, launch_id, system)
 VALUES (NULL, 'test', 2, NULL, FALSE),
        (NULL, 'value', 2, NULL, FALSE);
 
-INSERT INTO test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+INSERT INTO test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 VALUES (3, 3, 'uuid3', 'test item 3', 'STEP', now(), 'desc', 'uuid3', now(), '3', NULL, 1);
 INSERT INTO test_item_results(result_id, status)
 VALUES (3, 'IN_PROGRESS');
@@ -40,7 +45,8 @@ WHERE result_id = 3;
 INSERT INTO issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 VALUES (3, 3, 'product bug', FALSE, TRUE);
 
-INSERT INTO test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+INSERT INTO test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 VALUES (4, 4, 'uuid4', 'test item 4', 'STEP', now(), 'desc', 'uuid4', now(), '4', NULL, 1);
 INSERT INTO test_item_results(result_id, status)
 VALUES (4, 'IN_PROGRESS');
@@ -49,7 +55,8 @@ SET status   = 'PASSED',
     end_time = now()
 WHERE result_id = 4;
 
-INSERT INTO test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+INSERT INTO test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 VALUES (5, 5, 'uuid5', 'test item 5', 'STEP', now(), 'desc', 'uuid5', now(), '5', NULL, 1);
 INSERT INTO test_item_results(result_id, status)
 VALUES (5, 'IN_PROGRESS');
@@ -61,10 +68,12 @@ INSERT INTO issue(issue_id, issue_type, issue_description, auto_analyzed, ignore
 VALUES (5, 1, 'to investigate', FALSE, TRUE);
 
 -- Second launch
-INSERT INTO launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number, last_modified, mode, status, has_retries)
+INSERT INTO launch(id, uuid, project_id, user_id, name, description, start_time, end_time, number,
+                   last_modified, mode, status, has_retries)
 VALUES (2, 'uuid2', 1, 1, 'test launch', 'desc', now(), NULL, 2, now(), 'DEFAULT', 'FAILED', FALSE);
 
-INSERT INTO test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+INSERT INTO test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 VALUES (6, 6, 'uuid6', 'test item 1', 'STEP', now(), 'desc', 'uuid6', now(), '6', NULL, 2);
 INSERT INTO test_item_results(result_id, status)
 VALUES (6, 'IN_PROGRESS');
@@ -73,7 +82,8 @@ SET status   = 'PASSED',
     end_time = now()
 WHERE result_id = 6;
 
-INSERT INTO test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+INSERT INTO test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 VALUES (7, 7, 'uuid7', 'test item 2', 'STEP', now(), 'desc', 'uuid7', now(), '7', NULL, 2);
 INSERT INTO test_item_results(result_id, status)
 VALUES (7, 'IN_PROGRESS');
@@ -84,7 +94,8 @@ WHERE result_id = 7;
 INSERT INTO issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 VALUES (7, 1, 'unknown bug', FALSE, TRUE);
 
-INSERT INTO test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+INSERT INTO test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 VALUES (8, 8, 'uuid8', 'test item 3', 'STEP', now(), 'desc', 'uuid8', now(), '8', NULL, 2);
 INSERT INTO test_item_results(result_id, status)
 VALUES (8, 'IN_PROGRESS');
@@ -95,7 +106,8 @@ WHERE result_id = 8;
 INSERT INTO issue(issue_id, issue_type, issue_description, auto_analyzed, ignore_analyzer)
 VALUES (8, 3, 'product bug', FALSE, TRUE);
 
-INSERT INTO test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+INSERT INTO test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 VALUES (9, 9, 'uuid9', 'test item 4', 'STEP', now(), 'desc', 'uuid9', now(), '9', NULL, 2);
 INSERT INTO test_item_results(result_id, status)
 VALUES (9, 'IN_PROGRESS');
@@ -104,7 +116,8 @@ SET status   = 'SKIPPED',
     end_time = now()
 WHERE result_id = 9;
 
-INSERT INTO test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id, last_modified, path, parent_id, launch_id)
+INSERT INTO test_item(test_case_hash, item_id, uuid, name, type, start_time, description, unique_id,
+                      last_modified, path, parent_id, launch_id)
 VALUES (10, 10, 'uuid10', 'test item 5', 'STEP', now(), 'desc', 'uuid10', now(), '10', NULL, 2);
 INSERT INTO test_item_results(result_id, status)
 VALUES (10, 'IN_PROGRESS');
diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml
index e3f22441eb..3065ff9ea5 100644
--- a/src/test/resources/logback-test.xml
+++ b/src/test/resources/logback-test.xml
@@ -1,16 +1,18 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <configuration>
-    <include resource="org/springframework/boot/logging/logback/base.xml"/>
-    <logger name="org.springframework" level="ERROR"/>
-    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
-        <encoder>
-            <pattern>%d{dd-MM-yyyy HH:mm:ss.SSS} %magenta([%thread]) %highlight(%-5level) %logger{36}.%M - %msg%n</pattern>
-        </encoder>
-    </appender>
+  <include resource="org/springframework/boot/logging/logback/base.xml"/>
+  <logger name="org.springframework" level="ERROR"/>
+  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+    <encoder>
+      <pattern>%d{dd-MM-yyyy HH:mm:ss.SSS} %magenta([%thread]) %highlight(%-5level) %logger{36}.%M -
+        %msg%n
+      </pattern>
+    </encoder>
+  </appender>
 
-    <logger name="org.springframework.security" level="info"/>
+  <logger name="org.springframework.security" level="info"/>
 
-    <root level="info">
-        <appender-ref ref="STDOUT"/>
-    </root>
+  <root level="info">
+    <appender-ref ref="STDOUT"/>
+  </root>
 </configuration>
\ No newline at end of file

From 6f65e2d58ff7b78a31e84ea1763de978845d9ac2 Mon Sep 17 00:00:00 2001
From: Pavel Bortnik <pavel_bortnik@epam.com>
Date: Fri, 1 Mar 2024 11:54:56 +0300
Subject: [PATCH 15/25] 5.11.0 || Update gradle wrapper jar

---
 gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 63721 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)

diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..7f93135c49b765f8051ef9d0a6055ff8e46073d8 100644
GIT binary patch
literal 63721
zcmb5Wb9gP!wgnp7wrv|bwr$&XvSZt}Z6`anZSUAlc9NHKf9JdJ;NJVr`=eI(_pMp0
zy1VAAG3FfAOI`{X1O)&90s;U4K;XLp008~hCjbEC_fbYfS%6kTR+JtXK>nW$ZR+`W
ze|#J8f4A@M|F5BpfUJb5h>|j$jOe}0<b<>oE!`Zf6fM>C<V>R?!y@zU(cL8NsKk`a
z6tx5mAk<liamrzlCS@BsX~|&`RS-HU8cGq`t>djD;J=LcJ;;Aw8p!v#ouk>mUDZF@
zK>yvw%+bKu+T{N<MgC_~H%9||dlSch>k@LZ;zkYy0HBKw06_IWcM<!q!PNfx0T}}e
zTRJ0a11G0!b#QO&CEQP4n)k!|A)#qSG|8;N24)yY|3OH|n9Ef#Qn-}F#h?W3i%43c
z)2szbS#t|1^laxjK<9Y@_Ix3>Ho*0HKpTsEFZhn<oTMi&w}vW*Ra?K_!_)1rk7w^0
zcz%y-9{{$<M=0I0eaFor!J){*JHz%a;XWx9WpR5@-ICoSDBGt4RNpQ|Al>5qCHH9j
z)|XpN&{`!0a>Vl+PmdQc)Yg4A(AG-z!+@Q#eHr&g<9D?7E)_aEB?s_rx>UE9TUq|?
z;(ggJt>9l?C|zoO@5)tu?<y?2z)*Z;1quxvz;2Wr$0J)*8MlO}_`_m{D`H0p@e^(M
z$iAC}1xU~1A4L(ddtDLl_Pr6{Hx8(|zsON}%665gG;b|X+4q@!y;YHT4o3!{_{jPB
z>EV0x_7T17q4fF-q3{yZ^ipUbKcRZ4Qftd!xO(#UGhb2y>?*@{xq%`(-`2T^vc=#<
zx!+@4pRdk&*1ht2OWk^Z5IAQ0YTAXLkL{(D*$gENaD)7A%^XXrCchN&<gtMWk{spc
zdf)IQ%Esm7d(=p(gnM#+I?kJb&Lb5@<u)2i>z2x+*>o2FwPFjWpeaL=!tzv#JOW#(
z$B)Nel<+$bkH1KZv3&-}=SiG~w2sbDbAWarg%5>YbC|}*d9hBjBkR(@tyM0T)FO$#
zPtRXukGPnOd)~z=?avu+4Co@wF}1T)-uh5jI<1$HLtyDrVak{gw`mcH@Q-@wg{v^c
zRzu}hMKFHV<8w}o*yg6p@Sq%=gkd~;`_VGTS?L@yVu`xuGy+dH6YOwcP6ZE`_0rK%
zAx5!FjDuss`FQ3eF|mhrWkjux(Pny^k$u_)dyCSEbAsecHsq#8B3n3kDU(zW5yE|(
zgc>sFQywFj5}U*qtF9Y(bi*;>B7WJykcAXF86@)z|0-Vm<fczTCmKxlM?(K(U1MI{
zH7CsNY39I?b2iW&6QmO%p`j~N;r{IyO6k!4?8&O+JtB37&qWiLadcH|I)VEU4X_&G
z2Ff&+i<CegULNGA;Rqo82kZIenL`+2Sql2b=gdn7-sCd|*$dW%v3%JHM_jz-$G*h(
z2Zhp66mL0wC-)~7Dg~G4tT5AYOjgU1YJq|3QV~+nZV4#kZI8ONh{_OOoJD(-6)TQN
zW~`V4m}~|uOv@KO-ydJ-Zh&N$+FY<g0*jjHHbxmR>@jt!EPoLA6>r)?@DIobIZ5Sx
zsc@OC{b|3%vaMbyeM|O^UxEYlEMHK4r)V-{r)_yz`w1*xV0|lh-LQOP`OP`Pk1aW(
z8DSlG<ofVg|3LaJ-=P0V))`RIkE+lq+qJ{`jPVl(|5Va1SGyg3MTkZ3a5}sBX&c*A
ztSA~lX)HnZl`w$}6pc6PwMwbP#y;;c$+yzscOU^s%U^DuE7fk%u_oE_r4U9DlvWzf
zB&zu$+)hR%%$d2sDve|n{X>N>Ts|n*xj+%If~+E_B<wY#42?CSY)Lp9f}%hd8G2BV
zYz5{>xK)~5T#w6Q1WEKt{!Xtbd`J;`2a>8boRo;7u2M&iOop4qcy<)z023=oghSFV
zST;?S;ye+dRQe>ygiJ6HCv4;~3DHtJ({fWeE~$H@mKn@Oh6Z(_sO>01JwH5oA4nvK
zr5<Xf@p4l8GDDqq9Ca=)oYjzaL8(efxR9(LX_X`~m?l6@BVW;!8T+Uyif6_AH70S3
z1&@6Mj!ceBBfVQ`!9u3Zf{wVpf0C(t(aC=1R{{IVv+00AMAS(+n-xbkL&B4F#nFqZ
ztPDBX@p?jtnq^cL=+U%~e$BEw+yxI)sZyO4JhtoSg*p=}x1?BGLbn0LMY>Sr^g+LC
zLt(i&ecdmqsIJGNOSUyUpglvhhrY8lGkzO=0USEKNL%8zHshS>Qziu|`eyWP^5xL4
zRP122_dCJl>hZc~?58w~><cp^hJ_ZV5fj>`P_s18VoU|7(|Eit0-lZRgLTZKNq5{k
zE?V=`7=R&ro(X%LTS*f+#H-mGo_j3dm@F_krAYegDLk6UV{`UKE;{<k$0*s;%bL~F
z;<2lwblZB7HV^gmjYfnL$(oz3yiwuVBNdItsJS*edKT4)myLcW$QJUM;r94>YSsn$
z(yz{v1@p|p!0>g04!eRSrSVb>MQYPr8_MA|MpoGzqyd*$@4j|)cD_%^Hrd>SorF>@
zBX+V<@vEB5PRLGR(uP9&U&5=(HVc?6B58NJT_igiAH*q~Wb`dDZpJSKfy5#Aag4IX
zj~uv74EQ_Q_1qaXWI!7Vf@ZrdUhZFE;L&P_Xr8l@GMkhc#=plV0+g(ki>+7fO%?Jb
zl+b<?C%WXJNEX{LzvH<usRTrr8A!~O>Ty7q{w^pTb{>(Xf2q1BVdq?#f=!geqssXp
z4pMu*q;iiHmA*IjOj4`4S&|8@gSw*^{|PT}Aw~}ZXU`6=vZ<Hcy3%$%v9V&0Kee&a
zKV!#7+J;9|6x<uodo*>B=GGeMm}V6W46|pU&58~P+?LUs%n@J}CSrICkeng6YJ^M?
zS(W?K4nOtoBe4tvBXs@@`i<!ZAMR~@rqD5uMjjRS2DHf>?4G$S2W&;$z8VBSM;Mn9
zxcaEiQ9=v<fz_-ouh|d?S}QqE(0qsl4bj8_Oo|Bt%%h=cX$JXg7?LJ&<ET0ro2;%t
z1-1gS%DOru2m?YDj1D3wKn1f3YvfFowv0`#z<)Q7Eu0mY1aD;Bp(<0D*dvtLJmX0i
zAI;vT=wP6!8*)iKc4+k{>S|bIJ>*tf9AH~m&U%2+Dim<)E=<ebn)#5-YItTnbgMqQ
zt=Y>}KORp+cZ^!@wI`h1NVBXu{@%hB2Cq(dXx_aQ9x3mr*fwL5!ZryQqi|KFJuzvP
zK1)nrKZ7U+B{1ZmJub?4)Ln^J6k!i0t~VO#=q1{?T)%OV?MN}k5M{}vjyZu#M0_*u
z8jwZKJ#Df~1jcLXZL7bnCEhB6IzQZ-GcoQJ!16I*39iazoVGugcKA{lhiHg4Ta2fD
zk1Utyc<n(<e1-Rj>5%QzZ$s3;p0N+N8VX{sd!~l*Ta3|t>lhI&G`sr6L~G5Lul`>m
z{!^INm?J|&7X=;{XveF!(b*=?9NAp4y&r&N3(GKcW4rS(Ejk|Lzs1PrxPI_owB-`H
zg3(Rruh^&)`TKA6+_!n>RdI6pw>Vt1_j&+bKIaMTYLiqhZ#y_=J8`TK{Jd<7l9&sY
z^^`hmi7^14s16B6)1O;vJWOF$=$B5ONW;;2&|pUvJlmeUS&F;DbSHCrEb0QBDR|my
zIs+pE0Y^`q<Mo02TIpLU)qh7WQ?@rM6U&!Z;VW(ggXdTSsIrFphI+dpATgu%)3IHs
z@+Xj*BwLyZ=r@R=;kqR6lCAdnF<CWp%t6J7J#JoVQ!Q2LM-rk#T_J^oRW%%3=2#t<
zlx+Py@hbE`=>JTyH-_mP=)Y+u^LHcuZhsM3+P||?+W#V!_6E-8boP#R-*na4!o-Q1
zVthtYhK{mDhF(&7Okzo9dTi03X(AE{8cH$JIg%MEQc<ZbLh@dc$w|qk{r@1?l>a`S
zy@8{Fjft~~BdzWC(di#X{ny;!yYGK9b@=b|zcKZ{vv4D8i+`ilOPl;PJl{!&5-0!w
z<G-5=7&<vS8W=eX+1c0_*cwY)*qR90*}8t;u!-Ye>^fOl#|}vVg%=n)@_e1BrP)`A
zKPgs`O0EO}Y2KWLuo`iGaKu1k#YR6BMySxQf2V++Wo{6EH<oD|H%>mK>A~Q5o73yM
z-RbxC7Qdh0Cz!nG+7BRZE>~FLI-?&W_rJUl-8FDIaXoNBL)@1hwKa^wOr1($*5h~T
zF;%f^%<$p8Y_yu(JEg=c_O!aZ#)Gjh$n(hfJAp$C2he555W5zdrBqjFmo|VY+el;o
z=*D_w|GXG|p0**hQ7~9-n|y5k%B}TAF0iarDM!q-jYbR^us(>&y;n^2l0C%@2B}KM
zyeRT9)oMt97Agvc4sEKUEy%M<cvw&A<E0smes0HD4KT3M{WaOQQ;89w>pXr2vz*lb
zh*L}}iG>-pqDRw7ud{=FvTD?}<cu3Tk)KD+t)3BG<`{7$)a-(xssJsd76$3kXZ|K+
zux7WJ7n@%B)`GvtXt2vB^wx3Cq%hbMjsz#YIUp6%4@(wA$XOe1;039$$Hc7QvIpbU
zLS8D9A2JK!>xjD)w{`KzjNom-$jS^;iw0+7n<H%EYFc(Oy%QoCT$qyKODp6T3?dHk
z!A)db&e@dFRGDaEZ1f6Uhkq#S5W3t3q@<p|gafXRD$(FZPe|Di#nme60l3B9fVDQI
z7v|md<AFmDM_>XSnt1R@G|VqoRh<xeTuMLt3A;kkH;cO*#r^ytgz}n?7coM19}rK`
z);^|be>E%12<OWj>nm+PH?9`(4rM0kfrZzIK9JU=^$YNyLvAIoxl#Q)xxDz!^0@zZ
zSCs$nfcxK_vRYM34O<1}Q<iD$7sC+}q<B7R-C|JDpp;azgo0#wbVy`Lz$zBEbO-~2
z>HZ|hp4`ioX3x8(UV(FU$J@o%tw3t4k1QPmlEpZa2IujG&(roX_q*%e`Hq|);0;@k
z0z=fZiFckp#JzW0p+2A+D$PC~IsakhJJkG(c;CqAgFfU0Z`u$PzG~-9I1oPHrC<wq
zp!=`znU^{;qwI4(IwPTBbeO&*i}Y=rKz<}0qd2sSuD;n+Mp~oxu2u^U_@*f$2SH4&
zl?ba0Bgc;6q%NBUleYBwY{7zE^Vfp-*+^4E--SmUnP*kpPGgQ7i#F(|?Htpi_BGIr
zb@Gxu5=<~CQJoX};=}ZoAqI?aQ`aURT7|_bL85cc5*32Ec(l3BkkWJ!;u(fz)0rjQ
zM$>w&)@s^Dc~^)#<wKTL<XKhL5mN0<#J&V|X6YXFoTAHh1v3e?`1qzOHJxAfrJ&Ia
z>HPW0Ra}J^=|h7Fs*<8|b13ZzG6MP*Q1dkoZ6&A^!}|hbjM{2HpqlSXv_UUg1U4gn
z3Q)2VjU^ti1myod<e*tXJ``;<uRxWgHj9DL9reuUk;3Yai3$ZVxc$Lik!QkFkY_p-
zQ0zfew$syu%`J??OaA$e3yhROoyi??MOs)*6Y|FoRjo5YG8>v+tjhSZp%D978m~p&
z43uZUrraHs80Mq&vcetqfQpQP?m!CFj)44t8Z}k`E798wxg&~aCm+DBoI+nKq}&j^
zlPY3W$)K;KtEajks1`G?-@me7C>{PiiBu+41#yU_c(dITaqE?IQ(DBu+c^Ux!>pCj
zLC|HJGU*v+!it1(;3e`6igkH(VA)-S+k(*yqxM<DMa${DuB@U~n2TvsN>gUah3$@C
zz`7hEM47xr>j8^g`%*f=6S5n>z%Bt_Fg{Tvmr+MIsCx=0gsu_sF`q2hlkEmisz#Fy
zj_0;zUWr;Gz}$BS%Y`meb(=$d%@Crs(<S5im8rZJ+hXaeF4?)$Bxlh$wotZoqo;9C
zoV$lbzz-{=kDm#H-UEvsDLF6Q650PW_m^)`Fnl2k7$|cT<4p%DP+QQ%Pm<dng5Tlm
zJY!}F9=K|jqEaN6rLUGWH!wZ0U(TSP7a_ulN!0{(D76G_DCCMYc~&1UiwGoGVvr{o
zKJ*3=vWF1EmCF?ngO(A#QHO73AHw39x4#7x|2*uRJP=H^WAL{ITtOufKQPefaR-dw
z;G$VL`0sIgw-zB%E@}zvSQFs9-~l@jy~i@_j=aHRkdEWSDI;LT_XD0ffYvUye7<si
z2Fb>OoJ|}m#<7=-A~PQbyN$x%2iXP2@e*nO0b7AwfH8cCUa*Wfu@b)D_>I*%uE4O3
z(lfnB`-Xf<Eah_TH0`p#iJ%bwIruYbtv4=i&#2ev1%ADQ5<nqfk9TiY>*L<pJwX*6
z6rk6>fC)E}e?%X2kK7DItK6Tf<+M^mX0Ijf_!IP>7c8IZX%8_#0060P{QMuV^B<Nc
z0Y@_z8xvb+5qBdKduI!~zgMP`<EJEn8Bv1e-k1xUTQqH`&-$;LRKPb?p@^XRcl%SW
z7A(?4O_9bX%W97*cKg9^@&`$1Rhl479TL49uifNE-$%}|e=@U3QRq(u*`T|i!vY;=
zLFYU{oP~b!`V{F3i<~?v4T-GsVj-c>9i<^E`_Qf0pv9(P%_<ZnXV3#<!Itln<wgcO
z_ag@&>s8D`qvDE9LK9u-jB}J2S`(mCO&XHTS04Z5Ez*vl^T%!^$<HtTbQGA?-M`Fa
zN~3r+{;f4I^wTt)Y$;V0A?b}t39$3`u-!SmQRz2~BgR0Y22AtoiqyTce$gRQ#;)xn
z(H=h1rzHb3B0D>~EH8M-UdwhegL>3IQ*)(MtuH2Xt1p!fS4o~*rR?WLxlA!sjc2(O
znjJn~wQ!Fp9s2e^IWP1C<4%sFF}T4omr}7+4asciyo3DntTgWIzhQpQirM$9{EbQd
z3jz9vS@{<x6RjX4HShz$XJL7Gv9^MIhKL19l!vXDKtut8g2a8N<h+4&Yt&WgZG-0p
z_>aOqTQHI|l#aUV@2Q^Wko4T0T04Me4!2nsdrA8QY1%fnAYb~d2GDz@lAtfcHq(P7
zaMBAGo}+NcE-K*@9y;Vt3*(aCaMKXBB*BJcD_Qnx<UAAx@pFpd`WS-_yK7SJSHbCM
zJ+sycj{FkEU&9Ysa-wV2!;2(ImdDdIZgJ}`9j;jTiYPXEDq*CO`T4-t*|XS#9~HNC
zu96BV=Ry2qi)VUChoa}C_CB44h;*&oc0EWPU$hYH8{zPphs-sTrb;$I`Tk25Ef6wI
z)-7g@DMK6f){DP<6&$RnaJ4vp86eii6XT#?kKzCG^Hnm1S^@(5e!g%30A&B?^OgGt
zSI<_}azj?Z*h(zPW=Yo#YqH4KJ|wab#BOfNtKQV48`7O!MvH)0FqQ@{NoPp6N4$3X
z1K#yg(se^X=dYqMag+$(^NRillP<Mw#+WO8vuGkT>pt75r?GeAQ}*|>pYJE=uZb73
zC>sv)18)q#EGrTG6io*}JLuB_jP3AU1Uiu$D7r|2<a!(dEKJOdD7OJ~`mJ#&3lVWo
z2(|vK+K6Dp{tAw<@IDkF-OU~{Fey=i5LyAY`xe{ZP)J-QHDxPH%5%%ni&>_zlIGb9
zjhst#ni)Y`$)!fc#reM*$~iaYoz~_Cy7J3ZTiPm)E?%`fbk`3Tu-F#`{i!l5pNEn5
zO-Tw-=TojYhzT{J=?SZj=Z8#|eoF>434b-DXiU<dJw*iNTYgDXXO3%H4$mrD2+2if
zR#sZlF&7^<X^ey&*l`pd(b870Yl;d^q~$DJ4j>si<i1L1H7=S6VPERSA>gnxXNaR3
zm_}4iWU$gt2Mw5NvZ5(Vp<B5%4ml4%u2XX{cb%`vs{9^lq|NV~2Us}ADnGUgJZqX-
zvwS;i%5bY0rx<UeBWyPSiTAfxZ8Te<Y^2=Q6Uyjb@`B9@uPO^RqSGRQ8L=vx?~S*{
zt!O7dY09tk+Q(K@^7dsqbRFj3D?R)D=uSPhZfFr)&^PL7B^!(GLR_d(Kw!yNd&IP$
znV)B>F`?X*f2UZDs1TEa1oZCif?Jdgr{>O~7}-$|BZ7I(IKW`{f;@|IZFX*R8&iT=
zoWstN8&R;}@2Ka%d3vrLtR|O??ben;k8QbS-WB0VgiCz;<$pBmIZdN!aalyCS<xwK
zC7(yN8jDThv(|6XTqj5k)nXJHl?i2Q&>Em)crpS9dcD^Y@XT1a3+zpi-`D}e#HV<}
z$Y(G&o~PvL-xSVD5D?JqF3?B9rxGWeb=oEGJ3vRp5xfBPlngh1O$yI95EL+T8{GC@
z98i1H9KhZGFl|;`)_=QpM6H?eDPpw~^(aFQWwyXZ8_EEE4#@QeT_URray*mEOGsGc
z6|sdXtq!hVZo=d#+9^@lm&L5|q&-GDCyUx#YQiccq;spOBe3V+VKdjJA=IL=Zn%P}
zNk=_8u}VhzFf{UYZV0`lUwcD&)9AFx0@Fc6LD9A6Rd1=ga>Mi0)_QxM2ddCVRmZ0d
z+J=uXc(?5JLX3=)e)Jm$HS2yF`44IKhwRnm2*669_J=<i2xqPYPe_t`z^~U4bI&mS
zeK8h(VJQzW*&0F;1J5rkP14OFRVV|<ULvN%7sx(;Rti9xZLhau-~!P2{WfUAn2q*`
zd|=*_Vb!;8;KGMfl41$VF7fE>2LlwuF5$1tAo@ROSU@-y+;Foy2IEl2^V1N;fk~YR
z?&EP8#t&m0B=?aJeuz~lH<ij*LuuHi5!4Rd8ZU2wg>jAzRBX>&x=A;gIvb>MD{XEV
zV%l-+9N-)i;YH%nKP?>f`=?#`>B(`*t`aiPLoQM(a6(qs4p5KFjDBN?8JGrf3z8>=
zi7sD)c)Nm~x{e<^jy4nTx${P~cwz_*a>%0_;ULou<DyN^`2@H+<{3q_pZ|fCRGf^h
zvtT4FGJj|vS-l9;nX`=;6AMdLY77qfRlAH(xzJbez);$Wc|j0JS86%Riccga7l&Q^
z7DDh5jhBvJ0eBnJZoBnclA)#bn$D1A`JT3aY&tu3wlfU}!It+X%B_(|pGP1-6at%6
z9G;Q{hFp?BH`-HYKrn-(5-7%bIR8)}bl%^bc}8y}>3kHCAD7EYkw@l$8TN#LO9jC(
z1B<i{*|v`>eFW`k+bu5e8Ns^a8dPcjEVHM;r6UX+cN=Uy7HU)j-myRU0wHd$<r<rS
z?gfFH3ULExuxO;h09`>A1fNI~`4;I~`zC)3ul#8#^rXVSO*m}Ag>c%_;nj=Nv$rCZ
z*~L@C@OZg%Q^m)lc-kcX&a*a5`y&DaRxh6O*dfhLfF+fU5wKs(1v*!TkZidw*)YBP
za@r`3+^IHRFeO%!ai%rxy;R;;V^Fr=OJlpBX;(b*3+SIw<j-Y9ZSgmH9DO&6{}V;z
z4IG_J97!1eDmMg22|)ETAc%aKH#bAM9(9CS1?uKgKtu$Phh55R&4VPI?P<FMz>}7=
zIq$*Thr(Zft-RlY)D3e8V;BmD&HOfX+E$H#Y@B3?UL5L~_fA-@*IB-!gItK7PIgG9
zgWuGZK_nuZjHVT_Fv(XxtU%)58;W39vzTI2n&)&4Dmq7&JX6G>XFaAR{7_3QB6zsT
z?$L8c*WdN~nZGiscY%5KljQARN;`w$gho=p006z;n(qIQ*Zu<``TMO3n0{ARL@gYh
zoRwS*|Niw~cR!?hE{m*y@F`1)vx-JRfqET=dJ5_(076st(=lFfjtKHoYg`k3oNmo_
zNbQEw8&sO5jAYmkD|Zaz_yUb0rC})U<yhPFxA*<jTKd}k{c~z90FpaZKIj}7mLZZR
zVlskQe<0xI9>!rCHOl}JhbYIDLzLvrZVw0~JO`d*6f;X&?V=#T@ND*cv^I;`sFeq4
z##H5;gpZTb^0Hz@3C*~u0AqqNZ-r%rN3KD~%Gw`0XsIq$(^MEb<~H(2*5G^<2(*aI
z%7}WB+TRlMIrEK<z8Y-G_4JTi0dxbex2YwD(&eIklPGFZaWLB&GD=ZnUD^~B#;k{<
zjP^KiL#JbSns`pE$?*&<=bFPwu*}^i6&=HjW3#5UHflvIkmn+HmO8$)V)qRxk*3l@
zOO9ib60_+Zpll9hiP2eYZBRUKjvXd)MdN}}smA0!UK^qy;<^pk_jf6elpJ`B)>#s0
z93xn*Ohb=kWFc)BNHG4I(~RPn-R8#0lqyBBz5OM6o5|>x9LK@%HaM}}Y5goCQRt2C
z{j*2TtT4ne!Z}vh89mjwiSXG=%DURar~=kGNNaO_+Nkb+tRi~Rkf!7a$*QlavziD(
z83s4GmQ^Wf*0Bd04f#0H<rzc{Zw2|AZqo(GiNDwicoG{misd0-Mku7fEh(b%bV@{&
zro_rCgoAMr<vEX067x&DjEdA&lB?SNTC@l2#eL4j&Fx~(S<U2Qj$}%g_p>X@ua_d8
z23~z*53ePD6@xwZ(vdl0DLc=>cPIOPOdca&MyR^jhhKrdQO?_jJh`xV3GKz&2lvP8
zEOwW6L*ufvK;TN{=S&R@pzV^U=Q<n5LbrjaQ=f5@7_~`mTQ9mj1lTX|puGXCkhc-%
zDqQ!ov(P;Fh`r;zNT#tw6ShQ_Wb=wsd)-t85jQ<PT~cSb(KG~zb^;j9%nmc1=u1J=
znM6vCx;p+afnlGOK^Z(FtJX%b2Laq9%EC)v3-}QHS=dL;;3Z|eP=v~{8Igl4x<in+
zs+~^lyBk3)zB{QIT=g<UC4Dvc@uY$A(I$Qm(r%M)rb;eRGv~cUyVvsbhIKxiBZOdE
z&4GjvPs^czPS?~yx=kmokn<?z^Iu|gjSZTs;5%U;1OKb!`@bg*{}`ix5nQLgVzWB=
zOBPuGVWiiKw%d`msf^&W1_DTJ7XVcxDttFKPMJj@Q@p^`V#d*Pi+Mxn7SS91D^8en
zZty#+i)vgc%xXIPl}6Ud+}N0#zLvf5`S$Ta{!?R<CC_N_2bR$mN%T1dmbl^kFBBTw
z1ujzzCe&Kp;{r{`peY9BJL9Pe30)VP%6+b7BRXtX7mFD)e?pfD#2CL!17n(PpRUO`
z?Yjz)8OniiQ=hFAxt9*96eH5w{w=1|n0X<i`5k*Km^JQNZ!JF0bM74Zvj&6~ZAXtn
zgG9^ASe$T762j2Jcgl0`Y(Mo@H6OZ<lK6bTs)vl;gOmx8Db2@XVoT@)D;P*RE2{Pu
zkq|sNVFWHy%(o0jW-8h@<pE7_$58cKk*4~kS1*H4Ot~s|!`6&RJxm(c3R*s0mV_8;
zn2FG~1NRH*S@8AcCakja5ctO6KJ`a7lcApLvK|cc`*cNA(|7?@ShdEJko*Iz0dJa*
za(Cjc=YoMHSiGhp!^zXOoFUjrW@)@~Kuoe2$0wLZF+12d?*qAHgQiPS_>Nk^Ec}5H
z+2~JvEVA{`uMAr)?Kf|aW>33`)UL@bnfIUQc~L;TsTQ6>r-<^rB8uoNOJ>HWgqMI8
zSW}pZmp_;z_2O5_RD|fGyTxaxk53Hg_3Khc<8AUzV|ZeK{fp|Ne933=1&_^Dbv5^u
zB9n=*)k*tjHDRJ@$bp9mrh}qFn*s}npMl5BMDC%Hs0M0g-hW~P*3CNG06G!MOPEQ_
zi}Qs-6M8aMt;sL$vlmVBR^+Ry<64jrm1EI1%#j?c?4b*7>)a{aDw#TfTYKq+SjEFA
z(aJ&z_0?0JB83D-i3Vh+o|XV4UP+YJ$9Boid2^M2en@APw&wx7vU~t$r2V`F|7Qfo
z>WKgI@eNBZ-+Og<{u2ZiG%>YvH2L3fNpV9J;WLJoBZda)01Rn;o@){01{7E#ke(7U
zHK>S#qZ(N=aoae*4X!0A{)nu0R_sKpi1{)u>GVjC+b5Jyl6#AoQ-1_3UDovNSo`T>
z?c-@7XX*2GMy?k?{g)7?Sv;SJkmxYPJPs!&QqB12ejq`Lee^-cDveVWL^CTUldb(G
zjDGe(O4P=S{4fF=#~oAu>LG>wrU^z<Zw*_46AZG)LPZf(N{7;dl4f;=ChNJ&((0HR
z>_?3yt24FOx>}{^lCGh8?vtvY$^hbZ)9I0E3r3NOlb9I?F-Yc=r$*~l`4N^xzlV~N
zl~#oc>U)Yjl0BxV>O*Kr@lKT{Z09OXt2GlvE38nfs+DD7exl|&vT;)>VFXJVZp9Np
zDK}aO;R3~ag$X*|hRVY3OPax|PG`@_ESc8E!mHRByJbZQR<iP3ONA)u3T^sr$hJu)
z!;4BKQQ3Ke*v_=`LpX`s9^P!rY`x6m`OB{xdu)~9l-PrYu_eSHL`$3Jn77r}HXM<V
zt(63|ZNf?J_G2$D@(>S38V2F__7MW~sgh!a>98Q2%lUNFO=^x<M$kfz5r<ep4<gy2
zqj#v58_1DTD9KgRF!$T?T|hpgQFqS{y9=z}$c192Is9kheW211%6d$Lv95L2Dj6<Y
zb#^>U52|?D=IK#QjwBky-C>zO<IBf}7iok}7&M@d#5zo!yo-N`Xt*z8pz#W=a}edt
zZG-pIp+-`FRdYN5kGiz~5pI5v{UL@+ll7;0f%sl_#Rz#s#c=hclIZch%vfdNL6kTn
zr*OojJocIA;LUP<Ni!nCp8^IKsKOF;%d~A3Zec1Z)onv06oLt;&zK*gg)?kMAG~wt
z$?%9ZDd#C*i@r2pEnc3pbg`;ZSgHhk8hnJ=MZQDKa})LR^M<VYo_<&7>WlsiiM&1n
z;!&1((Xn1$9K}xabq~222gYvx3hnZPg}VMF_GV~5ocE=-v>V=T&RsLBo&`)DOyIj*
zLV{h)JU_y*7SdRtDajP_Y+rBkNN*1_TXiKwHH2&p51d(#zv~s#HwbNy?<+(=9WBvo
zw2hkk2Dj%kTFhY+$T+W-b7@qD!bkfN#Z2ng@Pd=i3-i?xYfs5Z*1hO?kd7Sp^9`;Y
zM2jeGg<-nJD1er@Pc_cSY7wo5dzQX44=%6rn}P_SRbpzsA{6B+!$3B0#;}qwO37G^
zL(V_5JK`XT?OH<!?|M@&0-Z{-IE8Y%j&9{KOrqhAFsdE>Vk|{_$vQ|oNEpab*BO4F
zUTNQ7RUhnRsU`TK#~`)$icsvKh~(pl=3p6m98@k3P#~upd=k*u20SNcb{l^<aLnRI
zIQFl^{&&$2$-fmuufLTX(f?#w5i)Qxk+5|#v30U=ws193a(1+^HT!10f0I0&?f$MZ
z7Axt<A%ClkjrclcTIHY>1rUa)>qO997)pYRWMncC8A&&MHlbW?7i^7M`+B$hH~Y|J
zd>FYOGQ;j>Zc2e7R{KK7)0>>nn_jYJy&o@sK!4G>-rLKM8Hv)f;hi1D2fAc$+six2
zyVZ@wZ6x|fJ!4KrpCJY=!Mq0;)X)OoS~{<zp2fNOj3=!d#J-DZOZZGDsQytEg`t+g
z3s*%5CrGI0LC#hm)1QTr3)Q~mP=>Lkh6u8J<B0%4?J^Iw+=WHCe(yhjohQDag#Q-y
zuxp6&sgx+NVPxq!=P=H(FOhwRd2_*m=|$Mcn3vF&f(Fz>`eK%u0WtKh6B>GW_)PVc
zl}-k`p09qwGtZ@VbYJC!>29V?Dr>>vk?)o(x?!z*9DJ||9qG-&G~#kXxbw{KKYy}J
zQKa-dPt<oy^t}rwUk4E{A=4M9sOFfr7Ds9yI!q0r@t|+qU_|sPwWo~)0N*{XeSJ2j
zt||$@K&w$2s%KuI4R}Av!VN4FKqSw8V4~H!Grt8-#>~M~E}V?PhW0R26xdA%<ogsP
zN|DDB6`HT`^}UE=1A}Thaak~Emv(0YF@z$Cl+aE_pyty?6u<ojo%}e0uS=bI+~z8+
zN@qxB>1T*%ra6SguGu50YHngOTIv)@N|YttEXo#OZfgtP7;H?EeZZxo<}3YlYxtBq
znJ!W<Tk7rKF4_TgJoZCW5Z^!*fTJ-Zk)y;)2fnZbAE(sksf_kg&-X&Eg#6@NPIv)e
zPk4oG=#<n+u~!?2Waj@D(b4RIBp>FR^tmGf0Py}N?kZ(#=VtpC@%xJkDmfcCoBTxq
zr_|5gP?u1@vJZbxPZ|G0AW4=tpb84gM2DpJU||(b8kMOV1S3|(yuwZJ&rIiFW(U;5
zUtAW`O6F6Zy+eZ1EDuP~AAHlSY-+A_eI5Gx)%*uro5tljy}kCZU*_d7)oJ>oQSZ3*
zneTn`{gnNC&uJd)0aMBzAg021?YJ~b(fmkwZAd696a=0NzBAqBN54KuNDwa*no(^O
z6p05bioXUR^uXjpTol*ppHp%1v9e)vkoUAUJyBx3lw0UO39b0?^{}yb!$yca(@DUn
zCquRF?t=Zb9`Ed3AI6|L{eX~ijVH`VzSMheKoP7LSSf4g>md>`yi!TkoG5P>Ofp+n
z(v~rW+(5L96L{vBb<M(xcH!jFDY91P;>^g51B=(o)?%%xhvT*A5btOpw(TKh^g^4c
zw>0%X!_0`{iN%RbVk+A^f{w-4-SSf*fu@FhruNL##F~sF<TNlh3Zu<wDObc>24O~u
zyYF<3el2b$$wZ_|uW#@Ak+VAGk#e|kS8nL1g>2B-SNMjMp^8;-FfeofY2fphFHO!{
z*!o4oTb{4e;S<|JEs<1_hPsmAlVNk?_5-Fp5KKU&d#FiNW~Y+pVFk@Cua1I{T+1|+
zHx6rFMor)7L)krbilqsWwy@T+g3DiH5MyVf8Wy}XbE<yUx>aoFIDr~y;@r&I>FMW{
z?Q+(IgyebZ)-i4jNoXQhq4Muy9Fv+OxU;9_Jmn+<`mEC#%2Q_2bpcgzcinygNI!&^
z=V$)o2&Yz04~+&pPWWn`rrWxJ&}8k<h1nlJpEW7DYjzCm^(#wnSe&>hR)6B(--!9Q
zubo}h+1T)>a@c)H^i``@<^j?|r4*{<Pxu7~B&!$dLmL9Ys=1M8gJeDpJrYz<2V9nr
zTvmS4mM<@Hxmfnk<1RI6FD*TtRhU+s9@>;tQf78(xn0g39IoZw0(CwY1f<%F>kEaJ
zp9u|IeMY5mRdAlw*+gSN^5$Q)ShM<~E=(c8QM+T-Qk)FyKz#<J1rUcxa8T8CP^@o-
z9LUqXz6y%L)dYBeo?hHD`m4vf;Ko!GhH#gWIg{IB<GEyusoLX^qjW_iBFR#|P|H$t
z1PVdv4xB@M4hvXb%aZB@j?)`0DTujf<&yn?+Ww^h>Sw0EJ*edYcuOtO#~Cx^(M7w5
z3)rl#L)rF|(Vun2LkFr!rg8Q@=r>9p>(t3Gf_auiJ2Xx9HmxYTa|=MH_SUlYL`mz9
zTTS$`%;D-|Jt}AP1&k7PcnfFNTH0A-*FmxstjBDiZX?}%u%Yq94$fUT&z6od+(Uk>
zuqsld#G(b$G8tus=M!<V>N#oPd|PVFX)?M?tCD0tS%2IGTfh}3YA3f&UM)W$_GNV8
zQo+a(ml2Km4o6O%gKTCSDNq+#zCTIQ1<zRinbW1<P#|UQotg93waYH2w1*h*jWPj6
z^zMSH#dD)R!pp{n89hOchS-cu?Yi0ISv7!)1hAHH{1T%@r!ud3;HLw5<Vb67p@OE@
zP1TDxu7L{<vN=z>*`TIJh~k6Gp;htHBFnne))rlFdGqwC6dx2+La1&Mnko*352k0y
z+tQcwndQlX`nc6nb$A9?<-o|r*%aWXV#=6PQic0Ok_D;q>wbv&j7cKc!w4~KF#-{6
z(S%6Za)WpGIWf7jZ3svNG5OLs0>vCL9{V7cgO%zevIVMH{WgP*^D9ws&OqA{yr|m|
zKD4*07dGXshJHd#e%x%J+qmS^lS|0Bp?{drv;{@{l9ArPO&?Q5=?OO9=}h$oVe#3b
z3Yofj&Cb}WC$PxmRRS)H%&$1-)z7jELS}!u!zQ?A^Y{Tv4QVt*vd@uj-^t2fYRzQj
zfxGR>-q|o$3sGn^#VzZ!QQx?h9`njeJry}@x?|k0-GTTA4y3t2E`3DZ!A~D?GiJup
z)8%PK2^9OVRlP(24P^4_<|D=H^7}WlWu#LgsdHzB%cPy|f8dD3|A^mh4WXxhLTVu_
z@abE{6Saz|Y{rXYPd4$tfPYo}ef(oQWZ=4Bct-=_9`#Qgp4ma$n$`tOwq#&E18$B;
z@Bp)bn3&rEi0>fWWZ@7k5WazfoX`SCO4jQWwVuo+$PmSZn^Hz?O(-tW@*DGxuf)V1
zO_xm&;NVCaHD4dqt(-MlszI3F-p?0!-e$fbiCeuaw66h^TTDLWuaV<@C-`=Xe5WL)
zwooG7h>4&*)p3pKMS3O!4>-4jQUN}iAMQ)2*70?hP~)TzzR?-f@?Aqy$$1Iy8VGG$
zMM?8;j!pUX7QQD$gRc_#+=raAS577ga-w?jd`vCiN5lu)dEUkkUPl9!?{$IJNxQys
z*E4e$eF&n&+AMRQR2gcaFEjAy*r)G!s(P6D&TfoApMFC_*Ftx0|D0@E-=B7tezU@d
zZ{hGiN;YLIoSeRS;9o%dEua4b%4R3;$SugDjP$x;Z!M!@QibuSBb)HY!3zJ7M;^jw
zlx6AD50FD&p3JyP*>o+t9YWW8(7P2t!VQQ21pHJOcG_SXQD;(5aX#M6x##5H_<Vgo
zXaA`|b1qI$OB^nkP*k8;>Re>6lPyDCjxr*R(+HE%c&QN+b^tbT<D}=?S8O%T8tX+C
zcq<H{RI|G2B9m%Rvp=d?PUf-1CZ*M)qUmtvLRWz*mFB-QNI1$Q(ryDe(K%5UcMcw>
zXBJk?p)zhJj#<NYmRaIG#%{yKso~Jl);(QZ{BXnYyStuZE8Z;ST(ba;;Cf6`eaY~e
zro&T_@|5eV&LV-Vdlye+OlA8HSGS?PEP0tn!gk^nHiROTHF+mL6DBZ*<LBy0zzNW0
z?K`Dd6_+8u^4Tx%YqyDRx3oaO`51F%4~hz9FS=g55uAbZ9<uEXv*DeH(f5XqNd{@0
zp<n?$CoIPaZ{u=WOkQK=>I?&Y2n&~XiytG9!1ox;bw5Rbj~)7c(MFBb4>IiRATdhg
zmiEFlj@S_hwYYI(ki{}&<;_7(Z0Qkf<vz98R4^QE*0+j0Yt5Bq_8W~pIEsdB>q>am
z&LtL=2qc7rWguk3BtE4zL41@#S;NN*-jWw|7Kx7H7~_%7fPt;TIX}Ubo>;Rmj94V>
zN<mGWxPciFI#UK&1{)&R+tKETKKJppI5eS&4QOQDb2gC@9#amL!Z4`6_?sgG50#TO
zUE{XN@zEh;wAcp{%1UraASTco@__6>B1=;-9AR7s`Pxn}t_6^3ahlq53e&!Lh85uG
zec0vJY_6e`tg7LgfrJ3k!DjR)Bi#L@DHIrZ`sK=<5O0Ip!fxGf*OgGSpP@Hbbe&$9
z;ZI}8lEoC2_7;%L2=w?tb%1oL0V+=Z`7b=P&lNGY;yVBazXRYu;+cQ<d^ZC}lYirx
z)hZjd3qKHeGus^Y+enhww8u%4lE|(|Z6qnX?I}@3Q1b~uMX2mD2SFAFYnI`H<@TW6
z_W((t!X&)`@PpH2wi2iW=uqjmv(p=oqs&Y%b9;Nf0OWslW9*Nb&oWZEt+0AVS&R~u
z_Wf#$fP|$gQ9fiHWGF1iGfW}Wb;*#iU5QAsVTwY*RhU@;t!16`ZZ<f|b==EnUgA$9
z4GDXmcVu4RoyBc?5+IzLNU`y7!@x5Q-0Qn*X9{dMTclVEa<*>DKvm*7NCxu&i;zub
zAJ<l&f69)KP9=Oa-e|<}G6{v&t3Gsy-GA$_$uw;4(^(<e6x2^i-<E!;86)%4VjM%-
z<_j^P(DEMAyY~*<c=R4aPSMdD=QV?HQb>h#11%?w>E2rf2e~C4+rAb-&$^vsdACs7
z@|<k_fU+PhC9U|KK^m>Ra!OfVM(ke{vyiqh7puf&Yp6cd6{DptUteYfIRWG3pI+5<
zBVBI_xkBAc<(p<um#S5<Wtzr=ckJ6;=I>cb$!Y%dTW(b;B;2pOI-(QCsLv@U-D1XJ
z(Gk8Q3l7Ws46Aktuj>|s{$6zA&xCPuXL-kB`CgYMs}4IeyG*P51IDwW?8UNQd+$i~
zlxOPtSi5L|gJcF@DwmJA5Ju8HEJ>o{{upwIpb!f{2(vLNBw`7xMbvcw<^{Fj@E~1(
z?w`iIMieunS#>nXlmUcSMU+D3rX28f?s7z;X=se6bo8;5vM|O^(D6{A9*ChnGH!RG
zP##3>LDC3jZPE4PH32<r6$U<HX=R_L2D`8>AxrqPk|yIIrq~`aL-=}`okhNu9aT%q
z1b<WnlSbT*V4<ymTCe0MD#5~7Whz|=;>)7iJ)CN=V#Ly84N_r7U^SH2FGdE5FpTO2
z630TF$P>GNMu8`rOytb(lB2};`;P4YNwW1<5d3Q~AX#P0aX}R2b2)`rgkp#zTxcGj
zAV^cvFbhP|JgWrq_e`~exr~sIR$6p5V?o4Wym3kQ3HA+;Pr$bQ0(PmADVO%MKL!^q
z?zAM8j1l4jrq|5X+V!8S*2<l)&qsCusW$QhU{vI`y!|$e;d+{bf(RH@<)nJ517c7s
zDim)TBb^~cK*c)35Gg|q1$&KAYNncsQOHJ|nu#)~+T76>Wl@=7*pPgciTVK6kS1Ge
zMsd_u6DFK$jTnvVtE;qa+8(1sGBu~n&F%dh(&c(Zs4Fc#A=gG^^%^AyH}1^?|8quj
zl@Z47h$){PlEL<j^JXcV*jDSt#inW`1Gn}CBm-N=8TRh<K)!JpM`mq>JgYZCIHHL=
z{U8O>Tw4x3<1{?$8>k-P<}1y9DmAZP_;(3Y*{<b??kNj&VqPGa79d@(m$2L68%nd!
z{_JjeX;XQdwTu-^XN2zhv1k+fQHndX43k}u83t_z&A52ZBFI*?6D8Q{uBSWGwQ#nR
zSnaCVwkuW{YP1TLJ@kJx_A>Sk^H^A=_iSJ@+s5ktgwTXz_2$~W9>VVZsfwCm@s0sQ
zeB50_yu@uS+e7QoPvdCwDz{prjo(AFwR%C?z`EL{1`|coJHQTk^nX=tvs1<0arUOJ
z!^`*x&&BvTYmemyZ)2p~{%eYX=JVR?DYr(rNgqRMA5<s3FN;{WX^H?!5dAC7_ToT&
z049v%;5~bT4K%9GqC;d+sXL`9S9+;oZpLE#7knG~OKbHmpUA?yU6n&99^Z!ZI?xYz
z{BGz0U$>E1PR1Iw=prk=L2ldy3r3Vg@27IZx43+ywyzr-X*p*d@tZV+!U#~$-q=8c
zgdSuh#r?b4GhEGNai)ayHQpk>5(%j5c@C1K3(W1pb~HeHpaqijJZa-e6vq_8t-^M^
zBJxq|MqZc?pjXPIH}70a5vt!IUh;l}<>VX<-Qcv^u@5(@@M2CHSe_hD$VG-eiV^V(
zj7*9T0?di?P$FaD6oo?)<)QT>Npf6Og!GO^GmPV(Km0!=<c9QK{JSBnxbTl~S4d3F
zZhX~`iBZf``YC!s;R3x;^$k-@k$#)|!OTN1novAwmG;&P2)PD!FyXg4r(4gHh?ySe
z7<%V?@*d*j&#%W*MAHm*B6GjS8B_74D&Msq691~iVscJ{Zps}t4Abjxm(LlYOjt<z
z0=dj7A`k(bp)&5Hm__k9JT(e0PyOe3?@>+dE&bk#SNI+C9RGQ|{~O*VC+tXK3!n`5
zHfl6>lwf_aEVV3`0T!aHNZLsj$paS$=LL(?b!Czaa5bbSuZ6#$_@LK<(7yrrl+80|
z{tOFd=|ta2Z`^ssozD9BINn45NxUeCQis?-BKmU*Kt=FY-NJ+)8S1ecuFtN-M?&42
zl2$G>u!iNhAk*HoJ^4v^9#ORYp5t^wDj6|lx~5w45#E5wVqI1JQ~9l?nPp1YINf++
zMAdSif~_ETv@Er(EFBI^@L4BULFW>)NI+ejHFP*<T<d*k5U>T}UhWNN`I)RRS8za?
z*@`1>9ZB}An%aT5K=_2iQmfE;GcBVHLF!$`I99o5GO`O%O_zLr9AG18>&^HkG(;=V
z%}c!OBQ~?MX(9h~tajX{=x)+!cbM7$YzTlmsPOdp2L-?GoW`@{lY9U3f;OUo*BwRB
z8A+nv(br0-SH#VxGy#ZrgnGD(=@;HME;yd46EgWJ`EL%oXc&lFpc@Y}^>G(W>h_v_
zlN!`idhX+OjL+~T?19sroAFVGfa5tX-D49w$1g2g_-T|EpHL6}K_aX4$K=LTvwtlF
zL*z}j{f+Uoe7{-px3_5iKPA<_7W=>Izkk)!l9ez2w%vi(?Y;i8AxRNLSOGDzNoqoI
zP!1uAl}r=_871(G?y`i&)-7{u=%nxk<TF^9;4ekh$qpT49mIUTo!QB3IxD^Xo8$2N
z0jCW$vUnPpla#O+%Oja`23x?g8&sst<rR<!i-fJAT!pW4qQWcl7>7CZ_Qh#!|ITec
zwQn`33GTUM`;D2POWnkqngqJhJRlM>CTONzTG}>^Q0wUunQyn|TAiHzyX2_%ATx%P
z%7gW)%4rA9^)M<_%k@`Y?RbC<29sWU&5;@|9thf2#zf8z12$hRcZ!CSb>kUp=4N#y
zl3hE#y6>kkA8VY2`W`g5Ip?2qC_BY$>R`iGQLhz2-S>x(RuWv)SPaGdl^)gGw7tjR
zH@;jwk!jIaCgSg_*9iF|a);sRUTq30(8I(obh^|}S~}P4U^BIGYqcz;MPpC~Y@k_m
zaw4WG1_vz2GdCAX!$_a%GHK**@IrHSkGoN>)e}>yzUTm52on`hYot7cB=oA-h1u|R
ztH$11t?54Qg2L+i33FPFKKRm1aOjKST{l1*(nps`>sv%VqeVMWjl5+Gh+9);hIP8?
zA<Q7k-wX5MjEY4*mC%%h!I%wsiVeW4+`u*(F}G%hLu4v_No<?+)c0h3mM0wvOcTzb
z6mLpttd1pgh;LPDfUyEl9?m3fSr8}4WkXDbERL<t;7gDrg+uTPTiBati$g>@$?}Sc
z3qIRpba+y5yf{R6G(u8Z^vkg0Fu&D-7?1s=QZU`Ub{-!Y`I?AGf1VNuc^L3v>)>i#
z{DV9W$)>34<d17om!!)9&{`T5uHYJXV$G;?A+9420_wrs59Q5xU_?zk<S-MZw#YF!
z)5TK_({W1E10+oWfpH?yLthllM<4BAQSN*>wnzAXUiV^ZpYKw>UElrN_5Xj6{r_3|
z$X5PK`e5$7>~9Dj7gK5ash(dvs`vwfk}&RD`>04;j62zoXESkFBklYaKm5seyiX(P
z<ID{omUfJz++3+6M6A3|He)%RuG>qQ-;XxlV*yg?Dhlx%xt!b0N3GHp@(p$A;8|%#
zZ5m2KL|{on4nr>2_s9Yh=r5ScQ0;aMF)G$-9-Ca6%wA`Pa)i?NGFA|#Yi?{X-4ZO_
z^}%7%vkzvUHa$-^Y#aA+aiR5sa%S|Ebyn`EV<3Pc?ax_f>@sBZF1S<H?5z{)#QL{V
zr*a_q>;7y$CXd5t5=WGsTKBk8$OfH4v|0?0I=Yp}7c=WBSCg!{0n)XmiU;lfx)<uN
zPvr+1FFDIM@A4#y;a<?S=xTH`XYK!+^->**zZaYqmDJelxk$)nZyx5`x$6R|fz(;u
zEje5Dtm|a%zK!!tk3{i9$I2b{vXNFy%Bf{50X!x{98+BsDr_u9i>G5%*sqEX|06J0
z^IY{UcEbj6LDwuMh7cH`H@9sVt1l1#8kEQ(LyT@&+K}(ReE`ux8gb0r6L_#bDUo^P
z3Ka2l<H7(tNv_ycRF43oWEx{?2ychJaXYk!nafC$;QPt)Dhl%pHY&kHF=u*jMxFxR
z8hs|e%r39oE}ts%zE`x;@(JZF%`*hV&TQs;k7&^PC%_|U=Z^yM6XVPX3WWp6H|w9J
z45Q%jM?z_P7Kg74lHMQ_-ZVr_NbHvg3EMK85#qK7Y#v#ov_?2?Wu|DHo1}82@XlNo
z*7dav>Ro52Hdtl_%+pwVs14=q`{d^L58PsU@AMf(hENumaxM{7iAT5sYmWh@hQCO^
zK&}ijo=`VqZ#a3vE?`7QW0ZREL17ZvDfdqKGD?0D4fg{7v%|Yj&_jcKJAB)>=*RS*
zto8p6@k%;&^ZF>hvXm&$PCuEp{uqw3VPG$9VMdW5$w-fy2CNNT>E;>ejBgy-m_6`&
z97L1p{%srn@O_JQgFpa_#f(_)eb#YS>o>q3(*uB;uZb605(iqM$=NK{nHY=+X2*G)
zO3-_Xh%aG}fHWe*==58zBwp<ewOv=l7F;`(EW(2I^P`O~+>%&`mg<U+`XEp_tI#7M
zlHXq!JFASK8=TxtsItown-vYtx@G%cb7t%FpgERtlejdO-?8O0py|EQiBWNJ#diHb
z8h^Y>e<8uq8;xIxOd=P%9EK!34^E9sk|(Zq1QSz-JVeP12Fp)-`F|KY$LPwUE?rku
zY@OJ)Z9A!ojfzfeyJ9;zv2EM7ZQB)AR5xGa-tMn^bl)FmoIiVyJ@!~@%{}qXXD&Ns
zPnfe5U+&ohKefILu_1mPfLGuapX@btta5C#gPB2cjk5m4T}Nfi+Vfka!Yd(L?-c~5
z#ZK4VeQEXNPc4r$K00F<wRh*06<c<Cw!0P4***aS+tgLJ2H$n=v+UM@P`jG9HJHW0
zeqBot9>g>g#_W!YZ)cJ?JTS<&68_$#cZT-ME`}tcwqg3#``3M3UPvn+pi}(VNNx6y
zFIMVb6OwYU(2`at$gHba*qrMVUl8xk5z-z~fb@Q3Y_+aXuEKH}L+>eW__!IAd@V}L
zkw#s%H0v2k5-=vh$^vPCuAi22Luu3uKTf6fPo?*nvj$9(u)4$6tvF-%IM+3pt*cgs
z_?wW}J7VAA{_~!?))?s6{M=KPpVhg4fNuU*|3THp@_(q!b*hdl{fjRVFWtu^1dV(f
z6iOux9hi&+UK=|%M*~|aqFK{Urfl!TA}UWY#`w(0P!KMe1Si<jiK`FCX|r(xrQ!0U
zNF-2!m|??dd%b!3w5!;b;@Y>{8|o))Gy6d7;!JQYhgMYmXl?3FfOM2nQGN@~Ap6(G
z3+d_5y<nkN(o+zEYZBPE7qE4X4RTq~xP<0UuT}eq);wA`P~5mS&}Ni6sX$kQ!#Y14
zw<=&7Ca^#oAVnvbz-T-b@50=C)>@=nkpKAhRqf{qQ~k7Z$v&l&@m7Ppt#FSNzKPZM
z8LhihcE6i=<(#87E|Wr~HKvVWhkll4iSK$^mUHaxgy8*K$_Zj;zJ`L$naPj+^3zTi
z-3NTaaKnD5FPY-~?Tq6QHnmDDRxu0mh0D|zD~Y=vv_qig5r-cIbCpxlju&8Sya)@{
zsmv6XUSi)@(?PvItkiZEeN*)AE~I_?#+Ja-r8$(XiXei2d@Hi7<U!}O-C%Wp93|!6
z_maftKQVDsmc-oSX^Wf5%~c*ohRjQuXO7WUoJr4mKQ1O_S_G_rS=b~3S&JLLEOKDV
z{3LUpGl1vt1pkI#r_j=V*y<p!g}(O0?op0V5}i0e<PEWYB8x5J4<%9#9y9X9M*bUx
zicdfReJ#lhlVUp=<yC<tza847t{vKR$R*ci-p`+Gl}ts*E09J&7%h92yemiDYmk~}
zTm@z(hV@tXo`0Xdz4V~IJu7i|)?jOn6Nt~0dUv^z2PHbxR-jssAHfY`%7{ql=vzVB
zs_4Na@y!!YjTV?bkxAK(=I=549YO&vP5F{dsX_6-68_n)LiIx2IwV=E#EmY<Yodu6
z9z7+@5zk>Rx8+rZZb?ZLa{;@*EHeRQ-YDadz~M*YCM4&F-r;E#M+@CSJMJ0oU|PQ^
z=E!HBJDMQ2TN*Y(Ag(ynAL8%^v;=~q?s4plA_hig&5Z0x_^Oab!T)@6kRN$)qEJ6E
zNuQjg|G7iwU(N8pI@_6==0CL;lRh<Er=!!1>1dQF#wePhmu@hADFd3B5KIH#dx(2A
zp~K&;Xw}F_N6CU~0)<woWpm{<(lL~%8t8hZ?O>QpQk7s$a+LcTOj1%=WXI(U=Dv!6
z{#<#-)2+gCyyv=Jw?Ab#PV<kuPJ4UouiQa>kxPDeH|sAxyG`|Ys}A$PW4TdBv%zDz
z^?lwrxWR<%Vzc8Sgt|?FL6ej_*e&rhqJZ3Y>k=X(^dytycR;XDU16}Pc9Vn0>_@H+
zQ;a`GSMEG64=JRAOg%~L)x*w{2re6DVprNp+FcNra4VdNjiaF0M^*<Z21jxz28!z4
z)+Qw^>>Cd<OYjfTeBDpnxINod_ps<v{(V~~r+~z4oEIjOYCK|$#(JnCT7;!!Y}f=y
zFNsGLXIqR_Lc24Epk`I91kx04#KNLQB=sN}`>Pkt(m150rCue?FVdL0nFL$V%5y6N
z%eLr5%YN7D06k5ji5*p4v$UMM)G??Q%RB27IvH7vYr_^3>1D-M66#MN8tWGw>WED}
z5AhlsanO=STFYFs)Il_0i)l)f<8qn|$DW7ZXhf5xI;m+7M5-%P63XFQrG9>DMqHc}
zsgNU9nR`b}E^mL5=@7<1_R~j@q_2U^3h|+`7YH-?C=vme1C3m`Fe0HC>pjt6f_XMh
zy~-i-8R46QNYneL4t@)<0VU7({aUO?aH`z4V2+kxgH5pYD5)wCh75JqQY)jIPN=U6
z+qi8cGiOtXG2tXm;_CfpH9ESCz#i5B(42}rBJJF$jh<1sbpj^8&L;gzGHb8M{of+}
zzF^8VgML2O9nxBW7AvdEt90vp+#kZxWf@A)o<TP7Iv6D<p-`geitU42O0|5*#cI2&
zD#rHm-Vc3+vP+a)$@(=16*wM+J-aXvee~$jPN+y)1J;9JyU$}nCH;?MkiD^?^{YXd
z()hszm1?+Vl-hdUHRO1qu43l7<f-+JFAVi;sMe)sVUTGeF5*U18gVs~b3a#HICwn?
zOc3D$MdBtKd+A-2`!?hp+dNtbrf)b+gMTQ^qA%J;1l0Bf$I4T>9f9}vKJy9NDBjBW
zSt=Hcs=YWCwnfY1UYx*+msp{g!w0HC<_SM!VL1(I2PE?CS}r(eh?{I)mQixmo5^p#
zV?2R!R@3GV6hwTCrfHiK#3Orj>I!GS2kYhk1S;aFBD_}u2v;0HYFq}Iz1Z(I4oca4
zxquja8$+8JW_EagDHf$a1OTk5S97umGSDaj)gH=fLs9>_=XvVj^Xj9a#gLdk=&3tl
zf<JQN-rLl3?(b@3I(eFE1!7*!5QjuNkUcQB*{SCO?Dz6>mK9MNnIX9v{?%xdw7568
zNrZ|roYs(vC4pHB5RJ8>)^*OuyNC>x7ad)tB_}3SgQ96+-JT^Qi<`xi=)_=$Skwv~
zdqeT9Pa`LYvCAn&rMa2aCDV(TMI#PA5g#RtV|CWpgDYRA^|55LLN^u<JFRGA?x);o
z`Z~}R6`4W#%h(d)aQ>Nh*gOU>Z=a06qJ;$C9z8;n-Pq=qZnc1zUwJ@t)L;&NN+E5m
zRkQ(SeM8=l-aoAKGKD>!@?mWTW&~)uF2PYUJ;tB^my`r9n|Ly~0c%diYzqs9W#<S`
z2%`mn3A&KL|FUYx1DDYTb2GMnO1WEyfJ-eVoSqd~=r!kw@InSGE<>FTjy?h&X3TnH
zXqA{QI82sdjPO->f=^K^f>N`+B`q9&rN0bOXO79S&a9XX8zund(kW7O76f4dcWhIu
zER`XSMSFbSL>b;Rp#`CuGJ&p$s~G|76){d?xSA5wVg##_O0DrmyEYppyBr%fyWbbv
zp`K84JwRNP$d-pJ!Qk|(RMr?*!wi1if-9G#0p>>1QXKXWFy)eB3ai)l3601q8!9JC
zvU#ZWWDNKq9g6fYs?JQ)Q4C_cgTy3FhgKb8s&m)DdmL5zhNK#8wWg!J*7G7Qhe9VU
zha?^AQTDpYcuN!B+<Y^i3NB&h=8l2*^8*j@dwN-$SX`JG4?X#EO)n_d+Mm*qNtLvW
z1{=j+)$5S8QKKaCKpO>#1dE*X{<#!M%zfUQbj=zL<r~1!%Q56_&?RVt*j39RdBbdU
zvt>E{dW0XeQ7-oIsGY6RbkP2re@Q{}r_$iiH0xU%iN*ST`A)-EH6eaZB$GA#v)cLi
z*MpA(3bYk$oBDKAzu^kJoSUsDd|856DApz={3u8sbQV@JnRkp2nC|)m;#T=DvIL-O
zI4vh;g7824l}*`_p@MT4+d`JZ<NgM|d-wED*_BDR=X2CYG0s+@tH~}mHA<v@@*LLa
zcTk2OQd|qCF;Irq7ZT2t<bCnFzjKHMYi_FEX5uA1sMB~b=-gExnk*fx9Jolk@GBaP
zo2{A-B!6SMvS~u~??*1DY*%B^{i&5Xid$7&jHLv;Csgpyh12H&Wr+sb8jR356U$OH
z#keINf2882?;$z(=9b`_o!xWZsvxb)AId~zQ-ypi#22f~snWv+_Q$md&MYLZH1*5&
zgU2`BbMmltaER}JO!m5!`^u~)I>2%6NQh=N9bmgJ#q!hK@_<`HQq3}Z8Ij>3%~<*=
zcv=!oT#5xmeGI92lqm9sGVE%#X$ls;St|F#u!?5Y7syhx6q#MVRa&lBmmn%$C0QzU
z);*ldgwwCmzM3ug<bwv^{e8k-I_Ia))Ca<<K85KO7s<Z8_qINV*w7o<JN><pez`8$
z*U(_%(Oddx;Dy@<By6!p<ae@SHe5;+DISJZbTAq-U`Q`A1)YLa`3xqvnU#=JMDwvc
zT=fd_B(g|SbuM?{hEp2{k!4hh2k1}qTl{TSl*cD|duWT^U1%zqX9UbNuTdGS)?ic-
zFWu0OzODT7)oL^9a3Iy*#7Rk@72_$KGruLmz}W@8{rhO(Lndv7z61c>lr}!Z2G+?&
zf%Dpo&mD%2ZcNFiN-Z0f;c_Q;A%f@>26f?{d1kxIJD}LxsQkB47SAdwinfMILZdN3
zfj^HmTzS3Ku5BxY>ANutS8WPQ-G>v4^_Qndy==P3pDm+Xc?>rUHl-4+^%Sp5atOja
z2oP}ftw-rqnb}+khR3CrRg^ibi6?QYk1*i^;kQGirQ<G&YKu_KEA~r2_|MY6U!vEc
zYq^WKw2*I=^(R7(!~~v`>=uB9Sd1NTfT-Rbv;hqnY4neE5H1YUrjS2m+2&@uXiAo-
zrKUX|Ohg7(6F(AoP~tj;NZlV#xsfo-5reuQHB$&EIAhyZk;bL;k9ouDmJNBAun;H&
zn;Of1z_Qj`x&M;5X;{s~iGzBQTY^kv-k{ksbE*Dl%Qf%N@hQCfY~iUw!=F-*$cpf2
z3wix|aL<TqR7Y;}gRV7Q6u)-qpm%oMjSmV6D=p0OrNXwr5;y^b5cF7C7&Mp&D`?Ob
z8ESq3ScyN7w@J>BV0b;W@z^%7S{>9Z^T^fLOI68_;l@+Qzaxo`nAI8emTV@rRhEKZ
z?*z_{oGdI~R*#<2{bkz$G~^Qef}$*4OYTgtL$e9q!FY7EqxJ2`zk6SQc}M(k(_MaV
zSLJnTXw&@djco1~a(vhBl^&w=$fa9{Sru>7g8SHahv$&Bl(D@(Zwxo_3r=;VH|uc5
zi1Ny)J!<(KN-EcQ(xlw%PNwK8U>4$9nVOhj(y0l9X^vP1TA>r_7WtSExIOsz`nDOP
zs}d>Vxb2Vo2e5x8p(n~Y5ggAyvib>d)6?)|E@{FIz?G3PVGLf7-;BxaP;c?7ddH$z
zA+{~k^V=bZuXafOv!RPsE1GrR3J2TH<Ny`yVx$sah_BnMO|Vl_4M%y|BVBOcD(&Tf
zIi%w5mBkQA-m8WhIS+m)@HEq^i=}^RPX#BvtKJYieRDhM9CpMXBxjmn?hoV<pKsfM
zQ3`)(<)?1Do&LG^9T4w<TIx#Djhk>9uB=Z67gok+u`V#}BR86hB1xl}H4v`F+mRfr
zYhortD%@IGfh!JB(NUNSDh+qDz?4ztEgCz&bIG-Wg7w-ua4ChgQR_c+z8dT3<1?uX
z*G(DKy_LTl*Ea!%v!RhpCXW1WJO6F`bgS-SB;Xw9<cxOL&fF^435YAz<*2lIsx>#!
z<*K}=#wVu9$`Yo|e!z-CPYH!nj7s9dEPr-E`DXUBu0n!xX~&|%#G=BeM?X@shQQMf
zMvr2!y7p_gD5-!Lnm|a@z8Of^EKboZsTMk%5VsJEm>Vs<fWSaAAk=E0a4xz;CoE+n
zvV|`k(cS-gI#<~znD&6(Dyi8%>J4W7Kv{<|#4f-qDE$D-W>gWT%<wM^e7+vR+ZVxu
zJA%k!wV1jm=-?CPfHci1I%oS6_$rRC_i%Dy1_C}}(R>z-!qXnDHhOvLk=?^a1*|0j
z{pW{M0{#1VcR5;F!!fIl<yJC4LQf<m+NFcvrhH-9Oq`TslF!sxh9CTya<1|Z@Sf8S
z#)!cL{VHJYkWIKNj^M2D@K4#yCJQKlT2}zO7tRTvNED*cmVv~6G8g$V6W>LVNh_Gj
zbnW(_j?0c2q$EHIi@fSMR{OUKBcLr{Y&$hrM8XhPByyZa<R$b|!F4rBVu<@_&`m0`
zvC-aJ+X!p>Xy|dd&{hYQRJ9@Fn%h3p7*VQolBIV@Eq`=y%5BU~3RPa^$a?ixp^cCg
z+}Q*X+CW9~TL29@OOng(#OAOd!)e$d%sr}^KBJ-?-X&|4HTmtemxmp?cT3uA?md4%
zT8yZ0U;6Rg6JHy3fJae{6TMGS?ZUX6+gGTT{Q{)SI85$5FD{g-eR%O0KMpWPY`4@O
zx!hen1*8^E(*}{m^V_?}(b5k3hYo=T+$&M32+B`}81~KKZhY;2H{7O-M@vbCzuX0n
zW-&HXeyr1%I3$@ns-V1~Lb@wIpkmx|8I~ob1Of7i6BTNysEwI}=!nU%q7(V_^+d*G
z7G;07m(CRTJup!`cdYi93r^+LY+`M*>aMuHJm(A8_O8C#A*$!Xvddgpjx5)?_EB*q
zgE8o5O>e~9IiSC@WtZpF{4Bj2J5eZ>uUzY%TgWF7wdDE!fSQIAWCP)V{;HsU3ap?4
znRsiiDbtN7i9hapO;(|Ew>Ip2TZSvK9Z^N21%J?OiA_&eP1{(Pu_=%JjKy|HOardq
ze?zK^<n_C~sSO$T&zHJ&gqMJm2ooswNa9fe;pI&q8BGtsLvsv{E`UcDopP-qDeO>K
zA%sj<KGR#nku^U`P7U%dm^(-)^vJ8a7zEx#hISA%f9a1Ybx@Dr&>F64*Wufad%H<)
z^|t>e*h+Z1#l=5wHexzt9HNDNXgM=-OPWKd^5p!~%SIl>Fo&7BvNpbf8{NXmH)o{r
zO=aBJ;meX1^{O%q;kqdw*5k<?!FYD}X~SRg{bAptI6CT~WZcECii<d{!~H9SptJA{
z(IMO5d`_qI=h*DGo=n0v@_q*TN1Rb~B&ITpk8DJlRXa*ROudIg-K94et8*W|ahl(A
z2RLvW1}v%VuO9`Ef9t?PKUXTW2f&D}3vrtNJ87$D?Y9if%$|t@;m`i#_BSRV)jj(n
z<)v7wOK4@tW$UKKWR0fsc^c<~vm5M`u2vnP<@`C7-1h}V)vH?GIQ6kut>!Y7%t_30
zy{nGRVc&5qt?dBwLs+^Sfp;f`YVMSB#C>z^a9@fpZ!xb|b-JEz1LBX7ci)V@W+k<d
z?qR|O?7_P?Q6<qQfw{t}<omxO-y4wzz13f^3s3)!sA+n!=}0n9^jL6z6UFtDDE}Mp
z!BsppJn%YvdkxcpH0L^o3RScOB1lQrKBaMr+6<a345~U+wL$oOCB}VtK17ZH;V1Ue
zdj4e4ug6v=rEE8!n9=MxEf@easRS`JT*=LVd(P_|@2%P^bJF0dJak~<TFSD+7ZH;0
zk0}Z5&3UxSBxu~{Rz*8BKG13&fcf@9dyUN>vQ89KWA0T~L<vZ;GW*aTR}HF1-jedY
z#-MsfGyBFAcQAdcd`Yx-bcvlJbsoc$%4C5;EuOf%FC1$=NHxR@P$wjlROtPJ?~8@j
z{p*zq)|ri!j1uu-Pw*x?ETPT6(jkMz{tB)03YK+l%8c_vwo>j$aCcfW#nD5bt&Y_<
z-q{4ZXDqVg?|0o)j1%l0^_it0WF*LCn-+)c!2y5yS7aZIN$>0LqNnkujV*YVes(v$
zY@_-!Q;!ZyJ}Bg|G-~w@or&u0RO?vlt5*9~yeoPV_UWrO2J54b4#{D(D>jF(R88u2
zo#B^@iF_%S>{iXSol8jpmsZuJ?+;epg>k=$d`?GSegAVp3n$`GVDvK${N*#L_1`44
z{w0fL{2%)0|E+qgZtjX}itZz^KJt4Y;*8uSK}Ft38+3>j|K(PxIXXR-t4VopXo#9#
zt|F{LWr-?34y`$nLBVV_*UEgA6AUI65dYIbqpNq9cl&uLJ0~L}<=ESlOm?Y-S@L*d
z<7vt}`)TW#f%Rp$Q}6@3=j$7Tze@_uZ<ObsOT=LjG!@YPQ+Y%TP2q;%&e6bD0<;#D
zn1mKO23ndd^;;2ec_vb`0m}1R5{A-e6@I<Gaf6P$y+!C|ZytXPFNr}*6sJD;{rbI+
zRwg~nC(gjZ<H0G$h5d*YGLSy%7k#zcB&IGLVazVInCg9bgF6KKKSeDarF+`2IFlWj
z%#J~%w5&}@qlKlZ9XX8WVB)+9_$hOD{jg_1meULyOnTAY(X(RGDVFl%IWWYYn*#Gf
zs5wy97!DZR>O@aMn<|si{?S}~maII`VTjs&?}jQ4_cut9$)PEqMukwoXobzaKx^MV
z2fQwl+;LSZ$qy%Tys0oo^K=jOw$!YwCv^e<e%~cuMqeXJnyNEIpgKcP&BSGZ3-V#G
zgnyc%fsRb47ImAxDT<IihCipil@oTF)0wHSZ%ab4RM$MVn<5Pqo=k;p=s1{wkr4K3
zPn=Vq->i4NBVauL)tN%=wz9M{uf{IB(BxK|lT*pFkmN<Z(NFM5`sDgUq1$L^2{X$m
zQ<@5WTkRGfqF>K_1tV`nb%jH=a0~VNq2RCKY(rG7jz!-D^k)Ec)yS%17pE#o6&eY+
z^qN(hQT$}5F(=4lgNQhlxj?nB4N6ntUY<e6n(3tLO%M0YHj0diWfkmtmb0?9X&BDU
zs6Tl5CHz~g>6(?+R#B?W3hY_a*)hnr4PA|v<bL3cOEhhyT5k=(qGlmAL3eDw%3aS)
z+mMt2HXmQhxUE+tIpq`0N<C;yWn7~iBEGnslqQO0EY^z~!M$i!^_m>J<6p`K3Z5Hy
z{{8(|ux~NLUW=!?9Qe&WXMTAkQnLXg(g=I@(VG3{HE13OaUT|DljyWXPs2FE@?`iU
z4GQlM&Q=T<4&v@Fe<+TuXiZQT3G~v<S1*NrZ8z<H*IRys?O`Oqz|}FcV<W%7zks=K
zjhgy^OR8^T{XcG5A)q#Ixd7)hWJZgOgp%s-!KiICJ<7)nHG%9IeF-=|(W+fGO(~eL
zUZW|&`a8*ZnEW_JOqB-k$82w~>Z&^POfmI1K2h6t4eD}Gk5XFGpbj1n_g*{qmD6Xy
z`6<o)fI|_!EcP+Bw?+2|y3t!@@OewwE@am14Pw<&ymmicd%g=pQX-4Dl6iXM5Mi<r
zx3XG;>Vv|lLZtLmrnv*{Q%xxtcWVj3K4M%$bdBk_a&ar{{GWyu#ljM;dII;*jP;QH
z#+^o-A4np{@|Mz+LphTD0`FTyxYq#wY)*&Ls5o{0z9yg2K+K7ZN>j1>N&;r+Z`vI|
zDzG1LJZ+sE?m?>x{5LJx^)g&pGEpY=fQ-4}{x=ru;}FL$inHemOg%|R*ZXPodU}Kh
zFEd5#+8rGq$Y<_?k-}r5zgQ3jRV=ooHiF|@z_#D4pKVEmn5CGV(9VKCyG|sT9nc=U
zEoT67<jXapz33SQGdVleW*J=p6l-iq5HGgGZNX3gcnDtqDqT6Lxf&Cy#Ap6*__@(N
zI9l&1+PZ(2&t7;rjbr<N3;GXPQmR+Jb=l@GOikZr!v7KeKwAmIz6g%ucSA?oWgocV
zk;d7L7JWl9$p0E+2q4zN?=f=Aph6SF??-{0uw#y<{6dXC$UJvvFots-eZ*CWmiR<m
z^L^@#CZ2{u<>R`C->KY8Wp-fEcjjFm^;Cg(ls|*ABVHq8clBE(;~K^b+S>6uj70g?
z&{XQ5U&!Z$SO7zfP+y^8XBbiu*Cv-yJG|l-oe*!s5$@Lh_KpxYL2sx`<G0?@o|1&5
z++RB?zrCfT7`A&iZHeO}uiAn(9Y;?H+|QxaD&F$T&wYPv^@%QzORq4V7h)QaA?IS+
zFB!z6yTuA4F{2w*bnO?o`KM7U>B|V=dETN>5K+C+CU~a_3cI8{vbu$TNVdGf15*>D
zz@f{zIlorkY>TRh7mKuAlN9A0>N>SV`X)+bEHms=mfYTMWt_AJtz_h+JMmrgH?mZt
zm=lfdF`t^J*XLg7v+iS)XZROygK=CS@CvUaJo&w2W!Wb@aa?~Drtf`JV^cCMjngVZ
zv&xaIBEo8EYWuML+vxCpjjY^s1-ahXJzAV6hTw%ZIy!FjI}aJ+{rE&u#>rs)vzuxz
z+$5z=7W?zH2>Eb32dvgHYZtCAf!=OLY-pb4>Ae79rd68E2LkVPj-|jFeyqtBCCwiW
zkB@kO_(3wFq)7qwV}bA=zD!*@UhT`geq}ITo%@O(Z5Y80nEX~;0-8kO{oB6|(4fQh
z);73T!>3@{ZobPwRv*W?7<u$fR#FIIDQ|?d;-=4~nL_DQNR_L(s2gGB|Bi%bXbI)!
ztn@6?NW&ORN!+hVmb|xpUMHeP-Y*-8YoeQ$=7K(Sd>m0Ml9GmJBCJd&6E?hdj9lV=
z4flNfsc(J*DyPv?RCOx!MSvk(M952PJ-G|JeVxWVjN~SN<fFWRb2=9964Bd}-9L0#
za&bfyJOi!#T%8p@)e{#M*HC~_RDcB;kF@?XCf0o$;#0Tz<%{^IxQ6b()`kCzGw`pn
zvVV06qCVS*7lZ)(o7Gp6ekOkuzzxs?O%%&Yp1+cWnn|fKYX<Z-8@MV#wqF)qqV5*o
zSnWk1rIdh6FPQo!-hS8qsY!O5JD<AlIn95(ae6Jd?fWIAFM+L&sw_o{)ZY*mza^{a
zFgSda?4Av^CAF7cj@(}R6JgOpyFKsFTD;d44h4&<Jz-_1F5J{G+LW?&6IhxYcs@xb
zl@w&aT)k@tK}w%(8c;t<C(7s<T@#tgO(Q)4E9>S6n-_Ge3Q;TGE;EQvZg86%wZ`MB
zSMQua(i*R8a75!6$QRO^(o7sGoomb+Y{OMy;m~Oa`;P9Yqo><o$qrN{Uy#{EYZAYV
zhkQ~i`~tBVbX%VYXh`B$bAR$*>?bJAhqXxLr7_3g_n>f#UVtxG!^F#1+y@os6x(sg
z^28bsQ@8rw%Gxk-stAEPRbv^}5sLe=VMbkc@J<s@rA3iE(48`CbnWn(=&3DF#J=}a
z4FTXYopd?mZI}}1ZlC8~VV`QLNWV;~TVEZ~uaDc-&}W%0xomagCDhH<gooe&naXnn
z<tUH-X!YNVZ5{|0$(F_l%}+PcEZ$(<;b4&E&i=){rcO+Hkk=zdTK^Ffd=*LS^6eUA
zUbs7^NXMxkl#^HyJ=dcJiSCooRo<stw%BQ{lj}<*D~N?4*Cut%z#~2r#dSIApv9<Q
zjHtNwb#+f5agUh9@-@^){GvYFJ5KG7zCVqj%Df~m{m3x+{p&MW3!dR+pvL^5ZRmC0
zC309}MqA9m^d9B_Vk}86VV~U#6&}A3g}?sHV+qTd>jimqjvmd!3E7+QnL>|(^3!R}
zD-l1l7*Amu@j+PWLGHXXaFG0Ct2Q=}5YNUxEQHCAU7gA$sSC<5OGylNnQUa>>l%sM
zyu}z6i&({U@x^hln**o6r2s-(C-L50tQvz|zHTqW!ir?w&V23tuYEDJVV#5pE|OJu
z7^R!A$iM$YCe?8n67l*J-okwfZ+ZTkGvZ)tVPfR;|3gyFjF<h<Cj<zZh5#4y5>)8V
zyXXN=!*bpyRg9#~Bg1+U<pnWYhrolu{FPCsV0iobLA4JkV_p&4r@K1M;NHG>DYCt0
ztp4&?t1X0q>uz;an<Pmca*5{xy^4kc>n$OrZs{5*r`(oNvw=$7O#rD|Wuv*wIi)4b
zGtq4%BX+kkagv3F9Id6~-c+1&?zny%w5j&nk9SQfo0k4LhdSU_kWGW7axkfpgR`8*
z!?UTG*Zi_baA1^0<wK9e#G~fPDt@KdN$SZ|%nA9j-17!`BH9vUH0o`1P&6J*h<;ef
zVW;53QYa7AXJdrlTA-n?%wp6d3?_b6<x05IZ{WEejqFp)B0lVPV-bRe>eda8S|@&F
z{)Rad0kiLjB|=}XFJhD(S3ssKlveFFmkN{Vl^_nb!o5M!RC=m)V&v2%e?ZoRC@h3>
zJ(?pvToFd`*Zc@HFPL#=otWKwtuuQ_dT-Hr{S%pQX<6dqVJ8;f(o)4~VM_kEQkMR+
zs1SCVi~k>M`u1u2xc}>#D!V&6nOOh-E$O&SzYrjJdZpaDv1!R-QGA141WjQe2s0J~
zQ;AXG)F+K#K8_5HVqRoRM%^EduqOnS(j2)|ctA6Q^=|s_WJYU;Z%5bHp08HPL`YF2
zR)Ad1z{zh`=sDs<zGHk8(=f(sFR?;R<HJ%pYo-KSa+@gOo;(hTO4p7NJfbujY~Kee
zGHQPHC}zX0H$dR?nrR`jLKzUvcA{-a5@SQ^UbQXYN=CS}aw?OAqkUt?H8F&>^&V}J
z%$Z$!jd7BY5AkT?j`eqMs%!Gm@T8)4w3GYEX~IwgE~`d|@T{WYHkudy(47brgHXx&
zBL1yFG6!!!VOSmDxBpefy2{L_u5yTwja&HA!mYA#wg#bc-m%~8aRR|~AvMnind@zs
zy>wkShe5&*un^zvSOdlVu%kHsEo>@puMQ`b1}(|)l~E{5)f7gC=E$fP(FC2=F<^|A
zxeIm?{EE!3sO!Gr7e{w)Dx(uU#3WrFZ>ibmKSQ1tY?*-Nh1TDHLe+k*;{Rp!Bmd_m
zb#^kh`Y*8l|9Cz2e{;RL%_lg{#^Ar+NH|3z*Zye>!alpt{z;4dFAw^^H!6ING*EFc
z_yqhr8d!;%nHX9AKhFQZBGrSzfzYCi%C!(Q5*~hX>)0N`vbhZ@N|i;_972WSx*>LH
z87?en(;2_`{_JHF`Sv6Wlps;dCcj+8IJ8ca6`DsOQCMb<Z@pezuQ&fWzt;cz#SUWI
zcqV2XJ90lftQ?~%HDz)~)GJXKcKN}4st=)aT3chrg_EA{?3LcT)!JaRZ}=sv*>3n#
z3)_w%FuJ3>fjeOOtWyq)ag|PmgQbC-s}KRHG~enBcIwqIiGW8R8jFeBNY9|YswRY5
zjGUxdGgUD26wOpwM#8a!Nuqg68*dG@VM~SbOroL_On0N6QdT9?)NeB3@0FCC?Z|E0
z6TPZj<t(m7DtKHBH@$**2Zo{c79USiF>(AsPtwCw>*{eDEE}Gby>0q{*lI+g2e&<d
zeHwJP(&NSri;iaCB`Kw+7PmoLhp%WLBbMtYj3S7->(YQrsY&uGM{O~}(oM@YWmb*F
zA0^rr5~UD^qmNljq$F#ARXRZ1igP`MQx4aS6*MS;Ot(1L5jF2NJ;de!NujUYg$dr#
z=TEL_zTj2@>ZZN(NYCeVX2==~=aT)R30gETO{G&GM4XN<+!&W&(WcDP%oL8PyIVUC
zs5AvMgh6qr-2?^unB@mXK*Dbil^y-GTC+>&N5HkzXtozVf93m~xOUHn8`HpX=$_v2
z61H;Z1qK9o;>->tb8y%#4H)765W4E>TQ1o0PFj)uTOPEvv&}%(_<LSzDTRe;Ie+2@
ztS!_=d%s5$G(s@--l3N6rQ)s8U_l;8K^1JNd@9$&rF%j>mG0ISmyhnQV33Z$#&yd{
zc{>8V8XK$3u8}04CmAQ#I@XvtmB*s4t8va?-IY4@CN>;)mLb_4!&P3XSw4pA_NzDb
zORn!blT-aHk1%Jpi>T~oGLuh{DB)JIGZ9KOsciWs2N7mM1JWM+lna4vkDL?Q)z_Ct
z`!mi0jtr+4*L&N7jk&LodVO#6?_qRGVaucqVB8*us6i3BTa<Q)$L85GR#EfdqV+R=
zf3l>^^EI0x%EREQSXV@f!lak6Wf1cNZ8>*artIJ(ADO*=<-an`3zB4d*oO*8D1K!f
z*<txU<LU~pP7SiW&ptI|Ssyh1rN!%<&LcD}5;B1lVw_<Fz9i;*7Icnh+iR{wkbxFv
zHQ>A@P1bZCNtU=p!742MrAj%&5v%Xp_dSX@4YCw%F|%Dk=u|1BOmo)HsVz)nD5USa
zR~??e61sO(;PR)iaxK{M%QM_rIua9C^4ppVS$qCT9j2%?*em?`4Z;4@>I(c%M&#cH
z>4}*;ej<4cKkbCAjjDsyKS8rIm90O)Jjgyxj5^venBx&7B!xLmzxW3jhj7sR(^3Fz
z84EY|p1NauwXUr;FfZjdaAfh%ivyp+^!jBjJuAaKa!yCq=?T_)R!>16?{~<b2tOP~
z47Nm=L%=a2H5%-;PoTI9Zf8Q{gX)6FgL99Sq~HCCHEEWym2icXnIe}8P_;ArgG0CO
zf`4Rr(ciS_AIGt|OsCGh)=l12V2IHdqu&-WW<-O!NRu$)_PXwf_YA1=lIto-SBdBp
zc;mWJN=QE`GD!ww=QztESZcD3U_Jx*+2x>p)FQ3LDoMyG%hL#pR!f@P%*;#90rs_y
z@9}@r1BmM-SJ#DeuqCQk=J?ixDSwL*wh|G#us;dd{H}3*-Y7Tv5m=<O-p8_PlVR?L
zh4I(^CY;zbW$TKH9!Xrci9D`~7Tt_MnPoyJiw3E%9=)V8`no!#&SD?Z3i8z<VyM}0
zABD#E*H)<&R|%HW;*e1VGvE8RGjpVF<el}tkQ-ZH>bQJMcH+_S`zVtf;!0kt*(zwJ
zs+kedTm!A}cMiM!qv(c$o5K%}Yd0|nOd0iLjus&;s0Acvoi-PFrWm?+q9f^FslxGi
z6ywB`QpL$rJzWDg(4)C4+!2cLE}UPCTBLa*_=c#*$b2PWrRN46$y~yST3a2$7hEH=
zNjux+wna^AzQ=KEa_5#9Ph=G1{S0#hh1L3hQ`@HrVnCx{!fw_a0N5xV(iPdKZ-HOM
za)LdgK}1ww*C_>V7hbQnTzjURJL`S%`6nTHcg<XB+ozL*{rR!_$M~K9Ao~6H!H^=h
zwoacr(!lN?6COXY0RI?8^Y3)nD5dew#%KWle2X)4QJ|3aSbkvB3|XvJ4T7PtDp@RC
zL=FRTdKkZak;Ble+c&|%U<4_;=Pv@V_7`H`L@;$HHik1Cov%9Y?v|ejzhoH-_ORGg
z?z#NpZ8<kuALb{N_e(NeGkem>S+dB6b_;PY1FsrdE8(2K6<T$5h-ID+y%Pgc&YiJj
zQSx)n1qnTmVVNMYY68M{^SPS)&CE>FN>37!62j_cBlui{jO^$dPkGHV>pXvW0EiOA
z<TH9~Xay1oO$zQ#3a3<TF-+#*^SkQT;5{#&5>qW`YaSUBWg_v^Y5tPJfWLcLpsA8T
zG)<v7DAcVy#7Wn65S?qZDrUX35PlA`Aoi+&wVKj813Fm5$JK2HOhK_!#&jYh-6-UE
z?+!tn`6hPZXOsq_tvt7v))8yvK|C^QB-3YDBn&zFRg<%>!x>pKMpt!lv3&KV!-um=
zKCir6`bEL_LCFx4Z5bAFXW$g3Cq`?Q%)3q0r852XI*Der*JNuKUZ`C{cCuu8R8nkt
z%pnF>R$uY8L+D!V{s^9>IC+bmt<05h**>49R*#vpM*4i0qRB2uPbg8{{s#9yC;Z18
zD7|4m<9qneQ84uX|J&f-g8a|nFKFt34@Bt{CU`v(SYbbn95Q67*)_Esl_;v291s=9
z+#2F2apZU4Tq=x+?V}CjwD(P=U~d<=mfEFuyPB`Ey82V9G#Sk8H_Ob_RnP3s?)S_3
zr%}Pb?;lt_)Nf>@zX~D~TBr;-LS<1I##8z`;0ZCvI_QbXNh8Iv)$LS=*gHr;<k-Rm
zCOX3iwRBMS%2HbhB&55bKxXVrjksHaE!$yhFQVOkB9&b;RXWYu12Q{oZxRnIOVr=+
zV;u%|w58=ulh(mY=94oS*pT{cO%ppm(zvJWm<qAqWJ+tsD$mc#zQ-$!O_aUVS(xv&
zlic&3<NOINl%vfa(YE-09OenqqI00N?`6YZ&y5jRWu1$*;ND0xgkIT8GGJ<pZ_BqS
zfzf6E9oArEF5xqlU<TZaFS?_~jIlVR?u(-sg0I7Ln4&`lfjy*Sukl^_TcEsDm~(l}
z+s}VbwTMn&y0~O&Noc7}EK>}dgb=w5$3k2la1keIm|=7<-JD>)U%=Avl0Vj@+&vxn
zt-)`vJxJr88D&!}2^{GPXc^nmRf#}nb$4MMkBA21GzB`-Or`-3lq^O^svO7Vs~FdM
zv`NvzyG+0T!P8l_&8gH|pzE{N(gv_tgDU7SWeiI-iHC#0Ai%Ixn4&nt{5y3(GQs)i
z&uA;~_0shP$0Wh0VooIeyC|lak__#KVJfxa7*mYmZ22@(<^W}FdKjd*U1CqSjNKW%
z*z$5$=t^+;Ui=MoDW~A7;)Mj%ibX1_p4gu>RC}Z_pl`U*{_z@+HN?AF{_<AT&sf>W
z?M_X@o%w8fgFIJ$fIzBeK=v#*`mtY$HC3tqw7q^GCT!P$I%=2N4FY7j9nG8aIm$c9
zeKTxVKN!UJ{#W)zxW|Q^K!3s;(*7Gbn;e@pQBCDS(I|Y0euK#dSQ_W^)sv5pa%<^o
zyu}3d?Lx`)3-n5Sy9r#`I{+t6x%I%G(iewGbvor&I^{lhu-!#}*Q3^itvY<Y65Bs!
z6}9J&T3Jmx%Jeo0UA1RUWfC4^3~`bOw#&=(RdYfoBOtonl9x?Q%%ud_8xGfac}V3S
z_t?8@P9D{AMY+HQj#M?0#<Loprwk<zPs3>(^UWXgvthH52zLy&T+B)Pw;5>4D6>74
zO_EBS)>l!zLTVkX@NDqyN2cXTwsUVao7$HcqV2%t$YzdAC&T)dwzExa3*kt9d(}al
zA~M}=%2NVNUjZiO7c>04YH)sRelXJYpWSn^aC$|Ji|E13a^-v2MB!Nc*b+=KY7MCm
zqIteKfNkONq}uM;PB?vvgQvfKLPMB8u5+Am=d#<Ofl>>g+o&Ys<k|1Ag^|(Lcq#YS
zJ3m+ShjMEKKXbb?#zc6~_{8T^k&I4kx<j?2OLnw(e9?2R%ab*KIh|OcYkV*-ppCU+
z&<4=VL>b>dX9EC8q?D$pJH!MTA<fJX`-o>qa=DS5$cb+;hEvjwVfF{4;M{5U&^_+r
zvZdu_rildI!*|*A$TzJ&apQWV@p{!W`=?t(o0{?9y&vM)V)ycGSlI3`;ps(vf2PUq
zX745#`cmT*ra7XECC0gKkpu2eyhFEUb?;4@X7weEnLjXj_F~?<g~DII^Bcx&poTYi
zLVuwObActGKn>OzL1U1L0|s6M+kIhmi%`n5vvDALMagi4`wM<y{<R6>c=JV{XiO+^
z?s9i7;GgrRW{Mx)d7rj)?(;|b-`iBNPqdwtt%32se@?w4<^KU&585_kZ=`Wy^oLu9
z?DQAh5z%q;UkP48jgMFH<isTC5e=i>Tf#m<K<awZyB<dC!4ZWVVj?0l^>j?#z|=w=
z(q6~17Vn}P)J3M?O)x))%a5+>TFW3No~TgP;f}K$#icBh;rSS+R|}l&#X9BCa%1Et
zwk~hMkhq;MOw^Q5`7oC{CUUyTw9x>^%*FHx^qJw(LB+E0WBX@{Ghw;)6aA-KyYg8p
z7XDveQOpEr;B4je@2~usI5BlFadedX^ma{b{ypd|RNYqo#~d*mj&y`^iojR}s%~vF
z(H!u`yx68D1Tj(3(m;Q+Ma}s2n#;O~bcB1`lYk%Irx60&-nWIUBr2x&@}@76+*zJ5
ze&4?q8?m%L9c6h=J$WBzbiTf1Z-0Eb5$IZs>lvm$>1n_Mezp*qw_pr8<8$6f)5f<@
zyV#tzMCs51nTv_5ca`x`yfE5YA^*%O_H<xfnQ6>?;tWYdM_kHPubA%vy47i=9>Bq)
zRQ&0UwLQHeswmB1yP)+Bi<gYuF=;5%P5fb($ua)vN{<dTS}pc$-noYj&~P(-vz}$v
zu3jpy02nRu2m5&K8!o)7k}0wq<;X00@Xx7A<mINk!<+VpN#`s2^mC5Ofe4$`&tl#*
z>R;S+Vc-5TX84KUA;8VY9}yEj0eESSO`7HQ4lO<y)w_Q~B}%2$aGK(6Ummn<`kl%;
z`ex#21X!9UBm3Vc-U~%seDuubCS=6He};CM149#aL;PRFuT<U<#xD2*e6V!HB9TS@
z-1@gJDr5k3GW(TMRP`M0C}32Sp)@iN+m7Q7FVkR-!Q93t0T{<wiGM)0t%$WJc@v;>
z4(CyA8y1G7_C;6kd4U3K-aNOK!sHE}KL_-^EDl(vB42P$2Km7<xlD85HX*0-hkMZF
zkjr5ZvT-#;Mth(cu<tj#atu~`yerH!&_Rq;m6S6;E=E^t8E;_e)$<aCEe^z9S}-Gm
zR}d6r*AN)OHk0vR$wldVl&!rNQoW*!$WBpDRw`=6+$-g54384TvT>$WGqNy=%fqB+
zSLdrlcbEH=T@W8V4(TgoXZ*G1_aq$K^@ek=TVhoKRjw;HyI&coln|uRr5mMOy2GXP
zwr*F^Y|!Sjr2YQXX(Fp^*`Wk905K%$bd03R<H!tySet(EP)5Lj`0&gFCZ@coqtHFV
zq;TC+Ud)isOY`?v*vYVa0u2u<OuzeQhQx-th#lEeb|E85m0u7j#xz<Q(27O50YNZG
z_X!_ZeKj36XsF4fNkWJ-X&&`{PiP|d5I{)ntoL7!_lyc3!C3?s@K?fxx2uj~W~|6a
z@37XYDSt)e<cy5Hg6yFElSnilL`l_9#54dfOVI=v!_cyZ8P0}j&eAUCbFyagF03t)
ziN>4(igl0&7IIm*#f`A!DCarW9$h$z`kYk9MjjqN&5-DsH@8xh63!fTNPxWsFQhNv
z#|3RjnP$Thdb#Ys7M+v|>AHm0BVTw)EH}>x@_f4zca&3tXJhTZ8pO}aN?(dHo)44Z
z_5j+YP=jMlFqwvf3lq!57-SAuRV2_gJ*wsR_!Y4Z(trO}0wmB9%f#jNDHPdQGHFR;
zZXzS-$`;7DQ5vF~oSgP3bNV$6Z(rwo6W(U07b1n3UHqml>{=6&-4PALATsH@Bh^W?
z)ob%oAPaiw{?9HfMzpGb)@Kys^J$CN{uf*HX?)z=g`J(uK1YO^8~s1(ZIbG%Et(|q
z$D@_QqltVZu9Py4R0Ld8!U|#`5~^M=b>fnHthzKBRr=i+w@0Vr^l|W;=zFT#PJ?*a
zbC}G#It}rQP^Ait^W&aa6B;+0gNvz4cWUMzpv(1gvfw-X4xJ2Sv;mt;zb2Tsn|kSS
zo*U9N?I{=-;a-OybL4r;PolCfiaL=y@o9{%`>+&FI#D^uy#>)R@b^1ue&AKKwuI*`
zx%+6r48EIX6nF4o;>)zhV_8(IEX})NGU6Vs(yslrx{5fII}o3SMHW7wG<xJ7RkURX
zL?-%U*5SbEvYh>tK9oIO4OM&@@ECtXSICLcPXoS|{;=_yj>hh*%hP27yZwOmj4&Lh
z*Nd@OMkd!aKReoqNOkp5cW*lC)&C$P?+H3*%8)6HcpBg&IhGP^77XPZpc%WKYLX$T
zsSQ$|ntaVVOoRat$6lvZO(G-QM5s#N4j*|N_;8cc2v_k4n6zx9c1L4JL*83F-C1Cn
zaJhd;>rHXB%%ZN=3_o3&Qd2YOxrK~&?1=UuN9QhL$~OY-Qyg&})#ez*8Np<qwhY!r
zPGi5Uv36_KU&P;Ysny7Yn7Aq*w^YJk+j;r5!{54y2KTRW=n4P9Q$RrUV@IzXwTG1s
zzW93%6>QW_*<cOtWE@YNsI)L#ntpV!%&tkEA2b<G(kTCfol|w3coc&So$?P2SFmWk
zBWp7V`+IlUb`e$B*<dRPJ-ehhZQ$M{k7#onRlEE~dw{L=-9ElX-V5A(;-ZBE+Yf{^
z{+-Mf7yUbWUdboXPA1sh*z~xCt^6m6c{6_JCok9HQbYRhr51?*l;sOM;AIxuJ4Q$p
z`CgAJ+<9O64PUJ^k}^%FQclq}Wk!;S2TZ^{;?u15<et5AgcPi>a&kD&ANjedxT0Ar
z<6r{eaVz3`d~+N~vkMaV8{F?RBVemN(jD@S8qO~L{rUw#=2a$V(7rLE+kGUZ<%pdr
z?$DP|Vg#gZ9S}w((O2NbxzQ^zTot=89!0^~hE{|c9q1hVzv0?YC5s42Yx($;hAp*E
zyoGuRyphQY{Q2ee0Xx`1&lv(l-SeC$NEyS~8iil3_aNlnqF_G|;zt#F%1;J)jnPT&
z@iU0S;wHJ2$f!juqEzPZeZkjcQ+Pa@eE<F$7REzl$4Vg!h~1-QZGdPJ^bJ@K4OS*c
zP-fR4iXy^QA;#1=y2VI*LRPhjykLV({@6o-twx$xfBE}QnTt6vqFElm=UM-(NfZCi
z=lx&9)JZKEFO|hbLCVw#&(sbpFfqulk`VBkNi?$lD5(B0WM5ff*mCA1f5%740p~O|
ztQOb8UFr=BBea^EKn!z+v}nk*YvS7NtKQ8K+R4>RSLKsWf=`{R@yv7AuRh&ALRTAy
z8=g&nxsSJCe!QLchJ=}6|LshnX<g_y(YX??7D<ya@4%V<9h+|Ic_N&p+^6cL1%rRw
zI`_<$r7i-QeU%G7oxJ6b$}<GVE+7g7j;H#VPbD7FMNK~{pfkqz8k&Qk100>IK)SNd
zRkJNiqHwKK{SO;N5m5wdL&qK`v|d?5<4!(FAsDxR>Ky#0#t$8XCMptvNo?|SY?d8b
z`*8dVBlXTUanlh6n)!EHf2<Z;<pqvCOZ=A2H>&PDG8sXNAt6~u-_1EjPI1|<=33T8
zEnA00E!`4Ave0d&VVh0e>)Dc}=FfAFxpsC1u9ATfQ`-Cu;mhc8Z>2;uyXtqpLb7(P
zd2F9<3cXS<T6BO6%Wff4)w8RK^!PZ}fJ&%B?D(O0phg;sxkMq1g;&s2yVy|dlo7$&
zut6p%Pt5t7R%%o@lpz7mamy48(tCjGd57eFCrjgxV_IjQOo{Eq=LdqW@am;MINbXP
zIQr$cxXwNaQ_H6v`p4(aUBXrmz}**&%<Zzfbtj+pDbBMu#7x_{KfkOxH1}OCyx<aM
zu@SXrn_{seG?|N7mo)o<BmjNPRWwBLiQLKA5vhgn!8ZTe76=gv#-hh7?ex$Xtz9>}
znMg?{&8_YFTGRQZEPU-XPq55%51}RJpw@LO_|)CFAt62-_!u_Uq$csc+7|3+TV_!h
z+2a7Yh^5AA{q^m|=KSJL+w-EWDBc&I_I1vOr^}P8i?cKMhGy$CP0XKrQzCheG$}G#
zuglf8*PAFO8%xop7KSwI8||liTaQ9NCAFarr~psQt)g*pC@9bORZ>m`_GA`_K@~&%
zijH0z;T$fd;-Liw8%EKZas>BH8nYTqsK7F;>>@YsE=Rqo?_8}UO-S#|6~CAW0Oz1}
z3F(1=+#wrBJh4H)9jTQ_$~@#9|Bc1Pd3rAIA_&vOpvvbgDJOM(yNPhJJq2%PCcMaI
zrbe~toYzvkZYQ{ea(Wiyu#4WB#RRN%bMe=SOk!CbJZv^m?Flo5p{W8|0i3`hI3Np#
zvCZqY%o258CI=SGb+A3yJe~J<XAm<h+@x%=dk!>H^i{uU`#U#fvSC~rWTq+K`E%J@
zasU07&pB6A4w3b?d?q<ZUdN`d9`jSQ6}@hE_t>}2=0rA#SA7D`X+zg@&zm^iA*HVi
z009#PUH<%lk4z~p^l0S{lCJk1Uxi=F4e_DwlfHA`X`rv(|JqWKAA5nH+u4Da+E_p+
zVmH@lg^n4ixs~*@gm_dgQ&eDmE1mnw5wBz9Yg?QdZwF|an67Xd*x!He)Gc8&2!urh
z4_uXzbYz-aX)X1>&iUjGp;P1u8&7TID<T*k)hrSs$ZMYU#eY?f%J<TYM`ZV5WD$80
zG6we^sim<v0ffzyR3HV@k#_?T5yB1?r-E~gnJ!jx=#l~KWX=|*TsGqUMbMy7&Dlm$
zkg`~ug9}A)NTCqAmF?i{?tn%$xnbe}sXgn0Ns#1Tz9yxnXess97ti7|9c?mVx|E|M
zsw|@!R#sWRksSuwE0qkq{xVpVBsF7Y5`nBxFc=Vb@S*=tu3_rkiM*j^3$OH{X3IB$
zsB0-+Fdr>0bTH-jCL&Xk8b&<MC!nk<L_l*|?aq$M0{!H9`RQ21GGD+c^BcX*2|SYI
zugFZ`gqDwwr<(%$82O_6nOWDm!eA(RGpBfa<+B;MKzgz`W@E7E&XQR*%r|=RjJ(AQ
z1GcBC!v)wKu_J~RfHh}+ZjQp_Xx>;;6p2op_=y^m@Nq*0{#o!!A;wNAFG@0%Z9rHo
zcJs?Th>Ny6+hI`+1XoU*ED$Yf@9f91m9Y=#N(HJP^Y@ZEYR6I?oM{>&Wq4|v0IB(p
zqX#Z<_3X(&{H+{3Tr|sFy}~=bv+l=P;|sBz$wk-n^R`G3p0(p>p=5ahpaD7>r|>pm
zv;V`_IR@tvZreIuv2EM7ZQHhO+qUgw#kOs%*ekY^n|=1#x9&c;Ro&I~{rG-#_3ZB1
z?|9}IFdbP}^DneP*T-JaoYHt~r@EfvnPE5<mj|3vYvi%XA!0DTe17}~aG2h7eq*~r
z9|l2u19&ExDJOsRZ$@8=z;;HhZw$_SviSm}uAwc_ow2rT=iX2K1>EKUwIxjPbsr$%
zfWW83pgWST7*B(o=kmo)74$8UU)v0{@4DI+ci&%=#90}!CZz|rnH+Mz=HN~97G3~@
z;v5(9_2%eca(9iu@J@aqaMS6*$TM<otkyEUfDAtMmVO5=3I}?EG6T26ue>w!S>H(b
z4(*B!|H|8&EuB%mITr~O?vV<E-8Z6S)k5lzkIaVLJC566nZk>Ef%(Gr)6E=>H~1VR
z&1YOXluJSG1!?TnT)_*YmJ*o_Q@om~(GdrhI{$Fsx_zrkupc#y{DK1WOUR>tk>ZE)
ziOLoBkhZZ?0Uf}cm>GsA>Rd6V8@JF)J*EQlQ<=JD@m<)hyElXR0`pTku*3MU`HJn|
zIf7$)RlK^pW-$87U;431;<klhG5_ER>Ye4Ie+l~_B3*bH1>*yKzn23cH0u(i5pXV!
z4K?{3oF7ZavmmtTq((wtml)m6i)8X6ot_mrE-QJCW}Yn!(3~aUHYG=^fA<^~`e3yc
z-NWTb{gR;DOUcK#zPbN^D*e=2eR^_!(!RKkiwMW@@yYtEoOp4XjOGgzi`;=8<Yusf
zN5l6kO$1L;ws<m1`Zh#?`63unV{T(2V21gcCYV&FhZqe6Nass1MK|Z4KyXbkzmY5}
zZ?_?UexvC&zoC0o1N+Vde1)9v5Lgfss-n~Y`wrFPCpU&f2y~X5VS8!)_$jxG?x+Q>
zi3`Ccw1%L*y(FDj=C7Ro-V?q)-%p?Ob2ZElu`eZ99n14-ZkEV#y5C+{Pq87Gu3&>g
zFy~Wk7^6v*)4pF3@F@rE__k3ikx(hzN3@e*^0=KNA6|jC^B5nf(XaoQaZN?Xi}Rn3
z$8&m*KmWvPaUQ(V<#J+S&zO|8P-#!f%7G+n_%sXp9=J%Z4&9OkWXeuZN}ssgQ#Tcj
z8p6ErJQJWZ+fXLCco=RN8D{W%+*kko*2-LEb))xcHwNl~Xmir>kmAxW?eW50Osw3#
zki8Fl$#fvw*7rqd?%E?}ZX4`c5-R&w!Y0#EBbelVXSng+kUfeUiqofPehl}$ormli
zg%r)}?<O#LIQ<x^r>%=?_pHb9`Cq9Z|B`L8b>(!+8HSX?`5+5mm81AFXfnAt1*R3F
z%b2RPIacKAddx%JfQ8l{3U|vK@W7KB$CdLqn@wP^?azRks@x8z59#$Q*7q!KilY-P
zHUbs(IFYRGG1{~@RF;Lqyho$~7^hNC`NL3kn^Td%A7dRgr_&`2k=t+}D-o9&C!y^?
z6MsQ=tc3g0xkK(O%DzR9nbNB(r@L;1zQrs8mzx&4dz}?3KNYozOW5;=w18U6$G4U2
z#2^qRLT*Mo4bV1Oeo1PKQ2WQS2Y-hv&S|C7`xh6=Pj7MNLC5K-zokZ67S)C;(F0Dd
zloDK2_o1$Fmza>EMj3X9je7e%Q`$39Dk~GoOj89-6q9|_WJlSl!!+*{R=t<I5W)Q1
zkAGZ6mVbAZdwNx+cM^(`G%H7T29zgao{aSHP_2`opHKbyoo@LZV-ND6*ct<1X->Gp
z8u|MuSwm^t7K^nUe+^0G3dkGZr3@(X+T<R{A2|{q4h1HZkio;YA1t6>L5eah)K^Tn
zXEtHmR9UIaEYgD5Nhh(s*fcG_lh-mfy5iUF3xxpRZ0q3nZ=1qAtUa?(LnT9I&~uxX
z`pV?+=|-Gl(kz?w!zIieXT}o}7@`QO>;u$Z!QB${a08_bW0_o@&9cjJUXzVyNGCm8
zm=W+$H!;_Kzp6WQqxUI;JlPY&`V}9C$8HZ^m?NvI*JT@~BM<?RV=J&{dty%0kuvcV
zvDY*i(P?K=6~(~xZAsj_c^PMb&#Z`Y|Lurd8fSVQU$p5WH?x?Xpj)rsBdv*QxJ##A
zM=~|M*Y>=()T()Ii#+*$y@lTZBkmMMda><ZXF}$122DAC4inciHEXN*L_tT(?E|%+
zt7Py*&-=;dUzJ7C=EUZz8ph9x9vB|ACLKw@s&c^<^F0YA3k;p}2F-(+6L*|cO&Kx|
zGV=>7s#O(1YZR+zTG@&<R7(G2<E$<wduz9!FnD8M=}U%cAl$d*6}Sq3Sm>}!EXFG{
zEWPSDI5bFi;NT>Yj*FjH((=oe%t%xYmE~AGaOc4#9K_XsVpl<4SP@E!TgC0qpe1oi
zNpxU2b0(lEMcoibQ-G^cxO?ySVW26HoBNa;n0}CWL*{k)oBu1>F18X061$SP{Gu67
z-v-Fa=Fl^u3lnGY^o5v)Bux}<gD3`?Qhv)PX)U=^-kffCXQ$p2csKZNM5x8!RMUOX
zrn9?t`{WKqC0A+hrI3CS?R@viwL~gPCU^BRur-hw0CEwaK7f#%S}_w7_H%2lZVcgk
zQL;J=ry;kmi}ZUr-!!m`rCH2ERpwJ6Q|G`5r-Xy0r?6;<g{<5%zr{9CmP^vf>bNZ~
z5pL+7F_Esoun8^5>z8NFoIdb$sNS&xT8_|`GTe8zSXQzs4r^<Z>g0kZjg(b0b<J|)
z&kyXHVzP24v$IxevEHN?k6>Jvz`g<70u9Z3fQILX1Lj@;@+##bP|FAOl)U^9U>0rx
zGi)M1(Hce)LAvQO-pW!MN$;#ZMX?VE(22lTlJrk#pB0FJNqVwC+*%${Gt#r_tH9I_
z;+#)#8cWAl?d@R+O+}@1A^hAR1s3UcW{G+>;X4utD2d9X(jF555}!TVN-hByV6t+A
zdFR^aE@GNNgSxxixS2p=on4(+*+f<8xrwAObC)D5)4!z7)}m<cS(iD4<A0N$g+SqA
zl%O;ERC__&2rvP%TMdpBGey$+i_(aSuJSoOVG@%hWSWo?*uZz-46eyt;fOY4@j*cs
z(Nlf$ie?ANAv6K4_-a2q*kk+$A3)y-+s^rqkRC|T=Yj2fF?eZ}!9uZg3msy525K;C
zG$r&@M9n%7`Sgm&aIl}13Vz%ip9hGWt!og5bdx1qTG)j2nL>Tpb7&ofF3u&9&wPS<
zB62WHLGMhmrmOAgmJ+|c>qEWTD#jd~lHNgT0?t-p{T<Fhnjc^O*n1^SI<&BNNFb%X
zHxbuJadh!4YtYH|wpEljX5ubnIb*m`KO@(XQ|K!ErMf$l_=~Nst8I^_;~LFMY;jPd
z>=~#E<K9VH{%))?p1uEh9GO_D_^6?&!kOhc5(&300G7)A4!13Ozm(lvh<tIpVpv;w
z$Zq4R)GbGst(09X1uL^1TcWYOO$_QS5|?mAC8?<QY1GusEAbgtUMGPRN?~sU>McB|
z=AoDKOL+qXCfk~F)-Rv**V}}gWFl>liXOl7Uec_8v)(S#av99PX1sQIVZ9eNLkhq$
zt|qu0b?GW_uo}TbU8!jYn8iJeIP)r@;!Ze_7mj{AUV$GEz6bDSDO=D!&C9!M@*S2!
zfGyA|EPlXGMjkH6x7OMF?gKL7{GvGfED=Jte^p=91FpCu)#{whAMw`vSLa`K#atdN
zThnL+7!ZNmP{rc=Z>%$meH;Qi1=m1E3Lq2D_O1-X5C;!I0L>zur@tPAC<By>9*7<!
z3r5ih2IB%6&?*r6Z<C9~bdv;$Jz)vwe<Nu0(L5l%QJ@HdxjvyfFnvb*!a}9oGNK6E
zqHxM7juWe=SSnY{v&Q7EoMOb}E}wD)CsC?77@`e0AQsRgp-@%+t|BGqN=<`p&67Ay
z|1Ca)Xw?J?`0+tpDJa4VbOI+nCoMRhc94J)*YTm*Cvm6NKcmS0S8lEaP@BDlDO2j!
z3B#9mbQbob%QSF`NGB1uJE%GFPC5TQVb=AS_#@8Xn3od@{x#f5jU7spPqbI@;gM2n
zy<$hk+Hy??zt_V4Zq9&R;7&^l#vS@`iD+}{y4jLIDKXTJNC<QY9H?-HD>Je<e@N~V
zM8{whHc_Y)oJRTaE@}6XBK;XqJh6DOZ%b~};oF1$Ja8>h)`;eec}1`nkRP(%iv-`N
zZ@ip-g|7l6Hz%j%gcAM}6<zu1Fy2Y69l>-nrC8oA$BkOTz^?dakvX?`^=ZkYh%vUE
z9+&)K1UTK=ahYiaNn&G5nHUY5niLGus@p5E2@RwZufRvF{@$hW{;{3QhjvEHMvduO
z#Wf-@oYU4ht?#uP{N3utVzV49mEc9>*TV_W2TVC`6+oI)zAjy$KJrr=*q##&kobiQ
z1vNbya&OVjK`<C+)|Y=S6qD0g+yj}rJu+*{Nv+8EH`6C*w=QvJZy_0aJA=(RR*FuE
z=Ve*%{0>2pdRr<aX@8G=KRVz8TtomBSpcq@r(_ajX~o2yoaeZ}oez2h)8-QBk)?}3
z07=L4P3BU4*%bpPu*ZY*FM)E8NlN*R9eF#VQ}7$t%LL}o3#|L+gi2ok?oW7%M=|~p
zC5<%;sq@8S<pakq(618P52%D<(#5rYl@k)nhPsY1k)aFy(uH>M?LuK6BgrLN7H_3m
z!qpNKg~87XgCwb#I=Q&0rI*l$wM!qTkXrx1ko5q-f;=R2fImRMwt5Qs{P*p^z@9ex
z`2#v(qE&F%MXlHpdO#QEZyZftn4f05ab^f2vjxuFaat2}jke{j?5GrF=WYBR?gS(^
z9SBiNi}anzBDBRc+QqizTTQuJrzm^bNA~A{j%ugXP7McZqJ}65l10({wk++$=e8O{
zxWjG!Qp#5OmI#XRQQM?n6?1ztl6^D40hDJr?4$Wc&O<sMJO3^;cmzln7W^zYPW<c)
z|Nn)@|5@a8iRp(7<VO~{rdqT_5uSV!nd9F~6^REIQGA!cD-9=NGWybr;?0kXWZrN^
z3+v>_{*OfMfxe)V0=e{|N?J#fgE>j9jA<EEh|%C%>ajze$iN!*yeF%jJU#G1c@@rm
zolGW!j?W6Q8pP=lkctNFdfgUMg92wlM4E$aks1??M$~WQfzzzXtS)wKrr2sJeCN4X
zY(X^H_c^PzfcO8Bq(Q*p4c_v@F$Y8cH<tNdh?t1Gk+qA{Pne*ng|&%*k<pK?D`Q}5
zVD>LrH$`pJ2}=#*8%JYdqsqnGqEdBQMpl!Ot04tUGSXTQdsX&GDtjbWD=prcCT9(+
z&UM%lW%Q3yrl1yiYs;LxzIy>2G}EPY6|sBhL&X&RAQrSAV4Tlh2nITR?{6xO9ujGu
zr*)^E`>o!c=gT*_@6S&>0POxcXYNQd&HMw6<|#{eSute2C3{&h?Ah|cw56-AP^f8l
zT^kvZY$YiH8j)sk7_=;gx)vx-PW`hbSBXJGCTkpt;ap(}G2GY=2bbjABU5)ty%G#x
zAi07{Bjhv}>OD#5zh#$0w;-vvC@^}<H!J~9x8ns3P(-h{dr(SdVxo7mkj}AsjC5HV
zo6g6-m3quL?mvNQgld&;Wk&NDE-R7EZ)*~rtG<Lq_zyu{lXW&{xOyIFvsws8eo>F!
z#X$@)zIs1L^E;2xDAwEjaXhTBw2<{&JkF*`;c3<1U@A4MaLPe{M5DGGkL}#{cHL%*
zYMG+-Fm0#qzPL#V)TvQVI|?_M>=zVJr9>(<nvsf&9hvsWr%#7CsQ**Fe-0<7veWn*
zbd^GxM~>6ib*#z8q@mYKXDP`k&A4A};xMK0h=yrMp~JW{L?mE~ph&1Y1a#4%SO)@{
zK2juwynUOC)U*hVlJU17%llUxAJFuKZh3K0gU`a<X-1W{<+F6zY3jg>P)pc~b<Vo8
zn2YAtCd;B0Avz@7p^Po{xMRCQYS{JVW8Z`GH$zG=#SS&KZ2A$u^x!Isx6mLPi?<ZN
z*{kt-YdG0}`9!9hbnjn<=b=7lTPuWEpF+k^SZAjar2B<DQb{uEO;vTv3FqIDI3!LU
zvasv6BD^}y#db_7<6NwPQSk6X)=~uy$Zd95xS~u)s@;O!EALmaQ@kYB`EY75*h2)s
z-R#8r)o{~&P%kZgz*(Kw!pn_O3rshJwHWRYI|!$r!a4#|kLw{Kz&k3CZ#RtrYB!Yu
z*A++a?kRokM)%Uo3N_uT!~ugsw#&4oIID7K+!k+)I;<)Si^E{(i)cD@HTao5;+q!0
zbwB*KzCL0ZC~g-PH7MbBVgTO07?^K#9=bcG8FQEIE=(6id^)U|^hS5OYQT5$J-!Sa
zBvfO%E+b9eID~Xvvo@#oSJO3E?jiXTQ<upuXRYN+dqAs$<{%yP2cnwB9G5^{RErN2
z5a`n%B*&Qd&SoW|&P~{87+q;P_bbKnMD-j91aHnUm-Ol<>E~mM!i1mi!~LTf>1Wp<
zuG+ah<cN%^mGc@zm->p^gH8g8-M$u{HUWh0m^9Rg@cQ{&DAO{PTMudV6c?ka7+AO&
z746QylZ&Oj`1aqfu?l&zGtJnpEQOt;OAFq19MXTcI~`ZcoZmyMrIKDFRIDi`FH)w;
z8+*8tdevMDv*VtQi|e}CnB_JWs>fhLOH-+Os2Lh!&)Oh2utl{*AwR)QVLS49iTp{6
z;|172Jl!Ml17unF+pd+Ff@jIE-{Oxv)5|pOm@CkHW?{l}b@1>Pe!l}VccX#xp@xgJ
zyE<&ep<?&Ja!<vf;^Rc_Ext&<l)$GW^vhyI+JCe2O3`LUd|)s%0qsYi2%EvJz-tM3
zKY=mZW?7k^N!wTSw*{;yb$3mRD9vNKYL6QIU4KGF{JZXpqeFF?UNh<Hsu=#~nZ?*`
z8?`-sY#3wWljoYqahkg_LR+fxC=Ok@srcz_lf5JG(Aw?<nC(WNHZ^iNeqvbZ784f|
zUF|zFa%ZSkIT}iZS*J5%>$=*vT=}7vtvif0B?9xw_3Gej7mN*dOHdQPtW5kA5_zGD
zpA4tV2*0E^OUimSsV#?Tg#oiQ<Gc63Xnq8{B?9(QSV36W&7QYB_fY=P6DiK#CwX}S
zgr8jyAKT1k<~JoNlpe8K#uDWD6A;w{rqu&jtmBFgY_BM6uK=HK6yOqhbD)4G&d4Zx
zgx}5JZQcjx2iiz|qys{K@f>>%4D@1F5@AHwT8Kgen$bSMHD3sXCkq8^(uo7CWk`mT
zuslYq`6Yz;L%wJh$3l1%SZv#QnG3=NZ=BK4yzk#HAPbqXa92;3K5?0kn4TQ`%E%X}
z&>Lbt!!QclYKd6+J7Nl@xv!uD%)*bY-;p`y^ZCC<%LEHUi$l5biu!sT3TGGSTPA21
zT8@B&a0lJH<Is)g$je?v)zrGnVnN*a?`1A_B7jSFYFL!G^YdU54T8BJ`&=Grt0wbK
zm=GTh#mq0;L&QL~1)M*45{rzjOV&&Ibr2i!Ltb})&Q3g>Vn1I$I3I1I{W9fJAYc+8
zVj8>HvD}&O`TqU2AAb={?eT;0hyL(R{|h23=4fDSZKC32;wWxsV<K&5XXRr5uQ}LF
z+0CB-DJWvs=zyhUDM(~V3gV_A(2WHskwSfbLhWS!Vr~&q4bY$lqS1mvz2zv7a&eyv
zq27v0&hua?e7Hjc)2G9WDUS0kzHi?zAo?IsP=#m-cTywmevo}cL`cE(<Xi1(J>j`P
z3J3{M$PwdH!ro*Cn!D&=jnFR>BNGR<<|I8CI@+@658Dy(lhqbhXfPTVecY@L8%`3Q
z1Fux2w?2C3th60jI~%OC9BtpNF$QPqcG+Pz96qZJ71_`0o0w_q7|h&O>`6U+^BA&5
zXd5Zp1Xkw~>M%RixTm&OqpNl8Q+ue=92Op_>T~_9UON?ZM2c0aGm=^A4ejrXj3dV9
zhh_bCt-b9`uOX#cFLj!vhZ#lS8Tc47OH>*)y#{O9?AT~KR9LntM|#l#Dlm^8{nZdk
zjMl#>ZM%#^nK2TPzLcKxqx24P7R1FPlBy7LSBrRvx>fE$9AJ;7{PQm~^LBX^k#6Zq
zw*Z(zJC|`!6_)EFR}8|n8&&Rbj8y028~P~sFXBFRt+tmqH-S3<%N;C&WGH!f3{7cm
zy_fCAb9@HqaXa1Y5vFbxWf%#zg6SI$C+Uz5=CTO}e|2fjWkZ;Dx|84Ow~bkI=LW+U
zuq;KSv9VMboRvs<muUdEos4J@28PT^*5txvGZbKDaszyz$QdH{051B8A}wS50ihLR
z^}*xLvwA_M{Vi%9v2EHPcjW2dClsn~)MPlr{(wj9a}gF+Q-M)HC}0<xaSL~ZQN-$F
z7pVo2NF$PZ!~7c5`YO~K2nWlk*2_#MS>9)}2PAO|b(JCEC_A0wq{uEj|3x@}*=bOd
zwr{TgeCGG>HT<@Zeq8y}vTpwDg#UBvD)BEs@1KP$^3$sh&_joQPn{hjBXmLPJ{tC)
z*HS`*2+VtJO{|e$mM^|q<Nl<aNnR+M;uGuLoy^|5_yMTrUl*Jc;J-xFCNFUlNS9`1
z>v1R*8i(m1`%)}g=SU#T#0KlTM2RSvYUc1fP+va|4;5}Bfz98UvDCpq7}+SMV&;nX
zQw~N6qOX{P55{#LQkrZk(e5YGzr|(B;Q;ju;2a`q+S9bsEH@i1{_Y0;hWYn1-79jl
z5c&bytD*k)GqrVcHn6t-7kinadiD>B{Tl`ZY@`g|b~pvHh5!gKP4({rp?D0aFd_cN
zhHRo4dd5^S6ViN(>(28qZT6E>??aRhc($kP`>@<+lIKS5HdhjVU;>f7<4))E*5|g{
z&d1}<wI2Yxf4k?!umu<cm>D|vpuV^eRj5j|xx9nwaCxXFG?Qbjn~_WSy=N}P0W>MP
zG-F%70lX5Xr$a)2i6?i|iMyM|;Jtf*hO?=Jxj12oz&>P=1#h~lf%#fc73M2_(SUM-
zf&qnjS80|_Y0lDgl&I?*eMumUklLe_=Td!9G@eR*tcPOgIShJipp3{A10u(4eT~DY
zHezEj8V+7m!knn7)W!-5QI3=IvC<r`G1r;-#=KH#^bDsbD^<>^as5+TW1@Ern@yX|
z7Nn~xVx&fGSr+L%4iohtS3w^{-H1A_5=r&x8}R!YZvp<2T^YFvj8G_vm}5q;^UOJf
ztl=X3iL;;^^a#`t{Ae-%5Oq{?M#s6Npj+L(n-*LMI-yMR{)qki!~{5z{&`-iL}lgW
zxo+tnvICK=lImjV$<vu==Ri_*yyu6*srp=+w%VMI++>Z|O_c<d`u5Z43azu#^&ypv
z2XQf<KjK;)X-?wB*Sewpf;vW`6)cGyqY0^Kmt<sX6AgDavh{KfTqndPyGjf#w5CPH
zd5wvsmzb)a>Yj_PlEYCzu-XBz&XC-JVxUh9;6*z4fuBG+H{voCC;`~GYV|hj%j_&I
zDZCj>Q_0RCwFauYoVMiUSB+*Mx`tg)bWmM^SwMA+?lBg12QUF_x2b)b?qb88K-YUd
z0dO}3k#QirBV<5%jL$#wlf!60dizu;tsp(7XLdI=eQs?P`tOZYMjVq&jE)qK*6B^$
zBe>VvH5TO>s>izhwJJ$<`a8fakTL!yM^Zfr2hV9`f}}VVUXK39p@G|xYRz{fTI+Yq
z20d=)iwjuG9RB$%$^&8#(c0_j0t_C~^|n+c`Apu|x7~;#cS-s=X1|C*YxX3ailh<R
zTW0JnWEDqjPC~D*L>g_|0`g!E&GZJEr?bh#T<kIti^!4|N+ecge$#dzW2oYeVA6W^
zTf=2ts!v<D6N@P&^Yk^QSZQdun$SpPGW!lb8i(GI;CLFfP&>pb8siR=JxWKc{#w7g
zWznLwi;zLFmM1g8V5-P#RsM@iX>TK$xsWuujcsVR^7TQ@!+vCD<>Bk9tdCo7Mzgq5
zv8<xjOE`)Xl$&nfKK_(a*GxWq=IP<8*TsiQ<?73@Fo<n&f=T#zZE61~c1WExC#Z*C
zBR?0KIU<_708sM|Ni}WhSK@G4$2@TsRGI0k6P~Edb~#f7+1%73{4^^R;XGADxxf+k
zSKP@Qw?N!!n%j~Ps{Av<y>d>dK9x8C@Qoh01u@3h0X_`SZ<H1Jt*l+r%vhj38gu7(
zi%Y(Yu(yCRu7j&QPtzY&|NIVK<{aX%!5|>luTb@5o;{4{{eF!-4405x8X7hewZWpz
z2qEi4UTiXTvsa(0X7kQH{3VMF>W|6;6iTrrYD2fMggFA&-CBEfSqPlQDxqsa>{e2M
z(R5PJ7uOooFc|9GU0ELA%m4&4Ja#cQpNw8i8ACAoK6?-px+oBl_yKmenZut#Xumjz
zk8p^OV2KY&?5MUwGrB<d@yk90?8kfe*7#9+-#&)Q0>Oo?ki`Sxo#?-Q4gw*Sh0k`@
zFTaYK2;}%Zk-68`#5DXU$2#=%YL#S&<HGFJsB^*5Aw|=c;4ki9<qCK7e%Vj(VHL~6
z&DTbldm(&0B0fTx|5re(!MJSE^QU1#`&m2qUm7Nf|9k}h=kY)0pa1#ZNlE^hgpfxc
z$@}d>MTN8bF+!J2VT6x^XBci6O)Q#JfW{<sb5)HkTF~_Sa_M^vi<UXTocVSE>YMz)
zOBM>t2rSj)n#0a3cjvu}r|k3od6W(SN}V-cL?bi<J46HHYSLL&OeFRm%u#)=VN9PH
zxaTYq?JHLwz2fTT`H!RbdHX@6n6p6?mn|3kIU%%1k}C2(3hi^IDh(udokZ1xF-p+u
z0u<3zht=l5wn_zAAWK?U0XT-L6xs5k3ZJ=V1H`#dpB4>*Iz-8uOcCcsX0L>ZXjLqk
zZu2uHq5B|Kt>e+=pPKu=1P@1r9WLgYFq_TNV1p9pu0erHGd!+bBp!qGi+~4<N?Fq)
zn=ndP#eVyN4)AOmF>A(RsYN@CyXNrC&hxGmW)u5m35Om<gLIl43|ftfxD;4@0U%W{
zfCt<dp}9hk8dzvf-#}P{$rRcsI2FbF%>WwX`I+0yByglO`}HC4nGE^_HUs^&A(uaM
zKPj^=qI{&ayOq#z=p&pnx@@k&I1JI>cttJcu@Ihljt?6p^6{|ds`0MoQwp+I{3l6`
zB<9S((RpLG^>=Kic`1LnhpW2=Gu!x`m~=y;A`Qk!-w`IN;S8S930#vBVMv2vCKi}u
z6<-VPrU0AnE&vzwV(CFC0gnZYcpa-l5T0ZS$P6(?9AM;`Aj~XDvt;Jua=jIgF=Fm?
zdp=M$>`phx%+Gu};;-&7T|B1AcC#L4@mW5SV_^1BRbo6;2PWe$r+npRV`yc;T1mo&
z+~_?7rA<BY)cqU~+}^_%&5(AuHg02IxD?AG?j^Zhn%1`rT{GFYPZA>+(Um&o@Tddl
zL_hxvWk~a)yY}%j`Y+200D%9$bWHy&;(yj{jpi?Rtz{J66ANw)UyPOm;t6FzY3$hx
zcn)Ir79nhFvNa7^a{SHN7XH*|Vlsx`CddPnA&Qvh8aNhEA;mPV<ryWQl0P?MiPwBL
z+vex2kKClH;6k1Et=IFG!&SyN$8+S#_UnR?aFa6Eq|~rBS)8W_vwKAj+o^X)(9027
z*WrGQ$Ej`dD5*y_K^!R^&+N3W?cTJmXL9S<fpm^mH*?0O@w{qI>v;Ah=k<*u!Zq^7
z<=xs*iQTQOMMcg|(NA_auh@x`3#_LFt=)}%SQppP{E>mu_LgquAWvh<>L7tf9+~rO
znwUDS52u)OtY<~!d$;m9+87aO+&`#2ICl@Y>&F{jI=H(K+@3M1$rr=*H^dye#~TyD
z!){#Pyfn+|ugUu}G;a~!&&0aqQ59U@UT3|_JuBlYUpT$2+11;}JBJ`{+lQN9T@QFY
z5+`t;6(TS0F?OlBTE!@7D`8#URDNqx2t6`GZ{ZgXeS@v%-eJzZOHz18aS|svxII$a
zZeFjrJ*$IwX$f-Rz<J3Ld3QGgbbgt9L|A^RC+}TLgII?Lz8a4l887}}cuTMGGhsX*
z9&mmFqP?djyuRYNLb|y#gPeE?&x5*{yL4yV`z1bx{$hup<=h=EzEhKN_egi{3sPw}
z!?<6KVR?6VYA;nDAIyA2AKd4Ab>r_G>xbu@euGl)B7pC&S+CmDJBg$BoV~jxSO#>y
z33`bupN#LDoW0feZe0%q8un0rYN|eRAnwDHQ6e_)xBTbtoZtTA=Fvk){q}9Os~6mQ
zKB80VI_&6iSq`LnK7*kfHZoeX6?WE}8yjuDn=2#JG$+;-TOA1%^=DnXx%w{b=w}tS
zQbU3XxtOI8E(!%`64r2`zog;5<0b4i)xBmGP^jiDZ2%HNSxIf3@wKs~uk4%3Mxz;~
zts_S~E4>W+YwI<-*-$U8*^HKDEa8oLbmqGg?3vewnaNg%Mm)W=)lcC_J+1ov^u*N3
zXJ?!BrH-+wGYziJq2Y#vyry6Z>NPgkEk+Ke`^DvNRdb>Q2Nlr#v%O@<5hbflI6EKE
z9dWc0-ORk^T}jP!nkJ1imyjdVX@GrjOs%cpgA8-c&FH&$(4od#x6Y&=LiJZPINVyW
z0snY$8JW@>tc2}DlrD3StQmA0Twck~@>8dSix9CyQOALcREdxoM$Sw*l!}bXKq9&r
zysMWR@%OY24@e`?+#xV2bk{T^C_xSo8v2ZI=lBI*l{RciPwuE>L5<W5z;@6p;6;|O
z%1xS<PrHS@9bs_>@uhz@{!l)rtVlWC>)6(G)1~n=Q|S!{E9~6*f<w%m`;Qd>dpa*n
z!()-8EpTdj=zr_Lswi;#{TxbtH$8*G=UM`I+icz7sr_SdnHXrv=?iEOF1UL+*6O;%
zPw>t^kb<Y!37E>W9X@oEXx<97%lBm-9?O_7L!DeD)Me#rwE5<?Y(}PPRapoJOytLr
zH%=!UQ}Y5J_(3KVTFf%D7DXvmTFStSsvMk1_bhZw*QC=UXI9MplG;au>4t~UBu9VZ
zl_I1tBB~>jm@bw<SOr`xU7_Kg$PU){Os_I8cve<UKbUg-U~fB$8f2Y<)c>0Aljz8!
zXBB6ATG6i<ky6{p$)@{!N}M!yKr)m#;X?<H(Z75&7#=qg5yAe!nNXMBxO$uuu4{+;
zB;Z$SC9Hkye>ByKIxs!qr%pz%wgqbg(l{65DP4#v(vqhhL{0b#0C8mq`bnqZ1OwFV
z7mlZZJFMACm>h9v^2J9+^_zc1<NQ`E;}bmano=+KqF=1iDw+>=JjL#qM5ZHaThH&n
zXPTsR8(+)cj&>Un{6v*z?@VTLr{TmZ@-fY%*o2G}*G}#!bmqpoo*<pdMvH^(qd~4b
z&U$~Fo(WzrnMy~ykcI{stgLy~unZF&M1>Ay@U!JI^Q@7gj;Kg-HIrLj4}#ec<Vnys
z#0P7P+6h@<uM?dbofaPCeGw4^GKj)BhZ;UWJ+<6Nx^ge1;*1yP2rFzRz&wW{MTEr2
zHXxRizPbhoG%+`mqNb$aK0~}2_bn~FMY2@vFZ0AA!pFio4f|r;(+@Q1=`h#RqX!CO
zrKiCBy`_GlRuCrdEk+*L2qw)Xi3a$4Yu;T-ek#YzAVQMsU=A4R@x`B#O+Rf$w;qdW
z?}xS=&C)dEt1bY5wPQ*Qhbfh3qM{iKuWW?ZRgK1yH>4~D2~X6vo;ghep-@&yOivYP
zC19L0D`jjKy1Yi-SGPAn94(768<MS&a!S%v@?~BDz5em7uiJCVng8mCX4kKzoQ6PZ
z2Tk0a6O=C#;z%H(u6zVb=|H2_?Mkm8Gc%N0k^Pp7o_nH69Yyq@mT_v(ZVS($NBa&F
z6xwW+#+_X3s)pC4l=DX;IIvOLHG0qBsgo?lu%3&9euMN`&SyK73Bo<x@&AHA*=am&
z1@no;r9Z{@*~p)rGlS`fyJCBB`|!&7#=qvn{2=@K-S4-@S0u|BDv=7_-i!Ic_QmBs
zjXb>Tcf$urAf{)1)9W58P`6MA{YG%O?|07!g9(b`8PXG1B1Sh0?HQmeJtP0M$O$hI
z{5G`&9XzYhh|y@qsF1GnHN|~^ru~HVf#)lOTSrv=S<uFZ_;?KwDx~9UUr?%y@ex}8
z_9H~!Xc3m^qNrtT@3y|;1c?=J#VjGm2#~m8gbETU8K{z_hDYEnF$+2Q2Oc9Mp&ga4
z#Mhq}0`Jk@q}^00F79AOKffu=y|_%9nA^(yl2kj(9G$y+k?BKg2^S**>@DyR$UKQk
zjdEPFDz{uHM&UM;=mG!xKvp;xAGHOBo~>_=WFTmh$chpC7c`~7?36h)7$fF~Ii}8q
zF|YXxH-Z?d+Q+27Rs3X9S&K3N+)OBxMHn1u(vlrUC6ckBY@@jl+mgr#KQUKo#VeFm
zFwNYgv0<%~Wn}KeLeD9e1$S>jhOq&(e*I@L<=I5b(?G(zpqI*WBqf|Zge0&aoDUsC
zngMRA_Kt0>La+Erl=Uv_J^p(z=!?XHpenzn$%EA`JIq#yYF?JLDMYiPfM(&Csr#f{
zdd+LJL1by?xz|D8+(fgzRs~(N1k9DSyK@LJygwaYX8dZl0W!I&c^K?7)z{2is;OkE
zd$VK-(uH#AUaZrp=1z;O*n=b?QJkxu`Xsw&7yrX0?(CX=I-C#T;yi8a<{E~?vr3W>
zQrpPqOW2M+AnZ&p{hqmHZU-;Q(7<pG4gt)B4$6wsrn;hWv_Oig17Y?jJ&7E4<tmZn
zOCP%0<fYi!jPBWOw9w}#K7$n=jY!?ZAO-w*mO9|G92xj4(OrW0?2j);##sDv4x>?-
zP8L|Q0RM<y7372ia7WA3T&finv`tA1B}OSEw3SiAZho>~sB0w1w53f&Kd*y}ofx@c
z5Y6B8qGel+uT1JMot$nT1!Tim6{>oZzJXdyA+4euOLME?5Fd_85Uk%#E*ln%y{u8Q
z$|?|R@Hpb~yTVK-Yr_S#%NUy7EBfYGAg>b({J|5b+j-PBpPy$Ns`PaJin4JdRfOaS
zE|<<io8>HjH%NuJgsd2wOlv>~y=np%=2)$M9LS|>P)zJ+Fei5vYo_N~B0XCn+GM76
z)Xz3tg*FRVFgIl9zpESgdpWAavvVViGlU8|UFY{{gVJskg*I!ZjWyk~OW-Td4(mZ6
zB&SQreAAMqwp}rjy`HsG<WwCuHn5_unq_y9e#cRc8<%lnA}KbA9;x1=pR7&&N!F-G
zjdr@AW->({l2&q5Y52<@AULVAu~rWI$UbFuZs>Sc*x+XI<+ez%$U)|a^unjpiW0l0
zj1!<ZReHVMm7dlC$9b#yLY{IPu{3a%?*mdb?Ln7M9kK-6dElH{UJFdM&-U|~tV)|A
zbcx=;RI5^&eB34O5VoIsgM>K0(b6$8LOjzRqQ~K&dfbMIE=TF}XFAi)$+h}5SD3lo
z%%Qd>p9se=VtQG{kQ;N`sI)G^u|DN#7{aoEd<IbwTtn<2Y5Nlu3=6HqY@ID|;XJ`>
zkksYP%_X$Rq08);-s6o>CGJ<}v`qs%eYf+J%DQ^2k68C%nvikRsN?$ap--f+vCS`K
z#&~)f7!N^;sdUXu54gl3L=LN>FB^tuK=y2e#|hWiWUls__n@L|>xH{%8lIJTd5`w?
zSwZbnS;W~DawT4OwSJVdAylbY+u5S+ZH{4hAi2&}Iv~W(UvHg(1GTZRPz`@{SOqzy
z(8g&Dz=$PfRV=6FgxN~zo+G8OoPI&d-thcGVR*_^(R8COTM@bq?fDwY{}WhsQS1AK
zF6R1t8!RdFmfocpJ6?9Yv~;WYi~XPgs(|>{5})j!<TEFe=Er$+pf$t`J5iiJseKY6
zOKcLAm!-S>AR!voO7y9&cMPo#80A(`za@t>cx<0;qxM<p_$AQsg0LlIt|lbiT;}c3
zw^mT}aw%3C?rkh$t46uo%m3)>@S*m(jYP)dMXr*?q0E`oL;12}VAep179uEr8c<=D
zr5?A*C{eJ`z9Ee;E$8)ME<J+@MZh2qBdMetA0Ap@SWv(BczRx8QLfufLwM}8P0mCM
zqL)NPc0jmFO8S}^g)dV@LX%jnUO0Nfp9J$lfwZiNA(bY@QLPrgG(eM{>CqatHkbHH
z&Y+ho0B$31MIB-xm&;xyaFCtg<{m~M-Q<p|>DbY)fQ>Q*Xibb~8ytxZQ?QMf9!%cV
zU0_X1@b4d+Pg#R!`OJ~DOrQz3@cpi<UUDp%7N@Va%&%d{hBCU%M}b3(4mHNaXl%^x
zy!Jj<1JK)G8qrZwHKQaxXMHgDJ>Gy~XSKjZQQ|^4J1puvwKeScrH8o{bscBsowomu
z^f12kTvje`yEI3eEXDHJ6L+O{Jv$HVj%IKb<P1JL_~J>|J{IvD*l6IG8WUgDJ*UGz
z3!C%>?=dlfSJ>4U88)V+`U-!9r^@AxJBx8R;)J4Fn@`~k>8>v0M9xp90OJElWP&R5
zM#v*vtT}*Gm1<v7k$Q8)e+>^)Bv!s7<Pmunc}KvQIoTurYA$VFfn68@NS2!fMC<J7
zU5k+UNB7w2H5=t<P?=shL{5Ib0NG240C`@MTdpWV847hZ=*V+;L(?h<*^25EoClgz
zyD7a#m?)n<0d;}sfn7Zdh>2T3PB0yVIjJW)H7a)ilkAvoaH?)jjb`MP>2z{%Y?}83
zUIwBKn`-MSg)=?R)1Q0z3b>dHE^)D8LFs}6ASG1|da<c-!XQ(Z6e^nFF6CW&kh!QD
zJBO*^4S)F;_i)EMF6B*oE&=d8{@I29Wcz|o39n|gU$iV{0mmf~bE{AKN63AsId2PB
zg*_mqkTRn*8K3S&kIzHn;I0dhO)-->Dly_^lOSy&zIIhm*HXm1?VS=_iacG);_I9c
zUQH1>i#*?oPIwBMJkzi_*>HoUe}_4o>2(SHWzqQ=;TyhAHS;Enr7!#8;sdlty&(>d
zl%5cjri8`2X^Ds`jnw7>A`X|bl=U8n+3LKLy(1dAu8`g@9=5iw$R0qk)w8Vh_Dt^U
zIglK}sn^)W7aB(Q<l{uKGQ*rm=eJZ(-a1nFbLMjzjPyq^Zl*<ly16J->>HvrX=rxB
z+*L)3DiqpQ_%~|m=44LcD4-bxO3OO*LPjsh%p(k?&<Y@4%3KJjIC&Ci<sWjP2Dfw=
zuyvM4SPH14EA{O`2rzE>jvLp0py57oMH|*IMa(<|{m1(0S|x)?R-mqJ=I;_YUZA>J
z62v*eSK;5w!h8J+6Z2~oyGdZ68waWfy09?4fU&m7%u~zi?YPHPgK6LDwphgaYu%0j
zurtw)AYOpYKgHBrkX189mlJ`q)w-f|6>IER{5Lk97%P~<Lp)MD3iR}ejbGt7Rtt!H
zbM>a-JyCRFjejW@L>n4vt6#hq;!|m;hNE||LK3nw1{bJOy+eBJjK=QqNjI;Q6;Rp5
z&035pZDUZ#%Oa;&_7x0T<7!RW`#YBOj}F380Bq?MjjEhrvlCATPdkCTTl+2efTX$k
zH&0zR1n^`C3ef~^sXzJK-)52(T}uTG%OF8yDhT76L~|^+hZ2hiSM*QA9*D5odI1>&
z9kV9<p~_g)xTTw=X;R>jC~twA5MwyOx(lsGD_ggYmztXPD`2=_V|ks_FOx!_J8!zM
zTzh^cc+=VNZ&(OdN<cEfx!)Rv#OxA~Op%fRB@%V*lRYTee=t2@R^;Yw?#mEg+C=Q=
zojy#mB^&>=y4Juw)@8-85lwf_#VMN!Ed(eQiRiLB2^2e`4dp286h@v@`O%_b)Y~A;
zv}r6U?zs&@uD_+(_4bwoy7*uozNvp?bXFoB8?l8yG0qsm1JYzIvB_OH4_2G*IIOwT
zVl%HX1562vLVcxM_RG*~w_`FbIc!(T=3>r528#%mwwMK}uEhJ()3ME<NoNRheH>by
zQQjzqjWkwfI~;Fuj(Lj=Ug0y`>~C7`w&wzjK(rPw+Hpd~EvQ-ufQOiB4OMpyUKJhw
zqEt~jle9d7S~LI~$6Z->J~QJ{Vdn3!c}g9}*KG^Kzr^(7V<ce%+9mXv^Yaa3Jhd!0
zVk?95!P$`MAquqor+9D#c(4q*0U*gkAX5okY6G!AZg^p?IbWVd!~IAXj%<mibcw^E
z0M3HMVXuXDmhDXxE;Vjmfy%F+0X%+{&lK~`;T7cS`cLHThTCpHZupIqw|&Aqppk3r
z-&np;eZoZM2&XOVoZ;>I5Gk(mHLL{itj_hG?&K4Ws0+T4gLfi3eu$N=`s36geNC?c
zm<tGIMBC*Y4;VwmbLfiAj7y{1&1Jb>!~}vG6lx9Uf^5M;bWntF<-{p^bruy~f?sk9
zcETAPQZLoJ8JzMMg<-=ju4keY@SY%Wo?u9Gx=j&dfa6LIAB|IrbORLV1-H==Z1zCM
zeZcOYpm5><v|;Qz(!vWawg1_tKdRVrHI_W5DOUncaXPaZDhIYYS>U2fU7V*h;%n`8
zN95Qh<STRuU64jVjbmKjdqZSJY%8zw4$Tfj@Wvru9*X0H8*3HTGDxdEq_neggWPUu
z?xft@*y1f4!?2gYA)>fD994={1*<2vKLCNF)feKOGk`R#K~G=;rfq}|)s20&MCa65
zUM?xF5!&e0lF%|U!#rD@I{~OsS_?=;s_MQ_b_s=PuWdC)q|UQ&ea)DMRh5>fpQjXe
z<T?`@;|?};a~ft^83ljDfAQ3!94d~hNv5n{)4AwKJATa`zA71ee}fN!jaN8Z#4EjL
z-f$?vQg}|9Xo{%n!=1Mx&dq=e%YrtN37{wyLgfqAgdwo({~~Q__5WR5p+@9NOz51F
zn`CL;9K(yDAz%jg^1P_Hc`Bi##Ur7V7Egt@oIK-E#LjT)$}{W%w45C#V=-fOXxI=t
z^7_J*h#~Pik#Js#zy5ys39=Vz5a6#V82w{&CtitoXAwOl8~H^TQXd+vIaX<UxmEZ+
zVA?E;a0GBuKV>%9#*x=7{iRCtBKT#H>#v%>77|{4_slZ)XCY{s3<vj3F!Lf~Ms<;i
zbhaGgzo{F~=cvK)<7sgUCyNidX;S2p_?WD^=yZOmYaGxQQ-~@!!w5=kxBhe-MppxS
zf%rYJdpz6$k?w>j_r{tdpvb#|r|sbS^dU1x70$eJMU!h{Y7Kd{dl}9&vxQl6Jt1a`
zHQZrWyY0?!vqf@u-fxU_@+}u(%Wm>0<h|8_^}%F!#OlpyrbcO<dw!GUDNyxENZ?*z
zXa;m>I#KP48tiAPYY!T<suq7MlJU4p2C@*^!}?Z}Bs+ffZEdwIV~rhP4EI#LVSE#E
zKAv&oq@=|P;@PtQ@(J{wnUWAbS17e!I7@`^bq|U&TSNB%V@)WhqU`zr*SYoRa15`t
zq@?ryhS#AfQ#j8*PNC?6U-qg<^sQ_jI^Oh8HLIjwIVAJWx<QIp$*(EZ9$rxFs<o(f
z&qU=|nW^RP$x<u*s5N|2WXF}vN|`Y{xjc0I<5vRQ@T4U1{aj`*N<gWmUnEJdAd=LM
zS<sS>dW(o|KtVI|EUB9V`CBBN<Jb6P#IAaNVgj&r>aBLVih7+yMVF|GSoIQD0Jfb{
z!OXq;(>Z?O`1gap(L~bUcp>Lc@Jl-})^=6P%<~~9ywY=$iu8pJ0m*hOPzr~q`23eX
zgbs;VOxxENe0UMVeN*>uCn9Gk!4siN-e>x)pIKAbQ<D_NGuAv_X}p9rcKdkJ-CY72
zY;M@t?NA)MG(kc+%pPv#HrW@CR&+GK&%ZfgLEA^}da`PjtxP`2he{N2tMkOQBzSdU
zqbmpW3;gHqz$`asO$luCw6=w|wgSS|BN5dhU^m;NTBn4zBEe1bKmQJTcIjeq=_4;-
z<%Lk#6J$}CB#|%0(w^Q++N0xCR7{uhNVvN{SCZ__oxC7+<4L39n=PVh0~(Pz$Z2kz
zsD-eU@YACA>z!G)TcqIJ0`JBBaX>1-4_XO_-HCS^vr2vjv#7KltDZdyQ{tlWh4$Gm
zB>|O1cBDC)yG(sbnc*@w6e%e}r*|IhpXckx&;sQCwGdKH+3oSG-2)Bf#x`@<4ETAr
z0My%7RFh6ZLi<P3fz)VD6=F(UIjNi&4<Piytn-i3OvEhi7O_1<!4Bb=elUisJ5+JC
zX3<Z{mUVV<bu6}1{$m+MIUKl?IZ(DneHsoYb;kLtxDj9+Q`hKxkGfO!F3`9no26-x
zqe3&#LrJ-tqEc7B*%q?Pp5?r>Z_;X6Mu1YmXx7C$lSZ^}1h;j`EZd6@%JNUe=btBE
z%s=Xmo1Ps?8G`}9+6>iaB8bgjUdXT?=trMu|4yLX^m0Dg{m7rpKNJey|EwHI+nN1e
zL^>qN%5Fg)dGs4DO~uwIdXImN)QJ*Jhpj7$fq_^`{3fwpztL@WBB}OwQ#Epo-mqMO
zsM$UgpFiG&d#)lzEQ{3Q;)&zTw;SzGOah-Dpm{!q7<8*)Ti_;xvV2TYXa}=faXZy?
z3y?~GY@kl)>G&EvEijk9y1S`*=zBJSB1iet>0;x1Ai)*`^{pj0JMs)KAM=@UyOGtO
z3y0BouW$N&TnwU6!%<gf6*u=C<iEed;KBwJxLRtV%EsYYZE^_I&am&FwOQIrs&rNv
zsJkfwCitU8wV%PAV4*8&C!5{qUgyYY#T}|<>zS%nIrnANvZF&vB1~P5_d`x-giHuG
zPJ;>XkVoghm#kZXRf>qxxEix;2;D1CC~NrbO6NBX!`&_$iXwP~P*c($EVV|669kDO
zKoTLZNF4Cskh!Jz5ga9uZ`3o%7Pv`d^;a=cXI|>y;zC3rYPFLQkF*nv(r>SQvD*##
z(Vo%^9g`%XwS0t#94zPq;mYGLKu4LU3;txF26?V~A0xZbU4Lmy`)>SoQX^m7fd^*E
z+%{R4eN!rIk~K)M&UEzxp9dbY;_I^<z6SRx&;ge+MnfR=LP4lbl*GlbJMl=;M7>c}
zOc{wlIrN_P(PPqi51k_$>Lt|X6A^|CGYgKAmoI#Li?;Wq%q~q*L7ehZkUrMxW67Jl
zhsb~+U?33QS>eqyN{(odAkbopo=Q$Az?L+NZW>j;#~@wCDX?=L5SI|OxI~7!Pli;e
zELMFcZ<bg~PJE<rY>tJY3!|=Gr2L4>z8yQ-{To>(f80*#;6`4IAiqUw`=Pg$%C?#1
z_g@hIGerILSU>=P>z{gM|DS91A4cT@PEIB^hSop!uhMo#2G;+tQSpDO_6nOnPWSLU
zS;a9m^DFMXR4?*X=<qwp0>}d7l;nXuHk&0|m`NQn%d?8|Ab3A9l9Jh5s120ibWBdB
z$5YwsK3;wvp!Kn@)Qae{ef`0#NwlRpQ}k^r>yos_Ne1;xyKLO?4)t_G4eK<Q62tM^
zi3!pz7{^fEGTr8{(f#W&Re=O*i3#l1dMP2CM@R9Dz7(}LH_=oT4s2({F6)NqjLkfn
zWyb9}W9)`Eu!Z8~Tk)-$ftsw64V9oQ!&L>~wkUS2A&@_;)K0-03XGBzU+5f+uMDxC
z(s8!8!RvdC#@`~fx$r)TKdLD6fWEVdEYtV#{ncT-ZMX~eI#UeQ-+H(Z43vVn%Yj9X
zLdu9>o%wnWdvzA-#d6Z~vzj-}V3FQ5;axDIZ;i(95IIU=GQ4WuU{tl-{gk!5{l4_d
zvvb&uE{%!iFwpymz{wh?bKr1*qzeZb5f6e<hIoTpEPx(5QYd%^TYj)|S%=LSr!JTs
zz!;*wB%3?qZoTm|(U@GJ+#WuaK@<xquK@r4JW{I|?LhkR#^Q(lZ<%iY8sqr4Yy6*A
zRP{^`YZZkjC>6m_ozRF&zux2mlK=v_(_s^R6b5l<OklUMWKH5m9CK)GA(}BNrnAhY
z)mdhvSSE{gE9<H_hJ>u?_W4W3#<$zeG~Pd)^!4tzhs}-Sx$FJP>)ZGF(hVTH|C3(U
zs0PO&*<Bq@X!wy{g3X=$ULK*~ws9t@GTdzNv=8$q3p#^9{iAshe2<iFXWu|*=#t*^
zHiMowYBuE7!#m)z7kwaYz#Uc(_5ibIU;zg~@927U0DWlH<0UlQF4CPh*e--2*e>h_
zNA-&qZpTP$$LtIgfiCn07}XDbK#HIXdmv8zdz4TY;ifNIH-0jy(gMSByG2<C3EzZ8
zhJn#!of$=`Z!hW|DTzs`N(xHpzG~5_y<$0J`1RsK1TZ1v{7!~LCAC@6G637W!~rk|
zLx+h*<9F&&V-5Ie2REOa1?BIx`oEMIjt$k+8IcS%|EII70E=pQ-+-W`(g+CBps;jE
zhtk~$2oej@U6M;lmo$jPN{1kgAl)GCrAtadSp-2s|A(twE-P34{pWf1IZMp@&U{nf
zIWy<|G__isvfkx&jFyQpKg<vGx_3kCalUAl^%NntK#6(2lW1e<U)CGbFQUPSU&Hih
zN~SsTvwJ7vUK%oWe<^FW<$VJlS91FR+Ang7i@BCO7_QPS9$yRY9L+a`GWU$_BS$My
z%KO<mCE#1|s27xKI4jobQyI#G#shn67pXsz&cAj4?7POazD<?>EF~Th#eb_TueZC`
zE?3I>UTMpKQ})=C;6p!?G)M6w^u*A57bD?2X`m3X^6;&4%i_m(uGJ3Z5h`nwxM<)H
z$I5m?wN>O~8`BGnZ=y^p6;0+%_0K}Dcg|K;+fEi|qoBqvHj(M&aHGqNF48~XqhtU?
z^ogwBzRlOfpAJ+Rw7IED8lRbTdBdyEK$gPUpUG}j-M42xDj_&qEAQEtbs>D#dRd7Y
z<&TpSZ(quQDHiCFn&0xsrz~4`4tz!CdL8m~HxZM_agu@IrBpyeL1Ft}V$HX_ZqDPm
z-f89)pjuEzGdq-PRu`b1m+qBGY{zr_>{6Ss>F|<HR3fdmQIEk)2Sh}0yO~96C1H<%
z?QzVeMOyeG53X0w(8tYWACBt{TjL#WIIj{m`My#tMB;vJ{a~L+FxMlWMgTKK^KR0o
zJ;X}EooSp!+2+G$e0wWSL-uZ;icHwY>xHZlJj9dt5HD$u`1*WZe)qEIuDSR)%z+|n
zatVlhQ?$w#XRS7xUrFE;Y8vMGhQS5*T{ZnY=q1P?w5g$OKJ#M&e??tAmPWHMj3xhS
ziGxapy?kn@$~2%ZY;M8Bc@%$pkl%Rvj!?o%agBvpQ-Q61n9kznC4ttrRNQ4%GFR5u
zyv%Yo9~yxQJWJSf<lJl-iWu&1UwGnK(pvra?!Ge}y|x}g-8E3%rQnB2p@S*aS0l>j
z?#HY$y=O<nlXsK9%dUnfsdN1u-Swe<-W_b&r&^uHFD7qA9zLa8;*KhGP$Wd1TRU3&
ztEwlUTD>~F|2pZs22pu|_&Ajd<gZcA$Jk5{2YpKm>+D(Mt!nPUG{|1nlvP`=R#kKH
zO*s$r_%ss5h1YO7k0bHJ2CXN)Y<zvl5N}16U~{2_GuG6q#_|JfMPqxfGtP5?Y4Mg|
zyuvVEU!;&g*bD4Uw&V&*(NB>d6C<gbrz78@@`&t*Y)2+zhDQ!r1~__bZ$!MIY{hdK
zBvhOU_=wf9=WDc_17is97>Hn~W!R=SqkWe=&nAZu(Q1G!xgcUilM@YVei@2@a`8he
z9@pM`)VB*=e7-MWgLlXlc)t;fF&-AwM{E-EX}pViFn0I0CNw2bNEnN2dj!^4(^zS3
zobUm1uQnpqk_4q{pl*n06=TfK_C>UgurKFjRXsK_LEn};=79`TB12tv6KzwSu*-C8
z;=~ohDLZylHQ|Mpx-?yql>|e=vI1Z!epyUpAcDCp4T|*RV&X`Q$0ogNwy6mFALo^@
z9=&(9txO8V@E!@6^(W0{*~CT>+-MA~vnJULBxCTUW>X5>r7*eXYUT0B6+w@lzw%n>
z_VjJ<2qf|(d6jYq2(x$(ZDf!yVkfnbvNmb5c|hhZ^2TV_LBz`9w!e_V*W_(MiA7|=
z&EeIIkw*+$Xd!)j<aFr1R~xS}s~%p?Tvbh^pTwhKxj)!tQV8+Fl)bzUj`73ZqG~f+
zWSqF|`Gl$F?L)li$PwFjgAh#|DN8z!3tX5Sk_}`_4}-ZspoOseDU{j7Ti8%*vj}b6
z!IL&Z(PW4r+7(`f(&N9n^0NAMH0{AUeVSnnjZI%3h9AB_P13b({Q?6h@ewu{vztxi
zi*&5Pl_mU)Ysqz^vmyhLIWWvN)Hw=`Cx$Vrwrqq?{hpCEd*k5Ph0hP@wEBG#s4-aR
zr>8<@_<}A5;~A_>3JT*kX^@}cDoLd>Qj<`Se^wdUa(j0dp+Tl8EptwBm{9OGsdFEq
zM`!pjf(Lm(`$e3<VugKu#}L&f$tPP-i|8Q%zt8Y0zy98R@0)>FLOjqA5LnN5o!}z{
zNf}rJuZh@yUtq&ErjHeGzX4(!luV!jB&;FAP|!R_QHYw#^Z1LwTePAKJ6X&IDNO#;
z)#I@Xnnzyij~C@UH~X51JCgQeF0&hTXnuoElz#m{heZRexWc<T<>0k4<>0+ClX7%0
zEBqCCld1tD9Zwkr4{?Nor19#E5-YKfB8d?qgR82-Ow2^AuNevly2*tHA|sK!ybYkX
zm-sLQH72P&{vEAW6+z~O5d0qd=xW~rua~5a?ymYFSD@8&gV)E5@RNNBAj^C99+Z5Z
zR@Pq55mbCQbz+Mn$<DWdXQ3R#5&V?~bks;#i}6WLoWplVhIsF#fA%#X=}+{bA9=wr
zM^>d_CMW<-+?TU960agEk1J<>d>0K=pF19yN))a~4>m^G&tc*xR+yMD*S=yip-q=H
zIlredHpsJV8H(32@Zxc@bX6a21dUV95Th--8pE6C&3F>pk=yv$yd6@Haw;$v4+Fcb
zRwn{Qo@0`7aPa2LQOP}j9v>sjO<JEcz!71PwCy&w1EL#RH@3db^Ta;FM00H0|Mp0R
zTpn{$THw|Y^1IL=kOtj&J`-2ec-4zB&kyxvlF+QM;i6t6y+_@6dbj@S^owU3pQ_HH
z9V4D!R*q77p6}D`1gWi#=H#L`<?!BK(-r>o5K<lY0`DON8bR;qp%j?!ikO3v{CO;C
zr0hoVGpgX&#zAv@v~t0WKK3UWhFI@!4za_cZypgom@RlHWXjhb*zkH>qvn|`FLizX
zB+@<Q$;$QqzF2GLY>-u4Lw|jsvz{p^>n8Vo8H2peIqJJnMN}A)q6%$Tmig7eu^}K2
zrh$X?T|ZMsoh{6pdw1G$_T<`Ds-G=jc;qcGdK4{?dN2-XxjDNbb(7pk|3JUVCU4y;
z)?LXR>f+AAu)JEiti_Zy#z5{RgsC}R(@jl%9YZ>zu~hKQ*AxbvhC378-I@{~#%Y`Z
zy=a=9YpewPIC+gkEUUwtUL7|RU7=!^Aa}Mk^6uxOgRGA#JXjWLsjFUnix|Mau{hDT
z7mn*z1m5g`vP(#tjT0Zy4eAY(br&!RiiXE=ZI!{sE1#^#%x^Z7t1U)b<;%Y}Q9=5v
z;wp<LcU26iy~^KE9SueUhM9hSw5kFoch;KoAlT!eZTy6~rH?gNli?L&L}beKU`4T0
z({~FKWDwz-RkBOo`jHu$QZ~kQ5hqg(17SNo!H8^sKoQ@sO@9*??XWU5dC7fKZfAM^
z2&bW;u5NQsiN78LoRoCLadg3L1V;2%Am2iq%z(Q$=@X7Rr39Bjk?oA-7B^0IaaHoZ
z3%j;&y}ZdKT?VLFIiCAzK=`ZWp2^>DCEZ@OE36TWT=|gxigT@VaW9BvHS05;_P(#s
z8z<ixvefPSW(R``v-ey(C3!C1-J|HQHNtMWDk@k-%_AI{727f2fp)E3nzP2zne83t
z(KHQ3Yp(UnUc1B>I4XFQys}q)<X?lz9;PIDH}W2ejg(xq4^Dln*?prNo2!$AYL(&x
zQ^n*upjhh><`tkX$WnSarn{3e!s}4(J!=Yf>+Y>cP3f;vr63f2{|S^`_pWc)^5_!R
z*(x-fuBxL51@xe!lnDBKi}Br$c$BMZ3%f2Sa6kLabiBS{pq*yj;q|k(86x`PiC{p6
z_bxCW{>Q2BA8~Ggz&0jkrcU+-$ANBsOop*ms>34K9lNYil@}jC;?cYP(m^P}nR6FV
zk(M%48Z&%2Rx$A&FhOEirEhY0(dn;-k(qkTU)sFQ`+-ih+s@A8g?r8Pw+}2;35WYf
zi}VO`jS`p(tc)$X$a>-#WXoW!phhatC*$}|rk>|wUU71eUJG^$c6_jwX?iSHM@6__
zvV|6%U*$sSXJu9SX?2%M^kK|}a2QJ8AhF{fuX<l$E^Sy6fzZeBWpXwtZtJ*+^5CvK
zm5o@)Vb`rsjDy{;ty&^h;yuf(Qr~Ixfg8~=YlY3#vkGe-He?J$+-qAU_lqZP;hegA
zk*AEh4ihR~5Jo#08klD@qHx90U57vSVf9#s#`LJAUz(qMmmvGKi`3#h#kmAJjG9h6
zQ)B)8jyj(255#*8@2i<tO5B5CO)}P|yt3DVt)qJDZd`sE+o{(_Ii^q?>rHZxXsI~O
zGKX45!K7p*MCPEQ=gp?eu&#AW*pR{lhQR##P_*{c_DjMGL|3T3-bSJ(o$|M{ytU}>
zAV>wq*uE*qFo9KvnA^@juy{x<-u*#2NvkV={Ly}ysKYB-k`K3@K#^S1Bb$8Y#0L0#
z`6IkSG&|Z$ODy|VLS+y5pFJx&8tvPmMd8c9FhCyiU8~k6FwkakUd^(_ml8`rnl>JS
zZV){9G*)xBqPz^LDqRwyS6w86#D^~xP4($150M)SOZRe9sn=>V#aG0Iy(_^Yc<Qa{
zc=f(3k0FXE4g8yHjnttlIF~$;u0A21@bchm@(lE%*(K8|UX&n%>PpIz8QYM-#s+n%
z@Jd?xQq?Xk6=<3xSY7XYP$$yd&Spu{A#uafiIfy8gRC`o0nk{ezEDjb=q_qRAlR1d
zFq^*9Gn)yTG4b}R{!+3hWQ+u3GT~8nwl2S1lpw`s<ATc7q8AYRlt3+=;0YO5Kh=m6
zcJQSxR8f1@n@G{FQOYA>0X_qpxv)g+JIkVKl${sYf_nV~B>Em>M;RlqGb5WVil(89
zs<BCtUSSVUPQs2-L)cP6#hn*j_NRz!rNALK#^L&c9rXdhSPT_+NmK*)Z5xF$xiJ=3
z8+Mc<!WJ?e3I&g_14W8h)QxMzSB66MIj*RP^*N)W9*O3{I9!<#lwG5$#G;69c_Ici
z`@Ou~cYuw(AE3NQtoUi`%GvRnV9k1A0~o8pga`->=ld@|#;dq1*vQGz=7--Br-|l)
zZ%Xh@v8>B7P?~}?Cg$q9_={59l%m~O&*a6TKsCMAzG&vD>k2WDzJ6!tc!V)+oxF;h
zJH;apM=wO?r_+*#;ulohuP=E>^zon}a$<j`_j%GZX3(oc_SxO~-G*=c4ZAbD8%BzP
zd)Pi)VtGNDLDj>NnlcQ{1$SO*i=jnGVcQa^>QOILc)e6;eNTI>os=eaJ{*^DE+~jc
zS}TYeOykDmJ=6O%>m`i*>&pO_S;qMySJIyP=}4E&J%#1zju$RpVAkZbEl+p%?ZP^C
z*$$2b4t%a(e+%>a>d_f_<<lO{*K50r$dT8<<B_m+L}7)kTP?9nuT8`~rXnwmPpNu&
z_<Hj7^*-8j&~7D0OWBmB6J|2NeYzm{G=39Rh<aW*6|DbSdXI^GaeRfwgIs@eF%-$X
z>JjxI#J1x;=hPd1zFPx=6T$;;X1TD*2(edZ3f46zaAoW>L53vS_J*N8TMB|n+;LD|
zC=GkQPpyDY#Am4l49chDv*gojhRj_?63&&8#doW`INATAo(qY#{q}%nf@eTIXmtU<
zdB<7YWfyCmBs|c)cK>1)v&M#!yNj#4d$~pVfDWQc_ke1?fw{T1Nce_b`v|Vp5ig(H
zJvRD^+p<xU1eMV2Dp)d&jL}1T-4yJBks?w&E4)Bl#ayf5z?e)=tGbQS;h3(gA$e=k
z6KY(=q)^im5{@d1i=Ix4={^<VU*;0T*7?%g*~`NlJ)S&FWzzYph<0?QcO=pLP8?e$
z*FaH6Y-^O^gO|=h>s46^hLX;=e2!2e;w9y1D@!D$c@Jc&%%%IL=<b6daWfefB)Aj<
zmFAkvPGmuOH|UXs98|Izd34i4mjd%!t1Qfh2QG#C`?Q72>+xzw55&2?darw=9g~>P
z9>?Kdc$r?6c$m%x2S$sdpPl>GQZ{rC9mPS63*<SW1ss4Nyr-0;)>qjCVa?OIBj!fW
zm|g?>CVfG<LKn)qVK&7vOUVLdB{HCz?|MJr^jJ<qMG*a<=xVmP)}?vXFtiYfxJQ@S
z#a>XNjOfcyqImXR_(tXS(F{FcoNzKvG5R$IgGaxC@)i(e+$ME}vPVIhd|mx2IIE+f
zM?9opQHIVgBWu)^A|RzXw!^??S!x)SZOwZaJkGjc<_}2l^eSBm!eAJG9T>EC6I_sy
z?bxzDIAn&K5*mX)$RQzDA?s)-no-XF(g*yl4%+GBf`##bDXJ==AQk*xmnatI;SsLp
zP9XTHq5mmS=iWu~9E<z?vk<wVk?axOB(w*1mgxPEOC4Q_bKOg8aZS|<Jy7e5qZiZy
zi_|O~v^<Tb8jU^hW(}=ov(p@txag^UbHjwTdt5JHG|siOz_cTtZE_L!P;3VdkA;2O
zLo^GkBN2HNqX9mQqP?;}M=Weu;f8w@!h2(}g9(ObqEVL=EgisIBV{7fu4ome13nCE
zdwW~^rkG^r1c_Jwl>S>b%Q=1aMa|ya^vj$@qz9S!ih{T8_PD%Sf_QrNKwgrXw9ldm
zHRVR98*{C?_XNpJn{<p15xt>abA!oix_mowRMu^2lV-LPi;0+?-F(>^5#OHX-fPED
zCu^l7u3E%STI}c4{J2!)9S<WqRBxZXWrLfD3v(g<)+j7~DBJ!D1`Yc*cLPVUN6i!o
z<WHr{5RdXyi7LHb^NKbKUg}tH*PPH!`V-!@Sd!s(E-vzsn6!5N&eAaqoX%HxTMM{P
zIJeCXkWwFSIEY&)8%SeRPki$2eJ?TcIF$5@j`=f}32hbX8_y10W!UQZL+acoY3HWL
z^6U9-tleDkD!6JsRBj>UlGP_@!d?5W^QJXOI-Ea`hFMKjR7TluLvzC-ozCPn1`Tpy
z!vlv@_Z58ILX6>nDjTp-1LlFMx~-%GA`aJvG$?8*Ihn;mH37eK**rmOEwqegf-Ccx
zrIX4;{c~RK>XuTXxYo5kMiWMy)!IC{*DHG@E$hx?RwP@+wuad(P1{@%tRkyJRqD)3
zMHHHZ4boqDn>-=DgR5VlhQTpfVy182Gk;A_S8A1-;U1RR>+$62>(MUx@Nox$vTjHq
z%QR=j!6Gdyb5wu7y(YUktwMuW5<@jl?m4cv4BODiT5o8qVdC0MBqGr@-YBIwnpZAY
znX9(_uQjP}JJ=!~Ve9#5I~rUnN|P_3D$LqZcvBnywYhjlMSFHm`;u9GPla{5Q<X)1
z%$Q)YQ_xs_u@fVbNBxjMBTpgM&=XlBlp}w#R&41H+3NH%W*0}&d|5rv#al8&><AlF
z8HoEcIWb_>D7(7*6Tb3Svr8;(nuAd81q$*uq6HC_&~je*Ca7hP4sJp0av{M8480wF
zxASi7Qv+~@2U%Nu1Ud;s-G4CTVWIPyx!sg&8ZG0<u*j8bI(fE4R+~6W9t@%ANP1F@
zp$eJoBlfrurBBjoT#vaVVYUuEOoWffDHI4t?-V4p5pZZ3DkD`0^rkb1n)as8WP>Wq
zG_}i3C(6_1>q3w!EH7$Kwq8uBp2F2N7}l65mk1p*9v0&+;th=_E-W)E;w}P(j&it;
zv5o9#E7!G0XmdzfsS{efPNi`1b44~SZ4Z8f<yhFr_4W{*sa2b)64y#l+N#ywviYKA
zHs^$|vSmQ9h25pfc|F}ni`8kid}w)OD+3UEhP%9Dlwy33NMgJ*oN!k%?qfbTx#r!J
zY-dPtmtNT~GY1Wt*spshItZ8i4R+jh2L%btp^)9t=mbb(EpeeR#tnR}gtoxxvFD|m
zhb}`&kCesZUqA7FVifG~RXu8NP->uX!I}#8g+(wxzQwUT#Xb2(t<I|Vdp4<hf#R}E
zO$m~GhlyfnIij1YM1#7L8*;8lzFA>bY1+EUhG<XbGlkEvuzFKy+tnOPm$r=L#YRzV
zwl2E?nbHJTp_m!TZ`;N8RAqq@pSx_H9#jNyRdy^@&BAm<aBE+@>KoT@KEU9Ktl>_0
z%bjDJg;#*gtJZv!-Zs`?^}<Hop~&Xqn<t%=;~lIDY-u92ye&Z%8~1AbQ5!`jhH%qI
zx(5`}Haa*r;yTwa;Iry8BUl6}+9-EGitaF$Aq_C?<%Xbp{$*-bSPHf$IdY92oxi$9
zcggG$CBdW=NKdNvJ@yJUY`u+>v5eKmnbjqlvnSzE@_SP|LG_PJ6CYU+6zY6>92%E+
z=j@TZf-iW4(%U{lnYxQA;7Q!b;^brF<nu9$;OS+a41|h`ofOZC21#Y@_xv+k3^Ljg
zEP^3r*gL6M9RW3lIubK}wzMJ3Vq#cPO<cz7xXnc!R;|M8d|v`nL0G&xB&n;gb?&kd
z#fHl)FBAfL#Kd5aQG;&jsz|6*t@OWoiXQ1Qs^e+x9z47f=xOXd8X%iV!R%6NpDAQ2
zTW=KVlc2NZatQ2fBO>8n0D>)`q5>|WDDXLrqYU_tKN2>=#@~OE7grMnNh?UOz-O~6
z6%rHy{#h9K0AT+lDC7q4{hw^|q6*Ry;;L%Q@)Ga}$60_q%D)rv(CtS$CQbpq9|y1e
zRSrN4;$Jyl{m5bZw`$8TGvb}(LpY{-cQ)fcyJv7l3S52TLXVDsphtv&aPuDk1OzCA
z4A^QtC(!11`IsNx_HnSy?>EKpHJWT^wmS~hc^p^zIIh@9f<nT83VyE*=trSIMwSK+
z4z|GFEwin?jV;*T(G2VW4|oi4V$|b?I7v{*;m?4!2KEM4VBj1m$Qrmh{2}a>6U@I2
zC=Mve{j2^)mS#U$e{@Q?SO6%LDsXz@SY+=cK_QMmXBIU)j!$ajc-zLx3V60EXJ!qC
zi<%2x<u`s6FSLLTv<|cn{|Pp5g+jgo+oN!0JAnt({C-&Q&xt&X`rRaf=9UHOa<(4N
zfldWS^e<RZds8PXAUYACtOvF|eLw<Vj~BBG`@{geDFA=A=_Ck#1^*lKsG6XUA_1@M
zoBr4<KCuuKk`3G@{&%Sre^J!KjgXRO0MHWfIlj?6Nl?i8wO?T>8Q24YN+&8U@CIlN
zrZkcT9yh%LrlGS9`G)KdP(@9Eo-AQz@8GEFWcb7U=a0H^ZVbLmz{+&M7W(nXJ4sN8
zJLR7eeK(K8`2-}j(T7JsO`L!+CvbueT%izanm-^A1Dn{`1Nw`9P?cq<h|F<+{0IyH
zi8D-XK*RiZ>;7no+XfC`K(GO9?O^5zNIt4M+M8LM0=7Gz8UA@Z0N+lg+cX)NfazRu
z5D)~<a5^&n0jI1r5GnDy`M#F|h(qiMKHrd*pVsPffa+}n9r&yvC)xjiO5V)D0jSV-
zGGG|~f~m<FCo&&kY6Y0iR%(jt514*XxER=je_N@~Rw;NXK<|(S7GRz;_L~O|?EJRP
zzEl0Kks34-UgZF@NftnKd<^I$K_P>HA^(u%w^cz+@2@_#S|u>GpB+j4KzQ^&Wcl9f
z&hG#bCA(Yk0D&t&aJE^xME^&E-&xGHhXn%}psEIj641H+Nl-}boj;)Zt*t(4wZ5DN
z@GXF$bL=&pBq-#v<R9RxTU-1O0|)yvA4xba;H&`N3f&14aD_soWPVR}ep`@)E(vu3
zg+~Bz&teka`w8=Ja~S`ahL2bA^D*6KQ5+`#qlg3T%XFrkbl~4(ejf_wBkMZ1i+KP8
z00S5Rd}okl9{h}KZ(|NNa{T{z1?aDD2_Ewt0=3{h!$WTV6A%3M@xSczn`QhM8DRK3
zVgI-y{Oy6kEY8q4IhtAi<boY%ILQqtp!`V34lt$V&$-R4ftA$S;AfcY{Zw*wfIWkO
zN%HJ)*Zw68;IpdP8#sgQ9Ski076v-mF^6ATl(pNMM1g`517i@FK>kTkh>7hl%K5|3
z{`Vn9b$iR-SoGENp}bn4;fR3>9sA%X2@1L3aE9yTra;Wb#_`xWwLSLdfu+PAu+o3|
zGVnpzPr=ch{uuoHjtw7+_!L_2;knQ!DuDl0R`|%jr+}jFzXtrHIKc323?JO{l&;VF
z*L1+}JU7%QJOg|<!Bd8Mzh5$(Z*X{#@KZSM#9zVz<vk}ZGJI*_HMvjW>5|Tc|D8fN
zJORAg=_vsy{ak|o);@)Yh8Lkcg@$FG3k@ep36BRa^>~UmnRPziS>Z=`Jb2x*Q#`%A
zU*i3&Vg?TluO@X0O<nja==1v+{2K<RX!qLBMf>;r2Jl6LKLUOVhSqg1*qOt^|8*c7
zo(298@+r$k_wQNGHv{|$tW(T8L+4_`FQ{kEW5Jgg{yf7ey4ss_(SNKfz(N9lx&a;<
je(UuV8hP?p&}TPdm1I$XmG#(RzlD&B2izSj9sl%y5~4qc

literal 0
HcmV?d00001


From 0c426d5c4885afcd23d735724a9edf865e0a8d0a Mon Sep 17 00:00:00 2001
From: Pavel Bortnik <pavel_bortnik@epam.com>
Date: Fri, 1 Mar 2024 12:52:37 +0300
Subject: [PATCH 16/25] 5.11.0 || Fix unit tests

---
 build.gradle                                              | 2 +-
 .../core/analyzer/auto/indexer/BatchLogIndexer.java       | 2 +-
 .../ta/reportportal/core/imprt/XmlImportStrategyTest.java | 8 +++++++-
 3 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/build.gradle b/build.gradle
index 1ff5d40461..366629fa49 100644
--- a/build.gradle
+++ b/build.gradle
@@ -24,7 +24,7 @@ plugins {
 import org.owasp.dependencycheck.reporting.ReportGenerator
 
 apply from: 'project-properties.gradle'
-apply from: "$scriptsUrl/build-docker.gradle"
+//apply from: "$scriptsUrl/build-docker.gradle"
 apply from: "$scriptsUrl/build-commons.gradle"
 apply from: "$scriptsUrl/build-info.gradle"
 apply from: "$scriptsUrl/release-service.gradle"
diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/indexer/BatchLogIndexer.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/indexer/BatchLogIndexer.java
index 7a98614b1d..606b69f7d8 100644
--- a/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/indexer/BatchLogIndexer.java
+++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/auto/indexer/BatchLogIndexer.java
@@ -99,7 +99,7 @@ private Long indexPartition(List<Long> itemIds, AnalyzerConfig analyzerConfig, L
   private Long countLogs(List<IndexLaunch> indexLaunch) {
     return indexLaunch.stream()
         .flatMap(launch -> launch.getTestItems().stream())
-        .mapToLong(item -> item.getLogs().size())
+        .mapToLong(item -> item.getLogs() != null ? item.getLogs().size() : 0)
         .sum();
   }
 
diff --git a/src/test/java/com/epam/ta/reportportal/core/imprt/XmlImportStrategyTest.java b/src/test/java/com/epam/ta/reportportal/core/imprt/XmlImportStrategyTest.java
index 8dc2699d08..cc024c378a 100644
--- a/src/test/java/com/epam/ta/reportportal/core/imprt/XmlImportStrategyTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/imprt/XmlImportStrategyTest.java
@@ -26,6 +26,7 @@
 import java.nio.file.Path;
 import java.time.Instant;
 import java.util.Date;
+import java.util.HashSet;
 import java.util.Optional;
 import java.util.Set;
 import javax.inject.Provider;
@@ -106,7 +107,12 @@ void whenImportLaunch_thenProcessXmlFile(@TempDir Path tempDir) throws Exception
   void whenImportLaunch_andIsSkippedIssue_thenProcessXmlFileWithSkippedTrue(@TempDir Path tempDir)
       throws Exception {
     LaunchImportRQ rq = new LaunchImportRQ();
-    rq.setAttributes(Set.of(new ItemAttributesRQ(AbstractImportStrategy.SKIPPED_IS_NOT_ISSUE, "true")));
+    ItemAttributesRQ attributesRQ =
+        new ItemAttributesRQ(AbstractImportStrategy.SKIPPED_IS_NOT_ISSUE, "true");
+    attributesRQ.setSystem(true);
+    Set<ItemAttributesRQ> attributes = new HashSet<>();
+    attributes.add(attributesRQ);
+    rq.setAttributes(attributes);
 
     File xmlFile = createFile(tempDir);
 

From 4d0e3e9db36b996810a107a5631d979065adafe0 Mon Sep 17 00:00:00 2001
From: Andrei Piankouski <andrei_piankouski@epam.com>
Date: Mon, 25 Mar 2024 13:05:33 +0300
Subject: [PATCH 17/25] EPMRPP-89755 || Sort parameters in alphabetical order

---
 .../ws/rabbit/AsyncReportingListener.java     | 29 +++++++++++--------
 1 file changed, 17 insertions(+), 12 deletions(-)

diff --git a/src/main/java/com/epam/ta/reportportal/ws/rabbit/AsyncReportingListener.java b/src/main/java/com/epam/ta/reportportal/ws/rabbit/AsyncReportingListener.java
index 54e9a9bfe3..69d550646f 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/rabbit/AsyncReportingListener.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/rabbit/AsyncReportingListener.java
@@ -312,15 +312,17 @@ private void createItemLog(SaveLogRQ request, TestItem item, BinaryDataMetaInfo
     Launch effectiveLaunch = testItemService.getEffectiveLaunch(item);
     logService.saveLogMessage(logFull, effectiveLaunch.getId());
 
-    if (Objects.nonNull(request.getFile())) {saveAttachment(request.getFile().getName(), metaInfo,
-        logFull.getId(),
-        projectId,
-        effectiveLaunch.getId(),
-        item.getItemId(),
-        effectiveLaunch.getUuid(),
-        logFull.getUuid()
-    );
-  }}
+    if (Objects.nonNull(request.getFile())) {
+      saveAttachment(request.getFile().getName(), metaInfo,
+          logFull.getId(),
+          projectId,
+          effectiveLaunch.getId(),
+          item.getItemId(),
+          effectiveLaunch.getUuid(),
+          logFull.getUuid()
+      );
+    }
+  }
 
   private void createLaunchLog(SaveLogRQ request, Launch launch, BinaryDataMetaInfo metaInfo,
       Long projectId) {
@@ -331,9 +333,12 @@ private void createLaunchLog(SaveLogRQ request, Launch launch, BinaryDataMetaInf
     logFull.setId(log.getId());
     logService.saveLogMessage(logFull, launch.getId());
 
-    saveAttachment(request.getFile().getName(), metaInfo, logFull.getId(), projectId, launch.getId(),
-				null, launch.getUuid(),
-        logFull.getUuid());
+    if (Objects.nonNull(request.getFile())) {
+      saveAttachment(request.getFile().getName(), metaInfo, logFull.getId(), projectId,
+          launch.getId(),
+          null, launch.getUuid(),
+          logFull.getUuid());
+    }
   }
 
   private void saveAttachment(String fileName, BinaryDataMetaInfo metaInfo, Long logId,

From 6b0ec09e355ff187953b9a8eebb54a4404f802c4 Mon Sep 17 00:00:00 2001
From: Andrei Piankouski <andrei_piankouski@epam.com>
Date: Tue, 26 Mar 2024 12:01:00 +0300
Subject: [PATCH 18/25] EPMRPP-89932 || Add possibility to configure
 autocomplete suggestions when inviting users

---
 .../ws/controller/ProjectController.java             | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/ProjectController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/ProjectController.java
index ee505599a1..c210c6b16b 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/controller/ProjectController.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/controller/ProjectController.java
@@ -44,6 +44,7 @@
 import com.epam.ta.reportportal.entity.jasper.ReportFormat;
 import com.epam.ta.reportportal.entity.project.ProjectInfo;
 import com.epam.ta.reportportal.entity.user.User;
+import com.epam.ta.reportportal.entity.user.UserRole;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.util.ProjectExtractor;
 import com.epam.ta.reportportal.ws.model.DeleteBulkRQ;
@@ -69,6 +70,7 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.security.Principal;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import javax.servlet.http.HttpServletResponse;
@@ -76,6 +78,7 @@
 import org.jooq.Operator;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.domain.Pageable;
 import org.springframework.http.HttpStatus;
 import org.springframework.security.access.prepost.PreAuthorize;
@@ -112,6 +115,8 @@ public class ProjectController {
   private final UpdatePreferenceHandler updatePreference;
   private final GetJasperReportHandler<ProjectInfo> jasperReportHandler;
 
+  private final boolean isUserSuggestions;
+
   @Autowired
   public ProjectController(ProjectExtractor projectExtractor, GetProjectHandler getProjectHandler,
       GetProjectInfoHandler projectInfoHandler,
@@ -120,7 +125,8 @@ public ProjectController(ProjectExtractor projectExtractor, GetProjectHandler ge
       GetUserHandler getUserHandler, GetPreferenceHandler getPreference,
       UpdatePreferenceHandler updatePreference,
       @Qualifier("projectJasperReportHandler")
-      GetJasperReportHandler<ProjectInfo> jasperReportHandler) {
+      GetJasperReportHandler<ProjectInfo> jasperReportHandler,
+      @Value("${rp.environment.variable.user.suggestions:true}") boolean isUserSuggestions) {
     this.projectExtractor = projectExtractor;
     this.getProjectHandler = getProjectHandler;
     this.projectInfoHandler = projectInfoHandler;
@@ -131,6 +137,7 @@ public ProjectController(ProjectExtractor projectExtractor, GetProjectHandler ge
     this.getPreference = getPreference;
     this.updatePreference = updatePreference;
     this.jasperReportHandler = jasperReportHandler;
+    this.isUserSuggestions = isUserSuggestions;
   }
 
   @Transactional
@@ -276,6 +283,9 @@ public List<String> getProjectUsers(@PathVariable String projectName,
   public Iterable<SearchUserResource> searchForUser(@PathVariable String projectName,
       @RequestParam(value = "term") String term,
       Pageable pageable, @AuthenticationPrincipal ReportPortalUser user) {
+    if (!user.getUserRole().equals(UserRole.ADMINISTRATOR) && !isUserSuggestions) {
+      return Collections.emptyList();
+    }
     return getProjectHandler.getUserNames(term,
         projectExtractor.extractProjectDetails(user, projectName), pageable);
   }

From 53f8a9065b1344dd9d80c9c293e89268fa5de8c6 Mon Sep 17 00:00:00 2001
From: Ivan Kustau <86599591+IvanKustau@users.noreply.github.com>
Date: Thu, 28 Mar 2024 12:09:29 +0300
Subject: [PATCH 19/25] EPMRPP-89924 || Security vulnerabilities fix (#1958)

---
 build.gradle                                  | 27 +++++++----
 .../core/integration/plugin/PluginLoader.java |  6 +--
 .../plugin/impl/PluginLoaderImpl.java         |  7 ++-
 .../plugin/Pf4jPluginManager.java             |  7 +--
 .../plugin/ReportPortalExtensionFactory.java  | 12 ++---
 .../plugin/impl/PluginLoaderTest.java         |  4 +-
 .../plugin/Pf4jPluginManagerTest.java         | 45 +++++++++----------
 7 files changed, 58 insertions(+), 50 deletions(-)

diff --git a/build.gradle b/build.gradle
index 366629fa49..78c6d0cbd9 100644
--- a/build.gradle
+++ b/build.gradle
@@ -58,7 +58,7 @@ ext['spring-boot.version'] = '2.5.15'
 
 dependencyManagement {
     imports {
-        mavenBom(releaseMode ? 'com.epam.reportportal:commons-bom:' + '5.11.6' : 'com.epam.reportportal:commons-bom:5.11.6')
+        mavenBom(releaseMode ? 'com.epam.reportportal:commons-bom:' + '5.11.6' : 'com.github.reportportal:commons-bom:8603a03b4f')
         mavenBom('io.zonky.test.postgres:embedded-postgres-binaries-bom:12.9.0')
     }
 }
@@ -74,12 +74,12 @@ dependencies {
         implementation 'com.epam.reportportal:plugin-api'
     } else {
         implementation 'com.epam.reportportal:commons-events'
-        implementation 'com.epam.reportportal:commons-dao'
+        implementation 'com.github.reportportal:commons-dao:586c730aaf'
         implementation 'com.epam.reportportal:commons-rules'
         implementation 'com.epam.reportportal:commons-model'
         implementation 'com.epam.reportportal:commons'
         implementation 'com.epam.reportportal:commons-fonts'
-        implementation 'com.epam.reportportal:plugin-api'
+        implementation 'com.github.reportportal:plugin-api:399273afd2'
     }
 
     implementation 'org.springframework.boot:spring-boot-starter-aop'
@@ -90,13 +90,19 @@ dependencies {
     implementation 'org.springframework.boot:spring-boot-starter-amqp'
     implementation 'org.springframework.boot:spring-boot-starter-batch'
 
+    //Fix CVE-2023-34050
+    implementation 'org.springframework.amqp:spring-amqp:2.4.17'
+
+    //Fix CVE-2023-40827, CVE-2023-40828, CVE-2023-40826
+    implementation 'org.springframework:spring-webmvc:5.3.32'
+    implementation 'org.springframework:spring-web:5.3.32'
 
     implementation 'com.opencsv:opencsv:5.8'
 
-    // Fix CVE-2021-41079, CVE-2022-23181, CVE-2021-33037, CVE-2021-30640, CVE-2022-42252
-    implementation 'org.apache.tomcat.embed:tomcat-embed-core:9.0.82'
-    implementation 'org.apache.tomcat.embed:tomcat-embed-el:9.0.82'
-    implementation 'org.apache.tomcat.embed:tomcat-embed-websocket:9.0.82'
+    // Fix CVE-2023-46589, CVE-2024-24549
+    implementation 'org.apache.tomcat.embed:tomcat-embed-core:9.0.86'
+    implementation 'org.apache.tomcat.embed:tomcat-embed-el:9.0.86'
+    implementation 'org.apache.tomcat.embed:tomcat-embed-websocket:9.0.86'
     //
 
     //https://nvd.nist.gov/vuln/detail/CVE-2020-5411
@@ -139,10 +145,15 @@ dependencies {
     implementation 'org.codehaus.jettison:jettison:1.5.4'
     // Fix CVE-2020-15522
     implementation 'org.bouncycastle:bcprov-jdk15on:1.70'
-    implementation 'org.apache.commons:commons-compress:1.25.0'
+    // Fix CVE-2024-25710, CVE-2024-26308
+    implementation 'org.apache.commons:commons-compress:1.26.0'
     implementation 'org.yaml:snakeyaml:1.33'
     implementation 'org.hibernate:hibernate-core:5.6.15.Final'
 
+    //Fix CVE-2023-6378, CVE-2023-6481, CVE-2023-6378, CVE-2023-6481
+    implementation 'ch.qos.logback:logback-classic:1.2.13'
+    implementation 'ch.qos.logback:logback-core:1.2.13'
+
     // Metrics
     implementation 'io.micrometer:micrometer-registry-prometheus:1.8.13'
 
diff --git a/src/main/java/com/epam/ta/reportportal/core/integration/plugin/PluginLoader.java b/src/main/java/com/epam/ta/reportportal/core/integration/plugin/PluginLoader.java
index 602a523b32..a70683cc2c 100644
--- a/src/main/java/com/epam/ta/reportportal/core/integration/plugin/PluginLoader.java
+++ b/src/main/java/com/epam/ta/reportportal/core/integration/plugin/PluginLoader.java
@@ -22,7 +22,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.file.Path;
-import org.pf4j.PluginException;
+import org.pf4j.PluginRuntimeException;
 import org.pf4j.PluginWrapper;
 
 /**
@@ -35,9 +35,9 @@ public interface PluginLoader {
    *
    * @param pluginPath Plugin's path
    * @return {@link PluginInfo} with {@link PluginInfo#getId()} and {@link PluginInfo#getVersion()}
-   * @throws PluginException if there is an issue in loading the plugin or the plugin is not found in the specified path
+   * @throws PluginRuntimeException if there is an issue in loading the plugin or the plugin is not found in the specified path
    */
-  PluginInfo extractPluginInfo(Path pluginPath) throws PluginException;
+  PluginInfo extractPluginInfo(Path pluginPath) throws PluginRuntimeException;
 
   /**
    * Creates the {@link IntegrationTypeDetails} object based on the params of the plugin
diff --git a/src/main/java/com/epam/ta/reportportal/core/integration/plugin/impl/PluginLoaderImpl.java b/src/main/java/com/epam/ta/reportportal/core/integration/plugin/impl/PluginLoaderImpl.java
index f165d7241e..a0cb905392 100644
--- a/src/main/java/com/epam/ta/reportportal/core/integration/plugin/impl/PluginLoaderImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/integration/plugin/impl/PluginLoaderImpl.java
@@ -48,7 +48,7 @@
 import org.apache.commons.lang3.StringUtils;
 import org.pf4j.PluginDescriptor;
 import org.pf4j.PluginDescriptorFinder;
-import org.pf4j.PluginException;
+import org.pf4j.PluginRuntimeException;
 import org.pf4j.PluginWrapper;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -87,7 +87,7 @@ public PluginLoaderImpl(DataStore dataStore, IntegrationTypeRepository integrati
 
   @Override
   @NotNull
-  public PluginInfo extractPluginInfo(Path pluginPath) throws PluginException {
+  public PluginInfo extractPluginInfo(Path pluginPath) throws PluginRuntimeException {
     PluginDescriptor pluginDescriptor = pluginDescriptorFinder.find(pluginPath);
     return new PluginInfo(pluginDescriptor.getPluginId(), pluginDescriptor.getVersion());
   }
@@ -99,8 +99,7 @@ public IntegrationTypeDetails resolvePluginDetails(PluginInfo pluginInfo) {
         .flatMap(it -> ofNullable(it.getDetails())).flatMap(
             typeDetails -> IntegrationTypeProperties.VERSION.getValue(typeDetails.getDetails())
                 .map(String::valueOf)).ifPresent(
-                    version -> BusinessRule.expect(version, v -> !v.equalsIgnoreCase(
-                pluginInfo.getVersion()))
+            version -> BusinessRule.expect(version, v -> !v.equalsIgnoreCase(pluginInfo.getVersion()))
                 .verify(
                     ErrorType.PLUGIN_UPLOAD_ERROR, Suppliers.formattedSupplier(
                         "Plugin with ID = '{}' of the same VERSION = '{}' "
diff --git a/src/main/java/com/epam/ta/reportportal/plugin/Pf4jPluginManager.java b/src/main/java/com/epam/ta/reportportal/plugin/Pf4jPluginManager.java
index 07b539354e..23fbbcb3f4 100644
--- a/src/main/java/com/epam/ta/reportportal/plugin/Pf4jPluginManager.java
+++ b/src/main/java/com/epam/ta/reportportal/plugin/Pf4jPluginManager.java
@@ -50,11 +50,12 @@
 import java.util.Optional;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
+import org.apache.commons.digester.plugins.PluginException;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.pf4j.PluginException;
 import org.pf4j.PluginManager;
+import org.pf4j.PluginRuntimeException;
 import org.pf4j.PluginState;
 import org.pf4j.PluginWrapper;
 import org.slf4j.Logger;
@@ -385,7 +386,7 @@ private PluginInfo resolvePluginInfo(final String fileName, InputStream fileStre
       BusinessRule.expect(validatePluginMetaInfo(newPluginInfo), equalTo(Boolean.TRUE))
           .verify(ErrorType.PLUGIN_UPLOAD_ERROR, "Plugin version should be specified.");
       return newPluginInfo;
-    } catch (PluginException e) {
+    } catch (PluginRuntimeException e) {
       removeUploadingPlugin(fileName);
       throw new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR, e.getMessage());
     }
@@ -746,7 +747,7 @@ private PluginState loadPreviousPlugin(PluginWrapper previousPlugin,
                         previousPlugin.getPluginId())
                     .get()
             )));
-      } catch (PluginException e) {
+      } catch (PluginRuntimeException e) {
         throw new ReportPortalException(ErrorType.PLUGIN_UPLOAD_ERROR,
             Suppliers.formattedSupplier("Unable to reload previousPlugin with id = '{}': '{}'",
                 previousPlugin.getPluginId(),
diff --git a/src/main/java/com/epam/ta/reportportal/plugin/ReportPortalExtensionFactory.java b/src/main/java/com/epam/ta/reportportal/plugin/ReportPortalExtensionFactory.java
index ec6db33aaa..2af01a5b83 100644
--- a/src/main/java/com/epam/ta/reportportal/plugin/ReportPortalExtensionFactory.java
+++ b/src/main/java/com/epam/ta/reportportal/plugin/ReportPortalExtensionFactory.java
@@ -44,18 +44,18 @@ public ReportPortalExtensionFactory(String resourcesDir, PluginManager pluginMan
   }
 
   @Override
-  public Object create(Class<?> extensionClass) {
+  public <T> T create(Class<T> extensionClass) {
     PluginWrapper pluginWrapper = pluginManager.whichPlugin(extensionClass);
     if (beanFactory.containsSingleton(pluginWrapper.getPluginId())) {
-      return beanFactory.getSingleton(pluginWrapper.getPluginId());
+      return extensionClass.cast(beanFactory.getSingleton(pluginWrapper.getPluginId()));
     } else {
-      return createExtension(extensionClass, pluginWrapper);
+      return extensionClass.cast(createExtension(extensionClass, pluginWrapper));
     }
   }
 
-  private Object createExtension(Class<?> extensionClass, PluginWrapper pluginWrapper) {
+  private <T> T createExtension(Class<T> extensionClass, PluginWrapper pluginWrapper) {
     Map<String, Object> initParams = getInitParams(pluginWrapper);
-    Object plugin = createPlugin(extensionClass, initParams);
+    T plugin = createPlugin(extensionClass, initParams);
     beanFactory.autowireBean(plugin);
     beanFactory.initializeBean(plugin, pluginWrapper.getDescriptor().getPluginId());
     beanFactory.registerSingleton(pluginWrapper.getDescriptor().getPluginId(), plugin);
@@ -66,7 +66,7 @@ private Object createExtension(Class<?> extensionClass, PluginWrapper pluginWrap
     return plugin;
   }
 
-  private Object createPlugin(Class<?> extensionClass, Map<String, Object> initParams) {
+  private <T> T createPlugin(Class<T> extensionClass, Map<String, Object> initParams) {
     try {
       return extensionClass.getDeclaredConstructor(Map.class).newInstance(initParams);
     } catch (Exception ex) {
diff --git a/src/test/java/com/epam/ta/reportportal/core/integration/plugin/impl/PluginLoaderTest.java b/src/test/java/com/epam/ta/reportportal/core/integration/plugin/impl/PluginLoaderTest.java
index 8672c4505b..e4e4af6125 100644
--- a/src/test/java/com/epam/ta/reportportal/core/integration/plugin/impl/PluginLoaderTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/integration/plugin/impl/PluginLoaderTest.java
@@ -36,8 +36,8 @@
 import org.junit.jupiter.api.Test;
 import org.pf4j.PluginDescriptor;
 import org.pf4j.PluginDescriptorFinder;
-import org.pf4j.PluginException;
 import org.pf4j.PluginManager;
+import org.pf4j.PluginRuntimeException;
 import org.pf4j.PluginWrapper;
 
 /**
@@ -72,7 +72,7 @@ class PluginLoaderTest {
       );
 
   @Test
-  void shouldExtractPluginIdWhenExists() throws PluginException {
+  void shouldExtractPluginIdWhenExists() throws PluginRuntimeException {
 
     Path path = Paths.get("dir", FILE_NAME);
 
diff --git a/src/test/java/com/epam/ta/reportportal/plugin/Pf4jPluginManagerTest.java b/src/test/java/com/epam/ta/reportportal/plugin/Pf4jPluginManagerTest.java
index fd9aeef652..7b612afc80 100644
--- a/src/test/java/com/epam/ta/reportportal/plugin/Pf4jPluginManagerTest.java
+++ b/src/test/java/com/epam/ta/reportportal/plugin/Pf4jPluginManagerTest.java
@@ -44,7 +44,7 @@
 import org.apache.commons.io.FileUtils;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Test;
-import org.pf4j.PluginException;
+import org.pf4j.PluginRuntimeException;
 import org.pf4j.PluginManager;
 import org.pf4j.PluginState;
 import org.pf4j.PluginWrapper;
@@ -65,24 +65,19 @@ class Pf4jPluginManagerTest {
   public static final String NEW_JIRA_PLUGIN_VERSION = "1.0";
 
   private final PluginLoader pluginLoader = mock(PluginLoader.class);
-  private final IntegrationTypeRepository integrationTypeRepository = mock(
-      IntegrationTypeRepository.class);
+  private final IntegrationTypeRepository integrationTypeRepository =
+      mock(IntegrationTypeRepository.class);
   private final AutowireCapableBeanFactory beanFactory = mock(AutowireCapableBeanFactory.class);
   private final PluginManager pluginManager = mock(PluginManager.class);
   private final PluginWrapper previousPlugin = mock(PluginWrapper.class);
   private final PluginWrapper newPlugin = mock(PluginWrapper.class);
-  private final ApplicationEventPublisher applicationEventPublisher = mock(
-      ApplicationEventPublisher.class);
+  private final ApplicationEventPublisher applicationEventPublisher =
+      mock(ApplicationEventPublisher.class);
 
-  private final Pf4jPluginManager pluginBox = new Pf4jPluginManager(PLUGINS_PATH,
-      PLUGINS_TEMP_PATH,
-      RESOURCES_PATH,
-      pluginLoader,
-      integrationTypeRepository,
-      pluginManager,
-      beanFactory,
-      applicationEventPublisher
-  );
+  private final Pf4jPluginManager pluginBox =
+      new Pf4jPluginManager(PLUGINS_PATH, PLUGINS_TEMP_PATH, RESOURCES_PATH, pluginLoader,
+          integrationTypeRepository, pluginManager, beanFactory, applicationEventPublisher
+      );
 
   private final InputStream fileStream = mock(InputStream.class);
 
@@ -98,7 +93,7 @@ void cleanUp() throws IOException {
   }
 
   @Test
-  void uploadPlugin() throws PluginException, IOException {
+  void uploadPlugin() throws PluginRuntimeException, IOException {
     PluginInfo pluginInfo = getPluginInfo();
 
     when(pluginLoader.extractPluginInfo(
@@ -130,7 +125,7 @@ void uploadPlugin() throws PluginException, IOException {
   }
 
   @Test
-  void uploadPluginWithExistingFile() throws PluginException, IOException {
+  void uploadPluginWithExistingFile() throws PluginRuntimeException, IOException {
     File tempFile = File.createTempFile(NEW_PLUGIN_FILE_NAME, ".jar", new File(PLUGINS_TEMP_PATH));
     tempFile.deleteOnExit();
     PluginInfo pluginInfo = getPluginInfo();
@@ -158,7 +153,7 @@ void uploadPluginWithExistingFile() throws PluginException, IOException {
   }
 
   @Test
-  void uploadPluginWithLoadingError() throws PluginException {
+  void uploadPluginWithLoadingError() throws PluginRuntimeException {
 
     PluginInfo pluginInfo = getPluginInfo();
     when(pluginLoader.extractPluginInfo(
@@ -179,11 +174,12 @@ void uploadPluginWithLoadingError() throws PluginException {
     );
     assertEquals(
         "Error during plugin uploading: 'Failed to load new plugin from file = 'plugin.jar''",
-        exception.getMessage());
+        exception.getMessage()
+    );
   }
 
   @Test
-  void uploadPluginWithoutExtensionClasses() throws PluginException {
+  void uploadPluginWithoutExtensionClasses() throws PluginRuntimeException {
 
     PluginInfo pluginInfo = getPluginInfo();
     when(pluginLoader.extractPluginInfo(
@@ -210,11 +206,11 @@ void uploadPluginWithoutExtensionClasses() throws PluginException {
   }
 
   @Test
-  void uploadPluginWithPluginException() throws PluginException {
+  void uploadPluginWithPluginException() throws PluginRuntimeException {
 
     when(pluginLoader.extractPluginInfo(
-        Paths.get(PLUGINS_TEMP_PATH, NEW_PLUGIN_FILE_NAME))).thenThrow(new PluginException(
-        "Manifest not found"));
+        Paths.get(PLUGINS_TEMP_PATH, NEW_PLUGIN_FILE_NAME))).thenThrow(
+        new PluginRuntimeException("Manifest not found"));
 
     final ReportPortalException exception = assertThrows(ReportPortalException.class,
         () -> pluginBox.uploadPlugin(NEW_PLUGIN_FILE_NAME, fileStream)
@@ -223,7 +219,7 @@ void uploadPluginWithPluginException() throws PluginException {
   }
 
   @Test
-  void uploadPluginWithoutVersion() throws PluginException {
+  void uploadPluginWithoutVersion() throws PluginRuntimeException {
 
     when(pluginLoader.extractPluginInfo(
         Paths.get(PLUGINS_TEMP_PATH, NEW_PLUGIN_FILE_NAME))).thenReturn(
@@ -233,7 +229,8 @@ void uploadPluginWithoutVersion() throws PluginException {
         () -> pluginBox.uploadPlugin(NEW_PLUGIN_FILE_NAME, fileStream)
     );
     assertEquals("Error during plugin uploading: 'Plugin version should be specified.'",
-        exception.getMessage());
+        exception.getMessage()
+    );
   }
 
   @Test

From fbc5e2902bc0238bf6f21f3e491bdf151722c25f Mon Sep 17 00:00:00 2001
From: Ivan Kustau <86599591+IvanKustau@users.noreply.github.com>
Date: Mon, 1 Apr 2024 11:21:04 +0300
Subject: [PATCH 20/25] =?UTF-8?q?EPMRPP-89958=20||=20Remove=20update=20of?=
 =?UTF-8?q?=20parent=20test=20item=20if=20it=20has=20status=20an=E2=80=A6?=
 =?UTF-8?q?=20(#1960)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../core/item/impl/status/ChangeStatusHandlerImpl.java          | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/status/ChangeStatusHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/status/ChangeStatusHandlerImpl.java
index 9d4eef2b72..3700988023 100644
--- a/src/main/java/com/epam/ta/reportportal/core/item/impl/status/ChangeStatusHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/status/ChangeStatusHandlerImpl.java
@@ -19,6 +19,7 @@
 import static com.epam.ta.reportportal.entity.enums.StatusEnum.FAILED;
 import static com.epam.ta.reportportal.entity.enums.StatusEnum.INFO;
 import static com.epam.ta.reportportal.entity.enums.StatusEnum.PASSED;
+import static com.epam.ta.reportportal.entity.enums.StatusEnum.SKIPPED;
 import static com.epam.ta.reportportal.entity.enums.StatusEnum.WARN;
 import static com.epam.ta.reportportal.ws.converter.converters.TestItemConverter.TO_ACTIVITY_RESOURCE;
 import static java.util.Optional.ofNullable;
@@ -93,6 +94,7 @@ private boolean isParentStatusUpdateRequired(TestItem parent) {
     return parent.getItemResults().getStatus() != StatusEnum.IN_PROGRESS
         && parent.getItemResults().getStatus() != PASSED
         && parent.getItemResults().getStatus() != FAILED
+        && parent.getItemResults().getStatus() != SKIPPED
         && !testItemRepository.hasItemsInStatusByParent(parent.getItemId(), parent.getPath(),
         StatusEnum.IN_PROGRESS.name());
   }

From 00435ff94ffb7d8080be67ba5b1c9f72c7916b13 Mon Sep 17 00:00:00 2001
From: Andrei Piankouski <andrei_piankouski@epam.com>
Date: Mon, 1 Apr 2024 13:32:40 +0300
Subject: [PATCH 21/25] EPMRPP-89932 || Add possibility to configure
 autocomplete suggestions when inviting users

---
 .../project/impl/GetProjectHandlerImpl.java    | 18 +++++++++++++++---
 .../ws/controller/ProjectController.java       | 12 +-----------
 2 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/src/main/java/com/epam/ta/reportportal/core/project/impl/GetProjectHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/project/impl/GetProjectHandlerImpl.java
index 976ea58141..cdaf32bf96 100644
--- a/src/main/java/com/epam/ta/reportportal/core/project/impl/GetProjectHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/project/impl/GetProjectHandlerImpl.java
@@ -43,6 +43,7 @@
 import org.jooq.Operator;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
@@ -77,14 +78,18 @@ public class GetProjectHandlerImpl implements GetProjectHandler {
 
 	private final ProjectConverter projectConverter;
 
+	private final boolean isUserSuggestions;
+
 	@Autowired
 	public GetProjectHandlerImpl(ProjectRepository projectRepository, UserRepository userRepository,
 			@Qualifier("projectJasperReportHandler") GetJasperReportHandler<ProjectInfo> jasperReportHandler,
-			ProjectConverter projectConverter) {
+			ProjectConverter projectConverter,
+			@Value("${rp.environment.variable.user.suggestions:true}") boolean isUserSuggestions) {
 		this.projectRepository = projectRepository;
 		this.userRepository = userRepository;
 		this.jasperReportHandler = jasperReportHandler;
 		this.projectConverter = projectConverter;
+		this.isUserSuggestions = isUserSuggestions;
 	}
 
 	@Override
@@ -150,7 +155,8 @@ private void checkBusinessRuleLessThan1Symbol(String value) {
 	public Iterable<SearchUserResource> getUserNames(String value, ReportPortalUser.ProjectDetails projectDetails, Pageable pageable) {
 		checkBusinessRuleLessThan1Symbol(value);
 
-		final CompositeFilterCondition userCondition = getUserSearchCondition(value);
+		final CompositeFilterCondition userCondition =
+				isUserSuggestions ? getUserSearchSuggestCondition(value) : getUserSearchCondition(value);
 
 		final Filter filter = Filter.builder()
 				.withTarget(User.class)
@@ -162,13 +168,19 @@ public Iterable<SearchUserResource> getUserNames(String value, ReportPortalUser.
 				.apply(userRepository.findByFilterExcludingProjects(filter, pageable));
 	}
 
-	private CompositeFilterCondition getUserSearchCondition(String value) {
+	private CompositeFilterCondition getUserSearchSuggestCondition(String value) {
 		return new CompositeFilterCondition(List.of(new FilterCondition(Operator.OR, Condition.CONTAINS, false, value, CRITERIA_USER),
 				new FilterCondition(Operator.OR, Condition.CONTAINS, false, value, CRITERIA_FULL_NAME),
 				new FilterCondition(Operator.OR, Condition.CONTAINS, false, value, CRITERIA_EMAIL)
 		), Operator.AND);
 	}
 
+	private CompositeFilterCondition getUserSearchCondition(String value) {
+		return new CompositeFilterCondition(List.of(
+				new FilterCondition(Operator.OR, Condition.EQUALS, false, value, CRITERIA_EMAIL)
+		), Operator.AND);
+	}
+
 	@Override
 	public List<String> getAllProjectNames() {
 		return projectRepository.findAllProjectNames();
diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/ProjectController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/ProjectController.java
index c210c6b16b..ee505599a1 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/controller/ProjectController.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/controller/ProjectController.java
@@ -44,7 +44,6 @@
 import com.epam.ta.reportportal.entity.jasper.ReportFormat;
 import com.epam.ta.reportportal.entity.project.ProjectInfo;
 import com.epam.ta.reportportal.entity.user.User;
-import com.epam.ta.reportportal.entity.user.UserRole;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.util.ProjectExtractor;
 import com.epam.ta.reportportal.ws.model.DeleteBulkRQ;
@@ -70,7 +69,6 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.security.Principal;
-import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import javax.servlet.http.HttpServletResponse;
@@ -78,7 +76,6 @@
 import org.jooq.Operator;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.domain.Pageable;
 import org.springframework.http.HttpStatus;
 import org.springframework.security.access.prepost.PreAuthorize;
@@ -115,8 +112,6 @@ public class ProjectController {
   private final UpdatePreferenceHandler updatePreference;
   private final GetJasperReportHandler<ProjectInfo> jasperReportHandler;
 
-  private final boolean isUserSuggestions;
-
   @Autowired
   public ProjectController(ProjectExtractor projectExtractor, GetProjectHandler getProjectHandler,
       GetProjectInfoHandler projectInfoHandler,
@@ -125,8 +120,7 @@ public ProjectController(ProjectExtractor projectExtractor, GetProjectHandler ge
       GetUserHandler getUserHandler, GetPreferenceHandler getPreference,
       UpdatePreferenceHandler updatePreference,
       @Qualifier("projectJasperReportHandler")
-      GetJasperReportHandler<ProjectInfo> jasperReportHandler,
-      @Value("${rp.environment.variable.user.suggestions:true}") boolean isUserSuggestions) {
+      GetJasperReportHandler<ProjectInfo> jasperReportHandler) {
     this.projectExtractor = projectExtractor;
     this.getProjectHandler = getProjectHandler;
     this.projectInfoHandler = projectInfoHandler;
@@ -137,7 +131,6 @@ public ProjectController(ProjectExtractor projectExtractor, GetProjectHandler ge
     this.getPreference = getPreference;
     this.updatePreference = updatePreference;
     this.jasperReportHandler = jasperReportHandler;
-    this.isUserSuggestions = isUserSuggestions;
   }
 
   @Transactional
@@ -283,9 +276,6 @@ public List<String> getProjectUsers(@PathVariable String projectName,
   public Iterable<SearchUserResource> searchForUser(@PathVariable String projectName,
       @RequestParam(value = "term") String term,
       Pageable pageable, @AuthenticationPrincipal ReportPortalUser user) {
-    if (!user.getUserRole().equals(UserRole.ADMINISTRATOR) && !isUserSuggestions) {
-      return Collections.emptyList();
-    }
     return getProjectHandler.getUserNames(term,
         projectExtractor.extractProjectDetails(user, projectName), pageable);
   }

From d328565c56c375e0997a42c0f6ba0423cabc98b9 Mon Sep 17 00:00:00 2001
From: Andrei Piankouski <andrei_piankouski@epam.com>
Date: Tue, 2 Apr 2024 15:53:47 +0300
Subject: [PATCH 22/25] Fix test

---
 .../project/impl/GetProjectHandlerImpl.java   | 25 +++++++++----------
 .../impl/GetProjectHandlerImplTest.java       |  8 ++++--
 2 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/src/main/java/com/epam/ta/reportportal/core/project/impl/GetProjectHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/project/impl/GetProjectHandlerImpl.java
index cdaf32bf96..cbf178eb97 100644
--- a/src/main/java/com/epam/ta/reportportal/core/project/impl/GetProjectHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/project/impl/GetProjectHandlerImpl.java
@@ -78,19 +78,18 @@ public class GetProjectHandlerImpl implements GetProjectHandler {
 
 	private final ProjectConverter projectConverter;
 
-	private final boolean isUserSuggestions;
-
-	@Autowired
-	public GetProjectHandlerImpl(ProjectRepository projectRepository, UserRepository userRepository,
-			@Qualifier("projectJasperReportHandler") GetJasperReportHandler<ProjectInfo> jasperReportHandler,
-			ProjectConverter projectConverter,
-			@Value("${rp.environment.variable.user.suggestions:true}") boolean isUserSuggestions) {
-		this.projectRepository = projectRepository;
-		this.userRepository = userRepository;
-		this.jasperReportHandler = jasperReportHandler;
-		this.projectConverter = projectConverter;
-		this.isUserSuggestions = isUserSuggestions;
-	}
+  @Value("${rp.environment.variable.user.suggestions:true}")
+  boolean isUserSuggestions;
+
+  @Autowired
+  public GetProjectHandlerImpl(ProjectRepository projectRepository, UserRepository userRepository,
+      @Qualifier("projectJasperReportHandler") GetJasperReportHandler<ProjectInfo> jasperReportHandler,
+      ProjectConverter projectConverter) {
+    this.projectRepository = projectRepository;
+    this.userRepository = userRepository;
+    this.jasperReportHandler = jasperReportHandler;
+    this.projectConverter = projectConverter;
+  }
 
 	@Override
 	public Iterable<UserResource> getProjectUsers(String projectName, Filter filter, Pageable pageable) {
diff --git a/src/test/java/com/epam/ta/reportportal/core/project/impl/GetProjectHandlerImplTest.java b/src/test/java/com/epam/ta/reportportal/core/project/impl/GetProjectHandlerImplTest.java
index 9b371960d5..909d47e89f 100644
--- a/src/test/java/com/epam/ta/reportportal/core/project/impl/GetProjectHandlerImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/project/impl/GetProjectHandlerImplTest.java
@@ -30,8 +30,10 @@
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
+import org.mockito.Spy;
 import org.mockito.junit.jupiter.MockitoExtension;
 import org.springframework.data.domain.PageRequest;
+import org.springframework.test.context.TestPropertySource;
 
 import java.util.Optional;
 
@@ -45,13 +47,15 @@
  * @author <a href="mailto:ihar_kahadouski@epam.com">Ihar Kahadouski</a>
  */
 @ExtendWith(MockitoExtension.class)
+@TestPropertySource(properties = {"rp.environment.variable.user.suggestions=true"})
 class GetProjectHandlerImplTest {
 
 	@Mock
 	private ProjectRepository projectRepository;
 
-	@InjectMocks
-	private GetProjectHandlerImpl handler;
+  @Spy
+  @InjectMocks
+  private GetProjectHandlerImpl handler;
 
 	@Test
 	void getUsersOnNotExistProject() {

From b78ea18f5a0a295d50e733c9e0567d4bdcec6e20 Mon Sep 17 00:00:00 2001
From: Andrei Piankouski <andrei_piankouski@epam.com>
Date: Fri, 5 Apr 2024 12:39:30 +0300
Subject: [PATCH 23/25] EPMRPP-90309 || Empty content is returned for Admin
 user via API when searching for users

---
 .../ta/reportportal/core/project/GetProjectHandler.java    | 3 ++-
 .../core/project/impl/GetProjectHandlerImpl.java           | 7 +++++--
 .../ta/reportportal/ws/controller/ProjectController.java   | 2 +-
 .../core/project/impl/GetProjectHandlerImplTest.java       | 2 +-
 4 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/src/main/java/com/epam/ta/reportportal/core/project/GetProjectHandler.java b/src/main/java/com/epam/ta/reportportal/core/project/GetProjectHandler.java
index 81ee3dc926..0a70aec7ab 100644
--- a/src/main/java/com/epam/ta/reportportal/core/project/GetProjectHandler.java
+++ b/src/main/java/com/epam/ta/reportportal/core/project/GetProjectHandler.java
@@ -21,6 +21,7 @@
 import com.epam.ta.reportportal.commons.querygen.Queryable;
 import com.epam.ta.reportportal.entity.jasper.ReportFormat;
 import com.epam.ta.reportportal.entity.project.Project;
+import com.epam.ta.reportportal.entity.user.UserRole;
 import com.epam.ta.reportportal.ws.model.project.ProjectResource;
 import com.epam.ta.reportportal.ws.model.user.SearchUserResource;
 import com.epam.ta.reportportal.ws.model.user.UserResource;
@@ -87,7 +88,7 @@ public interface GetProjectHandler {
    * @param pageable       {@link Pageable} Page Details
    * @return List of found user resources
    */
-  Iterable<SearchUserResource> getUserNames(String value,
+  Iterable<SearchUserResource> getUserNames(String value, UserRole userRole,
       ReportPortalUser.ProjectDetails projectDetails, Pageable pageable);
 
   /**
diff --git a/src/main/java/com/epam/ta/reportportal/core/project/impl/GetProjectHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/project/impl/GetProjectHandlerImpl.java
index cbf178eb97..dcfc761244 100644
--- a/src/main/java/com/epam/ta/reportportal/core/project/impl/GetProjectHandlerImpl.java
+++ b/src/main/java/com/epam/ta/reportportal/core/project/impl/GetProjectHandlerImpl.java
@@ -29,6 +29,7 @@
 import com.epam.ta.reportportal.entity.project.Project;
 import com.epam.ta.reportportal.entity.project.ProjectInfo;
 import com.epam.ta.reportportal.entity.user.User;
+import com.epam.ta.reportportal.entity.user.UserRole;
 import com.epam.ta.reportportal.exception.ReportPortalException;
 import com.epam.ta.reportportal.ws.converter.PagedResourcesAssembler;
 import com.epam.ta.reportportal.ws.converter.converters.ProjectConverter;
@@ -151,11 +152,13 @@ private void checkBusinessRuleLessThan1Symbol(String value) {
 	}
 
 	@Override
-	public Iterable<SearchUserResource> getUserNames(String value, ReportPortalUser.ProjectDetails projectDetails, Pageable pageable) {
+	public Iterable<SearchUserResource> getUserNames(String value, UserRole userRole,
+			ReportPortalUser.ProjectDetails projectDetails, Pageable pageable) {
 		checkBusinessRuleLessThan1Symbol(value);
 
 		final CompositeFilterCondition userCondition =
-				isUserSuggestions ? getUserSearchSuggestCondition(value) : getUserSearchCondition(value);
+				(userRole.equals(UserRole.ADMINISTRATOR) || isUserSuggestions)
+						? getUserSearchSuggestCondition(value) : getUserSearchCondition(value);
 
 		final Filter filter = Filter.builder()
 				.withTarget(User.class)
diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/ProjectController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/ProjectController.java
index ee505599a1..fc35a243d7 100644
--- a/src/main/java/com/epam/ta/reportportal/ws/controller/ProjectController.java
+++ b/src/main/java/com/epam/ta/reportportal/ws/controller/ProjectController.java
@@ -276,7 +276,7 @@ public List<String> getProjectUsers(@PathVariable String projectName,
   public Iterable<SearchUserResource> searchForUser(@PathVariable String projectName,
       @RequestParam(value = "term") String term,
       Pageable pageable, @AuthenticationPrincipal ReportPortalUser user) {
-    return getProjectHandler.getUserNames(term,
+    return getProjectHandler.getUserNames(term, user.getUserRole(),
         projectExtractor.extractProjectDetails(user, projectName), pageable);
   }
 
diff --git a/src/test/java/com/epam/ta/reportportal/core/project/impl/GetProjectHandlerImplTest.java b/src/test/java/com/epam/ta/reportportal/core/project/impl/GetProjectHandlerImplTest.java
index 909d47e89f..b490fcf802 100644
--- a/src/test/java/com/epam/ta/reportportal/core/project/impl/GetProjectHandlerImplTest.java
+++ b/src/test/java/com/epam/ta/reportportal/core/project/impl/GetProjectHandlerImplTest.java
@@ -125,7 +125,7 @@ void getUserNamesByIncorrectTerm() {
 
 	@Test
 	void getUserNamesNegative() {
-		ReportPortalException exception = assertThrows(ReportPortalException.class, () -> handler.getUserNames("",
+		ReportPortalException exception = assertThrows(ReportPortalException.class, () -> handler.getUserNames("", UserRole.ADMINISTRATOR,
 				new ReportPortalUser.ProjectDetails(1L, "superadmin_personal", ProjectRole.PROJECT_MANAGER),
 				PageRequest.of(0, 10)));
 		assertEquals("Incorrect filtering parameters. Length of the filtering string '' is less than 1 symbol", exception.getMessage());

From 9d71a7ffb0dae78d1ba6f914daa900a7bb9dfaab Mon Sep 17 00:00:00 2001
From: Ivan_Kustau <Ivan_Kustau@epam.com>
Date: Wed, 10 Apr 2024 13:43:21 +0300
Subject: [PATCH 24/25] Update release versions

---
 .github/workflows/release.yml |  2 +-
 build.gradle                  | 12 ++++++------
 gradle.properties             |  2 +-
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index ef232831f9..8fe675b7ea 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -11,7 +11,7 @@ on:
 
 env:
   GH_USER_NAME: github.actor
-  RELEASE_VERSION: 5.11.0
+  RELEASE_VERSION: 5.11.1
   REPOSITORY_URL: 'https://maven.pkg.github.com/'
 
 jobs:
diff --git a/build.gradle b/build.gradle
index 78c6d0cbd9..a3275c90b4 100644
--- a/build.gradle
+++ b/build.gradle
@@ -58,7 +58,7 @@ ext['spring-boot.version'] = '2.5.15'
 
 dependencyManagement {
     imports {
-        mavenBom(releaseMode ? 'com.epam.reportportal:commons-bom:' + '5.11.6' : 'com.github.reportportal:commons-bom:8603a03b4f')
+        mavenBom(releaseMode ? 'com.epam.reportportal:commons-bom:' + '5.11.7' : 'com.epam.reportportal:commons-bom:5.11.7')
         mavenBom('io.zonky.test.postgres:embedded-postgres-binaries-bom:12.9.0')
     }
 }
@@ -71,15 +71,15 @@ dependencies {
         implementation 'com.epam.reportportal:commons-model'
         implementation 'com.epam.reportportal:commons'
         implementation 'com.epam.reportportal:commons-fonts'
-        implementation 'com.epam.reportportal:plugin-api'
+        implementation 'com.epam.reportportal:plugin-api:5.11.1'
     } else {
         implementation 'com.epam.reportportal:commons-events'
-        implementation 'com.github.reportportal:commons-dao:586c730aaf'
+        implementation 'com.epam.reportportal:commons-dao'
         implementation 'com.epam.reportportal:commons-rules'
         implementation 'com.epam.reportportal:commons-model'
         implementation 'com.epam.reportportal:commons'
         implementation 'com.epam.reportportal:commons-fonts'
-        implementation 'com.github.reportportal:plugin-api:399273afd2'
+        implementation 'com.epam.reportportal:plugin-api:5.11.1'
     }
 
     implementation 'org.springframework.boot:spring-boot-starter-aop'
@@ -94,8 +94,8 @@ dependencies {
     implementation 'org.springframework.amqp:spring-amqp:2.4.17'
 
     //Fix CVE-2023-40827, CVE-2023-40828, CVE-2023-40826
-    implementation 'org.springframework:spring-webmvc:5.3.32'
-    implementation 'org.springframework:spring-web:5.3.32'
+    implementation 'org.springframework:spring-webmvc:5.3.33'
+    implementation 'org.springframework:spring-web:5.3.33'
 
     implementation 'com.opencsv:opencsv:5.8'
 
diff --git a/gradle.properties b/gradle.properties
index 489863e567..54e45f0fc4 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version=5.11.0
+version=5.11.1
 description=EPAM Report portal. Main API Service
 dockerPrepareEnvironment=
 dockerJavaOpts=-Xmx1g -XX:+UseG1GC -XX:InitiatingHeapOccupancyPercent=70 -Djava.security.egd=file:/dev/./urandom

From 9f4b2ccf2de63a573b991d581a2451bcf5b601c3 Mon Sep 17 00:00:00 2001
From: "reportportal.io" <support@reportportal.io>
Date: Thu, 18 Apr 2024 11:33:31 +0000
Subject: [PATCH 25/25] [Gradle Release Plugin] - new version commit: 
 '5.11.2'.

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 54e45f0fc4..b2c6c1f5a0 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version=5.11.1
+version=5.11.2
 description=EPAM Report portal. Main API Service
 dockerPrepareEnvironment=
 dockerJavaOpts=-Xmx1g -XX:+UseG1GC -XX:InitiatingHeapOccupancyPercent=70 -Djava.security.egd=file:/dev/./urandom