diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 4f55449b1f31cf8f8cb780c4c747d9547f4c941c..fb8c65524504c119b7fecab807eef8b078c1a92c 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -64,8 +64,8 @@ update(metager2):
     - cd MetaGer_neu
     - composer install
     - scp -P 63824 metager@metager3.de:~/.env .
-    - scp -P 63824 metager@metager3.de:~/sumas.json config/
-    - scp -P 63824 metager@metager3.de:~/sumasEn.json config/
+    - cp $SUMAS config/
+    - cp $SUMASEN config/
     - scp -P 63824 metager@metager3.de:~/blacklistUrl.txt config/
     - scp -P 63824 metager@metager3.de:~/blacklistDomains.txt config/
     - scp -P 63824 metager@metager3.de:~/adBlacklistUrl.txt config/
diff --git a/app/MetaGer.php b/app/MetaGer.php
index e2c12c76865f9d45663d30fa1a49186cc8ba6f8a..368861c0b3e673246c734430840342fd4c99e17c 100644
--- a/app/MetaGer.php
+++ b/app/MetaGer.php
@@ -1,4 +1,5 @@
 <?php
+
 namespace App;
 
 use App;
@@ -121,7 +122,6 @@ class MetaGer
         $this->redisEngineResult = $redisPrefix . "." . $this->searchUid . ".results.";
         # A list of all search results already delivered to the user (sorted of course)
         $this->redisCurrentResultList = $redisPrefix . "." . $this->searchUid . ".currentResults";
-
     }
 
     # Erstellt aus den gesammelten Ergebnissen den View
@@ -284,9 +284,9 @@ class MetaGer
         $newResults = [];
         foreach ($this->ads as $ad) {
             if (($ad->strippedHost !== "" && (in_array($ad->strippedHost, $this->adDomainsBlacklisted) ||
-                in_array($ad->strippedLink, $this->adUrlsBlacklisted))) ||
-                ($ad->strippedHostAnzeige !== "" && (in_array($ad->strippedHostAnzeige, $this->adDomainsBlacklisted) ||
-                    in_array($ad->strippedLinkAnzeige, $this->adUrlsBlacklisted)))) {
+                    in_array($ad->strippedLink, $this->adUrlsBlacklisted))) || ($ad->strippedHostAnzeige !== "" && (in_array($ad->strippedHostAnzeige, $this->adDomainsBlacklisted) ||
+                    in_array($ad->strippedLinkAnzeige, $this->adUrlsBlacklisted)))
+            ) {
                 continue;
             }
             $newResults[] = $ad;
@@ -324,7 +324,6 @@ class MetaGer
         } else {
             $this->next = [];
         }
-
     }
 
     public function combineResults($engines)
@@ -436,11 +435,12 @@ class MetaGer
         $postdata = http_build_query(array(
             'dummy' => rand(),
         ));
-        $opts = array('http' => array(
-            'method' => 'POST',
-            'header' => 'Content-type: application/x-www-form-urlencoded',
-            'content' => $postdata,
-        ),
+        $opts = array(
+            'http' => array(
+                'method' => 'POST',
+                'header' => 'Content-type: application/x-www-form-urlencoded',
+                'content' => $postdata,
+            ),
         );
 
         $context = stream_context_create($opts);
@@ -453,7 +453,6 @@ class MetaGer
             } else {
                 return false;
             }
-
         } catch (\ErrorException $e) {
             return false;
         }
@@ -485,50 +484,53 @@ class MetaGer
             $this->fokus = "web";
         }
 
-        $sumaList = $this->sumaFile->foki->{$this->fokus}->sumas;
+        $sumaNames = $this->sumaFile->foki->{$this->fokus}->sumas;
 
-        # If the user is authorized to use adfree search we won't activate yahoo or yahoo-ads
-        if ($this->apiAuthorized && ($key = array_search("yahoo", $sumaList)) !== false) {
-            unset($sumaList[$key]);
-            if ($this->fokus === "web") {
-                $this->sumaFile->sumas->{"bing"}->{"filter-opt-in"} = false;
-            }
-        } elseif ($this->apiAuthorized && ($key = array_search("yahoo-ads", $sumaList)) !== false) {
-            unset($sumaList[$key]);
+        $sumas = [];
+        foreach ($sumaNames as $sumaName) {
+            $sumas[$sumaName] = $this->sumaFile->sumas->{$sumaName};
         }
 
-        foreach ($sumaList as $suma) {
+        $this->removeAdsFromListIfAdfree($sumas);
+
+        foreach ($sumas as $sumaName => $suma) {
             # Check if this engine is disabled and can't be used
-            $disabled = empty($this->sumaFile->sumas->{$suma}->disabled) ? false : $this->sumaFile->sumas->{$suma}->disabled;
-            $autoDisabled = empty($this->sumaFile->sumas->{$suma}->{"auto-disabled"}) ? false : $this->sumaFile->sumas->{$suma}->{"auto-disabled"};
-            if ($disabled || $autoDisabled
-                || \Cookie::get($this->getFokus() . "_engine_" . $suma) === "off") { # Check if the user has disabled this engine
-            continue;
+            $disabled = empty($suma->disabled) ? false : $suma->disabled;
+            $autoDisabled = empty($suma->{"auto-disabled"}) ? false : $suma->{"auto-disabled"};
+            if (
+                $disabled || $autoDisabled
+                || \Cookie::get($this->getFokus() . "_engine_" . $sumaName) === "off"
+            ) {
+                continue;
             }
-            # Check if this engine can use eventually defined query-filter
+
             $valid = true;
-            foreach ($this->queryFilter as $queryFilter => $filter) {
-                if (empty($this->sumaFile->filter->{"query-filter"}->$queryFilter->sumas->$suma)) {
+
+            # Check if this engine can use potentially defined query-filter
+            foreach ($this->queryFilter as $filterName => $filter) {
+                if (empty($this->sumaFile->filter->{"query-filter"}->$filterName->sumas->$sumaName)) {
                     $valid = false;
                     break;
                 }
             }
-            # Check if this engine can use eventually defined parameter-filter
+
+            # Check if this engine can use potentially defined parameter-filter
             if ($valid) {
                 foreach ($this->parameterFilter as $filterName => $filter) {
                     # We need to check if the searchengine supports the parameter value, too
-                    if (empty($filter->sumas->$suma) || empty($filter->sumas->{$suma}->values->{$filter->value})) {
+                    if (empty($filter->sumas->$sumaName) || empty($filter->sumas->{$sumaName}->values->{$filter->value})) {
                         $valid = false;
                         break;
                     }
                 }
             }
+
             # Check if this engine should only be active when filter is used
-            if ($this->sumaFile->sumas->{$suma}->{"filter-opt-in"}) {
+            if ($suma->{"filter-opt-in"}) {
                 # This search engine should only be used when a parameter filter of it is used
                 $validTmp = false;
                 foreach ($this->parameterFilter as $filterName => $filter) {
-                    if (!empty($filter->sumas->{$suma})) {
+                    if (!empty($filter->sumas->{$sumaName})) {
                         $validTmp = true;
                         break;
                     }
@@ -536,17 +538,16 @@ class MetaGer
                 if (!$validTmp) {
                     $valid = false;
                 }
-
             }
-            # If it can we add it
+
+            # If the suma is still valid, we can add it
             if ($valid) {
-                $this->enabledSearchengines[$suma] = $this->sumaFile->sumas->{$suma};
+                $this->enabledSearchengines[$sumaName] = $suma;
             }
-
         }
 
-        # Implements Yahoo Ads if Yahoo is not enabled as a searchengine
-        if (!$this->apiAuthorized && empty($this->enabledSearchengines["yahoo"]) && $this->fokus != "bilder" && !empty($this->sumaFile->sumas->{"yahoo-ads"})) {
+        # Include Yahoo Ads if Yahoo is not enabled as a searchengine
+        if (!$this->apiAuthorized && $this->fokus != "bilder" && empty($this->enabledSearchengines["yahoo"]) && isset($this->sumaFile->sumas->{"yahoo-ads"})) {
             $this->enabledSearchengines["yahoo-ads"] = $this->sumaFile->sumas->{"yahoo-ads"};
         }
 
@@ -562,16 +563,33 @@ class MetaGer
                 $filter .= trans($this->sumaFile->filter->{"query-filter"}->{$queryFilter}->name) . ",";
             }
             $filter = rtrim($filter, ",");
-            $error = trans('metaGer.engines.noSpecialSearch', ['fokus' => trans($this->sumaFile->foki->{$this->fokus}->{"display-name"}),
-                'filter' => $filter]);
+            $error = trans('metaGer.engines.noSpecialSearch', [
+                'fokus' => trans($this->sumaFile->foki->{$this->fokus}->{"display-name"}),
+                'filter' => $filter
+            ]);
             $this->errors[] = $error;
         }
-        $engines = [];
-        $typeslist = [];
-        $counter = 0;
         $this->setEngines($request);
     }
 
+    private function removeAdsFromListIfAdfree(&$sumas)
+    {
+        if ($this->apiAuthorized) {
+            foreach ($sumas as $sumaName => $suma) {
+                $ads = $suma->ads ?? false;
+                if ($ads) {
+                    unset($sumas[$sumaName]);
+
+                    $adBackups = $suma->{"ad-backups"} ?? [];
+                    $adBackupName = $adBackups->{$this->fokus} ?? null;
+                    if (isset($adBackupName)) {
+                        $this->sumaFile->sumas->{$adBackupName}->{"filter-opt-in"} = false;
+                    }
+                }
+            }
+        }
+    }
+
     public function setEngines(Request $request, $enabledSearchengines = [])
     {
         if ($this->requestIsCached($request)) {
@@ -676,7 +694,8 @@ class MetaGer
                     if (!empty($filter->sumas->{$suma})) {
                         # If the searchengine is disabled this filter shouldn't be available
                         if ((!empty($this->sumaFile->sumas->{$suma}->disabled) && $this->sumaFile->sumas->{$suma}->disabled === true)
-                            || (!empty($this->sumaFile->sumas->{$suma}->{"auto-disabled"}) && $this->sumaFile->sumas->{$suma}->{"auto-disabled"} === true)) {
+                            || (!empty($this->sumaFile->sumas->{$suma}->{"auto-disabled"}) && $this->sumaFile->sumas->{$suma}->{"auto-disabled"} === true)
+                        ) {
                             continue;
                         }
                         if (empty($availableFilter[$filterName])) {
@@ -723,31 +742,31 @@ class MetaGer
     public function sumaIsDisabled($suma)
     {
         return
-        isset($suma['disabled'])
-        && $suma['disabled']->__toString() === "1";
+            isset($suma['disabled'])
+            && $suma['disabled']->__toString() === "1";
     }
 
     public function sumaIsOverture($suma)
     {
         return
-        $suma["name"]->__toString() === "overture"
-        || $suma["name"]->__toString() === "overtureAds";
+            $suma["name"]->__toString() === "overture"
+            || $suma["name"]->__toString() === "overtureAds";
     }
 
     public function sumaIsNotAdsuche($suma)
     {
         return
-        $suma["name"]->__toString() !== "qualigo"
-        && $suma["name"]->__toString() !== "similar_product_ads"
-        && $suma["name"]->__toString() !== "overtureAds";
+            $suma["name"]->__toString() !== "qualigo"
+            && $suma["name"]->__toString() !== "similar_product_ads"
+            && $suma["name"]->__toString() !== "overtureAds";
     }
 
     public function requestIsCached($request)
     {
         return
-        $request->filled('next')
-        && Cache::has($request->input('next'))
-        && unserialize(Cache::get($request->input('next')))['page'] > 1;
+            $request->filled('next')
+            && Cache::has($request->input('next'))
+            && unserialize(Cache::get($request->input('next')))['page'] > 1;
     }
 
     public function getCachedEngines($request)
@@ -818,7 +837,6 @@ class MetaGer
             $pipeline->hset($this->getRedisEngineResult() . $engine, "delivered", "1");
         }
         $pipeline->execute();
-
     }
 
     public function retrieveResults()
@@ -843,7 +861,7 @@ class MetaGer
         }
     }
 
-/*
+    /*
  * Ende Suchmaschinenerstellung und Ergebniserhalt
  */
 
@@ -1060,7 +1078,6 @@ class MetaGer
                         $this->q = preg_replace('/' . $toDelete . '/si', '', $this->q, 1);
                 }
             }
-
         }
         # Check for parameter-filter (i.e. SafeSearch)
         $this->parameterFilter = [];
@@ -1073,8 +1090,9 @@ class MetaGer
             }
 
             if (($request->filled($filter->{"get-parameter"}) && $request->input($filter->{"get-parameter"}) !== "off") ||
-                \Cookie::get($this->getFokus() . "_setting_" . $filter->{"get-parameter"}) !== null) { # If the filter is set via Cookie
-            $this->parameterFilter[$filterName] = $filter;
+                \Cookie::get($this->getFokus() . "_setting_" . $filter->{"get-parameter"}) !== null
+            ) { # If the filter is set via Cookie
+                $this->parameterFilter[$filterName] = $filter;
                 $this->parameterFilter[$filterName]->value = $request->input($filter->{"get-parameter"}, '');
                 if (empty($this->parameterFilter[$filterName]->value)) {
                     $this->parameterFilter[$filterName]->value = \Cookie::get($this->getFokus() . "_setting_" . $filter->{"get-parameter"});
@@ -1263,7 +1281,7 @@ class MetaGer
         }
     }
 
-# Hilfsfunktionen
+    # Hilfsfunktionen
     public function startsWith($haystack, $needle)
     {
         $length = strlen($needle);
@@ -1314,8 +1332,7 @@ class MetaGer
     {
         if ($this->shouldLog) {
             $redis = Redis::connection('redisLogs');
-            try
-            {
+            try {
                 $logEntry = "";
                 $logEntry .= "[" . date("D M d H:i:s") . "]";
                 /*
@@ -1385,7 +1402,7 @@ class MetaGer
         }
     }
 
-# Generators
+    # Generators
 
     public function generateSearchLink($fokus, $results = true)
     {
@@ -1455,7 +1472,7 @@ class MetaGer
         return $link;
     }
 
-# Komplexe Getter
+    # Komplexe Getter
 
     public function getHostCount($host)
     {
@@ -1484,8 +1501,10 @@ class MetaGer
     {
         $filters = $this->sumaFile->filter->{"parameter-filter"};
         foreach ($filters as $filterName => $filter) {
-            if (\Request::filled($filter->{"get-parameter"})
-                && \Cookie::get($this->getFokus() . "_setting_" . $filter->{"get-parameter"}) !== \Request::input($filter->{"get-parameter"})) {
+            if (
+                \Request::filled($filter->{"get-parameter"})
+                && \Cookie::get($this->getFokus() . "_setting_" . $filter->{"get-parameter"}) !== \Request::input($filter->{"get-parameter"})
+            ) {
                 return true;
             }
         }
@@ -1505,7 +1524,7 @@ class MetaGer
         return $count;
     }
 
-# Einfache Getter
+    # Einfache Getter
 
     public function getVerificationId()
     {
diff --git a/app/Models/Searchengine.php b/app/Models/Searchengine.php
index 0ca550a50abff92538e9fcd279e24c962d26ba6c..204bec805d89089740019a03f3ad6ea67a3c6a37 100644
--- a/app/Models/Searchengine.php
+++ b/app/Models/Searchengine.php
@@ -86,7 +86,7 @@ abstract class Searchengine
         }
 
         $this->getString = $this->generateGetString($q);
-        $this->hash = md5($this->engine->host . $this->getString . $this->engine->port . $this->name);
+        $this->updateHash();
         $this->resultHash = $metager->getSearchUid();
         $this->canCache = $metager->canCache();
     }
@@ -95,9 +95,7 @@ abstract class Searchengine
 
     # Standardimplementierung der getNext Funktion, damit diese immer verwendet werden kann
     public function getNext(MetaGer $metager, $result)
-    {
-
-    }
+    { }
 
     # Prüft, ob die Suche bereits gecached ist, ansonsted wird sie als Job dispatched
     public function startSearch(\App\MetaGer $metager)
@@ -200,6 +198,11 @@ abstract class Searchengine
         $this->resultHash = $hash;
     }
 
+    public function updateHash()
+    {
+        $this->hash = md5($this->engine->host . $this->getString . $this->engine->port . $this->name);
+    }
+
     # Fragt die Ergebnisse von Redis ab und lädt Sie
     public function retrieveResults(MetaGer $metager)
     {
@@ -250,6 +253,8 @@ abstract class Searchengine
         # Append the Query String
         $getString .= "&" . $this->engine->{"query-parameter"} . "=" . $this->urlEncode($query);
 
+        $getString .= $this->getDynamicParamsString();
+
         return $getString;
     }
 
@@ -262,4 +267,21 @@ abstract class Searchengine
             return urlencode($string);
         }
     }
+
+    private function getDynamicParamsString()
+    {
+        $paramString = "";
+
+        $params = $this->getDynamicParams();
+        foreach ($params as $key => $value) {
+            $paramString .= sprintf("&%s=%s", urlencode($key), urlencode($value));
+        }
+
+        return $paramString;
+    }
+
+    protected function getDynamicParams()
+    {
+        return [];
+    }
 }
diff --git a/app/Models/XmlSearchengine.php b/app/Models/XmlSearchengine.php
new file mode 100644
index 0000000000000000000000000000000000000000..00472b4a7bc64d1771243bc94ff6e017b0836e1a
--- /dev/null
+++ b/app/Models/XmlSearchengine.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace App\Models;
+
+abstract class XmlSearchengine extends Searchengine
+{
+    public function loadresults($results)
+    {
+        try {
+            $resultsXml = simplexml_load_string($results);
+            $this->loadXmlResults($resultsXml);
+        } catch (\Exception $e) {
+            abort(500, "\n~~~~~~~~\n$results\n~~~~~~~~\nis not a valid xml string");
+        }
+    }
+
+    protected abstract function loadXmlResults($resultsXml);
+}
diff --git a/app/Models/parserSkripte/Overture.php b/app/Models/parserSkripte/Overture.php
index 5d7a7e8ebb5fdac79b14892a117b8c5338f99902..9a2825e8f95fd07828210e9889e20a41891dc8da 100644
--- a/app/Models/parserSkripte/Overture.php
+++ b/app/Models/parserSkripte/Overture.php
@@ -14,7 +14,7 @@ class Overture extends Searchengine
         parent::__construct($name, $engine, $metager);
         # We need some Affil-Data for the advertisements
         $this->getString .= $this->getOvertureAffilData($metager->getUrl());
-        $this->hash = md5($this->engine->host . $this->getString . $this->engine->port . $this->name);
+        $this->updateHash();
     }
 
     public function loadResults($result)
diff --git a/app/Models/parserSkripte/Qualigo.php b/app/Models/parserSkripte/Qualigo.php
index d78e9529ce17c8e42a47ce722e089780a9b17bbf..ff9c29ccd02703e2fa6647c89bcea0eca28090e3 100644
--- a/app/Models/parserSkripte/Qualigo.php
+++ b/app/Models/parserSkripte/Qualigo.php
@@ -2,9 +2,9 @@
 
 namespace App\Models\parserSkripte;
 
-use App\Models\Searchengine;
+use App\Models\XmlSearchengine;
 
-class Qualigo extends Searchengine
+class Qualigo extends XmlSearchengine
 {
 
     public function __construct($name, \StdClass $engine, \App\MetaGer $metager)
@@ -12,18 +12,9 @@ class Qualigo extends Searchengine
         parent::__construct($name, $engine, $metager);
     }
 
-    public function loadResults($results)
+    protected function loadXmlResults($resultsXml)
     {
-        try {
-            $content = simplexml_load_string($results);
-        } catch (\Exception $e) {
-            abort(500, "$result is not a valid xml string");
-        }
-
-        if (!$content) {
-            return;
-        }
-        $results = $content->xpath('//RL/RANK');
+        $results = $resultsXml->xpath('//RL/RANK');
         foreach ($results as $result) {
             $title       = $result->{"TITLE"}->__toString();
             $link        = $result->{"URL"}->__toString();
@@ -36,10 +27,20 @@ class Qualigo extends Searchengine
                 $link,
                 $anzeigeLink,
                 $descr,
-                $this->engine->{"display-name"},$this->engine->homepage,
+                $this->engine->{"display-name"},
+                $this->engine->homepage,
                 $this->counter
             );
         }
     }
 
+    protected function getDynamicParams()
+    {
+        $params = [];
+
+        $params["ip"] = $this->ip;
+        $params["agent"] = $this->useragent;
+
+        return $params;
+    }
 }
diff --git a/resources/views/parts/searchbar.blade.php b/resources/views/parts/searchbar.blade.php
index c64874a3d753c4035abf6f8743e9dd5f5e544b74..1cb823adbf605fdad0acd841485d2be734cb0acf 100644
--- a/resources/views/parts/searchbar.blade.php
+++ b/resources/views/parts/searchbar.blade.php
@@ -8,7 +8,7 @@
 					</a>
 				</div>
 				<div class="search-input">
-					<input type="search" name="eingabe" value="@if(isset($eingabe)){{$eingabe}}@endif" required=""  @if(\Request::is('/')) autofocus @endif autocomplete="off" class="form-control" placeholder="{{ trans('index.placeholder') }}" tabindex="0">
+					<input type="search" name="eingabe" value="@if(isset($eingabe)){{$eingabe}}@endif" required=""  @if(\Request::is('/') && stripos(\Request::header('User-Agent'), "MetaGer App") !== 0) autofocus @endif autocomplete="off" class="form-control" placeholder="{{ trans('index.placeholder') }}" tabindex="0">
 					<button id="search-delete-btn" name="delete-search-input" type="button" tabindex="-1">
 						&#xd7;
 					</button>
diff --git a/routes/web.php b/routes/web.php
index 1aceef359f6dcabafdfffeba8127be7069906f6e..ffc44c4080181a408faa3dd70410561819fb5b77 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -216,17 +216,10 @@ Route::group(
                     ->with('navbarFocus', 'dienste');
             });
             Route::get('metager', function () {
-                $filePath = storage_path() . "/app/public/MetaGer-release.apk";
-                return response()->download($filePath, "MetaGer-release.apk");
+                return redirect("https://gitlab.metager.de/open-source/app-en/raw/latest/app/release/app-release.apk?inline=false");
             });
             Route::get('maps', function () {
-                $filePath = env('maps_app');
-                $fileContents = file_get_contents($filePath);
-                return response($fileContents, 200)
-                    ->header('Cache-Control', 'public')
-                    ->header('Content-Type', 'application/vnd.android.package-archive')
-                    ->header('Content-Transfer-Encoding', 'Binary')
-                    ->header("Content-Disposition", "attachment; filename=app-release.apk");
+                return redirect("https://gitlab.metager.de/open-source/metager-maps-android/raw/latest/app/release/app-release.apk?inline=false");
             });
 
             Route::get('maps/version', function () {
diff --git a/storage/framework/cache/data/.gitignore b/storage/framework/cache/data/.gitignore
deleted file mode 100755
index d6b7ef32c8478a48c3994dcadc86837f4371184d..0000000000000000000000000000000000000000
--- a/storage/framework/cache/data/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-*
-!.gitignore