diff --git a/menu_trail_by_path.install b/menu_trail_by_path.install
new file mode 100644
index 0000000..e844776
--- /dev/null
+++ b/menu_trail_by_path.install
@@ -0,0 +1,13 @@
+<?php
+
+/**
+ * @file
+ * Install and update hooks for menu trail by path.
+ */
+
+/**
+ * Ensure that container is rebuilt.
+ */
+function menu_trail_by_path_update_20000() {
+  // Existence of an update function is enough to force a rebuild.
+}
diff --git a/menu_trail_by_path.services.yml b/menu_trail_by_path.services.yml
deleted file mode 100644
index 25c21e5..0000000
--- a/menu_trail_by_path.services.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-services:
-  menu_trail_by_path.menu_tree_storage:
-    class: Drupal\menu_trail_by_path\Menu\MenuTreeStorage
-    arguments: ['@database', '@cache.menu', '@cache_tags.invalidator', 'menu_tree']
-    public: false  # Private to plugin.manager.menu.link and menu.link_tree
-    tags:
-      - { name: backend_overridable }
-  menu_trail_by_path.path_helper:
-    class: Drupal\menu_trail_by_path\Path\CurrentPathHelper
-    arguments: ['@current_route_match', '@router.request_context', '@config.factory']
-  menu_trail_by_path.menu_helper:
-    class: Drupal\menu_trail_by_path\Menu\MenuTreeStorageMenuHelper
-    arguments: ['@plugin.manager.menu.link', '@menu_trail_by_path.menu_tree_storage']
diff --git a/src/Menu/MenuHelperInterface.php b/src/Menu/MenuHelperInterface.php
deleted file mode 100644
index 997f4b9..0000000
--- a/src/Menu/MenuHelperInterface.php
+++ /dev/null
@@ -1,11 +0,0 @@
-<?php
-
-namespace Drupal\menu_trail_by_path\Menu;
-
-interface MenuHelperInterface {
-  /**
-   * @param $menu_name
-   * @return \Drupal\Core\Menu\MenuLinkInterface[]
-   */
-  public function getMenuLinks($menu_name);
-}
diff --git a/src/Menu/MenuTreeStorage.php b/src/Menu/MenuTreeStorage.php
deleted file mode 100644
index 4540b59..0000000
--- a/src/Menu/MenuTreeStorage.php
+++ /dev/null
@@ -1,34 +0,0 @@
-<?php
-
-namespace Drupal\menu_trail_by_path\Menu;
-
-use Drupal\Core\Menu\MenuTreeStorage AS CoreMenuTreeStorage;
-use Drupal\Core\Menu\MenuTreeStorageInterface;
-
-class MenuTreeStorage extends CoreMenuTreeStorage implements MenuTreeStorageInterface {
-  /**
-   * Same as parent, but with ordering
-   *
-   * {@inheritdoc}
-   */
-  public function loadByProperties(array $properties) {
-    $query = $this->connection->select($this->table, $this->options);
-    $query->fields($this->table, $this->definitionFields());
-    foreach ($properties as $name => $value) {
-      if (!in_array($name, $this->definitionFields(), TRUE)) {
-        $fields = implode(', ', $this->definitionFields());
-        throw new \InvalidArgumentException("An invalid property name, $name was specified. Allowed property names are: $fields.");
-      }
-      $query->condition($name, $value);
-    }
-    // Make the ordering deterministic.
-    $query->orderBy('depth');
-    $query->orderBy('weight');
-    $query->orderBy('id');
-    $loaded = $this->safeExecuteSelect($query)->fetchAllAssoc('id', \PDO::FETCH_ASSOC);
-    foreach ($loaded as $id => $link) {
-      $loaded[$id] = $this->prepareLink($link);
-    }
-    return $loaded;
-  }
-}
diff --git a/src/Menu/MenuTreeStorageMenuHelper.php b/src/Menu/MenuTreeStorageMenuHelper.php
deleted file mode 100644
index 03f3d66..0000000
--- a/src/Menu/MenuTreeStorageMenuHelper.php
+++ /dev/null
@@ -1,41 +0,0 @@
-<?php
-
-namespace Drupal\menu_trail_by_path\Menu;
-
-use Drupal\Core\Menu\MenuLinkManagerInterface;
-use Drupal\Core\Menu\MenuTreeStorageInterface;
-
-class MenuTreeStorageMenuHelper implements MenuHelperInterface {
-  /**
-   * @var MenuLinkManagerInterface
-   */
-  protected $menuLinkManager;
-
-  /**
-   * @var MenuTreeStorageInterface
-   */
-  protected $menuTreeStorage;
-
-  /**
-   * MenuTreeStorageMenuHelper constructor.
-   * @param \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager
-   * @param \Drupal\Core\Menu\MenuTreeStorageInterface $menu_tree_storage
-   */
-  public function __construct(MenuLinkManagerInterface $menu_link_manager, MenuTreeStorageInterface $menu_tree_storage) {
-    $this->menuLinkManager = $menu_link_manager;
-    $this->menuTreeStorage = $menu_tree_storage;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getMenuLinks($menu_name) {
-    // nice to have: implement filtering like public/core/lib/Drupal/Core/Menu/MenuLinkTree.php:153
-    $menu_links    = [];
-    $menu_plugins = $this->menuTreeStorage->loadByProperties(['menu_name' => $menu_name]);
-    foreach ($menu_plugins as $plugin_id => $definition) {
-      $menu_links[$plugin_id] = $this->menuLinkManager->createInstance($plugin_id);
-    }
-    return $menu_links;
-  }
-}
diff --git a/src/MenuTrailByPathActiveTrail.php b/src/MenuTrailByPathActiveTrail.php
index dab24a8..3c727c7 100644
--- a/src/MenuTrailByPathActiveTrail.php
+++ b/src/MenuTrailByPathActiveTrail.php
@@ -2,14 +2,16 @@
 
 namespace Drupal\menu_trail_by_path;
 
+use Drupal\Component\Utility\UrlHelper;
 use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Menu\MenuActiveTrail;
 use Drupal\Core\Menu\MenuLinkManagerInterface;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Lock\LockBackendInterface;
-use Drupal\menu_trail_by_path\Menu\MenuHelperInterface;
+use Drupal\Core\Url;
 use Drupal\menu_trail_by_path\Path\PathHelperInterface;
+use Drupal\Core\Path\PathValidatorInterface;
 use Drupal\Core\Routing\RequestContext;
 use Drupal\Core\Language\LanguageManagerInterface;
 use Drupal\system\Entity\Menu;
@@ -35,14 +37,9 @@ class MenuTrailByPathActiveTrail extends MenuActiveTrail {
   const MENU_TRAIL_CORE = 'core';
 
   /**
-   * @var \Drupal\menu_trail_by_path\Path\PathHelperInterface
+   * @var \Drupal\Core\Path\PathValidatorInterface
    */
-  protected $pathHelper;
-
-  /**
-   * @var \Drupal\menu_trail_by_path\Menu\MenuHelperInterface
-   */
-  protected $menuHelper;
+   protected $pathValidator;
 
   /**
    * @var \Drupal\Core\Routing\RequestContext
@@ -63,20 +60,19 @@ class MenuTrailByPathActiveTrail extends MenuActiveTrail {
 
   /**
    * MenuTrailByPathActiveTrail constructor.
+   *
    * @param \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager
    * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
    * @param \Drupal\Core\Cache\CacheBackendInterface $cache
    * @param \Drupal\Core\Lock\LockBackendInterface $lock
-   * @param \Drupal\menu_trail_by_path\Path\PathHelperInterface $path_helper
-   * @param \Drupal\menu_trail_by_path\Menu\MenuHelperInterface $menu_helper
+   * @param \Drupal\Core\Path\PathValidatorInterface $path_validator
    * @param \Drupal\Core\Routing\RequestContext $context
    * @param \Drupal\Core\Language\LanguageManagerInterface $languageManager
    * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
    */
-  public function __construct(MenuLinkManagerInterface $menu_link_manager, RouteMatchInterface $route_match, CacheBackendInterface $cache, LockBackendInterface $lock, PathHelperInterface $path_helper, MenuHelperInterface $menu_helper, RequestContext $context, LanguageManagerInterface $languageManager, ConfigFactoryInterface $config_factory) {
+  public function __construct(MenuLinkManagerInterface $menu_link_manager, RouteMatchInterface $route_match, CacheBackendInterface $cache, LockBackendInterface $lock, PathValidatorInterface $path_validator, RequestContext $context, LanguageManagerInterface $languageManager, ConfigFactoryInterface $config_factory) {
     parent::__construct($menu_link_manager, $route_match, $cache, $lock);
-    $this->pathHelper      = $path_helper;
-    $this->menuHelper      = $menu_helper;
+    $this->pathValidator   = $path_validator;
     $this->context         = $context;
     $this->languageManager = $languageManager;
     $this->config = $config_factory->get('menu_trail_by_path.settings');
@@ -101,7 +97,7 @@ class MenuTrailByPathActiveTrail extends MenuActiveTrail {
   protected function doGetActiveTrailIds($menu_name) {
     // Parent ids; used both as key and value to ensure uniqueness.
     // We always want all the top-level links with parent == ''.
-    $active_trail = array('' => '');
+    $active_trail = ['' => ''];
 
     $entity = Menu::load($menu_name);
     if (!$entity) {
@@ -138,19 +134,99 @@ class MenuTrailByPathActiveTrail extends MenuActiveTrail {
    *   The menu link for the given menu, or NULL if there is no matching menu link.
    */
   public function getActiveTrailLink($menu_name) {
-    $menu_links = $this->menuHelper->getMenuLinks($menu_name);
-    $trail_urls = $this->pathHelper->getUrls();
+    $trail_urls = $this->getTrailUrls();
 
     foreach (array_reverse($trail_urls) as $trail_url) {
-      foreach (array_reverse($menu_links) as $menu_link) {
-        /* @var $menu_link \Drupal\Core\Menu\MenuLinkInterface */
-        /* @var $trail_url \Drupal\Core\Url */
-        if ($menu_link->getUrlObject()->toString() == $trail_url->toString()) {
-          return $menu_link;
-        }
+      $links = $this->menuLinkManager->loadLinksByRoute($trail_url->getRouteName(), $trail_url->getRouteParameters(), $menu_name);
+      if ($links) {
+        // Menu link manager sorts ascending by depth, weight, id. Get the
+        // last one which should be the deepest menu item.
+        return end($links);
       }
     }
 
     return NULL;
   }
+
+  /**
+   * Returns a list of URL objects that represent the current path elements.
+   *
+   * @return \Drupal\Core\Url[]
+   *   List of routed URL objects for each path element.
+   */
+  protected function getTrailUrls() {
+    $trail_urls = $this->getCurrentPathUrls();
+    if ($current_request_url = $this->getCurrentRequestUrl()) {
+      $trail_urls[] = $current_request_url;
+    }
+
+    return $trail_urls;
+  }
+
+  /**
+   * Returns the current request Url.
+   *
+   * NOTE: There is a difference between $this->routeMatch->getRouteName and $this->context->getPathInfo()
+   * for now it seems more logical to prefer the latter, because that's the "real" url that visitors enter in their browser..
+   *
+   * @return \Drupal\Core\Url|null
+   */
+  protected function getCurrentRequestUrl() {
+    // Special case on frontpage, allow to explicitly match on <front> menu
+    // links.
+    if ($this->context->getPathInfo() === '/') {
+      return Url::fromRoute('<front>');
+    }
+
+    $current_pathinfo_url = $this->pathValidator->getUrlIfValidWithoutAccessCheck($this->context->getPathInfo());
+    if ($current_pathinfo_url && $current_pathinfo_url->isRouted()) {
+      return $current_pathinfo_url;
+    }
+    elseif ($route_name = $this->routeMatch->getRouteName()) {
+      if (!\in_array($route_name, ['system.404', 'system.403'])) {
+        $route_parameters = $this->routeMatch->getRawParameters()->all();
+        return Url::fromRoute($route_name, $route_parameters);
+
+      }
+    }
+
+    return NULL;
+  }
+
+  /**
+   * Returns a list of path elements based on the maximum path parts setting.
+   *
+   * @return string[]
+   *   A list of path elements.
+   */
+  protected function getPathElements() {
+    $path = trim($this->context->getPathInfo(), '/');
+    $path_elements = explode('/', $path);
+
+    // Limit the maximum number of path parts.
+    if (is_array($path_elements) && $max_path_parts = $this->config->get('max_path_parts')) {
+      return array_splice($path_elements, 0, $max_path_parts);
+    }
+
+    return $path_elements;
+  }
+
+  /**
+   * @return \Drupal\Core\Url[]
+   */
+  protected function getCurrentPathUrls() {
+    $urls = [];
+    $path_elements = $this->getPathElements();
+
+    while (count($path_elements) > 1) {
+      array_pop($path_elements);
+      $url = $this->pathValidator->getUrlIfValidWithoutAccessCheck('/' . implode('/', $path_elements));
+      if ($url && $url->isRouted()) {
+        $urls[] = $url;
+      }
+    }
+
+    return array_reverse($urls);
+  }
+
 }
diff --git a/src/MenuTrailByPathServiceProvider.php b/src/MenuTrailByPathServiceProvider.php
index 2054932..f5c189d 100644
--- a/src/MenuTrailByPathServiceProvider.php
+++ b/src/MenuTrailByPathServiceProvider.php
@@ -16,8 +16,7 @@ class MenuTrailByPathServiceProvider extends ServiceProviderBase {
   public function alter(ContainerBuilder $container) {
     $definition = $container->getDefinition('menu.active_trail');
     $definition->setClass('Drupal\menu_trail_by_path\MenuTrailByPathActiveTrail');
-    $definition->addArgument(new Reference('menu_trail_by_path.path_helper'));
-    $definition->addArgument(new Reference('menu_trail_by_path.menu_helper'));
+    $definition->addArgument(new Reference('path.validator'));
     $definition->addArgument(new Reference('router.request_context'));
     $definition->addArgument(new Reference('language_manager'));
     $definition->addArgument(new Reference('config.factory'));
diff --git a/src/Path/CurrentPathHelper.php b/src/Path/CurrentPathHelper.php
deleted file mode 100644
index 5110568..0000000
--- a/src/Path/CurrentPathHelper.php
+++ /dev/null
@@ -1,116 +0,0 @@
-<?php
-
-namespace Drupal\menu_trail_by_path\Path;
-
-use Drupal\Component\Utility\UrlHelper;
-use Drupal\Core\Config\ConfigFactoryInterface;
-use Drupal\Core\Routing\RequestContext;
-use Drupal\Core\Routing\RouteMatchInterface;
-use Drupal\Core\Url;
-
-class CurrentPathHelper implements PathHelperInterface {
-  /**
-   * @var \Drupal\Core\Routing\RouteMatchInterface
-   */
-  protected $routeMatch;
-
-  /**
-   * The configuration object.
-   *
-   * @var \Drupal\Core\Config\ImmutableConfig
-   */
-  protected $config;
-
-  /**
-   * @var \Drupal\Core\Routing\RequestContext
-   */
-  private $context;
-
-  public function __construct(RouteMatchInterface $route_match, RequestContext $context, ConfigFactoryInterface $config_factory) {
-    $this->routeMatch = $route_match;
-    $this->context    = $context;
-    $this->config = $config_factory->get('menu_trail_by_path.settings');
-  }
-
-  /**
-   * @inheritdoc
-   */
-  public function getUrls() {
-    $trail_urls = $this->getCurrentPathUrls();
-    if ($current_request_url = $this->getCurrentRequestUrl()) {
-      $trail_urls[] = $current_request_url;
-    }
-
-    return $trail_urls;
-  }
-
-  /**
-   * Returns the current request Url
-   *
-   * NOTE: There is a difference between $this->routeMatch->getRouteName and $this->context->getPathInfo()
-   * for now it seems more logical to prefer the latter, because that's the "real" url that visitors enter in their browser..
-   *
-   * @return \Drupal\Core\Url|null
-   */
-  protected function getCurrentRequestUrl() {
-    $current_pathinfo_url = $this->createUrlFromRelativeUri($this->context->getPathInfo());
-    if ($current_pathinfo_url->isRouted()) {
-      return $current_pathinfo_url;
-    }
-    elseif ($route_name = $this->routeMatch->getRouteName()) {
-      $route_parameters = $this->routeMatch->getRawParameters()->all();
-      return new Url($route_name, $route_parameters);
-    }
-
-    return NULL;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getPathElements() {
-    $path = trim($this->context->getPathInfo(), '/');
-    $path_elements = explode('/', $path);
-
-    // Limit the maximum number of path parts.
-    if (is_array($path_elements) && $max_path_parts = $this->config->get('max_path_parts')) {
-      return array_splice($path_elements, 0, $max_path_parts);
-    }
-
-    return $path_elements;
-  }
-
-  /**
-   * @return \Drupal\Core\Url[]
-   */
-  protected function getCurrentPathUrls() {
-    $urls = [];
-    $path_elements = $this->getPathElements();
-
-    while (count($path_elements) > 1) {
-      array_pop($path_elements);
-      $url = $this->createUrlFromRelativeUri('/' . implode('/', $path_elements));
-      if ($url->isRouted()) {
-        $urls[] = $url;
-      }
-    }
-
-    return array_reverse($urls);
-  }
-
-  /**
-   * Create a Url Object from a relative uri (e.g. /news/drupal8-release-party)
-   *
-   * @param $relativeUri
-   * @return Url
-   */
-  protected function createUrlFromRelativeUri($relativeUri) {
-    // @see https://www.drupal.org/node/2810961
-    if (UrlHelper::isExternal(substr($relativeUri, 1))) {
-      return Url::fromUri('base:' . $relativeUri);
-    }
-
-    $relativeUri = str_replace('//', '/', $relativeUri);
-    return Url::fromUserInput($relativeUri);
-  }
-}
diff --git a/src/Path/PathHelperInterface.php b/src/Path/PathHelperInterface.php
deleted file mode 100644
index ca84b97..0000000
--- a/src/Path/PathHelperInterface.php
+++ /dev/null
@@ -1,19 +0,0 @@
-<?php
-
-namespace Drupal\menu_trail_by_path\Path;
-
-interface PathHelperInterface {
-  /**
-   * @return \Drupal\Core\Url[]
-   */
-  public function getUrls();
-
-  /**
-   * Returns a list of path elements based on the maximum path parts setting.
-   *
-   * @return string[]
-   *   A list of path elements.
-   */
-  public function getPathElements();
-
-}
diff --git a/tests/src/Functional/MenuTrailByPathActiveTrailHtmlClassTest.php b/tests/src/Functional/MenuTrailByPathActiveTrailHtmlClassTest.php
index c435098..fe05874 100644
--- a/tests/src/Functional/MenuTrailByPathActiveTrailHtmlClassTest.php
+++ b/tests/src/Functional/MenuTrailByPathActiveTrailHtmlClassTest.php
@@ -61,6 +61,14 @@ class MenuTrailByPathActiveTrailHtmlClassTest extends BrowserTestBase {
     // Create content type
     $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page'));
 
+    // Create nodes
+    $home = $this->drupalCreateNode();
+    $this->createPathAlias('/node/' . $home->id(), '/home');
+
+    $this->config('system.site')
+      ->set('page.front', '/node/' . $home->id())
+      ->save();
+
     // Create nodes
     $node1 = $this->drupalCreateNode();
     $this->createPathAlias('/node/' . $node1->id(), '/news');
@@ -133,7 +141,7 @@ class MenuTrailByPathActiveTrailHtmlClassTest extends BrowserTestBase {
     $this->rebuildAll();
 
     $this->drupalGet(clone $this->menuUrls['User password']);
-    $this->assertNoRaw('menu-item--active-trail');
+    $this->assertSession()->responseNotContains('menu-item--active-trail');
 
     // Set a menu specific setting to override the default.
     $menu = Menu::load('main');
@@ -221,7 +229,7 @@ class MenuTrailByPathActiveTrailHtmlClassTest extends BrowserTestBase {
    */
   public function testUrlNewsCategoryaItema() {
     $node3 = $this->drupalCreateNode();
-    \Drupal::service('path.alias_storage')->save('/node/' . $node3->id(), '/news/category-a/item-a');
+    $this->createPathAlias('/node/' . $node3->id(), '/news/category-a/item-a');
 
     $this->drupalGet($node3->toUrl());
     $this->assertMenuActiveTrail(
@@ -238,7 +246,16 @@ class MenuTrailByPathActiveTrailHtmlClassTest extends BrowserTestBase {
     $this->rebuildAll();
 
     $this->drupalGet($node3->toUrl());
-    $this->assertNoRaw('menu-item--active-trail');
+    $this->assertSession()->responseNotContains('menu-item--active-trail');
+  }
+
+  /**
+   * Test url: 404 page.
+   */
+  public function testUrl404() {
+    $this->drupalGet('foo/bar');
+    $this->assertSession()->responseNotContains('is-active');
+    $this->assertSession()->responseNotContains('menu-item--active-trail');
   }
 
   /**
