]> git.saurik.com Git - cydia.git/blobdiff - MobileCydia.mm
Avoid sorting packages_ (it is now Foundation :/).
[cydia.git] / MobileCydia.mm
index 2a694ee6f76b446dd59f2f26cacce541f731abb2..470337418681ce9741715fbf1680918805c21ccb 100644 (file)
@@ -53,7 +53,6 @@
 #include <QuartzCore/CALayer.h>
 
 #include <WebCore/WebCoreThread.h>
-#include <WebKit/DOMHTMLIFrameElement.h>
 
 #include <algorithm>
 #include <fstream>
@@ -113,7 +112,8 @@ extern "C" {
 #include "Substrate.hpp"
 #include "Menes/Menes.h"
 
-#include "CyteKit/IndirectDelegate.h"
+#include "CyteKit/Application.h"
+#include "CyteKit/NavigationController.h"
 #include "CyteKit/RegEx.hpp"
 #include "CyteKit/TableViewCell.h"
 #include "CyteKit/TabBarController.h"
@@ -329,53 +329,47 @@ static const CFStringCompareFlags LaxCompareFlags_ = kCFCompareNumerically | kCF
 
 /* Insertion Sort {{{ */
 
-CFIndex SKBSearch_(const void *element, CFIndex elementSize, const void *list, CFIndex count, CFComparatorFunction comparator, void *context) {
+template <typename Type_>
+size_t CFBSearch_(const Type_ &element, const void *list, size_t count, CFComparisonResult (*comparator)(Type_, Type_, void *), void *context) {
     const char *ptr = (const char *)list;
     while (0 < count) {
-        CFIndex half = count / 2;
-        const char *probe = ptr + elementSize * half;
-        CFComparisonResult cr = comparator(element, probe, context);
-    if (0 == cr) return (probe - (const char *)list) / elementSize;
-        ptr = (cr < 0) ? ptr : probe + elementSize;
+        size_t half = count / 2;
+        const char *probe = ptr + sizeof(Type_) * half;
+        CFComparisonResult cr = comparator(element, * (const Type_ *) probe, context);
+        if (0 == cr) return (probe - (const char *)list) / sizeof(Type_);
+        ptr = (cr < 0) ? ptr : probe + sizeof(Type_);
         count = (cr < 0) ? half : (half + (count & 1) - 1);
     }
-    return (ptr - (const char *)list) / elementSize;
+    return (ptr - (const char *)list) / sizeof(Type_);
 }
 
-CFIndex CFBSearch_(const void *element, CFIndex elementSize, const void *list, CFIndex count, CFComparatorFunction comparator, void *context) {
-    const char *ptr = (const char *)list;
-    while (0 < count) {
-        CFIndex half = count / 2;
-        const char *probe = ptr + elementSize * half;
-        CFComparisonResult cr = comparator(element, probe, context);
-    if (0 == cr) return (probe - (const char *)list) / elementSize;
-        ptr = (cr < 0) ? ptr : probe + elementSize;
-        count = (cr < 0) ? half : (half + (count & 1) - 1);
-    }
-    return (ptr - (const char *)list) / elementSize;
-}
-
-void CFArrayInsertionSortValues(CFMutableArrayRef array, CFRange range, CFComparatorFunction comparator, void *context) {
-    if (range.length == 0)
+template <typename Type_>
+void CYArrayInsertionSortValues(Type_ *values, size_t length, CFComparisonResult (*comparator)(Type_, Type_, void *), void *context) {
+    if (length == 0)
         return;
-    const void **values(new const void *[range.length]);
-    CFArrayGetValues(array, range, values);
 
 #if HistogramInsertionSort > 0
-    uint32_t total(0), *offsets(new uint32_t[range.length]);
+    uint32_t total(0), *offsets(new uint32_t[length]);
 #endif
 
-    for (CFIndex index(1); index != range.length; ++index) {
-        const void *value(values[index]);
-        //CFIndex correct(SKBSearch_(&value, sizeof(const void *), values, index, comparator, context));
-        CFIndex correct(index);
+    for (size_t index(1); index != length; ++index) {
+        Type_ value(values[index]);
+#if 0
+        size_t correct(CFBSearch_(value, values, index, comparator, context));
+#else
+        size_t correct(index);
         while (comparator(value, values[correct - 1], context) == kCFCompareLessThan) {
 #if HistogramInsertionSort > 1
             NSLog(@"%@ < %@", value, values[correct - 1]);
 #endif
             if (--correct == 0)
                 break;
+            if (index - correct >= 8) {
+                correct = CFBSearch_(value, values, correct, comparator, context);
+                break;
+            }
         }
+#endif
         if (correct != index) {
             size_t offset(index - correct);
 #if HistogramInsertionSort
@@ -389,11 +383,8 @@ void CFArrayInsertionSortValues(CFMutableArrayRef array, CFRange range, CFCompar
         }
     }
 
-    CFArrayReplaceValues(array, range, values, range.length);
-    delete [] values;
-
 #if HistogramInsertionSort > 0
-    for (CFIndex index(0); index != range.length; ++index)
+    for (size_t index(0); index != range.length; ++index)
         if (offsets[index] != 0)
             NSLog(@"Insertion Displacement [%u]: %u", index, offsets[index]);
     NSLog(@"Average Insertion Displacement: %f", double(total) / range.length);
@@ -1119,7 +1110,7 @@ typedef std::map< unsigned long, _H<Source> > SourceMap;
     SourceMap sourceMap_;
     _H<NSMutableArray> sourceList_;
 
-    CFMutableArrayRef packages_;
+    _H<NSArray> packages_;
 
     _transient NSObject<DatabaseDelegate> *delegate_;
     _transient NSObject<ProgressDelegate> *progress_;
@@ -1135,6 +1126,7 @@ typedef std::map< unsigned long, _H<Source> > SourceMap;
 
 + (Database *) sharedInstance;
 - (unsigned) era;
+- (bool) hasPackages;
 
 - (void) _readCydia:(NSNumber *)fd;
 - (void) _readStatus:(NSNumber *)fd;
@@ -1420,14 +1412,14 @@ struct PackageValue :
 
     char version_[8];
     char name_[];
-};
+} _packed;
 
 struct MetaValue :
     Cytore::Block
 {
     uint32_t active_;
     Cytore::Offset<PackageValue> packages_[1 << 16];
-};
+} _packed;
 
 static Cytore::File<MetaValue> MetaFile_;
 // }}}
@@ -2142,6 +2134,8 @@ struct ParsedPackage {
 }
 
 - (Package *) initWithVersion:(pkgCache::VerIterator)version withZone:(NSZone *)zone inPool:(CYPool *)pool database:(Database *)database;
++ (Package *) newPackageWithIterator:(pkgCache::PkgIterator)iterator withZone:(NSZone *)zone inPool:(CYPool *)pool database:(Database *)database;
+
 + (Package *) packageWithIterator:(pkgCache::PkgIterator)iterator withZone:(NSZone *)zone inPool:(CYPool *)pool database:(Database *)database;
 
 - (pkgCache::PkgIterator) iterator;
@@ -2711,7 +2705,7 @@ struct PackageNameOrdering :
     _end } return self;
 }
 
-+ (Package *) packageWithIterator:(pkgCache::PkgIterator)iterator withZone:(NSZone *)zone inPool:(CYPool *)pool database:(Database *)database {
++ (Package *) newPackageWithIterator:(pkgCache::PkgIterator)iterator withZone:(NSZone *)zone inPool:(CYPool *)pool database:(Database *)database {
     pkgCache::VerIterator version;
 
     _profile(Package$packageWithIterator$GetCandidateVer)
@@ -2736,13 +2730,14 @@ struct PackageNameOrdering :
         ];
     _end
 
-    _profile(Package$packageWithIterator$Autorelease)
-        package = [package autorelease];
-    _end
-
     return package;
 }
 
+// XXX: just in case a Cydia extension is using this (I bet this is unlikely, though, due to CYPool?)
++ (Package *) packageWithIterator:(pkgCache::PkgIterator)iterator withZone:(NSZone *)zone inPool:(CYPool *)pool database:(Database *)database {
+    return [[self newPackageWithIterator:iterator withZone:zone inPool:pool database:database] autorelease];
+}
+
 - (pkgCache::PkgIterator) iterator {
     return iterator_;
 }
@@ -3327,8 +3322,8 @@ struct PackageNameOrdering :
 }
 
 - (void) setIndex:(size_t)index {
-    if (metadata_->index_ != index)
-        metadata_->index_ = index;
+    if (metadata_->index_ != index + 1)
+        metadata_->index_ = index + 1;
 }
 
 - (CYString &) cyname {
@@ -3519,8 +3514,11 @@ class CydiaLogCleaner :
 }
 
 - (void) releasePackages {
-    CFArrayApplyFunction(packages_, CFRangeMake(0, CFArrayGetCount(packages_)), reinterpret_cast<CFArrayApplierFunction>(&CFRelease), NULL);
-    CFArrayRemoveAllValues(packages_);
+    packages_ = nil;
+}
+
+- (bool) hasPackages {
+    return [packages_ count] != 0;
 }
 
 - (void) dealloc {
@@ -3646,7 +3644,7 @@ class CydiaLogCleaner :
         , "any"
 #endif
     ));
-    return iterator.end() ? nil : [Package packageWithIterator:iterator withZone:NULL inPool:NULL database:self];
+    return iterator.end() ? nil : [[Package newPackageWithIterator:iterator withZone:NULL inPool:NULL database:self] autorelease];
 } }
 
 - (id) init {
@@ -3659,13 +3657,6 @@ class CydiaLogCleaner :
 
         zone_ = NSCreateZone(1024 * 1024, 256 * 1024, NO);
 
-        size_t capacity(MetaFile_->active_);
-        if (capacity == 0)
-            capacity = 16384;
-        else
-            capacity += 1024;
-
-        packages_ = CFArrayCreateMutable(kCFAllocatorDefault, capacity, NULL);
         sourceList_ = [NSMutableArray arrayWithCapacity:16];
 
         int fds[2];
@@ -3734,7 +3725,7 @@ class CydiaLogCleaner :
 }
 
 - (NSArray *) packages {
-    return (NSArray *) packages_;
+    return packages_;
 }
 
 - (NSArray *) sources {
@@ -3869,7 +3860,7 @@ class CydiaLogCleaner :
         opened = cache_.Open(progress, false);
     _end
     if (!opened) {
-        // XXX: what if there are errors, but Open() == true? this should be merged with popError:
+        // XXX: this block should probably be merged with popError: in some way
         while (!_error->empty()) {
             std::string error;
             bool warning(!_error->PopMessage(error));
@@ -3897,7 +3888,8 @@ class CydiaLogCleaner :
         }
 
         return;
-    }
+    } else if ([self popErrorWithTitle:title forOperation:true])
+        return;
     _trace();
 
     unlink("/tmp/cydia.chk");
@@ -3950,40 +3942,88 @@ class CydiaLogCleaner :
     }
 
     {
-        /*std::vector<Package *> packages;
-        packages.reserve(std::max(10000U, [packages_ count] + 1000));
-        packages_ = nil;*/
+        size_t capacity(MetaFile_->active_);
+        if (capacity == 0)
+            capacity = 128*1024;
+        else
+            capacity += 1024;
+
+        std::vector<Package *> packages;
+        packages.reserve(capacity);
+        size_t lost(0);
 
+        size_t last(0);
         _profile(reloadDataWithInvocation$packageWithIterator)
         for (pkgCache::PkgIterator iterator = cache_->PkgBegin(); !iterator.end(); ++iterator)
-            if (Package *package = [Package packageWithIterator:iterator withZone:zone_ inPool:&pool_ database:self])
-                //packages.push_back(package);
-                CFArrayAppendValue(packages_, CFRetain(package));
+            if (Package *package = [Package newPackageWithIterator:iterator withZone:zone_ inPool:&pool_ database:self]) {
+                if (unsigned index = package.metadata->index_) {
+                    --index;
+                    if (packages.size() == index) {
+                        packages.push_back(package);
+                    } else if (packages.size() <= index) {
+                        packages.resize(index + 1, nil);
+                        packages[index] = package;
+                        continue;
+                    } else {
+                        std::swap(package, packages[index]);
+                        if (package != nil)
+                            goto lost;
+                        if (last != index)
+                            continue;
+                    }
+                } else lost: {
+                    ++lost;
+                    if (last == packages.size()) {
+                        packages.push_back(package);
+                        ++last;
+                    } else {
+                        packages[last] = package;
+                        ++last;
+                    }
+                }
+
+                for (; last != packages.size(); ++last)
+                    if (packages[last] == nil)
+                        break;
+            }
         _end
 
+        for (size_t next(last + 1); last != packages.size(); ++last, ++next) {
+            while (true) {
+                if (next == packages.size())
+                    goto done;
+                if (packages[next] != nil)
+                    break;
+                ++next;
+            }
 
-        /*if (packages.empty())
-            packages_ = [[NSArray alloc] init];
-        else
-            packages_ = [[NSArray alloc] initWithObjects:&packages.front() count:packages.size()];
-        _trace();*/
+            std::swap(packages[last], packages[next]);
+        } done:;
 
-        _profile(reloadDataWithInvocation$radix$8)
-        [(NSMutableArray *) packages_ radixSortUsingFunction:reinterpret_cast<MenesRadixSortFunction>(&PackagePrefixRadix) withContext:reinterpret_cast<void *>(8)];
-        _end
+        packages.resize(last);
 
-        _profile(reloadDataWithInvocation$radix$4)
-        [(NSMutableArray *) packages_ radixSortUsingFunction:reinterpret_cast<MenesRadixSortFunction>(&PackagePrefixRadix) withContext:reinterpret_cast<void *>(4)];
-        _end
+        if (lost > 128) {
+            NSLog(@"lost = %zu", lost);
 
-        _profile(reloadDataWithInvocation$radix$0)
-        [(NSMutableArray *) packages_ radixSortUsingFunction:reinterpret_cast<MenesRadixSortFunction>(&PackagePrefixRadix) withContext:reinterpret_cast<void *>(0)];
-        _end
+            _profile(reloadDataWithInvocation$radix$8)
+            CYRadixSortUsingFunction(packages.data(), packages.size(), reinterpret_cast<MenesRadixSortFunction>(&PackagePrefixRadix), reinterpret_cast<void *>(8));
+            _end
+
+            _profile(reloadDataWithInvocation$radix$4)
+            CYRadixSortUsingFunction(packages.data(), packages.size(), reinterpret_cast<MenesRadixSortFunction>(&PackagePrefixRadix), reinterpret_cast<void *>(4));
+            _end
+
+            _profile(reloadDataWithInvocation$radix$0)
+            CYRadixSortUsingFunction(packages.data(), packages.size(), reinterpret_cast<MenesRadixSortFunction>(&PackagePrefixRadix), reinterpret_cast<void *>(0));
+            _end
+        }
 
         _profile(reloadDataWithInvocation$insertion)
-        CFArrayInsertionSortValues(packages_, CFRangeMake(0, CFArrayGetCount(packages_)), reinterpret_cast<CFComparatorFunction>(&PackageNameCompare), NULL);
+        CYArrayInsertionSortValues(packages.data(), packages.size(), &PackageNameCompare, NULL);
         _end
 
+        packages_ = [[[NSArray alloc] initWithObjects:packages.data() count:packages.size()] autorelease];
+
         /*_profile(reloadDataWithInvocation$CFQSortArray)
         CFQSortArray(&packages.front(), packages.size(), sizeof(packages.front()), reinterpret_cast<CFComparatorFunction>(&PackageNameCompare_), NULL);
         _end*/
@@ -4000,11 +4040,12 @@ class CydiaLogCleaner :
         [packages_ sortUsingFunction:reinterpret_cast<NSComparisonResult (*)(id, id, void *)>(&PackageNameCompare) context:NULL];
         _end*/
 
-
-        size_t count(CFArrayGetCount(packages_));
-        MetaFile_->active_ = count;
-        for (size_t index(0); index != count; ++index)
-            [(Package *) CFArrayGetValueAtIndex(packages_, index) setIndex:index];
+        MetaFile_->active_ = packages.size();
+        for (size_t index(0), count(packages.size()); index != count; ++index) {
+            auto package(packages[index]);
+            [package setIndex:index];
+            [package release];
+        }
     }
 } }
 
@@ -4332,7 +4373,7 @@ static _H<NSMutableSet> Diversions_;
     _transient id delegate_;
 }
 
-- (id) initWithDelegate:(IndirectDelegate *)indirect;
+- (id) initWithDelegate:(CyteWebViewController *)indirect;
 
 @end
 
@@ -4352,9 +4393,9 @@ static _H<NSMutableSet> Diversions_;
 /* Web Scripting {{{ */
 @implementation CydiaObject
 
-- (id) initWithDelegate:(IndirectDelegate *)indirect {
+- (id) initWithDelegate:(CyteWebViewController *)indirect {
     if ((self = [super init]) != nil) {
-        indirect_ = (CyteWebViewController *) indirect;
+        indirect_ = indirect;
     } return self;
 }
 
@@ -4856,10 +4897,16 @@ static _H<NSMutableSet> Diversions_;
 }
 
 - (NSString *) substitutePackageNames:(NSString *)message {
+    auto database([Database sharedInstance]);
+
+    // XXX: this check is less racy than you'd expect, but this entire concept is a little awkward
+    if (![database hasPackages])
+        return message;
+
     NSMutableArray *words([[[message componentsSeparatedByString:@" "] mutableCopy] autorelease]);
     for (size_t i(0), e([words count]); i != e; ++i) {
         NSString *word([words objectAtIndex:i]);
-        if (Package *package = [[Database sharedInstance] packageWithName:word])
+        if (Package *package = [database packageWithName:word])
             [words replaceObjectAtIndex:i withObject:[package name]];
     }
 
@@ -4967,7 +5014,10 @@ static _H<NSMutableSet> Diversions_;
 @implementation CydiaWebViewController
 
 - (NSURL *) navigationURL {
-    return request_ == nil ? nil : [NSURL URLWithString:[NSString stringWithFormat:@"cydia://url/%@", [[request_ URL] absoluteString]]];
+    if (NSURLRequest *request = self.request)
+        return [NSURL URLWithString:[NSString stringWithFormat:@"cydia://url/%@", [[request URL] absoluteString]]];
+    else
+        return nil;
 }
 
 + (void) _initialize {
@@ -5070,7 +5120,7 @@ static _H<NSMutableSet> Diversions_;
 
 - (id) init {
     if ((self = [super initWithWidth:0 ofClass:[CydiaWebViewController class]]) != nil) {
-        cydia_ = [[[CydiaObject alloc] initWithDelegate:indirect_] autorelease];
+        cydia_ = [[[CydiaObject alloc] initWithDelegate:self.indirect] autorelease];
     } return self;
 }
 
@@ -5173,7 +5223,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 - (void) complete {
     if (substrate_)
         RestartSubstrate_ = true;
-    [delegate_ confirmWithNavigationController:[self navigationController]];
+    [self.delegate confirmWithNavigationController:[self navigationController]];
 }
 
 - (void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)button {
@@ -5196,7 +5246,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (void) _doContinue {
-    [delegate_ cancelAndClear:NO];
+    [self.delegate cancelAndClear:NO];
     [self dismissModalViewControllerAnimated:YES];
 }
 
@@ -5419,7 +5469,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 #endif
 
 - (void) cancelButtonClicked {
-    [delegate_ cancelAndClear:YES];
+    [self.delegate cancelAndClear:YES];
     [self dismissModalViewControllerAnimated:YES];
 }
 
@@ -5603,7 +5653,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 - (id) initWithDatabase:(Database *)database delegate:(id)delegate {
     if ((self = [super init]) != nil) {
         database_ = database;
-        delegate_ = delegate;
+        self.delegate = delegate;
 
         [database_ setProgressDelegate:self];
 
@@ -5612,7 +5662,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
         [self setURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/#!/progress/", UI_]]];
 
-        [scroller_ setBackgroundColor:[UIColor blackColor]];
+        [self setPageColor:[UIColor blackColor]];
 
         [[self navigationItem] setHidesBackButton:YES];
 
@@ -5638,19 +5688,19 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     UpdateExternalStatus(0);
 
     if (Finish_ > 1)
-        [delegate_ saveState];
+        [self.delegate saveState];
 
     switch (Finish_) {
         case 0:
-            [delegate_ returnToCydia];
+            [self.delegate returnToCydia];
         break;
 
         case 1:
-            [delegate_ terminateWithSuccess];
-            /*if ([delegate_ respondsToSelector:@selector(suspendWithAnimation:)])
-                [delegate_ suspendWithAnimation:YES];
+            [self.delegate terminateWithSuccess];
+            /*if ([self.delegate respondsToSelector:@selector(suspendWithAnimation:)])
+                [self.delegate suspendWithAnimation:YES];
             else
-                [delegate_ suspend];*/
+                [self.delegate suspend];*/
         break;
 
         case 2:
@@ -5662,9 +5712,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
             goto reload;
 
         reload: {
-            UIProgressHUD *hud([delegate_ addProgressHUD]);
+            UIProgressHUD *hud([self.delegate addProgressHUD]);
             [hud setText:UCLocalize("LOADING")];
-            [delegate_ performSelector:@selector(reloadSpringBoard) withObject:nil afterDelay:0.5];
+            [self.delegate performSelector:@selector(reloadSpringBoard) withObject:nil afterDelay:0.5];
             return;
         }
 
@@ -5862,12 +5912,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         UIView *content([self contentView]);
         CGRect bounds([content bounds]);
 
-        content_ = [[[CyteTableViewCellContentView alloc] initWithFrame:bounds] autorelease];
-        [content_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
-        [content addSubview:content_];
+        self.content = [[[CyteTableViewCellContentView alloc] initWithFrame:bounds] autorelease];
+        [self.content setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+        [content addSubview:self.content];
 
-        [content_ setDelegate:self];
-        [content_ setOpaque:YES];
+        [self.content setDelegate:self];
+        [self.content setOpaque:YES];
     } return self;
 }
 
@@ -5886,7 +5936,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     placard_ = nil;
 
     if (package == nil)
-        [content_ setBackgroundColor:[UIColor whiteColor]];
+        [self.content setBackgroundColor:[UIColor whiteColor]];
     else {
         [package parse];
 
@@ -5946,18 +5996,18 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
                 placard = nil;
         }
 
-        [content_ setBackgroundColor:color];
+        [self.content setBackgroundColor:color];
 
         if (placard != nil)
             placard_ = [UIImage imageAtPath:[NSString stringWithFormat:@"%@/%@.png", App_, placard]];
     }
 
     [self setNeedsDisplay];
-    [content_ setNeedsDisplay];
+    [self.content setNeedsDisplay];
 }
 
 - (void) drawSummaryContentRect:(CGRect)rect {
-    bool highlighted(highlighted_);
+    bool highlighted(self.highlighted);
     float width([self bounds].size.width);
 
     if (icon_ != nil) {
@@ -6000,7 +6050,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (void) drawNormalContentRect:(CGRect)rect {
-    bool highlighted(highlighted_);
+    bool highlighted(self.highlighted);
     float width([self bounds].size.width);
 
     if (icon_ != nil) {
@@ -6085,12 +6135,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         UIView *content([self contentView]);
         CGRect bounds([content bounds]);
 
-        content_ = [[[CyteTableViewCellContentView alloc] initWithFrame:bounds] autorelease];
-        [content_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
-        [content addSubview:content_];
-        [content_ setBackgroundColor:[UIColor whiteColor]];
+        self.content = [[[CyteTableViewCellContentView alloc] initWithFrame:bounds] autorelease];
+        [self.content setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+        [content addSubview:self.content];
+        [self.content setBackgroundColor:[UIColor whiteColor]];
 
-        [content_ setDelegate:self];
+        [self.content setDelegate:self];
     } return self;
 }
 
@@ -6135,7 +6185,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [self setAccessoryType:editing ? UITableViewCellAccessoryNone : UITableViewCellAccessoryDisclosureIndicator];
     [self setSelectionStyle:editing ? UITableViewCellSelectionStyleNone : UITableViewCellSelectionStyleBlue];
 
-    [content_ setNeedsDisplay];
+    [self.content setNeedsDisplay];
 }
 
 - (void) setFrame:(CGRect)frame {
@@ -6150,7 +6200,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (void) drawContentRect:(CGRect)rect {
-    bool highlighted(highlighted_ && !editing_);
+    bool highlighted(self.highlighted && !editing_);
 
     [icon_ drawInRect:CGRectMake(7, 7, 32, 32)];
 
@@ -6321,14 +6371,14 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (void) _clickButtonWithPackage:(Package *)package {
-    [delegate_ installPackage:package];
+    [self.delegate installPackage:package];
 }
 
 - (void) _clickButtonWithName:(NSString *)name {
     if ([name isEqualToString:@"CLEAR"])
-        return [delegate_ clearPackage:package_];
+        return [self.delegate clearPackage:package_];
     else if ([name isEqualToString:@"REMOVE"])
-        return [delegate_ removePackage:package_];
+        return [self.delegate removePackage:package_];
     else if ([name isEqualToString:@"DOWNGRADE"]) {
         sheet_ = [[[UIActionSheet alloc]
             initWithTitle:nil
@@ -6342,7 +6392,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
             [sheet_ addButtonWithTitle:[version latest]];
         [sheet_ setContext:@"version"];
 
-        [delegate_ showActionSheet:sheet_ fromItem:[[self navigationItem] rightBarButtonItem]];
+        [self.delegate showActionSheet:sheet_ fromItem:[[self navigationItem] rightBarButtonItem]];
         return;
     }
 
@@ -6351,7 +6401,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     else if ([name isEqualToString:@"UPGRADE"]);
     else _assert(false);
 
-    [delegate_ installPackage:package_];
+    [self.delegate installPackage:package_];
 }
 
 - (void) actionSheet:(UIActionSheet *)sheet clickedButtonAtIndex:(NSInteger)button {
@@ -6387,6 +6437,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
 #if !AlwaysReload
 - (void) _customButtonClicked {
+    if (commercial_ && [package_ uninstalled])
+        return [self reloadURLWithCache:NO];
+
     size_t count(buttons_.size());
     if (count == 0)
         return;
@@ -6410,16 +6463,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
             [sheet_ addButtonWithTitle:button];
         [sheet_ setContext:@"modify"];
 
-        [delegate_ showActionSheet:sheet_ fromItem:[[self navigationItem] rightBarButtonItem]];
+        [self.delegate showActionSheet:sheet_ fromItem:[[self navigationItem] rightBarButtonItem]];
     }
 }
 
-- (void) reloadButtonClicked {
-    if (commercial_ && function_ == nil && [package_ uninstalled])
-        return;
-    [self customButtonClicked];
-}
-
 - (void) applyLoadingTitle {
     // Don't show "Loading" as the title. Ever.
 }
@@ -6513,7 +6560,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (id) initWithDatabase:(Database *)database title:(NSString *)title;
-- (void) setDelegate:(id)delegate;
 - (void) resetCursor;
 - (void) clearData;
 
@@ -6626,7 +6672,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
 - (void) didSelectPackage:(Package *)package {
     CYPackageController *view([[[CYPackageController alloc] initWithDatabase:database_ forPackage:[package id] withReferrer:[[self referrerURL] absoluteString]] autorelease]);
-    [view setDelegate:delegate_];
+    [view setDelegate:self.delegate];
     [[self navigationController] pushViewController:view animated:YES];
 }
 
@@ -6724,10 +6770,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [super releaseSubviews];
 }
 
-- (void) setDelegate:(id)delegate {
-    delegate_ = delegate;
-}
-
 - (bool) shouldYield {
     return false;
 }
@@ -6760,7 +6802,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
             if (![self shouldBlock])
                 hud = nil;
             else {
-                hud = [delegate_ addProgressHUD];
+                hud = [self.delegate addProgressHUD];
                 [hud setText:UCLocalize("LOADING")];
             }
 
@@ -6768,7 +6810,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
             packages = [self yieldToSelector:@selector(_reloadPackages)];
 
             if (hud != nil)
-                [delegate_ removeProgressHUD:hud];
+                [self.delegate removeProgressHUD:hud];
         } while (reloading_ == 2);
     } else {
         packages = [self _reloadPackages];
@@ -7014,15 +7056,6 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
 @end
 /* }}} */
 
-/* Cydia Navigation Controller Interface {{{ */
-@interface UINavigationController (Cydia)
-
-- (NSArray *) navigationURLCollection;
-- (void) unloadData;
-
-@end
-/* }}} */
-
 /* Cydia Tab Bar Controller {{{ */
 @interface CydiaTabBarController : CyteTabBarController <
     UITabBarControllerDelegate,
@@ -7037,7 +7070,6 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
     _transient NSObject<CydiaDelegate> *updatedelegate_;
 }
 
-- (NSArray *) navigationURLCollection;
 - (void) beginUpdate;
 - (BOOL) updating;
 
@@ -7045,19 +7077,6 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
 
 @implementation CydiaTabBarController
 
-- (NSArray *) navigationURLCollection {
-    NSMutableArray *items([NSMutableArray array]);
-
-    // XXX: Should this deal with transient view controllers?
-    for (id navigation in [self viewControllers]) {
-        NSArray *stack = [navigation performSelector:@selector(navigationURLCollection)];
-        if (stack != nil)
-            [items addObject:stack];
-    }
-
-    return items;
-}
-
 - (id) initWithDatabase:(Database *)database {
     if ((self = [super init]) != nil) {
         database_ = database;
@@ -7156,47 +7175,6 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
 @end
 /* }}} */
 
-/* Cydia Navigation Controller Implementation {{{ */
-@implementation UINavigationController (Cydia)
-
-- (NSArray *) navigationURLCollection {
-    NSMutableArray *stack([NSMutableArray array]);
-
-    for (CyteViewController *controller in [self viewControllers]) {
-        NSString *url = [[controller navigationURL] absoluteString];
-        if (url != nil)
-            [stack addObject:url];
-    }
-
-    return stack;
-}
-
-- (void) reloadData {
-    [super reloadData];
-
-    UIViewController *visible([self visibleViewController]);
-    if (visible != nil)
-        [visible reloadData];
-
-    // on the iPad, this view controller is ALSO visible. :(
-    if (IsWildcat_)
-        if (UIViewController *modal = [self modalViewController])
-            if ([modal modalPresentationStyle] == UIModalPresentationFormSheet)
-                if (UIViewController *top = [self topViewController])
-                    if (top != visible)
-                        [top reloadData];
-}
-
-- (void) unloadData {
-    for (CyteViewController *page in [self viewControllers])
-        [page unloadData];
-
-    [super unloadData];
-}
-
-@end
-/* }}} */
-
 /* Cydia:// Protocol {{{ */
 @interface CydiaURLProtocol : NSURLProtocol {
 }
@@ -7435,7 +7413,7 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
     if (editing)
         [list_ reloadData];
     else
-        [delegate_ updateData];
+        [self.delegate updateData];
 
     [self updateNavigationItem];
 }
@@ -7497,7 +7475,7 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
         source:[self source]
         section:[section name]
     ] autorelease];
-    [controller setDelegate:delegate_];
+    [controller setDelegate:self.delegate];
 
     [[self navigationController] pushViewController:controller animated:YES];
 }
@@ -7642,7 +7620,7 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
 }
 
 - (void) setLeftBarButtonItem {
-    if ([delegate_ updating])
+    if ([self.delegate updating])
         [[self navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc]
             initWithTitle:UCLocalize("CANCEL")
             style:UIBarButtonItemStyleDone
@@ -7659,16 +7637,16 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
 }
 
 - (void) refreshButtonClicked {
-    if ([delegate_ requestUpdate])
+    if ([self.delegate requestUpdate])
         [self setLeftBarButtonItem];
 }
 
 - (void) cancelButtonClicked {
-    [delegate_ cancelUpdate];
+    [self.delegate cancelUpdate];
 }
 
 - (void) upgradeButtonClicked {
-    [delegate_ distUpgrade];
+    [self.delegate distUpgrade];
     [[self navigationItem] setRightBarButtonItem:nil animated:YES];
 }
 
@@ -8013,7 +7991,7 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
     if (package_ == nil)
         return;
     if ([package_ setSubscribed:value])
-        [delegate_ updateData];
+        [self.delegate updateData];
 }
 
 - (void) _updateIgnored {
@@ -8036,7 +8014,7 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
     [invocation setTarget:self];
     [invocation setSelector:@selector(_updateIgnored)];
 
-    [delegate_ reloadDataWithInvocation:invocation];
+    [self.delegate reloadDataWithInvocation:invocation];
 }
 
 - (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
@@ -8227,7 +8205,7 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
 
 #if !AlwaysReload
 - (void) queueButtonClicked {
-    [delegate_ queue];
+    [self.delegate queue];
 }
 #endif
 
@@ -8277,7 +8255,7 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
 - (void) _setImage:(NSArray *)data {
     if ([url_ isEqual:[data objectAtIndex:0]]) {
         icon_ = [data objectAtIndex:1];
-        [content_ setNeedsDisplay];
+        [self.content setNeedsDisplay];
     }
 }
 
@@ -8311,7 +8289,7 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
     origin_ = [source name];
     label_ = [source rooturi];
 
-    [content_ setNeedsDisplay];
+    [self.content setNeedsDisplay];
 
     url_ = [source iconURL];
     [NSThread detachNewThreadSelector:@selector(_setSource:) toTarget:self withObject:url_];
@@ -8324,7 +8302,7 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
     icon_ = [UIImage imageNamed:@"folder.png"];
     origin_ = UCLocalize("ALL_SOURCES");
     label_ = UCLocalize("ALL_SOURCES_EX");
-    [content_ setNeedsDisplay];
+    [self.content setNeedsDisplay];
 }
 
 - (SourceCell *) initWithFrame:(CGRect)frame reuseIdentifier:(NSString *)reuseIdentifier {
@@ -8332,19 +8310,19 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
         UIView *content([self contentView]);
         CGRect bounds([content bounds]);
 
-        content_ = [[[CyteTableViewCellContentView alloc] initWithFrame:bounds] autorelease];
-        [content_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
-        [content_ setBackgroundColor:[UIColor whiteColor]];
-        [content addSubview:content_];
+        self.content = [[[CyteTableViewCellContentView alloc] initWithFrame:bounds] autorelease];
+        [self.content setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+        [self.content setBackgroundColor:[UIColor whiteColor]];
+        [content addSubview:self.content];
 
-        [content_ setDelegate:self];
-        [content_ setOpaque:YES];
+        [self.content setDelegate:self];
+        [self.content setOpaque:YES];
 
         indicator_ = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGraySmall] autorelease];
         [indicator_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin];// | UIViewAutoresizingFlexibleBottomMargin];
         [content addSubview:indicator_];
 
-        [[content_ layer] setContentsGravity:kCAGravityTopLeft];
+        [[self.content layer] setContentsGravity:kCAGravityTopLeft];
     } return self;
 }
 
@@ -8368,7 +8346,7 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
 }
 
 - (void) drawContentRect:(CGRect)rect {
-    bool highlighted(highlighted_);
+    bool highlighted(self.highlighted);
     float width(rect.size.width);
 
     if (icon_ != nil) {
@@ -8512,7 +8490,7 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
         source:[self sourceAtIndexPath:indexPath]
     ] autorelease]);
 
-    [controller setDelegate:delegate_];
+    [controller setDelegate:self.delegate];
     [[self navigationController] pushViewController:controller animated:YES];
 }
 
@@ -8531,8 +8509,7 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
 
         [Sources_ removeObjectForKey:[source key]];
 
-        [delegate_ _saveConfig];
-        [delegate_ reloadDataWithInvocation:nil];
+        [self.delegate syncData];
     }
 }
 
@@ -8541,10 +8518,10 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
 }
 
 - (void) complete {
-    [delegate_ addTrivialSource:href_];
+    [self.delegate addTrivialSource:href_];
     href_ = nil;
 
-    [delegate_ syncData];
+    [self.delegate syncData];
 }
 
 - (NSString *) getWarning {
@@ -8583,9 +8560,9 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
     ) {
         NSString *warning(cydia_ ? [self yieldToSelector:@selector(getWarning)] : nil);
 
-        [delegate_ releaseNetworkActivityIndicator];
+        [self.delegate releaseNetworkActivityIndicator];
 
-        [delegate_ removeProgressHUD:hud_];
+        [self.delegate removeProgressHUD:hud_];
         hud_ = nil;
 
         if (cydia_) {
@@ -8702,9 +8679,9 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
                 cydia_ = false;
 
                 // XXX: this is stupid
-                hud_ = [delegate_ addProgressHUD];
+                hud_ = [self.delegate addProgressHUD];
                 [hud_ setText:UCLocalize("VERIFYING_URL")];
-                [delegate_ retainNetworkActivityIndicator];
+                [self.delegate retainNetworkActivityIndicator];
             } break;
 
             case 0:
@@ -8744,7 +8721,7 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
             target:self
             action:@selector(addButtonClicked)
         ] autorelease] animated:animated];
-    else if ([delegate_ updating])
+    else if ([self.delegate updating])
         [[self navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc]
             initWithTitle:UCLocalize("CANCEL")
             style:UIBarButtonItemStyleDone
@@ -8844,7 +8821,7 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
     [alert setNumberOfRows:1];
     [alert addTextFieldWithValue:@"http://" label:@""];
 
-    UITextInputTraits *traits = [[alert textField] textInputTraits];
+    NSObject<UITextInputTraits> *traits = [[alert textField] textInputTraits];
     [traits setAutocapitalizationType:UITextAutocapitalizationTypeNone];
     [traits setAutocorrectionType:UITextAutocorrectionTypeNo];
     [traits setKeyboardType:UIKeyboardTypeURL];
@@ -8859,12 +8836,12 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
 }
 
 - (void) refreshButtonClicked {
-    if ([delegate_ requestUpdate])
+    if ([self.delegate requestUpdate])
         [self updateButtonsForEditingStatusAnimated:YES];
 }
 
 - (void) cancelButtonClicked {
-    [delegate_ cancelUpdate];
+    [self.delegate cancelUpdate];
 }
 
 - (void) editButtonClicked {
@@ -8995,7 +8972,7 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
 
 @end
 
-@interface Cydia : UIApplication <
+@interface Cydia : CyteApplication <
     ConfirmationControllerDelegate,
     DatabaseDelegate,
     CydiaDelegate
@@ -9118,9 +9095,9 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
 
 - (void) reloadSpringBoard {
     if (kCFCoreFoundationVersionNumber >= 700) // XXX: iOS 6.x
-        system("/bin/launchctl stop com.apple.backboardd");
+        system("/usr/libexec/cydia/cydo /bin/launchctl stop com.apple.backboardd");
     else
-        system("/bin/launchctl stop com.apple.SpringBoard");
+        system("/usr/libexec/cydia/cydo /bin/launchctl stop com.apple.SpringBoard");
     sleep(15);
     system("/usr/bin/killall backboardd SpringBoard");
 }
@@ -9594,7 +9571,7 @@ _end
         [super applicationSuspend];
 }
 
-- (void) applicationSuspend:(__GSEvent *)event {
+- (void) applicationSuspend:(GSEventRef)event {
     if ([self isSafeToSuspend])
         [super applicationSuspend:event];
 }
@@ -9894,32 +9871,9 @@ _end
     [tabbar_ setUpdateDelegate:self];
 }
 
-- (void) _sendMemoryWarningNotification {
-    if (kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iPhoneOS_3_0) // XXX: maybe 4_0?
-        [[NSNotificationCenter defaultCenter] postNotificationName:@"UIApplicationMemoryWarningNotification" object:[UIApplication sharedApplication]];
-    else
-        [[NSNotificationCenter defaultCenter] postNotificationName:@"UIApplicationDidReceiveMemoryWarningNotification" object:[UIApplication sharedApplication]];
-}
-
-- (void) _sendMemoryWarningNotifications {
-    while (true) {
-        [self performSelectorOnMainThread:@selector(_sendMemoryWarningNotification) withObject:nil waitUntilDone:NO];
-        sleep(2);
-        //usleep(2000000);
-    }
-}
-
-- (void) applicationDidReceiveMemoryWarning:(UIApplication *)application {
-    NSLog(@"--");
-    [[NSURLCache sharedURLCache] removeAllCachedResponses];
-}
-
 - (void) applicationDidFinishLaunching:(id)unused {
-    //[NSThread detachNewThreadSelector:@selector(_sendMemoryWarningNotifications) toTarget:self withObject:nil];
-
+    [super applicationDidFinishLaunching:unused];
 _trace();
-    if ([self respondsToSelector:@selector(setApplicationSupportsShakeToEdit:)])
-        [self setApplicationSupportsShakeToEdit:NO];
 
     @synchronized (HostConfig_) {
         [BridgedHosts_ addObject:[[NSURL URLWithString:CydiaURL(@"")] host]];
@@ -10325,7 +10279,7 @@ int main(int argc, char *argv[]) {
         }
 
     languages += "en";
-    NSLog(@"Setting Language: %s", languages.c_str());
+    NSLog(@"Setting Language: [%s] %s", translation, languages.c_str());
     /* }}} */
     /* Index Collation {{{ */
     if (Class $UILocalizedIndexedCollation = objc_getClass("UILocalizedIndexedCollation")) { @try {
@@ -10579,8 +10533,7 @@ int main(int argc, char *argv[]) {
 
     if (translation != NULL)
         _config->Set("APT::Acquire::Translation", translation);
-    if (!languages.empty())
-        _config->Set("Acquire::Languages", languages);
+    _config->Set("Acquire::Languages", languages);
 
     // XXX: this timeout might be important :(
     //_config->Set("Acquire::http::Timeout", 15);