]> git.saurik.com Git - cydia.git/blobdiff - Cydia.mm
We don't like the SWF debugging.
[cydia.git] / Cydia.mm
index 3daeb4547cd78673dfa2347389fe6c474cd87f1e..c40a0d27d118be750bbde57800cbbd9ddb8c76cb 100644 (file)
--- a/Cydia.mm
+++ b/Cydia.mm
 #include <GraphicsServices/GraphicsServices.h>
 #include <Foundation/Foundation.h>
 
+#if 0
+#define DEPLOYMENT_TARGET_MACOSX 1
+#define CF_BUILDING_CF 1
+#include <CoreFoundation/CFInternal.h>
+#endif
+
+#include <CoreFoundation/CFPriv.h>
+#include <CoreFoundation/CFUniChar.h>
+
 #import <QuartzCore/CALayer.h>
 #import <UIKit/UIKit.h>
 
 #include <WebCore/WebCoreThread.h>
 #import <WebKit/WebDefaultUIKitDelegate.h>
 
+#include <algorithm>
 #include <iomanip>
 #include <sstream>
 #include <string>
@@ -216,12 +226,18 @@ class _H {
         Clear_();
     }
 
+    _finline operator Type_ *() const {
+        return value_;
+    }
+
     _finline This_ &operator =(Type_ *value) {
         if (value_ != value) {
-            Clear_();
+            Type_ *old(value_);
             value_ = value;
             Retain_();
-        } return this;
+            if (old != nil)
+                [old release];
+        } return *this;
     }
 };
 /* }}} */
@@ -254,8 +270,9 @@ void NSLogRect(const char *fix, const CGRect &rect) {
     /* XXX: deal with exceptions */
     id value([self performSelector:selector withObject:object]);
 
+    NSMethodSignature *signature([self methodSignatureForSelector:selector]);
     [context removeAllObjects];
-    if (value != nil)
+    if ([signature methodReturnLength] != 0 && value != nil)
         [context addObject:value];
 
     stopped = true;
@@ -302,9 +319,8 @@ void NSLogRect(const char *fix, const CGRect &rect) {
 
 /* NSForcedOrderingSearch doesn't work on the iPhone */
 static const NSStringCompareOptions MatchCompareOptions_ = NSLiteralSearch | NSCaseInsensitiveSearch;
-static const NSStringCompareOptions BaseCompareOptions_ = NSNumericSearch | NSDiacriticInsensitiveSearch | NSWidthInsensitiveSearch;
-static const NSStringCompareOptions ForcedCompareOptions_ = BaseCompareOptions_;
-static const NSStringCompareOptions LaxCompareOptions_ = BaseCompareOptions_ | NSCaseInsensitiveSearch;
+static const NSStringCompareOptions LaxCompareOptions_ = NSNumericSearch | NSDiacriticInsensitiveSearch | NSWidthInsensitiveSearch | NSCaseInsensitiveSearch;
+static const CFStringCompareFlags LaxCompareFlags_ = kCFCompareCaseInsensitive | kCFCompareNonliteral | kCFCompareLocalized | kCFCompareNumerically | kCFCompareWidthInsensitive | kCFCompareForcedOrdering;
 
 /* iPhoneOS 2.0 Compatibility {{{ */
 #ifdef __OBJC2__
@@ -387,17 +403,24 @@ extern NSString * const kCAFilterNearest;
 #define lprintf(args...) fprintf(stderr, args)
 
 #define ForRelease 0
+#define TraceLogging (1 && !ForRelease)
+#define HistogramInsertionSort (0 && !ForRelease)
+#define ProfileTimes (1 && !ForRelease)
 #define ForSaurik (0 && !ForRelease)
-#define LogBrowser (1 && !ForRelease)
+#define LogBrowser (0 && !ForRelease)
+#define TrackResize (0 && !ForRelease)
 #define ManualRefresh (1 && !ForRelease)
 #define ShowInternals (0 && !ForRelease)
 #define IgnoreInstall (0 && !ForRelease)
 #define RecycleWebViews 0
 #define AlwaysReload (1 && !ForRelease)
 
-#if ForRelease
+#if !TraceLogging
 #undef _trace
 #define _trace(args...)
+#endif
+
+#if !ProfileTimes
 #undef _profile
 #define _profile(name) {
 #undef _end
@@ -406,9 +429,11 @@ extern NSString * const kCAFilterNearest;
 #endif
 
 /* Radix Sort {{{ */
+typedef uint32_t (*SKRadixFunction)(id, void *);
+
 @interface NSMutableArray (Radix)
 - (void) radixSortUsingSelector:(SEL)selector withObject:(id)object;
-- (void) radixSortUsingFunction:(uint32_t (*)(id, void *))function withArgument:(void *)argument;
+- (void) radixSortUsingFunction:(SKRadixFunction)function withContext:(void *)argument;
 @end
 
 struct RadixItem_ {
@@ -468,11 +493,22 @@ static void RadixSort_(NSMutableArray *self, size_t count, struct RadixItem_ *sw
 @implementation NSMutableArray (Radix)
 
 - (void) radixSortUsingSelector:(SEL)selector withObject:(id)object {
+    size_t count([self count]);
+    if (count == 0)
+        return;
+
+#if 0
     NSInvocation *invocation([NSInvocation invocationWithMethodSignature:[NSMethodSignature signatureWithObjCTypes:"L12@0:4@8"]]);
     [invocation setSelector:selector];
     [invocation setArgument:&object atIndex:2];
+#else
+    /* XXX: this is an unsafe optimization of doomy hell */
+    Method method(class_getInstanceMethod([[self objectAtIndex:0] class], selector));
+    _assert(method != NULL);
+    uint32_t (*imp)(id, SEL, id) = reinterpret_cast<uint32_t (*)(id, SEL, id)>(method_getImplementation(method));
+    _assert(imp != NULL);
+#endif
 
-    size_t count([self count]);
     struct RadixItem_ *swap(new RadixItem_[count * 2]);
 
     for (size_t i(0); i != count; ++i) {
@@ -480,16 +516,20 @@ static void RadixSort_(NSMutableArray *self, size_t count, struct RadixItem_ *sw
         item.index = i;
 
         id object([self objectAtIndex:i]);
-        [invocation setTarget:object];
 
+#if 0
+        [invocation setTarget:object];
         [invocation invoke];
         [invocation getReturnValue:&item.key];
+#else
+        item.key = imp(object, selector, object);
+#endif
     }
 
     RadixSort_(self, count, swap);
 }
 
-- (void) radixSortUsingFunction:(uint32_t (*)(id, void *))function withArgument:(void *)argument {
+- (void) radixSortUsingFunction:(SKRadixFunction)function withContext:(void *)argument {
     size_t count([self count]);
     struct RadixItem_ *swap(new RadixItem_[count * 2]);
 
@@ -505,6 +545,77 @@ static void RadixSort_(NSMutableArray *self, size_t count, struct RadixItem_ *sw
 }
 
 @end
+/* }}} */
+/* Insertion Sort {{{ */
+
+CFIndex SKBSearch_(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;
+}
+
+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)
+        return;
+    const void **values(new const void *[range.length]);
+    CFArrayGetValues(array, range, values);
+
+#if HistogramInsertionSort
+    uint32_t total(0), *offsets(new uint32_t[range.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);
+        while (comparator(value, values[correct - 1], context) == kCFCompareLessThan)
+            if (--correct == 0)
+                break;
+        if (correct != index) {
+            size_t offset(index - correct);
+#if HistogramInsertionSort
+            total += offset;
+            ++offsets[offset];
+            if (offset > 10)
+                NSLog(@"Heavy Insertion Displacement: %u = %@", offset, value);
+#endif
+            memmove(values + correct + 1, values + correct, sizeof(const void *) * offset);
+            values[correct] = value;
+        }
+    }
+
+    CFArrayReplaceValues(array, range, values, range.length);
+    delete [] values;
+
+#if HistogramInsertionSort
+    for (CFIndex 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);
+    delete [] offsets;
+#endif
+}
+
 /* }}} */
 
 /* Apple Bug Fixes {{{ */
@@ -701,8 +812,9 @@ class CYString {
         else {
             clear_();
 
-            char *temp(reinterpret_cast<char *>(apr_palloc(pool, size)));
+            char *temp(reinterpret_cast<char *>(apr_palloc(pool, size + 1)));
             memcpy(temp, data, size);
+            temp[size] = '\0';
             data_ = temp;
             size_ = size;
         }
@@ -720,12 +832,16 @@ class CYString {
         return size_ == rhs.size_ && memcmp(data_, rhs.data_, size_) == 0;
     }
 
-    operator id() {
+    operator CFStringRef() {
         if (cache_ == NULL) {
             if (size_ == 0)
                 return nil;
             cache_ = CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<uint8_t *>(data_), size_, kCFStringEncodingUTF8, NO, kCFAllocatorNull);
-        } return (id) cache_;
+        } return cache_;
+    }
+
+    _finline operator id() {
+        return (NSString *) static_cast<CFStringRef>(*this);
     }
 };
 
@@ -966,6 +1082,7 @@ static const NSString *Product_ = nil;
 static const NSString *Safari_ = nil;
 
 CFLocaleRef Locale_;
+NSArray *Languages_;
 CGColorSpaceRef space_;
 
 bool bootstrap_;
@@ -1021,15 +1138,30 @@ NSString *SizeString(double size) {
     return [NSString stringWithFormat:@"%s%.1f %s", (negative ? "-" : ""), size, powers_[power]];
 }
 
-NSString *StripVersion(NSString *version) {
-    NSRange colon = [version rangeOfString:@":"];
-    if (colon.location != NSNotFound)
-        version = [version substringFromIndex:(colon.location + 1)];
-    return version;
+static _finline CFStringRef CFCString(const char *value) {
+    return CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<const uint8_t *>(value), strlen(value), kCFStringEncodingUTF8, NO, kCFAllocatorNull);
+}
+
+CFStringRef StripVersion(const char *version) {
+    const char *colon(strchr(version, ':'));
+    if (colon != NULL)
+        version = colon + 1;
+    return CFCString(version);
 }
 
 NSString *LocalizeSection(NSString *section) {
-    return section;
+    static Pcre title_r("^(.*?) \\((.*)\\)$");
+    if (title_r(section)) {
+        NSString *parent(title_r[1]);
+        NSString *child(title_r[2]);
+
+        return [NSString stringWithFormat:CYLocalize("PARENTHETICAL"),
+            LocalizeSection(parent),
+            LocalizeSection(child)
+        ];
+    }
+
+    return [[NSBundle mainBundle] localizedStringForKey:section value:nil table:@"Sections"];
 }
 
 NSString *Simplify(NSString *title) {
@@ -1044,7 +1176,7 @@ NSString *Simplify(NSString *title) {
     if (paren_r(data, size))
         return Simplify(paren_r[1]);
 
-    static Pcre title_r("^(.*?) \\(.*\\)$");
+    static Pcre title_r("^(.*?) \\((.*)\\)$");
     if (title_r(data, size))
         return Simplify(title_r[1]);
 
@@ -1053,8 +1185,8 @@ NSString *Simplify(NSString *title) {
 /* }}} */
 
 bool isSectionVisible(NSString *section) {
-    NSDictionary *metadata = [Sections_ objectForKey:section];
-    NSNumber *hidden = metadata == nil ? nil : [metadata objectForKey:@"Hidden"];
+    NSDictionary *metadata([Sections_ objectForKey:section]);
+    NSNumber *hidden(metadata == nil ? nil : [metadata objectForKey:@"Hidden"]);
     return hidden == nil || ![hidden boolValue];
 }
 
@@ -1218,6 +1350,8 @@ class Progress :
 /* }}} */
 
 /* Database Interface {{{ */
+typedef std::map< unsigned long, _H<Source> > SourceMap;
+
 @interface Database : NSObject {
     NSZone *zone_;
     apr_pool_t *pool_;
@@ -1233,7 +1367,7 @@ class Progress :
     SPtr<pkgPackageManager> manager_;
     pkgSourceList *list_;
 
-    NSMutableDictionary *sources_;
+    SourceMap sources_;
     NSMutableArray *packages_;
 
     _transient NSObject<ConfigurationDelegate, ProgressDelegate> *delegate_;
@@ -1528,6 +1662,7 @@ class Progress :
 /* Package Class {{{ */
 @interface Package : NSObject {
     unsigned era_;
+    apr_pool_t *pool_;
 
     pkgCache::VerIterator version_;
     pkgCache::PkgIterator iterator_;
@@ -1536,15 +1671,17 @@ class Progress :
 
     Source *source_;
     bool cached_;
+    bool parsed_;
 
     CYString section_;
     NSString *section$_;
     bool essential_;
+    bool visible_;
 
     NSString *latest_;
     NSString *installed_;
 
-    NSString *id_;
+    CYString id_;
     CYString name_;
     CYString tagline_;
     CYString icon_;
@@ -1558,17 +1695,22 @@ class Progress :
     Address *author$_;
 
     CYString support_;
-    NSArray *tags_;
+    NSMutableArray *tags_;
     NSString *role_;
 
     NSArray *relationships_;
+
     NSMutableDictionary *metadata_;
+    _transient NSDate *firstSeen_;
+    _transient NSDate *lastSeen_;
+    bool subscribed_;
 }
 
 - (Package *) initWithVersion:(pkgCache::VerIterator)version withZone:(NSZone *)zone inPool:(apr_pool_t *)pool database:(Database *)database;
 + (Package *) packageWithIterator:(pkgCache::PkgIterator)iterator withZone:(NSZone *)zone inPool:(apr_pool_t *)pool database:(Database *)database;
 
 - (pkgCache::PkgIterator) iterator;
+- (void) parse;
 
 - (NSString *) section;
 - (NSString *) simpleSection;
@@ -1580,7 +1722,8 @@ class Progress :
 
 - (Address *) maintainer;
 - (size_t) size;
-- (NSString *) description;
+- (NSString *) longDescription;
+- (NSString *) shortDescription;
 - (unichar) index;
 
 - (NSMutableDictionary *) metadata;
@@ -1606,7 +1749,6 @@ class Progress :
 
 - (NSString *) id;
 - (NSString *) name;
-- (NSString *) tagline;
 - (UIImage *) icon;
 - (NSString *) homepage;
 - (NSString *) depiction;
@@ -1630,8 +1772,8 @@ class Progress :
 - (NSArray *) purposes;
 - (bool) isCommercial;
 
-- (uint32_t) compareByPrefix;
-- (NSComparisonResult) compareByName:(Package *)package;
+- (CYString &) cyname;
+
 - (uint32_t) compareBySection:(NSArray *)sections;
 
 - (uint32_t) compareForChanges;
@@ -1673,8 +1815,107 @@ uint32_t PackageChangesRadix(Package *self, void *) {
     return _not(uint32_t) - value.key;
 }
 
+_finline static void Stifle(uint8_t &value) {
+}
+
+uint32_t PackagePrefixRadix(Package *self, void *context) {
+    size_t offset(reinterpret_cast<size_t>(context));
+    CYString &name([self cyname]);
+
+    size_t size(name.size());
+    if (size == 0)
+        return 0;
+    char *text(name.data());
+
+    size_t zeros;
+    if (!isdigit(text[0]))
+        zeros = 0;
+    else {
+        size_t digits(1);
+        while (size != digits && isdigit(text[digits]))
+            if (++digits == 4)
+                break;
+        zeros = 4 - digits;
+    }
+
+    uint8_t data[4];
+
+    // 0.607997
+
+    if (offset == 0 && zeros != 0) {
+        memset(data, '0', zeros);
+        memcpy(data + zeros, text, 4 - zeros);
+    } else {
+        /* XXX: there's some danger here if you request a non-zero offset < 4 and it gets zero padded */
+        if (size <= offset - zeros)
+            return 0;
+
+        text += offset - zeros;
+        size -= offset - zeros;
+
+        if (size >= 4)
+            memcpy(data, text, 4);
+        else {
+            memcpy(data, text, size);
+            memset(data + size, 0, 4 - size);
+        }
+
+        for (size_t i(0); i != 4; ++i)
+            if (isalpha(data[i]))
+                data[i] &= 0xdf;
+    }
+
+    if (offset == 0)
+        data[0] = (data[0] & 0x3f) | "\x80\x00\xc0\x40"[data[0] >> 6];
+
+    /* XXX: ntohl may be more honest */
+    return OSSwapInt32(*reinterpret_cast<uint32_t *>(data));
+}
+
+CYString &(*PackageName)(Package *self, SEL sel);
+
+CFComparisonResult PackageNameCompare(Package *lhs, Package *rhs, void *arg) {
+    _profile(PackageNameCompare)
+        CYString &lhi(PackageName(lhs, @selector(cyname)));
+        CYString &rhi(PackageName(rhs, @selector(cyname)));
+        CFStringRef lhn(lhi), rhn(rhi);
+
+        _profile(PackageNameCompare$NumbersLast)
+            if (!lhi.empty() && !rhi.empty()) {
+                UniChar lhc(CFStringGetCharacterAtIndex(lhn, 0));
+                UniChar rhc(CFStringGetCharacterAtIndex(rhn, 0));
+                bool lha(CFUniCharIsMemberOf(lhc, kCFUniCharLetterCharacterSet));
+                if (lha != CFUniCharIsMemberOf(rhc, kCFUniCharLetterCharacterSet))
+                    return lha ? NSOrderedAscending : NSOrderedDescending;
+            }
+        _end
+
+        CFIndex length = CFStringGetLength(lhn);
+
+        _profile(PackageNameCompare$Compare)
+            return CFStringCompareWithOptionsAndLocale(lhn, rhn, CFRangeMake(0, length), LaxCompareFlags_, Locale_);
+        _end
+    _end
+}
+
+CFComparisonResult PackageNameCompare_(Package **lhs, Package **rhs, void *context) {
+    return PackageNameCompare(*lhs, *rhs, context);
+}
+
+struct PackageNameOrdering :
+    std::binary_function<Package *, Package *, bool>
+{
+    _finline bool operator ()(Package *lhs, Package *rhs) const {
+        return PackageNameCompare(lhs, rhs, NULL) == NSOrderedAscending;
+    }
+};
+
 @implementation Package
 
+- (NSString *) description {
+    return [NSString stringWithFormat:@"<Package:%@>", static_cast<NSString *>(name_)];
+}
+
 - (void) dealloc {
     if (source_ != nil)
         [source_ release];
@@ -1686,8 +1927,6 @@ uint32_t PackageChangesRadix(Package *self, void *) {
     if (installed_ != nil)
         [installed_ release];
 
-    if (id_ != nil)
-        [id_ release];
     if (sponsor$_ != nil)
         [sponsor$_ release];
     if (author$_ != nil)
@@ -1717,7 +1956,7 @@ uint32_t PackageChangesRadix(Package *self, void *) {
 }
 
 + (NSArray *) _attributeKeys {
-    return [NSArray arrayWithObjects:@"applications", @"author", @"depiction", @"description", @"essential", @"homepage", @"icon", @"id", @"installed", @"latest", @"longSection", @"maintainer", @"mode", @"name", @"purposes", @"section", @"shortSection", @"simpleSection", @"size", @"source", @"sponsor", @"support", @"tagline", @"warnings", nil];
+    return [NSArray arrayWithObjects:@"applications", @"author", @"depiction", @"longDescription", @"essential", @"homepage", @"icon", @"id", @"installed", @"latest", @"longSection", @"maintainer", @"mode", @"name", @"purposes", @"section", @"shortDescription", @"shortSection", @"simpleSection", @"size", @"source", @"sponsor", @"support", @"warnings", nil];
 }
 
 - (NSArray *) attributeKeys {
@@ -1728,33 +1967,90 @@ uint32_t PackageChangesRadix(Package *self, void *) {
     return ![[self _attributeKeys] containsObject:[NSString stringWithUTF8String:name]] && [super isKeyExcludedFromWebScript:name];
 }
 
+- (void) parse {
+    if (parsed_)
+        return;
+    parsed_ = true;
+    if (file_.end())
+        return;
+
+    _profile(Package$parse)
+        pkgRecords::Parser *parser;
+
+        _profile(Package$parse$Lookup)
+            parser = &[database_ records]->Lookup(file_);
+        _end
+
+        CYString website;
+
+        _profile(Package$parse$Find)
+            struct {
+                const char *name_;
+                CYString *value_;
+            } names[] = {
+                {"icon", &icon_},
+                {"depiction", &depiction_},
+                {"homepage", &homepage_},
+                {"website", &website},
+                {"support", &support_},
+                {"sponsor", &sponsor_},
+                {"author", &author_},
+            };
+
+            for (size_t i(0); i != sizeof(names) / sizeof(names[0]); ++i) {
+                const char *start, *end;
+
+                if (parser->Find(names[i].name_, start, end)) {
+                    CYString &value(*names[i].value_);
+                    _profile(Package$parse$Value)
+                        value.set(pool_, start, end - start);
+                    _end
+                }
+            }
+        _end
+
+        _profile(Package$parse$Tagline)
+            const char *start, *end;
+            if (parser->ShortDesc(start, end)) {
+                const char *stop(reinterpret_cast<const char *>(memchr(start, '\n', end - start)));
+                if (stop == NULL)
+                    stop = end;
+                while (stop != start && stop[-1] == '\r')
+                    --stop;
+                tagline_.set(pool_, start, stop - start);
+            }
+        _end
+
+        _profile(Package$parse$Retain)
+            if (!homepage_.empty())
+                homepage_ = website;
+            if (homepage_ == depiction_)
+                homepage_.clear();
+        _end
+    _end
+}
+
 - (Package *) initWithVersion:(pkgCache::VerIterator)version withZone:(NSZone *)zone inPool:(apr_pool_t *)pool database:(Database *)database {
     if ((self = [super init]) != nil) {
     _profile(Package$initWithVersion)
     @synchronized (database) {
         era_ = [database era];
+        pool_ = pool;
 
         version_ = version;
         iterator_ = version.ParentPkg();
         database_ = database;
 
         _profile(Package$initWithVersion$Latest)
-            latest_ = [StripVersion([NSString stringWithUTF8String:version_.VerStr()]) retain];
+            latest_ = (NSString *) StripVersion(version_.VerStr());
         _end
 
         pkgCache::VerIterator current;
-        NSString *installed;
-
-        _profile(Package$initWithVersion$Current)
+        _profile(Package$initWithVersion$Versions)
             current = iterator_.CurrentVer();
-            installed = current.end() ? nil : [NSString stringWithUTF8String:current.VerStr()];
-        _end
-
-        _profile(Package$initWithVersion$Installed)
-            installed_ = [StripVersion(installed) retain];
-        _end
+            if (!current.end())
+                installed_ = (NSString *) StripVersion(current.VerStr());
 
-        _profile(Package$initWithVersion$File)
             if (!version_.end())
                 file_ = version_.FileList();
             else {
@@ -1764,101 +2060,31 @@ uint32_t PackageChangesRadix(Package *self, void *) {
         _end
 
         _profile(Package$initWithVersion$Name)
-            id_ = [[NSString stringWithUTF8String:iterator_.Name()] retain];
+            id_.set(pool_, iterator_.Name());
+            name_.set(pool, iterator_.Display());
         _end
 
-        if (!file_.end())
-            source_ = [database_ getSource:file_.File()];
-            if (source_ != nil)
-                [source_ retain];
-            cached_ = true;
-
-            _profile(Package$initWithVersion$Parse)
-                pkgRecords::Parser *parser;
-
-                _profile(Package$initWithVersion$Parse$Lookup)
-                    parser = &[database_ records]->Lookup(file_);
-                _end
-
-                const char *begin, *end;
-                parser->GetRec(begin, end);
-
-                CYString website;
-                CYString tag;
-
-                struct {
-                    const char *name_;
-                    CYString *value_;
-                } names[] = {
-                    {"name", &name_},
-                    {"icon", &icon_},
-                    {"depiction", &depiction_},
-                    {"homepage", &homepage_},
-                    {"website", &website},
-                    {"support", &support_},
-                    {"sponsor", &sponsor_},
-                    {"author", &author_},
-                    {"tag", &tag},
-                };
-
-                while (begin != end)
-                    if (*begin == '\n') {
-                        ++begin;
-                        continue;
-                    } else if (isblank(*begin)) next: {
-                        begin = static_cast<char *>(memchr(begin + 1, '\n', end - begin - 1));
-                        if (begin == NULL)
-                            break;
-                    } else if (const char *colon = static_cast<char *>(memchr(begin, ':', end - begin))) {
-                        const char *name(begin);
-                        size_t size(colon - begin);
-
-                        begin = static_cast<char *>(memchr(begin, '\n', end - begin));
-
-                        {
-                            const char *stop(begin == NULL ? end : begin);
-                            while (stop[-1] == '\r')
-                                --stop;
-                            while (++colon != stop && isblank(*colon));
-
-                            for (size_t i(0); i != sizeof(names) / sizeof(names[0]); ++i)
-                                if (strncasecmp(names[i].name_, name, size) == 0) {
-                                    CYString &value(*names[i].value_);
-
-                                    _profile(Package$initWithVersion$Parse$Value)
-                                        value.set(pool, colon, stop - colon);
-                                    _end
-
-                                    break;
-                                }
-                        }
-
-                        if (begin == NULL)
-                            break;
-                        ++begin;
-                    } else goto next;
-
-                _profile(Package$initWithVersion$Parse$Tagline)
-                    tagline_.set(pool, parser->ShortDesc());
-                _end
-
-                _profile(Package$initWithVersion$Parse$Retain)
-                    if (!homepage_.empty())
-                        homepage_ = website;
-                    if (homepage_ == depiction_)
-                        homepage_.clear();
-                    if (!tag.empty())
-                        tags_ = [[tag componentsSeparatedByString:@", "] retain];
-                _end
+        if (!file_.end()) {
+            _profile(Package$initWithVersion$Source)
+                source_ = [database_ getSource:file_.File()];
+                if (source_ != nil)
+                    [source_ retain];
+                cached_ = true;
             _end
+        }
 
         _profile(Package$initWithVersion$Tags)
-            if (tags_ != nil)
-                for (NSString *tag in tags_)
-                    if ([tag hasPrefix:@"role::"]) {
-                        role_ = [[tag substringFromIndex:6] retain];
-                        break;
-                    }
+            pkgCache::TagIterator tag(iterator_.TagList());
+            if (!tag.end()) {
+                tags_ = [[NSMutableArray alloc] initWithCapacity:8];
+                do {
+                    const char *name(tag.Name());
+                    [tags_ addObject:(NSString *)CFCString(name)];
+                    if (role_ == nil && strncmp(name, "role::", 6) == 0)
+                        role_ = (NSString *) CFCString(name + 6);
+                    ++tag;
+                } while (!tag.end());
+            }
         _end
 
         bool changed(false);
@@ -1866,21 +2092,28 @@ uint32_t PackageChangesRadix(Package *self, void *) {
 
         _profile(Package$initWithVersion$Metadata)
             metadata_ = [Packages_ objectForKey:key];
+
             if (metadata_ == nil) {
+                firstSeen_ = now_;
+
                 metadata_ = [[NSMutableDictionary dictionaryWithObjectsAndKeys:
-                    now_, @"FirstSeen",
+                    firstSeen_, @"FirstSeen",
+                    latest_, @"LastVersion",
                 nil] mutableCopy];
 
-                [metadata_ setObject:latest_ forKey:@"LastVersion"];
                 changed = true;
             } else {
-                NSDate *first([metadata_ objectForKey:@"FirstSeen"]);
-                NSDate *last([metadata_ objectForKey:@"LastSeen"]);
+                firstSeen_ = [metadata_ objectForKey:@"FirstSeen"];
+                lastSeen_ = [metadata_ objectForKey:@"LastSeen"];
+
+                if (NSNumber *subscribed = [metadata_ objectForKey:@"IsSubscribed"])
+                    subscribed_ = [subscribed boolValue];
+
                 NSString *version([metadata_ objectForKey:@"LastVersion"]);
 
-                if (first == nil) {
-                    first = last == nil ? now_ : last;
-                    [metadata_ setObject:first forKey:@"FirstSeen"];
+                if (firstSeen_ == nil) {
+                    firstSeen_ = lastSeen_ == nil ? now_ : lastSeen_;
+                    [metadata_ setObject:firstSeen_ forKey:@"FirstSeen"];
                     changed = true;
                 }
 
@@ -1889,8 +2122,8 @@ uint32_t PackageChangesRadix(Package *self, void *) {
                     changed = true;
                 } else if (![version isEqualToString:latest_]) {
                     [metadata_ setObject:latest_ forKey:@"LastVersion"];
-                    last = now_;
-                    [metadata_ setObject:last forKey:@"LastSeen"];
+                    lastSeen_ = now_;
+                    [metadata_ setObject:lastSeen_ forKey:@"LastSeen"];
                     changed = true;
                 }
             }
@@ -1904,17 +2137,24 @@ uint32_t PackageChangesRadix(Package *self, void *) {
         _end
 
         _profile(Package$initWithVersion$Section)
-            section_.set(pool, iterator_.Section());
+            section_.set(pool_, iterator_.Section());
         _end
 
         essential_ = ((iterator_->Flags & pkgCache::Flag::Essential) == 0 ? NO : YES) || [self hasTag:@"cydia::essential"];
+        visible_ = [self hasSupportingRole] && [self unfiltered];
     } _end } return self;
 }
 
 + (Package *) packageWithIterator:(pkgCache::PkgIterator)iterator withZone:(NSZone *)zone inPool:(apr_pool_t *)pool database:(Database *)database {
-    pkgCache::VerIterator version([database policy]->GetCandidateVer(iterator));
+    pkgCache::VerIterator version;
+
+    _profile(Package$packageWithIterator$GetCandidateVer)
+        version = [database policy]->GetCandidateVer(iterator);
+    _end
+
     if (version.end())
         return nil;
+
     return [[[Package alloc]
         initWithVersion:version
         withZone:zone
@@ -1986,7 +2226,7 @@ uint32_t PackageChangesRadix(Package *self, void *) {
     return version_.end() ? 0 : version_->InstalledSize;
 }
 
-- (NSString *) description {
+- (NSString *) longDescription {
     if (file_.end())
         return nil;
     pkgRecords::Parser *parser = &[database_ records]->Lookup(file_);
@@ -2006,38 +2246,34 @@ uint32_t PackageChangesRadix(Package *self, void *) {
     return [trimmed componentsJoinedByString:@"\n"];
 }
 
+- (NSString *) shortDescription {
+    return tagline_;
+}
+
 - (unichar) index {
     _profile(Package$index)
-        NSString *name([self name]);
-        if ([name length] == 0)
+        CFStringRef name((CFStringRef) [self name]);
+        if (CFStringGetLength(name) == 0)
             return '#';
-        unichar character([name characterAtIndex:0]);
-        if (!isalpha(character))
+        UniChar character(CFStringGetCharacterAtIndex(name, 0));
+        if (!CFUniCharIsMemberOf(character, kCFUniCharLetterCharacterSet))
             return '#';
         return toupper(character);
     _end
 }
 
 - (NSMutableDictionary *) metadata {
-    if (metadata_ == nil)
-        metadata_ = [[Packages_ objectForKey:[id_ lowercaseString]] retain];
     return metadata_;
 }
 
 - (NSDate *) seen {
-    NSDictionary *metadata([self metadata]);
-    if ([self subscribed])
-        if (NSDate *last = [metadata objectForKey:@"LastSeen"])
-            return last;
-    return [metadata objectForKey:@"FirstSeen"];
+    if (subscribed_ && lastSeen_ != nil)
+        return lastSeen_;
+    return firstSeen_;
 }
 
 - (BOOL) subscribed {
-    NSDictionary *metadata([self metadata]);
-    if (NSNumber *subscribed = [metadata objectForKey:@"IsSubscribed"])
-        return [subscribed boolValue];
-    else
-        return false;
+    return subscribed_;
 }
 
 - (BOOL) ignored {
@@ -2061,14 +2297,13 @@ uint32_t PackageChangesRadix(Package *self, void *) {
 }
 
 - (BOOL) upgradableAndEssential:(BOOL)essential {
-    pkgCache::VerIterator current = iterator_.CurrentVer();
-
-    bool value;
-    if (current.end())
-        value = essential && [self essential] && [self visible];
-    else
-        value = !version_.end() && version_ != current;// && (!essential || ![database_ cache][iterator_].Keep());
-    return value;
+    _profile(Package$upgradableAndEssential)
+        pkgCache::VerIterator current(iterator_.CurrentVer());
+        if (current.end())
+            return essential && essential_ && visible_;
+        else
+            return !version_.end() && version_ != current;// && (!essential || ![database_ cache][iterator_].Keep());
+    _end
 }
 
 - (BOOL) essential {
@@ -2080,16 +2315,16 @@ uint32_t PackageChangesRadix(Package *self, void *) {
 }
 
 - (BOOL) unfiltered {
-    NSString *section = [self section];
+    NSString *section([self section]);
     return section == nil || isSectionVisible(section);
 }
 
 - (BOOL) visible {
-    return [self hasSupportingRole] && [self unfiltered];
+    return visible_;
 }
 
 - (BOOL) half {
-    unsigned char current = iterator_->CurrentState;
+    unsigned char current(iterator_->CurrentState);
     return current == pkgCache::State::HalfConfigured || current == pkgCache::State::HalfInstalled;
 }
 
@@ -2147,18 +2382,14 @@ uint32_t PackageChangesRadix(Package *self, void *) {
 }
 
 - (NSString *) name {
-    return name_ == nil ? id_ : name_;
-}
-
-- (NSString *) tagline {
-    return tagline_;
+    return name_.empty() ? id_ : name_;
 }
 
 - (UIImage *) icon {
     NSString *section = [self simpleSection];
 
     UIImage *icon(nil);
-    if (icon_ != nil)
+    if (!icon_.empty())
         if ([icon_ hasPrefix:@"file:///"])
             icon = [UIImage imageAtPath:[icon_ substringFromIndex:7]];
     if (icon == nil) if (section != nil)
@@ -2196,11 +2427,11 @@ uint32_t PackageChangesRadix(Package *self, void *) {
 }
 
 - (NSString *) support {
-    return support_ != nil ? support_ : [[self source] supportForPackage:id_];
+    return !support_.empty() ? support_ : [[self source] supportForPackage:id_];
 }
 
 - (NSArray *) files {
-    NSString *path = [NSString stringWithFormat:@"/var/lib/dpkg/info/%@.list", id_];
+    NSString *path = [NSString stringWithFormat:@"/var/lib/dpkg/info/%@.list", static_cast<NSString *>(id_)];
     NSMutableArray *files = [NSMutableArray arrayWithCapacity:128];
 
     std::ifstream fin;
@@ -2334,7 +2565,7 @@ uint32_t PackageChangesRadix(Package *self, void *) {
     if (range.location != NSNotFound)
         return YES;
 
-    range = [[self tagline] rangeOfString:text options:MatchCompareOptions_];
+    range = [[self shortDescription] rangeOfString:text options:MatchCompareOptions_];
     if (range.location != NSNotFound)
         return YES;
 
@@ -2382,25 +2613,8 @@ uint32_t PackageChangesRadix(Package *self, void *) {
     return [self hasTag:@"cydia::commercial"];
 }
 
-- (uint32_t) compareByPrefix {
-    return 0;
-}
-
-- (NSComparisonResult) compareByName:(Package *)package {
-    NSString *lhs = [self name];
-    NSString *rhs = [package name];
-
-    if ([lhs length] != 0 && [rhs length] != 0) {
-        unichar lhc = [lhs characterAtIndex:0];
-        unichar rhc = [rhs characterAtIndex:0];
-
-        if (isalpha(lhc) && !isalpha(rhc))
-            return NSOrderedAscending;
-        else if (!isalpha(lhc) && isalpha(rhc))
-            return NSOrderedDescending;
-    }
-
-    return [lhs compare:rhs options:LaxCompareOptions_];
+- (CYString &) cyname {
+    return name_.empty() ? id_ : name_;
 }
 
 - (uint32_t) compareBySection:(NSArray *)sections {
@@ -2512,9 +2726,10 @@ uint32_t PackageChangesRadix(Package *self, void *) {
     NSString *localized_;
 }
 
-- (NSComparisonResult) compareByName:(Section *)section;
-- (Section *) initWithName:(NSString *)name;
-- (Section *) initWithName:(NSString *)name row:(size_t)row;
+- (NSComparisonResult) compareByLocalized:(Section *)section;
+- (Section *) initWithName:(NSString *)name localized:(NSString *)localized;
+- (Section *) initWithName:(NSString *)name localize:(BOOL)localize;
+- (Section *) initWithName:(NSString *)name row:(size_t)row localize:(BOOL)localize;
 - (Section *) initWithIndex:(unichar)index row:(size_t)row;
 - (NSString *) name;
 - (unichar) index;
@@ -2526,6 +2741,7 @@ uint32_t PackageChangesRadix(Package *self, void *) {
 - (void) addToCount;
 
 - (void) setCount:(size_t)count;
+- (NSString *) localized;
 
 @end
 
@@ -2538,11 +2754,11 @@ uint32_t PackageChangesRadix(Package *self, void *) {
     [super dealloc];
 }
 
-- (NSComparisonResult) compareByName:(Section *)section {
-    NSString *lhs = [self name];
-    NSString *rhs = [section name];
+- (NSComparisonResult) compareByLocalized:(Section *)section {
+    NSString *lhs(localized_);
+    NSString *rhs([section localized]);
 
-    if ([lhs length] != 0 && [rhs length] != 0) {
+    /*if ([lhs length] != 0 && [rhs length] != 0) {
         unichar lhc = [lhs characterAtIndex:0];
         unichar rhc = [rhs characterAtIndex:0];
 
@@ -2550,21 +2766,29 @@ uint32_t PackageChangesRadix(Package *self, void *) {
             return NSOrderedAscending;
         else if (!isalpha(lhc) && isalpha(rhc))
             return NSOrderedDescending;
-    }
+    }*/
 
     return [lhs compare:rhs options:LaxCompareOptions_];
 }
 
-- (Section *) initWithName:(NSString *)name {
-    return [self initWithName:name row:0];
+- (Section *) initWithName:(NSString *)name localized:(NSString *)localized {
+    if ((self = [self initWithName:name localize:NO]) != nil) {
+        if (localized != nil)
+            localized_ = [localized retain];
+    } return self;
 }
 
-- (Section *) initWithName:(NSString *)name row:(size_t)row {
+- (Section *) initWithName:(NSString *)name localize:(BOOL)localize {
+    return [self initWithName:name row:0 localize:localize];
+}
+
+- (Section *) initWithName:(NSString *)name row:(size_t)row localize:(BOOL)localize {
     if ((self = [super init]) != nil) {
         name_ = [name retain];
         index_ = '\0';
         row_ = row;
-        localized_ = [LocalizeSection(name_) retain];
+        if (localize)
+            localized_ = [LocalizeSection(name_) retain];
     } return self;
 }
 
@@ -2738,8 +2962,7 @@ static NSArray *Finishes_;
         zone_ = NSCreateZone(1024 * 1024, 256 * 1024, NO);
         apr_pool_create(&pool_, NULL);
 
-        sources_ = [[NSMutableDictionary dictionaryWithCapacity:16] retain];
-        packages_ = [[NSMutableArray arrayWithCapacity:16] retain];
+        packages_ = [[NSMutableArray alloc] init];
 
         int fds[2];
 
@@ -2811,7 +3034,10 @@ static NSArray *Finishes_;
 }
 
 - (NSArray *) sources {
-    return [sources_ allValues];
+    NSMutableArray *sources([NSMutableArray arrayWithCapacity:sources_.size()]);
+    for (SourceMap::const_iterator i(sources_.begin()); i != sources_.end(); ++i)
+        [sources addObject:i->second];
+    return sources;
 }
 
 - (NSArray *) issues {
@@ -2883,6 +3109,9 @@ static NSArray *Finishes_;
         ++era_;
     }
 
+    [packages_ removeAllObjects];
+    sources_.clear();
+
     _error->Discard();
 
     delete list_;
@@ -2899,6 +3128,11 @@ static NSArray *Finishes_;
     delete policy_;
     policy_ = NULL;
 
+    if (now_ != nil) {
+        [now_ release];
+        now_ = nil;
+    }
+
     cache_.Close();
 
     apr_pool_clear(pool_);
@@ -2952,36 +3186,63 @@ static NSArray *Finishes_;
     }
 
     _trace();
-    {
-        std::string lists(_config->FindDir("Dir::State::lists"));
-
-        [sources_ removeAllObjects];
-        for (pkgSourceList::const_iterator source = list_->begin(); source != list_->end(); ++source) {
-            std::vector<pkgIndexFile *> *indices = (*source)->GetIndexFiles();
-            for (std::vector<pkgIndexFile *>::const_iterator index = indices->begin(); index != indices->end(); ++index)
-                if (debPackagesIndex *packages = dynamic_cast<debPackagesIndex *>(*index))
-                    [sources_
-                        setObject:[[[Source alloc] initWithMetaIndex:*source] autorelease]
-                        forKey:[NSString stringWithFormat:@"%s%s",
-                            lists.c_str(),
-                            URItoFileName(packages->IndexURI("Packages")).c_str()
-                        ]
-                    ];
-        }
+
+    for (pkgSourceList::const_iterator source = list_->begin(); source != list_->end(); ++source) {
+        std::vector<pkgIndexFile *> *indices = (*source)->GetIndexFiles();
+        for (std::vector<pkgIndexFile *>::const_iterator index = indices->begin(); index != indices->end(); ++index)
+            // XXX: this could be more intelligent
+            if (dynamic_cast<debPackagesIndex *>(*index) != NULL) {
+                pkgCache::PkgFileIterator cached((*index)->FindInCache(cache_));
+                if (!cached.end())
+                    sources_[cached->ID] = [[[Source alloc] initWithMetaIndex:*source] autorelease];
+            }
     }
-    _trace();
 
-    [packages_ removeAllObjects];
-    _trace();
-    for (pkgCache::PkgIterator iterator = cache_->PkgBegin(); !iterator.end(); ++iterator)
-        if (Package *package = [Package packageWithIterator:iterator withZone:zone_ inPool:pool_ database:self])
-            [packages_ addObject:package];
-    _trace();
-    [packages_ sortUsingSelector:@selector(compareByName:)];
     _trace();
 
-    _config->Set("Acquire::http::Timeout", 15);
-    _config->Set("Acquire::http::MaxParallel", 4);
+    {
+        /*std::vector<Package *> packages;
+        packages.reserve(std::max(10000U, [packages_ count] + 1000));
+        [packages_ release];
+        packages_ = nil;*/
+
+        _trace();
+
+        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);
+                [packages_ addObject:package];
+
+        _trace();
+
+        /*if (packages.empty())
+            packages_ = [[NSArray alloc] init];
+        else
+            packages_ = [[NSArray alloc] initWithObjects:&packages.front() count:packages.size()];
+        _trace();*/
+
+        [packages_ radixSortUsingFunction:reinterpret_cast<SKRadixFunction>(&PackagePrefixRadix) withContext:reinterpret_cast<void *>(16)];
+        [packages_ radixSortUsingFunction:reinterpret_cast<SKRadixFunction>(&PackagePrefixRadix) withContext:reinterpret_cast<void *>(4)];
+        [packages_ radixSortUsingFunction:reinterpret_cast<SKRadixFunction>(&PackagePrefixRadix) withContext:reinterpret_cast<void *>(0)];
+
+        /*_trace();
+        PrintTimes();
+        _trace();*/
+
+        _trace();
+
+        /*if (!packages.empty())
+            CFQSortArray(&packages.front(), packages.size(), sizeof(packages.front()), reinterpret_cast<CFComparatorFunction>(&PackageNameCompare_), NULL);*/
+        //std::sort(packages.begin(), packages.end(), PackageNameOrdering());
+
+        //CFArraySortValues((CFMutableArrayRef) packages_, CFRangeMake(0, [packages_ count]), reinterpret_cast<CFComparatorFunction>(&PackageNameCompare), NULL);
+
+        CFArrayInsertionSortValues((CFMutableArrayRef) packages_, CFRangeMake(0, [packages_ count]), reinterpret_cast<CFComparatorFunction>(&PackageNameCompare), NULL);
+
+        //[packages_ sortUsingFunction:reinterpret_cast<NSComparisonResult (*)(id, id, void *)>(&PackageNameCompare) context:NULL];
+
+        _trace();
+    }
 }
 
 - (void) configure {
@@ -3142,10 +3403,7 @@ static NSArray *Finishes_;
 }
 
 - (Source *) getSource:(pkgCache::PkgFileIterator)file {
-    if (const char *name = file.FileName())
-        if (Source *source = [sources_ objectForKey:[NSString stringWithUTF8String:name]])
-            return source;
-    return nil;
+    return sources_[file->ID];
 }
 
 @end
@@ -4097,12 +4355,13 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
 - (void) setPackage:(Package *)package {
     [self clearPackage];
+    [package parse];
 
     Source *source = [package source];
 
     icon_ = [[package icon] retain];
     name_ = [[package name] retain];
-    description_ = [[package tagline] retain];
+    description_ = [[package shortDescription] retain];
     commercial_ = [package isCommercial];
 
     package_ = [package retain];
@@ -4227,14 +4486,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 + (int) heightForPackage:(Package *)package {
-    NSString *tagline([package tagline]);
-    int height = tagline == nil || [tagline length] == 0 ? -17 : 0;
-#ifdef USE_BADGES
-    if ([package hasMode] || [package half])
-        return height + 96;
-    else
-#endif
-        return height + 73;
+    return 73;
 }
 
 @end
@@ -4315,7 +4567,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         name_ = [CYLocalize("ALL_PACKAGES") retain];
         count_ = nil;
     } else {
-        section_ = [section name];
+        section_ = [section localized];
         if (section_ != nil)
             section_ = [section_ retain];
         name_  = [(section_ == nil ? CYLocalize("NO_SECTION") : section_) retain];
@@ -4619,6 +4871,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [buttons_ removeAllObjects];
 
     if (package != nil) {
+        [package parse];
+
         package_ = [package retain];
         name_ = [[package id] retain];
         commercial_ = [package isCommercial];
@@ -4652,6 +4906,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
             [self setPopupHook:nil];
             WebThreadUnlock();
 
+            //[self yieldToSelector:@selector(callFunction:) withObject:special_];
             [super callFunction:special_];
         }
     }
@@ -4893,6 +5148,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
         /* 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);
 
@@ -5767,7 +6023,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         [cancel_ addTarget:self action:@selector(_onCancel) forControlEvents:UIControlEventTouchUpInside];
 
         CGRect frame = [cancel_ frame];
-        frame.size.width = 65;
         frame.origin.x = ovrrect.size.width - frame.size.width - 5;
         frame.origin.y = (ovrrect.size.height - frame.size.height) / 2;
         [cancel_ setFrame:frame];
@@ -5795,7 +6050,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (void) setProgressError:(NSString *)error forPackage:(NSString *)id {
-    [prompt_ setText:[NSString stringWithFormat:CYLocalize("ERROR_MESSAGE"), error]];
+    [prompt_ setText:[NSString stringWithFormat:CYLocalize("COLON_DELIMITED"), CYLocalize("ERROR"), error]];
 }
 
 - (void) setProgressTitle:(NSString *)title {
@@ -6100,7 +6355,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
             section = &sections[key];
             if (*section == nil) {
                 _profile(SectionsView$reloadData$Section$Allocate)
-                    *section = [[[Section alloc] initWithName:name] autorelease];
+                    *section = [[[Section alloc] initWithName:name localize:YES] autorelease];
                 _end
             }
         _end
@@ -6120,7 +6375,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
             section = [sections objectForKey:key];
             if (section == nil) {
                 _profile(SectionsView$reloadData$Section$Allocate)
-                    section = [[[Section alloc] initWithName:name] autorelease];
+                    section = [[[Section alloc] initWithName:name localize:YES] autorelease];
                     [sections setObject:section forKey:key];
                 _end
             }
@@ -6145,14 +6400,14 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [sections_ addObjectsFromArray:[sections allValues]];
 #endif
 
-    [sections_ sortUsingSelector:@selector(compareByName:)];
+    [sections_ sortUsingSelector:@selector(compareByLocalized:)];
 
     for (Section *section in sections_) {
         size_t count([section row]);
-        if ([section row] == 0)
+        if (count == 0)
             continue;
 
-        section = [[[Section alloc] initWithName:[section name]] autorelease];
+        section = [[[Section alloc] initWithName:[section name] localized:[section localized]] autorelease];
         [section setCount:count];
         [filtered_ addObject:section];
     }
@@ -6326,27 +6581,23 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
             [packages_ addObject:package];
 
     _trace();
-    [packages_ radixSortUsingFunction:reinterpret_cast<uint32_t (*)(id, void *)>(&PackageChangesRadix) withArgument:NULL];
+    [packages_ radixSortUsingFunction:reinterpret_cast<SKRadixFunction>(&PackageChangesRadix) withContext:NULL];
     _trace();
 
-    Section *upgradable = [[[Section alloc] initWithName:CYLocalize("AVAILABLE_UPGRADES")] autorelease];
-    Section *ignored = [[[Section alloc] initWithName:CYLocalize("IGNORED_UPGRADES")] autorelease];
+    Section *upgradable = [[[Section alloc] initWithName:CYLocalize("AVAILABLE_UPGRADES") localize:NO] autorelease];
+    Section *ignored = [[[Section alloc] initWithName:CYLocalize("IGNORED_UPGRADES") localize:NO] autorelease];
     Section *section = nil;
     NSDate *last = nil;
 
     upgrades_ = 0;
     bool unseens = false;
 
-    CFDateFormatterRef formatter = CFDateFormatterCreate(NULL, Locale_, kCFDateFormatterMediumStyle, kCFDateFormatterMediumStyle);
+    CFDateFormatterRef formatter(CFDateFormatterCreate(NULL, Locale_, kCFDateFormatterMediumStyle, kCFDateFormatterMediumStyle));
 
-    _trace();
     for (size_t offset = 0, count = [packages_ count]; offset != count; ++offset) {
         Package *package = [packages_ objectAtIndex:offset];
 
-        BOOL uae;
-        _profile(ChangesView$reloadData$Upgrade)
-            uae = [package upgradableAndEssential:YES];
-        _end
+        BOOL uae = [package upgradableAndEssential:YES];
 
         if (!uae) {
             unseens = true;
@@ -6356,28 +6607,20 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
                 seen = [package seen];
             _end
 
-            bool different;
-            _profile(ChangesView$reloadData$Compare)
-                different = section == nil || last != seen && (seen == nil || [seen compare:last] != NSOrderedSame);
-            _end
-
-            if (different) {
+            if (section == nil || last != seen && (seen == nil || [seen compare:last] != NSOrderedSame)) {
                 last = seen;
 
                 NSString *name;
                 if (seen == nil)
                     name = CYLocalize("UNKNOWN");
                 else {
-                    _profile(ChangesView$reloadData$Format)
-                        name = (NSString *) CFDateFormatterCreateStringWithDate(NULL, formatter, (CFDateRef) seen);
-                    _end
-
+                    name = (NSString *) CFDateFormatterCreateStringWithDate(NULL, formatter, (CFDateRef) seen);
                     [name autorelease];
                 }
 
                 _profile(ChangesView$reloadData$Allocate)
                     name = [NSString stringWithFormat:CYLocalize("NEW_AT"), name];
-                    section = [[[Section alloc] initWithName:name row:offset] autorelease];
+                    section = [[[Section alloc] initWithName:name row:offset localize:NO] autorelease];
                     [sections_ addObject:section];
                 _end
             }
@@ -7390,7 +7633,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
             @"home-dn.png", kUIButtonBarButtonSelectedInfo,
             [NSNumber numberWithInt:1], kUIButtonBarButtonTag,
             self, kUIButtonBarButtonTarget,
-            CYLocalize("HOME"), kUIButtonBarButtonTitle,
+            @"Cydia", kUIButtonBarButtonTitle,
             @"0", kUIButtonBarButtonType,
         nil],
 
@@ -7744,9 +7987,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     Font18Bold_ = [[UIFont boldSystemFontOfSize:18] retain];
     Font22Bold_ = [[UIFont boldSystemFontOfSize:22] retain];
 
-    _assert(pkgInitConfig(*_config));
-    _assert(pkgInitSystem(*_config, _system));
-
     tag_ = 1;
 
     essential_ = [[NSMutableArray alloc] initWithCapacity:4];
@@ -7894,6 +8134,8 @@ void $UIWebDocumentView$_setUIKitDelegate$(UIWebDocumentView *self, SEL sel, id
 int main(int argc, char *argv[]) { _pooled
     _trace();
 
+    PackageName = reinterpret_cast<CYString &(*)(Package *, SEL)>(method_getImplementation(class_getInstanceMethod([Package class], @selector(cyname))));
+
     /* Library Hacks {{{ */
     class_addMethod(objc_getClass("DOMNodeList"), @selector(countByEnumeratingWithState:objects:count:), (IMP) &DOMNodeList$countByEnumeratingWithState$objects$count$, "I20@0:4^{NSFastEnumerationState}8^@12I16");
 
@@ -7906,9 +8148,17 @@ int main(int argc, char *argv[]) { _pooled
     /* }}} */
     /* Set Locale {{{ */
     Locale_ = CFLocaleCopyCurrent();
-
-    CFStringRef locale(CFLocaleGetIdentifier(Locale_));
-    setenv("LANG", [(NSString *) locale UTF8String], true);
+    Languages_ = [NSLocale preferredLanguages];
+    //CFStringRef locale(CFLocaleGetIdentifier(Locale_));
+    //NSLog(@"%@", [Languages_ description]);
+    const char *lang;
+    if (Languages_ == nil || [Languages_ count] == 0)
+        lang = NULL;
+    else
+        lang = [[Languages_ objectAtIndex:0] UTF8String];
+    setenv("LANG", lang, true);
+    //std::setlocale(LC_ALL, lang);
+    NSLog(@"Setting Language: %s", lang);
     /* }}} */
 
     // XXX: apr_app_initialize?
@@ -8057,6 +8307,14 @@ int main(int argc, char *argv[]) { _pooled
             _assert(errno == ENOENT);
     }
 
+    _assert(pkgInitConfig(*_config));
+    _assert(pkgInitSystem(*_config, _system));
+
+    if (lang != NULL)
+        _config->Set("APT::Acquire::Translation", lang);
+    _config->Set("Acquire::http::Timeout", 15);
+    _config->Set("Acquire::http::MaxParallel", 4);
+
     /* Color Choices {{{ */
     space_ = CGColorSpaceCreateDeviceRGB();