nsresult rv = NS_OK;
nsAppShellService::Quit(){  // Quit the application. We will asynchronously call the appshell's  // Exit() method via the ExitCallback() to allow one last pass  // through any events in the queue. This guarantees a tidy cleanup.  nsresult rv = NS_OK;  if (! mShuttingDown) {    mShuttingDown = PR_TRUE;    // Shutdown native app support; doing this first will prevent new    // requests to open additional windows coming in.    if ( mNativeAppSupport ) {        mNativeAppSupport->Quit();        mNativeAppSupport = 0;    }    // Enumerate through each open window and close it    if (mWindowMediator) {      nsCOMPtr<nsISimpleEnumerator> windowEnumerator;      rv = mWindowMediator->GetEnumerator(nsnull, getter_AddRefs(windowEnumerator));      if (NS_SUCCEEDED(rv)) {        PRBool more;        while (1) {          rv = windowEnumerator->HasMoreElements(&more);          if (NS_FAILED(rv) || !more)            break;          nsCOMPtr<nsISupports> isupports;          rv = windowEnumerator->GetNext(getter_AddRefs(isupports));          if (NS_FAILED(rv))            break;          nsCOMPtr<nsIDOMWindowInternal> window = do_QueryInterface(isupports);          NS_ASSERTION(window != nsnull, "not an nsIDOMWindowInternal");          if (! window)            continue;          window->Close();        }      }    }    {      nsCOMPtr<nsIWebShellWindow> hiddenWin(do_QueryInterface(mHiddenWindow));      if (hiddenWin) {        ClearXPConnectSafeContext();        hiddenWin->Close();      }      mHiddenWindow = nsnull;    }        // Note that we don't allow any premature returns from the above    // loop: no matter what, make sure we send the exit event.  If    // worst comes to worst, we'll do a leaky shutdown but we WILL    // shut down. Well, assuming that all *this* stuff works ;-).    nsCOMPtr<nsIEventQueueService> svc = do_GetService(kEventQueueServiceCID, &rv);    if (NS_FAILED(rv)) return rv;    nsCOMPtr<nsIEventQueue> queue;    rv = svc->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(queue));    if (NS_FAILED(rv)) return rv;    ExitEvent* event = new ExitEvent;    if (! event)      return NS_ERROR_OUT_OF_MEMORY;    PL_InitEvent(NS_REINTERPRET_CAST(PLEvent*, event),                 nsnull,                 HandleExitEvent,                 DestroyExitEvent);    event->mService = this;    NS_ADDREF(event->mService);    rv = queue->EnterMonitor();    if (NS_SUCCEEDED(rv)) {      rv = queue->PostEvent(NS_REINTERPRET_CAST(PLEvent*, event));    }    (void) queue->ExitMonitor();    if (NS_FAILED(rv)) {      NS_RELEASE(event->mService);      delete event;    }  }  return rv;}