diff --git a/includes/url_to_absolute.inc b/includes/url_to_absolute.inc
deleted file mode 100644
index 82a9195..0000000
--- a/includes/url_to_absolute.inc
+++ /dev/null
@@ -1,566 +0,0 @@
-<?php
-/**
- * @file
- * Edited by Nitin Kr. Gupta, publicmind.in
- *
- * A library with some url-related functions.
- */
-
-/**
- * Copyright (c) 2008, David R. Nadeau, NadeauSoftware.com.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *   * Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *
- *   * Redistributions in binary form must reproduce the above
- *     copyright notice, this list of conditions and the following
- *     disclaimer in the documentation and/or other materials provided
- *     with the distribution.
- *
- *   * Neither the names of David R. Nadeau or NadeauSoftware.com, nor
- *     the names of its contributors may be used to endorse or promote
- *     products derived from this software without specific prior
- *     written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
- * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- */
-
-/*
- * This is a BSD License approved by the Open Source Initiative (OSI).
- * See:  http://www.opensource.org/licenses/bsd-license.php
- */
-
-/**
- * Combine a base URL and a relative URL to produce a new
- * absolute URL.  The base URL is often the URL of a page,
- * and the relative URL is a URL embedded on that page.
- *
- * This function implements the "absolutize" algorithm from
- * the RFC3986 specification for URLs.
- *
- * This function supports multi-byte characters with the UTF-8 encoding,
- * per the URL specification.
- *
- * Parameters:
- *    baseUrl      the absolute base URL.
- *
- *    url      the relative URL to convert.
- *
- * Return values:
- *    An absolute URL that combines parts of the base and relative
- *    URLs, or FALSE if the base URL is not absolute or if either
- *    URL cannot be parsed.
- */
-function url_to_absolute($base_url, $relative_url) {
-  // If relative URL has a scheme, clean path and return.
-  $r = split_url($relative_url);
-  if ($r === FALSE) {
-    return FALSE;
-  }
-  if (!empty($r['scheme'])) {
-    if (!empty($r['path']) && $r['path'][0] == '/') {
-      $r['path'] = url_remove_dot_segments($r['path']);
-    }
-
-    return join_url($r);
-  }
-
-  // Make sure the base URL is absolute.
-  $b = split_url($base_url);
-  if ($b === FALSE || empty($b['scheme']) || empty($b['host'])) {
-    return FALSE;
-  }
-  $r['scheme'] = $b['scheme'];
-
-  // If relative URL has an authority, clean path and return.
-  if (isset($r['host'])) {
-    if (!empty($r['path'])) {
-      $r['path'] = url_remove_dot_segments($r['path']);
-    }
-
-    return join_url($r);
-  }
-  unset($r['port']);
-  unset($r['user']);
-  unset($r['pass']);
-
-  // Copy base authority.
-  $r['host'] = $b['host'];
-  if (isset($b['port'])) {
-    $r['port'] = $b['port'];
-  }
-  if (isset($b['user'])) {
-    $r['user'] = $b['user'];
-  }
-  if (isset($b['pass'])) {
-    $r['pass'] = $b['pass'];
-  }
-
-  // If relative URL has no path, use base path
-  if (empty($r['path'])) {
-    if (!empty($b['path'])) {
-      $r['path'] = $b['path'];
-    }
-    if (!isset($r['query']) && isset($b['query'])) {
-      $r['query'] = $b['query'];
-    }
-
-    return join_url($r);
-  }
-
-  // If relative URL path doesn't start with /, merge with base path
-  if (isset($b['path']) && $r['path'][0] != '/') {
-    $base = mb_strrchr($b['path'], '/', TRUE, 'UTF-8');
-    if ($base === FALSE) {
-      $base = '';
-    }
-    $r['path'] = $base . '/' . $r['path'];
-  }
-  $r['path'] = url_remove_dot_segments($r['path']);
-
-  return join_url($r);
-}
-
-/**
- * Filter out "." and ".." segments from a URL's path and return
- * the result.
- *
- * This function implements the "remove_dot_segments" algorithm from
- * the RFC3986 specification for URLs.
- *
- * This function supports multi-byte characters with the UTF-8 encoding,
- * per the URL specification.
- *
- * Parameters:
- *    path   the path to filter
- *
- * Return values:
- *    The filtered path with "." and ".." removed.
- */
-function url_remove_dot_segments($path) {
-  // multi-byte character explode
-  $in_segs = preg_split('!/!u', $path);
-  $out_segs = array();
-  foreach ($in_segs as $seg) {
-    if ($seg == '' || $seg == '.') {
-      continue;
-    }
-    if ($seg == '..') {
-      array_pop($out_segs);
-    }
-    else {
-      array_push($out_segs, $seg);
-    }
-  }
-  $out_path = implode('/', $out_segs);
-  if ($path[0] == '/') {
-    $out_path = '/' . $out_path;
-  }
-  // compare last multi-byte character against '/'
-  if ($out_path != '/' &&
-    (mb_strlen($path) - 1) == mb_strrpos($path, '/', 'UTF-8')
-  ) {
-    $out_path .= '/';
-  }
-
-  return $out_path;
-}
-
-/**
- * This function parses an absolute or relative URL and splits it
- * into individual components.
- *
- * RFC3986 specifies the components of a Uniform Resource Identifier (URI).
- * A portion of the ABNFs are repeated here:
- *
- *   URI-reference   = URI
- *         / relative-ref
- *
- *   URI      = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
- *
- *   relative-ref   = relative-part [ "?" query ] [ "#" fragment ]
- *
- *   hier-part   = "//" authority path-abempty
- *         / path-absolute
- *         / path-rootless
- *         / path-empty
- *
- *   relative-part   = "//" authority path-abempty
- *         / path-absolute
- *         / path-noscheme
- *         / path-empty
- *
- *   authority   = [ userinfo "@" ] host [ ":" port ]
- *
- * So, a URL has the following major components:
- *
- *   scheme
- *      The name of a method used to interpret the rest of
- *      the URL.  Examples:  "http", "https", "mailto", "file'.
- *
- *   authority
- *      The name of the authority governing the URL's name
- *      space.  Examples:  "example.com", "user@example.com",
- *      "example.com:80", "user:password@example.com:80".
- *
- *      The authority may include a host name, port number,
- *      user name, and password.
- *
- *      The host may be a name, an IPv4 numeric address, or
- *      an IPv6 numeric address.
- *
- *   path
- *      The hierarchical path to the URL's resource.
- *      Examples:  "/index.htm", "/scripts/page.php".
- *
- *   query
- *      The data for a query.  Examples:  "?search=google.com".
- *
- *   fragment
- *      The name of a secondary resource relative to that named
- *      by the path.  Examples:  "#section1", "#header".
- *
- * An "absolute" URL must include a scheme and path.  The authority, query,
- * and fragment components are optional.
- *
- * A "relative" URL does not include a scheme and must include a path.  The
- * authority, query, and fragment components are optional.
- *
- * This function splits the $url argument into the following components
- * and returns them in an associative array.  Keys to that array include:
- *
- *   "scheme"   The scheme, such as "http".
- *   "host"      The host name, IPv4, or IPv6 address.
- *   "port"      The port number.
- *   "user"      The user name.
- *   "pass"      The user password.
- *   "path"      The path, such as a file path for "http".
- *   "query"      The query.
- *   "fragment"   The fragment.
- *
- * One or more of these may not be present, depending upon the URL.
- *
- * Optionally, the "user", "pass", "host" (if a name, not an IP address),
- * "path", "query", and "fragment" may have percent-encoded characters
- * decoded.  The "scheme" and "port" cannot include percent-encoded
- * characters and are never decoded.  Decoding occurs after the URL has
- * been parsed.
- *
- * Parameters:
- *    url      the URL to parse.
- *
- *    decode      an optional boolean flag selecting whether
- *          to decode percent encoding or not.  Default = TRUE.
- *
- * Return values:
- *    the associative array of URL parts, or FALSE if the URL is
- *    too malformed to recognize any parts.
- */
-function split_url($url, $decode = FALSE) {
-  $parts = array();
-
-  // Character sets from RFC3986.
-  $xunressub = 'a-zA-Z\d\-._~\!$&\'()*+,;=';
-  $xpchar = $xunressub . ':@% ';
-
-  // Scheme from RFC3986.
-  $xscheme = '([a-zA-Z][a-zA-Z\d+-.]*)';
-
-  // User info (user + password) from RFC3986.
-  $xuserinfo = '(([' . $xunressub . '%]*)' .
-    '(:([' . $xunressub . ':%]*))?)';
-
-  // IPv4 from RFC3986 (without digit constraints).
-  $xipv4 = '(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})';
-
-  // IPv6 from RFC2732 (without digit and grouping constraints).
-  $xipv6 = '(\[([a-fA-F\d.:]+)\])';
-
-  // Host name from RFC1035.  Technically, must start with a letter.
-  // Relax that restriction to better parse URL structure, then
-  // leave host name validation to application.
-  $xhost_name = '([a-zA-Z\d-.%]+)';
-
-  // Authority from RFC3986.  Skip IP future.
-  $xhost = '(' . $xhost_name . '|' . $xipv4 . '|' . $xipv6 . ')';
-  $xport = '(\d*)';
-  $xauthority = '((' . $xuserinfo . '@)?' . $xhost .
-    '?(:' . $xport . ')?)';
-
-  // Path from RFC3986.  Blend absolute & relative for efficiency.
-  $xslash_seg = '(/[' . $xpchar . ']*)';
-  $xpath_authabs = '((//' . $xauthority . ')((/[' . $xpchar . ']*)*))';
-  $xpath_rel = '([' . $xpchar . ']+' . $xslash_seg . '*)';
-  $xpath_abs = '(/(' . $xpath_rel . ')?)';
-  $xapath = '(' . $xpath_authabs . '|' . $xpath_abs .
-    '|' . $xpath_rel . ')';
-
-  // Query and fragment from RFC3986.
-  $xqueryfrag = '([' . $xpchar . '/?' . ']*)';
-
-  // URL.
-  $xurl = '^(' . $xscheme . ':)?' . $xapath . '?' .
-    '(\?' . $xqueryfrag . ')?(#' . $xqueryfrag . ')?$';
-
-  // Split the URL into components.
-  if (!preg_match('!' . $xurl . '!', $url, $m)) {
-    return FALSE;
-  }
-
-  if (!empty($m[2])) {
-    $parts['scheme'] = strtolower($m[2]);
-  }
-
-  if (!empty($m[7])) {
-    if (isset($m[9])) {
-      $parts['user'] = $m[9];
-    }
-    else {
-      $parts['user'] = '';
-    }
-  }
-  if (!empty($m[10])) {
-    $parts['pass'] = $m[11];
-  }
-
-  if (!empty($m[13])) {
-    $h = $parts['host'] = $m[13];
-  }
-  else {
-    if (!empty($m[14])) {
-      $parts['host'] = $m[14];
-    }
-    else {
-      if (!empty($m[16])) {
-        $parts['host'] = $m[16];
-      }
-      else {
-        if (!empty($m[5])) {
-          $parts['host'] = '';
-        }
-      }
-    }
-  }
-  if (!empty($m[17])) {
-    $parts['port'] = $m[18];
-  }
-
-  if (!empty($m[19])) {
-    $parts['path'] = $m[19];
-  }
-  else {
-    if (!empty($m[21])) {
-      $parts['path'] = $m[21];
-    }
-    else {
-      if (!empty($m[25])) {
-        $parts['path'] = $m[25];
-      }
-    }
-  }
-
-  if (!empty($m[27])) {
-    $parts['query'] = $m[28];
-  }
-  if (!empty($m[29])) {
-    $parts['fragment'] = $m[30];
-  }
-
-  if (!$decode) {
-    return $parts;
-  }
-  if (!empty($parts['user'])) {
-    $parts['user'] = rawurldecode($parts['user']);
-  }
-  if (!empty($parts['pass'])) {
-    $parts['pass'] = rawurldecode($parts['pass']);
-  }
-  if (!empty($parts['path'])) {
-    $parts['path'] = rawurldecode($parts['path']);
-  }
-  if (isset($h)) {
-    $parts['host'] = rawurldecode($parts['host']);
-  }
-  if (!empty($parts['query'])) {
-    $parts['query'] = rawurldecode($parts['query']);
-  }
-  if (!empty($parts['fragment'])) {
-    $parts['fragment'] = rawurldecode($parts['fragment']);
-  }
-
-  return $parts;
-}
-
-/**
- * This function joins together URL components to form a complete URL.
- *
- * RFC3986 specifies the components of a Uniform Resource Identifier (URI).
- * This function implements the specification's "component recomposition"
- * algorithm for combining URI components into a full URI string.
- *
- * The $parts argument is an associative array containing zero or
- * more of the following:
- *
- *   "scheme"   The scheme, such as "http".
- *   "host"      The host name, IPv4, or IPv6 address.
- *   "port"      The port number.
- *   "user"      The user name.
- *   "pass"      The user password.
- *   "path"      The path, such as a file path for "http".
- *   "query"      The query.
- *   "fragment"   The fragment.
- *
- * The "port", "user", and "pass" values are only used when a "host"
- * is present.
- *
- * The optional $encode argument indicates if appropriate URL components
- * should be percent-encoded as they are assembled into the URL.  Encoding
- * is only applied to the "user", "pass", "host" (if a host name, not an
- * IP address), "path", "query", and "fragment" components.  The "scheme"
- * and "port" are never encoded.  When a "scheme" and "host" are both
- * present, the "path" is presumed to be hierarchical and encoding
- * processes each segment of the hierarchy separately (i.e., the slashes
- * are left alone).
- *
- * The assembled URL string is returned.
- *
- * Parameters:
- *    parts      an associative array of strings containing the
- *          individual parts of a URL.
- *
- *    encode      an optional boolean flag selecting whether
- *          to do percent encoding or not.  Default = true.
- *
- * Return values:
- *    Returns the assembled URL string.  The string is an absolute
- *    URL if a scheme is supplied, and a relative URL if not.  An
- *    empty string is returned if the $parts array does not contain
- *    any of the needed values.
- */
-function join_url($parts, $encode = FALSE) {
-  if ($encode) {
-    if (isset($parts['user'])) {
-      $parts['user'] = rawurlencode($parts['user']);
-    }
-    if (isset($parts['pass'])) {
-      $parts['pass'] = rawurlencode($parts['pass']);
-    }
-    if (isset($parts['host']) &&
-      !preg_match('!^(\[[\da-f.:]+\]])|([\da-f.:]+)$!ui', $parts['host'])
-    ) {
-      $parts['host'] = rawurlencode($parts['host']);
-    }
-    if (!empty($parts['path'])) {
-      $parts['path'] = preg_replace(
-        '!%2F!ui',
-        '/',
-        rawurlencode($parts['path'])
-      );
-    }
-    if (isset($parts['query'])) {
-      $parts['query'] = rawurlencode($parts['query']);
-    }
-    if (isset($parts['fragment'])) {
-      $parts['fragment'] = rawurlencode($parts['fragment']);
-    }
-  }
-
-  $url = '';
-  if (!empty($parts['scheme'])) {
-    $url .= $parts['scheme'] . ':';
-  }
-  if (isset($parts['host'])) {
-    $url .= '//';
-    if (isset($parts['user'])) {
-      $url .= $parts['user'];
-      if (isset($parts['pass'])) {
-        $url .= ':' . $parts['pass'];
-      }
-      $url .= '@';
-    }
-    if (preg_match('!^[\da-f]*:[\da-f.:]+$!ui', $parts['host'])) {
-      $url .= '[' . $parts['host'] . ']';
-    } // IPv6
-    else {
-      $url .= $parts['host'];
-    } // IPv4 or name
-    if (isset($parts['port'])) {
-      $url .= ':' . $parts['port'];
-    }
-    if (!empty($parts['path']) && $parts['path'][0] != '/') {
-      $url .= '/';
-    }
-  }
-  if (!empty($parts['path'])) {
-    $url .= $parts['path'];
-  }
-  if (isset($parts['query'])) {
-    $url .= '?' . $parts['query'];
-  }
-  if (isset($parts['fragment'])) {
-    $url .= '#' . $parts['fragment'];
-  }
-
-  return $url;
-}
-
-/**
- * This function encodes URL to form a URL which is properly
- * percent encoded to replace disallowed characters.
- *
- * RFC3986 specifies the allowed characters in the URL as well as
- * reserved characters in the URL. This function replaces all the
- * disallowed characters in the URL with their repective percent
- * encodings. Already encoded characters are not encoded again,
- * such as '%20' is not encoded to '%2520'.
- *
- * Parameters:
- *    url      the url to encode.
- *
- * Return values:
- *    Returns the encoded URL string.
- */
-function encode_url($url) {
-  $reserved = array(
-    ":" => '!%3A!ui',
-    "/" => '!%2F!ui',
-    "?" => '!%3F!ui',
-    "#" => '!%23!ui',
-    "[" => '!%5B!ui',
-    "]" => '!%5D!ui',
-    "@" => '!%40!ui',
-    "!" => '!%21!ui',
-    "$" => '!%24!ui',
-    "&" => '!%26!ui',
-    "'" => '!%27!ui',
-    "(" => '!%28!ui',
-    ")" => '!%29!ui',
-    "*" => '!%2A!ui',
-    "+" => '!%2B!ui',
-    "," => '!%2C!ui',
-    ";" => '!%3B!ui',
-    "=" => '!%3D!ui',
-    "%" => '!%25!ui',
-  );
-
-  $url = rawurlencode($url);
-  $url = preg_replace(array_values($reserved), array_keys($reserved), $url);
-
-  return $url;
-}
\ No newline at end of file
diff --git a/src/Context/ContextUploader.php b/src/Context/ContextUploader.php
index 4420ffa..fca5d49 100644
--- a/src/Context/ContextUploader.php
+++ b/src/Context/ContextUploader.php
@@ -182,75 +182,94 @@ class ContextUploader {
 
     try {
       $api = $this->getApi($proj_settings, 'context');
-      $all_missing_resources = $api->getAllMissingResources();
+      $time_out = PHP_SAPI == 'cli' ? 300 : 30;
+      $start_time = time();
 
-      // Method getAllMissingResources can return not all missing resources
-      // in case it took to much time. Log this information.
-      if (!$all_missing_resources['all']) {
-        $this->logger->warning('Not all missing context resources are received. Context might look incomplete.');
-      }
+      do {
+        $delta = time() - $start_time;
 
-      // Walk through missing resources and try to upload them.
-      foreach ($all_missing_resources['items'] as $item) {
-        // If current resource isn't in the cache and it's accessible then
-        // it means we can try to upload it.
-        if (!in_array($item['resourceId'], $cached_data) && $this->assetInliner->remote_file_exists($item['url'], $proj_settings)) {
-          $smartling_context_resource_file = $smartling_context_resources_directory . '/' . $item['resourceId'];
-          $smartling_context_resource_file_content = $this->assetInliner->getUrlContents($item['url'],
-            0,
-            'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.215 Safari/534.10',
-            $proj_settings
-          );
-
-          // Ensure that resources directory is accessible, resource
-          // downloaded properly and only then upload it. ContextAPI will not
-          // be able to fopen() resource which is behind basic auth. So
-          // download it first (with a help of curl), save it to smartling's
-          // directory and then upload.
-          if ($file = file_save_data($smartling_context_resource_file_content, $smartling_context_resource_file, FILE_EXISTS_REPLACE)) {
-            $stream_wrapper_manager = \Drupal::service('stream_wrapper_manager')->getViaUri($file->getFileUri());
-            $params = new UploadResourceParameters();
-            $params->setFile($stream_wrapper_manager->realpath());
-            $is_resource_uploaded = $api->uploadResource($item['resourceId'], $params);
-
-            // Resource isn't uploaded for some reason. Log this info and set
-            // resource id into the cache. We will not try to upload this
-            // resource for the next hour.
-            if (!$is_resource_uploaded) {
-              $update_cache = TRUE;
-              $cached_data[] = $item['resourceId'];
+        if ($delta > $time_out) {
+          throw new SmartlingApiException(vsprintf('Not all context resources are uploaded after %s seconds.', [$delta]));
+        }
+
+        $all_missing_resources = $api->getAllMissingResources();
+
+        // Method getAllMissingResources can return not all missing resources
+        // in case it took to much time. Log this information.
+        if (!$all_missing_resources['all']) {
+          $this->logger->warning('Not all missing context resources are received. Context might look incomplete.');
+        }
+
+        $fresh_resources = [];
+
+        foreach ($all_missing_resources['items'] as $item) {
+          if (!in_array($item['resourceId'], $cached_data)) {
+            $fresh_resources[] = $item;
+          }
+        }
 
-              $this->logger->warning("Can't upload context resource file with id = @id and url = @url. Context might look incomplete.", [
-                '@id' => $item['resourceId'],
-                '@url' => $item['url'],
+        // Walk through missing resources and try to upload them.
+        foreach ($fresh_resources as $item) {
+          // If current resource isn't in the cache and it's accessible then
+          // it means we can try to upload it.
+          if (!in_array($item['resourceId'], $cached_data) && $this->assetInliner->remote_file_exists($item['url'], $proj_settings)) {
+            $smartling_context_resource_file = $smartling_context_resources_directory . '/' . $item['resourceId'];
+            $smartling_context_resource_file_content = $this->assetInliner->getUrlContents($item['url'],
+              0,
+              'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.215 Safari/534.10',
+              $proj_settings
+            );
+
+            // Ensure that resources directory is accessible, resource
+            // downloaded properly and only then upload it. ContextAPI will not
+            // be able to fopen() resource which is behind basic auth. So
+            // download it first (with a help of curl), save it to smartling's
+            // directory and then upload.
+            if ($file = file_save_data($smartling_context_resource_file_content, $smartling_context_resource_file, FILE_EXISTS_REPLACE)) {
+              $stream_wrapper_manager = \Drupal::service('stream_wrapper_manager')->getViaUri($file->getFileUri());
+              $params = new UploadResourceParameters();
+              $params->setFile($stream_wrapper_manager->realpath());
+              $is_resource_uploaded = $api->uploadResource($item['resourceId'], $params);
+
+              // Resource isn't uploaded for some reason. Log this info and set
+              // resource id into the cache. We will not try to upload this
+              // resource for the next hour.
+              if (!$is_resource_uploaded) {
+                $update_cache = TRUE;
+                $cached_data[] = $item['resourceId'];
+
+                $this->logger->warning("Can't upload context resource file with id = @id and url = @url. Context might look incomplete.", [
+                  '@id' => $item['resourceId'],
+                  '@url' => $item['url'],
+                ]);
+              }
+            }
+            // We can't save context resource file. Log this info.
+            else {
+              $this->logger->error("Can't save context resource file: @path", [
+                '@path' => $smartling_context_resource_file,
               ]);
             }
           }
-          // We can't save context resource file. Log this info.
           else {
-            $this->logger->error("Can't save context resource file: @path", [
-              '@path' => $smartling_context_resource_file,
-            ]);
-          }
-        }
-        else {
-          // Current resource isn't accessible (or already in the cache).
-          // If first case then add inaccessible resource into the cache.
-          if (!in_array($item['resourceId'], $cached_data)) {
-            $update_cache = TRUE;
-            $cached_data[] = $item['resourceId'];
+            // Current resource isn't accessible (or already in the cache).
+            // If first case then add inaccessible resource into the cache.
+            if (!in_array($item['resourceId'], $cached_data)) {
+              $update_cache = TRUE;
+              $cached_data[] = $item['resourceId'];
 
-            $this->logger->warning("File @file can not be downloaded.", [
-              '@file' => $item['url'],
-            ]);
+              $this->logger->warning("File @file can not be downloaded.", [
+                '@file' => $item['url'],
+              ]);
+            }
           }
         }
-      }
 
-      // Set failed resources into the cache for the next hour.
-      if ($update_cache) {
-        \Drupal::cache()->set($cache_name, $cached_data, time() + $time_to_live);
-      }
+        // Set failed resources into the cache for the next hour.
+        if ($update_cache) {
+          \Drupal::cache()->set($cache_name, $cached_data, time() + $time_to_live);
+        }
+      } while (!empty($fresh_resources));
     }
     catch (Exception $e) {
       watchdog_exception('tmgmt_smartling', $e);
diff --git a/src/Context/HtmlAssetInliner.php b/src/Context/HtmlAssetInliner.php
index 2c049d7..d6907d8 100644
--- a/src/Context/HtmlAssetInliner.php
+++ b/src/Context/HtmlAssetInliner.php
@@ -4,8 +4,6 @@ namespace Drupal\tmgmt_smartling\Context;
 
 //set_time_limit(300);
 
-//require_once 'includes/url_to_absolute.inc'; # or implement your own function to convert relative URLs to absolute
-
 use Drupal;
 
 class HtmlAssetInliner {
@@ -94,20 +92,6 @@ class HtmlAssetInliner {
       $debug
     );
 
-    $this->embedLocalCss();
-    $this->embedLocalJs();
-    $this->embedContentImages();
-
-
-    # remove useless stuff such as <link>, <meta> and <script> tags
-    //$this->removeUseless($keepjs);
-
-    # convert <img> tags to data URIs
-    //$this->convertImageToDataUri();
-
-    # convert all relative links for <a> tags to absolute
-    //$this->toAbsoluteURLs();
-
     if (strlen($this->html) <= 300) {
       if ($debug) {
         Drupal::logger('tmgmt_smartling_context_debug')->info('Response is too small.');
@@ -120,50 +104,6 @@ class HtmlAssetInliner {
   }
 
   /**
-   * Converts images to data URIs
-   */
-  private function convertImageToDataUri() {
-    $tags = $this->getTags('//img');
-    $tagsLength = $tags->length;
-
-    # loop over all <img> tags and convert them to data uri
-    for ($i = 0; $i < $tagsLength; $i++) {
-      $tag = $tags->item($i);
-      $src = $this->getFullUrl($tag->getAttribute('src'));
-
-      if ($this->remote_file_exists($src)) {
-        $dataUri = $this->imageToDataUri($src);
-        $tag->setAttribute('src', $dataUri);
-      }
-    }
-
-    # now save html with converted images
-    $this->html = $this->dom->saveHTML();
-  }
-
-  /**
-   * Returns tags list for specified selector
-   *
-   * @param $selector - xpath selector expression
-   *
-   * @return DOMNodeList
-   */
-  private function getTags($selector) {
-    $this->dom->loadHTML($this->html);
-    $xpath = new DOMXpath($this->dom);
-    $tags = $xpath->query($selector);
-
-    # free memory
-    libxml_use_internal_errors(FALSE);
-    libxml_use_internal_errors(TRUE);
-    libxml_clear_errors();
-    unset($xpath);
-    $xpath = NULL;
-
-    return $tags;
-  }
-
-  /**
    * Checks whether or not remote file exists
    *
    * @param $url
@@ -188,94 +128,6 @@ class HtmlAssetInliner {
   }
 
   /**
-   * Converts images from <img> tags to data URIs
-   *
-   * @param $path - image path eg src value
-   *
-   * @return string - generated data uri
-   */
-  private function imageToDataUri($path) {
-    $fileType = trim(strtolower(pathinfo($path, PATHINFO_EXTENSION)));
-    $mimType = $fileType;
-
-    # since jpg/jpeg images have image/jpeg mime-type
-    if (!$fileType || $fileType === 'jpg') {
-      $mimType = 'jpeg';
-    }
-    else {
-      if ($fileType === 'ico') {
-        $mimType = 'x-icon';
-      }
-    }
-
-    # make sure that it is an image and convert to data uri
-    if (preg_match('#^(gif|png|jp[e]?g|bmp)$#i', $fileType) || $this->isImage($path)) {
-      # in case of images from gravatar, etc
-      if ($mimType === 'php' || stripos($mimType, 'php') !== FALSE) {
-        $mimType = 'jpeg';
-      }
-
-      $data = $this->getContents($path);
-      $base64 = 'data:image/' . $mimType . ';base64,' . base64_encode($data);
-
-      return $base64;
-    }
-  }
-
-  /**
-   * Removes <link>, <meta> and <script> tags from generated page
-   */
-  private function removeUseless($keepjs = TRUE) {
-    # fix showing up of garbage characters
-    $this->html = mb_convert_encoding($this->html, 'HTML-ENTITIES', 'UTF-8');
-
-    $tags = $this->getTags('//meta | //link | //script');
-
-    $tagsLength = $tags->length;
-
-    # get all <link>, <meta> and <script> tags and remove them
-    for ($i = 0; $i < $tagsLength; $i++) {
-      $tag = $tags->item($i);
-
-      # delete only external scripts
-      if (strtolower($tag->nodeName) === 'script') {
-        if ($keepjs) {
-          if ($tag->getAttribute('src') !== '') {
-            $tag->parentNode->removeChild($tag);
-          }
-        }
-        else {
-          $tag->parentNode->removeChild($tag);
-        }
-      }
-      elseif (strtolower($tag->nodeName) === 'meta') {
-        # keep the charset meta
-        if (stripos($tag->getAttribute('content'), 'charset') === FALSE) {
-          $tag->parentNode->removeChild($tag);
-        }
-      }
-      else {
-        $tag->parentNode->removeChild($tag);
-      }
-    }
-
-    $this->html = $this->dom->saveHTML();
-  }
-
-  /**
-   * Converts relative <a> tag paths to absolute paths
-   */
-  private function toAbsoluteURLs() {
-    $links = $this->getTags('//a');
-
-    foreach ($links as $link) {
-      $link->setAttribute('href', $this->getFullUrl($link->getAttribute('href')));
-    }
-
-    $this->html = $this->dom->saveHTML();
-  }
-
-  /**
    * Compresses generated page by removing extra whitespace
    */
   private function compress($string) {
@@ -292,24 +144,6 @@ class HtmlAssetInliner {
   }
 
   /**
-   * Gets content for given url
-   *
-   * @param $url
-   *
-   * @return string
-   */
-  private function getContents($url) {
-    $data = @file_get_contents($url);
-
-    if ($data) {
-      return $data;
-    }
-
-    return @file_get_contents(trim($url));
-  }
-
-
-  /**
    * Gets content for given url using curl and optionally using user agent
    *
    * @param $url
@@ -391,163 +225,4 @@ class HtmlAssetInliner {
     }
   }
 
-  /**
-   * Converts relative URLs to absolute URLs
-   *
-   * @param $url
-   *
-   * @return bool|string
-   */
-  private function getFullUrl($url) {
-    if (strpos($url, '//') === FALSE) {
-      return url_to_absolute($this->url, $url);
-    }
-
-    return $url;
-  }
-
-  /**
-   * Checks if provided path is an image
-   *
-   * @param $path
-   *
-   * @return bool
-   */
-  private function isImage($path) {
-    list($width) = @getimagesize($path);
-
-    if (isset($width) && $width) {
-      return TRUE;
-    }
-
-    return FALSE;
-  }
-
-  private function embedLocalCss() {
-
-    //<link rel="stylesheet" href="/sites/default/files/css/css_DImuuvc9S8V88m4n2WP6xWYIYqktcP21urgDq7ksjK8.css?odb4fo" media="all" />
-    //<link rel="stylesheet" href="/sites/default/files/css/css_Va4zLdYXDM0x79wYfYIi_RSorpNS_xtrTcNUqq0psQA.css?odb4fo" media="screen" />
-    $css = [];
-    preg_match_all('/<link rel="stylesheet" href="([^"]+)\?.*" media="([a-zA-Z0-9]*)" \/>/iU', $this->html, $css);
-
-    foreach ($css[1] as $id => $filename) {
-      if (strpos($filename, '?') !== FALSE) {
-        $fil_splt = explode('?', $filename);
-        $filename = reset($fil_splt);
-      }
-
-      $path = DRUPAL_ROOT . $filename;
-      if (!file_exists($path)) {
-        continue;
-      }
-      $file_content = file_get_contents($path);
-
-      $file_content = $this->embedCssImages($file_content, $path);
-
-      $this->html = str_replace($css[0][$id], "<style media='{$css[2][$id]}'>\n $file_content \n</style>", $this->html);
-    }
-
-
-    //@import url("/core/assets/vendor/normalize-css/normalize.css?odb4fo");
-    //@import url("/core/themes/stable/css/toolbar/toolbar.icons.theme.css?odb4fo");
-    $css = [];
-    preg_match_all('/@import url\("([^"]+)"\);/iU', $this->html, $css);
-
-    foreach ($css[1] as $id => $filename) {
-      if (strpos($filename, '?') !== FALSE) {
-        $fil_splt = explode('?', $filename);
-        $filename = reset($fil_splt);
-      }
-
-      $path = DRUPAL_ROOT . $filename;
-      if (!file_exists($path)) {
-        continue;
-      }
-      $file_content = file_get_contents($path);
-
-      $file_content = $this->embedCssImages($file_content, $path);
-
-      $this->html = str_replace($css[0][$id], "\n\n $file_content \n\n", $this->html);
-    }
-  }
-
-  private function embedCssImages($css_content, $path) {
-    $matches = array();
-    preg_match_all('/url\(([\d\D^)]+)\)/iU', $css_content, $matches);
-
-    foreach ($matches[1] as $k => $img_url) {
-      $img_url = trim($img_url, '\'"');
-      # make sure that it is an image and convert to data uri
-      $fileType = trim(strtolower(pathinfo($img_url, PATHINFO_EXTENSION)));
-      if (!preg_match('#^(gif|png|jp[e]?g|bmp|svg)$#i', $fileType)) {
-        continue;
-      }
-
-      $src = ($img_url[0] === '/') ? DRUPAL_ROOT . $img_url : pathinfo($path, PATHINFO_DIRNAME) . '/' . $img_url;
-
-      if (!file_exists($src) || !($dataUri = file_get_contents($src))) {
-        continue;
-      }
-
-      $mimType = ($fileType === 'svg') ? 'svg+xml' : 'png';
-      $dataUri = 'url("data:image/' . $mimType . ';base64,' . base64_encode($dataUri) . '")';
-      $css_content = str_replace($matches[0][$k], $dataUri, $css_content);
-    }
-    return $css_content;
-  }
-
-  private function embedLocalJs() {
-
-    //<script src="/sites/default/files/js/js_BKcMdIbOMdbTdLn9dkUq3KCJfIKKo2SvKoQ1AnB8D-g.js"></script>
-    //<script src="/core/assets/vendor/modernizr/modernizr.min.js?v=3.3.1"></script>
-    $js = [];
-    preg_match_all('/<script src="([^"]+)"><\/script>/iU', $this->html, $js);
-
-    foreach ($js[1] as $id => $filename) {
-      if (strpos($filename, '?') !== FALSE) {
-        $fil_splt = explode('?', $filename);
-        $filename = reset($fil_splt);
-      }
-
-      $path = DRUPAL_ROOT . $filename;
-      if (!file_exists($path)) {
-        continue;
-      }
-      $file_content = file_get_contents($path);
-
-      $this->html = str_replace($js[0][$id], "<script>\n $file_content \n</script>", $this->html);
-    }
-  }
-
-  private function embedContentImages() {
-    $matches = array();
-    preg_match_all('/<img.*src="([^"]+)".*>/iU', $this->html, $matches);
-
-    foreach ($matches[1] as $k => $img_url) {
-      $img_url = trim($img_url, '\'"');
-      $img_url = str_replace($this->getBaseUrl(), '', $img_url);
-
-      # make sure that it is an image and convert to data uri
-      $fileType = trim(strtolower(pathinfo($img_url, PATHINFO_EXTENSION)));
-      if (!preg_match('#^(gif|png|jp[e]?g|bmp|svg)$#i', $fileType)) {
-        continue;
-      }
-
-      $src = DRUPAL_ROOT . $img_url;
-
-      if (!file_exists($src) || !($dataUri = file_get_contents($src))) {
-        continue;
-      }
-
-      $mimType = ($fileType === 'svg') ? 'svg+xml' : 'png';
-      $dataUri = '<img src="data:image/' . $mimType . ';base64,' . base64_encode($dataUri) . '" />';
-      $this->html = str_replace($matches[0][$k], $dataUri, $this->html);
-    }
-    //return $css_content;
-  }
-
-  private function getBaseUrl() {
-    global $base_url;
-    return $base_url;
-  }
-}
\ No newline at end of file
+}
diff --git a/src/SmartlingTranslatorUi.php b/src/SmartlingTranslatorUi.php
index 22c983f..93170ec 100755
--- a/src/SmartlingTranslatorUi.php
+++ b/src/SmartlingTranslatorUi.php
@@ -13,6 +13,7 @@ use Drupal\tmgmt\Entity\Job;
 use Drupal\tmgmt\JobInterface;
 use Drupal\tmgmt\TranslatorPluginUiBase;
 use Drupal\Core\Form\FormStateInterface;
+use Exception;
 
 /**
  * Smartling translator UI.
@@ -312,7 +313,13 @@ class SmartlingTranslatorUi extends TranslatorPluginUiBase {
 
             $translator_settings = $form_state->getValue('settings');
             \Drupal::getContainer()->get('user.shared_tempstore')->get(self::TEMP_STORAGE_NAME)->set(self::USER_NAME_BEFORE_SWITCHING, \Drupal::currentUser()->getAccountName());
-            \Drupal::getContainer()->get('tmgmt_smartling.utils.context.user_auth')->switchUser($translator_settings['contextUsername'], $translator_settings['context_silent_user_switching']);
+
+            try {
+              \Drupal::getContainer()->get('tmgmt_smartling.utils.context.user_auth')->switchUser($translator_settings['contextUsername'], $translator_settings['context_silent_user_switching']);
+            }
+            catch (Exception $e) {
+              watchdog_exception('tmgmt_smartling', $e);
+            }
           }
 
           foreach (range(1, $queue->numberOfItems()) as $index) {
@@ -376,7 +383,7 @@ class SmartlingTranslatorUi extends TranslatorPluginUiBase {
         // Skip to the next queue.
         $context['interrupted'] = TRUE;
       }
-      catch (\Exception $e) {
+      catch (Exception $e) {
         // In case of any other kind of exception, log it and leave the item
         // in the queue to be processed again later.
         watchdog_exception('cron', $e);
@@ -461,7 +468,7 @@ class SmartlingTranslatorUi extends TranslatorPluginUiBase {
 
       $output = $this->checkoutInfoWrapper($job, $output);
     }
-    catch (\Exception $e) {
+    catch (Exception $e) {
 
     }
 
