text:
using aura::Window;

namespace ash {
namespace internal {

// Returns a string containing the names of all the children of |window| (in
// order). Each entry is separated by a space.
std::string GetWindowNames(const aura::Window* window) {
  std::string result;
  for (size_t i = 0; i < window->children().size(); ++i) {
    if (i != 0)
      result += " ";
    result += window->children()[i]->name();
  }
  return result;
}

// Returns a string containing the names of windows corresponding to each of the
// child layers of |window|'s layer. Any layers that don't correspond to a child
// Window of |window| are ignored. The result is ordered based on the layer
// ordering.
std::string GetLayerNames(const aura::Window* window) {
  typedef std::map<const ui::Layer*, std::string> LayerToWindowNameMap;
  LayerToWindowNameMap window_names;
  for (size_t i = 0; i < window->children().size(); ++i) {
    window_names[window->children()[i]->layer()] =
        window->children()[i]->name();
  }

  std::string result;
  const std::vector<ui::Layer*>& layers(window->layer()->children());
  for (size_t i = 0; i < layers.size(); ++i) {
    LayerToWindowNameMap::iterator layer_i =
        window_names.find(layers[i]);
    if (layer_i != window_names.end()) {
      if (!result.empty())
        result += " ";
      result += layer_i->second;
    }
  }
  return result;
}

class WorkspaceManagerTest : public test::AshTestBase {
 public:
  WorkspaceManagerTest() : manager_(NULL) {}
  virtual ~WorkspaceManagerTest() {}

  aura::Window* CreateTestWindowUnparented() {
    aura::Window* window = new aura::Window(NULL);
    window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
    window->SetType(aura::client::WINDOW_TYPE_NORMAL);
    window->Init(ui::LAYER_TEXTURED);
    return window;
  }

  aura::Window* CreateTestWindow() {
    aura::Window* window = new aura::Window(NULL);
    window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
    window->SetType(aura::client::WINDOW_TYPE_NORMAL);
    window->Init(ui::LAYER_TEXTURED);
    SetDefaultParentByPrimaryRootWindow(window);
    return window;
  }

  aura::Window* CreateAppTestWindow(aura::Window* parent) {
    aura::Window* window = new aura::Window(NULL);
    window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
    window->SetType(aura::client::WINDOW_TYPE_POPUP);
    window->Init(ui::LAYER_TEXTURED);
    if (!parent)
      SetDefaultParentByPrimaryRootWindow(window);
    else
      parent->AddChild(window);
    return window;
  }

  aura::Window* GetViewport() {
    return Shell::GetContainer(Shell::GetPrimaryRootWindow(),
                               kShellWindowId_DefaultContainer);
  }

  const std::vector<Workspace*>& workspaces() const {
    return manager_->workspaces_;
  }

  gfx::Rect GetFullscreenBounds(aura::Window* window) {
    return Shell::GetScreen()->GetDisplayNearestWindow(window).bounds();
  }

  Workspace* active_workspace() {
    return manager_->active_workspace_;
  }

  ShelfWidget* shelf_widget() {
    return Shell::GetPrimaryRootWindowController()->shelf();
  }

  ShelfLayoutManager* shelf_layout_manager() {
    return Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager();
  }

  bool GetWindowOverlapsShelf() {
    return shelf_layout_manager()->window_overlaps_shelf();
  }

  Workspace* FindBy(aura::Window* window) const {
    return manager_->FindBy(window);
  }

  std::string WorkspaceStateString(Workspace* workspace) {
    return (workspace->is_maximized() ? "M" : "") +
        base::IntToString(static_cast<int>(
                              workspace->window()->children().size()));
  }

  int active_index() {
    return static_cast<int>(
        manager_->FindWorkspace(manager_->active_workspace_) -
        manager_->workspaces_.begin());
  }

  // Returns a string description of the current state. The string has the
  // following format:
  // W* P=W* active=N
  // Each W corresponds to a workspace. Each workspace is prefixed with an 'M'
  // if the workspace is maximized and is followed by the number of windows in
  // the workspace.
  // 'P=' is used for the pending workspaces (see
  // WorkspaceManager::pending_workspaces_ for details on pending workspaces).
  // N is the index of the active workspace (index into
  // WorkspaceManager::workspaces_).
  // For example, '2 M1 P=M1 active=1' means the first workspace (the desktop)
  // has 2 windows, the second workspace is a maximized workspace with 1 window,
  // there is a pending maximized workspace with 1 window and the second
  // workspace is active.
  std::string StateString() {
    std::string result;
    for (size_t i = 0; i < manager_->workspaces_.size(); ++i) {
      if (i > 0)
        result += " ";
      result += WorkspaceStateString(manager_->workspaces_[i]);
    }

    if (!manager_->pending_workspaces_.empty()) {
      result += " P=";
      for (std::set<Workspace*>::const_iterator i =
               manager_->pending_workspaces_.begin();
           i != manager_->pending_workspaces_.end(); ++i) {
        if (i != manager_->pending_workspaces_.begin())
          result += " ";
        result += WorkspaceStateString(*i);
      }
    }

    result += " active=" + base::IntToString(active_index());
    return result;
  }

  // Overridden from AshTestBase:
  virtual void SetUp() OVERRIDE {
    test::AshTestBase::SetUp();
    WorkspaceControllerTestHelper workspace_helper(
        test::ShellTestApi(Shell::GetInstance()).workspace_controller());
    manager_ = workspace_helper.workspace_manager();
  }

  virtual void TearDown() OVERRIDE {
    manager_ = NULL;
    test::AshTestBase::TearDown();
  }

 protected:
  WorkspaceManager* manager_;

 private:
  scoped_ptr<ActivationController> activation_controller_;

  DISALLOW_COPY_AND_ASSIGN(WorkspaceManagerTest);
};

// Assertions around adding a normal window.
TEST_F(WorkspaceManagerTest, AddNormalWindowWhenEmpty) {
  scoped_ptr<Window> w1(CreateTestWindow());
  w1->SetBounds(gfx::Rect(0, 0, 250, 251));

  EXPECT_TRUE(GetRestoreBoundsInScreen(w1.get()) == NULL);

  w1->Show();

  EXPECT_TRUE(GetRestoreBoundsInScreen(w1.get()) == NULL);

  ASSERT_TRUE(w1->layer() != NULL);
  EXPECT_TRUE(w1->layer()->visible());

  EXPECT_EQ("0,0 250x251", w1->bounds().ToString());

  // Should be 1 workspace for the desktop, not maximized.
  ASSERT_EQ("1 active=0", StateString());
  EXPECT_EQ(w1.get(), workspaces()[0]->window()->children()[0]);
}

// Assertions around maximizing/unmaximizing.
TEST_F(WorkspaceManagerTest, SingleMaximizeWindow) {
  scoped_ptr<Window> w1(CreateTestWindow());
  w1->SetBounds(gfx::Rect(0, 0, 250, 251));

  w1->Show();
  wm::ActivateWindow(w1.get());

  EXPECT_TRUE(wm::IsActiveWindow(w1.get()));

  ASSERT_TRUE(w1->layer() != NULL);
  EXPECT_TRUE(w1->layer()->visible());

  EXPECT_EQ("0,0 250x251", w1->bounds().ToString());

  // Maximize the window.
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);

  EXPECT_TRUE(wm::IsActiveWindow(w1.get()));

  // Should be 2 workspaces, the second maximized with w1.
  ASSERT_EQ("0 M1 active=1", StateString());
  EXPECT_EQ(w1.get(), workspaces()[1]->window()->children()[0]);
  EXPECT_EQ(ScreenAsh::GetMaximizedWindowBoundsInParent(w1.get()).width(),
            w1->bounds().width());
  EXPECT_EQ(ScreenAsh::GetMaximizedWindowBoundsInParent(w1.get()).height(),
            w1->bounds().height());

  // Restore the window.
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);

  // Should be 1 workspace for the desktop.
  ASSERT_EQ("1 active=0", StateString());
  EXPECT_EQ(w1.get(), workspaces()[0]->window()->children()[0]);
  EXPECT_EQ("0,0 250x251", w1->bounds().ToString());
}

// Assertions around closing the last window in a workspace.
TEST_F(WorkspaceManagerTest, CloseLastWindowInWorkspace) {
  scoped_ptr<Window> w1(CreateTestWindow());
  scoped_ptr<Window> w2(CreateTestWindow());
  w1->SetBounds(gfx::Rect(0, 0, 250, 251));
  w1->Show();
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  w2->Show();
  wm::ActivateWindow(w1.get());

  // Should be 1 workspace and 1 pending, !maximized and maximized. The second
  // workspace is pending since the window wasn't active.
  ASSERT_EQ("1 P=M1 active=0", StateString());
  EXPECT_EQ(w1.get(), workspaces()[0]->window()->children()[0]);

  // Close w2.
  w2.reset();

  // Should have one workspace.
  ASSERT_EQ("1 active=0", StateString());
  EXPECT_EQ(w1.get(), workspaces()[0]->window()->children()[0]);
  EXPECT_TRUE(w1->IsVisible());
}

// Assertions around adding a maximized window when empty.
TEST_F(WorkspaceManagerTest, AddMaximizedWindowWhenEmpty) {
  scoped_ptr<Window> w1(CreateTestWindow());
  w1->SetBounds(gfx::Rect(0, 0, 250, 251));
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  w1->Show();
  wm::ActivateWindow(w1.get());

  ASSERT_TRUE(w1->layer() != NULL);
  EXPECT_TRUE(w1->layer()->visible());
  gfx::Rect work_area(
      ScreenAsh::GetMaximizedWindowBoundsInParent(w1.get()));
  EXPECT_EQ(work_area.width(), w1->bounds().width());
  EXPECT_EQ(work_area.height(), w1->bounds().height());

  // Should be 2 workspaces (since we always keep the desktop).
  ASSERT_EQ("0 M1 active=1", StateString());
  EXPECT_EQ(w1.get(), workspaces()[1]->window()->children()[0]);
}

// Assertions around two windows and toggling one to be maximized.
TEST_F(WorkspaceManagerTest, MaximizeWithNormalWindow) {
  scoped_ptr<Window> w1(CreateTestWindow());
  scoped_ptr<Window> w2(CreateTestWindow());
  w1->SetBounds(gfx::Rect(0, 0, 250, 251));
  w1->Show();

  ASSERT_TRUE(w1->layer() != NULL);
  EXPECT_TRUE(w1->layer()->visible());

  w2->SetBounds(gfx::Rect(0, 0, 50, 51));
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  w2->Show();
  wm::ActivateWindow(w2.get());

  // Should now be two workspaces.
  ASSERT_EQ("1 M1 active=1", StateString());
  EXPECT_EQ(w1.get(), workspaces()[0]->window()->children()[0]);
  EXPECT_EQ(w2.get(), workspaces()[1]->window()->children()[0]);

  gfx::Rect work_area(ScreenAsh::GetMaximizedWindowBoundsInParent(w1.get()));
  EXPECT_EQ(work_area.width(), w2->bounds().width());
  EXPECT_EQ(work_area.height(), w2->bounds().height());

  // Restore w2, which should then go back to one workspace.
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
  ASSERT_EQ("2 active=0", StateString());
  EXPECT_EQ(w1.get(), workspaces()[0]->window()->children()[0]);
  EXPECT_EQ(w2.get(), workspaces()[0]->window()->children()[1]);
  EXPECT_EQ(50, w2->bounds().width());
  EXPECT_EQ(51, w2->bounds().height());
  EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
}

// Assertions around two maximized windows.
TEST_F(WorkspaceManagerTest, TwoMaximized) {
  scoped_ptr<Window> w1(CreateTestWindow());
  scoped_ptr<Window> w2(CreateTestWindow());
  w1->SetBounds(gfx::Rect(0, 0, 250, 251));
  w1->Show();
  wm::ActivateWindow(w1.get());
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  ASSERT_EQ("1 M1 active=1", StateString());

  w2->SetBounds(gfx::Rect(0, 0, 50, 51));
  w2->Show();
  wm::ActivateWindow(w2.get());
  ASSERT_EQ("1 M1 active=0", StateString());

  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
  ASSERT_EQ("0 M1 M1 active=2", StateString());

  // The last stacked window (|w2|) should be last since it was maximized last.
  EXPECT_EQ(w1.get(), workspaces()[1]->window()->children()[0]);
  EXPECT_EQ(w2.get(), workspaces()[2]->window()->children()[0]);
}

// Get the index of the layer inside its parent. This index can be used to
// determine the z-order / draw-order of objects in the render tree.
size_t IndexOfLayerInParent(ui::Layer* layer) {
  ui::Layer* parent = layer->parent();
  for (size_t i = 0; i < parent->children().size(); i++) {
    if (layer == parent->children()[i])
      return i;
  }
  // This should never be reached.
  NOTREACHED();
  return 0;
}

// Make sure that the layer z-order is correct for the time of the animation
// when in a workspace with a normal and a maximized window the normal window
// gets maximized. See crbug.com/232399.
TEST_F(WorkspaceManagerTest, MaximizeSecondInWorkspace) {
  // Create a maximized window.
  scoped_ptr<Window> w1(CreateTestWindow());
  ASSERT_EQ(1U, w1->layer()->parent()->children().size());
  w1->SetBounds(gfx::Rect(0, 0, 250, 251));
  w1->Show();
  wm::ActivateWindow(w1.get());
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  wm::ActivateWindow(w1.get());
  // There are two workspaces: A normal and a maximized one.
  ASSERT_EQ("0 M1 active=1", StateString());

  // Create a second window and make it part of the maximized workspace.
  scoped_ptr<Window> w2(CreateAppTestWindow(w1->parent()));
  w2->SetBounds(gfx::Rect(0, 0, 50, 51));
  w2->Show();
  wm::ActivateWindow(w2.get());
  // There are still two workspaces and two windows in the (maximized)
  // workspace.
  ASSERT_EQ("0 M2 active=1", StateString());
  ASSERT_EQ(w1->layer()->parent()->children()[0], w1->layer());
  ASSERT_EQ(w1->layer()->parent()->children()[1], w2->layer());

  // Now we need to enable all animations since the incorrect layer ordering we
  // want to test against happens only while the animation is going on.
  scoped_ptr<ui::ScopedAnimationDurationScaleMode> animation_duration(
      new ui::ScopedAnimationDurationScaleMode(
          ui::ScopedAnimationDurationScaleMode::FAST_DURATION));

  ui::Layer* old_w2_layer = w2->layer();

  // Maximize the second window and make sure that the workspace changes.
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);

  // Check the correct window hierarchy - (|w2|) should be last since it was
  // maximized last.
  ASSERT_EQ("0 M1 M1 active=2", StateString());
  EXPECT_EQ(3U, workspaces().size());
  EXPECT_EQ(w1.get(), workspaces()[1]->window()->children()[0]);
  EXPECT_EQ(w2.get(), workspaces()[2]->window()->children()[0]);

  // Check the workspace layer visibility.
  EXPECT_EQ(1, workspaces()[1]->window()->layer()->opacity());
  EXPECT_EQ(1, workspaces()[2]->window()->layer()->opacity());

  // Check that |w2| got a new layer and that the old layer is still visible,
  // while the new one is not. Further and foremost the old layer should be a
  // member of the workspace's window and it should be the second last of the
  // list to be properly stacked while the animation is going on.
  EXPECT_NE(w2->layer(), old_w2_layer);
  EXPECT_EQ(0, w2->layer()->opacity());
  EXPECT_EQ(1, old_w2_layer->opacity());

  // For the animation to look right we need the following ordering:
  // workspace_1_layer_index < old_layer_index < workspace_2_layer_index.
  ASSERT_EQ(workspaces()[1]->window()->parent()->layer(),
            old_w2_layer->parent());
  const size_t workspace_1_layer_index = IndexOfLayerInParent(
      workspaces()[1]->window()->layer());
  const size_t workspace_2_layer_index = IndexOfLayerInParent(
      workspaces()[2]->window()->layer());
  const size_t old_layer_index = IndexOfLayerInParent(old_w2_layer);
  EXPECT_LT(workspace_1_layer_index, old_layer_index);
  EXPECT_LT(old_layer_index, workspace_2_layer_index);
}

// Makes sure requests to change the bounds of a normal window go through.
TEST_F(WorkspaceManagerTest, ChangeBoundsOfNormalWindow) {
  scoped_ptr<Window> w1(CreateTestWindow());
  w1->Show();

  // Setting the bounds should go through since the window is in the normal
  // workspace.
  w1->SetBounds(gfx::Rect(0, 0, 200, 500));
  EXPECT_EQ(200, w1->bounds().width());
  EXPECT_EQ(500, w1->bounds().height());
}

// Verifies the bounds is not altered when showing and grid is enabled.
TEST_F(WorkspaceManagerTest, SnapToGrid) {
  scoped_ptr<Window> w1(CreateTestWindowUnparented());
  w1->SetBounds(gfx::Rect(1, 6, 25, 30));
  SetDefaultParentByPrimaryRootWindow(w1.get());
  // We are not aligning this anymore this way. When the window gets shown
  // the window is expected to be handled differently, but this cannot be
  // tested with this test. So the result of this test should be that the
  // bounds are exactly as passed in.
  EXPECT_EQ("1,6 25x30", w1->bounds().ToString());
}

// Assertions around a fullscreen window.
TEST_F(WorkspaceManagerTest, SingleFullscreenWindow) {
  scoped_ptr<Window> w1(CreateTestWindow());
  w1->SetBounds(gfx::Rect(0, 0, 250, 251));
  // Make the window fullscreen.
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
  w1->Show();
  wm::ActivateWindow(w1.get());

  // Should be 2 workspaces, normal and maximized.
  ASSERT_EQ("0 M1 active=1", StateString());
  EXPECT_EQ(w1.get(), workspaces()[1]->window()->children()[0]);
  EXPECT_EQ(GetFullscreenBounds(w1.get()).width(), w1->bounds().width());
  EXPECT_EQ(GetFullscreenBounds(w1.get()).height(), w1->bounds().height());

  // Restore the window. Use SHOW_STATE_DEFAULT as that is what we'll end up
  // with when using views::Widget.
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_DEFAULT);
  EXPECT_EQ("0,0 250x251", w1->bounds().ToString());

  // Should be 1 workspace for the desktop.
  ASSERT_EQ("1 active=0", StateString());
  EXPECT_EQ(w1.get(), workspaces()[0]->window()->children()[0]);
  EXPECT_EQ(250, w1->bounds().width());
  EXPECT_EQ(251, w1->bounds().height());

  // Back to fullscreen.
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
  ASSERT_EQ("0 M1 active=1", StateString());
  EXPECT_EQ(w1.get(), workspaces()[1]->window()->children()[0]);
  EXPECT_EQ(GetFullscreenBounds(w1.get()).width(), w1->bounds().width());
  EXPECT_EQ(GetFullscreenBounds(w1.get()).height(), w1->bounds().height());
  ASSERT_TRUE(GetRestoreBoundsInScreen(w1.get()));
  EXPECT_EQ("0,0 250x251", GetRestoreBoundsInScreen(w1.get())->ToString());
}

// Makes sure switching workspaces doesn't show transient windows.
TEST_F(WorkspaceManagerTest, DontShowTransientsOnSwitch) {
  scoped_ptr<Window> w1(CreateTestWindow());
  scoped_ptr<Window> w2(CreateTestWindow());

  w1->SetBounds(gfx::Rect(0, 0, 250, 251));
  w2->SetBounds(gfx::Rect(0, 0, 250, 251));
  w1->AddTransientChild(w2.get());

  w1->Show();

  scoped_ptr<Window> w3(CreateTestWindow());
  w3->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  w3->Show();
  wm::ActivateWindow(w3.get());

  EXPECT_FALSE(w1->layer()->IsDrawn());
  EXPECT_FALSE(w2->layer()->IsDrawn());
  EXPECT_TRUE(w3->layer()->IsDrawn());

  wm::ActivateWindow(w1.get());
  EXPECT_TRUE(w1->layer()->IsDrawn());
  EXPECT_FALSE(w2->layer()->IsDrawn());
  EXPECT_FALSE(w3->layer()->IsDrawn());
}

// Persists-across-all-workspace flag should not cause a transient child
// to be activated at desktop workspace.
TEST_F(WorkspaceManagerTest, PersistsTransientChildStayInSameWorkspace) {
  scoped_ptr<Window> w1(CreateTestWindow());
  SetPersistsAcrossAllWorkspaces(
      w1.get(),
      WINDOW_PERSISTS_ACROSS_ALL_WORKSPACES_VALUE_YES);
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  w1->Show();
  wm::ActivateWindow(w1.get());
  ASSERT_EQ("0 M1 active=1", StateString());

  scoped_ptr<Window> w2(CreateTestWindowUnparented());
  w1->AddTransientChild(w2.get());
  SetPersistsAcrossAllWorkspaces(
      w2.get(),
      WINDOW_PERSISTS_ACROSS_ALL_WORKSPACES_VALUE_YES);
  SetDefaultParentByPrimaryRootWindow(w2.get());
  w2->Show();
  wm::ActivateWindow(w2.get());

  ASSERT_EQ("0 M2 active=1", StateString());
}

// Assertions around minimizing a single window.
TEST_F(WorkspaceManagerTest, MinimizeSingleWindow) {
  scoped_ptr<Window> w1(CreateTestWindow());

  w1->Show();
  ASSERT_EQ("1 active=0", StateString());

  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
  ASSERT_EQ("1 active=0", StateString());
  EXPECT_FALSE(w1->layer()->IsDrawn());

  // Show the window.
  w1->Show();
  EXPECT_TRUE(wm::IsWindowNormal(w1.get()));
  ASSERT_EQ("1 active=0", StateString());
  EXPECT_TRUE(w1->layer()->IsDrawn());
}

// Assertions around minimizing a maximized window.
TEST_F(WorkspaceManagerTest, MinimizeMaximizedWindow) {
  // Two windows, w1 normal, w2 maximized.
  scoped_ptr<Window> w1(CreateTestWindow());
  scoped_ptr<Window> w2(CreateTestWindow());
  w1->Show();
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  w2->Show();
  wm::ActivateWindow(w2.get());
  ASSERT_EQ("1 M1 active=1", StateString());

  // Minimize w2.
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
  ASSERT_EQ("1 P=M1 active=0", StateString());
  EXPECT_TRUE(w1->layer()->IsDrawn());
  EXPECT_FALSE(w2->layer()->IsDrawn());

  // Show the window, which should trigger unminimizing.
  w2->Show();
  ASSERT_EQ("1 P=M1 active=0", StateString());

  wm::ActivateWindow(w2.get());
  ASSERT_EQ("1 M1 active=1", StateString());

  EXPECT_TRUE(wm::IsWindowMaximized(w2.get()));
  EXPECT_FALSE(w1->layer()->IsDrawn());
  EXPECT_TRUE(w2->layer()->IsDrawn());

  // Minimize the window, which should hide the window and activate another.
  EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
  EXPECT_FALSE(wm::IsActiveWindow(w2.get()));
  EXPECT_FALSE(w2->layer()->IsDrawn());
  EXPECT_TRUE(wm::IsActiveWindow(w1.get()));

  // Make the window normal.
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
  ASSERT_EQ("2 active=0", StateString());
  EXPECT_EQ(w1.get(), workspaces()[0]->window()->children()[0]);
  EXPECT_EQ(w2.get(), workspaces()[0]->window()->children()[1]);
  EXPECT_TRUE(w2->layer()->IsDrawn());
}

// Verifies ShelfLayoutManager's visibility/auto-hide state is correctly
// updated.
TEST_F(WorkspaceManagerTest, ShelfStateUpdated) {
  // Since ShelfLayoutManager queries for mouse location, move the mouse so
  // it isn't over the shelf.
  aura::test::EventGenerator generator(
      Shell::GetPrimaryRootWindow(), gfx::Point());
  generator.MoveMouseTo(0, 0);

  scoped_ptr<Window> w1(CreateTestWindow());
  const gfx::Rect w1_bounds(0, 1, 101, 102);
  ShelfLayoutManager* shelf = shelf_layout_manager();
  shelf->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
  const gfx::Rect touches_shelf_bounds(
      0, shelf->GetIdealBounds().y() - 10, 101, 102);
  // Move |w1| to overlap the shelf.
  w1->SetBounds(touches_shelf_bounds);
  EXPECT_FALSE(GetWindowOverlapsShelf());

  // A visible ignored window should not trigger the overlap.
  scoped_ptr<Window> w_ignored(CreateTestWindow());
  w_ignored->SetBounds(touches_shelf_bounds);
  SetIgnoredByShelf(&(*w_ignored), true);
  w_ignored->Show();
  EXPECT_FALSE(GetWindowOverlapsShelf());

  // Make it visible, since visible shelf overlaps should be true.
  w1->Show();
  EXPECT_TRUE(GetWindowOverlapsShelf());

  wm::ActivateWindow(w1.get());
  w1->SetBounds(w1_bounds);
  w1->Show();
  wm::ActivateWindow(w1.get());

  EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());

  // Maximize the window.
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
  EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());

  // Restore.
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
  EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
  EXPECT_EQ("0,1 101x102", w1->bounds().ToString());

  // Fullscreen.
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
  EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());

  // Normal.
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
  EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
  EXPECT_EQ("0,1 101x102", w1->bounds().ToString());
  EXPECT_FALSE(GetWindowOverlapsShelf());

  // Move window so it obscures shelf.
  w1->SetBounds(touches_shelf_bounds);
  EXPECT_TRUE(GetWindowOverlapsShelf());

  // Move it back.
  w1->SetBounds(w1_bounds);
  EXPECT_FALSE(GetWindowOverlapsShelf());

  // Maximize again.
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
  EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());

  // Minimize.
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
  EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());

  // Since the restore from minimize will restore to the pre-minimize
  // state (tested elsewhere), we abandon the current size and restore
  // rect and set them to the window.
  gfx::Rect restore = *GetRestoreBoundsInScreen(w1.get());
  EXPECT_EQ("0,0 800x597", w1->bounds().ToString());
  EXPECT_EQ("0,1 101x102", restore.ToString());
  ClearRestoreBounds(w1.get());
  w1->SetBounds(restore);

  // Restore.
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
  EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
  EXPECT_EQ("0,1 101x102", w1->bounds().ToString());

  // Create another window, maximized.
  scoped_ptr<Window> w2(CreateTestWindow());
  w2->SetBounds(gfx::Rect(10, 11, 250, 251));
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  w2->Show();
  wm::ActivateWindow(w2.get());
  EXPECT_EQ(1, active_index());
  EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
  EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
  EXPECT_EQ("0,1 101x102", w1->bounds().ToString());

  // Switch to w1.
  wm::ActivateWindow(w1.get());
  EXPECT_EQ(0, active_index());
  EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
  EXPECT_EQ("0,1 101x102", w1->bounds().ToString());
  EXPECT_EQ(ScreenAsh::GetMaximizedWindowBoundsInParent(
                w2->parent()).ToString(),
            w2->bounds().ToString());

  // Switch to w2.
  wm::ActivateWindow(w2.get());
  EXPECT_EQ(1, active_index());
  EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
  EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
  EXPECT_EQ("0,1 101x102", w1->bounds().ToString());
  EXPECT_EQ(ScreenAsh::GetMaximizedWindowBoundsInParent(w2.get()).ToString(),
            w2->bounds().ToString());

  // Turn off auto-hide, switch back to w2 (maximized) and verify overlap.
  shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
  wm::ActivateWindow(w2.get());
  EXPECT_FALSE(GetWindowOverlapsShelf());

  // Move w1 to overlap shelf, it shouldn't change window overlaps shelf since
  // the window isn't in the visible workspace.
  w1->SetBounds(touches_shelf_bounds);
  EXPECT_FALSE(GetWindowOverlapsShelf());

  // Activate w1. Since w1 is visible the overlap state should be true.
  wm::ActivateWindow(w1.get());
  EXPECT_TRUE(GetWindowOverlapsShelf());
}

// Verifies persist across all workspaces.
TEST_F(WorkspaceManagerTest, PersistAcrossAllWorkspaces) {
  // Create a maximized window.
  scoped_ptr<Window> w1(CreateTestWindow());
  w1->Show();
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  wm::ActivateWindow(w1.get());
  ASSERT_EQ("0 M1 active=1", StateString());

  // Create a window that persists across all workspaces. It should be placed in
  // the current maximized workspace.
  scoped_ptr<Window> w2(CreateTestWindow());
  SetPersistsAcrossAllWorkspaces(
      w2.get(),
      WINDOW_PERSISTS_ACROSS_ALL_WORKSPACES_VALUE_YES);
  w2->Show();
  ASSERT_EQ("1 M1 active=1", StateString());

  // Activate w2, which should move it to the 2nd workspace.
  wm::ActivateWindow(w2.get());
  ASSERT_EQ("0 M2 active=1", StateString());

  // Restoring w2 should drop the persists window back to the desktop, and drop
  // it to the bottom of the stack.
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
  ASSERT_EQ("2 active=0", StateString());
  EXPECT_EQ(w2.get(), workspaces()[0]->window()->children()[0]);
  EXPECT_EQ(w1.get(), workspaces()[0]->window()->children()[1]);

  // Repeat, but this time minimize. The minimized window should end up in
  // pending.
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  ASSERT_EQ("1 P=M1 active=0", StateString());
  w2.reset(CreateTestWindow());
  SetPersistsAcrossAllWorkspaces(
      w2.get(),
      WINDOW_PERSISTS_ACROSS_ALL_WORKSPACES_VALUE_YES);
  w2->Show();
  ASSERT_EQ("1 P=M1 active=0", StateString());
  wm::ActivateWindow(w2.get());
  ASSERT_EQ("1 P=M1 active=0", StateString());
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
  ASSERT_EQ("1 P=M1 active=0", StateString());
  EXPECT_EQ(w2.get(), workspaces()[0]->window()->children()[0]);
}

// Verifies that when a window persists across all workpaces is activated that
// it moves to the current workspace.
TEST_F(WorkspaceManagerTest, ActivatePersistAcrossAllWorkspacesWhenNotActive) {
  // Create a window that persists across all workspaces.
  scoped_ptr<Window> w2(CreateTestWindow());
  SetPersistsAcrossAllWorkspaces(
      w2.get(),
      WINDOW_PERSISTS_ACROSS_ALL_WORKSPACES_VALUE_YES);
  w2->Show();
  ASSERT_EQ("1 active=0", StateString());

  // Create a maximized window.
  scoped_ptr<Window> w1(CreateTestWindow());
  w1->Show();
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  wm::ActivateWindow(w1.get());
  ASSERT_EQ("1 M1 active=1", StateString());

  // Activate the persists across all workspace window. It should move to the
  // current workspace.
  wm::ActivateWindow(w2.get());
  ASSERT_EQ("0 M2 active=1", StateString());
  // The window that persists across all workspaces should be moved to the top
  // of the stacking order.
  EXPECT_EQ(w1.get(), workspaces()[1]->window()->children()[0]);
  EXPECT_EQ(w2.get(), workspaces()[1]->window()->children()[1]);
  EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
}

// Verifies Show()ing a minimized window that persists across all workspaces
// unminimizes the window.
TEST_F(WorkspaceManagerTest, ShowMinimizedPersistWindow) {
  // Create a window that persists across all workspaces.
  scoped_ptr<Window> w1(CreateTestWindow());
  SetPersistsAcrossAllWorkspaces(
      w1.get(),
      WINDOW_PERSISTS_ACROSS_ALL_WORKSPACES_VALUE_YES);
  w1->Show();
  wm::ActivateWindow(w1.get());
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
  EXPECT_FALSE(w1->IsVisible());
  w1->Show();
  EXPECT_TRUE(w1->IsVisible());
}

// Test that a persistent window across all workspaces which was first
// maximized, then got minimized and finally got restored does not crash the
// system (see http://crbug.com/151698) and restores its maximized workspace
// instead.
TEST_F(WorkspaceManagerTest, MaximizeMinimizeRestoreDoesNotCrash) {
  // We need to create a regular window first so there's an active workspace.
  scoped_ptr<Window> w1(CreateTestWindow());
  w1->Show();

  // Create a window that persists across all workspaces.
  scoped_ptr<Window> w2(CreateTestWindow());
  SetPersistsAcrossAllWorkspaces(
      w2.get(),
      WINDOW_PERSISTS_ACROSS_ALL_WORKSPACES_VALUE_YES);
  w2->Show();
  wm::ActivateWindow(w2.get());
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
  EXPECT_FALSE(w2->IsVisible());
  // This is the critical call which should switch to the maximized workspace
  // of that window instead of reparenting it to the other workspace (and
  // crashing while trying to do so).
  wm::ActivateWindow(w2.get());
  EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED,
            w2->GetProperty(aura::client::kShowStateKey));
  EXPECT_TRUE(w2->IsVisible());
}

// Test that we report we're in the fullscreen state even if the fullscreen
// window isn't being managed by us (http://crbug.com/123931).
TEST_F(WorkspaceManagerTest, GetWindowStateWithUnmanagedFullscreenWindow) {
  ShelfLayoutManager* shelf = shelf_layout_manager();

  // We need to create a regular window first so there's an active workspace.
  scoped_ptr<Window> w1(CreateTestWindow());
  w1->Show();

  scoped_ptr<Window> w2(CreateTestWindow());
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
  SetPersistsAcrossAllWorkspaces(
      w2.get(),
      WINDOW_PERSISTS_ACROSS_ALL_WORKSPACES_VALUE_YES);
  w2->Show();
  wm::ActivateWindow(w2.get());

  ASSERT_EQ("1 M1 active=1", StateString());

  EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
  EXPECT_EQ(WORKSPACE_WINDOW_STATE_FULL_SCREEN, manager_->GetWindowState());

  w2->Hide();
  ASSERT_EQ("1 P=M1 active=0", StateString());
  EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());

  w2->Show();
  ASSERT_EQ("1 P=M1 active=0", StateString());
  EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
  EXPECT_EQ(WORKSPACE_WINDOW_STATE_DEFAULT, manager_->GetWindowState());

  wm::ActivateWindow(w2.get());
  ASSERT_EQ("1 M1 active=1", StateString());
  EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
  EXPECT_EQ(WORKSPACE_WINDOW_STATE_FULL_SCREEN, manager_->GetWindowState());

  w2.reset();
  ASSERT_EQ("1 active=0", StateString());
  EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
  EXPECT_EQ(WORKSPACE_WINDOW_STATE_DEFAULT, manager_->GetWindowState());
}

// Variant of GetWindowStateWithUnmanagedFullscreenWindow that uses a maximized
// window rather than a normal window.
TEST_F(WorkspaceManagerTest,
       GetWindowStateWithUnmanagedFullscreenWindowWithMaximized) {
  ShelfLayoutManager* shelf = shelf_layout_manager();
  shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);

  // Make the first window maximized.
  scoped_ptr<Window> w1(CreateTestWindow());
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  w1->Show();

  scoped_ptr<Window> w2(CreateTestWindow());
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
  SetPersistsAcrossAllWorkspaces(
      w2.get(),
      WINDOW_PERSISTS_ACROSS_ALL_WORKSPACES_VALUE_YES);
  w2->Show();
  wm::ActivateWindow(w2.get());

  // Even though auto-hide behavior is NEVER full-screen windows cause the shelf
  // to hide.
  EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
  EXPECT_EQ(WORKSPACE_WINDOW_STATE_FULL_SCREEN,
            manager_->GetWindowState());

  w2->Hide();
  EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());

  w2->Show();
  wm::ActivateWindow(w2.get());
  EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
  EXPECT_EQ(WORKSPACE_WINDOW_STATE_FULL_SCREEN,
            manager_->GetWindowState());

  w2.reset();
  EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
}

// Verifies a window marked as persisting across all workspaces ends up in its
// own workspace when maximized.
TEST_F(WorkspaceManagerTest, MaximizeDontPersistEndsUpInOwnWorkspace) {
  scoped_ptr<Window> w1(CreateTestWindow());

  SetPersistsAcrossAllWorkspaces(
      w1.get(),
      WINDOW_PERSISTS_ACROSS_ALL_WORKSPACES_VALUE_YES);
  w1->Show();

  ASSERT_EQ("1 active=0", StateString());

  // Maximize should trigger containing the window.
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  ASSERT_EQ("0 P=M1 active=0", StateString());

  // And resetting to normal should remove it.
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
  ASSERT_EQ("1 active=0", StateString());
}

// Verifies going from maximized to minimized sets the right state for painting
// the background of the launcher.
TEST_F(WorkspaceManagerTest, MinimizeResetsVisibility) {
  scoped_ptr<Window> w1(CreateTestWindow());
  w1->Show();
  wm::ActivateWindow(w1.get());
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
  EXPECT_EQ(SHELF_VISIBLE,
            shelf_layout_manager()->visibility_state());
  EXPECT_FALSE(shelf_widget()->paints_background());
}

// Verifies transients are moved when maximizing.
TEST_F(WorkspaceManagerTest, MoveTransientOnMaximize) {
  scoped_ptr<Window> w1(CreateTestWindow());
  w1->Show();
  scoped_ptr<Window> w2(CreateTestWindow());
  w1->AddTransientChild(w2.get());
  w2->Show();
  wm::ActivateWindow(w1.get());
  ASSERT_EQ("2 active=0", StateString());

  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  ASSERT_EQ("0 M2 active=1", StateString());
  EXPECT_TRUE(wm::IsActiveWindow(w1.get()));

  // Create another transient child of |w1|. We do this unparented, set up the
  // transient parent then set parent. This is how NativeWidgetAura does things
  // too.
  scoped_ptr<Window> w3(CreateTestWindowUnparented());
  w1->AddTransientChild(w3.get());
  SetDefaultParentByPrimaryRootWindow(w3.get());
  w3->Show();
  ASSERT_EQ("0 M3 active=1", StateString());

  // Minimize the window. All the transients are hidden as a result, so it ends
  // up in pending.
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
  ASSERT_EQ("0 P=M3 active=0", StateString());

  // Restore and everything should go back to the first workspace.
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
  ASSERT_EQ("3 active=0", StateString());
}

// Verifies window visibility during various workspace changes.
TEST_F(WorkspaceManagerTest, VisibilityTests) {
  scoped_ptr<Window> w1(CreateTestWindow());
  w1->Show();
  EXPECT_TRUE(w1->IsVisible());
  EXPECT_EQ(1.0f, w1->layer()->GetCombinedOpacity());

  // Create another window, activate it and maximized it.
  scoped_ptr<Window> w2(CreateTestWindow());
  w2->Show();
  wm::ActivateWindow(w2.get());
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  EXPECT_TRUE(w2->IsVisible());
  EXPECT_EQ(1.0f, w2->layer()->GetCombinedOpacity());
  EXPECT_FALSE(w1->IsVisible());

  // Switch to w1. |w1| should be visible and |w2| hidden.
  wm::ActivateWindow(w1.get());
  EXPECT_TRUE(w1->IsVisible());
  EXPECT_EQ(1.0f, w1->layer()->GetCombinedOpacity());
  EXPECT_FALSE(w2->IsVisible());

  // Switch back to |w2|.
  wm::ActivateWindow(w2.get());
  EXPECT_TRUE(w2->IsVisible());
  EXPECT_EQ(1.0f, w2->layer()->GetCombinedOpacity());
  EXPECT_FALSE(w1->IsVisible());

  // Restore |w2|, both windows should be visible.
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
  EXPECT_TRUE(w1->IsVisible());
  EXPECT_EQ(1.0f, w1->layer()->GetCombinedOpacity());
  EXPECT_TRUE(w2->IsVisible());
  EXPECT_EQ(1.0f, w2->layer()->GetCombinedOpacity());

  // Maximize |w2| again, then close it.
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  w2->Hide();
  EXPECT_FALSE(w2->IsVisible());
  EXPECT_EQ(1.0f, w1->layer()->GetCombinedOpacity());
  EXPECT_TRUE(w1->IsVisible());

  // Create |w2| and make it fullscreen.
  w2.reset(CreateTestWindow());
  w2->Show();
  wm::ActivateWindow(w2.get());
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
  EXPECT_TRUE(w2->IsVisible());
  EXPECT_EQ(1.0f, w2->layer()->GetCombinedOpacity());
  EXPECT_FALSE(w1->IsVisible());

  // Close |w2|.
  w2.reset();
  EXPECT_EQ(1.0f, w1->layer()->GetCombinedOpacity());
  EXPECT_TRUE(w1->IsVisible());
}

// Verifies windows that are offscreen don't move when switching workspaces.
TEST_F(WorkspaceManagerTest, DontMoveOnSwitch) {
  aura::test::EventGenerator generator(
      Shell::GetPrimaryRootWindow(), gfx::Point());
  generator.MoveMouseTo(0, 0);

  scoped_ptr<Window> w1(CreateTestWindow());
  ShelfLayoutManager* shelf = shelf_layout_manager();
  const gfx::Rect touches_shelf_bounds(
      0, shelf->GetIdealBounds().y() - 10, 101, 102);
  // Move |w1| to overlap the shelf.
  w1->SetBounds(touches_shelf_bounds);
  w1->Show();
  wm::ActivateWindow(w1.get());

  // Create another window and maximize it.
  scoped_ptr<Window> w2(CreateTestWindow());
  w2->SetBounds(gfx::Rect(10, 11, 250, 251));
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  w2->Show();
  wm::ActivateWindow(w2.get());

  // Switch to w1.
  wm::ActivateWindow(w1.get());
  EXPECT_EQ(touches_shelf_bounds.ToString(), w1->bounds().ToString());
}

// Verifies that windows that are completely offscreen move when switching
// workspaces.
TEST_F(WorkspaceManagerTest, MoveOnSwitch) {
  aura::test::EventGenerator generator(
      Shell::GetPrimaryRootWindow(), gfx::Point());
  generator.MoveMouseTo(0, 0);

  scoped_ptr<Window> w1(CreateTestWindow());
  ShelfLayoutManager* shelf = shelf_layout_manager();
  const gfx::Rect w1_bounds(0, shelf->GetIdealBounds().y(), 100, 200);
  // Move |w1| so that the top edge is the same as the top edge of the shelf.
  w1->SetBounds(w1_bounds);
  w1->Show();
  wm::ActivateWindow(w1.get());
  EXPECT_EQ(w1_bounds.ToString(), w1->bounds().ToString());

  // Create another window and maximize it.
  scoped_ptr<Window> w2(CreateTestWindow());
  w2->SetBounds(gfx::Rect(10, 11, 250, 251));
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  w2->Show();
  wm::ActivateWindow(w2.get());

  // Increase the size of the WorkAreaInsets. This would make |w1| fall
  // completely out of the display work area.
  gfx::Insets insets =
      Shell::GetScreen()->GetPrimaryDisplay().GetWorkAreaInsets();
  insets.Set(0, 0, insets.bottom() + 30, 0);
  Shell::GetInstance()->SetDisplayWorkAreaInsets(w1.get(), insets);

  // Switch to w1. The window should have moved.
  wm::ActivateWindow(w1.get());
  EXPECT_NE(w1_bounds.ToString(), w1->bounds().ToString());
}

// Verifies Focus() works in a window that isn't in the active workspace.
TEST_F(WorkspaceManagerTest, FocusOnFullscreenInSeparateWorkspace) {
  scoped_ptr<Window> w1(CreateTestWindow());
  w1->SetBounds(gfx::Rect(10, 11, 250, 251));
  w1->Show();
  wm::ActivateWindow(w1.get());

  scoped_ptr<Window> w2(CreateTestWindow());
  w2->SetBounds(gfx::Rect(10, 11, 250, 251));
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
  w2->Show();
  EXPECT_FALSE(w2->IsVisible());
  EXPECT_FALSE(wm::IsActiveWindow(w2.get()));

  w2->Focus();
  EXPECT_TRUE(w2->IsVisible());
  EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
  EXPECT_FALSE(w1->IsVisible());
}

namespace {

// WindowDelegate used by DontCrashOnChangeAndActivate.
class DontCrashOnChangeAndActivateDelegate
    : public aura::test::TestWindowDelegate {
 public:
  DontCrashOnChangeAndActivateDelegate() : window_(NULL) {}

  void set_window(aura::Window* window) { window_ = window; }

  // WindowDelegate overrides:
  virtual void OnBoundsChanged(const gfx::Rect& old_bounds,
                               const gfx::Rect& new_bounds) OVERRIDE {
    if (window_) {
      wm::ActivateWindow(window_);
      window_ = NULL;
    }
  }

 private:
  aura::Window* window_;

  DISALLOW_COPY_AND_ASSIGN(DontCrashOnChangeAndActivateDelegate);
};

}  // namespace

// Exercises possible crash in W2. Here's the sequence:
// . minimize a maximized window.
// . remove the window (which happens when switching displays).
// . add the window back.
// . show the window and during the bounds change activate it.
TEST_F(WorkspaceManagerTest, DontCrashOnChangeAndActivate) {
  // Force the shelf
  ShelfLayoutManager* shelf = shelf_layout_manager();
  shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);

  DontCrashOnChangeAndActivateDelegate delegate;
  scoped_ptr<Window> w1(CreateTestWindowInShellWithDelegate(
      &delegate, 1000, gfx::Rect(10, 11, 250, 251)));

  w1->Show();
  wm::ActivateWindow(w1.get());
  wm::MaximizeWindow(w1.get());
  wm::MinimizeWindow(w1.get());

  w1->parent()->RemoveChild(w1.get());

  // Do this so that when we Show() the window a resize occurs and we make the
  // window active.
  shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);

  SetDefaultParentByPrimaryRootWindow(w1.get());
  delegate.set_window(w1.get());
  w1->Show();
}

// Verifies a window with a transient parent not managed by workspace works.
TEST_F(WorkspaceManagerTest, TransientParent) {
  // Normal window with no transient parent.
  scoped_ptr<Window> w2(CreateTestWindow());
  w2->SetBounds(gfx::Rect(10, 11, 250, 251));
  w2->Show();
  wm::ActivateWindow(w2.get());

  // Window with a transient parent. We set the transient parent to the root,
  // which would never happen but is enough to exercise the bug.
  scoped_ptr<Window> w1(CreateTestWindowUnparented());
  Shell::GetInstance()->GetPrimaryRootWindow()->AddTransientChild(w1.get());
  w1->SetBounds(gfx::Rect(10, 11, 250, 251));
  SetDefaultParentByPrimaryRootWindow(w1.get());
  w1->Show();
  wm::ActivateWindow(w1.get());

  // The window with the transient parent should get added to the same parent as
  // the normal window.
  EXPECT_EQ(w2->parent(), w1->parent());
}

// Verifies changing TrackedByWorkspace works.
TEST_F(WorkspaceManagerTest, TrackedByWorkspace) {
  // Create a window maximized.
  scoped_ptr<Window> w1(CreateTestWindow());
  w1->Show();
  wm::ActivateWindow(w1.get());
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
  EXPECT_TRUE(w1->IsVisible());

  // Create a second window maximized and mark it not tracked by workspace
  // manager.
  scoped_ptr<Window> w2(CreateTestWindowUnparented());
  w2->SetBounds(gfx::Rect(1, 6, 25, 30));
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  SetDefaultParentByPrimaryRootWindow(w2.get());
  w2->Show();
  SetTrackedByWorkspace(w2.get(), false);
  wm::ActivateWindow(w2.get());

  // Activating |w2| should force it to have the same parent as |w1|.
  EXPECT_EQ(w1->parent(), w2->parent());
  EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
  EXPECT_TRUE(w1->IsVisible());
  EXPECT_TRUE(w2->IsVisible());

  // Because |w2| isn't tracked we should be able to set the bounds of it.
  gfx::Rect bounds(w2->bounds());
  bounds.Offset(4, 5);
  w2->SetBounds(bounds);
  EXPECT_EQ(bounds.ToString(), w2->bounds().ToString());

  // Transition it to tracked by worskpace. It should end up in its own
  // workspace.
  SetTrackedByWorkspace(w2.get(), true);
  EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
  EXPECT_FALSE(w1->IsVisible());
  EXPECT_TRUE(w2->IsVisible());
  EXPECT_NE(w1->parent(), w2->parent());
}

// Verifies a window marked as persisting across all workspaces ends up in its
// own workspace when maximized.
TEST_F(WorkspaceManagerTest, DeactivateDropsToDesktop) {
  // Create a window maximized.
  scoped_ptr<Window> w1(CreateTestWindow());
  w1->Show();
  wm::ActivateWindow(w1.get());
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
  EXPECT_TRUE(w1->IsVisible());

  // Create another window that persists across all workspaces. It should end
  // up with the same parent as |w1|.
  scoped_ptr<Window> w2(CreateTestWindow());
  SetPersistsAcrossAllWorkspaces(
      w2.get(),
      WINDOW_PERSISTS_ACROSS_ALL_WORKSPACES_VALUE_YES);
  w2->Show();
  wm::ActivateWindow(w2.get());
  EXPECT_EQ(w1->parent(), w2->parent());
  ASSERT_EQ("0 M2 active=1", StateString());

  // Activate |w1|, should result in dropping |w2| to the desktop.
  wm::ActivateWindow(w1.get());
  ASSERT_EQ("1 M1 active=1", StateString());
}

// Test the basic auto placement of one and or two windows in a "simulated
// session" of sequential window operations.
TEST_F(WorkspaceManagerTest, BasicAutoPlacing) {
  // Test 1: In case there is no manageable window, no window should shift.

  scoped_ptr<aura::Window> window1(CreateTestWindowInShellWithId(0));
  window1->SetBounds(gfx::Rect(16, 32, 640, 320));
  gfx::Rect desktop_area = window1->parent()->bounds();

  scoped_ptr<aura::Window> window2(CreateTestWindowInShellWithId(1));
  // Trigger the auto window placement function by making it visible.
  // Note that the bounds are getting changed while it is invisible.
  window2->Hide();
  window2->SetBounds(gfx::Rect(32, 48, 256, 512));
  window2->Show();

  // Check the initial position of the windows is unchanged.
  EXPECT_EQ("16,32 640x320", window1->bounds().ToString());
  EXPECT_EQ("32,48 256x512", window2->bounds().ToString());

  // Remove the second window and make sure that the first window
  // does NOT get centered.
  window2.reset();
  EXPECT_EQ("16,32 640x320", window1->bounds().ToString());

  // Test 2: Set up two managed windows and check their auto positioning.
  ash::wm::SetWindowPositionManaged(window1.get(), true);
  scoped_ptr<aura::Window> window3(CreateTestWindowInShellWithId(2));
  ash::wm::SetWindowPositionManaged(window3.get(), true);
  // To avoid any auto window manager changes due to SetBounds, the window
  // gets first hidden and then shown again.
  window3->Hide();
  window3->SetBounds(gfx::Rect(32, 48, 256, 512));
  window3->Show();
  // |window1| should be flush right and |window3| flush left.
  EXPECT_EQ("0,32 640x320", window1->bounds().ToString());
  EXPECT_EQ(base::IntToString(
                desktop_area.width() - window3->bounds().width()) +
            ",48 256x512", window3->bounds().ToString());

  // After removing |window3|, |window1| should be centered again.
  window3.reset();
  EXPECT_EQ(
      base::IntToString(
          (desktop_area.width() - window1->bounds().width()) / 2) +
      ",32 640x320", window1->bounds().ToString());

  // Test 3: Set up a manageable and a non manageable window and check
  // positioning.
  scoped_ptr<aura::Window> window4(CreateTestWindowInShellWithId(3));
  // To avoid any auto window manager changes due to SetBounds, the window
  // gets first hidden and then shown again.
  window1->Hide();
  window1->SetBounds(gfx::Rect(16, 32, 640, 320));
  window4->SetBounds(gfx::Rect(32, 48, 256, 512));
  window1->Show();
  // |window1| should be centered and |window4| untouched.
  EXPECT_EQ(
      base::IntToString(
          (desktop_area.width() - window1->bounds().width()) / 2) +
      ",32 640x320", window1->bounds().ToString());
  EXPECT_EQ("32,48 256x512", window4->bounds().ToString());

  // Test4: A single manageable window should get centered.
  window4.reset();
  ash::wm::SetUserHasChangedWindowPositionOrSize(window1.get(), false);
  // Trigger the auto window placement function by showing (and hiding) it.
  window1->Hide();
  window1->Show();
  // |window1| should be centered.
  EXPECT_EQ(
      base::IntToString(
          (desktop_area.width() - window1->bounds().width()) / 2) +
      ",32 640x320", window1->bounds().ToString());
}

// Test the proper usage of user window movement interaction.
TEST_F(WorkspaceManagerTest, TestUserMovedWindowRepositioning) {
  scoped_ptr<aura::Window> window1(CreateTestWindowInShellWithId(0));
  window1->SetBounds(gfx::Rect(16, 32, 640, 320));
  gfx::Rect desktop_area = window1->parent()->bounds();
  scoped_ptr<aura::Window> window2(CreateTestWindowInShellWithId(1));
  window2->SetBounds(gfx::Rect(32, 48, 256, 512));
  window1->Hide();
  window2->Hide();
  ash::wm::SetWindowPositionManaged(window1.get(), true);
  ash::wm::SetWindowPositionManaged(window2.get(), true);
  EXPECT_FALSE(ash::wm::HasUserChangedWindowPositionOrSize(window1.get()));
  EXPECT_FALSE(ash::wm::HasUserChangedWindowPositionOrSize(window2.get()));

  // Check that the current location gets preserved if the user has
  // positioned it previously.
  ash::wm::SetUserHasChangedWindowPositionOrSize(window1.get(), true);
  window1->Show();
  EXPECT_EQ("16,32 640x320", window1->bounds().ToString());
  // Flag should be still set.
  EXPECT_TRUE(ash::wm::HasUserChangedWindowPositionOrSize(window1.get()));
  EXPECT_FALSE(ash::wm::HasUserChangedWindowPositionOrSize(window2.get()));

  // Turn on the second window and make sure that both windows are now
  // positionable again (user movement cleared).
  window2->Show();

  // |window1| should be flush left and |window3| flush right.
  EXPECT_EQ("0,32 640x320", window1->bounds().ToString());
  EXPECT_EQ(
      base::IntToString(desktop_area.width() - window2->bounds().width()) +
      ",48 256x512", window2->bounds().ToString());
  // FLag should now be reset.
  EXPECT_FALSE(ash::wm::HasUserChangedWindowPositionOrSize(window1.get()));
  EXPECT_FALSE(ash::wm::HasUserChangedWindowPositionOrSize(window1.get()));

  // Going back to one shown window should keep the state.
  ash::wm::SetUserHasChangedWindowPositionOrSize(window1.get(), true);
  window2->Hide();
  EXPECT_EQ("0,32 640x320", window1->bounds().ToString());
  EXPECT_TRUE(ash::wm::HasUserChangedWindowPositionOrSize(window1.get()));
}

// Test that user placed windows go back to their user placement after the user
// closes all other windows.
TEST_F(WorkspaceManagerTest, TestUserHandledWindowRestore) {
  scoped_ptr<aura::Window> window1(CreateTestWindowInShellWithId(0));
  gfx::Rect user_pos = gfx::Rect(16, 42, 640, 320);
  window1->SetBounds(user_pos);
  ash::wm::SetPreAutoManageWindowBounds(window1.get(), user_pos);
  gfx::Rect desktop_area = window1->parent()->bounds();

  // Create a second window to let the auto manager kick in.
  scoped_ptr<aura::Window> window2(CreateTestWindowInShellWithId(1));
  window2->SetBounds(gfx::Rect(32, 48, 256, 512));
  window1->Hide();
  window2->Hide();
  ash::wm::SetWindowPositionManaged(window1.get(), true);
  ash::wm::SetWindowPositionManaged(window2.get(), true);
  window1->Show();
  EXPECT_EQ(user_pos.ToString(), window1->bounds().ToString());
  window2->Show();

  // |window1| should be flush left and |window2| flush right.
  EXPECT_EQ("0," + base::IntToString(user_pos.y()) +
            " 640x320", window1->bounds().ToString());
  EXPECT_EQ(
      base::IntToString(desktop_area.width() - window2->bounds().width()) +
      ",48 256x512", window2->bounds().ToString());
  window2->Hide();

  // After the other window get hidden the window has to move back to the
  // previous position and the bounds should still be set and unchanged.
  EXPECT_EQ(user_pos.ToString(), window1->bounds().ToString());
  ASSERT_TRUE(ash::wm::GetPreAutoManageWindowBounds(window1.get()));
  EXPECT_EQ(user_pos.ToString(),
            ash::wm::GetPreAutoManageWindowBounds(window1.get())->ToString());
}

// Test that a window from normal to minimize will repos the remaining.
TEST_F(WorkspaceManagerTest, ToMinimizeRepositionsRemaining) {
  scoped_ptr<aura::Window> window1(CreateTestWindowInShellWithId(0));
  ash::wm::SetWindowPositionManaged(window1.get(), true);
  window1->SetBounds(gfx::Rect(16, 32, 640, 320));
  gfx::Rect desktop_area = window1->parent()->bounds();

  scoped_ptr<aura::Window> window2(CreateTestWindowInShellWithId(1));
  ash::wm::SetWindowPositionManaged(window2.get(), true);
  window2->SetBounds(gfx::Rect(32, 48, 256, 512));

  ash::wm::MinimizeWindow(window1.get());

  // |window2| should be centered now.
  EXPECT_TRUE(window2->IsVisible());
  EXPECT_TRUE(ash::wm::IsWindowNormal(window2.get()));
  EXPECT_EQ(base::IntToString(
                (desktop_area.width() - window2->bounds().width()) / 2) +
            ",48 256x512", window2->bounds().ToString());

  ash::wm::RestoreWindow(window1.get());
  // |window1| should be flush right and |window3| flush left.
  EXPECT_EQ(base::IntToString(
                desktop_area.width() - window1->bounds().width()) +
            ",32 640x320", window1->bounds().ToString());
  EXPECT_EQ("0,48 256x512", window2->bounds().ToString());
}

// Test that minimizing an initially maximized window will repos the remaining.
TEST_F(WorkspaceManagerTest, MaxToMinRepositionsRemaining) {
  scoped_ptr<aura::Window> window1(CreateTestWindowInShellWithId(0));
  ash::wm::SetWindowPositionManaged(window1.get(), true);
  gfx::Rect desktop_area = window1->parent()->bounds();

  scoped_ptr<aura::Window> window2(CreateTestWindowInShellWithId(1));
  ash::wm::SetWindowPositionManaged(window2.get(), true);
  window2->SetBounds(gfx::Rect(32, 48, 256, 512));

  ash::wm::MaximizeWindow(window1.get());
  ash::wm::MinimizeWindow(window1.get());

  // |window2| should be centered now.
  EXPECT_TRUE(window2->IsVisible());
  EXPECT_TRUE(ash::wm::IsWindowNormal(window2.get()));
  EXPECT_EQ(base::IntToString(
                (desktop_area.width() - window2->bounds().width()) / 2) +
            ",48 256x512", window2->bounds().ToString());
}

// Test that nomral, maximize, minimizing will repos the remaining.
TEST_F(WorkspaceManagerTest, NormToMaxToMinRepositionsRemaining) {
  scoped_ptr<aura::Window> window1(CreateTestWindowInShellWithId(0));
  window1->SetBounds(gfx::Rect(16, 32, 640, 320));
  ash::wm::SetWindowPositionManaged(window1.get(), true);
  gfx::Rect desktop_area = window1->parent()->bounds();

  scoped_ptr<aura::Window> window2(CreateTestWindowInShellWithId(1));
  ash::wm::SetWindowPositionManaged(window2.get(), true);
  window2->SetBounds(gfx::Rect(32, 40, 256, 512));

  // Trigger the auto window placement function by showing (and hiding) it.
  window1->Hide();
  window1->Show();

  // |window1| should be flush right and |window3| flush left.
  EXPECT_EQ(base::IntToString(
                desktop_area.width() - window1->bounds().width()) +
            ",32 640x320", window1->bounds().ToString());
  EXPECT_EQ("0,40 256x512", window2->bounds().ToString());

  ash::wm::MaximizeWindow(window1.get());
  ash::wm::MinimizeWindow(window1.get());

  // |window2| should be centered now.
  EXPECT_TRUE(window2->IsVisible());
  EXPECT_TRUE(ash::wm::IsWindowNormal(window2.get()));
  EXPECT_EQ(base::IntToString(
                (desktop_area.width() - window2->bounds().width()) / 2) +
            ",40 256x512", window2->bounds().ToString());
}

// Test that nomral, maximize, normal will repos the remaining.
TEST_F(WorkspaceManagerTest, NormToMaxToNormRepositionsRemaining) {
  scoped_ptr<aura::Window> window1(CreateTestWindowInShellWithId(0));
  window1->SetBounds(gfx::Rect(16, 32, 640, 320));
  ash::wm::SetWindowPositionManaged(window1.get(), true);
  gfx::Rect desktop_area = window1->parent()->bounds();

  scoped_ptr<aura::Window> window2(CreateTestWindowInShellWithId(1));
  ash::wm::SetWindowPositionManaged(window2.get(), true);
  window2->SetBounds(gfx::Rect(32, 40, 256, 512));

  // Trigger the auto window placement function by showing (and hiding) it.
  window1->Hide();
  window1->Show();

  // |window1| should be flush right and |window3| flush left.
  EXPECT_EQ(base::IntToString(
                desktop_area.width() - window1->bounds().width()) +
            ",32 640x320", window1->bounds().ToString());
  EXPECT_EQ("0,40 256x512", window2->bounds().ToString());

  ash::wm::MaximizeWindow(window1.get());
  ash::wm::RestoreWindow(window1.get());

  // |window1| should be flush right and |window2| flush left.
  EXPECT_EQ(base::IntToString(
                desktop_area.width() - window1->bounds().width()) +
            ",32 640x320", window1->bounds().ToString());
  EXPECT_EQ("0,40 256x512", window2->bounds().ToString());
}

// Test that animations are triggered.
TEST_F(WorkspaceManagerTest, AnimatedNormToMaxToNormRepositionsRemaining) {
  ui::ScopedAnimationDurationScaleMode normal_duration_mode(
      ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
  scoped_ptr<aura::Window> window1(CreateTestWindowInShellWithId(0));
  window1->Hide();
  window1->SetBounds(gfx::Rect(16, 32, 640, 320));
  gfx::Rect desktop_area = window1->parent()->bounds();
  scoped_ptr<aura::Window> window2(CreateTestWindowInShellWithId(1));
  window2->Hide();
  window2->SetBounds(gfx::Rect(32, 48, 256, 512));

  ash::wm::SetWindowPositionManaged(window1.get(), true);
  ash::wm::SetWindowPositionManaged(window2.get(), true);
  // Make sure nothing is animating.
  window1->layer()->GetAnimator()->StopAnimating();
  window2->layer()->GetAnimator()->StopAnimating();
  window2->Show();

  // The second window should now animate.
  EXPECT_FALSE(window1->layer()->GetAnimator()->is_animating());
  EXPECT_TRUE(window2->layer()->GetAnimator()->is_animating());
  window2->layer()->GetAnimator()->StopAnimating();

  window1->Show();
  EXPECT_TRUE(window1->layer()->GetAnimator()->is_animating());
  EXPECT_TRUE(window2->layer()->GetAnimator()->is_animating());

  window1->layer()->GetAnimator()->StopAnimating();
  window2->layer()->GetAnimator()->StopAnimating();
  // |window1| should be flush right and |window2| flush left.
  EXPECT_EQ(base::IntToString(
                desktop_area.width() - window1->bounds().width()) +
            ",32 640x320", window1->bounds().ToString());
  EXPECT_EQ("0,48 256x512", window2->bounds().ToString());
}

// This tests simulates a browser and an app and verifies the ordering of the
// windows and layers doesn't get out of sync as various operations occur. Its
// really testing code in FocusController, but easier to simulate here. Just as
// with a real browser the browser here has a transient child window
// (corresponds to the status bubble).
TEST_F(WorkspaceManagerTest, VerifyLayerOrdering) {
  scoped_ptr<Window> browser(
      aura::test::CreateTestWindowWithDelegate(
          NULL,
          aura::client::WINDOW_TYPE_NORMAL,
          gfx::Rect(5, 6, 7, 8),
          NULL));
  browser->SetName("browser");
  SetDefaultParentByPrimaryRootWindow(browser.get());
  browser->Show();
  wm::ActivateWindow(browser.get());

  // |status_bubble| is made a transient child of |browser| and as a result
  // owned by |browser|.
  aura::test::TestWindowDelegate* status_bubble_delegate =
      aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate();
  status_bubble_delegate->set_can_focus(false);
  Window* status_bubble =
      aura::test::CreateTestWindowWithDelegate(
          status_bubble_delegate,
          aura::client::WINDOW_TYPE_POPUP,
          gfx::Rect(5, 6, 7, 8),
          NULL);
  browser->AddTransientChild(status_bubble);
  SetDefaultParentByPrimaryRootWindow(status_bubble);
  status_bubble->SetName("status_bubble");

  scoped_ptr<Window> app(
      aura::test::CreateTestWindowWithDelegate(
          NULL,
          aura::client::WINDOW_TYPE_NORMAL,
          gfx::Rect(5, 6, 7, 8),
          NULL));
  app->SetName("app");
  SetDefaultParentByPrimaryRootWindow(app.get());

  aura::Window* parent = browser->parent();

  app->Show();
  wm::ActivateWindow(app.get());
  EXPECT_EQ(GetWindowNames(parent), GetLayerNames(parent));

  // Minimize the app, focus should go the browser.
  app->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
  EXPECT_TRUE(wm::IsActiveWindow(browser.get()));
  EXPECT_EQ(GetWindowNames(parent), GetLayerNames(parent));

  // Minimize the browser (neither windows are focused).
  browser->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
  EXPECT_FALSE(wm::IsActiveWindow(browser.get()));
  EXPECT_FALSE(wm::IsActiveWindow(app.get()));
  EXPECT_EQ(GetWindowNames(parent), GetLayerNames(parent));

  // Show the browser (which should restore it).
  browser->Show();
  EXPECT_EQ(GetWindowNames(parent), GetLayerNames(parent));

  // Activate the browser.
  ash::wm::ActivateWindow(browser.get());
  EXPECT_TRUE(wm::IsActiveWindow(browser.get()));
  EXPECT_EQ(GetWindowNames(parent), GetLayerNames(parent));

  // Restore the app. This differs from above code for |browser| as internally
  // the app code does this. Restoring this way or using Show() should not make
  // a difference.
  app->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
  EXPECT_EQ(GetWindowNames(parent), GetLayerNames(parent));

  // Activate the app.
  ash::wm::ActivateWindow(app.get());
  EXPECT_TRUE(wm::IsActiveWindow(app.get()));
  EXPECT_EQ(GetWindowNames(parent), GetLayerNames(parent));
}

namespace {

// Used by DragMaximizedNonTrackedWindow to track how many times the window
// hierarchy changes.
class DragMaximizedNonTrackedWindowObserver
    : public aura::WindowObserver {
 public:
  DragMaximizedNonTrackedWindowObserver() : change_count_(0) {
  }

  // Number of times OnWindowHierarchyChanged() has been received.
  void clear_change_count() { change_count_ = 0; }
  int change_count() const {
    return change_count_;
  }

  // aura::WindowObserver overrides:
  virtual void OnWindowHierarchyChanged(
      const HierarchyChangeParams& params) OVERRIDE {
    change_count_++;
  }

 private:
  int change_count_;

  DISALLOW_COPY_AND_ASSIGN(DragMaximizedNonTrackedWindowObserver);
};

}  // namespace

// Verifies setting tracked by workspace to false and then dragging a maximized
// window doesn't result in changing the window hierarchy (which typically
// indicates new workspaces have been created).
TEST_F(WorkspaceManagerTest, DragMaximizedNonTrackedWindow) {
  aura::test::EventGenerator generator(
      Shell::GetPrimaryRootWindow(), gfx::Point());
  generator.MoveMouseTo(5, 5);

  aura::test::TestWindowDelegate delegate;
  delegate.set_window_component(HTCAPTION);
  scoped_ptr<Window> w1(
      aura::test::CreateTestWindowWithDelegate(&delegate,
                                               aura::client::WINDOW_TYPE_NORMAL,
                                               gfx::Rect(5, 6, 7, 8),
                                               NULL));
  SetDefaultParentByPrimaryRootWindow(w1.get());
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  w1->Show();
  wm::ActivateWindow(w1.get());
  DragMaximizedNonTrackedWindowObserver observer;
  w1->parent()->parent()->AddObserver(&observer);
  const gfx::Rect max_bounds(w1->bounds());

  // There should be two workspace, one for the desktop and one for the
  // maximized window with the maximized active.
  EXPECT_EQ("0 M1 active=1", StateString());

  generator.PressLeftButton();
  generator.MoveMouseTo(100, 100);
  // The bounds shouldn't change (drag should result in nothing happening
  // now.
  EXPECT_EQ(max_bounds.ToString(), w1->bounds().ToString());
  EXPECT_EQ("0 M1 active=1", StateString());

  generator.ReleaseLeftButton();
  EXPECT_EQ(0, observer.change_count());

  // Set tracked to false and repeat, now the window should move.
  SetTrackedByWorkspace(w1.get(), false);
  generator.MoveMouseTo(5, 5);
  generator.PressLeftButton();
  generator.MoveMouseBy(100, 100);
  EXPECT_EQ(gfx::Rect(max_bounds.x() + 100, max_bounds.y() + 100,
                      max_bounds.width(), max_bounds.height()).ToString(),
            w1->bounds().ToString());
  EXPECT_EQ("0 M1 active=1", StateString());

  generator.ReleaseLeftButton();
  SetTrackedByWorkspace(w1.get(), true);
  // Marking the window tracked again should snap back to origin.
  EXPECT_EQ("0 M1 active=1", StateString());
  EXPECT_EQ(max_bounds.ToString(), w1->bounds().ToString());
  EXPECT_EQ(0, observer.change_count());

  w1->parent()->parent()->RemoveObserver(&observer);
}

// Verifies that a new maximized window becomes visible after its activation
// is requested, even though it does not become activated because a system
// modal window is active.
TEST_F(WorkspaceManagerTest, SwitchFromModal) {
  scoped_ptr<Window> modal_window(CreateTestWindowUnparented());
  modal_window->SetBounds(gfx::Rect(10, 11, 21, 22));
  modal_window->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_SYSTEM);
  SetDefaultParentByPrimaryRootWindow(modal_window.get());
  modal_window->Show();
  wm::ActivateWindow(modal_window.get());

  scoped_ptr<Window> maximized_window(CreateTestWindow());
  maximized_window->SetProperty(
      aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  maximized_window->Show();
  wm::ActivateWindow(maximized_window.get());
  EXPECT_TRUE(maximized_window->IsVisible());
}

}  // namespace internal
}  // namespace ash


text:
package org.openksavi.sponge.test.script;

public interface EventsTest extends ScriptTest {

    void testClonePolicy();

    void testCron();

    void testRemovingEvent();
}

redpajama_set_name: RedPajamaGithub


text:
extern "C" {
#include "nodes/plannodes.h"
}

namespace gpdxl
{
// fwd decl
class CDXLTranslateContext;

using HMUlDxltrctx =
	CHashMap<ULONG, CDXLTranslateContext, gpos::HashValue<ULONG>,
			 gpos::Equals<ULONG>, CleanupDelete<ULONG>,
			 CleanupDelete<CDXLTranslateContext>>;

//---------------------------------------------------------------------------
//	@class:
//		CContextDXLToPlStmt
//
//	@doc:
//		Class providing access to CIdGenerators (needed to number initplans, motion
//		nodes as well as params), list of RangeTableEntries and Subplans
//		generated so far during DXL-->PlStmt translation.
//
//---------------------------------------------------------------------------
class CContextDXLToPlStmt
{
private:
	// cte consumer information
	struct SCTEConsumerInfo
	{
		// list of ShareInputScan represent cte consumers
		List *m_cte_consumer_list;

		// ctor
		SCTEConsumerInfo(List *plan_cte) : m_cte_consumer_list(plan_cte)
		{
		}

		void
		AddCTEPlan(ShareInputScan *share_input_scan)
		{
			GPOS_ASSERT(nullptr != share_input_scan);
			m_cte_consumer_list =
				gpdb::LAppend(m_cte_consumer_list, share_input_scan);
		}

		~SCTEConsumerInfo()
		{
			gpdb::ListFree(m_cte_consumer_list);
		}
	};

	// hash maps mapping ULONG -> SCTEConsumerInfo
	using HMUlCTEConsumerInfo =
		CHashMap<ULONG, SCTEConsumerInfo, gpos::HashValue<ULONG>,
				 gpos::Equals<ULONG>, CleanupDelete<ULONG>,
				 CleanupDelete<SCTEConsumerInfo>>;

	CMemoryPool *m_mp;

	// counter for generating plan ids
	CIdGenerator *m_plan_id_counter;

	// counter for generating motion ids
	CIdGenerator *m_motion_id_counter;

	// counter for generating unique param ids
	CIdGenerator *m_param_id_counter;
	List *m_param_types_list;

	// What operator classes to use for distribution keys?
	DistributionHashOpsKind m_distribution_hashops;

	// list of all rtable entries
	List *m_rtable_entries_list;

	// list of oids of partitioned tables
	List *m_partitioned_tables_list;

	// number of partition selectors for each dynamic scan
	ULongPtrArray *m_num_partition_selectors_array;

	// list of all subplan entries
	List *m_subplan_entries_list;
	List *m_subplan_sliceids_list;

	// List of PlanSlices
	List *m_slices_list;

	PlanSlice *m_current_slice;

	// index of the target relation in the rtable or 0 if not a DML statement
	ULONG m_result_relation_index;

	// hash map of the cte identifiers and the cte consumers with the same cte identifier
	HMUlCTEConsumerInfo *m_cte_consumer_info;

	// into clause
	IntoClause *m_into_clause;

	// CTAS distribution policy
	GpPolicy *m_distribution_policy;

	// FXIME: this uses NEW/DELETE, should we use palloc/pfree/memory pool?
	std::vector<List *> m_static_prune_results;

	UlongToUlongMap *m_part_selector_to_param_map;

public:
	// ctor/dtor
	CContextDXLToPlStmt(CMemoryPool *mp, CIdGenerator *plan_id_counter,
						CIdGenerator *motion_id_counter,
						CIdGenerator *param_id_counter,
						DistributionHashOpsKind distribution_hashops);

	// dtor
	~CContextDXLToPlStmt();

	// retrieve the next plan id
	ULONG GetNextPlanId();

	// retrieve the current motion id
	ULONG GetCurrentMotionId();

	// retrieve the next motion id
	ULONG GetNextMotionId();

	// retrieve the current parameter type list
	List *GetParamTypes();

	// retrieve the next parameter id
	ULONG GetNextParamId(OID typeoid);

	// add a newly found CTE consumer
	void AddCTEConsumerInfo(ULONG cte_id, ShareInputScan *share_input_scan);

	// return the list of shared input scan plans representing the CTE consumers
	List *GetCTEConsumerList(ULONG cte_id) const;

	// return list of range table entries
	List *
	GetRTableEntriesList() const
	{
		return m_rtable_entries_list;
	}

	// return list of partitioned table indexes
	List *
	GetPartitionedTablesList() const
	{
		return m_partitioned_tables_list;
	}

	// return list containing number of partition selectors for every scan id
	List *GetNumPartitionSelectorsList() const;

	List *
	GetSubplanEntriesList() const
	{
		return m_subplan_entries_list;
	}

	// index of result relation in the rtable
	ULONG
	GetResultRelationIndex() const
	{
		return m_result_relation_index;
	}

	int *GetSubplanSliceIdArray();

	PlanSlice *GetSlices(int *numSlices_p);

	// add a range table entry
	void AddRTE(RangeTblEntry *rte, BOOL is_result_relation = false);

	// add a partitioned table index
	void AddPartitionedTable(OID oid);

	// increment the number of partition selectors for the given scan id
	void IncrementPartitionSelectors(ULONG scan_id);

	void AddSubplan(Plan *);

	// add a slice table entry
	int AddSlice(PlanSlice *);

	PlanSlice *
	GetCurrentSlice() const
	{
		return m_current_slice;
	}

	void
	SetCurrentSlice(PlanSlice *slice)
	{
		m_current_slice = slice;
	}

	// add CTAS information
	void AddCtasInfo(IntoClause *into_clause, GpPolicy *distribution_policy);

	// into clause
	IntoClause *
	GetIntoClause() const
	{
		return m_into_clause;
	}

	// CTAS distribution policy
	GpPolicy *
	GetDistributionPolicy() const
	{
		return m_distribution_policy;
	}

	// Get the hash opclass or hash function for given datatype,
	// based on decision made by DetermineDistributionHashOpclasses()
	Oid GetDistributionHashOpclassForType(Oid typid);
	Oid GetDistributionHashFuncForType(Oid typid);

	List *GetStaticPruneResult(ULONG scanId);
	void SetStaticPruneResult(ULONG scanId, List *static_prune_result);

	ULONG GetParamIdForSelector(OID oid_type, const ULONG selectorId);

	Index FindRTE(Oid reloid);
};

}  // namespace gpdxl
#endif	// !GPDXL_CContextDXLToPlStmt_H

//EOF


text:
package mil.nga.giat.geowave.accumulo.mapreduce;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import mil.nga.giat.geowave.accumulo.AccumuloOperations;
import mil.nga.giat.geowave.accumulo.BasicAccumuloOperations;
import mil.nga.giat.geowave.index.ByteArrayId;
import mil.nga.giat.geowave.index.ByteArrayUtils;
import mil.nga.giat.geowave.index.PersistenceUtils;
import mil.nga.giat.geowave.store.adapter.DataAdapter;
import mil.nga.giat.geowave.store.index.Index;

import org.apache.accumulo.core.client.AccumuloException;
import org.apache.accumulo.core.client.AccumuloSecurityException;
import org.apache.accumulo.core.client.mapreduce.InputFormatBase;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.JobContext;
import org.apache.log4j.Logger;

/**
 * This class forms the basis for GeoWave input and output format configuration.
 */
public class GeoWaveConfiguratorBase
{
	protected static final Logger LOGGER = Logger.getLogger(GeoWaveConfiguratorBase.class);

	protected static enum GeoWaveMetaStore {
		INDEX,
		DATA_ADAPTER,
	}

	/**
	 * Configuration keys for AccumuloOperations configuration.
	 *
	 */
	protected static enum AccumuloOperationsConfig {
		ZOOKEEPER_URL,
		INSTANCE_NAME,
		USER_NAME,
		PASSWORD,
		TABLE_NAMESPACE
	}

	// TODO use these options to restrict creation when set (currently, within
	// the GeoWavevDataStore if anything doesn't exist it is automatically
	// persisted)
	protected static enum GeneralConfig {
		CREATE_ADAPTERS,
		CREATE_INDEX,
		CREATE_TABLES
	}

	/**
	 * Provides a configuration key for a given feature enum, prefixed by the
	 * implementingClass, and suffixed by a custom String
	 *
	 * @param implementingClass
	 *            the class whose name will be used as a prefix for the property
	 *            configuration key
	 * @param e
	 *            the enum used to provide the unique part of the configuration
	 *            key
	 *
	 * @param suffix
	 *            the custom suffix to be used in the configuration key
	 * @return the configuration key
	 */
	protected static String enumToConfKey(
			final Class<?> implementingClass,
			final Enum<?> e,
			final String suffix ) {
		return enumToConfKey(
				implementingClass,
				e) + "-" + suffix;
	}

	/**
	 * Provides a configuration key for a given feature enum, prefixed by the
	 * implementingClass
	 *
	 * @param implementingClass
	 *            the class whose name will be used as a prefix for the property
	 *            configuration key
	 * @param e
	 *            the enum used to provide the unique part of the configuration
	 *            key
	 * @return the configuration key
	 */
	protected static String enumToConfKey(
			final Class<?> implementingClass,
			final Enum<?> e ) {
		return implementingClass.getSimpleName() + "." + e.getDeclaringClass().getSimpleName() + "." + org.apache.hadoop.util.StringUtils.camelize(e.name().toLowerCase());
	}

	public static void setZookeeperUrl(
			final Class<?> implementingClass,
			final Job job,
			final String zookeeperUrl ) {
		if (zookeeperUrl != null) {
			job.getConfiguration().set(
					enumToConfKey(
							implementingClass,
							AccumuloOperationsConfig.ZOOKEEPER_URL),
					zookeeperUrl);
		}

	}

	public static AccumuloOperations getAccumuloOperations(
			final Class<?> implementingClass,
			final JobContext context )
			throws AccumuloException,
			AccumuloSecurityException {
		return new BasicAccumuloOperations(
				getZookeeperUrl(
						implementingClass,
						context),
				getInstanceName(
						implementingClass,
						context),
				getUserName(
						implementingClass,
						context),
				getPassword(
						implementingClass,
						context),
				getTableNamespace(
						implementingClass,
						context));
	}

	public static String getZookeeperUrl(
			final Class<?> implementingClass,
			final JobContext context ) {
		return getZookeeperUrlInternal(
				implementingClass,
				getConfiguration(context));
	}

	public static void setInstanceName(
			final Class<?> implementingClass,
			final Job job,
			final String instanceName ) {
		if (instanceName != null) {
			job.getConfiguration().set(
					enumToConfKey(
							implementingClass,
							AccumuloOperationsConfig.INSTANCE_NAME),
					instanceName);
		}

	}

	public static String getInstanceName(
			final Class<?> implementingClass,
			final JobContext context ) {
		return getInstanceNameInternal(
				implementingClass,
				getConfiguration(context));
	}

	public static void setUserName(
			final Class<?> implementingClass,
			final Job job,
			final String userName ) {
		if (userName != null) {
			job.getConfiguration().set(
					enumToConfKey(
							implementingClass,
							AccumuloOperationsConfig.USER_NAME),
					userName);
		}

	}

	public static String getUserName(
			final Class<?> implementingClass,
			final JobContext context ) {
		return getUserNameInternal(
				implementingClass,
				getConfiguration(context));
	}

	public static void setPassword(
			final Class<?> implementingClass,
			final Job job,
			final String password ) {
		if (password != null) {
			job.getConfiguration().set(
					enumToConfKey(
							implementingClass,
							AccumuloOperationsConfig.PASSWORD),
					password);
		}
	}

	public static String getPassword(
			final Class<?> implementingClass,
			final JobContext context ) {
		return getPasswordInternal(
				implementingClass,
				getConfiguration(context));
	}

	public static void setTableNamespace(
			final Class<?> implementingClass,
			final Job job,
			final String tableNamespace ) {
		if (tableNamespace != null) {
			job.getConfiguration().set(
					enumToConfKey(
							implementingClass,
							AccumuloOperationsConfig.TABLE_NAMESPACE),
					tableNamespace);
		}
	}

	public static String getTableNamespace(
			final Class<?> implementingClass,
			final JobContext context ) {
		return getTableNamespaceInternal(
				implementingClass,
				getConfiguration(context));
	}

	public static void addIndex(
			final Class<?> implementingClass,
			final Job job,
			final Index index ) {
		if (index != null) {
			job.getConfiguration().set(
					enumToConfKey(
							implementingClass,
							GeoWaveMetaStore.INDEX,
							index.getId().getString()),
					ByteArrayUtils.byteArrayToString(PersistenceUtils.toBinary(index)));
		}
	}

	public static Index getIndex(
			final Class<?> implementingClass,
			final JobContext context,
			final ByteArrayId indexId ) {
		return getIndexInternal(
				implementingClass,
				getConfiguration(context),
				indexId);
	}

	public static void addDataAdapter(
			final Class<?> implementingClass,
			final Job job,
			final DataAdapter<?> adapter ) {
		if (adapter != null) {
			job.getConfiguration().set(
					enumToConfKey(
							implementingClass,
							GeoWaveMetaStore.DATA_ADAPTER,
							adapter.getAdapterId().getString()),
					ByteArrayUtils.byteArrayToString(PersistenceUtils.toBinary(adapter)));
		}
	}

	public static DataAdapter<?> getDataAdapter(
			final Class<?> implementingClass,
			final JobContext context,
			final ByteArrayId adapterId ) {
		return getDataAdapterInternal(
				implementingClass,
				getConfiguration(context),
				adapterId);
	}

	private static DataAdapter<?> getDataAdapterInternal(
			final Class<?> implementingClass,
			final Configuration configuration,
			final ByteArrayId adapterId ) {
		final String input = configuration.get(enumToConfKey(
				implementingClass,
				GeoWaveMetaStore.DATA_ADAPTER,
				adapterId.getString()));
		if (input != null) {
			final byte[] dataAdapterBytes = ByteArrayUtils.byteArrayFromString(input);
			return PersistenceUtils.fromBinary(
					dataAdapterBytes,
					DataAdapter.class);
		}
		return null;
	}

	public static DataAdapter<?>[] getDataAdapters(
			final Class<?> implementingClass,
			final JobContext context ) {
		return getDataAdaptersInternal(
				implementingClass,
				getConfiguration(context));
	}

	private static DataAdapter<?>[] getDataAdaptersInternal(
			final Class<?> implementingClass,
			final Configuration configuration ) {
		final Map<String, String> input = configuration.getValByRegex(enumToConfKey(
				implementingClass,
				GeoWaveMetaStore.DATA_ADAPTER) + "*");
		if (input != null) {
			final List<DataAdapter<?>> adapters = new ArrayList<DataAdapter<?>>(
					input.size());
			for (final String dataAdapterStr : input.values()) {
				final byte[] dataAdapterBytes = ByteArrayUtils.byteArrayFromString(dataAdapterStr);
				adapters.add(PersistenceUtils.fromBinary(
						dataAdapterBytes,
						DataAdapter.class));
			}
			return adapters.toArray(new DataAdapter[] {});
		}
		return new DataAdapter[] {};
	}

	private static Boolean canCreateAdaptersInternal(
			final Class<?> implementingClass,
			final Configuration configuration ) {
		return configuration.getBoolean(
				enumToConfKey(
						implementingClass,
						GeneralConfig.CREATE_ADAPTERS),
				true);
	}

	public static Boolean canCreateAdapters(
			final Class<?> implementingClass,
			final JobContext context ) {
		return canCreateAdaptersInternal(
				implementingClass,
				getConfiguration(context));
	}

	public static void setCreateAdapters(
			final Class<?> implementingClass,
			final Job job,
			final boolean enableFeature ) {
		job.getConfiguration().setBoolean(
				enumToConfKey(
						implementingClass,
						GeneralConfig.CREATE_ADAPTERS),
				enableFeature);
	}

	private static Index getIndexInternal(
			final Class<?> implementingClass,
			final Configuration configuration,
			final ByteArrayId indexId ) {
		final String input = configuration.get(enumToConfKey(
				implementingClass,
				GeoWaveMetaStore.INDEX,
				indexId.getString()));
		if (input != null) {
			final byte[] indexBytes = ByteArrayUtils.byteArrayFromString(input);
			return PersistenceUtils.fromBinary(
					indexBytes,
					Index.class);
		}
		return null;
	}

	public static Index[] getIndices(
			final Class<?> implementingClass,
			final JobContext context ) {
		return getIndicesInternal(
				implementingClass,
				getConfiguration(context));
	}

	private static Index[] getIndicesInternal(
			final Class<?> implementingClass,
			final Configuration configuration ) {
		final Map<String, String> input = configuration.getValByRegex(enumToConfKey(
				implementingClass,
				GeoWaveMetaStore.INDEX) + "*");
		if (input != null) {
			final List<Index> indices = new ArrayList<Index>(
					input.size());
			for (final String indexStr : input.values()) {
				final byte[] indexBytes = ByteArrayUtils.byteArrayFromString(indexStr);
				indices.add(PersistenceUtils.fromBinary(
						indexBytes,
						Index.class));
			}
			return indices.toArray(new Index[] {});
		}
		return new Index[] {};
	}

	private static String getTableNamespaceInternal(
			final Class<?> implementingClass,
			final Configuration configuration ) {
		return configuration.get(
				enumToConfKey(
						implementingClass,
						AccumuloOperationsConfig.TABLE_NAMESPACE),
				"");
	}

	private static String getInstanceNameInternal(
			final Class<?> implementingClass,
			final Configuration configuration ) {
		return configuration.get(
				enumToConfKey(
						implementingClass,
						AccumuloOperationsConfig.INSTANCE_NAME),
				"");
	}

	private static String getZookeeperUrlInternal(
			final Class<?> implementingClass,
			final Configuration configuration ) {
		return configuration.get(
				enumToConfKey(
						implementingClass,
						AccumuloOperationsConfig.ZOOKEEPER_URL),
				"");
	}

	private static String getUserNameInternal(
			final Class<?> implementingClass,
			final Configuration configuration ) {
		return configuration.get(
				enumToConfKey(
						implementingClass,
						AccumuloOperationsConfig.USER_NAME),
				"");
	}

	private static String getPasswordInternal(
			final Class<?> implementingClass,
			final Configuration configuration ) {
		return configuration.get(
				enumToConfKey(
						implementingClass,
						AccumuloOperationsConfig.PASSWORD),
				"");
	}

	// use reflection to pull the Configuration out of the JobContext for Hadoop
	// 1 and Hadoop 2 compatibility
	public static Configuration getConfiguration(
			final JobContext context ) {
		try {
			final Class<?> c = InputFormatBase.class.getClassLoader().loadClass(
					"org.apache.hadoop.mapreduce.JobContext");
			final Method m = c.getMethod("getConfiguration");
			final Object o = m.invoke(
					context,
					new Object[0]);
			return (Configuration) o;
		}
		catch (final Exception e) {
			throw new RuntimeException(
					e);
		}
	}
}


text:
package com.byteperceptions.require.gui.stockpurchase;

import java.awt.Color;

import javax.swing.JButton;

import com.byteperceptions.require.model.HotelChain;

/**
 * @author Ryan Ylitalo
 *
 */
public class StocksPurchaseButton extends JButton
{
	private static final long serialVersionUID = 1L;

	private Color originalColor;
	private HotelPurchaseButton hotelPurchaseButton;

	public StocksPurchaseButton()
	{
		super("Stock Purchase");
		originalColor = this.getBackground();
	}

	public void setHotelPurchaseButton(HotelPurchaseButton hotelPurchaseButton)
	{
		this.hotelPurchaseButton = hotelPurchaseButton;
		if (hotelPurchaseButton == null)
		{
			setBackground(originalColor);
			setText("Stock Purchase");
			setForeground(Color.BLACK);
		}
		else
		{
			setBackground(hotelPurchaseButton.getHotelChain().getColor());
			if(hotelPurchaseButton.getHotelChain() == HotelChain.AMERICAN)
			{
				setForeground(Color.WHITE);
			}
			setText(hotelPurchaseButton.getHotelChain().getLabel() + " $" + hotelPurchaseButton.getHotelChain().getPrice());
			hotelPurchaseButton.decrementSharesRemaining();
		}
	}

	public HotelPurchaseButton getHotelPurchaseButton()
	{
		return hotelPurchaseButton;
	}

}


text:
<?php

/**
 * Created by PhpStorm.
 * User: alexwinter
 * Date: 04.02.18
 * Time: 14:36
 */

namespace BitcoinVietnam\BitcoinVietnam\Request\Withdrawal\PostWithdrawal;

use BitcoinVietnam\BitcoinVietnam\Request\Withdrawal\PostWithdrawal\Withdrawal\Payout;
use JMS\Serializer\Annotation as Serializer;

/**
 * Class Withdrawal
 * @package BitcoinVietnam\BitcoinVietnam\Request\Withdrawal\PostWithdrawal
 */
class Withdrawal
{
    /**
     * @var float
     *
     * @Serializer\Type("float")
     * @Serializer\SerializedName("amount")
     */
    private $amount;

    /**
     * @var string
     *
     * @Serializer\Type("string")
     * @Serializer\SerializedName("currency")
     */
    private $currency;

    /**
     * @var Payout
     *
     * @Serializer\Type("BitcoinVietnam\BitcoinVietnam\Request\Withdrawal\PostWithdrawal\Withdrawal\Payout")
     * @Serializer\SerializedName("payout")
     */
    private $payout;

    /**
     * Withdrawal constructor.
     */
    public function __construct()
    {
        $this->payout = new Payout();
    }

    /**
     * @return float
     */
    public function getAmount()
    {
        return $this->amount;
    }

    /**
     * @param float $amount
     * @return Withdrawal
     */
    public function setAmount($amount)
    {
        $this->amount = $amount;
        return $this;
    }

    /**
     * @return string
     */
    public function getCurrency()
    {
        return $this->currency;
    }

    /**
     * @param string $currency
     * @return Withdrawal
     */
    public function setCurrency($currency)
    {
        $this->currency = $currency;
        return $this;
    }

    /**
     * @return Payout
     */
    public function getPayout()
    {
        return $this->payout;
    }

    /**
     * @param Payout $payout
     * @return Withdrawal
     */
    public function setPayout($payout)
    {
        $this->payout = $payout;
        return $this;
    }
}


text:
<?php

namespace Brazanation\Doctrine\Tests\Types;

use Brazanation\Doctrine;
use Brazanation\Documents\Cnpj;

class CnpjTypeTest extends TestCase
{
    public function getTypeName()
    {
        return Doctrine\DocumentType::CNPJ;
    }

    public function getTypeClass()
    {
        return Doctrine\Types\CnpjType::class;
    }

    public function provideValidToDatabaseValue()
    {
        return [
            ['49367159000138', new Cnpj('49367159000138')],
        ];
    }

    public function provideValidToPHPValue()
    {
        return [
            [new Cnpj('49367159000138'), '49367159000138'],
        ];
    }

    public function provideValidSQLDeclaration()
    {
        return [
            'length' => Cnpj::LENGTH,
            'fixed' => Doctrine\Types\CnpjType::FIELD_FIXED,
        ];
    }
}


text:
<?php

namespace allejo\stakx\Document;

/**
 * A document that will have a permalink.
 */
interface PermalinkDocument
{
    /**
     * If a document has extra redirects defined in a special manner, overload this function.
     *
     * @return void
     */
    public function handleSpecialRedirects();

    /**
     * Get the destination of where this Content Item would be written to when the website is compiled.
     *
     * @param $permalink string|null Get the target file from a given permalink. When this is null, it will call the
     *                               `permalink()` method.
     *
     * @return string
     */
    public function getTargetFile($permalink = null);

    /**
     * Get the permalink of this Content Item.
     *
     * @return string
     */
    public function getPermalink();

    /**
     * Get an array of URLs that will redirect to.
     *
     * @return string[]
     */
    public function getRedirects();

    /**
     * Get the relative path to the file, with respect to the site root.
     *
     * @return string
     */
    public function getRelativeFilePath();

    /**
     * Build the permalink from whatever information is available.
     *
     * For example, this function can take information from FrontMatter and build the permalink from there.
     *
     * @param bool $force permalinks are often cached internal; set to true to force the permalink to be rebuilt
     *
     * @return void
     */
    public function buildPermalink($force = false);
}


text:
package com.asakusafw.dmdl.analyzer.driver;

import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;

import org.junit.Before;
import org.junit.Test;

import com.asakusafw.dmdl.DmdlTesterRoot;
import com.asakusafw.dmdl.semantics.DmdlSemantics;
import com.asakusafw.dmdl.semantics.ModelDeclaration;
import com.asakusafw.dmdl.semantics.trait.NamespaceTrait;

/**
 * Test for {@link NamespaceDriver}.
 */
public class NamespaceDriverTest extends DmdlTesterRoot {

    /**
     * Initializes the test.
     * @throws Exception if some errors were occurred
     */
    @Before
    public void setUp() throws Exception {
        attributeDrivers.add(new NamespaceDriver());
    }

    /**
     * simple namespace.
     */
    @Test
    public void namespace() {
        DmdlSemantics world = resolve();
        ModelDeclaration model = world.findModelDeclaration("simple");
        assertThat(model.getSymbol(), is(model("simple")));

        NamespaceTrait trait = model.getTrait(NamespaceTrait.class);
        assertThat(trait, not(nullValue()));
        assertThat(trait.getNamespace().toString(), is("com.example"));
    }

    /**
     * namespace is not specified.
     */
    @Test
    public void empty() {
        DmdlSemantics world = resolve();
        ModelDeclaration model = world.findModelDeclaration("simple");
        assertThat(model.getSymbol(), is(model("simple")));

        NamespaceTrait trait = model.getTrait(NamespaceTrait.class);
        assertThat(trait, nullValue());
    }

    /**
     * namespace is attached to property.
     */
    @Test
    public void invalid_namespace_property() {
        shouldSemanticError();
    }

    /**
     * missing element.
     */
    @Test
    public void invalid_namespace_empty() {
        shouldSemanticError();
    }

    /**
     * extra element.
     */
    @Test
    public void invalid_namespace_extra() {
        shouldSemanticError();
    }

    /**
     * inconsistent type.
     */
    @Test
    public void invalid_namespace_string() {
        shouldSemanticError();
    }
}


text:
import os
import json

from jedi._compatibility import FileNotFoundError, NotADirectoryError
from jedi.api.environment import SameEnvironment, \
    get_cached_default_environment
from jedi.api.exceptions import WrongVersion
from jedi._compatibility import force_unicode
from jedi.evaluate.sys_path import discover_buildout_paths
from jedi.evaluate.cache import evaluator_as_method_param_cache
from jedi.common.utils import traverse_parents

_CONFIG_FOLDER = '.jedi'
_CONTAINS_POTENTIAL_PROJECT = 'setup.py', '.git', '.hg', 'requirements.txt', 'MANIFEST.in'

_SERIALIZER_VERSION = 1

def _remove_duplicates_from_path(path):
    used = set()
    for p in path:
        if p in used:
            continue
        used.add(p)
        yield p

def _force_unicode_list(lst):
    return list(map(force_unicode, lst))

class Project(object):
    # TODO serialize environment
    _serializer_ignore_attributes = ('_environment',)
    _environment = None

    @staticmethod
    def _get_json_path(base_path):
        return os.path.join(base_path, _CONFIG_FOLDER, 'project.json')

    @classmethod
    def load(cls, path):
        """
        :param path: The path of the directory you want to use as a project.
        """
        with open(cls._get_json_path(path)) as f:
            version, data = json.load(f)

        if version == 1:
            self = cls.__new__()
            self.__dict__.update(data)
            return self
        else:
            raise WrongVersion(
                "The Jedi version of this project seems newer than what we can handle."
            )

    def __init__(self, path, **kwargs):
        """
        :param path: The base path for this project.
        :param sys_path: list of str. You can override the sys path if you
            want. By default the ``sys.path.`` is generated from the
            environment (virtualenvs, etc).
        :param smart_sys_path: If this is enabled (default), adds paths from
            local directories. Otherwise you will have to rely on your packages
            being properly configured on the ``sys.path``.
        """
        def py2_comp(path, environment=None, sys_path=None,
                     smart_sys_path=True, _django=False):
            self._path = path
            if isinstance(environment, SameEnvironment):
                self._environment = environment

            self._sys_path = sys_path
            self._smart_sys_path = smart_sys_path
            self._django = _django

        py2_comp(path, **kwargs)

    def _get_base_sys_path(self, environment=None):
        if self._sys_path is not None:
            return self._sys_path

        # The sys path has not been set explicitly.
        if environment is None:
            environment = self.get_environment()

        sys_path = list(environment.get_sys_path())
        try:
            sys_path.remove('')
        except ValueError:
            pass
        return sys_path

    @evaluator_as_method_param_cache()
    def _get_sys_path(self, evaluator, environment=None):
        """
        Keep this method private for all users of jedi. However internally this
        one is used like a public method.
        """
        suffixed = []
        prefixed = []

        sys_path = list(self._get_base_sys_path(environment))
        if self._smart_sys_path:
            prefixed.append(self._path)

            if evaluator.script_path is not None:
                suffixed += discover_buildout_paths(evaluator, evaluator.script_path)

                traversed = list(traverse_parents(evaluator.script_path))

                # AFAIK some libraries have imports like `foo.foo.bar`, which
                # leads to the conclusion to by default prefer longer paths
                # rather than shorter ones by default.
                suffixed += reversed(traversed)

        if self._django:
            prefixed.append(self._path)

        path = prefixed + sys_path + suffixed
        return list(_force_unicode_list(_remove_duplicates_from_path(path)))

    def save(self):
        data = dict(self.__dict__)
        for attribute in self._serializer_ignore_attributes:
            data.pop(attribute, None)

        with open(self._get_json_path(self._path), 'wb') as f:
            return json.dump((_SERIALIZER_VERSION, data), f)

    def get_environment(self):
        if self._environment is None:
            return get_cached_default_environment()

        return self._environment

    def __repr__(self):
        return '<%s: %s>' % (self.__class__.__name__, self._path)

def _is_potential_project(path):
    for name in _CONTAINS_POTENTIAL_PROJECT:
        if os.path.exists(os.path.join(path, name)):
            return True
    return False

def _is_django_path(directory):
    """ Detects the path of the very well known Django library (if used) """
    try:
        with open(os.path.join(directory, 'manage.py'), 'rb') as f:
            return b"DJANGO_SETTINGS_MODULE" in f.read()
    except (FileNotFoundError, NotADirectoryError):
        return False

    return False

def get_default_project(path=None):
    if path is None:
        path = os.getcwd()

    check = os.path.realpath(path)
    probable_path = None
    first_no_init_file = None
    for dir in traverse_parents(check, include_current=True):
        try:
            return Project.load(dir)
        except (FileNotFoundError, NotADirectoryError):
            pass

        if first_no_init_file is None:
            if os.path.exists(os.path.join(dir, '__init__.py')):
                # In the case that a __init__.py exists, it's in 99% just a
                # Python package and the project sits at least one level above.
                continue
            else:
                first_no_init_file = dir

        if _is_django_path(dir):
            return Project(dir, _django=True)

        if probable_path is None and _is_potential_project(dir):
            probable_path = dir

    if probable_path is not None:
        # TODO search for setup.py etc
        return Project(probable_path)

    if first_no_init_file is not None:
        return Project(first_no_init_file)

    curdir = path if os.path.isdir(path) else os.path.dirname(path)
    return Project(curdir)