diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml
index 8ce75d9..f698d3f 100644
--- a/.github/workflows/python-tests.yml
+++ b/.github/workflows/python-tests.yml
@@ -13,7 +13,7 @@ jobs:
     name: Tox test
     strategy:
       matrix:
-        tox_env: [py36, py37, py38, py39, py310, py311, py312]
+        tox_env: [py38, py39, py310, py311, py312]
     # Use GitHub's Linux Docker host
     runs-on: ubuntu-latest
     steps:
diff --git a/auto-merger b/auto-merger
index 25c5c9e..b2f7ed7 100755
--- a/auto-merger
+++ b/auto-merger
@@ -30,39 +30,29 @@ import sys
 
 import click
 
-from auto_merger.merger import AutoMerger
-from auto_merger.utils import setup_logger
 
+from auto_merger.config import GlobalConfig
+from auto_merger.utils import setup_logger
+from auto_merger.cli.pr_checker import pr_checker
+from auto_merger.cli.merger import merger
 logger = logging.getLogger(__name__)
 
 
-@click.command()
+@click.group("auto-merger")
 @click.option("-d", "--debug", is_flag=True, help="Enable debug logs")
-@click.option("--print-results", is_flag=True, help="Prints readable summary")
-@click.option("--github-labels", required=True, multiple=True,
-              help="Specify Git Hub labels to meet criteria")
-@click.option("--blocking-labels", multiple=True,
-              help="Specify Git Hub labels that blocks PR to merge")
-@click.option("--send-email", multiple=True, help="Specify email addresses to which the mail will be sent.")
-@click.option("--approvals",
-              default=2, type=int,
-              help="Specify number of approvals to automatically merge PR. Default 2")
-def auto_merger(debug, print_results, github_labels, blocking_labels, approvals, send_email):
-    am = AutoMerger(github_labels, blocking_labels,  approvals)
+@click.pass_context
+def auto_merger(ctx, debug):
+    ctx.obj = GlobalConfig(debug=debug)
     if debug:
         setup_logger("auto-merger", level=logging.DEBUG)
+        logger.debug("Logging set to DEBUG")
     else:
         setup_logger("auto-merger", level=logging.INFO)
-    ret_value = am.check_all_containers()
-    if ret_value != 0:
-        sys.exit(2)
-    if print_results:
-        am.print_blocked_pull_request()
-        am.print_approval_pull_request()
-    if not am.send_results(send_email):
-        sys.exit(1)
-    sys.exit(ret_value)
+        logger.debug("Logging set to INFO")
+
+auto_merger.add_command(pr_checker)
+auto_merger.add_command(merger)
 
 
 if __name__ == "__main__":
-    auto_merger()
+    auto_merger(obj={})
diff --git a/auto_merger/api.py b/auto_merger/api.py
new file mode 100644
index 0000000..d549e96
--- /dev/null
+++ b/auto_merger/api.py
@@ -0,0 +1,60 @@
+# MIT License
+#
+# Copyright (c) 2018-2019 Red Hat, Inc.
+
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import logging
+import sys
+
+from pathlib import Path
+from typing import Dict
+
+from auto_merger.pr_checker import PRStatusChecker
+from auto_merger.merger import AutoMerger
+
+logger = logging.getLogger(__name__)
+
+
+def pr_checker(print_results, github_labels, blocking_labels, approvals, send_email) -> int:
+    """
+    Checks NVR from brew build against pulp
+    """
+    pr_status_checker = PRStatusChecker(github_labels, blocking_labels, approvals)
+    ret_value = pr_status_checker.check_all_containers()
+    if ret_value != 0:
+        return ret_value
+    if print_results:
+        pr_status_checker.print_blocked_pull_request()
+        pr_status_checker.print_approval_pull_request()
+    if not pr_status_checker.send_results(send_email):
+        return 1
+    return ret_value
+
+
+def merger(print_results, merger_labels, approvals, pr_lifetime, send_email) -> int:
+    auto_merger = AutoMerger(merger_labels, approvals, pr_lifetime)
+    ret_value = auto_merger.check_all_containers()
+    if ret_value != 0:
+        return ret_value
+    if print_results:
+        auto_merger.print_pull_request_to_merge()
+    if not auto_merger.send_results(send_email):
+        return 1
+    return ret_value
\ No newline at end of file
diff --git a/auto_merger/cli/__init__.py b/auto_merger/cli/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/auto_merger/cli/merger.py b/auto_merger/cli/merger.py
new file mode 100644
index 0000000..5d817cb
--- /dev/null
+++ b/auto_merger/cli/merger.py
@@ -0,0 +1,47 @@
+# MIT License
+#
+# Copyright (c) 2018-2019 Red Hat, Inc.
+
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+import logging
+import click
+import sys
+
+from auto_merger.config import pass_global_config
+from auto_merger import api
+logger = logging.getLogger(__name__)
+
+
+@click.command("merger")
+@click.option("--print-results", is_flag=True, help="Prints readable summary")
+@click.option("--merger-labels", required=True, multiple=True,
+              help="Specify Git Hub labels to meet criteria")
+@click.option("--send-email", multiple=True, help="Specify email addresses to which the mail will be sent.")
+@click.option("--approvals",
+              default=2, type=int,
+              help="Specify number of approvals to automatically merge PR. Default 2")
+@click.option("--pr-lifetime", default=1, type=int, help="Specify a smallest time for which PR should opened")
+@pass_global_config
+def merger(ctx, print_results, merger_labels, approvals, pr_lifetime, send_email):
+    logger.debug(ctx.debug)
+    ret_value = api.merger(print_results, merger_labels, approvals, pr_lifetime, send_email)
+    sys.exit(ret_value)
+
diff --git a/auto_merger/cli/pr_checker.py b/auto_merger/cli/pr_checker.py
new file mode 100644
index 0000000..05518f0
--- /dev/null
+++ b/auto_merger/cli/pr_checker.py
@@ -0,0 +1,49 @@
+# MIT License
+#
+# Copyright (c) 2018-2019 Red Hat, Inc.
+
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+import logging
+import click
+import sys
+
+from auto_merger.config import pass_global_config
+from auto_merger import api
+
+logger = logging.getLogger(__name__)
+
+
+@click.command("pr-checker")
+@click.option("--print-results", is_flag=True, help="Prints readable summary")
+@click.option("--github-labels", required=True, multiple=True,
+              help="Specify Git Hub labels to meet criteria")
+@click.option("--blocking-labels", multiple=True,
+              help="Specify Git Hub labels that blocks PR to merge")
+@click.option("--send-email", multiple=True, help="Specify email addresses to which the mail will be sent.")
+@click.option("--approvals",
+              default=2, type=int,
+              help="Specify number of approvals to automatically merge PR. Default 2")
+@pass_global_config
+def pr_checker(ctx, print_results, github_labels, blocking_labels, approvals, send_email):
+    logger.debug(ctx.debug)
+    ret_value = api.pr_checker(print_results, github_labels, blocking_labels, approvals, send_email)
+    sys.exit(ret_value)
+
diff --git a/auto_merger/config.py b/auto_merger/config.py
new file mode 100644
index 0000000..83102fb
--- /dev/null
+++ b/auto_merger/config.py
@@ -0,0 +1,32 @@
+# MIT License
+#
+# Copyright (c) 2018-2019 Red Hat, Inc.
+
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+import click
+
+
+class GlobalConfig(object):
+    def __init__(self, debug: bool = False):
+        self.debug = debug
+
+
+pass_global_config = click.make_pass_decorator(GlobalConfig)
diff --git a/auto_merger/merger.py b/auto_merger/merger.py
index eb72b84..cb1c7d3 100644
--- a/auto_merger/merger.py
+++ b/auto_merger/merger.py
@@ -42,17 +42,13 @@ class AutoMerger:
     container_dir: Path
     current_dir = os.getcwd()
 
-    def __init__(self, github_labels, blocking_labels, approvals=2):
+    def __init__(self, github_labels, approvals: int = 2, pr_lifetime: int = 1):
         self.logger = setup_logger("AutoMerger")
-        self.github_labels = list(github_labels)
-        self.blocking_labels = list(blocking_labels)
+        self.approval_labels = list(github_labels)
         self.approvals = approvals
-        self.logger.debug(f"GitHub Labels: {self.github_labels}")
-        self.logger.debug(f"GitHub Blocking Labels: {self.blocking_labels}")
+        self.logger.debug(f"GitHub Labels: {self.approval_labels}")
         self.logger.debug(f"Approvals Labels: {self.approvals}")
-        self.blocked_pr = {}
         self.pr_to_merge = {}
-        self.blocked_body = []
         self.approval_body = []
         self.repo_data: List = []
 
@@ -93,22 +89,6 @@ def is_authenticated(self):
             return False
         return True
 
-    def add_blocked_pr(self, pr: {}):
-        present = False
-        for stored_pr in self.blocked_pr[self.container_name]:
-            if int(stored_pr["number"]) == int(pr["number"]):
-                present = True
-        if present:
-            return
-        self.blocked_pr[self.container_name].append({
-            "number": pr["number"],
-            "pr_dict": {
-                "title": pr["title"],
-                "labels": pr["labels"]
-            }
-        })
-        self.logger.debug(f"PR {pr['number']} added to blocked")
-
     def add_approved_pr(self, pr: {}):
         self.pr_to_merge[self.container_name].append({
             "number": pr["number"],
@@ -119,22 +99,11 @@ def add_approved_pr(self, pr: {}):
         })
         self.logger.debug(f"PR {pr['number']} added to approved")
 
-    def check_blocked_labels(self):
-        for pr in self.repo_data:
-            self.logger.debug(f"Check blocked: {pr}")
-            if "labels" not in pr:
-                continue
-            for label in pr["labels"]:
-                if label["name"] not in self.blocking_labels:
-                    continue
-                self.logger.debug(f"Add '{pr['number']}' to blocked PRs.")
-                self.add_blocked_pr(pr)
-
     def check_labels_to_merge(self, pr):
         if "labels" not in pr:
             return True
         for label in pr["labels"]:
-            if label["name"] in self.blocking_labels:
+            if label["name"] in self.approval_labels:
                 return False
         self.logger.debug(f"Add '{pr['number']}' to approved PRs.")
         return True
@@ -215,17 +184,10 @@ def check_all_containers(self) -> int:
                 self.logger.error(f"This is not correct repo {self.container_name}.")
                 self.clean_dirs()
                 continue
-            if self.container_name not in self.blocked_pr:
-                self.blocked_pr[self.container_name] = []
             if self.container_name not in self.pr_to_merge:
                 self.pr_to_merge[self.container_name] = []
             try:
                 self.get_gh_pr_list()
-                self.check_blocked_labels()
-                if len(self.blocked_pr[self.container_name]) != 0:
-                    self.logger.info(
-                        f"This pull request can not be merged {self.pr_to_merge}"
-                    )
                 self.check_pr_to_merge()
             except subprocess.CalledProcessError:
                 self.clean_dirs()
@@ -234,52 +196,31 @@ def check_all_containers(self) -> int:
             self.clean_dirs()
         return 0
 
-    def get_blocked_labels(self, pr_dict) -> List [str]:
-        labels = []
-        for lbl in pr_dict["labels"]:
-            labels.append(lbl["name"])
-        return labels
-
-    def print_blocked_pull_request(self):
-        # Do not print anything in case we do not have PR.
-        if not [x for x in self.blocked_pr if self.blocked_pr[x]]:
-            return 0
-        self.blocked_body.append(
-            f"Pull requests that are blocked by labels <b>[{', '.join(self.blocking_labels)}]</b><br><br>"
-        )
-
-        for container, pull_requests in self.blocked_pr.items():
-            if not pull_requests:
-                continue
-            self.blocked_body.append(f"<b>{container}<b>:")
-            self.blocked_body.append("<table><tr><th>Pull request URL</th><th>Title</th><th>Missing labels</th></tr>")
-            for pr in pull_requests:
-                blocked_labels = self.get_blocked_labels(pr["pr_dict"])
-                self.blocked_body.append(
-                    f"<tr><td>https://github.com/sclorg/{container}/pull/{pr['number']}</td>"
-                    f"<td>{pr['pr_dict']['title']}</td><td><p style='color:red;'>{' '.join(blocked_labels)}</p></td></tr>"
-                )
-            self.blocked_body.append("</table><br><br>")
-        print('\n'.join(self.blocked_body))
 
-    def print_approval_pull_request(self):
+    def print_pull_request_to_merge(self):
         # Do not print anything in case we do not have PR.
         if not [x for x in self.pr_to_merge if self.pr_to_merge[x]]:
             return 0
-        self.approval_body.append(f"Pull requests that can be merged or missing {self.approvals} approvals")
-        self.approval_body.append("<table><tr><th>Pull request URL</th><th>Title</th><th>Approval status</th></tr>")
+        to_approval: bool = False
+        pr_body: List = []
         for container, pr in self.pr_to_merge.items():
             if not pr:
                 continue
-            if int(pr["approvals"]) >= self.approvals:
-                result_pr = f"CAN BE MERGED"
-            else:
-                result_pr = f"Missing {self.approvals-int(pr['approvals'])} APPROVAL"
-            self.approval_body.append(
+            if int(pr["approvals"]) < self.approvals:
+                continue
+            to_approval = True
+            result_pr = f"CAN BE MERGED"
+            pr_body.append(
                 f"<tr><td>https://github.com/sclorg/{container}/pull/{pr['number']}</td>"
                 f"<td>{pr['pr_dict']['title']}</td><td><p style='color:red;'>{result_pr}</p></td></tr>"
             )
-        self.approval_body.append("</table><br>")
+        if to_approval:
+            self.approval_body.append(f"Pull requests that can be merged.")
+            self.approval_body.append("<table><tr><th>Pull request URL</th><th>Title</th><th>Approval status</th></tr>")
+            self.approval_body.extend(pr_body)
+            self.approval_body.append("</table><br>")
+        else:
+            self.approval_body.append("There are not pull requests to be merged.")
         print('\n'.join(self.approval_body))
 
     def send_results(self, recipients):
@@ -288,7 +229,7 @@ def send_results(self, recipients):
             return 1
         sender_class = EmailSender(recipient_email=list(recipients))
         subject_msg = "Pull request statuses for organization https://gibhub.com/sclorg"
-        sender_class.send_email(subject_msg, self.blocked_body + self.approval_body)
+        sender_class.send_email(subject_msg, self.approval_body)
 
 
 def run():
diff --git a/auto_merger/pr_checker.py b/auto_merger/pr_checker.py
new file mode 100644
index 0000000..53e458f
--- /dev/null
+++ b/auto_merger/pr_checker.py
@@ -0,0 +1,296 @@
+#!/usr/bin/env python3
+
+# MIT License
+#
+# Copyright (c) 2024 Red Hat, Inc.
+
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+import json
+import subprocess
+import os
+import shutil
+
+from typing import List
+from pathlib import Path
+
+from auto_merger import utils
+from auto_merger.constants import UPSTREAM_REPOS
+from auto_merger.utils import setup_logger
+from auto_merger.email import EmailSender
+
+
+class PRStatusChecker:
+    container_name: str = ""
+    container_dir: Path
+    current_dir = os.getcwd()
+
+    def __init__(self, github_labels, blocking_labels, approvals: int = 2):
+        self.logger = setup_logger("AutoMerger")
+        self.github_labels = list(github_labels)
+        self.blocking_labels = list(blocking_labels)
+        self.approvals = approvals
+        self.logger.debug(f"GitHub Labels: {self.github_labels}")
+        self.logger.debug(f"GitHub Blocking Labels: {self.blocking_labels}")
+        self.logger.debug(f"Approvals Labels: {self.approvals}")
+        self.blocked_pr = {}
+        self.pr_to_merge = {}
+        self.blocked_body = []
+        self.approval_body = []
+        self.repo_data: List = []
+
+    def is_correct_repo(self) -> bool:
+        cmd = ["gh repo view --json name"]
+        repo_name = PRStatusChecker.get_gh_json_output(cmd=cmd)
+        self.logger.debug(repo_name)
+        if repo_name["name"] == self.container_name:
+            return True
+        return False
+
+    @staticmethod
+    def get_gh_json_output(cmd):
+        gh_repo_list = utils.run_command(cmd=cmd, return_output=True)
+        return json.loads(gh_repo_list)
+
+    def get_gh_pr_list(self):
+        cmd = ["gh pr list -s open --json number,title,labels,reviews,isDraft"]
+        repo_data_output = PRStatusChecker.get_gh_json_output(cmd=cmd)
+        for pr in repo_data_output:
+            if PRStatusChecker.is_draft(pr):
+                continue
+            if self.is_changes_requested(pr):
+                continue
+            self.repo_data.append(pr)
+
+    def is_authenticated(self):
+        token = os.getenv("GH_TOKEN")
+        if token == "":
+            self.logger.error(f"Environment variable GH_TOKEN is not specified.")
+            return False
+        cmd = [f"gh status"]
+        self.logger.debug(f"Authentication command: {cmd}")
+        try:
+            return_output = utils.run_command(cmd=cmd, return_output=True)
+        except subprocess.CalledProcessError as cpe:
+            self.logger.error(f"Authentication to GitHub failed. {cpe}")
+            return False
+        return True
+
+    def add_blocked_pr(self, pr: {}):
+        present = False
+        for stored_pr in self.blocked_pr[self.container_name]:
+            if int(stored_pr["number"]) == int(pr["number"]):
+                present = True
+        if present:
+            return
+        self.blocked_pr[self.container_name].append({
+            "number": pr["number"],
+            "pr_dict": {
+                "title": pr["title"],
+                "labels": pr["labels"]
+            }
+        })
+        self.logger.debug(f"PR {pr['number']} added to blocked")
+
+    def add_approved_pr(self, pr: {}):
+        self.pr_to_merge[self.container_name].append({
+            "number": pr["number"],
+            "pr_dict": {
+                "title": pr["title"],
+                "labels": pr["labels"]
+            }
+        })
+        self.logger.debug(f"PR {pr['number']} added to approved")
+
+    def check_blocked_labels(self):
+        for pr in self.repo_data:
+            self.logger.debug(f"Check blocked: {pr}")
+            if "labels" not in pr:
+                continue
+            for label in pr["labels"]:
+                if label["name"] not in self.blocking_labels:
+                    continue
+                self.logger.debug(f"Add '{pr['number']}' to blocked PRs.")
+                self.add_blocked_pr(pr)
+
+    def check_labels_to_merge(self, pr):
+        if "labels" not in pr:
+            return True
+        for label in pr["labels"]:
+            if label["name"] in self.blocking_labels:
+                return False
+        self.logger.debug(f"Add '{pr['number']}' to approved PRs.")
+        return True
+
+    def check_pr_approvals(self, reviews_to_check) -> int:
+        self.logger.debug(f"Approvals to check: {reviews_to_check}")
+        if not reviews_to_check:
+            return False
+        approval_cnt = 0
+        for review in reviews_to_check:
+            if review["state"] == "APPROVED":
+                approval_cnt += 1
+        if approval_cnt < 2:
+            self.logger.debug(f"Approval count: {approval_cnt}")
+        return approval_cnt
+
+    def is_changes_requested(self, pr):
+        if "labels" not in pr:
+            return False
+        for labels in pr["labels"]:
+            if "pr/changes-requested" == labels["name"]:
+                return True
+        return False
+
+    @staticmethod
+    def is_draft(pull_request):
+        if "isDraft" in pull_request:
+            if pull_request["isDraft"] in ["True", "true"]:
+                return True
+        return False
+
+    def check_pr_to_merge(self) -> bool:
+        if len(self.repo_data) == 0:
+            return False
+        for pr in self.repo_data:
+            if PRStatusChecker.is_draft(pr):
+                continue
+            self.logger.debug(f"PR status: {pr}")
+            if not self.check_labels_to_merge(pr):
+                continue
+            if "reviews" not in pr:
+                continue
+            approval_count = self.check_pr_approvals(pr["reviews"])
+            self.pr_to_merge[self.container_name] = {
+                "number": pr["number"],
+                "approvals": approval_count,
+                "pr_dict": {
+                    "title": pr["title"]
+                }
+            }
+
+    def clone_repo(self):
+        temp_dir = utils.temporary_dir()
+        utils.run_command(
+            f"gh repo clone https://github.com/sclorg/{self.container_name} {temp_dir}/{self.container_name}"
+        )
+        self.container_dir = Path(temp_dir) / f"{self.container_name}"
+        if self.container_dir.exists():
+            os.chdir(self.container_dir)
+
+    def merge_pull_requests(self):
+        for pr in self.pr_to_merge:
+            self.logger.debug(f"PR to merge {pr} in repo {self.container_name}.")
+
+    def clean_dirs(self):
+        os.chdir(self.current_dir)
+        if self.container_dir.exists():
+            shutil.rmtree(self.container_dir)
+
+    def check_all_containers(self) -> int:
+        if not self.is_authenticated():
+            return 1
+        for container in UPSTREAM_REPOS:
+            self.container_name = container
+            self.repo_data = []
+            self.clone_repo()
+            if not self.is_correct_repo():
+                self.logger.error(f"This is not correct repo {self.container_name}.")
+                self.clean_dirs()
+                continue
+            if self.container_name not in self.blocked_pr:
+                self.blocked_pr[self.container_name] = []
+            if self.container_name not in self.pr_to_merge:
+                self.pr_to_merge[self.container_name] = []
+            try:
+                self.get_gh_pr_list()
+                self.check_blocked_labels()
+                if len(self.blocked_pr[self.container_name]) != 0:
+                    self.logger.info(
+                        f"This pull request can not be merged {self.pr_to_merge}"
+                    )
+                self.check_pr_to_merge()
+            except subprocess.CalledProcessError:
+                self.clean_dirs()
+                self.logger.error(f"Something went wrong {self.container_name}.")
+                continue
+            self.clean_dirs()
+        return 0
+
+    def get_blocked_labels(self, pr_dict) -> List [str]:
+        labels = []
+        for lbl in pr_dict["labels"]:
+            labels.append(lbl["name"])
+        return labels
+
+    def print_blocked_pull_request(self):
+        # Do not print anything in case we do not have PR.
+        if not [x for x in self.blocked_pr if self.blocked_pr[x]]:
+            return 0
+        self.blocked_body.append(
+            f"Pull requests that are blocked by labels <b>[{', '.join(self.blocking_labels)}]</b><br><br>"
+        )
+
+        for container, pull_requests in self.blocked_pr.items():
+            if not pull_requests:
+                continue
+            self.blocked_body.append(f"<b>{container}<b>:")
+            self.blocked_body.append("<table><tr><th>Pull request URL</th><th>Title</th><th>Missing labels</th></tr>")
+            for pr in pull_requests:
+                blocked_labels = self.get_blocked_labels(pr["pr_dict"])
+                self.blocked_body.append(
+                    f"<tr><td>https://github.com/sclorg/{container}/pull/{pr['number']}</td>"
+                    f"<td>{pr['pr_dict']['title']}</td><td><p style='color:red;'>{' '.join(blocked_labels)}</p></td></tr>"
+                )
+            self.blocked_body.append("</table><br><br>")
+        print('\n'.join(self.blocked_body))
+
+    def print_approval_pull_request(self):
+        # Do not print anything in case we do not have PR.
+        if not [x for x in self.pr_to_merge if self.pr_to_merge[x]]:
+            return 0
+        self.approval_body.append(f"Pull requests that can be merged or missing {self.approvals} approvals")
+        self.approval_body.append("<table><tr><th>Pull request URL</th><th>Title</th><th>Approval status</th></tr>")
+        for container, pr in self.pr_to_merge.items():
+            if not pr:
+                continue
+            if int(pr["approvals"]) >= self.approvals:
+                result_pr = f"CAN BE MERGED"
+            else:
+                result_pr = f"Missing {self.approvals-int(pr['approvals'])} APPROVAL"
+            self.approval_body.append(
+                f"<tr><td>https://github.com/sclorg/{container}/pull/{pr['number']}</td>"
+                f"<td>{pr['pr_dict']['title']}</td><td><p style='color:red;'>{result_pr}</p></td></tr>"
+            )
+        self.approval_body.append("</table><br>")
+        print('\n'.join(self.approval_body))
+
+    def send_results(self, recipients):
+        self.logger.debug(f"Recepients are: {recipients}")
+        if not recipients:
+            return 1
+        sender_class = EmailSender(recipient_email=list(recipients))
+        subject_msg = "Pull request statuses for organization https://gibhub.com/sclorg"
+        sender_class.send_email(subject_msg, self.blocked_body + self.approval_body)
+
+
+def run():
+    auto_merger = PRStatusChecker()
+    auto_merger.check_all_containers()
diff --git a/tests/test_correct_repo.py b/tests/test_correct_repo.py
index 1c7f411..9b5c630 100644
--- a/tests/test_correct_repo.py
+++ b/tests/test_correct_repo.py
@@ -2,20 +2,20 @@
 
 from flexmock import flexmock
 
-from auto_merger.merger import AutoMerger
+from auto_merger.pr_checker import PRStatusChecker
 
 
 def test_get_gh_pr_correct_repo(get_repo_name):
-    flexmock(AutoMerger).should_receive("get_gh_json_output").and_return(get_repo_name)
-    auto_merger = AutoMerger(github_labels=[], blocking_labels=["pr/missing-review"])
+    flexmock(PRStatusChecker).should_receive("get_gh_json_output").and_return(get_repo_name)
+    auto_merger = PRStatusChecker(github_labels=[], blocking_labels=["pr/missing-review"])
     auto_merger.container_name = "s2i-nodejs-container"
     assert auto_merger.is_correct_repo()
 
 
 def test_get_gh_pr_wrong_repo(get_repo_wrong_name):
-    flexmock(AutoMerger).should_receive("get_gh_json_output").and_return(
+    flexmock(PRStatusChecker).should_receive("get_gh_json_output").and_return(
         get_repo_wrong_name
     )
-    auto_merger = AutoMerger(github_labels=[], blocking_labels=["pr/missing-review"])
+    auto_merger = PRStatusChecker(github_labels=[], blocking_labels=["pr/missing-review"])
     auto_merger.container_name = "s2i-nodejs-container"
     assert not auto_merger.is_correct_repo()
diff --git a/tests/test_pr_status.py b/tests/test_pr_status.py
index 4b50617..53ca9c8 100644
--- a/tests/test_pr_status.py
+++ b/tests/test_pr_status.py
@@ -2,24 +2,24 @@
 
 from flexmock import flexmock
 
-from auto_merger.merger import AutoMerger
+from auto_merger.pr_checker import PRStatusChecker
 
 
 def test_get_gh_pr_list(get_pr_missing_ci):
-    flexmock(AutoMerger).should_receive("get_gh_json_output").and_return(
+    flexmock(PRStatusChecker).should_receive("get_gh_json_output").and_return(
         get_pr_missing_ci
     )
-    auto_merger = AutoMerger(github_labels=["READY-to-MERGE"], blocking_labels=["pr/missing-review", 'pr/failing-ci'])
+    auto_merger = PRStatusChecker(github_labels=["READY-to-MERGE"], blocking_labels=["pr/missing-review", 'pr/failing-ci'])
     auto_merger.container_name = "s2i-nodejs-container"
     auto_merger.get_gh_pr_list()
     assert auto_merger.repo_data
 
 
 def test_get_gh_two_pr_labels_missing(get_two_pr_missing_labels):
-    flexmock(AutoMerger).should_receive("get_gh_json_output").and_return(
+    flexmock(PRStatusChecker).should_receive("get_gh_json_output").and_return(
         get_two_pr_missing_labels
     )
-    auto_merger = AutoMerger(github_labels=["READY-to-MERGE"], blocking_labels=["pr/missing-review", 'pr/failing-ci'])
+    auto_merger = PRStatusChecker(github_labels=["READY-to-MERGE"], blocking_labels=["pr/missing-review", 'pr/failing-ci'])
     auto_merger.container_name = "s2i-nodejs-container"
     auto_merger.get_gh_pr_list()
     assert auto_merger.repo_data
@@ -27,10 +27,10 @@ def test_get_gh_two_pr_labels_missing(get_two_pr_missing_labels):
 
 
 def test_get_gh_pr_missing_ci(get_pr_missing_ci):
-    flexmock(AutoMerger).should_receive("get_gh_json_output").and_return(
+    flexmock(PRStatusChecker).should_receive("get_gh_json_output").and_return(
         get_pr_missing_ci
     )
-    auto_merger = AutoMerger(github_labels=["READY-to-MERGE"], blocking_labels=["pr/missing-review", 'pr/failing-ci'])
+    auto_merger = PRStatusChecker(github_labels=["READY-to-MERGE"], blocking_labels=["pr/missing-review", 'pr/failing-ci'])
     auto_merger.container_name = "s2i-nodejs-container"
     auto_merger.get_gh_pr_list()
     assert auto_merger.repo_data
@@ -38,8 +38,8 @@ def test_get_gh_pr_missing_ci(get_pr_missing_ci):
 
 
 def test_get_no_pr_for_merge():
-    flexmock(AutoMerger).should_receive("get_gh_json_output").and_return([])
-    auto_merger = AutoMerger(github_labels=["READY-to-MERGE"], blocking_labels=["pr/missing-review", 'pr/failing-ci'])
+    flexmock(PRStatusChecker).should_receive("get_gh_json_output").and_return([])
+    auto_merger = PRStatusChecker(github_labels=["READY-to-MERGE"], blocking_labels=["pr/missing-review", 'pr/failing-ci'])
     auto_merger.container_name = "s2i-nodejs-container"
     auto_merger.get_gh_pr_list()
     assert not auto_merger.repo_data
diff --git a/tox.ini b/tox.ini
index efeb282..16622a7 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,6 +1,6 @@
 [tox]
 skipsdist = True
-envlist = py36,py37,py38,py39,py310,py311,py312
+envlist = py38,py39,py310,py311,py312
 
 [testenv]
 commands = python3 -m pytest --color=yes -vv --verbose --showlocals