text:
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/wm/core/focus_controller.h"

#include <map>

#include "base/memory/raw_ptr.h"
#include "base/test/scoped_feature_list.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/client/default_capture_client.h"
#include "ui/aura/client/focus_change_observer.h"
#include "ui/aura/test/aura_test_base.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/test/test_windows.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_tracker.h"
#include "ui/base/ui_base_features.h"
#include "ui/events/event.h"
#include "ui/events/event_constants.h"
#include "ui/events/event_handler.h"
#include "ui/events/test/event_generator.h"
#include "ui/wm/core/base_focus_rules.h"
#include "ui/wm/core/window_util.h"
#include "ui/wm/public/activation_change_observer.h"
#include "ui/wm/public/activation_client.h"

// EXPECT_DCHECK executes statement and expects a DCHECK death when DCHECK is
// enabled.
#if DCHECK_IS_ON()
#define EXPECT_DCHECK(statement, regex) \
  EXPECT_DEATH_IF_SUPPORTED(statement, regex)
#else
#define EXPECT_DCHECK(statement, regex) \
  { statement; }
#endif

namespace wm {

class FocusNotificationObserver : public ActivationChangeObserver,
                                  public aura::client::FocusChangeObserver {
 public:
  FocusNotificationObserver()
      : last_activation_reason_(ActivationReason::ACTIVATION_CLIENT),
        activation_changed_count_(0),
        focus_changed_count_(0),
        reactivation_count_(0),
        reactivation_requested_window_(nullptr),
        reactivation_actual_window_(nullptr) {}

  FocusNotificationObserver(const FocusNotificationObserver&) = delete;
  FocusNotificationObserver& operator=(const FocusNotificationObserver&) =
      delete;

  ~FocusNotificationObserver() override {}

  void ExpectCounts(int activation_changed_count, int focus_changed_count) {
    EXPECT_EQ(activation_changed_count, activation_changed_count_);
    EXPECT_EQ(focus_changed_count, focus_changed_count_);
  }
  ActivationReason last_activation_reason() const {
    return last_activation_reason_;
  }
  int reactivation_count() const { return reactivation_count_; }
  aura::Window* reactivation_requested_window() const {
    return reactivation_requested_window_;
  }
  aura::Window* reactivation_actual_window() const {
    return reactivation_actual_window_;
  }

 private:
  // Overridden from ActivationChangeObserver:
  void OnWindowActivated(ActivationReason reason,
                         aura::Window* gained_active,
                         aura::Window* lost_active) override {
    last_activation_reason_ = reason;
    ++activation_changed_count_;
  }
  void OnAttemptToReactivateWindow(aura::Window* request_active,
                                   aura::Window* actual_active) override {
    ++reactivation_count_;
    reactivation_requested_window_ = request_active;
    reactivation_actual_window_ = actual_active;
  }

  // Overridden from aura::client::FocusChangeObserver:
  void OnWindowFocused(aura::Window* gained_focus,
                       aura::Window* lost_focus) override {
    ++focus_changed_count_;
  }

  ActivationReason last_activation_reason_;
  int activation_changed_count_;
  int focus_changed_count_;
  int reactivation_count_;
  raw_ptr<aura::Window> reactivation_requested_window_;
  raw_ptr<aura::Window> reactivation_actual_window_;
};

class WindowDeleter {
 public:
  virtual aura::Window* GetDeletedWindow() = 0;

 protected:
  virtual ~WindowDeleter() {}
};

// ActivationChangeObserver and FocusChangeObserver that keeps track of whether
// it was notified about activation changes or focus changes with a deleted
// window.
class RecordingActivationAndFocusChangeObserver
    : public ActivationChangeObserver,
      public aura::client::FocusChangeObserver {
 public:
  RecordingActivationAndFocusChangeObserver(aura::Window* root,
                                            WindowDeleter* deleter)
      : root_(root),
        deleter_(deleter),
        was_notified_with_deleted_window_(false) {
    GetActivationClient(root_)->AddObserver(this);
    aura::client::GetFocusClient(root_)->AddObserver(this);
  }

  RecordingActivationAndFocusChangeObserver(
      const RecordingActivationAndFocusChangeObserver&) = delete;
  RecordingActivationAndFocusChangeObserver& operator=(
      const RecordingActivationAndFocusChangeObserver&) = delete;

  ~RecordingActivationAndFocusChangeObserver() override {
    GetActivationClient(root_)->RemoveObserver(this);
    aura::client::GetFocusClient(root_)->RemoveObserver(this);
  }

  bool was_notified_with_deleted_window() const {
    return was_notified_with_deleted_window_;
  }

  // Overridden from ActivationChangeObserver:
  void OnWindowActivating(ActivationReason reason,
                          aura::Window* gaining_active,
                          aura::Window* losing_active) override {
    if (deleter_->GetDeletedWindow()) {
      // A deleted window during activation should never be return as either the
      // gaining or losing active windows, nor should it be returned as the
      // currently active one.
      auto* active_window = GetActivationClient(root_)->GetActiveWindow();
      EXPECT_NE(active_window, deleter_->GetDeletedWindow());
      EXPECT_NE(gaining_active, deleter_->GetDeletedWindow());
      EXPECT_NE(losing_active, deleter_->GetDeletedWindow());
    }
  }

  void OnWindowActivated(ActivationReason reason,
                         aura::Window* gained_active,
                         aura::Window* lost_active) override {
    if (lost_active && lost_active == deleter_->GetDeletedWindow())
      was_notified_with_deleted_window_ = true;
  }

  // Overridden from aura::client::FocusChangeObserver:
  void OnWindowFocused(aura::Window* gained_focus,
                       aura::Window* lost_focus) override {
    if (lost_focus && lost_focus == deleter_->GetDeletedWindow())
      was_notified_with_deleted_window_ = true;
  }

 private:
  raw_ptr<aura::Window> root_;

  // Not owned.
  raw_ptr<WindowDeleter> deleter_;

  // Whether the observer was notified about the loss of activation or the
  // loss of focus with a window already deleted by |deleter_| as the
  // |lost_active| or |lost_focus| parameter.
  bool was_notified_with_deleted_window_;
};

// Hides a window when activation changes.
class HideOnLoseActivationChangeObserver : public ActivationChangeObserver {
 public:
  explicit HideOnLoseActivationChangeObserver(aura::Window* window_to_hide)
      : root_(window_to_hide->GetRootWindow()),
        window_to_hide_(window_to_hide) {
    GetActivationClient(root_)->AddObserver(this);
  }

  HideOnLoseActivationChangeObserver(
      const HideOnLoseActivationChangeObserver&) = delete;
  HideOnLoseActivationChangeObserver& operator=(
      const HideOnLoseActivationChangeObserver&) = delete;

  ~HideOnLoseActivationChangeObserver() override {
    GetActivationClient(root_)->RemoveObserver(this);
  }

  aura::Window* window_to_hide() { return window_to_hide_; }

 private:
  // Overridden from ActivationChangeObserver:
  void OnWindowActivated(ActivationReason reason,
                         aura::Window* gained_active,
                         aura::Window* lost_active) override {
    if (window_to_hide_) {
      aura::Window* window_to_hide = window_to_hide_;
      window_to_hide_ = nullptr;
      window_to_hide->Hide();
    }
  }

  raw_ptr<aura::Window> root_;
  raw_ptr<aura::Window> window_to_hide_;
};

// ActivationChangeObserver that deletes the window losing activation.
class DeleteOnActivationChangeObserver : public ActivationChangeObserver,
                                         public WindowDeleter {
 public:
  // If |delete_on_activating| is true, |window| will be deleted when
  // OnWindowActivating() is called, otherwise, it will be deleted when
  // OnWindowActivated() is called.
  // If |delete_window_losing_active| is true, |window| will be deleted if it is
  // the window losing activation, otherwise, will be deleted if it is the one
  // gaining activation.
  DeleteOnActivationChangeObserver(aura::Window* window,
                                   bool delete_on_activating,
                                   bool delete_window_losing_active)
      : root_(window->GetRootWindow()),
        window_(window),
        delete_on_activating_(delete_on_activating),
        delete_window_losing_active_(delete_window_losing_active),
        did_delete_(false) {
    GetActivationClient(root_)->AddObserver(this);
  }

  DeleteOnActivationChangeObserver(const DeleteOnActivationChangeObserver&) =
      delete;
  DeleteOnActivationChangeObserver& operator=(
      const DeleteOnActivationChangeObserver&) = delete;

  ~DeleteOnActivationChangeObserver() override {
    GetActivationClient(root_)->RemoveObserver(this);
  }

  // Overridden from ActivationChangeObserver:
  void OnWindowActivating(ActivationReason reason,
                          aura::Window* gaining_active,
                          aura::Window* losing_active) override {
    if (!delete_on_activating_)
      return;

    auto* window_to_delete =
        delete_window_losing_active_ ? losing_active : gaining_active;
    if (window_ && window_to_delete == window_) {
      delete window_to_delete;
      did_delete_ = true;
    }
  }

  void OnWindowActivated(ActivationReason reason,
                         aura::Window* gained_active,
                         aura::Window* lost_active) override {
    if (delete_on_activating_)
      return;

    auto* window_to_delete =
        delete_window_losing_active_ ? lost_active : gained_active;
    if (window_ && window_to_delete == window_) {
      delete window_to_delete;
      did_delete_ = true;
    }
  }

  // Overridden from WindowDeleter:
  aura::Window* GetDeletedWindow() override {
    return did_delete_ ? window_.get() : nullptr;
  }

 private:
  raw_ptr<aura::Window> root_;
  // TODO(crbug.com/1298696): Breaks wm_unittests.
  raw_ptr<aura::Window, DegradeToNoOpWhenMTE> window_;
  const bool delete_on_activating_;
  const bool delete_window_losing_active_;
  bool did_delete_;
};

// FocusChangeObserver that deletes the window losing focus.
class DeleteOnLoseFocusChangeObserver
    : public aura::client::FocusChangeObserver,
      public WindowDeleter {
 public:
  explicit DeleteOnLoseFocusChangeObserver(aura::Window* window)
      : root_(window->GetRootWindow()), window_(window), did_delete_(false) {
    aura::client::GetFocusClient(root_)->AddObserver(this);
  }

  DeleteOnLoseFocusChangeObserver(const DeleteOnLoseFocusChangeObserver&) =
      delete;
  DeleteOnLoseFocusChangeObserver& operator=(
      const DeleteOnLoseFocusChangeObserver&) = delete;

  ~DeleteOnLoseFocusChangeObserver() override {
    aura::client::GetFocusClient(root_)->RemoveObserver(this);
  }

  // Overridden from aura::client::FocusChangeObserver:
  void OnWindowFocused(aura::Window* gained_focus,
                       aura::Window* lost_focus) override {
    if (window_ && lost_focus == window_) {
      delete lost_focus;
      did_delete_ = true;
    }
  }

  // Overridden from WindowDeleter:
  aura::Window* GetDeletedWindow() override {
    return did_delete_ ? window_.get() : nullptr;
  }

 private:
  raw_ptr<aura::Window> root_;
  // TODO(crbug.com/1298696): Breaks wm_unittests.
  raw_ptr<aura::Window, DegradeToNoOpWhenMTE> window_;
  bool did_delete_;
};

class ScopedFocusNotificationObserver : public FocusNotificationObserver {
 public:
  ScopedFocusNotificationObserver(aura::Window* root_window)
      : root_window_(root_window) {
    GetActivationClient(root_window_)->AddObserver(this);
    aura::client::GetFocusClient(root_window_)->AddObserver(this);
  }

  ScopedFocusNotificationObserver(const ScopedFocusNotificationObserver&) =
      delete;
  ScopedFocusNotificationObserver& operator=(
      const ScopedFocusNotificationObserver&) = delete;

  ~ScopedFocusNotificationObserver() override {
    GetActivationClient(root_window_)->RemoveObserver(this);
    aura::client::GetFocusClient(root_window_)->RemoveObserver(this);
  }

 private:
  raw_ptr<aura::Window> root_window_;
};

class ScopedTargetFocusNotificationObserver : public FocusNotificationObserver {
 public:
  ScopedTargetFocusNotificationObserver(aura::Window* root_window, int id)
      : target_(root_window->GetChildById(id)) {
    SetActivationChangeObserver(target_, this);
    aura::client::SetFocusChangeObserver(target_, this);
    tracker_.Add(target_);
  }

  ScopedTargetFocusNotificationObserver(
      const ScopedTargetFocusNotificationObserver&) = delete;
  ScopedTargetFocusNotificationObserver& operator=(
      const ScopedTargetFocusNotificationObserver&) = delete;

  ~ScopedTargetFocusNotificationObserver() override {
    if (tracker_.Contains(target_)) {
      SetActivationChangeObserver(target_, nullptr);
      aura::client::SetFocusChangeObserver(target_, nullptr);
    }
  }

 private:
  // TODO(crbug.com/1298696): Breaks wm_unittests.
  raw_ptr<aura::Window, DegradeToNoOpWhenMTE> target_;
  aura::WindowTracker tracker_;
};

// Used to fake the handling of events in the pre-target phase.
class SimpleEventHandler : public ui::EventHandler {
 public:
  SimpleEventHandler() {}

  SimpleEventHandler(const SimpleEventHandler&) = delete;
  SimpleEventHandler& operator=(const SimpleEventHandler&) = delete;

  ~SimpleEventHandler() override {}

  // Overridden from ui::EventHandler:
  void OnMouseEvent(ui::MouseEvent* event) override { event->SetHandled(); }
  void OnGestureEvent(ui::GestureEvent* event) override { event->SetHandled(); }
};

class FocusShiftingActivationObserver : public ActivationChangeObserver {
 public:
  explicit FocusShiftingActivationObserver(aura::Window* activated_window)
      : activated_window_(activated_window), shift_focus_to_(nullptr) {}

  FocusShiftingActivationObserver(const FocusShiftingActivationObserver&) =
      delete;
  FocusShiftingActivationObserver& operator=(
      const FocusShiftingActivationObserver&) = delete;

  ~FocusShiftingActivationObserver() override {}

  void set_shift_focus_to(aura::Window* shift_focus_to) {
    shift_focus_to_ = shift_focus_to;
  }

 private:
  // Overridden from ActivationChangeObserver:
  void OnWindowActivated(ActivationReason reason,
                         aura::Window* gained_active,
                         aura::Window* lost_active) override {
    // Shift focus to a child. This should prevent the default focusing from
    // occurring in FocusController::FocusWindow().
    if (gained_active == activated_window_) {
      aura::client::FocusClient* client =
          aura::client::GetFocusClient(gained_active);
      client->FocusWindow(shift_focus_to_);
    }
  }

  raw_ptr<aura::Window> activated_window_;
  raw_ptr<aura::Window> shift_focus_to_;
};

class ActivateWhileActivatingObserver : public ActivationChangeObserver {
 public:
  ActivateWhileActivatingObserver(aura::Window* to_observe,
                                  aura::Window* to_activate,
                                  aura::Window* to_focus)
      : to_observe_(to_observe),
        to_activate_(to_activate),
        to_focus_(to_focus) {
    GetActivationClient(to_observe_->GetRootWindow())->AddObserver(this);
  }

  ActivateWhileActivatingObserver(const ActivateWhileActivatingObserver&) =
      delete;
  ActivateWhileActivatingObserver& operator=(
      const ActivateWhileActivatingObserver&) = delete;

  ~ActivateWhileActivatingObserver() override {
    GetActivationClient(to_observe_->GetRootWindow())->RemoveObserver(this);
  }

 private:
  // Overridden from ActivationChangeObserver:
  void OnWindowActivating(ActivationReason reason,
                          aura::Window* gaining_active,
                          aura::Window* losing_active) override {
    if (gaining_active != to_observe_)
      return;

    if (to_activate_)
      ActivateWindow(to_activate_);
    if (to_focus_)
      FocusWindow(to_focus_);
  }
  void OnWindowActivated(ActivationReason reason,
                         aura::Window* gained_active,
                         aura::Window* lost_active) override {}

  void ActivateWindow(aura::Window* window) {
    GetActivationClient(to_observe_->GetRootWindow())->ActivateWindow(window);
  }

  void FocusWindow(aura::Window* window) {
    aura::client::GetFocusClient(to_observe_->GetRootWindow())
        ->FocusWindow(window);
  }

  raw_ptr<aura::Window> to_observe_;
  raw_ptr<aura::Window> to_activate_;
  raw_ptr<aura::Window> to_focus_;
};

// BaseFocusRules subclass that allows basic overrides of focus/activation to
// be tested. This is intended more as a test that the override system works at
// all, rather than as an exhaustive set of use cases, those should be covered
// in tests for those FocusRules implementations.
class TestFocusRules : public BaseFocusRules {
 public:
  TestFocusRules() : focus_restriction_(nullptr) {}

  TestFocusRules(const TestFocusRules&) = delete;
  TestFocusRules& operator=(const TestFocusRules&) = delete;

  // Restricts focus and activation to this window and its child hierarchy.
  void set_focus_restriction(aura::Window* focus_restriction) {
    focus_restriction_ = focus_restriction;
  }

  // Overridden from BaseFocusRules:
  bool SupportsChildActivation(const aura::Window* window) const override {
    // In FocusControllerTests, only the RootWindow has activatable children.
    return window->GetRootWindow() == window;
  }
  bool CanActivateWindow(const aura::Window* window) const override {
    // Restricting focus to a non-activatable child window means the activatable
    // parent outside the focus restriction is activatable.
    bool can_activate =
        CanFocusOrActivate(window) || window->Contains(focus_restriction_);
    return can_activate ? BaseFocusRules::CanActivateWindow(window) : false;
  }
  bool CanFocusWindow(const aura::Window* window,
                      const ui::Event* event) const override {
    return CanFocusOrActivate(window)
               ? BaseFocusRules::CanFocusWindow(window, event)
               : false;
  }
  aura::Window* GetActivatableWindow(aura::Window* window) const override {
    return BaseFocusRules::GetActivatableWindow(
        CanFocusOrActivate(window) ? window : focus_restriction_.get());
  }
  aura::Window* GetFocusableWindow(aura::Window* window) const override {
    return BaseFocusRules::GetFocusableWindow(
        CanFocusOrActivate(window) ? window : focus_restriction_.get());
  }
  aura::Window* GetNextActivatableWindow(aura::Window* ignore) const override {
    aura::Window* next_activatable =
        BaseFocusRules::GetNextActivatableWindow(ignore);
    return CanFocusOrActivate(next_activatable)
               ? next_activatable
               : GetActivatableWindow(focus_restriction_);
  }

 private:
  bool CanFocusOrActivate(const aura::Window* window) const {
    return !focus_restriction_ || focus_restriction_->Contains(window);
  }

  raw_ptr<aura::Window> focus_restriction_;
};

// Common infrastructure shared by all FocusController test types.
class FocusControllerTestBase : public aura::test::AuraTestBase {
 public:
  FocusControllerTestBase(const FocusControllerTestBase&) = delete;
  FocusControllerTestBase& operator=(const FocusControllerTestBase&) = delete;

 protected:
  FocusControllerTestBase() {}

  // Overridden from aura::test::AuraTestBase:
  void SetUp() override {
    // FocusController registers itself as an Env observer so it can catch all
    // window initializations, including the root_window()'s, so we create it
    // before allowing the base setup.
    test_focus_rules_ = new TestFocusRules;
    focus_controller_ = std::make_unique<FocusController>(test_focus_rules_);
    aura::test::AuraTestBase::SetUp();
    root_window()->AddPreTargetHandler(focus_controller_.get());
    aura::client::SetFocusClient(root_window(), focus_controller_.get());
    SetActivationClient(root_window(), focus_controller_.get());

    // Hierarchy used by all tests:
    // root_window
    //       +-- w1
    //       |    +-- w11
    //       |    +-- w12
    //       +-- w2
    //       |    +-- w21
    //       |         +-- w211
    //       +-- w3
    aura::Window* w1 = aura::test::CreateTestWindowWithDelegate(
        aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 1,
        gfx::Rect(0, 0, 50, 50), root_window());
    aura::test::CreateTestWindowWithDelegate(
        aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 11,
        gfx::Rect(5, 5, 10, 10), w1);
    aura::test::CreateTestWindowWithDelegate(
        aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 12,
        gfx::Rect(15, 15, 10, 10), w1);
    aura::Window* w2 = aura::test::CreateTestWindowWithDelegate(
        aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 2,
        gfx::Rect(75, 75, 50, 50), root_window());
    aura::Window* w21 = aura::test::CreateTestWindowWithDelegate(
        aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 21,
        gfx::Rect(5, 5, 10, 10), w2);
    aura::test::CreateTestWindowWithDelegate(
        aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 211,
        gfx::Rect(1, 1, 5, 5), w21);
    aura::test::CreateTestWindowWithDelegate(
        aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 3,
        gfx::Rect(125, 125, 50, 50), root_window());
  }
  void TearDown() override {
    root_window()->RemovePreTargetHandler(focus_controller_.get());
    aura::test::AuraTestBase::TearDown();
    test_focus_rules_ = nullptr;  // Owned by FocusController.
    focus_controller_.reset();
  }

  void FocusWindow(aura::Window* window) {
    aura::client::GetFocusClient(root_window())->FocusWindow(window);
  }
  aura::Window* GetFocusedWindow() {
    return aura::client::GetFocusClient(root_window())->GetFocusedWindow();
  }
  int GetFocusedWindowId() {
    aura::Window* focused_window = GetFocusedWindow();
    return focused_window ? focused_window->GetId() : -1;
  }
  void ActivateWindow(aura::Window* window) {
    GetActivationClient(root_window())->ActivateWindow(window);
  }
  void DeactivateWindow(aura::Window* window) {
    GetActivationClient(root_window())->DeactivateWindow(window);
  }
  aura::Window* GetActiveWindow() {
    return GetActivationClient(root_window())->GetActiveWindow();
  }
  int GetActiveWindowId() {
    aura::Window* active_window = GetActiveWindow();
    return active_window ? active_window->GetId() : -1;
  }

  TestFocusRules* test_focus_rules() { return test_focus_rules_; }

  // Test functions.
  virtual void BasicFocus() = 0;
  virtual void BasicActivation() = 0;
  virtual void FocusEvents() = 0;
  virtual void DuplicateFocusEvents() {}
  virtual void ActivationEvents() = 0;
  virtual void ReactivationEvents() {}
  virtual void DuplicateActivationEvents() {}
  virtual void ShiftFocusWithinActiveWindow() {}
  virtual void ShiftFocusToChildOfInactiveWindow() {}
  virtual void ShiftFocusToParentOfFocusedWindow() {}
  virtual void FocusRulesOverride() = 0;
  virtual void ActivationRulesOverride() = 0;
  virtual void ShiftFocusOnActivation() {}
  virtual void ShiftFocusOnActivationDueToHide() {}
  virtual void NoShiftActiveOnActivation() {}
  virtual void FocusChangeDuringDrag() {}
  virtual void ChangeFocusWhenNothingFocusedAndCaptured() {}
  virtual void DontPassDeletedWindow() {}
  virtual void StackWindowAtTopOnActivation() {}
  virtual void HideFocusedWindowDuringActivationLoss() {}
  virtual void ActivateWhileActivating() {}

 private:
  std::unique_ptr<FocusController> focus_controller_;
  raw_ptr<TestFocusRules> test_focus_rules_;
};

// Test base for tests where focus is directly set to a target window.
class FocusControllerDirectTestBase : public FocusControllerTestBase {
 public:
  FocusControllerDirectTestBase(const FocusControllerDirectTestBase&) = delete;
  FocusControllerDirectTestBase& operator=(
      const FocusControllerDirectTestBase&) = delete;

 protected:
  FocusControllerDirectTestBase() {}

  // Different test types shift focus in different ways.
  virtual void FocusWindowDirect(aura::Window* window) = 0;
  virtual void ActivateWindowDirect(aura::Window* window) = 0;
  virtual void DeactivateWindowDirect(aura::Window* window) = 0;

  // Input events do not change focus if the window can not be focused.
  virtual bool IsInputEvent() = 0;

  // Returns the expected ActivationReason caused by calling the
  // ActivatedWindowDirect(...) or DeactivateWindowDirect(...) methods.
  virtual ActivationChangeObserver::ActivationReason
  GetExpectedActivationReason() const = 0;

  void FocusWindowById(int id) {
    aura::Window* window = root_window()->GetChildById(id);
    DCHECK(window);
    FocusWindowDirect(window);
  }
  void ActivateWindowById(int id) {
    aura::Window* window = root_window()->GetChildById(id);
    DCHECK(window);
    ActivateWindowDirect(window);
  }

  void DeactivateWindowById(int id) {
    aura::Window* window = root_window()->GetChildById(id);
    EXPECT_TRUE(window);
    GetActivationClient(root_window())->DeactivateWindow(window);
  }

  // Overridden from FocusControllerTestBase:
  void BasicFocus() override {
    EXPECT_FALSE(GetFocusedWindow());
    FocusWindowById(1);
    EXPECT_EQ(1, GetFocusedWindowId());
    FocusWindowById(2);
    EXPECT_EQ(2, GetFocusedWindowId());
  }
  void BasicActivation() override {
    EXPECT_FALSE(GetActiveWindow());
    ActivateWindowById(1);
    EXPECT_EQ(1, GetActiveWindowId());
    ActivateWindowById(2);
    EXPECT_EQ(2, GetActiveWindowId());
    // Create a new window without activing it. Move it to the
    // top.
    aura::Window* window3 = root_window()->GetChildById(3);
    root_window()->StackChildAtTop(window3);

    // Verify that diactivating a non-active window won't affect the current
    // active window.
    DeactivateWindowById(1);
    EXPECT_EQ(2, GetActiveWindowId());

    // Verify that attempting to deactivate NULL does not crash and does not
    // change activation.
    DeactivateWindow(nullptr);
    EXPECT_EQ(2, GetActiveWindowId());
    DeactivateWindow(GetActiveWindow());
    EXPECT_EQ(3, GetActiveWindowId());
  }
  void FocusEvents() override {
    ScopedFocusNotificationObserver root_observer(root_window());
    ScopedTargetFocusNotificationObserver observer1(root_window(), 1);
    ScopedTargetFocusNotificationObserver observer2(root_window(), 2);

    root_observer.ExpectCounts(0, 0);
    observer1.ExpectCounts(0, 0);
    observer2.ExpectCounts(0, 0);

    FocusWindowById(1);
    root_observer.ExpectCounts(1, 1);
    observer1.ExpectCounts(1, 1);
    observer2.ExpectCounts(0, 0);

    FocusWindowById(2);
    root_observer.ExpectCounts(2, 2);
    observer1.ExpectCounts(2, 2);
    observer2.ExpectCounts(1, 1);
  }
  void DuplicateFocusEvents() override {
    // Focusing an existing focused window should not resend focus events.
    ScopedFocusNotificationObserver root_observer(root_window());
    ScopedTargetFocusNotificationObserver observer1(root_window(), 1);

    root_observer.ExpectCounts(0, 0);
    observer1.ExpectCounts(0, 0);

    FocusWindowById(1);
    root_observer.ExpectCounts(1, 1);
    observer1.ExpectCounts(1, 1);

    FocusWindowById(1);
    root_observer.ExpectCounts(1, 1);
    observer1.ExpectCounts(1, 1);
  }
  void ActivationEvents() override {
    ActivateWindowById(1);

    ScopedFocusNotificationObserver root_observer(root_window());
    ScopedTargetFocusNotificationObserver observer1(root_window(), 1);
    ScopedTargetFocusNotificationObserver observer2(root_window(), 2);

    root_observer.ExpectCounts(0, 0);
    observer1.ExpectCounts(0, 0);
    observer2.ExpectCounts(0, 0);

    ActivateWindowById(2);
    root_observer.ExpectCounts(1, 1);
    EXPECT_EQ(GetExpectedActivationReason(),
              root_observer.last_activation_reason());
    observer1.ExpectCounts(1, 1);
    observer2.ExpectCounts(1, 1);
  }
  void ReactivationEvents() override {
    ActivateWindowById(1);
    ScopedFocusNotificationObserver root_observer(root_window());
    EXPECT_EQ(0, root_observer.reactivation_count());
    root_window()->GetChildById(2)->Hide();
    // When we attempt to activate "2", which cannot be activated because it
    // is not visible, "1" will be reactivated.
    ActivateWindowById(2);
    EXPECT_EQ(1, root_observer.reactivation_count());
    EXPECT_EQ(root_window()->GetChildById(2),
              root_observer.reactivation_requested_window());
    EXPECT_EQ(root_window()->GetChildById(1),
              root_observer.reactivation_actual_window());
  }
  void DuplicateActivationEvents() override {
    // Activating an existing active window should not resend activation events.
    ActivateWindowById(1);

    ScopedFocusNotificationObserver root_observer(root_window());
    ScopedTargetFocusNotificationObserver observer1(root_window(), 1);
    ScopedTargetFocusNotificationObserver observer2(root_window(), 2);

    root_observer.ExpectCounts(0, 0);
    observer1.ExpectCounts(0, 0);
    observer2.ExpectCounts(0, 0);

    ActivateWindowById(2);
    root_observer.ExpectCounts(1, 1);
    observer1.ExpectCounts(1, 1);
    observer2.ExpectCounts(1, 1);

    ActivateWindowById(2);
    root_observer.ExpectCounts(1, 1);
    observer1.ExpectCounts(1, 1);
    observer2.ExpectCounts(1, 1);
  }
  void ShiftFocusWithinActiveWindow() override {
    ActivateWindowById(1);
    EXPECT_EQ(1, GetActiveWindowId());
    EXPECT_EQ(1, GetFocusedWindowId());
    FocusWindowById(11);
    EXPECT_EQ(11, GetFocusedWindowId());
    FocusWindowById(12);
    EXPECT_EQ(12, GetFocusedWindowId());
  }
  void ShiftFocusToChildOfInactiveWindow() override {
    ActivateWindowById(2);
    EXPECT_EQ(2, GetActiveWindowId());
    EXPECT_EQ(2, GetFocusedWindowId());
    FocusWindowById(11);
    EXPECT_EQ(1, GetActiveWindowId());
    EXPECT_EQ(11, GetFocusedWindowId());
  }
  void ShiftFocusToParentOfFocusedWindow() override {
    ActivateWindowById(1);
    EXPECT_EQ(1, GetFocusedWindowId());
    FocusWindowById(11);
    EXPECT_EQ(11, GetFocusedWindowId());
    FocusWindowById(1);
    // Focus should _not_ shift to the parent of the already-focused window.
    EXPECT_EQ(11, GetFocusedWindowId());
  }
  void FocusRulesOverride() override {
    EXPECT_FALSE(GetFocusedWindow());
    FocusWindowById(11);
    EXPECT_EQ(11, GetFocusedWindowId());

    test_focus_rules()->set_focus_restriction(root_window()->GetChildById(211));
    FocusWindowById(12);
    // Input events leave focus unchanged; direct API calls will change focus
    // to the restricted window.
    int focused_window = IsInputEvent() ? 11 : 211;
    EXPECT_EQ(focused_window, GetFocusedWindowId());

    test_focus_rules()->set_focus_restriction(nullptr);
    FocusWindowById(12);
    EXPECT_EQ(12, GetFocusedWindowId());
  }
  void ActivationRulesOverride() override {
    ActivateWindowById(1);
    EXPECT_EQ(1, GetActiveWindowId());
    EXPECT_EQ(1, GetFocusedWindowId());

    aura::Window* w3 = root_window()->GetChildById(3);
    test_focus_rules()->set_focus_restriction(w3);

    ActivateWindowById(2);
    // Input events leave activation unchanged; direct API calls will activate
    // the restricted window.
    int active_window = IsInputEvent() ? 1 : 3;
    EXPECT_EQ(active_window, GetActiveWindowId());
    EXPECT_EQ(active_window, GetFocusedWindowId());

    test_focus_rules()->set_focus_restriction(nullptr);
    ActivateWindowById(2);
    EXPECT_EQ(2, GetActiveWindowId());
    EXPECT_EQ(2, GetFocusedWindowId());
  }
  void ShiftFocusOnActivation() override {
    // When a window is activated, by default that window is also focused.
    // An ActivationChangeObserver may shift focus to another window within the
    // same activatable window.
    ActivateWindowById(2);
    EXPECT_EQ(2, GetFocusedWindowId());
    ActivateWindowById(1);
    EXPECT_EQ(1, GetFocusedWindowId());

    ActivateWindowById(2);

    aura::Window* target = root_window()->GetChildById(1);
    ActivationClient* client = GetActivationClient(root_window());

    std::unique_ptr<FocusShiftingActivationObserver> observer(
        new FocusShiftingActivationObserver(target));
    observer->set_shift_focus_to(target->GetChildById(11));
    client->AddObserver(observer.get());

    ActivateWindowById(1);

    // w1's ActivationChangeObserver shifted focus to this child, pre-empting
    // FocusController's default setting.
    EXPECT_EQ(11, GetFocusedWindowId());

    ActivateWindowById(2);
    EXPECT_EQ(2, GetFocusedWindowId());

    // Simulate a focus reset by the ActivationChangeObserver. This should
    // trigger the default setting in FocusController.
    observer->set_shift_focus_to(nullptr);
    ActivateWindowById(1);
    EXPECT_EQ(1, GetFocusedWindowId());

    client->RemoveObserver(observer.get());

    ActivateWindowById(2);
    EXPECT_EQ(2, GetFocusedWindowId());
    ActivateWindowById(1);
    EXPECT_EQ(1, GetFocusedWindowId());
  }
  void ShiftFocusOnActivationDueToHide() override {
    // Similar to ShiftFocusOnActivation except the activation change is
    // triggered by hiding the active window.
    ActivateWindowById(1);
    EXPECT_EQ(1, GetFocusedWindowId());

    // Removes window 3 as candidate for next activatable window.
    root_window()->GetChildById(3)->Hide();
    EXPECT_EQ(1, GetFocusedWindowId());

    aura::Window* target = root_window()->GetChildById(2);
    ActivationClient* client = GetActivationClient(root_window());

    std::unique_ptr<FocusShiftingActivationObserver> observer(
        new FocusShiftingActivationObserver(target));
    observer->set_shift_focus_to(target->GetChildById(21));
    client->AddObserver(observer.get());

    // Hide the active window.
    root_window()->GetChildById(1)->Hide();

    EXPECT_EQ(21, GetFocusedWindowId());

    client->RemoveObserver(observer.get());
  }
  void NoShiftActiveOnActivation() override {
    // When a window is activated, we need to prevent any change to activation
    // from being made in response to an activation change notification.
  }

  void FocusChangeDuringDrag() override {
    std::unique_ptr<aura::client::DefaultCaptureClient> capture_client(
        new aura::client::DefaultCaptureClient(root_window()));
    // Activating an inactive window during drag should activate the window.
    // This emulates the behavior of tab dragging which is merged into the
    // window below.
    ActivateWindowById(1);

    EXPECT_EQ(1, GetActiveWindowId());
    EXPECT_EQ(1, GetFocusedWindowId());

    aura::Window* w2 = root_window()->GetChildById(2);
    ui::test::EventGenerator generator(root_window(), w2);
    generator.PressLeftButton();
    aura::client::GetCaptureClient(root_window())->SetCapture(w2);
    EXPECT_EQ(2, GetActiveWindowId());
    EXPECT_EQ(2, GetFocusedWindowId());
    generator.MoveMouseTo(gfx::Point(0, 0));

    // Emulate the behavior of merging a tab into an inactive window:
    // transferring the mouse capture and activate the window.
    aura::Window* w1 = root_window()->GetChildById(1);
    aura::client::GetCaptureClient(root_window())->SetCapture(w1);
    GetActivationClient(root_window())->ActivateWindow(w1);
    EXPECT_EQ(1, GetActiveWindowId());
    EXPECT_EQ(1, GetFocusedWindowId());

    generator.ReleaseLeftButton();
    aura::client::GetCaptureClient(root_window())->ReleaseCapture(w1);
  }

  // Verifies focus change is honored while capture held.
  void ChangeFocusWhenNothingFocusedAndCaptured() override {
    std::unique_ptr<aura::client::DefaultCaptureClient> capture_client(
        new aura::client::DefaultCaptureClient(root_window()));
    aura::Window* w1 = root_window()->GetChildById(1);
    aura::client::GetCaptureClient(root_window())->SetCapture(w1);

    EXPECT_EQ(-1, GetActiveWindowId());
    EXPECT_EQ(-1, GetFocusedWindowId());

    FocusWindowById(1);

    EXPECT_EQ(1, GetActiveWindowId());
    EXPECT_EQ(1, GetFocusedWindowId());

    aura::client::GetCaptureClient(root_window())->ReleaseCapture(w1);
  }

  // Verifies if a window that loses activation or focus is deleted during
  // observer notification we don't pass the deleted window to other observers.
  void DontPassDeletedWindow() override {
    FocusWindowById(1);

    EXPECT_EQ(1, GetActiveWindowId());
    EXPECT_EQ(1, GetFocusedWindowId());

    {
      aura::Window* to_delete = root_window()->GetChildById(1);
      DeleteOnActivationChangeObserver observer1(
          to_delete,
          /*delete_on_activating=*/true,
          /*delete_window_losing_active=*/true);
      RecordingActivationAndFocusChangeObserver observer2(root_window(),
                                                          &observer1);

      FocusWindowById(2);

      EXPECT_EQ(2, GetActiveWindowId());
      EXPECT_EQ(2, GetFocusedWindowId());

      EXPECT_EQ(to_delete, observer1.GetDeletedWindow());
      EXPECT_FALSE(observer2.was_notified_with_deleted_window());
    }

    {
      aura::Window* to_delete = root_window()->GetChildById(2);
      DeleteOnActivationChangeObserver observer1(
          to_delete, /*delete_on_activating=*/false,
          /*delete_window_losing_active=*/true);
      RecordingActivationAndFocusChangeObserver observer2(root_window(),
                                                          &observer1);

      FocusWindowById(3);

      EXPECT_EQ(3, GetActiveWindowId());
      EXPECT_EQ(3, GetFocusedWindowId());

      EXPECT_EQ(to_delete, observer1.GetDeletedWindow());
      EXPECT_FALSE(observer2.was_notified_with_deleted_window());
    }

    {
      aura::test::CreateTestWindowWithDelegate(
          aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 4,
          gfx::Rect(125, 125, 50, 50), root_window());

      EXPECT_EQ(3, GetActiveWindowId());
      EXPECT_EQ(3, GetFocusedWindowId());

      aura::Window* to_delete = root_window()->GetChildById(3);
      DeleteOnLoseFocusChangeObserver observer1(to_delete);
      RecordingActivationAndFocusChangeObserver observer2(root_window(),
                                                          &observer1);

      FocusWindowById(4);

      EXPECT_EQ(4, GetActiveWindowId());
      EXPECT_EQ(4, GetFocusedWindowId());

      EXPECT_EQ(to_delete, observer1.GetDeletedWindow());
      EXPECT_FALSE(observer2.was_notified_with_deleted_window());
    }

    {
      aura::test::CreateTestWindowWithDelegate(
          aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 5,
          gfx::Rect(125, 125, 50, 50), root_window());
      aura::test::CreateTestWindowWithDelegate(
          aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 6,
          gfx::Rect(125, 125, 50, 50), root_window());

      EXPECT_EQ(4, GetActiveWindowId());
      EXPECT_EQ(4, GetFocusedWindowId());

      // Delete the window that is gaining activation at both the "activating"
      // and "activated" phases. Make sure the activations were interrupted
      // properly and the correct next activatable window is activated.
      aura::Window* to_delete1 = root_window()->GetChildById(5);
      DeleteOnActivationChangeObserver observer1(
          to_delete1, /*delete_on_activating=*/false,
          /*delete_window_losing_active=*/false);
      RecordingActivationAndFocusChangeObserver observer2(root_window(),
                                                          &observer1);
      // Test a recursive scenario by having another observer that would delete
      // the next activatable window during the "activating" phase.
      aura::Window* to_delete2 = root_window()->GetChildById(6);
      DeleteOnActivationChangeObserver observer3(
          to_delete2, /*delete_on_activating=*/true,
          /*delete_window_losing_active=*/false);
      RecordingActivationAndFocusChangeObserver observer4(root_window(),
                                                          &observer3);

      FocusWindowById(5);

      EXPECT_EQ(4, GetActiveWindowId());
      EXPECT_EQ(4, GetFocusedWindowId());

      EXPECT_EQ(to_delete1, observer1.GetDeletedWindow());
      EXPECT_FALSE(observer2.was_notified_with_deleted_window());
      EXPECT_EQ(to_delete2, observer3.GetDeletedWindow());
      EXPECT_FALSE(observer4.was_notified_with_deleted_window());
    }
  }

  // Test that the activation of the current active window will bring the window
  // to the top of the window stack.
  void StackWindowAtTopOnActivation() override {
    // Create a window, show it and then activate it.
    std::unique_ptr<aura::Window> window1 =
        std::make_unique<aura::Window>(nullptr);
    window1->SetType(aura::client::WINDOW_TYPE_NORMAL);
    window1->Init(ui::LAYER_TEXTURED);
    root_window()->AddChild(window1.get());
    window1->Show();
    ActivateWindow(window1.get());
    EXPECT_EQ(window1.get(), root_window()->children().back());
    EXPECT_EQ(window1.get(), GetActiveWindow());

    // Create another window, show it but don't activate it. The window is not
    // the active window but is placed on top of window stack.
    std::unique_ptr<aura::Window> window2 =
        std::make_unique<aura::Window>(nullptr);
    window2->SetType(aura::client::WINDOW_TYPE_NORMAL);
    window2->Init(ui::LAYER_TEXTURED);
    root_window()->AddChild(window2.get());
    window2->Show();
    EXPECT_EQ(window2.get(), root_window()->children().back());
    EXPECT_EQ(window1.get(), GetActiveWindow());

    // Try to reactivate the active window. It should bring the active window
    // to the top of the window stack.
    ActivateWindow(window1.get());
    EXPECT_EQ(window1.get(), root_window()->children().back());
    EXPECT_EQ(window1.get(), GetActiveWindow());
  }

  // Verifies focus isn't left when during notification of an activation change
  // the focused window is hidden.
  void HideFocusedWindowDuringActivationLoss() override {
    aura::Window* w11 = root_window()->GetChildById(11);
    FocusWindow(w11);
    EXPECT_EQ(11, GetFocusedWindowId());
    EXPECT_EQ(1, GetActiveWindowId());
    {
      HideOnLoseActivationChangeObserver observer(w11);
      ActivateWindowById(2);
      EXPECT_EQ(nullptr, observer.window_to_hide());
      EXPECT_EQ(2, GetActiveWindowId());
      EXPECT_EQ(2, GetFocusedWindowId());
    }
  }

  // Tests that activating a window while a window is being activated is a
  // no-op.
  void ActivateWhileActivating() override {
    aura::Window* w1 = root_window()->GetChildById(1);
    aura::Window* w2 = root_window()->GetChildById(2);

    ActivateWindowById(3);
    // Activate a window while it is being activated does not DCHECK and the
    // window is made active.
    {
      ActivateWhileActivatingObserver observer(/*to_observe=*/w1,
                                               /*to_activate=*/w1,
                                               /*to_focus=*/nullptr);
      ActivateWindow(w1);
      EXPECT_EQ(1, GetActiveWindowId());
    }

    ActivateWindowById(3);
    // Focus a window while it is being activated does not DCHECK and the
    // window is made active and focused.
    {
      ActivateWhileActivatingObserver observer(/*to_observe=*/w1,
                                               /*to_activate=*/nullptr,
                                               /*to_focus=*/w1);
      ActivateWindow(w1);
      EXPECT_EQ(1, GetActiveWindowId());
      EXPECT_EQ(1, GetFocusedWindowId());
    }

    ActivateWindowById(3);
    // Shift focus while activating a window is allowed as long as it does
    // not attempt to activate a different window.
    {
      aura::Window* w11 = root_window()->GetChildById(11);
      aura::Window* w12 = root_window()->GetChildById(12);
      ActivateWhileActivatingObserver observer(/*to_observe=*/w1,
                                               /*to_activate=*/nullptr,
                                               /*to_focus=*/w12);
      FocusWindow(w11);
      EXPECT_EQ(1, GetActiveWindowId());
      EXPECT_EQ(12, GetFocusedWindowId());
    }

    ActivateWindowById(3);
    // Activate a different window while activating one fails. The window being
    // activated in the 1st activation request will be activated.
    {
      ActivateWhileActivatingObserver observer(/*to_observe=*/w2,
                                               /*to_activate=*/w1,
                                               /*to_focus=*/nullptr);
      // This should hit a DCHECK.
      EXPECT_DCHECK(
          {
            ActivateWindow(w2);
            EXPECT_EQ(2, GetActiveWindowId());
          },
          "");
    }
  }
};

// Focus and Activation changes via ActivationClient API.
class FocusControllerApiTest : public FocusControllerDirectTestBase {
 public:
  FocusControllerApiTest() {}

  FocusControllerApiTest(const FocusControllerApiTest&) = delete;
  FocusControllerApiTest& operator=(const FocusControllerApiTest&) = delete;

 private:
  // Overridden from FocusControllerTestBase:
  void FocusWindowDirect(aura::Window* window) override { FocusWindow(window); }
  void ActivateWindowDirect(aura::Window* window) override {
    ActivateWindow(window);
  }
  void DeactivateWindowDirect(aura::Window* window) override {
    DeactivateWindow(window);
  }
  bool IsInputEvent() override { return false; }
  // Overridden from FocusControllerDirectTestBase:
  ActivationChangeObserver::ActivationReason GetExpectedActivationReason()
      const override {
    return ActivationChangeObserver::ActivationReason::ACTIVATION_CLIENT;
  }
};

// Focus and Activation changes via input events.
class FocusControllerMouseEventTest : public FocusControllerDirectTestBase {
 public:
  FocusControllerMouseEventTest() {}

  FocusControllerMouseEventTest(const FocusControllerMouseEventTest&) = delete;
  FocusControllerMouseEventTest& operator=(
      const FocusControllerMouseEventTest&) = delete;

  // Tests that a handled mouse or gesture event does not trigger a window
  // activation.
  void IgnoreHandledEvent() {
    EXPECT_FALSE(GetActiveWindow());
    aura::Window* w1 = root_window()->GetChildById(1);
    SimpleEventHandler handler;
    root_window()->AddPreTargetHandler(&handler,
                                       ui::EventTarget::Priority::kSystem);
    ui::test::EventGenerator generator(root_window(), w1);
    generator.ClickLeftButton();
    EXPECT_FALSE(GetActiveWindow());
    generator.GestureTapAt(w1->bounds().CenterPoint());
    EXPECT_FALSE(GetActiveWindow());
    root_window()->RemovePreTargetHandler(&handler);
    generator.ClickLeftButton();
    EXPECT_EQ(1, GetActiveWindowId());
  }

 private:
  // Overridden from FocusControllerTestBase:
  void FocusWindowDirect(aura::Window* window) override {
    ui::test::EventGenerator generator(root_window(), window);
    generator.ClickLeftButton();
  }
  void ActivateWindowDirect(aura::Window* window) override {
    ui::test::EventGenerator generator(root_window(), window);
    generator.ClickLeftButton();
  }
  void DeactivateWindowDirect(aura::Window* window) override {
    aura::Window* next_activatable =
        test_focus_rules()->GetNextActivatableWindow(window);
    ui::test::EventGenerator generator(root_window(), next_activatable);
    generator.ClickLeftButton();
  }
  // Overridden from FocusControllerDirectTestBase:
  bool IsInputEvent() override { return true; }
  ActivationChangeObserver::ActivationReason GetExpectedActivationReason()
      const override {
    return ActivationChangeObserver::ActivationReason::INPUT_EVENT;
  }
};

class FocusControllerMouseEnterEventTest
    : public FocusControllerMouseEventTest {
 public:
  FocusControllerMouseEnterEventTest() {
    scoped_feature_list_.InitAndEnableFeature(features::kFocusFollowsCursor);
  }

  void MouseEnteredEvent() {
    aura::Window::Windows children_before = root_window()->children();
    aura::Window* w2 = root_window()->GetChildById(2);

    ui::test::EventGenerator generator(root_window(), w2);
    generator.SendMouseEnter();

    // The enter event should activate the window, but not stack the window.
    EXPECT_EQ(w2, GetActiveWindow());
    EXPECT_EQ(children_before, root_window()->children());
  }

  void MouseEnteredWithActiveParent() {
    aura::Window* w2 = root_window()->GetChildById(2);
    aura::Window* w21 = root_window()->GetChildById(21);

    ActivateWindow(w2);

    // The enter event should not focus the window.
    ui::test::EventGenerator generator(root_window(), w21);
    generator.SendMouseEnter();

    EXPECT_EQ(w2, GetFocusedWindow());
  }

  base::test::ScopedFeatureList scoped_feature_list_;
};

class FocusControllerGestureEventTest : public FocusControllerDirectTestBase {
 public:
  FocusControllerGestureEventTest() {}

  FocusControllerGestureEventTest(const FocusControllerGestureEventTest&) =
      delete;
  FocusControllerGestureEventTest& operator=(
      const FocusControllerGestureEventTest&) = delete;

 private:
  // Overridden from FocusControllerTestBase:
  void FocusWindowDirect(aura::Window* window) override {
    ui::test::EventGenerator generator(root_window(), window);
    generator.GestureTapAt(window->bounds().CenterPoint());
  }
  void ActivateWindowDirect(aura::Window* window) override {
    ui::test::EventGenerator generator(root_window(), window);
    generator.GestureTapAt(window->bounds().CenterPoint());
  }
  void DeactivateWindowDirect(aura::Window* window) override {
    aura::Window* next_activatable =
        test_focus_rules()->GetNextActivatableWindow(window);
    ui::test::EventGenerator generator(root_window(), next_activatable);
    generator.GestureTapAt(window->bounds().CenterPoint());
  }
  bool IsInputEvent() override { return true; }
  ActivationChangeObserver::ActivationReason GetExpectedActivationReason()
      const override {
    return ActivationChangeObserver::ActivationReason::INPUT_EVENT;
  }
};

// Test base for tests where focus is implicitly set to a window as the result
// of a disposition change to the focused window or the hierarchy that contains
// it.
class FocusControllerImplicitTestBase : public FocusControllerTestBase {
 public:
  FocusControllerImplicitTestBase(const FocusControllerImplicitTestBase&) =
      delete;
  FocusControllerImplicitTestBase& operator=(
      const FocusControllerImplicitTestBase&) = delete;

 protected:
  explicit FocusControllerImplicitTestBase(bool parent) : parent_(parent) {}

  aura::Window* GetDispositionWindow(aura::Window* window) {
    return parent_ ? window->parent() : window;
  }

  // Returns the expected ActivationReason caused by calling the
  // ActivatedWindowDirect(...) or DeactivateWindowDirect(...) methods.
  ActivationChangeObserver::ActivationReason GetExpectedActivationReason()
      const {
    return ActivationChangeObserver::ActivationReason::
        WINDOW_DISPOSITION_CHANGED;
  }

  // Change the disposition of |window| in such a way as it will lose focus.
  virtual void ChangeWindowDisposition(aura::Window* window) = 0;

  // Allow each disposition change test to add additional post-disposition
  // change expectations.
  virtual void PostDispositionChangeExpectations() {}

  // Overridden from FocusControllerTestBase:
  void BasicFocus() override {
    EXPECT_FALSE(GetFocusedWindow());

    aura::Window* w211 = root_window()->GetChildById(211);
    FocusWindow(w211);
    EXPECT_EQ(211, GetFocusedWindowId());

    ChangeWindowDisposition(w211);
    // BasicFocusRules passes focus to the parent.
    EXPECT_EQ(parent_ ? 2 : 21, GetFocusedWindowId());
  }
  void BasicActivation() override {
    DCHECK(!parent_) << "Activation tests don't support parent changes.";

    EXPECT_FALSE(GetActiveWindow());

    aura::Window* w2 = root_window()->GetChildById(2);
    ActivateWindow(w2);
    EXPECT_EQ(2, GetActiveWindowId());

    ChangeWindowDisposition(w2);
    EXPECT_EQ(3, GetActiveWindowId());
    PostDispositionChangeExpectations();
  }
  void FocusEvents() override {
    aura::Window* w211 = root_window()->GetChildById(211);
    FocusWindow(w211);

    ScopedFocusNotificationObserver root_observer(root_window());
    ScopedTargetFocusNotificationObserver observer211(root_window(), 211);
    root_observer.ExpectCounts(0, 0);
    observer211.ExpectCounts(0, 0);

    ChangeWindowDisposition(w211);
    root_observer.ExpectCounts(0, 1);
    observer211.ExpectCounts(0, 1);
  }
  void ActivationEvents() override {
    DCHECK(!parent_) << "Activation tests don't support parent changes.";

    aura::Window* w2 = root_window()->GetChildById(2);
    ActivateWindow(w2);

    ScopedFocusNotificationObserver root_observer(root_window());
    ScopedTargetFocusNotificationObserver observer2(root_window(), 2);
    ScopedTargetFocusNotificationObserver observer3(root_window(), 3);
    root_observer.ExpectCounts(0, 0);
    observer2.ExpectCounts(0, 0);
    observer3.ExpectCounts(0, 0);

    ChangeWindowDisposition(w2);
    root_observer.ExpectCounts(1, 1);
    EXPECT_EQ(GetExpectedActivationReason(),
              root_observer.last_activation_reason());
    observer2.ExpectCounts(1, 1);
    observer3.ExpectCounts(1, 1);
  }
  void FocusRulesOverride() override {
    EXPECT_FALSE(GetFocusedWindow());
    aura::Window* w211 = root_window()->GetChildById(211);
    FocusWindow(w211);
    EXPECT_EQ(211, GetFocusedWindowId());

    test_focus_rules()->set_focus_restriction(root_window()->GetChildById(11));
    ChangeWindowDisposition(w211);
    // Normally, focus would shift to the parent (w21) but the override shifts
    // it to 11.
    EXPECT_EQ(11, GetFocusedWindowId());

    test_focus_rules()->set_focus_restriction(nullptr);
  }
  void ActivationRulesOverride() override {
    DCHECK(!parent_) << "Activation tests don't support parent changes.";

    aura::Window* w1 = root_window()->GetChildById(1);
    ActivateWindow(w1);

    EXPECT_EQ(1, GetActiveWindowId());
    EXPECT_EQ(1, GetFocusedWindowId());

    aura::Window* w3 = root_window()->GetChildById(3);
    test_focus_rules()->set_focus_restriction(w3);

    // Normally, activation/focus would move to w2, but since we have a focus
    // restriction, it should move to w3 instead.
    ChangeWindowDisposition(w1);
    EXPECT_EQ(3, GetActiveWindowId());
    EXPECT_EQ(3, GetFocusedWindowId());

    test_focus_rules()->set_focus_restriction(nullptr);
    ActivateWindow(root_window()->GetChildById(2));
    EXPECT_EQ(2, GetActiveWindowId());
    EXPECT_EQ(2, GetFocusedWindowId());
  }

 private:
  // When true, the disposition change occurs to the parent of the window
  // instead of to the window. This verifies that changes occurring in the
  // hierarchy that contains the window affect the window's focus.
  bool parent_;
};

// Focus and Activation changes in response to window visibility changes.
class FocusControllerHideTest : public FocusControllerImplicitTestBase {
 public:
  FocusControllerHideTest() : FocusControllerImplicitTestBase(false) {}

  FocusControllerHideTest(const FocusControllerHideTest&) = delete;
  FocusControllerHideTest& operator=(const FocusControllerHideTest&) = delete;

 protected:
  FocusControllerHideTest(bool parent)
      : FocusControllerImplicitTestBase(parent) {}

  // Overridden from FocusControllerImplicitTestBase:
  void ChangeWindowDisposition(aura::Window* window) override {
    GetDispositionWindow(window)->Hide();
  }
};

// Focus and Activation changes in response to window parent visibility
// changes.
class FocusControllerParentHideTest : public FocusControllerHideTest {
 public:
  FocusControllerParentHideTest() : FocusControllerHideTest(true) {}

  FocusControllerParentHideTest(const FocusControllerParentHideTest&) = delete;
  FocusControllerParentHideTest& operator=(
      const FocusControllerParentHideTest&) = delete;

  // The parent window's visibility change should not change its transient child
  // window's modality property.
  void TransientChildWindowActivationTest() {
    aura::Window* w1 = root_window()->GetChildById(1);
    aura::Window* w11 = root_window()->GetChildById(11);
    ::wm::AddTransientChild(w1, w11);
    w11->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW);

    EXPECT_EQ(ui::MODAL_TYPE_NONE, w1->GetProperty(aura::client::kModalKey));
    EXPECT_EQ(ui::MODAL_TYPE_WINDOW, w11->GetProperty(aura::client::kModalKey));

    // Hide the parent window w1 and show it again.
    w1->Hide();
    w1->Show();

    // Test that child window w11 doesn't change its modality property.
    EXPECT_EQ(ui::MODAL_TYPE_NONE, w1->GetProperty(aura::client::kModalKey));
    EXPECT_EQ(ui::MODAL_TYPE_WINDOW, w11->GetProperty(aura::client::kModalKey));
  }
};

// Focus and Activation changes in response to window destruction.
class FocusControllerDestructionTest : public FocusControllerImplicitTestBase {
 public:
  FocusControllerDestructionTest() : FocusControllerImplicitTestBase(false) {}

  FocusControllerDestructionTest(const FocusControllerDestructionTest&) =
      delete;
  FocusControllerDestructionTest& operator=(
      const FocusControllerDestructionTest&) = delete;

 protected:
  FocusControllerDestructionTest(bool parent)
      : FocusControllerImplicitTestBase(parent) {}

  // Overridden from FocusControllerImplicitTestBase:
  void ChangeWindowDisposition(aura::Window* window) override {
    delete GetDispositionWindow(window);
  }
};

// Focus and Activation changes in response to window parent destruction.
class FocusControllerParentDestructionTest
    : public FocusControllerDestructionTest {
 public:
  FocusControllerParentDestructionTest()
      : FocusControllerDestructionTest(true) {}

  FocusControllerParentDestructionTest(
      const FocusControllerParentDestructionTest&) = delete;
  FocusControllerParentDestructionTest& operator=(
      const FocusControllerParentDestructionTest&) = delete;
};

// Focus and Activation changes in response to window removal.
class FocusControllerRemovalTest : public FocusControllerImplicitTestBase {
 public:
  FocusControllerRemovalTest() : FocusControllerImplicitTestBase(false) {}

  FocusControllerRemovalTest(const FocusControllerRemovalTest&) = delete;
  FocusControllerRemovalTest& operator=(const FocusControllerRemovalTest&) =
      delete;

 protected:
  FocusControllerRemovalTest(bool parent)
      : FocusControllerImplicitTestBase(parent) {}

  // Overridden from FocusControllerImplicitTestBase:
  void ChangeWindowDisposition(aura::Window* window) override {
    aura::Window* disposition_window = GetDispositionWindow(window);
    disposition_window->parent()->RemoveChild(disposition_window);
    window_owner_.reset(disposition_window);
  }
  void TearDown() override {
    window_owner_.reset();
    FocusControllerImplicitTestBase::TearDown();
  }

 private:
  std::unique_ptr<aura::Window> window_owner_;
};

// Focus and Activation changes in response to window parent removal.
class FocusControllerParentRemovalTest : public FocusControllerRemovalTest {
 public:
  FocusControllerParentRemovalTest() : FocusControllerRemovalTest(true) {}

  FocusControllerParentRemovalTest(const FocusControllerParentRemovalTest&) =
      delete;
  FocusControllerParentRemovalTest& operator=(
      const FocusControllerParentRemovalTest&) = delete;
};

#define FOCUS_CONTROLLER_TEST(TESTCLASS, TESTNAME) \
  TEST_F(TESTCLASS, TESTNAME) { TESTNAME(); }

// Runs direct focus change tests (input events and API calls).
#define DIRECT_FOCUS_CHANGE_TESTS(TESTNAME)                           \
  FOCUS_CONTROLLER_TEST(FocusControllerApiTest, TESTNAME)             \
  FOCUS_CONTROLLER_TEST(FocusControllerMouseEventTest, TESTNAME)      \
  FOCUS_CONTROLLER_TEST(FocusControllerMouseEnterEventTest, TESTNAME) \
  FOCUS_CONTROLLER_TEST(FocusControllerGestureEventTest, TESTNAME)

// Runs implicit focus change tests for disposition changes to target.
#define IMPLICIT_FOCUS_CHANGE_TARGET_TESTS(TESTNAME)              \
  FOCUS_CONTROLLER_TEST(FocusControllerHideTest, TESTNAME)        \
  FOCUS_CONTROLLER_TEST(FocusControllerDestructionTest, TESTNAME) \
  FOCUS_CONTROLLER_TEST(FocusControllerRemovalTest, TESTNAME)

// Runs implicit focus change tests for disposition changes to target's parent
// hierarchy.
#define IMPLICIT_FOCUS_CHANGE_PARENT_TESTS(TESTNAME)                       \
  /* TODO(beng): parent destruction tests are not supported at             \
     present due to workspace manager issues.                              \
  FOCUS_CONTROLLER_TEST(FocusControllerParentDestructionTest, TESTNAME) */ \
  FOCUS_CONTROLLER_TEST(FocusControllerParentHideTest, TESTNAME)           \
  FOCUS_CONTROLLER_TEST(FocusControllerParentRemovalTest, TESTNAME)

// Runs all implicit focus change tests (changes to the target and target's
// parent hierarchy)
#define IMPLICIT_FOCUS_CHANGE_TESTS(TESTNAME)  \
  IMPLICIT_FOCUS_CHANGE_TARGET_TESTS(TESTNAME) \
  IMPLICIT_FOCUS_CHANGE_PARENT_TESTS(TESTNAME)

// Runs all possible focus change tests.
#define ALL_FOCUS_TESTS(TESTNAME)     \
  DIRECT_FOCUS_CHANGE_TESTS(TESTNAME) \
  IMPLICIT_FOCUS_CHANGE_TESTS(TESTNAME)

// Runs focus change tests that apply only to the target. For example,
// implicit activation changes caused by window disposition changes do not
// occur when changes to the containing hierarchy happen.
#define TARGET_FOCUS_TESTS(TESTNAME)  \
  DIRECT_FOCUS_CHANGE_TESTS(TESTNAME) \
  IMPLICIT_FOCUS_CHANGE_TARGET_TESTS(TESTNAME)

// - Focuses a window, verifies that focus changed.
ALL_FOCUS_TESTS(BasicFocus)

// - Activates a window, verifies that activation changed.
TARGET_FOCUS_TESTS(BasicActivation)

// - Focuses a window, verifies that focus events were dispatched.
ALL_FOCUS_TESTS(FocusEvents)

// - Focuses or activates a window multiple times, verifies that events are only
//   dispatched when focus/activation actually changes.
DIRECT_FOCUS_CHANGE_TESTS(DuplicateFocusEvents)
DIRECT_FOCUS_CHANGE_TESTS(DuplicateActivationEvents)

// - Activates a window, verifies that activation events were dispatched.
TARGET_FOCUS_TESTS(ActivationEvents)

// - Attempts to active a hidden window, verifies that current window is
//   attempted to be reactivated and the appropriate event dispatched.
FOCUS_CONTROLLER_TEST(FocusControllerApiTest, ReactivationEvents)

// - Input events/API calls shift focus between focusable windows within the
//   active window.
DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusWithinActiveWindow)

// - Input events/API calls to a child window of an inactive window shifts
//   activation to the activatable parent and focuses the child.
DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusToChildOfInactiveWindow)

// - Input events/API calls to focus the parent of the focused window do not
//   shift focus away from the child.
DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusToParentOfFocusedWindow)

// - Verifies that FocusRules determine what can be focused.
ALL_FOCUS_TESTS(FocusRulesOverride)

// - Verifies that FocusRules determine what can be activated.
TARGET_FOCUS_TESTS(ActivationRulesOverride)

// - Verifies that attempts to change focus or activation from a focus or
//   activation change observer are ignored.
DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusOnActivation)
DIRECT_FOCUS_CHANGE_TESTS(ShiftFocusOnActivationDueToHide)
DIRECT_FOCUS_CHANGE_TESTS(NoShiftActiveOnActivation)

FOCUS_CONTROLLER_TEST(FocusControllerApiTest, FocusChangeDuringDrag)

FOCUS_CONTROLLER_TEST(FocusControllerApiTest,
                      ChangeFocusWhenNothingFocusedAndCaptured)

// See description above DontPassDeletedWindow() for details.
FOCUS_CONTROLLER_TEST(FocusControllerApiTest, DontPassDeletedWindow)

FOCUS_CONTROLLER_TEST(FocusControllerApiTest, StackWindowAtTopOnActivation)

FOCUS_CONTROLLER_TEST(FocusControllerApiTest,
                      HideFocusedWindowDuringActivationLoss)

FOCUS_CONTROLLER_TEST(FocusControllerApiTest, ActivateWhileActivating)

// See description above TransientChildWindowActivationTest() for details.
FOCUS_CONTROLLER_TEST(FocusControllerParentHideTest,
                      TransientChildWindowActivationTest)

// If a mouse event was handled, it should not activate a window.
FOCUS_CONTROLLER_TEST(FocusControllerMouseEventTest, IgnoreHandledEvent)

// Mouse over window should activate it.
FOCUS_CONTROLLER_TEST(FocusControllerMouseEnterEventTest, MouseEnteredEvent)

// Mouse over window with active parent should not focus it.
FOCUS_CONTROLLER_TEST(FocusControllerMouseEnterEventTest,
                      MouseEnteredWithActiveParent)

}  // namespace wm


text:
/**
 * Available transfer services for a given data type.
 */
export interface TransferServices {
    dataType: string;
    exportServices: Array<string>;
    importServices: Array<string>;
}

redpajama_set_name: RedPajamaGithub


text:
"""This script applies parsed BLAST results from a CSV file (produced by
parseblast.pl) to a series of GenBank files.

Oct 26, 2009 by Simon Eng
    Changed the method of outputting statistics.
"""

try:
     import optparse, csv, re, sys
     from os import path
     import logging.handlers
     from libs.python_modules.utils.errorcodes import error_message, get_error_list, insert_error
except:
     print """ Could not load some user defined  module functions"""
     print """ Make sure your typed 'source MetaPathwaysrc'"""
     print """ """
     sys.exit(3)

errorcode= 3
def fprintf(file, fmt, *args):
    file.write(fmt % args)

def printf(fmt, *args):
    sys.stdout.write(fmt % args)

def get_translation_table(num):
   translation_table={}
   translation_table['11'] =\
        {
          'GCC' : 'A',
          'AGT' : 'S',
          'TGA' : '*',
          'TGT' : 'C',
          'CGA' : 'R',
          'ATC' : 'I',
          'AAC' : 'N',
          'AGC' : 'S',
          'TAC' : 'Y',
          'ACA' : 'T',
          'TCG' : 'S',
          'CCG' : 'P',
          'CTG' : 'L',
          'GCA' : 'A',
          'GTG' : 'V',
          'AAG' : 'K',
          'GTT' : 'V',
          'CAC' : 'H',
          'AGA' : 'R',
          'ACC' : 'T',
          'CCA' : 'P',
          'TGG' : 'W',
          'CTC' : 'L',
          'CGC' : 'R',
          'TTG' : 'L',
          'TAA' : '*',
          'CAG' : 'Q',
          'ACG' : 'T',
          'AAA' : 'K',
          'ATG' : 'M',
          'GTA' : 'V',
          'TAG' : '*',
          'CTT' : 'L',
          'GGA' : 'G',
          'GTC' : 'V',
          'TGC' : 'C',
          'TCA' : 'S',
          'ATT' : 'I',
          'TAT' : 'Y',
          'AAT' : 'N',
          'ACT' : 'T',
          'CAA' : 'Q',
          'GAC' : 'D',
          'GGT' : 'G',
          'TCC' : 'S',
          'TTT' : 'F',
          'AGG' : 'R',
          'CGT' : 'R',
          'CGG' : 'R',
          'CAT' : 'H',
          'ATA' : 'I',
          'CCC' : 'P',
          'GGG' : 'G',
          'TTA' : 'L',
          'GAG' : 'E',
          'CTA' : 'L',
          'GAT' : 'D',
          'TCT' : 'S',
          'TTC' : 'F',
          'GCG' : 'A',
          'GGC' : 'G',
          'GCT' : 'A',
          'GAA' : 'E',
          'CCT' : 'P'
        }

   return translation_table[str(num)]

def files_exist( files ):
     for file in files:
        if not path.exists(file):
           print 'Could not read File ' +  file
           print 'Please make sure these sequences are in the \"blastDB\" folder'
           sys.exit(3)
           return False
     return True

def insert_attribute(attributes, attribStr):
     rawfields = re.split('=', attribStr)
     if len(rawfields) == 2:
       attributes[rawfields[0].strip().lower()] = rawfields[1].strip()

def split_attributes(str, attributes):
     rawattributes = re.split(';', str)
     for attribStr in rawattributes:
        insert_attribute(attributes, attribStr)

     return attributes

def insert_orf_into_dict(line, contig_dict):
     rawfields = re.split('\t', line)
     fields = []
     for field in rawfields:
        fields.append(field.strip());

     if( len(fields) != 9):
       return

     attributes = {}
     attributes['seqname'] =  fields[0]   # this is a bit of a  duplication
     attributes['source'] =  fields[1]
     attributes['feature'] =  fields[2]
     attributes['start'] =  int(fields[3])
     attributes['end'] =  int(fields[4])
     attributes['orf_length'] =  attributes['end'] - attributes['start']

     try:
        attributes['score'] =  float(fields[5])
     except:
        attributes['score'] =  fields[5]

     attributes['strand'] =  fields[6]
     attributes['frame'] =  fields[7]
     split_attributes(fields[8], attributes)

     if not fields[0] in contig_dict :
       contig_dict[fields[0]] = []

     contig_dict[fields[0]].append(attributes)

def get_sequence_name(line):
     fields = re.split(' ', line)
     name = re.sub('>','',fields[0])
     #print name
     return name

note = """GFF File Format

Fields

Fields must be tab-separated. Also, all but the final field in each feature line must contain a value; "empty" columns should be denoted with a '.'

    seqname - name of the chromosome or scaffold; chromosome names can be given with or without the 'chr' prefix.
    source - name of the program that generated this feature, or the data source (database or project name)
    feature - feature type name, e.g. Gene, Variation, Similarity
    start - Start position of the feature, with sequence numbering starting at 1.
    end - End position of the feature, with sequence numbering starting at 1.
    score - A floating point value.
    strand - defined as + (forward) or - (reverse).
    frame - One of '0', '1' or '2'. '0' indicates that the first base of the feature is the first base of a codon, '1' that the second base is the first base of a codon, and so on..
    attribute - A semicolon-separated list of tag-value pairs, providing additional information about each feature.
"""

#def get_date():

def process_gff_file(gff_file_name, output_amino_file_name, output_nuc_file_name, output_gff_file_name,  nucleotide_seq_dict):
     try:
        gfffile = open(gff_file_name, 'r')
     except IOError:
        print "Cannot read file " + gff_file_name + " !"

     sample_name= re.sub('.gff', '', gff_file_name)
     gff_lines = gfffile.readlines()
     gff_beg_pattern = re.compile("^#")
     gfffile.close()

     contig_dict={}
     for line in gff_lines:
        line = line.strip()
        if gff_beg_pattern.search(line):
          continue
        insert_orf_into_dict(line, contig_dict)

     create_the_gene_IDs(contig_dict, nucleotide_seq_dict)
     create_sequnces(output_amino_file_name, output_nuc_file_name, contig_dict, nucleotide_seq_dict)
     write_gff_file(output_gff_file_name, contig_dict)

def write_gff_file(output_gff_file, contig_dict):
     outputfile = open(output_gff_file, 'w')

     for key in contig_dict:
        for elem in contig_dict[key]  :
            fprintf(outputfile,"%s",elem['seqname'])
            fprintf(outputfile,"\t%s",elem['source'])
            fprintf(outputfile,"\t%s",elem['feature'])
            fprintf(outputfile,"\t%s",elem['start'])
            fprintf(outputfile,"\t%s",elem['end'])
            fprintf(outputfile,"\t%s",elem['score'])
            fprintf(outputfile,"\t%s",elem['strand'])
            fprintf(outputfile,"\t%s",elem['frame'])

            if 'ID' in elem :
               line = 'ID=' + elem['ID']
               line = line +';' + 'locus_tag=' + elem['ID']
            else:
               line = 'ID= '

            if 'partial' in elem :
               line = line +';' + 'partial=' + elem['partial']

            if 'orf_length' in elem :
               line = line +';' + 'orf_length=' + str(elem['orf_length'])

            if 'contig_length' in elem :
               line = line +';' + 'contig_length=' + str(elem['contig_length'])

            fprintf(outputfile,"\t%s",line)
            fprintf(outputfile,"\n")

     outputfile.close()

def create_the_gene_IDs(contig_dict, nucleotide_seq_dict):
     for key in contig_dict:
        count = 0
        for elem in contig_dict[key]  :
           name = elem['seqname'] + "_%d" % (count)
           contig_dict[key][count]['ID'] = name
           contig_dict[key][count]['contig_length'] = len(nucleotide_seq_dict[key])
           count += 1

def create_sequnces(output_amino_file_name, output_nuc_file_name, contig_dict, nucleotide_seq_dict):

     translation_table = get_translation_table(11)
     #print translation_table
     #print contig_dict

     aa_outputfile = open(output_amino_file_name, 'w')
     nucl_outputfile = open(output_nuc_file_name, 'w')

     for key in contig_dict:
        for elem in contig_dict[key]  :
          nuc_orf_sequence, aa_orf_sequence=get_amino_acid_sequence(nucleotide_seq_dict, translation_table,  elem['seqname'], elem['start'], elem['end'], elem['strand'])
          name = '>' + elem['ID']
          if len(aa_orf_sequence) > 0 :
             fprintf(aa_outputfile, "%s\n", name)
             fprintf(aa_outputfile, "%s\n", aa_orf_sequence)

          if len(nuc_orf_sequence) > 0 :
             fprintf(nucl_outputfile, "%s\n", name)
             fprintf(nucl_outputfile, "%s\n", nuc_orf_sequence)

     aa_outputfile.close()
     nucl_outputfile.close()

def get_amino_acid_sequence(nucleotide_seq_dict, translation_table, seqname, start, end, strand):

    try:
       if strand=='-':
#          nuc_orf_sequence = reverse(nucleotide_seq_dict[seqname])
#          nuc_orf_sequence = nuc_orf_sequence[start-1:end-1].upper()

          nuc_orf_sequence = nucleotide_seq_dict[seqname]

          nuc_orf_sequence = nuc_orf_sequence[start-1:end].upper()
          a = len(nuc_orf_sequence)
          nuc_orf_sequence = reverse(nuc_orf_sequence)
          b = len(nuc_orf_sequence)
          nuc_orf_sequence = complement(nuc_orf_sequence)
          c = len(nuc_orf_sequence)
          #print str(a) + ' ' + str(b) + ' ' + str(c)
       else:
          nuc_orf_sequence = nucleotide_seq_dict[seqname][start-1:end-1].upper()

       aa_orf_sequence = convert_to_amino_acid(translation_table, nuc_orf_sequence, strand)
       return (nuc_orf_sequence, aa_orf_sequence)
    except:
       return ("XXXXX", "YYYYY")

def convert_to_amino_acid(translation_table, nuc_orf_sequence, strand) :
    #print nuc_orf_sequence
    letters = list(nuc_orf_sequence)
    aa_sequence =''
    codon = ''
    for i in range(len(nuc_orf_sequence)):
        codon = codon + letters[i]
        if i%3==2 :
           if (codon in translation_table)  and not (translation_table[codon]=='*') :
              aa_sequence = aa_sequence + translation_table[codon]
           codon=''

    return aa_sequence

def reverse(nuc_orf_sequence):
    letters = list(nuc_orf_sequence)
    i = len(nuc_orf_sequence)-1
    reverselist = []
    while i >= 0:
        reverselist.append(letters[i])
        i=i-1

    result_string ="".join(reverselist)
    return result_string

def complement(nuc_orf_sequence):
    letters = list(nuc_orf_sequence)
    length = len(nuc_orf_sequence)
    complementlist = []
    i = 0
    while i < length:
        if letters[i] == 'A':
           complementlist.append('T')
        elif letters[i] == 'T':
           complementlist.append('A')
        elif letters[i] == 'C':
           complementlist.append('G')
        elif letters[i] == 'G':
           complementlist.append('C')
        elif letters[i] == 'N':
           complementlist.append('N')
        else:
           complementlist.append('*')
        i=i+1

    result_string ="".join(complementlist)
    return result_string

def format_sequence_origin(dna_seq):
    output=""
    Len =  len(dna_seq)
    for i in range(0, Len):
       if i==0:
          output+= '%9d' % (i+1)
       if i%10==0:
          output+=' '
       if i!=0  and i%60==0:
          output+= '\n%9d ' % (i+1)
       output +=dna_seq[i]
       i+=1
    return output

def spaces(n):
    space=''
    for  i in  range(0, n):
      space+=' '
    return space

def wrap(prefix, start, end, string):
    output=''
    prefixLen = len(prefix)
    i = prefixLen
    output+=prefix
    while i< start:
      output += ' '
      i += 1

    for c in string:
       if i > end:
          output+='\n'
          i = start
          output+=spaces(i)
       i+=1
       output+=c

    return output

def process_sequence_file(sequence_file_name,  seq_dictionary):
     try:
        sequencefile = open(sequence_file_name, 'r')
     except IOError:
        print "Cannot read file " + sequence_file_name + " !"

     sequence_lines = sequencefile.readlines()

     sequencefile.close()
     fragments= []
     name=""

     seq_beg_pattern = re.compile(">")
     for line in sequence_lines:
        line = line.strip()
        if seq_beg_pattern.search(line):
          if len(name) > 0:
             sequence=''.join(fragments)
             seq_dictionary[name]=sequence
             fragments = []
          name=get_sequence_name(line)
        else:
          fragments.append(line)
     if len(name) > 0:
        sequence=''.join(fragments)
        seq_dictionary[name]=sequence

usage = sys.argv[0] + """ -g gff_files -n nucleotide_sequences --output-nuc output_nuc --output_amino  output_amino  --output_gff output_gff_file"""

parser = None
def createParser():
    # Parse options (many!)
    # TODO: Create option groups
    global parser

    epilog = """The GFF files produced by the gene prediction algorithm, say prodigal, in the ORF Prediction step are used to translate into the amino acid sequences and gff files that contains more detailed information such as orf_length, strand, start and end positions, contig_length, etc. In the pipeline the resulting file is in the orf_prediction folder with the extension .faa """

    epilog = re.sub(r'\s+', ' ', epilog)
    parser = optparse.OptionParser(usage = usage, epilog = epilog)
    # Input options

    input_group = optparse.OptionGroup(parser, 'input options')

    input_group.add_option('-g', '--gff', dest='gff_file',
                           metavar='GFF_FILE',
                           help='GFF files to convert to genbank format')

    input_group.add_option('-n', '--nucleotide', dest='nucleotide_sequences',
                           metavar='NUCLEOTIDE_SEQUENCE',
                           help='nucleotide sequences input file ')

    input_group.add_option('--output_amino', dest='output_amino',
                           metavar='OUTPUT', help='nmino acid output file')

    input_group.add_option('--output_nuc', dest='output_nuc',
                           metavar='OUTPUT', help='nucleotide Sequence file')

    input_group.add_option('--output_gff', dest='output_gff',
                           metavar='OUTPUT', help='output file in gff format')

    parser.add_option_group(input_group)

def main(argv, errorlogger = None, runstatslogger = None):
    # filtering options
    global parser
    options, args = parser.parse_args(argv)

    if not(options.gff_file or options.nucleotide_sequences or options.output_amino or  options.output_nuc  or options.output_gff):
       insert_error(errorcode)
       return(1,'')

    if not options.gff_file:
       parser.error('No gff files are specified')
       insert_error(errorcode)
       return(1,'')

    if not options.nucleotide_sequences:
       parser.error('Nucleotide sequences')
       insert_error(errorcode)
       return(1,'')

    if not options.output_amino:
       parser.error('Output anino acid file must be specified')
       insert_error(errorcode)
       return(1,'')

    if not options.output_nuc:
       parser.error('Output nucloetide sequences file must be specified')
       insert_error(errorcode)
       return(1,'')

    if not options.output_gff:
       parser.error('Output gff file must be specified')
       insert_error(errorcode)
       return(1,'')
    #print options

    if not path.exists(options.gff_file):
        print "gff file does not exist"
        insert_error(errorcode)
        return(1,'')

    if not path.exists(options.nucleotide_sequences):
        print "nucloetide sequences file does not exist"
        insert_error(errorcode)
        return(1,'')

    nucleotide_seq_dict = {}
    process_sequence_file( options.nucleotide_sequences, nucleotide_seq_dict)
    process_gff_file(options.gff_file, options.output_amino, options.output_nuc, options.output_gff, nucleotide_seq_dict)

    #print params['bitscore']

def MetaPathways_create_amino_sequences(argv, errorlogger = None, runstatslogger = None):
    global errorcode
    createParser()
    try:
       res = main(argv, errorlogger = errorlogger, runstatslogger = runstatslogger)
    except:
       insert_error(errorcode)
       return (1,'')

    return (res[0], res[1])

if __name__ == '__main__':
    createParser()
    main(sys.argv[1:])


text:
module ApplicationHelper
  def title(*parts)
    unless parts.empty?
      content_for :title do
        (parts << "TickTee").join(" - ")
      end
    end
  end
end


text:
package etcdserver

import (
	"bytes"
	"fmt"

	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/gogo/protobuf/proto"
	"github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
	"github.com/coreos/etcd/lease"
	dstorage "github.com/coreos/etcd/storage"
	"github.com/coreos/etcd/storage/storagepb"
)

type RaftKV interface {
	Range(ctx context.Context, r *pb.RangeRequest) (*pb.RangeResponse, error)
	Put(ctx context.Context, r *pb.PutRequest) (*pb.PutResponse, error)
	DeleteRange(ctx context.Context, r *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error)
	Txn(ctx context.Context, r *pb.TxnRequest) (*pb.TxnResponse, error)
	Compact(ctx context.Context, r *pb.CompactionRequest) (*pb.CompactionResponse, error)
}

func (s *EtcdServer) Range(ctx context.Context, r *pb.RangeRequest) (*pb.RangeResponse, error) {
	result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{Range: r})
	if err != nil {
		return nil, err
	}
	return result.resp.(*pb.RangeResponse), result.err
}

func (s *EtcdServer) Put(ctx context.Context, r *pb.PutRequest) (*pb.PutResponse, error) {
	result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{Put: r})
	if err != nil {
		return nil, err
	}
	return result.resp.(*pb.PutResponse), result.err
}

func (s *EtcdServer) DeleteRange(ctx context.Context, r *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error) {
	result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{DeleteRange: r})
	if err != nil {
		return nil, err
	}
	return result.resp.(*pb.DeleteRangeResponse), result.err
}

func (s *EtcdServer) Txn(ctx context.Context, r *pb.TxnRequest) (*pb.TxnResponse, error) {
	result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{Txn: r})
	if err != nil {
		return nil, err
	}
	return result.resp.(*pb.TxnResponse), result.err
}

func (s *EtcdServer) Compact(ctx context.Context, r *pb.CompactionRequest) (*pb.CompactionResponse, error) {
	result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{Compaction: r})
	if err != nil {
		return nil, err
	}
	return result.resp.(*pb.CompactionResponse), result.err
}

type applyResult struct {
	resp proto.Message
	err  error
}

func (s *EtcdServer) processInternalRaftRequest(ctx context.Context, r pb.InternalRaftRequest) (*applyResult, error) {
	r.ID = s.reqIDGen.Next()

	data, err := r.Marshal()
	if err != nil {
		return nil, err
	}
	ch := s.w.Register(r.ID)

	s.r.Propose(ctx, data)

	select {
	case x := <-ch:
		return x.(*applyResult), nil
	case <-ctx.Done():
		s.w.Trigger(r.ID, nil) // GC wait
		return nil, ctx.Err()
	case <-s.done:
		return nil, ErrStopped
	}
}

// Watcable returns a watchable interface attached to the etcdserver.
func (s *EtcdServer) Watchable() dstorage.Watchable {
	return s.getKV()
}

const (
	// noTxn is an invalid txn ID.
	// To apply with independent Range, Put, Delete, you can pass noTxn
	// to apply functions instead of a valid txn ID.
	noTxn = -1
)

func (s *EtcdServer) applyV3Request(r *pb.InternalRaftRequest) interface{} {
	kv := s.getKV()

	ar := &applyResult{}

	switch {
	case r.Range != nil:
		ar.resp, ar.err = applyRange(noTxn, kv, r.Range)
	case r.Put != nil:
		ar.resp, ar.err = applyPut(noTxn, kv, r.Put)
	case r.DeleteRange != nil:
		ar.resp, ar.err = applyDeleteRange(noTxn, kv, r.DeleteRange)
	case r.Txn != nil:
		ar.resp, ar.err = applyTxn(kv, r.Txn)
	case r.Compaction != nil:
		ar.resp, ar.err = applyCompaction(kv, r.Compaction)
	default:
		panic("not implemented")
	}

	return ar
}

func applyPut(txnID int64, kv dstorage.KV, p *pb.PutRequest) (*pb.PutResponse, error) {
	resp := &pb.PutResponse{}
	resp.Header = &pb.ResponseHeader{}
	var (
		rev int64
		err error
	)
	if txnID != noTxn {
		rev, err = kv.TxnPut(txnID, p.Key, p.Value, lease.LeaseID(p.Lease))
		if err != nil {
			return nil, err
		}
	} else {
		rev = kv.Put(p.Key, p.Value, lease.LeaseID(p.Lease))
	}
	resp.Header.Revision = rev
	return resp, nil
}

func applyRange(txnID int64, kv dstorage.KV, r *pb.RangeRequest) (*pb.RangeResponse, error) {
	resp := &pb.RangeResponse{}
	resp.Header = &pb.ResponseHeader{}

	var (
		kvs []storagepb.KeyValue
		rev int64
		err error
	)

	if txnID != noTxn {
		kvs, rev, err = kv.TxnRange(txnID, r.Key, r.RangeEnd, r.Limit, 0)
		if err != nil {
			return nil, err
		}
	} else {
		kvs, rev, err = kv.Range(r.Key, r.RangeEnd, r.Limit, 0)
		if err != nil {
			return nil, err
		}
	}

	resp.Header.Revision = rev
	for i := range kvs {
		resp.Kvs = append(resp.Kvs, &kvs[i])
	}
	return resp, nil
}

func applyDeleteRange(txnID int64, kv dstorage.KV, dr *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error) {
	resp := &pb.DeleteRangeResponse{}
	resp.Header = &pb.ResponseHeader{}

	var (
		rev int64
		err error
	)

	if txnID != noTxn {
		_, rev, err = kv.TxnDeleteRange(txnID, dr.Key, dr.RangeEnd)
		if err != nil {
			return nil, err
		}
	} else {
		_, rev = kv.DeleteRange(dr.Key, dr.RangeEnd)
	}

	resp.Header.Revision = rev
	return resp, nil
}

func applyTxn(kv dstorage.KV, rt *pb.TxnRequest) (*pb.TxnResponse, error) {
	var revision int64

	txnID := kv.TxnBegin()
	defer func() {
		err := kv.TxnEnd(txnID)
		if err != nil {
			panic(fmt.Sprint("unexpected error when closing txn", txnID))
		}
	}()

	ok := true
	for _, c := range rt.Compare {
		if revision, ok = applyCompare(txnID, kv, c); !ok {
			break
		}
	}

	// TODO: check potential errors before actually applying anything

	var reqs []*pb.RequestUnion
	if ok {
		reqs = rt.Success
	} else {
		reqs = rt.Failure
	}

	resps := make([]*pb.ResponseUnion, len(reqs))
	for i := range reqs {
		resps[i] = applyUnion(txnID, kv, reqs[i])
	}

	if len(resps) != 0 {
		revision += 1
	}

	txnResp := &pb.TxnResponse{}
	txnResp.Header = &pb.ResponseHeader{}
	txnResp.Header.Revision = revision
	txnResp.Responses = resps
	txnResp.Succeeded = ok
	return txnResp, nil
}

func applyCompaction(kv dstorage.KV, compaction *pb.CompactionRequest) (*pb.CompactionResponse, error) {
	resp := &pb.CompactionResponse{}
	resp.Header = &pb.ResponseHeader{}
	err := kv.Compact(compaction.Revision)
	if err != nil {
		return nil, err
	}
	// get the current revision. which key to get is not important.
	_, resp.Header.Revision, _ = kv.Range([]byte("compaction"), nil, 1, 0)
	return resp, err
}

func applyUnion(txnID int64, kv dstorage.KV, union *pb.RequestUnion) *pb.ResponseUnion {
	switch {
	case union.RequestRange != nil:
		resp, err := applyRange(txnID, kv, union.RequestRange)
		if err != nil {
			panic("unexpected error during txn")
		}
		return &pb.ResponseUnion{ResponseRange: resp}
	case union.RequestPut != nil:
		resp, err := applyPut(txnID, kv, union.RequestPut)
		if err != nil {
			panic("unexpected error during txn")
		}
		return &pb.ResponseUnion{ResponsePut: resp}
	case union.RequestDeleteRange != nil:
		resp, err := applyDeleteRange(txnID, kv, union.RequestDeleteRange)
		if err != nil {
			panic("unexpected error during txn")
		}
		return &pb.ResponseUnion{ResponseDeleteRange: resp}
	default:
		// empty union
		return nil
	}
}

// applyCompare applies the compare request.
// applyCompare should only be called within a txn request and an valid txn ID must
// be presented. Or applyCompare panics.
// It returns the revision at which the comparison happens. If the comparison
// succeeds, the it returns true. Otherwise it returns false.
func applyCompare(txnID int64, kv dstorage.KV, c *pb.Compare) (int64, bool) {
	if txnID == noTxn {
		panic("applyCompare called with noTxn")
	}
	ckvs, rev, err := kv.TxnRange(txnID, c.Key, nil, 1, 0)
	if err != nil {
		if err == dstorage.ErrTxnIDMismatch {
			panic("unexpected txn ID mismatch error")
		}
		return rev, false
	}
	var ckv storagepb.KeyValue
	if len(ckvs) != 0 {
		ckv = ckvs[0]
	} else {
		// Use the zero value of ckv normally. However...
		if c.Target == pb.Compare_VALUE {
			// Always fail if we're comparing a value on a key that doesn't exist.
			// We can treat non-existence as the empty set explicitly, such that
			// even a key with a value of length 0 bytes is still a real key
			// that was written that way
			return rev, false
		}
	}

	// -1 is less, 0 is equal, 1 is greater
	var result int
	switch c.Target {
	case pb.Compare_VALUE:
		result = bytes.Compare(ckv.Value, c.Value)
	case pb.Compare_CREATE:
		result = compareInt64(ckv.CreateRevision, c.CreateRevision)
	case pb.Compare_MOD:
		result = compareInt64(ckv.ModRevision, c.ModRevision)
	case pb.Compare_VERSION:
		result = compareInt64(ckv.Version, c.Version)
	}

	switch c.Result {
	case pb.Compare_EQUAL:
		if result != 0 {
			return rev, false
		}
	case pb.Compare_GREATER:
		if result != 1 {
			return rev, false
		}
	case pb.Compare_LESS:
		if result != -1 {
			return rev, false
		}
	}
	return rev, true
}

func compareInt64(a, b int64) int {
	switch {
	case a < b:
		return -1
	case a > b:
		return 1
	default:
		return 0
	}
}


text:
require "codeclimate-test-reporter"
CodeClimate::TestReporter.start
require 'sidekiq_rejector'