speed optimizations
diff --git a/src/com/fairphone/updater/FairphoneUpdater.java b/src/com/fairphone/updater/FairphoneUpdater.java
index 3078162..ca2b7f5 100644
--- a/src/com/fairphone/updater/FairphoneUpdater.java
+++ b/src/com/fairphone/updater/FairphoneUpdater.java
@@ -150,7 +150,7 @@
         // reset download URL
         Editor editor = mSharedPreferences.edit();
         editor.putString(PREFERENCE_OTA_DOWNLOAD_URL, otaDownloadUrl);
-        editor.commit();
+        editor.apply();
 
         // get system data
         mDeviceVersion = VersionParserHelper.getDeviceVersion(this);
diff --git a/src/com/fairphone/updater/UpdaterService.java b/src/com/fairphone/updater/UpdaterService.java
index a0527ce..a211cd8 100644
--- a/src/com/fairphone/updater/UpdaterService.java
+++ b/src/com/fairphone/updater/UpdaterService.java
@@ -73,6 +73,7 @@
 
     public static final String PREFERENCE_LAST_CONFIG_DOWNLOAD_ID = "LastConfigDownloadId";
     public static final String PREFERENCE_REINSTALL_GAPPS = "ReinstallGappsOmnStartUp";
+    public static final String PREFERENCE_CONFIG_MD_5 = "CONFIG_MD5";
     private DownloadManager mDownloadManager = null;
     private DownloadBroadCastReceiver mDownloadBroadCastReceiver = null;
 
@@ -493,18 +494,20 @@
 
         if (file.exists())
         {
-            if (RSAUtils.checkFileSignature(context, filePath, targetPath))
-            {
+            String md5sum = Utils.calculateMD5(file);
+            SharedPreferences sp = context.getSharedPreferences(FairphoneUpdater.FAIRPHONE_UPDATER_PREFERENCES, MODE_PRIVATE);
+            if(sp.getString(PREFERENCE_CONFIG_MD_5, "").equals(md5sum)){
+                retVal = true;
+            } else if (RSAUtils.checkFileSignature(context, filePath, targetPath)) {
                 checkVersionValidation(context);
                 retVal = true;
-            }
-            else
-            {
+                sp.edit().putString(PREFERENCE_CONFIG_MD_5, md5sum).apply();
+            } else {
                 //Toast.makeText(context, resources.getString(R.string.invalid_signature_download_message), Toast.LENGTH_LONG).show();
                 final boolean notDeleted = !file.delete();
-	            if(notDeleted) {
-		            Log.d(TAG, "Unable to delete "+file.getAbsolutePath());
-	            }
+                if(notDeleted) {
+                    Log.d(TAG, "Unable to delete "+file.getAbsolutePath());
+                }
 
             }
         }
diff --git a/src/com/fairphone/updater/data/VersionParserHelper.java b/src/com/fairphone/updater/data/VersionParserHelper.java
index 1392271..320a935 100644
--- a/src/com/fairphone/updater/data/VersionParserHelper.java
+++ b/src/com/fairphone/updater/data/VersionParserHelper.java
@@ -49,36 +49,39 @@
     private static final String CURRENT_VERSION_IMAGE_TYPE = "fairphone.ota.image_type";
     private static final String CURRENT_VERSION_BUILD_DATE = "ro.build.date.utc";
 
+    private static Version version;
     public static Version getDeviceVersion(Context context)
     {
+        if (version == null){
+            Version versionBuilder = new Version();
+            String[] suportedDevices = context.getResources().getString(R.string.knownFPDevices).split(";");
+            String modelWithoutSpaces = Build.MODEL.replaceAll("\\s", "");
+            boolean knownFPDevice = false;
+            for(String device : suportedDevices){
+                knownFPDevice = knownFPDevice || device.equals(modelWithoutSpaces);
+            }
 
-        Version version = new Version();
-        String[] suportedDevices = context.getResources().getString(R.string.knownFPDevices).split(";");
-        String modelWithoutSpaces = Build.MODEL.replaceAll("\\s", "");
-        boolean knownFPDevice = false;
-        for(String device : suportedDevices){
-            knownFPDevice = knownFPDevice || device.equals(modelWithoutSpaces);
-        }
-        
-        try
-        {
-            version.setNumber(Integer.valueOf(getSystemData(context, CURRENT_VERSION_NUMBER, knownFPDevice)));
-        } catch (NumberFormatException e)
-        {
-            int defaultVersionNumber = context.getResources().getInteger(R.integer.defaultVersionNumber);
-            Log.w(TAG, "Error parsing current version number. Defaulting to " + defaultVersionNumber + ": " + e.getLocalizedMessage());
-            version.setNumber(defaultVersionNumber);
-        }
-        version.setName(getSystemData(context, CURRENT_VERSION_NAME, knownFPDevice));
-        version.setBuildNumber(getSystemData(context, CURRENT_VERSION_BUILD_NUMBER, knownFPDevice));
-        version.setAndroidVersion(getSystemData(context, CURRENT_ANDROID_VERSION, knownFPDevice));
-        version.setImageType(getSystemData(context, CURRENT_VERSION_IMAGE_TYPE, knownFPDevice));
-        version.setReleaseDate(getSystemData(context, CURRENT_VERSION_BUILD_DATE, knownFPDevice));
-        version.setBetaStatus(getSystemData(context, CURRENT_BETA_STATUS, knownFPDevice));
+            try
+            {
+                versionBuilder.setNumber(Integer.valueOf(getSystemData(context, CURRENT_VERSION_NUMBER, knownFPDevice)));
+            } catch (NumberFormatException e)
+            {
+                int defaultVersionNumber = context.getResources().getInteger(R.integer.defaultVersionNumber);
+                Log.w(TAG, "Error parsing current version number. Defaulting to " + defaultVersionNumber + ": " + e.getLocalizedMessage());
+                versionBuilder.setNumber(defaultVersionNumber);
+            }
+            versionBuilder.setName(getSystemData(context, CURRENT_VERSION_NAME, knownFPDevice));
+            versionBuilder.setBuildNumber(getSystemData(context, CURRENT_VERSION_BUILD_NUMBER, knownFPDevice));
+            versionBuilder.setAndroidVersion(getSystemData(context, CURRENT_ANDROID_VERSION, knownFPDevice));
+            versionBuilder.setImageType(getSystemData(context, CURRENT_VERSION_IMAGE_TYPE, knownFPDevice));
+            versionBuilder.setReleaseDate(getSystemData(context, CURRENT_VERSION_BUILD_DATE, knownFPDevice));
+            versionBuilder.setBetaStatus(getSystemData(context, CURRENT_BETA_STATUS, knownFPDevice));
 
-        Version versionData = UpdaterData.getInstance().getVersion(version.getImageType(), version.getNumber());
-        version.setThumbnailLink(versionData != null ? versionData.getThumbnailLink() : "");
-        version.setReleaseNotes(Locale.getDefault().getLanguage(), versionData != null ? versionData.getReleaseNotes(Locale.getDefault().getLanguage()) : "");
+            Version versionData = UpdaterData.getInstance().getVersion(versionBuilder.getImageType(), versionBuilder.getNumber());
+            versionBuilder.setThumbnailLink(versionData != null ? versionData.getThumbnailLink() : "");
+            versionBuilder.setReleaseNotes(Locale.getDefault().getLanguage(), versionData != null ? versionData.getReleaseNotes(Locale.getDefault().getLanguage()) : "");
+            version = versionBuilder;
+        }
 
         return version;
     }
diff --git a/src/com/fairphone/updater/tools/Utils.java b/src/com/fairphone/updater/tools/Utils.java
index a407c13..92abe04 100644
--- a/src/com/fairphone/updater/tools/Utils.java
+++ b/src/com/fairphone/updater/tools/Utils.java
@@ -55,9 +55,13 @@
 import java.nio.channels.FileChannel;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Scanner;
 import java.util.concurrent.TimeoutException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 public class Utils
 {
@@ -186,7 +190,7 @@
         return calculatedDigest.equalsIgnoreCase(md5);
     }
 
-    private static String calculateMD5(File updateFile)
+    public static String calculateMD5(File updateFile)
     {
         MessageDigest digest;
         try
@@ -396,47 +400,46 @@
         Version deviceVersion = VersionParserHelper.getDeviceVersion(context);
         return deviceVersion == null || TextUtils.isEmpty(deviceVersion.getName());
     }
-    
-    public static String getprop(String name, String defaultValue)
-    {
-        ProcessBuilder pb = new ProcessBuilder("/system/bin/getprop", name);
-        pb.redirectErrorStream(true);
 
-        Process p;
-        InputStream is = null;
-        try
-        {
-            p = pb.start();
-            is = p.getInputStream();
-            Scanner scan = new Scanner(is);
-            scan.useDelimiter("\n");
-            String prop = scan.next();
-            if (prop.isEmpty())
-            {
-                return defaultValue;
-            }
-            return prop;
-        } catch (NoSuchElementException e)
-        {
-            Log.d(TAG, "Error reading prop "+name+". Defaulting to " + defaultValue + ": " + e.getLocalizedMessage());
-            return defaultValue;
-        } catch (Exception e)
-        {
-            e.printStackTrace();
-        } finally
-        {
-            if (is != null)
-            {
-                try
-                {
-                    is.close();
-                } catch (Exception e)
-                {
-	                Log.d(TAG, "Unexpected issue: "+e.getLocalizedMessage() );
-                }
+    private static Map<String,String> buildProps;
+    public static Map<String,String> getpropAll(){
+
+        if(buildProps==null) {
+            buildProps = new HashMap<>();
+            ProcessBuilder pb = new ProcessBuilder("/system/bin/getprop");
+            pb.redirectErrorStream(true);
+            Pattern propRegex = Pattern.compile("\\[([^\\]]+)\\]: \\[([^\\]]+)\\]");
+
+            Process p;
+            InputStream is = null;
+            try {
+                p = pb.start();
+                is = p.getInputStream();
+                Scanner scan = new Scanner(is);
+                String prop;
+                do {
+                    prop = scan.nextLine();
+                    Matcher match = propRegex.matcher(prop);
+                    if(match.find()){
+                        buildProps.put(match.group(1), match.group(2));
+                    }
+                } while(!prop.isEmpty());
+            } catch (NoSuchElementException e) {
+            } catch (IOException e) {
             }
         }
-        return defaultValue;
+        return buildProps;
+    }
+
+    public static String getprop(String name, String defaultValue)
+    {
+        String result;
+        if (getpropAll().containsKey(name)){
+            result = getpropAll().get(name);
+        } else {
+            result = defaultValue;
+        }
+        return result;
     }
 
 	public static void setBetaPropToEnable() {