diff --git a/twinstall.cpp b/twinstall.cpp
index e1133c0..e7d23ec 100644
--- a/twinstall.cpp
+++ b/twinstall.cpp
@@ -1,18 +1,3 @@
-/*
- * Copyright (C) 2007 The Android Open Source 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.
- */
 
 #include <ctype.h>
 #include <errno.h>
@@ -25,7 +10,7 @@
 #include <string.h>
 #include <stdio.h>
 
-#include "common.h"
+#include "twcommon.h"
 #include "mincrypt/rsa.h"
 #include "mincrypt/sha.h"
 #include "minui/minui.h"
@@ -33,290 +18,150 @@
 #include "minzip/Zip.h"
 #include "mtdutils/mounts.h"
 #include "mtdutils/mtdutils.h"
-#include "roots.h"
 #include "verifier.h"
-#include "ui.h"
 #include "variables.h"
 #include "data.hpp"
 #include "partitions.hpp"
 #include "twrpDigest.hpp"
 #include "twrp-functions.hpp"
+extern "C" {
+	#include "gui/gui.h"
+}
 
-extern RecoveryUI* ui;
+static int Run_Update_Binary(const char *path, ZipArchive *Zip, int* wipe_cache) {
+	const ZipEntry* binary_location = mzFindZipEntry(Zip, ASSUMED_UPDATE_BINARY_NAME);
+	string Temp_Binary = "/tmp/updater";
+	int binary_fd, ret_val, pipe_fd[2], status, zip_verify;
+	char buffer[1024];
+	const char** args = (const char**)malloc(sizeof(char*) * 5);
+	FILE* child_data;
 
-#define ASSUMED_UPDATE_BINARY_NAME  "META-INF/com/google/android/update-binary"
-#define PUBLIC_KEYS_FILE "/res/keys"
+	if (binary_location == NULL) {
+		mzCloseZipArchive(Zip);
+		return INSTALL_CORRUPT;
+	}
 
-// Default allocation of progress bar segments to operations
-static const int VERIFICATION_PROGRESS_TIME = 60;
-static const float VERIFICATION_PROGRESS_FRACTION = 0.25;
-static const float DEFAULT_FILES_PROGRESS_FRACTION = 0.4;
-static const float DEFAULT_IMAGE_PROGRESS_FRACTION = 0.1;
+	// Delete any existing updater
+	if (TWFunc::Path_Exists(Temp_Binary) && unlink(Temp_Binary.c_str()) != 0) {
+		LOGINFO("Unable to unlink '%s'\n", Temp_Binary.c_str());
+	}
 
-enum { INSTALL_SUCCESS, INSTALL_ERROR, INSTALL_CORRUPT };
+	binary_fd = creat(Temp_Binary.c_str(), 0755);
+	if (binary_fd < 0) {
+		mzCloseZipArchive(Zip);
+		LOGERR("Could not create file for updater extract in '%s'\n", Temp_Binary.c_str());
+		return INSTALL_ERROR;
+	}
 
-// If the package contains an update binary, extract it and run it.
-static int
-try_update_binary(const char *path, ZipArchive *zip, int* wipe_cache) {
-    const ZipEntry* binary_entry =
-            mzFindZipEntry(zip, ASSUMED_UPDATE_BINARY_NAME);
-    if (binary_entry == NULL) {
-        mzCloseZipArchive(zip);
-        return INSTALL_CORRUPT;
-    }
+	ret_val = mzExtractZipEntryToFile(Zip, binary_location, binary_fd);
+	close(binary_fd);
+	mzCloseZipArchive(Zip);
 
-    const char* binary = "/tmp/update_binary";
-    unlink(binary);
-    int fd = creat(binary, 0755);
-    if (fd < 0) {
-        mzCloseZipArchive(zip);
-        LOGE("Can't make %s\n", binary);
-        return INSTALL_ERROR;
-    }
-    bool ok = mzExtractZipEntryToFile(zip, binary_entry, fd);
-    close(fd);
-    mzCloseZipArchive(zip);
+	if (!ret_val) {
+		LOGERR("Could not extract '%s'\n", ASSUMED_UPDATE_BINARY_NAME);
+		return INSTALL_ERROR;
+	}
 
-    if (!ok) {
-        LOGE("Can't copy %s\n", ASSUMED_UPDATE_BINARY_NAME);
-        return INSTALL_ERROR;
-    }
+	pipe(pipe_fd);
 
-    int pipefd[2];
-    pipe(pipefd);
+	args[0] = Temp_Binary.c_str();
+	args[1] = EXPAND(RECOVERY_API_VERSION);
+	char* temp = (char*)malloc(10);
+	sprintf(temp, "%d", pipe_fd[1]);
+	args[2] = temp;
+	args[3] = (char*)path;
+	args[4] = NULL;
 
-    // When executing the update binary contained in the package, the
-    // arguments passed are:
-    //
-    //   - the version number for this interface
-    //
-    //   - an fd to which the program can write in order to update the
-    //     progress bar.  The program can write single-line commands:
-    //
-    //        progress <frac> <secs>
-    //            fill up the next <frac> part of of the progress bar
-    //            over <secs> seconds.  If <secs> is zero, use
-    //            set_progress commands to manually control the
-    //            progress of this segment of the bar
-    //
-    //        set_progress <frac>
-    //            <frac> should be between 0.0 and 1.0; sets the
-    //            progress bar within the segment defined by the most
-    //            recent progress command.
-    //
-    //        firmware <"hboot"|"radio"> <filename>
-    //            arrange to install the contents of <filename> in the
-    //            given partition on reboot.
-    //
-    //            (API v2: <filename> may start with "PACKAGE:" to
-    //            indicate taking a file from the OTA package.)
-    //
-    //            (API v3: this command no longer exists.)
-    //
-    //        ui_print <string>
-    //            display <string> on the screen.
-    //
-    //   - the name of the package zip file.
-    //
+	pid_t pid = fork();
+	if (pid == 0) {
+		close(pipe_fd[0]);
+		execv(Temp_Binary.c_str(), (char* const*)args);
+		printf("E:Can't execute '%s'\n", Temp_Binary.c_str());
+		_exit(-1);
+	}
+	close(pipe_fd[1]);
 
-    const char** args = (const char**)malloc(sizeof(char*) * 5);
-    args[0] = binary;
-    args[1] = EXPAND(RECOVERY_API_VERSION);   // defined in Android.mk
-    char* temp = (char*)malloc(10);
-    sprintf(temp, "%d", pipefd[1]);
-    args[2] = temp;
-    args[3] = (char*)path;
-    args[4] = NULL;
+	*wipe_cache = 0;
 
-    pid_t pid = fork();
-    if (pid == 0) {
-        close(pipefd[0]);
-        execv(binary, (char* const*)args);
-        fprintf(stdout, "E:Can't run %s (%s)\n", binary, strerror(errno));
-        _exit(-1);
-    }
-    close(pipefd[1]);
-
-    *wipe_cache = 0;
-
-    char buffer[1024];
-    FILE* from_child = fdopen(pipefd[0], "r");
-    while (fgets(buffer, sizeof(buffer), from_child) != NULL) {
-        char* command = strtok(buffer, " \n");
+	DataManager::GetValue(TW_SIGNED_ZIP_VERIFY_VAR, zip_verify);
+	child_data = fdopen(pipe_fd[0], "r");
+	while (fgets(buffer, sizeof(buffer), child_data) != NULL) {
+		char* command = strtok(buffer, " \n");
         if (command == NULL) {
             continue;
         } else if (strcmp(command, "progress") == 0) {
-            char* fraction_s = strtok(NULL, " \n");
-            char* seconds_s = strtok(NULL, " \n");
+            char* fraction_char = strtok(NULL, " \n");
+            char* seconds_char = strtok(NULL, " \n");
 
-            float fraction = strtof(fraction_s, NULL);
-            int seconds = strtol(seconds_s, NULL, 10);
+            float fraction_float = strtof(fraction_char, NULL);
+            int seconds_float = strtol(seconds_char, NULL, 10);
 
-            ui->ShowProgress(fraction * (1-VERIFICATION_PROGRESS_FRACTION), seconds);
+            if (zip_verify)
+				DataManager::ShowProgress(fraction_float * (1 - VERIFICATION_PROGRESS_FRACTION), seconds_float);
+			else
+				DataManager::ShowProgress(fraction_float, seconds_float);
         } else if (strcmp(command, "set_progress") == 0) {
-            char* fraction_s = strtok(NULL, " \n");
-            float fraction = strtof(fraction_s, NULL);
-            ui->SetProgress(fraction);
+            char* fraction_char = strtok(NULL, " \n");
+            float fraction_float = strtof(fraction_char, NULL);
+            DataManager::SetProgress(fraction_float);
         } else if (strcmp(command, "ui_print") == 0) {
-            char* str = strtok(NULL, "\n");
-            if (str) {
-                ui->Print("%s", str);
+            char* display_value = strtok(NULL, "\n");
+            if (display_value) {
+                gui_print("%s", display_value);
             } else {
-                ui->Print("\n");
+                gui_print("\n");
             }
         } else if (strcmp(command, "wipe_cache") == 0) {
             *wipe_cache = 1;
         } else if (strcmp(command, "clear_display") == 0) {
-            //ui->SetBackground(RecoveryUI::NONE);
+            // Do nothing, not supported by TWRP
         } else {
-            LOGE("unknown command [%s]\n", command);
+            LOGERR("unknown command [%s]\n", command);
         }
-    }
-    fclose(from_child);
+	}
+	fclose(child_data);
 
-    int status;
-    waitpid(pid, &status, 0);
-    if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
-        LOGE("Error in %s\n(Status %d)\n", path, WEXITSTATUS(status));
-        return INSTALL_ERROR;
-    }
+	waitpid(pid, &status, 0);
+	if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
+		LOGERR("Error executing updater binary in zip '%s'\n", path);
+		return INSTALL_ERROR;
+	}
 
-    return INSTALL_SUCCESS;
-}
-
-// Reads a file containing one or more public keys as produced by
-// DumpPublicKey:  this is an RSAPublicKey struct as it would appear
-// as a C source literal, eg:
-//
-//  "{64,0xc926ad21,{1795090719,...,-695002876},{-857949815,...,1175080310}}"
-//
-// (Note that the braces and commas in this example are actual
-// characters the parser expects to find in the file; the ellipses
-// indicate more numbers omitted from this example.)
-//
-// The file may contain multiple keys in this format, separated by
-// commas.  The last key must not be followed by a comma.
-//
-// Returns NULL if the file failed to parse, or if it contain zero keys.
-static RSAPublicKey*
-load_keys(const char* filename, int* numKeys) {
-    RSAPublicKey* out = NULL;
-    *numKeys = 0;
-
-    FILE* f = fopen(filename, "r");
-    if (f == NULL) {
-        LOGE("opening %s: %s\n", filename, strerror(errno));
-        goto exit;
-    }
-
-    {
-        int i;
-        bool done = false;
-        while (!done) {
-            ++*numKeys;
-            out = (RSAPublicKey*)realloc(out, *numKeys * sizeof(RSAPublicKey));
-            RSAPublicKey* key = out + (*numKeys - 1);
-            if (fscanf(f, " { %i , 0x%x , { %u",
-                       &(key->len), &(key->n0inv), &(key->n[0])) != 3) {
-                goto exit;
-            }
-            if (key->len != RSANUMWORDS) {
-                LOGE("key length (%d) does not match expected size\n", key->len);
-                goto exit;
-            }
-            for (i = 1; i < key->len; ++i) {
-                if (fscanf(f, " , %u", &(key->n[i])) != 1) goto exit;
-            }
-            if (fscanf(f, " } , { %u", &(key->rr[0])) != 1) goto exit;
-            for (i = 1; i < key->len; ++i) {
-                if (fscanf(f, " , %u", &(key->rr[i])) != 1) goto exit;
-            }
-            fscanf(f, " } } ");
-
-            // if the line ends in a comma, this file has more keys.
-            switch (fgetc(f)) {
-            case ',':
-                // more keys to come.
-                break;
-
-            case EOF:
-                done = true;
-                break;
-
-            default:
-                LOGE("unexpected character between keys\n");
-                goto exit;
-            }
-        }
-    }
-
-    fclose(f);
-    return out;
-
-exit:
-    if (f) fclose(f);
-    free(out);
-    *numKeys = 0;
-    return NULL;
+	return INSTALL_SUCCESS;
 }
 
 extern "C" int TWinstall_zip(const char* path, int* wipe_cache) {
-	int err, zip_verify, md5_return;
+	int ret_val, zip_verify, md5_return, key_count;
 	twrpDigest md5sum;
 	string strpath = path;
-	ui_print("Installing '%s'...\n", path);
+	ZipArchive Zip;
 
-	if (!PartitionManager.Mount_By_Path(path, 0)) {
-		LOGE("Failed to mount '%s'\n", path);
-		return -1;
-	}
-
-	ui_print("Checking for MD5 file...\n");
+	gui_print("Installing '%s'...\nChecking for MD5 file...\n", path);
 	md5sum.setfn(strpath);
 	md5_return = md5sum.verify_md5digest();
 	if (md5_return == -2) {
 		// MD5 did not match.
-		LOGE("Zip MD5 does not match.\nUnable to install zip.\n");
+		LOGERR("Zip MD5 does not match.\nUnable to install zip.\n");
 		return INSTALL_CORRUPT;
 	} else if (md5_return == -1) {
-		ui_print("Skipping MD5 check: no MD5 file found.\n");
+		gui_print("Skipping MD5 check: no MD5 file found.\n");
 	} else if (md5_return == 0)
-		ui_print("Zip MD5 matched.\n"); // MD5 found and matched.
+		gui_print("Zip MD5 matched.\n"); // MD5 found and matched.
 
 	DataManager::GetValue(TW_SIGNED_ZIP_VERIFY_VAR, zip_verify);
+	DataManager::SetProgress(0);
 	if (zip_verify) {
-		ui_print("Verifying zip signature...\n");
-		int numKeys;
-		RSAPublicKey* loadedKeys = load_keys(PUBLIC_KEYS_FILE, &numKeys);
-		if (loadedKeys == NULL) {
-			LOGE("Failed to load keys\n");
-			return -1;
-		}
-		LOGI("%d key(s) loaded from %s\n", numKeys, PUBLIC_KEYS_FILE);
-
-		// Give verification half the progress bar...
-		ui->Print("Verifying update package...\n");
-		ui->SetProgressType(RecoveryUI::DETERMINATE);
-		ui->ShowProgress(VERIFICATION_PROGRESS_FRACTION, VERIFICATION_PROGRESS_TIME);
-
-		err = verify_file(path, loadedKeys, numKeys);
-		free(loadedKeys);
-		LOGI("verify_file returned %d\n", err);
-		if (err != VERIFY_SUCCESS) {
-			LOGE("signature verification failed\n");
+		gui_print("Verifying zip signature...\n");
+		ret_val = verify_file(path);
+		if (ret_val != VERIFY_SUCCESS) {
+			LOGERR("Zip signature verification failed: %i\n", ret_val);
 			return -1;
 		}
 	}
-	/* Try to open the package.
-     */
-    ZipArchive zip;
-    err = mzOpenZipArchive(path, &zip);
-    if (err != 0) {
-        LOGE("Can't open %s\n(%s)\n", path, err != -1 ? strerror(err) : "bad");
-        return INSTALL_CORRUPT;
-    }
-
-    /* Verify and install the contents of the package.
-     */
-    return try_update_binary(path, &zip, wipe_cache);
+	ret_val = mzOpenZipArchive(path, &Zip);
+	if (ret_val != 0) {
+		LOGERR("Zip file is corrupt!\n", path);
+		return INSTALL_CORRUPT;
+	}
+	return Run_Update_Binary(path, &Zip, wipe_cache);
 }
