diff --git a/res/drawable/ic_baseline_settings_24.xml b/res/drawable/ic_baseline_settings_24.xml
new file mode 100644
--- /dev/null
+++ b/res/drawable/ic_baseline_settings_24.xml
@@ -0,0 +1,5 @@
+<vector android:height="24dp" android:tint="#FFFFFF"
+    android:viewportHeight="24" android:viewportWidth="24"
+    android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="@android:color/white" android:pathData="M19.14,12.94c0.04,-0.3 0.06,-0.61 0.06,-0.94c0,-0.32 -0.02,-0.64 -0.07,-0.94l2.03,-1.58c0.18,-0.14 0.23,-0.41 0.12,-0.61l-1.92,-3.32c-0.12,-0.22 -0.37,-0.29 -0.59,-0.22l-2.39,0.96c-0.5,-0.38 -1.03,-0.7 -1.62,-0.94L14.4,2.81c-0.04,-0.24 -0.24,-0.41 -0.48,-0.41h-3.84c-0.24,0 -0.43,0.17 -0.47,0.41L9.25,5.35C8.66,5.59 8.12,5.92 7.63,6.29L5.24,5.33c-0.22,-0.08 -0.47,0 -0.59,0.22L2.74,8.87C2.62,9.08 2.66,9.34 2.86,9.48l2.03,1.58C4.84,11.36 4.8,11.69 4.8,12s0.02,0.64 0.07,0.94l-2.03,1.58c-0.18,0.14 -0.23,0.41 -0.12,0.61l1.92,3.32c0.12,0.22 0.37,0.29 0.59,0.22l2.39,-0.96c0.5,0.38 1.03,0.7 1.62,0.94l0.36,2.54c0.05,0.24 0.24,0.41 0.48,0.41h3.84c0.24,0 0.44,-0.17 0.47,-0.41l0.36,-2.54c0.59,-0.24 1.13,-0.56 1.62,-0.94l2.39,0.96c0.22,0.08 0.47,0 0.59,-0.22l1.92,-3.32c0.12,-0.22 0.07,-0.47 -0.12,-0.61L19.14,12.94zM12,15.6c-1.98,0 -3.6,-1.62 -3.6,-3.6s1.62,-3.6 3.6,-3.6s3.6,1.62 3.6,3.6S13.98,15.6 12,15.6z"/>
+</vector>
diff --git a/res/layout/activity_about.xml b/res/layout/activity_about.xml
--- a/res/layout/activity_about.xml
+++ b/res/layout/activity_about.xml
@@ -2,15 +2,21 @@
                 xmlns:tools="http://schemas.android.com/tools"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
-                android:paddingLeft="@dimen/activity_horizontal_margin"
-                android:paddingRight="@dimen/activity_horizontal_margin"
                 tools:context="it.reyboz.bustorino.ActivityAbout">
+    <!-- The ActionBar displayed at the top -->
+
+    <include
+        layout="@layout/default_toobar"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" />
 
     <TextView
         android:id="@+id/aboutTextView"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginTop="5dip"
+        android:layout_marginLeft="@dimen/activity_horizontal_margin"
+        android:layout_marginRight="@dimen/activity_horizontal_margin"
         android:textAppearance="?android:attr/textAppearanceMedium"/>
 
 </RelativeLayout>
\ No newline at end of file
diff --git a/res/layout/new_main_activity.xml b/res/layout/activity_principal.xml
rename from res/layout/new_main_activity.xml
rename to res/layout/activity_principal.xml
diff --git a/res/layout/fragment_main_screen.xml b/res/layout/fragment_main_screen.xml
--- a/res/layout/fragment_main_screen.xml
+++ b/res/layout/fragment_main_screen.xml
@@ -3,7 +3,9 @@
              xmlns:tools="http://schemas.android.com/tools"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
-             tools:context=".fragments.MainScreenFragment">
+             tools:context=".fragments.MainScreenFragment"
+             android:paddingTop="10dip"
+    >
 
     <ImageButton
             android:id="@+id/QRButton"
@@ -17,7 +19,7 @@
             android:layout_marginStart="16dp"
             android:background="@drawable/qrcode_button_custom"
             android:contentDescription="@string/qrcode"
-            android:onClick="onQRButtonClick" />
+        />
 
     <EditText
             android:id="@+id/busStopSearchByIDEditText"
@@ -44,21 +46,22 @@
     <!--android:layout_alignParentLeft="true"
     android:layout_alignParentStart="true"-->
     <EditText
-            android:id="@+id/busStopSearchByNameEditText"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginEnd="5dp"
-            android:layout_marginLeft="5dip"
-            android:layout_marginRight="5dip"
-            android:layout_toEndOf="@+id/QRButton"
-            android:layout_toLeftOf="@+id/searchButton"
-            android:layout_toRightOf="@+id/QRButton"
-            android:layout_toStartOf="@+id/searchButton"
-            android:ems="10"
-            android:hint="@string/insert_bus_stop_name"
-            android:imeOptions="actionSearch"
-            android:singleLine="true"
-            android:visibility="gone">
+        android:id="@+id/busStopSearchByNameEditText"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="5dp"
+        android:layout_marginLeft="5dip"
+        android:layout_marginRight="5dip"
+        android:layout_toEndOf="@+id/QRButton"
+        android:layout_toLeftOf="@+id/searchButton"
+        android:layout_toRightOf="@+id/QRButton"
+        android:layout_toStartOf="@+id/searchButton"
+
+        android:ems="10"
+        android:hint="@string/insert_bus_stop_name"
+        android:imeOptions="actionSearch"
+        android:singleLine="true"
+        android:visibility="gone">
 
         <requestFocus />
     </EditText>
@@ -75,7 +78,7 @@
             android:layout_marginRight="16dp"
             android:background="@drawable/search_button_custom"
             android:contentDescription="@string/search"
-            android:onClick="onSearchClick" />
+            />
 
     <ProgressBar
             android:id="@+id/progressBar"
@@ -121,7 +124,6 @@
             android:layout_marginEnd="16dp"
             android:layout_marginRight="16dp"
             android:background="@drawable/route_background_bus"
-            android:onClick="onHideHint"
             android:text="@string/hint_button"
             android:textColor="@color/grey_100"
             android:textSize="19sp"
@@ -152,7 +154,6 @@
             android:layout_alignParentRight="true"
             android:layout_gravity="bottom|end"
             android:layout_margin="16dp"
-            android:onClick="onToggleKeyboardLayout"
             android:src="@drawable/alphabetical"
             fabSize="normal"
             backgroundTint="@color/teal_500"
diff --git a/res/menu/drawer_main.xml b/res/menu/drawer_main.xml
--- a/res/menu/drawer_main.xml
+++ b/res/menu/drawer_main.xml
@@ -16,4 +16,9 @@
             android:title="@string/nav_favorites_text" />
     </group>
 
+    <item android:id="@+id/drawer_action_settings"
+        android:title="@string/action_settings"
+        android:icon="@drawable/ic_baseline_settings_24"
+        />
+
 </menu>
\ No newline at end of file
diff --git a/res/menu/extra_menu_items.xml b/res/menu/extra_menu_items.xml
new file mode 100644
--- /dev/null
+++ b/res/menu/extra_menu_items.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    >
+        <item
+            android:id="@+id/action_about"
+            android:orderInCategory="4"
+            android:title="@string/action_about_more" />
+        <item
+            android:id="@+id/action_hack"
+            android:orderInCategory="6"
+            android:title="@string/action_hack"
+            app:showAsAction="never" />
+        <item
+            android:id="@+id/action_source"
+            android:orderInCategory="7"
+            android:title="@string/action_source"
+            app:showAsAction="never" />
+        <item
+            android:id="@+id/action_licence"
+            android:orderInCategory="8"
+            android:title="@string/action_licence"
+            app:showAsAction="never" />
+</menu>
\ No newline at end of file
diff --git a/res/values/theme.xml b/res/values/theme.xml
--- a/res/values/theme.xml
+++ b/res/values/theme.xml
@@ -7,7 +7,7 @@
         <item name="colorAccent">@color/teal_500</item>
     </style>
 
-    <style name="AboutTheme" parent="Theme.AppCompat.Light.DarkActionBar">
+    <style name="AboutTheme" parent="AppTheme.NoActionBar">
         <item name="colorPrimary">@color/teal_300</item>
         <item name="colorPrimaryDark">@color/teal_500</item>
         <item name="colorAccent">@color/blue_700</item>
diff --git a/src/it/reyboz/bustorino/ActivityAbout.java b/src/it/reyboz/bustorino/ActivityAbout.java
--- a/src/it/reyboz/bustorino/ActivityAbout.java
+++ b/src/it/reyboz/bustorino/ActivityAbout.java
@@ -17,6 +17,7 @@
  */
 package it.reyboz.bustorino;
 
+import androidx.appcompat.widget.Toolbar;
 import androidx.core.app.NavUtils;
 import androidx.appcompat.app.ActionBar;
 import androidx.appcompat.app.AppCompatActivity;
@@ -40,19 +41,18 @@
         aboutTextView.setText(htmlText);
         aboutTextView.setMovementMethod(LinkMovementMethod.getInstance());
 
-        // Back button
-        ActionBar ab = getSupportActionBar();
-        assert ab != null;
-        ab.setDisplayHomeAsUpEnabled(true);
+        Toolbar mToolbar = findViewById(R.id.default_toolbar);
+        setSupportActionBar(mToolbar);
+        if (getSupportActionBar()!=null)
+            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
     }
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-            // Respond to the action bar's Up/Home button
-            case android.R.id.home:
-                NavUtils.navigateUpFromSameTask(this);
-                return true;
+        // Respond to the action bar's Up/Home button
+        if (item.getItemId() == android.R.id.home) {//NavUtils.navigateUpFromSameTask(this);
+            onBackPressed();
+            return true;
         }
         return super.onOptionsItemSelected(item);
     }
diff --git a/src/it/reyboz/bustorino/ActivityMain.java b/src/it/reyboz/bustorino/ActivityMain.java
--- a/src/it/reyboz/bustorino/ActivityMain.java
+++ b/src/it/reyboz/bustorino/ActivityMain.java
@@ -18,6 +18,7 @@
 package it.reyboz.bustorino;
 
 import android.Manifest;
+import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
@@ -69,11 +70,14 @@
 import it.reyboz.bustorino.data.UserDB;
 import it.reyboz.bustorino.fragments.*;
 import it.reyboz.bustorino.middleware.*;
+import it.reyboz.bustorino.util.Permissions;
 
 import java.util.Arrays;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
+import static it.reyboz.bustorino.backend.utils.getBusStopIDFromUri;
+
 public class ActivityMain extends GeneralActivity implements FragmentListenerMain {
 
     /*
@@ -132,15 +136,19 @@
      * @see swipeRefreshLayout
      */
     private final Handler theHandler = new Handler();
-    private final Runnable refreshing = new Runnable() {
+    private final Runnable refreshStop = new Runnable() {
         public void run() {
             if (framan.findFragmentById(R.id.resultFrame) instanceof ArrivalsFragment) {
                 ArrivalsFragment fragment = (ArrivalsFragment) framan.findFragmentById(R.id.resultFrame);
-                String stopName = fragment.getStopID();
+                if (fragment == null){
+                    new AsyncDataDownload(fh, arrivalsFetchers, getApplicationContext()).execute();
+                } else{
+                    String stopName = fragment.getStopID();
 
-                new AsyncDataDownload(fh, fragment.getCurrentFetchersAsArray()).execute(stopName);
+                    new AsyncDataDownload(fh, fragment.getCurrentFetchersAsArray(), getApplicationContext()).execute(stopName);
+                }
             } else //we create a new fragment, which is WRONG
-                new AsyncDataDownload(fh, arrivalsFetchers).execute();
+                new AsyncDataDownload(fh, arrivalsFetchers, getApplicationContext()).execute();
         }
     };
 
@@ -191,14 +199,14 @@
 
         // Called when the layout is pulled down
         swipeRefreshLayout
-                .setOnRefreshListener(() -> theHandler.post(refreshing));
+                .setOnRefreshListener(() -> theHandler.post(refreshStop));
 
         /**
          * @author Marco Gagino!!!
          */
         //swipeRefreshLayout.setColorSchemeColors(R.color.blue_500, R.color.orange_500); // setColorScheme is deprecated, setColorSchemeColors isn't
         swipeRefreshLayout.setColorSchemeResources(R.color.blue_500, R.color.orange_500);
-        fh = new FragmentHelper(this, R.id.listRefreshLayout, R.id.resultFrame);
+        fh = new FragmentHelper(this, framan, getApplicationContext(),R.id.resultFrame);
         setSearchModeBusStopID();
 
         //---------------------------- START INTENT CHECK QUEUE ------------------------------------
@@ -258,9 +266,6 @@
             requestArrivalsForStopID(busStopID);
         }
         //Try (hopefully) database update
-        //TODO: Check if service shows the notification
-        //Old code for the db update
-        //DatabaseUpdateService.startDBUpdate(getApplicationContext());
 
 
         PeriodicWorkRequest wr = new PeriodicWorkRequest.Builder(DBUpdateWorker.class, 1, TimeUnit.DAYS)
@@ -317,7 +322,7 @@
         cr.setCostAllowed(true);
         cr.setPowerRequirement(Criteria.NO_REQUIREMENT);
         //We want the nearby bus stops!
-        theHandler.post(new NearbyStopsRequester());
+        theHandler.post(new NearbyStopsRequester(this));
         //If there are no providers available, then, wait for them
 
 
@@ -363,7 +368,7 @@
         fh.setBlockAllActivities(false);
         //TODO: check if current LiveData-bound observer works
         if (pendingNearbyStopsRequest)
-            theHandler.post(new NearbyStopsRequester());
+            theHandler.post(new NearbyStopsRequester(this));
         ActionBar bar = getSupportActionBar();
         if(bar!=null) bar.show();
         else Log.w(DEBUG_TAG, "ACTION BAR IS NULL");
@@ -469,7 +474,7 @@
         } else { // searchMode == SEARCH_BY_NAME
             String query = busStopSearchByNameEditText.getText().toString();
             //new asyncWgetBusStopSuggestions(query, stopsDB, StopsFindersByNameRecursionHelper);
-            new AsyncDataDownload(fh, stopsFinderByNames).execute(query);
+            new AsyncDataDownload(fh, stopsFinderByNames, getApplicationContext()).execute(query);
         }
     }
 
@@ -486,7 +491,7 @@
                     //if we sent a request for a new NearbyStopsFragment
                     if (pendingNearbyStopsRequest) {
                         pendingNearbyStopsRequest = false;
-                        theHandler.post(new NearbyStopsRequester());
+                        theHandler.post(new NearbyStopsRequester(this));
                     }
 
                 } else {
@@ -535,13 +540,13 @@
             if (fragment !=null && fragment.getStopID() != null && fragment.getStopID().equals(ID)){
                 // Run with previous fetchers
                 //fragment.getCurrentFetchers().toArray()
-                new AsyncDataDownload(fh,fragment.getCurrentFetchersAsArray()).execute(ID);
+                new AsyncDataDownload(fh,fragment.getCurrentFetchersAsArray(), this).execute(ID);
             } else{
-                new AsyncDataDownload(fh, arrivalsFetchers).execute(ID);
+                new AsyncDataDownload(fh, arrivalsFetchers, this).execute(ID);
             }
         }
         else {
-            new AsyncDataDownload(fh,arrivalsFetchers).execute(ID);
+            new AsyncDataDownload(fh, arrivalsFetchers, this).execute(ID);
             Log.d("MainActiv", "Started search for arrivals of stop " + ID);
         }
     }
@@ -609,7 +614,7 @@
         Log.d(DEBUG_TAG, "Provider " + provider + " got enabled");
         if (locmgr != null && pendingNearbyStopsRequest && locmgr.getProvider(provider).meetsCriteria(cr)) {
             pendingNearbyStopsRequest = false;
-            theHandler.post(new NearbyStopsRequester());
+            theHandler.post(new NearbyStopsRequester(this));
         }
     }
 
@@ -642,6 +647,13 @@
      * Run location requests separately and asynchronously
      */
     class NearbyStopsRequester implements Runnable {
+
+        Activity runningAct;
+
+        public NearbyStopsRequester(Activity runningAct) {
+            this.runningAct = runningAct;
+        }
+
         @Override
         public void run() {
             final boolean canRunPosition = Build.VERSION.SDK_INT < Build.VERSION_CODES.M || getOption(LOCATION_PERMISSION_GIVEN, false);
@@ -653,7 +665,7 @@
             if (noPermission) {
                 if (!canRunPosition) {
                     pendingNearbyStopsRequest = true;
-                    assertLocationPermissions();
+                    Permissions.assertLocationPermissions(getApplicationContext(),runningAct);
                     Log.w(DEBUG_TAG, "Cannot get position: Asking permission, noPositionFromSys: " + noPermission);
                     return;
                 } else {
@@ -703,26 +715,6 @@
 
 
     ///////////////////////////////// OTHER STUFF //////////////////////////////////////////////////
-    /**
-     * Check if the last Bus Stop is in the favorites
-     *
-     * @return
-     */
-    public boolean isStopInFavorites(String busStopId) {
-        boolean found = false;
-
-        // no stop no party
-        if (busStopId != null) {
-            SQLiteDatabase userDB = new UserDB(getApplicationContext()).getReadableDatabase();
-            found = UserDB.isStopInFavorites(userDB, busStopId);
-        }
-
-        return found;
-    }
-
-    /**
-     * Add the last Stop to favorites
-     */
 
 
     @Override
@@ -841,55 +833,8 @@
 
     }
 
-    /**
-     * Open an URL in the default browser.
-     *
-     * @param url URL
-     */
-    public void openIceweasel(String url) {
-        Intent browserIntent1 = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
-        startActivity(browserIntent1);
-    }
-
-    ///////////////////// INTENT HELPER ////////////////////////////////////////////////////////////
-
-    /**
-     * Try to extract the bus stop ID from a URi
-     *
-     * @param uri The URL
-     * @return bus stop ID or null
-     */
-    public static String getBusStopIDFromUri(Uri uri) {
-        String busStopID;
-
-        // everithing catches fire when passing null to a switch.
-        String host = uri.getHost();
-        if (host == null) {
-            Log.e("ActivityMain", "Not an URL: " + uri);
-            return null;
-        }
-
-        switch (host) {
-            case "m.gtt.to.it":
-                // http://m.gtt.to.it/m/it/arrivi.jsp?n=1254
-                busStopID = uri.getQueryParameter("n");
-                if (busStopID == null) {
-                    Log.e("ActivityMain", "Expected ?n from: " + uri);
-                }
-                break;
-            case "www.gtt.to.it":
-            case "gtt.to.it":
-                // http://www.gtt.to.it/cms/percorari/arrivi?palina=1254
-                busStopID = uri.getQueryParameter("palina");
-                if (busStopID == null) {
-                    Log.e("ActivityMain", "Expected ?palina from: " + uri);
-                }
-                break;
-            default:
-                Log.e("ActivityMain", "Unexpected intent URL: " + uri);
-                busStopID = null;
-        }
-        return busStopID;
+    private void openIceweasel(String url){
+        utils.openIceweasel(url, this);
     }
 
 }
\ No newline at end of file
diff --git a/src/it/reyboz/bustorino/ActivityMap.java b/src/it/reyboz/bustorino/ActivityMap.java
--- a/src/it/reyboz/bustorino/ActivityMap.java
+++ b/src/it/reyboz/bustorino/ActivityMap.java
@@ -87,7 +87,7 @@
     protected ImageButton btCenterMap;
     protected ImageButton btFollowMe;
 
-    @RequiresApi(api = Build.VERSION_CODES.HONEYCOMB)
+    //@RequiresApi(api = Build.VERSION_CODES.HONEYCOMB)
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
diff --git a/src/it/reyboz/bustorino/ActivityPrincipal.java b/src/it/reyboz/bustorino/ActivityPrincipal.java
--- a/src/it/reyboz/bustorino/ActivityPrincipal.java
+++ b/src/it/reyboz/bustorino/ActivityPrincipal.java
@@ -1,33 +1,62 @@
 package it.reyboz.bustorino;
 
+import android.content.Intent;
+import android.content.SharedPreferences;
 import android.content.res.Configuration;
-import android.content.res.Resources;
+import android.net.Uri;
 import android.os.Bundle;
 import android.util.Log;
+import android.view.Menu;
 import android.view.MenuItem;
+import android.widget.Toast;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.appcompat.app.ActionBarDrawerToggle;
 import androidx.appcompat.widget.Toolbar;
-import androidx.core.app.NavUtils;
 import androidx.core.view.GravityCompat;
 import androidx.drawerlayout.widget.DrawerLayout;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
+import androidx.work.BackoffPolicy;
+import androidx.work.Constraints;
+import androidx.work.ExistingPeriodicWorkPolicy;
+import androidx.work.NetworkType;
+import androidx.work.PeriodicWorkRequest;
+import androidx.work.WorkInfo;
+import androidx.work.WorkManager;
 
 import com.google.android.material.navigation.NavigationView;
+import com.google.android.material.snackbar.Snackbar;
 
+import java.util.concurrent.TimeUnit;
+
+import it.reyboz.bustorino.data.DBUpdateWorker;
+import it.reyboz.bustorino.data.DatabaseUpdate;
+import it.reyboz.bustorino.fragments.FragmentKind;
+import it.reyboz.bustorino.fragments.FragmentListenerMain;
+import it.reyboz.bustorino.fragments.MainScreenFragment;
 import it.reyboz.bustorino.middleware.GeneralActivity;
 
-public class ActivityPrincipal extends GeneralActivity {
+import static it.reyboz.bustorino.backend.utils.getBusStopIDFromUri;
+import static it.reyboz.bustorino.backend.utils.openIceweasel;
+
+public class ActivityPrincipal extends GeneralActivity implements FragmentListenerMain {
     private DrawerLayout mDrawer;
     private NavigationView mNavView;
     private ActionBarDrawerToggle drawerToggle;
     private final static String DEBUG_TAG="BusTO Act Principal";
 
+    private Snackbar snackbar;
+
+
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        setContentView(R.layout.new_main_activity);
+        setContentView(R.layout.activity_principal);
+        final SharedPreferences theShPr = getMainSharedPreferences();
+
 
         Toolbar mToolbar = findViewById(R.id.default_toolbar);
         setSupportActionBar(mToolbar);
@@ -35,6 +64,8 @@
         getSupportActionBar().setDisplayHomeAsUpEnabled(true);
         else Log.w(DEBUG_TAG, "NO ACTION BAR");
 
+        mToolbar.setOnMenuItemClickListener(new ToolbarItemClickListener());
+
 
         mDrawer = findViewById(R.id.drawer_layout);
         drawerToggle = setupDrawerToggle(mToolbar);
@@ -50,6 +81,101 @@
         setupDrawerContent(mNavView);
 
 
+        /// LEGACY CODE
+        //---------------------------- START INTENT CHECK QUEUE ------------------------------------
+
+        // Intercept calls from URL intent
+        boolean tryedFromIntent = false;
+
+        String busStopID = null;
+        Uri data = getIntent().getData();
+        if (data != null) {
+            busStopID = getBusStopIDFromUri(data);
+            tryedFromIntent = true;
+        }
+
+        // Intercept calls from other activities
+        if (!tryedFromIntent) {
+            Bundle b = getIntent().getExtras();
+            if (b != null) {
+                busStopID = b.getString("bus-stop-ID");
+
+                /**
+                 * I'm not very sure if you are coming from an Intent.
+                 * Some launchers work in strange ways.
+                 */
+                tryedFromIntent = busStopID != null;
+            }
+        }
+
+        //---------------------------- END INTENT CHECK QUEUE --------------------------------------
+
+        if (busStopID == null) {
+            // Show keyboard if can't start from intent
+            // JUST DON'T
+            // showKeyboard();
+
+            // You haven't obtained anything... from an intent?
+            if (tryedFromIntent) {
+
+                // This shows a luser warning
+                Toast.makeText(getApplicationContext(),
+                        R.string.insert_bus_stop_number_error, Toast.LENGTH_SHORT).show();
+            }
+        } else {
+            // If you are here an intent has worked successfully
+            //setBusStopSearchByIDEditText(busStopID);
+
+            requestArrivalsForStopID(busStopID);
+        }
+        //Try (hopefully) database update
+
+
+        PeriodicWorkRequest wr = new PeriodicWorkRequest.Builder(DBUpdateWorker.class, 1, TimeUnit.DAYS)
+                .setBackoffCriteria(BackoffPolicy.LINEAR, 30, TimeUnit.MINUTES)
+                .setConstraints(new Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED)
+                        .build())
+                .build();
+        final WorkManager workManager = WorkManager.getInstance(this);
+
+        final int version = theShPr.getInt(DatabaseUpdate.DB_VERSION_KEY, -10);
+        if (version >= 0)
+            workManager.enqueueUniquePeriodicWork(DBUpdateWorker.DEBUG_TAG,
+                    ExistingPeriodicWorkPolicy.KEEP, wr);
+        else workManager.enqueueUniquePeriodicWork(DBUpdateWorker.DEBUG_TAG,
+                ExistingPeriodicWorkPolicy.REPLACE, wr);
+        /*
+        Set database update
+         */
+        workManager.getWorkInfosForUniqueWorkLiveData(DBUpdateWorker.DEBUG_TAG)
+                .observe(this, workInfoList -> {
+                    // If there are no matching work info, do nothing
+                    if (workInfoList == null || workInfoList.isEmpty()) {
+                        return;
+                    }
+                    Log.d(DEBUG_TAG, "WorkerInfo: "+workInfoList);
+
+                    boolean showProgress = false;
+                    for (WorkInfo workInfo : workInfoList) {
+                        if (workInfo.getState() == WorkInfo.State.RUNNING) {
+                            showProgress = true;
+                        }
+                    }
+
+                    if (showProgress) {
+                        createDefaultSnackbar();
+                    } else {
+                        if(snackbar!=null) {
+                            snackbar.dismiss();
+                            snackbar = null;
+                        }
+                    }
+
+                });
+        // show the main fragment
+        showMainFragment();
+
+
     }
     private ActionBarDrawerToggle setupDrawerToggle(Toolbar toolbar) {
         // NOTE: Make sure you pass in a valid toolbar reference.  ActionBarDrawToggle() does not require it
@@ -60,7 +186,12 @@
     private void setupDrawerContent(NavigationView navigationView) {
         navigationView.setNavigationItemSelectedListener(
                 menuItem -> {
-
+                    if (menuItem.getItemId() == R.id.drawer_action_settings) {
+                        Log.d("MAINBusTO", "Pressed button preferences");
+                        closeDrawerIfOpen();
+                        startActivity(new Intent(ActivityPrincipal.this, ActivitySettings.class));
+                        return true;
+                    }
                     //selectDrawerItem(menuItem);
                     Log.d(DEBUG_TAG, "pressed item "+menuItem.toString());
 
@@ -70,6 +201,11 @@
 
     }
 
+    private void closeDrawerIfOpen(){
+        if (mDrawer.isDrawerOpen(GravityCompat.START))
+            mDrawer.closeDrawer(GravityCompat.START);
+    }
+
 
     // `onPostCreate` called when activity start-up is complete after `onStart()`
     // NOTE 1: Make sure to override the method with only a single `Bundle` argument
@@ -89,20 +225,24 @@
         drawerToggle.onConfigurationChanged(newConfig);
 
     }
+
     @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        getMenuInflater().inflate(R.menu.extra_menu_items, menu);
+        return super.onCreateOptionsMenu(menu);
+    }
 
+    @Override
     public boolean onOptionsItemSelected(@NonNull MenuItem item) {
 
         int[] cases = {R.id.nav_arrivals, R.id.nav_favorites_item};
+        Log.d(DEBUG_TAG, "Item pressed");
+
 
         switch (item.getItemId()){
             case android.R.id.home:
                 mDrawer.openDrawer(GravityCompat.START);
                 return true;
-
-            case R.id.nav_arrivals:
-                //do something
-                break;
             default:
 
         }
@@ -118,9 +258,116 @@
 
     @Override
     public void onBackPressed() {
+        boolean foundFragment = false;
+        Fragment shownFrag = getSupportFragmentManager().findFragmentById(R.id.mainActContentFrame);
         if (mDrawer.isDrawerOpen(GravityCompat.START))
             mDrawer.closeDrawer(GravityCompat.START);
+        else if(shownFrag != null && shownFrag.isVisible() && shownFrag.getChildFragmentManager().getBackStackEntryCount() > 0){
+            shownFrag.getChildFragmentManager().popBackStack();
+        }
+        else if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
+            getSupportFragmentManager().popBackStack();
+        }
         else
             super.onBackPressed();
     }
+
+    private void createDefaultSnackbar() {
+        if (snackbar == null) {
+            snackbar = Snackbar.make(findViewById(R.id.searchButton), R.string.database_update_message, Snackbar.LENGTH_INDEFINITE);
+        }
+        snackbar.show();
+    }
+
+    private MainScreenFragment showMainFragment(){
+        FragmentManager fraMan = getSupportFragmentManager();
+
+        MainScreenFragment fragment = MainScreenFragment.newInstance();
+
+        FragmentTransaction transaction = fraMan.beginTransaction();
+        transaction.replace(R.id.mainActContentFrame, fragment, MainScreenFragment.FRAGMENT_TAG);
+        transaction.commit();
+        return fragment;
+    }
+    @Nullable
+    private MainScreenFragment getMainFragmentIfVisible(){
+        FragmentManager fraMan = getSupportFragmentManager();
+        Fragment fragment = fraMan.findFragmentByTag(MainScreenFragment.FRAGMENT_TAG);
+        if (fragment!= null && fragment.isVisible()) return (MainScreenFragment) fragment;
+        else return null;
+    }
+
+    @Override
+    public void showFloatingActionButton(boolean yes) {
+        //TODO
+    }
+
+    @Override
+    public void readyGUIfor(FragmentKind fragmentType) {
+        MainScreenFragment probableFragment = getMainFragmentIfVisible();
+        if (probableFragment!=null){
+            probableFragment.readyGUIfor(fragmentType);
+        }
+    }
+
+    @Override
+    public void requestArrivalsForStopID(String ID) {
+        FragmentManager fraMan = getSupportFragmentManager();
+        Fragment fragment = fraMan.findFragmentByTag(MainScreenFragment.FRAGMENT_TAG);
+        MainScreenFragment mainScreenFragment = null;
+        if (fragment==null | !(fragment instanceof MainScreenFragment)){
+            mainScreenFragment = showMainFragment();
+        }
+        else if(!fragment.isVisible()){
+
+            fraMan.beginTransaction().replace(R.id.mainActContentFrame, fragment)
+                    .addToBackStack(null)
+                    .commit();
+            mainScreenFragment = (MainScreenFragment) fragment;
+            Log.d(DEBUG_TAG, "Found the main fragment");
+        } else{
+            mainScreenFragment = (MainScreenFragment) fragment;
+        }
+
+        mainScreenFragment.requestArrivalsForStopID(ID);
+    }
+
+    @Override
+    public void toggleSpinner(boolean state) {
+        MainScreenFragment probableFragment = getMainFragmentIfVisible();
+        if (probableFragment!=null){
+            probableFragment.toggleSpinner(state);
+        }
+    }
+
+    @Override
+    public void enableRefreshLayout(boolean yes) {
+        MainScreenFragment probableFragment = getMainFragmentIfVisible();
+        if (probableFragment!=null){
+            probableFragment.enableRefreshLayout(yes);
+        }
+    }
+
+    class ToolbarItemClickListener implements Toolbar.OnMenuItemClickListener{
+
+        @Override
+        public boolean onMenuItemClick(MenuItem item) {
+            switch (item.getItemId()) {
+                case R.id.action_about:
+                    startActivity(new Intent(ActivityPrincipal.this, ActivityAbout.class));
+                    return true;
+                case R.id.action_hack:
+                    openIceweasel(getString(R.string.hack_url), getApplicationContext());
+                    return true;
+                case R.id.action_source:
+                    openIceweasel("https://gitpull.it/source/libre-busto/", getApplicationContext());
+                    return true;
+                case R.id.action_licence:
+                    openIceweasel("https://www.gnu.org/licenses/gpl-3.0.html", getApplicationContext());
+                    return true;
+                default:
+            }
+            return false;
+        }
+    }
 }
diff --git a/src/it/reyboz/bustorino/backend/FiveTAPIFetcher.java b/src/it/reyboz/bustorino/backend/FiveTAPIFetcher.java
--- a/src/it/reyboz/bustorino/backend/FiveTAPIFetcher.java
+++ b/src/it/reyboz/bustorino/backend/FiveTAPIFetcher.java
@@ -59,6 +59,7 @@
             }
         } catch (JSONException ex){
             res.set(result.PARSER_ERROR);
+            Log.w(DEBUG_NAME, "Couldn't get the JSON repr of:\n"+response);
             return null;
         }
         res.set(result.OK);
diff --git a/src/it/reyboz/bustorino/backend/Palina.java b/src/it/reyboz/bustorino/backend/Palina.java
--- a/src/it/reyboz/bustorino/backend/Palina.java
+++ b/src/it/reyboz/bustorino/backend/Palina.java
@@ -20,6 +20,8 @@
 
 import android.util.Log;
 
+import androidx.annotation.NonNull;
+
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Collections;
@@ -173,11 +175,14 @@
             if(mSource == Passaggio.Source.UNDETERMINED)
                 break;
         }
+        // if the Source is still null, set undetermined
+        if (mSource == null) mSource = Passaggio.Source.UNDETERMINED;
         //finished with the check, setting flags
         routesModified = false;
         allSource = mSource;
     }
 
+    @NonNull
     public Passaggio.Source getPassaggiSourceIfAny(){
         if(allSource==null || routesModified){
             checkPassaggi();
diff --git a/src/it/reyboz/bustorino/backend/utils.java b/src/it/reyboz/bustorino/backend/utils.java
--- a/src/it/reyboz/bustorino/backend/utils.java
+++ b/src/it/reyboz/bustorino/backend/utils.java
@@ -1,6 +1,11 @@
 package it.reyboz.bustorino.backend;
 
 import android.content.Context;
+import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.Uri;
+import android.util.Log;
 import android.view.View;
 
 public abstract class utils {
@@ -28,4 +33,67 @@
         float ncols = ((float)width)/pixelsize;
         return (int) Math.floor(ncols);
     }
+
+    /**
+     * Check if there is an internet connection
+     * @param con context object to get the system service
+     * @return true if we are
+     */
+    public static boolean isConnected(Context con) {
+        ConnectivityManager connMgr = (ConnectivityManager) con.getSystemService(Context.CONNECTIVITY_SERVICE);
+        NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
+        return networkInfo != null && networkInfo.isConnected();
+    }
+
+
+    ///////////////////// INTENT HELPER ////////////////////////////////////////////////////////////
+
+    /**
+     * Try to extract the bus stop ID from a URi
+     *
+     * @param uri The URL
+     * @return bus stop ID or null
+     */
+    public static String getBusStopIDFromUri(Uri uri) {
+        String busStopID;
+
+        // everithing catches fire when passing null to a switch.
+        String host = uri.getHost();
+        if (host == null) {
+            Log.e("ActivityMain", "Not an URL: " + uri);
+            return null;
+        }
+
+        switch (host) {
+            case "m.gtt.to.it":
+                // http://m.gtt.to.it/m/it/arrivi.jsp?n=1254
+                busStopID = uri.getQueryParameter("n");
+                if (busStopID == null) {
+                    Log.e("ActivityMain", "Expected ?n from: " + uri);
+                }
+                break;
+            case "www.gtt.to.it":
+            case "gtt.to.it":
+                // http://www.gtt.to.it/cms/percorari/arrivi?palina=1254
+                busStopID = uri.getQueryParameter("palina");
+                if (busStopID == null) {
+                    Log.e("ActivityMain", "Expected ?palina from: " + uri);
+                }
+                break;
+            default:
+                Log.e("ActivityMain", "Unexpected intent URL: " + uri);
+                busStopID = null;
+        }
+        return busStopID;
+    }
+
+    /**
+     * Open an URL in the default browser.
+     *
+     * @param url URL
+     */
+    public static void openIceweasel(String url, Context context) {
+        Intent browserIntent1 = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
+        context.startActivity(browserIntent1);
+    }
 }
diff --git a/src/it/reyboz/bustorino/fragments/ArrivalsFragment.java b/src/it/reyboz/bustorino/fragments/ArrivalsFragment.java
--- a/src/it/reyboz/bustorino/fragments/ArrivalsFragment.java
+++ b/src/it/reyboz/bustorino/fragments/ArrivalsFragment.java
@@ -276,7 +276,10 @@
      */
     protected void showArrivalsSources(Palina p){
         final Passaggio.Source source = p.getPassaggiSourceIfAny();
-
+        if (source == null){
+            Log.e(DEBUG_TAG, "NULL SOURCE");
+            return;
+        }
         String source_txt;
         switch (source){
             case GTTJSON:
diff --git a/src/it/reyboz/bustorino/fragments/CommonFragmentListener.java b/src/it/reyboz/bustorino/fragments/CommonFragmentListener.java
--- a/src/it/reyboz/bustorino/fragments/CommonFragmentListener.java
+++ b/src/it/reyboz/bustorino/fragments/CommonFragmentListener.java
@@ -21,4 +21,9 @@
      * @param ID the Stop ID
      */
     void requestArrivalsForStopID(String ID);
+
+    /**
+     * Method to call when we want to hide the keyboard
+     */
+    void hideKeyboard();
 }
diff --git a/src/it/reyboz/bustorino/fragments/FragmentHelper.java b/src/it/reyboz/bustorino/fragments/FragmentHelper.java
--- a/src/it/reyboz/bustorino/fragments/FragmentHelper.java
+++ b/src/it/reyboz/bustorino/fragments/FragmentHelper.java
@@ -18,18 +18,18 @@
 package it.reyboz.bustorino.fragments;
 
 
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.database.sqlite.SQLiteException;
+import android.content.Context;
 import androidx.fragment.app.Fragment;
 import androidx.fragment.app.FragmentManager;
 import androidx.fragment.app.FragmentTransaction;
-import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
 import android.util.Log;
+import android.widget.Toast;
+
 import it.reyboz.bustorino.R;
 import it.reyboz.bustorino.backend.Fetcher;
 import it.reyboz.bustorino.backend.Palina;
 import it.reyboz.bustorino.backend.Stop;
+import it.reyboz.bustorino.backend.utils;
 import it.reyboz.bustorino.data.NextGenDB;
 import it.reyboz.bustorino.middleware.*;
 
@@ -40,28 +40,30 @@
  * Helper class to manage the fragments and their needs
  */
 public class FragmentHelper {
-    GeneralActivity act;
+    //GeneralActivity act;
+    private final FragmentListenerMain listenerMain;
+    private final WeakReference<FragmentManager> managerWeakRef;
     private Stop lastSuccessfullySearchedBusStop;
     //support for multiple frames
     private final int secondaryFrameLayout;
-    private final int swipeRefID;
     private final int primaryFrameLayout;
+    private final Context context;
     public static final int NO_FRAME = -3;
+    private static final String DEBUG_TAG = "BusTO FragmHelper";
     private WeakReference<AsyncDataDownload> lastTaskRef;
-    private NextGenDB newDBHelper;
     private boolean shouldHaltAllActivities=false;
 
 
-    public FragmentHelper(GeneralActivity act, int swipeRefID, int mainFrame) {
-        this(act,swipeRefID,mainFrame,NO_FRAME);
+    public FragmentHelper(FragmentListenerMain listener, FragmentManager framan, Context context, int mainFrame) {
+        this(listener,framan, context,mainFrame,NO_FRAME);
     }
 
-    public FragmentHelper(GeneralActivity act, int swipeRefID, int primaryFrameLayout, int secondaryFrameLayout) {
-        this.act = act;
-        this.swipeRefID = swipeRefID;
+    public FragmentHelper(FragmentListenerMain listener, FragmentManager fraMan, Context context, int primaryFrameLayout, int secondaryFrameLayout) {
+        this.listenerMain = listener;
+        this.managerWeakRef = new WeakReference<>(fraMan);
         this.primaryFrameLayout = primaryFrameLayout;
         this.secondaryFrameLayout = secondaryFrameLayout;
-        newDBHelper = new NextGenDB(act.getApplicationContext());
+        this.context = context.getApplicationContext();
     }
 
     /**
@@ -89,19 +91,23 @@
         boolean sameFragment;
         ArrivalsFragment arrivalsFragment;
 
-        if(act==null || shouldHaltAllActivities) {
+        if(managerWeakRef.get()==null || shouldHaltAllActivities) {
             //SOMETHING WENT VERY WRONG
+            Log.e(DEBUG_TAG, "We are asked for a new stop but we can't show anything");
             return;
         }
 
-        FragmentManager fm = act.getSupportFragmentManager();
+        FragmentManager fm = managerWeakRef.get();
 
         if(fm.findFragmentById(primaryFrameLayout) instanceof ArrivalsFragment) {
             arrivalsFragment = (ArrivalsFragment) fm.findFragmentById(primaryFrameLayout);
+            //Log.d(DEBUG_TAG, "Arrivals are for fragment with same stop?");
             sameFragment = arrivalsFragment.isFragmentForTheSameStop(p);
-        } else
+        } else {
             sameFragment = false;
+            Log.d(DEBUG_TAG, "We aren't showing an ArrivalsFragment");
 
+        }
         setLastSuccessfullySearchedBusStop(p);
 
         if(!sameFragment) {
@@ -122,7 +128,7 @@
         // DO NOT CALL `setListAdapter` ever on arrivals fragment
         arrivalsFragment.updateFragmentData(p);
 
-        act.hideKeyboard();
+        listenerMain.hideKeyboard();
         toggleSpinner(false);
     }
 
@@ -132,9 +138,14 @@
      * @param query String queried
      */
     public void createFragmentFor(List<Stop> resultList,String query){
-        act.hideKeyboard();
+        listenerMain.hideKeyboard();
         StopListFragment listfragment = StopListFragment.newInstance(query);
-        attachFragmentToContainer(act.getSupportFragmentManager(),listfragment,false,"search_"+query);
+        if(managerWeakRef.get()==null || shouldHaltAllActivities) {
+            //SOMETHING WENT VERY WRONG
+            Log.e(DEBUG_TAG, "We are asked for a new stop but we can't show anything");
+            return;
+        }
+        attachFragmentToContainer(managerWeakRef.get(),listfragment,false,"search_"+query);
         listfragment.setStopList(resultList);
         toggleSpinner(false);
 
@@ -145,12 +156,7 @@
      * @param on new status of spinner system
      */
     public void toggleSpinner(boolean on){
-        if (act instanceof FragmentListenerMain)
-            ((FragmentListenerMain) act).toggleSpinner(on);
-        else {
-            SwipeRefreshLayout srl = (SwipeRefreshLayout) act.findViewById(swipeRefID);
-            srl.setRefreshing(false);
-        }
+        listenerMain.toggleSpinner(on);
     }
 
     /**
@@ -171,21 +177,6 @@
         //fm.executePendingTransactions();
     }
 
-    synchronized public int insertBatchDataInNextGenDB(ContentValues[] valuesArr,String tableName){
-        if(newDBHelper !=null)
-            try {
-                return newDBHelper.insertBatchContent(valuesArr, tableName);
-            } catch (SQLiteException exc){
-                Log.w("DB Batch inserting: ","ERROR Inserting the data batch: ",exc.fillInStackTrace());
-                return -2;
-            }
-        else return -1;
-    }
-
-    synchronized public ContentResolver getContentResolver(){
-        return act.getContentResolver();
-    }
-
     public void setBlockAllActivities(boolean shouldI) {
         this.shouldHaltAllActivities = shouldI;
     }
@@ -208,13 +199,13 @@
             case OK:
                 break;
             case CLIENT_OFFLINE:
-                act.showToastMessage(R.string.network_error, true);
+                showToastMessage(R.string.network_error, true);
                 break;
             case SERVER_ERROR:
-                if (act.isConnected()) {
-                    act.showToastMessage(R.string.parsing_error, true);
+                if (utils.isConnected(context)) {
+                    showToastMessage(R.string.parsing_error, true);
                 } else {
-                    act.showToastMessage(R.string.network_error, true);
+                    showToastMessage(R.string.network_error, true);
                 }
             case PARSER_ERROR:
             default:
@@ -229,9 +220,13 @@
         }
     }
 
-    public void showShortToast(int message){
-        if (act!=null)
-        act.showToastMessage(message,true);
+    public void showToastMessage(int messageID, boolean short_lenght) {
+        final int length = short_lenght ? Toast.LENGTH_SHORT : Toast.LENGTH_LONG;
+        if (context != null)
+        Toast.makeText(context, messageID, length).show();
+    }
+    private void showShortToast(int messageID){
+        showToastMessage(messageID, true);
     }
 
 }
diff --git a/src/it/reyboz/bustorino/fragments/MainScreenFragment.java b/src/it/reyboz/bustorino/fragments/MainScreenFragment.java
--- a/src/it/reyboz/bustorino/fragments/MainScreenFragment.java
+++ b/src/it/reyboz/bustorino/fragments/MainScreenFragment.java
@@ -1,25 +1,43 @@
 package it.reyboz.bustorino.fragments;
 
+import android.Manifest;
 import android.content.Context;
+import android.content.pm.PackageManager;
+import android.location.Criteria;
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
+import android.location.LocationProvider;
+import android.os.Build;
 import android.os.Bundle;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.widget.AppCompatImageButton;
+import androidx.core.app.ActivityCompat;
 import androidx.fragment.app.Fragment;
 import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
 import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
 
+import android.os.Handler;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.Button;
 import android.widget.EditText;
 import android.widget.ImageButton;
 import android.widget.ProgressBar;
 import android.widget.TextView;
+import android.widget.Toast;
 
 import com.google.android.material.floatingactionbutton.FloatingActionButton;
 import com.google.zxing.integration.android.IntentIntegrator;
+
+import it.reyboz.bustorino.ActivityMain;
 import it.reyboz.bustorino.R;
 import it.reyboz.bustorino.backend.ArrivalsFetcher;
 import it.reyboz.bustorino.backend.FiveTAPIFetcher;
@@ -31,6 +49,10 @@
 import it.reyboz.bustorino.backend.StopsFinderByName;
 import it.reyboz.bustorino.data.UserDB;
 import it.reyboz.bustorino.middleware.AsyncDataDownload;
+import it.reyboz.bustorino.util.Permissions;
+
+import static android.content.Context.LOCATION_SERVICE;
+import static it.reyboz.bustorino.util.Permissions.LOCATION_PERMISSION_GIVEN;
 
 
 /**
@@ -45,7 +67,8 @@
 
     private static final String DEBUG_TAG = "BusTO - MainFragment";
 
-    private CommonFragmentListener mListener;
+    public final static String FRAGMENT_TAG = "MainScreenFragment";
+
     /// UI ELEMENTS //
     private ImageButton addToFavorites;
     private FragmentHelper fragmentHelper;
@@ -57,6 +80,8 @@
     private Button hideHintButton;
     private MenuItem actionHelpMenuItem;
     private FloatingActionButton floatingActionButton;
+
+    private boolean setupOnAttached = true;
     //private Snackbar snackbar;
     /*
      * Search mode
@@ -67,8 +92,38 @@
     private int searchMode;
     //private ImageButton addToFavorites;
     private final ArrivalsFetcher[] arrivalsFetchers = new ArrivalsFetcher[]{new FiveTAPIFetcher(), new GTTJSONFetcher(), new FiveTScraperFetcher()};
+    //// HIDDEN BUT IMPORTANT ELEMENTS ////
+    FragmentManager fragMan;
+    Handler mainHandler;
+    private final Runnable refreshStop = new Runnable() {
+        public void run() {
+            if (fragMan.findFragmentById(R.id.resultFrame) instanceof ArrivalsFragment) {
+                ArrivalsFragment fragment = (ArrivalsFragment) fragMan.findFragmentById(R.id.resultFrame);
+                if (fragment == null){
+                    //we create a new fragment, which is WRONG
+                    new AsyncDataDownload(fragmentHelper, arrivalsFetchers,getContext()).execute();
+                } else{
+                    String stopName = fragment.getStopID();
+
+                    new AsyncDataDownload(fragmentHelper, fragment.getCurrentFetchersAsArray(), getContext()).execute(stopName);
+                }
+            } else //we create a new fragment, which is WRONG
+                new AsyncDataDownload(fragmentHelper, arrivalsFetchers, getContext()).execute();
+        }
+    };
+
+
 
 
+    /// LOCATION STUFF ///
+    boolean pendingNearbyStopsRequest = false;
+    LocationManager locmgr;
+
+    private final Criteria cr = new Criteria();
+
+    //// ACTIVITY ATTACHED (LISTENER ///
+    private CommonFragmentListener mListener;
+
     public MainScreenFragment() {
         // Required empty public constructor
     }
@@ -104,11 +159,100 @@
         hideHintButton = root.findViewById(R.id.hideHintButton);
         swipeRefreshLayout = root.findViewById(R.id.listRefreshLayout);
         floatingActionButton = root.findViewById(R.id.floatingActionButton);
+        busStopSearchByIDEditText.setSelectAllOnFocus(true);
+        busStopSearchByIDEditText
+                .setOnEditorActionListener((v, actionId, event) -> {
+                    // IME_ACTION_SEARCH alphabetical option
+                    if (actionId == EditorInfo.IME_ACTION_SEARCH) {
+                        onSearchClick(v);
+                        return true;
+                    }
+                    return false;
+                });
+        busStopSearchByNameEditText
+                .setOnEditorActionListener((v, actionId, event) -> {
+                    // IME_ACTION_SEARCH alphabetical option
+                    if (actionId == EditorInfo.IME_ACTION_SEARCH) {
+                        onSearchClick(v);
+                        return true;
+                    }
+                    return false;
+                });
+
+        swipeRefreshLayout
+                .setOnRefreshListener(() -> mainHandler.post(refreshStop));
+        swipeRefreshLayout.setColorSchemeResources(R.color.blue_500, R.color.orange_500);
+
+        floatingActionButton.setOnClickListener((this::onToggleKeyboardLayout));
+        hideHintButton.setOnClickListener(this::onHideHint);
+
+        AppCompatImageButton qrButton = root.findViewById(R.id.QRButton);
+        qrButton.setOnClickListener(this::onQRButtonClick);
+
+        AppCompatImageButton searchButton = root.findViewById(R.id.searchButton);
+        searchButton.setOnClickListener(this::onSearchClick);
+
+        // Fragment stuff
+        fragMan = getChildFragmentManager();
+        fragMan.addOnBackStackChangedListener(() -> Log.d("BusTO Main Fragment", "BACK STACK CHANGED"));
+
+        fragmentHelper = new FragmentHelper(this, getChildFragmentManager(), getContext(), R.id.resultFrame);
+        setSearchModeBusStopID();
+
+
+        cr.setAccuracy(Criteria.ACCURACY_FINE);
+        cr.setAltitudeRequired(false);
+        cr.setBearingRequired(false);
+        cr.setCostAllowed(true);
+        cr.setPowerRequirement(Criteria.NO_REQUIREMENT);
+
+        locmgr = (LocationManager) getContext().getSystemService(LOCATION_SERVICE);
         return root;
     }
+    @Override
+    public void onAttach(@NonNull Context context) {
+        super.onAttach(context);
+        mainHandler = new Handler();
+        if (context instanceof CommonFragmentListener) {
+            mListener = (CommonFragmentListener) context;
+        } else {
+            throw new RuntimeException(context.toString()
+                    + " must implement CommonFragmentListener");
+        }
+        if (setupOnAttached){
+            //We want the nearby bus stops!
+            mainHandler.post(new NearbyStopsRequester(getContext(),cr, locListener));
+            //If there are no providers available, then, wait for them
+
+            setupOnAttached = false;
+        }
+
+    }
+    @Override
+    public void onDetach() {
+        super.onDetach();
+        mListener = null;
+    }
 
 
+    @Override
+    public void onResume() {
+
+        final Context con = getContext();
+        if (con != null)
+            locmgr = (LocationManager) getContext().getSystemService(LOCATION_SERVICE);
+        else {
+            Log.w(DEBUG_TAG, "Context is null at onResume");
+        }
+        super.onResume();
+    }
 
+    @Override
+    public void onPause() {
+        //mainHandler = null;
+        locmgr = null;
+        super.onPause();
+    }
     /*
     GUI METHODS
      */
@@ -139,7 +283,7 @@
         } else { // searchMode == SEARCH_BY_NAME
             String query = busStopSearchByNameEditText.getText().toString();
             //new asyncWgetBusStopSuggestions(query, stopsDB, StopsFindersByNameRecursionHelper);
-            new AsyncDataDownload(fragmentHelper, stopsFinderByNames).execute(query);
+            new AsyncDataDownload(fragmentHelper, stopsFinderByNames, getContext()).execute(query);
         }
     }
 
@@ -201,16 +345,15 @@
     private void showHints() {
         howDoesItWorkTextView.setVisibility(View.VISIBLE);
         hideHintButton.setVisibility(View.VISIBLE);
-        actionHelpMenuItem.setVisible(false);
+        //actionHelpMenuItem.setVisible(false);
     }
 
     private void hideHints() {
         howDoesItWorkTextView.setVisibility(View.GONE);
         hideHintButton.setVisibility(View.GONE);
-        actionHelpMenuItem.setVisible(true);
+        //actionHelpMenuItem.setVisible(true);
     }
 
-    //TODO: toggle spinner from mainActivity
     @Override
     public void toggleSpinner(boolean enable) {
         if (enable) {
@@ -227,13 +370,13 @@
     private void prepareGUIForBusLines() {
         swipeRefreshLayout.setEnabled(true);
         swipeRefreshLayout.setVisibility(View.VISIBLE);
-        actionHelpMenuItem.setVisible(true);
+        //actionHelpMenuItem.setVisible(true);
     }
 
     private void prepareGUIForBusStops() {
         swipeRefreshLayout.setEnabled(false);
         swipeRefreshLayout.setVisibility(View.VISIBLE);
-        actionHelpMenuItem.setVisible(false);
+        //actionHelpMenuItem.setVisible(false);
     }
 
 
@@ -250,10 +393,9 @@
      */
     @Override
     public void readyGUIfor(FragmentKind fragmentType) {
-        throw new UnsupportedOperationException();
-        /*
+
         hideKeyboard();
-        //TODO: fix this
+
         //if we are getting results, already, stop waiting for nearbyStops
         if (pendingNearbyStopsRequest && (fragmentType == FragmentKind.ARRIVALS || fragmentType == FragmentKind.STOPS)) {
             locmgr.removeUpdates(locListener);
@@ -277,7 +419,7 @@
                     return;
             }
         // Shows hints
-        */
+
 
     }
 
@@ -293,16 +435,112 @@
             if (fragment != null && fragment.getStopID() != null && fragment.getStopID().equals(ID)){
                 // Run with previous fetchers
                 //fragment.getCurrentFetchers().toArray()
-                new AsyncDataDownload(fragmentHelper,fragment.getCurrentFetchersAsArray()).execute(ID);
+                new AsyncDataDownload(fragmentHelper,fragment.getCurrentFetchersAsArray(), getContext()).execute(ID);
             } else{
-                new AsyncDataDownload(fragmentHelper, arrivalsFetchers).execute(ID);
+                new AsyncDataDownload(fragmentHelper, arrivalsFetchers, getContext()).execute(ID);
             }
         }
         else {
-            new AsyncDataDownload(fragmentHelper,arrivalsFetchers).execute(ID);
+            new AsyncDataDownload(fragmentHelper,arrivalsFetchers, getContext()).execute(ID);
             Log.d("MainActiv", "Started search for arrivals of stop " + ID);
         }
     }
+    /////////// LOCATION METHODS //////////
+    final LocationListener locListener = new LocationListener() {
+        @Override
+        public void onLocationChanged(Location location) {
+            Log.d(DEBUG_TAG, "Location changed");
+        }
+
+        @Override
+        public void onStatusChanged(String provider, int status, Bundle extras) {
+            Log.d(DEBUG_TAG, "Location provider status: " + status);
+            if (status == LocationProvider.AVAILABLE) {
+                resolveStopRequest(provider);
+            }
+        }
+
+        @Override
+        public void onProviderEnabled(String provider) {
+            resolveStopRequest(provider);
+        }
+
+        @Override
+        public void onProviderDisabled(String provider) {
 
+        }
+    };
+
+    private void resolveStopRequest(String provider) {
+        Log.d(DEBUG_TAG, "Provider " + provider + " got enabled");
+        if (locmgr != null && mainHandler != null && pendingNearbyStopsRequest && locmgr.getProvider(provider).meetsCriteria(cr)) {
+            pendingNearbyStopsRequest = false;
+            mainHandler.post(new NearbyStopsRequester(getContext(), cr, locListener));
+        }
+    }
+
+    /**
+     * Run location requests separately and asynchronously
+     */
+    class NearbyStopsRequester implements Runnable {
+        Context appContext;
+        Criteria cr;
+        LocationListener listener;
+
+        public NearbyStopsRequester(Context appContext, Criteria criteria, LocationListener listener) {
+            this.appContext = appContext.getApplicationContext();
+            this.cr = criteria;
+            this.listener = listener;
+        }
+
+        @Override
+        public void run() {
+            final boolean canRunPosition = Build.VERSION.SDK_INT < Build.VERSION_CODES.M || getOption(LOCATION_PERMISSION_GIVEN, false);
+            final boolean noPermission = ActivityCompat.checkSelfPermission(appContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
+                    ActivityCompat.checkSelfPermission(appContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED;
+
+            //if we don't have the permission, we have to ask for it, if we haven't
+            // asked too many times before
+            if (noPermission) {
+                if (!canRunPosition) {
+                    pendingNearbyStopsRequest = true;
+                    Permissions.assertLocationPermissions(appContext,getActivity());
+                    Log.w(DEBUG_TAG, "Cannot get position: Asking permission, noPositionFromSys: " + noPermission);
+                    return;
+                } else {
+                    Toast.makeText(appContext, "Asked for permission position too many times", Toast.LENGTH_LONG).show();
+                }
+            } else setOption(LOCATION_PERMISSION_GIVEN, true);
+
+            LocationManager locManager = (LocationManager) appContext.getSystemService(LOCATION_SERVICE);
+            if (locManager == null) {
+                Log.e(DEBUG_TAG, "location manager is nihil, cannot create NearbyStopsFragment");
+                return;
+            }
+            if (Permissions.anyLocationProviderMatchesCriteria(locManager, cr, true)
+                    && fragmentHelper.getLastSuccessfullySearchedBusStop() == null
+                    && !fragMan.isDestroyed()) {
+                //Go ahead with the request
+                Log.d("mainActivity", "Recreating stop fragment");
+                swipeRefreshLayout.setVisibility(View.VISIBLE);
+                NearbyStopsFragment fragment = NearbyStopsFragment.newInstance(NearbyStopsFragment.TYPE_STOPS);
+                Fragment oldFrag = fragMan.findFragmentById(R.id.resultFrame);
+                FragmentTransaction ft = fragMan.beginTransaction();
+                if (oldFrag != null)
+                    ft.remove(oldFrag);
+                ft.add(R.id.resultFrame, fragment, "nearbyStop_correct");
+                ft.commit();
+                //fragMan.executePendingTransactions();
+                pendingNearbyStopsRequest = false;
+            } else if (!Permissions.anyLocationProviderMatchesCriteria(locManager, cr, true)) {
+                //Wait for the providers
+                Log.d(DEBUG_TAG, "Queuing position request");
+                pendingNearbyStopsRequest = true;
+
+                locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10, 0.1f, listener);
+            }
+
+        }
+    }
 
 }
\ No newline at end of file
diff --git a/src/it/reyboz/bustorino/fragments/NearbyStopsFragment.java b/src/it/reyboz/bustorino/fragments/NearbyStopsFragment.java
--- a/src/it/reyboz/bustorino/fragments/NearbyStopsFragment.java
+++ b/src/it/reyboz/bustorino/fragments/NearbyStopsFragment.java
@@ -139,15 +139,15 @@
                              Bundle savedInstanceState) {
         // Inflate the layout for this fragment
         View root = inflater.inflate(R.layout.fragment_nearby_stops, container, false);
-        gridRecyclerView = (RecyclerView) root.findViewById(R.id.stopGridRecyclerView);
+        gridRecyclerView = root.findViewById(R.id.stopGridRecyclerView);
         gridLayoutManager = new AutoFitGridLayoutManager(getContext().getApplicationContext(), utils.convertDipToPixels(getContext(),COLUMN_WIDTH_DP));
         gridRecyclerView.setLayoutManager(gridLayoutManager);
         gridRecyclerView.setHasFixedSize(false);
-        circlingProgressBar = (ProgressBar) root.findViewById(R.id.loadingBar);
-        flatProgressBar = (ProgressBar) root.findViewById(R.id.horizontalProgressBar);
-        messageTextView = (TextView) root.findViewById(R.id.messageTextView);
-        titleTextView = (TextView) root.findViewById(R.id.titleTextView);
-        switchButton = (AppCompatButton) root.findViewById(R.id.switchButton);
+        circlingProgressBar = root.findViewById(R.id.loadingBar);
+        flatProgressBar = root.findViewById(R.id.horizontalProgressBar);
+        messageTextView = root.findViewById(R.id.messageTextView);
+        titleTextView = root.findViewById(R.id.titleTextView);
+        switchButton = root.findViewById(R.id.switchButton);
 
         preferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
             @Override
@@ -217,6 +217,7 @@
     @Override
     public void onAttach(Context context) {
         super.onAttach(context);
+        /// TODO: RISOLVERE PROBLEMA: il context qui e' l'Activity non il Fragment
         if (context instanceof FragmentListenerMain) {
             mListener = (FragmentListenerMain) context;
         } else {
diff --git a/src/it/reyboz/bustorino/middleware/AppLocationManager.java b/src/it/reyboz/bustorino/middleware/AppLocationManager.java
--- a/src/it/reyboz/bustorino/middleware/AppLocationManager.java
+++ b/src/it/reyboz/bustorino/middleware/AppLocationManager.java
@@ -104,6 +104,7 @@
             Log.d(DEBUG_TAG,"Added new stop requester, instance of "+req.getClass().getSimpleName());
         }
         if(requestersRef.size()>0){
+            Log.d(DEBUG_TAG,"Requesting position updates");
             requestGPSPositionUpdates();
 
         }
@@ -136,7 +137,7 @@
 
     @Override
     public void onLocationChanged(Location location) {
-        Log.d("GPSLocationListener","found location:\nlat: "+location.getLatitude()+" lon: "+location.getLongitude()+"\naccuracy: "+location.getAccuracy());
+        Log.d(DEBUG_TAG,"found location:\nlat: "+location.getLatitude()+" lon: "+location.getLongitude()+"\naccuracy: "+location.getAccuracy());
         ListIterator<WeakReference<LocationRequester>> iter = requestersRef.listIterator();
         int new_min_interval = Integer.MAX_VALUE;
         while(iter.hasNext()){
@@ -175,16 +176,19 @@
             }
                 oldGPSLocStatus = status;
             }
+        Log.d(DEBUG_TAG, "Provider: "+provider+" status: "+status);
     }
 
     @Override
     public void onProviderEnabled(String provider) {
         requestGPSPositionUpdates();
+        Log.d(DEBUG_TAG, "Provider: "+provider+" enabled");
     }
 
     @Override
     public void onProviderDisabled(String provider) {
         locMan.removeUpdates(this);
+        Log.d(DEBUG_TAG, "Provider: "+provider+" disabled");
     }
 
     /**
diff --git a/src/it/reyboz/bustorino/middleware/AsyncDataDownload.java b/src/it/reyboz/bustorino/middleware/AsyncDataDownload.java
--- a/src/it/reyboz/bustorino/middleware/AsyncDataDownload.java
+++ b/src/it/reyboz/bustorino/middleware/AsyncDataDownload.java
@@ -19,6 +19,7 @@
 
 import android.content.ContentResolver;
 import android.content.ContentValues;
+import android.content.Context;
 import android.database.SQLException;
 import android.net.Uri;
 import android.os.AsyncTask;
@@ -28,6 +29,7 @@
 
 import it.reyboz.bustorino.backend.*;
 import it.reyboz.bustorino.data.AppDataProvider;
+import it.reyboz.bustorino.data.NextGenDB;
 import it.reyboz.bustorino.fragments.FragmentHelper;
 import it.reyboz.bustorino.data.NextGenDB.Contract.*;
 
@@ -51,13 +53,15 @@
     WeakReference<FragmentHelper> helperRef;
     private final ArrayList<Thread> otherActivities = new ArrayList<>();
     private final Fetcher[] theFetchers;
+    private Context context;
 
 
-    public AsyncDataDownload(FragmentHelper fh, @NonNull Fetcher[] fetchers) {
+    public AsyncDataDownload(FragmentHelper fh, @NonNull Fetcher[] fetchers, Context context) {
         RequestType type;
         helperRef = new WeakReference<>(fh);
         fh.setLastTaskRef(new WeakReference<>(this));
         res = new AtomicReference<>();
+        this.context = context.getApplicationContext();
 
         theFetchers = fetchers;
         if (theFetchers.length < 1){
@@ -118,7 +122,7 @@
                         List<Route> branches = ((FiveTAPIFetcher) f).getDirectionsForStop(stopID,gres);
                         if(gres.get() == Fetcher.result.OK){
                             p.addInfoFromRoutes(branches);
-                            Thread t = new Thread(new BranchInserter(branches,fh,stopID));
+                            Thread t = new Thread(new BranchInserter(branches, context));
                             t.start();
                             otherActivities.add(t);
 
@@ -236,11 +240,13 @@
     public class BranchInserter implements Runnable{
         private final List<Route> routesToInsert;
 
-        private final FragmentHelper fragmentHelper;
+        private final Context context;
+        private final NextGenDB nextGenDB;
 
-        public BranchInserter(List<Route> routesToInsert,FragmentHelper fh,String stopID) {
+        public BranchInserter(List<Route> routesToInsert,@NonNull Context con) {
             this.routesToInsert = routesToInsert;
-            this.fragmentHelper = fh;
+            this.context = con;
+            nextGenDB = new NextGenDB(context);
         }
 
         @Override
@@ -298,7 +304,7 @@
                 }
             }
             starttime = System.currentTimeMillis();
-            ContentResolver cr = fragmentHelper.getContentResolver();
+            ContentResolver cr = context.getContentResolver();
             try {
                 cr.bulkInsert(Uri.parse("content://" + AppDataProvider.AUTHORITY + "/branches/"), values);
                 endtime = System.currentTimeMillis();
@@ -313,7 +319,7 @@
             starttime = System.currentTimeMillis();
             ContentValues[] valArr = connectionsVals.toArray(new ContentValues[0]);
             Log.d("DataDownloadInsert","inserting "+valArr.length+" connections");
-            int rows = fragmentHelper.insertBatchDataInNextGenDB(valArr,ConnectionsTable.TABLE_NAME);
+            int rows = nextGenDB.insertBatchContent(valArr,ConnectionsTable.TABLE_NAME);
             endtime = System.currentTimeMillis();
             Log.d("DataDownload","Inserted connections found, took "+(endtime-starttime)+" ms, inserted "+rows+" rows");
         }
diff --git a/src/it/reyboz/bustorino/middleware/GeneralActivity.java b/src/it/reyboz/bustorino/middleware/GeneralActivity.java
--- a/src/it/reyboz/bustorino/middleware/GeneralActivity.java
+++ b/src/it/reyboz/bustorino/middleware/GeneralActivity.java
@@ -63,23 +63,12 @@
                             InputMethodManager.HIDE_NOT_ALWAYS);
         }
     }
-    public boolean isConnected() {
-        ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
-        NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
-        return networkInfo != null && networkInfo.isConnected();
-    }
 
     public void showToastMessage(int messageID, boolean short_lenght) {
         final int length = short_lenght ? Toast.LENGTH_SHORT : Toast.LENGTH_LONG;
         Toast.makeText(getApplicationContext(), messageID, length).show();
     }
 
-    public void assertLocationPermissions() {
-        if(ContextCompat.checkSelfPermission(getApplicationContext(),Manifest.permission.ACCESS_FINE_LOCATION)!=PackageManager.PERMISSION_GRANTED){
-            ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_REQUEST_POSITION);
-        }
-    }
-
     public int askForPermissionIfNeeded(String permission, int requestID){
 
         if(ContextCompat.checkSelfPermission(getApplicationContext(),permission)==PackageManager.PERMISSION_GRANTED){
diff --git a/src/it/reyboz/bustorino/util/Permissions.java b/src/it/reyboz/bustorino/util/Permissions.java
new file mode 100644
--- /dev/null
+++ b/src/it/reyboz/bustorino/util/Permissions.java
@@ -0,0 +1,41 @@
+package it.reyboz.bustorino.util;
+
+import android.Manifest;
+import android.app.Activity;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.location.Criteria;
+import android.location.LocationManager;
+import android.util.Log;
+
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
+
+import java.util.List;
+
+public class Permissions {
+    final static public String DEBUG_TAG = "BusTO -Permissions";
+
+    final static public int PERMISSION_REQUEST_POSITION = 33;
+    final static public String LOCATION_PERMISSION_GIVEN = "loc_permission";
+    final static public int STORAGE_PERMISSION_REQ = 291;
+
+    final static public int PERMISSION_OK = 0;
+    final static public int PERMISSION_ASKING = 11;
+    final static public int PERMISSION_NEG_CANNOT_ASK = -3;
+
+    public static boolean anyLocationProviderMatchesCriteria(LocationManager mng, Criteria cr, boolean enabled) {
+        List<String> providers = mng.getProviders(cr, enabled);
+        Log.d(DEBUG_TAG, "Getting enabled location providers: ");
+        for (String s : providers) {
+            Log.d(DEBUG_TAG, "Provider " + s);
+        }
+        return providers.size() > 0;
+    }
+
+    public static void assertLocationPermissions(Context con, Activity activity) {
+        if(ContextCompat.checkSelfPermission(con, Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED){
+            ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_REQUEST_POSITION);
+        }
+    }
+}