diff --git a/AppKit/CPAlert.j b/AppKit/CPAlert.j index 5eb8a8245..832c06443 100644 --- a/AppKit/CPAlert.j +++ b/AppKit/CPAlert.j @@ -371,8 +371,8 @@ CPCriticalAlertStyle = 2; [_informativeLabel setAlignment:[self currentValueForThemeAttribute:@"informative-text-alignment"]]; [_informativeLabel setLineBreakMode:CPLineBreakByWordWrapping]; - informativeLabelWidth = CGRectGetWidth([[_window contentView] frame]) - inset.left - inset.right, - informativeLabelOriginY = [_messageLabel frameOrigin].y + [_messageLabel frameSize].height + defaultElementsMargin, + informativeLabelWidth = CGRectGetWidth([[_window contentView] frame]) - inset.left - inset.right; + informativeLabelOriginY = [_messageLabel frameOrigin].y + [_messageLabel frameSize].height + defaultElementsMargin; informativeLabelTextSize = [[_informativeLabel stringValue] sizeWithFont:[_informativeLabel font] inWidth:informativeLabelWidth]; [_informativeLabel setFrame:CGRectMake(inset.left, informativeLabelOriginY, informativeLabelTextSize.width, informativeLabelTextSize.height + sizeWithFontCorrection)]; diff --git a/AppKit/CPApplication.j b/AppKit/CPApplication.j index 8699a7a52..1e7a618ae 100644 --- a/AppKit/CPApplication.j +++ b/AppKit/CPApplication.j @@ -338,7 +338,7 @@ CPRunContinuesResponse = -1002; Copyright - Human readable copyright information. - If you choose not the include any of the above keys, they will default + If you choose not the include any of the above keys, they will default to the following respective keys in your info.plist file.
@@ -1003,7 +1003,7 @@ CPRunContinuesResponse  = -1002;
 }
 
 /*!
-    Sets the arguments of your application. 
+    Sets the arguments of your application.
     That is, set the slash seperated values of an array as the window location hash.
 
     For example if you pass an array:
@@ -1340,8 +1340,8 @@ var _CPAppBootstrapperActions = nil;
     [editMenu addItem:undoMenuItem];
     [editMenu addItem:redoMenuItem];
 
-    [editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Cut" action:@selector(cut:) keyEquivalent:@"x"]],
-    [editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Copy" action:@selector(copy:) keyEquivalent:@"c"]],
+    [editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Cut" action:@selector(cut:) keyEquivalent:@"x"]];
+    [editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Copy" action:@selector(copy:) keyEquivalent:@"c"]];
     [editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Paste" action:@selector(paste:) keyEquivalent:@"v"]];
 
     [editMenuItem setSubmenu:editMenu];
diff --git a/AppKit/CPColor.j b/AppKit/CPColor.j
index 8a3bcf98b..ca9e7996a 100644
--- a/AppKit/CPColor.j
+++ b/AppKit/CPColor.j
@@ -60,7 +60,7 @@ var cachedBlackColor,
 /*!
     Orientation to use with \c CPColorPattern for vertical patterns.
 */
-CPColorPatternIsVertical = YES,
+CPColorPatternIsVertical = YES;
 
 /*!
     Orientation to use with \c CPColorPattern for horizontal patterns.
diff --git a/AppKit/CPColorPanel.j b/AppKit/CPColorPanel.j
index a2331b508..d9fe9bbf7 100644
--- a/AppKit/CPColorPanel.j
+++ b/AppKit/CPColorPanel.j
@@ -51,7 +51,7 @@ CPWheelColorPickerMode = 1;
 */
 CPSliderColorPickerMode = 2;
 
-CPColorPickerViewWidth  = 265,
+CPColorPickerViewWidth  = 265;
 CPColorPickerViewHeight = 370;
 
 /*!
diff --git a/AppKit/CPEvent.j b/AppKit/CPEvent.j
index dc3f918a0..80d931f76 100644
--- a/AppKit/CPEvent.j
+++ b/AppKit/CPEvent.j
@@ -571,10 +571,12 @@ var _CPEventPeriodicEventPeriod         = 0,
     if (_modifierFlags & (CPCommandKeyMask | CPControlKeyMask))
         return YES;
 
-    // Cocoa does not consider space, backspace, or escape a key equivalent
-    // if the first responder is a text field (presumably a subclass of NSText).
+    // Cocoa allows almost any key as a key equivalent unless the first responder is a
+    // text field (presumably a subclass of NSText.)
     var firstResponderIsText = [[_window firstResponder] isKindOfClass:[CPTextField class]];
 
+    // Some keys are accepted as key equivalents even if the first responder is a text
+    // field.
     for (var i = 0; i < characterCount; i++)
     {
         var c = _characters.charAt(i);
@@ -583,18 +585,13 @@ var _CPEventPeriodicEventPeriod         = 0,
             c === CPEnterCharacter ||
             c === CPNewlineCharacter ||
             c === CPCarriageReturnCharacter ||
-            c === CPEscapeFunctionKey ||
-            (!firstResponderIsText &&
-                (c === CPSpaceFunctionKey ||
-                 c === CPDeleteCharacter ||
-                 c === CPBackspaceCharacter)))
+            c === CPEscapeFunctionKey)
         {
             return YES;
         }
     }
 
-    // FIXME: More cases?
-    return NO;
+    return !firstResponderIsText;
 }
 
 /*!
diff --git a/AppKit/CPMenu/CPMenu.j b/AppKit/CPMenu/CPMenu.j
index 8b8c350a3..494598252 100644
--- a/AppKit/CPMenu/CPMenu.j
+++ b/AppKit/CPMenu/CPMenu.j
@@ -352,8 +352,12 @@ var _CPMenuBarVisible               = NO,
     while (count--)
         [_items[count] setMenu:nil];
 
-    _items = [CPMutableArray array];
     _highlightedIndex = CPNotFound;
+
+    // Because we are changing _items directly, be sure to notify KVO
+    [self willChangeValueForKey:@"items"];
+    _items = [CPMutableArray array];
+    [self didChangeValueForKey:@"items"];
 }
 
 /*!
diff --git a/AppKit/CPMenu/_CPMenuManager.j b/AppKit/CPMenu/_CPMenuManager.j
index abe9c15ee..062571161 100644
--- a/AppKit/CPMenu/_CPMenuManager.j
+++ b/AppKit/CPMenu/_CPMenuManager.j
@@ -1,8 +1,8 @@
 @import 
 
 
-_CPMenuManagerScrollingStateUp      = -1,
-_CPMenuManagerScrollingStateDown    = 1,
+_CPMenuManagerScrollingStateUp      = -1;
+_CPMenuManagerScrollingStateDown    = 1;
 _CPMenuManagerScrollingStateNone    = 0;
 
 var STICKY_TIME_INTERVAL            = 500,
diff --git a/AppKit/CPPopUpButton.j b/AppKit/CPPopUpButton.j
index 193b5bcd5..0086e9c5d 100644
--- a/AppKit/CPPopUpButton.j
+++ b/AppKit/CPPopUpButton.j
@@ -86,7 +86,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
 
         [self setPullsDown:shouldPullDown];
 
-        var options = CPKeyValueObservingOptionNew |CPKeyValueObservingOptionOld;/* |CPKeyValueObservingOptionInitial;*/
+        var options = CPKeyValueObservingOptionNew | CPKeyValueObservingOptionOld; // | CPKeyValueObservingOptionInitial;
         [self addObserver:self forKeyPath:@"menu.items" options:options context:nil];
         [self addObserver:self forKeyPath:@"_firstItem.changeCount" options:options context:nil];
         [self addObserver:self forKeyPath:@"selectedItem.changeCount" options:options context:nil];
@@ -193,6 +193,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
 - (void)removeAllItems
 {
     [[self menu] removeAllItems];
+    [self synchronizeTitleAndSelectedItem];
 }
 
 /*!
diff --git a/AppKit/CPRuleEditor/CPPredicateEditor.j b/AppKit/CPRuleEditor/CPPredicateEditor.j
index b26bdc520..61b5ee498 100644
--- a/AppKit/CPRuleEditor/CPPredicateEditor.j
+++ b/AppKit/CPRuleEditor/CPPredicateEditor.j
@@ -200,7 +200,7 @@
         if (isPopup)
         {
             itemArray = [[templateView itemArray] valueForKey:@"title"];
-            itemsCount = [itemArray count],
+            itemsCount = [itemArray count];
             menuIndex = 0;
         }
 
@@ -501,4 +501,4 @@ var CPPredicateTemplatesKey = @"CPPredicateTemplates";
 
 @end
 
-/*! @endcond */
\ No newline at end of file
+/*! @endcond */
diff --git a/AppKit/CPRuleEditor/CPPredicateEditorRowTemplate.j b/AppKit/CPRuleEditor/CPPredicateEditorRowTemplate.j
index dbca2884a..66f92adb8 100644
--- a/AppKit/CPRuleEditor/CPPredicateEditorRowTemplate.j
+++ b/AppKit/CPRuleEditor/CPPredicateEditorRowTemplate.j
@@ -20,17 +20,17 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-CPUndefinedAttributeType     = 0,
-CPInteger16AttributeType     = 100,
-CPInteger32AttributeType     = 200,
-CPInteger64AttributeType     = 300,
-CPDecimalAttributeType       = 400,
-CPDoubleAttributeType        = 500,
-CPFloatAttributeType         = 600,
-CPStringAttributeType        = 700,
-CPBooleanAttributeType       = 800,
-CPDateAttributeType          = 900,
-CPBinaryDataAttributeType    = 1000,
+CPUndefinedAttributeType     = 0;
+CPInteger16AttributeType     = 100;
+CPInteger32AttributeType     = 200;
+CPInteger64AttributeType     = 300;
+CPDecimalAttributeType       = 400;
+CPDoubleAttributeType        = 500;
+CPFloatAttributeType         = 600;
+CPStringAttributeType        = 700;
+CPBooleanAttributeType       = 800;
+CPDateAttributeType          = 900;
+CPBinaryDataAttributeType    = 1000;
 CPTransformableAttributeType = 1800;
 
 @implementation CPPredicateEditorRowTemplate : CPObject
@@ -785,4 +785,4 @@ var CPPredicateTemplateTypeKey = @"CPPredicateTemplateType",
 }
 
 @end
-/*! @endcond */
\ No newline at end of file
+/*! @endcond */
diff --git a/AppKit/CPRuleEditor/_CPRuleEditorPopUpButton.j b/AppKit/CPRuleEditor/_CPRuleEditorPopUpButton.j
index 7393e5a36..f89379874 100644
--- a/AppKit/CPRuleEditor/_CPRuleEditorPopUpButton.j
+++ b/AppKit/CPRuleEditor/_CPRuleEditorPopUpButton.j
@@ -16,12 +16,12 @@ var GRADIENT_NORMAL,
 {
     if (CPBrowserIsEngine(CPWebKitBrowserEngine))
     {
-        GRADIENT_NORMAL = "-webkit-gradient(linear, left top, left bottom, from(rgb(252, 252, 252)), to(rgb(223, 223, 223)))",
+        GRADIENT_NORMAL = "-webkit-gradient(linear, left top, left bottom, from(rgb(252, 252, 252)), to(rgb(223, 223, 223)))";
         GRADIENT_HIGHLIGHTED = "-webkit-gradient(linear, left top, left bottom, from(rgb(223, 223, 223)), to(rgb(252, 252, 252)))";
     }
     else if (CPBrowserIsEngine(CPGeckoBrowserEngine))
     {
-        GRADIENT_NORMAL = "-moz-linear-gradient(top,  rgb(252, 252, 252),  rgb(223, 223, 223))",
+        GRADIENT_NORMAL = "-moz-linear-gradient(top,  rgb(252, 252, 252),  rgb(223, 223, 223))";
         GRADIENT_HIGHLIGHTED = "-moz-linear-gradient(top,  rgb(223, 223, 223),  rgb(252, 252, 252))";
     }
 }
@@ -35,7 +35,7 @@ var GRADIENT_NORMAL,
         style.border = "1px solid rgb(189, 189, 189)";
         style.filter = IE_FILTER;
 
-        [self setTextColor:[CPColor colorWithWhite:101/255 alpha:1]];
+        [self setTextColor:[CPColor colorWithWhite:101 / 255 alpha:1]];
         [self setBordered:NO];
      }
 
diff --git a/AppKit/CPScroller.j b/AppKit/CPScroller.j
index ad5051ba4..55c884139 100644
--- a/AppKit/CPScroller.j
+++ b/AppKit/CPScroller.j
@@ -112,8 +112,8 @@ CPThemeStateScrollerKnobDark    = CPThemeState("scroller-knob-dark");
         @"track-inset":_CGInsetMakeZero(),
         @"knob-inset": _CGInsetMakeZero(),
         @"minimum-knob-length":21.0,
-        @"track-border-overlay": 9.0,
-    }]
+        @"track-border-overlay": 9.0
+    }];
 }
 
 + (float)scrollerWidth
@@ -190,7 +190,7 @@ CPThemeStateScrollerKnobDark    = CPThemeState("scroller-knob-dark");
 */
 - (void)style
 {
-    return _style
+    return _style;
 }
 
 /*!
diff --git a/AppKit/CPTextField.j b/AppKit/CPTextField.j
index afcab8aaf..01382148a 100644
--- a/AppKit/CPTextField.j
+++ b/AppKit/CPTextField.j
@@ -1,4 +1,3 @@
-
 /*
  * CPTextField.j
  * AppKit
@@ -29,7 +28,7 @@
 @import "_CPImageAndTextView.j"
 
 
-CPTextFieldSquareBezel          = 0;    /*! A textfield bezel with a squared corners. */
+CPTextFieldSquareBezel          = 0;    /*! A textfield bezel with squared corners. */
 CPTextFieldRoundedBezel         = 1;    /*! A textfield bezel with rounded corners. */
 
 CPTextFieldDidFocusNotification = @"CPTextFieldDidFocusNotification";
@@ -574,11 +573,17 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
 #if PLATFORM(DOM)
 
     var element = [self _inputElement],
+        newValue = element.value,
         error = @"";
 
+    if (newValue !== _stringValue)
+    {
+        [self _setStringValue:newValue];
+    }
+
     // If there is a formatter, always give it a chance to reject the resignation,
     // even if the value has not changed.
-    if ([self _valueIsValid:element.value] === NO)
+    if ([self _valueIsValid:newValue] === NO)
     {
         [self setThemeState:CPThemeStateEditing];
         element.focus();
@@ -774,6 +779,13 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
 
 - (void)insertNewline:(id)sender
 {
+    var newValue = [self _inputElement].value;
+
+    if (newValue !== _stringValue)
+    {
+        [self _setStringValue:newValue];
+    }
+
     if ([self _valueIsValid:_stringValue])
     {
         // If _isEditing == YES then the target action can also be called via
@@ -1010,7 +1022,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
     However, since you don't know how tall it needs to be if you change the font, sizeToFit will still be
     useful for making the textfield an appropriate height.
 */
-
 - (void)sizeToFit
 {
     [self setFrameSize:[self _minimumFrameSize]];
diff --git a/AppKit/Cib/CPCib.j b/AppKit/Cib/CPCib.j
index 5686c5f21..8e85a012b 100644
--- a/AppKit/Cib/CPCib.j
+++ b/AppKit/Cib/CPCib.j
@@ -34,9 +34,9 @@
 @import "_CPCibWindowTemplate.j"
 
 
-CPCibOwner              = @"CPCibOwner",
-CPCibTopLevelObjects    = @"CPCibTopLevelObjects",
-CPCibReplacementClasses = @"CPCibReplacementClasses",
+CPCibOwner              = @"CPCibOwner";
+CPCibTopLevelObjects    = @"CPCibTopLevelObjects";
+CPCibReplacementClasses = @"CPCibReplacementClasses";
 CPCibExternalObjects    = @"CPCibExternalObjects";
 
 var CPCibObjectDataKey  = @"CPCibObjectDataKey";
diff --git a/AppKit/Platform/DOM/CPPlatformWindow+DOM.j b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j
index 58ab7269e..026d0296b 100644
--- a/AppKit/Platform/DOM/CPPlatformWindow+DOM.j
+++ b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j
@@ -708,7 +708,8 @@ var ModifierKeyCodes = [
                             var characters;
 
                             // Handle key codes for which String.fromCharCode won't work.
-                            if (aDOMEvent.which === 0 || aDOMEvent.charCode === 0)
+                            // Refs #1036: In Internet Explorer, both 'which' and 'charCode' are undefined for special keys.
+                            if (aDOMEvent.which === 0 || aDOMEvent.charCode === 0 || (aDOMEvent.which === undefined && aDOMEvent.charCode === undefined))
                                 characters = KeyCodesToUnicodeMap[_keyCode];
 
                             if (!characters)
diff --git a/AppKit/Themes/BlendKit/BKThemeDescriptor.j b/AppKit/Themes/BlendKit/BKThemeDescriptor.j
index 5c42e8582..93133d489 100644
--- a/AppKit/Themes/BlendKit/BKThemeDescriptor.j
+++ b/AppKit/Themes/BlendKit/BKThemeDescriptor.j
@@ -341,8 +341,7 @@ function BKLabelFromIdentifier(anIdentifier)
 }
 
 
-
-PatternIsVertical = YES,
+PatternIsVertical = YES;
 PatternIsHorizontal = NO;
 
 /*
diff --git a/AppKit/_CPAttachedWindow.j b/AppKit/_CPAttachedWindow.j
index ad69465ef..f67dba070 100644
--- a/AppKit/_CPAttachedWindow.j
+++ b/AppKit/_CPAttachedWindow.j
@@ -110,7 +110,7 @@ var _CPAttachedWindow_attachedWindowShouldClose_    = 1 << 0,
 */
 - (id)initWithContentRect:(CGRect)aFrame
 {
-    self = [self initWithContentRect:aFrame styleMask:nil]
+    self = [self initWithContentRect:aFrame styleMask:nil];
     return self;
 }
 
@@ -250,11 +250,11 @@ var _CPAttachedWindow_attachedWindowShouldClose_    = 1 << 0,
 
     // CPMaxXEdge
     originRight.x += aRect.size.width;
-    originRight.y += (aRect.size.height / 2.0) - (CPRectGetHeight([self frame]) / 2.0)
+    originRight.y += (aRect.size.height / 2.0) - (CPRectGetHeight([self frame]) / 2.0);
 
     // CPMinXEdge
     originLeft.x -= CPRectGetWidth([self frame]);
-    originLeft.y += (aRect.size.height / 2.0) - (CPRectGetHeight([self frame]) / 2.0)
+    originLeft.y += (aRect.size.height / 2.0) - (CPRectGetHeight([self frame]) / 2.0);
 
     // CPMaxYEdge
     originBottom.x += aRect.size.width / 2.0 - CPRectGetWidth([self frame]) / 2.0;
@@ -381,7 +381,7 @@ var _CPAttachedWindow_attachedWindowShouldClose_    = 1 << 0,
 */
 - (void)positionRelativeToRect:(CPRect)aRect
 {
-    [self positionRelativeToRect:aRect preferredEdge:nil]
+    [self positionRelativeToRect:aRect preferredEdge:nil];
 }
 
 /*!
@@ -470,16 +470,18 @@ var _CPAttachedWindow_attachedWindowShouldClose_    = 1 << 0,
         _DOMElement.style.opacity = 0;
         _DOMElement.style.WebkitTransform = "scale(0)";
         _DOMElement.style.WebkitTransformOrigin = tranformOrigin;
-        window.setTimeout(function(){
+        window.setTimeout(function()
+        {
             _DOMElement.style.height = _frame.size.height + @"px";
             _DOMElement.style.width = _frame.size.width + @"px";
             _DOMElement.style.opacity = 1;
             _DOMElement.style.WebkitTransform = "scale(1.1)";
-            var transitionEndFunction = function(){
+            var transitionEndFunction = function()
+            {
                 _DOMElement.style.WebkitTransform = "scale(1)";
                 _DOMElement.removeEventListener("webkitTransitionEnd", transitionEndFunction, YES);
             };
-            _DOMElement.addEventListener("webkitTransitionEnd", transitionEndFunction, YES)
+            _DOMElement.addEventListener("webkitTransitionEnd", transitionEndFunction, YES);
         },0);
     }
 
diff --git a/AppKit/_CPCornerView.j b/AppKit/_CPCornerView.j
index 30b003bbc..c68d8d4f5 100644
--- a/AppKit/_CPCornerView.j
+++ b/AppKit/_CPCornerView.j
@@ -64,7 +64,7 @@
 
 - (id)initWithFrame:(CGRect)aFrame
 {
-    self = [super initWithFrame:aFrame]
+    self = [super initWithFrame:aFrame];
 
     if (self)
         [self _init];
diff --git a/Foundation/CPDictionary.j b/Foundation/CPDictionary.j
index ee328905a..61780fe18 100755
--- a/Foundation/CPDictionary.j
+++ b/Foundation/CPDictionary.j
@@ -176,7 +176,7 @@
                 for (; i < count; i++)
                 {
                     var thisValue = value[i];
-                    
+
                     if (thisValue === null)
                     {
                         newValue.push([CPNull null]);
@@ -364,7 +364,7 @@
 
     for (; index < count; ++index)
     {
-        thisKey = _keys[index],
+        thisKey = _keys[index];
         thisValue = _buckets[thisKey];
         if (thisValue.isa && anObject && anObject.isa && [thisValue respondsToSelector:@selector(isEqual:)] && [thisValue isEqual:anObject])
             matchingKeys.push(thisKey);
diff --git a/Objective-J/CommonJS/lib/objective-j.js b/Objective-J/CommonJS/lib/objective-j.js
index 3bb275a27..8b0d4e2f5 100644
--- a/Objective-J/CommonJS/lib/objective-j.js
+++ b/Objective-J/CommonJS/lib/objective-j.js
@@ -9,7 +9,7 @@ if (system.engine === "rhino")
     window.__parent__ = null;
     window.__proto__ = global;
 }
- 
+
 // setup OBJJ_HOME, OBJJ_INCLUDE_PATHS, etc
 window.OBJJ_HOME = exports.OBJJ_HOME = FILE.resolve(module.path, "..");
 
@@ -146,7 +146,7 @@ exports.repl = function()
 
         require("browser/timeout").serviceTimeouts();
     }
-}
+};
 
 // creates a narwhal factory function in the objj module scope
 exports.make_narwhal_factory = function(path)
@@ -157,7 +157,7 @@ exports.make_narwhal_factory = function(path)
         Executable.setCommonJSArguments(require, exports, module, system, print, window);
         Executable.fileImporterForURL(FILE.dirname(path))(path, YES);
     }
-}
+};
 
 } // end "with"
 
diff --git a/Objective-J/CommonJS/lib/objective-j/compiler.js b/Objective-J/CommonJS/lib/objective-j/compiler.js
index a0c54468c..d34451446 100644
--- a/Objective-J/CommonJS/lib/objective-j/compiler.js
+++ b/Objective-J/CommonJS/lib/objective-j/compiler.js
@@ -31,12 +31,14 @@ function compressor(code) {
     return winner;
 }
 
-function compileWithResolvedFlags(aFilePath, objjcFlags, gccFlags)
+function compileWithResolvedFlags(aFilePath, objjcFlags, gccFlags, asPlainJavascript)
 {
     var shouldObjjPreprocess = objjcFlags & ObjectiveJ.Preprocessor.Flags.Preprocess,
         shouldCheckSyntax = objjcFlags & ObjectiveJ.Preprocessor.Flags.CheckSyntax,
         shouldCompress = objjcFlags & ObjectiveJ.Preprocessor.Flags.Compress,
-        fileContents = "";
+        fileContents = "",
+        executable,
+        code;
 
     if (OS.popen("which gcc").stdout.read().length === 0)
         fileContents = FILE.read(aFilePath, { charset:"UTF-8" });
@@ -58,7 +60,7 @@ function compileWithResolvedFlags(aFilePath, objjcFlags, gccFlags)
     // FIXME: should calculate relative path, etc.
     try
     {
-        var executable = ObjectiveJ.preprocess(fileContents, FILE.basename(aFilePath), objjcFlags);
+        executable = ObjectiveJ.preprocess(fileContents, FILE.basename(aFilePath), objjcFlags);
     }
     catch (anException)
     {print(anException);
@@ -76,14 +78,14 @@ function compileWithResolvedFlags(aFilePath, objjcFlags, gccFlags)
 
     if (shouldCompress)
     {
-        var code = executable.code();
+        code = executable.code();
         code = compressor("function(){" + code + "}");
         // more robust function wrapper stripping
         code = code.replace(/^\s*function\s*\(\s*\)\s*{|}\s*;?\s*$/g, "");
         executable.setCode(code);
     }
 
-    return executable.toMarkedString();
+    return asPlainJavascript ? executable.code() : executable.toMarkedString();
 }
 
 function resolveFlags(args)
@@ -100,16 +102,16 @@ function resolveFlags(args)
     for (; index < count; ++index)
     {
         var argument = args[index];
-        
+
         if (argument === "-o")
         {
             if (++index < count)
                 outputFilePaths.push(args[index]);
         }
-        
+
         else if (argument.indexOf("-D") === 0)
-            gccFlags.push(argument)
-            
+            gccFlags.push(argument);
+
         else if (argument.indexOf("-U") === 0)
             gccFlags.push(argument);
 
@@ -124,13 +126,13 @@ function resolveFlags(args)
 
         else if (argument.indexOf("-E") === 0)
             objjcFlags &= ~ObjectiveJ.Preprocessor.Flags.Preprocess;
-            
+
         else if (argument.indexOf("-S") === 0)
             objjcFlags &= ~ObjectiveJ.Preprocessor.Flags.CheckSyntax;
-            
+
         else if (argument.indexOf("-g") === 0)
             objjcFlags |= ObjectiveJ.Preprocessor.Flags.IncludeDebugSymbols;
-            
+
         else if (argument.indexOf("-O") === 0)
             objjcFlags |= ObjectiveJ.Preprocessor.Flags.Compress;
 
@@ -149,25 +151,69 @@ exports.compile = function(aFilePath, flags)
     var resolvedFlags = resolveFlags(flags);
 
     return compileWithResolvedFlags(aFilePath, resolvedFlags.objjcFlags, resolvedFlags.gccFlags);
-}
+};
 
 exports.main = function(args)
 {
-    // TODO: args parser
-    args.shift();
+    var shouldPrintOutput = false,
+        asPlainJavascript = false;
 
-    var resolved = resolveFlags(args),
+    var argv = args.slice(1);
+
+    while(argv.length)
+    {
+        if (argv[0] === '--')
+        {
+            argv.shift();
+            break;
+        }
+
+        if (argv[0] === "-p" || argv[0] === "--print")
+        {
+            shouldPrintOutput = YES;
+            argv.shift();
+            continue;
+        }
+
+        if (argv[0] === "--unmarked")
+        {
+            asPlainJavascript = true;
+            argv.shift();
+            continue;
+        }
+
+        if (argv[0] === "--help" || argv[0].substr(0, 1) == '-')
+        {
+            print("Usage: " + args[0] + " [options] [--] file...");
+            print("  -p, --print    print the output directly to stdout");
+            print("  --unmarked     don't tag the output with @STATIC header");
+            print("  --help         print this help");
+            return;
+        }
+
+        // Current argument doesn't begin with - so it's not an argument but the
+        // first filename.
+        // TODO Full GNU getopt parsing which doesn't stop on the first non-argument.
+        break;
+    }
+
+    var resolved = resolveFlags(argv),
         outputFilePaths = resolved.outputFilePaths,
         objjcFlags = resolved.objjcFlags,
         gccFlags = resolved.gccFlags;
 
     resolved.filePaths.forEach(function(filePath, index)
     {
-        print("Statically Compiling " + filePath);
+        if (!shouldPrintOutput)
+            print("Statically Compiling " + filePath);
+        var output = compileWithResolvedFlags(filePath, objjcFlags, gccFlags, asPlainJavascript);
 
-        FILE.write(outputFilePaths[index], compileWithResolvedFlags(filePath, objjcFlags, gccFlags), { charset: "UTF-8" });
+        if (shouldPrintOutput)
+            print(output);
+        else
+            FILE.write(outputFilePaths[index], output, { charset: "UTF-8" });
     });
-}
+};
 
 if (require.main == module.id)
     exports.main(system.args);
diff --git a/Objective-J/Executable.js b/Objective-J/Executable.js
index f3c4423ac..55d4d05ec 100644
--- a/Objective-J/Executable.js
+++ b/Objective-J/Executable.js
@@ -56,12 +56,12 @@ exports.Executable = Executable;
 Executable.prototype.path = function()
 {
     return this.URL().path();
-}
+};
 
 Executable.prototype.URL = function()
 {
     return this._URL;
-}
+};
 
 DISPLAY_NAME(Executable.prototype.URL);
 
@@ -76,7 +76,7 @@ Executable.prototype.functionParameters = function()
 #endif
 
     return functionParameters;
-}
+};
 
 DISPLAY_NAME(Executable.prototype.functionParameters);
 
@@ -89,7 +89,7 @@ Executable.prototype.functionArguments = function()
 #endif
 
     return functionArguments;
-}
+};
 
 DISPLAY_NAME(Executable.prototype.functionArguments);
 
@@ -97,22 +97,22 @@ DISPLAY_NAME(Executable.prototype.functionArguments);
 Executable.setCommonJSParameters = function()
 {
     this._commonJSParameters = Array.prototype.slice.call(arguments);
-}
+};
 
 Executable.commonJSParameters = function()
 {
     return this._commonJSParameters || [];
-}
+};
 
 Executable.setCommonJSArguments = function()
 {
     this._commonJSArguments = Array.prototype.slice.call(arguments);
-}
+};
 
 Executable.commonJSArguments = function()
 {
     return this._commonJSArguments || [];
-}
+};
 
 Executable.prototype.toMarkedString = function()
 {
@@ -127,7 +127,7 @@ Executable.prototype.toMarkedString = function()
     var code = this.code();
 
     return markedString + MARKER_TEXT + ";" + code.length + ";" + code;
-}
+};
 #endif
 
 Executable.prototype.execute = function()
@@ -145,14 +145,14 @@ Executable.prototype.execute = function()
     CONTEXT_BUNDLE = oldContextBundle;
 
     return result;
-}
+};
 
 DISPLAY_NAME(Executable.prototype.execute);
 
 Executable.prototype.code = function()
 {
     return this._code;
-}
+};
 
 DISPLAY_NAME(Executable.prototype.code);
 
diff --git a/Objective-J/Preprocessor.js b/Objective-J/Preprocessor.js
index 5b14dac32..84489f1e0 100644
--- a/Objective-J/Preprocessor.js
+++ b/Objective-J/Preprocessor.js
@@ -910,7 +910,7 @@ Preprocessor.prototype.preprocess = function(tokens, /*StringBuffer*/ aStringBuf
             // If it's not a parenthesis, we know we have a non-supported function declaration, so fix it:
             else
             {
-                CONCAT(buffer, token + "= function");
+                CONCAT(buffer, token + " = function");
 
 #if FIREBUG
                 var functionName = token;
diff --git a/README.markdown b/README.markdown
index a7b604d94..8745eeac1 100644
--- a/README.markdown
+++ b/README.markdown
@@ -20,7 +20,8 @@ System Requirements
 To run Cappuccino applications, all you need is a web browser that understands
 JavaScript.
 
-To build Cappuccino itself, please read more here: [Getting and Building the Source](http://wiki.github.com/cappuccino/cappuccino/getting-and-building-the-source>).
+To build Cappuccino itself, please read below. More information is available
+here: [Getting and Building the Source](http://wiki.github.com/cappuccino/cappuccino/getting-and-building-the-source>).
 
 If you're using Windows, you'll also need [Cygwin](http://www.cygwin.com/).
 
@@ -30,12 +31,13 @@ and contribute your work back to the Cappuccino community, you'll want to
 
 Getting Started
 ---------------
-These instructions are for building a development copy of Cappuccino. If you'd
-just like to get started using Cappuccino for your web apps, you should
-instead download a pre-compiled copy of Cappuccino from:
+To get started, download and install the current release version of Cappuccino:
 
-  
+    $ curl https://raw.github.com/cappuccino/cappuccino/0.9.2a/bootstrap.sh >/tmp/cappuccino_bootstrap.sh && sh /tmp/cappuccino_bootstrap.sh
 
+If you'd just like to get started using Cappuccino for your web apps, you are done.
+
+The rest of these instructions are for building a development copy of Cappuccino.
 To build Cappuccino from source, check out the most recent stable version from GitHub:
 
     $ git clone git://github.com/cappuccino/cappuccino.git (git)
@@ -44,13 +46,11 @@ or download the zipball of the most recent source code:
 
    (zip)
 
-If this is your first build and your system does not have narwhal and jake
-installed, run the bootstrap script to install it and all of its dependencies:
+Then, simply type `jake` from within the root of the Cappuccino directory. If you
+get an error like `jake: command not found`, you forgot to run the bootstrap script
+as described above.
 
-    $ ./bootstrap.sh
-
-Then, simply type `jake` from within the root of the Cappuccino directory.
-This will build a "release" copy of the frameworks. Typing `jake debug` will
+Jake will build a "release" copy of the frameworks. Typing `jake debug` will
 build a debug version.
 
 `jake install` will build Cappuccino and associated tools and install them for general use.
diff --git a/Tests/Manual/CPPopUpButtonTest/AppController.j b/Tests/Manual/CPPopUpButtonTest/AppController.j
index 0cbd92a58..549c46033 100644
--- a/Tests/Manual/CPPopUpButtonTest/AppController.j
+++ b/Tests/Manual/CPPopUpButtonTest/AppController.j
@@ -11,6 +11,8 @@
 
 @implementation AppController : CPObject
 {
+    CPPopUpButton popUpButton;
+    CPPopUpButton popUpButton2;
 }
 
 - (void)applicationDidFinishLaunching:(CPNotification)aNotification
@@ -18,8 +20,8 @@
     var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask],
         contentView = [theWindow contentView];
 
-    var popUpButton = [[CPPopUpButton alloc] initWithFrame:CGRectMakeZero()],
-        popUpButton2 = [[CPPopUpButton alloc] initWithFrame:CGRectMakeZero()];
+    popUpButton = [[CPPopUpButton alloc] initWithFrame:CGRectMakeZero()];
+    popUpButton2 = [[CPPopUpButton alloc] initWithFrame:CGRectMakeZero()];
 
     for (var i = 0; i < 5; i++)
     {
@@ -43,7 +45,7 @@
     [popUpButton2 setCenter:CGPointMake([contentView center].x + 25.0, [contentView center].y)];
     [contentView addSubview:popUpButton2];
 
-    var textField = [[CPTextField alloc] initWithFrame:CGRectMake(0.0, 0.0, 200.0, 29.0)];
+    var textField = [[CPTextField alloc] initWithFrame:CGRectMake(0.0, 0.0, 200.0, 29.0)],
         frameOrigin = [popUpButton frameOrigin];
 
     [textField setEditable:YES];
@@ -53,6 +55,15 @@
     [textField bind:@"value" toObject:popUpButton withKeyPath:@"selectedTag" options:0];
     [contentView addSubview:textField];
 
+    var button = [CPButton buttonWithTitle:@"Remove Items"],
+        frame = [textField frame];
+
+    [button setCenter:CGPointMake([contentView center].x, 0)];
+    [button setFrameOrigin:CGPointMake(CGRectGetMinX([button frame]), CGRectGetMaxY(frame) + 15)];
+    [button setTarget:self];
+    [button setAction:@selector(removeItems:)];
+    [contentView addSubview:button];
+
     [popUpButton bind:@"selectedTag" toObject:textField withKeyPath:@"value" options:0]
     [popUpButton2 bind:@"selectedTag" toObject:popUpButton withKeyPath:@"selectedTag" options:0];
 
@@ -64,4 +75,11 @@
     [theWindow orderFront:self];
 }
 
+- (@action)removeItems:(id)sender
+{
+    [popUpButton2 removeAllItems];
+    [popUpButton removeAllItems];
+    CPLog("objectValue = %d", [popUpButton objectValue]);
+}
+
 @end
diff --git a/Tests/Manual/KeyEquivalents/AppController.j b/Tests/Manual/KeyEquivalents/AppController.j
index 2ce94fea8..f32bddf20 100644
--- a/Tests/Manual/KeyEquivalents/AppController.j
+++ b/Tests/Manual/KeyEquivalents/AppController.j
@@ -60,7 +60,6 @@
         [contentView addSubview:button];
     }
 
-
     var label = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
     [label setStringValue:@"Press the appropriate key on the keyboard for each button and verify that it reacts."];
     [label setFont:[CPFont boldSystemFontOfSize:14.0]];
@@ -86,7 +85,7 @@
         ["down arrow", CPDownArrowFunctionKey],
         ["home", CPHomeFunctionKey],
         ["end", CPEndFunctionKey]
-        ];
+    ];
 
     for (var i = 0, buttonsWide = 6, yOffset = 0; i < functionKeysToTest.length; i++)
     {
@@ -102,6 +101,15 @@
         [contentView addSubview:button];
     }
 
+    var label2 = [[CPTextField alloc] initWithFrame:CGRectMake(10, 140 + yOffset + 24, 100, 24)];
+    [label2 setStringValue:@"If a text field is the first responder, some key equivalents are ignored."];
+    [label2 sizeToFit];
+    [contentView addSubview:label2];
+
+    var textField = [CPTextField textFieldWithStringValue:"" placeholder:"" width:100];
+    [textField setFrameOrigin:CGPointMake(10, CGRectGetMaxY([label2 frame]) + 10)];
+    [contentView addSubview:textField];
+
     [theWindow orderFront:self];
 }
 
diff --git a/bootstrap.sh b/bootstrap.sh
index 1a443aab7..215e3de89 100755
--- a/bootstrap.sh
+++ b/bootstrap.sh
@@ -30,14 +30,16 @@ function which () {
 }
 
 function ask_remove_dir () {
-    dir="$1"
-    if [ -d "$dir" ]; then
+    a_longish_dir_name="$1"
+    if [ -d "$a_longish_dir_name" ]; then
         echo "================================================================================"
-        echo "Found an existing Narwhal/Cappuccino installation, $dir. Remove it automatically now?"
-        echo "WARNING: the ENTIRE directory, $dir, will be removed (i.e. 'rm -rf $dir')."
-        echo "Be sure this is correct. Custom modifications and installed packages WILL BE DELETED."
+        echo "Found an existing Cappuccino installation: $a_longish_dir_name. Remove it "
+        echo "automatically now? "
+        echo "WARNING: the ENTIRE directory, $a_longish_dir_name, will be removed (i.e. "
+        echo "'rm -rf $a_longish_dir_name'). Be sure this is correct. Custom modifications and "
+        echo "installed packages WILL BE DELETED."
         if prompt "no"; then
-            rm -rf "$dir"
+            rm -rf "$a_longish_dir_name"
         fi
     fi
 }
@@ -76,14 +78,14 @@ function ask_append_shell_config () {
 
 function check_and_exit () {
     if [ ! "$?" = "0" ]; then
-        echo "Error: problem running boostrap.sh. Exiting."
+        echo "Error: problem running bootstrap.sh. Exiting."
         exit 1
     fi
 }
 
-function check_build_environment () {
+function check_install_environment () {
     # make sure dependencies are installed and on the $PATH
-    CAPP_BUILD_DEPS=(java gcc unzip)
+    CAPP_BUILD_DEPS=(java unzip)
 
     for dep in ${CAPP_BUILD_DEPS[@]}; do
         which "$dep" &> /dev/null
@@ -113,7 +115,19 @@ function check_build_environment () {
     fi
 }
 
-check_build_environment
+function check_build_environment () {
+    CAPP_BUILD_DEPS=(gcc)
+
+    for dep in ${CAPP_BUILD_DEPS[@]}; do
+        which "$dep" &> /dev/null
+        if [ ! "$?" = "0" ]; then
+            echo "Error: $dep is required to build Cappuccino components. Please install $dep and re-run bootstrap.sh."
+            exit 1
+        fi
+    done
+}
+
+check_install_environment
 
 if [ -w "/usr/local" ]; then
     default_directory="/usr/local/narwhal"
@@ -122,47 +136,71 @@ else
 fi
 
 install_directory=""
-tmp_zip="/tmp/narwhal.zip"
+tmp_zip="/tmp/cappuccino.zip"
 
-github_user="280north"
-github_ref="master"
-tusk_install_command="install"
+github_user="cappuccino"
+github_ref="0.9.2"
 
 noprompt=""
 install_capp=""
+install_method="zip"
 
 while [ $# -gt 0 ]; do
     case "$1" in
         --noprompt)     noprompt="yes";;
         --directory)    install_directory="$2"; shift;;
-        --clone)        tusk_install_command="clone";;
-        --clone-http)   tusk_install_command="clone --http";;
+        --clone)        install_method="clone";;
+        --clone-http)   install_method="clone --http";;
         --github-user)  github_user="$2"; shift;;
         --github-ref)   github_ref="$2"; shift;;
-        --install-capp) install_capp="yes";;
-        --install-test) install_test="yes";;
-        --install)      install_capp="yes"; install_test="yes";;
         *)              cat >&2 <<-EOT
 usage: ./bootstrap.sh [OPTIONS]
 
     --noprompt:             Don't prompt, use relatively safe defaults.
-    --directory [DIR]:      Use a directory other than /usr/local/narwhal.
+    --directory [DIR]:      Use a directory other than $default_directory.
     --clone:                Do "git clone git://" instead of downloading zips.
     --clone-http:           Do "git clone http://" instead of downloading zips.
-    --github-user [USER]:   Github user for the narwhal project (default: 280north).
-    --github-ref [REF]:     Use another git ref (default: master).
-    --install-capp:         Install "objective-j" and "cappuccino" packages.
-    --install-test:         Install "ojtest" package.
-    --install               Install all packages.
+    --github-user [USER]:   Github user (default: $github_user).
+    --github-ref [REF]:     Use another git ref (default: $github_ref).
 EOT
                         exit 1;;
     esac
     shift
 done
 
-github_project="$github_user-narwhal"
-github_path=$(echo "$github_project" | tr '-' '/')
+github_project="$github_user-cappuccino-base"
+github_path="$github_user/cappuccino-base"
 
+# The purpose of bootstrap is to install Cappuccino.
+install_cappuccino="yes"
+
+sed "s/\[\[ CAPPUCCINO_VERSION \]\]/$github_ref/" < /dev/null; then
-    echo "================================================================================"
-    echo "Narwhal JavaScript platform is required. Install it automatically now?"
-    if prompt "yes"; then
-        install_narwhal="yes"
-    fi
-fi
-
-if [ "$install_narwhal" ]; then
+if [ "$install_cappuccino" ]; then
     if [ ! "$install_directory" ]; then
         echo "================================================================================"
-        echo "To use the default location, \"$default_directory\", just hit enter/return, or enter another path:"
+        echo "Enter an installation path, or hit enter/return to use \"$default_directory\":"
         if [ "$noprompt" ]; then
             input=""
         else
@@ -217,7 +246,7 @@ if [ "$install_narwhal" ]; then
     install_directory="$(cd "$(dirname "$install_directory")" && echo "$(pwd)/$(basename "$install_directory")")"
 
     if [ ! -d "$(dirname "$install_directory")" ]; then
-        echo "Error: parent directory of $install_directory does not exist"
+        echo "Error: parent directory of $install_directory does not exist."
         exit 1
     fi
 
@@ -231,24 +260,24 @@ if [ "$install_narwhal" ]; then
         fi
     fi
 
-    if [ "$(echo $tusk_install_command | cut -c-5)" = "clone" ]; then
-        if [ "$(echo $tusk_install_command | cut -c7-)" = "--http" ]; then
+    if [ "$(echo $install_method | cut -c-5)" = "clone" ]; then
+        if [ "$(echo $install_method | cut -c7-)" = "--http" ]; then
             git_protocol="http"
         else
             git_protocol="git"
         fi
         git_repo="$git_protocol://github.com/$github_path.git"
-        echo "Cloning Narwhal from \"$git_repo\"..."
+        echo "Cloning Cappuccino base from \"$git_repo\"..."
         git clone "$git_repo" "$install_directory"
         (cd "$install_directory" && git checkout "origin/$github_ref")
     else
         zip_ball="http://github.com/$github_path/zipball/$github_ref"
 
-        echo "Downloading Narwhal from \"$zip_ball\"..."
+        echo "Downloading Cappuccino base from \"$zip_ball\"..."
         $(which curl &> /dev/null && echo curl -L -o || echo wget --no-check-certificate -O) "$tmp_zip" "$zip_ball"
         check_and_exit
 
-        echo "Installing Narwhal..."
+        echo "Installing Cappuccino base..."
         unzip "$tmp_zip" -d "$install_directory"
         check_and_exit
         rm "$tmp_zip"
@@ -264,92 +293,48 @@ if [ "$install_narwhal" ]; then
 fi
 
 if ! which "narwhal" > /dev/null; then
-    echo "Problem installing Narwhal. To install Narwhal manually follow the instructions at http://narwhaljs.org/"
+    echo "Problem installing Narwhal. To install Narwhal manually follow the "
+    echo "instructions at http://narwhaljs.org/."
     exit 1
 fi
 
 install_directory="$(dirname -- "$(dirname -- "$(which narwhal)")")"
 
-echo "================================================================================"
-echo "Using Narwhal installation at \"$install_directory\". Is this correct?"
-if ! prompt "yes"; then
-    exit 1
-fi
-
-if [ ! "$install_capp" ]; then
-    echo "================================================================================"
-    echo "Would you like to install the pre-built Objective-J and Cappuccino packages?"
-    echo "If you intend to build Cappuccino yourself this is not neccessary. To use "
-    echo "the checked out branch of Cappuccino say NO, and when bootstrap is finished "
-    echo "run \"jake install\"."
-    if prompt; then
-      install_capp="yes"
-    fi
-fi
-
-if [ ! "$install_test" ]; then
-    echo "================================================================================"
-    echo "Would you like to install the OJTest package?"
-    if [ ! "$install_capp" ]; then
-        echo "This will also install the Objective-J and Cappuccino packages."
-    fi
-    if prompt; then
-      install_test="yes"
-    fi
-fi
-
-# Make sure tusk can access GitHub's HTTPS URLs.
-NARWHAL_ENGINE=rhino js -e "javax.net.ssl.SSLContext.getDefault()" &> /dev/null
-if [ ! "$?" = "0" ]; then
-    echo "Installing packages from GitHub requires SSL support in Java."
-    if [ "$(uname)" = "Linux" ]; then
-        echo "Try installing the libbcprov-java package, if it exists for your Linux distro."
-    fi
-    exit 1
-fi
-
-extra_packages=""
-if [ "$install_capp" ]; then
-    extra_packages="objective-j cappuccino"
-fi
-
-echo "Installing necessary packages..."
-
-if ! tusk update; then
-    echo "Error: unable to update tusk catalog. Check that you have sufficient permissions."
-    exit 1
-fi
-
-
-tusk $tusk_install_command browserjs jake shrinksafe
-
-
-echo "Installing extra packages..."
-tusk $tusk_install_command $extra_packages
-
-
-if [ "$install_test" ]; then
-    echo "Installing OJTest from GitHub..."
-    NARWHAL_ENGINE=rhino tusk install https://www.github.com/cappuccino/OJTest/zipball/latest
-fi
+#echo "================================================================================"
+#echo "Using Cappuccino base installation at \"$install_directory\". Is this correct?"
+#if ! prompt "yes"; then
+#    exit 1
+#fi
 
 if [ `uname` = "Darwin" ]; then
     echo "================================================================================"
-    echo "Would you like to install the JavaScriptCore engine for Narwhal?"
-    echo "This is optional but will make building and running Objective-J much faster."
+    echo "Would you like to build the JavaScriptCore engine? This is optional but will "
+    echo "make building and running Cappuccino and Objective-J much faster."
     if prompt "yes"; then
-        tusk $tusk_install_command narwhal-jsc
+        check_build_environment
 
-        if ! (cd "$install_directory/packages/narwhal-jsc" && make webkit); then
+        # The narwhal-jsc package is already installed within the base kit.
+
+        # This autoreconf command improves compatibility with MacPorts, but only works with autoconf 2.65+.
+        needed_autoconf_major=2
+        needed_autoconf_minor=65
+        if $(autoconf --version | head -1 | python -c "import sys, re; major, minor=re.search(r'(\d+)\.(\d+)', sys.stdin.read()).groups(); sys.exit((int(major) < $needed_autoconf_major or int(minor) < $needed_autoconf_minor) and 1)"); then
+            # Don't bother checking the return code of this operation. Even if it fails, it's still
+            # worthwhile to continue and attempt the full build.
+            (cd "$install_directory/packages/narwhal-jsc/deps/libedit-20100424-3.0" && autoreconf -if)
+        fi
+
+        if ! (cd "$install_directory/packages/narwhal-jsc/" && make webkit); then
             rm -rf "$install_directory/packages/narwhal-jsc"
             echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
             echo "WARNING: building narwhal-jsc failed. Hit enter to continue."
             echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
             # read
-        elif ! [ "$NARWHAL_ENGINE" = "jsc" ]; then
+        elif ! [ "$NARWHAL_ENGINE_SAVED" = "jsc" ]; then
             echo "================================================================================"
-            echo "Rhino is the default Narwhal engine, should we change the default to JavaScriptCore for you?"
-            echo "This can by overridden by setting the NARWHAL_ENGINE environment variable to \"jsc\" or \"rhino\"."
+            echo "Rhino is the default engine. Should we change the default to JavaScriptCore for "
+            echo "you? This can by overridden by setting the NARWHAL_ENGINE environment variable "
+            echo "to \"jsc\" or \"rhino\"."
             ask_append_shell_config "export NARWHAL_ENGINE=jsc"
         fi
     fi
@@ -358,12 +343,14 @@ fi
 export PATH="$PATH_SAVED"
 if ! which "narwhal" > /dev/null; then
     echo "================================================================================"
-    echo "You must add Narwhal's \"bin\" directory to your PATH environment variable. Do this automatically now?"
+    echo "You must add Cappuccino's \"bin\" directory to your PATH environment variable. "
+    echo "Do this automatically now?"
 
     export_path_string="export PATH=\"$install_directory/bin:\$PATH\""
 
     if ! ask_append_shell_config "$export_path_string"; then
-        echo "Add \"$install_directory/bin\" to your PATH environment variable in your shell configuration file (e.x. .profile, .bashrc, .bash_profile)."
+        echo "Add \"$install_directory/bin\" to your PATH environment variable in your shell "
+        echo "configuration file (e.x. .profile, .bashrc, .bash_profile)."
         echo "For example:"
         echo "    $export_path_string"
     fi
@@ -372,18 +359,21 @@ fi
 if [ "$CAPP_BUILD" ]; then
     if [ -d "$CAPP_BUILD" ]; then
         echo "================================================================================"
-        echo "An existing \$CAPP_BUILD directory at \"$CAPP_BUILD\" exists. The previous build may be incompatible. Remove it automatically now?"
+        echo "An existing \$CAPP_BUILD directory at \"$CAPP_BUILD\" exists. The previous "
+        echo "build may be incompatible. Remove it automatically now?"
         if prompt "no"; then
             rm -rf "$CAPP_BUILD"
         fi
     fi
 else
     echo "================================================================================"
-    echo "Before building Cappuccino we recommend you set the \$CAPP_BUILD environment variable to a path where you wish to build Cappuccino."
-    echo "This can be automatically set to the default value of \"$PWD/Build\", or you can set \$CAPP_BUILD yourself."
+    echo "Before building Cappuccino we recommend you set the \$CAPP_BUILD environment "
+    echo "variable to a path where you wish to build Cappuccino. This can be automatically"
+    echo "set to the default value of \"$PWD/Build\", or you can set \$CAPP_BUILD yourself."
     ask_append_shell_config "export CAPP_BUILD=\"$PWD/Build\""
 fi
 
 echo "================================================================================"
-echo "Bootstrapping of Narwhal and other required tools is complete."
-echo "NOTE: any changes made to the shell configuration files won't take place until you restart the shell."
+echo "Bootstrapping of Cappuccino and other required tools is complete."
+echo "NOTE: any changes made to the shell configuration files won't take place until "
+echo "you restart the shell."
diff --git a/version.json b/version.json
index 14230b4a6..2cec8054e 100644
--- a/version.json
+++ b/version.json
@@ -1,3 +1,3 @@
 {
-    "version": "0.9.1"
+    "version": "0.9.2"
 }
\ No newline at end of file