diff --git a/CHANGELOG.md b/CHANGELOG.md
index b99460cb1559a8dd6c0c506a2ba2fc55e3ef1b82..f0cdf93136256ae5555dda08b5ac29656d79ed74 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,12 @@
+## [3.0.0] - 2019-09-17
+### Changed
+- Plugin classes moved to wp-builder
+### Added
+- Factory can create checker from requirement array
+- Support for update suggestion when required plugin not found
+- WPDesk_Basic_Requirement_Checker_With_Update_Disable can temporarily say that requirements are not met when required plugin is in the process of being updated
+- Translations
+
 ## [2.4.0] - 2019-06-04
 ### Added
 - Plugin name in plugin info
diff --git a/composer.json b/composer.json
index 0f7b8c9029c31b5f3ec89d7a21373b8e113a2730..b025d7f2fce6f6552a845762208dce3c8275f06d 100644
--- a/composer.json
+++ b/composer.json
@@ -7,7 +7,7 @@
         }
     ],
     "require": {
-        "php": ">=5.2"
+        "php": ">=5.3"
     },
     "require-dev": {
         "php": ">=5.5",
diff --git a/lang/wp-basic-requirements-pl_PL.mo b/lang/wp-basic-requirements-pl_PL.mo
new file mode 100644
index 0000000000000000000000000000000000000000..1be5028dc9cb2e5a10787862f5a381c950c230a7
Binary files /dev/null and b/lang/wp-basic-requirements-pl_PL.mo differ
diff --git a/lang/wp-basic-requirements-pl_PL.po b/lang/wp-basic-requirements-pl_PL.po
new file mode 100644
index 0000000000000000000000000000000000000000..b621343cd841f8083a7cb9c9853759db9d0cfb9e
--- /dev/null
+++ b/lang/wp-basic-requirements-pl_PL.po
@@ -0,0 +1,132 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: \n"
+"POT-Creation-Date: 2019-09-18 15:50+0200\n"
+"PO-Revision-Date: 2019-09-18 15:59+0200\n"
+"Last-Translator: Krzysztof Dyszczyk <krzysztof.dyszczyk@gmail.com>\n"
+"Language-Team: \n"
+"Language: pl_PL\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 2.2.3\n"
+"X-Poedit-Basepath: ../src\n"
+"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
+"|| n%100>=20) ? 1 : 2);\n"
+"X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;esc_attr__;"
+"esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c;_n_noop:1,2;"
+"\"\n"
+"X-Poedit-SearchPath-0: .\n"
+
+#: Basic_Requirement_Checker.php:187
+#, php-format
+msgid ""
+"The &#8220;%s&#8221; plugin cannot run on PHP versions older than %s. Please "
+"contact your host and ask them to upgrade."
+msgstr ""
+"Wtyczka &#8220;%s&#8221; nie może działać w wersjach PHP starszych niż %s. "
+"Skontaktuj się z administratorem hostingu i poproś o aktualizację."
+
+#: Basic_Requirement_Checker.php:191
+#, php-format
+msgid ""
+"The &#8220;%s&#8221; plugin cannot run on WordPress versions older than %s. "
+"Please update WordPress."
+msgstr ""
+"Wtyczka &#8220;%s&#8221; nie może działać w wersjach WordPress starszych niż "
+"%s. Prosimy o aktualizację WordPress."
+
+#: Basic_Requirement_Checker.php:195
+#, php-format
+msgid ""
+"The &#8220;%s&#8221; plugin cannot run on WooCommerce versions older than "
+"%s. Please update WooCommerce."
+msgstr ""
+"Wtyczka &#8220;%s&#8221; nie może działać w wersjach WooCommerce starszych "
+"niż %s. Prosimy o aktualizację WooCommerce."
+
+#: Basic_Requirement_Checker.php:199
+#, php-format
+msgid ""
+"The &#8220;%s&#8221; plugin cannot run without OpenSSL module version at "
+"least %s. Please update OpenSSL module."
+msgstr ""
+"Wtyczka &#8220;%s&#8221; nie może działać bez aktywacji OpenSSL co najmniej "
+"w wersji %s. Zaktualizuj wersję OpenSSL."
+
+#: Basic_Requirement_Checker.php:290
+#, php-format
+msgid ""
+"The &#8220;%s&#8221; plugin cannot run without %s active. Please install and "
+"activate %s plugin."
+msgstr ""
+"Wtyczka &#8220;%s&#8221; nie może działać bez aktywacji %s. Zainstaluj i "
+"aktywuj wtyczkę %s."
+
+#: Basic_Requirement_Checker.php:349
+#, php-format
+msgid ""
+"The &#8220;%s&#8221; plugin requires free %s plugin. <a href=\"%s\">Install "
+"%s →</a>"
+msgstr ""
+"Wtyczka &#8220;%s&#8221; wymaga bezpłatnej wtyczki %s. <a href=\"%s"
+"\">Zainstaluj %s →</a>"
+
+#: Basic_Requirement_Checker.php:357
+#, php-format
+msgid ""
+"The &#8220;%s&#8221; plugin requires activating %s plugin. <a href=\"%s"
+"\">Activate %s →</a>"
+msgstr ""
+"Wtyczka &#8220;%s&#8221; wymaga aktywnej wtyczki %s. <a href=“%s”>Aktywuj %s "
+"→</a>"
+
+#: Basic_Requirement_Checker.php:403
+#, php-format
+msgid ""
+"The &#8220;%s&#8221; plugin cannot run without %s php module installed. "
+"Please contact your host and ask them to install %s."
+msgstr ""
+"Wtyczka &#8220;%s&#8221; nie może działać bez modułu php: %s. Skontaktuj się "
+"z administratorem hostingu i poproś o instalację %s."
+
+#: Basic_Requirement_Checker.php:431
+#, php-format
+msgid ""
+"The &#8220;%s&#8221; plugin cannot run without %s php setting set to %s. "
+"Please contact your host and ask them to set %s."
+msgstr ""
+"Wtyczka &#8220;%s&#8221; nie może działać bez ustawienia php %s ustawionego "
+"na %s. Skontaktuj się z administratorem hostingu i poproś o ustawienie %s."
+
+#: Basic_Requirement_Checker_With_Update_Disable.php:27
+#, php-format
+msgid ""
+"The &#8220;%s&#8221; plugin disables temporarily as required %s plugin is "
+"being upgraded."
+msgstr ""
+"Wtyczka &#8220;%s&#8221; jest chwilowo nieaktywna, ponieważ wymagana wtyczka "
+"%s jest właśnie aktualizowana."
+
+#~ msgid ""
+#~ "The &#8220;%s&#8221; plugin cannot start as there is a dependency "
+#~ "conflict with other existing plugin &#8220;%s&#8221;. Please upgrade all "
+#~ "plugins to the most recent version or disable the &#8220;%s&#8221; plugin."
+#~ msgstr ""
+#~ "Wtyczka &#8220;%s&#8221; nie może zostać uruchomiona, ponieważ powstał "
+#~ "konflikt zależności z już uruchomioną wtyczką &#8220;%s&#8221;. Proszę "
+#~ "zaktualizuj wtyczki do najnowszych wersji lub dezaktywuj wtyczkę &#8220;"
+#~ "%s&#8221;."
+
+#~ msgid ""
+#~ "The &#8220;%s&#8221; plugin cannot start as there is a dependency "
+#~ "conflict with other existing plugin &#8220;%s&#8221;. The required "
+#~ "version of dependency %s is %s and the version used by plugin &#8220;"
+#~ "%s&#8221; is %s. Please upgrade all plugins to the most recent version or "
+#~ "disable the &#8220;%s&#8221; plugin."
+#~ msgstr ""
+#~ "Plugin &#8220;%s&#8221; nie może zostać uruchomiony, ponieważ powstał "
+#~ "konflikt zależności z już uruchomionem pluginem &#8220;%s&#8221;. "
+#~ "Wymagana wersja zależności %s to %s, a wersja używana przez plugin &#8220;"
+#~ "%s&#8221; to %s. Proszę zaktualizuj pluginy do najnowszej wersji lub "
+#~ "deaktywuj plugin &#8220;%s&#8221;."
diff --git a/src/Basic_Requirement_Checker.php b/src/Basic_Requirement_Checker.php
index fe8638a80b69b785ab9fbe19cb26e270767a40c2..f68f7dae761b919f0abde94dffc1a8ba129118fc 100644
--- a/src/Basic_Requirement_Checker.php
+++ b/src/Basic_Requirement_Checker.php
@@ -1,403 +1,503 @@
 <?php
 
-if ( ! interface_exists( 'WPDesk_Translatable' ) ) {
-	require_once 'Translatable.php';
-}
-
 if ( ! interface_exists( 'WPDesk_Requirement_Checker' ) ) {
 	require_once 'Requirement_Checker.php';
 }
 
-if (! class_exists('WPDesk_Basic_Requirement_Checker') ) {
-    /**
-     * Checks requirements for plugin
-     * have to be compatible with PHP 5.2.x
-     */
-    class WPDesk_Basic_Requirement_Checker implements WPDesk_Translatable, WPDesk_Requirement_Checker
-    {
-        const EXTENSION_NAME_OPENSSL = 'openssl';
-        const HOOK_ADMIN_NOTICES_ACTION = 'admin_notices';
-
-        /** @var string */
-        private $plugin_name;
-        /** @var string */
-        private $plugin_file;
-        /** @var string */
-        private $min_php_version;
-        /** @var string */
-        private $min_wp_version;
-        /** @var string|null */
-        private $min_wc_version = null;
-        /** @var int|null */
-        private $min_openssl_version = null;
-        /** @var array */
-        private $plugin_require;
-        /** @var array */
-        private $module_require;
-        /** @var array */
-        private $setting_require;
-        /** @var array */
-        private $notices;
-        /** @var @string */
-        private $text_domain;
-
-        /**
-         * @param string $plugin_file
-         * @param string $plugin_name
-         * @param string $text_domain
-         * @param string $php_version
-         * @param string $wp_version
-         */
-        public function __construct( $plugin_file, $plugin_name, $text_domain, $php_version, $wp_version ) {
-            $this->plugin_file = $plugin_file;
-            $this->plugin_name = $plugin_name;
-            $this->text_domain = $text_domain;
-
-            $this->set_min_php_require( $php_version );
-            $this->set_min_wp_require( $wp_version );
-
-            $this->plugin_require  = array();
-            $this->module_require  = array();
-            $this->setting_require = array();
-            $this->notices         = array();
-        }
-
-        /**
-         * @param string $version
-         *
-         * @return $this
-         */
-        public function set_min_php_require( $version ) {
-            $this->min_php_version = $version;
-
-            return $this;
-        }
-
-        /**
-         * @param string $version
-         *
-         * @return $this
-         */
-        public function set_min_wp_require( $version ) {
-            $this->min_wp_version = $version;
-
-            return $this;
-        }
-
-        /**
-         * @param string $version
-         *
-         * @return $this
-         */
-        public function set_min_wc_require( $version ) {
-            $this->min_wc_version = $version;
-
-            return $this;
-        }
-
-        /**
-         * @param $version
-         *
-         * @return $this
-         */
-        public function set_min_openssl_require( $version ) {
-            $this->min_openssl_version = $version;
-
-            return $this;
-        }
-
-        /**
-         * @param string $plugin_name
-         * @param string $nice_plugin_name Nice plugin name for better looks in notice
-         *
-         * @return $this
-         */
-        public function add_plugin_require( $plugin_name, $nice_plugin_name = null ) {
-            if ( $nice_plugin_name === null ) {
-                $this->plugin_require[ $plugin_name ] = $plugin_name;
-            } else {
-                $this->plugin_require[ $plugin_name ] = $nice_plugin_name;
-            }
-
-            return $this;
-        }
-
-        /**
-         * @param string $module_name
-         * @param string $nice_name Nice module name for better looks in notice
-         *
-         * @return $this
-         */
-        public function add_php_module_require( $module_name, $nice_name = null ) {
-            if ( $nice_name === null ) {
-                $this->module_require[ $module_name ] = $module_name;
-            } else {
-                $this->module_require[ $module_name ] = $nice_name;
-            }
-
-            return $this;
-        }
-
-        /**
-         * @param string $setting
-         * @param mixed $value
-         *
-         * @return $this
-         */
-        public function add_php_setting_require( $setting, $value ) {
-            $this->setting_require[ $setting ] = $value;
-
-            return $this;
-        }
-
-        /**
-         * @return bool
-         */
-        public function are_requirements_met() {
-            $this->notices = $this->prepare_requirement_notices();
-
-            return count( $this->notices ) === 0;
-        }
-
-        /**
-         * @return array
-         */
-        private function prepare_requirement_notices() {
-            $notices = array();
-            if ( ! self::is_php_at_least( $this->min_php_version ) ) {
-                $notices[] = $this->prepare_notice_message( sprintf( __( 'The &#8220;%s&#8221; plugin cannot run on PHP versions older than %s. Please contact your host and ask them to upgrade.',
-                    $this->get_text_domain() ), esc_html( $this->plugin_name ), $this->min_php_version ) );
-            }
-            if ( ! self::is_wp_at_least( $this->min_wp_version ) ) {
-                $notices[] = $this->prepare_notice_message( sprintf( __( 'The &#8220;%s&#8221; plugin cannot run on WordPress versions older than %s. Please update WordPress.',
-                    $this->get_text_domain() ), esc_html( $this->plugin_name ), $this->min_wp_version ) );
-            }
-            if ( $this->min_wc_version !== null && $this->can_check_plugin_version() && ! self::is_wc_at_least( $this->min_wc_version ) ) {
-                $notices[] = $this->prepare_notice_message( sprintf( __( 'The &#8220;%s&#8221; plugin cannot run on WooCommerce versions older than %s. Please update WooCommerce.',
-                    $this->get_text_domain() ), esc_html( $this->plugin_name ), $this->min_wc_version ) );
-            }
-            if ( $this->min_openssl_version !== null && ! self::is_open_ssl_at_least( $this->min_openssl_version ) ) {
-                $notices[] = $this->prepare_notice_message( sprintf( __( 'The &#8220;%s&#8221; plugin cannot run without OpenSSL module version at least %s. Please update OpenSSL module.',
-                    $this->get_text_domain() ), esc_html( $this->plugin_name ),
-                    '0x' . dechex( $this->min_openssl_version ) ) );
-            }
-
-            $notices = $this->append_plugin_require_notices( $notices );
-            $notices = $this->append_module_require_notices( $notices );
-            $notices = $this->append_settings_require_notices( $notices );
-
-            return $notices;
-        }
-
-        /**
-         * @param $min_version
-         *
-         * @return mixed
-         */
-        public static function is_php_at_least( $min_version ) {
-            return version_compare( PHP_VERSION, $min_version, '>=' );
-        }
-
-        /**
-         * Prepares message in html format
-         *
-         * @param string $message
-         *
-         * @return string
-         */
-        private function prepare_notice_message( $message ) {
-            return '<div class="error"><p>' . $message . '</p></div>';
-        }
-
-        public function get_text_domain() {
-            return $this->text_domain;
-        }
-
-        /**
-         * @param string $min_version
-         *
-         * @return bool
-         */
-        public static function is_wp_at_least( $min_version ) {
-            return version_compare( get_bloginfo( 'version' ), $min_version, '>=' );
-        }
-
-        /**
-         * Are plugins loaded so we can check the version
-         *
-         * @return bool
-         */
-        private function can_check_plugin_version() {
-            return did_action( 'plugins_loaded' ) > 0;
-        }
-
-        /**
-         * Checks if plugin is active and have designated version. Needs to be enabled in deferred way.
-         *
-         * @param string $min_version
-         *
-         * @return bool
-         */
-        public static function is_wc_at_least( $min_version ) {
-            return defined( 'WC_VERSION' ) &&
-                   version_compare( WC_VERSION, $min_version, '>=' );
-        }
-
-        /**
-         * Checks if ssl version is valid
-         *
-         * @param int $required_version Version in hex. Version 9.6 is 0x000906000
-         *
-         * @see https://www.openssl.org/docs/man1.1.0/crypto/OPENSSL_VERSION_NUMBER.html
-         *
-         * @return bool
-         */
-        public static function is_open_ssl_at_least( $required_version ) {
-            return defined( 'OPENSSL_VERSION_NUMBER' ) && OPENSSL_VERSION_NUMBER > (int) $required_version;
-        }
-
-        /**
-         * @param array $notices
-         *
-         * @return array
-         */
-        private function append_plugin_require_notices( $notices ) {
-            if ( count( $this->plugin_require ) > 0 ) {
-                foreach ( $this->plugin_require as $plugin_name => $nice_plugin_name ) {
-                    if ( ! self::is_wp_plugin_active( $plugin_name ) ) {
-                        $notices[] = $this->prepare_notice_message( sprintf( __( 'The &#8220;%s&#8221; plugin cannot run without %s active. Please install and activate %s plugin.',
-                            $this->get_text_domain() ), esc_html( $this->plugin_name ),
-                            esc_html( basename( $nice_plugin_name ) ), esc_html( basename( $nice_plugin_name ) ) ) );
-                    }
-                }
-            }
-
-            return $notices;
-        }
-
-        /**
-         * Checks if plugin is active. Needs to be enabled in deferred way.
-         *
-         * @param string $plugin_file
-         *
-         * @return bool
-         */
-        public static function is_wp_plugin_active( $plugin_file ) {
-            $active_plugins = (array) get_option( 'active_plugins', array() );
-
-            if ( is_multisite() ) {
-                $active_plugins = array_merge( $active_plugins, get_site_option( 'active_sitewide_plugins', array() ) );
-            }
-
-            return in_array( $plugin_file, $active_plugins ) || array_key_exists( $plugin_file, $active_plugins );
-        }
-
-        /**
-         * @param array $notices
-         *
-         * @return array
-         */
-        private function append_module_require_notices( $notices ) {
-            if ( count( $this->module_require ) > 0 ) {
-                foreach ( $this->module_require as $module_name => $nice_module_name ) {
-                    if ( ! self::is_module_active( $module_name ) ) {
-                        $notices[] = $this->prepare_notice_message( sprintf( __( 'The &#8220;%s&#8221; plugin cannot run without %s php module installed. Please contact your host and ask them to install %s.',
-                            $this->get_text_domain() ), esc_html( $this->plugin_name ),
-                            esc_html( basename( $nice_module_name ) ), esc_html( basename( $nice_module_name ) ) ) );
-                    }
-                }
-            }
-
-            return $notices;
-        }
-
-        /**
-         * @param string $name
-         *
-         * @return bool
-         */
-        public static function is_module_active( $name ) {
-            return extension_loaded( $name );
-        }
-
-        /**
-         * @param array $notices
-         *
-         * @return array
-         */
-        private function append_settings_require_notices( $notices ) {
-            if ( count( $this->setting_require ) > 0 ) {
-                foreach ( $this->setting_require as $setting => $value ) {
-                    if ( ! self::is_setting_set( $setting, $value ) ) {
-                        $notices[] = $this->prepare_notice_message( sprintf( __( 'The &#8220;%s&#8221; plugin cannot run without %s php setting set to %s. Please contact your host and ask them to set %s.',
-                            $this->get_text_domain() ), esc_html( $this->plugin_name ), esc_html( basename( $setting ) ),
-                            esc_html( basename( $value ) ), esc_html( basename( $setting ) ) ) );
-                    }
-                }
-            }
-
-            return $notices;
-        }
-
-        /**
-         * @param string $name
-         * @param mixed $value
-         *
-         * @return bool
-         */
-        public static function is_setting_set( $name, $value ) {
-            return ini_get( $name ) === (string) $value;
-        }
-
-        /**
-         * @return void
-         *
-         * @deprecated use render_notices or disable_plugin
-         */
-        public function disable_plugin_render_notice() {
-            add_action( self::HOOK_ADMIN_NOTICES_ACTION, array( $this, 'handle_render_notices_action') );
-        }
-
-        /**
-         * Renders requirement notices in admin panel
-         *
-         * @return void
-         */
-        public function render_notices() {
-            add_action( self::HOOK_ADMIN_NOTICES_ACTION, array( $this, 'handle_render_notices_action') );
-        }
-
-        /**
-         * Renders requirement notices in admin panel
-         *
-         * @return void
-         */
-        public function disable_plugin() {
-            add_action( self::HOOK_ADMIN_NOTICES_ACTION, array( $this, 'handle_deactivate_action') );
-        }
-
-        /**
-         * @internal Do not use as public. Public only for wp action.
-         *
-         * @return void
-         */
-        public function handle_deactivate_action() {
-            if ( isset( $this->plugin_file ) ) {
-                deactivate_plugins( plugin_basename( $this->plugin_file ) );
-            }
-        }
-
-        /**
-         * Should be called as WordPress action
-         *
-         * @internal Do not use as public. Public only for wp action.
-         *
-         * @return void
-         */
-        public function handle_render_notices_action() {
-            foreach ( $this->notices as $notice ) {
-                echo $notice;
-            }
-        }
-    }
+if ( ! class_exists( 'WPDesk_Basic_Requirement_Checker' ) ) {
+	/**
+	 * Checks requirements for plugin
+	 * have to be compatible with PHP 5.3.x
+	 */
+	class WPDesk_Basic_Requirement_Checker implements WPDesk_Requirement_Checker {
+		const EXTENSION_NAME_OPENSSL = 'openssl';
+		const HOOK_ADMIN_NOTICES_ACTION = 'admin_notices';
+
+		const PLUGIN_INFO_KEY_NICE_NAME = 'nice_name';
+		const PLUGIN_INFO_KEY_NAME = 'name';
+
+		/** @var string */
+		protected $plugin_name;
+		/** @var string */
+		private $plugin_file;
+		/** @var string */
+		private $min_php_version;
+		/** @var string */
+		private $min_wp_version;
+		/** @var string|null */
+		private $min_wc_version = null;
+		/** @var int|null */
+		private $min_openssl_version = null;
+		/** @var array */
+		protected $plugin_require;
+		/** @var array */
+		private $module_require;
+		/** @var array */
+		private $setting_require;
+		/** @var array */
+		protected $notices;
+		/** @var @string */
+		private $text_domain;
+
+		/**
+		 * @param string $plugin_file
+		 * @param string $plugin_name
+		 * @param string $text_domain
+		 * @param string $php_version
+		 * @param string $wp_version
+		 */
+		public function __construct( $plugin_file, $plugin_name, $text_domain, $php_version, $wp_version ) {
+			$this->plugin_file = $plugin_file;
+			$this->plugin_name = $plugin_name;
+			$this->text_domain = $text_domain;
+
+			$this->set_min_php_require( $php_version );
+			$this->set_min_wp_require( $wp_version );
+
+			$this->plugin_require  = array();
+			$this->module_require  = array();
+			$this->setting_require = array();
+			$this->notices         = array();
+		}
+
+		/**
+		 * @param string $version
+		 *
+		 * @return $this
+		 */
+		public function set_min_php_require( $version ) {
+			$this->min_php_version = $version;
+
+			return $this;
+		}
+
+		/**
+		 * @param string $version
+		 *
+		 * @return $this
+		 */
+		public function set_min_wp_require( $version ) {
+			$this->min_wp_version = $version;
+
+			return $this;
+		}
+
+		/**
+		 * @param string $version
+		 *
+		 * @return $this
+		 */
+		public function set_min_wc_require( $version ) {
+			$this->min_wc_version = $version;
+
+			return $this;
+		}
+
+		/**
+		 * @param $version
+		 *
+		 * @return $this
+		 */
+		public function set_min_openssl_require( $version ) {
+			$this->min_openssl_version = $version;
+
+			return $this;
+		}
+
+		/**
+		 * @param string $plugin_name Name in wp format dir/file.php
+		 * @param string $nice_plugin_name Nice plugin name for better looks in notice
+		 *
+		 * @return $this
+		 */
+		public function add_plugin_require( $plugin_name, $nice_plugin_name = null ) {
+			$this->plugin_require[ $plugin_name ] = array(
+				self::PLUGIN_INFO_KEY_NAME      => $plugin_name,
+				self::PLUGIN_INFO_KEY_NICE_NAME => $nice_plugin_name === null ? $plugin_name : $nice_plugin_name
+			);
+
+			return $this;
+		}
+
+		/**
+		 * Add plugin to require list. Plugin is from repository so we can ask for installation.
+		 *
+		 * @param string $plugin_name Name in wp format dir/file.php
+		 * @param string $version Required version of the plugin.
+		 * @param string $nice_plugin_name Nice plugin name for better looks in notice
+		 *
+		 * @return $this
+		 */
+		public function add_plugin_repository_require( $plugin_name, $version, $nice_plugin_name = null ) {
+			$this->plugin_require[ $plugin_name ] = array(
+				self::PLUGIN_INFO_KEY_NAME      => $plugin_name,
+				'version'                       => $version,
+				'repository_url'                => 'http://downloads.wordpress.org/plugin/' . dirname( $plugin_name ) . '.latest-stable.zip',
+				self::PLUGIN_INFO_KEY_NICE_NAME => $nice_plugin_name === null ? $plugin_name : $nice_plugin_name
+			);
+
+			return $this;
+		}
+
+		/**
+		 * @param string $module_name
+		 * @param string $nice_name Nice module name for better looks in notice
+		 *
+		 * @return $this
+		 */
+		public function add_php_module_require( $module_name, $nice_name = null ) {
+			if ( $nice_name === null ) {
+				$this->module_require[ $module_name ] = $module_name;
+			} else {
+				$this->module_require[ $module_name ] = $nice_name;
+			}
+
+			return $this;
+		}
+
+		/**
+		 * @param string $setting
+		 * @param mixed $value
+		 *
+		 * @return $this
+		 */
+		public function add_php_setting_require( $setting, $value ) {
+			$this->setting_require[ $setting ] = $value;
+
+			return $this;
+		}
+
+		/**
+		 * Returns true if are requirements are met.
+		 *
+		 * @return bool
+		 */
+		public function are_requirements_met() {
+			$this->notices = $this->prepare_requirement_notices();
+
+			return count( $this->notices ) === 0;
+		}
+
+		/**
+		 * @return array
+		 */
+		private function prepare_requirement_notices() {
+			$notices = array();
+			if ( ! self::is_php_at_least( $this->min_php_version ) ) {
+				$notices[] = $this->prepare_notice_message( sprintf( __( 'The &#8220;%s&#8221; plugin cannot run on PHP versions older than %s. Please contact your host and ask them to upgrade.',
+					$this->get_text_domain() ), esc_html( $this->plugin_name ), $this->min_php_version ) );
+			}
+			if ( ! self::is_wp_at_least( $this->min_wp_version ) ) {
+				$notices[] = $this->prepare_notice_message( sprintf( __( 'The &#8220;%s&#8221; plugin cannot run on WordPress versions older than %s. Please update WordPress.',
+					$this->get_text_domain() ), esc_html( $this->plugin_name ), $this->min_wp_version ) );
+			}
+			if ( $this->min_wc_version !== null && $this->can_check_plugin_version() && ! self::is_wc_at_least( $this->min_wc_version ) ) {
+				$notices[] = $this->prepare_notice_message( sprintf( __( 'The &#8220;%s&#8221; plugin cannot run on WooCommerce versions older than %s. Please update WooCommerce.',
+					$this->get_text_domain() ), esc_html( $this->plugin_name ), $this->min_wc_version ) );
+			}
+			if ( $this->min_openssl_version !== null && ! self::is_open_ssl_at_least( $this->min_openssl_version ) ) {
+				$notices[] = $this->prepare_notice_message( sprintf( __( 'The &#8220;%s&#8221; plugin cannot run without OpenSSL module version at least %s. Please update OpenSSL module.',
+					$this->get_text_domain() ), esc_html( $this->plugin_name ),
+					'0x' . dechex( $this->min_openssl_version ) ) );
+			}
+
+			$notices = $this->append_plugin_require_notices( $notices );
+			$notices = $this->append_module_require_notices( $notices );
+			$notices = $this->append_settings_require_notices( $notices );
+
+			return $notices;
+		}
+
+		/**
+		 * @param $min_version
+		 *
+		 * @return mixed
+		 */
+		public static function is_php_at_least( $min_version ) {
+			return version_compare( PHP_VERSION, $min_version, '>=' );
+		}
+
+		/**
+		 * Prepares message in html format
+		 *
+		 * @param string $message
+		 *
+		 * @return string
+		 */
+		private function prepare_notice_message( $message ) {
+			return '<div class="error"><p>' . $message . '</p></div>';
+		}
+
+		public function get_text_domain() {
+			return $this->text_domain;
+		}
+
+		/**
+		 * @param string $min_version
+		 *
+		 * @return bool
+		 */
+		public static function is_wp_at_least( $min_version ) {
+			return version_compare( get_bloginfo( 'version' ), $min_version, '>=' );
+		}
+
+		/**
+		 * Are plugins loaded so we can check the version
+		 *
+		 * @return bool
+		 */
+		private function can_check_plugin_version() {
+			return did_action( 'plugins_loaded' ) > 0;
+		}
+
+		/**
+		 * Checks if plugin is active and have designated version. Needs to be enabled in deferred way.
+		 *
+		 * @param string $min_version
+		 *
+		 * @return bool
+		 */
+		public static function is_wc_at_least( $min_version ) {
+			return defined( 'WC_VERSION' ) &&
+			       version_compare( WC_VERSION, $min_version, '>=' );
+		}
+
+		/**
+		 * Checks if ssl version is valid
+		 *
+		 * @param int $required_version Version in hex. Version 9.6 is 0x000906000
+		 *
+		 * @return bool
+		 * @see https://www.openssl.org/docs/man1.1.0/crypto/OPENSSL_VERSION_NUMBER.html
+		 *
+		 */
+		public static function is_open_ssl_at_least( $required_version ) {
+			return defined( 'OPENSSL_VERSION_NUMBER' ) && OPENSSL_VERSION_NUMBER > (int) $required_version;
+		}
+
+		/**
+		 * @param array $notices
+		 *
+		 * @return array
+		 */
+		private function append_plugin_require_notices( $notices ) {
+			if ( count( $this->plugin_require ) > 0 ) {
+				foreach ( $this->plugin_require as $plugin_name => $plugin_info ) {
+					$notice = null;
+					if ( isset( $plugin_info['repository_url'] ) ) {
+						$notice = $this->prepare_plugin_repository_require_notice( $plugin_info );
+					} elseif ( ! self::is_wp_plugin_active( $plugin_name ) ) {
+						$notice = $this->prepare_notice_message( sprintf( __( 'The &#8220;%s&#8221; plugin cannot run without %s active. Please install and activate %s plugin.',
+							$this->get_text_domain() ), esc_html( $this->plugin_name ),
+							esc_html( basename( $plugin_info[ self::PLUGIN_INFO_KEY_NICE_NAME ] ) ),
+							esc_html( basename( $plugin_info[ self::PLUGIN_INFO_KEY_NICE_NAME ] ) ) ) );
+					}
+
+					if ( $notice !== null ) {
+						$notices[] = $notice;
+					}
+				}
+			}
+
+			return $notices;
+		}
+
+		/**
+		 * Prepares WP install url and injects info about plugin to the WP update engine.
+		 *
+		 * @param array $plugin_info
+		 *
+		 * @return string
+		 */
+		private function prepare_plugin_repository_install_url( $plugin_info ) {
+			$slug        = basename( $plugin_info[ self::PLUGIN_INFO_KEY_NAME ] );
+			$install_url = wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=' . $slug ),
+				'install-plugin_' . $slug );
+
+			add_filter( 'plugins_api', function ( $api, $action, $args ) use ( $plugin_info ) {
+				if ( 'plugin_information' !== $action ||
+				     false !== $api ||
+				     ! isset( $args->slug ) ||
+				     'wpdesk-helper' !== $args->slug
+				) {
+					return $api;
+				}
+
+				$api                = new stdClass();
+				$api->name          = $plugin_info['nice_name']; // self in closures requires 5.4
+				$api->version       = $plugin_info['version']; // self in closures requires 5.4
+				$api->download_link = esc_url( $plugin_info['repository_url'] ); // self in closures requires 5.4
+
+				return $api;
+			}, 10, 3 );
+
+			return $install_url;
+		}
+
+		/**
+		 * @param array $plugin_info Internal required plugin info data.
+		 *
+		 * @return string|null Return null if no notice is needed.
+		 */
+		private function prepare_plugin_repository_require_notice( $plugin_info ) {
+			$name      = $plugin_info[ self::PLUGIN_INFO_KEY_NAME ];
+			$nice_name = $plugin_info[ self::PLUGIN_INFO_KEY_NICE_NAME ];
+
+			if ( ! self::is_wp_plugin_installed( $name ) ) {
+				$install_url = $this->prepare_plugin_repository_install_url( $plugin_info );
+
+				return sprintf( wp_kses( __( 'The &#8220;%s&#8221; plugin requires free %s plugin. <a href="%s">Install %s →</a>',
+					$this->get_text_domain() ), array( 'a' => array( 'href' => array() ) ) ),
+					$this->plugin_name, $nice_name, esc_url( $install_url ), $nice_name );
+			}
+
+			if ( ! self::is_wp_plugin_active( $name ) ) {
+				$activate_url = 'plugins.php?action=activate&plugin=' . urlencode( $plugin_info[ self::PLUGIN_INFO_KEY_NAME ] ) . '&plugin_status=all&paged=1&s&_wpnonce=' . urlencode( wp_create_nonce( 'activate-plugin_' . $name ) );
+
+				return sprintf( wp_kses( __( 'The &#8220;%s&#8221; plugin requires activating %s plugin. <a href="%s">Activate %s →</a>',
+					$this->get_text_domain() ), array( 'a' => array( 'href' => array() ) ) ),
+					$this->plugin_name, $nice_name, esc_url( admin_url( $activate_url ) ), $nice_name );
+
+			}
+
+			return null;
+		}
+
+		/**
+		 * Checks if plugin is active. Needs to be used in deferred way.
+		 *
+		 * @param string $plugin_file
+		 *
+		 * @return bool
+		 */
+		public static function is_wp_plugin_active( $plugin_file ) {
+			$active_plugins = (array) get_option( 'active_plugins', array() );
+
+			if ( is_multisite() ) {
+				$active_plugins = array_merge( $active_plugins, get_site_option( 'active_sitewide_plugins', array() ) );
+			}
+
+			return in_array( $plugin_file, $active_plugins ) || array_key_exists( $plugin_file, $active_plugins );
+		}
+
+		/**
+		 * Checks if plugin is installed. Needs to be enabled in deferred way.
+		 *
+		 * @param string $plugin_file
+		 *
+		 * @return bool
+		 */
+		public static function is_wp_plugin_installed( $plugin_file ) {
+			return array_key_exists( $plugin_file, get_plugins() );
+		}
+
+		/**
+		 * @param array $notices
+		 *
+		 * @return array
+		 */
+		private function append_module_require_notices( $notices ) {
+			if ( count( $this->module_require ) > 0 ) {
+				foreach ( $this->module_require as $module_name => $nice_module_name ) {
+					if ( ! self::is_module_active( $module_name ) ) {
+						$notices[] = $this->prepare_notice_message( sprintf( __( 'The &#8220;%s&#8221; plugin cannot run without %s php module installed. Please contact your host and ask them to install %s.',
+							$this->get_text_domain() ), esc_html( $this->plugin_name ),
+							esc_html( basename( $nice_module_name ) ), esc_html( basename( $nice_module_name ) ) ) );
+					}
+				}
+			}
+
+			return $notices;
+		}
+
+		/**
+		 * @param string $name
+		 *
+		 * @return bool
+		 */
+		public static function is_module_active( $name ) {
+			return extension_loaded( $name );
+		}
+
+		/**
+		 * @param array $notices
+		 *
+		 * @return array
+		 */
+		private function append_settings_require_notices( $notices ) {
+			if ( count( $this->setting_require ) > 0 ) {
+				foreach ( $this->setting_require as $setting => $value ) {
+					if ( ! self::is_setting_set( $setting, $value ) ) {
+						$notices[] = $this->prepare_notice_message( sprintf( __( 'The &#8220;%s&#8221; plugin cannot run without %s php setting set to %s. Please contact your host and ask them to set %s.',
+							$this->get_text_domain() ), esc_html( $this->plugin_name ),
+							esc_html( basename( $setting ) ),
+							esc_html( basename( $value ) ), esc_html( basename( $setting ) ) ) );
+					}
+				}
+			}
+
+			return $notices;
+		}
+
+		/**
+		 * @param string $name
+		 * @param mixed $value
+		 *
+		 * @return bool
+		 */
+		public static function is_setting_set( $name, $value ) {
+			return ini_get( $name ) === (string) $value;
+		}
+
+		/**
+		 * @return void
+		 *
+		 * @deprecated use render_notices or disable_plugin
+		 */
+		public function disable_plugin_render_notice() {
+			add_action( self::HOOK_ADMIN_NOTICES_ACTION, array( $this, 'handle_render_notices_action' ) );
+		}
+
+		/**
+		 * Renders requirement notices in admin panel
+		 *
+		 * @return void
+		 */
+		public function render_notices() {
+			add_action( self::HOOK_ADMIN_NOTICES_ACTION, array( $this, 'handle_render_notices_action' ) );
+		}
+
+		/**
+		 * Renders requirement notices in admin panel
+		 *
+		 * @return void
+		 */
+		public function disable_plugin() {
+			add_action( self::HOOK_ADMIN_NOTICES_ACTION, array( $this, 'handle_deactivate_action' ) );
+		}
+
+		/**
+		 * @return void
+		 * @internal Do not use as public. Public only for wp action.
+		 *
+		 */
+		public function handle_deactivate_action() {
+			if ( isset( $this->plugin_file ) ) {
+				deactivate_plugins( plugin_basename( $this->plugin_file ) );
+			}
+		}
+
+		/**
+		 * Should be called as WordPress action
+		 *
+		 * @return void
+		 * @internal Do not use as public. Public only for wp action.
+		 *
+		 */
+		public function handle_render_notices_action() {
+			foreach ( $this->notices as $notice ) {
+				echo $notice;
+			}
+		}
+	}
 }
\ No newline at end of file
diff --git a/src/Basic_Requirement_Checker_Factory.php b/src/Basic_Requirement_Checker_Factory.php
index a4bbb9cedf9dd6e93b43659438955140177043b0..5c691b679b8f52844f78e3af1d63a5ec64074689 100644
--- a/src/Basic_Requirement_Checker_Factory.php
+++ b/src/Basic_Requirement_Checker_Factory.php
@@ -1,22 +1,98 @@
 <?php
 
-if ( ! class_exists('Basic_Requirement_Checker')) {
-    require_once 'Basic_Requirement_Checker.php';
+if ( ! class_exists( 'Basic_Requirement_Checker' ) ) {
+	require_once 'Basic_Requirement_Checker.php';
 }
 
-class WPDesk_Basic_Requirement_Checker_Factory
-{
-    /**
-     * @param $plugin_file
-     * @param $plugin_name
-     * @param $text_domain
-     * @param $php_version
-     * @param $wp_version
-     *
-     * @return WPDesk_Requirement_Checker
-     */
-    public function create_requirement_checker($plugin_file, $plugin_name, $text_domain)
-    {
-        return new WPDesk_Basic_Requirement_Checker($plugin_file, $plugin_name, $text_domain, null, null);
-    }
+if ( ! class_exists( 'WPDesk_Basic_Requirement_Checker_With_Update_Disable' ) ) {
+	require_once 'Basic_Requirement_Checker_With_Update_Disable.php';
+}
+
+/**
+ * Falicitates createion of requirement checker
+ */
+class WPDesk_Basic_Requirement_Checker_Factory {
+	const LIBRARY_TEXT_DOMAIN = 'wp-basic-requirements';
+
+	/**
+	 * Creates a simplest possible version of requirement checker.
+	 *
+	 * @param string $plugin_file
+	 * @param string $plugin_name
+	 * @param string|null $text_domain Text domain to use. If null try to use library text domain.
+	 *
+	 * @return WPDesk_Requirement_Checker
+	 */
+	public function create_requirement_checker( $plugin_file, $plugin_name, $text_domain = null ) {
+		return new WPDesk_Basic_Requirement_Checker( $plugin_file, $plugin_name,
+			$this->initialize_translations( $text_domain ), null, null );
+	}
+
+	/**
+	 * Creates a requirement checker according to given requirements array info.
+	 *
+	 * @param string $plugin_file
+	 * @param string $plugin_name
+	 * @param string $text_domain Text domain to use. If null try to use library text domain.
+	 * @param array $requirements Requirements array as given by plugin.
+	 *
+	 * @return WPDesk_Requirement_Checker
+	 */
+	public function create_from_requirement_array( $plugin_file, $plugin_name, $requirements, $text_domain = null ) {
+		$requirements_checker = new WPDesk_Basic_Requirement_Checker_With_Update_Disable(
+			$plugin_file,
+			$plugin_name,
+			$this->initialize_translations( $text_domain ),
+			$requirements['php'],
+			$requirements['wp']
+		);
+
+		if ( isset( $requirements['plugins'] ) ) {
+			foreach ( $requirements['plugins'] as $requirement ) {
+				$requirements_checker->add_plugin_require( $requirement['name'], $requirement['nice_name'] );
+			}
+		}
+
+		if ( isset( $requirements['repo_plugins'] ) ) {
+			foreach ( $requirements['repo_plugins'] as $requirement ) {
+				$requirements_checker->add_plugin_repository_require( $requirement['name'], $requirement['version'],
+					$requirement['nice_name'] );
+			}
+		}
+
+		if ( isset( $requirements['modules'] ) ) {
+			foreach ( $requirements['modules'] as $requirement ) {
+				$requirements_checker->add_php_module_require( $requirement['name'], $requirement['nice_name'] );
+			}
+		}
+
+		return $requirements_checker;
+	}
+
+	/**
+	 * Tries to initialize translations for requirement checker. If not given then default library translation is used.
+	 *
+	 * @param string|null $text_domain
+	 *
+	 * @return string
+	 */
+	private function initialize_translations( $text_domain = null ) {
+		if ( $text_domain === null ) {
+			$text_domain = self::LIBRARY_TEXT_DOMAIN;
+
+			if ( function_exists( 'determine_locale' ) ) {
+				$locale = determine_locale();
+			} else { // before WP 5.0 compatibility
+				$locale = get_locale();
+			}
+			$locale = apply_filters( 'plugin_locale', $locale, self::LIBRARY_TEXT_DOMAIN );
+
+			$lang_mo_file = __DIR__ . '/../lang/' . self::LIBRARY_TEXT_DOMAIN . '-' . $locale . '.mo';
+			if ( file_exists( $lang_mo_file ) ) {
+				load_textdomain( self::LIBRARY_TEXT_DOMAIN, $lang_mo_file );
+			}
+		}
+
+		return $text_domain;
+	}
 }
diff --git a/src/Basic_Requirement_Checker_With_Update_Disable.php b/src/Basic_Requirement_Checker_With_Update_Disable.php
new file mode 100644
index 0000000000000000000000000000000000000000..aeaf871381680523dd8218e7d291bc669bf518c4
--- /dev/null
+++ b/src/Basic_Requirement_Checker_With_Update_Disable.php
@@ -0,0 +1,47 @@
+<?php
+
+if ( ! class_exists( 'WPDesk_Basic_Requirement_Checker' ) ) {
+	require_once 'Basic_Requirement_Checker.php';
+}
+
+if ( ! class_exists( 'WPDesk_Basic_Requirement_Checker_With_Update_Disable' ) ) {
+	/**
+	 * Checks requirements for plugin. When required plugin is updated right now, then say that requirements are not met temporary.
+	 * have to be compatible with PHP 5.2.x
+	 */
+	class WPDesk_Basic_Requirement_Checker_With_Update_Disable extends WPDesk_Basic_Requirement_Checker {
+
+		/**
+		 * Returns true if are requirements are met.
+		 *
+		 * @return bool
+		 */
+		public function are_requirements_met() {
+			$has_been_met = parent::are_requirements_met();
+			if ( ! $has_been_met ) {
+				return $has_been_met;
+			}
+			foreach ( $this->plugin_require as $name => $plugin_info ) {
+				if ( $this->is_currently_updated( $name ) ) {
+					$nice_name = $plugin_info[self::PLUGIN_INFO_KEY_NICE_NAME];
+					$this->notices[] = sprintf( __( 'The &#8220;%s&#8221; plugin disables temporarily as required %s plugin is being upgraded.',
+						$this->get_text_domain() ),
+						$this->plugin_name, $nice_name, $nice_name );
+				}
+			}
+
+			return count( $this->notices ) === 0;
+		}
+
+		/**
+		 * Is plugin upgrading right now?
+		 *
+		 * @param string $name
+		 *
+		 * @return bool
+		 */
+		private function is_currently_updated( $name ) {
+			return isset( $_GET['action'] ) && $_GET['action'] === 'upgrade-plugin' && $_GET['plugin'] === $name;
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/Buildable.php b/src/Buildable.php
deleted file mode 100644
index 78c73224961af9592e346b83fd58f360d06971fa..0000000000000000000000000000000000000000
--- a/src/Buildable.php
+++ /dev/null
@@ -1,11 +0,0 @@
-<?php
-
-/**
- * Have info about what class should be built by WPDesk_Builder
- *
- * have to be compatible with PHP 5.2.x
- */
-interface WPDesk_Buildable {
-	/** @return string */
-	public function get_class_name();
-}
\ No newline at end of file
diff --git a/src/Plugin/Has_Plugin_Info.php b/src/Plugin/Has_Plugin_Info.php
deleted file mode 100644
index 5ecf98d525474f04c37ff04a64ec6926e653e5c4..0000000000000000000000000000000000000000
--- a/src/Plugin/Has_Plugin_Info.php
+++ /dev/null
@@ -1,29 +0,0 @@
-<?php
-
-if ( ! interface_exists( 'WPDesk_Translatable' ) ) {
-	require_once __DIR__ . '/../Translatable.php';
-}
-
-
-/**
- * Have MUST HAVE info for plugin instantion
- *
- * have to be compatible with PHP 5.2.x
- */
-interface WPDesk_Has_Plugin_Info extends WPDesk_Translatable {
-	/**
-	 * @return string
-	 */
-	public function get_plugin_file_name();
-
-	/**
-	 * @return string
-	 */
-	public function get_plugin_dir();
-
-	/**
-	 * @return string
-	 */
-	public function get_version();
-
-}
\ No newline at end of file
diff --git a/src/Plugin/Plugin_Info.php b/src/Plugin/Plugin_Info.php
deleted file mode 100644
index 693b408066013e55319f7b6ca32159849081ffea..0000000000000000000000000000000000000000
--- a/src/Plugin/Plugin_Info.php
+++ /dev/null
@@ -1,171 +0,0 @@
-<?php
-
-if ( ! interface_exists( 'WPDesk_Translatable' ) ) {
-	require_once __DIR__ . '/../Translatable.php';
-}
-if ( ! class_exists( 'WPDesk_Buildable' ) ) {
-	require_once __DIR__ . '/../Buildable.php';
-}
-if ( ! class_exists( 'WPDesk_Has_Plugin_Info' ) ) {
-	require_once 'Has_Plugin_Info.php';
-}
-
-/**
- * Structure with core info about plugin
- *
- * have to be compatible with PHP 5.2.x
- */
-class WPDesk_Plugin_Info implements WPDesk_Translatable, WPDesk_Buildable, WPDesk_Has_Plugin_Info {
-	/** @var string */
-	private $plugin_file_name;
-
-	/** @var string */
-	private $plugin_dir;
-
-	/** @var string */
-	private $plugin_url;
-
-	/** @var string */
-	private $class_name;
-
-	/** @var string */
-	private $version;
-
-	/** @var string */
-	private $product_id;
-
-	/** @var string */
-	private $plugin_name;
-
-	/** @var \DateTimeInterface */
-	private $release_date;
-
-	/** string */
-	private $text_domain;
-
-	/**
-	 * @return string
-	 */
-	public function get_plugin_file_name() {
-		return $this->plugin_file_name;
-	}
-
-	/**
-	 * @param string $plugin_name
-	 */
-	public function set_plugin_file_name( $plugin_name ) {
-		$this->plugin_file_name = $plugin_name;
-	}
-
-	/**
-	 * @return string
-	 */
-	public function get_plugin_dir() {
-		return $this->plugin_dir;
-	}
-
-	/**
-	 * @param string $plugin_dir
-	 */
-	public function set_plugin_dir( $plugin_dir ) {
-		$this->plugin_dir = $plugin_dir;
-	}
-
-	/**
-	 * @return string
-	 */
-	public function get_plugin_url() {
-		return $this->plugin_url;
-	}
-
-	/**
-	 * @param string $plugin_url
-	 */
-	public function set_plugin_url( $plugin_url ) {
-		$this->plugin_url = $plugin_url;
-	}
-
-	/**
-	 * @return string
-	 */
-	public function get_version() {
-		return $this->version;
-	}
-
-	/**
-	 * @param string $version
-	 */
-	public function set_version( $version ) {
-		$this->version = $version;
-	}
-
-	/**
-	 * @return string
-	 */
-	public function get_product_id() {
-		return $this->product_id;
-	}
-
-	/**
-	 * @param string $product_id
-	 */
-	public function set_product_id( $product_id ) {
-		$this->product_id = $product_id;
-	}
-
-	/**
-	 * @return string
-	 */
-	public function get_plugin_name() {
-		return $this->plugin_name;
-	}
-
-	/**
-	 * @param string $plugin_name
-	 */
-	public function set_plugin_name( $plugin_name ) {
-		$this->plugin_name = $plugin_name;
-	}
-
-	/**
-	 * @return DateTimeInterface
-	 */
-	public function get_release_date() {
-		return $this->release_date;
-	}
-
-	/**
-	 * @param \DateTimeInterface $release_date
-	 */
-	public function set_release_date( $release_date ) {
-		$this->release_date = $release_date;
-	}
-
-	/**
-	 * @return string
-	 */
-	public function get_class_name() {
-		return $this->class_name;
-	}
-
-	/**
-	 * @param string $class_name
-	 */
-	public function set_class_name( $class_name ) {
-		$this->class_name = $class_name;
-	}
-
-	/**
-	 * @return string
-	 */
-	public function get_text_domain() {
-		return $this->text_domain;
-	}
-
-	/**
-	 * @param $value
-	 */
-	public function set_text_domain( $value ) {
-		$this->text_domain = $value;
-	}
-}
\ No newline at end of file
diff --git a/src/Translable.php b/src/Translable.php
deleted file mode 100644
index c13e2a7e778efd5765940d3517969136766540fc..0000000000000000000000000000000000000000
--- a/src/Translable.php
+++ /dev/null
@@ -1,9 +0,0 @@
-<?php
-
-/**
- * @deprecated Have typo so better use WPDesk_Translatable
- */
-interface WPDesk_Translable  {
-	/** @return string */
-	public function get_text_domain();
-}
\ No newline at end of file
diff --git a/src/Translatable.php b/src/Translatable.php
deleted file mode 100644
index a1d9eea460dfe4fd8a113ee8c670b813f5e76786..0000000000000000000000000000000000000000
--- a/src/Translatable.php
+++ /dev/null
@@ -1,15 +0,0 @@
-<?php
-
-if ( ! interface_exists( 'WPDesk_Translable' ) ) {
-    require_once 'Translable.php';
-}
-
-/**
- * Have info about textdomain - how to translate texts
- *
- * have to be compatible with PHP 5.2.x
- */
-interface WPDesk_Translatable extends WPDesk_Translable {
-	/** @return string */
-	public function get_text_domain();
-}
\ No newline at end of file
diff --git a/tests/unit/Test_Basic_Requirement_Checker.php b/tests/unit/Test_Basic_Requirement_Checker.php
index 260369cb7ae4e8233e25b552878685d7a4ac2250..552b31fbbff8e58fc1d9ee8a26eb7f8fe3912e69 100644
--- a/tests/unit/Test_Basic_Requirement_Checker.php
+++ b/tests/unit/Test_Basic_Requirement_Checker.php
@@ -27,7 +27,7 @@ class Test_Basic_Requirement_Checker extends PHPUnit\Framework\TestCase {
 	}
 
 	public function test_php_version_check() {
-		$known_PHP_versions = [ '7.3', '7.2', '7.1', '7.0', '5.6', '5.5', '5.4', '5.3', '5.2' ];
+		$known_PHP_versions = array( '7.3', '7.2', '7.1', '7.0', '5.6', '5.5', '5.4', '5.3', '5.2' );
 
 		$requirements = $this->create_requirements_for_php_wp(
 			self::ALWAYS_VALID_PHP_VERSION,
@@ -55,7 +55,7 @@ class Test_Basic_Requirement_Checker extends PHPUnit\Framework\TestCase {
 	 *
 	 * @return WPDesk_Basic_Requirement_Checker
 	 */
-	public function create_requirements_for_php_wp( $php, $wp ) {
+	private function create_requirements_for_php_wp( $php, $wp ) {
 		return new WPDesk_Basic_Requirement_Checker( self::RANDOM_PLUGIN_FILE, self::RANDOM_PLUGIN_NAME,
 			self::RANDOM_PLUGIN_TEXTDOMAIN, $php, $wp );
 	}
@@ -98,15 +98,15 @@ class Test_Basic_Requirement_Checker extends PHPUnit\Framework\TestCase {
 		$not_existing_plugin_name      = 'Not exist';
 
 		WP_Mock::wpFunction( 'get_option' )
-		       ->withArgs( [ 'active_plugins', [] ] )
-		       ->andReturn( [ $exising_plugin_name ] );
+		       ->withArgs( array( 'active_plugins', array() ) )
+		       ->andReturn( array( $exising_plugin_name ) );
 
 		WP_Mock::wpFunction( 'is_multisite' )
 		       ->andReturn( $multisite );
 
 		WP_Mock::wpFunction( 'get_site_option' )
-		       ->withArgs( [ 'active_sitewide_plugins', [] ] )
-		       ->andReturn( [ $exising_multisite_plugin_name ] );
+		       ->withArgs( array( 'active_sitewide_plugins', array() ) )
+		       ->andReturn( array( $exising_multisite_plugin_name ) );
 
 
 		$requirements = $this->create_requirements_for_php_wp( self::ALWAYS_VALID_PHP_VERSION,
@@ -155,13 +155,53 @@ class Test_Basic_Requirement_Checker extends PHPUnit\Framework\TestCase {
 			self::ALWAYS_VALID_WP_VERSION );
 
 		WP_Mock::expectActionAdded( WPDesk_Basic_Requirement_Checker::HOOK_ADMIN_NOTICES_ACTION,
-			[ $requirements, 'handle_render_notices_action'] );
+			array( $requirements, 'handle_render_notices_action' ) );
 
 		$this->assertFalse( $requirements->are_requirements_met() );
 		$requirements->disable_plugin();
-        $requirements->render_notices();
+		$requirements->render_notices();
 
 		$this->expectOutputRegex( '/cannot run on PHP/' );
 		$requirements->handle_render_notices_action();
 	}
+
+	public function test_add_plugin_repository_require_checks_for_activation_and_installs() {
+		$random_version            = "1.0";
+		$activated_plugin_name     = 'WooCommerce';
+		$not_activated_plugin_name = "some_other";
+		$not_installed_plugin_name = "not_installed";
+		$installed_plugin_names    = array( $activated_plugin_name, $not_activated_plugin_name );
+
+
+		WP_Mock::wpFunction( 'get_plugins' )
+		       ->andReturn( array_flip( $installed_plugin_names ) );
+
+		WP_Mock::wpFunction( 'get_option' )
+		       ->withArgs( array( 'active_plugins', array() ) )
+		       ->andReturn( array( $activated_plugin_name ) );
+
+		WP_Mock::passthruFunction( 'self_admin_url' );
+		WP_Mock::passthruFunction( 'wp_kses' );
+		WP_Mock::passthruFunction( 'wp_nonce_url' );
+		WP_Mock::passthruFunction( 'wp_create_nonce' );
+		WP_Mock::passthruFunction( 'admin_url' );
+
+		$requirements = $this->create_requirements_for_php_wp( self::ALWAYS_VALID_PHP_VERSION,
+			self::ALWAYS_VALID_WP_VERSION );
+
+		$requirements->add_plugin_repository_require( $activated_plugin_name, $random_version );
+		$this->assertTrue( $requirements->are_requirements_met(), "Should be met for activated plugin" );
+
+		$requirements->add_plugin_repository_require( $not_activated_plugin_name, $random_version );
+		$this->assertFalse( $requirements->are_requirements_met(), "Should NOT be met for only installed plugin" );
+
+		$this->expectOutputRegex( "/Activate $not_activated_plugin_name/" );
+		$requirements->handle_render_notices_action();
+
+		$requirements->add_plugin_repository_require( $not_installed_plugin_name, $random_version );
+		$this->expectOutputRegex( "/Install $not_installed_plugin_name/" );
+		$this->assertFalse( $requirements->are_requirements_met(),
+			"Should NOT be met - uninstalled and unactive plugins are required" );
+		$requirements->handle_render_notices_action();
+	}
 }
diff --git a/tests/unit/Test_Basic_Requirement_Checker_Factory.php b/tests/unit/Test_Basic_Requirement_Checker_Factory.php
new file mode 100644
index 0000000000000000000000000000000000000000..adbf8d9578ddb9e8c825983c1e9a90a661e3389e
--- /dev/null
+++ b/tests/unit/Test_Basic_Requirement_Checker_Factory.php
@@ -0,0 +1,52 @@
+<?php
+
+
+class Test_Basic_Requirement_Checker_Factory extends PHPUnit\Framework\TestCase {
+	public function test_can_create_checker_withn_valid_requirements() {
+		$existing_locale = 'pl_PL';
+		$requirements = array(
+			'php'          => '5.6',
+			'wp'           => '4.5',
+			'plugins'      => array(
+				array(
+					'name'      => 'woocommerce/woocommerce.php',
+					'nice_name' => 'WooCommerce',
+				),
+			),
+			'repo_plugins' => array(
+				array(
+					'name'      => 'flexible-checkout-fields/flexible-checkout-fields.php',
+					'version'   => '1.0',
+					'nice_name' => 'Flexible Checkout Fields',
+				),
+			),
+		);
+
+		WP_Mock::wpFunction( 'get_locale' )
+		       ->andReturn( $existing_locale );
+		WP_Mock::wpFunction( 'load_textdomain' )
+			->once(); // locale pl_PL exists so it should try to load it
+
+		$factory = new WPDesk_Basic_Requirement_Checker_Factory();
+		$checker = $factory->create_from_requirement_array( 'whatever', 'whatever', $requirements );
+
+		WP_Mock::wpFunction( 'get_plugins' )
+		       ->andReturn( array() );
+
+		WP_Mock::wpFunction( 'get_option' )
+		       ->withArgs( array( 'active_plugins', array() ) )
+		       ->andReturn( array() );
+
+		WP_Mock::passthruFunction( 'self_admin_url' );
+		WP_Mock::passthruFunction( 'wp_kses' );
+		WP_Mock::passthruFunction( 'wp_nonce_url' );
+		WP_Mock::passthruFunction( 'wp_create_nonce' );
+		WP_Mock::passthruFunction( 'admin_url' );
+
+		$this->assertFalse( $checker->are_requirements_met(), '2 plugins required and there should be none activated' );
+
+		$this->expectOutputRegex( '/Flexible Checkout Fields/' );
+		$this->expectOutputRegex( '/WooCommerce/' );
+		$checker->handle_render_notices_action();
+	}
+}
diff --git a/tests/unit/Test_Basic_Requirement_Checker_With_Update_Disable.php b/tests/unit/Test_Basic_Requirement_Checker_With_Update_Disable.php
new file mode 100644
index 0000000000000000000000000000000000000000..ce3d688f1ea514b93196ae8b8800729fa511847a
--- /dev/null
+++ b/tests/unit/Test_Basic_Requirement_Checker_With_Update_Disable.php
@@ -0,0 +1,42 @@
+<?php
+
+class Test_Basic_Requirement_Checker_With_Update_Disable extends PHPUnit\Framework\TestCase {
+	const RANDOM_PLUGIN_FILE = 'file';
+	const RANDOM_PLUGIN_NAME = 'name';
+	const ALWAYS_VALID_PHP_VERSION = '5.2';
+	const ALWAYS_VALID_WP_VERSION = '4.0';
+	const RANDOM_PLUGIN_TEXTDOMAIN = 'text';
+
+	public function setUp() {
+		WP_Mock::setUp();
+
+		WP_Mock::wpFunction( 'get_bloginfo' )
+		       ->andReturn( self::ALWAYS_VALID_WP_VERSION );
+	}
+
+	public function tearDown() {
+		WP_Mock::tearDown();
+	}
+
+	public function test_requirements_are_not_met_when_plugin_update() {
+		$checker = new WPDesk_Basic_Requirement_Checker_With_Update_Disable( self::RANDOM_PLUGIN_FILE,
+			self::RANDOM_PLUGIN_NAME,
+			self::RANDOM_PLUGIN_TEXTDOMAIN, self::ALWAYS_VALID_PHP_VERSION, self::ALWAYS_VALID_WP_VERSION );
+
+		$this->assertTrue( $checker->are_requirements_met(), 'Initial php and wp version should be met' );
+
+		$valid_plugin_name = 'woocommerce/woocommerce.php';
+
+		WP_Mock::wpFunction( 'get_option' )
+		       ->withArgs( array( 'active_plugins', array() ) )
+		       ->andReturn( array( $valid_plugin_name ) );
+
+		$checker->add_plugin_require( $valid_plugin_name );
+		$this->assertTrue( $checker->are_requirements_met(), 'Plugin is activated so initial requirements should be met' );
+
+		$real_woocommerce_upgrade_url = '/wp-admin/update.php?action=upgrade-plugin&plugin=woocommerce%2Fwoocommerce.php&_wpnonce=263d805825';
+		$url                     = parse_url( $real_woocommerce_upgrade_url );
+		parse_str( $url['query'], $_GET );
+		$this->assertFalse( $checker->are_requirements_met(), 'Info about upgrade should switch result' );
+	}
+}