// Copyright (c) 2012 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.

#include "chrome/browser/browser_process.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_system.h"
#include "chrome/browser/notifications/balloon.h"
#include "chrome/browser/notifications/balloon_collection.h"
#include "chrome/browser/notifications/balloon_host.h"
#include "chrome/browser/notifications/balloon_notification_ui_manager.h"
#include "chrome/browser/notifications/notification.h"
#include "chrome/browser/notifications/notification_delegate.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/result_codes.h"
#include "extensions/browser/process_manager.h"
#include "ui/message_center/message_center.h"
#include "ui/message_center/message_center_switches.h"
#include "ui/message_center/message_center_util.h"
#include "ui/message_center/notification_list.h"

using content::NavigationController;
using content::WebContents;
using extensions::Extension;

// Tests are timing out waiting for extension to crash.
// http://crbug.com/174705
#if defined(OS_MACOSX) || defined(USE_AURA) || defined(OS_LINUX)
#define MAYBE_ExtensionCrashRecoveryTest DISABLED_ExtensionCrashRecoveryTest
#else
#define MAYBE_ExtensionCrashRecoveryTest ExtensionCrashRecoveryTest
#endif  // defined(OS_MACOSX) || defined(USE_AURA) || defined(OS_LINUX)

class ExtensionCrashRecoveryTestBase : public ExtensionBrowserTest {
 protected:
  virtual void AcceptNotification(size_t index) = 0;
  virtual void CancelNotification(size_t index) = 0;
  virtual size_t CountBalloons() = 0;

  ExtensionService* GetExtensionService() {
    return browser()->profile()->GetExtensionService();
  }

  extensions::ProcessManager* GetProcessManager() {
    return extensions::ExtensionSystem::Get(browser()->profile())->
        process_manager();
  }

  void CrashExtension(std::string extension_id) {
    const Extension* extension =
        GetExtensionService()->GetExtensionById(extension_id, false);
    ASSERT_TRUE(extension);
    extensions::ExtensionHost* extension_host = GetProcessManager()->
        GetBackgroundHostForExtension(extension_id);
    ASSERT_TRUE(extension_host);

    base::KillProcess(extension_host->render_process_host()->GetHandle(),
                      content::RESULT_CODE_KILLED, false);
    ASSERT_TRUE(WaitForExtensionCrash(extension_id));
    ASSERT_FALSE(GetProcessManager()->
                 GetBackgroundHostForExtension(extension_id));

    // Wait for extension crash balloon to appear.
    base::MessageLoop::current()->RunUntilIdle();
  }

  void CheckExtensionConsistency(std::string extension_id) {
    const Extension* extension =
        GetExtensionService()->extensions()->GetByID(extension_id);
    ASSERT_TRUE(extension);
    extensions::ExtensionHost* extension_host = GetProcessManager()->
        GetBackgroundHostForExtension(extension_id);
    ASSERT_TRUE(extension_host);
    extensions::ProcessManager::ViewSet all_views =
        GetProcessManager()->GetAllViews();
    extensions::ProcessManager::ViewSet::const_iterator it =
        all_views.find(extension_host->host_contents()->GetRenderViewHost());
    ASSERT_FALSE(it == all_views.end());
    ASSERT_TRUE(extension_host->IsRenderViewLive());
    extensions::ProcessMap* process_map =
        browser()->profile()->GetExtensionService()->process_map();
    ASSERT_TRUE(process_map->Contains(
        extension_id,
        extension_host->render_view_host()->GetProcess()->GetID()));
  }

  void LoadTestExtension() {
    ExtensionBrowserTest::SetUpInProcessBrowserTestFixture();
    const Extension* extension = LoadExtension(
        test_data_dir_.AppendASCII("common").AppendASCII("background_page"));
    ASSERT_TRUE(extension);
    first_extension_id_ = extension->id();
    CheckExtensionConsistency(first_extension_id_);
  }

  void LoadSecondExtension() {
    const Extension* extension = LoadExtension(
        test_data_dir_.AppendASCII("install").AppendASCII("install"));
    ASSERT_TRUE(extension);
    second_extension_id_ = extension->id();
    CheckExtensionConsistency(second_extension_id_);
  }

  std::string first_extension_id_;
  std::string second_extension_id_;
};

class MAYBE_ExtensionCrashRecoveryTest
    : public ExtensionCrashRecoveryTestBase {
 protected:
  virtual void AcceptNotification(size_t index) OVERRIDE {
    if (message_center::IsRichNotificationEnabled()) {
      message_center::MessageCenter* message_center =
          message_center::MessageCenter::Get();
      ASSERT_GT(message_center->NotificationCount(), index);
      message_center::NotificationList::Notifications::reverse_iterator it =
          message_center->GetVisibleNotifications().rbegin();
      for (size_t i=0; i < index; ++i)
        it++;
      std::string id = (*it)->id();
      message_center->ClickOnNotification(id);
    } else {
      Balloon* balloon = GetNotificationDelegate(index);
      ASSERT_TRUE(balloon);
      balloon->OnClick();
    }
    WaitForExtensionLoad();
  }

  virtual void CancelNotification(size_t index) OVERRIDE {
    if (message_center::IsRichNotificationEnabled()) {
      message_center::MessageCenter* message_center =
          message_center::MessageCenter::Get();
      ASSERT_GT(message_center->NotificationCount(), index);
      message_center::NotificationList::Notifications::reverse_iterator it =
          message_center->GetVisibleNotifications().rbegin();
      for (size_t i=0; i < index; i++) { it++; }
      ASSERT_TRUE(g_browser_process->notification_ui_manager()->
          CancelById((*it)->id()));
    } else {
      Balloon* balloon = GetNotificationDelegate(index);
      ASSERT_TRUE(balloon);
      std::string id = balloon->notification().notification_id();
      ASSERT_TRUE(g_browser_process->notification_ui_manager()->CancelById(id));
    }
  }

  virtual size_t CountBalloons() OVERRIDE {
    if (message_center::IsRichNotificationEnabled())
      return message_center::MessageCenter::Get()->NotificationCount();

    return BalloonNotificationUIManager::GetInstanceForTesting()->
        balloon_collection()->GetActiveBalloons().size();
  }

private:
     Balloon* GetNotificationDelegate(size_t index) {
       BalloonNotificationUIManager* manager =
           BalloonNotificationUIManager::GetInstanceForTesting();
       BalloonCollection::Balloons balloons =
           manager->balloon_collection()->GetActiveBalloons();
       return index < balloons.size() ? balloons.at(index) : NULL;
     }
};

// Flaky: http://crbug.com/242167.
IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest, DISABLED_Basic) {
  const size_t size_before = GetExtensionService()->extensions()->size();
  const size_t crash_size_before =
      GetExtensionService()->terminated_extensions()->size();
  LoadTestExtension();
  CrashExtension(first_extension_id_);
  ASSERT_EQ(size_before, GetExtensionService()->extensions()->size());
  ASSERT_EQ(crash_size_before + 1,
            GetExtensionService()->terminated_extensions()->size());
  ASSERT_NO_FATAL_FAILURE(AcceptNotification(0));

  SCOPED_TRACE("after clicking the balloon");
  CheckExtensionConsistency(first_extension_id_);
  ASSERT_EQ(crash_size_before,
            GetExtensionService()->terminated_extensions()->size());
}

// Flaky, http://crbug.com/241191.
IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
                       DISABLED_CloseAndReload) {
  const size_t size_before = GetExtensionService()->extensions()->size();
  const size_t crash_size_before =
      GetExtensionService()->terminated_extensions()->size();
  LoadTestExtension();
  CrashExtension(first_extension_id_);

  ASSERT_EQ(size_before, GetExtensionService()->extensions()->size());
  ASSERT_EQ(crash_size_before + 1,
            GetExtensionService()->terminated_extensions()->size());

  ASSERT_NO_FATAL_FAILURE(CancelNotification(0));
  ReloadExtension(first_extension_id_);

  SCOPED_TRACE("after reloading");
  CheckExtensionConsistency(first_extension_id_);
  ASSERT_EQ(crash_size_before,
            GetExtensionService()->terminated_extensions()->size());
}

// Test is timing out on Windows http://crbug.com/174705.
#if defined(OS_WIN)
#define MAYBE_ReloadIndependently DISABLED_ReloadIndependently
#else
#define MAYBE_ReloadIndependently ReloadIndependently
#endif  // defined(OS_WIN)
IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
                       MAYBE_ReloadIndependently) {
  const size_t size_before = GetExtensionService()->extensions()->size();
  LoadTestExtension();
  CrashExtension(first_extension_id_);
  ASSERT_EQ(size_before, GetExtensionService()->extensions()->size());

  ReloadExtension(first_extension_id_);

  SCOPED_TRACE("after reloading");
  CheckExtensionConsistency(first_extension_id_);

  WebContents* current_tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_TRUE(current_tab);

  // The balloon should automatically hide after the extension is successfully
  // reloaded.
  ASSERT_EQ(0U, CountBalloons());
}

// Test is timing out on Windows http://crbug.com/174705.
#if defined(OS_WIN)
#define MAYBE_ReloadIndependentlyChangeTabs DISABLED_ReloadIndependentlyChangeTabs
#else
#define MAYBE_ReloadIndependentlyChangeTabs ReloadIndependentlyChangeTabs
#endif  // defined(OS_WIN)

IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
                       MAYBE_ReloadIndependentlyChangeTabs) {
  const size_t size_before = GetExtensionService()->extensions()->size();
  LoadTestExtension();
  CrashExtension(first_extension_id_);
  ASSERT_EQ(size_before, GetExtensionService()->extensions()->size());

  WebContents* original_tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_TRUE(original_tab);
  ASSERT_EQ(1U, CountBalloons());

  // Open a new tab, but the balloon will still be there.
  chrome::NewTab(browser());
  WebContents* new_current_tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_TRUE(new_current_tab);
  ASSERT_NE(new_current_tab, original_tab);
  ASSERT_EQ(1U, CountBalloons());

  ReloadExtension(first_extension_id_);

  SCOPED_TRACE("after reloading");
  CheckExtensionConsistency(first_extension_id_);

  // The balloon should automatically hide after the extension is successfully
  // reloaded.
  ASSERT_EQ(0U, CountBalloons());
}

IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
                       DISABLED_ReloadIndependentlyNavigatePage) {
  const size_t size_before = GetExtensionService()->extensions()->size();
  LoadTestExtension();
  CrashExtension(first_extension_id_);
  ASSERT_EQ(size_before, GetExtensionService()->extensions()->size());

  WebContents* current_tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_TRUE(current_tab);
  ASSERT_EQ(1U, CountBalloons());

  // Navigate to another page.
  ui_test_utils::NavigateToURL(
      browser(), ui_test_utils::GetTestUrl(
                     base::FilePath(base::FilePath::kCurrentDirectory),
                     base::FilePath(FILE_PATH_LITERAL("title1.html"))));
  ASSERT_EQ(1U, CountBalloons());

  ReloadExtension(first_extension_id_);

  SCOPED_TRACE("after reloading");
  CheckExtensionConsistency(first_extension_id_);

  // The balloon should automatically hide after the extension is successfully
  // reloaded.
  ASSERT_EQ(0U, CountBalloons());
}

// Make sure that when we don't do anything about the crashed extension
// and close the browser, it doesn't crash. The browser is closed implicitly
// at the end of each browser test.
//
// http://crbug.com/84719
#if defined(OS_LINUX)
#define MAYBE_ShutdownWhileCrashed DISABLED_ShutdownWhileCrashed
#else
#define MAYBE_ShutdownWhileCrashed ShutdownWhileCrashed
#endif  // defined(OS_LINUX)

IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
                       MAYBE_ShutdownWhileCrashed) {
  const size_t size_before = GetExtensionService()->extensions()->size();
  LoadTestExtension();
  CrashExtension(first_extension_id_);
  ASSERT_EQ(size_before, GetExtensionService()->extensions()->size());
}

// Flaky, http://crbug.com/241245.
IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
                       DISABLED_TwoExtensionsCrashFirst) {
  const size_t size_before = GetExtensionService()->extensions()->size();
  LoadTestExtension();
  LoadSecondExtension();
  CrashExtension(first_extension_id_);
  ASSERT_EQ(size_before + 1, GetExtensionService()->extensions()->size());
  ASSERT_NO_FATAL_FAILURE(AcceptNotification(0));

  SCOPED_TRACE("after clicking the balloon");
  CheckExtensionConsistency(first_extension_id_);
  CheckExtensionConsistency(second_extension_id_);
}

// Flaky: http://crbug.com/242196
IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
                       DISABLED_TwoExtensionsCrashSecond) {
  const size_t size_before = GetExtensionService()->extensions()->size();
  LoadTestExtension();
  LoadSecondExtension();
  CrashExtension(second_extension_id_);
  ASSERT_EQ(size_before + 1, GetExtensionService()->extensions()->size());
  ASSERT_NO_FATAL_FAILURE(AcceptNotification(0));

  SCOPED_TRACE("after clicking the balloon");
  CheckExtensionConsistency(first_extension_id_);
  CheckExtensionConsistency(second_extension_id_);
}

IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
                       TwoExtensionsCrashBothAtOnce) {
  const size_t size_before = GetExtensionService()->extensions()->size();
  const size_t crash_size_before =
      GetExtensionService()->terminated_extensions()->size();
  LoadTestExtension();
  LoadSecondExtension();
  CrashExtension(first_extension_id_);
  ASSERT_EQ(size_before + 1, GetExtensionService()->extensions()->size());
  ASSERT_EQ(crash_size_before + 1,
            GetExtensionService()->terminated_extensions()->size());
  CrashExtension(second_extension_id_);
  ASSERT_EQ(size_before, GetExtensionService()->extensions()->size());
  ASSERT_EQ(crash_size_before + 2,
            GetExtensionService()->terminated_extensions()->size());

  {
    SCOPED_TRACE("first balloon");
    ASSERT_NO_FATAL_FAILURE(AcceptNotification(0));
    CheckExtensionConsistency(first_extension_id_);
  }

  {
    SCOPED_TRACE("second balloon");
    ASSERT_NO_FATAL_FAILURE(AcceptNotification(0));
    CheckExtensionConsistency(first_extension_id_);
    CheckExtensionConsistency(second_extension_id_);
  }
}

IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
                       TwoExtensionsOneByOne) {
  const size_t size_before = GetExtensionService()->extensions()->size();
  LoadTestExtension();
  CrashExtension(first_extension_id_);
  ASSERT_EQ(size_before, GetExtensionService()->extensions()->size());
  LoadSecondExtension();
  CrashExtension(second_extension_id_);
  ASSERT_EQ(size_before, GetExtensionService()->extensions()->size());

  {
    SCOPED_TRACE("first balloon");
    ASSERT_NO_FATAL_FAILURE(AcceptNotification(0));
    CheckExtensionConsistency(first_extension_id_);
  }

  {
    SCOPED_TRACE("second balloon");
    ASSERT_NO_FATAL_FAILURE(AcceptNotification(0));
    CheckExtensionConsistency(first_extension_id_);
    CheckExtensionConsistency(second_extension_id_);
  }
}

// http://crbug.com/84719
#if defined(OS_LINUX)
#define MAYBE_TwoExtensionsShutdownWhileCrashed \
    DISABLED_TwoExtensionsShutdownWhileCrashed
#else
#define MAYBE_TwoExtensionsShutdownWhileCrashed \
    TwoExtensionsShutdownWhileCrashed
#endif  // defined(OS_LINUX)

// Make sure that when we don't do anything about the crashed extensions
// and close the browser, it doesn't crash. The browser is closed implicitly
// at the end of each browser test.
IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
                       MAYBE_TwoExtensionsShutdownWhileCrashed) {
  const size_t size_before = GetExtensionService()->extensions()->size();
  LoadTestExtension();
  CrashExtension(first_extension_id_);
  ASSERT_EQ(size_before, GetExtensionService()->extensions()->size());
  LoadSecondExtension();
  CrashExtension(second_extension_id_);
  ASSERT_EQ(size_before, GetExtensionService()->extensions()->size());
}

// Flaky, http://crbug.com/241573.
IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
                       DISABLED_TwoExtensionsIgnoreFirst) {
  const size_t size_before = GetExtensionService()->extensions()->size();
  LoadTestExtension();
  LoadSecondExtension();
  CrashExtension(first_extension_id_);
  ASSERT_EQ(size_before + 1, GetExtensionService()->extensions()->size());
  CrashExtension(second_extension_id_);
  ASSERT_EQ(size_before, GetExtensionService()->extensions()->size());

  // Accept notification 1 before canceling notification 0.
  // Otherwise, on Linux and Windows, there is a race here, in which
  // canceled notifications do not immediately go away.
  ASSERT_NO_FATAL_FAILURE(AcceptNotification(1));
  ASSERT_NO_FATAL_FAILURE(CancelNotification(0));

  SCOPED_TRACE("balloons done");
  ASSERT_EQ(size_before + 1, GetExtensionService()->extensions()->size());
  CheckExtensionConsistency(second_extension_id_);
}

// Flaky, http://crbug.com/241164.
IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
                       DISABLED_TwoExtensionsReloadIndependently) {
  const size_t size_before = GetExtensionService()->extensions()->size();
  LoadTestExtension();
  LoadSecondExtension();
  CrashExtension(first_extension_id_);
  ASSERT_EQ(size_before + 1, GetExtensionService()->extensions()->size());
  CrashExtension(second_extension_id_);
  ASSERT_EQ(size_before, GetExtensionService()->extensions()->size());

  {
    SCOPED_TRACE("first: reload");
    WebContents* current_tab =
        browser()->tab_strip_model()->GetActiveWebContents();
    ASSERT_TRUE(current_tab);
    // At the beginning we should have one balloon displayed for each extension.
    ASSERT_EQ(2U, CountBalloons());
    ReloadExtension(first_extension_id_);
    // One of the balloons should hide after the extension is reloaded.
    ASSERT_EQ(1U, CountBalloons());
    CheckExtensionConsistency(first_extension_id_);
  }

  {
    SCOPED_TRACE("second: balloon");
    ASSERT_NO_FATAL_FAILURE(AcceptNotification(0));
    CheckExtensionConsistency(first_extension_id_);
    CheckExtensionConsistency(second_extension_id_);
  }
}

// http://crbug.com/243648
#if defined(OS_WIN)
#define MAYBE_CrashAndUninstall DISABLED_CrashAndUninstall
#else
#define MAYBE_CrashAndUninstall CrashAndUninstall
#endif
IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
                       MAYBE_CrashAndUninstall) {
  const size_t size_before = GetExtensionService()->extensions()->size();
  const size_t crash_size_before =
      GetExtensionService()->terminated_extensions()->size();
  LoadTestExtension();
  LoadSecondExtension();
  CrashExtension(first_extension_id_);
  ASSERT_EQ(size_before + 1, GetExtensionService()->extensions()->size());
  ASSERT_EQ(crash_size_before + 1,
            GetExtensionService()->terminated_extensions()->size());

  ASSERT_EQ(1U, CountBalloons());
  UninstallExtension(first_extension_id_);
  base::MessageLoop::current()->RunUntilIdle();

  SCOPED_TRACE("after uninstalling");
  ASSERT_EQ(size_before + 1, GetExtensionService()->extensions()->size());
  ASSERT_EQ(crash_size_before,
            GetExtensionService()->terminated_extensions()->size());
  ASSERT_EQ(0U, CountBalloons());
}

// http://crbug.com/84719
#if defined(OS_LINUX)
#define MAYBE_CrashAndUnloadAll DISABLED_CrashAndUnloadAll
#else
#define MAYBE_CrashAndUnloadAll CrashAndUnloadAll
#endif  // defined(OS_LINUX)

IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
                       MAYBE_CrashAndUnloadAll) {
  const size_t size_before = GetExtensionService()->extensions()->size();
  const size_t crash_size_before =
      GetExtensionService()->terminated_extensions()->size();
  LoadTestExtension();
  LoadSecondExtension();
  CrashExtension(first_extension_id_);
  ASSERT_EQ(size_before + 1, GetExtensionService()->extensions()->size());
  ASSERT_EQ(crash_size_before + 1,
            GetExtensionService()->terminated_extensions()->size());

  GetExtensionService()->UnloadAllExtensions();
  ASSERT_EQ(crash_size_before,
            GetExtensionService()->terminated_extensions()->size());
}

// Fails a DCHECK on Aura and Linux: http://crbug.com/169622
// Failing on Windows: http://crbug.com/232340
#if defined(USE_AURA) || defined(OS_WIN) || defined(OS_LINUX)
#define MAYBE_ReloadTabsWithBackgroundPage DISABLED_ReloadTabsWithBackgroundPage
#else
#define MAYBE_ReloadTabsWithBackgroundPage ReloadTabsWithBackgroundPage
#endif

// Test that when an extension with a background page that has a tab open
// crashes, the tab stays open, and reloading it reloads the extension.
// Regression test for issue 71629.
IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
                       MAYBE_ReloadTabsWithBackgroundPage) {
  TabStripModel* tab_strip = browser()->tab_strip_model();
  const size_t size_before = GetExtensionService()->extensions()->size();
  const size_t crash_size_before =
      GetExtensionService()->terminated_extensions()->size();
  LoadTestExtension();

  // Open a tab extension.
  chrome::NewTab(browser());
  ui_test_utils::NavigateToURL(
      browser(),
      GURL("chrome-extension://" + first_extension_id_ + "/background.html"));

  const int tabs_before = tab_strip->count();
  CrashExtension(first_extension_id_);

  // Tab should still be open, and extension should be crashed.
  EXPECT_EQ(tabs_before, tab_strip->count());
  EXPECT_EQ(size_before, GetExtensionService()->extensions()->size());
  EXPECT_EQ(crash_size_before + 1,
            GetExtensionService()->terminated_extensions()->size());

  {
    content::WindowedNotificationObserver observer(
        content::NOTIFICATION_LOAD_STOP,
        content::Source<NavigationController>(
            &browser()->tab_strip_model()->GetActiveWebContents()->
                GetController()));
    chrome::Reload(browser(), CURRENT_TAB);
    observer.Wait();
  }
  // Extension should now be loaded.
  SCOPED_TRACE("after reloading the tab");
  CheckExtensionConsistency(first_extension_id_);
  ASSERT_EQ(size_before + 1, GetExtensionService()->extensions()->size());
  ASSERT_EQ(0U, CountBalloons());
}
