Merge tag 'r4275.1_FP2_gms59_1.5.1' into fp2-sibon-staging-16.07.00rc2
diff --git a/Android.mk b/Android.mk
index 6e0965a..787532e 100644
--- a/Android.mk
+++ b/Android.mk
@@ -16,14 +16,18 @@
 
 LOCAL_PATH := $(call my-dir)
 include $(CLEAR_VARS)
+RES_DIR := app/src/main/res
 
 LOCAL_MODULE_TAGS := optional
 
 LOCAL_STATIC_JAVA_LIBRARIES := android-common android-support-v4 roottoolslib fpucrashlytics
 
-LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
+LOCAL_RESOURCE_DIR := $(addprefix $(LOCAL_PATH)/, $(RES_DIR))
+LOCAL_SRC_FILES := $(call all-java-files-under, app/src/main/java) $(call all-renderscript-files-under, app/src/main/java)
 #LOCAL_SDK_VERSION := current
 
+LOCAL_MANIFEST_FILE := app/src/main/AndroidManifest.xml
+
 LOCAL_PACKAGE_NAME := FairphoneUpdater
 LOCAL_CERTIFICATE := platform
 
@@ -33,7 +37,7 @@
 
 include $(CLEAR_VARS)
 
-LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := roottoolslib:libs/RootTools-3.3.jar fpucrashlytics:libs/crashlytics.jar
+LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := roottoolslib:app/libs/RootTools-3.3.jar fpucrashlytics:app/libs/crashlytics.jar
 
 include $(BUILD_MULTI_PREBUILT)
 
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..d114a6a
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,33 @@
+// Module level gradle declarations
+
+apply plugin: 'com.android.application'
+
+apply plugin: 'crashlytics'
+
+repositories {
+    maven { url 'http://download.crashlytics.com/maven' }
+}
+
+android {
+    compileSdkVersion 21
+    buildToolsVersion "21.1.2"
+    defaultConfig {
+        applicationId "com.fairphone.updater"
+        minSdkVersion 17
+        targetSdkVersion 21
+    }
+    buildTypes {
+        release {
+            minifyEnabled true
+            shrinkResources true
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
+        }
+    }
+}
+
+dependencies {
+    compile 'com.android.support:support-v4:21.0.+'
+    compile 'com.crashlytics.android:crashlytics:1.+'
+    compile files('libs/RootTools-3.3.jar')
+    testCompile "org.robolectric:robolectric:3.0"
+}
\ No newline at end of file
diff --git a/libs/RootTools-3.3.jar b/app/libs/RootTools-3.3.jar
similarity index 100%
rename from libs/RootTools-3.3.jar
rename to app/libs/RootTools-3.3.jar
Binary files differ
diff --git a/libs/android-support-v4.jar b/app/libs/android-support-v4.jar
similarity index 100%
rename from libs/android-support-v4.jar
rename to app/libs/android-support-v4.jar
Binary files differ
diff --git a/libs/crashlytics.jar b/app/libs/crashlytics.jar
similarity index 100%
rename from libs/crashlytics.jar
rename to app/libs/crashlytics.jar
Binary files differ
diff --git a/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
similarity index 98%
rename from AndroidManifest.xml
rename to app/src/main/AndroidManifest.xml
index 92867d9..5240dbe 100644
--- a/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -2,8 +2,8 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           xmlns:tools="http://schemas.android.com/tools"
           package="com.fairphone.updater"
-    android:versionCode="31"
-    android:versionName="31" >
+    android:versionCode="33"
+    android:versionName="33" >
 
     <uses-sdk
         android:minSdkVersion="17"
diff --git a/src/com/fairphone/updater/BetaEnabler.java b/app/src/main/java/com/fairphone/updater/BetaEnabler.java
similarity index 100%
rename from src/com/fairphone/updater/BetaEnabler.java
rename to app/src/main/java/com/fairphone/updater/BetaEnabler.java
diff --git a/src/com/fairphone/updater/BootBroadcastReceiver.java b/app/src/main/java/com/fairphone/updater/BootBroadcastReceiver.java
similarity index 100%
rename from src/com/fairphone/updater/BootBroadcastReceiver.java
rename to app/src/main/java/com/fairphone/updater/BootBroadcastReceiver.java
diff --git a/src/com/fairphone/updater/FairphoneUpdater.java b/app/src/main/java/com/fairphone/updater/FairphoneUpdater.java
similarity index 100%
rename from src/com/fairphone/updater/FairphoneUpdater.java
rename to app/src/main/java/com/fairphone/updater/FairphoneUpdater.java
diff --git a/src/com/fairphone/updater/UpdaterService.java b/app/src/main/java/com/fairphone/updater/UpdaterService.java
similarity index 99%
rename from src/com/fairphone/updater/UpdaterService.java
rename to app/src/main/java/com/fairphone/updater/UpdaterService.java
index 76f7de6..04d12fc 100644
--- a/src/com/fairphone/updater/UpdaterService.java
+++ b/app/src/main/java/com/fairphone/updater/UpdaterService.java
@@ -243,6 +243,7 @@
         String downloadLink = getConfigDownloadLink(getApplicationContext());
         // set the download for the latest version on the download manager
         Request request = createDownloadRequest(downloadLink, resources.getString(R.string.configFilename) + resources.getString(R.string.config_zip));
+        request.setNotificationVisibility(Request.VISIBILITY_HIDDEN);
 
         if (request != null && mDownloadManager != null)
         {
diff --git a/src/com/fairphone/updater/data/DownloadableItem.java b/app/src/main/java/com/fairphone/updater/data/DownloadableItem.java
similarity index 98%
rename from src/com/fairphone/updater/data/DownloadableItem.java
rename to app/src/main/java/com/fairphone/updater/data/DownloadableItem.java
index 05dcf40..c0a11a3 100644
--- a/src/com/fairphone/updater/data/DownloadableItem.java
+++ b/app/src/main/java/com/fairphone/updater/data/DownloadableItem.java
@@ -30,13 +30,13 @@
 
     private String mId;
 
-    private String mName;
+    protected String mName;
 
     private String mOTADownloadLink;
 
     private String mOTAMd5Sum;
 
-    private String mBuildNumber;
+    protected String mBuildNumber;
     
     private final Map<String, String> mReleaseNotesMap;
 
diff --git a/src/com/fairphone/updater/data/Store.java b/app/src/main/java/com/fairphone/updater/data/Store.java
similarity index 100%
rename from src/com/fairphone/updater/data/Store.java
rename to app/src/main/java/com/fairphone/updater/data/Store.java
diff --git a/src/com/fairphone/updater/data/UpdaterData.java b/app/src/main/java/com/fairphone/updater/data/UpdaterData.java
similarity index 100%
rename from src/com/fairphone/updater/data/UpdaterData.java
rename to app/src/main/java/com/fairphone/updater/data/UpdaterData.java
diff --git a/src/com/fairphone/updater/data/Version.java b/app/src/main/java/com/fairphone/updater/data/Version.java
similarity index 100%
rename from src/com/fairphone/updater/data/Version.java
rename to app/src/main/java/com/fairphone/updater/data/Version.java
diff --git a/app/src/main/java/com/fairphone/updater/data/VersionParserHelper.java b/app/src/main/java/com/fairphone/updater/data/VersionParserHelper.java
new file mode 100644
index 0000000..5334b7f
--- /dev/null
+++ b/app/src/main/java/com/fairphone/updater/data/VersionParserHelper.java
@@ -0,0 +1,172 @@
+package com.fairphone.updater.data;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.Build;
+import android.os.Environment;
+import android.util.Log;
+
+import com.fairphone.updater.R;
+import com.fairphone.updater.tools.Utils;
+import com.fairphone.updater.tools.XmlParser;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Locale;
+
+public class VersionParserHelper {
+
+    private static final String TAG = VersionParserHelper.class.getSimpleName();
+
+    private static final String CURRENT_VERSION_NUMBER = "fairphone.ota.version.number";
+    private static final String CURRENT_VERSION_NAME = "fairphone.ota.version.name";
+    private static final String CURRENT_VERSION_BUILD_NUMBER = "fairphone.ota.build_number";
+    private static final String CURRENT_VERSION_IMAGE_TYPE = "fairphone.ota.image_type";
+    private static final String CURRENT_VERSION_ID = "ro.build.version.incremental";                // for FP2
+
+
+    private static Version version;
+    public static Version getDeviceVersion(Context context)
+    {
+        if (version == null){
+            Version versionBuilder = new Version();
+            String[] supportedDevices = context.getResources().getString(R.string.knownFPDevices).split(";");
+            String modelWithoutSpaces = Build.MODEL.replaceAll("\\s", "");
+            boolean knownFPDevice = false;
+            for (String device : supportedDevices) {
+                knownFPDevice = knownFPDevice || device.equals(modelWithoutSpaces);
+            }
+
+            if(modelWithoutSpaces.equals(context.getResources().getString(R.string.FP2Model))) {
+                // FP2
+                try {
+                    versionBuilder.setId(getSystemData(context, CURRENT_VERSION_ID, knownFPDevice));
+                } catch (NumberFormatException e) {
+                    String defaultVersionId = context.getResources().getString(R.string.defaultVersionId);
+                    Log.w(TAG, "Error parsing current version id. Defaulting to " + defaultVersionId + ": " + e.getLocalizedMessage());
+                    versionBuilder.setId(defaultVersionId);
+                }
+                versionBuilder.setName(versionBuilder.getCurrentImageType());
+                versionBuilder.setBuildNumber(versionBuilder.getBuildNumberFromId());
+            } else {
+                // FP1(U)
+                try
+                {
+                    versionBuilder.setId(getSystemData(context, CURRENT_VERSION_NUMBER, knownFPDevice) );
+                } catch (NumberFormatException e) {
+                    String defaultVersionNumber = context.getResources().getString(R.string.defaultVersionId);
+                    Log.w(TAG, "Error parsing current version number. Defaulting to " + defaultVersionNumber + ": " + e.getLocalizedMessage());
+                    versionBuilder.setId(defaultVersionNumber);
+                }
+                versionBuilder.setName(getSystemData(context, CURRENT_VERSION_NAME, knownFPDevice));
+                versionBuilder.setBuildNumber(getSystemData(context, CURRENT_VERSION_BUILD_NUMBER, knownFPDevice));
+            }
+
+            versionBuilder.setImageType(getSystemData(context, CURRENT_VERSION_IMAGE_TYPE, knownFPDevice));
+
+            Version versionData = UpdaterData.getInstance().getVersion(versionBuilder.getImageType(), versionBuilder.getId());
+            versionBuilder.setThumbnailLink(versionData != null ? versionData.getThumbnailLink() : "");
+            versionBuilder.setReleaseNotes(Locale.getDefault().getLanguage(), versionData != null ? versionData.getReleaseNotes(Locale.getDefault().getLanguage()) : "");
+            version = versionBuilder;
+        }
+
+        return version;
+    }
+
+    private static String getSystemData(Context context, String property, boolean useDefaults)
+    {
+        String result;
+        switch (property) {
+            case CURRENT_VERSION_NUMBER:
+                result = Utils.getprop(CURRENT_VERSION_NUMBER, useDefaults ? String.valueOf(context.getResources().getString(R.string.defaultVersionId)) : "");
+                break;
+            case CURRENT_VERSION_NAME:
+                result = Utils.getprop(CURRENT_VERSION_NAME, useDefaults ? context.getResources().getString(R.string.defaultVersionName) : "");
+                break;
+            case CURRENT_VERSION_BUILD_NUMBER:
+                result = Utils.getprop(CURRENT_VERSION_BUILD_NUMBER, useDefaults ? context.getResources().getString(R.string.defaultBuildNumber) : "");
+                break;
+            case CURRENT_VERSION_IMAGE_TYPE:
+                result = Utils.getprop(CURRENT_VERSION_IMAGE_TYPE, useDefaults ? context.getResources().getString(R.string.defaultImageType) : "");
+                break;
+            case CURRENT_VERSION_ID:
+                result = Utils.getprop(CURRENT_VERSION_ID, useDefaults ? "" : ""); // TODO: define default value for fingerprint
+                break;
+            default:
+                result = "";
+                break;
+        }
+
+        return result;
+    }
+
+    public static Version getLatestVersion(Context context)
+    {
+
+        Version latest = null;
+        Resources resources = context.getResources();
+        FileInputStream fis = null;
+        try {
+            fis = context.openFileInput(resources.getString(R.string.configFilename) + resources.getString(R.string.config_xml));
+        } catch (FileNotFoundException e){
+        }
+
+        if (fis != null)
+        {
+            try
+            {
+                XmlParser xmlParser = new XmlParser();
+                UpdaterData updaterData = xmlParser.parse(fis);
+                latest = updaterData.getLatestVersion(getSystemData(context, CURRENT_VERSION_IMAGE_TYPE, true));
+            } catch (XmlPullParserException e)
+            {
+                Log.e(TAG, "Could not start the XML parser", e);
+            } catch (IOException e)
+            {
+                Log.e(TAG, "Invalid data in File", e);
+                // remove the files
+                removeConfigFiles(context);
+            }
+        }
+
+        removeZipContents(context);
+
+        return latest;
+    }
+
+    public static void removeConfigFiles(Context context)
+    {
+        Resources resources = context.getResources();
+        String filePath =
+                Environment.getExternalStorageDirectory() + resources.getString(R.string.updaterFolder) + resources.getString(R.string.configFilename);
+
+        removeFile(filePath + resources.getString(R.string.config_zip));
+        removeZipContents(context);
+    }
+
+    private static void removeZipContents(Context context)
+    {
+        Resources resources = context.getResources();
+        String filePath =
+                Environment.getExternalStorageDirectory() + resources.getString(R.string.updaterFolder) + resources.getString(R.string.configFilename);
+
+        removeFile(filePath + resources.getString(R.string.config_xml));
+        removeFile(filePath + resources.getString(R.string.config_sig));
+    }
+
+    private static void removeFile(String filePath)
+    {
+        File file = new File(filePath);
+        if (file.exists())
+        {
+            final boolean notDeleted = !file.delete();
+            if (notDeleted) {
+                Log.d(TAG, "Couldn't delete file: " + file.getAbsolutePath());
+            }
+        }
+    }
+}
diff --git a/src/com/fairphone/updater/fragments/BaseFragment.java b/app/src/main/java/com/fairphone/updater/fragments/BaseFragment.java
similarity index 100%
rename from src/com/fairphone/updater/fragments/BaseFragment.java
rename to app/src/main/java/com/fairphone/updater/fragments/BaseFragment.java
diff --git a/src/com/fairphone/updater/fragments/ConfirmationPopupDialog.java b/app/src/main/java/com/fairphone/updater/fragments/ConfirmationPopupDialog.java
similarity index 100%
rename from src/com/fairphone/updater/fragments/ConfirmationPopupDialog.java
rename to app/src/main/java/com/fairphone/updater/fragments/ConfirmationPopupDialog.java
diff --git a/src/com/fairphone/updater/fragments/DownloadAndRestartFragment.java b/app/src/main/java/com/fairphone/updater/fragments/DownloadAndRestartFragment.java
similarity index 100%
rename from src/com/fairphone/updater/fragments/DownloadAndRestartFragment.java
rename to app/src/main/java/com/fairphone/updater/fragments/DownloadAndRestartFragment.java
diff --git a/src/com/fairphone/updater/fragments/InfoPopupDialog.java b/app/src/main/java/com/fairphone/updater/fragments/InfoPopupDialog.java
similarity index 100%
rename from src/com/fairphone/updater/fragments/InfoPopupDialog.java
rename to app/src/main/java/com/fairphone/updater/fragments/InfoPopupDialog.java
diff --git a/src/com/fairphone/updater/fragments/MainFragment.java b/app/src/main/java/com/fairphone/updater/fragments/MainFragment.java
similarity index 100%
rename from src/com/fairphone/updater/fragments/MainFragment.java
rename to app/src/main/java/com/fairphone/updater/fragments/MainFragment.java
diff --git a/src/com/fairphone/updater/fragments/OtherOSOptionsFragment.java b/app/src/main/java/com/fairphone/updater/fragments/OtherOSOptionsFragment.java
similarity index 100%
rename from src/com/fairphone/updater/fragments/OtherOSOptionsFragment.java
rename to app/src/main/java/com/fairphone/updater/fragments/OtherOSOptionsFragment.java
diff --git a/src/com/fairphone/updater/fragments/VersionDetailFragment.java b/app/src/main/java/com/fairphone/updater/fragments/VersionDetailFragment.java
similarity index 98%
rename from src/com/fairphone/updater/fragments/VersionDetailFragment.java
rename to app/src/main/java/com/fairphone/updater/fragments/VersionDetailFragment.java
index 37dc5be..1dcfb0a 100644
--- a/src/com/fairphone/updater/fragments/VersionDetailFragment.java
+++ b/app/src/main/java/com/fairphone/updater/fragments/VersionDetailFragment.java
@@ -260,8 +260,7 @@
                 mHeaderText = mSelectedVersion.getHumanReadableName();
                 mVersionDetailsTitle = resources.getString(R.string.latest_version);
                 mIsOSChange = deviceVersion.getImageType().equalsIgnoreCase(Version.IMAGE_TYPE_AOSP);
-                mIsOlderVersion =
-                        (deviceVersion.getImageType().equalsIgnoreCase(Version.IMAGE_TYPE_FAIRPHONE) && deviceVersion.isNewerVersionThan(mSelectedVersion));
+                mIsOlderVersion = false;
                 break;
             case FAIRPHONE:
             default:
diff --git a/src/com/fairphone/updater/fragments/VersionListFragment.java b/app/src/main/java/com/fairphone/updater/fragments/VersionListFragment.java
similarity index 100%
rename from src/com/fairphone/updater/fragments/VersionListFragment.java
rename to app/src/main/java/com/fairphone/updater/fragments/VersionListFragment.java
diff --git a/src/com/fairphone/updater/gappsinstaller/GappsInstallerHelper.java b/app/src/main/java/com/fairphone/updater/gappsinstaller/GappsInstallerHelper.java
similarity index 100%
rename from src/com/fairphone/updater/gappsinstaller/GappsInstallerHelper.java
rename to app/src/main/java/com/fairphone/updater/gappsinstaller/GappsInstallerHelper.java
diff --git a/src/com/fairphone/updater/tools/PrivilegeChecker.java b/app/src/main/java/com/fairphone/updater/tools/PrivilegeChecker.java
similarity index 100%
rename from src/com/fairphone/updater/tools/PrivilegeChecker.java
rename to app/src/main/java/com/fairphone/updater/tools/PrivilegeChecker.java
diff --git a/src/com/fairphone/updater/tools/RSAUtils.java b/app/src/main/java/com/fairphone/updater/tools/RSAUtils.java
similarity index 100%
rename from src/com/fairphone/updater/tools/RSAUtils.java
rename to app/src/main/java/com/fairphone/updater/tools/RSAUtils.java
diff --git a/src/com/fairphone/updater/tools/Utils.java b/app/src/main/java/com/fairphone/updater/tools/Utils.java
similarity index 100%
rename from src/com/fairphone/updater/tools/Utils.java
rename to app/src/main/java/com/fairphone/updater/tools/Utils.java
diff --git a/app/src/main/java/com/fairphone/updater/tools/XmlParser.java b/app/src/main/java/com/fairphone/updater/tools/XmlParser.java
new file mode 100644
index 0000000..d0efbf8
--- /dev/null
+++ b/app/src/main/java/com/fairphone/updater/tools/XmlParser.java
@@ -0,0 +1,286 @@
+package com.fairphone.updater.tools;
+
+import android.util.Xml;
+
+import com.fairphone.updater.data.Store;
+import com.fairphone.updater.data.UpdaterData;
+import com.fairphone.updater.data.Version;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Locale;
+
+/**
+ * A helper class for parsing the XML received from the server into a data structure.
+ *
+ * @author Maarten Derks
+ */
+public class XmlParser {
+
+    private static final String ns = null;
+
+    /**
+     * Parse the content of the specified file input stream into an UpdaterData object.
+     *
+     * @param fis A FileInputStream containing the XML to be parsed
+     * @return an UpdaterData object
+     * @throws XmlPullParserException This exception is thrown to signal XML Pull Parser related faults.
+     * @throws IOException Signals a general, I/O-related error.
+     */
+    public UpdaterData parse(FileInputStream fis) throws XmlPullParserException, IOException {
+        try {
+            XmlPullParser parser = Xml.newPullParser();
+            parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
+            parser.setInput(fis, null);
+            parser.nextTag();
+            return readUpdaterXml(parser);
+        } finally {
+            fis.close();
+        }
+    }
+
+    private UpdaterData readUpdaterXml(XmlPullParser parser) throws XmlPullParserException, IOException {
+        UpdaterData updaterData = UpdaterData.getInstance();
+        updaterData.resetUpdaterData();
+
+        parser.require(XmlPullParser.START_TAG, ns, "updater");
+        while (parser.next() != XmlPullParser.END_TAG) {
+            if (parser.getEventType() != XmlPullParser.START_TAG) {
+                continue;
+            }
+            String tagName = parser.getName();
+            if (tagName.equals("releases")) {
+                parser.require(XmlPullParser.START_TAG, ns, "releases");
+                while (parser.next() != XmlPullParser.END_TAG) {
+                    if (parser.getEventType() != XmlPullParser.START_TAG) {
+                        continue;
+                    }
+                    String releaseType = parser.getName();
+                    if (releaseType.equals("fairphone")) {
+                        parser.require(XmlPullParser.START_TAG, ns, "fairphone");
+                        updaterData.setLatestFairphoneVersionNumber(parser.getAttributeValue(ns, "latest"));
+                        while (parser.next() != XmlPullParser.END_TAG) {
+                            if (parser.getEventType() != XmlPullParser.START_TAG) {
+                                continue;
+                            }
+                            String name = parser.getName();
+                            if (name.equals("version")) {
+                                updaterData.addFairphoneVersion(readVersion(parser, Version.IMAGE_TYPE_FAIRPHONE));
+                            } else {
+                                skip(parser);
+                            }
+                        }
+                    }
+
+                    if (releaseType.equals("aosp")) {
+                        parser.require(XmlPullParser.START_TAG, ns, "aosp");
+                        updaterData.setLatestAOSPVersionNumber(parser.getAttributeValue(ns, "latest"));
+                        while (parser.next() != XmlPullParser.END_TAG) {
+                            if (parser.getEventType() != XmlPullParser.START_TAG) {
+                                continue;
+                            }
+                            String name = parser.getName();
+                            if (name.equals("version")) {
+                                updaterData.addAOSPVersion(readVersion(parser, Version.IMAGE_TYPE_AOSP));
+                            } else {
+                                skip(parser);
+                            }
+                        }
+                    }
+                }
+            }
+
+            if (tagName.equals("stores")) {
+                parser.require(XmlPullParser.START_TAG, ns, "stores");
+                while (parser.next() != XmlPullParser.END_TAG) {
+                    if (parser.getEventType() != XmlPullParser.START_TAG) {
+                        continue;
+                    }
+                    String name = parser.getName();
+                    if (name.equals("store")) {
+                        updaterData.addAppStore(readStore(parser));
+                    } else {
+                        skip(parser);
+                    }
+                }
+            }
+        }
+        return updaterData;
+    }
+
+    private Version readVersion(XmlPullParser parser, String imageType) throws XmlPullParserException, IOException {
+        parser.require(XmlPullParser.START_TAG, ns, "version");
+
+        Version version = new Version();
+
+        version.setId(parser.getAttributeValue(ns, "number"));
+        version.setImageType(imageType);
+
+        while (parser.next() != XmlPullParser.END_TAG) {
+            if (parser.getEventType() != XmlPullParser.START_TAG) {
+                continue;
+            }
+            String tagName = parser.getName();
+            if (tagName.equals("name")) {
+                version.setName(readName(parser));
+            } else if (tagName.equals("build_number")) {
+                version.setBuildNumber(readBuildNumber(parser));
+            } else if (tagName.equals("android_version")) {
+                version.setAndroidVersion(readAndroidVersion(parser));
+            } else if (tagName.equals("release_notes")) {
+                version.setReleaseNotes(Version.DEFAULT_NOTES_LANG, readReleaseNotes(parser));
+            } else if (tagName.equals("release_notes" + "_" + Locale.getDefault().getLanguage())) {
+                version.setReleaseNotes(Locale.getDefault().getLanguage(), readLocalizedReleaseNotes(parser));
+            } else if (tagName.equals("release_date")) {
+                version.setReleaseDate(readReleaseDate(parser));
+            } else if (tagName.equals("md5sum")) {
+                version.setMd5Sum(readMd5sum(parser));
+            } else if(tagName.equals("thumbnail_link")) {
+                version.setThumbnailLink(readThumbnailLink(parser));
+            } else if (tagName.equals("update_link")) {
+                version.setDownloadLink(readUpdateLink(parser));
+            } else if (tagName.equals("dependencies")) {
+                version.setVersionDependencies(readDependencies(parser));
+            } else if (tagName.equals("erase_data_warning")) {
+                version.setEraseAllPartitionWarning();
+            } else {
+                skip(parser);
+            }
+        }
+        return version;
+    }
+
+    private Store readStore(XmlPullParser parser) throws XmlPullParserException, IOException {
+        parser.require(XmlPullParser.START_TAG, ns, "store");
+
+        Store store = new Store();
+
+        store.setId(parser.getAttributeValue(ns, "number"));
+
+        while (parser.next() != XmlPullParser.END_TAG) {
+            if (parser.getEventType() != XmlPullParser.START_TAG) {
+                continue;
+            }
+            String tagName = parser.getName();
+            if (tagName.equals("name")) {
+                store.setName(readName(parser));
+            } else if (tagName.equals("build_number")) {
+                store.setBuildNumber(readBuildNumber(parser));
+            } else if (tagName.equals("release_notes")) {
+                store.setReleaseNotes(Version.DEFAULT_NOTES_LANG, readReleaseNotes(parser));
+            } else if (tagName.equals("release_notes" + "_" + Locale.getDefault().getLanguage())) {
+                store.setReleaseNotes(Locale.getDefault().getLanguage(), readLocalizedReleaseNotes(parser));
+            } else if (tagName.equals("release_date")) {
+                store.setReleaseDate(readReleaseDate(parser));
+            } else if (tagName.equals("md5sum")) {
+                store.setMd5Sum(readMd5sum(parser));
+            } else if (tagName.equals("update_link")) {
+                store.setDownloadLink(readUpdateLink(parser));
+            } else if (tagName.equals("show_disclaimer")) {
+               store.setShowDisclaimer();
+            } else {
+                skip(parser);
+            }
+        }
+        return store;
+    }
+
+    private String readName(XmlPullParser parser) throws IOException, XmlPullParserException {
+        parser.require(XmlPullParser.START_TAG, ns, "name");
+        String name = readText(parser);
+        parser.require(XmlPullParser.END_TAG, ns, "name");
+        return name;
+    }
+
+    private String readBuildNumber(XmlPullParser parser) throws IOException, XmlPullParserException {
+        parser.require(XmlPullParser.START_TAG, ns, "build_number");
+        String buildNumber = readText(parser);
+        parser.require(XmlPullParser.END_TAG, ns, "build_number");
+        return buildNumber;
+    }
+
+    private String readAndroidVersion(XmlPullParser parser) throws IOException, XmlPullParserException {
+        parser.require(XmlPullParser.START_TAG, ns, "android_version");
+        String androidVersion = readText(parser);
+        parser.require(XmlPullParser.END_TAG, ns, "android_version");
+        return androidVersion;
+    }
+
+    private String readReleaseNotes(XmlPullParser parser) throws IOException, XmlPullParserException {
+        parser.require(XmlPullParser.START_TAG, ns, "release_notes");
+        String releaseNotes = readText(parser);
+        parser.require(XmlPullParser.END_TAG, ns, "release_notes");
+        return releaseNotes;
+    }
+
+    private String readLocalizedReleaseNotes(XmlPullParser parser) throws IOException, XmlPullParserException {
+        parser.require(XmlPullParser.START_TAG, ns, "release_notes" + "_" + Locale.getDefault().getLanguage());
+        String releaseNotes = readText(parser);
+        parser.require(XmlPullParser.END_TAG, ns, "release_notes" + "_" + Locale.getDefault().getLanguage());
+        return releaseNotes;
+    }
+
+    private String readReleaseDate(XmlPullParser parser) throws IOException, XmlPullParserException {
+        parser.require(XmlPullParser.START_TAG, ns, "release_date");
+        String releaseDate = readText(parser);
+        parser.require(XmlPullParser.END_TAG, ns, "release_date");
+        return releaseDate;
+    }
+
+    private String readMd5sum(XmlPullParser parser) throws IOException, XmlPullParserException {
+        parser.require(XmlPullParser.START_TAG, ns, "md5sum");
+        String md5sum = readText(parser);
+        parser.require(XmlPullParser.END_TAG, ns, "md5sum");
+        return md5sum;
+    }
+
+    private String readThumbnailLink(XmlPullParser parser) throws IOException, XmlPullParserException {
+        parser.require(XmlPullParser.START_TAG, ns, "thumbnail_link");
+        String thumbnailLink = readText(parser);
+        parser.require(XmlPullParser.END_TAG, ns, "thumbnail_link");
+        return thumbnailLink;
+    }
+
+    private String readUpdateLink(XmlPullParser parser) throws IOException, XmlPullParserException {
+        parser.require(XmlPullParser.START_TAG, ns, "update_link");
+        String updateLink = readText(parser);
+        parser.require(XmlPullParser.END_TAG, ns, "update_link");
+        return updateLink;
+    }
+
+    private String readDependencies(XmlPullParser parser) throws IOException, XmlPullParserException {
+        parser.require(XmlPullParser.START_TAG, ns, "dependencies");
+        String dependencies = readText(parser);
+        parser.require(XmlPullParser.END_TAG, ns, "dependencies");
+        return dependencies;
+    }
+
+    private String readText(XmlPullParser parser) throws IOException, XmlPullParserException {
+        String result = "";
+        if (parser.next() == XmlPullParser.TEXT) {
+            result = parser.getText();
+            parser.nextTag();
+        }
+        return result;
+    }
+
+    private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
+        if (parser.getEventType() != XmlPullParser.START_TAG) {
+            throw new IllegalStateException();
+        }
+        int depth = 1;
+        while (depth != 0) {
+            switch (parser.next()) {
+                case XmlPullParser.END_TAG:
+                    depth--;
+                    break;
+                case XmlPullParser.START_TAG:
+                    depth++;
+                    break;
+            }
+        }
+    }
+}
diff --git a/src/com/fairphone/updater/widgets/gapps/GoogleAppsInstallerWidget.java b/app/src/main/java/com/fairphone/updater/widgets/gapps/GoogleAppsInstallerWidget.java
similarity index 100%
rename from src/com/fairphone/updater/widgets/gapps/GoogleAppsInstallerWidget.java
rename to app/src/main/java/com/fairphone/updater/widgets/gapps/GoogleAppsInstallerWidget.java
diff --git a/res/anim/enter.xml b/app/src/main/res/anim/enter.xml
similarity index 100%
rename from res/anim/enter.xml
rename to app/src/main/res/anim/enter.xml
diff --git a/res/anim/exit.xml b/app/src/main/res/anim/exit.xml
similarity index 100%
rename from res/anim/exit.xml
rename to app/src/main/res/anim/exit.xml
diff --git a/res/anim/pop_enter.xml b/app/src/main/res/anim/pop_enter.xml
similarity index 100%
rename from res/anim/pop_enter.xml
rename to app/src/main/res/anim/pop_enter.xml
diff --git a/res/anim/pop_exit.xml b/app/src/main/res/anim/pop_exit.xml
similarity index 100%
rename from res/anim/pop_exit.xml
rename to app/src/main/res/anim/pop_exit.xml
diff --git a/res/color/button_blue_dark_text.xml b/app/src/main/res/color/button_blue_dark_text.xml
similarity index 100%
rename from res/color/button_blue_dark_text.xml
rename to app/src/main/res/color/button_blue_dark_text.xml
diff --git a/res/color/button_green_dark_text.xml b/app/src/main/res/color/button_green_dark_text.xml
similarity index 100%
rename from res/color/button_green_dark_text.xml
rename to app/src/main/res/color/button_green_dark_text.xml
diff --git a/res/color/button_pink_dark_text.xml b/app/src/main/res/color/button_pink_dark_text.xml
similarity index 100%
rename from res/color/button_pink_dark_text.xml
rename to app/src/main/res/color/button_pink_dark_text.xml
diff --git a/res/color/button_text_blue_text.xml b/app/src/main/res/color/button_text_blue_text.xml
similarity index 100%
rename from res/color/button_text_blue_text.xml
rename to app/src/main/res/color/button_text_blue_text.xml
diff --git a/res/color/button_text_green_text.xml b/app/src/main/res/color/button_text_green_text.xml
similarity index 100%
rename from res/color/button_text_green_text.xml
rename to app/src/main/res/color/button_text_green_text.xml
diff --git a/res/color/button_text_grey_text.xml b/app/src/main/res/color/button_text_grey_text.xml
similarity index 100%
rename from res/color/button_text_grey_text.xml
rename to app/src/main/res/color/button_text_grey_text.xml
diff --git a/res/color/button_text_pink_text.xml b/app/src/main/res/color/button_text_pink_text.xml
similarity index 100%
rename from res/color/button_text_pink_text.xml
rename to app/src/main/res/color/button_text_pink_text.xml
diff --git a/res/color/button_text_white_text.xml b/app/src/main/res/color/button_text_white_text.xml
similarity index 100%
rename from res/color/button_text_white_text.xml
rename to app/src/main/res/color/button_text_white_text.xml
diff --git a/res/color/button_white_blue_text.xml b/app/src/main/res/color/button_white_blue_text.xml
similarity index 100%
rename from res/color/button_white_blue_text.xml
rename to app/src/main/res/color/button_white_blue_text.xml
diff --git a/res/color/button_white_green_text.xml b/app/src/main/res/color/button_white_green_text.xml
similarity index 100%
rename from res/color/button_white_green_text.xml
rename to app/src/main/res/color/button_white_green_text.xml
diff --git a/res/color/button_white_pink_text.xml b/app/src/main/res/color/button_white_pink_text.xml
similarity index 100%
rename from res/color/button_white_pink_text.xml
rename to app/src/main/res/color/button_white_pink_text.xml
diff --git a/res/drawable-hdpi/icn_updater.png b/app/src/main/res/drawable-hdpi/icn_updater.png
similarity index 100%
rename from res/drawable-hdpi/icn_updater.png
rename to app/src/main/res/drawable-hdpi/icn_updater.png
Binary files differ
diff --git a/res/drawable-hdpi/updater.png b/app/src/main/res/drawable-hdpi/updater.png
similarity index 100%
rename from res/drawable-hdpi/updater.png
rename to app/src/main/res/drawable-hdpi/updater.png
Binary files differ
diff --git a/res/drawable-hdpi/updater_googleapps.png b/app/src/main/res/drawable-hdpi/updater_googleapps.png
similarity index 100%
rename from res/drawable-hdpi/updater_googleapps.png
rename to app/src/main/res/drawable-hdpi/updater_googleapps.png
Binary files differ
diff --git a/res/drawable-hdpi/updater_googleapps_dismiss_button.png b/app/src/main/res/drawable-hdpi/updater_googleapps_dismiss_button.png
similarity index 100%
rename from res/drawable-hdpi/updater_googleapps_dismiss_button.png
rename to app/src/main/res/drawable-hdpi/updater_googleapps_dismiss_button.png
Binary files differ
diff --git a/res/drawable-hdpi/updater_googleapps_dismiss_button_pressed.png b/app/src/main/res/drawable-hdpi/updater_googleapps_dismiss_button_pressed.png
similarity index 100%
rename from res/drawable-hdpi/updater_googleapps_dismiss_button_pressed.png
rename to app/src/main/res/drawable-hdpi/updater_googleapps_dismiss_button_pressed.png
Binary files differ
diff --git a/res/drawable-hdpi/updater_googleapps_pressed.png b/app/src/main/res/drawable-hdpi/updater_googleapps_pressed.png
similarity index 100%
rename from res/drawable-hdpi/updater_googleapps_pressed.png
rename to app/src/main/res/drawable-hdpi/updater_googleapps_pressed.png
Binary files differ
diff --git a/res/drawable-hdpi/updater_tray_icon.png b/app/src/main/res/drawable-hdpi/updater_tray_icon.png
similarity index 100%
rename from res/drawable-hdpi/updater_tray_icon.png
rename to app/src/main/res/drawable-hdpi/updater_tray_icon.png
Binary files differ
diff --git a/res/drawable-hdpi/updater_tray_icon_small.png b/app/src/main/res/drawable-hdpi/updater_tray_icon_small.png
similarity index 100%
rename from res/drawable-hdpi/updater_tray_icon_small.png
rename to app/src/main/res/drawable-hdpi/updater_tray_icon_small.png
Binary files differ
diff --git a/res/drawable-hdpi/updater_white.png b/app/src/main/res/drawable-hdpi/updater_white.png
similarity index 100%
rename from res/drawable-hdpi/updater_white.png
rename to app/src/main/res/drawable-hdpi/updater_white.png
Binary files differ
diff --git a/res/drawable-hdpi/widget_gapps_installer_icon.png b/app/src/main/res/drawable-hdpi/widget_gapps_installer_icon.png
similarity index 100%
rename from res/drawable-hdpi/widget_gapps_installer_icon.png
rename to app/src/main/res/drawable-hdpi/widget_gapps_installer_icon.png
Binary files differ
diff --git a/res/drawable-hdpi/widget_gapps_widget_install.png b/app/src/main/res/drawable-hdpi/widget_gapps_widget_install.png
similarity index 100%
rename from res/drawable-hdpi/widget_gapps_widget_install.png
rename to app/src/main/res/drawable-hdpi/widget_gapps_widget_install.png
Binary files differ
diff --git a/res/drawable-hdpi/widget_gapps_widget_uninstall.png b/app/src/main/res/drawable-hdpi/widget_gapps_widget_uninstall.png
similarity index 100%
rename from res/drawable-hdpi/widget_gapps_widget_uninstall.png
rename to app/src/main/res/drawable-hdpi/widget_gapps_widget_uninstall.png
Binary files differ
diff --git a/res/drawable-mdpi/icn_updater.png b/app/src/main/res/drawable-mdpi/icn_updater.png
similarity index 100%
rename from res/drawable-mdpi/icn_updater.png
rename to app/src/main/res/drawable-mdpi/icn_updater.png
Binary files differ
diff --git a/res/drawable-mdpi/updater.png b/app/src/main/res/drawable-mdpi/updater.png
similarity index 100%
rename from res/drawable-mdpi/updater.png
rename to app/src/main/res/drawable-mdpi/updater.png
Binary files differ
diff --git a/res/drawable-mdpi/updater_white.png b/app/src/main/res/drawable-mdpi/updater_white.png
similarity index 100%
rename from res/drawable-mdpi/updater_white.png
rename to app/src/main/res/drawable-mdpi/updater_white.png
Binary files differ
diff --git a/res/drawable-xhdpi/icn_updater.png b/app/src/main/res/drawable-xhdpi/icn_updater.png
similarity index 100%
rename from res/drawable-xhdpi/icn_updater.png
rename to app/src/main/res/drawable-xhdpi/icn_updater.png
Binary files differ
diff --git a/res/drawable-xhdpi/updater.png b/app/src/main/res/drawable-xhdpi/updater.png
similarity index 100%
rename from res/drawable-xhdpi/updater.png
rename to app/src/main/res/drawable-xhdpi/updater.png
Binary files differ
diff --git a/res/drawable-xhdpi/updater_white.png b/app/src/main/res/drawable-xhdpi/updater_white.png
similarity index 100%
rename from res/drawable-xhdpi/updater_white.png
rename to app/src/main/res/drawable-xhdpi/updater_white.png
Binary files differ
diff --git a/res/drawable-xxhdpi/button_back_blue.png b/app/src/main/res/drawable-xxhdpi/button_back_blue.png
similarity index 100%
rename from res/drawable-xxhdpi/button_back_blue.png
rename to app/src/main/res/drawable-xxhdpi/button_back_blue.png
Binary files differ
diff --git a/res/drawable-xxhdpi/button_back_blue_pressed.png b/app/src/main/res/drawable-xxhdpi/button_back_blue_pressed.png
similarity index 100%
rename from res/drawable-xxhdpi/button_back_blue_pressed.png
rename to app/src/main/res/drawable-xxhdpi/button_back_blue_pressed.png
Binary files differ
diff --git a/res/drawable-xxhdpi/button_back_green.png b/app/src/main/res/drawable-xxhdpi/button_back_green.png
similarity index 100%
rename from res/drawable-xxhdpi/button_back_green.png
rename to app/src/main/res/drawable-xxhdpi/button_back_green.png
Binary files differ
diff --git a/res/drawable-xxhdpi/button_back_green_pressed.png b/app/src/main/res/drawable-xxhdpi/button_back_green_pressed.png
similarity index 100%
rename from res/drawable-xxhdpi/button_back_green_pressed.png
rename to app/src/main/res/drawable-xxhdpi/button_back_green_pressed.png
Binary files differ
diff --git a/res/drawable-xxhdpi/button_back_red.png b/app/src/main/res/drawable-xxhdpi/button_back_red.png
similarity index 100%
rename from res/drawable-xxhdpi/button_back_red.png
rename to app/src/main/res/drawable-xxhdpi/button_back_red.png
Binary files differ
diff --git a/res/drawable-xxhdpi/button_back_red_pressed.png b/app/src/main/res/drawable-xxhdpi/button_back_red_pressed.png
similarity index 100%
rename from res/drawable-xxhdpi/button_back_red_pressed.png
rename to app/src/main/res/drawable-xxhdpi/button_back_red_pressed.png
Binary files differ
diff --git a/res/drawable-xxhdpi/button_info_blue.png b/app/src/main/res/drawable-xxhdpi/button_info_blue.png
similarity index 100%
rename from res/drawable-xxhdpi/button_info_blue.png
rename to app/src/main/res/drawable-xxhdpi/button_info_blue.png
Binary files differ
diff --git a/res/drawable-xxhdpi/button_info_blue_pressed.png b/app/src/main/res/drawable-xxhdpi/button_info_blue_pressed.png
similarity index 100%
rename from res/drawable-xxhdpi/button_info_blue_pressed.png
rename to app/src/main/res/drawable-xxhdpi/button_info_blue_pressed.png
Binary files differ
diff --git a/res/drawable-xxhdpi/button_info_green.png b/app/src/main/res/drawable-xxhdpi/button_info_green.png
similarity index 100%
rename from res/drawable-xxhdpi/button_info_green.png
rename to app/src/main/res/drawable-xxhdpi/button_info_green.png
Binary files differ
diff --git a/res/drawable-xxhdpi/button_info_green_pressed.png b/app/src/main/res/drawable-xxhdpi/button_info_green_pressed.png
similarity index 100%
rename from res/drawable-xxhdpi/button_info_green_pressed.png
rename to app/src/main/res/drawable-xxhdpi/button_info_green_pressed.png
Binary files differ
diff --git a/res/drawable-xxhdpi/checkbox_button_blue_check.png b/app/src/main/res/drawable-xxhdpi/checkbox_button_blue_check.png
similarity index 100%
rename from res/drawable-xxhdpi/checkbox_button_blue_check.png
rename to app/src/main/res/drawable-xxhdpi/checkbox_button_blue_check.png
Binary files differ
diff --git a/res/drawable-xxhdpi/checkbox_button_blue_uncheck.png b/app/src/main/res/drawable-xxhdpi/checkbox_button_blue_uncheck.png
similarity index 100%
rename from res/drawable-xxhdpi/checkbox_button_blue_uncheck.png
rename to app/src/main/res/drawable-xxhdpi/checkbox_button_blue_uncheck.png
Binary files differ
diff --git a/res/drawable-xxhdpi/checkbox_button_green_check.png b/app/src/main/res/drawable-xxhdpi/checkbox_button_green_check.png
similarity index 100%
rename from res/drawable-xxhdpi/checkbox_button_green_check.png
rename to app/src/main/res/drawable-xxhdpi/checkbox_button_green_check.png
Binary files differ
diff --git a/res/drawable-xxhdpi/checkbox_button_green_uncheck.png b/app/src/main/res/drawable-xxhdpi/checkbox_button_green_uncheck.png
similarity index 100%
rename from res/drawable-xxhdpi/checkbox_button_green_uncheck.png
rename to app/src/main/res/drawable-xxhdpi/checkbox_button_green_uncheck.png
Binary files differ
diff --git a/res/drawable-xxhdpi/checkbox_button_grey_check.png b/app/src/main/res/drawable-xxhdpi/checkbox_button_grey_check.png
similarity index 100%
rename from res/drawable-xxhdpi/checkbox_button_grey_check.png
rename to app/src/main/res/drawable-xxhdpi/checkbox_button_grey_check.png
Binary files differ
diff --git a/res/drawable-xxhdpi/checkbox_button_grey_uncheck.png b/app/src/main/res/drawable-xxhdpi/checkbox_button_grey_uncheck.png
similarity index 100%
rename from res/drawable-xxhdpi/checkbox_button_grey_uncheck.png
rename to app/src/main/res/drawable-xxhdpi/checkbox_button_grey_uncheck.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_battery_std_fpblue_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_battery_std_fpblue_24dp.png
similarity index 100%
rename from res/drawable-xxhdpi/ic_battery_std_fpblue_24dp.png
rename to app/src/main/res/drawable-xxhdpi/ic_battery_std_fpblue_24dp.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_import_export_fpblue_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_import_export_fpblue_24dp.png
similarity index 100%
rename from res/drawable-xxhdpi/ic_import_export_fpblue_24dp.png
rename to app/src/main/res/drawable-xxhdpi/ic_import_export_fpblue_24dp.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_signal_wifi_4_bar_fpblue_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_signal_wifi_4_bar_fpblue_24dp.png
similarity index 100%
rename from res/drawable-xxhdpi/ic_signal_wifi_4_bar_fpblue_24dp.png
rename to app/src/main/res/drawable-xxhdpi/ic_signal_wifi_4_bar_fpblue_24dp.png
Binary files differ
diff --git a/res/drawable-xxhdpi/icn_updater.png b/app/src/main/res/drawable-xxhdpi/icn_updater.png
similarity index 100%
rename from res/drawable-xxhdpi/icn_updater.png
rename to app/src/main/res/drawable-xxhdpi/icn_updater.png
Binary files differ
diff --git a/res/drawable-xxhdpi/updater.png b/app/src/main/res/drawable-xxhdpi/updater.png
similarity index 100%
rename from res/drawable-xxhdpi/updater.png
rename to app/src/main/res/drawable-xxhdpi/updater.png
Binary files differ
diff --git a/res/drawable-xxhdpi/updater_white.png b/app/src/main/res/drawable-xxhdpi/updater_white.png
similarity index 100%
rename from res/drawable-xxhdpi/updater_white.png
rename to app/src/main/res/drawable-xxhdpi/updater_white.png
Binary files differ
diff --git a/res/drawable-xxxhdpi/icn_updater.png b/app/src/main/res/drawable-xxxhdpi/icn_updater.png
similarity index 100%
rename from res/drawable-xxxhdpi/icn_updater.png
rename to app/src/main/res/drawable-xxxhdpi/icn_updater.png
Binary files differ
diff --git a/res/drawable-xxxhdpi/updater.png b/app/src/main/res/drawable-xxxhdpi/updater.png
similarity index 100%
rename from res/drawable-xxxhdpi/updater.png
rename to app/src/main/res/drawable-xxxhdpi/updater.png
Binary files differ
diff --git a/res/drawable-xxxhdpi/updater_white.png b/app/src/main/res/drawable-xxxhdpi/updater_white.png
similarity index 100%
rename from res/drawable-xxxhdpi/updater_white.png
rename to app/src/main/res/drawable-xxxhdpi/updater_white.png
Binary files differ
diff --git a/res/drawable/button_apps_installer.xml b/app/src/main/res/drawable/button_apps_installer.xml
similarity index 100%
rename from res/drawable/button_apps_installer.xml
rename to app/src/main/res/drawable/button_apps_installer.xml
diff --git a/res/drawable/button_back_states_blue.xml b/app/src/main/res/drawable/button_back_states_blue.xml
similarity index 100%
rename from res/drawable/button_back_states_blue.xml
rename to app/src/main/res/drawable/button_back_states_blue.xml
diff --git a/res/drawable/button_back_states_green.xml b/app/src/main/res/drawable/button_back_states_green.xml
similarity index 100%
rename from res/drawable/button_back_states_green.xml
rename to app/src/main/res/drawable/button_back_states_green.xml
diff --git a/res/drawable/button_back_states_red.xml b/app/src/main/res/drawable/button_back_states_red.xml
similarity index 100%
rename from res/drawable/button_back_states_red.xml
rename to app/src/main/res/drawable/button_back_states_red.xml
diff --git a/res/drawable/button_big_blue_text_background.xml b/app/src/main/res/drawable/button_big_blue_text_background.xml
similarity index 100%
rename from res/drawable/button_big_blue_text_background.xml
rename to app/src/main/res/drawable/button_big_blue_text_background.xml
diff --git a/res/drawable/button_big_green_text_background.xml b/app/src/main/res/drawable/button_big_green_text_background.xml
similarity index 100%
rename from res/drawable/button_big_green_text_background.xml
rename to app/src/main/res/drawable/button_big_green_text_background.xml
diff --git a/res/drawable/button_blue_background.xml b/app/src/main/res/drawable/button_blue_background.xml
similarity index 100%
rename from res/drawable/button_blue_background.xml
rename to app/src/main/res/drawable/button_blue_background.xml
diff --git a/res/drawable/button_blue_dark_background.xml b/app/src/main/res/drawable/button_blue_dark_background.xml
similarity index 100%
rename from res/drawable/button_blue_dark_background.xml
rename to app/src/main/res/drawable/button_blue_dark_background.xml
diff --git a/res/drawable/button_blue_dark_grey_background.xml b/app/src/main/res/drawable/button_blue_dark_grey_background.xml
similarity index 100%
rename from res/drawable/button_blue_dark_grey_background.xml
rename to app/src/main/res/drawable/button_blue_dark_grey_background.xml
diff --git a/res/drawable/button_blue_dark_white_background.xml b/app/src/main/res/drawable/button_blue_dark_white_background.xml
similarity index 100%
rename from res/drawable/button_blue_dark_white_background.xml
rename to app/src/main/res/drawable/button_blue_dark_white_background.xml
diff --git a/res/drawable/button_blue_text_background.xml b/app/src/main/res/drawable/button_blue_text_background.xml
similarity index 100%
rename from res/drawable/button_blue_text_background.xml
rename to app/src/main/res/drawable/button_blue_text_background.xml
diff --git a/res/drawable/button_dismiss_apps_installer.xml b/app/src/main/res/drawable/button_dismiss_apps_installer.xml
similarity index 100%
rename from res/drawable/button_dismiss_apps_installer.xml
rename to app/src/main/res/drawable/button_dismiss_apps_installer.xml
diff --git a/res/drawable/button_green_background.xml b/app/src/main/res/drawable/button_green_background.xml
similarity index 100%
rename from res/drawable/button_green_background.xml
rename to app/src/main/res/drawable/button_green_background.xml
diff --git a/res/drawable/button_green_dark_background.xml b/app/src/main/res/drawable/button_green_dark_background.xml
similarity index 100%
rename from res/drawable/button_green_dark_background.xml
rename to app/src/main/res/drawable/button_green_dark_background.xml
diff --git a/res/drawable/button_green_dark_grey_background.xml b/app/src/main/res/drawable/button_green_dark_grey_background.xml
similarity index 100%
rename from res/drawable/button_green_dark_grey_background.xml
rename to app/src/main/res/drawable/button_green_dark_grey_background.xml
diff --git a/res/drawable/button_green_dark_white_background.xml b/app/src/main/res/drawable/button_green_dark_white_background.xml
similarity index 100%
rename from res/drawable/button_green_dark_white_background.xml
rename to app/src/main/res/drawable/button_green_dark_white_background.xml
diff --git a/res/drawable/button_green_text_background.xml b/app/src/main/res/drawable/button_green_text_background.xml
similarity index 100%
rename from res/drawable/button_green_text_background.xml
rename to app/src/main/res/drawable/button_green_text_background.xml
diff --git a/res/drawable/button_grey_background.xml b/app/src/main/res/drawable/button_grey_background.xml
similarity index 100%
rename from res/drawable/button_grey_background.xml
rename to app/src/main/res/drawable/button_grey_background.xml
diff --git a/res/drawable/button_info_states_blue.xml b/app/src/main/res/drawable/button_info_states_blue.xml
similarity index 100%
rename from res/drawable/button_info_states_blue.xml
rename to app/src/main/res/drawable/button_info_states_blue.xml
diff --git a/res/drawable/button_info_states_green.xml b/app/src/main/res/drawable/button_info_states_green.xml
similarity index 100%
rename from res/drawable/button_info_states_green.xml
rename to app/src/main/res/drawable/button_info_states_green.xml
diff --git a/res/drawable/button_pink_dark_background.xml b/app/src/main/res/drawable/button_pink_dark_background.xml
similarity index 100%
rename from res/drawable/button_pink_dark_background.xml
rename to app/src/main/res/drawable/button_pink_dark_background.xml
diff --git a/res/drawable/button_pink_text_background.xml b/app/src/main/res/drawable/button_pink_text_background.xml
similarity index 100%
rename from res/drawable/button_pink_text_background.xml
rename to app/src/main/res/drawable/button_pink_text_background.xml
diff --git a/res/drawable/button_white_blue_background.xml b/app/src/main/res/drawable/button_white_blue_background.xml
similarity index 100%
rename from res/drawable/button_white_blue_background.xml
rename to app/src/main/res/drawable/button_white_blue_background.xml
diff --git a/res/drawable/button_white_green_background.xml b/app/src/main/res/drawable/button_white_green_background.xml
similarity index 100%
rename from res/drawable/button_white_green_background.xml
rename to app/src/main/res/drawable/button_white_green_background.xml
diff --git a/res/drawable/button_white_pink_background.xml b/app/src/main/res/drawable/button_white_pink_background.xml
similarity index 100%
rename from res/drawable/button_white_pink_background.xml
rename to app/src/main/res/drawable/button_white_pink_background.xml
diff --git a/res/drawable/checkbox_button_blue.xml b/app/src/main/res/drawable/checkbox_button_blue.xml
similarity index 100%
rename from res/drawable/checkbox_button_blue.xml
rename to app/src/main/res/drawable/checkbox_button_blue.xml
diff --git a/res/drawable/checkbox_button_green.xml b/app/src/main/res/drawable/checkbox_button_green.xml
similarity index 100%
rename from res/drawable/checkbox_button_green.xml
rename to app/src/main/res/drawable/checkbox_button_green.xml
diff --git a/res/drawable/checkbox_button_grey.xml b/app/src/main/res/drawable/checkbox_button_grey.xml
similarity index 100%
rename from res/drawable/checkbox_button_grey.xml
rename to app/src/main/res/drawable/checkbox_button_grey.xml
diff --git a/res/drawable/checkbox_button_pink.xml b/app/src/main/res/drawable/checkbox_button_pink.xml
similarity index 100%
rename from res/drawable/checkbox_button_pink.xml
rename to app/src/main/res/drawable/checkbox_button_pink.xml
diff --git a/res/drawable/progress_bar_background.xml b/app/src/main/res/drawable/progress_bar_background.xml
similarity index 100%
rename from res/drawable/progress_bar_background.xml
rename to app/src/main/res/drawable/progress_bar_background.xml
diff --git a/res/layout-de/widget_google_apps_installer.xml b/app/src/main/res/layout-de/widget_google_apps_installer.xml
similarity index 100%
rename from res/layout-de/widget_google_apps_installer.xml
rename to app/src/main/res/layout-de/widget_google_apps_installer.xml
diff --git a/res/layout-fr/widget_google_apps_installer.xml b/app/src/main/res/layout-fr/widget_google_apps_installer.xml
similarity index 100%
rename from res/layout-fr/widget_google_apps_installer.xml
rename to app/src/main/res/layout-fr/widget_google_apps_installer.xml
diff --git a/res/layout-nl/widget_google_apps_installer.xml b/app/src/main/res/layout-nl/widget_google_apps_installer.xml
similarity index 100%
rename from res/layout-nl/widget_google_apps_installer.xml
rename to app/src/main/res/layout-nl/widget_google_apps_installer.xml
diff --git a/res/layout-pt/widget_google_apps_installer.xml b/app/src/main/res/layout-pt/widget_google_apps_installer.xml
similarity index 100%
rename from res/layout-pt/widget_google_apps_installer.xml
rename to app/src/main/res/layout-pt/widget_google_apps_installer.xml
diff --git a/res/layout/activity_beta_enabler.xml b/app/src/main/res/layout/activity_beta_enabler.xml
similarity index 100%
rename from res/layout/activity_beta_enabler.xml
rename to app/src/main/res/layout/activity_beta_enabler.xml
diff --git a/res/layout/activity_updater.xml b/app/src/main/res/layout/activity_updater.xml
similarity index 100%
rename from res/layout/activity_updater.xml
rename to app/src/main/res/layout/activity_updater.xml
diff --git a/res/layout/fragment_app_store_detail.xml b/app/src/main/res/layout/fragment_app_store_detail.xml
similarity index 100%
rename from res/layout/fragment_app_store_detail.xml
rename to app/src/main/res/layout/fragment_app_store_detail.xml
diff --git a/res/layout/fragment_app_store_options_list.xml b/app/src/main/res/layout/fragment_app_store_options_list.xml
similarity index 100%
rename from res/layout/fragment_app_store_options_list.xml
rename to app/src/main/res/layout/fragment_app_store_options_list.xml
diff --git a/res/layout/fragment_app_store_options_list_button.xml b/app/src/main/res/layout/fragment_app_store_options_list_button.xml
similarity index 100%
rename from res/layout/fragment_app_store_options_list_button.xml
rename to app/src/main/res/layout/fragment_app_store_options_list_button.xml
diff --git a/res/layout/fragment_download_android.xml b/app/src/main/res/layout/fragment_download_android.xml
similarity index 100%
rename from res/layout/fragment_download_android.xml
rename to app/src/main/res/layout/fragment_download_android.xml
diff --git a/res/layout/fragment_download_android_confirmation_popup.xml b/app/src/main/res/layout/fragment_download_android_confirmation_popup.xml
similarity index 100%
rename from res/layout/fragment_download_android_confirmation_popup.xml
rename to app/src/main/res/layout/fragment_download_android_confirmation_popup.xml
diff --git a/res/layout/fragment_download_android_downloading.xml b/app/src/main/res/layout/fragment_download_android_downloading.xml
similarity index 100%
rename from res/layout/fragment_download_android_downloading.xml
rename to app/src/main/res/layout/fragment_download_android_downloading.xml
diff --git a/res/layout/fragment_download_android_install.xml b/app/src/main/res/layout/fragment_download_android_install.xml
similarity index 100%
rename from res/layout/fragment_download_android_install.xml
rename to app/src/main/res/layout/fragment_download_android_install.xml
diff --git a/res/layout/fragment_download_app_store.xml b/app/src/main/res/layout/fragment_download_app_store.xml
similarity index 100%
rename from res/layout/fragment_download_app_store.xml
rename to app/src/main/res/layout/fragment_download_app_store.xml
diff --git a/res/layout/fragment_download_app_store_downloading.xml b/app/src/main/res/layout/fragment_download_app_store_downloading.xml
similarity index 100%
rename from res/layout/fragment_download_app_store_downloading.xml
rename to app/src/main/res/layout/fragment_download_app_store_downloading.xml
diff --git a/res/layout/fragment_download_app_store_install.xml b/app/src/main/res/layout/fragment_download_app_store_install.xml
similarity index 100%
rename from res/layout/fragment_download_app_store_install.xml
rename to app/src/main/res/layout/fragment_download_app_store_install.xml
diff --git a/res/layout/fragment_download_fairphone.xml b/app/src/main/res/layout/fragment_download_fairphone.xml
similarity index 100%
rename from res/layout/fragment_download_fairphone.xml
rename to app/src/main/res/layout/fragment_download_fairphone.xml
diff --git a/res/layout/fragment_download_fairphone_confirmation_popup.xml b/app/src/main/res/layout/fragment_download_fairphone_confirmation_popup.xml
similarity index 100%
rename from res/layout/fragment_download_fairphone_confirmation_popup.xml
rename to app/src/main/res/layout/fragment_download_fairphone_confirmation_popup.xml
diff --git a/res/layout/fragment_download_fairphone_downloading.xml b/app/src/main/res/layout/fragment_download_fairphone_downloading.xml
similarity index 100%
rename from res/layout/fragment_download_fairphone_downloading.xml
rename to app/src/main/res/layout/fragment_download_fairphone_downloading.xml
diff --git a/res/layout/fragment_download_fairphone_install.xml b/app/src/main/res/layout/fragment_download_fairphone_install.xml
similarity index 100%
rename from res/layout/fragment_download_fairphone_install.xml
rename to app/src/main/res/layout/fragment_download_fairphone_install.xml
diff --git a/res/layout/fragment_info_android_popup.xml b/app/src/main/res/layout/fragment_info_android_popup.xml
similarity index 100%
rename from res/layout/fragment_info_android_popup.xml
rename to app/src/main/res/layout/fragment_info_android_popup.xml
diff --git a/res/layout/fragment_info_fairphone_popup.xml b/app/src/main/res/layout/fragment_info_fairphone_popup.xml
similarity index 100%
rename from res/layout/fragment_info_fairphone_popup.xml
rename to app/src/main/res/layout/fragment_info_fairphone_popup.xml
diff --git a/res/layout/fragment_main.xml b/app/src/main/res/layout/fragment_main.xml
similarity index 100%
rename from res/layout/fragment_main.xml
rename to app/src/main/res/layout/fragment_main.xml
diff --git a/res/layout/fragment_main_update_available_android.xml b/app/src/main/res/layout/fragment_main_update_available_android.xml
similarity index 100%
rename from res/layout/fragment_main_update_available_android.xml
rename to app/src/main/res/layout/fragment_main_update_available_android.xml
diff --git a/res/layout/fragment_main_update_available_fairphone.xml b/app/src/main/res/layout/fragment_main_update_available_fairphone.xml
similarity index 100%
rename from res/layout/fragment_main_update_available_fairphone.xml
rename to app/src/main/res/layout/fragment_main_update_available_fairphone.xml
diff --git a/res/layout/fragment_main_version_up_to_date.xml b/app/src/main/res/layout/fragment_main_version_up_to_date.xml
similarity index 100%
rename from res/layout/fragment_main_version_up_to_date.xml
rename to app/src/main/res/layout/fragment_main_version_up_to_date.xml
diff --git a/res/layout/fragment_other_os_options.xml b/app/src/main/res/layout/fragment_other_os_options.xml
similarity index 100%
rename from res/layout/fragment_other_os_options.xml
rename to app/src/main/res/layout/fragment_other_os_options.xml
diff --git a/res/layout/fragment_other_os_options_android_list.xml b/app/src/main/res/layout/fragment_other_os_options_android_list.xml
similarity index 100%
rename from res/layout/fragment_other_os_options_android_list.xml
rename to app/src/main/res/layout/fragment_other_os_options_android_list.xml
diff --git a/res/layout/fragment_other_os_options_android_list_button.xml b/app/src/main/res/layout/fragment_other_os_options_android_list_button.xml
similarity index 100%
rename from res/layout/fragment_other_os_options_android_list_button.xml
rename to app/src/main/res/layout/fragment_other_os_options_android_list_button.xml
diff --git a/res/layout/fragment_other_os_options_fairphone_list.xml b/app/src/main/res/layout/fragment_other_os_options_fairphone_list.xml
similarity index 100%
rename from res/layout/fragment_other_os_options_fairphone_list.xml
rename to app/src/main/res/layout/fragment_other_os_options_fairphone_list.xml
diff --git a/res/layout/fragment_other_os_options_fairphone_list_button.xml b/app/src/main/res/layout/fragment_other_os_options_fairphone_list_button.xml
similarity index 100%
rename from res/layout/fragment_other_os_options_fairphone_list_button.xml
rename to app/src/main/res/layout/fragment_other_os_options_fairphone_list_button.xml
diff --git a/res/layout/fragment_version_detail_android.xml b/app/src/main/res/layout/fragment_version_detail_android.xml
similarity index 100%
rename from res/layout/fragment_version_detail_android.xml
rename to app/src/main/res/layout/fragment_version_detail_android.xml
diff --git a/res/layout/fragment_version_detail_fairphone.xml b/app/src/main/res/layout/fragment_version_detail_fairphone.xml
similarity index 100%
rename from res/layout/fragment_version_detail_fairphone.xml
rename to app/src/main/res/layout/fragment_version_detail_fairphone.xml
diff --git a/res/layout/header.xml b/app/src/main/res/layout/header.xml
similarity index 100%
rename from res/layout/header.xml
rename to app/src/main/res/layout/header.xml
diff --git a/res/layout/widget_google_apps_installer.xml b/app/src/main/res/layout/widget_google_apps_installer.xml
similarity index 100%
rename from res/layout/widget_google_apps_installer.xml
rename to app/src/main/res/layout/widget_google_apps_installer.xml
diff --git a/res/raw/public_key.pem b/app/src/main/res/raw/public_key.pem
similarity index 100%
rename from res/raw/public_key.pem
rename to app/src/main/res/raw/public_key.pem
diff --git a/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml
similarity index 100%
rename from res/values-ca/strings.xml
rename to app/src/main/res/values-ca/strings.xml
diff --git a/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
similarity index 99%
rename from res/values-de/strings.xml
rename to app/src/main/res/values-de/strings.xml
index 8c2319b..1fd8f00 100644
--- a/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -76,7 +76,7 @@
     <string name="app_store">App Stores</string>
     <string name="got_it">Ich verstehe</string>
     <string name="connect_to_wifi">Stell eine Verbindung zum WLAN her</string>
-    <string name="charge_battery">Bitte lade die Batterie mindestens 80% auf</string>
+    <string name="charge_battery">Bitte lade die Batterie mindestens 40% auf</string>
     <string name="connect_to_internet">Stelle sicher, dass eine Internetverbindung besteht</string>
 
 </resources>
diff --git a/res/values-de/styles.xml b/app/src/main/res/values-de/styles.xml
similarity index 100%
rename from res/values-de/styles.xml
rename to app/src/main/res/values-de/styles.xml
diff --git a/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
similarity index 99%
rename from res/values-es/strings.xml
rename to app/src/main/res/values-es/strings.xml
index e2997cc..6add2c8 100644
--- a/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -76,7 +76,7 @@
     <string name="app_store">App Stores</string>
     <string name="got_it">Lo entiendo</string>
     <string name="connect_to_wifi">Conéctate a la red Wi-Fi</string>
-    <string name="charge_battery">Asegúrate de que tu batería está cargada al menos un 80%</string>
+    <string name="charge_battery">Asegúrate de que tu batería está cargada al menos un 40%</string>
     <string name="connect_to_internet">Asegúrate de que tienes conexión a internet</string>
 
 </resources>
diff --git a/res/values-es/styles.xml b/app/src/main/res/values-es/styles.xml
similarity index 100%
rename from res/values-es/styles.xml
rename to app/src/main/res/values-es/styles.xml
diff --git a/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
similarity index 98%
rename from res/values-fr/strings.xml
rename to app/src/main/res/values-fr/strings.xml
index 0e4c9a4..855b5ec 100644
--- a/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -76,8 +76,7 @@
     <string name="app_store">App Stores</string>
     <string name="got_it">OK</string>
     <string name="connect_to_wifi">Merci de vous connecter à un réseau Wi-Fi</string>
-    <string name="charge_battery">Chargez votre batterie à au moins 80%</string>
-    <string name="config_zip" translatable="false"></string>
+    <string name="charge_battery">Chargez votre batterie à au moins 40%</string>
     <string name="connect_to_internet">Assurez-vous d\'être connecté à internet</string>
 
 </resources>
diff --git a/res/values-fr/styles.xml b/app/src/main/res/values-fr/styles.xml
similarity index 100%
rename from res/values-fr/styles.xml
rename to app/src/main/res/values-fr/styles.xml
diff --git a/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
similarity index 99%
rename from res/values-nl/strings.xml
rename to app/src/main/res/values-nl/strings.xml
index e2d8b3e..6abe6e6 100644
--- a/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -76,7 +76,7 @@
     <string name="app_store">App Stores</string>
     <string name="got_it">Ik snap het</string>
     <string name="connect_to_wifi">Maak verbinding met een Wi-Fi netwerk</string>
-    <string name="charge_battery">Zorg ervoor dat je batterij minstens 80% opgeladen is</string>
+    <string name="charge_battery">Zorg ervoor dat je batterij minstens 40% opgeladen is</string>
     <string name="connect_to_internet">Zorg ervoor dat je bent verbonden met het internet</string>
 
 </resources>
diff --git a/res/values-nl/styles.xml b/app/src/main/res/values-nl/styles.xml
similarity index 100%
rename from res/values-nl/styles.xml
rename to app/src/main/res/values-nl/styles.xml
diff --git a/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml
similarity index 99%
rename from res/values-pt/strings.xml
rename to app/src/main/res/values-pt/strings.xml
index f28df05..277c222 100644
--- a/res/values-pt/strings.xml
+++ b/app/src/main/res/values-pt/strings.xml
@@ -76,7 +76,7 @@
     <string name="app_store">App Stores</string>
     <string name="got_it">Entendi</string>
     <string name="connect_to_wifi">Por favor ligue-se a uma rede Wi-Fi</string>
-    <string name="charge_battery">Por favor carregue a bateria até pelo menos 80%</string>
+    <string name="charge_battery">Por favor carregue a bateria até pelo menos 40%</string>
     <string name="connect_to_internet">Certifique-se que está ligado à internet</string>
 
 </resources>
diff --git a/res/values-pt/styles.xml b/app/src/main/res/values-pt/styles.xml
similarity index 100%
rename from res/values-pt/styles.xml
rename to app/src/main/res/values-pt/styles.xml
diff --git a/res/values/colors.xml b/app/src/main/res/values/colors.xml
similarity index 100%
rename from res/values/colors.xml
rename to app/src/main/res/values/colors.xml
diff --git a/res/values/config.xml b/app/src/main/res/values/config.xml
similarity index 97%
rename from res/values/config.xml
rename to app/src/main/res/values/config.xml
index 3160eda..452ffde 100644
--- a/res/values/config.xml
+++ b/app/src/main/res/values/config.xml
@@ -26,7 +26,7 @@
 
 	<string name="FP2Model" translatable="false">FP2</string>
 
-	<string name="minimumBatteryLevel" translatable="false">0.8</string>
+	<string name="minimumBatteryLevel" translatable="false">0.4</string>
 	
 	<!-- Packager -->
 	<string name="removePlayStoreCommand" translatable="false">rm /data/app/com.android.vending-*.apk</string>
diff --git a/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
similarity index 100%
rename from res/values/dimens.xml
rename to app/src/main/res/values/dimens.xml
diff --git a/res/values/strings.xml b/app/src/main/res/values/strings.xml
similarity index 99%
rename from res/values/strings.xml
rename to app/src/main/res/values/strings.xml
index a6297e8..7a34978 100644
--- a/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -76,7 +76,7 @@
     <string name="appStoreReinstall">Reinstall the app store</string>
     <string name="app_store">App Stores</string>
     <string name="connect_to_wifi">Please connect to a Wi-Fi network</string>
-    <string name="charge_battery">Please charge your battery to at least 80%</string>
+    <string name="charge_battery">Please charge your battery to at least 40%</string>
     <string name="got_it">Got it</string>
     <string name="beta_mode">beta mode</string>
     <string name="connect_to_internet">Make sure you\'re connected to the internet</string>
diff --git a/res/values/styles.xml b/app/src/main/res/values/styles.xml
similarity index 100%
rename from res/values/styles.xml
rename to app/src/main/res/values/styles.xml
diff --git a/res/xml/google_apps_widget.xml b/app/src/main/res/xml/google_apps_widget.xml
similarity index 100%
rename from res/xml/google_apps_widget.xml
rename to app/src/main/res/xml/google_apps_widget.xml
diff --git a/app/src/test/java/com/fairphone/updater/tools/XmlParserTest.java b/app/src/test/java/com/fairphone/updater/tools/XmlParserTest.java
new file mode 100644
index 0000000..67c8849
--- /dev/null
+++ b/app/src/test/java/com/fairphone/updater/tools/XmlParserTest.java
@@ -0,0 +1,170 @@
+package com.fairphone.updater.tools;
+
+import com.fairphone.updater.BuildConfig;
+import com.fairphone.updater.data.Store;
+import com.fairphone.updater.data.UpdaterData;
+import com.fairphone.updater.data.Version;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricGradleTestRunner;
+import org.robolectric.annotation.Config;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.URL;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+
+@RunWith(RobolectricGradleTestRunner.class)
+@Config(constants = BuildConfig.class)
+public class XmlParserTest {
+
+    private XmlParser xmlParser;
+
+    private static File getFileFromPath(Object obj, String fileName) {
+        ClassLoader classLoader = obj.getClass().getClassLoader();
+        URL resource = classLoader.getResource(fileName);
+        return new File(resource.getPath());
+    }
+
+    private static FileInputStream getFileInputStreamFromFile(Object obj, String filename) {
+        File file = getFileFromPath(obj, filename);
+        FileInputStream fis = null;
+        try {
+            fis = new FileInputStream(file);
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        }
+        return fis;
+    }
+
+    @Before
+    public void setUp() {
+        xmlParser = new XmlParser();
+    }
+
+    @Test
+    public void latestFp1Xml() {
+        FileInputStream fis = getFileInputStreamFromFile(this, "fp1_fpos_latest.xml");
+        UpdaterData updaterData = null;
+        try {
+            updaterData = xmlParser.parse(fis);
+        } catch (XmlPullParserException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        assertNotNull(updaterData);
+
+        assertNotNull(updaterData.getFairphoneVersionList());
+        assertThat(updaterData.isFairphoneVersionListNotEmpty(), is(true));
+        assertThat(updaterData.getFairphoneVersionList().size(), is(6));
+        assertNotNull(updaterData.getLatestVersion(Version.IMAGE_TYPE_FAIRPHONE));
+
+        assertNotNull(updaterData.getAOSPVersionList());
+        assertThat(updaterData.isAOSPVersionListNotEmpty(), is(true));
+        assertThat(updaterData.getAOSPVersionList().size(), is(1));
+        assertNotNull(updaterData.getLatestVersion(Version.IMAGE_TYPE_AOSP));
+        Version latest = updaterData.getLatestVersion(Version.IMAGE_TYPE_AOSP);
+        assertThat(latest.getImageType(), is(Version.IMAGE_TYPE_AOSP));
+        assertThat(latest.getName(), is("Jelly Bean 11-2014"));
+        assertThat(latest.getBuildNumber(), is("4.2.2"));
+        assertThat(latest.getMd5Sum(), is("20286cb405e1487066c31b55438311ac"));
+        assertThat(latest.getDownloadLink(), is("http://storage.googleapis.com/update-v1_8/AOSP-4.2.2_OTA_2014-11-26.zip"));
+        assertThat(latest.hasEraseAllPartitionWarning(), is(false));
+
+        assertNotNull(updaterData.getAppStoreList());
+        assertThat(updaterData.isAppStoreListEmpty(), is(false));
+        assertThat(updaterData.getAppStoreList().size(), is(1));
+
+        Store store = updaterData.getStore("0");
+        assertThat(store.getId(), is("0"));
+        assertThat(store.getName(), is("Google Apps"));
+        assertThat(store.getBuildNumber(), is("1.0"));
+        assertThat(store.getReleaseNotes(Version.DEFAULT_NOTES_LANG), is("Google Apps package"));
+        assertThat(store.getMd5Sum(), is("9444e40ed5afc9d61530681542f97b97"));
+        assertThat(store.getDownloadLink(), is("http://s3-eu-west-1.amazonaws.com/gatest15/gapps_1.5.zip"));
+        assertThat(store.showDisclaimer(), is(true));
+    }
+
+    @Test
+    public void latestFp2Xml() {
+        FileInputStream fis = getFileInputStreamFromFile(this, "fp2_fpos_latest.xml");
+        UpdaterData updaterData = null;
+        try {
+            updaterData = xmlParser.parse(fis);
+        } catch (XmlPullParserException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        assertNotNull(updaterData);
+
+        assertNotNull(updaterData.getFairphoneVersionList());
+        assertThat(updaterData.isFairphoneVersionListNotEmpty(), is(true));
+        assertThat(updaterData.getFairphoneVersionList().size(), is(1));
+        assertNotNull(updaterData.getLatestVersion(Version.IMAGE_TYPE_FAIRPHONE));
+        Version latest = updaterData.getLatestVersion(Version.IMAGE_TYPE_FAIRPHONE);
+        assertThat(latest.getImageType(), is(Version.IMAGE_TYPE_FAIRPHONE));
+        assertThat(latest.getName(), is("Fairphone OS"));
+        assertThat(latest.getBuildNumber(), is("1.4.2"));
+        assertThat(latest.getMd5Sum(), is("f0d157ef40fc0bfa4bdb3911e772a4c0"));
+        assertThat(latest.getDownloadLink(), is("http://storage.googleapis.com/fairphone-updates/FP2-gms56-1.4.2-ota.zip"));
+        assertThat(latest.hasEraseAllPartitionWarning(), is(false));
+
+        assertNotNull(updaterData.getAOSPVersionList());
+        assertThat(updaterData.isAOSPVersionListNotEmpty(), is(false));
+        assertThat(updaterData.getAOSPVersionList().size(), is(0));
+        assertNull(updaterData.getLatestVersion(Version.IMAGE_TYPE_AOSP));
+
+        assertNotNull(updaterData.getAppStoreList());
+        assertThat(updaterData.isAppStoreListEmpty(), is(true));
+        assertThat(updaterData.getAppStoreList().size(), is(0));
+    }
+
+    @Test
+    public void latestFp2OpenXml() {
+        FileInputStream fis = getFileInputStreamFromFile(this, "fp2_fpopen_latest.xml");
+        UpdaterData updaterData = null;
+        try {
+            updaterData = xmlParser.parse(fis);
+        } catch (XmlPullParserException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        assertNotNull(updaterData);
+
+        assertNotNull(updaterData.getFairphoneVersionList());
+        assertThat(updaterData.isFairphoneVersionListNotEmpty(), is(true));
+        assertThat(updaterData.getFairphoneVersionList().size(), is(2));
+        assertNotNull(updaterData.getLatestVersion(Version.IMAGE_TYPE_FAIRPHONE));
+        Version latest = updaterData.getLatestVersion(Version.IMAGE_TYPE_FAIRPHONE);
+        assertThat(latest.getImageType(), is(Version.IMAGE_TYPE_FAIRPHONE));
+        assertThat(latest.getName(), is("Fairphone Open Source OS"));
+        assertThat(latest.getBuildNumber(), is("16.05.0"));
+        assertThat(latest.getMd5Sum(), is("ad533205938163686aaed40a75073fcd"));
+        assertThat(latest.getDownloadLink(), is("http://storage.googleapis.com/fairphone-updates/fp2-sibon-16.05.0-ota-userdebug.zip"));
+        assertThat(latest.hasEraseAllPartitionWarning(), is(false));
+
+        assertNotNull(updaterData.getAOSPVersionList());
+        assertThat(updaterData.isAOSPVersionListNotEmpty(), is(false));
+        assertThat(updaterData.getAOSPVersionList().size(), is(0));
+        assertNull(updaterData.getLatestVersion(Version.IMAGE_TYPE_AOSP));
+
+        assertNotNull(updaterData.getAppStoreList());
+        assertThat(updaterData.isAppStoreListEmpty(), is(true));
+        assertThat(updaterData.getAppStoreList().size(), is(0));
+    }
+}
diff --git a/app/src/test/resources/fp1_fpos_latest.xml b/app/src/test/resources/fp1_fpos_latest.xml
new file mode 100644
index 0000000..98e1666
--- /dev/null
+++ b/app/src/test/resources/fp1_fpos_latest.xml
@@ -0,0 +1,109 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<updater>
+    <releases>
+        <aosp latest="4">
+            <version number="4">
+                <name>Jelly Bean 11-2014</name>
+                <build_number>4.2.2</build_number>
+                <android_version>4.2.2</android_version>
+                <release_notes>Stock Android image
+                    Jelly Bean</release_notes>
+                <release_date>26/11/2014</release_date>
+                <md5sum>20286cb405e1487066c31b55438311ac</md5sum>
+                <thumbnail_link>http://192.168.0.29:8080/</thumbnail_link>
+                <update_link>http://storage.googleapis.com/update-v1_8/AOSP-4.2.2_OTA_2014-11-26.zip</update_link>
+            </version>
+        </aosp>
+        <fairphone latest="2015081400">
+            <version number="3">
+                <name>Cherry</name>
+                <build_number>1.6</build_number>
+                <android_version>4.2.2</android_version>
+                <release_notes>Release notes: For the full list of changes, please visit fairphone.com/support</release_notes>
+                <release_notes_de>Notiz: Für die vollständige Liste von Veränderungen, bitte besuche fairphone.com/support</release_notes_de>
+                <release_notes_nl>Versie-informatie: voor de volledige lijst met veranderingen, ga naar fairphone.com/support</release_notes_nl>
+                <release_notes_fr>Notes de mise à jour: pour connaître la liste complète des modifications, rendez-vous sur fairphone.com/support</release_notes_fr>
+                <release_notes_es>Nota: para ver la lista de novedades de esta actualización, visita la web fairphone.com/support</release_notes_es>
+                <release_notes_pt>Nota: Para ver a lista completa de novidades desta actualização, visite fairphone.com/support</release_notes_pt>
+                <release_notes_ca>Nota: per a veure la llista de novetats d'aquesta actualització, visita la web fairphone.com/support</release_notes_ca>
+                <release_date>31/07/2014</release_date>
+                <md5sum>664ca09368a4c922a12dc2526afe092b</md5sum>
+                <thumbnail_link>http://192.168.0.29:8080/</thumbnail_link>
+                <update_link>http://storage.googleapis.com/update-v1_6/FP1_Fairphone_OS_v1_6_OTA_2014-07-31.zip</update_link>
+            </version>
+            <version number="21">
+                <name>Kola Nut</name>
+                <build_number>1.8.5</build_number>
+                <android_version>4.2.2</android_version>
+                <release_notes>Release notes: For the full list of changes, please visit fairphone.com/support</release_notes>
+                <release_notes_de>Notiz: Für die vollständige Liste von Veränderungen, bitte besuche fairphone.com/support</release_notes_de>
+                <release_notes_nl>Versie-informatie: voor de volledige lijst met veranderingen, ga naar fairphone.com/support</release_notes_nl>
+                <release_notes_fr>Notes de mise à jour: pour connaître la liste complète des modifications, rendez-vous sur fairphone.com/support</release_notes_fr>
+                <release_notes_es>Nota: para ver la lista de novedades de esta actualización, visita la web fairphone.com/support</release_notes_es>
+                <release_notes_pt>Nota: Para ver a lista completa de novidades desta actualização, visite fairphone.com/support</release_notes_pt>
+                <release_notes_ca>Nota: per a veure la llista de novetats d'aquesta actualització, visita la web fairphone.com/support</release_notes_ca>
+                <release_date>07/05/2015</release_date>
+                <md5sum>b1b3272933d7f53c573b31d1c09c40f7</md5sum>
+                <thumbnail_link>http://192.168.0.29:8080/</thumbnail_link>
+                <update_link>http://storage.googleapis.com/fairphone-updates/FP1-Fairphone_OS_v1_8_5_OTA_2015-05-07.zip</update_link>
+            </version>
+            <version number="22">
+                <name>Kola Nut</name>
+                <build_number>1.8.6</build_number>
+                <android_version>4.2.2</android_version>
+                <release_notes>Release notes: For the full list of changes, please visit fairphone.com/support</release_notes>
+                <release_notes_de>Notiz: Für die vollständige Liste von Veränderungen, bitte besuche fairphone.com/support</release_notes_de>
+                <release_notes_nl>Versie-informatie: voor de volledige lijst met veranderingen, ga naar fairphone.com/support</release_notes_nl>
+                <release_notes_fr>Notes de mise à jour: pour connaître la liste complète des modifications, rendez-vous sur fairphone.com/support</release_notes_fr>
+                <release_notes_es>Nota: para ver la lista de novedades de esta actualización, visita la web fairphone.com/support</release_notes_es>
+                <release_notes_pt>Nota: Para ver a lista completa de novidades desta actualização, visite fairphone.com/support</release_notes_pt>
+                <release_notes_ca>Nota: per a veure la llista de novetats d'aquesta actualització, visita la web fairphone.com/support</release_notes_ca>
+                <release_date>07/07/2015</release_date>
+                <md5sum>555a763439aa8e39fc5433aeca9fdee3</md5sum>
+                <thumbnail_link>http://192.168.0.29:8080/</thumbnail_link>
+                <update_link>http://storage.googleapis.com/fairphone-updates/FP1-Fairphone_OS_v1_8_6_OTA-2015-07-07.zip</update_link>
+            </version>
+            <version number="24">
+                <name>FP1X</name>
+                <build_number>13</build_number>
+                <android_version>4.2.2</android_version>
+                <release_notes>Release notes: For the full list of changes, please visit fairphone.com/support</release_notes>
+                <release_notes_de>Notiz: Für die vollständige Liste von Veränderungen, bitte besuche fairphone.com/support</release_notes_de>
+                <release_notes_nl>Versie-informatie: voor de volledige lijst met veranderingen, ga naar fairphone.com/support</release_notes_nl>
+                <release_notes_fr>Notes de mise à jour: pour connaître la liste complète des modifications, rendez-vous sur fairphone.com/support</release_notes_fr>
+                <release_notes_es>Nota: para ver la lista de novedades de esta actualización, visita la web fairphone.com/support</release_notes_es>
+                <release_notes_pt>Nota: Para ver a lista completa de novidades desta actualização, visite fairphone.com/support</release_notes_pt>
+                <release_notes_ca>Nota: per a veure la llista de novetats d'aquesta actualització, visita la web fairphone.com/support</release_notes_ca>
+                <release_date>08/07/2015</release_date>
+                <md5sum>318a6d4c6936e4a713f6b1b3263d92f7</md5sum>
+                <thumbnail_link>http://192.168.0.29:8080/</thumbnail_link>
+                <update_link>http://storage.googleapis.com/fairphone-updates/FP1X-Fairphone_OS_OTA_13.zip</update_link>
+            </version>
+            <version number="2015070700"><name>FP1X</name><build_number>2015070700</build_number><android_version>4.2.2</android_version><release_notes /><release_date>13/07/2015</release_date><md5sum>ab71735cb7b4c89e23124a2d7ff8c9c9</md5sum><update_link>http://storage.googleapis.com/fairphone-updates/FP1X-Fairphone_OS_2015070700.zip</update_link></version>
+            <version number="2015081400"><name>Kola Nut</name><build_number>1.8.7</build_number><android_version>4.2.2</android_version><release_notes>Release notes: For the full list of changes, please visit fairphone.com/support</release_notes><release_notes_de>Notiz: Für die vollständige Liste von Veränderungen, bitte besuche fairphone.com/support</release_notes_de><release_notes_nl>Versie-informatie: voor de volledige lijst met veranderingen, ga naar fairphone.com/support</release_notes_nl><release_notes_fr>Notes de mise à jour: pour connaître la liste complète des modifications, rendez-vous sur fairphone.com/support</release_notes_fr><release_notes_es>Nota: para ver la lista de novedades de esta actualización, visita la web fairphone.com/support</release_notes_es><release_notes_pt>Nota: Para ver a lista completa de novidades desta actualização, visite fairphone.com/support</release_notes_pt><release_notes_ca>Nota: per a veure la llista de novetats d'aquesta actualització, visita la web fairphone.com/support</release_notes_ca><release_date>14/08/2015</release_date><md5sum>7f3b6a7c11f9b5444fa90cb73f82bff9</md5sum><update_link>http://storage.googleapis.com/fairphone-updates/FP1-Fairphone_OS_v1_8_7_OTA_2015081400.zip</update_link></version></fairphone>
+    </releases>
+    <stores>
+
+        <store number="0">
+
+            <name>Google Apps</name>
+            <build_number>1.0</build_number>
+            <release_notes>Google Apps package</release_notes>
+
+            <release_notes_fr>Google Apps package</release_notes_fr>
+
+            <release_notes_nl>Google Apps package</release_notes_nl>
+
+            <release_notes_es>Google Apps package</release_notes_es>
+
+            <release_notes_de>Google Apps package</release_notes_de>
+
+            <release_notes_pt>Google Apps package</release_notes_pt>
+            <release_date>20/12/2013</release_date>
+            <md5sum>9444e40ed5afc9d61530681542f97b97</md5sum>
+            <update_link>http://s3-eu-west-1.amazonaws.com/gatest15/gapps_1.5.zip</update_link>
+            <show_disclaimer />
+
+        </store>
+    </stores>
+</updater>
\ No newline at end of file
diff --git a/app/src/test/resources/fp2_fpopen_latest.xml b/app/src/test/resources/fp2_fpopen_latest.xml
new file mode 100644
index 0000000..86bd093
--- /dev/null
+++ b/app/src/test/resources/fp2_fpopen_latest.xml
@@ -0,0 +1,32 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<updater>
+    <releases>
+        <fairphone latest="fp2-sibon-16.05.0">
+            <version number="fp2-sibon-16.05.0">
+                <name>Fairphone Open Source OS</name>
+                <build_number>16.05.0</build_number>
+                <android_version>5.1</android_version>
+                <release_notes>
+                </release_notes>
+                <release_date>27/05/2016</release_date>
+                <md5sum>ad533205938163686aaed40a75073fcd</md5sum>
+                <update_link>http://storage.googleapis.com/fairphone-updates/fp2-sibon-16.05.0-ota-userdebug.zip</update_link>
+            </version>
+            <version number="r4275.1_FP2_gms54_1.3.6">
+                <name>Fairphone OS</name>
+                <build_number>1.3.6</build_number>
+                <android_version>5.1</android_version>
+                <release_notes>Installing this Fairphone OS version will bring you back to the default Fairphone software that includes Google Services.
+
+                    Important: All of your data will be erased, so make sure you’ve backed up any important data beforehand.
+
+                    Before starting the update installation, make sure you're connected to a Wi-Fi network and your battery is fully charged.
+                </release_notes>
+                <release_date>28/04/2016</release_date>
+                <md5sum>3ac91fca0d2c51801bd6a72f747c1b3d</md5sum>
+                <update_link>http://storage.googleapis.com/fairphone-updates/FP2-gms54-1.3.6-ota_from_open.zip</update_link>
+                <erase_data_warning />
+            </version>
+        </fairphone>
+    </releases>
+</updater>
\ No newline at end of file
diff --git a/app/src/test/resources/fp2_fpos_latest.xml b/app/src/test/resources/fp2_fpos_latest.xml
new file mode 100644
index 0000000..5328f54
--- /dev/null
+++ b/app/src/test/resources/fp2_fpos_latest.xml
@@ -0,0 +1,45 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<updater>
+    <releases>
+        <fairphone latest="r4275.1_FP2_gms56_1.4.2">
+            <version number="r4275.1_FP2_gms56_1.4.2">
+                <name>Fairphone OS</name>
+                <build_number>1.4.2</build_number>
+                <android_version>5.1</android_version>
+                <release_notes>Before starting the update installation, make sure you're connected to a Wi-Fi network and your battery is charged to at least 80%
+
+                    For the full release notes, check
+                    fairphone.com/support
+                </release_notes>
+                <release_notes_nl>Voordat je verder gaat met de installatie, zorg dat je verbonden bent met een Wi-Fi netwerk en dat je batterij minstens 80% opgeladen is.
+
+                    Voor de volledige lijst met veranderingen,
+                    kijk op fairphone.com/support
+                </release_notes_nl>
+                <release_notes_de>Stell sicher, dass du mit dem WLAN verbunden und die Batterie mindestens 80% aufgeladen ist, bevor du mit der Installation des Updates beginnst.
+
+                    Eine Liste mit allen Änderungen findest du unter
+                    fairphone.com/support
+                </release_notes_de>
+                <release_notes_fr>Assurez-vous d’être connecté à un réseau Wi-Fi et d’avoir chargé votre batterie à au moins 80% avant de procéder à la mise à jour.
+
+                    Rendez-vous à l’adresse
+                    fairphone.com/support pour la liste complète des changements et améliorations.
+                </release_notes_fr>
+                <release_notes_es>Antes de comenzar la actualización, asegúrate que estás conectado a una red Wi-Fi y que tu batería está cargada un 80% como mínimo.
+
+                    Para acceder a los detalles sobre esta actualización, visita
+                    fairphone.com/support
+                </release_notes_es>
+                <release_notes_pt>Antes de prosseguir com a instalação, certifique-se que está conectado a uma rede Wi-Fi e que a sua bateria está com pelo menos 80% de carga.
+
+                    Para a lista completa de alterações, consulte
+                    fairphone.com/support
+                </release_notes_pt>
+                <release_date>07/06/2016</release_date>
+                <md5sum>f0d157ef40fc0bfa4bdb3911e772a4c0</md5sum>
+                <update_link>http://storage.googleapis.com/fairphone-updates/FP2-gms56-1.4.2-ota.zip</update_link>
+            </version>
+        </fairphone>
+    </releases>
+</updater>
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 296ab9b..f04b8cb 100644
--- a/build.gradle
+++ b/build.gradle
@@ -7,7 +7,7 @@
         maven { url 'http://download.crashlytics.com/maven' }
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:1.3.0'
+        classpath 'com.android.tools.build:gradle:2.1.2'
         classpath 'com.crashlytics.tools.gradle:crashlytics-gradle:1.+'
     }
 }
@@ -17,63 +17,3 @@
         jcenter()
     }
 }
-
-// Module level gradle declarations
-
-apply plugin: 'com.android.application'
-
-apply plugin: 'crashlytics'
-
-repositories {
-    maven { url 'http://download.crashlytics.com/maven' }
-}
-
-android {
-    compileSdkVersion 21
-    buildToolsVersion "21.1.2"
-
-    defaultConfig {
-        applicationId "com.fairphone.updater"
-        minSdkVersion 17
-        targetSdkVersion 21
-    }
-
-    buildTypes {
-        release {
-            minifyEnabled true
-            shrinkResources true
-            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
-        }
-    }
-
-    sourceSets {
-        main {
-            manifest.srcFile 'AndroidManifest.xml'
-            java.srcDirs = ['src']
-            resources.srcDirs = ['src']
-            aidl.srcDirs = ['src']
-            renderscript.srcDirs = ['src']
-            res.srcDirs = ['res']
-            assets.srcDirs = ['assets']
-        }
-
-        // Move the tests to tests/java, tests/res, etc...
-        instrumentTest.setRoot('tests')
-        androidTest.setRoot('tests')
-        
-        // Move the build types to build-types/<type>
-        // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...
-        // This moves them out of them default location under src/<type>/... which would
-        // conflict with src/ being used by the main source set.
-        // Adding new build types or product flavors should be accompanied
-        // by a similar customization.
-        debug.setRoot('build-types/debug')
-        release.setRoot('build-types/release')
-    }
-}
-
-dependencies {
-    compile 'com.android.support:support-v4:21.0.+'
-    compile 'com.crashlytics.android:crashlytics:1.+'
-    compile files('libs/RootTools-3.3.jar')
-}
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 0c71e76..3241fbc 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Wed Apr 10 15:27:10 PDT 2013
+#Tue Jun 14 16:10:04 CEST 2016
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/src/com/fairphone/updater/data/VersionParserHelper.java b/src/com/fairphone/updater/data/VersionParserHelper.java
deleted file mode 100644
index 4120743..0000000
--- a/src/com/fairphone/updater/data/VersionParserHelper.java
+++ /dev/null
@@ -1,488 +0,0 @@
-/*
- * Copyright (C) 2013 Fairphone Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.fairphone.updater.data;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.os.Build;
-import android.os.Environment;
-import android.util.Log;
-import android.util.Pair;
-
-import com.fairphone.updater.R;
-import com.fairphone.updater.tools.Utils;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlPullParserFactory;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.Locale;
-
-public class VersionParserHelper
-{
-
-    private static final String TAG = VersionParserHelper.class.getSimpleName();
-
-    private static final String CURRENT_VERSION_NUMBER = "fairphone.ota.version.number";
-    private static final String CURRENT_VERSION_NAME = "fairphone.ota.version.name";
-    private static final String CURRENT_VERSION_BUILD_NUMBER = "fairphone.ota.build_number";
-    private static final String CURRENT_VERSION_IMAGE_TYPE = "fairphone.ota.image_type";
-    private static final String CURRENT_VERSION_ID = "ro.build.version.incremental";                // for FP2
-
-
-    private static Version version;
-    public static Version getDeviceVersion(Context context)
-    {
-        if (version == null){
-            Version versionBuilder = new Version();
-            String[] supportedDevices = context.getResources().getString(R.string.knownFPDevices).split(";");
-            String modelWithoutSpaces = Build.MODEL.replaceAll("\\s", "");
-            boolean knownFPDevice = false;
-            for (String device : supportedDevices) {
-                knownFPDevice = knownFPDevice || device.equals(modelWithoutSpaces);
-            }
-
-            if(modelWithoutSpaces.equals(context.getResources().getString(R.string.FP2Model))) {
-                // FP2
-                try {
-                    versionBuilder.setId(getSystemData(context, CURRENT_VERSION_ID, knownFPDevice));
-                } catch (NumberFormatException e) {
-                    String defaultVersionId = context.getResources().getString(R.string.defaultVersionId);
-                    Log.w(TAG, "Error parsing current version id. Defaulting to " + defaultVersionId + ": " + e.getLocalizedMessage());
-                    versionBuilder.setId(defaultVersionId);
-                }
-                versionBuilder.setName(versionBuilder.getCurrentImageType());
-                versionBuilder.setBuildNumber(versionBuilder.getBuildNumberFromId());
-            } else {
-                // FP1(U)
-                try
-                {
-                    versionBuilder.setId(getSystemData(context, CURRENT_VERSION_NUMBER, knownFPDevice) );
-                } catch (NumberFormatException e) {
-                    String defaultVersionNumber = context.getResources().getString(R.string.defaultVersionId);
-                    Log.w(TAG, "Error parsing current version number. Defaulting to " + defaultVersionNumber + ": " + e.getLocalizedMessage());
-                    versionBuilder.setId(defaultVersionNumber);
-                }
-                versionBuilder.setName(getSystemData(context, CURRENT_VERSION_NAME, knownFPDevice));
-                versionBuilder.setBuildNumber(getSystemData(context, CURRENT_VERSION_BUILD_NUMBER, knownFPDevice));
-            }
-
-            versionBuilder.setImageType(getSystemData(context, CURRENT_VERSION_IMAGE_TYPE, knownFPDevice));
-
-            Version versionData = UpdaterData.getInstance().getVersion(versionBuilder.getImageType(), versionBuilder.getId());
-            versionBuilder.setThumbnailLink(versionData != null ? versionData.getThumbnailLink() : "");
-            versionBuilder.setReleaseNotes(Locale.getDefault().getLanguage(), versionData != null ? versionData.getReleaseNotes(Locale.getDefault().getLanguage()) : "");
-            version = versionBuilder;
-        }
-
-        return version;
-    }
-
-    private static String getSystemData(Context context, String property, boolean useDefaults)
-    {
-		String result;
-	    switch (property) {
-		    case CURRENT_VERSION_NUMBER:
-			    result = Utils.getprop(CURRENT_VERSION_NUMBER, useDefaults ? String.valueOf(context.getResources().getString(R.string.defaultVersionId)) : "");
-			    break;
-		    case CURRENT_VERSION_NAME:
-			    result = Utils.getprop(CURRENT_VERSION_NAME, useDefaults ? context.getResources().getString(R.string.defaultVersionName) : "");
-			    break;
-		    case CURRENT_VERSION_BUILD_NUMBER:
-			    result = Utils.getprop(CURRENT_VERSION_BUILD_NUMBER, useDefaults ? context.getResources().getString(R.string.defaultBuildNumber) : "");
-			    break;
-		    case CURRENT_VERSION_IMAGE_TYPE:
-			    result = Utils.getprop(CURRENT_VERSION_IMAGE_TYPE, useDefaults ? context.getResources().getString(R.string.defaultImageType) : "");
-			    break;
-            case CURRENT_VERSION_ID:
-                result = Utils.getprop(CURRENT_VERSION_ID, useDefaults ? "" : ""); // TODO: define default value for fingerprint
-                break;
-		    default:
-			    result = "";
-			    break;
-	    }
-
-        return result;
-    }
-
-    public static Version getLatestVersion(Context context)
-    {
-
-        Version latest = null;
-        Resources resources = context.getResources();
-        FileInputStream fis = null;
-        try {
-            fis = context.openFileInput(resources.getString(R.string.configFilename) + resources.getString(R.string.config_xml));
-        } catch (FileNotFoundException e){
-        }
-
-        if (fis != null)
-        {
-            try
-            {
-                latest = parseLatestXML(context, fis);
-            } catch (XmlPullParserException e)
-            {
-                Log.e(TAG, "Could not start the XML parser", e);
-            } catch (IOException e)
-            {
-                Log.e(TAG, "Invalid data in File", e);
-                // remove the files
-                removeConfigFiles(context);
-            }
-        }
-
-        removeZipContents(context);
-
-        return latest;
-    }
-
-    // @formatter:off
-    public enum XML_LEVEL_TAGS
-    {
-        NONE, AOSP, FAIRPHONE, STORES
-    }
-
-    public enum XML_TAGS
-    {
-        /*RELEASES,*/ AOSP, FAIRPHONE, VERSION, NAME, BUILD_NUMBER, ANDROID_VERSION, RELEASE_NOTES, RELEASE_DATE, MD5SUM, THUMBNAIL_LINK, UPDATE_LINK, ERASE_DATA_WARNING, DEPENDENCIES, /*STORES,*/ STORE, SHOW_DISCLAIMER
-    }
-
-    // @formatter:on
-
-    private static Version parseLatestXML(Context context, File latestFile) throws XmlPullParserException, IOException {
-        FileInputStream fis = new FileInputStream(latestFile);
-        return parseLatestXML(context, fis);
-    }
-
-    private static Version parseLatestXML(Context context, FileInputStream fis) throws XmlPullParserException, IOException
-    {
-
-        Version version = null;
-        Store store = null;
-        Pair<Version, Store> result;
-
-        UpdaterData update = UpdaterData.getInstance();
-        update.resetUpdaterData();
-
-        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
-        factory.setNamespaceAware(true);
-
-
-        XmlPullParser xpp = factory.newPullParser();
-
-        xpp.setInput(new InputStreamReader(fis));
-
-        int eventType = xpp.getEventType();
-
-        XML_LEVEL_TAGS currentTag = XML_LEVEL_TAGS.NONE;
-
-        while (eventType != XmlPullParser.END_DOCUMENT)
-        {
-            String tagName;
-            switch (eventType)
-            {
-                case XmlPullParser.START_DOCUMENT:
-                    break;
-                case XmlPullParser.START_TAG:
-                    tagName = xpp.getName();
-                    currentTag = getCurrentXmlElement(tagName, currentTag);
-                    result = readStartTag(xpp, currentTag, tagName, update, version, store);
-                    version = result.first;
-                    store = result.second;
-                    break;
-                case XmlPullParser.END_TAG:
-                    tagName = xpp.getName();
-                    currentTag = getCurrentXmlElement(tagName, currentTag);
-                    result = readEndTag(currentTag, tagName, update, version, store);
-                    version = result.first;
-                    store = result.second;
-                    break;
-                default:
-                    break;
-            }
-
-            eventType = xpp.next();
-        }
-        fis.close();
-
-        removeZipContents(context);
-        return update.getLatestVersion(getSystemData(context, CURRENT_VERSION_IMAGE_TYPE, true));
-    }
-
-    private static Pair<Version, Store> readStartTag(XmlPullParser xpp, XML_LEVEL_TAGS currentTag, String tagName, UpdaterData update, Version version, Store store) throws XmlPullParserException, IOException
-    {
-        Version updateVersion = null;
-        Store updateStore = null;
-        switch (currentTag)
-        {
-            case AOSP:
-                if (tagName.equalsIgnoreCase(XML_TAGS.AOSP.name()))
-                {
-                    update.setLatestAOSPVersionNumber(xpp.getAttributeValue(0));
-                }
-                updateVersion = readVersion(version, xpp, tagName);
-                updateVersion.setImageType(Version.IMAGE_TYPE_AOSP);
-                break;
-            case FAIRPHONE:
-                if (tagName.equalsIgnoreCase(XML_TAGS.FAIRPHONE.name()))
-                {
-                    update.setLatestFairphoneVersionNumber(xpp.getAttributeValue(0));
-                }
-                updateVersion = readVersion(version, xpp, tagName);
-                updateVersion.setImageType(Version.IMAGE_TYPE_FAIRPHONE);
-                break;
-            case STORES:
-                updateStore = readStore(store, xpp, tagName);
-                break;
-            case NONE:
-            default:
-                if(version != null)
-                {
-                    updateVersion = new Version(version);
-                }
-
-                if(store != null)
-                {
-                    updateStore = new Store(store);
-                }
-                break;
-        }
-
-        return new Pair<>(updateVersion, updateStore);
-    }
-
-    private static Pair<Version, Store> readEndTag(XML_LEVEL_TAGS currentTag, String tagName, UpdaterData update, Version version, Store store) {
-        Version updateVersion = null;
-        Store updateStore = null;
-        switch (currentTag)
-        {
-            case AOSP:
-                if (tagName.equalsIgnoreCase(XML_TAGS.VERSION.name()))
-                {
-                    update.addAOSPVersion(version);
-                    updateVersion = null;
-                }
-                else
-                {
-                    if(version != null)
-                    {
-                        updateVersion = new Version(version);
-                    }
-                }
-                break;
-            case FAIRPHONE:
-                if (tagName.equalsIgnoreCase(XML_TAGS.VERSION.name()))
-                {
-                    update.addFairphoneVersion(version);
-                    updateVersion = null;
-                }
-                else
-                {
-                    if(version != null)
-                    {
-                        updateVersion = new Version(version);
-                    }
-                }
-                break;
-            case STORES:
-                if (tagName.equalsIgnoreCase(XML_TAGS.STORE.name()))
-                {
-                    update.addAppStore(store);
-                    updateStore = null;
-                }
-                else
-                {
-                    if(store != null)
-                    {
-                        updateStore = new Store(store);
-                    }
-                }
-                break;
-            case NONE:
-            default:
-                if(version != null)
-                {
-                    updateVersion = new Version(version);
-                }
-
-                if(store != null)
-                {
-                    updateStore = new Store(store);
-                }
-                break;
-        }
-
-        return new Pair<>(updateVersion, updateStore);
-    }
-
-    private static Version readVersion(Version version, XmlPullParser xpp, String tagName) throws XmlPullParserException, IOException
-    {
-        Version updateVersion;
-        if (version == null)
-        {
-            updateVersion = new Version();
-        }
-        else
-        {
-            updateVersion = new Version(version);
-        }
-
-        readDownloadableItem(updateVersion, xpp, tagName);
-
-        if (tagName.equalsIgnoreCase(XML_TAGS.VERSION.name()))
-        {
-            updateVersion.setId(xpp.getAttributeValue(0));
-        }
-        else if (tagName.equalsIgnoreCase(XML_TAGS.ANDROID_VERSION.name()))
-        {
-            updateVersion.setAndroidVersion(xpp.nextText());
-        }
-        else if (tagName.equalsIgnoreCase(XML_TAGS.DEPENDENCIES.name()))
-        {
-            updateVersion.setVersionDependencies(xpp.nextText());
-        }
-        else if (tagName.equalsIgnoreCase(XML_TAGS.ERASE_DATA_WARNING.name()))
-        {
-            updateVersion.setEraseAllPartitionWarning();
-        }
-
-        return updateVersion;
-    }
-
-    private static Store readStore(Store store, XmlPullParser xpp, String tagName) throws XmlPullParserException, IOException
-    {
-
-        Store updateStore;
-        if (store == null)
-        {
-            updateStore = new Store();
-        }
-        else
-        {
-            updateStore = new Store(store);
-        }
-
-        readDownloadableItem(updateStore, xpp, tagName);
-
-        if (tagName.equalsIgnoreCase(XML_TAGS.STORE.name()))
-        {
-            updateStore.setId(xpp.getAttributeValue(0));
-        }
-        else if (tagName.equalsIgnoreCase(XML_TAGS.SHOW_DISCLAIMER.name()))
-        {
-            updateStore.setShowDisclaimer();
-        }
-
-        return updateStore;
-    }
-
-    private static void readDownloadableItem(DownloadableItem item, XmlPullParser xpp, String tagName) throws XmlPullParserException, IOException
-    {
-        if (tagName.equalsIgnoreCase(XML_TAGS.NAME.name()))
-        {
-            item.setName(xpp.nextText());
-        }
-        else if (tagName.equalsIgnoreCase(XML_TAGS.BUILD_NUMBER.name()))
-        {
-            item.setBuildNumber(xpp.nextText());
-        }
-        else if (tagName.equalsIgnoreCase(XML_TAGS.RELEASE_NOTES.name()))
-        {
-            item.setReleaseNotes(Version.DEFAULT_NOTES_LANG, xpp.nextText());
-        }
-        else if (tagName.equalsIgnoreCase(XML_TAGS.RELEASE_NOTES.name() + "_" + Locale.getDefault().getLanguage()))
-        {
-            item.setReleaseNotes(Locale.getDefault().getLanguage(), xpp.nextText());
-        }
-        else if (tagName.equalsIgnoreCase(XML_TAGS.RELEASE_DATE.name()))
-        {
-            item.setReleaseDate(xpp.nextText());
-        }
-        else if (tagName.equalsIgnoreCase(XML_TAGS.MD5SUM.name()))
-        {
-            item.setMd5Sum(xpp.nextText());
-        }
-        else if (tagName.equalsIgnoreCase(XML_TAGS.THUMBNAIL_LINK.name()))
-        {
-            item.setThumbnailLink(xpp.nextText());
-        }
-        else if (tagName.equalsIgnoreCase(XML_TAGS.UPDATE_LINK.name()))
-        {
-            item.setDownloadLink(xpp.nextText());
-        }
-    }
-
-    private static XML_LEVEL_TAGS getCurrentXmlElement(String tagName, XML_LEVEL_TAGS current)
-    {
-        XML_LEVEL_TAGS retval = current;
-
-        if (tagName.equalsIgnoreCase(XML_LEVEL_TAGS.AOSP.name()))
-        {
-            retval = XML_LEVEL_TAGS.AOSP;
-        }
-        else if (tagName.equalsIgnoreCase(XML_LEVEL_TAGS.FAIRPHONE.name()))
-        {
-            retval = XML_LEVEL_TAGS.FAIRPHONE;
-        }
-        else if (tagName.equalsIgnoreCase(XML_LEVEL_TAGS.STORES.name()))
-        {
-            retval = XML_LEVEL_TAGS.STORES;
-        }
-        return retval;
-    }
-
-    
-
-    public static void removeConfigFiles(Context context)
-    {
-        Resources resources = context.getResources();
-        String filePath =
-                Environment.getExternalStorageDirectory() + resources.getString(R.string.updaterFolder) + resources.getString(R.string.configFilename);
-
-        removeFile(filePath + resources.getString(R.string.config_zip));
-        removeZipContents(context);
-    }
-
-    private static void removeZipContents(Context context)
-    {
-        Resources resources = context.getResources();
-        String filePath =
-                Environment.getExternalStorageDirectory() + resources.getString(R.string.updaterFolder) + resources.getString(R.string.configFilename);
-
-        removeFile(filePath + resources.getString(R.string.config_xml));
-        removeFile(filePath + resources.getString(R.string.config_sig));
-    }
-
-    private static void removeFile(String filePath)
-    {
-        File file = new File(filePath);
-        if (file.exists())
-        {
-	        final boolean notDeleted = !file.delete();
-	        if (notDeleted) {
-		        Log.d(TAG, "Couldn't delete file: " + file.getAbsolutePath());
-	        }
-        }
-    }
-
-}