working recovery image!
diff --git a/default_recovery_ui.c b/default_recovery_ui.c
index 025ee98..3514477 100644
--- a/default_recovery_ui.c
+++ b/default_recovery_ui.c
@@ -27,6 +27,7 @@
                        "apply sdcard:update.zip",
                        "wipe data/factory reset",
                        "wipe cache partition",
+                       "install zip from sdcard",
                        "toggle signature verification",
                        "toggle script asserts",
                        NULL };
@@ -56,6 +57,9 @@
             case KEY_ENTER:
             case BTN_MOUSE:
                 return SELECT_ITEM;
+            case KEY_BACKSPACE:
+            case KEY_END:
+                return GO_BACK;
         }
     }
 
diff --git a/extendedcommands.c b/extendedcommands.c
index b2aacc9..4ef23f7 100644
--- a/extendedcommands.c
+++ b/extendedcommands.c
@@ -12,6 +12,10 @@
 #include <time.h>
 #include <unistd.h>
 
+#include <sys/wait.h>
+#include <sys/limits.h>
+#include <dirent.h>
+
 #include "bootloader.h"
 #include "common.h"
 #include "cutils/properties.h"
@@ -35,5 +39,100 @@
 void toggle_script_asserts()
 {
     script_assert_enabled = !script_assert_enabled;
-    ui_print("Script Asserts: %s\n", signature_check_enabled ? "Enabled" : "Disabled");
+    ui_print("Script Asserts: %s\n", script_assert_enabled ? "Enabled" : "Disabled");
+}
+
+void show_choose_zip_menu()
+{
+    static char* headers[] = { "Choose a zip or press POWER to return",
+			       "",
+			       NULL };
+    
+    char path[PATH_MAX] = "";
+    DIR *dir;
+    struct dirent *de;
+    int total = 0;
+    int i;
+    char** files;
+    char** list;
+
+    if (ensure_root_path_mounted("SDCARD:") != 0) {
+        LOGE ("Can't mount /sdcard\n");
+        return;
+    }
+
+    dir = opendir("/sdcard");
+    if (dir == NULL) {
+        LOGE("Couldn't open /sdcard");
+        return;
+    }
+    
+    const char *extension = ".zip";
+    const int extension_length = strlen(extension);
+    
+    while ((de=readdir(dir)) != NULL) {
+        if (de->d_name[0] != '.' && strlen(de->d_name) > extension_length && strcmp(de->d_name + strlen(de->d_name) - extension_length, extension) == 0) {
+            total++;
+	      }
+    }
+
+    if (total==0) {
+        LOGE("No tar archives found\n");
+        if(closedir(dir) < 0) {
+            LOGE("Failed to close directory /sdcard");
+            return;
+	      }
+    }
+    else {
+        files = (char**) malloc((total+1)*sizeof(char*));
+        files[total]=NULL;
+
+        list = (char**) malloc((total+1)*sizeof(char*));
+        list[total]=NULL;
+	
+        rewinddir(dir);
+
+        i = 0;
+        while ((de = readdir(dir)) != NULL) {
+            if (de->d_name[0] != '.' && strlen(de->d_name) > extension_length && strcmp(de->d_name + strlen(de->d_name) - extension_length, extension) == 0) {
+                files[i] = (char*) malloc(strlen("/sdcard/")+strlen(de->d_name)+1);
+                strcpy(files[i], "/sdcard/");
+                strcat(files[i], de->d_name);
+
+                list[i] = (char*) malloc(strlen(de->d_name)+1);
+                strcpy(list[i], de->d_name);
+
+                i++;
+            }
+        }
+
+        if (closedir(dir) <0) {
+            LOGE("Failure closing directory /sdcard\n");
+            return;
+        }
+
+        int chosen_item = get_menu_selection(headers, list, 1);
+        if (chosen_item >= 0 && chosen_item != GO_BACK) {
+          char sdcard_package_file[1024];
+          strcpy(sdcard_package_file, "SDCARD:");
+          strcat(sdcard_package_file, files[chosen_item] + strlen("/sdcard"));
+
+          ui_print("\n-- Install from sdcard...\n");
+          set_sdcard_update_bootloader_message();
+          int status = install_package(sdcard_package_file);
+          if (status != INSTALL_SUCCESS) {
+              ui_set_background(BACKGROUND_ICON_ERROR);
+              ui_print("Installation aborted.\n");
+          } else if (!ui_text_visible()) {
+              return;  // reboot if logs aren't visible
+          } else {
+              if (firmware_update_pending()) {
+                  ui_print("\nReboot via menu to complete\n"
+                           "installation.\n");
+              } else {
+                  ui_print("\nInstall from sdcard complete.\n");
+              }
+          }
+        }
+    }
 }
\ No newline at end of file
diff --git a/extendedcommands.h b/extendedcommands.h
index 5b82960..a4d4992 100644
--- a/extendedcommands.h
+++ b/extendedcommands.h
@@ -2,4 +2,10 @@
 extern int script_assert_enabled;
 
 void
-toggle_signature_check();
\ No newline at end of file
+toggle_signature_check();
+
+void
+toggle_script_asserts();
+
+void
+show_choose_zip_menu();
\ No newline at end of file
diff --git a/install.c b/install.c
index 3a37b4a..5768960 100644
--- a/install.c
+++ b/install.c
@@ -106,7 +106,7 @@
     const ZipEntry* binary_entry =
             mzFindZipEntry(zip, ASSUMED_UPDATE_BINARY_NAME);
     if (binary_entry == NULL) {
-        return INSTALL_UPDATE_BINARY_MISSING;
+        return INSTALL_ERROR;
     }
 
     char* binary = "/tmp/update_binary";
@@ -242,17 +242,21 @@
     // Update should take the rest of the progress bar.
     ui_print("Installing update...\n");
 
-    int result = try_update_binary(path, zip);
-    if (result == INSTALL_UPDATE_BINARY_MISSING)
-    {
-        if (register_package_root(zip, path) < 0) {
-            LOGE("Can't register package root\n");
-            return INSTALL_ERROR;
-        }
-        const ZipEntry *script_entry;
-        script_entry = find_update_script(zip);
-        result = handle_update_script(zip, script_entry);
+    // Try installing via the update-script first, because we 
+    // have more control over the asserts it may contain.
+    // If it does not exist, try the update-binary.
+    if (register_package_root(zip, path) < 0) {
+        LOGE("Can't register package root\n");
+        return INSTALL_ERROR;
     }
+    const ZipEntry *script_entry;
+    script_entry = find_update_script(zip);
+    int result = handle_update_script(zip, script_entry);
+    if (result == INSTALL_UPDATE_SCRIPT_MISSING)
+    {
+        result = try_update_binary(path, zip);
+    }
+    
     register_package_root(NULL, NULL);  // Unregister package root
     return result;
 }
diff --git a/install.h b/install.h
index 42c1444..3ee814b 100644
--- a/install.h
+++ b/install.h
@@ -19,7 +19,7 @@
 
 #include "common.h"
 
-enum { INSTALL_SUCCESS, INSTALL_ERROR, INSTALL_CORRUPT, INSTALL_UPDATE_BINARY_MISSING };
+enum { INSTALL_SUCCESS, INSTALL_ERROR, INSTALL_CORRUPT, INSTALL_UPDATE_SCRIPT_MISSING };
 int install_package(const char *root_path);
 
 #endif  // RECOVERY_INSTALL_H_
diff --git a/legacy.c b/legacy.c
index dab06ad..cf903ce 100644
--- a/legacy.c
+++ b/legacy.c
@@ -90,7 +90,7 @@
     char* script_data;
     if (read_data(zip, update_script_entry, &script_data, &script_len) < 0) {
         LOGE("Can't read update script\n");
-        return INSTALL_ERROR;
+        return INSTALL_UPDATE_SCRIPT_MISSING;
     }
 
     /* Parse the script.  Note that the script and parse tree are never freed.
diff --git a/recovery.c b/recovery.c
index b857610..7a12e10 100644
--- a/recovery.c
+++ b/recovery.c
@@ -212,7 +212,7 @@
     set_bootloader_message(&boot);
 }
 
-static void
+void
 set_sdcard_update_bootloader_message()
 {
     struct bootloader_message boot;
@@ -303,7 +303,7 @@
     return new_headers;
 }
 
-static int
+int
 get_menu_selection(char** headers, char** items, int menu_only) {
     // throw away keys pressed previously, so user doesn't
     // accidentally trigger menu items.
@@ -334,6 +334,8 @@
                     break;
                 case NO_ACTION:
                     break;
+                case GO_BACK:
+                    return GO_BACK;
             }
         } else if (!menu_only) {
             chosen_item = action;
@@ -439,6 +441,9 @@
             case ITEM_ASSERTS:
                 toggle_script_asserts();
                 break;
+            case ITEM_INSTALL_ZIP:
+                show_choose_zip_menu();
+                break;
         }
     }
 }
diff --git a/recovery_ui.h b/recovery_ui.h
index 1aabbdf..4d3d3e2 100644
--- a/recovery_ui.h
+++ b/recovery_ui.h
@@ -61,13 +61,15 @@
 #define HIGHLIGHT_UP        -2
 #define HIGHLIGHT_DOWN      -3
 #define SELECT_ITEM         -4
+#define GO_BACK             -5
 
 #define ITEM_REBOOT          0
 #define ITEM_APPLY_SDCARD    1
 #define ITEM_WIPE_DATA       2
 #define ITEM_WIPE_CACHE      3
-#define ITEM_SIG_CHECK       4
-#define ITEM_ASSERTS         5
+#define ITEM_INSTALL_ZIP     4
+#define ITEM_SIG_CHECK       5
+#define ITEM_ASSERTS         6
 
 // Header text to display above the main menu.
 extern char* MENU_HEADERS[];
@@ -75,4 +77,10 @@
 // Text of menu items.
 extern char* MENU_ITEMS[];
 
+int
+get_menu_selection(char** headers, char** items, int menu_only);
+
+void
+set_sdcard_update_bootloader_message();
+
 #endif