]> git.saurik.com Git - cydia.git/blobdiff - Cydia.mm
Commit (chpwn): good-bye-uiactionsheet.patch
[cydia.git] / Cydia.mm
index f00d4d71a6b3014e48e5a01e7cc6e6aaee3c8529..f792200194afb041200d02057256f2b9cb03becd 100644 (file)
--- a/Cydia.mm
+++ b/Cydia.mm
@@ -1,5 +1,5 @@
 /* Cydia - iPhone UIKit Front-End for Debian APT
- * Copyright (C) 2008-2009  Jay Freeman (saurik)
+ * Copyright (C) 2008-2010  Jay Freeman (saurik)
 */
 
 /* Modified BSD License {{{ */
@@ -44,7 +44,6 @@
 #import "UICaboodle/UCPlatform.h"
 #import "UICaboodle/UCLocalize.h"
 
-#include <objc/message.h>
 #include <objc/objc.h>
 #include <objc/runtime.h>
 
@@ -73,6 +72,8 @@
 
 #include <ext/stdio_filebuf.h>
 
+#undef ABS
+
 #include <apt-pkg/acquire.h>
 #include <apt-pkg/acquire-item.h>
 #include <apt-pkg/algorithms.h>
@@ -190,59 +191,11 @@ void PrintTimes() {
 
 #define _end }
 /* }}} */
-/* Objective-C Handle<> {{{ */
-template <typename Type_>
-class _H {
-    typedef _H<Type_> This_;
-
-  private:
-    Type_ *value_;
-
-    _finline void Retain_() {
-        if (value_ != nil)
-            [value_ retain];
-    }
-
-    _finline void Clear_() {
-        if (value_ != nil)
-            [value_ release];
-    }
-
-  public:
-    _finline _H(const This_ &rhs) :
-        value_(rhs.value_ == nil ? nil : [rhs.value_ retain])
-    {
-    }
-
-    _finline _H(Type_ *value = NULL, bool mended = false) :
-        value_(value)
-    {
-        if (!mended)
-            Retain_();
-    }
-
-    _finline ~_H() {
-        Clear_();
-    }
-
-    _finline operator Type_ *() const {
-        return value_;
-    }
-
-    _finline This_ &operator =(Type_ *value) {
-        if (value_ != value) {
-            Type_ *old(value_);
-            value_ = value;
-            Retain_();
-            if (old != nil)
-                [old release];
-        } return *this;
-    }
-};
-/* }}} */
 
 #define _pooled _H<NSAutoreleasePool> _pool([[NSAutoreleasePool alloc] init], true);
 
+static const NSUInteger UIViewAutoresizingFlexibleBoth(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
+
 void NSLogPoint(const char *fix, const CGPoint &point) {
     NSLog(@"%s(%g,%g)", fix, point.x, point.y);
 }
@@ -251,6 +204,16 @@ void NSLogRect(const char *fix, const CGRect &rect) {
     NSLog(@"%s(%g,%g)+(%g,%g)", fix, rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
 }
 
+static _finline NSString *CydiaURL(NSString *path) {
+    char page[25];
+    page[0] = 'h'; page[1] = 't'; page[2] = 't'; page[3] = 'p'; page[4] = ':';
+    page[5] = '/'; page[6] = '/'; page[7] = 'c'; page[8] = 'y'; page[9] = 'd';
+    page[10] = 'i'; page[11] = 'a'; page[12] = '.'; page[13] = 's'; page[14] = 'a';
+    page[15] = 'u'; page[16] = 'r'; page[17] = 'i'; page[18] = 'k'; page[19] = '.';
+    page[20] = 'c'; page[21] = 'o'; page[22] = 'm'; page[23] = '/'; page[24] = '\0';
+    return [[NSString stringWithUTF8String:page] stringByAppendingString:path];
+}
+
 /* [NSObject yieldToSelector:(withObject:)] {{{*/
 @interface NSObject (Cydia)
 - (id) yieldToSelector:(SEL)selector withObject:(id)object;
@@ -318,26 +281,47 @@ void NSLogRect(const char *fix, const CGRect &rect) {
 @end
 /* }}} */
 
-/* NSForcedOrderingSearch doesn't work on the iPhone */
-static const NSStringCompareOptions MatchCompareOptions_ = NSLiteralSearch | NSCaseInsensitiveSearch;
-static const NSStringCompareOptions LaxCompareOptions_ = NSNumericSearch | NSDiacriticInsensitiveSearch | NSWidthInsensitiveSearch | NSCaseInsensitiveSearch;
-static const CFStringCompareFlags LaxCompareFlags_ = kCFCompareCaseInsensitive | kCFCompareNonliteral | kCFCompareLocalized | kCFCompareNumerically | kCFCompareWidthInsensitive | kCFCompareForcedOrdering;
+@interface CYActionSheet : UIAlertView {
+    unsigned button_;
+}
 
-/* iPhoneOS 2.0 Compatibility {{{ */
-#ifdef __OBJC2__
-@interface UITextView (iPhoneOS)
-- (void) setTextSize:(float)size;
+- (int) yieldToPopupAlertAnimated:(BOOL)animated;
 @end
 
-@implementation UITextView (iPhoneOS)
+@implementation CYActionSheet
+
+- (id) initWithTitle:(NSString *)title buttons:(NSArray *)buttons defaultButtonIndex:(int)index {
+    if ((self = [super init])) {
+               [self setTitle:title];
+               [self setDelegate:self];
+               for (NSString *button in buttons) [self addButtonWithTitle:button];
+               [self setCancelButtonIndex:index];
+    } return self;
+}
+
+- (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
+    button_ = buttonIndex + 1;
+}
+
+- (void) dismiss {
+       [self dismissWithClickedButtonIndex:-1 animated:YES];
+}
 
-- (void) setTextSize:(float)size {
-    [self setFont:[[self font] fontWithSize:size]];
+- (int) yieldToPopupAlertAnimated:(BOOL)animated {
+    button_ = 0;
+    [self show];
+    NSRunLoop *loop([NSRunLoop currentRunLoop]);
+    NSDate *future([NSDate distantFuture]);
+    while (button_ == 0 && [loop runMode:NSDefaultRunLoopMode beforeDate:future]);
+    return button_;
 }
 
 @end
-#endif
-/* }}} */
+
+/* NSForcedOrderingSearch doesn't work on the iPhone */
+static const NSStringCompareOptions MatchCompareOptions_ = NSLiteralSearch | NSCaseInsensitiveSearch;
+static const NSStringCompareOptions LaxCompareOptions_ = NSNumericSearch | NSDiacriticInsensitiveSearch | NSWidthInsensitiveSearch | NSCaseInsensitiveSearch;
+static const CFStringCompareFlags LaxCompareFlags_ = kCFCompareCaseInsensitive | kCFCompareNonliteral | kCFCompareLocalized | kCFCompareNumerically | kCFCompareWidthInsensitive | kCFCompareForcedOrdering;
 
 /* Information Dictionaries {{{ */
 @interface NSMutableArray (Cydia)
@@ -387,10 +371,14 @@ static const CFStringCompareFlags LaxCompareFlags_ = kCFCompareCaseInsensitive |
 
 - (void) popSubview:(UIView *)view {
     UITransitionView *transition([[[PopTransitionView alloc] initWithFrame:[self bounds]] autorelease]);
-    [transition setDelegate:transition];
+    [transition setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];
     [self addSubview:transition];
 
-    UIView *blank = [[[UIView alloc] initWithFrame:[transition bounds]] autorelease];
+    [transition setDelegate:transition];
+
+    UIView *blank([[[UIView alloc] initWithFrame:[transition bounds]] autorelease]);
+    [blank setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];
+
     [transition transition:UITransitionNone toView:blank];
     [transition transition:UITransitionPushFromBottom toView:view];
 }
@@ -405,14 +393,14 @@ static const CFStringCompareFlags LaxCompareFlags_ = kCFCompareCaseInsensitive |
 #define HistogramInsertionSort (0 && !ForRelease)
 #define ProfileTimes (0 && !ForRelease)
 #define ForSaurik (0 && !ForRelease)
-#define LogBrowser (1 && !ForRelease)
+#define LogBrowser (0 && !ForRelease)
 #define TrackResize (0 && !ForRelease)
-#define ManualRefresh (1 && !ForRelease)
+#define ManualRefresh (0 && !ForRelease)
 #define ShowInternals (0 && !ForRelease)
 #define IgnoreInstall (0 && !ForRelease)
 #define RecycleWebViews 0
-#define RecyclePackageViews 1
-#define AlwaysReload (0 && !ForRelease)
+#define RecyclePackageViews (1 && ForRelease)
+#define AlwaysReload (1 && !ForRelease)
 
 #if !TraceLogging
 #undef _trace
@@ -645,6 +633,19 @@ void CFArrayInsertionSortValues(CFMutableArrayRef array, CFRange range, CFCompar
 @end
 /* }}} */
 
+NSUInteger WebScriptObject$countByEnumeratingWithState$objects$count$(WebScriptObject *self, SEL sel, NSFastEnumerationState *state, id *objects, NSUInteger count) {
+    size_t length([self count] - state->state);
+    if (length <= 0)
+        return 0;
+    else if (length > count)
+        length = count;
+    for (size_t i(0); i != length; ++i)
+        objects[i] = [self objectAtIndex:state->state++];
+    state->itemsPtr = objects;
+    state->mutationsPtr = (unsigned long *) self;
+    return length;
+}
+
 NSUInteger DOMNodeList$countByEnumeratingWithState$objects$count$(DOMNodeList *self, SEL sel, NSFastEnumerationState *state, id *objects, NSUInteger count) {
     size_t length([self length] - state->state);
     if (length <= 0)
@@ -720,11 +721,8 @@ NSUInteger DOMNodeList$countByEnumeratingWithState$objects$count$(DOMNodeList *s
 
 - (NSString *) stringByCachingURLWithCurrentCDN {
     return [self
-        stringByReplacingOccurrencesOfString:@"://"
-        withString:@"://ne.edgecastcdn.net/8003A4/"
-        options:0
-        /* XXX: this is somewhat inaccurate */
-        range:NSMakeRange(0, 10)
+        stringByReplacingOccurrencesOfString:@"://cydia.saurik.com/"
+        withString:@"://cache.cydia.saurik.com/"
     ];
 }
 
@@ -825,6 +823,8 @@ class CYString {
             if (size_ == 0)
                 return nil;
             cache_ = CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<uint8_t *>(data_), size_, kCFStringEncodingUTF8, NO, kCFAllocatorNull);
+            if (cache_ == NULL)
+                cache_ = CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<uint8_t *>(data_), size_, kCFStringEncodingISOLatin1, NO, kCFAllocatorNull);
         } return cache_;
     }
 
@@ -1027,9 +1027,13 @@ class CGColor {
 
 /* Random Global Variables {{{ */
 static const int PulseInterval_ = 50000;
+static const int ButtonBarWidth_ = 60;
 static const int ButtonBarHeight_ = 48;
 static const float KeyboardTime_ = 0.3f;
 
+static int Finish_;
+static NSArray *Finishes_;
+
 #define SpringBoard_ "/System/Library/LaunchDaemons/com.apple.SpringBoard.plist"
 #define NotifyConfig_ "/etc/notify.conf"
 
@@ -1052,7 +1056,6 @@ static NSString *App_;
 static NSString *Home_;
 
 static BOOL Advanced_;
-static BOOL Loaded_;
 static BOOL Ignored_;
 
 static UIFont *Font12_;
@@ -1065,17 +1068,17 @@ static const char *Machine_ = NULL;
 static const NSString *System_ = NULL;
 static const NSString *SerialNumber_ = nil;
 static const NSString *ChipID_ = nil;
+static const NSString *Token_ = nil;
 static const NSString *UniqueID_ = nil;
 static const NSString *Build_ = nil;
 static const NSString *Product_ = nil;
 static const NSString *Safari_ = nil;
 
-CFLocaleRef Locale_;
-NSArray *Languages_;
-CGColorSpaceRef space_;
+static CFLocaleRef Locale_;
+static NSArray *Languages_;
+static CGColorSpaceRef space_;
 
-bool bootstrap_;
-bool reload_;
+static bool reload_;
 
 static NSDictionary *SectionMap_;
 static NSMutableDictionary *Metadata_;
@@ -1087,24 +1090,13 @@ static _transient NSMutableDictionary *Sources_;
 static bool Changed_;
 static NSDate *now_;
 
+static bool IsWildcat_;
+
 #if RecycleWebViews
 static NSMutableArray *Documents_;
 #endif
-
-NSString *GetLastUpdate() {
-    NSDate *update = [Metadata_ objectForKey:@"LastUpdate"];
-
-    if (update == nil)
-        return UCLocalize("NEVER_OR_UNKNOWN");
-
-    CFDateFormatterRef formatter = CFDateFormatterCreate(NULL, Locale_, kCFDateFormatterMediumStyle, kCFDateFormatterMediumStyle);
-    CFStringRef formatted = CFDateFormatterCreateStringWithDate(NULL, formatter, (CFDateRef) update);
-
-    CFRelease(formatter);
-
-    return [(NSString *) formatted autorelease];
-}
 /* }}} */
+
 /* Display Helpers {{{ */
 inline float Interpolate(float begin, float end, float fraction) {
     return (end - begin) * fraction + begin;
@@ -1182,15 +1174,26 @@ NSString *Simplify(NSString *title) {
 }
 /* }}} */
 
+NSString *GetLastUpdate() {
+    NSDate *update = [Metadata_ objectForKey:@"LastUpdate"];
+
+    if (update == nil)
+        return UCLocalize("NEVER_OR_UNKNOWN");
+
+    CFDateFormatterRef formatter = CFDateFormatterCreate(NULL, Locale_, kCFDateFormatterMediumStyle, kCFDateFormatterMediumStyle);
+    CFStringRef formatted = CFDateFormatterCreateStringWithDate(NULL, formatter, (CFDateRef) update);
+
+    CFRelease(formatter);
+
+    return [(NSString *) formatted autorelease];
+}
+
 bool isSectionVisible(NSString *section) {
     NSDictionary *metadata([Sections_ objectForKey:section]);
     NSNumber *hidden(metadata == nil ? nil : [metadata objectForKey:@"Hidden"]);
     return hidden == nil || ![hidden boolValue];
 }
 
-static int Finish_;
-static NSArray *Finishes_;
-
 /* Delegate Prototypes {{{ */
 @class Package;
 @class Source;
@@ -1198,19 +1201,8 @@ static NSArray *Finishes_;
 @interface NSObject (ProgressDelegate)
 @end
 
-@implementation NSObject(ProgressDelegate)
-
-- (void) _setProgressError:(NSArray *)args {
-    [self performSelector:@selector(setProgressError:forPackage:)
-        withObject:[args objectAtIndex:0]
-        withObject:([args count] == 1 ? nil : [args objectAtIndex:1])
-    ];
-}
-
-@end
-
 @protocol ProgressDelegate
-- (void) setProgressError:(NSString *)error forPackage:(NSString *)id;
+- (void) setProgressError:(NSString *)error withTitle:(NSString *)id;
 - (void) setProgressTitle:(NSString *)title;
 - (void) setProgressPercent:(float)percent;
 - (void) startProgress;
@@ -1229,6 +1221,7 @@ static NSArray *Finishes_;
 - (void) setPackageView:(PackageView *)view;
 - (void) clearPackage:(Package *)package;
 - (void) installPackage:(Package *)package;
+- (void) installPackages:(NSArray *)packages;
 - (void) removePackage:(Package *)package;
 - (void) slideUp:(UIActionSheet *)alert;
 - (void) distUpgrade;
@@ -1259,6 +1252,10 @@ class Status :
         delegate_ = delegate;
     }
 
+    NSObject<ProgressDelegate> *getDelegate() const {
+        return delegate_;
+    }
+
     virtual bool MediaChange(std::string media, std::string drive) {
         return false;
     }
@@ -1268,7 +1265,7 @@ class Status :
 
     virtual void Fetch(pkgAcquire::ItemDesc &item) {
         //NSString *name([NSString stringWithUTF8String:item.ShortDesc.c_str()]);
-        [delegate_ setProgressTitle:[NSString stringWithFormat:UCLocalize("DOWNLOADING"), [NSString stringWithUTF8String:item.ShortDesc.c_str()]]];
+        [delegate_ setProgressTitle:[NSString stringWithFormat:UCLocalize("DOWNLOADING_"), [NSString stringWithUTF8String:item.ShortDesc.c_str()]]];
     }
 
     virtual void Done(pkgAcquire::ItemDesc &item) {
@@ -1289,7 +1286,7 @@ class Status :
         NSArray *fields([description componentsSeparatedByString:@" "]);
         NSString *source([fields count] == 0 ? nil : [fields objectAtIndex:0]);
 
-        [delegate_ performSelectorOnMainThread:@selector(_setProgressError:)
+        [delegate_ performSelectorOnMainThread:@selector(_setProgressErrorPackage:)
             withObject:[NSArray arrayWithObjects:
                 [NSString stringWithUTF8String:error.c_str()],
                 source,
@@ -1328,10 +1325,10 @@ class Progress :
 
   protected:
     virtual void Update() {
-        if (abs(Percent - percent_) > 2) {
-            NSLog(@"%s:%s:%f", Op.c_str(), SubOp.c_str(), Percent);
+        /*if (abs(Percent - percent_) > 2)
+            //NSLog(@"%s:%s:%f", Op.c_str(), SubOp.c_str(), Percent);
             percent_ = Percent;
-        }
+        }*/
 
         /*[delegate_ setProgressTitle:[NSString stringWithUTF8String:Op.c_str()]];
         [delegate_ setProgressPercent:(Percent / 100)];*/
@@ -1348,8 +1345,12 @@ class Progress :
         delegate_ = delegate;
     }
 
+    id getDelegate() const {
+        return delegate_;
+    }
+
     virtual void Done() {
-        NSLog(@"DONE");
+        //NSLog(@"DONE");
         //[delegate_ setProgressPercent:1];
     }
 };
@@ -1407,17 +1408,49 @@ typedef std::map< unsigned long, _H<Source> > SourceMap;
 - (void) reloadData;
 
 - (void) configure;
-- (void) prepare;
+- (bool) prepare;
 - (void) perform;
-- (void) upgrade;
+- (bool) upgrade;
 - (void) update;
 
 - (void) setVisible;
 
-- (NSString *) updateWithStatus:(Status &)status;
+- (void) updateWithStatus:(Status &)status;
 
 - (void) setDelegate:(id)delegate;
 - (Source *) getSource:(pkgCache::PkgFileIterator)file;
+@end
+/* }}} */
+/* Delegate Helpers {{{ */
+@implementation NSObject(ProgressDelegate)
+
+- (void) _setProgressErrorPackage:(NSArray *)args {
+    [self performSelector:@selector(setProgressError:forPackage:)
+        withObject:[args objectAtIndex:0]
+        withObject:([args count] == 1 ? nil : [args objectAtIndex:1])
+    ];
+}
+
+- (void) _setProgressErrorTitle:(NSArray *)args {
+    [self performSelector:@selector(setProgressError:withTitle:)
+        withObject:[args objectAtIndex:0]
+        withObject:([args count] == 1 ? nil : [args objectAtIndex:1])
+    ];
+}
+
+- (void) _setProgressError:(NSString *)error withTitle:(NSString *)title {
+    [self performSelectorOnMainThread:@selector(_setProgressErrorTitle:)
+        withObject:[NSArray arrayWithObjects:error, title, nil]
+        waitUntilDone:YES
+    ];
+}
+
+- (void) setProgressError:(NSString *)error forPackage:(NSString *)id {
+    Package *package = id == nil ? nil : [[Database sharedInstance] packageWithName:id];
+    // XXX: holy typecast batman!
+    [(id<ProgressDelegate>)self setProgressError:error withTitle:(package == nil ? id : [package name])];
+}
+
 @end
 /* }}} */
 
@@ -1572,9 +1605,12 @@ typedef std::map< unsigned long, _H<Source> > SourceMap;
         host_ = [[host_ lowercaseString] retain];
 
     if (host_ != nil)
-        authority_ = [host_ retain];
+        authority_ = host_;
     else
         authority_ = [url path];
+
+    if (authority_ != nil)
+        authority_ = [authority_ retain];
 }
 
 - (Source *) initWithMetaIndex:(metaIndex *)index inPool:(apr_pool_t *)pool {
@@ -1722,6 +1758,7 @@ typedef std::map< unsigned long, _H<Source> > SourceMap;
     bool essential_;
     bool required_;
     bool visible_;
+    bool obsolete_;
 
     NSString *latest_;
     CYString installed_;
@@ -1831,8 +1868,9 @@ typedef std::map< unsigned long, _H<Source> > SourceMap;
 - (void) remove;
 
 - (bool) isUnfilteredAndSearchedForBy:(NSString *)search;
+- (bool) isUnfilteredAndSelectedForBy:(NSString *)search;
 - (bool) isInstalledAndVisible:(NSNumber *)number;
-- (bool) isVisiblyUninstalledInSection:(NSString *)section;
+- (bool) isVisibleInSection:(NSString *)section;
 - (bool) isVisibleInSource:(Source *)source;
 
 @end
@@ -1929,6 +1967,11 @@ CFComparisonResult PackageNameCompare(Package *lhs, Package *rhs, void *arg) {
         CYString &rhi(PackageName(rhs, @selector(cyname)));
         CFStringRef lhn(lhi), rhn(rhi);
 
+        if (lhn == NULL)
+            return rhn == NULL ? NSOrderedSame : NSOrderedAscending;
+        else if (rhn == NULL)
+            return NSOrderedDescending;
+
         _profile(PackageNameCompare$NumbersLast)
             if (!lhi.empty() && !rhi.empty()) {
                 UniChar lhc(CFStringGetCharacterAtIndex(lhn, 0));
@@ -2079,7 +2122,7 @@ struct PackageNameOrdering :
 }
 
 - (void) setVisible {
-    visible_ = required_ && [self hasSupportingRole] && [self unfiltered];
+    visible_ = required_ && [self unfiltered];
 }
 
 - (Package *) initWithVersion:(pkgCache::VerIterator)version withZone:(NSZone *)zone inPool:(apr_pool_t *)pool database:(Database *)database {
@@ -2178,13 +2221,12 @@ struct PackageNameOrdering :
                 if (version == nil) {
                     [metadata_ setObject:latest_ forKey:@"LastVersion"];
                     changed = true;
-                } else {
-                if (![version isEqualToString:latest_]) {
+                } else if (![version isEqualToString:latest_]) {
                     [metadata_ setObject:latest_ forKey:@"LastVersion"];
                     lastSeen_ = now_;
                     [metadata_ setObject:lastSeen_ forKey:@"LastSeen"];
                     changed = true;
-                } }
+                }
             }
 
             metadata_ = [metadata_ retain];
@@ -2199,6 +2241,7 @@ struct PackageNameOrdering :
             section_.set(pool_, iterator_.Section());
         _end
 
+        obsolete_ = [self hasTag:@"cydia::obsolete"];
         essential_ = ((iterator_->Flags & pkgCache::Flag::Essential) == 0 ? NO : YES) || [self hasTag:@"cydia::essential"];
         [self setVisible];
     } _end } return self;
@@ -2380,7 +2423,7 @@ struct PackageNameOrdering :
 
 - (BOOL) unfiltered {
     NSString *section([self section]);
-    return section == nil || isSectionVisible(section);
+    return !obsolete_ && [self hasSupportingRole] && (section == nil || isSectionVisible(section));
 }
 
 - (BOOL) visible {
@@ -2433,11 +2476,9 @@ struct PackageNameOrdering :
                     return @"UPGRADE";
                 case 2:
                     return @"NEW_INSTALL";
-                default:
-                    _assert(false);
+                _nodefault
             }
-        default:
-            _assert(false);
+        _nodefault
     }
 }
 
@@ -2764,16 +2805,34 @@ struct PackageNameOrdering :
     _end
 }
 
+- (bool) isUnfilteredAndSelectedForBy:(NSString *)search {
+    if ([search length] == 0)
+        return false;
+
+    _profile(Package$isUnfilteredAndSelectedForBy)
+        bool value(true);
+
+        _profile(Package$isUnfilteredAndSelectedForBy$Unfiltered)
+            value &= [self unfiltered];
+        _end
+
+        _profile(Package$isUnfilteredAndSelectedForBy$Match)
+            value &= [[self name] compare:search options:MatchCompareOptions_ range:NSMakeRange(0, [search length])] == NSOrderedSame;
+        _end
+
+        return value;
+    _end
+}
+
 - (bool) isInstalledAndVisible:(NSNumber *)number {
     return (![number boolValue] || [self visible]) && ![self uninstalled];
 }
 
-- (bool) isVisiblyUninstalledInSection:(NSString *)name {
+- (bool) isVisibleInSection:(NSString *)name {
     NSString *section = [self section];
 
     return
-        [self visible] &&
-        [self uninstalled] && (
+        [self visible] && (
             name == nil ||
             section == nil && [name length] == 0 ||
             [name isEqualToString:section]
@@ -2905,6 +2964,10 @@ struct PackageNameOrdering :
 @end
 /* }}} */
 
+static NSString *Colon_;
+static NSString *Error_;
+static NSString *Warning_;
+
 /* Database Implementation {{{ */
 @implementation Database
 
@@ -2947,7 +3010,7 @@ struct PackageNameOrdering :
         }
     }
 
-    _assert(false);
+    _assume(false);
 }
 
 - (void) _readStatus:(NSNumber *)fd { _pooled
@@ -2960,7 +3023,7 @@ struct PackageNameOrdering :
 
     while (std::getline(is, line)) {
         const char *data(line.c_str());
-        size_t size = line.size();
+        size_t size(line.size());
         lprintf("S:%s\n", data);
 
         if (conffile_r(data, size)) {
@@ -2978,7 +3041,7 @@ struct PackageNameOrdering :
             NSString *string = pmstatus_r[4];
 
             if (type == "pmerror")
-                [delegate_ performSelectorOnMainThread:@selector(_setProgressError:)
+                [delegate_ performSelectorOnMainThread:@selector(_setProgressErrorPackage:)
                     withObject:[NSArray arrayWithObjects:string, id, nil]
                     waitUntilDone:YES
                 ];
@@ -2986,11 +3049,13 @@ struct PackageNameOrdering :
                 [delegate_ setProgressTitle:string];
             } else if (type == "pmconffile")
                 [delegate_ setConfigurationData:string];
-            else _assert(false);
-        } else _assert(false);
+            else
+                lprintf("E:unknown pmstatus\n");
+        } else
+            lprintf("E:unknown status\n");
     }
 
-    _assert(false);
+    _assume(false);
 }
 
 - (void) _readOutput:(NSNumber *)fd { _pooled
@@ -3003,7 +3068,7 @@ struct PackageNameOrdering :
         [delegate_ addProgressOutput:[NSString stringWithUTF8String:line.c_str()]];
     }
 
-    _assert(false);
+    _assume(false);
 }
 
 - (FILE *) input {
@@ -3173,9 +3238,40 @@ struct PackageNameOrdering :
     return issues;
 }
 
+- (bool) popErrorWithTitle:(NSString *)title {
+    bool fatal(false);
+    std::string message;
+
+    while (!_error->empty()) {
+        std::string error;
+        bool warning(!_error->PopMessage(error));
+        if (!warning)
+            fatal = true;
+        for (;;) {
+            size_t size(error.size());
+            if (size == 0 || error[size - 1] != '\n')
+                break;
+            error.resize(size - 1);
+        }
+        lprintf("%c:[%s]\n", warning ? 'W' : 'E', error.c_str());
+
+        if (!message.empty())
+            message += "\n\n";
+        message += error;
+    }
+
+    if (fatal && !message.empty())
+        [delegate_ _setProgressError:[NSString stringWithUTF8String:message.c_str()] withTitle:[NSString stringWithFormat:Colon_, fatal ? Error_ : Warning_, title]];
+
+    return fatal;
+}
+
+- (bool) popErrorWithTitle:(NSString *)title forOperation:(bool)success {
+    return [self popErrorWithTitle:title] || !success;
+}
+
 - (void) reloadData { _pooled
 @synchronized ([Database class]) {
-
     @synchronized (self) {
         ++era_;
     }
@@ -3213,12 +3309,12 @@ struct PackageNameOrdering :
     if (chk != -1)
         close(chk);
 
+    NSString *title(UCLocalize("DATABASE"));
+
     _trace();
-    if (!cache_.Open(progress_, true)) {
+    if (!cache_.Open(progress_, true)) { pop:
         std::string error;
-        if (!_error->PopMessage(error))
-            _assert(false);
-        _error->Discard();
+        bool warning(!_error->PopMessage(error));
         lprintf("cache_.Open():[%s]\n", error.c_str());
 
         if (error == "dpkg was interrupted, you must manually run 'dpkg --configure -a' to correct the problem. ")
@@ -3228,8 +3324,12 @@ struct PackageNameOrdering :
         // else if (error == "Could not open lock file /var/lib/dpkg/lock - open (13 Permission denied)")
         // else if (error == "Could not get lock /var/lib/dpkg/lock - open (35 Resource temporarily unavailable)")
         // else if (error == "The list of sources could not be read.")
-        else _assert(false);
+        else
+            [delegate_ _setProgressError:[NSString stringWithUTF8String:error.c_str()] withTitle:[NSString stringWithFormat:Colon_, warning ? Warning_ : Error_, title]];
 
+        if (warning)
+            goto pop;
+        _error->Discard();
         return;
     }
     _trace();
@@ -3245,15 +3345,28 @@ struct PackageNameOrdering :
     lock_ = NULL;
 
     list_ = new pkgSourceList();
-    _assert(list_->ReadMainList());
+    if ([self popErrorWithTitle:title forOperation:list_->ReadMainList()])
+        return;
+
+    if (cache_->DelCount() != 0 || cache_->InstCount() != 0) {
+        [delegate_ _setProgressError:@"COUNTS_NONZERO_EX" withTitle:title];
+        return;
+    }
 
-    _assert(cache_->DelCount() == 0 && cache_->InstCount() == 0);
-    _assert(pkgApplyStatus(cache_));
+    if ([self popErrorWithTitle:title forOperation:pkgApplyStatus(cache_)])
+        return;
 
     if (cache_->BrokenCount() != 0) {
-        _assert(pkgFixBroken(cache_));
-        _assert(cache_->BrokenCount() == 0);
-        _assert(pkgMinimizeUpgrade(cache_));
+        if ([self popErrorWithTitle:title forOperation:pkgFixBroken(cache_)])
+            return;
+
+        if (cache_->BrokenCount() != 0) {
+            [delegate_ _setProgressError:@"STILL_BROKEN_EX" withTitle:title];
+            return;
+        }
+
+        if ([self popErrorWithTitle:title forOperation:pkgMinimizeUpgrade(cache_)])
+            return;
     }
 
     _trace();
@@ -3321,13 +3434,18 @@ struct PackageNameOrdering :
     system([dpkg UTF8String]);
 }
 
-- (void) clean {
+- (bool) clean {
+    // XXX: I don't remember this condition
     if (lock_ != NULL)
-        return;
+        return false;
 
     FileFd Lock;
     Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
-    _assert(!_error->PendingError());
+
+    NSString *title(UCLocalize("CLEAN_ARCHIVES"));
+
+    if ([self popErrorWithTitle:title])
+        return false;
 
     pkgAcquire fetcher;
     fetcher.Clean(_config->FindDir("Dir::Cache::Archives"));
@@ -3341,35 +3459,43 @@ struct PackageNameOrdering :
         }
     } cleaner;
 
-    if (!cleaner.Go(_config->FindDir("Dir::Cache::Archives") + "partial/", cache_)) {
-        std::string error;
-        while (_error->PopMessage(error))
-            lprintf("ArchiveCleaner: %s\n", error.c_str());
-    }
+    if ([self popErrorWithTitle:title forOperation:cleaner.Go(_config->FindDir("Dir::Cache::Archives") + "partial/", cache_)])
+        return false;
+
+    return true;
 }
 
-- (void) prepare {
+- (bool) prepare {
     fetcher_->Shutdown();
 
     pkgRecords records(cache_);
 
     lock_ = new FileFd();
     lock_->Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
-    _assert(!_error->PendingError());
+
+    NSString *title(UCLocalize("PREPARE_ARCHIVES"));
+
+    if ([self popErrorWithTitle:title])
+        return false;
 
     pkgSourceList list;
-    // XXX: explain this with an error message
-    _assert(list.ReadMainList());
+    if ([self popErrorWithTitle:title forOperation:list.ReadMainList()])
+        return false;
 
     manager_ = (_system->CreatePM(cache_));
-    _assert(manager_->GetArchives(fetcher_, &list, &records));
-    _assert(!_error->PendingError());
+    if ([self popErrorWithTitle:title forOperation:manager_->GetArchives(fetcher_, &list, &records)])
+        return false;
+
+    return true;
 }
 
 - (void) perform {
+    NSString *title(UCLocalize("PERFORM_SELECTIONS"));
+
     NSMutableArray *before = [NSMutableArray arrayWithCapacity:16]; {
         pkgSourceList list;
-        _assert(list.ReadMainList());
+        if ([self popErrorWithTitle:title forOperation:list.ReadMainList()])
+            return;
         for (pkgSourceList::const_iterator source = list.begin(); source != list.end(); ++source)
             [before addObject:[NSString stringWithUTF8String:(*source)->GetURI().c_str()]];
     }
@@ -3392,7 +3518,7 @@ struct PackageNameOrdering :
         lprintf("pAf:%s:%s\n", uri.c_str(), error.c_str());
         failed = true;
 
-        [delegate_ performSelectorOnMainThread:@selector(_setProgressError:)
+        [delegate_ performSelectorOnMainThread:@selector(_setProgressErrorPackage:)
             withObject:[NSArray arrayWithObjects:
                 [NSString stringWithUTF8String:error.c_str()],
             nil]
@@ -3425,7 +3551,8 @@ struct PackageNameOrdering :
 
     NSMutableArray *after = [NSMutableArray arrayWithCapacity:16]; {
         pkgSourceList list;
-        _assert(list.ReadMainList());
+        if ([self popErrorWithTitle:title forOperation:list.ReadMainList()])
+            return;
         for (pkgSourceList::const_iterator source = list.begin(); source != list.end(); ++source)
             [after addObject:[NSString stringWithUTF8String:(*source)->GetURI().c_str()]];
     }
@@ -3434,8 +3561,11 @@ struct PackageNameOrdering :
         [self update];
 }
 
-- (void) upgrade {
-    _assert(pkgDistUpgrade(cache_));
+- (bool) upgrade {
+    NSString *title(UCLocalize("UPGRADE"));
+    if ([self popErrorWithTitle:title forOperation:pkgDistUpgrade(cache_)])
+        return false;
+    return true;
 }
 
 - (void) update {
@@ -3447,28 +3577,24 @@ struct PackageNameOrdering :
         [package setVisible];
 }
 
-- (NSString *) updateWithStatus:(Status &)status {
+- (void) updateWithStatus:(Status &)status {
+    _transient NSObject<ProgressDelegate> *delegate(status.getDelegate());
+    NSString *title(UCLocalize("REFRESHING_DATA"));
+
     pkgSourceList list;
-    _assert(list.ReadMainList());
+    if (!list.ReadMainList())
+        [delegate _setProgressError:@"Unable to read source list." withTitle:title];
 
     FileFd lock;
     lock.Fd(GetLock(_config->FindDir("Dir::State::Lists") + "lock"));
+    if ([self popErrorWithTitle:title])
+        return;
 
-    if (_error->PendingError()) error: {
-        std::string error;
-        if (!_error->PopMessage(error))
-            _assert(false);
-        _error->Discard();
-        return [NSString stringWithUTF8String:error.c_str()];
-    }
-
-    if (!ListUpdate(status, list, PulseInterval_))
-        goto error;
+    if ([self popErrorWithTitle:title forOperation:ListUpdate(status, list, PulseInterval_)])
+        /* XXX: ignore this because users suck and don't understand why refreshing is important: return */;
 
     [Metadata_ setObject:[NSDate date] forKey:@"LastUpdate"];
     Changed_ = true;
-
-    return nil;
 }
 
 - (void) setDelegate:(id)delegate {
@@ -3485,93 +3611,46 @@ struct PackageNameOrdering :
 @end
 /* }}} */
 
-/* PopUp Windows {{{ */
-@interface PopUpView : UIView {
-    _transient id delegate_;
-    UITransitionView *transition_;
-    UIView *overlay_;
+/* Confirmation View {{{ */
+bool DepSubstrate(const pkgCache::VerIterator &iterator) {
+    if (!iterator.end())
+        for (pkgCache::DepIterator dep(iterator.DependsList()); !dep.end(); ++dep) {
+            if (dep->Type != pkgCache::Dep::Depends && dep->Type != pkgCache::Dep::PreDepends)
+                continue;
+            pkgCache::PkgIterator package(dep.TargetPkg());
+            if (package.end())
+                continue;
+            if (strcmp(package.Name(), "mobilesubstrate") == 0)
+                return true;
+        }
+
+    return false;
 }
 
-- (void) cancel;
-- (id) initWithView:(UIView *)view delegate:(id)delegate;
+/* Web Scripting {{{ */
+@interface CydiaObject : NSObject {
+    id indirect_;
+    id delegate_;
+}
 
+- (id) initWithDelegate:(IndirectDelegate *)indirect;
 @end
 
-@implementation PopUpView
+@implementation CydiaObject
 
 - (void) dealloc {
-    [transition_ setDelegate:nil];
-    [transition_ release];
-    [overlay_ release];
+    [indirect_ release];
     [super dealloc];
 }
 
-- (void) cancel {
-    [transition_ transition:UITransitionPushFromTop toView:nil];
+- (id) initWithDelegate:(IndirectDelegate *)indirect {
+    if ((self = [super init]) != nil) {
+        indirect_ = [indirect retain];
+    } return self;
 }
 
-- (void) transitionViewDidComplete:(UITransitionView*)view fromView:(UIView*)from toView:(UIView*)to {
-    if (from != nil && to == nil)
-        [self removeFromSuperview];
-}
-
-- (id) initWithView:(UIView *)view delegate:(id)delegate {
-    if ((self = [super initWithFrame:[view bounds]]) != nil) {
-        delegate_ = delegate;
-
-        transition_ = [[UITransitionView alloc] initWithFrame:[self bounds]];
-        [self addSubview:transition_];
-
-        overlay_ = [[UIView alloc] initWithFrame:[transition_ bounds]];
-
-        [view addSubview:self];
-
-        [transition_ setDelegate:self];
-
-        UIView *blank = [[[UIView alloc] initWithFrame:[transition_ bounds]] autorelease];
-        [transition_ transition:UITransitionNone toView:blank];
-        [transition_ transition:UITransitionPushFromBottom toView:overlay_];
-    } return self;
-}
-
-@end
-/* }}} */
-
-/* Confirmation View {{{ */
-bool DepSubstrate(const pkgCache::VerIterator &iterator) {
-    if (!iterator.end())
-        for (pkgCache::DepIterator dep(iterator.DependsList()); !dep.end(); ++dep) {
-            if (dep->Type != pkgCache::Dep::Depends && dep->Type != pkgCache::Dep::PreDepends)
-                continue;
-            pkgCache::PkgIterator package(dep.TargetPkg());
-            if (package.end())
-                continue;
-            if (strcmp(package.Name(), "mobilesubstrate") == 0)
-                return true;
-        }
-
-    return false;
-}
-
-/* Web Scripting {{{ */
-@interface CydiaObject : NSObject {
-    id indirect_;
-}
-
-- (id) initWithDelegate:(IndirectDelegate *)indirect;
-@end
-
-@implementation CydiaObject
-
-- (void) dealloc {
-    [indirect_ release];
-    [super dealloc];
-}
-
-- (id) initWithDelegate:(IndirectDelegate *)indirect {
-    if ((self = [super init]) != nil) {
-        indirect_ = [indirect retain];
-    } return self;
+- (void) setDelegate:(id)delegate {
+    delegate_ = delegate;
 }
 
 + (NSArray *) _attributeKeys {
@@ -3615,8 +3694,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 + (NSString *) webScriptNameForSelector:(SEL)selector {
     if (selector == @selector(close))
         return @"close";
+    else if (selector == @selector(getInstalledPackages))
+        return @"getInstalledPackages";
     else if (selector == @selector(getPackageById:))
         return @"getPackageById";
+    else if (selector == @selector(installPackages:))
+        return @"installPackages";
     else if (selector == @selector(setAutoPopup:))
         return @"setAutoPopup";
     else if (selector == @selector(setButtonImage:withStyle:toFunction:))
@@ -3629,6 +3712,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         return @"setPopupHook";
     else if (selector == @selector(setSpecial:))
         return @"setSpecial";
+    else if (selector == @selector(setToken:))
+        return @"setToken";
     else if (selector == @selector(setViewportWidth:))
         return @"setViewportWidth";
     else if (selector == @selector(supports:))
@@ -3653,6 +3738,15 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     return [feature isEqualToString:@"window.open"];
 }
 
+- (NSArray *) getInstalledPackages {
+    NSArray *packages([[Database sharedInstance] packages]);
+    NSMutableArray *installed([NSMutableArray arrayWithCapacity:[packages count]]);
+    for (Package *package in packages)
+        if ([package installed] != nil)
+            [installed addObject:package];
+    return installed;
+}
+
 - (Package *) getPackageById:(NSString *)id {
     Package *package([[Database sharedInstance] packageWithName:id]);
     [package parse];
@@ -3720,6 +3814,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [indirect_ close];
 }
 
+- (void) installPackages:(NSArray *)packages {
+    [delegate_ performSelectorOnMainThread:@selector(installPackages:) withObject:packages waitUntilDone:NO];
+}
+
 - (void) setAutoPopup:(BOOL)popup {
     [indirect_ setAutoPopup:popup];
 }
@@ -3736,6 +3834,15 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [indirect_ setSpecial:function];
 }
 
+- (void) setToken:(NSString *)token {
+    if (Token_ != nil)
+        [Token_ release];
+    Token_ = [token retain];
+
+    [Metadata_ setObject:Token_ forKey:@"Token"];
+    Changed_ = true;
+}
+
 - (void) setFinishHook:(id)function {
     [indirect_ setFinishHook:function];
 }
@@ -3781,9 +3888,33 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [super dealloc];
 }
 
+- (void) setHeaders:(NSDictionary *)headers forHost:(NSString *)host {
+}
+
 - (void) webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame {
     [super webView:sender didClearWindowObject:window forFrame:frame];
-    [window setValue:cydia_ forKey:@"cydia"];
+
+    WebDataSource *source([frame dataSource]);
+    NSURLResponse *response([source response]);
+    NSURL *url([response URL]);
+    NSString *scheme([url scheme]);
+
+    NSHTTPURLResponse *http;
+    if (scheme != nil && ([scheme isEqualToString:@"http"] || [scheme isEqualToString:@"https"]))
+        http = (NSHTTPURLResponse *) response;
+    else
+        http = nil;
+
+    NSDictionary *headers([http allHeaderFields]);
+    NSString *host([url host]);
+    [self setHeaders:headers forHost:host];
+
+    if (
+        [host isEqualToString:@"cydia.saurik.com"] ||
+        [host hasSuffix:@".cydia.saurik.com"] ||
+        [scheme isEqualToString:@"file"]
+    )
+        [window setValue:cydia_ forKey:@"cydia"];
 }
 
 - (void) _setMoreHeaders:(NSMutableURLRequest *)request {
@@ -3791,8 +3922,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         [request setValue:System_ forHTTPHeaderField:@"X-System"];
     if (Machine_ != NULL)
         [request setValue:[NSString stringWithUTF8String:Machine_] forHTTPHeaderField:@"X-Machine"];
-    if (UniqueID_ != nil)
-        [request setValue:UniqueID_ forHTTPHeaderField:@"X-Unique-ID"];
+    if (Token_ != nil)
+        [request setValue:Token_ forHTTPHeaderField:@"X-Cydia-Token"];
     if (Role_ != nil)
         [request setValue:Role_ forHTTPHeaderField:@"X-Role"];
 }
@@ -3803,11 +3934,16 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     return copy;
 }
 
+- (void) setDelegate:(id)delegate {
+    [super setDelegate:delegate];
+    [cydia_ setDelegate:delegate];
+}
+
 - (id) initWithBook:(RVBook *)book forWidth:(float)width {
     if ((self = [super initWithBook:book forWidth:width ofClass:[CydiaBrowserView class]]) != nil) {
         cydia_ = [[CydiaObject alloc] initWithDelegate:indirect_];
 
-        WebView *webview([webview_ webView]);
+        WebView *webview([document_ webView]);
 
         Package *package([[Database sharedInstance] packageWithName:@"cydia"]);
 
@@ -3817,11 +3953,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         ];
 
         if (Safari_ != nil)
-            application = [NSString stringWithFormat:@"Safari/%@ %@", application, Safari_];
+            application = [NSString stringWithFormat:@"Safari/%@ %@", Safari_, application];
         if (Build_ != nil)
-            application = [NSString stringWithFormat:@"Mobile/%@ %@", application, Build_];
+            application = [NSString stringWithFormat:@"Mobile/%@ %@", Build_, application];
         if (Product_ != nil)
-            application = [NSString stringWithFormat:@"Version/%@ %@", application, Product_];
+            application = [NSString stringWithFormat:@"Version/%@ %@", Product_, application];
 
         [webview setApplicationNameForUserAgent:application];
     } return self;
@@ -3837,7 +3973,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
 @interface ConfirmationView : CydiaBrowserView {
     _transient Database *database_;
-    UIActionSheet *essential_;
+    UIAlertView *essential_;
     NSArray *changes_;
     NSArray *issues_;
     NSArray *sizes_;
@@ -3865,29 +4001,25 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [book_ popFromSuperviewAnimated:YES];
 }
 
-- (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button {
-    NSString *context([sheet context]);
+- (void)alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)button {
+    NSString *context([alert context]);
 
     if ([context isEqualToString:@"remove"]) {
-        switch (button) {
-            case 1:
+               if (button == [alert cancelButtonIndex]) {
                 [self cancel];
-                break;
-            case 2:
+        } else if (button == [alert firstOtherButtonIndex]) {
                 if (substrate_)
                     Finish_ = 2;
                 [delegate_ confirm];
-                break;
-            default:
-                _assert(false);
         }
 
-        [sheet dismiss];
+        [alert dismissWithClickedButtonIndex:-1 animated:YES];
     } else if ([context isEqualToString:@"unable"]) {
         [self cancel];
-        [sheet dismiss];
-    } else
-        [super alertSheet:sheet buttonClicked:button];
+        [alert dismissWithClickedButtonIndex:-1 animated:YES];
+    } else {
+               [super alertView:alert clickedButtonAtIndex:button];
+       }
 }
 
 - (void) webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame {
@@ -3939,34 +4071,28 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
         if (!remove)
             essential_ = nil;
-        else if (Advanced_ || true) {
+        else if (Advanced_) {
             NSString *parenthetical(UCLocalize("PARENTHETICAL"));
 
-            essential_ = [[UIActionSheet alloc]
+            essential_ = [[UIAlertView alloc]
                 initWithTitle:UCLocalize("REMOVING_ESSENTIALS")
-                buttons:[NSArray arrayWithObjects:
-                    [NSString stringWithFormat:parenthetical, UCLocalize("CANCEL_OPERATION"), UCLocalize("SAFE")],
-                    [NSString stringWithFormat:parenthetical, UCLocalize("FORCE_REMOVAL"), UCLocalize("UNSAFE")],
-                nil]
-                defaultButtonIndex:0
-                delegate:self
-                context:@"remove"
-            ];
+                               message:UCLocalize("REMOVING_ESSENTIALS_EX")
+                               delegate:self
+                               cancelButtonTitle:[NSString stringWithFormat:parenthetical, UCLocalize("CANCEL_OPERATION"), UCLocalize("SAFE")]
+                               otherButtonTitles:[NSString stringWithFormat:parenthetical, UCLocalize("FORCE_REMOVAL"), UCLocalize("UNSAFE")], nil
+                       ];
 
-#ifndef __OBJC2__
-            [essential_ setDestructiveButton:[[essential_ buttons] objectAtIndex:0]];
-#endif
-            [essential_ setBodyText:UCLocalize("REMOVING_ESSENTIALS_EX")];
+            [essential_ setContext:@"remove"];
         } else {
-            essential_ = [[UIActionSheet alloc]
+            essential_ = [[UIAlertView alloc]
                 initWithTitle:UCLocalize("UNABLE_TO_COMPLY")
-                buttons:[NSArray arrayWithObjects:UCLocalize("OKAY"), nil]
-                defaultButtonIndex:0
-                delegate:self
-                context:@"unable"
+                               message:UCLocalize("UNABLE_TO_COMPLY_EX")
+                               delegate:self
+                               cancelButtonTitle:UCLocalize("OKAY")
+                               otherButtonTitles:nil
             ];
 
-            [essential_ setBodyText:UCLocalize("UNABLE_TO_COMPLY_EX")];
+                       [essential_ setContext:@"unable"];
         }
 
         changes_ = [[NSArray alloc] initWithObjects:
@@ -3988,6 +4114,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         nil];
 
         [self loadURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"confirm" ofType:@"html"]]];
+
+        [self setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
     } return self;
 }
 
@@ -4090,11 +4218,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     BOOL running_;
     SHA1SumValue springlist_;
     SHA1SumValue notifyconf_;
-    SHA1SumValue sandplate_;
+    NSString *title_;
 }
 
-- (void) transitionViewDidComplete:(UITransitionView*)view fromView:(UIView*)from toView:(UIView*)to;
-
 - (id) initWithFrame:(struct CGRect)frame database:(Database *)database delegate:(id)delegate;
 - (void) setContentView:(UIView *)view;
 - (void) resetView;
@@ -4127,31 +4253,26 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [output_ release];
     [status_ release];
     [close_ release];
+    if (title_ != nil)
+        [title_ release];
     [super dealloc];
 }
 
-- (void) transitionViewDidComplete:(UITransitionView*)view fromView:(UIView*)from toView:(UIView*)to {
-    if (bootstrap_ && from == overlay_ && to == view_)
-        exit(0);
-}
-
 - (id) initWithFrame:(struct CGRect)frame database:(Database *)database delegate:(id)delegate {
     if ((self = [super initWithFrame:frame]) != nil) {
         database_ = database;
         delegate_ = delegate;
 
         transition_ = [[UITransitionView alloc] initWithFrame:[self bounds]];
+        [transition_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
         [transition_ setDelegate:self];
 
         overlay_ = [[UIView alloc] initWithFrame:[transition_ bounds]];
+        [overlay_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
 
-        if (bootstrap_)
-            [overlay_ setBackgroundColor:[UIColor blackColor]];
-        else {
-            background_ = [[UIView alloc] initWithFrame:[self bounds]];
-            [background_ setBackgroundColor:[UIColor blackColor]];
-            [self addSubview:background_];
-        }
+        background_ = [[UIView alloc] initWithFrame:[self bounds]];
+        [background_ setBackgroundColor:[UIColor blackColor]];
+        [self addSubview:background_];
 
         [self addSubview:transition_];
 
@@ -4159,6 +4280,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         CGRect navrect = {{0, 0}, navsize};
 
         navbar_ = [[UINavigationBar alloc] initWithFrame:navrect];
+        [navbar_ setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
         [overlay_ addSubview:navbar_];
 
         [navbar_ setBarStyle:1];
@@ -4176,6 +4298,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         }, prgsize};
 
         progress_ = [[UIProgressBar alloc] initWithFrame:prgrect];
+        [progress_ setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin)];
         [progress_ setStyle:0];
 
         status_ = [[UITextLabel alloc] initWithFrame:CGRectMake(
@@ -4185,12 +4308,13 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
             24
         )];
 
+        [status_ setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin)];
+
         [status_ setColor:[UIColor whiteColor]];
         [status_ setBackgroundColor:[UIColor clearColor]];
 
         [status_ setCentersHorizontally:YES];
         //[status_ setFont:font];
-        _trace();
 
         output_ = [[UITextView alloc] initWithFrame:CGRectMake(
             10,
@@ -4198,10 +4322,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
             bounds.size.width - 20,
             bounds.size.height - navsize.height - 62 - navrect.size.height
         )];
-        _trace();
+
+        [output_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+        [overlay_ addSubview:output_];
 
         //[output_ setTextFont:@"Courier New"];
-        [output_ setTextSize:12];
+        [output_ setFont:[[output_ font] fontWithSize:12]];
 
         [output_ setTextColor:[UIColor whiteColor]];
         [output_ setBackgroundColor:[UIColor clearColor]];
@@ -4210,8 +4336,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         [output_ setAllowsRubberBanding:YES];
         [output_ setEditable:NO];
 
-        [overlay_ addSubview:output_];
-
         close_ = [[UIPushButton alloc] initWithFrame:CGRectMake(
             10,
             bounds.size.height - prgsize.height - 50,
@@ -4219,6 +4343,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
             32 + prgsize.height
         )];
 
+        [close_ setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin)];
+
         [close_ setAutosizesToFit:NO];
         [close_ setDrawsShadow:YES];
         [close_ setStretchBackground:YES];
@@ -4241,26 +4367,58 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [transition_ transition:6 toView:view_];
 }
 
-- (void) _checkError {
-    if (_error->PendingError()) {
-        std::string error;
-        if (!_error->PopMessage(error))
-            _assert(false);
+- (void)alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)button {
+    NSString *context([alert context]);
 
-        UIActionSheet *sheet = [[[UIActionSheet alloc]
-            initWithTitle:UCLocalize("ERROR")
-            buttons:[NSArray arrayWithObjects:UCLocalize("OKAY"), nil]
-            defaultButtonIndex:0
-            delegate:self
-            context:@"_error"
-        ] autorelease];
+    if ([context isEqualToString:@"conffile"]) {
+               FILE *input = [database_ input];
+        if (button == [alert cancelButtonIndex]) fprintf(input, "N\n");
+        else if (button == [alert firstOtherButtonIndex]) fprintf(input, "Y\n");
+               fflush(input);
+               
+        [alert dismissWithClickedButtonIndex:-1 animated:YES];
+    }
+}
 
-        [sheet setBodyText:[NSString stringWithUTF8String:error.c_str()]];
-        [sheet popupAlertAnimated:YES];
+- (void) closeButtonPushed {
+    running_ = NO;
 
-        return;
+    switch (Finish_) {
+        case 0:
+            [self resetView];
+        break;
+
+        case 1:
+            [delegate_ terminateWithSuccess];
+            /*if ([delegate_ respondsToSelector:@selector(suspendWithAnimation:)])
+                [delegate_ suspendWithAnimation:YES];
+            else
+                [delegate_ suspend];*/
+        break;
+
+        case 2:
+            system("launchctl stop com.apple.SpringBoard");
+        break;
+
+        case 3:
+            system("launchctl unload "SpringBoard_"; launchctl load "SpringBoard_);
+        break;
+
+        case 4:
+            system("reboot");
+        break;
     }
+}
 
+- (void) _retachThread {
+    UINavigationItem *item([navbar_ topItem]);
+    [item setTitle:UCLocalize("COMPLETE")];
+
+    [overlay_ addSubview:close_];
+    [progress_ removeFromSuperview];
+    [status_ removeFromSuperview];
+
+    [database_ popErrorWithTitle:title_];
     [delegate_ progressViewIsComplete:self];
 
     if (Finish_ < 4) {
@@ -4297,124 +4455,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         case 4: [close_ setTitle:UCLocalize("REBOOT_DEVICE")]; break;
     }
 
-#define ListCache_ "/User/Library/Caches/com.apple.mobile.installation.plist"
-#define IconCache_ "/User/Library/Caches/com.apple.springboard-imagecache-icons.plist"
-
-    unlink(IconCache_);
-
-    if (NSMutableDictionary *cache = [[NSMutableDictionary alloc] initWithContentsOfFile:@ListCache_]) {
-        [cache autorelease];
-
-        NSFileManager *manager = [NSFileManager defaultManager];
-        NSError *error = nil;
-
-        id system = [cache objectForKey:@"System"];
-        if (system == nil)
-            goto error;
-
-        struct stat info;
-        if (stat(ListCache_, &info) == -1)
-            goto error;
-
-        [system removeAllObjects];
-
-        if (NSArray *apps = [manager contentsOfDirectoryAtPath:@"/Applications" error:&error]) {
-            for (NSString *app in apps)
-                if ([app hasSuffix:@".app"]) {
-                    NSString *path = [@"/Applications" stringByAppendingPathComponent:app];
-                    NSString *plist = [path stringByAppendingPathComponent:@"Info.plist"];
-                    if (NSMutableDictionary *info = [[NSMutableDictionary alloc] initWithContentsOfFile:plist]) {
-                        [info autorelease];
-                        if ([info objectForKey:@"CFBundleIdentifier"] != nil) {
-                            [info setObject:path forKey:@"Path"];
-                            [info setObject:@"System" forKey:@"ApplicationType"];
-                            [system addInfoDictionary:info];
-                        }
-                    }
-                }
-        } else goto error;
-
-        [cache writeToFile:@ListCache_ atomically:YES];
-
-        if (chown(ListCache_, info.st_uid, info.st_gid) == -1)
-            goto error;
-        if (chmod(ListCache_, info.st_mode) == -1)
-            goto error;
-
-        if (false) error:
-            lprintf("%s\n", error == nil ? strerror(errno) : [[error localizedDescription] UTF8String]);
-    }
-
-    notify_post("com.apple.mobile.application_installed");
+    system("su -c /usr/bin/uicache mobile");
 
     [delegate_ setStatusBarShowsProgress:NO];
 }
 
-- (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button {
-    NSString *context([sheet context]);
-
-    if ([context isEqualToString:@"error"])
-        [sheet dismiss];
-    else if ([context isEqualToString:@"_error"]) {
-        [sheet dismiss];
-        [self _checkError];
-    } else if ([context isEqualToString:@"conffile"]) {
-        FILE *input = [database_ input];
-
-        switch (button) {
-            case 1:
-                fprintf(input, "N\n");
-                fflush(input);
-                break;
-            case 2:
-                fprintf(input, "Y\n");
-                fflush(input);
-                break;
-            default:
-                _assert(false);
-        }
-
-        [sheet dismiss];
-    }
-}
-
-- (void) closeButtonPushed {
-    running_ = NO;
-
-    switch (Finish_) {
-        case 0:
-            [self resetView];
-        break;
-
-        case 1:
-            [delegate_ suspendWithAnimation:YES];
-        break;
-
-        case 2:
-            system("launchctl stop com.apple.SpringBoard");
-        break;
-
-        case 3:
-            system("launchctl unload "SpringBoard_"; launchctl load "SpringBoard_);
-        break;
-
-        case 4:
-            system("reboot");
-        break;
-    }
-}
-
-- (void) _retachThread {
-    UINavigationItem *item = [navbar_ topItem];
-    [item setTitle:UCLocalize("COMPLETE")];
-
-    [overlay_ addSubview:close_];
-    [progress_ removeFromSuperview];
-    [status_ removeFromSuperview];
-
-    [self _checkError];
-}
-
 - (void) _detachNewThreadData:(ProgressData *)data { _pooled
     [[data target] performSelector:[data selector] withObject:[data object]];
     [data release];
@@ -4423,8 +4468,15 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (void) detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)object title:(NSString *)title {
-    UINavigationItem *item = [navbar_ topItem];
-    [item setTitle:title];
+    if (title_ != nil)
+        [title_ release];
+    if (title == nil)
+        title_ = nil;
+    else
+        title_ = [title retain];
+
+    UINavigationItem *item([navbar_ topItem]);
+    [item setTitle:title_];
 
     [status_ setText:nil];
     [output_ setText:@""];
@@ -4491,19 +4543,16 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     ];
 }
 
-- (void) setProgressError:(NSString *)error forPackage:(NSString *)id {
-    Package *package = id == nil ? nil : [database_ packageWithName:id];
-
-    UIActionSheet *sheet = [[[UIActionSheet alloc]
-        initWithTitle:(package == nil ? id : [package name])
+- (void) setProgressError:(NSString *)error withTitle:(NSString *)title {
+    CYActionSheet *sheet([[[CYActionSheet alloc]
+        initWithTitle:title
         buttons:[NSArray arrayWithObjects:UCLocalize("OKAY"), nil]
         defaultButtonIndex:0
-        delegate:self
-        context:@"error"
-    ] autorelease];
+    ] autorelease]);
 
-    [sheet setBodyText:error];
-    [sheet popupAlertAnimated:YES];
+    [sheet setMessage:error];
+    [sheet yieldToPopupAlertAnimated:YES];
+    [sheet dismiss];
 }
 
 - (void) setProgressTitle:(NSString *)title {
@@ -4540,25 +4589,26 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 - (void) _setConfigurationData:(NSString *)data {
     static Pcre conffile_r("^'(.*)' '(.*)' ([01]) ([01])$");
 
-    _assert(conffile_r(data));
+    if (!conffile_r(data)) {
+        lprintf("E:invalid conffile\n");
+        return;
+    }
 
     NSString *ofile = conffile_r[1];
     //NSString *nfile = conffile_r[2];
 
-    UIActionSheet *sheet = [[[UIActionSheet alloc]
+    UIAlertView *alert = [[[UIAlertView alloc]
         initWithTitle:UCLocalize("CONFIGURATION_UPGRADE")
-        buttons:[NSArray arrayWithObjects:
-            UCLocalize("KEEP_OLD_COPY"),
-            UCLocalize("ACCEPT_NEW_COPY"),
-            // XXX: UCLocalize("SEE_WHAT_CHANGED"),
-        nil]
-        defaultButtonIndex:0
-        delegate:self
-        context:@"conffile"
-    ] autorelease];
+               message:[NSString stringWithFormat:@"%@\n\n%@", UCLocalize("CONFIGURATION_UPGRADE_EX"), ofile]
+               delegate:self
+               cancelButtonTitle:UCLocalize("KEEP_OLD_COPY")
+               otherButtonTitles:UCLocalize("ACCEPT_NEW_COPY"),
+        // XXX: UCLocalize("SEE_WHAT_CHANGED"),
+               nil
+       ] autorelease];
 
-    [sheet setBodyText:[NSString stringWithFormat:@"%@\n\n%@", UCLocalize("CONFIGURATION_UPGRADE_EX"), ofile]];
-    [sheet popupAlertAnimated:YES];
+       [alert setContext:@"conffile"];
+    [alert show];
 }
 
 - (void) _setProgressTitle:(NSString *)title {
@@ -4609,6 +4659,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     ContentView *content_;
     BOOL faded_;
     float fade_;
+    UIImage *placard_;
 }
 
 - (PackageCell *) init;
@@ -4630,6 +4681,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     delegate_ = delegate;
 }
 
+/* Fix landscape: redraw when frame changes. */
+- (void) setFrame:(CGRect)frame {
+       [super setFrame:frame];
+       [self setNeedsDisplay];
+}
+
 - (void) drawRect:(CGRect)rect {
     [super drawRect:rect];
     [delegate_ drawContentRect:rect];
@@ -4665,6 +4722,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         badge_ = nil;
     }
 
+    if (placard_ != nil) {
+        [placard_ release];
+        placard_ = nil;
+    }
+
     [package_ release];
     package_ = nil;
 }
@@ -4685,13 +4747,17 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     if ((self = [super initWithFrame:frame reuseIdentifier:@"Package"]) != nil) {
         UIView *content([self contentView]);
         CGRect bounds([content bounds]);
+
         content_ = [[ContentView alloc] initWithFrame:bounds];
+        [content_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+        [content addSubview:content_];
+
         [content_ setDelegate:self];
-        [content_ setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];
         [content_ setOpaque:YES];
-        [content addSubview:content_];
         if ([self respondsToSelector:@selector(selectionPercent)])
             faded_ = YES;
+
+        [self setNeedsDisplayOnBoundsChange:YES];
     } return self;
 }
 
@@ -4715,7 +4781,14 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
     icon_ = [[package icon] retain];
     name_ = [[package name] retain];
-    description_ = [[package shortDescription] retain];
+
+    if (IsWildcat_)
+        description_ = [package longDescription];
+    if (description_ == nil)
+        description_ = [package shortDescription];
+    if (description_ != nil)
+        description_ = [description_ retain];
+
     commercial_ = [package isCommercial];
 
     package_ = [package retain];
@@ -4746,12 +4819,17 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         if ((badge_ = [UIImage imageAtPath:[NSString stringWithFormat:@"%@/Purposes/%@.png", App_, purpose]]) != nil)
             badge_ = [badge_ retain];
 
+    if ([package installed] != nil)
+        if ((placard_ = [UIImage imageAtPath:[NSString stringWithFormat:@"%@/installed.png", App_]]) != nil)
+            placard_ = [placard_ retain];
+
     [self _setBackgroundColor];
     [content_ setNeedsDisplay];
 }
 
 - (void) drawContentRect:(CGRect)rect {
     bool selected([self isSelected]);
+    float width([self bounds].size.width);
 
 #if 0
     CGContextRef context(UIGraphicsGetCurrentContext());
@@ -4786,12 +4864,15 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
     if (!selected)
         UISetColor(commercial_ ? Purple_ : Black_);
-    [name_ drawAtPoint:CGPointMake(48, 8) forWidth:240 withFont:Font18Bold_ ellipsis:2];
-    [source_ drawAtPoint:CGPointMake(58, 29) forWidth:225 withFont:Font12_ ellipsis:2];
+    [name_ drawAtPoint:CGPointMake(48, 8) forWidth:(width - (placard_ == nil ? 80 : 106)) withFont:Font18Bold_ ellipsis:2];
+    [source_ drawAtPoint:CGPointMake(58, 29) forWidth:(width - 95) withFont:Font12_ ellipsis:2];
 
     if (!selected)
         UISetColor(commercial_ ? Purplish_ : Gray_);
-    [description_ drawAtPoint:CGPointMake(12, 46) forWidth:280 withFont:Font14_ ellipsis:2];
+    [description_ drawAtPoint:CGPointMake(12, 46) forWidth:(width - 46) withFont:Font14_ ellipsis:2];
+
+    if (placard_ != nil)
+        [placard_ drawAtPoint:CGPointMake(width - 52, 9)];
 }
 
 - (void) setSelected:(BOOL)selected animated:(BOOL)fade {
@@ -4808,6 +4889,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 /* }}} */
 /* Section Cell {{{ */
 @interface SectionCell : UISimpleTableCell {
+    NSString *basic_;
     NSString *section_;
     NSString *name_;
     NSString *count_;
@@ -4824,6 +4906,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 @implementation SectionCell
 
 - (void) clearSection {
+    if (basic_ != nil) {
+        [basic_ release];
+        basic_ = nil;
+    }
+
     if (section_ != nil) {
         [section_ release];
         section_ = nil;
@@ -4850,17 +4937,16 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 - (id) init {
     if ((self = [super init]) != nil) {
         icon_ = [[UIImage applicationImageNamed:@"folder.png"] retain];
-
         switch_ = [[_UISwitchSlider alloc] initWithFrame:CGRectMake(218, 9, 60, 25)];
         [switch_ addTarget:self action:@selector(onSwitch:) forEvents:UIControlEventTouchUpInside];
     } return self;
 }
 
 - (void) onSwitch:(id)sender {
-    NSMutableDictionary *metadata = [Sections_ objectForKey:section_];
+    NSMutableDictionary *metadata = [Sections_ objectForKey:basic_];
     if (metadata == nil) {
         metadata = [NSMutableDictionary dictionaryWithCapacity:2];
-        [Sections_ setObject:metadata forKey:section_];
+        [Sections_ setObject:metadata forKey:basic_];
     }
 
     Changed_ = true;
@@ -4882,17 +4968,28 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         name_ = [UCLocalize("ALL_PACKAGES") retain];
         count_ = nil;
     } else {
+        basic_ = [section name];
+        if (basic_ != nil)
+            basic_ = [basic_ retain];
+
         section_ = [section localized];
         if (section_ != nil)
             section_ = [section_ retain];
+
         name_  = [(section_ == nil || [section_ length] == 0 ? UCLocalize("NO_SECTION") : section_) retain];
         count_ = [[NSString stringWithFormat:@"%d", [section count]] retain];
 
         if (editing_)
-            [switch_ setValue:(isSectionVisible(section_) ? 1 : 0) animated:NO];
+            [switch_ setValue:(isSectionVisible(basic_) ? 1 : 0) animated:NO];
     }
 }
 
+- (void) setFrame:(CGRect)frame {
+    [super setFrame:frame];
+    CGRect rect([switch_ frame]);
+    [switch_ setFrame:CGRectMake(frame.size.width - 102, 9, rect.size.width, rect.size.height)];
+}
+
 - (void) drawContentInRect:(CGRect)rect selected:(BOOL)selected {
     [icon_ drawInRect:CGRectMake(8, 7, 32, 32)];
 
@@ -4901,7 +4998,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
     if (!selected)
         UISetColor(Black_);
-    [name_ drawAtPoint:CGPointMake(48, 9) forWidth:(editing_ ? 164 : 250) withFont:Font22Bold_ ellipsis:2];
+
+    float width(rect.size.width + 23);
+    if (editing_)
+        width -= 110;
+
+    [name_ drawAtPoint:CGPointMake(48, 9) forWidth:(width - 70) withFont:Font22Bold_ ellipsis:2];
 
     CGSize size = [count_ sizeWithFont:Font14_];
 
@@ -4983,6 +5085,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         [list_ addTableColumn:column];
         [list_ setDelegate:self];
         [list_ setReusesTableCells:YES];
+
+               [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+        [self setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
     } return self;
 }
 
@@ -5127,8 +5232,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
 #if !AlwaysReload
 - (void) __rightButtonClicked {
-    int count = [buttons_ count];
-    _assert(count != 0);
+    int count([buttons_ count]);
+    if (count == 0)
+        return;
 
     if (count == 1)
         [self _clickButtonWithName:[buttons_ objectAtIndex:0]];
@@ -5205,15 +5311,18 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
             [buttons_ addObject:UCLocalize("REMOVE")];
 
         if (special_ != NULL) {
-            CGRect frame([webview_ frame]);
+            CGRect frame([document_ frame]);
             frame.size.width = 320;
             frame.size.height = 0;
-            [webview_ setFrame:frame];
+            [document_ setFrame:frame];
 
-            [scroller_ scrollPointVisibleAtTopLeft:CGPointZero];
+            if ([scroller_ respondsToSelector:@selector(scrollPointVisibleAtTopLeft:)])
+                [scroller_ scrollPointVisibleAtTopLeft:CGPointZero];
+            else
+                [scroller_ scrollRectToVisible:CGRectZero animated:NO];
 
             WebThreadLock();
-            [[[webview_ webView] windowScriptObject] setValue:package_ forKey:@"package"];
+            [[[document_ webView] windowScriptObject] setValue:package_ forKey:@"package"];
 
             [self setButtonTitle:nil withStyle:nil toFunction:nil];
 
@@ -5344,13 +5453,13 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         sections_ = [[NSMutableArray arrayWithCapacity:16] retain];
 
         list_ = [[UITableView alloc] initWithFrame:[self bounds] style:UITableViewStylePlain];
-        [list_ setDataSource:self];
-        [list_ setDelegate:self];
-
+        [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
         [self addSubview:list_];
 
-        [self setAutoresizingMask:UIViewAutoresizingFlexibleHeight];
-        [list_ setAutoresizingMask:UIViewAutoresizingFlexibleHeight];
+        [list_ setDataSource:self];
+        [list_ setDelegate:self];
+
+        [self setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
     } return self;
 }
 
@@ -5441,6 +5550,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (void) setObject:(id)object;
+- (void) setObject:(id)object forFilter:(SEL)filter;
 
 - (id) initWithBook:(RVBook *)book database:(Database *)database title:(NSString *)title filter:(SEL)filter with:(id)object;
 
@@ -5454,6 +5564,16 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [super dealloc];
 }
 
+- (void) setFilter:(SEL)filter {
+    filter_ = filter;
+
+    /* XXX: this is an unsafe optimization of doomy hell */
+    Method method(class_getInstanceMethod([Package class], filter));
+    _assert(method != NULL);
+    imp_ = method_getImplementation(method);
+    _assert(imp_ != NULL);
+}
+
 - (void) setObject:(id)object {
     if (object_ != nil)
         [object_ release];
@@ -5463,6 +5583,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         object_ = [object retain];
 }
 
+- (void) setObject:(id)object forFilter:(SEL)filter {
+    [self setFilter:filter];
+    [self setObject:object];
+
+}
+
 - (bool) hasPackage:(Package *)package {
     _profile(FilteredPackageTable$hasPackage)
         return [package valid] && (*reinterpret_cast<bool (*)(id, SEL, id)>(imp_))(package, filter_, object_);
@@ -5471,15 +5597,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
 - (id) initWithBook:(RVBook *)book database:(Database *)database title:(NSString *)title filter:(SEL)filter with:(id)object {
     if ((self = [super initWithBook:book database:database title:title]) != nil) {
-        filter_ = filter;
+        [self setFilter:filter];
         object_ = object == nil ? nil : [object retain];
-
-        /* XXX: this is an unsafe optimization of doomy hell */
-        Method method = class_getInstanceMethod([Package class], filter);
-        _assert(method != NULL);
-        imp_ = method_getImplementation(method);
-        _assert(imp_ != NULL);
-
         [self reloadData];
     } return self;
 }
@@ -5545,6 +5664,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (void) drawContentInRect:(CGRect)rect selected:(BOOL)selected {
+    float width(rect.size.width);
+
     if (icon_ != nil)
         [icon_ drawInRect:CGRectMake(10, 10, 30, 30)];
 
@@ -5553,15 +5674,15 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
     if (!selected)
         UISetColor(Black_);
-    [origin_ drawAtPoint:CGPointMake(48, 8) forWidth:240 withFont:Font18Bold_ ellipsis:2];
+    [origin_ drawAtPoint:CGPointMake(48, 8) forWidth:(width - 80) withFont:Font18Bold_ ellipsis:2];
 
     if (!selected)
         UISetColor(Blue_);
-    [label_ drawAtPoint:CGPointMake(58, 29) forWidth:225 withFont:Font12_ ellipsis:2];
+    [label_ drawAtPoint:CGPointMake(58, 29) forWidth:(width - 95) withFont:Font12_ ellipsis:2];
 
     if (!selected)
         UISetColor(Gray_);
-    [description_ drawAtPoint:CGPointMake(12, 46) forWidth:280 withFont:Font14_ ellipsis:2];
+    [description_ drawAtPoint:CGPointMake(12, 46) forWidth:(width - 40) withFont:Font14_ ellipsis:2];
 
     [super drawContentInRect:rect selected:selected];
 }
@@ -5581,11 +5702,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     NSError *error_;
 
     //NSURLConnection *installer_;
+    NSURLConnection *trivial_;
     NSURLConnection *trivial_bz2_;
     NSURLConnection *trivial_gz_;
     //NSURLConnection *automatic_;
 
-    BOOL trivial_;
+    BOOL cydia_;
 }
 
 - (id) initWithBook:(RVBook *)book database:(Database *)database;
@@ -5614,6 +5736,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         [error_ release];
 
     //[self _deallocConnection:installer_];
+    [self _deallocConnection:trivial_];
     [self _deallocConnection:trivial_gz_];
     [self _deallocConnection:trivial_bz2_];
     //[self _deallocConnection:automatic_];
@@ -5632,9 +5755,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         case 0: return UCLocalize("ENTERED_BY_USER");
         case 1: return UCLocalize("INSTALLED_BY_PACKAGE");
 
-        default:
-            _assert(false);
-            return nil;
+        _nodefault
     }
 }
 
@@ -5643,9 +5764,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         case 0: return 0;
         case 1: return offset_;
 
-        default:
-            _assert(false);
-            return -1;
+        _nodefault
     }
 }
 
@@ -5724,7 +5843,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     if (colon.location != NSNotFound)
         href = [href substringFromIndex:(colon.location + 3)];
     href = [href stringByAddingPercentEscapes];
-    href = [@"http://cydia.saurik.com/api/repotag/" stringByAppendingString:href];
+    href = [CydiaURL(@"api/repotag/") stringByAppendingString:href];
     href = [href stringByCachingURLWithCurrentCDN];
 
     NSURL *url([NSURL URLWithString:href]);
@@ -5739,7 +5858,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
 - (void) _endConnection:(NSURLConnection *)connection {
     NSURLConnection **field = NULL;
-    if (connection == trivial_bz2_)
+    if (connection == trivial_)
+        field = &trivial_;
+    else if (connection == trivial_bz2_)
         field = &trivial_bz2_;
     else if (connection == trivial_gz_)
         field = &trivial_gz_;
@@ -5748,51 +5869,51 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     *field = nil;
 
     if (
+        trivial_ == nil &&
         trivial_bz2_ == nil &&
         trivial_gz_ == nil
     ) {
         bool defer(false);
 
-        if (trivial_) {
+        if (cydia_) {
             if (NSString *warning = [self yieldToSelector:@selector(getWarning)]) {
                 defer = true;
 
-                UIActionSheet *sheet = [[[UIActionSheet alloc]
+                UIAlertView *alert = [[[UIAlertView alloc]
                     initWithTitle:UCLocalize("SOURCE_WARNING")
-                    buttons:[NSArray arrayWithObjects:UCLocalize("ADD_ANYWAY"), UCLocalize("CANCEL"), nil]
-                    defaultButtonIndex:0
-                    delegate:self
-                    context:@"warning"
+                                       message:warning
+                                       delegate:self
+                                       cancelButtonTitle:UCLocalize("CANCEL")
+                    otherButtonTitles:UCLocalize("ADD_ANYWAY"), nil
                 ] autorelease];
 
-                [sheet setNumberOfRows:1];
-
-                [sheet setBodyText:warning];
-                [sheet popupAlertAnimated:YES];
+                               [alert setContext:@"warning"];
+                [alert setNumberOfRows:1];
+                [alert show];
             } else
                 [self complete];
         } else if (error_ != nil) {
-            UIActionSheet *sheet = [[[UIActionSheet alloc]
+            UIAlertView *alert = [[[UIAlertView alloc]
                 initWithTitle:UCLocalize("VERIFICATION_ERROR")
-                buttons:[NSArray arrayWithObjects:UCLocalize("OK"), nil]
-                defaultButtonIndex:0
-                delegate:self
-                context:@"urlerror"
+                               message:[error_ localizedDescription]
+                               delegate:self
+                               cancelButtonTitle:UCLocalize("OK")
+                otherButtonTitles:nil
             ] autorelease];
 
-            [sheet setBodyText:[error_ localizedDescription]];
-            [sheet popupAlertAnimated:YES];
+                       [alert setContext:@"urlerror"];
+            [alert show];
         } else {
-            UIActionSheet *sheet = [[[UIActionSheet alloc]
+            UIAlertView *alert = [[[UIAlertView alloc]
                 initWithTitle:UCLocalize("NOT_REPOSITORY")
-                buttons:[NSArray arrayWithObjects:UCLocalize("OK"), nil]
-                defaultButtonIndex:0
-                delegate:self
-                context:@"trivial"
+                               message:UCLocalize("NOT_REPOSITORY_EX")
+                               delegate:self
+                               cancelButtonTitle:UCLocalize("OK")
+                otherButtonTitles:nil
             ] autorelease];
 
-            [sheet setBodyText:UCLocalize("NOT_REPOSITORY_EX")];
-            [sheet popupAlertAnimated:YES];
+                       [alert setContext:@"trivial"];
+            [alert show];
         }
 
         [delegate_ setStatusBarShowsProgress:NO];
@@ -5816,7 +5937,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 - (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response {
     switch ([response statusCode]) {
         case 200:
-            trivial_ = YES;
+            cydia_ = YES;
     }
 }
 
@@ -5835,7 +5956,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     NSMutableURLRequest *request = [NSMutableURLRequest
         requestWithURL:[NSURL URLWithString:href]
         cachePolicy:NSURLRequestUseProtocolCachePolicy
-        timeoutInterval:20.0
+        timeoutInterval:120.0
     ];
 
     [request setHTTPMethod:method];
@@ -5844,20 +5965,19 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         [request setValue:[NSString stringWithUTF8String:Machine_] forHTTPHeaderField:@"X-Machine"];
     if (UniqueID_ != nil)
         [request setValue:UniqueID_ forHTTPHeaderField:@"X-Unique-ID"];
-
     if (Role_ != nil)
         [request setValue:Role_ forHTTPHeaderField:@"X-Role"];
 
     return [[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease];
 }
 
-- (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button {
-    NSString *context([sheet context]);
+- (void)alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)button {
+    NSString *context([alert context]);
 
     if ([context isEqualToString:@"source"]) {
         switch (button) {
             case 1: {
-                NSString *href = [[sheet textField] text];
+                NSString *href = [[alert textField] text];
 
                 //installer_ = [[self _requestHRef:href method:@"GET"] retain];
 
@@ -5867,46 +5987,44 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
                     href_ = href;
                 href_ = [href_ retain];
 
-                trivial_bz2_ = [[self _requestHRef:[href_ stringByAppendingString:@"Packages"] method:@"HEAD"] retain];
+                trivial_ = [[self _requestHRef:[href_ stringByAppendingString:@"Packages"] method:@"HEAD"] retain];
                 trivial_bz2_ = [[self _requestHRef:[href_ stringByAppendingString:@"Packages.bz2"] method:@"HEAD"] retain];
                 trivial_gz_ = [[self _requestHRef:[href_ stringByAppendingString:@"Packages.gz"] method:@"HEAD"] retain];
                 //trivial_bz2_ = [[self _requestHRef:[href stringByAppendingString:@"dists/Release"] method:@"HEAD"] retain];
 
-                trivial_ = false;
+                cydia_ = false;
 
                 hud_ = [[delegate_ addProgressHUD] retain];
                 [hud_ setText:UCLocalize("VERIFYING_URL")];
             } break;
 
-            case 2:
+            case 0:
             break;
 
-            default:
-                _assert(false);
+            _nodefault
         }
 
-        [sheet dismiss];
+        [alert dismissWithClickedButtonIndex:-1 animated:YES];
     } else if ([context isEqualToString:@"trivial"])
-        [sheet dismiss];
+        [alert dismissWithClickedButtonIndex:-1 animated:YES];
     else if ([context isEqualToString:@"urlerror"])
-        [sheet dismiss];
+        [alert dismissWithClickedButtonIndex:-1 animated:YES];
     else if ([context isEqualToString:@"warning"]) {
         switch (button) {
             case 1:
                 [self complete];
             break;
 
-            case 2:
+            case 0:
             break;
 
-            default:
-                _assert(false);
+            _nodefault
         }
 
         [href_ release];
         href_ = nil;
 
-        [sheet dismiss];
+        [alert dismissWithClickedButtonIndex:-1 animated:YES];
     }
 }
 
@@ -5917,9 +6035,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
         //list_ = [[UITable alloc] initWithFrame:[self bounds]];
         list_ = [[UISectionList alloc] initWithFrame:[self bounds] showSectionIndex:NO];
-        [list_ setShouldHideHeaderInShortLists:NO];
-
+        [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
         [self addSubview:list_];
+
+        [list_ setShouldHideHeaderInShortLists:NO];
         [list_ setDataSource:self];
 
         UITableColumn *column = [[UITableColumn alloc]
@@ -5935,14 +6054,14 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
         [self reloadData];
 
-        [self setAutoresizingMask:UIViewAutoresizingFlexibleHeight];
-        [list_ setAutoresizingMask:UIViewAutoresizingFlexibleHeight];
+        [self setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
     } return self;
 }
 
 - (void) reloadData {
     pkgSourceList list;
-    _assert(list.ReadMainList());
+    if (!list.ReadMainList())
+        return;
 
     [sources_ removeAllObjects];
     [sources_ addObjectsFromArray:[database_ sources]];
@@ -5950,7 +6069,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [sources_ sortUsingSelector:@selector(compareByNameAndType:)];
     _trace();
 
-    int count = [sources_ count];
+    int count([sources_ count]);
     for (offset_ = 0; offset_ != count; ++offset_) {
         Source *source = [sources_ objectAtIndex:offset_];
         if ([source record] == nil)
@@ -5970,26 +6089,28 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         database:database_
     ] autorelease]];*/
 
-    UIActionSheet *sheet = [[[UIActionSheet alloc]
+    UIAlertView *alert = [[[UIAlertView alloc]
         initWithTitle:UCLocalize("ENTER_APT_URL")
-        buttons:[NSArray arrayWithObjects:UCLocalize("ADD_SOURCE"), UCLocalize("CANCEL"), nil]
-        defaultButtonIndex:0
-        delegate:self
-        context:@"source"
+               message:nil
+               delegate:self
+               cancelButtonTitle:UCLocalize("CANCEL")
+               otherButtonTitles:UCLocalize("ADD_SOURCE"), nil
     ] autorelease];
 
-    [sheet setNumberOfRows:1];
+       [alert setContext:@"source"];
+       [alert setTransform:CGAffineTransformTranslate([alert transform], 0.0, 100.0)];
 
-    [sheet addTextFieldWithValue:@"http://" label:@""];
+    [alert setNumberOfRows:1];
+    [alert addTextFieldWithValue:@"http://" label:@""];
 
-    UITextInputTraits *traits = [[sheet textField] textInputTraits];
+    UITextInputTraits *traits = [[alert textField] textInputTraits];
     [traits setAutocapitalizationType:UITextAutocapitalizationTypeNone];
     [traits setAutocorrectionType:UITextAutocorrectionTypeNo];
     [traits setKeyboardType:UIKeyboardTypeURL];
     // XXX: UIReturnKeyDone
     [traits setReturnKeyType:UIReturnKeyNext];
 
-    [sheet popupAlertAnimated:YES];
+    [alert show];
 }
 
 - (void) _rightButtonClicked {
@@ -6048,10 +6169,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
             with:[NSNumber numberWithBool:YES]
         ];
 
+        [packages_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
         [self addSubview:packages_];
 
-        [self setAutoresizingMask:UIViewAutoresizingFlexibleHeight];
-        [packages_ setAutoresizingMask:UIViewAutoresizingFlexibleHeight];
+        [self setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
     } return self;
 }
 
@@ -6102,46 +6223,28 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
 @implementation HomeView
 
-- (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button {
-    NSString *context([sheet context]);
-
-    if ([context isEqualToString:@"about"])
-        [sheet dismiss];
-    else
-        [super alertSheet:sheet buttonClicked:button];
-}
-
 - (void) _setMoreHeaders:(NSMutableURLRequest *)request {
     [super _setMoreHeaders:request];
     if (ChipID_ != nil)
         [request setValue:ChipID_ forHTTPHeaderField:@"X-Chip-ID"];
+    if (UniqueID_ != nil)
+        [request setValue:UniqueID_ forHTTPHeaderField:@"X-Unique-ID"];
 }
 
 - (void) _leftButtonClicked {
-    UIActionSheet *sheet = [[[UIActionSheet alloc]
-        initWithTitle:UCLocalize("ABOUT_CYDIA")
-        buttons:[NSArray arrayWithObjects:UCLocalize("CLOSE"), nil]
-        defaultButtonIndex:0
-        delegate:self
-        context:@"about"
-    ] autorelease];
+    UIAlertView *alert = [[[UIAlertView alloc] init] autorelease];
+    [alert setTitle:UCLocalize("ABOUT_CYDIA")];
+    [alert addButtonWithTitle:UCLocalize("CLOSE")];
+    [alert setCancelButtonIndex:0];
 
-    [sheet setBodyText:
-        @"Copyright (C) 2008-2009\n"
+    [alert setMessage:
+        @"Copyright (C) 2008-2010\n"
         "Jay Freeman (saurik)\n"
         "saurik@saurik.com\n"
-        "http://www.saurik.com/\n"
-        "\n"
-        "The Okori Group\n"
-        "http://www.theokorigroup.com/\n"
-        "\n"
-        "College of Creative Studies,\n"
-        "University of California,\n"
-        "Santa Barbara\n"
-        "http://www.ccs.ucsb.edu/"
+        "http://www.saurik.com/"
     ];
 
-    [sheet popupAlertAnimated:YES];
+    [alert show];
 }
 
 - (NSString *) leftButtonTitle {
@@ -6164,6 +6267,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
 - (void) _leftButtonClicked {
     [delegate_ askForSettings];
+    [delegate_ updateData];
 }
 
 - (NSString *) leftButtonTitle {
@@ -6203,11 +6307,13 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     UIProgressBar *progress_;
     UINavigationButton *cancel_;
     bool updating_;
+    bool dropped_;
 }
 
 - (id) initWithFrame:(CGRect)frame database:(Database *)database;
 - (void) update;
 - (BOOL) updating;
+- (void) setUpdate:(NSDate *)date;
 
 @end
 
@@ -6230,7 +6336,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     return updating_;
 }
 
-- (void) update {
+- (void) dropBar {
+    if (dropped_)
+        return;
+    dropped_ = true;
+
     [UIView beginAnimations:nil context:NULL];
 
     CGRect ovrframe = [overlay_ frame];
@@ -6247,6 +6357,37 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [transition_ setFrame:trnframe];
 
     [UIView endAnimations];
+}
+
+- (void) raiseBar {
+    if (!dropped_)
+        return;
+    dropped_ = false;
+
+    [UIView beginAnimations:nil context:NULL];
+
+    CGRect ovrframe = [overlay_ frame];
+    ovrframe.origin.y = -ovrframe.size.height;
+    [overlay_ setFrame:ovrframe];
+
+    CGRect barframe = [navbar_ frame];
+    barframe.origin.y -= ovrframe.size.height;
+    [navbar_ setFrame:barframe];
+
+    CGRect trnframe = [transition_ frame];
+    trnframe.origin.y -= ovrframe.size.height;
+    trnframe.size.height += ovrframe.size.height;
+    [transition_ setFrame:trnframe];
+
+    [UIView commitAnimations];
+}
+
+- (void) setUpdate:(NSDate *)date {
+    [self update];
+}
+
+- (void) update {
+    [self dropBar];
 
     [indicator_ startAnimation];
     [prompt_ setText:UCLocalize("UPDATING_DATABASE")];
@@ -6269,75 +6410,46 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         [sheet dismiss];
 }
 
-- (void) _update_:(NSString *)error {
+- (void) _update_ {
     updating_ = false;
 
     [indicator_ stopAnimation];
 
-    [UIView beginAnimations:nil context:NULL];
+    [self raiseBar];
 
-    CGRect ovrframe = [overlay_ frame];
-    ovrframe.origin.y = -ovrframe.size.height;
-    [overlay_ setFrame:ovrframe];
-
-    CGRect barframe = [navbar_ frame];
-    barframe.origin.y -= ovrframe.size.height;
-    [navbar_ setFrame:barframe];
-
-    CGRect trnframe = [transition_ frame];
-    trnframe.origin.y -= ovrframe.size.height;
-    trnframe.size.height += ovrframe.size.height;
-    [transition_ setFrame:trnframe];
-
-    [UIView commitAnimations];
-
-    if (error == nil)
-        [delegate_ performSelector:@selector(reloadData) withObject:nil afterDelay:0];
-    else {
-        UIActionSheet *sheet = [[[UIActionSheet alloc]
-            initWithTitle:[NSString stringWithFormat:UCLocalize("COLON_DELIMITED"), UCLocalize("ERROR"), UCLocalize("REFRESH")]
-            buttons:[NSArray arrayWithObjects:
-                UCLocalize("OK"),
-            nil]
-            defaultButtonIndex:0
-            delegate:self
-            context:@"refresh"
-        ] autorelease];
-
-        [sheet setBodyText:error];
-        [sheet popupAlertAnimated:YES];
-
-        [self reloadButtons];
-    }
+    [delegate_ performSelector:@selector(reloadData) withObject:nil afterDelay:0];
 }
 
 - (id) initWithFrame:(CGRect)frame database:(Database *)database {
     if ((self = [super initWithFrame:frame]) != nil) {
         database_ = database;
 
-        CGRect ovrrect = [navbar_ bounds];
+        CGRect ovrrect([navbar_ bounds]);
         ovrrect.size.height = [UINavigationBar defaultSize].height;
         ovrrect.origin.y = -ovrrect.size.height;
 
         overlay_ = [[UINavigationBar alloc] initWithFrame:ovrrect];
+        [overlay_ setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
         [self addSubview:overlay_];
 
         ovrrect.origin.y = frame.size.height;
         underlay_ = [[UINavigationBar alloc] initWithFrame:ovrrect];
-        [underlay_ setTintColor:[UIColor colorWithRed:0.23 green:0.23 blue:0.23 alpha:1]];
+        [underlay_ setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
         [self addSubview:underlay_];
 
+        [underlay_ setTintColor:[UIColor colorWithRed:0.23 green:0.23 blue:0.23 alpha:1]];
+
         [overlay_ setBarStyle:1];
         [underlay_ setBarStyle:1];
 
-        int barstyle = [overlay_ _barStyle:NO];
-        bool ugly = barstyle == 0;
+        int barstyle([overlay_ _barStyle:NO]);
+        bool ugly(barstyle == 0);
 
         UIProgressIndicatorStyle style = ugly ?
             UIProgressIndicatorStyleMediumBrown :
             UIProgressIndicatorStyleMediumWhite;
 
-        CGSize indsize = [UIProgressIndicator defaultSizeForStyle:style];
+        CGSize indsize([UIProgressIndicator defaultSizeForStyle:style]);
         unsigned indoffset = (ovrrect.size.height - indsize.height) / 2;
         CGRect indrect = {{indoffset, indoffset}, indsize};
 
@@ -6349,13 +6461,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
         CGRect prmrect = {{
             indoffset * 2 + indsize.width,
-#ifdef __OBJC2__
-            -1 +
-#endif
-            unsigned(ovrrect.size.height - prmsize.height) / 2
+            unsigned(ovrrect.size.height - prmsize.height) / 2 - 1
         }, prmsize};
 
-        UIFont *font = [UIFont systemFontOfSize:15];
+        UIFont *font([UIFont systemFontOfSize:15]);
 
         prompt_ = [[UITextLabel alloc] initWithFrame:prmrect];
 
@@ -6373,10 +6482,13 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         } , prgsize};
 
         progress_ = [[UIProgressBar alloc] initWithFrame:prgrect];
-        [progress_ setStyle:0];
+        [progress_ setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
         [overlay_ addSubview:progress_];
 
+        [progress_ setStyle:0];
+
         cancel_ = [[UINavigationButton alloc] initWithTitle:UCLocalize("CANCEL") style:UINavigationButtonStyleHighlighted];
+        [progress_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin];
         [cancel_ addTarget:self action:@selector(_onCancel) forControlEvents:UIControlEventTouchUpInside];
 
         CGRect frame = [cancel_ frame];
@@ -6396,20 +6508,38 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 - (void) _update { _pooled
     Status status;
     status.setDelegate(self);
-
-    NSString *error([database_ updateWithStatus:status]);
+    [database_ updateWithStatus:status];
 
     [self
-        performSelectorOnMainThread:@selector(_update_:)
-        withObject:error
+        performSelectorOnMainThread:@selector(_update_)
+        withObject:nil
         waitUntilDone:NO
     ];
 }
 
-- (void) setProgressError:(NSString *)error forPackage:(NSString *)id {
+- (void) setProgressError:(NSString *)error withTitle:(NSString *)title {
     [prompt_ setText:[NSString stringWithFormat:UCLocalize("COLON_DELIMITED"), UCLocalize("ERROR"), error]];
 }
 
+/*
+    UIActionSheet *sheet = [[[UIActionSheet alloc]
+        initWithTitle:[NSString stringWithFormat:UCLocalize("COLON_DELIMITED"), UCLocalize("ERROR"), UCLocalize("REFRESH")]
+        buttons:[NSArray arrayWithObjects:
+            UCLocalize("OK"),
+        nil]
+        defaultButtonIndex:0
+        delegate:self
+        context:@"refresh"
+    ] autorelease];
+
+    [sheet setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];
+
+    [sheet setBodyText:error];
+    [sheet popupAlertAnimated:YES];
+
+    [self reloadButtons];
+*/
+
 - (void) setProgressTitle:(NSString *)title {
     [self
         performSelectorOnMainThread:@selector(_setProgressTitle:)
@@ -6560,7 +6690,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     _transient Database *database_;
     NSMutableArray *sections_;
     NSMutableArray *filtered_;
-    UITransitionView *transition_;
     UITable *list_;
     UIView *accessory_;
     BOOL editing_;
@@ -6580,7 +6709,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
     [sections_ release];
     [filtered_ release];
-    [transition_ release];
     [list_ release];
     [accessory_ release];
     [super dealloc];
@@ -6642,7 +6770,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         initWithBook:book_
         database:database_
         title:title
-        filter:@selector(isVisiblyUninstalledInSection:)
+        filter:@selector(isVisibleInSection:)
         with:name
     ] autorelease];
 
@@ -6658,11 +6786,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         sections_ = [[NSMutableArray arrayWithCapacity:16] retain];
         filtered_ = [[NSMutableArray arrayWithCapacity:16] retain];
 
-        transition_ = [[UITransitionView alloc] initWithFrame:[self bounds]];
-        [self addSubview:transition_];
-
-        list_ = [[UITable alloc] initWithFrame:[transition_ bounds]];
-        [transition_ transition:0 toView:list_];
+        list_ = [[UITable alloc] initWithFrame:[self bounds]];
+        [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+        [self addSubview:list_];
 
         UITableColumn *column = [[[UITableColumn alloc]
             initWithTitle:UCLocalize("NAME")
@@ -6678,8 +6804,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
         [self reloadData];
 
-        [self setAutoresizingMask:UIViewAutoresizingFlexibleHeight];
-        [list_ setAutoresizingMask:UIViewAutoresizingFlexibleHeight];
+        [self setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
     } return self;
 }
 
@@ -6717,7 +6842,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         [*section addToCount];
 
         _profile(SectionsView$reloadData$Filter)
-            if (![package valid] || ![package uninstalled] || ![package visible])
+            if (![package valid] || ![package visible])
                 continue;
         _end
 
@@ -6738,7 +6863,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         [section addToCount];
 
         _profile(SectionsView$reloadData$Filter)
-            if (![package valid] || ![package uninstalled] || ![package visible])
+            if (![package valid] || ![package visible])
                 continue;
         _end
 
@@ -6789,7 +6914,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (NSString *) title {
-    return editing_ ? UCLocalize("SECTION_VISIBILITY") : UCLocalize("INSTALL_BY_SECTION");
+    return editing_ ? UCLocalize("SECTION_VISIBILITY") : UCLocalize("SECTIONS");
 }
 
 - (NSString *) backButtonTitle {
@@ -6819,7 +6944,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     unsigned upgrades_;
 }
 
-- (id) initWithBook:(RVBook *)book database:(Database *)database;
+- (id) initWithBook:(RVBook *)book database:(Database *)database delegate:(id)delegate;
 - (void) reloadData;
 
 @end
@@ -6890,7 +7015,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [delegate_ distUpgrade];
 }
 
-- (id) initWithBook:(RVBook *)book database:(Database *)database {
+- (id) initWithBook:(RVBook *)book database:(Database *)database delegate:(id)delegate {
     if ((self = [super initWithBook:book]) != nil) {
         database_ = database;
 
@@ -6898,6 +7023,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         sections_ = [[NSMutableArray arrayWithCapacity:16] retain];
 
         list_ = [[UITableView alloc] initWithFrame:[self bounds] style:UITableViewStylePlain];
+        [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
         [self addSubview:list_];
 
         //XXX:[list_ setShouldHideHeaderInShortLists:NO];
@@ -6905,19 +7031,14 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         [list_ setDelegate:self];
         //[list_ setSectionListStyle:1];
 
+        delegate_ = delegate;
         [self reloadData];
 
-        [self setAutoresizingMask:UIViewAutoresizingFlexibleHeight];
-        [list_ setAutoresizingMask:UIViewAutoresizingFlexibleHeight];
+        [self setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
     } return self;
 }
 
-- (void) reloadData {
-    NSArray *packages = [database_ packages];
-
-    [packages_ removeAllObjects];
-    [sections_ removeAllObjects];
-
+- (void) _reloadPackages:(NSArray *)packages {
     _trace();
     for (Package *package in packages)
         if (
@@ -6929,6 +7050,20 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     _trace();
     [packages_ radixSortUsingFunction:reinterpret_cast<SKRadixFunction>(&PackageChangesRadix) withContext:NULL];
     _trace();
+}
+
+- (void) reloadData {
+    NSArray *packages = [database_ packages];
+
+    [packages_ removeAllObjects];
+    [sections_ removeAllObjects];
+
+    UIProgressHUD *hud([delegate_ addProgressHUD]);
+    // XXX: localize
+    [hud setText:@"Loading Changes"];
+    NSLog(@"HUD:%@::%@", delegate_, hud);
+    [self yieldToSelector:@selector(_reloadPackages:) withObject:packages];
+    [delegate_ removeProgressHUD:hud];
 
     Section *upgradable = [[[Section alloc] initWithName:UCLocalize("AVAILABLE_UPGRADES") localize:NO] autorelease];
     Section *ignored = [[[Section alloc] initWithName:UCLocalize("IGNORED_UPGRADES") localize:NO] autorelease];
@@ -7025,11 +7160,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 @interface SearchView : RVPage {
     UIView *accessory_;
     UISearchField *field_;
-    UITransitionView *transition_;
     FilteredPackageTable *table_;
-    UIPreferencesTable *advanced_;
-    UIView *dimmed_;
-    bool flipped_;
     bool reload_;
 }
 
@@ -7045,33 +7176,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
     [accessory_ release];
     [field_ release];
-    [transition_ release];
     [table_ release];
-    [advanced_ release];
-    [dimmed_ release];
     [super dealloc];
 }
 
-- (int) numberOfGroupsInPreferencesTable:(UIPreferencesTable *)table {
-    return 1;
-}
-
-- (NSString *) preferencesTable:(UIPreferencesTable *)table titleForGroup:(int)group {
-    switch (group) {
-        case 0: return [NSString stringWithFormat:UCLocalize("PARENTHETICAL"), UCLocalize("ADVANCED_SEARCH"), UCLocalize("COMING_SOON")];
-
-        default: _assert(false);
-    }
-}
-
-- (int) preferencesTable:(UIPreferencesTable *)table numberOfRowsInGroup:(int)group {
-    switch (group) {
-        case 0: return 0;
-
-        default: _assert(false);
-    }
-}
-
 - (void) _showKeyboard:(BOOL)show {
     CGSize keysize = [UIKeyboard defaultSize];
     CGRect keydown = [book_ pageBounds];
@@ -7102,21 +7210,26 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     if (show)
         [animator performSelector:@selector(startAnimation:) withObject:animation afterDelay:delay];
 
-    [delegate_ showKeyboard:show];
+    //[delegate_ showKeyboard:show];
 }
 
 - (void) textFieldDidBecomeFirstResponder:(UITextField *)field {
     [self _showKeyboard:YES];
+    [table_ setObject:[field_ text] forFilter:@selector(isUnfilteredAndSelectedForBy:)];
+    [self reloadData];
 }
 
 - (void) textFieldDidResignFirstResponder:(UITextField *)field {
     [self _showKeyboard:NO];
+    [table_ setObject:[field_ text] forFilter:@selector(isUnfilteredAndSearchedForBy:)];
+    [self reloadData];
 }
 
 - (void) keyboardInputChanged:(UIFieldEditor *)editor {
     if (reload_) {
         NSString *text([field_ text]);
         [field_ setClearButtonStyle:(text == nil || [text length] == 0 ? 0 : 2)];
+        [table_ setObject:text forFilter:@selector(isUnfilteredAndSelectedForBy:)];
         [self reloadData];
         reload_ = false;
     }
@@ -7144,19 +7257,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     if ((self = [super initWithBook:book]) != nil) {
         CGRect pageBounds = [book_ pageBounds];
 
-        transition_ = [[UITransitionView alloc] initWithFrame:pageBounds];
-        [self addSubview:transition_];
-
-        advanced_ = [[UIPreferencesTable alloc] initWithFrame:pageBounds];
-
-        [advanced_ setReusesTableCells:YES];
-        [advanced_ setDataSource:self];
-        [advanced_ reloadData];
-
-        dimmed_ = [[UIView alloc] initWithFrame:pageBounds];
-        CGColor dimmed(space_, 0, 0, 0, 0.5);
-        [dimmed_ setBackgroundColor:[UIColor colorWithCGColor:dimmed]];
-
         table_ = [[FilteredPackageTable alloc]
             initWithBook:book
             database:database
@@ -7165,28 +7265,23 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
             with:nil
         ];
 
+        [table_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+        [self addSubview:table_];
+
         [table_ setShouldHideHeaderInShortLists:NO];
-        [transition_ transition:0 toView:table_];
 
-        CGRect cnfrect = {{
-#ifdef __OBJC2__
-        6 +
-#endif
-        1, 38}, {17, 18}};
+        CGRect cnfrect = {{7, 38}, {17, 18}};
 
         CGRect area;
-        area.origin.x = /*cnfrect.origin.x + cnfrect.size.width + 4 +*/ 10;
-        area.origin.y = 1;
 
-        area.size.width =
-#ifdef __OBJC2__
-            8 +
-#endif
-            [self bounds].size.width - area.origin.x - 18;
+        area.origin.x = 10;
+        area.origin.y = 1;
 
+        area.size.width = [self bounds].size.width - area.origin.x * 2;
         area.size.height = [UISearchField defaultHeight];
 
         field_ = [[UISearchField alloc] initWithFrame:area];
+        [field_ setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
 
         UIFont *font = [UIFont systemFontOfSize:16];
         [field_ setFont:font];
@@ -7204,43 +7299,14 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         CGRect accrect = {{0, 6}, {6 + cnfrect.size.width + 6 + area.size.width + 6, area.size.height}};
 
         accessory_ = [[UIView alloc] initWithFrame:accrect];
+        [accessory_ setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
         [accessory_ addSubview:field_];
 
-        /*UIPushButton *configure = [[[UIPushButton alloc] initWithFrame:cnfrect] autorelease];
-        [configure setShowPressFeedback:YES];
-        [configure setImage:[UIImage applicationImageNamed:@"advanced.png"]];
-        [configure addTarget:self action:@selector(configurePushed) forEvents:1];
-        [accessory_ addSubview:configure];*/
-
-        [self setAutoresizingMask:UIViewAutoresizingFlexibleHeight];
-        [table_ setAutoresizingMask:UIViewAutoresizingFlexibleHeight];
+        [self setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
     } return self;
 }
 
-- (void) flipPage {
-#ifndef __OBJC2__
-    LKAnimation *animation = [LKTransition animation];
-    [animation setType:@"oglFlip"];
-    [animation setTimingFunction:[LKTimingFunction functionWithName:@"easeInEaseOut"]];
-    [animation setFillMode:@"extended"];
-    [animation setTransitionFlags:3];
-    [animation setDuration:10];
-    [animation setSpeed:0.35];
-    [animation setSubtype:(flipped_ ? @"fromLeft" : @"fromRight")];
-    [[transition_ _layer] addAnimation:animation forKey:0];
-    [transition_ transition:0 toView:(flipped_ ? (UIView *) table_ : (UIView *) advanced_)];
-    flipped_ = !flipped_;
-#endif
-}
-
-- (void) configurePushed {
-    [field_ resignFirstResponder];
-    [self flipPage];
-}
-
 - (void) resetViewAnimated:(BOOL)animated {
-    if (flipped_)
-        [self flipPage];
     [table_ resetViewAnimated:animated];
 }
 
@@ -7248,9 +7314,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (void) reloadData {
-    if (flipped_)
-        [self flipPage];
-    [table_ setObject:[field_ text]];
     _profile(SearchView$reloadData)
         [table_ reloadData];
     _end
@@ -7324,7 +7387,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         case 0: return nil;
         case 1: return nil;
 
-        default: _assert(false);
+        _nodefault
     }
 
     return nil;
@@ -7338,7 +7401,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         case 0: return NO;
         case 1: return YES;
 
-        default: _assert(false);
+        _nodefault
     }
 
     return NO;
@@ -7352,7 +7415,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         case 0: return 1;
         case 1: return 1;
 
-        default: _assert(false);
+        _nodefault
     }
 
     return 0;
@@ -7397,7 +7460,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
                 return subscribedCell_;
             case 1:
                 return ignoredCell_;
-            default: _assert(false);
+            _nodefault
         } break;
 
         case 1: switch (row) {
@@ -7408,10 +7471,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
                 return cell;
             }
 
-            default: _assert(false);
+            _nodefault
         } break;
 
-        default: _assert(false);
+        _nodefault
     }
 
     return nil;
@@ -7510,6 +7573,19 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 @end
 /* }}} */
 
+@interface CydiaViewController : UIViewController {
+}
+
+@end
+
+@implementation CydiaViewController
+
+- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation {
+    return NO; // XXX: return YES;
+}
+
+@end
+
 @interface Cydia : UIApplication <
     ConfirmationViewDelegate,
     ProgressViewDelegate,
@@ -7517,11 +7593,14 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     CydiaDelegate
 > {
     UIWindow *window_;
+    CydiaViewController *root_;
 
     UIView *underlay_;
     UIView *overlay_;
     CYBook *book_;
-    UIToolbar *buttonbar_;
+
+    NSArray *items_;
+    UITabBar *toolbar_;
 
     RVBook *confirm_;
 
@@ -7531,7 +7610,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     Database *database_;
     ProgressView *progress_;
 
-    unsigned tag_;
+    int tag_;
 
     UIKeyboard *keyboard_;
     UIProgressHUD *hud_;
@@ -7546,44 +7625,48 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 #endif
 }
 
+- (RVPage *) _pageForURL:(NSURL *)url withClass:(Class)_class;
+- (void) setPage:(RVPage *)page;
+
 @end
 
+static _finline void _setHomePage(Cydia *self) {
+    [self setPage:[self _pageForURL:[NSURL URLWithString:CydiaURL(@"")] withClass:[HomeView class]]];
+}
+
 @implementation Cydia
 
+- (UIView *) rotatingContentViewForWindow:(UIWindow *)window {
+    return window_;
+}
+
 - (void) _loaded {
     if ([broken_ count] != 0) {
         int count = [broken_ count];
 
-        UIActionSheet *sheet = [[[UIActionSheet alloc]
+        UIAlertView *alert = [[[UIAlertView alloc]
             initWithTitle:(count == 1 ? UCLocalize("HALFINSTALLED_PACKAGE") : [NSString stringWithFormat:UCLocalize("HALFINSTALLED_PACKAGES"), count])
-            buttons:[NSArray arrayWithObjects:
-                UCLocalize("FORCIBLY_CLEAR"),
-                UCLocalize("TEMPORARY_IGNORE"),
-            nil]
-            defaultButtonIndex:0
-            delegate:self
-            context:@"fixhalf"
+                       message:UCLocalize("HALFINSTALLED_PACKAGE_EX")
+                       delegate:self
+                       cancelButtonTitle:UCLocalize("FORCIBLY_CLEAR")
+                       otherButtonTitles:UCLocalize("TEMPORARY_IGNORE"), nil
         ] autorelease];
 
-        [sheet setBodyText:UCLocalize("HALFINSTALLED_PACKAGE_EX")];
-        [sheet popupAlertAnimated:YES];
+        [alert setContext:@"fixhalf"];
+        [alert show];
     } else if (!Ignored_ && [essential_ count] != 0) {
         int count = [essential_ count];
 
-        UIActionSheet *sheet = [[[UIActionSheet alloc]
+        UIAlertView *alert = [[[UIAlertView alloc]
             initWithTitle:(count == 1 ? UCLocalize("ESSENTIAL_UPGRADE") : [NSString stringWithFormat:UCLocalize("ESSENTIAL_UPGRADES"), count])
-            buttons:[NSArray arrayWithObjects:
-                UCLocalize("UPGRADE_ESSENTIAL"),
-                UCLocalize("COMPLETE_UPGRADE"),
-                UCLocalize("TEMPORARY_IGNORE"),
-            nil]
-            defaultButtonIndex:0
-            delegate:self
-            context:@"upgrade"
+                       message:UCLocalize("ESSENTIAL_UPGRADE_EX")
+                       delegate:self
+                       cancelButtonTitle:UCLocalize("TEMPORARY_IGNORE")
+            otherButtonTitles:UCLocalize("UPGRADE_ESSENTIAL"), UCLocalize("COMPLETE_UPGRADE"), nil
         ] autorelease];
 
-        [sheet setBodyText:UCLocalize("ESSENTIAL_UPGRADE_EX")];
-        [sheet popupAlertAnimated:YES];
+        [alert setContext:@"upgrade"];
+        [alert show];
     }
 }
 
@@ -7610,11 +7693,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [self _saveConfig];
 
     /* XXX: this is just stupid */
-    if (tag_ != 2 && sections_ != nil)
+    if (tag_ != 1 && sections_ != nil)
         [sections_ reloadData];
-    if (tag_ != 3 && changes_ != nil)
+    if (tag_ != 2 && changes_ != nil)
         [changes_ reloadData];
-    if (tag_ != 5 && search_ != nil)
+    if (tag_ != 4 && search_ != nil)
         [search_ reloadData];
 
     [book_ reloadData];
@@ -7626,7 +7709,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     static bool loaded(false);
     UIProgressHUD *hud([self addProgressHUD]);
     [hud setText:(loaded ? UCLocalize("RELOADING_DATA") : UCLocalize("LOADING_DATA"))];
-    loaded = true;
 
     [database_ yieldToSelector:@selector(reloadData) withObject:nil];
     _trace();
@@ -7638,7 +7720,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [essential_ removeAllObjects];
     [broken_ removeAllObjects];
 
-    NSArray *packages = [database_ packages];
+    NSArray *packages([database_ packages]);
     for (Package *package in packages) {
         if ([package half])
             [broken_ addObject:package];
@@ -7651,17 +7733,17 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
     if (changes != 0) {
         NSString *badge([[NSNumber numberWithInt:changes] stringValue]);
-        [buttonbar_ setBadgeValue:badge forButton:3];
-        if ([buttonbar_ respondsToSelector:@selector(setBadgeAnimated:forButton:)])
-            [buttonbar_ setBadgeAnimated:([essential_ count] != 0) forButton:3];
+               [[[toolbar_ items] objectAtIndex:2] setBadgeValue:badge];
+        if ([toolbar_ respondsToSelector:@selector(setBadgeAnimated:forButton:)])
+                       [[[toolbar_ items] objectAtIndex:2] setAnimatedBadge:YES];
         if ([self respondsToSelector:@selector(setApplicationBadge:)])
             [self setApplicationBadge:badge];
         else
             [self setApplicationBadgeString:badge];
     } else {
-        [buttonbar_ setBadgeValue:nil forButton:3];
-        if ([buttonbar_ respondsToSelector:@selector(setBadgeAnimated:forButton:)])
-            [buttonbar_ setBadgeAnimated:NO forButton:3];
+               [[[toolbar_ items] objectAtIndex:2] setBadgeValue:nil];
+        if ([toolbar_ respondsToSelector:@selector(setBadgeAnimated:forButton:)])
+            [[[toolbar_ items] objectAtIndex:2] setAnimatedBadge:NO];
         if ([self respondsToSelector:@selector(removeApplicationBadge)])
             [self removeApplicationBadge];
         else // XXX: maybe use setApplicationBadgeString also?
@@ -7669,24 +7751,24 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     }
 
     Queuing_ = false;
-    [buttonbar_ setBadgeValue:nil forButton:4];
+    [[[toolbar_ items] objectAtIndex:3] setBadgeValue:nil];
 
     [self _updateData];
 
-    // XXX: what is this line of code for?
-    if ([packages count] == 0);
-    else if (Loaded_ || ManualRefresh) loaded:
+    if (loaded || ManualRefresh) loaded:
         [self _loaded];
     else {
-        Loaded_ = YES;
+        loaded = true;
 
-        if (NSDate *update = [Metadata_ objectForKey:@"LastUpdate"]) {
+        NSDate *update([Metadata_ objectForKey:@"LastUpdate"]);
+
+        if (update != nil) {
             NSTimeInterval interval([update timeIntervalSinceNow]);
-            if (interval <= 0 && interval > -600)
+            if (interval <= 0 && interval > -(15*60))
                 goto loaded;
         }
 
-        [book_ update];
+        [book_ setUpdate:update];
     }
 }
 
@@ -7700,13 +7782,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (void) syncData {
-    FILE *file = fopen("/etc/apt/sources.list.d/cydia.list", "w");
+    FILE *file(fopen("/etc/apt/sources.list.d/cydia.list", "w"));
     _assert(file != NULL);
 
-    NSArray *keys = [Sources_ allKeys];
-
-    for (NSString *key in keys) {
-        NSDictionary *source = [Sources_ objectForKey:key];
+    for (NSString *key in [Sources_ allKeys]) {
+        NSDictionary *source([Sources_ objectForKey:key]);
 
         fprintf(file, "%s %s %s\n",
             [[source objectForKey:@"Type"] UTF8String],
@@ -7750,10 +7830,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     return [underlay_ bounds];
 }
 
-- (void) perform {
-    [database_ prepare];
+- (bool) perform {
+    if (![database_ prepare])
+        return false;
 
     confirm_ = [[RVBook alloc] initWithFrame:[self popUpBounds]];
+    [confirm_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
     [confirm_ setDelegate:self];
 
     ConfirmationView *page([[[ConfirmationView alloc] initWithBook:confirm_ database:database_] autorelease]);
@@ -7761,6 +7843,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
     [confirm_ setPage:page];
     [self popUpBook:confirm_];
+
+    return true;
 }
 
 - (void) queue {
@@ -7777,6 +7861,15 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     }
 }
 
+- (void) installPackages:(NSArray *)packages {
+    @synchronized (self) {
+        for (Package *package in packages)
+            [package install];
+        [self resolve];
+        [self perform];
+    }
+}
+
 - (void) installPackage:(Package *)package {
     @synchronized (self) {
         [package install];
@@ -7795,7 +7888,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
 - (void) distUpgrade {
     @synchronized (self) {
-        [database_ upgrade];
+        if (![database_ upgrade])
+            return;
         [self perform];
     }
 }
@@ -7833,23 +7927,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     ];
 }
 
-- (void) bootstrap_ {
-    [database_ update];
-    [database_ upgrade];
-    [database_ prepare];
-    [database_ perform];
-}
-
-/* XXX: replace and localize */
-- (void) bootstrap {
-    [progress_
-        detachNewThreadSelector:@selector(bootstrap_)
-        toTarget:self
-        withObject:nil
-        title:@"Bootstrap Install"
-    ];
-}
-
 - (void) progressViewIsComplete:(ProgressView *)progress {
     if (confirm_ != nil) {
         [underlay_ addSubview:overlay_];
@@ -7871,47 +7948,59 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     return browser;
 }
 
-- (void) _setHomePage {
-    [self setPage:[self _pageForURL:[NSURL URLWithString:@"http://cydia.saurik.com/"] withClass:[HomeView class]]];
-}
-
 - (SectionsView *) sectionsView {
     if (sections_ == nil)
         sections_ = [[SectionsView alloc] initWithBook:book_ database:database_];
     return sections_;
 }
 
-- (void) buttonBarItemTapped:(id)sender {
-    unsigned tag = [sender tag];
+- (ChangesView *) changesView {
+    if (changes_ == nil)
+        changes_ = [[ChangesView alloc] initWithBook:book_ database:database_ delegate:self];
+    return changes_;
+}
+
+- (ManageView *) manageView {
+    if (manage_ == nil)
+        manage_ = (ManageView *) [[self
+            _pageForURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"manage" ofType:@"html"]]
+            withClass:[ManageView class]
+        ] retain];
+    return manage_;
+}
+
+- (SearchView *) searchView {
+    if (search_ == nil)
+        search_ = [[SearchView alloc] initWithBook:book_ database:database_];
+    return search_;
+}
+
+- (void) tabBar:(UITabBar *)sender didSelectItem:(UITabBarItem *)item {
+    int tag = [item tag];
     if (tag == tag_) {
         [book_ resetViewAnimated:YES];
         return;
-    } else if (tag_ == 2 && tag != 2)
+    } else if (tag_ == 1)
         [[self sectionsView] resetView];
 
     switch (tag) {
-        case 1: [self _setHomePage]; break;
+        case 0: _setHomePage(self); break;
 
-        case 2: [self setPage:[self sectionsView]]; break;
-        case 3: [self setPage:changes_]; break;
-        case 4: [self setPage:manage_]; break;
-        case 5: [self setPage:search_]; break;
+        case 1: [self setPage:[self sectionsView]]; break;
+        case 2: [self setPage:[self changesView]]; break;
+        case 3: [self setPage:[self manageView]]; break;
+        case 4: [self setPage:[self searchView]]; break;
 
-        default: _assert(false);
+        _nodefault
     }
 
     tag_ = tag;
 }
 
-- (void) applicationWillSuspend {
-    [database_ clean];
-    [super applicationWillSuspend];
-}
-
 - (void) askForSettings {
     NSString *parenthetical(UCLocalize("PARENTHETICAL"));
 
-    UIActionSheet *role = [[[UIActionSheet alloc]
+    CYActionSheet *role([[[CYActionSheet alloc]
         initWithTitle:UCLocalize("WHO_ARE_YOU")
         buttons:[NSArray arrayWithObjects:
             [NSString stringWithFormat:parenthetical, UCLocalize("USER"), UCLocalize("USER_EX")],
@@ -7919,12 +8008,29 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
             [NSString stringWithFormat:parenthetical, UCLocalize("DEVELOPER"), UCLocalize("DEVELOPER_EX")],
         nil]
         defaultButtonIndex:-1
-        delegate:self
-        context:@"role"
-    ] autorelease];
+    ] autorelease]);
+
+    [role setMessage:UCLocalize("ROLE_EX")];
+
+    int button([role yieldToPopupAlertAnimated:YES]);
+
+    switch (button) {
+        case 1: Role_ = @"User"; break;
+        case 2: Role_ = @"Hacker"; break;
+        case 3: Role_ = @"Developer"; break;
+
+        _nodefault
+    }
+
+    Settings_ = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+        Role_, @"Role",
+    nil];
 
-    [role setBodyText:UCLocalize("ROLE_EX")];
-    [role popupAlertAnimated:YES];
+    [Metadata_ setObject:Settings_ forKey:@"Settings"];
+
+    Changed_ = true;
+
+    [role dismiss];
 }
 
 - (void) setPackageView:(PackageView *)view {
@@ -7963,151 +8069,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 #endif
 }
 
-- (void) finish {
-    if (hud_ != nil) {
-        [self setStatusBarShowsProgress:NO];
-        [self removeProgressHUD:hud_];
-
-        [hud_ autorelease];
-        hud_ = nil;
-
-        pid_t pid = ExecFork();
-        if (pid == 0) {
-            execlp("launchctl", "launchctl", "stop", "com.apple.SpringBoard", NULL);
-            perror("launchctl stop");
-        }
-
-        return;
-    }
-
-    if (Role_ == nil) {
-        [self askForSettings];
-        return;
-    }
-
-    _trace();
-    overlay_ = [[UIView alloc] initWithFrame:[underlay_ bounds]];
-
-    CGRect screenrect = [UIHardware fullScreenApplicationContentRect];
-    book_ = [[CYBook alloc] initWithFrame:CGRectMake(
-        0, 0, screenrect.size.width, screenrect.size.height - 48
-    ) database:database_];
-
-    [book_ setDelegate:self];
-
-    [overlay_ addSubview:book_];
-
-    NSArray *buttonitems = [NSArray arrayWithObjects:
-        [NSDictionary dictionaryWithObjectsAndKeys:
-            @"buttonBarItemTapped:", kUIButtonBarButtonAction,
-            @"home-up.png", kUIButtonBarButtonInfo,
-            @"home-dn.png", kUIButtonBarButtonSelectedInfo,
-            [NSNumber numberWithInt:1], kUIButtonBarButtonTag,
-            self, kUIButtonBarButtonTarget,
-            @"Cydia", kUIButtonBarButtonTitle,
-            @"0", kUIButtonBarButtonType,
-        nil],
-
-        [NSDictionary dictionaryWithObjectsAndKeys:
-            @"buttonBarItemTapped:", kUIButtonBarButtonAction,
-            @"install-up.png", kUIButtonBarButtonInfo,
-            @"install-dn.png", kUIButtonBarButtonSelectedInfo,
-            [NSNumber numberWithInt:2], kUIButtonBarButtonTag,
-            self, kUIButtonBarButtonTarget,
-            UCLocalize("SECTIONS"), kUIButtonBarButtonTitle,
-            @"0", kUIButtonBarButtonType,
-        nil],
-
-        [NSDictionary dictionaryWithObjectsAndKeys:
-            @"buttonBarItemTapped:", kUIButtonBarButtonAction,
-            @"changes-up.png", kUIButtonBarButtonInfo,
-            @"changes-dn.png", kUIButtonBarButtonSelectedInfo,
-            [NSNumber numberWithInt:3], kUIButtonBarButtonTag,
-            self, kUIButtonBarButtonTarget,
-            UCLocalize("CHANGES"), kUIButtonBarButtonTitle,
-            @"0", kUIButtonBarButtonType,
-        nil],
-
-        [NSDictionary dictionaryWithObjectsAndKeys:
-            @"buttonBarItemTapped:", kUIButtonBarButtonAction,
-            @"manage-up.png", kUIButtonBarButtonInfo,
-            @"manage-dn.png", kUIButtonBarButtonSelectedInfo,
-            [NSNumber numberWithInt:4], kUIButtonBarButtonTag,
-            self, kUIButtonBarButtonTarget,
-            UCLocalize("MANAGE"), kUIButtonBarButtonTitle,
-            @"0", kUIButtonBarButtonType,
-        nil],
-
-        [NSDictionary dictionaryWithObjectsAndKeys:
-            @"buttonBarItemTapped:", kUIButtonBarButtonAction,
-            @"search-up.png", kUIButtonBarButtonInfo,
-            @"search-dn.png", kUIButtonBarButtonSelectedInfo,
-            [NSNumber numberWithInt:5], kUIButtonBarButtonTag,
-            self, kUIButtonBarButtonTarget,
-            UCLocalize("SEARCH"), kUIButtonBarButtonTitle,
-            @"0", kUIButtonBarButtonType,
-        nil],
-    nil];
-
-    buttonbar_ = [[UIToolbar alloc]
-        initInView:overlay_
-        withFrame:CGRectMake(
-            0, screenrect.size.height - ButtonBarHeight_,
-            screenrect.size.width, ButtonBarHeight_
-        )
-        withItemList:buttonitems
-    ];
-
-    [buttonbar_ setDelegate:self];
-    [buttonbar_ setBarStyle:1];
-    [buttonbar_ setButtonBarTrackingMode:2];
-
-    int buttons[5] = {1, 2, 3, 4, 5};
-    [buttonbar_ registerButtonGroup:0 withButtons:buttons withCount:5];
-    [buttonbar_ showButtonGroup:0 withDuration:0];
-
-    for (int i = 0; i != 5; ++i)
-        [[buttonbar_ viewWithTag:(i + 1)] setFrame:CGRectMake(
-            i * 64 + 2, 1, 60, ButtonBarHeight_
-        )];
-
-    [buttonbar_ showSelectionForButton:1];
-    [overlay_ addSubview:buttonbar_];
-
-    [UIKeyboard initImplementationNow];
-    CGSize keysize = [UIKeyboard defaultSize];
-    CGRect keyrect = {{0, [overlay_ bounds].size.height}, keysize};
-    keyboard_ = [[UIKeyboard alloc] initWithFrame:keyrect];
-    [overlay_ addSubview:keyboard_];
-
-    if (!bootstrap_)
-        [underlay_ addSubview:overlay_];
-
-    [self reloadData];
-
-    [self sectionsView];
-    changes_ = [[ChangesView alloc] initWithBook:book_ database:database_];
-    search_ = [[SearchView alloc] initWithBook:book_ database:database_];
-
-    manage_ = (ManageView *) [[self
-        _pageForURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"manage" ofType:@"html"]]
-        withClass:[ManageView class]
-    ] retain];
-
-#if RecyclePackageViews
-    details_ = [[NSMutableArray alloc] initWithCapacity:4];
-    [details_ addObject:[self _packageView]];
-    [details_ addObject:[self _packageView]];
-#endif
-
-    PrintTimes();
-
-    if (bootstrap_)
-        [self bootstrap];
-    else
-        [self _setHomePage];
-}
-
 - (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button {
     NSString *context([sheet context]);
 
@@ -8125,8 +8086,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
                 clear = true;
             break;
 
-            default:
-                _assert(false);
+            _nodefault
         }
 
         [sheet dismiss];
@@ -8136,7 +8096,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
                 [self _reloadData];
             else {
                 Queuing_ = true;
-                [buttonbar_ setBadgeValue:UCLocalize("Q_D") forButton:4];
+                [[[toolbar_ items] objectAtIndex:3] setBadgeValue:UCLocalize("Q_D")];
                 [book_ reloadData];
             }
 
@@ -8145,93 +8105,60 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
                 confirm_ = nil;
             }
         }
-    } else if ([context isEqualToString:@"fixhalf"]) {
-        switch (button) {
-            case 1:
-                @synchronized (self) {
-                    for (Package *broken in broken_) {
-                        [broken remove];
-
-                        NSString *id = [broken id];
-                        unlink([[NSString stringWithFormat:@"/var/lib/dpkg/info/%@.prerm", id] UTF8String]);
-                        unlink([[NSString stringWithFormat:@"/var/lib/dpkg/info/%@.postrm", id] UTF8String]);
-                        unlink([[NSString stringWithFormat:@"/var/lib/dpkg/info/%@.preinst", id] UTF8String]);
-                        unlink([[NSString stringWithFormat:@"/var/lib/dpkg/info/%@.postinst", id] UTF8String]);
-                    }
-
-                    [self resolve];
-                    [self perform];
+    } 
+}
+
+- (void)alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)button {
+       NSString *context([alert context]);
+       
+       if ([context isEqualToString:@"fixhalf"]) {
+               if (button == [alert firstOtherButtonIndex]) {
+            @synchronized (self) {
+                for (Package *broken in broken_) {
+                    [broken remove];
+
+                    NSString *id = [broken id];
+                    unlink([[NSString stringWithFormat:@"/var/lib/dpkg/info/%@.prerm", id] UTF8String]);
+                    unlink([[NSString stringWithFormat:@"/var/lib/dpkg/info/%@.postrm", id] UTF8String]);
+                    unlink([[NSString stringWithFormat:@"/var/lib/dpkg/info/%@.preinst", id] UTF8String]);
+                    unlink([[NSString stringWithFormat:@"/var/lib/dpkg/info/%@.postinst", id] UTF8String]);
                 }
-            break;
 
-            case 2:
-                [broken_ removeAllObjects];
-                [self _loaded];
-            break;
-
-            default:
-                _assert(false);
-        }
-
-        [sheet dismiss];
-    } else if ([context isEqualToString:@"role"]) {
-        switch (button) {
-            case 1: Role_ = @"User"; break;
-            case 2: Role_ = @"Hacker"; break;
-            case 3: Role_ = @"Developer"; break;
-
-            default:
-                Role_ = nil;
-                _assert(false);
+                [self resolve];
+                [self perform];
+            }
+               } else if (button == [alert cancelButtonIndex]) {
+            [broken_ removeAllObjects];
+            [self _loaded];
         }
 
-        bool reset = Settings_ != nil;
-
-        Settings_ = [NSMutableDictionary dictionaryWithObjectsAndKeys:
-            Role_, @"Role",
-        nil];
-
-        [Metadata_ setObject:Settings_ forKey:@"Settings"];
-
-        Changed_ = true;
-
-        [sheet dismiss];
-
-        if (reset)
-            [self updateData];
-        else
-            [self finish];
+        [alert dismissWithClickedButtonIndex:-1 animated:YES];
     } else if ([context isEqualToString:@"upgrade"]) {
-        switch (button) {
-            case 1:
-                @synchronized (self) {
-                    for (Package *essential in essential_)
-                        [essential install];
-
-                    [self resolve];
-                    [self perform];
-                }
-            break;
-
-            case 2:
-                [self distUpgrade];
-            break;
-
-            case 3:
-                Ignored_ = YES;
-            break;
+        if (button == [alert firstOtherButtonIndex]) {
+            @synchronized (self) {
+                for (Package *essential in essential_)
+                    [essential install];
 
-            default:
-                _assert(false);
+                [self resolve];
+                [self perform];
+            }
+        } else if (button == [alert firstOtherButtonIndex] + 1) {
+            [self distUpgrade];
+        } else if (button == [alert cancelButtonIndex]) {
+            Ignored_ = YES;
         }
 
-        [sheet dismiss];
+        [alert dismissWithClickedButtonIndex:-1 animated:YES];
     }
 }
 
-- (void) reorganize { _pooled
-    system("/usr/libexec/cydia/free.sh");
-    [self performSelectorOnMainThread:@selector(finish) withObject:nil waitUntilDone:NO];
+- (void) system:(NSString *)command { _pooled
+    system([command UTF8String]);
+}
+
+- (void) applicationWillSuspend {
+    [database_ clean];
+    [super applicationWillSuspend];
 }
 
 - (void) applicationSuspend:(__GSEvent *)event {
@@ -8251,6 +8178,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
 - (UIProgressHUD *) addProgressHUD {
     UIProgressHUD *hud([[[UIProgressHUD alloc] initWithWindow:window_] autorelease]);
+    [hud setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+
     [window_ setUserInteractionEnabled:NO];
     [hud show:YES];
     [progress_ addSubview:hud];
@@ -8269,24 +8198,15 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         [view setPackage:package];
         return view;
     } else {
-        UIActionSheet *sheet = [[[UIActionSheet alloc]
-            initWithTitle:UCLocalize("CANNOT_LOCATE_PACKAGE")
-            buttons:[NSArray arrayWithObjects:UCLocalize("CLOSE"), nil]
-            defaultButtonIndex:0
-            delegate:self
-            context:@"missing"
-        ] autorelease];
-
-        [sheet setBodyText:[NSString stringWithFormat:UCLocalize("PACKAGE_CANNOT_BE_FOUND"), name]];
-
-        [sheet popupAlertAnimated:YES];
-        return nil;
+        NSURL *url([NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"unknown" ofType:@"html"]]);
+        url = [NSURL URLWithString:[[url absoluteString] stringByAppendingString:[NSString stringWithFormat:@"?%@", name]]];
+        return [self _pageForURL:url withClass:[CydiaBrowserView class]];
     }
 }
 
 - (RVPage *) pageForURL:(NSURL *)url hasTag:(int *)tag {
     if (tag != NULL)
-        tag = 0;
+        *tag = -1;
 
     NSString *href([url absoluteString]);
     if ([href hasPrefix:@"apptapp://package/"])
@@ -8338,8 +8258,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     int tag;
     if (RVPage *page = [self pageForURL:url hasTag:&tag]) {
         [self setPage:page];
-        [buttonbar_ showSelectionForButton:tag];
         tag_ = tag;
+        [toolbar_ setSelectedItem:(tag_ == -1 ? nil : [items_ objectAtIndex:tag_])];
     }
 }
 
@@ -8354,23 +8274,31 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     Font18Bold_ = [[UIFont boldSystemFontOfSize:18] retain];
     Font22Bold_ = [[UIFont boldSystemFontOfSize:22] retain];
 
-    tag_ = 1;
+    tag_ = 0;
 
     essential_ = [[NSMutableArray alloc] initWithCapacity:4];
     broken_ = [[NSMutableArray alloc] initWithCapacity:4];
 
-    window_ = [[UIWindow alloc] initWithContentRect:[UIHardware fullScreenApplicationContentRect]];
+    UIScreen *screen([UIScreen mainScreen]);
+
+    window_ = [[UIWindow alloc] initWithFrame:[screen bounds]];
     [window_ orderFront:self];
     [window_ makeKey:self];
     [window_ setHidden:NO];
 
+    root_ = [[CydiaViewController alloc] init];
+    [window_ addSubview:[root_ view]];
+
     database_ = [Database sharedInstance];
 
-    progress_ = [[ProgressView alloc] initWithFrame:[window_ bounds] database:database_ delegate:self];
+    progress_ = [[ProgressView alloc] initWithFrame:[[root_ view] bounds] database:database_ delegate:self];
+    [progress_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+    [[root_ view] addSubview:progress_];
+
     [database_ setDelegate:progress_];
-    [window_ setContentView:progress_];
 
     underlay_ = [[UIView alloc] initWithFrame:[progress_ bounds]];
+    [underlay_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
     [progress_ setContentView:underlay_];
 
     [progress_ resetView];
@@ -8389,27 +8317,109 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     ) {
         [self setIdleTimerDisabled:YES];
 
-        hud_ = [[self addProgressHUD] retain];
+        hud_ = [self addProgressHUD];
         [hud_ setText:@"Reorganizing\n\nWill Automatically\nClose When Done"];
-
         [self setStatusBarShowsProgress:YES];
 
-        [NSThread
-            detachNewThreadSelector:@selector(reorganize)
-            toTarget:self
-            withObject:nil
-        ];
-    } else
-        [self finish];
+        [self yieldToSelector:@selector(system:) withObject:@"/usr/libexec/cydia/free.sh"];
+
+        [self setStatusBarShowsProgress:NO];
+        [self removeProgressHUD:hud_];
+        hud_ = nil;
+
+        if (ExecFork() == 0) {
+            execlp("launchctl", "launchctl", "stop", "com.apple.SpringBoard", NULL);
+            perror("launchctl stop");
+        }
+
+        return;
+    }
+
+    if (Role_ == nil)
+        [self askForSettings];
+
+    _trace();
+    overlay_ = [[UIView alloc] initWithFrame:[underlay_ bounds]];
+    [overlay_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+
+    CGRect screenrect = [UIHardware fullScreenApplicationContentRect];
+
+    book_ = [[CYBook alloc] initWithFrame:CGRectMake(
+        0, 0, screenrect.size.width, screenrect.size.height - 48
+    ) database:database_];
+
+    [book_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+    [overlay_ addSubview:book_];
+
+    [book_ setDelegate:self];
+
+    items_ = [[NSArray arrayWithObjects:
+        [[[UITabBarItem alloc] initWithTitle:@"Cydia" image:[UIImage applicationImageNamed:@"home.png"] tag:0] autorelease],
+        [[[UITabBarItem alloc] initWithTitle:UCLocalize("SECTIONS") image:[UIImage applicationImageNamed:@"install.png"] tag:1] autorelease],
+        [[[UITabBarItem alloc] initWithTitle:UCLocalize("CHANGES") image:[UIImage applicationImageNamed:@"changes.png"] tag:2] autorelease],
+        [[[UITabBarItem alloc] initWithTitle:UCLocalize("MANAGE") image:[UIImage applicationImageNamed:@"manage.png"] tag:3] autorelease],
+        [[[UITabBarItem alloc] initWithTitle:UCLocalize("SEARCH") image:[UIImage applicationImageNamed:@"search.png"] tag:4] autorelease],
+    nil] retain];
+
+    toolbar_ = [[UITabBar alloc]
+        initWithFrame:CGRectMake(
+            0, screenrect.size.height - ButtonBarHeight_,
+            screenrect.size.width, ButtonBarHeight_
+        )
+    ];
+
+    [toolbar_ setItems:items_];
+
+    [toolbar_ setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin)];
+    [overlay_ addSubview:toolbar_];
+
+    [toolbar_ setDelegate:self];
+
+    /*int buttons[5] = {1, 2, 3, 4, 5};
+    [toolbar_ registerButtonGroup:0 withButtons:buttons withCount:5];
+    [toolbar_ showButtonGroup:0 withDuration:0];
+
+    for (int i = 0; i != 5; ++i) {
+        UIView *button([toolbar_ viewWithTag:(i + 1)]);
+
+        [button setFrame:CGRectMake(
+            i * (screenrect.size.width / 5) + (screenrect.size.width / 5 - ButtonBarWidth_) / 2, 1,
+            ButtonBarWidth_, ButtonBarHeight_
+        )];
+
+        [button setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin];
+    }*/
+
+    [toolbar_ setSelectedItem:[items_ objectAtIndex:0]];
+
+    [UIKeyboard initImplementationNow];
+    /*CGSize keysize = [UIKeyboard defaultSize];
+    CGRect keyrect = {{0, [overlay_ bounds].size.height}, keysize};
+    keyboard_ = [[UIKeyboard alloc] initWithFrame:keyrect];
+    [overlay_ addSubview:keyboard_];*/
+
+    [underlay_ addSubview:overlay_];
+
+    [self reloadData];
+
+#if RecyclePackageViews
+    details_ = [[NSMutableArray alloc] initWithCapacity:4];
+    [details_ addObject:[self _packageView]];
+    [details_ addObject:[self _packageView]];
+#endif
+
+    PrintTimes();
+
+    _setHomePage(self);
 }
 
 - (void) showKeyboard:(BOOL)show {
-    CGSize keysize = [UIKeyboard defaultSize];
+    CGSize keysize([UIKeyboard defaultSize]);
     CGRect keydown = {{0, [overlay_ bounds].size.height}, keysize};
-    CGRect keyup = keydown;
+    CGRect keyup(keydown);
     keyup.origin.y -= keysize.height;
 
-    UIFrameAnimation *animation = [[[UIFrameAnimation alloc] initWithTarget:keyboard_] autorelease];
+    UIFrameAnimation *animation([[[UIFrameAnimation alloc] initWithTarget:keyboard_] autorelease]);
     [animation setSignificantRectFields:2];
 
     if (show) {
@@ -8430,50 +8440,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (void) slideUp:(UIActionSheet *)alert {
-    if (Advanced_)
-        [alert presentSheetFromButtonBar:buttonbar_];
-    else
-        [alert presentSheetInView:overlay_];
+    [alert setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];
+    [alert presentSheetInView:overlay_];
 }
 
 @end
 
-void AddPreferences(NSString *plist) { _pooled
-    NSMutableDictionary *settings = [[[NSMutableDictionary alloc] initWithContentsOfFile:plist] autorelease];
-    _assert(settings != NULL);
-    NSMutableArray *items = [settings objectForKey:@"items"];
-
-    bool cydia(false);
-
-    for (NSMutableDictionary *item in items) {
-        NSString *label = [item objectForKey:@"label"];
-        if (label != nil && [label isEqualToString:@"Cydia"]) {
-            cydia = true;
-            break;
-        }
-    }
-
-    if (!cydia) {
-        for (size_t i(0); i != [items count]; ++i) {
-            NSDictionary *item([items objectAtIndex:i]);
-            NSString *label = [item objectForKey:@"label"];
-            if (label != nil && [label isEqualToString:@"General"]) {
-                [items insertObject:[NSDictionary dictionaryWithObjectsAndKeys:
-                    @"CydiaSettings", @"bundle",
-                    @"PSLinkCell", @"cell",
-                    [NSNumber numberWithBool:YES], @"hasIcon",
-                    [NSNumber numberWithBool:YES], @"isController",
-                    @"Cydia", @"label",
-                nil] atIndex:(i + 1)];
-
-                break;
-            }
-        }
-
-        _assert([settings writeToFile:plist atomically:YES] == YES);
-    }
-}
-
 /*IMP alloc_;
 id Alloc_(id self, SEL selector) {
     id object = alloc_(self, selector);
@@ -8490,20 +8462,25 @@ id Dealloc_(id self, SEL selector) {
 
 Class $WebDefaultUIKitDelegate;
 
-void (*_UIWebDocumentView$_setUIKitDelegate$)(UIWebDocumentView *, SEL, id);
-
-void $UIWebDocumentView$_setUIKitDelegate$(UIWebDocumentView *self, SEL sel, id delegate) {
+MSHook(void, UIWebDocumentView$_setUIKitDelegate$, UIWebDocumentView *self, SEL _cmd, id delegate) {
     if (delegate == nil && $WebDefaultUIKitDelegate != nil)
         delegate = [$WebDefaultUIKitDelegate sharedUIKitDelegate];
-    return _UIWebDocumentView$_setUIKitDelegate$(self, sel, delegate);
+    return _UIWebDocumentView$_setUIKitDelegate$(self, _cmd, delegate);
 }
 
 int main(int argc, char *argv[]) { _pooled
     _trace();
 
+    if (Class $UIDevice = objc_getClass("UIDevice")) {
+        UIDevice *device([$UIDevice currentDevice]);
+        IsWildcat_ = [device respondsToSelector:@selector(isWildcat)] && [device isWildcat];
+    } else
+        IsWildcat_ = false;
+
     PackageName = reinterpret_cast<CYString &(*)(Package *, SEL)>(method_getImplementation(class_getInstanceMethod([Package class], @selector(cyname))));
 
     /* Library Hacks {{{ */
+    class_addMethod(objc_getClass("WebScriptObject"), @selector(countByEnumeratingWithState:objects:count:), (IMP) &WebScriptObject$countByEnumeratingWithState$objects$count$, "I20@0:4^{NSFastEnumerationState}8^@12I16");
     class_addMethod(objc_getClass("DOMNodeList"), @selector(countByEnumeratingWithState:objects:count:), (IMP) &DOMNodeList$countByEnumeratingWithState$objects$count$, "I20@0:4^{NSFastEnumerationState}8^@12I16");
 
     $WebDefaultUIKitDelegate = objc_getClass("WebDefaultUIKitDelegate");
@@ -8518,18 +8495,21 @@ int main(int argc, char *argv[]) { _pooled
     Languages_ = [NSLocale preferredLanguages];
     //CFStringRef locale(CFLocaleGetIdentifier(Locale_));
     //NSLog(@"%@", [Languages_ description]);
+
     const char *lang;
     if (Languages_ == nil || [Languages_ count] == 0)
+        // XXX: consider just setting to C and then falling through?
         lang = NULL;
-    else
+    else {
         lang = [[Languages_ objectAtIndex:0] UTF8String];
-    setenv("LANG", lang, true);
+        setenv("LANG", lang, true);
+    }
+
     //std::setlocale(LC_ALL, lang);
     NSLog(@"Setting Language: %s", lang);
     /* }}} */
 
-    // XXX: apr_app_initialize?
-    apr_initialize();
+    apr_app_initialize(&argc, const_cast<const char * const **>(&argv), NULL);
 
     /* Parse Arguments {{{ */
     bool substrate(false);
@@ -8548,9 +8528,7 @@ int main(int argc, char *argv[]) { _pooled
             }
 
         for (int argi(1); argi != arge; ++argi)
-            if (strcmp(args[argi], "--bootstrap") == 0)
-                bootstrap_ = true;
-            else if (strcmp(args[argi], "--substrate") == 0)
+            if (strcmp(args[argi], "--substrate") == 0)
                 substrate = true;
             else
                 fprintf(stderr, "unknown argument: %s\n", args[argi]);
@@ -8559,6 +8537,7 @@ int main(int argc, char *argv[]) { _pooled
 
     App_ = [[NSBundle mainBundle] bundlePath];
     Home_ = NSHomeDirectory();
+    Advanced_ = YES;
 
     setuid(0);
     setgid(0);
@@ -8571,6 +8550,7 @@ int main(int argc, char *argv[]) { _pooled
     dealloc_ = dealloc->method_imp;
     dealloc->method_imp = (IMP) &Dealloc_;*/
 
+    /* System Information {{{ */
     size_t size;
 
     int maxproc;
@@ -8628,10 +8608,7 @@ int main(int argc, char *argv[]) { _pooled
         Product_ = [info objectForKey:@"SafariProductVersion"];
         Safari_ = [info objectForKey:@"CFBundleVersion"];
     }
-
-    /*AddPreferences(@"/Applications/Preferences.app/Settings-iPhone.plist");
-    AddPreferences(@"/Applications/Preferences.app/Settings-iPod.plist");*/
-
+    /* }}} */
     /* Load Database {{{ */
     _trace();
     Metadata_ = [[[NSMutableDictionary alloc] initWithContentsOfFile:@"/var/lib/cydia/metadata.plist"] autorelease];
@@ -8647,6 +8624,8 @@ int main(int argc, char *argv[]) { _pooled
         Packages_ = [Metadata_ objectForKey:@"Packages"];
         Sections_ = [Metadata_ objectForKey:@"Sections"];
         Sources_ = [Metadata_ objectForKey:@"Sources"];
+
+        Token_ = [Metadata_ objectForKey:@"Token"];
     }
 
     if (Settings_ != nil)
@@ -8672,15 +8651,21 @@ int main(int argc, char *argv[]) { _pooled
     Documents_ = [[[NSMutableArray alloc] initWithCapacity:4] autorelease];
 #endif
 
+    Finishes_ = [NSArray arrayWithObjects:@"return", @"reopen", @"restart", @"reload", @"reboot", nil];
+
+    if (substrate && access("/Library/MobileSubstrate/DynamicLibraries/SimulatedKeyEvents.dylib", F_OK) == 0)
+        dlopen("/Library/MobileSubstrate/DynamicLibraries/SimulatedKeyEvents.dylib", RTLD_LAZY | RTLD_GLOBAL);
     if (substrate && access("/Applications/WinterBoard.app/WinterBoard.dylib", F_OK) == 0)
         dlopen("/Applications/WinterBoard.app/WinterBoard.dylib", RTLD_LAZY | RTLD_GLOBAL);
     /*if (substrate && access("/Library/MobileSubstrate/MobileSubstrate.dylib", F_OK) == 0)
         dlopen("/Library/MobileSubstrate/MobileSubstrate.dylib", RTLD_LAZY | RTLD_GLOBAL);*/
 
+    int version([[NSString stringWithContentsOfFile:@"/var/lib/cydia/firmware.ver"] intValue]);
+
     if (access("/tmp/.cydia.fw", F_OK) == 0) {
         unlink("/tmp/.cydia.fw");
         goto firmware;
-    } else if (access("/User", F_OK) != 0) {
+    } else if (access("/User", F_OK) != 0 || version < 2) {
       firmware:
         _trace();
         system("/usr/libexec/cydia/firmware.sh");
@@ -8701,8 +8686,6 @@ int main(int argc, char *argv[]) { _pooled
             _assert(errno == ENOENT);
     }
 
-    Finishes_ = [NSArray arrayWithObjects:@"return", @"reopen", @"restart", @"reload", @"reboot", nil];
-
     /* APT Initialization {{{ */
     _assert(pkgInitConfig(*_config));
     _assert(pkgInitSystem(*_config, _system));
@@ -8733,9 +8716,14 @@ int main(int argc, char *argv[]) { _pooled
     if ($GSFontSetUseLegacyFontMetrics != NULL)
         $GSFontSetUseLegacyFontMetrics(YES);
 
-    UIKeyboardDisableAutomaticAppearance();
+    // XXX: I have a feeling this was important
+    //UIKeyboardDisableAutomaticAppearance();
     /* }}} */
 
+    Colon_ = UCLocalize("COLON_DELIMITED");
+    Error_ = UCLocalize("ERROR");
+    Warning_ = UCLocalize("WARNING");
+
     _trace();
     int value = UIApplicationMain(argc, argv, @"Cydia", @"Cydia");