diff --git a/chrome/app/app-Info.plist b/chrome/app/app-Info.plist
index 7ca9989071f7c319eb5d1eb3e61aeb2df6cf562c..5390a707ff07e66f24fdbc441a05655787de0ae0 100644
--- a/chrome/app/app-Info.plist
+++ b/chrome/app/app-Info.plist
@@ -187,7 +187,7 @@
 	<key>NSMainNibFile</key>
 	<string>MainMenu</string>
 	<key>NSPrincipalClass</key>
-	<string>NSApplication</string>
+	<string>CrApplication</string>
 	<key>UTExportedTypeDeclarations</key>
 	<array>
 		<dict>
diff --git a/chrome/app/nibs/MainMenu.xib b/chrome/app/nibs/MainMenu.xib
index dbc39c54a352bc114837aaac733b0885275f4dcb..55d33e259ab4a1ea116a32634fc4004014c45460 100644
--- a/chrome/app/nibs/MainMenu.xib
+++ b/chrome/app/nibs/MainMenu.xib
@@ -8,7 +8,7 @@
 		<string key="IBDocument.HIToolboxVersion">353.00</string>
 		<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
 			<bool key="EncodedWithXMLCoder">YES</bool>
-			<integer value="81"/>
+			<integer value="29"/>
 		</object>
 		<object class="NSArray" key="IBDocument.PluginDependencies">
 			<bool key="EncodedWithXMLCoder">YES</bool>
@@ -26,13 +26,13 @@
 		<object class="NSMutableArray" key="IBDocument.RootObjects" id="1048">
 			<bool key="EncodedWithXMLCoder">YES</bool>
 			<object class="NSCustomObject" id="1021">
-				<string key="NSClassName">NSApplication</string>
+				<string key="NSClassName">CrApplication</string>
 			</object>
 			<object class="NSCustomObject" id="1014">
 				<string key="NSClassName">FirstResponder</string>
 			</object>
 			<object class="NSCustomObject" id="1050">
-				<string key="NSClassName">NSApplication</string>
+				<string key="NSClassName">CrApplication</string>
 			</object>
 			<object class="NSCustomObject" id="163992474">
 				<string key="NSClassName">NSFontManager</string>
@@ -43,7 +43,7 @@
 					<bool key="EncodedWithXMLCoder">YES</bool>
 					<object class="NSMenuItem" id="694149608">
 						<reference key="NSMenu" ref="649796088"/>
-						<string key="NSTitle">Chromium</string>
+						<string key="NSTitle">^IDS_SHORT_PRODUCT_NAME</string>
 						<string key="NSKeyEquiv"/>
 						<int key="NSMnemonicLoc">2147483647</int>
 						<object class="NSCustomResource" key="NSOnImage" id="353210768">
@@ -56,7 +56,7 @@
 						</object>
 						<string key="NSAction">submenuAction:</string>
 						<object class="NSMenu" key="NSSubmenu" id="110575045">
-							<string key="NSTitle">Chromium</string>
+							<string key="NSTitle">^IDS_SHORT_PRODUCT_NAME</string>
 							<object class="NSMutableArray" key="NSMenuItems">
 								<bool key="EncodedWithXMLCoder">YES</bool>
 								<object class="NSMenuItem" id="238522557">
@@ -1230,14 +1230,6 @@
 					</object>
 					<int key="connectionID">485</int>
 				</object>
-				<object class="IBConnectionRecord">
-					<object class="IBActionConnection" key="connection">
-						<string key="label">quit:</string>
-						<reference key="source" ref="168151378"/>
-						<reference key="destination" ref="632727374"/>
-					</object>
-					<int key="connectionID">489</int>
-				</object>
 				<object class="IBConnectionRecord">
 					<object class="IBActionConnection" key="connection">
 						<string key="label">commandDispatch:</string>
@@ -1534,13 +1526,21 @@
 					</object>
 					<int key="connectionID">646</int>
 				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBActionConnection" key="connection">
+						<string key="label">terminate:</string>
+						<reference key="source" ref="1050"/>
+						<reference key="destination" ref="632727374"/>
+					</object>
+					<int key="connectionID">647</int>
+				</object>
 			</object>
 			<object class="IBMutableOrderedSet" key="objectRecords">
 				<object class="NSArray" key="orderedObjects">
 					<bool key="EncodedWithXMLCoder">YES</bool>
 					<object class="IBObjectRecord">
 						<int key="objectID">0</int>
-						<object class="NSArray" key="object" id="276974574">
+						<object class="NSArray" key="object" id="470821800">
 							<bool key="EncodedWithXMLCoder">YES</bool>
 						</object>
 						<reference key="children" ref="1048"/>
@@ -1549,19 +1549,19 @@
 					<object class="IBObjectRecord">
 						<int key="objectID">-2</int>
 						<reference key="object" ref="1021"/>
-						<reference key="parent" ref="276974574"/>
+						<reference key="parent" ref="470821800"/>
 						<string type="base64-UTF8" key="objectName">RmlsZSdzIE93bmVyA</string>
 					</object>
 					<object class="IBObjectRecord">
 						<int key="objectID">-1</int>
 						<reference key="object" ref="1014"/>
-						<reference key="parent" ref="276974574"/>
+						<reference key="parent" ref="470821800"/>
 						<string key="objectName">First Responder</string>
 					</object>
 					<object class="IBObjectRecord">
 						<int key="objectID">-3</int>
 						<reference key="object" ref="1050"/>
-						<reference key="parent" ref="276974574"/>
+						<reference key="parent" ref="470821800"/>
 						<string key="objectName">Application</string>
 					</object>
 					<object class="IBObjectRecord">
@@ -1578,7 +1578,7 @@
 							<reference ref="586577488"/>
 							<reference ref="445514911"/>
 						</object>
-						<reference key="parent" ref="276974574"/>
+						<reference key="parent" ref="470821800"/>
 						<string key="objectName">Main Menu</string>
 					</object>
 					<object class="IBObjectRecord">
@@ -2013,7 +2013,7 @@
 					<object class="IBObjectRecord">
 						<int key="objectID">373</int>
 						<reference key="object" ref="163992474"/>
-						<reference key="parent" ref="276974574"/>
+						<reference key="parent" ref="470821800"/>
 					</object>
 					<object class="IBObjectRecord">
 						<int key="objectID">449</int>
@@ -2104,7 +2104,7 @@
 					<object class="IBObjectRecord">
 						<int key="objectID">483</int>
 						<reference key="object" ref="168151378"/>
-						<reference key="parent" ref="276974574"/>
+						<reference key="parent" ref="470821800"/>
 					</object>
 					<object class="IBObjectRecord">
 						<int key="objectID">492</int>
@@ -2315,7 +2315,7 @@
 					<object class="IBObjectRecord">
 						<int key="objectID">641</int>
 						<reference key="object" ref="979722531"/>
-						<reference key="parent" ref="276974574"/>
+						<reference key="parent" ref="470821800"/>
 					</object>
 				</object>
 			</object>
@@ -2622,7 +2622,7 @@
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<reference ref="9"/>
 					<string>{{525, 802}, {197, 73}}</string>
-					<string>{{0, 482}, {1437, 20}}</string>
+					<string>{{0, 337}, {1578, 20}}</string>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<reference ref="9"/>
 					<string>{74, 862}</string>
@@ -2687,7 +2687,7 @@
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<reference ref="9"/>
-					<string>{{222, 551}, {385, 213}}</string>
+					<string>{{12, 124}, {385, 213}}</string>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<reference ref="9"/>
 					<string>{{23, 794}, {245, 183}}</string>
@@ -2714,7 +2714,7 @@
 					<reference ref="9"/>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<reference ref="9"/>
-					<string>{{106, 179}, {353, 303}}</string>
+					<string>{{106, 34}, {350, 303}}</string>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<reference ref="9"/>
 					<string>{{323, 672}, {199, 203}}</string>
@@ -2746,7 +2746,7 @@
 				</object>
 			</object>
 			<nil key="sourceID"/>
-			<int key="maxID">646</int>
+			<int key="maxID">647</int>
 		</object>
 		<object class="IBClassDescriber" key="IBDocument.Classes">
 			<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -2759,14 +2759,12 @@
 						<object class="NSMutableArray" key="dict.sortedKeys">
 							<bool key="EncodedWithXMLCoder">YES</bool>
 							<string>orderFrontStandardAboutPanel:</string>
-							<string>quit:</string>
 							<string>showPreferences:</string>
 						</object>
 						<object class="NSMutableArray" key="dict.values">
 							<bool key="EncodedWithXMLCoder">YES</bool>
 							<string>id</string>
 							<string>id</string>
-							<string>id</string>
 						</object>
 					</object>
 					<object class="NSMutableDictionary" key="outlets">
@@ -2795,6 +2793,14 @@
 						<string key="minorKey">browser/cocoa/ui_localizer.h</string>
 					</object>
 				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">CrApplication</string>
+					<string key="superclassName">NSApplication</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBProjectSource</string>
+						<string key="minorKey">browser/chrome_application_mac.h</string>
+					</object>
+				</object>
 				<object class="IBPartialClassDescription">
 					<string key="className">DownloadShelfController</string>
 					<string key="superclassName">NSViewController</string>
diff --git a/chrome/browser/app_controller_mac.h b/chrome/browser/app_controller_mac.h
index 091891cf929378388fd2c1e6c8804703d968e752..cb3785f151e3bad793b57f1ad913c751996fc93a 100644
--- a/chrome/browser/app_controller_mac.h
+++ b/chrome/browser/app_controller_mac.h
@@ -14,6 +14,7 @@
 @class AboutWindowController;
 class BookmarkMenuBridge;
 class CommandUpdater;
+@class CrApplication;
 class GURL;
 class HistoryMenuBridge;
 @class PreferencesWindowController;
@@ -45,7 +46,7 @@ class Profile;
   BOOL fileMenuUpdatePending_;  // ensure we only do this once per notificaion.
 }
 
-- (IBAction)quit:(id)sender;
+- (void)didEndMainMessageLoop;
 - (Profile*)defaultProfile;
 
 // Show the preferences window, or bring it to the front if it's already
diff --git a/chrome/browser/app_controller_mac.mm b/chrome/browser/app_controller_mac.mm
index b7a062f83bc73250280ce9068b39068cd1ecd33f..ccfb0ebaabaa4fde2864dc682c4ca8d8934fce63 100644
--- a/chrome/browser/app_controller_mac.mm
+++ b/chrome/browser/app_controller_mac.mm
@@ -16,6 +16,7 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_shutdown.h"
 #include "chrome/browser/browser_window.h"
+#import "chrome/browser/chrome_application_mac.h"
 #import "chrome/browser/cocoa/about_window_controller.h"
 #import "chrome/browser/cocoa/bookmark_menu_bridge.h"
 #import "chrome/browser/cocoa/browser_window_cocoa.h"
@@ -144,9 +145,6 @@
   return YES;
 }
 
-// We do not use the normal application teardown process -- this function is
-// not called by the system but by us in |quit:|. |NSTerminateLater| is not a
-// return value that is supported by |quit:|.
 - (NSApplicationTerminateReply)applicationShouldTerminate:
     (NSApplication *)sender {
   // Do not quit if any per-tab sheets are open, as required by
@@ -164,17 +162,38 @@
 
 // Called when the app is shutting down. Clean-up as appropriate.
 - (void)applicationWillTerminate:(NSNotification *)aNotification {
+  NSAppleEventManager* em = [NSAppleEventManager sharedAppleEventManager];
+  [em removeEventHandlerForEventClass:kInternetEventClass
+                           andEventID:kAEGetURL];
+  [em removeEventHandlerForEventClass:'WWW!'
+                           andEventID:'OURL'];
+  [em removeEventHandlerForEventClass:kCoreEventClass
+                           andEventID:kAEOpenDocuments];
+
+  // Close all the windows.
+  BrowserList::CloseAllBrowsers(true);
+
+  // On Windows, this is done in Browser::OnWindowClosing, but that's not
+  // appropriate on Mac since we don't shut down when we reach zero windows.
+  browser_shutdown::OnShutdownStarting(browser_shutdown::BROWSER_EXIT);
+
+  // Release the reference to the browser process. Once all the browsers get
+  // dealloc'd, it will stop the RunLoop and fall back into main().
+  g_browser_process->ReleaseModule();
+
+  [[NSNotificationCenter defaultCenter] removeObserver:self];
+}
+
+- (void)didEndMainMessageLoop {
   DCHECK(!BrowserList::HasBrowserWithProfile([self defaultProfile]));
   if (!BrowserList::HasBrowserWithProfile([self defaultProfile])) {
-    // As we're shutting down, we need to nuke the TabRestoreService, which will
-    // start the shutdown of the NavigationControllers and allow for proper
-    // shutdown. If we don't do this chrome won't shutdown cleanly, and may end
-    // up crashing when some thread tries to use the IO thread (or another
-    // thread) that is no longer valid.
+    // As we're shutting down, we need to nuke the TabRestoreService, which
+    // will start the shutdown of the NavigationControllers and allow for
+    // proper shutdown. If we don't do this, Chrome won't shut down cleanly,
+    // and may end up crashing when some thread tries to use the IO thread (or
+    // another thread) that is no longer valid.
     [self defaultProfile]->ResetTabRestoreService();
   }
-
-  [[NSNotificationCenter defaultCenter] removeObserver:self];
 }
 
 // Helper routine to get the window controller if the key window is a tabbed
@@ -380,43 +399,6 @@
   return YES;
 }
 
-// We can't use the standard terminate: method because it will abruptly exit
-// the app and leave things on the stack in an unfinalized state. We need to
-// post a quit message to our run loop so the stack can gracefully unwind.
-- (IBAction)quit:(id)sender {
-  if ([self applicationShouldTerminate:NSApp] == NSTerminateCancel)
-    return;
-
-  // TODO(pinkerton):
-  // since we have to roll it ourselves, ask the delegate (ourselves, really)
-  // if we should terminate. For example, we might not want to if the user
-  // has ongoing downloads or multiple windows/tabs open. However, this would
-  // require posting UI and may require spinning up another run loop to
-  // handle it. If it says to continue, post the quit message, otherwise
-  // go back to normal.
-
-  NSAppleEventManager* em = [NSAppleEventManager sharedAppleEventManager];
-  [em removeEventHandlerForEventClass:kInternetEventClass
-                           andEventID:kAEGetURL];
-  [em removeEventHandlerForEventClass:'WWW!'
-                           andEventID:'OURL'];
-  [em removeEventHandlerForEventClass:kCoreEventClass
-                           andEventID:kAEOpenDocuments];
-
-  // TODO(pinkerton): Not sure where this should live, including it here
-  // causes all sorts of asserts from the open renderers. On Windows, it
-  // lives in Browser::OnWindowClosing, but that's not appropriate on Mac
-  // since we don't shut down when we reach zero windows.
-  // browser_shutdown::OnShutdownStarting(browser_shutdown::WINDOW_CLOSE);
-
-  // Close all the windows.
-  BrowserList::CloseAllBrowsers(true);
-
-  // Release the reference to the browser process. Once all the browsers get
-  // dealloc'd, it will stop the RunLoop and fall back into main().
-  g_browser_process->ReleaseModule();
-}
-
 // Called to determine if we should enable the "restore tab" menu item.
 // Checks with the TabRestoreService to see if there's anything there to
 // restore and returns YES if so.
@@ -445,7 +427,7 @@
           enable = menuState_->IsCommandEnabled(tag) ? YES : NO;
       }
     }
-  } else if (action == @selector(quit:)) {
+  } else if (action == @selector(terminate:)) {
     enable = YES;
   } else if (action == @selector(showPreferences:)) {
     enable = YES;
diff --git a/chrome/browser/automation/automation_provider_list_mac.mm b/chrome/browser/automation/automation_provider_list_mac.mm
index 4d408fd7108a92f442e246e43434e34d8d1e3320..2cfdb3f2ca48b8a5f610374d494e49ec6b4666bc 100644
--- a/chrome/browser/automation/automation_provider_list_mac.mm
+++ b/chrome/browser/automation/automation_provider_list_mac.mm
@@ -4,10 +4,10 @@
 
 #include "chrome/browser/automation/automation_provider_list.h"
 
-#import "chrome/browser/app_controller_mac.h"
+#import <AppKit/AppKit.h>
 
 void AutomationProviderList::OnLastProviderRemoved() {
   // We need to explicitly quit the application here because on Mac
   // the controller holds an additional reference to g_browser_process.
-  [[NSApp delegate] quit:nil];
+  [NSApp terminate:nil];
 }
diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc
index c20c7a33929bf04a86468b86899fa6078bd0a806..97b589a28794df0e353e90cc56248fdd09d76aae 100644
--- a/chrome/browser/browser_main.cc
+++ b/chrome/browser/browser_main.cc
@@ -836,7 +836,7 @@ int BrowserMain(const MainFunctionParams& parameters) {
 
   process_singleton.Cleanup();
 
-  Platform::WillTerminate();
+  Platform::DidEndMainMessageLoop();
 
   if (metrics)
     metrics->Stop();
diff --git a/chrome/browser/browser_main.h b/chrome/browser/browser_main.h
index 204467078bffa62a18dede12bf7928244256d953..44bc6ab4a3047ac9ed09613d24e08b6e574d9eb2 100644
--- a/chrome/browser/browser_main.h
+++ b/chrome/browser/browser_main.h
@@ -18,7 +18,7 @@ void WillInitializeMainMessageLoop(const MainFunctionParams& parameters);
 
 // Perform platform-specific work that needs to be done after the main event
 // loop has ended.
-void WillTerminate();
+void DidEndMainMessageLoop();
 
 // Records the conditions that can prevent Breakpad from generating and
 // sending crash reports.  The presence of a Breakpad handler (after
diff --git a/chrome/browser/browser_main_gtk.cc b/chrome/browser/browser_main_gtk.cc
index 6bfa6de4116c9698cf3caae8714a40ae4cbe31ad..beeb702a6a396791613ee9bfd0ebeacd72b3da01 100644
--- a/chrome/browser/browser_main_gtk.cc
+++ b/chrome/browser/browser_main_gtk.cc
@@ -13,7 +13,7 @@ namespace Platform {
 void WillInitializeMainMessageLoop(const MainFunctionParams& parameters) {
 }
 
-void WillTerminate() {
+void DidEndMainMessageLoop() {
 }
 
 void RecordBreakpadStatusUMA(MetricsService* metrics) {
diff --git a/chrome/browser/browser_main_mac.mm b/chrome/browser/browser_main_mac.mm
index ca6d34650c30d716a4ee510f764cbef04f9b657a..8ed837f8397f3a8d5f7ec943a8105f554261846a 100644
--- a/chrome/browser/browser_main_mac.mm
+++ b/chrome/browser/browser_main_mac.mm
@@ -11,25 +11,33 @@
 #include "base/debug_util.h"
 #include "chrome/app/breakpad_mac.h"
 #import "chrome/app/keystone_glue.h"
+#import "chrome/browser/app_controller_mac.h"
 #include "chrome/browser/browser_main_win.h"
+#import "chrome/browser/chrome_application_mac.h"
 #include "chrome/browser/metrics/metrics_service.h"
 #include "chrome/common/main_function_params.h"
 #include "chrome/common/result_codes.h"
 
 namespace Platform {
 
-// Perform any platform-specific work that needs to be done before the main
-// message loop is created and initialized.
-//
-// For Mac, this involves telling Cooca to finish its initalization, which we
-// want to do manually instead of calling NSApplicationMain(). The primary
-// reason is that NSAM() never returns, which would leave all the objects
-// currently on the stack in scoped_ptrs hanging and never cleaned up. We then
-// load the main nib directly. The main event loop is run from common code using
-// the MessageLoop API, which works out ok for us because it's a wrapper around
+// Tell Cooca to finish its initalization, which we want to do manually
+// instead of calling NSApplicationMain(). The primary reason is that NSAM()
+// never returns, which would leave all the objects currently on the stack
+// in scoped_ptrs hanging and never cleaned up. We then load the main nib
+// directly. The main event loop is run from common code using the
+// MessageLoop API, which works out ok for us because it's a wrapper around
 // CFRunLoop.
 void WillInitializeMainMessageLoop(const MainFunctionParams& parameters) {
-  [NSApplication sharedApplication];
+  // Initialize NSApplication using the custom subclass.  Check whether NSApp
+  // was already initialized using another class, because that would break
+  // some things.
+  [CrApplication sharedApplication];
+  if (![NSApp isKindOfClass:[CrApplication class]]) {
+    LOG(ERROR) << "NSApp should be of type CrApplication, not "
+               << [[NSApp className] UTF8String];
+    DCHECK(false) << "NSApp is of wrong type";
+  }
+
   // Before we load the nib, we need to start up the resource bundle so we have
   // the strings avaiable for localization.
   if (!parameters.ui_task) {
@@ -46,13 +54,9 @@ void WillInitializeMainMessageLoop(const MainFunctionParams& parameters) {
   [[KeystoneGlue defaultKeystoneGlue] registerWithKeystone];
 }
 
-// Perform platform-specific work that needs to be done after the main event
-// loop has ended. We need to send the notifications that Cooca normally would
-// telling everyone the app is about to end.
-void WillTerminate() {
-  [[NSNotificationCenter defaultCenter]
-      postNotificationName:NSApplicationWillTerminateNotification
-                    object:NSApp];
+void DidEndMainMessageLoop() {
+  AppController* appController = [NSApp delegate];
+  [appController didEndMainMessageLoop];
 }
 
 void RecordBreakpadStatusUMA(MetricsService* metrics) {
diff --git a/chrome/browser/browser_main_win.cc b/chrome/browser/browser_main_win.cc
index b59572fa5111d15d7771619fa452145188ea5ee4..dca1bba18466f0abad8cd832b35bb56aebaa14f9 100644
--- a/chrome/browser/browser_main_win.cc
+++ b/chrome/browser/browser_main_win.cc
@@ -33,7 +33,7 @@ namespace Platform {
 void WillInitializeMainMessageLoop(const MainFunctionParams& parameters) {
 }
 
-void WillTerminate() {
+void DidEndMainMessageLoop() {
 }
 
 void RecordBreakpadStatusUMA(MetricsService* metrics) {
diff --git a/chrome/browser/chrome_application_mac.h b/chrome/browser/chrome_application_mac.h
new file mode 100644
index 0000000000000000000000000000000000000000..b09af381eacc6f904ac8cee614c54fd7f5615b8b
--- /dev/null
+++ b/chrome/browser/chrome_application_mac.h
@@ -0,0 +1,13 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROME_APPLICATION_MAC_H_
+#define CHROME_BROWSER_CHROME_APPLICATION_MAC_H_
+
+#import <AppKit/AppKit.h>
+
+@interface CrApplication : NSApplication
+@end
+
+#endif  // CHROME_BROWSER_CHROME_APPLICATION_MAC_H_
diff --git a/chrome/browser/chrome_application_mac.mm b/chrome/browser/chrome_application_mac.mm
new file mode 100644
index 0000000000000000000000000000000000000000..8c7d86014781eb42b8e6523f939fb92ebd349c69
--- /dev/null
+++ b/chrome/browser/chrome_application_mac.mm
@@ -0,0 +1,61 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "chrome/browser/chrome_application_mac.h"
+
+@implementation CrApplication
+
+// -terminate: is the entry point for orderly "quit" operations in Cocoa.
+// This includes the application menu's quit menu item and keyboard
+// equivalent, the application's dock icon menu's quit menu item, "quit" (not
+// "force quit") in the Activity Monitor, and quits triggered by user logout
+// and system restart and shutdown.
+//
+// The default NSApplication -terminate: implementation will end the process
+// by calling exit(), and thus never leave the main run loop.  This is
+// unsuitable for Chrome's purposes.  Chrome depends on leaving the main
+// run loop to perform a proper orderly shutdown.  This design is ingrained
+// in the application and the assumptions that its code makes, and is
+// entirely reasonable and works well on other platforms, but it's not
+// compatible with the standard Cocoa quit sequence.  Quits originated from
+// within the application can be redirected to not use -terminate:, but
+// quits from elsewhere cannot be.
+//
+// To allow the Cocoa-based Chrome to support the standard Cocoa -terminate:
+// interface, and allow all quits to cause Chrome to shut down properly
+// regardless of their origin, -terminate: is overriden.  The custom
+// -terminate: does not end the application with exit().  Instead, it simply
+// returns after posting the normal NSApplicationWillTerminateNotification
+// notification.  The application is responsible for exiting on its own in
+// whatever way it deems appropriate.  In Chrome's case, the main run loop will
+// end and the applicaton will exit by returning from main().
+//
+// This implementation of -terminate: is scaled back and is not as
+// fully-featured as the implementation in NSApplication, nor is it a direct
+// drop-in replacement -terminate: in most applications.  It is
+// purpose-specific to Chrome.
+- (void)terminate:(id)sender {
+  NSApplicationTerminateReply shouldTerminate = NSTerminateNow;
+  SEL selector = @selector(applicationShouldTerminate:);
+  if ([[self delegate] respondsToSelector:selector])
+    shouldTerminate = [[self delegate] applicationShouldTerminate:self];
+
+  // If shouldTerminate is NSTerminateLater, the application is expected to
+  // call -replyToApplicationShouldTerminate: when it knows whether or not it
+  // should terminate.  If the argument is YES,
+  // -replyToApplicationShouldTerminate: will call -terminate:.  This will
+  // result in another call to the delegate's -applicationShouldTerminate:,
+  // which would be expected to return NSTerminateNow at that point.
+  if (shouldTerminate != NSTerminateNow)
+    return;
+
+  [[NSNotificationCenter defaultCenter]
+      postNotificationName:NSApplicationWillTerminateNotification
+                    object:self];
+
+  // Return, don't exit.  The application is responsible for exiting on its
+  // own.
+}
+
+@end
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 5066b65c910b0931f8a7c0157b7dcdcde1bc2c34..a9fce171fe85639d37340be01e82216ca54bf224 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -845,6 +845,8 @@
         'browser/character_encoding.h',
         'browser/child_process_security_policy.cc',
         'browser/child_process_security_policy.h',
+        'browser/chrome_application_mac.h',
+        'browser/chrome_application_mac.mm',
         'browser/chrome_plugin_browsing_context.cc',
         'browser/chrome_plugin_browsing_context.h',
         'browser/chrome_plugin_host.cc',