diff --git a/.gitignore b/.gitignore
index 5706df6d3394b5b901d1cca5105e0c003c8a7bbd..9df732a6c0bbb289ad8b8ccc20728c24c47bbce7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,4 +31,6 @@ import/solrmarc.log*
 themes/boss/
 themes/finc-dbis/
 themes/vufind-results-grouping/
-themes/worldcat/
\ No newline at end of file
+themes/worldcat/
+module/finc/tests/selenium/vendor/
+module/finc/tests/selenium/logs/
\ No newline at end of file
diff --git a/config/vufind/config.ini b/config/vufind/config.ini
index b804c92fb9b49a4703e8b82bc15d5a48d67ff053..05cc919264d4ecb870f49bbe7a509d75e534a411 100644
--- a/config/vufind/config.ini
+++ b/config/vufind/config.ini
@@ -1313,8 +1313,16 @@ url             = https://www.myendnoteweb.com/EndNoteWeb.html
 ;host = your.proxy.server
 ;port = 8000
 
-; Uncomment following line to set proxy type to SOCKS 5
+; Uncomment one of the following lines to set proxy type to SOCKS 5 or SOCKS 5 with
+; name resolution done by proxy. Setting either of these will make VuFind use the
+; curl adapter for HTTP requests.
 ;type = socks5
+;type = socks5_hostname
+; This setting can be used to define a reqular expression pattern for addresses that
+; should be considered local and bypass proxy when making requests. Default is:
+;local_addresses = "@^(localhost|127(\.\d+){3}|\[::1\])@"
+; Following example bypasses also any address starting with '192.168.':
+;local_addresses = "@^(localhost|127(\.\d+){3}|\[::1\]|192\.168\.)@"
 
 ; Default HTTP settings can be loaded here. These values will be passed to
 ; the \Zend\Http\Client's setOptions method.
diff --git a/devops/i18n-merge.sh b/devops/i18n-merge.sh
index 9f9a20e0e0186a9225438133f61a32040f3ada06..41b511fe31d7ac7348d0c0049a14418ebaa06463 100755
--- a/devops/i18n-merge.sh
+++ b/devops/i18n-merge.sh
@@ -130,7 +130,7 @@ do
     #echo "$line"
     # only add to instanceTokensOrder when key entry is NOT already existing -> remove duplicates / ignored by letting latest entry win
     if [[ -n "${instanceTokens["$key"]}" ]]; then
-      echo "* remove duplicate token \"${key}\" with obsolete value ${instanceTokens["$key"]} by $value."
+      echo "* remove duplicate token \"${key% *}\" with obsolete value ${instanceTokens["$key"]} by \"${value#* }.\""
     else
       instanceTokensOrder+=("$key");
     fi
@@ -154,7 +154,7 @@ if [ -f "$PARENT_FILE" ]; then
     # only add to instanceTokensOrder when key entry is NOT already existing -> remove duplicates / ignored by letting latest entry win
     if [[ ${instanceTokens["$key"]} == "$value" ]] ; then
       #instanceTokens["$key"]="$value";
-      echo "* remove duplicate token \"${key}\" and $value with parent file."
+      echo "* remove duplicate token \"${key% *}\" with value \"${value#* }.\" - use parent file."
       instanceTokens["$key"]="X_duplicate_X";
     fi
   fi
@@ -165,7 +165,7 @@ echo "Adding new token translations..."
 for i in "${!newTokensOrder[@]}"
 do
   if [[ -n "${instanceTokens[${newTokensOrder[$i]}]}" ]]; then
-    echo "* replace token \"${newTokensOrder[$i]}\" with old value ${instanceTokens[${newTokensOrder[$i]}]} by new value $value"
+    echo "* set new value for token \"${newTokensOrder[$i]}\" with value ${newTokens[${newTokensOrder[$i]}]}"
   else
     instanceTokensOrder+=("${newTokensOrder[$i]}");
     echo "* add new token \"${newTokensOrder[$i]}\" with value ${newTokens[${newTokensOrder[$i]}]}"
diff --git a/local/config/vufind/config.ini b/local/config/vufind/config.ini
index 94f2c250dbc9f9c716c3315f47da1dbbee3deda2..779730170c56aea51ba963fcbfe91909d7c8dfcd 100644
--- a/local/config/vufind/config.ini
+++ b/local/config/vufind/config.ini
@@ -1327,8 +1327,16 @@ url             = https://www.myendnoteweb.com/EndNoteWeb.html
 ;host = your.proxy.server
 ;port = 8000
 
-; Uncomment following line to set proxy type to SOCKS 5
-;type = socks5
+; Uncomment one of the following lines to set proxy type to SOCKS 5 or SOCKS 5 with
+; name resolution done by proxy. Setting either of these will make VuFind use the
+; curl adapter for HTTP requests.
+; type = socks5
+; type = socks5_hostname
+; This setting can be used to define a reqular expression pattern for addresses that
+; should be considered local and bypass proxy when making requests. Default is:
+; local_addresses = "@^(localhost|127(\.\d+){3}|\[::1\])@"
+; Following example bypasses also any address starting with '192.168.':
+; local_addresses = "@^(localhost|127(\.\d+){3}|\[::1\]|192\.168\.)@"
 
 ; Default HTTP settings can be loaded here. These values will be passed to
 ; the \Zend\Http\Client's setOptions method.
@@ -2019,6 +2027,8 @@ remove[] = "gndmusic"
 ; identifier[function] calls a function if available with the link as parameter.
 ;    The function performed on the url *before* replacing with the replacement. It is 
 ;    intended to perform url-encoding links so they can be used as parameter value.
+; identifier[description] will replace the link description with the given value if
+;    the url was successfully replaced or a method got called upon it.
 ; Examples:
 ; url[pattern] = url.pattern.to.resolve.link
 ; url[method]  = resolveLink
diff --git a/local/languages/de.ini b/local/languages/de.ini
index 7980b367eac6fd631c9e651c394ed37fdf924281..ac985af71fe4010158539137720084038c9c6ec3 100644
--- a/local/languages/de.ini
+++ b/local/languages/de.ini
@@ -2110,4 +2110,8 @@ main_navigation = "Hauptnavigation"
 aria_search_header = "Bedienelemente zur Steuerung der Ansicht"
 
 ; 22240
-No linguistic content = "Nichtsprachlicher Inhalt"
\ No newline at end of file
+No linguistic content = "Nichtsprachlicher Inhalt"
+
+# Collections Search
+Search Collection Items = "Enthaltene Objekte durchsuchen"
+sidebar_expand_collections = "Ergebnisse weiter eingrenzen"
diff --git a/local/languages/en.ini b/local/languages/en.ini
index ee7ffca62fa7102466cbe0188d26d3b006558ec4..92b702f9d18ab5253bc62e25a4fa3dbe59a6fa0c 100644
--- a/local/languages/en.ini
+++ b/local/languages/en.ini
@@ -2195,4 +2195,9 @@ main_navigation = "Hauptnavigation"
 aria_search_header = "List view controls"
 
 ; 22240
-No linguistic content = "No linguistic content"
\ No newline at end of file
+No linguistic content = "No linguistic content"
+
+
+# Collections Search
+Search Collection Items = "Search Collection Items"
+sidebar_expand_collections = "Filter Collection Items"
diff --git a/module/VuFind/src/VuFind/Service/HttpServiceFactory.php b/module/VuFind/src/VuFind/Service/HttpServiceFactory.php
index b4801c73280a44d1b9fce4d17295b959d0839875..c907119c349068c368b631d480335ecaea58c212 100644
--- a/module/VuFind/src/VuFind/Service/HttpServiceFactory.php
+++ b/module/VuFind/src/VuFind/Service/HttpServiceFactory.php
@@ -75,6 +75,8 @@ class HttpServiceFactory implements FactoryInterface
         }
         $defaults = isset($config->Http)
             ? $config->Http->toArray() : [];
-        return new $requestedName($options, $defaults);
+        $config = !empty($config->Proxy->local_addresses)
+            ? ['localAddressesRegEx' => $config->Proxy->local_addresses] : [];
+        return new $requestedName($options, $defaults, $config);
     }
 }
diff --git a/module/finc/src/finc/ILS/Connection.php b/module/finc/src/finc/ILS/Connection.php
index 2fe8401af447bc639eac7cdc7f73c73ae5ddb913..5ea444a81161d36f980ffe445c349f76e318215d 100644
--- a/module/finc/src/finc/ILS/Connection.php
+++ b/module/finc/src/finc/ILS/Connection.php
@@ -115,7 +115,6 @@ class Connection extends \VuFind\ILS\Connection implements TranslatorAwareInterf
         return false;
     }
 
-
     /**
      * Get access to the driver object.
      * Extends parent function with a bypass of failover on InitException
@@ -172,4 +171,42 @@ class Connection extends \VuFind\ILS\Connection implements TranslatorAwareInterf
             throw $e;
         }
     }
+
+    /**
+     * Get Offline Mode
+     *
+     * This is responsible for returning the offline mode
+     *
+     * @param bool $healthCheck Perform a health check in addition to consulting
+     * the ILS status?
+     *
+     * @return string|bool "ils-offline" for systems where the main ILS is offline,
+     * "ils-none" for systems which do not use an ILS, false for online systems.
+     *
+     * @deprecated Backport of VuFind 8.1 (healthCheckId) - remove after upgrade
+     */
+    public function getOfflineMode($healthCheck = false)
+    {
+        // If we have NoILS failover configured, force driver initialization so
+        // we can know we are checking the offline mode against the correct driver.
+        if ($this->hasNoILSFailover()) {
+            $this->getDriver();
+        }
+        $hasOfflineMode = $this->checkCapability('getOfflineMode');
+        // If we need to perform a health check, try to do a random item lookup
+        // before proceeding.
+        if ($healthCheck && $this->config->healthCheckId) {
+            if (empty($this->getStatus($this->config->healthCheckId)) && $hasOfflineMode) {
+                // show different return string to separate between basic availability and PAIA later?
+                return 'ils-offline';
+            }
+        }
+
+        // If we're encountering failures, let's go into ils-offline mode if
+        // the ILS driver does not natively support getOfflineMode().
+        $default = $this->failing ? 'ils-offline' : false;
+
+        // Graceful degradation -- return false if no method supported.
+        return $hasOfflineMode ? $this->getDriver()->getOfflineMode() : $default;
+    }
 }
diff --git a/module/finc/src/finc/ILS/Driver/FincILS.php b/module/finc/src/finc/ILS/Driver/FincILS.php
index 786db5ce3cc10ed1fafd0ece4d0aab260f45b9a1..0843459cfd0bf3daa5c53815ee9623c0ff87e4ba 100644
--- a/module/finc/src/finc/ILS/Driver/FincILS.php
+++ b/module/finc/src/finc/ILS/Driver/FincILS.php
@@ -261,7 +261,7 @@ class FincILS extends PAIA implements LoggerAwareInterface
      * systems which do not use an ILS, false for systems that are fully online. If
      * not implemented, the value defaults to false
      *
-     * @return bool
+     * @return bool|string
      */
     public function getOfflineMode()
     {
@@ -271,7 +271,7 @@ class FincILS extends PAIA implements LoggerAwareInterface
                 return false;
             }
             // test again
-            $this->testILSConnections();
+            $this->_testILSConnections();
             return false;
         } catch (\Exception $e) {
             $this->debug($e->getMessage());
@@ -1504,15 +1504,25 @@ class FincILS extends PAIA implements LoggerAwareInterface
     protected function hasILSData($id)
     {
         foreach ($this->config['General']['queryIls'] as $value) {
-            [$methodName, $methodReturn] = explode(':', $value);
+            list($methodName, $methodReturn) = explode(':', $value);
             // if we have one mismatch we can already stop as this record does
             // not qualify for querying the ILS
             if ($methodReturn === "") {
                 if (null !== $this->getRecord($id)->tryMethod($methodName)) {
                     return false;
                 }
-            } elseif (!in_array($methodReturn, (array)$this->getRecord($id)->tryMethod($methodName))) {
-                return false;
+            } elseif (strpos($methodName, '!') === 0) {
+                // we have a negative filter, meaning, we don't query the ILS
+                // if the return value matches
+                $methodName = substr($methodName, 1);
+                if (in_array($methodReturn, (array) $this->getRecord($id)->tryMethod($methodName))) {
+                    return false;
+                }
+            } else {
+                // this is a positive filter i.e. the return value MUST match
+                if (!in_array($methodReturn, (array) $this->getRecord($id)->tryMethod($methodName))) {
+                    return false;
+                }
             }
         }
         // if we got this far the record qualifies for querying the ILS
@@ -1697,28 +1707,34 @@ class FincILS extends PAIA implements LoggerAwareInterface
     }
 
     /**
-     * Private service test method
+     * Private service test method for basic accessibility of DAIA / PAIA
+     *
+     * @param boolean $testDAIA test DAIA service
+     * @param boolean $testPAIA test PAIA service
      *
      * @return void
      * @throws ILSException
      */
-    private function testILSConnections()
+    private function _testILSConnections($testDAIA = true, $testPAIA = true)
     {
         try {
-            // test DAIA service
-            preg_match(
-                "/^(http[s:\/0-9a-zA-Z\.]*(:[0-9]*)?\/[0-9a-zA-Z\-\/]*)/",
-                $this->baseUrl,
-                $daiaMatches
-            );
-            $this->httpService->get($daiaMatches[1], [], $this->ilsTestTimeout);
-            // test PAIA service
-            preg_match(
-                "/^(http[s:\/0-9a-zA-Z\.]*(:[0-9]*)?\/[0-9a-zA-Z\-\/]*)/",
-                $this->paiaURL,
-                $paiaMatches
-            );
-            $this->httpService->get($paiaMatches[1], [], $this->ilsTestTimeout);
+            if ($testDAIA) {
+                preg_match(
+                    "/^(http[s:\/0-9a-zA-Z\.]*(:[0-9]*)?\/[0-9a-zA-Z\-\/]*)/",
+                    $this->baseUrl,
+                    $daiaMatches
+                );
+                $this->httpService->get($daiaMatches[1], [], $this->ilsTestTimeout);
+            }
+
+            if ($testPAIA) {
+                preg_match(
+                    "/^(http[s:\/0-9a-zA-Z\.]*(:[0-9]*)?\/[0-9a-zA-Z\-\/]*)/",
+                    $this->paiaURL,
+                    $paiaMatches
+                );
+                $this->httpService->get($paiaMatches[1], [], $this->ilsTestTimeout);
+            }
 
             // test succeeded, save state
             $this->isOnline = true;
diff --git a/module/finc/src/finc/ILS/Driver/FincLibero.php b/module/finc/src/finc/ILS/Driver/FincLibero.php
index 1fc98649fc39a63bb9b7dc095e7b76929d06ea35..6a6589dd246c6996ef921264f4050fe1831fa4b1 100644
--- a/module/finc/src/finc/ILS/Driver/FincLibero.php
+++ b/module/finc/src/finc/ILS/Driver/FincLibero.php
@@ -331,16 +331,14 @@ class FincLibero extends FincILS implements TranslatorAwareInterface
 
                 // custom DAIA field
                 $result_item['doc_id'] = $doc_id;
-                if (
-                    $isTitleHold
-                    &&
-                    (
-                        !isset($this->noTitleHoldStatuses)
+                if ($isTitleHold
+                    && ( !isset($this->noTitleHoldStatuses)
                     || empty($this->noTitleHoldStatuses)
-                    || !in_array($item['localIlsStatus'], $this->noTitleHoldStatuses)
-                    )
+                    || !in_array($item['localIlsStatus'], $this->noTitleHoldStatuses))
                 ) {
+                    // this is a titleHold and we show TitleHoldLink
                     $result_item['item_id'] = $titleHoldId;
+                    $result_item['addTitleHoldLink'] = true;
                 } else {
                     $result_item['item_id'] = $item['id'];
                 }
@@ -348,10 +346,6 @@ class FincLibero extends FincILS implements TranslatorAwareInterface
                 // custom DAIA field used in getHoldLink()
                 $result_item['ilslink']
                     = ($item['href'] ?? $doc_href);
-                // show TitleHoldLink except for defined noTitleHoldStatuses
-                if ($isTitleHold && !in_array($item['localIlsStatus'], $this->noTitleHoldStatuses)) {
-                    $result_item['addTitleHoldLink'] = true;
-                }
 
                 // count items
                 $number++;
diff --git a/module/finc/src/finc/View/Helper/Root/Record.php b/module/finc/src/finc/View/Helper/Root/Record.php
index c7117e000c20d159e2d93575dfd7706d58610e12..f6e0ea4d28767304774853e80e54191657f0dbd8 100644
--- a/module/finc/src/finc/View/Helper/Root/Record.php
+++ b/module/finc/src/finc/View/Helper/Root/Record.php
@@ -376,6 +376,15 @@ class Record extends \VuFind\View\Helper\Root\Record
     protected function rewriteLink(&$link)
     {
         $rewrite = $this->config->LinksRewrite->toArray();
+
+        // helper function to replace the link description with a configured value
+        $overwriteDescription = function (&$link, $currentRewrite) {
+            // if another link description is configured use this instead
+            if (isset($currentRewrite['description'])) {
+                $link['desc'] = $currentRewrite['description'];
+            }
+        };
+
         foreach ($rewrite as $r) {
             // is remove pattern than suppress link refs #10834
             if (isset($r['remove'])) {
@@ -411,15 +420,21 @@ class Record extends \VuFind\View\Helper\Root\Record
                         1,
                         $count
                     );
+                    if ($count) {
+                        // overwrite description as we have a successful replace
+                        $overwriteDescription($link, $r);
+                    }
                     // add http if needed
                     // @to-do make it https compatible
                     if (!preg_match('/^(https?:\/\/)/', $link['url'])) {
-                        $link['url'] = 'http://' . $link['url'];
+                        $link['url'] = 'https://' . $link['url'];
                     }
                 }
                 // is method set so call alternatively method proceed link
                 if (isset($r['method']) && method_exists($this, $r['method'])) {
                     $link['url'] = $this->$r['method']($link['url']);
+                    // overwrite description as we called the defined method
+                    $overwriteDescription($link, $r);
                 } // end if isset method
             } // end if isset pattern
         } // end foreach
diff --git a/module/finc/tests/selenium/README.md b/module/finc/tests/selenium/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..6856d7b8b38844410940c919445818be56841362
--- /dev/null
+++ b/module/finc/tests/selenium/README.md
@@ -0,0 +1,29 @@
+Selenium Tests
+======
+
+Introduction
+------------
+UI Tests for finc VuFind.
+TODO: integrate into VuFind docker-compose and composer.json
+
+Requirements
+------------
+* Docker version >= 20
+
+Usage
+------------
+1. running docker:
+   * ```docker-compose -f module/finc/tests/selenium/docker-compose.yaml up --scale firefox=[1|2|3|4|5]```
+   * detailed example: ```docker-compose -f module/finc/tests/selenium/docker-compose.yaml up --scale firefox=3```
+2. running tests:
+   * ```docker exec -it [SELENIUM-PHP-CONTAINERNAME] sh -c "./vendor/bin/steward run [local|alpha|staging] [firefox|chrome] [--group [de_15|adlr|...]] --server-url http://selenium:4444/wd/hub -v"```
+   * detailed example: ```docker exec -it selenium_php_1 sh -c "./vendor/bin/steward run staging firefox --group adlr --server-url http://selenium:4444/wd/hub -v"```
+
+Documentation and Support
+-------------------------
+* php library: https://github.com/lmc-eu/steward
+* docker: https://github.com/SeleniumHQ/docker-selenium
+* examples: https://github.com/lmc-eu/steward-example/tree/main/tests
+* commands: https://github.com/php-webdriver/php-webdriver/wiki/Example-command-reference
+* GUI for selenium grid: http://localhost:4444/ui#
+* Results: file:///[path to vufind directory]/module/finc/tests/selenium/logs/results.xml
diff --git a/module/finc/tests/selenium/composer.json b/module/finc/tests/selenium/composer.json
new file mode 100755
index 0000000000000000000000000000000000000000..76d0b2ab4582c4376d29a3186a1f5d522b6d618d
--- /dev/null
+++ b/module/finc/tests/selenium/composer.json
@@ -0,0 +1,21 @@
+{
+    "name": "selenium-tests",
+    "license": "GPL-2.0",
+    "config": {
+        "platform": {
+            "php": "7.3.0"
+        }
+    },
+    "autoload": {
+        "psr-4": {
+            "Selenium\\": "tests/"
+        }
+    },
+    "require": {
+        "php": ">=7.3.0"
+    },
+    "require-dev": {
+        "lmc/steward": "3.0.0",
+        "phpunit/phpunit": "8.5.15"
+    }
+}
diff --git a/module/finc/tests/selenium/composer.lock b/module/finc/tests/selenium/composer.lock
new file mode 100755
index 0000000000000000000000000000000000000000..00114fd7405e1b403ac0188c90f5f58735724d23
--- /dev/null
+++ b/module/finc/tests/selenium/composer.lock
@@ -0,0 +1,3217 @@
+{
+    "_readme": [
+        "This file locks the dependencies of your project to a known state",
+        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+        "This file is @generated automatically"
+    ],
+    "content-hash": "92b40d0d5b69eef490bb96ef7dea38f8",
+    "packages": [],
+    "packages-dev": [
+        {
+            "name": "beberlei/assert",
+            "version": "v3.3.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/beberlei/assert.git",
+                "reference": "cb70015c04be1baee6f5f5c953703347c0ac1655"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/beberlei/assert/zipball/cb70015c04be1baee6f5f5c953703347c0ac1655",
+                "reference": "cb70015c04be1baee6f5f5c953703347c0ac1655",
+                "shasum": ""
+            },
+            "require": {
+                "ext-ctype": "*",
+                "ext-json": "*",
+                "ext-mbstring": "*",
+                "ext-simplexml": "*",
+                "php": "^7.0 || ^8.0"
+            },
+            "require-dev": {
+                "friendsofphp/php-cs-fixer": "*",
+                "phpstan/phpstan": "*",
+                "phpunit/phpunit": ">=6.0.0",
+                "yoast/phpunit-polyfills": "^0.1.0"
+            },
+            "suggest": {
+                "ext-intl": "Needed to allow Assertion::count(), Assertion::isCountable(), Assertion::minCount(), and Assertion::maxCount() to operate on ResourceBundles"
+            },
+            "type": "library",
+            "autoload": {
+                "files": [
+                    "lib/Assert/functions.php"
+                ],
+                "psr-4": {
+                    "Assert\\": "lib/Assert"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-2-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Benjamin Eberlei",
+                    "email": "kontakt@beberlei.de",
+                    "role": "Lead Developer"
+                },
+                {
+                    "name": "Richard Quadling",
+                    "email": "rquadling@gmail.com",
+                    "role": "Collaborator"
+                }
+            ],
+            "description": "Thin assertion library for input validation in business models.",
+            "keywords": [
+                "assert",
+                "assertion",
+                "validation"
+            ],
+            "time": "2021-12-16T21:41:27+00:00"
+        },
+        {
+            "name": "clue/graph",
+            "version": "v0.9.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/graphp/graph.git",
+                "reference": "d1661c0a0e011a8550fa60ae5354f230d1555909"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/graphp/graph/zipball/d1661c0a0e011a8550fa60ae5354f230d1555909",
+                "reference": "d1661c0a0e011a8550fa60ae5354f230d1555909",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35"
+            },
+            "suggest": {
+                "graphp/algorithms": "Common graph algorithms, such as Dijkstra and Moore-Bellman-Ford (shortest path), minimum spanning tree (MST), Kruskal, Prim and many more..",
+                "graphp/graphviz": "GraphViz graph drawing / DOT output"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Fhaculty\\Graph\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Christian Lück",
+                    "email": "christian@clue.engineering"
+                }
+            ],
+            "description": "GraPHP is the mathematical graph/network library written in PHP.",
+            "homepage": "https://github.com/graphp/graph",
+            "keywords": [
+                "edge",
+                "graph",
+                "mathematical",
+                "network",
+                "vertex"
+            ],
+            "time": "2021-12-30T09:22:01+00:00"
+        },
+        {
+            "name": "doctrine/inflector",
+            "version": "2.0.6",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/doctrine/inflector.git",
+                "reference": "d9d313a36c872fd6ee06d9a6cbcf713eaa40f024"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/doctrine/inflector/zipball/d9d313a36c872fd6ee06d9a6cbcf713eaa40f024",
+                "reference": "d9d313a36c872fd6ee06d9a6cbcf713eaa40f024",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2 || ^8.0"
+            },
+            "require-dev": {
+                "doctrine/coding-standard": "^10",
+                "phpstan/phpstan": "^1.8",
+                "phpstan/phpstan-phpunit": "^1.1",
+                "phpstan/phpstan-strict-rules": "^1.3",
+                "phpunit/phpunit": "^8.5 || ^9.5",
+                "vimeo/psalm": "^4.25"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Doctrine\\Inflector\\": "lib/Doctrine/Inflector"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Guilherme Blanco",
+                    "email": "guilhermeblanco@gmail.com"
+                },
+                {
+                    "name": "Roman Borschel",
+                    "email": "roman@code-factory.org"
+                },
+                {
+                    "name": "Benjamin Eberlei",
+                    "email": "kontakt@beberlei.de"
+                },
+                {
+                    "name": "Jonathan Wage",
+                    "email": "jonwage@gmail.com"
+                },
+                {
+                    "name": "Johannes Schmitt",
+                    "email": "schmittjoh@gmail.com"
+                }
+            ],
+            "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.",
+            "homepage": "https://www.doctrine-project.org/projects/inflector.html",
+            "keywords": [
+                "inflection",
+                "inflector",
+                "lowercase",
+                "manipulation",
+                "php",
+                "plural",
+                "singular",
+                "strings",
+                "uppercase",
+                "words"
+            ],
+            "time": "2022-10-20T09:10:12+00:00"
+        },
+        {
+            "name": "doctrine/instantiator",
+            "version": "1.4.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/doctrine/instantiator.git",
+                "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc",
+                "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.1 || ^8.0"
+            },
+            "require-dev": {
+                "doctrine/coding-standard": "^9",
+                "ext-pdo": "*",
+                "ext-phar": "*",
+                "phpbench/phpbench": "^0.16 || ^1",
+                "phpstan/phpstan": "^1.4",
+                "phpstan/phpstan-phpunit": "^1",
+                "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
+                "vimeo/psalm": "^4.22"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Marco Pivetta",
+                    "email": "ocramius@gmail.com",
+                    "homepage": "https://ocramius.github.io/"
+                }
+            ],
+            "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
+            "homepage": "https://www.doctrine-project.org/projects/instantiator.html",
+            "keywords": [
+                "constructor",
+                "instantiate"
+            ],
+            "time": "2022-03-03T08:28:38+00:00"
+        },
+        {
+            "name": "graphp/algorithms",
+            "version": "v0.8.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/graphp/algorithms.git",
+                "reference": "abebbc44109f65c2962cd66f048ea3b8563e0a4a"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/graphp/algorithms/zipball/abebbc44109f65c2962cd66f048ea3b8563e0a4a",
+                "reference": "abebbc44109f65c2962cd66f048ea3b8563e0a4a",
+                "shasum": ""
+            },
+            "require": {
+                "clue/graph": "~0.9.0|~0.8.0",
+                "php": ">=5.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Graphp\\Algorithms\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Christian Lück",
+                    "email": "christian@clue.engineering"
+                }
+            ],
+            "description": "Common mathematical graph algorithms implemented in PHP",
+            "homepage": "https://github.com/graphp/algorithms",
+            "keywords": [
+                "Graph algorithms",
+                "dijkstra",
+                "kruskal",
+                "minimum spanning tree",
+                "moore-bellman-ford",
+                "prim",
+                "shortest path"
+            ],
+            "time": "2020-02-20T18:01:41+00:00"
+        },
+        {
+            "name": "hanneskod/classtools",
+            "version": "1.2.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/hanneskod/classtools.git",
+                "reference": "d365ddac0e602027c0471ea292f4ba2afcb49394"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/hanneskod/classtools/zipball/d365ddac0e602027c0471ea292f4ba2afcb49394",
+                "reference": "d365ddac0e602027c0471ea292f4ba2afcb49394",
+                "shasum": ""
+            },
+            "require": {
+                "nikic/php-parser": "^4",
+                "php": ">=7.1",
+                "symfony/finder": "^4|^5"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "hanneskod\\classtools\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "WTFPL"
+            ],
+            "authors": [
+                {
+                    "name": "Hannes Forsgård",
+                    "email": "hannes.forsgard@fripost.org"
+                }
+            ],
+            "description": "Find, extract and process classes from file system",
+            "homepage": "https://github.com/hanneskod/classtools",
+            "keywords": [
+                "class finder",
+                "code generator",
+                "metaprogramming",
+                "minimizer"
+            ],
+            "time": "2020-03-05T20:41:28+00:00"
+        },
+        {
+            "name": "lmc/steward",
+            "version": "3.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/lmc-eu/steward.git",
+                "reference": "39c5286e5d7a28d596573982b960604b1d330850"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/lmc-eu/steward/zipball/39c5286e5d7a28d596573982b960604b1d330850",
+                "reference": "39c5286e5d7a28d596573982b960604b1d330850",
+                "shasum": ""
+            },
+            "require": {
+                "beberlei/assert": "^3.0",
+                "clue/graph": "^0.9.2",
+                "doctrine/inflector": "^2.0.3",
+                "ext-curl": "*",
+                "ext-dom": "*",
+                "ext-filter": "*",
+                "ext-json": "*",
+                "ext-libxml": "*",
+                "ext-simplexml": "*",
+                "ext-zip": "*",
+                "graphp/algorithms": "^0.8.2",
+                "hanneskod/classtools": "^1.2",
+                "ondram/ci-detector": "^4.0",
+                "php": "^7.3 || ^8.0",
+                "php-webdriver/webdriver": "^1.10.0",
+                "phpdocumentor/reflection-docblock": "^5.2",
+                "phpunit/phpunit": "^8.5.15",
+                "symfony/console": "^5.2.6",
+                "symfony/event-dispatcher": "^5.2",
+                "symfony/event-dispatcher-contracts": "^2.2",
+                "symfony/filesystem": "^5.2",
+                "symfony/finder": "^5.2",
+                "symfony/options-resolver": "^5.2",
+                "symfony/polyfill-mbstring": "^1.12",
+                "symfony/process": "^5.2",
+                "symfony/stopwatch": "^5.2",
+                "symfony/yaml": "^5.2"
+            },
+            "require-dev": {
+                "ergebnis/composer-normalize": "^2.13",
+                "lmc/coding-standard": "^3.0.0",
+                "php-mock/php-mock-phpunit": "^2.6.0",
+                "php-parallel-lint/php-parallel-lint": "^1.2.0",
+                "phpstan/extension-installer": "^1.1",
+                "phpstan/phpstan": "^0.12.80",
+                "phpstan/phpstan-phpunit": "^0.12.17",
+                "symfony/var-dumper": "^5.2"
+            },
+            "suggest": {
+                "ext-posix": "For colored output",
+                "ext-xdebug": "For remote tests debugging"
+            },
+            "bin": [
+                "bin/steward",
+                "bin/steward.php"
+            ],
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "3.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Lmc\\Steward\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Ondřej Machulda",
+                    "email": "ondrej.machulda@gmail.com"
+                },
+                {
+                    "name": "LMC s.r.o.",
+                    "homepage": "https://github.com/lmc-eu"
+                }
+            ],
+            "description": "Steward - makes Selenium WebDriver + PHPUnit testing easy and robust",
+            "keywords": [
+                "phpunit",
+                "selenium",
+                "testing",
+                "webdriver"
+            ],
+            "time": "2021-12-02T22:53:23+00:00"
+        },
+        {
+            "name": "myclabs/deep-copy",
+            "version": "1.11.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/myclabs/DeepCopy.git",
+                "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614",
+                "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.1 || ^8.0"
+            },
+            "conflict": {
+                "doctrine/collections": "<1.6.8",
+                "doctrine/common": "<2.13.3 || >=3,<3.2.2"
+            },
+            "require-dev": {
+                "doctrine/collections": "^1.6.8",
+                "doctrine/common": "^2.13.3 || ^3.2.2",
+                "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
+            },
+            "type": "library",
+            "autoload": {
+                "files": [
+                    "src/DeepCopy/deep_copy.php"
+                ],
+                "psr-4": {
+                    "DeepCopy\\": "src/DeepCopy/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "Create deep copies (clones) of your objects",
+            "keywords": [
+                "clone",
+                "copy",
+                "duplicate",
+                "object",
+                "object graph"
+            ],
+            "time": "2022-03-03T13:19:32+00:00"
+        },
+        {
+            "name": "nikic/php-parser",
+            "version": "v4.15.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/nikic/PHP-Parser.git",
+                "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc",
+                "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc",
+                "shasum": ""
+            },
+            "require": {
+                "ext-tokenizer": "*",
+                "php": ">=7.0"
+            },
+            "require-dev": {
+                "ircmaxell/php-yacc": "^0.0.7",
+                "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0"
+            },
+            "bin": [
+                "bin/php-parse"
+            ],
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "4.9-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "PhpParser\\": "lib/PhpParser"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Nikita Popov"
+                }
+            ],
+            "description": "A PHP parser written in PHP",
+            "keywords": [
+                "parser",
+                "php"
+            ],
+            "time": "2022-11-12T15:38:23+00:00"
+        },
+        {
+            "name": "ondram/ci-detector",
+            "version": "4.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/OndraM/ci-detector.git",
+                "reference": "8a4b664e916df82ff26a44709942dfd593fa6f30"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/OndraM/ci-detector/zipball/8a4b664e916df82ff26a44709942dfd593fa6f30",
+                "reference": "8a4b664e916df82ff26a44709942dfd593fa6f30",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.1 || ^8.0"
+            },
+            "require-dev": {
+                "ergebnis/composer-normalize": "^2.2",
+                "lmc/coding-standard": "^1.3 || ^2.1",
+                "php-parallel-lint/php-parallel-lint": "^1.2",
+                "phpstan/extension-installer": "^1.0.5",
+                "phpstan/phpstan": "^0.12.58",
+                "phpstan/phpstan-phpunit": "^0.12.16",
+                "phpunit/phpunit": "^7.1 || ^8.0 || ^9.0"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "OndraM\\CiDetector\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Ondřej Machulda",
+                    "email": "ondrej.machulda@gmail.com"
+                }
+            ],
+            "description": "Detect continuous integration environment and provide unified access to properties of current build",
+            "keywords": [
+                "CircleCI",
+                "Codeship",
+                "Wercker",
+                "adapter",
+                "appveyor",
+                "aws",
+                "aws codebuild",
+                "azure",
+                "azure devops",
+                "azure pipelines",
+                "bamboo",
+                "bitbucket",
+                "buddy",
+                "ci-info",
+                "codebuild",
+                "continuous integration",
+                "continuousphp",
+                "devops",
+                "drone",
+                "github",
+                "gitlab",
+                "interface",
+                "jenkins",
+                "pipelines",
+                "sourcehut",
+                "teamcity",
+                "travis"
+            ],
+            "time": "2021-04-14T09:16:52+00:00"
+        },
+        {
+            "name": "phar-io/manifest",
+            "version": "2.0.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phar-io/manifest.git",
+                "reference": "97803eca37d319dfa7826cc2437fc020857acb53"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53",
+                "reference": "97803eca37d319dfa7826cc2437fc020857acb53",
+                "shasum": ""
+            },
+            "require": {
+                "ext-dom": "*",
+                "ext-phar": "*",
+                "ext-xmlwriter": "*",
+                "phar-io/version": "^3.0.1",
+                "php": "^7.2 || ^8.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0.x-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Arne Blankerts",
+                    "email": "arne@blankerts.de",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Sebastian Heuer",
+                    "email": "sebastian@phpeople.de",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "Developer"
+                }
+            ],
+            "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
+            "time": "2021-07-20T11:28:43+00:00"
+        },
+        {
+            "name": "phar-io/version",
+            "version": "3.2.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phar-io/version.git",
+                "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
+                "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2 || ^8.0"
+            },
+            "type": "library",
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Arne Blankerts",
+                    "email": "arne@blankerts.de",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Sebastian Heuer",
+                    "email": "sebastian@phpeople.de",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "Developer"
+                }
+            ],
+            "description": "Library for handling version information and constraints",
+            "time": "2022-02-21T01:04:05+00:00"
+        },
+        {
+            "name": "php-webdriver/webdriver",
+            "version": "1.13.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-webdriver/php-webdriver.git",
+                "reference": "6dfe5f814b796c1b5748850aa19f781b9274c36c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-webdriver/php-webdriver/zipball/6dfe5f814b796c1b5748850aa19f781b9274c36c",
+                "reference": "6dfe5f814b796c1b5748850aa19f781b9274c36c",
+                "shasum": ""
+            },
+            "require": {
+                "ext-curl": "*",
+                "ext-json": "*",
+                "ext-zip": "*",
+                "php": "^5.6 || ~7.0 || ^8.0",
+                "symfony/polyfill-mbstring": "^1.12",
+                "symfony/process": "^2.8 || ^3.1 || ^4.0 || ^5.0 || ^6.0"
+            },
+            "replace": {
+                "facebook/webdriver": "*"
+            },
+            "require-dev": {
+                "ondram/ci-detector": "^2.1 || ^3.5 || ^4.0",
+                "php-coveralls/php-coveralls": "^2.4",
+                "php-mock/php-mock-phpunit": "^1.1 || ^2.0",
+                "php-parallel-lint/php-parallel-lint": "^1.2",
+                "phpunit/phpunit": "^5.7 || ^7 || ^8 || ^9",
+                "squizlabs/php_codesniffer": "^3.5",
+                "symfony/var-dumper": "^3.3 || ^4.0 || ^5.0 || ^6.0"
+            },
+            "suggest": {
+                "ext-SimpleXML": "For Firefox profile creation"
+            },
+            "type": "library",
+            "autoload": {
+                "files": [
+                    "lib/Exception/TimeoutException.php"
+                ],
+                "psr-4": {
+                    "Facebook\\WebDriver\\": "lib/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "A PHP client for Selenium WebDriver. Previously facebook/webdriver.",
+            "homepage": "https://github.com/php-webdriver/php-webdriver",
+            "keywords": [
+                "Chromedriver",
+                "geckodriver",
+                "php",
+                "selenium",
+                "webdriver"
+            ],
+            "time": "2022-10-11T11:49:44+00:00"
+        },
+        {
+            "name": "phpdocumentor/reflection-common",
+            "version": "2.2.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
+                "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b",
+                "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2 || ^8.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-2.x": "2.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "phpDocumentor\\Reflection\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Jaap van Otterdijk",
+                    "email": "opensource@ijaap.nl"
+                }
+            ],
+            "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
+            "homepage": "http://www.phpdoc.org",
+            "keywords": [
+                "FQSEN",
+                "phpDocumentor",
+                "phpdoc",
+                "reflection",
+                "static analysis"
+            ],
+            "time": "2020-06-27T09:03:43+00:00"
+        },
+        {
+            "name": "phpdocumentor/reflection-docblock",
+            "version": "5.3.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
+                "reference": "622548b623e81ca6d78b721c5e029f4ce664f170"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170",
+                "reference": "622548b623e81ca6d78b721c5e029f4ce664f170",
+                "shasum": ""
+            },
+            "require": {
+                "ext-filter": "*",
+                "php": "^7.2 || ^8.0",
+                "phpdocumentor/reflection-common": "^2.2",
+                "phpdocumentor/type-resolver": "^1.3",
+                "webmozart/assert": "^1.9.1"
+            },
+            "require-dev": {
+                "mockery/mockery": "~1.3.2",
+                "psalm/phar": "^4.8"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "5.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "phpDocumentor\\Reflection\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Mike van Riel",
+                    "email": "me@mikevanriel.com"
+                },
+                {
+                    "name": "Jaap van Otterdijk",
+                    "email": "account@ijaap.nl"
+                }
+            ],
+            "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
+            "time": "2021-10-19T17:43:47+00:00"
+        },
+        {
+            "name": "phpdocumentor/type-resolver",
+            "version": "1.6.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpDocumentor/TypeResolver.git",
+                "reference": "77a32518733312af16a44300404e945338981de3"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/77a32518733312af16a44300404e945338981de3",
+                "reference": "77a32518733312af16a44300404e945338981de3",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2 || ^8.0",
+                "phpdocumentor/reflection-common": "^2.0"
+            },
+            "require-dev": {
+                "ext-tokenizer": "*",
+                "psalm/phar": "^4.8"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-1.x": "1.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "phpDocumentor\\Reflection\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Mike van Riel",
+                    "email": "me@mikevanriel.com"
+                }
+            ],
+            "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
+            "time": "2022-03-15T21:29:03+00:00"
+        },
+        {
+            "name": "phpspec/prophecy",
+            "version": "v1.15.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpspec/prophecy.git",
+                "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13",
+                "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13",
+                "shasum": ""
+            },
+            "require": {
+                "doctrine/instantiator": "^1.2",
+                "php": "^7.2 || ~8.0, <8.2",
+                "phpdocumentor/reflection-docblock": "^5.2",
+                "sebastian/comparator": "^3.0 || ^4.0",
+                "sebastian/recursion-context": "^3.0 || ^4.0"
+            },
+            "require-dev": {
+                "phpspec/phpspec": "^6.0 || ^7.0",
+                "phpunit/phpunit": "^8.0 || ^9.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Prophecy\\": "src/Prophecy"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Konstantin Kudryashov",
+                    "email": "ever.zet@gmail.com",
+                    "homepage": "http://everzet.com"
+                },
+                {
+                    "name": "Marcello Duarte",
+                    "email": "marcello.duarte@gmail.com"
+                }
+            ],
+            "description": "Highly opinionated mocking framework for PHP 5.3+",
+            "homepage": "https://github.com/phpspec/prophecy",
+            "keywords": [
+                "Double",
+                "Dummy",
+                "fake",
+                "mock",
+                "spy",
+                "stub"
+            ],
+            "time": "2021-12-08T12:19:24+00:00"
+        },
+        {
+            "name": "phpunit/php-code-coverage",
+            "version": "7.0.15",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
+                "reference": "819f92bba8b001d4363065928088de22f25a3a48"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/819f92bba8b001d4363065928088de22f25a3a48",
+                "reference": "819f92bba8b001d4363065928088de22f25a3a48",
+                "shasum": ""
+            },
+            "require": {
+                "ext-dom": "*",
+                "ext-xmlwriter": "*",
+                "php": ">=7.2",
+                "phpunit/php-file-iterator": "^2.0.2",
+                "phpunit/php-text-template": "^1.2.1",
+                "phpunit/php-token-stream": "^3.1.3 || ^4.0",
+                "sebastian/code-unit-reverse-lookup": "^1.0.1",
+                "sebastian/environment": "^4.2.2",
+                "sebastian/version": "^2.0.1",
+                "theseer/tokenizer": "^1.1.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^8.2.2"
+            },
+            "suggest": {
+                "ext-xdebug": "^2.7.2"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "7.0-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
+            "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
+            "keywords": [
+                "coverage",
+                "testing",
+                "xunit"
+            ],
+            "time": "2021-07-26T12:20:09+00:00"
+        },
+        {
+            "name": "phpunit/php-file-iterator",
+            "version": "2.0.5",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
+                "reference": "42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5",
+                "reference": "42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^8.5"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0.x-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "FilterIterator implementation that filters files based on a list of suffixes.",
+            "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
+            "keywords": [
+                "filesystem",
+                "iterator"
+            ],
+            "time": "2021-12-02T12:42:26+00:00"
+        },
+        {
+            "name": "phpunit/php-text-template",
+            "version": "1.2.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/php-text-template.git",
+                "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
+                "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "type": "library",
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "Simple template engine.",
+            "homepage": "https://github.com/sebastianbergmann/php-text-template/",
+            "keywords": [
+                "template"
+            ],
+            "time": "2015-06-21T13:50:34+00:00"
+        },
+        {
+            "name": "phpunit/php-timer",
+            "version": "2.1.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/php-timer.git",
+                "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/2454ae1765516d20c4ffe103d85a58a9a3bd5662",
+                "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^8.5"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.1-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "Utility class for timing",
+            "homepage": "https://github.com/sebastianbergmann/php-timer/",
+            "keywords": [
+                "timer"
+            ],
+            "time": "2020-11-30T08:20:02+00:00"
+        },
+        {
+            "name": "phpunit/php-token-stream",
+            "version": "4.0.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/php-token-stream.git",
+                "reference": "a853a0e183b9db7eed023d7933a858fa1c8d25a3"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/a853a0e183b9db7eed023d7933a858fa1c8d25a3",
+                "reference": "a853a0e183b9db7eed023d7933a858fa1c8d25a3",
+                "shasum": ""
+            },
+            "require": {
+                "ext-tokenizer": "*",
+                "php": "^7.3 || ^8.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "4.0-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Wrapper around PHP's tokenizer extension.",
+            "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
+            "keywords": [
+                "tokenizer"
+            ],
+            "abandoned": true,
+            "time": "2020-08-04T08:28:15+00:00"
+        },
+        {
+            "name": "phpunit/phpunit",
+            "version": "8.5.15",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/phpunit.git",
+                "reference": "038d4196d8e8cb405cd5e82cedfe413ad6eef9ef"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/038d4196d8e8cb405cd5e82cedfe413ad6eef9ef",
+                "reference": "038d4196d8e8cb405cd5e82cedfe413ad6eef9ef",
+                "shasum": ""
+            },
+            "require": {
+                "doctrine/instantiator": "^1.3.1",
+                "ext-dom": "*",
+                "ext-json": "*",
+                "ext-libxml": "*",
+                "ext-mbstring": "*",
+                "ext-xml": "*",
+                "ext-xmlwriter": "*",
+                "myclabs/deep-copy": "^1.10.0",
+                "phar-io/manifest": "^2.0.1",
+                "phar-io/version": "^3.0.2",
+                "php": ">=7.2",
+                "phpspec/prophecy": "^1.10.3",
+                "phpunit/php-code-coverage": "^7.0.12",
+                "phpunit/php-file-iterator": "^2.0.2",
+                "phpunit/php-text-template": "^1.2.1",
+                "phpunit/php-timer": "^2.1.2",
+                "sebastian/comparator": "^3.0.2",
+                "sebastian/diff": "^3.0.2",
+                "sebastian/environment": "^4.2.3",
+                "sebastian/exporter": "^3.1.2",
+                "sebastian/global-state": "^3.0.0",
+                "sebastian/object-enumerator": "^3.0.3",
+                "sebastian/resource-operations": "^2.0.1",
+                "sebastian/type": "^1.1.3",
+                "sebastian/version": "^2.0.1"
+            },
+            "require-dev": {
+                "ext-pdo": "*"
+            },
+            "suggest": {
+                "ext-soap": "*",
+                "ext-xdebug": "*",
+                "phpunit/php-invoker": "^2.0.0"
+            },
+            "bin": [
+                "phpunit"
+            ],
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "8.5-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "The PHP Unit Testing framework.",
+            "homepage": "https://phpunit.de/",
+            "keywords": [
+                "phpunit",
+                "testing",
+                "xunit"
+            ],
+            "time": "2021-03-17T07:27:54+00:00"
+        },
+        {
+            "name": "psr/container",
+            "version": "1.1.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/container.git",
+                "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf",
+                "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2.0"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Psr\\Container\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "https://www.php-fig.org/"
+                }
+            ],
+            "description": "Common Container Interface (PHP FIG PSR-11)",
+            "homepage": "https://github.com/php-fig/container",
+            "keywords": [
+                "PSR-11",
+                "container",
+                "container-interface",
+                "container-interop",
+                "psr"
+            ],
+            "time": "2021-03-05T17:36:06+00:00"
+        },
+        {
+            "name": "psr/event-dispatcher",
+            "version": "1.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/event-dispatcher.git",
+                "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0",
+                "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Psr\\EventDispatcher\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "http://www.php-fig.org/"
+                }
+            ],
+            "description": "Standard interfaces for event handling.",
+            "keywords": [
+                "events",
+                "psr",
+                "psr-14"
+            ],
+            "time": "2019-01-08T18:20:26+00:00"
+        },
+        {
+            "name": "sebastian/code-unit-reverse-lookup",
+            "version": "1.0.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
+                "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619",
+                "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.6"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^8.5"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Looks up which function or method a line of code belongs to",
+            "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
+            "time": "2020-11-30T08:15:22+00:00"
+        },
+        {
+            "name": "sebastian/comparator",
+            "version": "3.0.5",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/comparator.git",
+                "reference": "1dc7ceb4a24aede938c7af2a9ed1de09609ca770"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1dc7ceb4a24aede938c7af2a9ed1de09609ca770",
+                "reference": "1dc7ceb4a24aede938c7af2a9ed1de09609ca770",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1",
+                "sebastian/diff": "^3.0",
+                "sebastian/exporter": "^3.1"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^8.5"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.0-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                },
+                {
+                    "name": "Jeff Welch",
+                    "email": "whatthejeff@gmail.com"
+                },
+                {
+                    "name": "Volker Dusch",
+                    "email": "github@wallbash.com"
+                },
+                {
+                    "name": "Bernhard Schussek",
+                    "email": "bschussek@2bepublished.at"
+                }
+            ],
+            "description": "Provides the functionality to compare PHP values for equality",
+            "homepage": "https://github.com/sebastianbergmann/comparator",
+            "keywords": [
+                "comparator",
+                "compare",
+                "equality"
+            ],
+            "time": "2022-09-14T12:31:48+00:00"
+        },
+        {
+            "name": "sebastian/diff",
+            "version": "3.0.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/diff.git",
+                "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/14f72dd46eaf2f2293cbe79c93cc0bc43161a211",
+                "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^7.5 || ^8.0",
+                "symfony/process": "^2 || ^3.3 || ^4"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.0-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                },
+                {
+                    "name": "Kore Nordmann",
+                    "email": "mail@kore-nordmann.de"
+                }
+            ],
+            "description": "Diff implementation",
+            "homepage": "https://github.com/sebastianbergmann/diff",
+            "keywords": [
+                "diff",
+                "udiff",
+                "unidiff",
+                "unified diff"
+            ],
+            "time": "2020-11-30T07:59:04+00:00"
+        },
+        {
+            "name": "sebastian/environment",
+            "version": "4.2.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/environment.git",
+                "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/d47bbbad83711771f167c72d4e3f25f7fcc1f8b0",
+                "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^7.5"
+            },
+            "suggest": {
+                "ext-posix": "*"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "4.2-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Provides functionality to handle HHVM/PHP environments",
+            "homepage": "http://www.github.com/sebastianbergmann/environment",
+            "keywords": [
+                "Xdebug",
+                "environment",
+                "hhvm"
+            ],
+            "time": "2020-11-30T07:53:42+00:00"
+        },
+        {
+            "name": "sebastian/exporter",
+            "version": "3.1.5",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/exporter.git",
+                "reference": "73a9676f2833b9a7c36968f9d882589cd75511e6"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/73a9676f2833b9a7c36968f9d882589cd75511e6",
+                "reference": "73a9676f2833b9a7c36968f9d882589cd75511e6",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.0",
+                "sebastian/recursion-context": "^3.0"
+            },
+            "require-dev": {
+                "ext-mbstring": "*",
+                "phpunit/phpunit": "^8.5"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.1.x-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                },
+                {
+                    "name": "Jeff Welch",
+                    "email": "whatthejeff@gmail.com"
+                },
+                {
+                    "name": "Volker Dusch",
+                    "email": "github@wallbash.com"
+                },
+                {
+                    "name": "Adam Harvey",
+                    "email": "aharvey@php.net"
+                },
+                {
+                    "name": "Bernhard Schussek",
+                    "email": "bschussek@gmail.com"
+                }
+            ],
+            "description": "Provides the functionality to export PHP variables for visualization",
+            "homepage": "http://www.github.com/sebastianbergmann/exporter",
+            "keywords": [
+                "export",
+                "exporter"
+            ],
+            "time": "2022-09-14T06:00:17+00:00"
+        },
+        {
+            "name": "sebastian/global-state",
+            "version": "3.0.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/global-state.git",
+                "reference": "de036ec91d55d2a9e0db2ba975b512cdb1c23921"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/de036ec91d55d2a9e0db2ba975b512cdb1c23921",
+                "reference": "de036ec91d55d2a9e0db2ba975b512cdb1c23921",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2",
+                "sebastian/object-reflector": "^1.1.1",
+                "sebastian/recursion-context": "^3.0"
+            },
+            "require-dev": {
+                "ext-dom": "*",
+                "phpunit/phpunit": "^8.0"
+            },
+            "suggest": {
+                "ext-uopz": "*"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.0-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Snapshotting of global state",
+            "homepage": "http://www.github.com/sebastianbergmann/global-state",
+            "keywords": [
+                "global state"
+            ],
+            "time": "2022-02-10T06:55:38+00:00"
+        },
+        {
+            "name": "sebastian/object-enumerator",
+            "version": "3.0.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/object-enumerator.git",
+                "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2",
+                "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.0",
+                "sebastian/object-reflector": "^1.1.1",
+                "sebastian/recursion-context": "^3.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^6.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.0.x-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Traverses array structures and object graphs to enumerate all referenced objects",
+            "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
+            "time": "2020-11-30T07:40:27+00:00"
+        },
+        {
+            "name": "sebastian/object-reflector",
+            "version": "1.1.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/object-reflector.git",
+                "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/9b8772b9cbd456ab45d4a598d2dd1a1bced6363d",
+                "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^6.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.1-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Allows reflection of object attributes, including inherited and non-public ones",
+            "homepage": "https://github.com/sebastianbergmann/object-reflector/",
+            "time": "2020-11-30T07:37:18+00:00"
+        },
+        {
+            "name": "sebastian/recursion-context",
+            "version": "3.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/recursion-context.git",
+                "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/367dcba38d6e1977be014dc4b22f47a484dac7fb",
+                "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^6.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.0.x-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                },
+                {
+                    "name": "Jeff Welch",
+                    "email": "whatthejeff@gmail.com"
+                },
+                {
+                    "name": "Adam Harvey",
+                    "email": "aharvey@php.net"
+                }
+            ],
+            "description": "Provides functionality to recursively process PHP variables",
+            "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
+            "time": "2020-11-30T07:34:24+00:00"
+        },
+        {
+            "name": "sebastian/resource-operations",
+            "version": "2.0.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/resource-operations.git",
+                "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/31d35ca87926450c44eae7e2611d45a7a65ea8b3",
+                "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Provides a list of PHP built-in functions that operate on resources",
+            "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
+            "time": "2020-11-30T07:30:19+00:00"
+        },
+        {
+            "name": "sebastian/type",
+            "version": "1.1.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/type.git",
+                "reference": "0150cfbc4495ed2df3872fb31b26781e4e077eb4"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/0150cfbc4495ed2df3872fb31b26781e4e077eb4",
+                "reference": "0150cfbc4495ed2df3872fb31b26781e4e077eb4",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^8.2"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.1-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "Collection of value objects that represent the types of the PHP type system",
+            "homepage": "https://github.com/sebastianbergmann/type",
+            "time": "2020-11-30T07:25:11+00:00"
+        },
+        {
+            "name": "sebastian/version",
+            "version": "2.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/version.git",
+                "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019",
+                "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.6"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0.x-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "Library that helps with managing the version number of Git-hosted PHP projects",
+            "homepage": "https://github.com/sebastianbergmann/version",
+            "time": "2016-10-03T07:35:21+00:00"
+        },
+        {
+            "name": "symfony/console",
+            "version": "v5.4.15",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/console.git",
+                "reference": "ea59bb0edfaf9f28d18d8791410ee0355f317669"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/console/zipball/ea59bb0edfaf9f28d18d8791410ee0355f317669",
+                "reference": "ea59bb0edfaf9f28d18d8791410ee0355f317669",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2.5",
+                "symfony/deprecation-contracts": "^2.1|^3",
+                "symfony/polyfill-mbstring": "~1.0",
+                "symfony/polyfill-php73": "^1.9",
+                "symfony/polyfill-php80": "^1.16",
+                "symfony/service-contracts": "^1.1|^2|^3",
+                "symfony/string": "^5.1|^6.0"
+            },
+            "conflict": {
+                "psr/log": ">=3",
+                "symfony/dependency-injection": "<4.4",
+                "symfony/dotenv": "<5.1",
+                "symfony/event-dispatcher": "<4.4",
+                "symfony/lock": "<4.4",
+                "symfony/process": "<4.4"
+            },
+            "provide": {
+                "psr/log-implementation": "1.0|2.0"
+            },
+            "require-dev": {
+                "psr/log": "^1|^2",
+                "symfony/config": "^4.4|^5.0|^6.0",
+                "symfony/dependency-injection": "^4.4|^5.0|^6.0",
+                "symfony/event-dispatcher": "^4.4|^5.0|^6.0",
+                "symfony/lock": "^4.4|^5.0|^6.0",
+                "symfony/process": "^4.4|^5.0|^6.0",
+                "symfony/var-dumper": "^4.4|^5.0|^6.0"
+            },
+            "suggest": {
+                "psr/log": "For using the console logger",
+                "symfony/event-dispatcher": "",
+                "symfony/lock": "",
+                "symfony/process": ""
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\Console\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Eases the creation of beautiful and testable command line interfaces",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "cli",
+                "command line",
+                "console",
+                "terminal"
+            ],
+            "time": "2022-10-26T21:41:52+00:00"
+        },
+        {
+            "name": "symfony/deprecation-contracts",
+            "version": "v2.5.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/deprecation-contracts.git",
+                "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66",
+                "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "2.5-dev"
+                },
+                "thanks": {
+                    "name": "symfony/contracts",
+                    "url": "https://github.com/symfony/contracts"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "function.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "A generic function and convention to trigger deprecation notices",
+            "homepage": "https://symfony.com",
+            "time": "2022-01-02T09:53:40+00:00"
+        },
+        {
+            "name": "symfony/event-dispatcher",
+            "version": "v5.4.9",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/event-dispatcher.git",
+                "reference": "8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc",
+                "reference": "8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2.5",
+                "symfony/deprecation-contracts": "^2.1|^3",
+                "symfony/event-dispatcher-contracts": "^2|^3",
+                "symfony/polyfill-php80": "^1.16"
+            },
+            "conflict": {
+                "symfony/dependency-injection": "<4.4"
+            },
+            "provide": {
+                "psr/event-dispatcher-implementation": "1.0",
+                "symfony/event-dispatcher-implementation": "2.0"
+            },
+            "require-dev": {
+                "psr/log": "^1|^2|^3",
+                "symfony/config": "^4.4|^5.0|^6.0",
+                "symfony/dependency-injection": "^4.4|^5.0|^6.0",
+                "symfony/error-handler": "^4.4|^5.0|^6.0",
+                "symfony/expression-language": "^4.4|^5.0|^6.0",
+                "symfony/http-foundation": "^4.4|^5.0|^6.0",
+                "symfony/service-contracts": "^1.1|^2|^3",
+                "symfony/stopwatch": "^4.4|^5.0|^6.0"
+            },
+            "suggest": {
+                "symfony/dependency-injection": "",
+                "symfony/http-kernel": ""
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\EventDispatcher\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
+            "homepage": "https://symfony.com",
+            "time": "2022-05-05T16:45:39+00:00"
+        },
+        {
+            "name": "symfony/event-dispatcher-contracts",
+            "version": "v2.5.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/event-dispatcher-contracts.git",
+                "reference": "f98b54df6ad059855739db6fcbc2d36995283fe1"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/f98b54df6ad059855739db6fcbc2d36995283fe1",
+                "reference": "f98b54df6ad059855739db6fcbc2d36995283fe1",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2.5",
+                "psr/event-dispatcher": "^1"
+            },
+            "suggest": {
+                "symfony/event-dispatcher-implementation": ""
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "2.5-dev"
+                },
+                "thanks": {
+                    "name": "symfony/contracts",
+                    "url": "https://github.com/symfony/contracts"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Contracts\\EventDispatcher\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Generic abstractions related to dispatching event",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "abstractions",
+                "contracts",
+                "decoupling",
+                "interfaces",
+                "interoperability",
+                "standards"
+            ],
+            "time": "2022-01-02T09:53:40+00:00"
+        },
+        {
+            "name": "symfony/filesystem",
+            "version": "v5.4.13",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/filesystem.git",
+                "reference": "ac09569844a9109a5966b9438fc29113ce77cf51"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/filesystem/zipball/ac09569844a9109a5966b9438fc29113ce77cf51",
+                "reference": "ac09569844a9109a5966b9438fc29113ce77cf51",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2.5",
+                "symfony/polyfill-ctype": "~1.8",
+                "symfony/polyfill-mbstring": "~1.8",
+                "symfony/polyfill-php80": "^1.16"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\Filesystem\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Provides basic utilities for the filesystem",
+            "homepage": "https://symfony.com",
+            "time": "2022-09-21T19:53:16+00:00"
+        },
+        {
+            "name": "symfony/finder",
+            "version": "v5.4.11",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/finder.git",
+                "reference": "7872a66f57caffa2916a584db1aa7f12adc76f8c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/finder/zipball/7872a66f57caffa2916a584db1aa7f12adc76f8c",
+                "reference": "7872a66f57caffa2916a584db1aa7f12adc76f8c",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2.5",
+                "symfony/deprecation-contracts": "^2.1|^3",
+                "symfony/polyfill-php80": "^1.16"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\Finder\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Finds files and directories via an intuitive fluent interface",
+            "homepage": "https://symfony.com",
+            "time": "2022-07-29T07:37:50+00:00"
+        },
+        {
+            "name": "symfony/options-resolver",
+            "version": "v5.4.11",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/options-resolver.git",
+                "reference": "54f14e36aa73cb8f7261d7686691fd4d75ea2690"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/options-resolver/zipball/54f14e36aa73cb8f7261d7686691fd4d75ea2690",
+                "reference": "54f14e36aa73cb8f7261d7686691fd4d75ea2690",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2.5",
+                "symfony/deprecation-contracts": "^2.1|^3",
+                "symfony/polyfill-php73": "~1.0",
+                "symfony/polyfill-php80": "^1.16"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\OptionsResolver\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Provides an improved replacement for the array_replace PHP function",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "config",
+                "configuration",
+                "options"
+            ],
+            "time": "2022-07-20T13:00:38+00:00"
+        },
+        {
+            "name": "symfony/polyfill-ctype",
+            "version": "v1.27.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-ctype.git",
+                "reference": "5bbc823adecdae860bb64756d639ecfec17b050a"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a",
+                "reference": "5bbc823adecdae860bb64756d639ecfec17b050a",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "provide": {
+                "ext-ctype": "*"
+            },
+            "suggest": {
+                "ext-ctype": "For best performance"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.27-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "bootstrap.php"
+                ],
+                "psr-4": {
+                    "Symfony\\Polyfill\\Ctype\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Gert de Pagter",
+                    "email": "BackEndTea@gmail.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill for ctype functions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "ctype",
+                "polyfill",
+                "portable"
+            ],
+            "time": "2022-11-03T14:55:06+00:00"
+        },
+        {
+            "name": "symfony/polyfill-intl-grapheme",
+            "version": "v1.27.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-intl-grapheme.git",
+                "reference": "511a08c03c1960e08a883f4cffcacd219b758354"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/511a08c03c1960e08a883f4cffcacd219b758354",
+                "reference": "511a08c03c1960e08a883f4cffcacd219b758354",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "suggest": {
+                "ext-intl": "For best performance"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.27-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "bootstrap.php"
+                ],
+                "psr-4": {
+                    "Symfony\\Polyfill\\Intl\\Grapheme\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill for intl's grapheme_* functions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "grapheme",
+                "intl",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "time": "2022-11-03T14:55:06+00:00"
+        },
+        {
+            "name": "symfony/polyfill-intl-normalizer",
+            "version": "v1.27.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
+                "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6",
+                "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "suggest": {
+                "ext-intl": "For best performance"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.27-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "bootstrap.php"
+                ],
+                "psr-4": {
+                    "Symfony\\Polyfill\\Intl\\Normalizer\\": ""
+                },
+                "classmap": [
+                    "Resources/stubs"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill for intl's Normalizer class and related functions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "intl",
+                "normalizer",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "time": "2022-11-03T14:55:06+00:00"
+        },
+        {
+            "name": "symfony/polyfill-mbstring",
+            "version": "v1.27.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-mbstring.git",
+                "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
+                "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "provide": {
+                "ext-mbstring": "*"
+            },
+            "suggest": {
+                "ext-mbstring": "For best performance"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.27-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "bootstrap.php"
+                ],
+                "psr-4": {
+                    "Symfony\\Polyfill\\Mbstring\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill for the Mbstring extension",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "mbstring",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "time": "2022-11-03T14:55:06+00:00"
+        },
+        {
+            "name": "symfony/polyfill-php73",
+            "version": "v1.27.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-php73.git",
+                "reference": "9e8ecb5f92152187c4799efd3c96b78ccab18ff9"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/9e8ecb5f92152187c4799efd3c96b78ccab18ff9",
+                "reference": "9e8ecb5f92152187c4799efd3c96b78ccab18ff9",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.27-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "bootstrap.php"
+                ],
+                "psr-4": {
+                    "Symfony\\Polyfill\\Php73\\": ""
+                },
+                "classmap": [
+                    "Resources/stubs"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "time": "2022-11-03T14:55:06+00:00"
+        },
+        {
+            "name": "symfony/polyfill-php80",
+            "version": "v1.27.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-php80.git",
+                "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
+                "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.27-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "bootstrap.php"
+                ],
+                "psr-4": {
+                    "Symfony\\Polyfill\\Php80\\": ""
+                },
+                "classmap": [
+                    "Resources/stubs"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Ion Bazan",
+                    "email": "ion.bazan@gmail.com"
+                },
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "time": "2022-11-03T14:55:06+00:00"
+        },
+        {
+            "name": "symfony/process",
+            "version": "v5.4.11",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/process.git",
+                "reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/process/zipball/6e75fe6874cbc7e4773d049616ab450eff537bf1",
+                "reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2.5",
+                "symfony/polyfill-php80": "^1.16"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\Process\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Executes commands in sub-processes",
+            "homepage": "https://symfony.com",
+            "time": "2022-06-27T16:58:25+00:00"
+        },
+        {
+            "name": "symfony/service-contracts",
+            "version": "v2.5.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/service-contracts.git",
+                "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c",
+                "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2.5",
+                "psr/container": "^1.1",
+                "symfony/deprecation-contracts": "^2.1|^3"
+            },
+            "conflict": {
+                "ext-psr": "<1.1|>=2"
+            },
+            "suggest": {
+                "symfony/service-implementation": ""
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "2.5-dev"
+                },
+                "thanks": {
+                    "name": "symfony/contracts",
+                    "url": "https://github.com/symfony/contracts"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Contracts\\Service\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Generic abstractions related to writing services",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "abstractions",
+                "contracts",
+                "decoupling",
+                "interfaces",
+                "interoperability",
+                "standards"
+            ],
+            "time": "2022-05-30T19:17:29+00:00"
+        },
+        {
+            "name": "symfony/stopwatch",
+            "version": "v5.4.13",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/stopwatch.git",
+                "reference": "6df7a3effde34d81717bbef4591e5ffe32226d69"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/stopwatch/zipball/6df7a3effde34d81717bbef4591e5ffe32226d69",
+                "reference": "6df7a3effde34d81717bbef4591e5ffe32226d69",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2.5",
+                "symfony/service-contracts": "^1|^2|^3"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\Stopwatch\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Provides a way to profile code",
+            "homepage": "https://symfony.com",
+            "time": "2022-09-28T13:19:49+00:00"
+        },
+        {
+            "name": "symfony/string",
+            "version": "v5.4.15",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/string.git",
+                "reference": "571334ce9f687e3e6af72db4d3b2a9431e4fd9ed"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/string/zipball/571334ce9f687e3e6af72db4d3b2a9431e4fd9ed",
+                "reference": "571334ce9f687e3e6af72db4d3b2a9431e4fd9ed",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2.5",
+                "symfony/polyfill-ctype": "~1.8",
+                "symfony/polyfill-intl-grapheme": "~1.0",
+                "symfony/polyfill-intl-normalizer": "~1.0",
+                "symfony/polyfill-mbstring": "~1.0",
+                "symfony/polyfill-php80": "~1.15"
+            },
+            "conflict": {
+                "symfony/translation-contracts": ">=3.0"
+            },
+            "require-dev": {
+                "symfony/error-handler": "^4.4|^5.0|^6.0",
+                "symfony/http-client": "^4.4|^5.0|^6.0",
+                "symfony/translation-contracts": "^1.1|^2",
+                "symfony/var-exporter": "^4.4|^5.0|^6.0"
+            },
+            "type": "library",
+            "autoload": {
+                "files": [
+                    "Resources/functions.php"
+                ],
+                "psr-4": {
+                    "Symfony\\Component\\String\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "grapheme",
+                "i18n",
+                "string",
+                "unicode",
+                "utf-8",
+                "utf8"
+            ],
+            "time": "2022-10-05T15:16:54+00:00"
+        },
+        {
+            "name": "symfony/yaml",
+            "version": "v5.4.14",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/yaml.git",
+                "reference": "e83fe9a72011f07c662da46a05603d66deeeb487"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/yaml/zipball/e83fe9a72011f07c662da46a05603d66deeeb487",
+                "reference": "e83fe9a72011f07c662da46a05603d66deeeb487",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2.5",
+                "symfony/deprecation-contracts": "^2.1|^3",
+                "symfony/polyfill-ctype": "^1.8"
+            },
+            "conflict": {
+                "symfony/console": "<5.3"
+            },
+            "require-dev": {
+                "symfony/console": "^5.3|^6.0"
+            },
+            "suggest": {
+                "symfony/console": "For validating YAML files using the lint command"
+            },
+            "bin": [
+                "Resources/bin/yaml-lint"
+            ],
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\Yaml\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Loads and dumps YAML files",
+            "homepage": "https://symfony.com",
+            "time": "2022-10-03T15:15:50+00:00"
+        },
+        {
+            "name": "theseer/tokenizer",
+            "version": "1.2.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/theseer/tokenizer.git",
+                "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e",
+                "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e",
+                "shasum": ""
+            },
+            "require": {
+                "ext-dom": "*",
+                "ext-tokenizer": "*",
+                "ext-xmlwriter": "*",
+                "php": "^7.2 || ^8.0"
+            },
+            "type": "library",
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Arne Blankerts",
+                    "email": "arne@blankerts.de",
+                    "role": "Developer"
+                }
+            ],
+            "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
+            "time": "2021-07-28T10:34:58+00:00"
+        },
+        {
+            "name": "webmozart/assert",
+            "version": "1.11.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/webmozarts/assert.git",
+                "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991",
+                "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991",
+                "shasum": ""
+            },
+            "require": {
+                "ext-ctype": "*",
+                "php": "^7.2 || ^8.0"
+            },
+            "conflict": {
+                "phpstan/phpstan": "<0.12.20",
+                "vimeo/psalm": "<4.6.1 || 4.6.2"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^8.5.13"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.10-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Webmozart\\Assert\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Bernhard Schussek",
+                    "email": "bschussek@gmail.com"
+                }
+            ],
+            "description": "Assertions to validate method input/output with nice error messages.",
+            "keywords": [
+                "assert",
+                "check",
+                "validate"
+            ],
+            "time": "2022-06-03T18:03:27+00:00"
+        }
+    ],
+    "aliases": [],
+    "minimum-stability": "stable",
+    "stability-flags": [],
+    "prefer-stable": false,
+    "prefer-lowest": false,
+    "platform": {
+        "php": ">=7.3.0"
+    },
+    "platform-dev": [],
+    "platform-overrides": {
+        "php": "7.3.0"
+    }
+}
diff --git a/module/finc/tests/selenium/docker-compose.yaml b/module/finc/tests/selenium/docker-compose.yaml
new file mode 100755
index 0000000000000000000000000000000000000000..cfd8a9ffc65b2f71a1323eca2e9b69de41fe418c
--- /dev/null
+++ b/module/finc/tests/selenium/docker-compose.yaml
@@ -0,0 +1,45 @@
+version: "3.7"
+
+services:
+  selenium-hub:
+    image: selenium/hub
+    container_name: selenium
+    ports:
+      - "4442:4442"
+      - "4443:4443"
+      - "4444:4444"
+    extra_hosts:
+      - "host.docker.internal:10.111.0.1"
+  chrome:
+    image: selenium/node-chrome
+    depends_on:
+      - selenium-hub
+    environment:
+      - SE_EVENT_BUS_HOST=selenium-hub
+      - SE_EVENT_BUS_PUBLISH_PORT=4442
+      - SE_EVENT_BUS_SUBSCRIBE_PORT=4443
+  firefox:
+    image: selenium/node-firefox
+    depends_on:
+      - selenium-hub
+    environment:
+      - SE_EVENT_BUS_HOST=selenium-hub
+      - SE_EVENT_BUS_PUBLISH_PORT=4442
+      - SE_EVENT_BUS_SUBSCRIBE_PORT=4443
+
+  php:
+    image: php:7.3-fpm
+    working_dir: /usr/local/vufind
+    depends_on:
+      - selenium-hub
+    #command: ["./vendor/bin/steward run staging firefox"]
+    volumes:
+      - ./:/usr/local/vufind
+    entrypoint: ["php/entrypoint.sh"]
+    command: ["php-fpm"]
+
+  composer:
+    image: composer:1.9
+    command: ["composer", "install"]
+    volumes:
+      - .:/app
\ No newline at end of file
diff --git a/module/finc/tests/selenium/php.ini b/module/finc/tests/selenium/php.ini
new file mode 100755
index 0000000000000000000000000000000000000000..a49546fa2db2ed06b48f56cc829f1452c08f66c7
--- /dev/null
+++ b/module/finc/tests/selenium/php.ini
@@ -0,0 +1,31 @@
+;  Copyright (C) 2020  Leipzig University Library
+; 
+;  This program is free software: you can redistribute it and/or modify
+;  it under the terms of the GNU General Public License as published by
+;  the Free Software Foundation, either version 3 of the License, or
+;  (at your option) any later version.
+; 
+;  This program is distributed in the hope that it will be useful,
+;  but WITHOUT ANY WARRANTY; without even the implied warranty of
+;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;  GNU General Public License for more details.
+; 
+;  You should have received a copy of the GNU General Public License
+;  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+; 
+;  @author  Sebastian Kehr <kehr@ub.uni-leipzig.de>
+;  @license https://opensource.org/licenses/GPL-3.0 GNU GPLv3
+
+; See https://www.php.net/manual/en/function.error-reporting.php for more details.
+error_reporting = E_ALL
+
+; See https://xdebug.org/docs/all_settings for more details.
+xdebug.remote_autostart=0
+xdebug.remote_mode=req
+xdebug.remote_handler=dbgp
+xdebug.remote_connect_back=1
+xdebug.remote_port=9000
+xdebug.remote_enable=1
+short_open_tag=Off;
+log_errors = on
+error_reporting = 32767
\ No newline at end of file
diff --git a/module/finc/tests/selenium/php/Dockerfile b/module/finc/tests/selenium/php/Dockerfile
new file mode 100755
index 0000000000000000000000000000000000000000..8d87a43e02b5c3e0f0ffa894a068977bc937d62d
--- /dev/null
+++ b/module/finc/tests/selenium/php/Dockerfile
@@ -0,0 +1,30 @@
+# Copyright (C) 2020  Leipzig University Library
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# @author  Sebastian Kehr <kehr@ub.uni-leipzig.de>
+# @license https://opensource.org/licenses/GPL-3.0 GNU GPLv3
+
+FROM php:7.2-fpm-alpine
+RUN apk add --no-cache $PHPIZE_DEPS freetype-dev libxml2-dev icu-dev libxslt-dev \
+    && pecl install xdebug-2.9.6 \
+    && docker-php-ext-enable xdebug \
+    && docker-php-ext-install mysqli \
+    && docker-php-ext-install pdo_mysql \
+    && docker-php-ext-install gd \
+    && docker-php-ext-install soap \
+    && docker-php-ext-install intl \
+    && docker-php-ext-install dom \
+    && docker-php-ext-install xsl
+COPY php.ini /usr/local/etc/php/conf.d/php.ini
\ No newline at end of file
diff --git a/module/finc/tests/selenium/php/entrypoint.sh b/module/finc/tests/selenium/php/entrypoint.sh
new file mode 100755
index 0000000000000000000000000000000000000000..927b845f7d11d2f22a194b0751fbeb40957722d7
--- /dev/null
+++ b/module/finc/tests/selenium/php/entrypoint.sh
@@ -0,0 +1,25 @@
+#!/usr/bin/env sh
+# Copyright (C) 2020  Leipzig University Library
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# @author  Sebastian Kehr <kehr@ub.uni-leipzig.de>
+# @license https://opensource.org/licenses/GPL-3.0 GNU GPLv3
+
+until ! (ping -c1 env >/dev/null 2>&1) && [ -f ./data/docker/env/php ]; do :; done
+set -a; . ./data/docker/env/php; set +a
+
+: "${UIDGID:=$(stat -c '%u' .):$(stat -c '%g' .)}"
+sed -i "s/$(id -u www-data):$(id -g www-data)/$UIDGID/" /etc/passwd
+exec docker-php-entrypoint "$@"
diff --git a/module/finc/tests/selenium/php/php.ini b/module/finc/tests/selenium/php/php.ini
new file mode 100755
index 0000000000000000000000000000000000000000..abe39fa796940d546216f16ae4587f7a75417131
--- /dev/null
+++ b/module/finc/tests/selenium/php/php.ini
@@ -0,0 +1,29 @@
+;  Copyright (C) 2020  Leipzig University Library
+; 
+;  This program is free software: you can redistribute it and/or modify
+;  it under the terms of the GNU General Public License as published by
+;  the Free Software Foundation, either version 3 of the License, or
+;  (at your option) any later version.
+; 
+;  This program is distributed in the hope that it will be useful,
+;  but WITHOUT ANY WARRANTY; without even the implied warranty of
+;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;  GNU General Public License for more details.
+; 
+;  You should have received a copy of the GNU General Public License
+;  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+; 
+;  @author  Sebastian Kehr <kehr@ub.uni-leipzig.de>
+;  @license https://opensource.org/licenses/GPL-3.0 GNU GPLv3
+
+; See https://www.php.net/manual/en/function.error-reporting.php for more details.
+error_reporting = E_ALL
+
+; See https://xdebug.org/docs/all_settings for more details.
+xdebug.remote_autostart=0
+xdebug.remote_mode=req
+xdebug.remote_handler=dbgp
+xdebug.remote_connect_back=1
+xdebug.remote_port=9000
+xdebug.remote_enable=1
+short_open_tag=Off;
\ No newline at end of file
diff --git a/module/finc/tests/selenium/tests/adlr/AdlrBase.php b/module/finc/tests/selenium/tests/adlr/AdlrBase.php
new file mode 100644
index 0000000000000000000000000000000000000000..0339ebee0fb38ca39c9aee0c3893aa783df3b9d6
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/AdlrBase.php
@@ -0,0 +1,139 @@
+<?php
+namespace Selenium\adlr;
+
+use Facebook\WebDriver\WebDriverBy;
+use Facebook\WebDriver\WebDriverExpectedCondition;
+use Lmc\Steward\ConfigProvider;
+use Lmc\Steward\Test\AbstractTestCase;
+
+class AdlrBase extends AbstractTestCase
+{
+    public static $port = '';
+    // public static $port = ':81';
+
+    /** @var string */
+    public static $host = 'https://staging.finc.info/vufind2/fid_adlr';
+    // public static $baseUrl = 'http://host.docker.internal';
+    // public static $baseUrl = 'http://127.0.0.1';
+    // public static $baseUrl = 'http://localhost';
+
+    protected $user = false;
+
+    /**
+     * @before
+     */
+    public function initBaseUrl()
+    {
+        // Set base url according to environment
+        switch (ConfigProvider::getInstance()->env) {
+            case 'staging':
+                self::$host = 'https://staging.finc.info/vufind2/fid_adlr';
+                break;
+            case 'alpha':
+                self::$host = 'http://host.docker.internal';
+                // self::$host = 'https://alpha.finc.info/vufind2/fid_adlr/22589';
+                break;
+            case 'local':
+                self::$host = 'http://host.docker.internal';
+                break;
+            default:
+                throw new \RuntimeException(sprintf('Unknown environment "%s"', ConfigProvider::getInstance()->env));
+        }
+
+        $this->debug('Environment "%s"', ConfigProvider::getInstance()->env);
+        $this->debug('Base URL set to "%s"', self::$host);
+
+        if (ConfigProvider::getInstance()->env === 'production') {
+            $this->warn('The tests are run against production, so be careful!');
+        }
+    }
+
+    protected function runGetItTest($records = [], $rules = []): void
+    {
+        foreach ($records as $record) {
+            $this->log("object id of webdriver: " . spl_object_id($this->wd));
+            $this->wd->get(self::$host . self::$port . $record);
+            $this->wd->takeScreenshot("logs/adlr/info{$record}" . ($this->user ? '-' . $this->user : '') . ".png");
+
+            foreach ($rules["desc"] ?? [] as $rule) {
+                if ($rule["waitForClass"]) {
+                    $this->waitForClass($rule["waitForClass"], true);
+                }
+                if ($rule["waitForId"]) {
+                    $this->waitForId($rule["waitForId"], true);
+                }
+                if ($rule["waitForLinkText"]) {
+                    $this->waitForLinkText($rule["waitForLinkText"], true);
+                }
+                if ($rule["wait"]) {
+                    try {
+                        $this->wd->wait(5, 5000)->until(
+                            WebDriverExpectedCondition::elementTextContains(
+                                WebDriverBy::className($rule["wait"]),
+                                $rule["text"]
+                            )
+                        );
+                    } catch (\Facebook\WebDriver\Exception\NoSuchElementException $x) {
+                        $this->log("Timeout for $record when fething {$rule["wait"]}.");
+                    }
+                }
+                try {
+                    $value = $this->findByCss($rule["path"])->getText();
+                } catch (\Facebook\WebDriver\Exception\NoSuchElementException $x) {
+                    $value = false;
+                }
+                switch ($rule["type"] ?? '') {
+                    case 'text':
+                        $this->assertEqualsIgnoringCase(
+                            $rule["text"],
+                            $value,
+                            $rule["path"] . ($value === false ? " does not exists" : " is '" . $value . "' ")
+                            . ", but should be '" . $rule["text"] . "'"
+                        );
+                        break;
+                    case 'contains':
+                        $this->assertStringContainsStringIgnoringCase(
+                            $rule["text"],
+                            $value,
+                            $record . ": " .
+                            $rule["path"] . ($value === false ? " does not exists" : " is '" . $value . "' ")
+                            . ", but should contain '" . $rule["text"] . "'"
+                        );
+                        break;
+                    case 'anti-exi':
+                        $this->assertNotEqualsIgnoringCase(
+                            $rule["text"],
+                            $value,
+                            $rule["path"] . " must not be equals to '" . $rule["text"] . "'"
+                        );
+                        break;
+                }
+            }
+        }
+    }
+
+    #region helper methods
+    protected function changeLanguage($lang = 'de')
+    {
+        $this->wd->get(self::$host . self::$port);
+        $this->wd->executeScript("document.langForm.mylang.value='" . $lang . "';document.langForm.submit();");
+        $this->waitForPartialLinkText('MENÜ');
+    }
+
+    protected function setFullsreen()
+    {
+        $this->wd->manage()->window()->maximize();
+    }
+
+    protected function logout()
+    {
+        $this->wd->get(self::$host . self::$port . '/MyResearch/Logout');
+    }
+
+    protected function setUp(): void
+    {
+        $this->changeLanguage();
+        parent::setUp();
+    }
+    #endregion
+}
diff --git a/module/finc/tests/selenium/tests/adlr/AdlrLoginBase.php b/module/finc/tests/selenium/tests/adlr/AdlrLoginBase.php
new file mode 100644
index 0000000000000000000000000000000000000000..d087f2de03108467b3925d9b668087d56cd92f90
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/AdlrLoginBase.php
@@ -0,0 +1,16 @@
+<?php
+namespace Selenium\adlr;
+
+abstract class AdlrLoginBase extends AdlrBase implements Login
+{
+    protected function login($user, $password): bool
+    {
+        $this->user = $user;
+        $this->wd->get(self::$host . self::$port . '/MyResearch/UserLogin');
+        $this->findById('login_Authenticator_username')->sendKeys($user);
+        $this->findById('login_Authenticator_password')->sendKeys($password);
+        $this->findByName('processLogin')->click();
+        $this->waitForClass('myresearch-menu');
+        return true;
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit01DefaultTest.php b/module/finc/tests/selenium/tests/adlr/Getit01DefaultTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..1f33b8ebf10a7ceededf37a3d106021aa594c139
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit01DefaultTest.php
@@ -0,0 +1,55 @@
+<?php
+namespace Selenium\adlr;
+
+/**
+ * @group adlr
+ * @group adlr-getit-01
+ * @group adlr-getit-default
+ */
+class Getit01DefaultTest extends AdlrBase
+{
+    public const RECORDS = [
+        "/Record/finc-87-14159",
+        "/Record/finc-88-694",
+        "/Record/finc-99-1482",
+        "/Record/finc-101-aHR0cDovL3d3dy5maWxtbXVzaWsudW5pLWtpZWwuZGUvS0IxNC9LQjE0LVZvcndvcnQucGRm",
+        "/Record/finc-150-10500",
+        "/Record/finc-153-bWFuLWluLXRoZS1hdHRpYy0xOTUzLXJlc3RvcmVkLW1vdmllLTcyMHAtaGQ",
+        "/Record/finc-170-12835",
+        "/Record/191-eunhj",
+        "/Record/196-1213742994",
+        "/Record/26-80811",
+        "/Record/ai-28-d2580a888c2d405983dd08b4cbf24560",
+        "/Record/finc-30-61040",
+        "/Record/finc-39-comin118937881985num731329",
+        "/Record/ai-53-757382",
+        "/Record/finc-80-6678",
+        "/Record/84-on1079058527"
+    ];
+
+    public const RULES = [
+        "test_case_id" => "01",
+        "desc" => [
+            [
+                "type" => "text",
+                "path" => ".getitbox-getit > h4",
+                "text" => "GET IT"
+            ],
+            [
+                "type" => "text",
+                "path" => "#get-it-button",
+                "text" => "LINKS ZUR RESSOURCE"
+            ],
+            [
+                "type" => "text",
+                "path" => ".getitbox-notices",
+                "text" => "Diese Ressource ist frei verfügbar."
+            ]
+        ]
+    ];
+
+    public function testGetItDefault01()
+    {
+        $this->runGetItTest(self::RECORDS, self::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit01ProfessorTest.php b/module/finc/tests/selenium/tests/adlr/Getit01ProfessorTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..bc4d95b2a895c5eb4fed9cfab9e1a2919ba4b18c
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit01ProfessorTest.php
@@ -0,0 +1,19 @@
+<?php
+namespace Selenium\adlr;
+
+/**
+ * @group adlr
+ * @group adlr-getit-01
+ * @group adlr-getit-professor
+ */
+class Getit01ProfessorTest extends AdlrLoginBase
+{
+    use ProfessorTrait;
+
+    public function testGetItProfessor01()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit01DefaultTest::RECORDS, Getit01DefaultTest::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit01StudentTest.php b/module/finc/tests/selenium/tests/adlr/Getit01StudentTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..1687fe9abe6a17218ba4e9b15ffd86b6e4c81f15
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit01StudentTest.php
@@ -0,0 +1,20 @@
+<?php
+namespace Selenium\adlr;
+
+use Lmc\Steward\Test\AbstractTestCase;
+
+/**
+ * @group adlr-getit-01
+ * @group adlr-getit-student
+ */
+class Getit01StudentTest extends AdlrLoginBase
+{
+    use StudentTrait;
+
+    public function testGetItStudent01()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit01DefaultTest::RECORDS, Getit01DefaultTest::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit02DefaultTest.php b/module/finc/tests/selenium/tests/adlr/Getit02DefaultTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..7b42486e44f7ac9e93cbc9615d033a35f9d1df1a
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit02DefaultTest.php
@@ -0,0 +1,56 @@
+<?php
+namespace Selenium\adlr;
+
+/**
+ * @group adlr
+ * @group adlr-getit-02
+ * @group adlr-getit-default
+ */
+class Getit02DefaultTest extends AdlrBase
+{
+    public const RECORDS = [
+        "/Record/ai-49-aHR0cDovL2R4LmRvaS5vcmcvMTAuMTA4MC8xMDMwNDMxMi4yMDIxLjE5ODMyNTQ",
+        "/Record/ai-49-aHR0cDovL2R4LmRvaS5vcmcvMTAuMTA4MC8xNzQzOTg4NC4yMDIxLjE5MjI0Mzc",
+        "/Record/ai-55-aHR0cHM6Ly93d3cuanN0b3Iub3JnL3N0YWJsZS8xMC4yOTc5L2JsYWNrY2FtZXJhLjEwLjIuMTk",
+        "/Record/ai-55-aHR0cHM6Ly93d3cuanN0b3Iub3JnL3N0YWJsZS80MDQwNjAyMQ",
+        "/Record/ai-68-OLC1936107031",
+        "/Record/ai-68-OLC1852389117"
+    ];
+
+    public const RULES = [
+        "test_case_id" => "02",
+        "desc" => [
+            [
+                "type" => "text",
+                "path" => ".getitbox-getit > h4",
+                "text" => "NICHT ANGEMELDET",
+            ],
+            [
+                "type" => "text",
+                "path" => "#get-it-button",
+                "text" => "LINKS ZUR RESSOURCE",
+            ],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" => "Weitere Informationen sehen Sie, wenn Sie angemeldet sind.",
+                "waitForClass" => "openUrlPrint"
+            ],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" => "Noch keinen Account?",
+            ],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" => "Jetzt registrieren",
+            ]
+        ]
+    ];
+
+    public function testGetItDefault02()
+    {
+        $this->runGetItTest(self::RECORDS, self::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit03DefaultTest.php b/module/finc/tests/selenium/tests/adlr/Getit03DefaultTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..2f2df900956f87a82dda38de459724d875763ddd
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit03DefaultTest.php
@@ -0,0 +1,52 @@
+<?php
+namespace Selenium\adlr;
+
+/**
+ * @group adlr
+ * @group adlr-getit-03
+ * @group adlr-getit-default
+ */
+class Getit03DefaultTest extends AdlrBase
+{
+    public const RECORDS = [
+        "/Record/51-9783864881091",
+        "/Record/51-9781443890199",
+        "/Record/51-9783631784259",
+    ];
+
+    public const RULES = [
+        "test_case_id" => "03",
+        "desc" => [
+            [
+                "type" => "text",
+                "path" => ".getitbox-getit > h4",
+                "text" => "NICHT ANGEMELDET",
+            ],
+            [
+                "type" => "text",
+                "path" => "#get-it-button",
+                "text" => "INFOS ZUR RESSOURCE",
+            ],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" => "Diese Neuerscheinung können Sie zur Leihe bestellen, wenn Sie angemeldet sind.",
+            ],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" => "Noch keinen Account?",
+            ],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" => "Jetzt registrieren",
+            ]
+        ]
+    ];
+
+    public function testGetItDefault03()
+    {
+        $this->runGetItTest(self::RECORDS, self::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit03ProfessorTest.php b/module/finc/tests/selenium/tests/adlr/Getit03ProfessorTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..f74cfc57b3911af3a29b88190d0ba65ce088997e
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit03ProfessorTest.php
@@ -0,0 +1,57 @@
+<?php
+namespace Selenium\adlr;
+
+/**
+ * @group adlr
+ * @group adlr-getit-03
+ * @group adlr-getit-professor
+ */
+class Getit03ProfessorTest extends AdlrLoginBase
+{
+    use ProfessorTrait;
+
+    public const RECORDS = [
+        "/Record/51-9783864881091",
+        "/Record/51-9781443890199",
+        "/Record/51-9783631784259",
+    ];
+
+    public const RULES = [
+        "test_case_id" => "03L",
+        "desc" => [
+            [
+                "type" => "text",
+                "path" => ".getitbox-getit > h4",
+                "text" => "GET IT",
+            ],
+            [
+                "type" => "text",
+                "path" => "#get-it-button",
+                "text" => "INFOS ZUR RESSOURCE",
+            ],
+            [
+                "type" => "text",
+                "path" => ".full-order",
+                "text" => "KOSTENLOS BESTELLEN",
+            ],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" =>
+                    "Bestellen Sie ein Leihexemplar dieser Neuerscheinung auf Kosten von adlr.link. Das Buch wird direkt an Sie geschickt.",
+            ],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" => "Verfügbarkeit:",
+            ],
+        ],
+    ];
+
+    public function testGetItProfessor03()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(self::RECORDS, self::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit03StudentTest.php b/module/finc/tests/selenium/tests/adlr/Getit03StudentTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..790395b527a800126ac1d8ebe7b73b76c22cefa9
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit03StudentTest.php
@@ -0,0 +1,18 @@
+<?php
+namespace Selenium\adlr;
+
+/**
+ * @group adlr-getit-03
+ * @group adlr-getit-student
+ */
+class Getit03StudentTest extends AdlrLoginBase
+{
+    use StudentTrait;
+
+    public function testGetItStudent03()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit03ProfessorTest::RECORDS, Getit03ProfessorTest::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit04DefaultTest.php b/module/finc/tests/selenium/tests/adlr/Getit04DefaultTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..cf2fa4454cbb525efc508d56f894a4e98ca2534d
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit04DefaultTest.php
@@ -0,0 +1,49 @@
+<?php
+namespace Selenium\adlr;
+
+/**
+ * @group adlr
+ * @group adlr-getit-04
+ * @group adlr-getit-default
+ */
+class Getit04DefaultTest extends AdlrBase
+{
+    public const RECORDS = [
+        "/Record/76-EBC5939400",
+        "/Record/76-EBC6915648",
+        "/Record/76-EBC6138849",
+    ];
+
+    public const RULES = [
+        "test_case_id" => "04",
+        "desc" => [
+            [
+                "type" => "text",
+                "path" => ".getitbox-getit > h4",
+                "text" => "NICHT ANGEMELDET",
+            ],
+            ["type" => "anti-exi", "path" => "#get-it-button"],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" =>
+                    "Sie müssen angemeldet sein, um Zugang zu diesem Titel zu erhalten.",
+            ],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" => "Noch keinen Account?",
+            ],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" => "Jetzt registrieren",
+            ],
+        ]
+    ];
+
+    public function testGetItDefault04()
+    {
+        $this->runGetItTest(self::RECORDS, self::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit04ProfessorTest.php b/module/finc/tests/selenium/tests/adlr/Getit04ProfessorTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..f4afe9a83a060c35013a75e8e315bea41fd51130
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit04ProfessorTest.php
@@ -0,0 +1,47 @@
+<?php
+namespace Selenium\adlr;
+
+/**
+ * @group adlr
+ * @group adlr-getit-04
+ * @group adlr-getit-professor
+ */
+class Getit04ProfessorTest extends AdlrLoginBase
+{
+    use ProfessorTrait;
+
+    public const RECORDS = [
+        "/Record/76-EBC5939400",
+        "/Record/76-EBC6915648",
+        "/Record/76-EBC6138849",
+    ];
+
+    public const RULES = [
+        "test_case_id" => "04L",
+        "desc" => [
+            [
+                "type" => "text",
+                "path" => ".getitbox-getit > h4",
+                "text" => "GET IT",
+            ],
+            [
+                "type" => "text",
+                "path" => "#get-it-button",
+                "text" => "LINKS ZUR RESSOURCE",
+            ],
+            [
+                "type" => "text",
+                "path" => ".getitbox-notices",
+                "text" =>
+                    "Dieses E-Book ist für Sie über eine adlr.link-Lizenz freigeschaltet.",
+            ],
+        ],
+    ];
+
+    public function testGetItProfessor04()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(self::RECORDS, self::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit04StudentTest.php b/module/finc/tests/selenium/tests/adlr/Getit04StudentTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..0585fd201a1e377b1190324b03eea866be0b6c9d
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit04StudentTest.php
@@ -0,0 +1,18 @@
+<?php
+namespace Selenium\adlr;
+
+/**
+ * @group adlr-getit-04
+ * @group adlr-getit-student
+ */
+class Getit04StudentTest extends AdlrLoginBase
+{
+    use StudentTrait;
+
+    public function testGetItStudent04()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit04ProfessorTest::RECORDS, Getit04ProfessorTest::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit05DefaultTest.php b/module/finc/tests/selenium/tests/adlr/Getit05DefaultTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..4a69655b647213c75fff4e869c3504f5ad699e42
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit05DefaultTest.php
@@ -0,0 +1,47 @@
+<?php
+namespace Selenium\adlr;
+
+/**
+ * @group adlr
+ * @group adlr-getit-05
+ * @group adlr-getit-default
+ */
+class Getit05DefaultTest extends AdlrBase
+{
+    public const RECORDS = [
+        "/Record/finc-78-39818",
+        "/Record/finc-78-18524",
+        "/Record/finc-78-19486",
+    ];
+
+    public const RULES = [
+        "test_case_id" => "05",
+        "desc" => [
+            [
+                "type" => "text",
+                "path" => ".getitbox-getit > h4",
+                "text" => "GET IT",
+            ],
+            [
+                "type" => "text",
+                "path" => "#get-it-button",
+                "text" => "INFOS ZUR RESSOURCE",
+            ],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" => "Dieser Titel ist in der IZI-Datenbank des Internationalen Zentralinstituts für das Jugend- und Bildungsfernsehen nachgewiesen.",
+            ],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" => "Zugang zum Volltext erhalten Sie nur bei einigen Titeln dieser Quelle über den obigen Link.",
+            ],
+        ]
+    ];
+
+    public function testGetItDefault05()
+    {
+        $this->runGetItTest(self::RECORDS, self::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit05ProfessorTest.php b/module/finc/tests/selenium/tests/adlr/Getit05ProfessorTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..5fdc9779ee5bdb7f2aa8497d2beb28d6a202e145
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit05ProfessorTest.php
@@ -0,0 +1,21 @@
+<?php
+namespace Selenium\adlr;
+
+use Lmc\Steward\Test\AbstractTestCase;
+
+/**
+ * @group adlr
+ * @group adlr-getit-05
+ * @group adlr-getit-professor
+ */
+class Getit05ProfessorTest extends AdlrLoginBase
+{
+    use ProfessorTrait;
+
+    public function testGetItProfessor05()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit05DefaultTest::RECORDS, Getit05DefaultTest::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit05StudentTest.php b/module/finc/tests/selenium/tests/adlr/Getit05StudentTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..ba117f509a44acafa48fb00fe1551fff4b8ac031
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit05StudentTest.php
@@ -0,0 +1,20 @@
+<?php
+namespace Selenium\adlr;
+
+use Lmc\Steward\Test\AbstractTestCase;
+
+/**
+ * @group adlr-getit-05
+ * @group adlr-getit-student
+ */
+class Getit05StudentTest extends AdlrLoginBase
+{
+    use StudentTrait;
+
+    public function testGetItStudent05()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit05DefaultTest::RECORDS, Getit05DefaultTest::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit06DefaultTest.php b/module/finc/tests/selenium/tests/adlr/Getit06DefaultTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..8705037ce7a2c917f09dfb92f850426ee051b387
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit06DefaultTest.php
@@ -0,0 +1,48 @@
+<?php
+namespace Selenium\adlr;
+
+/**
+ * @group adlr
+ * @group adlr-getit-06
+ * @group adlr-getit-default
+ */
+class Getit06DefaultTest extends AdlrBase
+{
+    public const RECORDS = [
+        "/Record/finc-103-b2FpOmNkbTE1NzU5LmNvbnRlbnRkbS5vY2xjLm9yZzpwMTU3NTljb2xsOS8xMTgwNA",
+        "/Record/finc-103-b2FpOmNkbTE1NzU5LmNvbnRlbnRkbS5vY2xjLm9yZzpwMTU3NTljb2xsNy8xMDg",
+        "/Record/finc-103-b2FpOmNkbTE1NzU5LmNvbnRlbnRkbS5vY2xjLm9yZzpwMTU3NTljb2xsOS8xMTkyNw",
+    ];
+
+    public const RULES = [
+        "test_case_id" => "06",
+        "desc" => [
+            [
+                "type" => "text",
+                "path" => ".getitbox-getit > h4",
+                "text" => "GET IT",
+            ],
+            [
+                "type" => "text",
+                "path" => "#get-it-button",
+                "text" => "LINKS ZUR RESSOURCE",
+            ],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" => "Diese Ressource ist frei verfügbar.",
+            ],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" =>
+                    "Dieser Titel ist im Bestand der Margaret Herrick Library, Academy of Motion Picture Arts and Sciences, und wird mit freundlicher Genehmigung hier angezeigt.",
+            ],
+        ]
+    ];
+
+    public function testGetItDefault06()
+    {
+        $this->runGetItTest(self::RECORDS, self::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit06ProfessorTest.php b/module/finc/tests/selenium/tests/adlr/Getit06ProfessorTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..60b80b6a3e2925b851529785a382280de9c8a048
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit06ProfessorTest.php
@@ -0,0 +1,24 @@
+<?php
+namespace Selenium\adlr;
+
+use Lmc\Steward\Test\AbstractTestCase;
+
+/**
+ * @group adlr
+ * @group adlr-getit-06
+ * @group adlr-getit-professor
+ */
+class Getit06ProfessorTest extends AdlrLoginBase
+{
+    use ProfessorTrait;
+
+    /**
+     * @group adlr
+     */
+    public function testGetItProfessor06()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit06DefaultTest::RECORDS, Getit06DefaultTest::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit06StudentTest.php b/module/finc/tests/selenium/tests/adlr/Getit06StudentTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..3d6bdfb563c65c1715af43ed868fa8c557bd4224
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit06StudentTest.php
@@ -0,0 +1,20 @@
+<?php
+namespace Selenium\adlr;
+
+use Lmc\Steward\Test\AbstractTestCase;
+
+/**
+ * @group adlr-getit-06
+ * @group adlr-getit-student
+ */
+class Getit06StudentTest extends AdlrLoginBase
+{
+    use StudentTrait;
+
+    public function testGetItStudent06()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit06DefaultTest::RECORDS, Getit06DefaultTest::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit07DefaultTest.php b/module/finc/tests/selenium/tests/adlr/Getit07DefaultTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..122e5531121f3da81f16195940e0398e98ebae54
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit07DefaultTest.php
@@ -0,0 +1,48 @@
+<?php
+namespace Selenium\adlr;
+
+/**
+ * @group adlr
+ * @group adlr-getit-07
+ * @group adlr-getit-default
+ */
+class Getit07DefaultTest extends AdlrBase
+{
+    public const RECORDS = [
+        "/Record/dswarm-126-ZnR1bml2a2Fuc2FzOm9haTprdXNjaG9sYXJ3b3Jrcy5rdS5lZHU6MTgwOC8zMTgwNg",
+        "/Record/dswarm-126-ZnR1bmlhYXJodXNwdWJsOm9haTpwdXJlLmF0aXJhLmRrOnB1YmxpY2F0aW9ucy8wYzQ4NTgzNi0zOWU3LTRmNjMtOGViMi0wYmZjMDE1ZjJkMmQ"
+    ];
+
+    public const RULES = [
+        "test_case_id" => "07",
+        "desc" => [
+            [
+                "type" => "text",
+                "path" => ".getitbox-getit > h4",
+                "text" => "GET IT",
+            ],
+            [
+                "type" => "text",
+                "path" => "#get-it-button",
+                "text" => "INFOS ZUR RESSOURCE",
+            ],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" =>
+                    "Dieser Titel stammt aus der Bielefeld Academic Search Engine.",
+            ],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" =>
+                    "Einige Dokumente aus dieser Quelle sind möglicherweise nicht als Volltext zugänglich.",
+            ],
+        ]
+    ];
+
+    public function testGetItDefault07()
+    {
+        $this->runGetItTest(self::RECORDS, self::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit07ProfessorTest.php b/module/finc/tests/selenium/tests/adlr/Getit07ProfessorTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..825a0cce51a461d5defe3af395f19ca9b1017113
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit07ProfessorTest.php
@@ -0,0 +1,21 @@
+<?php
+namespace Selenium\adlr;
+
+use Lmc\Steward\Test\AbstractTestCase;
+
+/**
+ * @group adlr
+ * @group adlr-getit-07
+ * @group adlr-getit-professor
+ */
+class Getit07ProfessorTest extends AdlrLoginBase
+{
+    use ProfessorTrait;
+
+    public function testGetItProfessor07()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit07DefaultTest::RECORDS, Getit07DefaultTest::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit07StudentTest.php b/module/finc/tests/selenium/tests/adlr/Getit07StudentTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..a32f05c11aa17d8c77368aa27237c775f18fa8e5
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit07StudentTest.php
@@ -0,0 +1,20 @@
+<?php
+namespace Selenium\adlr;
+
+use Lmc\Steward\Test\AbstractTestCase;
+
+/**
+ * @group adlr-getit-07
+ * @group adlr-getit-student
+ */
+class Getit07StudentTest extends AdlrLoginBase
+{
+    use StudentTrait;
+
+    public function testGetItStudent07()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit07DefaultTest::RECORDS, Getit07DefaultTest::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit08DefaultTest.php b/module/finc/tests/selenium/tests/adlr/Getit08DefaultTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..51190d5b050a7ba88c0091fb46d5158bf7d23fae
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit08DefaultTest.php
@@ -0,0 +1,48 @@
+<?php
+namespace Selenium\adlr;
+
+/**
+ * @group adlr
+ * @group adlr-getit-08
+ * @group adlr-getit-default
+ */
+class Getit08DefaultTest extends AdlrBase
+{
+    public const RECORDS = [
+        "/Record/finc-169-QVJEQVJEIEtsYXNzaVdpbGxpYW1zIMK3IEhhcnJ5IFBvdGVyIMK3IE5pYyBSYWluZSDCtyBXRFIwMDowNToxMDYxMTY0NjkzMDI1Nw",
+        "/Record/finc-169-WkRGS3VsdHVyemVpdE1pbG8gUmF1IMO8YmVyICJEYXMgTnMgTmV1ZSBFdmFuZ2VsaXVtIiAtMDA6MDU6NTkxMDMxNTk5NDk5MjAw"
+    ];
+
+    public const RULES = [
+        "test_case_id" => "08",
+        "desc" => [
+            [
+                "type" => "text",
+                "path" => ".getitbox-getit > h4",
+                "text" => "GET IT",
+            ],
+            [
+                "type" => "text",
+                "path" => "#get-it-button",
+                "text" => "LINKS ZUR RESSOURCE",
+            ],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" =>
+                    "Aus Deutschland freier Zugang zu oder Download von Mediathek-Videos möglich.",
+            ],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" =>
+                    "Der Zugang kann aus rechtlichen Gründen nach Ablauf eines bestimmten Zeitraums oder aus anderen Ländern gesperrt sein.",
+            ],
+        ],
+    ];
+
+    public function testGetItDefault08()
+    {
+        $this->runGetItTest(self::RECORDS, self::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit08ProfessorTest.php b/module/finc/tests/selenium/tests/adlr/Getit08ProfessorTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..63472008367896c8adc810375f9ee384ced17edc
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit08ProfessorTest.php
@@ -0,0 +1,21 @@
+<?php
+namespace Selenium\adlr;
+
+use Lmc\Steward\Test\AbstractTestCase;
+
+/**
+ * @group adlr
+ * @group adlr-getit-08
+ * @group adlr-getit-professor
+ */
+class Getit08ProfessorTest extends AdlrLoginBase
+{
+    use ProfessorTrait;
+
+    public function testGetItProfessor08()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit08DefaultTest::RECORDS, Getit08DefaultTest::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit08StudentTest.php b/module/finc/tests/selenium/tests/adlr/Getit08StudentTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..6ca4a330a2e18de00be993b2a2e3bd9dc2e73f74
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit08StudentTest.php
@@ -0,0 +1,20 @@
+<?php
+namespace Selenium\adlr;
+
+use Lmc\Steward\Test\AbstractTestCase;
+
+/**
+ * @group adlr-getit-08
+ * @group adlr-getit-student
+ */
+class Getit08StudentTest extends AdlrLoginBase
+{
+    use StudentTrait;
+
+    public function testGetItStudent08()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit08DefaultTest::RECORDS, Getit08DefaultTest::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit09DefaultTest.php b/module/finc/tests/selenium/tests/adlr/Getit09DefaultTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..1a6a6d866c43725b42bf636df86501e710448492
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit09DefaultTest.php
@@ -0,0 +1,41 @@
+<?php
+namespace Selenium\adlr;
+
+/**
+ * @group adlr
+ * @group adlr-getit-09
+ * @group adlr-getit-default
+ */
+class Getit09DefaultTest extends AdlrBase
+{
+    public const RECORDS = [
+        "/Record/0-1049705947",
+        "/Record/0-1042440905"
+    ];
+
+    public const RULES = [
+        "test_case_id" => "09",
+        "desc" => [
+            [
+                "type" => "text",
+                "path" => ".getitbox-getit > h4",
+                "text" => "GET IT",
+            ],
+            [
+                "type" => "text",
+                "path" => "#get-it-button",
+                "text" => "LINKS ZUR RESSOURCE",
+            ],
+            [
+                "type" => "text",
+                "path" => ".getitbox-notices",
+                "text" => "Diese Ressource ist frei verfügbar.",
+            ]
+        ]
+    ];
+
+    public function testGetItDefault09()
+    {
+        $this->runGetItTest(self::RECORDS, self::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit09ProfessorTest.php b/module/finc/tests/selenium/tests/adlr/Getit09ProfessorTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..203acde53c7cd169c47cbc6630ab4d37dcac7c25
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit09ProfessorTest.php
@@ -0,0 +1,21 @@
+<?php
+namespace Selenium\adlr;
+
+use Lmc\Steward\Test\AbstractTestCase;
+
+/**
+ * @group adlr
+ * @group adlr-getit-09
+ * @group adlr-getit-professor
+ */
+class Getit09ProfessorTest extends AdlrLoginBase
+{
+    use ProfessorTrait;
+
+    public function testGetItProfessor09()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit09DefaultTest::RECORDS, Getit09DefaultTest::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit09StudentTest.php b/module/finc/tests/selenium/tests/adlr/Getit09StudentTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..7c718d10f8b87e658b92979d76d5788780bb2d91
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit09StudentTest.php
@@ -0,0 +1,20 @@
+<?php
+namespace Selenium\adlr;
+
+use Lmc\Steward\Test\AbstractTestCase;
+
+/**
+ * @group adlr-getit-09
+ * @group adlr-getit-student
+ */
+class Getit09StudentTest extends AdlrLoginBase
+{
+    use StudentTrait;
+
+    public function testGetItStudent09()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit09DefaultTest::RECORDS, Getit09DefaultTest::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit10DefaultTest.php b/module/finc/tests/selenium/tests/adlr/Getit10DefaultTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..a30d4b548c59ca71aaf32b0cecfd8f5649fe1f61
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit10DefaultTest.php
@@ -0,0 +1,48 @@
+<?php
+namespace Selenium\adlr;
+
+/**
+ * @group adlr
+ * @group adlr-getit-10
+ * @group adlr-getit-default
+ */
+class Getit10DefaultTest extends AdlrBase
+{
+    public const RECORDS = [
+        "/Record/0-1039949797",
+        "/Record/0-1656224038"
+    ];
+
+    public const RULES = [
+        "test_case_id" => "10",
+        "desc" => [
+            [
+                "type" => "text",
+                "path" => ".getitbox-getit > h4",
+                "text" => "NICHT ANGEMELDET",
+            ],
+            ["type" => "anti-exi", "path" => "#get-it-button"],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" =>
+                    "Sie müssen angemeldet sein, um Zugang zu diesem Titel zu erhalten.",
+            ],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" => "Noch keinen Account?",
+            ],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" => "Jetzt registrieren",
+            ],
+        ]
+    ];
+
+    public function testGetItDefault10()
+    {
+        $this->runGetItTest(self::RECORDS, self::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit10ProfessorTest.php b/module/finc/tests/selenium/tests/adlr/Getit10ProfessorTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..236b847a72803bdc20970cfa9931af76e7a4ba87
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit10ProfessorTest.php
@@ -0,0 +1,43 @@
+<?php
+namespace Selenium\adlr;
+
+use Lmc\Steward\Test\AbstractTestCase;
+
+/**
+ * @group adlr
+ * @group adlr-getit-10
+ * @group adlr-getit-professor
+ */
+class Getit10ProfessorTest extends AdlrLoginBase
+{
+    use ProfessorTrait;
+
+    public const RULES = [
+        "test_case_id" => "10",
+        "desc" => [
+            [
+                "type" => "text",
+                "path" => ".getitbox-getit > h4",
+                "text" => "GET IT",
+            ],
+            [
+                "type" => "text",
+                "path" => "#get-it-button",
+                "text" => "LINKS ZUR RESSOURCE",
+            ],
+            [
+                "type" => "text",
+                "path" => ".getitbox-notices",
+                "text" =>
+                    "Dieses E-Book ist für Sie über eine adlr.link-Lizenz freigeschaltet.",
+            ],
+        ]
+    ];
+
+    public function testGetItProfessor10()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit10DefaultTest::RECORDS, self::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit10StudentTest.php b/module/finc/tests/selenium/tests/adlr/Getit10StudentTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..d03afd49c3b2a3ae6b46d491f6b25f31dacf75bd
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit10StudentTest.php
@@ -0,0 +1,20 @@
+<?php
+namespace Selenium\adlr;
+
+use Lmc\Steward\Test\AbstractTestCase;
+
+/**
+ * @group adlr-getit-10
+ * @group adlr-getit-student
+ */
+class Getit10StudentTest extends AdlrLoginBase
+{
+    use StudentTrait;
+
+    public function testGetItStudent10()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit10DefaultTest::RECORDS, Getit10ProfessorTest::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit11DefaultTest.php b/module/finc/tests/selenium/tests/adlr/Getit11DefaultTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..e4a677d4af46caddebdc8ba20e0fca3105b6b991
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit11DefaultTest.php
@@ -0,0 +1,49 @@
+<?php
+namespace Selenium\adlr;
+
+/**
+ * @group adlr
+ * @group adlr-getit-11
+ * @group adlr-getit-default
+ */
+class Getit11DefaultTest extends AdlrBase
+{
+    public const RECORDS = [
+        "/Record/127-HF000229647", // ok, if logged in
+        "/Record/finc-148-000766970", // ok, if logged in
+        "/Record/finc-109-KM000085902", // error: mehrbändiges Werk
+        "/Record/0-1678979260", // error: Links zur Ressource
+        "/Record/0-1668331306", // error: derzeit leider keine Infos
+        "/Record/0-1667284800", // error: derzeit leider keine Infos
+        "/Record/finc-117-BV040630682", // error: mehrbändiges Werk
+        "/Record/finc-142-08034201", // error: mehrbändiges Werk
+        "/Record/finc-119-321520181" // error: mehrbändiges Werk
+    ];
+
+    public const RULES = [
+        "test_case_id" => "11",
+        "desc" => [
+            [
+                "type" => "text",
+                "path" => ".getitbox-getit > h4",
+                "text" => "GET IT",
+            ],
+            [
+                "type" => "text",
+                "path" => "#get-it-button",
+                "text" => "INFOS ZUR RESSOURCE",
+            ],
+            [
+                "type" => "text",
+                "path" => ".getitbox-notices",
+                "text" =>
+                    'Dieser Titel ist ein mehrbändiges Werk. Einzeltitel sind unter "Zugehörige Bände" aufgeführt.',
+            ],
+        ]
+    ];
+
+    public function testGetItDefault11()
+    {
+        $this->runGetItTest(self::RECORDS, self::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit11ProfessorTest.php b/module/finc/tests/selenium/tests/adlr/Getit11ProfessorTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..6041ec068385cfe1e3576e6bce32912fc02ce800
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit11ProfessorTest.php
@@ -0,0 +1,21 @@
+<?php
+namespace Selenium\adlr;
+
+use Lmc\Steward\Test\AbstractTestCase;
+
+/**
+ * @group adlr
+ * @group adlr-getit-11
+ * @group adlr-getit-professor
+ */
+class Getit11ProfessorTest extends AdlrLoginBase
+{
+    use ProfessorTrait;
+
+    public function testGetItProfessor11()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit11DefaultTest::RECORDS, Getit11DefaultTest::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit11StudentTest.php b/module/finc/tests/selenium/tests/adlr/Getit11StudentTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..9e33fcba65150f15f23b629b3d6ae02687c8da21
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit11StudentTest.php
@@ -0,0 +1,20 @@
+<?php
+namespace Selenium\adlr;
+
+use Lmc\Steward\Test\AbstractTestCase;
+
+/**
+ * @group adlr-getit-11
+ * @group adlr-getit-student
+ */
+class Getit11StudentTest extends AdlrLoginBase
+{
+    use StudentTrait;
+
+    public function testGetItStudent11()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit11DefaultTest::RECORDS, Getit11DefaultTest::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit12DefaultTest.php b/module/finc/tests/selenium/tests/adlr/Getit12DefaultTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..11d301ce5ae5a254e78d11584bc9fc3e03fa66fd
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit12DefaultTest.php
@@ -0,0 +1,57 @@
+<?php
+namespace Selenium\adlr;
+
+/**
+ * @group adlr
+ * @group adlr-getit-12
+ * @group adlr-getit-default
+ */
+class Getit12DefaultTest extends AdlrBase
+{
+    public const RECORDS = [
+        "/Record/0-1603202374",
+        "/Record/0-1067543112",
+        "/Record/0-1027717349",
+    ];
+
+    public const RULES = [
+        "test_case_id" => "12",
+        "desc" => [
+            [
+                "type" => "text",
+                "path" => ".getitbox-getit > h4",
+                "text" => "NICHT ANGEMELDET",
+            ],
+            [
+                "type" => "anti-exi",
+                "path" => ".full-order",
+                "text" => "KOSTENLOS BESTELLEN",
+            ],
+            [
+                "type" => "anti-exi",
+                "path" => ".part-order",
+                "text" => "TEILKOPIE BESORGEN",
+            ],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" => "Weitere Informationen sehen Sie, wenn Sie angemeldet sind.",
+            ],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" => "Noch keinen Account?",
+            ],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" => "Jetzt registrieren",
+            ],
+        ]
+    ];
+
+    public function testGetItDefault12()
+    {
+        $this->runGetItTest(self::RECORDS, self::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit12ProfessorTest.php b/module/finc/tests/selenium/tests/adlr/Getit12ProfessorTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..774780f357469624091884817e5f4eb32edc02bf
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit12ProfessorTest.php
@@ -0,0 +1,49 @@
+<?php
+namespace Selenium\adlr;
+
+use Lmc\Steward\Test\AbstractTestCase;
+
+/**
+ * @group adlr
+ * @group adlr-getit-12
+ * @group adlr-getit-professor
+ */
+class Getit12ProfessorTest extends AdlrLoginBase
+{
+    use ProfessorTrait;
+
+    public const RULES = [
+        "test_case_id" => "12",
+        "desc" => [
+            [
+                "type" => "text",
+                "path" => ".getitbox-getit > h4",
+                "text" => "GET IT",
+            ],
+            [
+                "type" => "text",
+                "path" => ".full-order",
+                "text" => "KOSTENLOS BESTELLEN",
+            ],
+            [
+                "type" => "text",
+                "path" => ".part-order",
+                "text" => "TEILKOPIE BESORGEN",
+            ],
+            /* should there be infos?
+                "type" => "text",
+                "path" => "#get-it-button",
+                "text" => "INFOS ZUR RESSOURCE",
+                "waitForId" => "get-it-button"
+            ],
+            */
+        ]
+    ];
+
+    public function testGetItProfessor12()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit12DefaultTest::RECORDS, self::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit12StudentTest.php b/module/finc/tests/selenium/tests/adlr/Getit12StudentTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..42c4a30712294a2ae0edfa795e7f0700992a6211
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit12StudentTest.php
@@ -0,0 +1,20 @@
+<?php
+namespace Selenium\adlr;
+
+use Lmc\Steward\Test\AbstractTestCase;
+
+/**
+ * @group adlr-getit-12
+ * @group adlr-getit-student
+ */
+class Getit12StudentTest extends AdlrLoginBase
+{
+    use StudentTrait;
+
+    public function testGetItStudent12()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit12DefaultTest::RECORDS, Getit12ProfessorTest::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit13DefaultTest.php b/module/finc/tests/selenium/tests/adlr/Getit13DefaultTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..8b1970813dd6a826331e713a1e888fb39a97ac09
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit13DefaultTest.php
@@ -0,0 +1,63 @@
+<?php
+namespace Selenium\adlr;
+
+/**
+ * @group adlr
+ * @group adlr-getit-13
+ * @group adlr-getit-default
+ */
+class Getit13DefaultTest extends AdlrBase
+{
+    public const RECORDS = [
+        "/Record/finc-109-KM000089451",
+        "/Record/finc-117-BV043403677",
+        "/Record/finc-119-365350478",
+        "/Record/127-HF000221927",
+        "/Record/finc-148-000759109",
+        /*  https://projekte.ub.uni-leipzig.de/issues/22013#note-26 */
+        /*"/Record/finc-142-11205879",*/
+        /*"/Record/finc-151-000055718",*/
+        "/Record/0-1667395157" // error: "GET IT" instead of "Nicht angemeldet"
+    ];
+
+    public const RULES = [
+        "test_case_id" => "13",
+        "desc" => [
+            [
+                "type" => "text",
+                "path" => ".getitbox-getit > h4",
+                "text" => "NICHT ANGEMELDET",
+            ],
+            [
+                "type" => "anti-exi",
+                "path" => ".part-order",
+                "text" => "TEILKOPIE BESORGEN",
+            ],
+            [
+                "type" => "text",
+                "path" => "#get-it-button",
+                "text" => "INFOS ZUR RESSOURCE",
+            ],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" => "Weitere Informationen sehen Sie, wenn Sie angemeldet sind.",
+            ],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" => "Noch keinen Account?",
+            ],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" => "Jetzt registrieren",
+            ],
+        ]
+    ];
+
+    public function testGetItDefault13()
+    {
+        $this->runGetItTest(self::RECORDS, self::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit13ProfessorTest.php b/module/finc/tests/selenium/tests/adlr/Getit13ProfessorTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..5f81fedb964b7ee1d6abf5b1fc1c2ed0dca0bcc7
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit13ProfessorTest.php
@@ -0,0 +1,45 @@
+<?php
+namespace Selenium\adlr;
+
+use Lmc\Steward\Test\AbstractTestCase;
+
+/**
+ * @group adlr
+ * @group adlr-getit-13
+ * @group adlr-getit-professor
+ */
+class Getit13ProfessorTest extends AdlrLoginBase
+{
+    use ProfessorTrait;
+
+    public const RULES = [
+        "test_case_id" => "13L",
+        "desc" => [
+            [
+                "type" => "text",
+                "path" => ".getitbox-getit > h4",
+                "text" => "GET IT",
+            ],
+            [
+                "type" => "text",
+                "path" => ".part-order",
+                "text" => "TEILKOPIE BESORGEN",
+            ],
+            /* see https://projekte.ub.uni-leipzig.de/issues/22013#note-26 */
+            /*
+            [
+                "type" => "text",
+                "path" => "#get-it-button",
+                "text" => "INFOS ZUR RESSOURCE",
+            ],
+            */
+        ]
+    ];
+
+    public function testGetItProfessor13()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit13DefaultTest::RECORDS, self::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit13StudentTest.php b/module/finc/tests/selenium/tests/adlr/Getit13StudentTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..de34801c87ceaf61d6f46a2c745e17c2c3704eba
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit13StudentTest.php
@@ -0,0 +1,20 @@
+<?php
+namespace Selenium\adlr;
+
+use Lmc\Steward\Test\AbstractTestCase;
+
+/**
+ * @group adlr-getit-13
+ * @group adlr-getit-student
+ */
+class Getit13StudentTest extends AdlrLoginBase
+{
+    use StudentTrait;
+
+    public function testGetItStudent13()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit13DefaultTest::RECORDS, Getit13ProfessorTest::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit14DefaultTest.php b/module/finc/tests/selenium/tests/adlr/Getit14DefaultTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..6beb75904ab0e0403e2bac0bb2398d22c682f122
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit14DefaultTest.php
@@ -0,0 +1,63 @@
+<?php
+namespace Selenium\adlr;
+
+/**
+ * @group adlr
+ * @group adlr-getit-14
+ * @group adlr-getit-default
+ */
+class Getit14DefaultTest extends AdlrBase
+{
+    public const RECORDS = [
+        "/Record/0-1670477886",
+        "/Record/0-1041254903",
+        "/Record/finc-109-KM000088077",
+        "/Record/finc-119-369836529",
+        "/Record/finc-119-321710606",
+        "/Record/finc-119-310607205",
+        "/Record/127-HF000223270",
+        "/Record/finc-142-08035064",
+        "/Record/finc-151-000055678",
+        "/Record/finc-148-000632095", // error: mehrbändiges Werk statt 'weitere informationen sehen sie..'
+        "/Record/finc-117-BV045542005", // error: 'GET IT' statt 'NICHT ANGEMELDET'
+        "/Record/finc-119-36435657X", // error: mehrbändiges Werk statt 'weitere informationen sehen sie..'
+    ];
+
+    public const RULES = [
+        "test_case_id" => "14",
+        "desc" => [
+            [
+                "type" => "text",
+                "path" => ".getitbox-getit > h4",
+                "text" => "NICHT ANGEMELDET",
+            ],
+            /* https://projekte.ub.uni-leipzig.de/issues/22013#note-26
+            [
+                "type" => "text",
+                "path" => "#get-it-button",
+                "text" => "INFOS ZUR RESSOURCE",
+            ],*/
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" =>
+                    "Weitere Informationen sehen Sie, wenn Sie angemeldet sind.",
+            ],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" => "Noch keinen Account?",
+            ],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" => "Jetzt registrieren",
+            ]
+        ]
+    ];
+
+    public function testGetItDefault14()
+    {
+        $this->runGetItTest(self::RECORDS, self::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit14ProfessorTest.php b/module/finc/tests/selenium/tests/adlr/Getit14ProfessorTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..53667dc1e4880f1ead78695101160066f855d1cb
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit14ProfessorTest.php
@@ -0,0 +1,44 @@
+<?php
+namespace Selenium\adlr;
+
+use Lmc\Steward\Test\AbstractTestCase;
+
+/**
+ * @group adlr
+ * @group adlr-getit-14
+ * @group adlr-getit-professor
+ */
+class Getit14ProfessorTest extends AdlrLoginBase
+{
+    use ProfessorTrait;
+
+    public const RULES = [
+        "test_case_id" => "14L",
+        "desc" => [
+            [
+                "type" => "text",
+                "path" => ".getitbox-getit > h4",
+                "text" => "GET IT",
+            ],
+            // https://projekte.ub.uni-leipzig.de/issues/22013#note-26
+/*            [
+                "type" => "text",
+                "path" => "#get-it-button",
+                "text" => "INFOS ZUR RESSOURCE",
+            ],*/
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" =>
+                    "Einige Medientypen (wie z. B. Manuskripte, Schallplatten, CDs, Videos) können von der Fernleihe ausgeschlossen sein.",
+            ],
+        ]
+    ];
+
+    public function testGetItProfessor14()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit14DefaultTest::RECORDS, self::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit14StudentTest.php b/module/finc/tests/selenium/tests/adlr/Getit14StudentTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..537da44746c4119730761bf54b6a19ef5fc08714
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit14StudentTest.php
@@ -0,0 +1,20 @@
+<?php
+namespace Selenium\adlr;
+
+use Lmc\Steward\Test\AbstractTestCase;
+
+/**
+ * @group adlr-getit-14
+ * @group adlr-getit-student
+ */
+class Getit14StudentTest extends AdlrLoginBase
+{
+    use StudentTrait;
+
+    public function testGetItStudent14()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit14DefaultTest::RECORDS, Getit14ProfessorTest::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit15DefaultTest.php b/module/finc/tests/selenium/tests/adlr/Getit15DefaultTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..3f80918e20a1a0449e25c58d09556eda2f091348
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit15DefaultTest.php
@@ -0,0 +1,58 @@
+<?php
+namespace Selenium\adlr;
+
+/**
+ * @group adlr
+ * @group adlr-getit-15
+ * @group adlr-getit-default
+ */
+class Getit15DefaultTest extends AdlrBase
+{
+    public const RECORDS = [
+        "/Record/0-1649918879",
+        "/Record/0-1668116529",
+        "/Record/finc-119-326140743",
+        "/Record/finc-119-320535185",
+        "/Record/finc-119-218381344",
+        "/Record/127-HF000220674",
+        "/Record/127-HF000224330",
+        "/Record/finc-142-10903814",
+        "/Record/finc-142-10891532",
+        "/Record/finc-151-000046616",
+        "/Record/finc-117-BV022883157",
+    ];
+
+    public const RULES = [
+        "test_case_id" => "15",
+        "desc" => [
+            [
+                "type" => "text",
+                "path" => ".getitbox-getit > h4",
+                "text" => "GET IT",
+            ],
+            //  https://projekte.ub.uni-leipzig.de/issues/22013#note-26
+/*            [
+                "type" => "text",
+                "path" => "#get-it-button",
+                "text" => "INFOS ZUR RESSOURCE",
+            ],*/
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" => "Für diesen Titel können wir derzeit leider keine weiteren Informationen zur Verfügbarkeit bereitstellen.",
+                "wait" => "getitbox-notices"
+            ],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" => "Ob der Titel per Fernleihe bestellbar ist, kann Ihnen Ihre Heimatbibliothek mitteilen.",
+                "wait" => "getitbox-notices"
+            ],
+        ]
+    ];
+
+    public function testGetItDefault15()
+    {
+        $this->runGetItTest(self::RECORDS, self::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit15ProfessorTest.php b/module/finc/tests/selenium/tests/adlr/Getit15ProfessorTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..ef1c12e40baf4c38e152eac4efed92b1fb1920ea
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit15ProfessorTest.php
@@ -0,0 +1,21 @@
+<?php
+namespace Selenium\adlr;
+
+use Lmc\Steward\Test\AbstractTestCase;
+
+/**
+ * @group adlr
+ * @group adlr-getit-15
+ * @group adlr-getit-professor
+ */
+class Getit15ProfessorTest extends AdlrLoginBase
+{
+    use ProfessorTrait;
+
+    public function testGetItProfessor15()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit15DefaultTest::RECORDS, Getit15DefaultTest::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit15StudentTest.php b/module/finc/tests/selenium/tests/adlr/Getit15StudentTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..85d7cdfc6cba9b587f48be572685609b99973e23
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit15StudentTest.php
@@ -0,0 +1,20 @@
+<?php
+namespace Selenium\adlr;
+
+use Lmc\Steward\Test\AbstractTestCase;
+
+/**
+ * @group adlr-getit-15
+ * @group adlr-getit-student
+ */
+class Getit15StudentTest extends AdlrLoginBase
+{
+    use StudentTrait;
+
+    public function testGetItStudent15()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit15DefaultTest::RECORDS, Getit15DefaultTest::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit16DefaultTest.php b/module/finc/tests/selenium/tests/adlr/Getit16DefaultTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..cf5f2877909e483396c73335d43894398619df61
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit16DefaultTest.php
@@ -0,0 +1,47 @@
+<?php
+namespace Selenium\adlr;
+
+/**
+ * @group adlr
+ * @group adlr-getit-16
+ * @group adlr-getit-default
+ */
+class Getit16DefaultTest extends AdlrBase
+{
+    public const RECORDS = [
+        "/Record/0-1678956775",
+        "/Record/0-1678647268",
+        "/Record/0-1678675431",
+        "/Record/finc-117-BV045203253",
+        "/Record/finc-117-BV044707116",
+        "/Record/finc-119-339980966",
+        "/Record/finc-119-356913473",
+        "/Record/finc-119-22918670X",
+    ];
+
+    public const RULES = [
+        "test_case_id" => "16",
+        "desc" => [
+            [
+                "type" => "text",
+                "path" => ".getitbox-getit > h4",
+                "text" => "GET IT",
+            ],
+            [
+                "type" => "text",
+                "path" => "#get-it-button",
+                "text" => "LINKS ZUR RESSOURCE",
+            ],
+            [
+                "type" => "text",
+                "path" => ".getitbox-notices",
+                "text" => "Diese Ressource ist frei verfügbar.",
+            ],
+        ]
+    ];
+
+    public function testGetItDefault16()
+    {
+        $this->runGetItTest(self::RECORDS, self::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit16ProfessorTest.php b/module/finc/tests/selenium/tests/adlr/Getit16ProfessorTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..721e8759f53c5677b3b4f4d1e254cd2e75a96956
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit16ProfessorTest.php
@@ -0,0 +1,21 @@
+<?php
+namespace Selenium\adlr;
+
+use Lmc\Steward\Test\AbstractTestCase;
+
+/**
+ * @group adlr
+ * @group adlr-getit-16
+ * @group adlr-getit-professor
+ */
+class Getit16ProfessorTest extends AdlrLoginBase
+{
+    use ProfessorTrait;
+
+    public function testGetItProfessor16()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit16DefaultTest::RECORDS, Getit16DefaultTest::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit16StudentTest.php b/module/finc/tests/selenium/tests/adlr/Getit16StudentTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..8d74356e6b1ac064ef61d64b1becb49dcd089f76
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit16StudentTest.php
@@ -0,0 +1,20 @@
+<?php
+namespace Selenium\adlr;
+
+use Lmc\Steward\Test\AbstractTestCase;
+
+/**
+ * @group adlr-getit-16
+ * @group adlr-getit-student
+ */
+class Getit16StudentTest extends AdlrLoginBase
+{
+    use StudentTrait;
+
+    public function testGetItStudent16()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit16DefaultTest::RECORDS, Getit16DefaultTest::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit17DefaultTest.php b/module/finc/tests/selenium/tests/adlr/Getit17DefaultTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..e6e6e97923e815fdf4628bf36ed55c992b8bc722
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit17DefaultTest.php
@@ -0,0 +1,54 @@
+<?php
+namespace Selenium\adlr;
+
+/**
+ * @group adlr
+ * @group adlr-getit-17
+ * @group adlr-getit-default
+ */
+class Getit17DefaultTest extends AdlrBase
+{
+    public const RECORDS = [
+        "/Record/0-1679317865",
+        "/Record/0-1678682802",
+        "/Record/finc-117-BV044276094",
+        "/Record/finc-117-BV045304712",
+        "/Record/finc-119-371587344",
+        "/Record/finc-119-377835137",
+        "/Record/127-HF000224597",
+        "/Record/127-HF000219912",
+    ];
+
+    public const RULES = [
+        "test_case_id" => "17",
+        "desc" => [
+            [
+                "type" => "text",
+                "path" => ".getitbox-getit > h4",
+                "text" => "GET IT",
+            ],
+            [
+                "type" => "text",
+                "path" => "#get-it-button",
+                "text" => "LINKS ZUR RESSOURCE",
+            ],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" =>
+                    "Dieses E-Book ist nur mit einer Lizenz Ihrer Heimatbibliothek nutzbar. Wenn es als bei Ihrer Bibliothek vorhanden angezeigt wird, dann sollte der direkte Zugang über den obigen Link möglich sein.",
+            ],
+            [
+                "type" => "contains",
+                "path" => ".getitbox-notices",
+                "text" =>
+                    "Teilkopien sind bei E-Books nicht möglich. Wenn Sie eine Teilkopie benötigen, suchen Sie bitte in unserem Portal nach der Printausgabe dieses Werkes.",
+            ],
+        ]
+    ];
+
+    public function testGetItDefault17()
+    {
+        $this->runGetItTest(self::RECORDS, self::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit17ProfessorTest.php b/module/finc/tests/selenium/tests/adlr/Getit17ProfessorTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..8a0166bc83949107ad6f6fcd1812f72e3a193aac
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit17ProfessorTest.php
@@ -0,0 +1,21 @@
+<?php
+namespace Selenium\adlr;
+
+use Lmc\Steward\Test\AbstractTestCase;
+
+/**
+ * @group adlr
+ * @group adlr-getit-17
+ * @group adlr-getit-professor
+ */
+class Getit17ProfessorTest extends AdlrLoginBase
+{
+    use ProfessorTrait;
+
+    public function testGetItProfessor17()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit17DefaultTest::RECORDS, Getit17DefaultTest::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit17StudentTest.php b/module/finc/tests/selenium/tests/adlr/Getit17StudentTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..14af504527ce9bfa60a72d0bff62b500d845e899
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit17StudentTest.php
@@ -0,0 +1,20 @@
+<?php
+namespace Selenium\adlr;
+
+use Lmc\Steward\Test\AbstractTestCase;
+
+/**
+ * @group adlr-getit-17
+ * @group adlr-getit-student
+ */
+class Getit17StudentTest extends AdlrLoginBase
+{
+    use StudentTrait;
+
+    public function testGetItStudent17()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit17DefaultTest::RECORDS, Getit17DefaultTest::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit18DefaultTest.php b/module/finc/tests/selenium/tests/adlr/Getit18DefaultTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..3e615e1946b3044a426d9e1355ed3981d89e7814
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit18DefaultTest.php
@@ -0,0 +1,48 @@
+<?php
+namespace Selenium\adlr;
+
+/**
+ * @group adlr
+ * @group adlr-getit-18
+ * @group adlr-getit-default
+ */
+class Getit18DefaultTest extends AdlrBase
+{
+    public const RECORDS = [
+        "/Record/0-1666903302",
+        "/Record/0-1588294307",
+        "/Record/0-1040676065",
+        "/Record/0-1667282492",
+        "/Record/0-1667362062",
+        "/Record/finc-117-BV022365028",
+        "/Record/finc-119-334239729",
+        "/Record/127-HF000224884",
+        "/Record/127-HF000224896",
+    ];
+
+    public const RULES = [
+        "test_case_id" => "18",
+        "desc" => [
+            [
+                "type" => "text",
+                "path" => ".getitbox-getit > h4",
+                "text" => "GET IT",
+            ],
+/*            [
+                "type" => "text",
+                "path" => "#get-it-button",
+                "text" => "LINKS ZUR RESSOURCE",
+            ],*/
+            [
+                "type" => "text",
+                "path" => ".getitbox-notices",
+                "text" => "Online-Ressourcen können Lizenzen erfordern oder kostenpflichtig sein.",
+            ],
+        ]
+    ];
+
+    public function testGetItDefault18()
+    {
+        $this->runGetItTest(self::RECORDS, self::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit18ProfessorTest.php b/module/finc/tests/selenium/tests/adlr/Getit18ProfessorTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..2273c31646014355985cf832b5104f4ed39499ae
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit18ProfessorTest.php
@@ -0,0 +1,21 @@
+<?php
+namespace Selenium\adlr;
+
+use Lmc\Steward\Test\AbstractTestCase;
+
+/**
+ * @group adlr
+ * @group adlr-getit-18
+ * @group adlr-getit-professor
+ */
+class Getit18ProfessorTest extends AdlrLoginBase
+{
+    use ProfessorTrait;
+
+    public function testGetItProfessor18()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit18DefaultTest::RECORDS, Getit18DefaultTest::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit18StudentTest.php b/module/finc/tests/selenium/tests/adlr/Getit18StudentTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..3391a54b8fb571828ae48d41d6ef07721c91f69a
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit18StudentTest.php
@@ -0,0 +1,20 @@
+<?php
+namespace Selenium\adlr;
+
+use Lmc\Steward\Test\AbstractTestCase;
+
+/**
+ * @group adlr-getit-18
+ * @group adlr-getit-student
+ */
+class Getit18StudentTest extends AdlrLoginBase
+{
+    use StudentTrait;
+
+    public function testGetItStudent18()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit18DefaultTest::RECORDS, Getit18DefaultTest::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit19DefaultTest.php b/module/finc/tests/selenium/tests/adlr/Getit19DefaultTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..78f549ee0c514753dce48c27e41d2ea02f99cb5c
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit19DefaultTest.php
@@ -0,0 +1,41 @@
+<?php
+namespace Selenium\adlr;
+
+/**
+ * @group adlr
+ * @group adlr-getit-19
+ * @group adlr-getit-default
+ */
+class Getit19DefaultTest extends AdlrBase
+{
+    public const RECORDS = [
+        "/Record/0-478507879"
+    ];
+
+    public const RULES = [
+        "test_case_id" => "19",
+        "desc" => [
+            [
+                "type" => "text",
+                "path" => ".getitbox-getit > h4",
+                "text" => "GET IT",
+            ],
+            [
+                "type" => "text",
+                "path" => "#get-it-button",
+                "text" => "LINKS ZUR RESSOURCE",
+            ],
+            [
+                "type" => "text",
+                "path" => ".getitbox-notices",
+                "text" =>
+                    "Online-Ressourcen können Lizenzen erfordern oder kostenpflichtig sein.",
+            ],
+        ]
+    ];
+
+    public function testGetItDefault19()
+    {
+        $this->runGetItTest(self::RECORDS, self::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit19ProfessorTest.php b/module/finc/tests/selenium/tests/adlr/Getit19ProfessorTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..95b447e8875f0234d8d0725b5ac49dc4e11dba01
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit19ProfessorTest.php
@@ -0,0 +1,21 @@
+<?php
+namespace Selenium\adlr;
+
+use Lmc\Steward\Test\AbstractTestCase;
+
+/**
+ * @group adlr
+ * @group adlr-getit-19
+ * @group adlr-getit-professor
+ */
+class Getit19ProfessorTest extends AdlrLoginBase
+{
+    use ProfessorTrait;
+
+    public function testGetItProfessor19()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit19DefaultTest::RECORDS, Getit19DefaultTest::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Getit19StudentTest.php b/module/finc/tests/selenium/tests/adlr/Getit19StudentTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..168df226ca3f2751784f5574f74ac71aea7f1e01
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Getit19StudentTest.php
@@ -0,0 +1,20 @@
+<?php
+namespace Selenium\adlr;
+
+use Lmc\Steward\Test\AbstractTestCase;
+
+/**
+ * @group adlr-getit-19
+ * @group adlr-getit-professor
+ */
+class Getit19StudentTest extends AdlrLoginBase
+{
+    use StudentTrait;
+
+    public function testGetItStudent19()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runGetItTest(Getit19DefaultTest::RECORDS, Getit19DefaultTest::RULES);
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/LibrarianTrait.php b/module/finc/tests/selenium/tests/adlr/LibrarianTrait.php
new file mode 100644
index 0000000000000000000000000000000000000000..0290a8bb5c01e510324819b4063e31ccfd73460d
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/LibrarianTrait.php
@@ -0,0 +1,14 @@
+<?php
+namespace Selenium\adlr;
+trait LibrarianTrait
+{
+    public function getUserName()
+    {
+        return 'librarian';
+    }
+
+    public function getPassword()
+    {
+        return 'test123$';
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/Login.php b/module/finc/tests/selenium/tests/adlr/Login.php
new file mode 100644
index 0000000000000000000000000000000000000000..327aef76e556ba35a6aef1f9f813923c04b471fd
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/Login.php
@@ -0,0 +1,7 @@
+<?php
+namespace Selenium\adlr;
+interface Login
+{
+    public function getUserName();
+    public function getPassword();
+}
\ No newline at end of file
diff --git a/module/finc/tests/selenium/tests/adlr/OrderTest.php b/module/finc/tests/selenium/tests/adlr/OrderTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..65e01e5081e42e195f7b70da2f060c85cab92fa3
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/OrderTest.php
@@ -0,0 +1,85 @@
+<?php
+namespace Selenium\adlr;
+
+use Facebook\WebDriver\WebDriverBy;
+use Facebook\WebDriver\WebDriverCheckboxes;
+use Facebook\WebDriver\WebDriverExpectedCondition;
+use Facebook\WebDriver\WebDriverSelect;
+
+/**
+ * @group adlr
+ * @group adlr-order
+ */
+class OrderTest extends AdlrLoginBase
+{
+    use LibrarianTrait;
+
+    public function testCreateOrderByUser()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runCreateOrderByUser();
+        $this->logout();
+    }
+
+    public function testDeleteOrder()
+    {
+        $this->runDeleteOrder();
+    }
+
+    protected function runCreateOrderByUser()
+    {
+        $this->log("Login as {$this->getUserName()} and create order.");
+        $this->findById('account-icon')->click();
+        $this->log("Show account of user.");
+
+        $this->log("Create order for partial copy.");
+        $this->wd->get(self::$host . self::$port . '/Record/127-HF000189856');
+        $this->findByXpath("//a[contains(@href,'/fidSubitoPartialCopy')]")->click();
+        $this->waitForName('pages');
+        // TODO: try some invalid inputs
+        $this->findByName('pages')->sendKeys('3-4');
+        $this->findByName('comment')->sendKeys('Harry Potter sucks.');
+        $this->wd->takeScreenshot("logs/adlr/orders/{$this->getUserName()}_create_order_form.png");
+        $this->findByName('fid-acquisition-form')->submit();
+        $this->wd->wait(10, 1000)->until(
+            WebDriverExpectedCondition::elementTextContains(
+                WebDriverBy::className('alert-success'),
+                'Ihre Bestellung wurde entgegengenommen und wird nun von uns bearbeitet.'
+            )
+        );
+        $this->wd->takeScreenshot("logs/adlr/orders/{$this->getUserName()}_create_order_success.png");
+        $this->wd->get(self::$host . self::$port . '/MyResearch/Home');
+
+        $this->log("Go to user orders.");
+        $this->findByXpath("//a[contains(@href,'/fid/user/order')]")->click();
+        $this->wd->takeScreenshot("logs/adlr/orders/{$this->getUserName()}_create_order_pages.png");
+        $this->assertNotEmpty($this->findByXpath("//a[contains(@href,'/Record/127-HF000189856')]")->getText());
+        $this->logout();
+    }
+
+    protected function runDeleteOrder()
+    {
+        $this->logout();
+        $this->log("Delete last order of user {$this->getUserName()} by admin.");
+        $this->wd->manage()->window()->fullscreen();
+        $this->login("admin@adlr.link", 'test123$');
+        $this->findById('account-icon')->click();
+        $this->findByXpath("//a[contains(@href,'/fid/admin/orders')]")->click();
+        $lastOrderTitle = $this->findByXpath(
+            "//*[@id='content']/table/tbody/tr[2]/td[4]/a"
+        )->getText();
+        $this->assertContains("Harry Potter", $lastOrderTitle);
+        $this->wd->takeScreenshot("logs/adlr/orders/{$this->getUserName()}_create_order_delete.png");
+        $this->findByXpath("//*[@id='content']/table/tbody/tr[2]/td[5]/a")->click(); // TODO use unique selector
+        $this->findByXpath("//*[@id='orderDeleteModal']/div/div/div[3]/a")->click(); // TODO use unique selector
+        $this->wd->wait(10, 1000)->until(
+            WebDriverExpectedCondition::elementTextContains(
+                WebDriverBy::className('alert-success'),
+                'Bestellung gelöscht'
+            )
+        );
+        $this->wd->takeScreenshot("logs/adlr/orders/{$this->getUserName()}_create_order_delete_success.png");
+        $this->logout();
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/ProfessorTrait.php b/module/finc/tests/selenium/tests/adlr/ProfessorTrait.php
new file mode 100644
index 0000000000000000000000000000000000000000..4b62b4cc97f4f146a2e34bdd6df799f567498633
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/ProfessorTrait.php
@@ -0,0 +1,14 @@
+<?php
+namespace Selenium\adlr;
+trait ProfessorTrait
+{
+    public function getUserName()
+    {
+        return 'professor';
+    }
+
+    public function getPassword()
+    {
+        return 'test123$';
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/StudentTrait.php b/module/finc/tests/selenium/tests/adlr/StudentTrait.php
new file mode 100644
index 0000000000000000000000000000000000000000..cdfaeeda6ff89c2382bc318ca7643775ef85290b
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/StudentTrait.php
@@ -0,0 +1,14 @@
+<?php
+namespace Selenium\adlr;
+trait StudentTrait
+{
+    public function getUserName()
+    {
+        return 'student';
+    }
+
+    public function getPassword()
+    {
+        return 'test123$';
+    }
+}
diff --git a/module/finc/tests/selenium/tests/adlr/UserDeleteTest.php b/module/finc/tests/selenium/tests/adlr/UserDeleteTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..20a6bb19a0e08f5e491a55543c07adce1f76e972
--- /dev/null
+++ b/module/finc/tests/selenium/tests/adlr/UserDeleteTest.php
@@ -0,0 +1,97 @@
+<?php
+namespace Selenium\adlr;
+
+use Facebook\WebDriver\WebDriverBy;
+use Facebook\WebDriver\WebDriverCheckboxes;
+use Facebook\WebDriver\WebDriverExpectedCondition;
+use Facebook\WebDriver\WebDriverSelect;
+
+/**
+ * @group adlr
+ * @group adlr-delete
+ * @group adlr-delete-librarian
+ */
+class UserDeleteTest extends AdlrLoginBase
+{
+    use LibrarianTrait;
+
+    public function testDeleteByUser()
+    {
+        $this->logout();
+        $this->assertTrue($this->login("{$this->getUserName()}@adlr.link", $this->getPassword()));
+        $this->runDeleteByUserTest();
+        $this->logout();
+    }
+
+    public function testReactivateUser()
+    {
+        $this->runReactivateUser();
+    }
+
+    protected function runDeleteByUserTest()
+    {
+        $this->log("Login as {$this->getUserName()} and mark own account for delete.");
+        $this->wd->get(self::$host . self::$port);
+        $this->findById('account-icon')->click();
+        $this->log("Show account of user.");
+
+        $this->log("Go to user delete form.");
+        $this->findByXpath("//a[contains(@href,'/fid/user/delete')]")->click();
+        $this->waitForName('passwordConfirmation');
+        $this->findByName('passwordConfirmation')->sendKeys($this->getPassword());
+        $this->wd->takeScreenshot("logs/adlr/user/delete/{$this->getUserName()}_1_deletes_account.png");
+        $this->findByName('submit')->click();
+        $this->wd->wait(10, 1000)->until(
+            WebDriverExpectedCondition::elementTextContains(
+                WebDriverBy::cssSelector('.modal-body > h1'),
+                'Konto gesperrt und zur Löschung vorgemerkt.'
+            )
+        );
+        $this->wd->takeScreenshot("logs/adlr/user/delete/{$this->getUserName()}_2_account_delete_success.png");
+        $this->logout();
+
+        $this->log("Try to log in again - should fail...");
+        $this->wd->get(self::$host . self::$port . '/MyResearch/UserLogin');
+        $this->findById('login_Authenticator_username')->sendKeys($this->getUserName() . "@adlr.link");
+        $this->findById('login_Authenticator_password')->sendKeys($this->getPassword());
+        $this->findByName('loginForm')->submit();
+        $this->wd->wait(10, 1000)->until(
+            WebDriverExpectedCondition::elementTextContains(
+                WebDriverBy::className('alert-danger'),
+                'Ihr Konto ist zur Löschung vorgemerkt und Ihre Daten werden beim nächsten Wartungslauf endgültig entfernt.'
+            )
+        );
+        $this->wd->takeScreenshot("logs/adlr/user/delete/{$this->getUserName()}_3_account_blocked.png");
+    }
+
+    protected function runReactivateUser()
+    {
+        $this->log("Reactivate account of user {$this->getUserName()} by admin.");
+        $this->wd->manage()->window()->fullscreen();
+        $this->login("admin@adlr.link", 'test123$');
+        $this->findById('account-icon')->click();
+        $this->wd->get(self::$host . self::$port . '/fid/admin/list');
+        $userId = $this->findByXpath(
+            "//tr/td[text()='{$this->getUserName()}@adlr.link']//preceding-sibling::th"
+        )->getText();
+        $this->log("Found userID $userId");
+        $this->wd->get(self::$host . self::$port . '/fid/admin/edit/' . $userId);
+        $selectElement = $this->wd->findElement(WebDriverBy::name('permissions[basic_access]'));
+        $select = new WebDriverSelect($selectElement);
+        $select->selectByValue('granted');
+        $deleteElement = $this->findById('deleted');
+        $delete = new WebDriverCheckboxes($deleteElement);
+        $delete->deselectAll();
+        $this->wd->takeScreenshot("logs/adlr/user/delete/{$this->getUserName()}_4_reactivate_account.png");
+        $this->wd->executeScript('window.scrollBy(0,document.body.scrollHeight);');
+        $this->findByName('submit')->click();
+        $this->wd->wait(10, 1000)->until(
+            WebDriverExpectedCondition::elementTextContains(
+                WebDriverBy::className('alert-info'),
+                'Ihr Profil wurde erfolgreich aktualisiert.'
+            )
+        );
+        $this->wd->takeScreenshot("logs/adlr/user/delete/{$this->getUserName()}_5_account_active_info.png");
+        $this->logout();
+    }
+}
diff --git a/module/finc/tests/selenium/tests/de_15/AccountTest.php b/module/finc/tests/selenium/tests/de_15/AccountTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..202a22fd98efd627810e2ece5d4118e3c61853eb
--- /dev/null
+++ b/module/finc/tests/selenium/tests/de_15/AccountTest.php
@@ -0,0 +1,54 @@
+<?php
+namespace Selenium\de_15;
+
+use Lmc\Steward\ConfigProvider;
+use Selenium\finc\FincBase;
+
+/**
+ * @group de_15
+ */
+class AccountTest extends FincBase
+{
+    /**
+     * @before
+     */
+    public function initBaseUrl()
+    {
+        // Set base url according to environment
+        switch (ConfigProvider::getInstance()->env) {
+            case 'staging':
+                self::$host = 'https://staging.finc.info/vufind2/de_15';
+                break;
+            case 'alpha':
+                self::$host = 'https://alpha.finc.info/vufind2/de_15/22797';
+                break;
+            case 'local':
+                self::$host = 'http://host.docker.internal';
+                break;
+            default:
+                throw new \RuntimeException(sprintf('Unknown environment "%s"', ConfigProvider::getInstance()->env));
+        }
+
+        $this->debug('Base URL set to "%s"', self::$host);
+
+        if (ConfigProvider::getInstance()->env === 'production') {
+            $this->warn('The tests are run against production, so be careful!');
+        }
+    }
+
+    /**
+     * @group de_15
+     */
+    public function testChangeProfile()
+    {
+        $this->runTestChangeProfile('0015TV000003', 'test123$');
+    }
+
+    #region helper methods
+    protected function changeLanguage($lang = 'de')
+    {
+        $this->wd->get(self::$host . self::$port);
+        $this->wd->executeScript("document.langForm.mylang.value='" . $lang . "';document.langForm.submit();");
+        $this->waitForPartialLinkText('Katalogsuche');
+    }
+}
diff --git a/module/finc/tests/selenium/tests/de_zwi2/AccountTest.php b/module/finc/tests/selenium/tests/de_zwi2/AccountTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d61a703334d23ca4ef8634b4f6f7501b287fe603
--- /dev/null
+++ b/module/finc/tests/selenium/tests/de_zwi2/AccountTest.php
@@ -0,0 +1,54 @@
+<?php
+namespace Selenium\de_zwi2;
+
+use Lmc\Steward\ConfigProvider;
+use Selenium\finc\FincBase;
+
+/**
+ * @group de_zwi2
+ */
+class AccountTest extends FincBase
+{
+    protected $user = false;
+
+    /**
+     * @before
+     */
+    public function initBaseUrl()
+    {
+        // Set base url according to environment
+        switch (ConfigProvider::getInstance()->env) {
+            case 'staging':
+                self::$host = 'https://staging.finc.info/vufind2/de_zwi2';
+                break;
+            case 'alpha':
+                self::$host = 'https://alpha.finc.info/vufind2/de_zwi2/22801';
+                break;
+            case 'local':
+                self::$host = 'http://host.docker.internal';
+                break;
+            default:
+                throw new \RuntimeException(sprintf('Unknown environment "%s"', ConfigProvider::getInstance()->env));
+        }
+
+        $this->debug('Base URL set to "%s"', self::$host);
+
+        if (ConfigProvider::getInstance()->env === 'production') {
+            $this->warn('The tests are run against production, so be careful!');
+        }
+    }
+
+    #region helper methods
+    protected function changeLanguage($lang = 'de')
+    {
+        $this->wd->get(self::$host . self::$port);
+        $this->wd->executeScript("document.langForm.mylang.value='" . $lang . "';document.langForm.submit();");
+        $this->waitForPartialLinkText('Mein Konto');
+    }
+
+    public function testChangeProfile()
+    {
+        $this->runTestChangeProfile('019300', '11111911');
+    }
+    #endregion
+}
diff --git a/module/finc/tests/selenium/tests/finc/FincBase.php b/module/finc/tests/selenium/tests/finc/FincBase.php
new file mode 100644
index 0000000000000000000000000000000000000000..96047cad735c7215f48c034174769a73c2051605
--- /dev/null
+++ b/module/finc/tests/selenium/tests/finc/FincBase.php
@@ -0,0 +1,102 @@
+<?php
+namespace Selenium\finc;
+
+use Lmc\Steward\ConfigProvider;
+use Lmc\Steward\Test\AbstractTestCase;
+
+class FincBase extends AbstractTestCase
+{
+    public static $port = '';
+    public static $host = 'https://staging.finc.info/vufind2/de_zwi2';
+
+    protected $user = false;
+
+    /**
+     * @before
+     */
+    public function initBaseUrl()
+    {
+        // Set base url according to environment
+        switch (ConfigProvider::getInstance()->env) {
+            case 'staging':
+                self::$host = 'https://staging.finc.info/vufind2/local';
+                break;
+            case 'local':
+                self::$host = 'http://host.docker.internal';
+                break;
+            default:
+                throw new \RuntimeException(sprintf('Unknown environment "%s"', ConfigProvider::getInstance()->env));
+        }
+
+        $this->debug('Base URL set to "%s"', self::$host);
+
+        if (ConfigProvider::getInstance()->env === 'production') {
+            $this->warn('The tests are run against production, so be careful!');
+        }
+    }
+
+    protected function runTestChangeProfile($user, $password)
+    {
+        $this->wd->get(self::$host . self::$port);
+        $this->logout();
+        $this->changeLanguage();
+        $this->user = $user;
+        $this->login("$this->user", $password);
+        $this->findByXpath('//*[@id="content"]/div[1]/a')->click();
+        $this->waitForName('accountForm');
+        $inputFirstname = $this->findById('firstname');
+        $oldFirstname = $inputFirstname->getAttribute('value');
+        $this->log("Old Vorname: $oldFirstname");
+        // $this->wd->takeScreenshot('logs/old.png');
+        $inputFirstname->clear();
+        $newFirstname = time();
+        $inputFirstname->sendKeys($newFirstname);
+        // $this->wd->takeScreenshot('logs/change.png');
+        $this->findById('submitAccount')->click();
+        $this->waitForClass('alert-success');
+        // $this->wd->takeScreenshot('logs/success.png');
+        $changedValue = $this->findByXpath('//*[@id="content"]/div[1]/table/tbody/tr[1]/td')->getText();
+        // restore old name
+        $this->findByXpath('//*[@id="content"]/div[1]/a')->click();
+        $this->waitForName('accountForm');
+        $this->findById('firstname')->clear();
+        $this->findById('firstname')->sendKeys($oldFirstname);
+        $this->findById('submitAccount')->click();
+        // $this->wd->takeScreenshot('logs/restored.png');
+
+        $this->assertStringContainsStringIgnoringCase(
+            $newFirstname,
+            $changedValue,
+            "Vorname could not be updated."
+        );
+    }
+
+    #region helper methods
+    protected function changeLanguage($lang = 'de')
+    {
+        $this->wd->get(self::$host . self::$port);
+        $this->wd->executeScript("document.langForm.mylang.value='" . $lang . "';document.langForm.submit();");
+        $this->waitForPartialLinkText('Konto');
+    }
+
+    protected function setFullsreen()
+    {
+        $this->wd->manage()->window()->maximize();
+    }
+
+    protected function logout()
+    {
+        $this->wd->get(self::$host . self::$port . '/MyResearch/Logout');
+    }
+
+    protected function login($user, $password): bool
+    {
+        $this->wd->get(self::$host . self::$port . '/MyResearch/UserLogin');
+        $this->findById('login_ILS_username')->sendKeys($user);
+        $this->findById('login_ILS_password')->sendKeys($password);
+        $this->findByName('processLogin')->click();
+        $this->waitForClass('myresearch-menu');
+        return true;
+    }
+    #endregion
+}
diff --git a/themes/finc-accessibility/js/record.js b/themes/finc-accessibility/js/record.js
index f6a80431ba6e9cfc63485d4bdfc2e0d679d3f18d..d9b01b9a996bb8f1346ea74a87165f0ab40b912b 100644
--- a/themes/finc-accessibility/js/record.js
+++ b/themes/finc-accessibility/js/record.js
@@ -289,4 +289,8 @@ function recordDocReady() {
 
   registerTabEvents();
   // finc 'applyRecordTabHash()' removed to remove hashes #21555
+
+  if (typeof recordDocReadyPlugin !== "undefined") {
+    recordDocReadyPlugin();
+  }
 }
diff --git a/themes/finc-accessibility/templates/myresearch/menu.phtml b/themes/finc-accessibility/templates/myresearch/menu.phtml
new file mode 100644
index 0000000000000000000000000000000000000000..cd4def5af7a35aa57c9f5dffb9f1a56c00314315
--- /dev/null
+++ b/themes/finc-accessibility/templates/myresearch/menu.phtml
@@ -0,0 +1,163 @@
+<!-- finc: myresearch - menu -->
+<?php
+
+/**
+ * origin: finc
+ *
+ * called by view helper/controller: MyResearchController
+ *
+ * usage:
+ ** renders side menu of profile/myreasearch menu
+ *
+ * configured in: --
+ */
+?>
+<?php
+  $user = $this->auth()->isLoggedIn();
+  $patron = $user ? $this->auth()->getILSPatron() : false;
+  $capabilityParams = $patron ? ['patron' => $patron] : [];
+  $ilsOnline = ('ils-none' !== $this->ils()->getOfflineMode());
+?>
+<?php /* finc change btn-link to btn-default */ ?>
+<button class="close-offcanvas btn btn-default" data-toggle="offcanvas"><?=$this->transEsc('navigate_back') ?></button>
+<?php /* finc: change h3 to h2 */ ?>
+<h2><?=$this->transEsc('Your Account')?></h2>
+<?php /* finc needs to add .facet-group class and classes on sub items for borders - CK */
+      /* also adds aria-current for correct menu action */ ?>
+<?php /* finc needs to add .facet-group class and classes on sub items for borders - CK */ ?>
+<?php /* finc: myreasearch menu as list #19734 */ ?>
+<?php /* finc: specify current page menu entry in following elements #19941 */ ?>
+<ul class="myresearch-menu account-menu facet-group">
+  <?php if ($this->userlist()->getMode() !== 'disabled'): ?>
+    <li class="facet">
+      <a href="<?=$this->url('myresearch-favorites')?>"<?=$this->active == 'favorites' ? ' class="active" aria-current="page"' : ''?>>
+        <i class="fa fa-fw fa-star" aria-hidden="true"></i> <?=$this->transEsc('Favorites')?>
+      </a>
+    </li>
+  <?php endif; ?>
+  <?php if ($ilsOnline && $this->ils()->checkCapability('getMyTransactions', $capabilityParams)): ?>
+    <li class="facet">
+      <a href="<?=$this->url('myresearch-checkedout')?>" class="flex checkedout<?=$this->active == 'checkedout' ? ' active' : ''?>"
+        <?=$this->active == 'checkedout' ? ' aria-current="page"' : ''?>
+      >
+        <span class="flex-col"><i class="fa fa-fw fa-book" aria-hidden="true"></i>&nbsp;<?=$this->transEsc('Checked Out Items')?></span>
+        <span class="checkedout-status status hidden"><i class="fa fa-spin fa-spinner" aria-hidden="true"></i></span>
+      </a>
+    </li>
+  <?php endif; ?>
+  <?php if ($ilsOnline && $this->ils()->checkFunction('getMyTransactionHistory', $capabilityParams)): ?>
+    <li class="facet">
+      <a href="<?=$this->url('myresearch-historicloans')?>"<?=$this->active == 'historicloans' ? ' class="active" aria-current="page"' : ''?>>
+        <i class="fa fa-fw fa-history" aria-hidden="true"></i> <?=$this->transEsc('Loan History')?>
+      </a>
+    </li>
+  <?php endif; ?>
+  <?php if ($ilsOnline && $this->ils()->checkCapability('getMyHolds', $capabilityParams)): ?>
+    <li class="facet">
+      <a href="<?=$this->url('myresearch-holds')?>" class="flex<?=$this->active == 'holds' ? ' active' : ''?>"
+        <?=$this->active == 'holds' ? ' aria-current="page"' : ''?>
+      >
+        <span class="flex-col"><i class="fa fa-fw fa-flag" aria-hidden="true"></i>&nbsp;<?=$this->transEsc('Holds and Recalls')?></span>
+        <span class="holds-status status hidden"><i class="fa fa-spin fa-spinner" aria-hidden="true"></i></span>
+      </a>
+    </li>
+  <?php endif; ?>
+  <?php if ($ilsOnline && $this->ils()->checkFunction('StorageRetrievalRequests', $capabilityParams)): ?>
+    <li class="facet">
+      <a href="<?=$this->url('myresearch-storageretrievalrequests')?>" class="flex<?=$this->active == 'storageRetrievalRequests' ? ' active' : ''?>"
+        <?=$this->active == 'storageRetrievalRequests' ? ' aria-current="page"' : ''?>
+      >
+        <span class="flex-col"><i class="fa fa-fw fa-archive" aria-hidden="true"></i> <?=$this->transEsc('Storage Retrieval Requests')?></span>
+        <span class="storageretrievalrequests-status status hidden"><i class="fa fa-spin fa-spinner" aria-hidden="true"></i></span>
+      </a>
+    </li>
+  <?php endif; ?>
+  <?php if ($ilsOnline && $this->ils()->checkFunction('ILLRequests', $capabilityParams)): ?>
+    <li class="facet">
+      <a href="<?=$this->url('myresearch-illrequests')?>" class="flex<?=$this->active == 'ILLRequests' ? ' active' : ''?>"
+        <?=$this->active == 'ILLRequests' ? ' aria-current="page"' : ''?>
+      >
+        <span class="flex-col"><i class="fa fa-fw fa-exchange" aria-hidden="true"></i> <?=$this->transEsc('Interlibrary Loan Requests')?></span>
+        <span class="illrequests-status status hidden"><i class="fa fa-spin fa-spinner" aria-hidden="true"></i></span>
+      </a>
+    </li>
+  <?php endif; ?>
+  <?php if ($ilsOnline && $this->ils()->checkCapability('getMyFines', $capabilityParams)): ?>
+    <li class="facet">
+      <a href="<?=$this->url('myresearch-fines')?>" class="flex<?=$this->active == 'fines' ? ' active' : ''?>"
+        <?=$this->active == 'fines' ? ' aria-current="page"' : ''?>
+      >
+        <span class="flex-col"><i class="fa fa-fw fa-usd" aria-hidden="true"></i>&nbsp;<?=$this->transEsc('Fines')?></span>
+        <span class="fines-status status hidden"><i class="fa fa-spin fa-spinner" aria-hidden="true"></i></span>
+      </a>
+    </li>
+  <?php endif; ?>
+  <li class="facet">
+    <a href="<?=$this->url('myresearch-profile')?>"<?=$this->active == 'profile' ? ' class="active" aria-current="page"' : ''?>>
+      <i class="fa fa-fw fa-user" aria-hidden="true"></i> <?=$this->transEsc('Profile')?>
+    </a>
+  </li>
+  <?php if ($ilsOnline && $user && $user->libraryCardsEnabled()): ?>
+    <li class="facet">
+      <a href="<?=$this->url('librarycards-home')?>"<?=$this->active == 'librarycards' ? ' class="active" aria-current="page"' : ''?>>
+        <i class="fa fa-fw fa-barcode" aria-hidden="true"></i> <?=$this->transEsc('Library Cards')?>
+      </a>
+    </li>
+  <?php endif; ?>
+  <?php if ($this->overdrive()->showMyContentLink()):?>
+    <li class="facet">
+      <a href="<?=$this->url('overdrive-mycontent')?>"<?=$this->active == 'dgcontent' ? ' class="active"' : ''?>>
+        <i class="fa fa-fw fa-download" aria-hidden="true"></i> <?=$this->transEsc('Overdrive Content')?>
+      </a>
+    </li>
+  <?php endif; ?>
+  <?php if ($this->accountCapabilities()->getSavedSearchSetting() === 'enabled'): ?>
+    <li class="facet">
+      <a href="<?=$this->url('search-history')?>?require_login"<?=$this->active == 'history' ? ' class="active" aria-current="page"' : ''?>>
+        <i class="fa fa-fw fa-search" aria-hidden="true"></i> <?=$this->transEsc('history_saved_searches')?>
+      </a>
+    </li>
+  <?php endif; ?>
+  <?php if ($user): ?>
+    <li class="facet">
+      <a href="<?=$this->url('myresearch-logout')?>">
+        <i class="fa fa-fw fa-sign-out" aria-hidden="true"></i> <?=$this->transEsc("Log Out")?>
+      </a>
+    </li>
+  <?php endif; ?>
+</ul>
+
+<?php if ($user && $this->userlist()->getMode() !== 'disabled'): ?>
+  <?php /* finc adds '.lists-heading' for styling purposes */ ?>
+  <h3 class="list-heading"><?=$this->transEsc('Your Lists')?></h3>
+  <?php /* finc: change menu into list */ ?>
+  <ul class="myresearch-menu facet-group">
+    <li class="facet">
+      <?php /* finc adds aria-current */ ?>
+      <a href="<?=$this->url('myresearch-favorites')?>"<?=$this->active == 'favorites' ? ' class="active"' : ''?>
+        <?=$this->active == 'favorites' ? ' aria-current="page"' : ''?>
+      >
+        <i class="fa fa-fw fa-star" aria-hidden="true"></i> <?=$this->transEsc('Your Favorites')?>
+      </a>
+    </li>
+    <?php $lists = $user->getLists() ?>
+    <?php foreach ($lists as $list): ?>
+      <li class="facet">
+        <a href="<?=$this->url('userList', ['id' => $list['id']])?>"<?=$this->active == 'list' . $list['id'] ? ' class="active"' : ''?>
+          <?=$this->active == 'list' . $list['id'] ? ' aria-current="page"' : ''?>
+        >
+          <?=$this->escapeHtml($list['title'])?>
+          <span class="badge"><?=$list->cnt ?></span>
+        </a>
+      </li>
+    <?php endforeach; ?>
+    <li class="facet">
+      <a href="<?=$this->url('editList', ['id' => 'NEW'])?>"
+        <?=$this->active == 'editlist/NEW' ? ' aria-current="page"' : ''?>
+      >
+        <i class="fa fa-fw fa-plus" aria-hidden="true"></i> <?=$this->transEsc('Create a List') ?>
+      </a>
+    </li>
+  </ul>
+<?php endif ?>
+<!-- finc: myresearch - menu - END -->
\ No newline at end of file
diff --git a/themes/finc/js/covers.js b/themes/finc/js/covers.js
index 7c0771977116dbf3aa7fd9648c982760b2accbbf..e1235742b58699e21bfe7b72972955af08eeb73a 100644
--- a/themes/finc/js/covers.js
+++ b/themes/finc/js/covers.js
@@ -22,7 +22,7 @@ function registerCoverForModal(anchor, url) {
 function loadCoverByElement(data, element) {
   var url = VuFind.path + '/AJAX/JSON?method=' + 'getRecordCover';
   var img = element.find('img');
-  var spinner = element.children('div.spinner');
+  var spinner = element.find('.spinner');
   var container = element.children('div.cover-container');
   var anchor = container.children('a.coverlink');
   function coverCallback(response) {
@@ -61,7 +61,7 @@ function loadCoverByElement(data, element) {
     data: data,
     element: element,
     success: coverCallback,
-    error: spinner.hide()
+    error: () => spinner.hide()
   });
 }
 
diff --git a/themes/finc/scss/_common.scss b/themes/finc/scss/_common.scss
index 5b24b9531e7cffe30a1c26e7dbc69a302709cd8a..d5e61ac17e6b90ee00786712e120635d5f22be6e 100644
--- a/themes/finc/scss/_common.scss
+++ b/themes/finc/scss/_common.scss
@@ -93,6 +93,13 @@ label,
   }
 }
 
+// Items visible on MD/Desktop and sr-only on all other devices
+.visible-md-up-sr-only {
+  @media (max-width: $screen-sm-max) {
+    @include sr-only;
+  }
+}
+
 
 // Flex container for wrapping flex elements, such als header
 .flex-container {
diff --git a/themes/finc/scss/_customVariables.scss b/themes/finc/scss/_customVariables.scss
index 7cbf663f4dd16f8c94d2d4c616e0ec6459157b75..e3a9ba786f9e070c4cb44ded912c50ad41ff526b 100644
--- a/themes/finc/scss/_customVariables.scss
+++ b/themes/finc/scss/_customVariables.scss
@@ -40,6 +40,11 @@ $black:       #000 !default;
 
 $red:         #f00 !default;
 
+// Reset filters button, this color is hard-coded into Bootstrap for '.toolbar-btn',
+// '.record-nav .cart-add', '.record-nav .cart-remove', '.reset-filters-btn' and the bulk action buttons
+$lightgrey-transparent: rgba(0, 0, 0, .05);
+
+
 // *****************************************************************
 // ************ Theme basic colors *********************************
 // *****************************************************************
@@ -87,8 +92,8 @@ $screen-wcag-above-mini-below-xs-viewports-max: 479px !default;
 // which gives you the left or right gutter width; this can be taken
 // further by using '$grid-gutter-width / 1.5' etc
 $grid-gutter-width: 30px !default;
-$half-gutter: ($grid-gutter-width / 2);
-$quarter-gutter: ($grid-gutter-width / 4);
+$half-gutter: ($grid-gutter-width / 2) !default;
+$quarter-gutter: ($grid-gutter-width / 4) !default;
 
 // Navigation elements default height:
 // This height _must_ be adapted to the button height
@@ -164,19 +169,19 @@ $margin-right-width: inherit !default;
 
 
 
+
 // *****************************************************************
 // ************ Default anchor/link styles general *****************
 // *****************************************************************
 $link-color: $brand-primary !default;
 $link-hover-color: darken($link-color, 15%) !default;
 $link-text-decoration: underline !default;
-$link-hover-decoration: underline !default;
+$link-hover-decoration: $link-text-decoration !default;
 $link-on-dark-bg-color: invert($link-color) !default;
 
 // see also '$state-link-hover-color' below
 
-$mainbody-link-text-decoration: $link-text-decoration;
-
+$mainbody-link-text-decoration: $link-text-decoration !default;
 
 
 
@@ -334,7 +339,7 @@ $sidebar-badge-fa-color: darken($brand-secondary, 40%) !default;
 // ************ Alerts/Feedback state ******************************
 // *****************************************************************
 
-$state-link-text-decoration: $link-text-decoration;
+$state-link-text-decoration: $link-text-decoration !default;
 
 $state-inside-holding-info-margin-left: 1rem !default;
 $state-inside-holding-info-margin-right:  1rem !default;
@@ -663,6 +668,9 @@ $navbar-bg-color-xs: $navbar-default-toggle-hover-bg !default;
 $navbar-xs-openend-margin-bottom: 1rem !default;
 $navbar-fixed-bg-color: $header-bg-color !default;
 
+// Bootstrap theme gives '.navbar-fixed-top' and '.navbar-fixed-bottom' a top or bottom border of 1px:
+// set this variable in your theme according to your preferences
+$navbar-fixed-top-border-bottom-width: 0 !default;
 
 // Header, navbar and breadcrumbs default margin for centered design - change here for full width
 $header-navbar-breadcrumbs-margin: 0 auto !default;
@@ -680,7 +688,6 @@ $navbar-height-sm: $navbar-height !default;
 
 // Set navbar-height for small devices, USE px as rem will throw an error in conjunction with _variables.scss
 $navbar-height-xs: $navbar-height + 14px !default;
-$navbar-min-height-adv-search: 3rem !default;
 $navbar-max-height-xs: $navbar-height + 32px !default;
 
 $navbar-opened-on-xs-position: absolute !default;
@@ -696,10 +703,10 @@ $hamburger-menu-margin-left-xs: 0 !default;
 $hamburger-menu-margin-right-xs: 0 !default;
 
 // This is for the menu items in the header incl. language, My account etc
-$header-menu-flex-sm-up: 1 0 40%;
-$header-menu-flex-adv-srch-sm-up: 1 0 100%;
-$header-menu-flex-order-sm-up: 3;
-$header-menu-padding-top-sm-up: 6px;
+$header-menu-flex-sm-up:  1 0 35% !default;
+$header-menu-flex-adv-srch-sm-up: 1 0 100% !default;
+$header-menu-flex-order-sm-up: 3 !default;
+$header-menu-padding-top-sm-up: 6px !default;
 
 
 $library-name-float: left !default;
@@ -716,7 +723,7 @@ $language-selector-dropdown-margin-right: 15px !default;
 $language-selector-dropdown-menu-background-color: $navbar-bg-color !default;
 $language-selector-dropdown-menu-border: 0 !default;
 $language-selector-dropdown-menu-min-width: auto !default;
-$language-selector-dropdown-menu-link-color: $link-color;
+$language-selector-dropdown-menu-link-color: $link-color !default;
 $language-selector-dropdown-menu-btn-padding-left: 0 !default;
 $language-selector-dropdown-menu-btn-padding-right: 0 !default;
 $language-selector-dropdown-menu-btn-focus-hover-background-color: $white !default;
@@ -785,6 +792,22 @@ $search-form-advanced-search-button-border: 1px solid $oil !default;
 
 
 
+// *****************************************************************
+// ************ Content box ****************************************
+// *****************************************************************
+
+// currently reused:
+// * avanced search term
+// * active filters
+
+$content-box-display: block !default;
+$content-box-margin-bottom: 1rem !default;
+$content-box-padding: 1rem !default;
+$content-box-border: 1px solid $brand-primary !default;
+$content-box-background-color: inherit !default;
+
+
+
 // *****************************************************************
 // ************ Advanced Search ************************************
 // *****************************************************************
@@ -794,6 +817,8 @@ $search-form-advanced-search-button-border: 1px solid $oil !default;
 // In most instance we have MOVED the advanced search TERMS INTO the BREADCRUMBS area
 // in order to keep the header ok on small devices. If this is the case in your instance,
 // you can ignore the '$adv_search_terms...' settings.
+// FIXME: REMOVE THE FOLLOWING SECTIONS + all RELATED VARIABLES when
+//  all instances have the new search terms display on top of search results - CK
 $adv-search-terms-bg: $brand-secondary !default;
 $adv-search-terms-border: 1px solid $brand-primary !default;
 $adv-search-terms-bottom-margin: 0 !default;
@@ -815,9 +840,14 @@ $adv-search-links-anchor-border-bottom-sm-up: 0 !default;
 $adv-search-links-anchor-border-right-sm-up: 1px solid $brand-primary !default;
 $adv-search-links-anchor-display-sm-up: inline !default;
 $adv-search-links-anchor-padding-right-sm-up: .5em !default;
-$adv-search-links-sm-to-md-max-max-width: 400px !default;
-
+$adv-search-links-sm-to-md-max-max-width: 470px !default;
 
+// Advanced Search Box Container in Result List
+$adv-search-box-display:                          flex !default;
+$adv-search-box-margin-bottom:                    $content-box-margin-bottom !default;
+$adv-search-box-padding:                          $content-box-padding !default;
+$adv-search-box-border:                           $content-box-border !default;
+$adv-search-box-background-color:                 $content-box-background-color !default;
 
 
 
@@ -825,20 +855,29 @@ $adv-search-links-sm-to-md-max-max-width: 400px !default;
 // ************ Active filters in header ***************************
 // *****************************************************************
 // Outer container for filter names and reset button;
-// we overwrite BS value 'display: flex;' so filters' container will fit
 // in searchbox without squashing right-hand menu;
-// Set this to 'flex' to maintain BS-theme behaviour
-$active-filters-outer-container-display: unset !default;
-// Remove left-padding of outer filters' container for alignment under 'Remove all' button
-$active-filters-outer-filters-container-padding-left: 0 !default;
+$active-filters-outer-container-display:          $content-box-display !default;
+$active-filters-outer-container-margin-bottom:    $content-box-margin-bottom !default;
+$active-filters-outer-container-padding:          $content-box-padding !default;
+
+$active-filters-outer-container-border:           $content-box-border !default;
+$active-filters-outer-container-background-color:  $content-box-background-color !default;
+
+
+// Define padding of filters' container for better alignment
+$active-filters-filter-padding-left: 0 !default;
+
 
 // Variables for 'Active filters' and 'Remove all filters' in Header
 // Use orange and black for sufficient color contrast
 $search-filter-remove-all-color: $black !default;
 $search-filter-remove-all-bg: $brand-warning !default;
+$search-filter-remove-all-float: right !default;
 
 $search-filter-text-decoration: none !default;
 
+// show-all-filters-toggler
+$search-filter-all-filters-toggle: left !default;
 
 // Give these the same look on focus/hover as 'Remove all'
 $search-filter-remove-hover-bg: $search-filter-remove-all-bg !default;
@@ -853,7 +892,7 @@ $search-filters-margin-bottom: 4px !default;
 $search-filters-padding: .5rem 5px !default;
 
 
-$search-filter-remove-button-vertical-align: top !default;
+$search-filter-remove-button-vertical-align: middle !default;
 $search-filter-remove-button-text-display: inline-block !default;
 $search-filter-remove-button-text-max-width: 200px !default;
 $search-filter-remove-button-text-overflow: hidden !default;
@@ -861,7 +900,9 @@ $search-filter-remove-button-text-text-overflow: ellipsis !default;
 $search-filter-remove-button-text-white-space: nowrap !default;
 
 $search-filter-remove-icon: '\f00d' !default;
+$search-filter-remove-icon-display: inline-block !default;
 $search-filter-remove-icon-hover-color: $red !default;
+$search-filter-remove-icon-top-margin: -2px !default;
 $search-filter-remove-icon-vertical-align: top !default;
 $search-filter-remove-icon-in-dropdown-distance-from-right: 1rem !default;
 $search-filter-remove-icon-in-dropdown-padding: 0 !default;
@@ -879,12 +920,13 @@ $search-filter-dropdown-button-float: none !default;
 $breadcrumb-bg: $brand-primary !default;
 // Default is 'white'
 $breadcrumb-color: $btn-primary-color !default;
+$breadcrumb-link-text-decoration: $link-text-decoration;
 
 // Link color for '.active' breadcrumb (last item in list)
 // For yellow, you can activate something like
 // $breadcrumb-active-color: $road-sign-yellow !default;
 // Default is button collor
-$breadcrumb-active-color: $btn-primary-color;
+$breadcrumb-active-color: $btn-primary-color !default;
 
 $breadcrumb-divider-color: $breadcrumb-color !default;
 
@@ -921,6 +963,9 @@ $content-xs-padding-top: 1.5rem !default;
 // This is for all lists that use the result list view or elements thereof.
 // For Search Control, Bulk Elements, Pagination, see below
 
+// sets padding on '.result-body' to prevent text from running into Add to Favorites etc
+$result-body-right-padding-sm-up: 1rem !default;
+
 // Media container
 $result-list-record-result-media-container-xs-sm-padding-left: 0 !default;
 $result-list-record-result-media-container-xs-sm-padding-right: 0 !default;
@@ -1038,8 +1083,8 @@ $pager-margin-bottom: 0 !default;
 $pager-margin-top-xs: em(40px) !default;
 
 $pager-bg: $silver !default;
-$pager-hover-bg: $brand-primary;
-$pager-hover-color: $black;
+$pager-hover-bg: $brand-primary !default;
+$pager-hover-color: $black !default;
 $pager-border: $border-default-styles !default;
 $pager-border-radius: 0 !default;
 
@@ -1061,7 +1106,7 @@ $book-bag-add-to-in-sidebar-toggler-color: $brand-primary !default;
 $record-view-toolbar-button-padding-add-to-bookbag: 1.2rem !default;
 $book-bag-add-to-in-sidebar-toggler-padding: $record-view-toolbar-button-padding  $record-view-toolbar-button-padding-add-to-bookbag !default;
 $book-bag-add-to-in-sidebar-toggler-text-align-xs: left !default;
-$book-bag-add-to-in-sidebar-toggler-text-decoration: $link-text-decoration;
+$book-bag-add-to-in-sidebar-toggler-text-decoration: $link-text-decoration !default;
 $book-bag-add-to-in-sidebar-toggler-width: 100% !default;
 
 $book-bag-add-to-icon-content: '\f067' !default;
@@ -1238,7 +1283,7 @@ $modal-dialog-close-button-opacity: unset !default;
 $modal-dialog-close-button-right: 0 !default;
 $modal-dialog-close-button-right-sm-up: -60px !default;
 $modal-dialog-close-button-left-sm-up-rtl: -60px !default;
-$modal-dialog-close-button-focus-hover-opacity: unset;
+$modal-dialog-close-button-focus-hover-opacity: unset !default;
 
 
 
@@ -1257,7 +1302,7 @@ $footer-poweredby-img-margin-left: ($grid-gutter-width / 4) !default;
 $footer-poweredby-img-margin-right: ($grid-gutter-width / 4) !default;
 $footer-poweredby-font-size: small !default;
 
-$footer-link-text-decoration: $link-text-decoration;
+$footer-link-text-decoration: $link-text-decoration !default;
 
 
 
@@ -1324,7 +1369,7 @@ $jstree-children-ul-padding-left: 0 !default;
 $jstree-children-li-before-icon-content: '\f016' !default;
 $jstree-children-li-before-icon-display: inline-block !default;
 $jstree-children-li-before-icon-font-family: FontAwesome, sans-serif !default;
-$jstree-children-li-left-padding: $jstree-facet-node-padding-left;
+$jstree-children-li-left-padding: $jstree-facet-node-padding-left !default;
 $jstree-children-li-before-icon-width: $jstree-children-li-left-padding !default;
 
 $jstree-anchor-hyphens: auto !default;
diff --git a/themes/finc/scss/components/_breadcrumbs.scss b/themes/finc/scss/components/_breadcrumbs.scss
index 2dab593b5c7e4f17c8ea459ce311ca04184510b0..766fe2afd95dbbc230c77b35083e52c9e645c530 100644
--- a/themes/finc/scss/components/_breadcrumbs.scss
+++ b/themes/finc/scss/components/_breadcrumbs.scss
@@ -36,6 +36,7 @@
   // color of links in breadcrumbs
   a {
     color: $breadcrumb-color;
+    text-decoration: $breadcrumb-link-text-decoration;
 
     // more contrast: switch the colors
     &:focus,
diff --git a/themes/finc/scss/components/_buttons.scss b/themes/finc/scss/components/_buttons.scss
index 93df8968529bd0cacd293495d7b0431e6d030e64..52c564edaf07dae474c283811142d7c2fdb97efd 100644
--- a/themes/finc/scss/components/_buttons.scss
+++ b/themes/finc/scss/components/_buttons.scss
@@ -118,3 +118,10 @@
   border-radius: $toolbar-button-radius;
 }
 
+// Add focus highlighting to bookbag toolbar dropdown buttons
+.toolbar-btn {
+  &:focus,
+  &:hover {
+    outline: 1px solid $outline-default-color;
+  }
+}
\ No newline at end of file
diff --git a/themes/finc/scss/components/_header-active-filters.scss b/themes/finc/scss/components/_header-active-filters.scss
index 91433495e65832585aa58a041afe7b0dad94cb8e..e3c67f2e23ba82b0260332f98a2757e352ca886d 100644
--- a/themes/finc/scss/components/_header-active-filters.scss
+++ b/themes/finc/scss/components/_header-active-filters.scss
@@ -2,10 +2,16 @@
 // The structure is like so:
 // <!-- Outer container -->
 // <div class="active-filters">
-//   <!-- Reset all button -->
-//   <a class="reset-filters-btn" ....
+//   <!-- vertical bar for Reset all button and Show-all-filters-toggler
+//   <div class="filters-toggle-bar">
+//     <!-- Reset all button -->
+//     <a class="reset-filters-btn" ....
+//     <!-- Show-all-filters-toggler -->
+//     <a class="filters-toggle" data-target="#active-filters-mobile" > ..
+//     <div class="clearfix"></div>
+//   </div>
 //   <!-- Outer container for all individual filters -->
-//   <div class="filters">
+//   <div id="active-filters-mobile" class="filters filters-bar">
 //     <div class="title-value-pair">
 //       <!-- Filtergroup title -->
 //       <span class="filters-title">
@@ -16,38 +22,66 @@
 
 // set general text decoration on filters
 .filters {
-  & button,
-  & a {
+  button,
+  a {
     text-decoration: $search-filter-text-decoration;
   }
 }
 
 .active-filters {
-  // Outer container for all filters and reset button
+  // Outer container for all filters, reset button and show-all-filters-toggler
   // overwrite BS values where necessary
+  border: $active-filters-outer-container-border;
+  background-color: $active-filters-outer-container-background-color;
   display: $active-filters-outer-container-display;
+  margin-bottom: $active-filters-outer-container-margin-bottom;
+  padding: $active-filters-outer-container-padding;
 
 
-  // Outer container for all individual filters
+  // Outer container for all _individual_ filters
   .filters {
-    padding-left: $active-filters-outer-filters-container-padding-left;
+    padding-left: $active-filters-filter-padding-left;
+
+    // Individual filters' outer container
+    // Make this the same height as .reset-filters-btn and other navigation elements
+    // for better usability - keep '.filters' for specifity (overwriting BS3)
+
+    // unset BS values for proper focus highlighting of contained anchor
+    .filter-value {
+      background: transparent;
+      margin: 0;
+      padding: 0;
+
+
+      // define styles for contained anchor
+      a {
+        // the background filter value in BS3 is '$list-group-active-bg'
+        background: $search-filter-values-remove-bg;
+        display: inline-block;
+        height: $navigation-element-default-height;
+        margin-bottom: $search-filters-margin-bottom;
+        padding: $search-filters-padding;
+        vertical-align: $search-filter-remove-button-vertical-align;
+
+        &:focus,
+        &:hover {
+          background: $search-filter-remove-hover-bg;
+          color: $search-filter-remove-hover-color;
+          // overwrite outline-offset ('a:focus')
+          outline-offset: 0;
+        }
+      }
+    }
   }
 
-  // Individual filters' outer container
-  // Make this the same height as .reset-filters-btn and other navigation elements
-  // for better usability - keep '.filters' for specifity (overwriting BS3)
-  .filters .filter-value {
-    // the background filter value in BS3 is '$list-group-active-bg'
-    background: $search-filter-values-remove-bg;
-    height: $navigation-element-default-height;
-    margin-bottom: $search-filters-margin-bottom;
-    padding: $search-filters-padding;
-
-    &:focus,
-    &:hover {
-      background: $search-filter-remove-hover-bg;
-      color: $search-filter-remove-hover-color;
-    }
+  // keep '.search-filter-dropdown' for specifity to overwrite BS
+  .search-filter-dropdown .dropdown-menu .filter-value a {
+    width: 100%;
+  }
+
+  // show-all-filters-toggler
+  .filters-toggle {
+    float: $search-filter-all-filters-toggle;
   }
 }
 
@@ -56,6 +90,7 @@
 .reset-filters-btn {
   background-color: $search-filter-remove-all-bg;
   color: $search-filter-remove-all-color;
+  float: $search-filter-remove-all-float;
 
   &:focus,
   &:hover {
@@ -65,16 +100,13 @@
 }
 
 
-// Set focus and hover styles for individual filter items'
-// outer container ('.filters .filter-value') and filter items ('.search-filter-remove')
-.filters .filter-value,
-.search-filter-remove {
+// Set focus and hover styles for individual filter items' ('.search-filter-remove')
+.search-filter-remove,
+.search-filter-remove:visited, {
   color: $search-filter-values-remove-color;
 
   &:focus,
-  &:hover,
-  &:visited:focus,
-  &:visited:hover {
+  &:hover {
     // Keep '.active-filters' for specifity to overwrite BS
     .active-filters & {
       background: $search-filter-remove-hover-bg;
@@ -85,20 +117,7 @@
   }
 
 
-  // Make this same color as un-visited item
-  &:visited {
-    // Keep '.active-filters' for specifity to overwrite BS
-    .active-filters & {
-      color: inherit;
-      text-decoration: inherit;
-    }
-  }
-}
-
-// Set color of individual filters when focus is on outer container
-.search-filter-remove,
-.search-filter-remove:visited {
-
+  // Set color of the individual filters when FOCUS is ON OUTER container
   .filters .filter-value:focus &,
   .filters .filter-value:hover & {
     background: $search-filter-remove-hover-bg;
@@ -110,13 +129,9 @@
       color: $search-filter-remove-icon-hover-color;
     }
   }
-}
 
-// This is the colored, button-like element with the 'x' icon
-.search-filter-remove {
-  // Align with text inside the element
-  vertical-align: $search-filter-remove-button-vertical-align;
 
+  // This is the colored, button-like element with the 'x' icon
   .text {
     // Create ellipsis for overlong filter text
     display: $search-filter-remove-button-text-display;
@@ -130,6 +145,8 @@
   // Set icon content
   &::after {
     content: $search-filter-remove-icon;
+    display: $search-filter-remove-icon-display;
+    margin-top: $search-filter-remove-icon-top-margin;
     vertical-align: $search-filter-remove-icon-vertical-align;
 
     // Move 'x' to the right of the buttons in dropdown
diff --git a/themes/finc/scss/components/_header-navbar.scss b/themes/finc/scss/components/_header-navbar.scss
index 2cffc9ceda3d679eca5326d651e3047f62ee739e..f9f8e523a6ecebb549c8e4d93ea703edbc5eebd2 100644
--- a/themes/finc/scss/components/_header-navbar.scss
+++ b/themes/finc/scss/components/_header-navbar.scss
@@ -54,6 +54,9 @@ header,
 // Keep navbar on left, when off-canvas is active, and give it the same appearance as ever
 // the '.active' class is set on body when the user hits the button to display the sidebar
 .navbar-fixed-top {
+  border-bottom: $navbar-fixed-top-border-bottom-width;
+
+
   .offcanvas.active & {
     margin-top: -$navbar-height-xs;
     position: relative;
@@ -70,11 +73,6 @@ header,
   // body -> padding-top would need to be taller than navbar minimum-height
   min-height: $navbar-height;
 
-  // Advanced search
-  .template-name-advanced & {
-    min-height: $navbar-min-height-adv-search;
-  }
-
   // Set min height for xs
   @media (max-width: $screen-xs-max) {
     min-height: $navbar-height-xs;
@@ -172,11 +170,6 @@ header,
     // position to the right!
     order: $header-menu-flex-order-sm-up;
     padding-top: $header-menu-padding-top-sm-up;
-
-    // Make right-hand header parts full width for advanced search page since it doesn't use any left-hand header parts
-    .template-name-advanced & {
-      flex: $header-menu-flex-adv-srch-sm-up;
-    }
   }
 }
 
diff --git a/themes/finc/scss/components/_hierarchy-tree.scss b/themes/finc/scss/components/_hierarchy-tree.scss
index 0830d5587083e21758b56be73fb98085349ec73f..45b072e82bde48d1e47c9cd5c7d938812cebcbfa 100644
--- a/themes/finc/scss/components/_hierarchy-tree.scss
+++ b/themes/finc/scss/components/_hierarchy-tree.scss
@@ -127,3 +127,17 @@
   }
 }
 
+/* ***************************************************************************************** */
+/* TODO move following styles to seprate component (_collection-view.scss) in finc or de_105 */
+/* TODO upcoming refs #22979 */
+
+.collection-control {
+  display: inline-block;
+  float: left;
+  margin-top: 6px;
+  width: 49%;
+}
+
+#moreInfoToggle.collapsed {
+  margin-bottom: 2em;
+}
diff --git a/themes/finc/scss/components/_record.scss b/themes/finc/scss/components/_record.scss
new file mode 100644
index 0000000000000000000000000000000000000000..7c2088ec6c870e7ab42b616930267e26aafc2df8
--- /dev/null
+++ b/themes/finc/scss/components/_record.scss
@@ -0,0 +1,10 @@
+// Use this for all record element styles (record view)
+// excluding record tabs -> see _record-tabs.scss
+
+// center access icon / cover on (mobile) record view by using full view port width: #23135
+.record .media-left,
+.record .media-right {
+  @media (max-width: $screen-xs-max) {
+    width: revert;
+  }
+}
\ No newline at end of file
diff --git a/themes/finc/scss/components/_result-list.scss b/themes/finc/scss/components/_result-list.scss
index 941f92ce15b4e581ee0cd9e8f04d8af39f94f350..0092eb8aa7f539d3c715387d2ceb5213650ad669 100644
--- a/themes/finc/scss/components/_result-list.scss
+++ b/themes/finc/scss/components/_result-list.scss
@@ -2,6 +2,11 @@
 // For Check boxes for bulk actions and bulk action buttons, see bulk-action-buttons.scss
 // Pls. note that the result elements are also used in several myaccount views, such as 'Favorites'
 
+.result-body {
+  @media (min-width: $screen-sm-min) {
+    padding-right: $result-body-right-padding-sm-up;
+  }
+}
 
 // *****************************************************************
 // ************ Media container ************************************
diff --git a/themes/finc/scss/components/_search.scss b/themes/finc/scss/components/_search.scss
index 528aeefad137439f4c6971311114de56e41227f1..774be16e16d3333e1d9db79632a39a97746895f5 100644
--- a/themes/finc/scss/components/_search.scss
+++ b/themes/finc/scss/components/_search.scss
@@ -123,6 +123,16 @@
       border: $search-form-advanced-search-button-border;
     }
   }
+
+  // when nav-tabs are active, style them flex-style as rest of search box; to activate, add
+  // [SearchTabs]
+  // Solr=Catalog
+  // WorldCat=WorldCat
+  // to dev/config.ini
+  .nav-tabs {
+    display: flex;
+    flex-basis: 100%;
+  }
 }
 
 
@@ -146,52 +156,7 @@
   }
 }
 
-// Advanced search terms in header (visible only after an advanced search was run)
-// i.e. the search terms entered
-.adv_search_terms {
-  background-color: $adv-search-terms-bg;
-  border: $adv-search-terms-border;
-  margin-bottom: $adv-search-terms-bottom-margin;
-  padding: $adv-search-terms-padding;
-  width: $adv-search-terms-width;
-}
-
-// Advanced search links in header (visible only after an advanced search was run)
-// i.e. 'Edit advanced search' | 'New advanced search' ...
-.adv_search_links {
-  border: $adv-search-links-border;
-  list-style: $adv-search-links-list-style;
-  margin: $adv-search-links-margin;
-  padding: $adv-search-links-padding;
-
-  @media (min-width: $screen-sm-min) {
-    margin-top: $adv-search-links-top-margin-sm;
-  }
-
-  a {
-    border-top: $adv-search-links-anchor-top-border;
-    display: $adv-search-links-anchor-display;
-    padding-left: $adv-search-links-anchor-padding-left;
-
-    &:last-of-type {
-      border-bottom: 0;
-    }
-
-    // 786px and above as inline list
-    @media (min-width: $screen-sm-min) {
-      border-bottom: $adv-search-links-anchor-border-bottom-sm-up;
-      border-right: $adv-search-links-anchor-border-right-sm-up;
-      display: $adv-search-links-anchor-display-sm-up;
-      padding-right: $adv-search-links-anchor-padding-right-sm-up;
-
-      &:last-of-type {
-        border-right: 0;
-      }
-    }
-  }
-}
-
-////////////// TODO: Review /////////////////////////////
+// FIXME: CHECK THE FOLLOWING for redundant code - it should all relate to the advanced search page but may not - CK
 // .tab-content.adv-search container wraps advanced search terms and links
 .adv-search {
   @media (max-width: $screen-xs-max) {
@@ -317,6 +282,105 @@
 }
 
 
+// *****************************************************************
+// ************ Display of Search Terms and Options ****************
+// ************ _AFTER_ sucessful advanced search   ****************
+// *****************************************************************
+
+// FIXME: REMOVE THE FOLLOWING TWO SECTIONS + all RELATED VARIABLES when
+//  all instances have the new search terms display on top of search results - CK
+// <-- REMOVE FROM HERE
+// Advanced search terms in header (visible only after an advanced search was run)
+// i.e. the search terms entered
+.adv_search_terms {
+  background-color: $adv-search-terms-bg;
+  border: $adv-search-terms-border;
+  margin-bottom: $adv-search-terms-bottom-margin;
+  padding: $adv-search-terms-padding;
+  width: $adv-search-terms-width;
+}
+
+// Advanced search links in header (visible only after an advanced search was run)
+// i.e. 'Edit advanced search' | 'New advanced search' ...
+.adv_search_links {
+  border: $adv-search-links-border;
+  list-style: $adv-search-links-list-style;
+  margin: $adv-search-links-margin;
+  padding: $adv-search-links-padding;
+
+  @media (min-width: $screen-sm-min) {
+    margin-top: $adv-search-links-top-margin-sm;
+  }
+
+  a {
+    border-top: $adv-search-links-anchor-top-border;
+    display: $adv-search-links-anchor-display;
+    padding-left: $adv-search-links-anchor-padding-left;
+
+    &:last-of-type {
+      border-bottom: 0;
+    }
+
+    // 786px and above as inline list
+    @media (min-width: $screen-sm-min) {
+      border-bottom: $adv-search-links-anchor-border-bottom-sm-up;
+      border-right: $adv-search-links-anchor-border-right-sm-up;
+      display: $adv-search-links-anchor-display-sm-up;
+      padding-right: $adv-search-links-anchor-padding-right-sm-up;
+
+      &:last-of-type {
+        border-right: 0;
+      }
+    }
+  }
+}
+
+// <-- REMOVE TO HERE
+
+// NEW VERSION
+.adv-search-box {
+  border: $adv-search-box-border;
+  background-color: $adv-search-box-background-color;
+  display: $adv-search-box-display;
+  margin-bottom: $adv-search-box-margin-bottom;
+  padding: $adv-search-box-padding;
+}
+
+.adv-terms-label {
+  display: flex;
+  flex-basis: 100%;
+}
+
+.adv-terms,
+.adv-delete {
+  flex: content;
+}
+
+.adv-terms {
+  word-break: break-word;
+}
+
+.adv-delete {
+  margin-top: 1.5rem;
+
+
+  .btn {
+    float: right;
+    vertical-align: bottom;
+  }
+}
+
+// Lend search terms and options the same height as the delete button for better alignment
+// Base this on the same code as for '.search-filter-toggle' in bootstrap
+.adv-edit {
+  @extend .btn;
+  // but align to left when there are many terms
+  padding-left: 0;
+  text-align: left;
+  white-space: normal;
+}
+
+
 // *****************************************************************
 // ************ Autocomplete ***************************************
 // *****************************************************************
diff --git a/themes/finc/scss/finc.scss b/themes/finc/scss/finc.scss
index 8921fad525c04d245a30f0f29759d7647aaffb97..c21d128ffddac15c0dc43cd0e3f53d6b81d227ff 100644
--- a/themes/finc/scss/finc.scss
+++ b/themes/finc/scss/finc.scss
@@ -33,6 +33,7 @@
 @import 'components/modal';
 @import 'components/offcanvas';
 @import 'components/pagination';
+@import 'components/record';
 @import 'components/record-tabs';
 @import 'components/resolver-links';
 @import 'components/result-list';
@@ -96,13 +97,6 @@ body {
     padding-top: 8.5rem;
   }
 
-  // for XS make exception for adv. search results
-  &.template-name-advanced {
-    @media (max-width: $screen-xs-max) {
-      padding-top: 3.25rem;
-    }
-  }
-
   // for tablet
   @media (min-width: $screen-sm-min) {
     padding-top: $navbar-height-sm;
diff --git a/themes/finc/templates/RecordDriver/DefaultRecord/list-entry.phtml b/themes/finc/templates/RecordDriver/DefaultRecord/list-entry.phtml
index f4e2c30343ff92bfc573938293db511978f75c5f..9107567f38bb821fdf7781c993ac22349d191002 100644
--- a/themes/finc/templates/RecordDriver/DefaultRecord/list-entry.phtml
+++ b/themes/finc/templates/RecordDriver/DefaultRecord/list-entry.phtml
@@ -46,8 +46,8 @@
             <?php /* finc: add aria-label and aria-describedby #18019 */ ?>
             <?php $describedById = $driver->getSourceIdentifier() . '|' . $driver->getUniqueId(); ?>
             <span id="<?=$describedById?>" class="title" lang=""><?=$this->record($this->driver)->getTitleHtml()?></span>
-            <?php /* finc uses <p> and aria for alerts */ ?>
-            <p class="alert alert-info" aria-live="polite">
+            <?php /* finc uses <p> and aria for alerts, use a div here, or h2 inside <p> will be invalid */ ?>
+            <div class="alert alert-info" aria-live="polite">
                     <?= $this->translate('record_from_cache')?>
                     <?php if ($queryParams = $this->record($this->driver)->getAdvancedSearchQueryParams()): ?>
                       <?php /* finc: add h2 for record title #22158 */ ?>
@@ -55,9 +55,9 @@
                         <a href="<?=$this->url('search-results', [], ['query' => $queryParams])?>"><?=$this->transEsc('search_cached_record', ['%%title_full%%' => $this->driver->getTitle()])?></a>
                       </h2>
               <?php endif; ?>
-            </p>
+            </div>
           <?php elseif (!$missing): ?>
-            <?php /* finc adds aria-lable and aria-describedby #18019 */ ?>
+            <?php /* finc adds aria-label and aria-describedby #18019 */ ?>
             <?php $describedById = $driver->getSourceIdentifier() . '|' . $driver->getUniqueId(); ?>
             <a href="<?=$this->recordLink()->getUrl($this->driver)?>" class="getFull" data-view="<?=$this->params->getOptions()->getListViewOption() ?>">
               <?php /* finc: change span to h2 element #22158 */ ?>
@@ -239,9 +239,9 @@
               <?=$this->transEsc('Delete') ?>
             </a>
             <ul class="dropdown-menu" role="menu" aria-labelledby="<?= $dLabel ?>">
-              <li>
+              <li role="none">
                 <?php /* #17711 give user feedback and dont reload page after deleting */ ?>
-                <a href="javascript:document.getElementById('<?=$dLabel?>').focus();" title="<?= $this->transEsc('confirm_delete_brief') ?>" onClick="
+                <a role="menuitem" href="javascript:document.getElementById('<?=$dLabel?>').focus();" title="<?= $this->transEsc('confirm_delete_brief') ?>" onClick="
                   let next = $(this).closest('.result.ajaxItem').next('.result.ajaxItem').find('.del-button');
                   if (next.length === 0) {
                     next = $('[id^=delete_list_items_]').first();
@@ -269,7 +269,9 @@
                   <?=$this->transEsc('confirm_dialog_yes')?>
                 </a>
               </li>
-              <li><a href="javascript:document.getElementById('<?=$dLabel?>').focus();"><?=$this->transEsc('confirm_dialog_no')?></a></li>
+              <li role="none">
+                <a role="menuitem" href="javascript:document.getElementById('<?=$dLabel?>').focus();"><?=$this->transEsc('confirm_dialog_no')?></a>
+              </li>
             </ul>
           </div>
   
diff --git a/themes/finc/templates/RecordDriver/FincMissing/record-icon.phtml b/themes/finc/templates/RecordDriver/FincMissing/record-icon.phtml
index 84bd80f349eccfae24c43c34dddb9fcf1ffe6fb7..5214b8aaf8d58b4a9cea1067f091a9007fae6421 100644
--- a/themes/finc/templates/RecordDriver/FincMissing/record-icon.phtml
+++ b/themes/finc/templates/RecordDriver/FincMissing/record-icon.phtml
@@ -1,4 +1,21 @@
+<!-- finc - RecordDriver - fincMissing - record-icon -->
+<?php
+/**
+ *
+ * origin: finc
+ *
+ * called by view helper/controller: --
+ *
+ * usage: renders an icon for missing records
+ *
+ * modified for de_l152:
+ *
+ * configured in: --
+ *
+ **/
+?>
 <span class="access-icon hidden-print">
   <i class="fa fa-times-circle" aria-hidden="true"></i>
-  <span class="hidden-xs"> <?=$this->transEsc("Missing Record")?></span>
+  <span class="visible-md-up-sr-only"> <?=$this->transEsc("Missing Record")?></span>
 </span>
+<!-- finc - RecordDriver - fincMissing - record-icon - END -->
diff --git a/themes/finc/templates/RecordDriver/SolrLido/core.phtml b/themes/finc/templates/RecordDriver/SolrLido/core.phtml
index 476427bd6c5626fc0cfcb65197db1886df61ba6a..5cf36cab4d6caf539635d65fd955639d4366a934 100644
--- a/themes/finc/templates/RecordDriver/SolrLido/core.phtml
+++ b/themes/finc/templates/RecordDriver/SolrLido/core.phtml
@@ -31,7 +31,7 @@
   $preview = $this->record($this->driver)->getPreviews();
   ?>
   <?php if ($QRCode || $cover || $preview): ?>
-    <div class="media-left <?=$this->escapeHtmlAttr($coverDetails['size'])?> img-col"?>
+    <div class="media-left <?=$this->escapeHtmlAttr($coverDetails['size'])?> img-col">
       <?php /* Display thumbnail if appropriate: */ ?>
       <?php if ($cover): ?>
         <?=$cover?>
diff --git a/themes/finc/templates/RecordDriver/SolrMarc/core.phtml b/themes/finc/templates/RecordDriver/SolrMarc/core.phtml
index 356d8967fda3d5649e61fbdf81cbfedecc41e5fb..2f58f7f1d328e0c12dbb78e377967f28e4205987 100644
--- a/themes/finc/templates/RecordDriver/SolrMarc/core.phtml
+++ b/themes/finc/templates/RecordDriver/SolrMarc/core.phtml
@@ -71,9 +71,8 @@
       $coreFields = $formatter->getData($driver, $formatter->getDefaults('core-marc'));
       ?>
       <?php if (!empty($coreFields)): ?>
-        <?php /* finc adds code for responsive data table here - CK */ ?>
-      <table class="table table-striped table-resp-data">
-        <caption class="sr-only"><?= $this->transEsc('Bibliographic Details') ?></caption>
+      <?php /* finc adds code for responsive data table here - CK */ ?>
+      <table class="table table-striped table-resp-data" aria-label="<?=$this->transEsc('Bibliographic Details')?>">
           <?php foreach ($coreFields as $current): ?>
             <?php if ($current['label'] == null): ?>
               <?= $current['value'] ?>
diff --git a/themes/finc/templates/RecordTab/collectionlist.phtml b/themes/finc/templates/RecordTab/collectionlist.phtml
new file mode 100644
index 0000000000000000000000000000000000000000..54d4e61c391497728a63b7ab0b2839c0b50374eb
--- /dev/null
+++ b/themes/finc/templates/RecordTab/collectionlist.phtml
@@ -0,0 +1,139 @@
+<!-- finc: RecordTab - collectionlist -->
+<?php
+  // Set page title.
+  $this->headTitle($this->translate('Collection Items') . ': ' . $this->driver->getBreadcrumb());
+
+  // Get search results
+  $results = $this->tab->getResults();
+  $params = $this->tab->getParams();
+  $searchDetails = ['results' => $results, 'params' => $params, 'indexStart' => 1];
+
+  $filterList = $params->getFilterList(true);
+  $checkboxFilters = $params->getCheckboxFacets();
+?>
+
+<div class="<?=$this->layoutClass('mainbody')?>">
+  
+  <?php /* de_15: add SECOND offcanvas-toggler here,
+ this one should hide the '.icon-bar' of the Record View and
+ show only the Facets Sidebar for the collection - CK */ ?>
+  <span class="offcanvas-toggler">
+    <a class="search-filter-toggle collections visible-xs" href="javascript:" data-toggle="offcanvas" title="<?= $this->transEsc('sidebar_expand_collections') ?>">
+      <?=$this->transEsc('sidebar_expand_collections')?>
+    </a>
+  </span>
+
+<?php if (($recordTotal = $results->getResultTotal()) > 0): // only display these at very top if we have results?>
+  <?php foreach ($results->getRecommendations('top') as $current): ?>
+    <?=$this->recommend($current)?>
+  <?php endforeach; ?>
+  <?php endif; ?>
+
+  <?php /* finc: do not use classname 'collection-list-results' here */ /*
+  <div> */ ?>
+    <?php /* finc: we use search in sidebar, see  'Recommend/CollectionSideFacets.phtml' */ /*
+    <div class="collection-control">
+      <form class="form-inline" role="form" method="get" name="keywordFilterForm" id="keywordFilterForm">
+        <div class="input-group">
+          <input id="keywordFilter_lookfor" type="text" name="lookfor" placeholder="<?=$this->transEsc('Search within collection')?>" value="<?=$params->getDisplayQuery()?>" class="form-control">
+            <?php foreach ($filterList as $field => $filters): ?>
+                <?php foreach ($filters as $filter): ?>
+                <input type="hidden" name="filter[]" value="<?=$this->escapeHtmlAttr($filter['field'])?>:&quot;<?=$this->escapeHtmlAttr($filter['value'])?>&quot;" />
+                <?php endforeach; ?>
+            <?php endforeach; ?>
+          <input type="hidden" name="limit" value="<?=$params->getLimit() ?>" />
+          <input type="hidden" name="sort" value="<?=$params->getSort() ?>" />
+          <span class="input-group-btn">
+            <button class="btn btn-primary" type="submit" name="submit">
+              <span class="sr-only"><?=$this->transEsc('Search')?></span><i class="fa fa-search"></i>
+            </button>
+          </span>
+        </div>
+      </form>
+    </div>
+    */?>
+    <div class="collection-control">
+      <?=$this->render('search/controls/limit.phtml', $searchDetails)?>
+    </div>
+    <div class="collection-control">
+      <?=$this->render('search/controls/sort.phtml', $searchDetails)?>
+    </div>
+  <?php /*
+  </div>
+  */?>
+
+
+  <?php if ($filterList || $checkboxFilters): ?>
+    <?=$this->render(
+    'search/filters.phtml',
+    [
+        'urlQuery' => $results->getUrlQuery(),
+        'filterList' => $filterList,
+        'checkboxFilters' => $checkboxFilters,
+        'searchClassId' => $this->searchClassId,
+        'searchType' => 'basic',
+      ]
+); ?>
+  <?php endif; ?>
+
+  <div class="collection-list-results">
+    <?php if ($recordTotal > 0): ?>
+      <div class="clearfix hidden-print">
+        <?php /* finc: We're NEITHER showing the found xxx of yyy number NOR the query time*/ ?>
+        <?php /*
+        <div class="pull-left flip">
+          <?php
+          $transParams = [
+            '%%start%%' => $this->localizedNumber($results->getStartRecord()),
+            '%%end%%'   => $this->localizedNumber($results->getEndRecord()),
+            '%%total%%' => $this->localizedNumber($recordTotal)
+          ];
+          ?>
+        <?php if (!isset($this->skipTotalCount)): ?>
+          <?=$this->translate('showing_items_of_html', $transParams); ?>
+        <?php else: ?>
+          <?=$this->translate('showing_items_html', $transParams); ?>
+        <?php endif; ?>
+      */?>
+      </div>
+      <form class="form-inline" method="post" name="bulkActionForm" action="<?=$this->url('cart-searchresultsbulk')?>">
+          <?=$this->context($this)->renderInContext('search/bulk-action-buttons.phtml', $searchDetails + ['idPrefix' => ''])?>
+          <?=$this->render('search/list-' . $results->getParams()->getView() . '.phtml', $searchDetails)?>
+          <?=$this->paginationControl($results->getPaginator(), 'Sliding', 'search/pagination.phtml', ['results' => $results])?>
+      </form>
+    <?php else: ?>
+      <?php /* finc: change h4 to h3 */ ?>
+      <h3><?=$this->transEsc($params->getDisplayQuery() || ($filterCount ?? 0) > 0 ? 'nohit_heading' : 'collection_empty')?></h3>
+      <div class="clearfix">
+      </div>
+    <?php endif; ?>
+  </div>
+</div>
+
+<?php /* finc: keep '.bottom' to differentiate top and bottom sidebars, CK */ ?>
+<div class="bottom <?=$this->layoutClass('sidebar')?>">
+<?php /* finc: we use search in sidebar, not in mainbody above, CK */ ?>
+  <h2><?=$this->transEsc('Search Collection Items')?></h2>
+  <form class="form-inline" role="form" method="get" name="keywordFilterForm" id="keywordFilterForm">
+    <div class="input-group">
+      <input id="keywordFilter_lookfor" type="text" name="lookfor" placeholder="<?=$this->transEsc('Search within collection')?>" value="<?=$params->getDisplayQuery()?>" class="form-control">
+      <?php foreach ($filterList as $field => $filters): ?>
+        <?php foreach ($filters as $filter): ?>
+          <input type="hidden" name="filter[]" value="<?=$this->escapeHtmlAttr($filter['field'])?>:&quot;<?=$this->escapeHtmlAttr($filter['value'])?>&quot;" />
+        <?php endforeach; ?>
+      <?php endforeach; ?>
+      <input type="hidden" name="limit" value="<?=$params->getLimit() ?>" />
+      <input type="hidden" name="sort" value="<?=$params->getSort() ?>" />
+      <span class="input-group-btn">
+        <button class="btn btn-primary" type="submit" name="submit">
+          <span class="sr-only"><?=$this->transEsc('Search Collection Items')?></span><i class="fa fa-search" aria-hidden="true"></i>
+        </button>
+      </span>
+    </div>
+  </form>
+
+  <?php foreach ($results->getRecommendations('side') as $current): ?>
+    <?=$this->recommend($current)?>
+  <?php endforeach; ?>
+</div>
+<!-- finc: RecordTab - collectionlist - END -->
\ No newline at end of file
diff --git a/themes/finc/templates/RecordTab/holdingsils/standard.phtml b/themes/finc/templates/RecordTab/holdingsils/standard.phtml
index 87229c24aba014a539a494126619a2b2f183ada3..3c1b35ad1800e29b394f5285d4f9e7837a094e41 100644
--- a/themes/finc/templates/RecordTab/holdingsils/standard.phtml
+++ b/themes/finc/templates/RecordTab/holdingsils/standard.phtml
@@ -28,10 +28,6 @@
           <?php /* Begin Available Items (Holds) */ ?>
            <span class="text-success"><?=$this->transEsc("Available")?><link property="availability" href="http://schema.org/InStock" /></span>
           <?php if ($holding['link'] ?? false): ?>
-          <?php /* finc adds class '.hidden-print' CK */ ?>
-            <a class="<?= $check ? 'checkRequest ' : '' ?>placehold hidden-print" <?php if (!empty($holding['linkLightbox'])): ?>data-lightbox <?php endif; ?>href="<?= $this->recordLink()->getRequestUrl($holding['link']) ?>">
-              <i class="fa fa-flag" aria-hidden="true"></i>&nbsp;<?= $this->transEsc($check ? "Check Hold" : "Place a Hold") ?>
-            </a>
             <?php /* finc: add class .hidden-print CK */ ?>
             <a class="<?=$check ? 'checkRequest ' : ''?>placehold hidden-print" <?php if (!empty($holding['linkLightbox'])): ?>data-lightbox <?php endif; ?>href="<?=$this->recordLink()->getRequestUrl($holding['link'])?>"><i class="fa fa-flag" aria-hidden="true"></i>&nbsp;<?=$this->transEsc($check ? "Check Hold" : "Place a Hold")?></a>
           <?php endif; ?>
diff --git a/themes/finc/templates/ajax/resolverLink.phtml b/themes/finc/templates/ajax/resolverLink.phtml
index 7c9b03763609794a698148ef980bf373666cd400..c67e5633863e2292d13d1d36f68637e059ed2374 100644
--- a/themes/finc/templates/ajax/resolverLink.phtml
+++ b/themes/finc/templates/ajax/resolverLink.phtml
@@ -1,7 +1,8 @@
 <!-- finc - templates - ajax - resolverLink -->
 <?php if (!empty($link['href'])): ?>
     <?php /* finc-specific change #7986 - CK - traffic light */ ?>
-    <div class="show-availability">
+    <div class="flex">
+      <div class="show-availability">
         <span class="sr-only">
           <?=$this->translate('Availability')?>: <?=$this->transEsc('resolver_link_access_' . $link['access'])?>
         </span>
@@ -10,23 +11,26 @@
         <span class="second"></span>
         <span class="last"></span>
       </div>
+      </div>
+      <?php /* finc-specific change #7986 - END */ ?>
+      <div>
+        <?= $this->externalLink(
+            $this->escapeHtmlAttr($link['href']),
+            $link['title'] ?? '',
+            [
+                'title' => $link['service_type'] ?? '',
+                'class' => !empty($link['access']) ? 'access-' . $link['access'] : ''
+            ]
+        ) ?>
+        <?php /* finc-specific change #5334 - CK */ ?>
+        <small>
+            <?= isset($link['coverage']) ? $this->escapeHtml($link['coverage']) : '' ?>
+            <?= isset($link['coverageHref'])
+                ? $this->externalLink($link['coverageHref'], $this->translate('Readme'))
+                : '' ?>
+        </small>
+      </div>
     </div>
-    <?php /* finc-specific change #7986 - END */ ?>
-    <?= $this->externalLink(
-        $this->escapeHtmlAttr($link['href']),
-        $link['title'] ?? '',
-        [
-            'title' => $link['service_type'] ?? '',
-            'class' => !empty($link['access']) ? 'access-' . $link['access'] : ''
-        ]
-    ) ?>
-    <?php /* finc-specific change #5334 - CK */ ?>
-    <small>
-        <?= isset($link['coverage']) ? $this->escapeHtml($link['coverage']) : '' ?>
-        <?= isset($link['coverageHref'])
-            ? $this->externalLink($link['coverageHref'], $this->translate('Readme'))
-            : '' ?>
-    </small>
     <?php /* finc-specific change #5334 - END */ ?>
 <?php else: ?>
     <?=isset($link['title'])?$this->escapeHtml($link['title']):''?> <?=isset($link['coverage'])?$this->transEsc($link['coverage']):''?>
diff --git a/themes/finc/templates/cart/cart.phtml b/themes/finc/templates/cart/cart.phtml
index d1d19ea46dddcb88883526bc30d39ff6b1507fcf..86a6df065a720f1c82a1b77649a587865dc6cbb2 100644
--- a/themes/finc/templates/cart/cart.phtml
+++ b/themes/finc/templates/cart/cart.phtml
@@ -4,7 +4,7 @@
   $this->headTitle($this->translate('Book Bag'));
 
   // Set up breadcrumbs:
-  $this->layout()->breadcrumbs = '<li>' . $this->searchMemory()->getLastSearchLink($this->transEsc('Search'), '', '</li> ')
+  $this->layout()->breadcrumbs = $this->searchMemory()->getLastSearchLink($this->transEsc('Search'), '<li>', '</li> ')
 ?>
 <?php /* finc: use h1 for correct header structure */ ?>
 <h1><?=$this->transEsc('Book Bag') ?></h1>
@@ -22,37 +22,45 @@
         </label>
       </div>
       <?php if ($this->userlist()->getMode() !== 'disabled'): ?>
-        <button type="submit" class="toolbar-btn btn-type-save" name="saveCart" value="1" title="<?=$this->transEsc('bookbag_save')?>">
+        <button type="submit" class="toolbar-btn btn-type-save" name="saveCart" title="<?=$this->transEsc('bookbag_save')?>" value="1">
           <?=$this->transEsc('Save')?>
         </button>
       <?php endif; ?>
-      <button type="submit" class="toolbar-btn btn-type-email" name="email" value="1" title="<?=$this->transEsc('bookbag_email')?>">
+      <button type="submit" class="toolbar-btn btn-type-email" name="email" title="<?=$this->transEsc('bookbag_email')?>" value="1">
         <?=$this->transEsc('Email')?>
       </button>
       <?php $exportOptions = $this->export()->getActiveFormats('bulk'); if (count($exportOptions) > 0): ?>
-        <button type="submit" class="toolbar-btn btn-type-export" name="export" value="1" title="<?=$this->transEsc('bookbag_export')?>">
+        <button type="submit" class="toolbar-btn btn-type-export" name="export" title="<?=$this->transEsc('bookbag_export')?>" value="1">
           <?=$this->transEsc('Export')?>
         </button>
       <?php endif; ?>
-      <button type="submit" class="toolbar-btn btn-type-print dropdown-toggle" name="print" value="1" title="<?=$this->transEsc('print_selected')?>">
+      <button type="submit" class="toolbar-btn btn-type-print" name="print" title="<?=$this->transEsc('print_selected')?>" value="1">
         <?=$this->transEsc('Print')?>
       </button>
       <div class="btn-group" id="cartDelete">
-        <button type="submit" name="delete" value="1" class="toolbar-btn btn-type-delete dropdown-toggle" data-toggle="dropdown" id="cart-delete-label">
+        <button type="submit" name="delete" class="toolbar-btn btn-type-delete dropdown-toggle" data-toggle="dropdown" id="cart-delete-label" value="1">
           <?=$this->transEsc('Delete')?>
         </button>
         <ul class="dropdown-menu" role="menu" aria-labelledby="cart-delete-label">
-          <li><a id="cart-confirm-delete" onClick="submitFormWithButton(this, 'delete')" title="<?=$this->transEsc('confirm_delete')?>"><?=$this->transEsc('confirm_dialog_yes')?></a></li>
-          <li><a><?=$this->transEsc('confirm_dialog_no')?></a></li>
+          <li role="none">
+            <a href="javascript:" id="cart-confirm-delete" title="<?=$this->transEsc('confirm_delete')?>" role="menuitem"><?=$this->transEsc('confirm_dialog_yes')?></a>
+          </li>
+          <li role="none">
+            <a href="javascript:" role="menuitem"><?=$this->transEsc('confirm_dialog_no')?></a>
+          </li>
         </ul>
       </div>
       <div class="btn-group">
-        <button type="submit" class="toolbar-btn btn-type-empty dropdown-toggle" name="empty" value="1" data-toggle="dropdown" id="cart-empty-label">
+        <button type="submit" class="toolbar-btn btn-type-empty dropdown-toggle" name="empty" data-toggle="dropdown" id="cart-empty-label" value="1">
           <?=$this->transEsc('Empty Book Bag')?>
         </button>
         <ul class="dropdown-menu" role="menu" aria-labelledby="cart-empty-label">
-          <li><a id="cart-confirm-empty" onClick="submitFormWithButton(this, 'empty')" title="<?=$this->transEsc('bookbag_confirm_empty')?>"><?=$this->transEsc('confirm_dialog_yes')?></a></li>
-          <li><a onClick="$('.fa.fa-spinner').remove()"><?=$this->transEsc('confirm_dialog_no')?></a></li>
+          <li role="none">
+            <a href="javascript:" id="cart-confirm-empty" title="<?=$this->transEsc('bookbag_confirm_empty')?>" role="menuitem"><?=$this->transEsc('confirm_dialog_yes')?></a>
+          </li>
+          <li role="none">
+            <a href="javascript:" id="cart-refuse-empty" onClick="$('.fa.fa-spinner').remove()" role="menuitem"><?=$this->transEsc('confirm_dialog_no')?></a>
+          </li>
         </ul>
       </div>
     </div>
@@ -61,11 +69,17 @@
 </form>
 
 <?php
-  $script = <<<JS
+  $script = <<<'JS'
   function submitFormWithButton(link, name) {
     $('#dropdown_value').attr('name', name).val(1);
     $(link).closest('form').submit();
   }
+  $("#cart-confirm-delete").click(function($e) {
+      submitFormWithButton(this, 'delete');
+  });
+  $("#cart-confirm-empty").click(function($e) {
+      submitFormWithButton(this, 'empty');
+  });
 JS;
 ?>
 <?=$this->inlineScript(\Zend\View\Helper\HeadScript::SCRIPT, $script, 'SET') ?>
diff --git a/themes/finc/templates/collection/view.phtml b/themes/finc/templates/collection/view.phtml
index 7c0dca05e567a8721057ea1daa3fd7d3c39a4e8a..209fcffa80124926ee002d2e960c79bb0eeb0850 100644
--- a/themes/finc/templates/collection/view.phtml
+++ b/themes/finc/templates/collection/view.phtml
@@ -10,7 +10,7 @@
 
   // Add RDF header link if applicable:
   if ($this->export()->recordSupportsFormat($this->driver, 'RDF')) {
-      $this->headLink()->appendAlternate($this->recordLink()->getActionUrl($this->driver, 'RDF'), 'application/rdf+xml', 'RDF Representation');
+    $this->headLink()->appendAlternate($this->recordLink()->getActionUrl($this->driver, 'RDF'), 'application/rdf+xml', 'RDF Representation');
   }
 
   // Set flag for special cases relating to full-width hierarchy tree tab:
@@ -22,69 +22,91 @@
     $this->layout()->breadcrumbs = '<li>' . $lastSearch . '</li> ';
   }
   $this->layout()->breadcrumbs .= '<li><a href="' . $this->url('collections-home') . '">' . $this->transEsc('Collections') . '</a></li> '
-     . '<li class="active">' . $this->recordLink()->getBreadcrumb($this->driver) . '</li>';
+    . '<li class="active" aria-current="page">' . $this->recordLink()->getBreadcrumb($this->driver) . '</li>';
 ?>
 
 <?php if (isset($this->scrollData) && ($this->scrollData['previousRecord'] || $this->scrollData['nextRecord'])): ?>
   <?=$this->render('record/prev-next.phtml'); ?>
 <?php endif; ?>
 
- <?=$this->record($this->driver)->getToolbar()?>
+<?php /* finc: add offcanvas-toggler here */ ?>
+<span class="offcanvas-toggler">
+  <a class="search-filter-toggle top visible-xs" href="#myresearch-sidebar" data-toggle="offcanvas" title="<?= $this->transEsc('sidebar_expand') ?>">
+    <?=$this->transEsc('offcanvas-toggler-record-view')?>
+  </a>
+</span>
+
+<?php /* DON'T pull the toolbar in here but below, finc-specific, CK */ ?>
 
 <div class="record">
   <?php /* finc - don't use '<?=count($sidebarList) < 1 ? ' solo' : '' ?>' or toolbar won't fit; BS count sidebars but our toolbar isn't counted */ ?>
-  <div<?php if (!$tree): /* in tree mode, do not constrain width with a class */ ?> class="<?= $this->layoutClass('mainbody') ?>"<?php endif; ?>>
+  <div<?php if (!$tree): /* in tree mode, do not constrain width with a class */ ?> class="<?= $this->layoutClass('mainbody') ?>" <?php else: ?> class="mainbody left" <?php endif; ?>>
     <input type="hidden" value="<?= $this->escapeHtmlAttr($this->driver->getUniqueId()) ?>" class="hiddenId" id="record_id"/>
     <input type="hidden" value="<?= $this->escapeHtmlAttr($this->driver->getSourceIdentifier()) ?>" class="hiddenSource"/>
-      <?= $this->flashmessages() ?>
-      <?= $this->record($this->driver)->getCollectionMetadata() ?>
-      
-      <?php if (count($this->tabs) > 0): ?>
-        <a name="tabnav"></a>
-        <div class="record-tabs">
-          <ul class="nav nav-tabs">
-              <?php foreach ($this->tabs as $tab => $obj): ?>
-                  <?php // add current tab to breadcrumbs if applicable:
+    <?= $this->flashmessages() ?>
+    <?= $this->record($this->driver)->getCollectionMetadata() ?>
+  </div>
+</div>
 
-                  if (strtolower($tab) === 'details'
-                      && $this->config()->get('config')->Site->showStaffViewInLightbox
-                      && strtolower($this->activeTab) !== 'details' /* load in new browser tab after right click */) {
-                      // #21993 show button for staff view in toolbar instead
-                      continue;
-                  }
+<?php /* finc: pull the first toolbar for top area here; add id for accessibility */ ?>
+<div id="myresearch-sidebar" class="<?= $this->layoutClass('sidebar') ?>" id="myresearch-sidebar">
+  <?= $this->record($this->driver)->getToolbar() ?>
+</div>
 
-                  $desc = $obj->getDescription();
-                  $tab_classes = [];
-                  if (0 === strcasecmp($this->activeTab, $tab)) {
-                      if (!$this->loadInitialTabWithAjax || !$obj->supportsAjax()) {
-                          $tab_classes[] = 'active';
-                      }
-                      $tab_classes[] = 'initiallyActive';
-                      $this->layout()->breadcrumbs .= '<li class="active">' . $this->transEsc($desc) . '</li>';
-                      $activeTabObj = $obj;
-                  }
-                  if (!$obj->isVisible()) {
-                      $tab_classes[] = 'hidden';}
-              if (!$obj->supportsAjax()) { $tab_classes[] = 'noajax'; }
-            ?>
-            <li<?=count($tab_classes) > 0 ? ' class="' . implode(' ', $tab_classes) . '"' : ''?>>
-              <a class="<?=strtolower($tab) ?>" href="<?=$this->recordLink()->getTabUrl($this->driver, $tab)?>#tabnav"<?php if ($obj->supportsAjax() && in_array($tab, $this->backgroundTabs)):?> data-background<?php endif ?>><?=$this->transEsc($desc)?></a>
-            </li>
-          <?php endforeach; ?>
-        </ul>
+<?php /* finc: NO initiate break between top and bottom here #22956 */ ?>
 
-        <div class="tab-content collectionDetails<?=$tree ? 'Tree' : ''?>">
-          <?php if (!$this->loadInitialTabWithAjax || !isset($activeTabObj) || !$activeTabObj->supportsAjax()): ?>
-            <div class="tab-pane active <?=$this->activeTab ?>-tab">
-              <?=isset($activeTabObj) ? $this->record($this->driver)->getTab($activeTabObj) : '' ?>
-            </div>
-          <?php endif; ?>
-        </div>
-      </div>
-    <?php endif; ?>
+<?php /* finc: use '.mainbody' class, so we do NOT get full width display (see TUF with closed record details, collection has to move up) #22956 */ ?>
+<div class="collection-hierarchy mainbody">
+  <?php /* de_15: create fake collapse items out of the tabs on XS (see caret, below) - CK */ ?>
+  <?php if (count($this->tabs) > 0): ?>
+    <a id="tabnav"></a>
+    <div class="record-tabs collection">
+      <ul class="nav nav-tabs">
+        <?php foreach ($this->tabs as $tab => $obj): ?>
+          <?php // add current tab to breadcrumbs if applicable:
 
-    <?=$this->driver->supportsCoinsOpenURL()?'<span class="Z3988" title="' . $this->escapeHtmlAttr($this->driver->getCoinsOpenURL()) . '"></span>':''?>
-  </div>
+          if (strtolower($tab) === 'details'
+            && $this->config()->get('config')->Site->showStaffViewInLightbox
+            && strtolower($this->activeTab) !== 'details' /* load in new browser tab after right click */) {
+            // #21993 show button for staff view in toolbar instead
+            continue;
+          }
+
+          $desc = $obj->getDescription();
+          $tab_classes = [];
+          if (0 === strcasecmp($this->activeTab, $tab)) {
+            if (!$this->loadInitialTabWithAjax || !$obj->supportsAjax()) {
+                $tab_classes[] = 'active';
+            }
+            $tab_classes[] = 'initiallyActive';
+            $this->layout()->breadcrumbs .= '<li class="active">' . $this->transEsc($desc) . '</li>';
+            $activeTabObj = $obj;
+          }
+          if (!$obj->isVisible()) {
+            $tab_classes[] = 'hidden';}
+          if (!$obj->supportsAjax()) { $tab_classes[] = 'noajax'; }
+          ?>
+          <li<?=count($tab_classes) > 0 ? ' class="' . implode(' ', $tab_classes) . '"' : ''?>>
+            <a class="<?=strtolower($tab) ?>" href="<?=$this->recordLink()->getTabUrl($this->driver, $tab)?>#tabnav"<?php if ($obj->supportsAjax() && in_array($tab, $this->backgroundTabs)):?> data-background<?php endif ?>>
+              <?=$this->transEsc($desc)?>
+              <?php /* finc: add span with icon #10126 */ ?>
+              <span class="visible-xs-inline right caret" aria-hidden="true"></span>
+            </a>
+          </li>
+        <?php endforeach; ?>
+      </ul>
+    </div>
+  <?php endif; ?>
+</div>
+
+<?php /* finc: show sidebar (rendered as tab) outside of '.mainbody' class #22956 */ ?>
+<?php if (!$this->loadInitialTabWithAjax || !isset($activeTabObj) || !$activeTabObj->supportsAjax()): ?>
+  <div class="tab-pane active <?=$this->activeTab ?>-tab">
+    <?=isset($activeTabObj) ? $this->record($this->driver)->getTab($activeTabObj) : '' ?>
   </div>
+<?php endif; ?>
+
+<?=$this->driver->supportsCoinsOpenURL()?'<span class="Z3988" title="' . $this->escapeHtmlAttr($this->driver->getCoinsOpenURL()) . '"></span>':''?>
+
 <?=$this->inlineScript(\Zend\View\Helper\HeadScript::SCRIPT, '$(document).ready(recordDocReady);', 'SET'); ?>
 <!-- finc: collection - view - END -->
diff --git a/themes/finc/templates/search/advanced-search-information.phtml b/themes/finc/templates/search/advanced-search-information.phtml
index c21a6fd815e55409703732f30e710da53526a8c7..23ddf424dad34733cc190b587fd4d7bf763e2250 100644
--- a/themes/finc/templates/search/advanced-search-information.phtml
+++ b/themes/finc/templates/search/advanced-search-information.phtml
@@ -27,18 +27,39 @@ $hiddenFilterParams = $this->searchTabs()->getCurrentHiddenFilterParams($this->s
 
 <?php $tabConfig = $this->searchTabs()->getTabConfig($this->searchClassId, $this->lookfor, $this->searchIndex, $this->searchType, $hiddenFilters); ?>
 <?php if ($this->params->getSearchType() == 'advanced'): ?>
+    <?php /* Disable search tabs on advanced search terms - refs #22361
+           * uncomment following block for using search tabs again
+           */ ?>
+    <?php /*
     <?php $tabs = $this->context($this)->renderInContext('search/searchTabs', ['searchTabs' => $tabConfig['tabs']]); ?>
     <?php if (!empty($tabs)): ?>
       <?=$tabs ?><div class="clearfix">
     <?php endif; ?>
-    <p class="content_adv_search_terms"><?=$this->transEsc("Your search terms")?> : "<strong><?=$this->escapeHtml($this->lookfor)?></strong>"</p>
-    <p class="content_adv_search_links">
-      <a class="btn btn-default" href="<?=$this->url($advSearch)?>?edit=<?=$this->escapeHtmlAttr($this->searchId)?>"><?=$this->transEsc("Edit this Advanced Search")?></a>
-      <a class="btn btn-default" href="<?=$this->url($advSearch) . $hiddenFilterParams?>"><?=$this->transEsc("Start a new Advanced Search")?></a>
-      <a class="btn btn-default" href="<?=$this->url($searchHome) . $hiddenFilterParams?>"><?=$this->transEsc("Start a new Basic Search")?></a>
-    </p>
+    <?php */ ?>
+    <div class="adv-search-box">
+        <div class="adv-terms">
+          <span class="adv-terms-label"><?=$this->transEsc("Advanced Search")?>:</span>
+            <a class="adv-edit" href="<?= $this->url($advSearch) ?>?edit=<?= $this->escapeHtmlAttr($this->searchId) ?>">
+                <i class="fa fa-pencil"></i>
+                <span class="hidden-xs"><?= $this->transEsc("Edit") ?>: </span>
+                <strong><?= $this->escapeHtml($this->lookfor) ?></strong>
+            </a>
+        </div>
+        <div class="adv-delete">
+            <a class="btn btn-danger" href="<?= $this->url($advSearch) . $hiddenFilterParams ?>">
+                <i class="fa fa-times" aria-hidden="true"></i>
+                <span class="hidden-xs"><?= $this->transEsc("Delete") ?></span>
+            </a>
+        </div>
+    </div>
+    
+    <?php /* Disable search tabs on advanced search terms - refs #22361
+           * uncomment following block for using search tabs again
+           */ ?>
+    <?php /*
     <?php if (!empty($tabs)): ?>
       </div>
     <?php endif; ?>
+    <?php */ ?>
 <?php endif; ?>
 <!-- finc: search - advanced-search-information - END -->
diff --git a/themes/finc/templates/search/advanced/layout.phtml b/themes/finc/templates/search/advanced/layout.phtml
index ee3e898c0a92c4189bbf767bf1832c833b927288..da3c44a8128dfb3976547d66a253b7798cf6da9f 100644
--- a/themes/finc/templates/search/advanced/layout.phtml
+++ b/themes/finc/templates/search/advanced/layout.phtml
@@ -4,7 +4,8 @@
   $this->headTitle($this->translate('Advanced Search'));
 
   // Disable top search box -- this page has a special layout.
-  $this->layout()->searchbox = false;
+  // finc: reenable searchbox by commenting out following line - refs #22361
+  //$this->layout()->searchbox = false;
 
   // Set up breadcrumbs:
   $this->layout()->breadcrumbs = '<li>';
diff --git a/themes/finc/templates/search/filters.phtml b/themes/finc/templates/search/filters.phtml
index 0a5a63cce457d10deaeb7f58b56b6300608ebaeb..e5c1bb0a17e631f799341300948493f0b1094bb3 100644
--- a/themes/finc/templates/search/filters.phtml
+++ b/themes/finc/templates/search/filters.phtml
@@ -50,12 +50,7 @@
   <?php foreach ($filterList as $field => $data): ?>
     <div class="title-value-pair">
       <span class="filters-title"><?=$this->transEsc($field)?>:</span>
-      <?php /* finc: set number of filters from one group for display in dropdown to '> 1'
-               so 2 and more filters from one group will be presented in a dropdown rather
-               than as a long chain of terms -
-               bootstrap3 has '<?php if (count($data) > 3): ?>'
-               CK */ ?>
-      <?php if (count($data) > 1): ?>
+      <?php if (count($data) > 3): ?>
         <div class="search-filter-dropdown dropdown">
           <?php $dropdown = true; ?>
           <?php $safeId = preg_replace('/[^a-zA-Z0-9]/', '', $field); ?>
@@ -128,36 +123,21 @@
         : $this->searchMemory()->getEditLink($this->searchClassId, 'removeAllFilters', 1);
     }
   ?>
-  <?php // Normal view ?>
-  <div class="active-filters hidden-xs">
-    <?php if ($resetLink && !empty($value) && $options->getRetainFilterSetting()): ?>
-      <?php /* finc adds verbose reload warning via aria-label */ ?>
-      <a class="reset-filters-btn" href="<?=$resetLink?>"
-         aria-label="<?=$this->transEsc('clear_tag_filter') ?> &ndash; <?=$this->transEsc('page_reload_on_deselect_all_hint', ['%%filter_name%%' => $value['displayText']])?>"
-      >
-        <?=$this->transEsc('reset_filters_button') ?>
-      </a>
-    <?php elseif ($advancedSearch): ?>
-      <p class="adv_search_filters"><?=$this->transEsc('adv_search_filters')?>:</p>
-    <?php endif; ?>
-    <div class="filters">
-      <?=$filters ?>
-    </div>
-    <div class="clearfix"></div>
-  </div>
-  <?php // Narrow view ?>
-  <div class="active-filters visible-xs">
+  <?php // Narrow view - for all sizes by default - refs #22869 */ ?>
+  <div class="active-filters">
     <div class="filters-toggle-bar">
-      <?php if ($resetLink && !empty($value) && $options->getRetainFilterSetting()): ?>
+      <? /* finc: disable check of RetainFilterSetting in context of 'reset filters'-button - #23168 */ ?>
+      <?php if ($resetLink && !empty($value)/* && $options->getRetainFilterSetting()*/): ?>
         <?php /* finc adds verbose reload warning via aria-label */ ?>
         <a class="reset-filters-btn active" href="<?=$resetLink?>"
            aria-label="<?=$this->transEsc('clear_tag_filter') ?> &ndash; <?=$this->transEsc('page_reload_on_deselect_all_hint', ['%%filter_name%%' => $value['displayText']])?>">
           <?=$this->transEsc('reset_filters_button')?>
         </a>
       <?php endif; ?>
-      <div class="filters-toggle collapsed" data-toggle="collapse" data-target="#active-filters-mobile">
+      <?php // make toggler accessible for tabbing - refs #22869 ?>
+      <a class="filters-toggle collapsed" data-toggle="collapse" href="#active-filters-mobile">
         <?=$this->transEsc('show_filters_html', ['%%count%%' => $filterCount])?>
-      </div>
+      </a>
       <div class="clearfix"></div>
     </div>
     <div id="active-filters-mobile" class="filters filters-bar collapse">
diff --git a/themes/finc/templates/search/history.phtml b/themes/finc/templates/search/history.phtml
index d1716c94b490647267c1b64d1e9a79b576aaac64..782571ae123063a34aaf9bc07e44e163daa3ab30 100644
--- a/themes/finc/templates/search/history.phtml
+++ b/themes/finc/templates/search/history.phtml
@@ -1,22 +1,36 @@
 <!-- finc - templates - search - history -->
+<?php
+/**
+origin:                            vufind
+called by view helper/controller:  --
+usage:                             (saved) search history
+modified for finc:                 special finc behavior:
+                                   * not logged in:
+                                   ** don't show offcancas-toggler and profile menu
+                                   ** breadcrumb like: Home -> History
+                                   * logged in:
+                                   ** show offcancas-toggler and profile menu
+                                   ** breadcrumb like: Home -> My Account -> History
+configured in:                     --
+ */
+?>
 <?php
   // Set page title.
   $this->headTitle($this->translate('Search History'));
 
-  // finc: handle disable account capabilities
-  $loginEnabled = is_object($account = $this->auth()->getManager()) && $account->loginEnabled();
+$saveSupported = $this->accountCapabilities()->getSavedSearchSetting() === 'enabled';
+$isLoggedIn = $this->auth()->isLoggedIn();
 
   // Set up breadcrumbs:
-  // finc: check for $loginEnabled
-  $this->layout()->breadcrumbs = ($loginEnabled ? '<li><a href="' . $this->url('myresearch-home') . '">' . $this->transEsc('Your Account') . '</a></li>'
+  // finc: check for $isLoggedIn
+  $this->layout()->breadcrumbs = (
+      $isLoggedIn ? '<li><a href="' . $this->url('myresearch-home') . '">' . $this->transEsc('Your Account') . '</a></li>'
     : '') . '<li class="active">' . $this->transEsc('History') . '</li>';
-
-  $saveSupported = $this->accountCapabilities()->getSavedSearchSetting() === 'enabled';
 ?>
 
 <div class="<?=$this->layoutClass('mainbody')?>">
-  <?php /* finc: show only when if $saveSupported */ ?>
-  <?php if ($saveSupported): ?>
+  <?php /* finc: show offcanvas-toggler and profile-menu only when if $isLoggedIn */ ?>
+  <?php if ($isLoggedIn): ?>
     <?=$this->render('RecordDriver/DefaultRecord/offcanvas-toggler-myresearch'); ?>
   <?php endif; ?>
 
@@ -27,16 +41,15 @@
         (<a href="<?=$this->url('myresearch-profile');?>"><?=$this->transEsc("edit");?></a>)
       <?php endif; ?>
     </div>
-  <?php elseif (!empty($this->schedule) && $this->auth()->isLoggedIn()): ?>
+  <?php elseif (!empty($this->schedule) && $isLoggedIn): ?>
     <div class="alert alert-danger alert-email-notification">
       <?=$this->transEsc("no_email_address") . ' ';?><a href="<?=$this->url('myresearch-profile');?>"><?=$this->transEsc("check_profile");?></a>
     </div>
   <?php endif; ?>
   <?=$this->flashmessages()?>
   <?php /* finc: add h1 heading for correct headings' hierarchy */ ?>
-  <h1><?=$this->transEsc('Search History')?></h1>
   <?php if ($saveSupported && !empty($this->saved)): ?>
-    <h2><?=$this->transEsc("history_saved_searches")?></h2>
+    <h1><?=$this->transEsc("history_saved_searches")?></h1>
     <?=$this->context()->renderInContext('search/history-table.phtml', ['showSaved' => true]);?>
   <?php endif; ?>
 
@@ -49,12 +62,13 @@
   <?php endif; ?>
 </div>
 
-<?php if ($saveSupported): ?>
+<?php /* finc: show offcanvas-toggler and profile-menu only if $isLoggedIn */ ?>
+<?php if ($isLoggedIn): ?>
   <div class="<?=$this->layoutClass('sidebar')?>" id="myresearch-sidebar">
     <?=$this->context($this)->renderInContext(
         "myresearch/menu.phtml",
-        // Only activate search history in account menu if user is logged in.
-        $this->auth()->isLoggedIn() ? ['active' => 'history'] : []
+        // apply active highlighting in profile-menu
+        ['active' => 'history']
      );
      ?>
   </div>
diff --git a/themes/finc/templates/search/results.phtml b/themes/finc/templates/search/results.phtml
index 13afdc03de5909ac9673c4ee61186563dd4a2b52..10915467d2991d20e3d8bcbaa0bb5c6be7b91108 100644
--- a/themes/finc/templates/search/results.phtml
+++ b/themes/finc/templates/search/results.phtml
@@ -80,8 +80,8 @@
   <?php endif; ?>
   <?=$this->flashmessages()?>
   
-  <?php /* finc: display advanced search terms and links in main container on top of content
-           origionally located in header (searchbox.phtml) into*/ ?>
+  <?php /* finc: display advanced search terms and links in main container on top of search results
+           origionally located in header (searchbox.phtml) */ ?>
   <?= $this->context($this)->renderInContext(
     'search/advanced-search-information.phtml',
     [
diff --git a/themes/finc/templates/search/searchbox.phtml b/themes/finc/templates/search/searchbox.phtml
index 322a9c679ab9ebb564b8813f912b49eaefb0acd8..fa58a64187b6fed981a6a48a60cb5d1bc9c7540b 100644
--- a/themes/finc/templates/search/searchbox.phtml
+++ b/themes/finc/templates/search/searchbox.phtml
@@ -42,49 +42,51 @@
     $showFilters = $filterDetails && (isset($results) || $options->getRetainFilterSetting());
 ?>
 <?php $tabConfig = $this->searchTabs()->getTabConfig($this->searchClassId, $this->lookfor, $this->searchIndex, $this->searchType, $hiddenFilters); ?>
-<?php if ($this->searchType == 'advanced'): ?>
-  <?php /* Do not show the advanced search terms (adv_search_terms) and advanced search links (adv_search_links)
-                because they will be shown within the breadcrumb - #17720 - #22331 */ ?>
-  <?php $showAdvancedSearchTermsAndLinksInHeader = false;?>
-  <?php if ($showAdvancedSearchTermsAndLinksInHeader): ?>
-    <?php /* finc: keep .no-margin-t or advanced search box will be pushed down too far (navbar-form) */ ?>
-    <div class="navbar-form navbar-left flip no-margin-t">
-      <?php $tabs = $this->context($this)->renderInContext('search/searchTabs', ['searchTabs' => $tabConfig['tabs']]); ?>
-      <?php if (!empty($tabs)): ?><?=$tabs ?><div class="tab-content clearfix no-gutter-all"><?php endif; ?>
-        <p class="adv_search_terms"><?=$this->transEsc("Your search terms")?> : "<strong><?=$this->escapeHtml($this->lookfor)?></strong>"</p>
-        <p class="adv_search_links">
-          <a href="<?=$this->url($advSearch)?>?edit=<?=$this->escapeHtmlAttr($this->searchId)?>"><?=$this->transEsc("Edit this Advanced Search")?></a>
-          <a href="<?=$this->url($advSearch) . $hiddenFilterParams?>"><?=$this->transEsc("Start a new Advanced Search")?></a>
-          <a href="<?=$this->url($searchHome) . $hiddenFilterParams?>"><?=$this->transEsc("Start a new Basic Search")?></a>
-        </p>
-        <?php /* finc: Don't load active filters here but above search results */ ?>
-        <?php /*
-        <?=$this->context($this)->renderInContext(
-          'search/filters.phtml',
-          [
-            'params' => $params ?? null,
-            'urlQuery' => isset($results) ? $results->getUrlQuery() : null,
-            'filterList' => $showFilters ? $filterList : [],
-            'checkboxFilters' => $showFilters ? $checkboxFilters : [],
-            'searchClassId' => $this->searchClassId,
-            'searchType' => $this->searchType,
-          ]
-        );?>
-        */ ?>
-      <?php if (!empty($tabs)): ?></div><?php endif; ?>
-    </div>
-  <?php endif; ?>
+<?php
+  /* Do not show the advanced search terms (adv_search_terms) and advanced search links (adv_search_links)
+   * because they will be shown within the breadcrumb - #17720 - #22331 - #22361
+   */
+  $showBasicSearchAlways = true;
+?>
+<?php if ($this->searchType == 'advanced' && !$showBasicSearchAlways): ?>
+  <?php /* finc: keep .no-margin-t or advanced search box will be pushed down too far (navbar-form) */ ?>
+  <div class="navbar-form navbar-left flip no-margin-t">
+    <?php $tabs = $this->context($this)->renderInContext('search/searchTabs', ['searchTabs' => $tabConfig['tabs']]); ?>
+    <?php if (!empty($tabs)): ?><?=$tabs ?><div class="tab-content clearfix no-gutter-all"><?php endif; ?>
+      <p class="adv_search_terms"><?=$this->transEsc("Your search terms")?> : "<strong><?=$this->escapeHtml($this->lookfor)?></strong>"</p>
+      <p class="adv_search_links">
+        <a href="<?=$this->url($advSearch)?>?edit=<?=$this->escapeHtmlAttr($this->searchId)?>"><?=$this->transEsc("Edit this Advanced Search")?></a>
+        <a href="<?=$this->url($advSearch) . $hiddenFilterParams?>"><?=$this->transEsc("Start a new Advanced Search")?></a>
+        <a href="<?=$this->url($searchHome) . $hiddenFilterParams?>"><?=$this->transEsc("Start a new Basic Search")?></a>
+      </p>
+      <?php /* finc: Don't load active filters here but above search results */ ?>
+      <?php /*
+      <?=$this->context($this)->renderInContext(
+        'search/filters.phtml',
+        [
+          'params' => $params ?? null,
+          'urlQuery' => isset($results) ? $results->getUrlQuery() : null,
+          'filterList' => $showFilters ? $filterList : [],
+          'checkboxFilters' => $showFilters ? $checkboxFilters : [],
+          'searchClassId' => $this->searchClassId,
+          'searchType' => $this->searchType,
+        ]
+      );?>
+      */ ?>
+    <?php if (!empty($tabs)): ?></div><?php endif; ?>
+  </div>
 <?php else: ?>
   <?php /* finc adds role='search' */ ?>
   <form id="searchForm" class="searchForm navbar-form navbar-left flip" method="get" action="<?=$this->url($basicSearch)?>" name="searchForm" autocomplete="off" role="search">
     <?= $this->context($this)->renderInContext('search/searchTabs', ['searchTabs' => $tabConfig['tabs']]); ?>
     <?php $placeholder = $this->searchbox()->getPlaceholderText($tabConfig['selected']['id'] ?? null); ?>
     <?php /* finc: keep "required", keep role="searchbox" */ ?>
+    <?php /* finc: leave lookfor blank if this is an advanced saerch - #22361 */ ?>
     <input id="searchForm_lookfor"
            class="searchForm_lookfor form-control search-query<?php if($this->searchbox()->autocompleteEnabled($this->searchClassId)):?> autocomplete searcher:<?=$this->escapeHtmlAttr($this->searchClassId) ?><?=$this->searchbox()->autocompleteAutoSubmit($this->searchClassId) ? ' ac-auto-submit' : '' ?><?php endif ?>"
            type="search"
            name="lookfor"
-           value="<?=$this->escapeHtmlAttr($this->lookfor)?>"
+           value="<?=$this->searchType !== 'advanced' ? $this->escapeHtmlAttr($this->lookfor) : ''?>"
       <?php if ($placeholder): ?>
         placeholder="<?=$this->transEsc($placeholder) ?>"
       <?php endif ?>