Merge from Chromium at DEPS revision r198571

This commit was generated by merge_to_master.py.

Change-Id: I951118a03836157090561764dd2627f0add8118f
diff --git a/ash/DEPS b/ash/DEPS
index 7aa545b..29f9c96 100644
--- a/ash/DEPS
+++ b/ash/DEPS
@@ -1,4 +1,5 @@
 include_rules = [
+  "+cc/debug",
   "+chromeos",
   "+content/public",
   "+grit/ash_resources.h",
diff --git a/ash/OWNERS b/ash/OWNERS
index 07bb4ae..ab22b20 100644
--- a/ash/OWNERS
+++ b/ash/OWNERS
@@ -1,10 +1,11 @@
-ben@chromium.org
 derat@chromium.org
 jamescook@chromium.org
 sky@chromium.org
 
 per-file ash_strings.grd=*
 per-file ash_chromeos_strings.grdp=*
-per-file root_window_controller.*=oshima@chromium.org
-per-file screen_ash.*=oshima@chromium.org
+
+per-file ash_root_window_transformer.*=oshima@chromium.org
 per-file extended_desktop_unittest.*=oshima@chromium.org
+per-file root_window_controller*=oshima@chromium.org
+per-file screen_ash*=oshima@chromium.org
diff --git a/ash/accelerators/accelerator_controller.cc b/ash/accelerators/accelerator_controller.cc
index 9a1f309..f7a9ecb 100644
--- a/ash/accelerators/accelerator_controller.cc
+++ b/ash/accelerators/accelerator_controller.cc
@@ -12,6 +12,7 @@
 #include "ash/accelerators/accelerator_table.h"
 #include "ash/ash_switches.h"
 #include "ash/caps_lock_delegate.h"
+#include "ash/debug.h"
 #include "ash/desktop_background/desktop_background_controller.h"
 #include "ash/desktop_background/user_wallpaper_delegate.h"
 #include "ash/display/display_controller.h"
@@ -26,6 +27,7 @@
 #include "ash/root_window_controller.h"
 #include "ash/rotator/screen_rotation.h"
 #include "ash/screenshot_delegate.h"
+#include "ash/session_state_delegate.h"
 #include "ash/shelf/shelf_widget.h"
 #include "ash/shell.h"
 #include "ash/shell_delegate.h"
@@ -59,6 +61,7 @@
 #include "ui/compositor/layer_animator.h"
 #include "ui/gfx/screen.h"
 #include "ui/oak/oak.h"
+#include "ui/views/controls/webview/webview.h"
 #include "ui/views/debug_utils.h"
 #include "ui/views/widget/widget.h"
 
@@ -72,11 +75,6 @@
 
 using internal::DisplayInfo;
 
-// Factor of magnification scale. For example, when this value is 1.189, scale
-// value will be changed x1.000, x1.189, x1.414, x1.681, x2.000, ...
-// Note: this value is 2.0 ^ (1 / 4).
-const float kMagnificationFactor = 1.18920712f;
-
 bool DebugShortcutsEnabled() {
 #if defined(NDEBUG)
   return CommandLine::ForCurrentProcess()->HasSwitch(
@@ -95,12 +93,41 @@
 }
 
 void HandleCycleWindowLinear(CycleDirection direction) {
-  Launcher::ForPrimaryDisplay()->CycleWindowLinear(direction);
+  Shell::GetInstance()->
+        window_cycle_controller()->HandleLinearCycleWindow();
+}
+
+bool HandleAccessibleFocusCycle(bool reverse) {
+  if (!Shell::GetInstance()->delegate()->IsSpokenFeedbackEnabled())
+    return false;
+  aura::Window* active_window = ash::wm::GetActiveWindow();
+  if (!active_window)
+    return false;
+  views::Widget* widget =
+      views::Widget::GetWidgetForNativeWindow(active_window);
+  if (!widget)
+    return false;
+  views::FocusManager* focus_manager = widget->GetFocusManager();
+  if (!focus_manager)
+    return false;
+  views::View* view = focus_manager->GetFocusedView();
+  if (view->GetClassName() == views::WebView::kViewClassName)
+    return false;
+
+  focus_manager->AdvanceFocus(reverse);
+  return true;
+}
+
+void HandleSilenceSpokenFeedback() {
+  if (!Shell::GetInstance()->delegate()->IsSpokenFeedbackEnabled())
+    return;
+
+  Shell::GetInstance()->delegate()->SilenceSpokenFeedback();
 }
 
 #if defined(OS_CHROMEOS)
 bool HandleLock() {
-  Shell::GetInstance()->delegate()->LockScreen();
+  Shell::GetInstance()->session_state_delegate()->LockScreen();
   return true;
 }
 
@@ -123,17 +150,14 @@
 #endif  // defined(OS_CHROMEOS)
 
 bool HandleRotatePaneFocus(Shell::Direction direction) {
-  if (!Shell::GetInstance()->delegate()->RotatePaneFocus(direction)) {
-    // No browser window is available. Focus the launcher.
-    Shell* shell = Shell::GetInstance();
-    switch (direction) {
-      case Shell::FORWARD:
-        shell->focus_cycler()->RotateFocus(internal::FocusCycler::FORWARD);
-        break;
-      case Shell::BACKWARD:
-        shell->focus_cycler()->RotateFocus(internal::FocusCycler::BACKWARD);
-        break;
-    }
+  Shell* shell = Shell::GetInstance();
+  switch (direction) {
+    case Shell::FORWARD:
+      shell->focus_cycler()->RotateFocus(internal::FocusCycler::FORWARD);
+      break;
+    case Shell::BACKWARD:
+      shell->focus_cycler()->RotateFocus(internal::FocusCycler::BACKWARD);
+      break;
   }
   return true;
 }
@@ -171,18 +195,25 @@
 }
 
 bool HandleScaleUI(bool up) {
-  // UI Scaling is effective only on internal display.
-  int64 display_id = gfx::Display::InternalDisplayId();
-#if defined(OS_CHROMEOS)
-  // On linux desktop, allow ui scalacing on the first dislpay.
-  if (!base::chromeos::IsRunningOnChromeOS())
-    display_id = Shell::GetInstance()->display_manager()->first_display_id();
-#endif
-  const DisplayInfo& display_info = Shell::GetInstance()->display_manager()->
-      GetDisplayInfo(display_id);
-  Shell::GetInstance()->display_manager()->SetDisplayUIScale(
-      display_id,
-      internal::DisplayManager::GetNextUIScale(display_info.ui_scale(), up));
+  internal::DisplayManager* display_manager =
+      Shell::GetInstance()->display_manager();
+  int64 display_id = display_manager->GetDisplayIdForUIScaling();
+  if (display_id == gfx::Display::kInvalidDisplayID)
+    return false;
+  const DisplayInfo& display_info = display_manager->GetDisplayInfo(display_id);
+  float next_scale =
+      internal::DisplayManager::GetNextUIScale(display_info, up);
+  display_manager->SetDisplayUIScale(display_id, next_scale);
+  return true;
+}
+
+bool HandleScaleReset() {
+  internal::DisplayManager* display_manager =
+      Shell::GetInstance()->display_manager();
+  int64 display_id = display_manager->GetDisplayIdForUIScaling();
+  if (display_id == gfx::Display::kInvalidDisplayID)
+    return false;
+  display_manager->SetDisplayUIScale(display_id, 1.0f);
   return true;
 }
 
@@ -219,18 +250,17 @@
 // Magnify the screen
 bool HandleMagnifyScreen(int delta_index) {
   if (ash::Shell::GetInstance()->magnification_controller()->IsEnabled()) {
-    // TODO(yoshiki): Create the class like MagnifierStepScaleController, and
-    // move the following scale control to it.
+    // TODO(yoshiki): Move the following logic to MagnificationController.
     float scale =
         ash::Shell::GetInstance()->magnification_controller()->GetScale();
-    // Calculate rounded logarithm (base kMagnificationFactor) of scale.
+    // Calculate rounded logarithm (base kMagnificationScaleFactor) of scale.
     int scale_index =
-        std::floor(std::log(scale) / std::log(kMagnificationFactor) + 0.5);
+        std::floor(std::log(scale) / std::log(kMagnificationScaleFactor) + 0.5);
 
     int new_scale_index = std::max(0, std::min(8, scale_index + delta_index));
 
     ash::Shell::GetInstance()->magnification_controller()->
-        SetScale(std::pow(kMagnificationFactor, new_scale_index), true);
+        SetScale(std::pow(kMagnificationScaleFactor, new_scale_index), true);
   } else if (ash::Shell::GetInstance()->
              partial_magnification_controller()->is_enabled()) {
     float scale = delta_index > 0 ? kDefaultPartialMagnifiedScale : 1;
@@ -365,6 +395,10 @@
 
   RegisterAccelerators(kAcceleratorData, kAcceleratorDataLength);
 
+#if !defined(NDEBUG)
+  RegisterAccelerators(kDesktopAcceleratorData, kDesktopAcceleratorDataLength);
+#endif
+
   if (DebugShortcutsEnabled())
     RegisterAccelerators(kDebugAcceleratorData, kDebugAcceleratorDataLength);
 
@@ -391,7 +425,7 @@
 }
 
 bool AcceleratorController::Process(const ui::Accelerator& accelerator) {
-  if (ime_control_delegate_.get()) {
+  if (ime_control_delegate_) {
     return accelerator_manager_->Process(
         ime_control_delegate_->RemapAccelerator(accelerator));
   }
@@ -419,16 +453,12 @@
 bool AcceleratorController::PerformAction(int action,
                                           const ui::Accelerator& accelerator) {
   ash::Shell* shell = ash::Shell::GetInstance();
-  bool at_login_screen = false;
-#if defined(OS_CHROMEOS)
-  at_login_screen = !shell->delegate()->IsSessionStarted();
-#endif
-  if (at_login_screen &&
+  if (!shell->session_state_delegate()->IsActiveUserSessionStarted() &&
       actions_allowed_at_login_screen_.find(action) ==
       actions_allowed_at_login_screen_.end()) {
     return false;
   }
-  if (shell->IsScreenLocked() &&
+  if (shell->session_state_delegate()->IsScreenLocked() &&
       actions_allowed_at_lock_screen_.find(action) ==
       actions_allowed_at_lock_screen_.end()) {
     return false;
@@ -470,6 +500,10 @@
   // function might be called *twice*, via BrowserView::PreHandleKeyboardEvent
   // and BrowserView::HandleKeyboardEvent, for a single accelerator press.
   switch (action) {
+    case ACCESSIBLE_FOCUS_NEXT:
+      return HandleAccessibleFocusCycle(false);
+    case ACCESSIBLE_FOCUS_PREVIOUS:
+      return HandleAccessibleFocusCycle(true);
     case CYCLE_BACKWARD_MRU:
       if (key_code == ui::VKEY_TAB)
         shell->delegate()->RecordUserMetricsAction(UMA_ACCEL_PREVWINDOW_TAB);
@@ -504,6 +538,9 @@
       return HandleFileManager(false /* as_dialog */);
     case OPEN_CROSH:
       return HandleCrosh();
+    case SILENCE_SPOKEN_FEEDBACK:
+      HandleSilenceSpokenFeedback();
+      break;
     case SWAP_PRIMARY_DISPLAY:
       Shell::GetInstance()->display_controller()->SwapPrimaryDisplay();
       return true;
@@ -512,18 +549,24 @@
     case TOGGLE_WIFI:
       Shell::GetInstance()->system_tray_delegate()->ToggleWifi();
       return true;
-    case TOUCH_HUD_CLEAR:
-      if (Shell::GetInstance()->touch_observer_hud()) {
-        Shell::GetInstance()->touch_observer_hud()->Clear();
+    case TOUCH_HUD_CLEAR: {
+      internal::RootWindowController* controller =
+          internal::RootWindowController::ForActiveRootWindow();
+      if (controller->touch_observer_hud()) {
+        controller->touch_observer_hud()->Clear();
         return true;
       }
       return false;
-    case TOUCH_HUD_MODE_CHANGE:
-      if (Shell::GetInstance()->touch_observer_hud()) {
-        Shell::GetInstance()->touch_observer_hud()->ChangeToNextMode();
+    }
+    case TOUCH_HUD_MODE_CHANGE: {
+      internal::RootWindowController* controller =
+          internal::RootWindowController::ForActiveRootWindow();
+      if (controller->touch_observer_hud()) {
+        controller->touch_observer_hud()->ChangeToNextMode();
         return true;
       }
       return false;
+    }
     case DISABLE_GPU_WATCHDOG:
       content::GpuDataManager::GetInstance()->DisableGpuWatchdog();
       return true;
@@ -556,7 +599,7 @@
       // Return true to prevent propagation of the key event.
       return true;
     case TAKE_PARTIAL_SCREENSHOT:
-      if (screenshot_delegate_.get()) {
+      if (screenshot_delegate_) {
         ash::PartialScreenshotView::StartPartialScreenshot(
             screenshot_delegate_.get());
       }
@@ -608,20 +651,20 @@
       shell->caps_lock_delegate()->ToggleCapsLock();
       return true;
     case BRIGHTNESS_DOWN:
-      if (brightness_control_delegate_.get())
+      if (brightness_control_delegate_)
         return brightness_control_delegate_->HandleBrightnessDown(accelerator);
       break;
     case BRIGHTNESS_UP:
-      if (brightness_control_delegate_.get())
+      if (brightness_control_delegate_)
         return brightness_control_delegate_->HandleBrightnessUp(accelerator);
       break;
     case KEYBOARD_BRIGHTNESS_DOWN:
-      if (keyboard_brightness_control_delegate_.get())
+      if (keyboard_brightness_control_delegate_)
         return keyboard_brightness_control_delegate_->
             HandleKeyboardBrightnessDown(accelerator);
       break;
     case KEYBOARD_BRIGHTNESS_UP:
-      if (keyboard_brightness_control_delegate_.get())
+      if (keyboard_brightness_control_delegate_)
         return keyboard_brightness_control_delegate_->
             HandleKeyboardBrightnessUp(accelerator);
       break;
@@ -700,17 +743,17 @@
         // TODO(mazda): Fix crbug.com/158217
         return false;
       }
-      if (ime_control_delegate_.get())
+      if (ime_control_delegate_)
         return ime_control_delegate_->HandleNextIme();
       break;
     case PREVIOUS_IME:
-      if (ime_control_delegate_.get())
+      if (ime_control_delegate_)
         return ime_control_delegate_->HandlePreviousIme();
       break;
     case PRINT_UI_HIERARCHIES:
       return HandlePrintUIHierarchies();
     case SWITCH_IME:
-      if (ime_control_delegate_.get())
+      if (ime_control_delegate_)
         return ime_control_delegate_->HandleSwitchIme(accelerator);
       break;
     case SELECT_WIN_0:
@@ -766,11 +809,21 @@
       // crbug.com/131709, which is a crashing issue related to minimizing
       // full screen pepper window.
       if (!wm::IsWindowFullscreen(window) && wm::CanMinimizeWindow(window)) {
+        ash::Shell::GetInstance()->delegate()->RecordUserMetricsAction(
+            ash::UMA_MINIMIZE_PER_KEY);
         wm::MinimizeWindow(window);
         return true;
       }
       break;
     }
+    case TOGGLE_FULLSCREEN: {
+      if (key_code == ui::VKEY_MEDIA_LAUNCH_APP2) {
+        shell->delegate()->RecordUserMetricsAction(
+            UMA_ACCEL_FULLSCREEN_F4);
+      }
+      shell->delegate()->ToggleFullscreen();
+      return true;
+    }
     case TOGGLE_MAXIMIZED: {
       if (key_code == ui::VKEY_MEDIA_LAUNCH_APP2) {
         shell->delegate()->RecordUserMetricsAction(
@@ -791,6 +844,8 @@
       return HandleScaleUI(true /* up */);
     case SCALE_UI_DOWN:
       return HandleScaleUI(false /* down */);
+    case SCALE_UI_RESET:
+      return HandleScaleReset();
     case ROTATE_WINDOW:
       return HandleRotateActiveWindow();
     case ROTATE_SCREEN:
@@ -799,9 +854,18 @@
       return HandleToggleDesktopBackgroundMode();
     case TOGGLE_ROOT_WINDOW_FULL_SCREEN:
       return HandleToggleRootWindowFullScreen();
-    case DISPLAY_TOGGLE_SCALE:
+    case DEBUG_TOGGLE_DEVICE_SCALE_FACTOR:
       internal::DisplayManager::ToggleDisplayScaleFactor();
       return true;
+    case DEBUG_TOGGLE_SHOW_DEBUG_BORDERS:
+      ash::debug::ToggleShowDebugBorders();
+      return true;
+    case DEBUG_TOGGLE_SHOW_FPS_COUNTER:
+      ash::debug::ToggleShowFpsCounter();
+      return true;
+    case DEBUG_TOGGLE_SHOW_PAINT_RECTS:
+      ash::debug::ToggleShowPaintRects();
+      return true;
     case MAGNIFY_SCREEN_ZOOM_IN:
       return HandleMagnifyScreen(1);
     case MAGNIFY_SCREEN_ZOOM_OUT:
diff --git a/ash/accelerators/accelerator_dispatcher.cc b/ash/accelerators/accelerator_dispatcher.cc
index 3dd60f8..91f0154 100644
--- a/ash/accelerators/accelerator_dispatcher.cc
+++ b/ash/accelerators/accelerator_dispatcher.cc
@@ -62,7 +62,8 @@
 }  // namespace
 
 AcceleratorDispatcher::AcceleratorDispatcher(
-    MessageLoop::Dispatcher* nested_dispatcher, aura::Window* associated_window)
+    base::MessageLoop::Dispatcher* nested_dispatcher,
+    aura::Window* associated_window)
     : nested_dispatcher_(nested_dispatcher),
       associated_window_(associated_window) {
   DCHECK(nested_dispatcher_);
diff --git a/ash/accelerators/accelerator_dispatcher.h b/ash/accelerators/accelerator_dispatcher.h
index d264a4b..c240b8d 100644
--- a/ash/accelerators/accelerator_dispatcher.h
+++ b/ash/accelerators/accelerator_dispatcher.h
@@ -19,10 +19,10 @@
 // TODO(pkotwicz): Port AcceleratorDispatcher to mac.
 // TODO(pkotwicz): Add support for a |nested_dispatcher| which sends
 //  events to a system IME.
-class ASH_EXPORT AcceleratorDispatcher : public MessageLoop::Dispatcher,
+class ASH_EXPORT AcceleratorDispatcher : public base::MessageLoop::Dispatcher,
                                          public aura::WindowObserver {
  public:
-  AcceleratorDispatcher(MessageLoop::Dispatcher* nested_dispatcher,
+  AcceleratorDispatcher(base::MessageLoop::Dispatcher* nested_dispatcher,
                         aura::Window* associated_window);
   virtual ~AcceleratorDispatcher();
 
@@ -33,7 +33,7 @@
   virtual void OnWindowDestroying(aura::Window* window) OVERRIDE;
 
  private:
-  MessageLoop::Dispatcher* nested_dispatcher_;
+  base::MessageLoop::Dispatcher* nested_dispatcher_;
 
   // Window associated with |nested_dispatcher_| which is used to determine
   // whether the |nested_dispatcher_| is allowed to receive events.
diff --git a/ash/accelerators/accelerator_table.cc b/ash/accelerators/accelerator_table.cc
index a8b21ca..62e4d81 100644
--- a/ash/accelerators/accelerator_table.cc
+++ b/ash/accelerators/accelerator_table.cc
@@ -64,25 +64,6 @@
   { false, ui::VKEY_F13, ui::EF_NONE, LOCK_RELEASED },
   { true, ui::VKEY_POWER, ui::EF_NONE, POWER_PRESSED },
   { false, ui::VKEY_POWER, ui::EF_NONE, POWER_RELEASED },
-#if !defined(NDEBUG)
-  // Extra shortcut for debug build to control magnifier on linux desktop.
-  { true, ui::VKEY_BRIGHTNESS_DOWN, ui::EF_CONTROL_DOWN,
-    MAGNIFY_SCREEN_ZOOM_OUT},
-  { true, ui::VKEY_BRIGHTNESS_UP, ui::EF_CONTROL_DOWN, MAGNIFY_SCREEN_ZOOM_IN},
-  // Extra shortcut for debug build to activate lock screen on linux desktop.
-  { true, ui::VKEY_L, ui::EF_ALT_DOWN, LOCK_SCREEN },
-  // Extra shortcut for display swaping as alt-f4 is taken on linux desktop.
-  { true, ui::VKEY_F4, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN,
-    SWAP_PRIMARY_DISPLAY },
-  // Extra shortcut to lock the screen on linux desktop.
-  { true, ui::VKEY_POWER, ui::EF_SHIFT_DOWN, LOCK_PRESSED },
-  { false, ui::VKEY_POWER, ui::EF_SHIFT_DOWN, LOCK_RELEASED },
-  // Extra shortcut to rotate/scale up/down the screen on linux desktop.
-  { true, ui::VKEY_F3, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, ROTATE_SCREEN },
-  { true, ui::VKEY_F2, ui::EF_CONTROL_DOWN , SCALE_UI_UP },
-  { true, ui::VKEY_F2,
-    ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN, SCALE_UI_DOWN },
-#endif  // !defined(NDEBUG)
   { true, ui::VKEY_O, ui::EF_CONTROL_DOWN, OPEN_FILE_DIALOG },
   { true, ui::VKEY_M, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
     OPEN_FILE_MANAGER },
@@ -94,8 +75,6 @@
 #if !defined(OS_WIN)
   { true, ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, EXIT },
 #endif
-  { true, ui::VKEY_Z, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
-    TOGGLE_SPOKEN_FEEDBACK },
   { true, ui::VKEY_I, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
     TOUCH_HUD_MODE_CHANGE },
   { true, ui::VKEY_I, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN,
@@ -105,10 +84,12 @@
     NEW_INCOGNITO_WINDOW },
   { true, ui::VKEY_N, ui::EF_CONTROL_DOWN, NEW_WINDOW },
   { true, ui::VKEY_T, ui::EF_CONTROL_DOWN, NEW_TAB },
-  { true, ui::VKEY_BROWSER_BACK,
+  { true, ui::VKEY_OEM_MINUS,
     ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN, SCALE_UI_UP },
-  { true, ui::VKEY_BROWSER_FORWARD,
+  { true, ui::VKEY_OEM_PLUS,
     ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN, SCALE_UI_DOWN },
+  { true, ui::VKEY_0,
+    ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN, SCALE_UI_RESET },
   { true, ui::VKEY_BROWSER_REFRESH,
     ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN, ROTATE_SCREEN },
   { true, ui::VKEY_BROWSER_REFRESH,
@@ -124,6 +105,7 @@
   { false, ui::VKEY_LWIN, ui::EF_NONE, TOGGLE_APP_LIST },
   { false, ui::VKEY_LWIN, ui::EF_ALT_DOWN, TOGGLE_CAPS_LOCK },
   { true, ui::VKEY_MEDIA_LAUNCH_APP2, ui::EF_NONE, TOGGLE_MAXIMIZED },
+  { true, ui::VKEY_MEDIA_LAUNCH_APP2, ui::EF_SHIFT_DOWN, TOGGLE_FULLSCREEN },
   { true, ui::VKEY_VOLUME_MUTE, ui::EF_NONE, VOLUME_MUTE },
   { true, ui::VKEY_VOLUME_DOWN, ui::EF_NONE, VOLUME_DOWN },
   { true, ui::VKEY_VOLUME_UP, ui::EF_NONE, VOLUME_UP },
@@ -175,31 +157,70 @@
   { true, ui::VKEY_U, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN,
     PRINT_UI_HIERARCHIES },
 
+  // Accessibility: Spoken feedback shortcuts. The first one is to toggle
+  // spoken feedback on or off. The others are only valid when
+  // spoken feedback is enabled.
+  { true, ui::VKEY_Z, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
+    TOGGLE_SPOKEN_FEEDBACK },
+  { true, ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN, SILENCE_SPOKEN_FEEDBACK},
+  { false, ui::VKEY_HOME, ui::EF_SHIFT_DOWN, ACCESSIBLE_FOCUS_PREVIOUS},
+  { false, ui::VKEY_PRIOR, ui::EF_SHIFT_DOWN, ACCESSIBLE_FOCUS_PREVIOUS},
+  { false, ui::VKEY_END, ui::EF_SHIFT_DOWN, ACCESSIBLE_FOCUS_NEXT},
+  { false, ui::VKEY_NEXT, ui::EF_SHIFT_DOWN, ACCESSIBLE_FOCUS_NEXT},
+
   // TODO(yusukes): Handle VKEY_MEDIA_STOP, and
   // VKEY_MEDIA_LAUNCH_MAIL.
 };
 
 const size_t kAcceleratorDataLength = arraysize(kAcceleratorData);
 
-const AcceleratorData kDebugAcceleratorData[] = {
-  { true, ui::VKEY_B, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
-    TOGGLE_DESKTOP_BACKGROUND_MODE },
-  { true, ui::VKEY_F11, ui::EF_CONTROL_DOWN, TOGGLE_ROOT_WINDOW_FULL_SCREEN },
-  { true, ui::VKEY_W, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, TOGGLE_WIFI },
+#if !defined(NDEBUG)
+const AcceleratorData kDesktopAcceleratorData[] = {
+#if defined(OS_CHROMEOS)
+  // Extra shortcut for debug build to control magnifier on linux desktop.
+  { true, ui::VKEY_BRIGHTNESS_DOWN, ui::EF_CONTROL_DOWN,
+    MAGNIFY_SCREEN_ZOOM_OUT},
+  { true, ui::VKEY_BRIGHTNESS_UP, ui::EF_CONTROL_DOWN, MAGNIFY_SCREEN_ZOOM_IN},
+  // Extra shortcuts to lock the screen on linux desktop.
+  { true, ui::VKEY_L, ui::EF_ALT_DOWN, LOCK_SCREEN },
+  { true, ui::VKEY_POWER, ui::EF_SHIFT_DOWN, LOCK_PRESSED },
+  { false, ui::VKEY_POWER, ui::EF_SHIFT_DOWN, LOCK_RELEASED },
+#endif
+  // Extra shortcut for display swaping as alt-f4 is taken on linux desktop.
+  { true, ui::VKEY_S, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN,
+    SWAP_PRIMARY_DISPLAY },
+  // Extra shortcut to rotate/scale up/down the screen on linux desktop.
+  { true, ui::VKEY_R,
+    ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, ROTATE_SCREEN },
   // For testing on systems where Alt-Tab is already mapped.
   { true, ui::VKEY_W, ui::EF_ALT_DOWN, CYCLE_FORWARD_MRU },
+
+  { true, ui::VKEY_F11, ui::EF_CONTROL_DOWN, TOGGLE_ROOT_WINDOW_FULL_SCREEN },
+  { true, ui::VKEY_W, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, TOGGLE_WIFI },
   { true, ui::VKEY_W, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
       CYCLE_BACKWARD_MRU },
-  { true, ui::VKEY_HOME, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN,
-    DISPLAY_TOGGLE_SCALE },
-#if !defined(NDEBUG)
+  { true, ui::VKEY_B, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
+    TOGGLE_DESKTOP_BACKGROUND_MODE },
+};
+
+const size_t kDesktopAcceleratorDataLength = arraysize(kDesktopAcceleratorData);
+#endif
+
+const AcceleratorData kDebugAcceleratorData[] = {
   { true, ui::VKEY_L, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
     PRINT_LAYER_HIERARCHY },
   { true, ui::VKEY_V, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
     PRINT_VIEW_HIERARCHY },
   { true, ui::VKEY_W, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
     PRINT_WINDOW_HIERARCHY },
-#endif
+  { true, ui::VKEY_S, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
+    DEBUG_TOGGLE_DEVICE_SCALE_FACTOR },
+  { true, ui::VKEY_B, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
+    DEBUG_TOGGLE_SHOW_DEBUG_BORDERS },
+  { true, ui::VKEY_F, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
+    DEBUG_TOGGLE_SHOW_FPS_COUNTER },
+  { true, ui::VKEY_P, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
+    DEBUG_TOGGLE_SHOW_PAINT_RECTS },
 };
 
 const size_t kDebugAcceleratorDataLength = arraysize(kDebugAcceleratorData);
@@ -219,10 +240,6 @@
 const AcceleratorAction kActionsAllowedAtLoginOrLockScreen[] = {
   BRIGHTNESS_DOWN,
   BRIGHTNESS_UP,
-#if defined(OS_CHROMEOS)
-  CYCLE_DISPLAY_MODE,
-  DISABLE_GPU_WATCHDOG,
-#endif  // defined(OS_CHROMEOS)
   DISABLE_CAPS_LOCK,
   KEYBOARD_BRIGHTNESS_DOWN,
   KEYBOARD_BRIGHTNESS_UP,
@@ -230,10 +247,14 @@
   MAGNIFY_SCREEN_ZOOM_OUT,  // Control+F6
   NEXT_IME,
   PREVIOUS_IME,
+  PRINT_LAYER_HIERARCHY,
   PRINT_UI_HIERARCHIES,
+  PRINT_VIEW_HIERARCHY,
+  PRINT_WINDOW_HIERARCHY,
+  ROTATE_WINDOW,
   SWITCH_IME,  // Switch to another IME depending on the accelerator.
-  TAKE_SCREENSHOT,
   TAKE_PARTIAL_SCREENSHOT,
+  TAKE_SCREENSHOT,
   TOGGLE_CAPS_LOCK,
   TOGGLE_SPOKEN_FEEDBACK,
   TOGGLE_WIFI,
@@ -241,16 +262,14 @@
   VOLUME_DOWN,
   VOLUME_MUTE,
   VOLUME_UP,
-  ROTATE_WINDOW,
-#if !defined(NDEBUG)
-  PRINT_LAYER_HIERARCHY,
-  PRINT_VIEW_HIERARCHY,
-  PRINT_WINDOW_HIERARCHY,
+#if defined(OS_CHROMEOS)
+  CYCLE_DISPLAY_MODE,
+  DISABLE_GPU_WATCHDOG,
 #endif
 #if defined(OS_CHROMEOS) && !defined(NDEBUG)
   POWER_PRESSED,
   POWER_RELEASED,
-#endif
+#endif  // defined(OS_CHROMEOS)
 };
 
 const size_t kActionsAllowedAtLoginOrLockScreenLength =
@@ -284,8 +303,8 @@
   SHOW_KEYBOARD_OVERLAY,
   SWAP_PRIMARY_DISPLAY,
   SWITCH_IME,
-  TAKE_SCREENSHOT,
   TAKE_PARTIAL_SCREENSHOT,
+  TAKE_SCREENSHOT,
   TOGGLE_CAPS_LOCK,
   TOGGLE_SPOKEN_FEEDBACK,
   TOGGLE_WIFI,
@@ -312,6 +331,8 @@
   ROTATE_WINDOW,
   SCALE_UI_UP,
   SCALE_UI_DOWN,
+  SCALE_UI_RESET,
+  TOGGLE_FULLSCREEN,
   TOGGLE_MAXIMIZED,
   WINDOW_MINIMIZE,
 };
@@ -322,11 +343,12 @@
 const AcceleratorAction kActionsAllowedInAppMode[] = {
   BRIGHTNESS_DOWN,
   BRIGHTNESS_UP,
-#if defined(OS_CHROMEOS)
-  CYCLE_DISPLAY_MODE,
-  DISABLE_GPU_WATCHDOG,
-#endif  // defined(OS_CHROMEOS)
+  CYCLE_BACKWARD_LINEAR,
+  CYCLE_BACKWARD_MRU,
+  CYCLE_FORWARD_LINEAR,
+  CYCLE_FORWARD_MRU,
   DISABLE_CAPS_LOCK,
+  EXIT,
   KEYBOARD_BRIGHTNESS_DOWN,
   KEYBOARD_BRIGHTNESS_UP,
   MAGNIFY_SCREEN_ZOOM_IN,  // Control+F7
@@ -338,10 +360,14 @@
   POWER_PRESSED,
   POWER_RELEASED,
   PREVIOUS_IME,
+  PRINT_LAYER_HIERARCHY,
   PRINT_UI_HIERARCHIES,
+  PRINT_VIEW_HIERARCHY,
+  PRINT_WINDOW_HIERARCHY,
   ROTATE_SCREEN,
-  SCALE_UI_UP,
   SCALE_UI_DOWN,
+  SCALE_UI_RESET,
+  SCALE_UI_UP,
   SWAP_PRIMARY_DISPLAY,
   SWITCH_IME,  // Switch to another IME depending on the accelerator.
   TOGGLE_CAPS_LOCK,
@@ -351,11 +377,10 @@
   VOLUME_DOWN,
   VOLUME_MUTE,
   VOLUME_UP,
-#if !defined(NDEBUG)
-  PRINT_LAYER_HIERARCHY,
-  PRINT_VIEW_HIERARCHY,
-  PRINT_WINDOW_HIERARCHY,
-#endif
+#if defined(OS_CHROMEOS)
+  CYCLE_DISPLAY_MODE,
+  DISABLE_GPU_WATCHDOG,
+#endif  // defined(OS_CHROMEOS)
 };
 
 const size_t kActionsAllowedInAppModeLength =
diff --git a/ash/accelerators/accelerator_table.h b/ash/accelerators/accelerator_table.h
index d358750..ca2d270 100644
--- a/ash/accelerators/accelerator_table.h
+++ b/ash/accelerators/accelerator_table.h
@@ -15,14 +15,19 @@
 // Please put if/def sections at the end of the bare section and keep the list
 // within each section in alphabetical order.
 enum AcceleratorAction {
+  ACCESSIBLE_FOCUS_NEXT,
+  ACCESSIBLE_FOCUS_PREVIOUS,
   BRIGHTNESS_DOWN,
   BRIGHTNESS_UP,
   CYCLE_BACKWARD_LINEAR,
   CYCLE_BACKWARD_MRU,
   CYCLE_FORWARD_LINEAR,
   CYCLE_FORWARD_MRU,
+  DEBUG_TOGGLE_DEVICE_SCALE_FACTOR,
+  DEBUG_TOGGLE_SHOW_DEBUG_BORDERS,
+  DEBUG_TOGGLE_SHOW_FPS_COUNTER,
+  DEBUG_TOGGLE_SHOW_PAINT_RECTS,
   DISABLE_CAPS_LOCK,
-  DISPLAY_TOGGLE_SCALE,
   EXIT,
   FOCUS_LAUNCHER,
   FOCUS_NEXT_PANE,
@@ -41,14 +46,18 @@
   NEW_WINDOW,
   NEXT_IME,
   OPEN_FEEDBACK_PAGE,
-  PREVIOUS_IME,
   POWER_PRESSED,
   POWER_RELEASED,
+  PREVIOUS_IME,
+  PRINT_LAYER_HIERARCHY,
   PRINT_UI_HIERARCHIES,
+  PRINT_VIEW_HIERARCHY,
+  PRINT_WINDOW_HIERARCHY,
   RESTORE_TAB,
   ROTATE_SCREEN,
   ROTATE_WINDOW,
   SCALE_UI_DOWN,
+  SCALE_UI_RESET,
   SCALE_UI_UP,
   SELECT_LAST_WIN,
   SELECT_WIN_0,
@@ -64,6 +73,7 @@
   SHOW_OAK,
   SHOW_SYSTEM_TRAY_BUBBLE,
   SHOW_TASK_MANAGER,
+  SILENCE_SPOKEN_FEEDBACK,
   SWAP_PRIMARY_DISPLAY,
   SWITCH_IME,  // Switch to another IME depending on the accelerator.
   TAKE_PARTIAL_SCREENSHOT,
@@ -72,6 +82,7 @@
   TOGGLE_CAPS_LOCK,
   TOGGLE_CAPS_LOCK_BY_ALT_LWIN,
   TOGGLE_DESKTOP_BACKGROUND_MODE,
+  TOGGLE_FULLSCREEN,
   TOGGLE_MAXIMIZED,
   TOGGLE_ROOT_WINDOW_FULL_SCREEN,
   TOGGLE_SPOKEN_FEEDBACK,
@@ -87,16 +98,11 @@
   WINDOW_SNAP_RIGHT,
 #if defined(OS_CHROMEOS)
   CYCLE_DISPLAY_MODE,
+  DISABLE_GPU_WATCHDOG,
   LOCK_SCREEN,
   OPEN_CROSH,
   OPEN_FILE_DIALOG,  // Open 'Open file' dialog.
   OPEN_FILE_MANAGER,
-  DISABLE_GPU_WATCHDOG,
-#endif
-#if !defined(NDEBUG)
-  PRINT_LAYER_HIERARCHY,
-  PRINT_VIEW_HIERARCHY,
-  PRINT_WINDOW_HIERARCHY,
 #endif
 };
 
@@ -113,6 +119,14 @@
 // The number of elements in kAcceleratorData.
 ASH_EXPORT extern const size_t kAcceleratorDataLength;
 
+#if !defined(NDEBUG)
+// Accelerators useful when running on desktop. Debug build only.
+ASH_EXPORT extern const AcceleratorData kDesktopAcceleratorData[];
+
+// The number of elements in kDesktopAcceleratorData.
+ASH_EXPORT extern const size_t kDesktopAcceleratorDataLength;
+#endif
+
 // Debug accelerators enabled only when "Debugging keyboard shortcuts" flag
 // (--ash-debug-shortcuts) is enabled.
 ASH_EXPORT extern const AcceleratorData kDebugAcceleratorData[];
diff --git a/ash/accelerators/nested_dispatcher_controller.cc b/ash/accelerators/nested_dispatcher_controller.cc
index 45ad0e4..82e477c 100644
--- a/ash/accelerators/nested_dispatcher_controller.cc
+++ b/ash/accelerators/nested_dispatcher_controller.cc
@@ -17,10 +17,10 @@
 }
 
 void NestedDispatcherController::RunWithDispatcher(
-    MessageLoop::Dispatcher* nested_dispatcher,
+    base::MessageLoop::Dispatcher* nested_dispatcher,
     aura::Window* associated_window,
     bool nestable_tasks_allowed) {
-  MessageLoopForUI* loop = MessageLoopForUI::current();
+  base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
   bool did_allow_task_nesting = loop->NestableTasksAllowed();
   loop->SetNestableTasksAllowed(nestable_tasks_allowed);
 
diff --git a/ash/accelerators/nested_dispatcher_controller.h b/ash/accelerators/nested_dispatcher_controller.h
index cc80cb3..8e77954 100644
--- a/ash/accelerators/nested_dispatcher_controller.h
+++ b/ash/accelerators/nested_dispatcher_controller.h
@@ -22,7 +22,7 @@
   NestedDispatcherController();
   virtual ~NestedDispatcherController();
 
-  virtual void RunWithDispatcher(MessageLoop::Dispatcher* dispatcher,
+  virtual void RunWithDispatcher(base::MessageLoop::Dispatcher* dispatcher,
                                  aura::Window* associated_window,
                                  bool nestable_tasks_allowed) OVERRIDE;
 
diff --git a/ash/accelerators/nested_dispatcher_controller_unittest.cc b/ash/accelerators/nested_dispatcher_controller_unittest.cc
index 4e42d6b..8febefa 100644
--- a/ash/accelerators/nested_dispatcher_controller_unittest.cc
+++ b/ash/accelerators/nested_dispatcher_controller_unittest.cc
@@ -3,8 +3,8 @@
 // found in the LICENSE file.
 
 #include "ash/accelerators/accelerator_controller.h"
+#include "ash/session_state_delegate.h"
 #include "ash/shell.h"
-#include "ash/shell_delegate.h"
 #include "ash/shell_window_ids.h"
 #include "ash/test/ash_test_base.h"
 #include "base/bind.h"
@@ -28,20 +28,20 @@
 
 namespace {
 
-class MockDispatcher : public MessageLoop::Dispatcher {
+class MockDispatcher : public base::MessageLoop::Dispatcher {
  public:
   MockDispatcher() : num_key_events_dispatched_(0) {
   }
 
   int num_key_events_dispatched() { return num_key_events_dispatched_; }
 
-#if defined(OS_WIN) || defined(USE_X11)
+#if defined(OS_WIN) || defined(USE_X11) || defined(USE_MESSAGEPUMP_LINUX)
   virtual bool Dispatch(const base::NativeEvent& event) OVERRIDE {
     if (ui::EventTypeFromNative(event) == ui::ET_KEY_RELEASED)
       num_key_events_dispatched_++;
     return !ui::IsNoopEvent(event);
   }
-#endif  //  defined(OS_WIN) || defined(USE_X11)
+#endif
 
  private:
   int num_key_events_dispatched_;
@@ -109,7 +109,7 @@
   MockDispatcher inner_dispatcher;
   scoped_ptr<aura::Window> associated_window(CreateTestWindowInShellWithId(0));
 
-  Shell::GetInstance()->delegate()->LockScreen();
+  Shell::GetInstance()->session_state_delegate()->LockScreen();
   DispatchKeyReleaseA();
   aura::RootWindow* root_window = ash::Shell::GetPrimaryRootWindow();
   aura::client::GetDispatcherClient(root_window)->RunWithDispatcher(
@@ -117,7 +117,7 @@
       associated_window.get(),
       true /* nestable_tasks_allowed */);
   EXPECT_EQ(0, inner_dispatcher.num_key_events_dispatched());
-  Shell::GetInstance()->delegate()->UnlockScreen();
+  Shell::GetInstance()->session_state_delegate()->UnlockScreen();
 }
 
 // Aura window above lock screen in z order.
diff --git a/ash/ash.gyp b/ash/ash.gyp
index 10314e6..533ff26 100644
--- a/ash/ash.gyp
+++ b/ash/ash.gyp
@@ -20,6 +20,7 @@
         '../base/base.gyp:base_i18n',
         '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations',
         '../build/temp_gyp/googleurl.gyp:googleurl',
+        '../cc/cc.gyp:cc',
         '../content/content.gyp:content',
         '../content/content.gyp:content_browser',
         '../ipc/ipc.gyp:ipc',
@@ -37,6 +38,7 @@
         '../ui/ui.gyp:ui_resources',
         '../ui/views/controls/webview/webview.gyp:webview',
         '../ui/views/views.gyp:views',
+        '../ui/keyboard/keyboard.gyp:keyboard',
         '../ui/web_dialogs/web_dialogs.gyp:web_dialogs',
         'ash_resources',
         'ash_wallpaper_resources',
@@ -60,6 +62,8 @@
         'accelerators/nested_dispatcher_controller.h',
         'ash_constants.cc',
         'ash_constants.h',
+        'ash_root_window_transformer.cc',
+        'ash_root_window_transformer.h',
         'ash_switches.cc',
         'ash_switches.h',
         'cancel_mode.cc',
@@ -67,6 +71,8 @@
         'caps_lock_delegate.h',
         'caps_lock_delegate_stub.cc',
         'caps_lock_delegate_stub.h',
+        'debug.cc',
+        'debug.h',
         'desktop_background/desktop_background_controller.cc',
         'desktop_background/desktop_background_controller.h',
         'desktop_background/desktop_background_controller_observer.h',
@@ -88,6 +94,7 @@
         'display/display_info.cc',
         'display/display_manager.cc',
         'display/display_manager.h',
+        'display/display_pref_util.h',
         'display/event_transformation_handler.cc',
         'display/event_transformation_handler.h',
         'display/mouse_cursor_event_filter.cc',
@@ -159,6 +166,7 @@
         'screensaver/screensaver_view.cc',
         'screensaver/screensaver_view.h',
         'screenshot_delegate.h',
+        'session_state_delegate.h',
         'shelf/background_animator.cc',
         'shelf/background_animator.h',
         'shelf/shelf_layout_manager.cc',
@@ -171,9 +179,6 @@
         'shell_delegate.h',
         'shell_factory.h',
         'shell_window_ids.h',
-        'system/audio/audio_observer.h',
-        'system/audio/tray_volume.cc',
-        'system/audio/tray_volume.h',
         'system/bluetooth/bluetooth_observer.h',
         'system/bluetooth/tray_bluetooth.cc',
         'system/bluetooth/tray_bluetooth.h',
@@ -181,11 +186,18 @@
         'system/brightness/brightness_control_delegate.h',
         'system/brightness/tray_brightness.cc',
         'system/brightness/tray_brightness.h',
+        'system/chromeos/audio/audio_observer.h',
+        'system/chromeos/audio/tray_audio.cc',
+        'system/chromeos/audio/tray_audio.h',        
         'system/chromeos/enterprise/enterprise_domain_observer.h',
         'system/chromeos/enterprise/tray_enterprise.h',
         'system/chromeos/enterprise/tray_enterprise.cc',
         'system/chromeos/keyboard_brightness_controller.cc',
         'system/chromeos/keyboard_brightness_controller.h',
+        'system/chromeos/label_tray_view.h',
+        'system/chromeos/label_tray_view.cc',
+        'system/chromeos/managed/tray_locally_managed_user.h',
+        'system/chromeos/managed/tray_locally_managed_user.cc',
         'system/chromeos/network/network_detailed_view.h',
         'system/chromeos/network/network_icon.cc',
         'system/chromeos/network/network_icon.h',
@@ -296,8 +308,15 @@
         'system/tray/tray_item_view.h',
         'system/tray/tray_notification_view.cc',
         'system/tray/tray_notification_view.h',
-        'system/tray/tray_views.cc',
-        'system/tray/tray_views.h',
+        'system/tray/tray_popup_header_button.cc',
+        'system/tray/tray_popup_header_button.h',
+        'system/tray/tray_popup_label_button.cc',
+        'system/tray/tray_popup_label_button.cc',
+        'system/tray/tray_popup_label_button.h',
+        'system/tray/tray_popup_label_button_border.cc',
+        'system/tray/tray_popup_label_button_border.h',
+        'system/tray/tray_utils.cc',
+        'system/tray/tray_utils.h',
         'system/tray/view_click_listener.h',
         'system/tray_accessibility.cc',
         'system/tray_accessibility.h',
@@ -353,8 +372,8 @@
         'wm/event_rewriter_event_filter.h',
         'wm/frame_painter.cc',
         'wm/frame_painter.h',
-        'wm/gestures/bezel_gesture_handler.cc',
-        'wm/gestures/bezel_gesture_handler.h',
+        'wm/gestures/border_gesture_handler.cc',
+        'wm/gestures/border_gesture_handler.h',
         'wm/gestures/long_press_affordance_handler.cc',
         'wm/gestures/long_press_affordance_handler.h',
         'wm/gestures/shelf_gesture_handler.cc',
@@ -525,6 +544,8 @@
       'sources': [
         'test/ash_test_base.cc',
         'test/ash_test_base.h',
+        'test/ash_test_helper.cc',
+        'test/ash_test_helper.h',
         'test/cursor_manager_test_api.cc',
         'test/cursor_manager_test_api.h',
         'test/launcher_view_test_api.cc',
@@ -537,6 +558,8 @@
         'test/test_activation_delegate.h',
         'test/test_launcher_delegate.cc',
         'test/test_launcher_delegate.h',
+        'test/test_session_state_delegate.cc',
+        'test/test_session_state_delegate.cc',
         'test/test_shell_delegate.cc',
         'test/test_shell_delegate.h',
         'test/test_suite.cc',
@@ -579,6 +602,7 @@
         '../ui/app_list/app_list.gyp:app_list',
         '../ui/compositor/compositor.gyp:compositor',
         '../ui/compositor/compositor.gyp:compositor_test_support',
+        '../ui/keyboard/keyboard.gyp:keyboard',
         '../ui/message_center/message_center.gyp:message_center',
         '../ui/ui.gyp:ui',
         '../ui/ui.gyp:ui_resources',
@@ -601,6 +625,7 @@
         'accelerators/accelerator_filter_unittest.cc',
         'accelerators/accelerator_table_unittest.cc',
         'accelerators/nested_dispatcher_controller_unittest.cc',
+        'ash_root_window_transformer_unittest.cc',
         'desktop_background/desktop_background_controller_unittest.cc',
         'dip_unittest.cc',
         'display/display_controller_unittest.cc',
@@ -624,6 +649,8 @@
         'root_window_controller_unittest.cc',
         'screen_ash_unittest.cc',
         'screensaver/screensaver_view_unittest.cc',
+        'session_state_delegate_stub.cc',
+        'session_state_delegate_stub.h',
         'shelf/shelf_layout_manager_unittest.cc',
         'shelf/shelf_widget_unittest.cc',
         'shell_unittest.cc',
@@ -644,8 +671,10 @@
         'system/chromeos/network/network_state_notifier_unittest.cc',
         'system/tray/system_tray_unittest.cc',
         'system/web_notification/web_notification_tray_unittest.cc',
+        'test/ash_test_helper_unittest.cc',
         'test/ash_unittests.cc',
         'tooltips/tooltip_controller_unittest.cc',
+        'touch/touch_observer_hud_unittest.cc',
         'wm/activation_controller_unittest.cc',
         'wm/ash_activation_controller_unittest.cc',
         'wm/ash_native_cursor_manager_unittest.cc',
@@ -655,6 +684,7 @@
         'wm/frame_painter_unittest.cc',
         'wm/panels/panel_layout_manager_unittest.cc',
         'wm/panels/panel_window_resizer_unittest.cc',
+        'wm/partial_screenshot_view_unittest.cc',
         'wm/power_button_controller_unittest.cc',
         'wm/screen_dimmer_unittest.cc',
         'wm/session_state_controller_impl2_unittest.cc',
@@ -668,6 +698,7 @@
         'wm/window_cycle_controller_unittest.cc',
         'wm/window_manager_unittest.cc',
         'wm/window_modality_controller_unittest.cc',
+        'wm/window_util_unittest.cc',
         'wm/workspace_controller_test_helper.cc',
         'wm/workspace_controller_test_helper.h',
         'wm/workspace/magnetism_matcher_unittest.cc',
@@ -689,6 +720,7 @@
             ['exclude', 'accelerators/nested_dispatcher_controller_unittest.cc'],
             ['exclude', 'wm/drag_window_resizer_unittest.cc'],
             # Can't resize on Windows Ash. http://crbug.com/165962
+            ['exclude', 'ash_root_window_transformer_unittest.cc'],
             ['exclude', 'magnifier/magnification_controller_unittest.cc'],
             ['exclude', 'wm/workspace/workspace_window_resizer_unittest.cc'],
           ],
@@ -738,6 +770,7 @@
         '../ui/aura/aura.gyp:aura',
         '../ui/compositor/compositor.gyp:compositor',
         '../ui/compositor/compositor.gyp:compositor_test_support',
+        '../ui/keyboard/keyboard.gyp:keyboard',
         '../ui/message_center/message_center.gyp:message_center',
         '../ui/ui.gyp:ui',
         '../ui/ui.gyp:ui_resources',
@@ -749,6 +782,8 @@
         'ash_resources',
       ],
       'sources': [
+        'session_state_delegate_stub.cc',
+        'session_state_delegate_stub.h',
         'shell/app_list.cc',
         'shell/bubble.cc',
         'shell/content_client/shell_browser_main_parts.cc',
diff --git a/ash/ash_chromeos_strings.grdp b/ash/ash_chromeos_strings.grdp
index 70dee20..7ecee26 100644
--- a/ash/ash_chromeos_strings.grdp
+++ b/ash/ash_chromeos_strings.grdp
@@ -234,5 +234,5 @@
   <message name="IDS_CHROMEOS_MEDIA_SCREEN_CAPTURE_NOTIFICATION_STOP" desc="label used for screen sharing stop button">
     Stop
   </message>
-  
+
 </grit-part>
diff --git a/ash/ash_root_window_transformer.cc b/ash/ash_root_window_transformer.cc
new file mode 100644
index 0000000..fa8a8a3
--- /dev/null
+++ b/ash/ash_root_window_transformer.cc
@@ -0,0 +1,176 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/ash_root_window_transformer.h"
+
+#include <cmath>
+
+#include "ash/display/display_info.h"
+#include "ash/display/display_manager.h"
+#include "ash/magnifier/magnification_controller.h"
+#include "ash/shell.h"
+#include "third_party/skia/include/utils/SkMatrix44.h"
+#include "ui/aura/root_window.h"
+#include "ui/aura/window_property.h"
+#include "ui/compositor/dip_util.h"
+#include "ui/gfx/display.h"
+#include "ui/gfx/size_conversions.h"
+#include "ui/gfx/transform.h"
+
+DECLARE_WINDOW_PROPERTY_TYPE(gfx::Display::Rotation);
+
+namespace ash {
+namespace {
+
+DEFINE_WINDOW_PROPERTY_KEY(gfx::Display::Rotation, kRotationPropertyKey,
+                           gfx::Display::ROTATE_0);
+
+// Round near zero value to zero.
+void RoundNearZero(gfx::Transform* transform) {
+  const float kEpsilon = 0.001f;
+  SkMatrix44& matrix = transform->matrix();
+  for (int x = 0; x < 4; ++x) {
+    for (int y = 0; y < 4; ++y) {
+      if (std::abs(SkMScalarToFloat(matrix.get(x, y))) < kEpsilon)
+        matrix.set(x, y, SkFloatToMScalar(0.0f));
+    }
+  }
+}
+
+gfx::Transform CreateRotationTransform(aura::RootWindow* root_window,
+                                       const gfx::Display& display) {
+  internal::DisplayInfo info =
+      Shell::GetInstance()->display_manager()->GetDisplayInfo(display.id());
+
+  // TODO(oshima): Add animation. (crossfade+rotation, or just cross-fade)
+#if defined(OS_WIN)
+  // Windows 8 bots refused to resize the host window, and
+  // updating the transform results in incorrectly resizing
+  // the root window. Don't apply the transform unless
+  // necessary so that unit tests pass on win8 bots.
+  if (info.rotation() == root_window->GetProperty(kRotationPropertyKey))
+    return gfx::Transform();
+  root_window->SetProperty(kRotationPropertyKey, info.rotation());
+#endif
+
+  gfx::Transform rotate;
+  // The origin is (0, 0), so the translate width/height must be reduced by
+  // 1 pixel.
+  float one_pixel = 1.0f / display.device_scale_factor();
+  switch (info.rotation()) {
+    case gfx::Display::ROTATE_0:
+      break;
+    case gfx::Display::ROTATE_90:
+      rotate.Translate(display.bounds().height() - one_pixel, 0);
+      rotate.Rotate(90);
+      break;
+    case gfx::Display::ROTATE_270:
+      rotate.Translate(0, display.bounds().width() - one_pixel);
+      rotate.Rotate(270);
+      break;
+    case gfx::Display::ROTATE_180:
+      rotate.Translate(display.bounds().width() - one_pixel,
+                       display.bounds().height() - one_pixel);
+      rotate.Rotate(180);
+      break;
+  }
+
+  RoundNearZero(&rotate);
+  return rotate;
+}
+
+gfx::Transform CreateMagnifierTransform(aura::RootWindow* root_window) {
+  MagnificationController* magnifier =
+      Shell::GetInstance()->magnification_controller();
+  float magnifier_scale = 1.f;
+  gfx::Point magnifier_offset;
+  if (magnifier && magnifier->IsEnabled()) {
+    magnifier_scale = magnifier->GetScale();
+    magnifier_offset = magnifier->GetWindowPosition();
+  }
+  gfx::Transform transform;
+  if (magnifier_scale != 1.f) {
+    transform.Scale(magnifier_scale, magnifier_scale);
+    transform.Translate(-magnifier_offset.x(), -magnifier_offset.y());
+  }
+  return transform;
+}
+
+gfx::Transform CreateOverscanAndUIScaleTransform(aura::RootWindow* root_window,
+                                                 const gfx::Display& display) {
+  internal::DisplayInfo info =
+      Shell::GetInstance()->display_manager()->GetDisplayInfo(display.id());
+  gfx::Insets insets = info.GetOverscanInsetsInPixel();
+  float scale = info.ui_scale();
+
+  gfx::Transform transform;
+  if (insets.top() != 0 || insets.left() != 0) {
+    float device_scale_factor = ui::GetDeviceScaleFactor(root_window->layer());
+    float x_offset = insets.left() / device_scale_factor;
+    float y_offset = insets.top() / device_scale_factor;
+    transform.Translate(x_offset, y_offset);
+  }
+  float inverted_scale = 1.0f / scale;
+  transform.Scale(inverted_scale, inverted_scale);
+  return transform;
+}
+
+}  // namespace
+
+AshRootWindowTransformer::AshRootWindowTransformer(aura::RootWindow* root,
+                                                   const gfx::Display& display)
+    : root_window_(root) {
+  root_window_bounds_transform_ =
+      CreateOverscanAndUIScaleTransform(root, display) *
+      CreateRotationTransform(root, display);
+  transform_ = root_window_bounds_transform_ * CreateMagnifierTransform(root);
+  CHECK(transform_.GetInverse(&invert_transform_));
+
+  internal::DisplayInfo info = Shell::GetInstance()->
+      display_manager()->GetDisplayInfo(display.id());
+  root_window_ui_scale_ = info.ui_scale();
+  host_insets_ = info.GetOverscanInsetsInPixel();
+  MagnificationController* magnifier =
+      Shell::GetInstance()->magnification_controller();
+
+  bool scaled = (root_window_ui_scale_ != 1.f) ||
+      (magnifier && magnifier->GetScale() != 1.f);
+  root_window_->layer()->SetForceRenderSurface(scaled);
+}
+
+AshRootWindowTransformer::~AshRootWindowTransformer() {}
+
+gfx::Transform AshRootWindowTransformer::GetTransform() const {
+  return transform_;
+}
+
+gfx::Transform AshRootWindowTransformer::GetInverseTransform() const {
+  return invert_transform_;
+}
+
+gfx::Rect AshRootWindowTransformer::GetRootWindowBounds(
+    const gfx::Size& host_size) const {
+  gfx::Rect bounds(host_size);
+  bounds.Inset(host_insets_);
+  bounds = ui::ConvertRectToDIP(root_window_->layer(), bounds);
+  gfx::RectF new_bounds(bounds);
+  root_window_bounds_transform_.TransformRect(&new_bounds);
+  // Apply |root_window_scale_| twice as the downscaling
+  // is already applied once in |SetTransformInternal()|.
+  // TODO(oshima): This is a bit ugly. Consider specifying
+  // the pseudo host resolution instead.
+  new_bounds.Scale(root_window_ui_scale_ * root_window_ui_scale_);
+  // Ignore the origin because RootWindow's insets are handled by
+  // the transform.
+  // Floor the size because the bounds is no longer aligned to
+  // backing pixel when |root_window_scale_| is specified
+  // (850 height at 1.25 scale becomes 1062.5 for example.)
+  return gfx::Rect(gfx::ToFlooredSize(new_bounds.size()));
+}
+
+gfx::Insets AshRootWindowTransformer::GetHostInsets() const {
+  return host_insets_;
+}
+
+}  // namespace ash
diff --git a/ash/ash_root_window_transformer.h b/ash/ash_root_window_transformer.h
new file mode 100644
index 0000000..424a6cf
--- /dev/null
+++ b/ash/ash_root_window_transformer.h
@@ -0,0 +1,65 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_ASH_ROOT_WINDOW_TRANSFORMER_H_
+#define ASH_ASH_ROOT_WINDOW_TRANSFORMER_H_
+
+#include "ash/ash_export.h"
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "ui/aura/root_window_transformer.h"
+#include "ui/gfx/insets.h"
+#include "ui/gfx/transform.h"
+
+namespace aura {
+class RootWindow;
+}
+
+namespace gfx {
+class Display;
+}
+
+namespace ash {
+
+// RootWindowTransformer for ash environment.
+class ASH_EXPORT AshRootWindowTransformer : public aura::RootWindowTransformer {
+ public:
+  AshRootWindowTransformer(aura::RootWindow* root,
+                           const gfx::Display& display);
+  // aura::RootWindowTransformer overrides:
+  virtual gfx::Transform GetTransform() const OVERRIDE;
+  virtual gfx::Transform GetInverseTransform() const OVERRIDE;
+  virtual gfx::Rect GetRootWindowBounds(
+      const gfx::Size& host_size) const OVERRIDE;
+  virtual gfx::Insets GetHostInsets() const OVERRIDE;
+
+ private:
+  virtual ~AshRootWindowTransformer();
+
+  aura::RootWindow* root_window_;
+  gfx::Transform transform_;
+
+  // The accurate representation of the inverse of the |transform_|.
+  // This is used to avoid computation error caused by
+  // |gfx::Transform::GetInverse|.
+  gfx::Transform invert_transform_;
+
+  // The transform of the root window bounds. This is used to calculate
+  // the size of root window.
+  gfx::Transform root_window_bounds_transform_;
+
+  // The scale of the root window. This is used to expand the
+  // area of the root window (useful in HighDPI display).
+  // Note that this should not be confused with the device scale
+  // factor, which specfies the pixel density of the display.
+  float root_window_ui_scale_;
+
+  gfx::Insets host_insets_;
+
+  DISALLOW_COPY_AND_ASSIGN(AshRootWindowTransformer);
+};
+
+}  // namespace ash
+
+#endif  // ASH_ASH_ROOT_WINDOW_TRANSFORMER_H_
diff --git a/ash/ash_root_window_transformer_unittest.cc b/ash/ash_root_window_transformer_unittest.cc
new file mode 100644
index 0000000..88b97ad
--- /dev/null
+++ b/ash/ash_root_window_transformer_unittest.cc
@@ -0,0 +1,398 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include"ash/ash_root_window_transformer.h"
+
+#include "ash/display/display_controller.h"
+#include "ash/display/display_info.h"
+#include "ash/display/display_manager.h"
+#include "ash/launcher/launcher.h"
+#include "ash/magnifier/magnification_controller.h"
+#include "ash/screen_ash.h"
+#include "ash/shelf/shelf_widget.h"
+#include "ash/shell.h"
+#include "ash/test/ash_test_base.h"
+#include "ash/test/cursor_manager_test_api.h"
+#include "base/synchronization/waitable_event.h"
+#include "ui/aura/env.h"
+#include "ui/aura/root_window.h"
+#include "ui/aura/test/event_generator.h"
+#include "ui/aura/window_tracker.h"
+#include "ui/base/events/event_handler.h"
+#include "ui/gfx/display.h"
+#include "ui/gfx/rect_conversions.h"
+#include "ui/gfx/screen.h"
+#include "ui/views/widget/widget.h"
+
+namespace ash {
+namespace test {
+
+namespace {
+
+const char kDesktopBackgroundView[] = "DesktopBackgroundView";
+
+class TestEventHandler : public ui::EventHandler {
+ public:
+  TestEventHandler() : target_root_(NULL),
+                       touch_radius_x_(0.0),
+                       touch_radius_y_(0.0),
+                       scroll_x_offset_(0.0),
+                       scroll_y_offset_(0.0),
+                       scroll_x_offset_ordinal_(0.0),
+                       scroll_y_offset_ordinal_(0.0) {}
+  virtual ~TestEventHandler() {}
+
+  virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
+    if (event->flags() & ui::EF_IS_SYNTHESIZED)
+      return;
+    aura::Window* target = static_cast<aura::Window*>(event->target());
+    mouse_location_ = event->root_location();
+    target_root_ = target->GetRootWindow();
+    event->StopPropagation();
+  }
+
+  virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE {
+    aura::Window* target = static_cast<aura::Window*>(event->target());
+    // Only record when the target is the background which covers
+    // entire root window.
+    if (target->name() != kDesktopBackgroundView)
+      return;
+    touch_radius_x_ = event->radius_x();
+    touch_radius_y_ = event->radius_y();
+    event->StopPropagation();
+  }
+
+  virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE {
+    aura::Window* target = static_cast<aura::Window*>(event->target());
+    // Only record when the target is the background which covers
+    // entire root window.
+    if (target->name() != kDesktopBackgroundView)
+      return;
+
+    if (event->type() == ui::ET_SCROLL) {
+      scroll_x_offset_ = event->x_offset();
+      scroll_y_offset_ = event->y_offset();
+      scroll_x_offset_ordinal_ = event->x_offset_ordinal();
+      scroll_y_offset_ordinal_ = event->y_offset_ordinal();
+    }
+    event->StopPropagation();
+  }
+
+  std::string GetLocationAndReset() {
+    std::string result = mouse_location_.ToString();
+    mouse_location_.SetPoint(0, 0);
+    target_root_ = NULL;
+    return result;
+  }
+
+  float touch_radius_x() const { return touch_radius_x_; }
+  float touch_radius_y() const { return touch_radius_y_; }
+  float scroll_x_offset() const { return scroll_x_offset_; }
+  float scroll_y_offset() const { return scroll_y_offset_; }
+  float scroll_x_offset_ordinal() const { return scroll_x_offset_ordinal_; }
+  float scroll_y_offset_ordinal() const { return scroll_y_offset_ordinal_; }
+
+ private:
+  gfx::Point mouse_location_;
+  aura::RootWindow* target_root_;
+
+  float touch_radius_x_;
+  float touch_radius_y_;
+  float scroll_x_offset_;
+  float scroll_y_offset_;
+  float scroll_x_offset_ordinal_;
+  float scroll_y_offset_ordinal_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestEventHandler);
+};
+
+gfx::Display::Rotation GetStoredRotation(int64 id) {
+  return Shell::GetInstance()->display_manager()->GetDisplayInfo(id).rotation();
+}
+
+float GetStoredUIScale(int64 id) {
+  return Shell::GetInstance()->display_manager()->GetDisplayInfo(id).ui_scale();
+}
+
+}  // namespace
+
+typedef test::AshTestBase AshRootWindowTransformerTest;
+
+#if defined(OS_WIN)
+// On Win8 bots, the host window can't be resized and
+// SetTransform updates the window using the orignal host window
+// size.
+#define MAYBE_RotateAndMagnify DISABLED_RotateAndMagniy
+#define MAYBE_ScaleAndMagnify DISABLED_ScaleAndMagnify
+#define MAYBE_TouchScaleAndMagnify DISABLED_TouchScaleAndMagnify
+#define MAYBE_ConvertHostToRootCoords DISABLED_ConvertHostToRootCoords
+#else
+#define MAYBE_RotateAndMagnify RotateAndMagniy
+#define MAYBE_ScaleAndMagnify ScaleAndMagnify
+#define MAYBE_TouchScaleAndMagnify TouchScaleAndMagnify
+#define MAYBE_ConvertHostToRootCoords ConvertHostToRootCoords
+#endif
+
+TEST_F(AshRootWindowTransformerTest, MAYBE_RotateAndMagnify) {
+  DisplayController* display_controller =
+      Shell::GetInstance()->display_controller();
+  MagnificationController* magnifier =
+      Shell::GetInstance()->magnification_controller();
+  internal::DisplayManager* display_manager =
+      Shell::GetInstance()->display_manager();
+
+  TestEventHandler event_handler;
+  Shell::GetInstance()->AddPreTargetHandler(&event_handler);
+
+  UpdateDisplay("120x200,300x400*2");
+  gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay();
+  int64 display2_id = ScreenAsh::GetSecondaryDisplay().id();
+
+  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
+  aura::test::EventGenerator generator1(root_windows[0]);
+  aura::test::EventGenerator generator2(root_windows[1]);
+
+  magnifier->SetEnabled(true);
+  EXPECT_EQ(2.0f, magnifier->GetScale());
+  EXPECT_EQ("120x200", root_windows[0]->bounds().size().ToString());
+  EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString());
+  EXPECT_EQ("120,0 150x200",
+            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
+  generator1.MoveMouseToInHost(40, 80);
+  EXPECT_EQ("50,90", event_handler.GetLocationAndReset());
+  EXPECT_EQ("50,90",
+            aura::Env::GetInstance()->last_mouse_location().ToString());
+  EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display1.id()));
+  EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display2_id));
+  magnifier->SetEnabled(false);
+
+  display_manager->SetDisplayRotation(display1.id(),
+                                      gfx::Display::ROTATE_90);
+  // Move the cursor to the center of the first root window.
+  generator1.MoveMouseToInHost(59, 100);
+
+  magnifier->SetEnabled(true);
+  EXPECT_EQ(2.0f, magnifier->GetScale());
+  EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString());
+  EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString());
+  EXPECT_EQ("200,0 150x200",
+            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
+  generator1.MoveMouseToInHost(39, 120);
+  EXPECT_EQ("110,70", event_handler.GetLocationAndReset());
+  EXPECT_EQ("110,70",
+            aura::Env::GetInstance()->last_mouse_location().ToString());
+  EXPECT_EQ(gfx::Display::ROTATE_90, GetStoredRotation(display1.id()));
+  EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display2_id));
+  magnifier->SetEnabled(false);
+
+  DisplayLayout display_layout(DisplayLayout::BOTTOM, 50);
+  display_controller->SetLayoutForCurrentDisplays(display_layout);
+  EXPECT_EQ("50,120 150x200",
+            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
+
+  display_manager->SetDisplayRotation(display2_id,
+                                      gfx::Display::ROTATE_270);
+  // Move the cursor to the center of the second root window.
+  generator2.MoveMouseToInHost(151, 199);
+
+  magnifier->SetEnabled(true);
+  EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString());
+  EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString());
+  EXPECT_EQ("50,120 200x150",
+            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
+  generator2.MoveMouseToInHost(172, 219);
+  EXPECT_EQ("95,80", event_handler.GetLocationAndReset());
+  EXPECT_EQ("169,175",
+            aura::Env::GetInstance()->last_mouse_location().ToString());
+  EXPECT_EQ(gfx::Display::ROTATE_90, GetStoredRotation(display1.id()));
+  EXPECT_EQ(gfx::Display::ROTATE_270, GetStoredRotation(display2_id));
+  magnifier->SetEnabled(false);
+
+  display_manager->SetDisplayRotation(display1.id(),
+                                      gfx::Display::ROTATE_180);
+  // Move the cursor to the center of the first root window.
+  generator1.MoveMouseToInHost(59, 99);
+
+  magnifier->SetEnabled(true);
+  EXPECT_EQ("120x200", root_windows[0]->bounds().size().ToString());
+  EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString());
+  // Dislay must share at least 100, so the x's offset becomes 20.
+  EXPECT_EQ("20,200 200x150",
+            ScreenAsh::GetSecondaryDisplay().bounds().ToString());
+  generator1.MoveMouseToInHost(39, 59);
+  EXPECT_EQ("70,120", event_handler.GetLocationAndReset());
+  EXPECT_EQ(gfx::Display::ROTATE_180, GetStoredRotation(display1.id()));
+  EXPECT_EQ(gfx::Display::ROTATE_270, GetStoredRotation(display2_id));
+  magnifier->SetEnabled(false);
+
+  Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
+}
+
+TEST_F(AshRootWindowTransformerTest, MAYBE_ScaleAndMagnify) {
+  TestEventHandler event_handler;
+  Shell::GetInstance()->AddPreTargetHandler(&event_handler);
+
+  UpdateDisplay("600x400*2@1.5,500x300");
+
+  gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay();
+  gfx::Display::SetInternalDisplayId(display1.id());
+  gfx::Display display2 = ScreenAsh::GetSecondaryDisplay();
+  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
+  MagnificationController* magnifier =
+      Shell::GetInstance()->magnification_controller();
+
+  magnifier->SetEnabled(true);
+  EXPECT_EQ(2.0f, magnifier->GetScale());
+  EXPECT_EQ("0,0 450x300", display1.bounds().ToString());
+  EXPECT_EQ("0,0 450x300", root_windows[0]->bounds().ToString());
+  EXPECT_EQ("450,0 500x300", display2.bounds().ToString());
+  EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
+  EXPECT_EQ(1.0f, GetStoredUIScale(display2.id()));
+
+  aura::test::EventGenerator generator(root_windows[0]);
+  generator.MoveMouseToInHost(500, 200);
+  EXPECT_EQ("299,150", event_handler.GetLocationAndReset());
+  magnifier->SetEnabled(false);
+
+  internal::DisplayManager* display_manager =
+      Shell::GetInstance()->display_manager();
+  display_manager->SetDisplayUIScale(display1.id(), 1.25);
+  display1 = Shell::GetScreen()->GetPrimaryDisplay();
+  display2 = ScreenAsh::GetSecondaryDisplay();
+  magnifier->SetEnabled(true);
+  EXPECT_EQ(2.0f, magnifier->GetScale());
+  EXPECT_EQ("0,0 375x250", display1.bounds().ToString());
+  EXPECT_EQ("0,0 375x250", root_windows[0]->bounds().ToString());
+  EXPECT_EQ("375,0 500x300", display2.bounds().ToString());
+  EXPECT_EQ(1.25f, GetStoredUIScale(display1.id()));
+  EXPECT_EQ(1.0f, GetStoredUIScale(display2.id()));
+  magnifier->SetEnabled(false);
+
+  Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
+}
+
+TEST_F(AshRootWindowTransformerTest, MAYBE_TouchScaleAndMagnify) {
+  TestEventHandler event_handler;
+  Shell::GetInstance()->AddPreTargetHandler(&event_handler);
+
+  UpdateDisplay("200x200*2");
+  gfx::Display display = Shell::GetScreen()->GetPrimaryDisplay();
+  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
+  aura::RootWindow* root_window = root_windows[0];
+  aura::test::EventGenerator generator(root_window);
+  MagnificationController* magnifier =
+      Shell::GetInstance()->magnification_controller();
+
+  magnifier->SetEnabled(true);
+  EXPECT_FLOAT_EQ(2.0f, magnifier->GetScale());
+  magnifier->SetScale(2.5f, false);
+  EXPECT_FLOAT_EQ(2.5f, magnifier->GetScale());
+  generator.PressMoveAndReleaseTouchTo(50, 50);
+  // Default test touches have radius_x/y = 1.0, with device scale
+  // factor = 2, the scaled radius_x/y should be 0.5.
+  EXPECT_FLOAT_EQ(0.2, event_handler.touch_radius_x());
+  EXPECT_FLOAT_EQ(0.2, event_handler.touch_radius_y());
+
+  generator.ScrollSequence(gfx::Point(0,0),
+                           base::TimeDelta::FromMilliseconds(100),
+                           10.0, 1.0, 5, 1);
+
+  // With device scale factor = 2, ordinal_offset * 2 = offset.
+  EXPECT_FLOAT_EQ(event_handler.scroll_x_offset(),
+                  event_handler.scroll_x_offset_ordinal() * 2 * 2.5f);
+  EXPECT_FLOAT_EQ(event_handler.scroll_y_offset(),
+                  event_handler.scroll_y_offset_ordinal() * 2 * 2.5f);
+  magnifier->SetEnabled(false);
+
+  Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
+}
+
+TEST_F(AshRootWindowTransformerTest, MAYBE_ConvertHostToRootCoords) {
+  TestEventHandler event_handler;
+  Shell::GetInstance()->AddPreTargetHandler(&event_handler);
+  MagnificationController* magnifier =
+      Shell::GetInstance()->magnification_controller();
+
+  // Test 1
+  UpdateDisplay("600x400*2/r@1.5");
+
+  gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay();
+  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
+  EXPECT_EQ("0,0 300x450", display1.bounds().ToString());
+  EXPECT_EQ("0,0 300x450", root_windows[0]->bounds().ToString());
+  EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
+
+  aura::test::EventGenerator generator(root_windows[0]);
+  generator.MoveMouseToInHost(300, 200);
+  magnifier->SetEnabled(true);
+  EXPECT_EQ("150,224", event_handler.GetLocationAndReset());
+  EXPECT_FLOAT_EQ(2.0f, magnifier->GetScale());
+
+  generator.MoveMouseToInHost(300, 200);
+  EXPECT_EQ("150,224", event_handler.GetLocationAndReset());
+  generator.MoveMouseToInHost(200, 300);
+  EXPECT_EQ("187,261", event_handler.GetLocationAndReset());
+  generator.MoveMouseToInHost(100, 400);
+  EXPECT_EQ("237,299", event_handler.GetLocationAndReset());
+  generator.MoveMouseToInHost(0, 0);
+  EXPECT_EQ("137,348", event_handler.GetLocationAndReset());
+
+  magnifier->SetEnabled(false);
+  EXPECT_FLOAT_EQ(1.0f, magnifier->GetScale());
+
+  // Test 2
+  UpdateDisplay("600x400*2/u@1.5");
+  display1 = Shell::GetScreen()->GetPrimaryDisplay();
+  root_windows = Shell::GetAllRootWindows();
+  EXPECT_EQ("0,0 450x300", display1.bounds().ToString());
+  EXPECT_EQ("0,0 450x300", root_windows[0]->bounds().ToString());
+  EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
+
+  generator.MoveMouseToInHost(300, 200);
+  magnifier->SetEnabled(true);
+  EXPECT_EQ("224,149", event_handler.GetLocationAndReset());
+  EXPECT_FLOAT_EQ(2.0f, magnifier->GetScale());
+
+  generator.MoveMouseToInHost(300, 200);
+  EXPECT_EQ("224,148", event_handler.GetLocationAndReset());
+  generator.MoveMouseToInHost(200, 300);
+  EXPECT_EQ("261,111", event_handler.GetLocationAndReset());
+  generator.MoveMouseToInHost(100, 400);
+  EXPECT_EQ("299,60", event_handler.GetLocationAndReset());
+  generator.MoveMouseToInHost(0, 0);
+  EXPECT_EQ("348,159", event_handler.GetLocationAndReset());
+
+  magnifier->SetEnabled(false);
+  EXPECT_FLOAT_EQ(1.0f, magnifier->GetScale());
+
+  // Test 3
+  UpdateDisplay("600x400*2/l@1.5");
+  display1 = Shell::GetScreen()->GetPrimaryDisplay();
+  root_windows = Shell::GetAllRootWindows();
+  EXPECT_EQ("0,0 300x450", display1.bounds().ToString());
+  EXPECT_EQ("0,0 300x450", root_windows[0]->bounds().ToString());
+  EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
+
+  generator.MoveMouseToInHost(300, 200);
+  magnifier->SetEnabled(true);
+  EXPECT_EQ("149,225", event_handler.GetLocationAndReset());
+  EXPECT_FLOAT_EQ(2.0f, magnifier->GetScale());
+
+  generator.MoveMouseToInHost(300, 200);
+  EXPECT_EQ("148,224", event_handler.GetLocationAndReset());
+  generator.MoveMouseToInHost(200, 300);
+  EXPECT_EQ("111,187", event_handler.GetLocationAndReset());
+  generator.MoveMouseToInHost(100, 400);
+  EXPECT_EQ("60,149", event_handler.GetLocationAndReset());
+  generator.MoveMouseToInHost(0, 0);
+  EXPECT_EQ("159,99", event_handler.GetLocationAndReset());
+
+  magnifier->SetEnabled(false);
+  EXPECT_FLOAT_EQ(1.0f, magnifier->GetScale());
+
+  Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
+}
+
+}  // namespace test
+}  // namespace ash
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd
index 2ad3038..ff576ed 100644
--- a/ash/ash_strings.grd
+++ b/ash/ash_strings.grd
@@ -258,9 +258,6 @@
       <message name="IDS_ASH_STATUS_TRAY_BLUETOOTH_CONNECTING" desc="Shows a connecting bluetooth device in the bluetooth list.">
         <ph name="BLUETOOTH">$1<ex>Apple Magic Mouse</ex></ph>: Connecting...
       </message>
-      <message name="IDS_ASH_STATUS_TRAY_BLUETOOTH_DISCONNECTING" desc="Shows a disconnecting bluetooth device in the bluetooth list.">
-        <ph name="BLUETOOTH">$1<ex>Apple Magic Mouse</ex></ph>: Disconnecting...
-      </message>      
       <message name="IDS_ASH_STATUS_TRAY_DISABLE_BLUETOOTH" desc="The label used in the tray popup to disable bluetooth.">
         Disable Bluetooth
       </message>
@@ -284,6 +281,15 @@
       <message name="IDS_ASH_STATUS_TRAY_VOLUME" desc="The accessible text for the volume slider.">
         Volume
       </message>
+      <message name="IDS_ASH_STATUS_TRAY_AUDIO" desc="The label used in audio detailed page bottom header of ash tray pop up.">
+        Audio Settings
+      </message>
+      <message name="IDS_ASH_STATUS_TRAY_AUDIO_OUTPUT" desc="The label used in audio detailed page for audio output section of ash tray pop up.">
+        OUTPUT
+      </message>
+      <message name="IDS_ASH_STATUS_TRAY_AUDIO_INPUT" desc="The label used in audio detailed page for audio input section of ash tray pop up.">
+        INPUT
+      </message>
 
       <message name="IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING" desc="The label used in the tray to show that the current status is mirroring.">
 	Mirroring to <ph name="DISPLAY_NAME">$1</ph>
@@ -357,7 +363,7 @@
       <message name="IDS_ASH_STATUS_TRAY_ACCESSIBILITY_TITLE" desc="The label used in the title of the accessibility option menu.">
         Accessibility
       </message>
-      <message name="IDS_ASH_STATUS_TRAY_ACCESSIBILITY_SPOKEN_FEEDBACK" desc="The label used in the accessibility menu of the 
+      <message name="IDS_ASH_STATUS_TRAY_ACCESSIBILITY_SPOKEN_FEEDBACK" desc="The label used in the accessibility menu of the
     system tray to toggle on/off spoken feedback feature.">
         Spoken feedback
       </message>
@@ -388,10 +394,13 @@
       </message>
       <message name="IDS_ASH_STATUS_TRAY_BATTERY_TIME_LEFT_SHORT" desc="The label in the tray bubble settings row to show a time estimate until the battery is empty.">
         <ph name="hour">$1<ex>2</ex></ph>:<ph name="minute">$2<ex>53</ex></ph> left
-      </message>      
+      </message>
       <message name="IDS_ASH_STATUS_TRAY_BATTERY_TIME_UNTIL_FULL_SHORT" desc="The label in the tray bubble settings row to show a time estimate until the battery is fully charged.">
         <ph name="hour">$1<ex>2</ex></ph>:<ph name="minute">$2<ex>53</ex></ph> until full
-      </message>      
+      </message>
+      <message name="IDS_ASH_STATUS_TRAY_BATTERY_CHARGING_UNRELIABLE" desc="The label in the tray dialog to indicate that battery charging is unreliable.">
+        Charging not reliable
+      </message>
       <message name="IDS_ASH_STATUS_TRAY_BATTERY_FULL_CHARGE_ACCESSIBLE" desc="The message used by accessibility to show battery is full and charging.">
         Battery is full and charging.
       </message>
@@ -400,10 +409,10 @@
       </message>
       <message name="IDS_ASH_STATUS_TRAY_BATTERY_PERCENT_CHARGING_ACCESSIBLE" desc="The message used by accessibility to show battery is calculating its time.">
         Battery is <ph name="percentage">$1<ex>56</ex></ph>% full and charging
-      </message>      
+      </message>
       <message name="IDS_ASH_STATUS_TRAY_BATTERY_CALCULATING_ACCESSIBLE" desc="The message used by accessibility to show battery is calculating its time in short message.">
         Calculating battery time.
-      </message>               
+      </message>
       <message name= "IDS_ASH_STATUS_TRAY_BATTERY_TIME_LEFT_ACCESSIBLE" desc="The message used by accessibility to read remaining battery time until empty.">
         Time left until battery is empty, <ph name="time_left">$1<ex>1 hour and 15 minutes</ex></ph>
       </message>
@@ -413,6 +422,9 @@
       <message name = "IDS_ASH_STATUS_TRAY_BATTERY_TIME_ACCESSIBLE" desc="The message used by accessibility to read battery time, which includes both non-zero hours and minutes.">
         <ph name="hour">$1<ex> 1 hour</ex></ph> and <ph name="minute">$2<ex>15 minutes</ex></ph>
       </message>
+      <message name="IDS_ASH_STATUS_TRAY_BATTERY_CHARGING_UNRELIABLE_ACCESSIBLE" desc="The message used by accessibility to indicate that battery charging is unreliable.">
+        Plugged in to a non-standard power supply. Battery charging may not be reliable.
+      </message>
       <message name="IDS_ASH_STATUS_TRAY_HELP" desc="The accessible text for the help button.">
         Help
       </message>
@@ -429,10 +441,17 @@
         This session will end in <ph name="session_time_remaining">$1<ex>15 minutes</ex></ph>. You will be automatically signed out.
       </message>
 
+      <message name="IDS_ASH_STATUS_TRAY_LOCALLY_MANAGED_LABEL" desc="Label shown instead of email for locally managed users">
+         Locally managed user
+      </message>
+
       <message name="IDS_ASH_STATUS_TRAY_PREVIOUS_MENU" desc="The accessible text for header entries for detailed versions of status tray items.">
         Previous menu
       </message>
 
+      <message name="IDS_ASH_NOTIFICATION_UNREAD_COUNT_NINE_PLUS" desc="The text shown in the notification icon for the unread count when the count is more than 9.">
+        9+
+      </message>
       <message name="IDS_ASH_MAXIMIZE_WINDOW" desc="A help text to show that when the button gets clicked the window get maximized.">
         Maximize
       </message>
@@ -457,6 +476,21 @@
       <message name="IDS_ASH_INTERNAL_DISPLAY_NAME" desc="The name of the internal display which is shown in the display settings.">
 	Internal Display
       </message>
+      <message name="IDS_ASH_LOW_PERIPHERAL_BATTERY_NOTIFICATION_TEXT" desc="The text of the notification when a peripheral device is in low battery condition.">
+        Battery low (<ph name="percentage">$1<ex>56</ex></ph>%)
+      </message>
+      <message name="IDS_ASH_SCREENSHOT_NOTIFICATION_TITLE_SUCCESS" desc="The title of the notification when a screenshot was taken.">
+        Screenshot taken
+      </message>
+      <message name="IDS_ASH_SCREENSHOT_NOTIFICATION_TITLE_FAIL" desc="The title of the notification when taking a screenshot failed.">
+        An error occurred
+      </message>
+      <message name="IDS_ASH_SCREENSHOT_NOTIFICATION_TEXT_SUCCESS" desc="The text of the notification when a screenshot was taken.">
+        Click to view
+      </message>
+      <message name="IDS_ASH_SCREENSHOT_NOTIFICATION_TEXT_FAIL" desc="The text of the notification when taking a screenshot failed.">
+        Failed to save screenshot
+      </message>
 
       <!-- ChromeOS-specific strings -->
       <if expr="pp_ifdef('chromeos')">
diff --git a/ash/ash_switches.cc b/ash/ash_switches.cc
index ac87287..516fa60 100644
--- a/ash/ash_switches.cc
+++ b/ash/ash_switches.cc
@@ -33,6 +33,9 @@
 // Enable keyboard shortcuts useful for debugging.
 const char kAshDebugShortcuts[] = "ash-debug-shortcuts";
 
+// Disable auto window maximization logic.
+const char kAshDisableAutoMaximizing[] = "ash-disable-auto-maximizing";
+
 // Disable support for auto window placement.
 const char kAshDisableAutoWindowPlacement[] =
     "ash-enable-auto-window-placement";
@@ -48,6 +51,9 @@
 // Disables creating a launcher per display.
 const char kAshDisableLauncherPerDisplay[] = "ash-disable-launcher-per-display";
 
+// Disable the new cras audio handler.
+const char kAshDisableNewAudioHandler[] = "ash-disable-new-audio-handler";
+
 // If present new lock animations are enabled.
 const char kAshDisableNewLockAnimations[] = "ash-disable-new-lock-animations";
 
@@ -61,9 +67,18 @@
 // Disables display rotation.
 const char kAshDisableDisplayRotation[] = "ash-disable-display-rotation";
 
+// Disable immersive fullscreen mode, regardless of default setting.
+const char kAshDisableImmersiveFullscreen[] =
+    "ash-disable-immersive-fullscreen";
+
 // Disables ui scaling.
 const char kAshDisableUIScaling[] = "ash-disable-ui-scaling";
 
+// Extend the status tray volume item to allow the user to choose an audio
+// input and output device.
+const char kAshEnableAudioDeviceMenu[] =
+    "ash-enable-audio-device-menu";
+
 // Enable advanced gestures (e.g. for window management).
 const char kAshEnableAdvancedGestures[] = "ash-enable-advanced-gestures";
 
@@ -71,6 +86,9 @@
 // main monitor as internal.
 const char kAshEnableBrightnessControl[] = "ash-enable-brightness-control";
 
+// Enable immersive fullscreen mode, regardless of default setting.
+const char kAshEnableImmersiveFullscreen[] = "ash-enable-immersive-fullscreen";
+
 #if defined(OS_LINUX)
 // Enable memory monitoring.
 const char kAshEnableMemoryMonitor[] = "ash-enable-memory-monitor";
@@ -79,6 +97,9 @@
 // Enables the Oak tree viewer.
 const char kAshEnableOak[] = "ash-enable-oak";
 
+// Enables "sticky" edges instead of "snap-to-edge"
+const char kAshEnableStickyEdges[] = "ash-enable-sticky-edges";
+
 // Enables showing the tray bubble by dragging on the shelf.
 const char kAshEnableTrayDragging[] = "ash-enable-tray-dragging";
 
@@ -91,17 +112,11 @@
 // "1024x768*2" sets the scale factor to 2 for a high DPI display.
 const char kAshHostWindowBounds[] = "ash-host-window-bounds";
 
-// Enable immersive fullscreen mode.
-const char kAshImmersiveFullscreen[] = "ash-immersive-fullscreen";
-
 // Hides the small tab indicators at the top of the screen during immersive
 // fullscreen mode.
 const char kAshImmersiveHideTabIndicators[] =
     "ash-immersive-hide-tab-indicators";
 
-// Specifies the internal display's ui scale.
-const char kAshInternalDisplayUIScale[] = "ash-internal-display-ui-scale";
-
 // Specifies the layout mode and offsets for the secondary display for
 // testing. The format is "<t|r|b|l>,<offset>" where t=TOP, r=RIGHT,
 // b=BOTTOM and L=LEFT. For example, 'r,-100' means the secondary display
@@ -111,6 +126,11 @@
 // Enables the heads-up display for tracking touch points.
 const char kAshTouchHud[] = "ash-touch-hud";
 
+// Uses the 1st display in --ash-host-window-bounds as internal display.
+// This is for debugging on linux desktop.
+const char kAshUseFirstDisplayAsInternal[] =
+    "ash-use-first-display-as-internal";
+
 // (Most) Chrome OS hardware reports ACPI power button releases correctly.
 // Standard hardware reports releases immediately after presses.  If set, we
 // lock the screen or shutdown the system immediately in response to a press
@@ -121,8 +141,11 @@
 // Force Ash to open its root window on the desktop, even on Windows 8 where
 // it would normally end up in metro.
 const char kForceAshToDesktop[] = "ash-force-desktop";
-;
 #endif
 
+// Enables a mode which enforces all browser & application windows to be created
+// in maximized mode.
+const char kForcedMaximizeMode[] = "forced-maximize-mode";
+
 }  // namespace switches
 }  // namespace ash
diff --git a/ash/ash_switches.h b/ash/ash_switches.h
index 25c37a3..003cd35 100644
--- a/ash/ash_switches.h
+++ b/ash/ash_switches.h
@@ -23,33 +23,39 @@
 ASH_EXPORT extern const char kAshConstrainPointerToRoot[];
 ASH_EXPORT extern const char kAshCopyHostBackgroundAtBoot[];
 ASH_EXPORT extern const char kAshDebugShortcuts[];
+ASH_EXPORT extern const char kAshDisableAutoMaximizing[];
 ASH_EXPORT extern const char kAshDisableAutoWindowPlacement[];
 ASH_EXPORT extern const char kAshDisableBootAnimation2[];
 ASH_EXPORT extern const char kAshDisableDisplayChangeLimiter[];
+ASH_EXPORT extern const char kAshDisableImmersiveFullscreen[];
 ASH_EXPORT extern const char kAshDisableLauncherPerDisplay[];
+ASH_EXPORT extern const char kAshDisableNewAudioHandler[];
 ASH_EXPORT extern const char kAshDisableNewLockAnimations[];
 ASH_EXPORT extern const char kAshDisableNewNetworkStatusArea[];
 ASH_EXPORT extern const char kAshDisablePerAppLauncher[];
 ASH_EXPORT extern const char kAshDisableUIScaling[];
 ASH_EXPORT extern const char kAshDisableDisplayRotation[];
+ASH_EXPORT extern const char kAshEnableAudioDeviceMenu[];
 ASH_EXPORT extern const char kAshEnableAdvancedGestures[];
 ASH_EXPORT extern const char kAshEnableBrightnessControl[];
 #if defined(OS_LINUX)
 ASH_EXPORT extern const char kAshEnableMemoryMonitor[];
 #endif
+ASH_EXPORT extern const char kAshEnableImmersiveFullscreen[];
 ASH_EXPORT extern const char kAshEnableOak[];
+ASH_EXPORT extern const char kAshEnableStickyEdges[];
 ASH_EXPORT extern const char kAshEnableTrayDragging[];
 ASH_EXPORT extern const char kAshEnableWorkspaceScrubbing[];
 ASH_EXPORT extern const char kAshHostWindowBounds[];
-ASH_EXPORT extern const char kAshImmersiveFullscreen[];
 ASH_EXPORT extern const char kAshImmersiveHideTabIndicators[];
-ASH_EXPORT extern const char kAshInternalDisplayUIScale[];
 ASH_EXPORT extern const char kAshSecondaryDisplayLayout[];
 ASH_EXPORT extern const char kAshTouchHud[];
+ASH_EXPORT extern const char kAshUseFirstDisplayAsInternal[];
 ASH_EXPORT extern const char kAuraLegacyPowerButton[];
 #if defined(OS_WIN)
 ASH_EXPORT extern const char kForceAshToDesktop[];
 #endif
+ASH_EXPORT extern const char kForcedMaximizeMode[];
 
 }  // namespace switches
 }  // namespace ash
diff --git a/ash/debug.cc b/ash/debug.cc
new file mode 100644
index 0000000..060627c
--- /dev/null
+++ b/ash/debug.cc
@@ -0,0 +1,61 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/debug.h"
+
+#include "ash/shell.h"
+#include "cc/debug/layer_tree_debug_state.h"
+#include "ui/aura/root_window.h"
+#include "ui/compositor/compositor.h"
+
+namespace ash {
+namespace debug {
+
+void ToggleShowDebugBorders() {
+  Shell::RootWindowList root_windows =
+      Shell::GetInstance()->GetAllRootWindows();
+  scoped_ptr<bool> value;
+  for (Shell::RootWindowList::iterator it = root_windows.begin();
+       it != root_windows.end(); ++it) {
+    ui::Compositor* compositor = (*it)->compositor();
+    cc::LayerTreeDebugState state = compositor->GetLayerTreeDebugState();
+    if (!value.get())
+      value.reset(new bool(!state.show_debug_borders));
+    state.show_debug_borders = *value.get();
+    compositor->SetLayerTreeDebugState(state);
+  }
+}
+
+void ToggleShowFpsCounter() {
+  Shell::RootWindowList root_windows =
+      Shell::GetInstance()->GetAllRootWindows();
+  scoped_ptr<bool> value;
+  for (Shell::RootWindowList::iterator it = root_windows.begin();
+       it != root_windows.end(); ++it) {
+    ui::Compositor* compositor = (*it)->compositor();
+    cc::LayerTreeDebugState state = compositor->GetLayerTreeDebugState();
+    if (!value.get())
+      value.reset(new bool(!state.show_fps_counter));
+    state.show_fps_counter = *value.get();
+    compositor->SetLayerTreeDebugState(state);
+  }
+}
+
+void ToggleShowPaintRects() {
+  Shell::RootWindowList root_windows =
+      Shell::GetInstance()->GetAllRootWindows();
+  scoped_ptr<bool> value;
+  for (Shell::RootWindowList::iterator it = root_windows.begin();
+       it != root_windows.end(); ++it) {
+    ui::Compositor* compositor = (*it)->compositor();
+    cc::LayerTreeDebugState state = compositor->GetLayerTreeDebugState();
+    if (!value.get())
+      value.reset(new bool(!state.show_paint_rects));
+    state.show_paint_rects = *value.get();
+    compositor->SetLayerTreeDebugState(state);
+  }
+}
+
+}  // debug
+}  // ash
diff --git a/ash/debug.h b/ash/debug.h
new file mode 100644
index 0000000..92838d6
--- /dev/null
+++ b/ash/debug.h
@@ -0,0 +1,22 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_DEBUG_H_
+#define ASH_DEBUG_H_
+
+#include "ash/ash_export.h"
+
+namespace ash {
+namespace debug {
+
+// Toggles debugging features controlled by
+// cc::LayerTreeDebugState.
+ASH_EXPORT void ToggleShowDebugBorders();
+ASH_EXPORT void ToggleShowFpsCounter();
+ASH_EXPORT void ToggleShowPaintRects();
+
+}  // debug
+}  // ash
+
+#endif  // ASH_DEBUG_H_
diff --git a/ash/desktop_background/desktop_background_controller.cc b/ash/desktop_background/desktop_background_controller.cc
index 385e3df..835ad22 100644
--- a/ash/desktop_background/desktop_background_controller.cc
+++ b/ash/desktop_background/desktop_background_controller.cc
@@ -121,7 +121,7 @@
     : locked_(false),
       desktop_background_mode_(BACKGROUND_NONE),
       background_color_(kTransparentColor),
-      weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
+      weak_ptr_factory_(this) {
 }
 
 DesktopBackgroundController::~DesktopBackgroundController() {
@@ -129,7 +129,7 @@
 }
 
 gfx::ImageSkia DesktopBackgroundController::GetWallpaper() const {
-  if (current_wallpaper_.get())
+  if (current_wallpaper_)
     return current_wallpaper_->wallpaper_image();
   return gfx::ImageSkia();
 }
@@ -145,7 +145,7 @@
 }
 
 WallpaperLayout DesktopBackgroundController::GetWallpaperLayout() const {
-  if (current_wallpaper_.get())
+  if (current_wallpaper_)
     return current_wallpaper_->wallpaper_info().layout;
   return WALLPAPER_LAYOUT_CENTER_CROPPED;
 }
@@ -157,9 +157,9 @@
 }
 
 int DesktopBackgroundController::GetWallpaperIDR() const {
-  if (wallpaper_loader_.get())
+  if (wallpaper_loader_)
     return wallpaper_loader_->idr();
-  else if (current_wallpaper_.get())
+  else if (current_wallpaper_)
     return current_wallpaper_->wallpaper_info().idr;
   else
     return -1;
@@ -224,7 +224,7 @@
 
 void DesktopBackgroundController::CancelPendingWallpaperOperation() {
   // Set canceled flag of previous request to skip unneeded loading.
-  if (wallpaper_loader_.get())
+  if (wallpaper_loader_)
     wallpaper_loader_->Cancel();
 
   // Cancel reply callback for previous request.
@@ -319,7 +319,8 @@
   Shell::GetContainer(root_window,container_id)->
       layer()->Add(background_layer);
 
-  MessageLoop::current()->PostTask(FROM_HERE,
+  base::MessageLoop::current()->PostTask(
+      FROM_HERE,
       base::Bind(&DesktopBackgroundController::NotifyAnimationFinished,
                  weak_ptr_factory_.GetWeakPtr()));
 
diff --git a/ash/desktop_background/desktop_background_controller_unittest.cc b/ash/desktop_background/desktop_background_controller_unittest.cc
index 201f7ac..6521663 100644
--- a/ash/desktop_background/desktop_background_controller_unittest.cc
+++ b/ash/desktop_background/desktop_background_controller_unittest.cc
@@ -75,11 +75,11 @@
   }
 
   void WaitForResize() {
-    MessageLoop::current()->Run();
+    base::MessageLoop::current()->Run();
   }
 
   virtual void OnWallpaperResized() OVERRIDE {
-    MessageLoop::current()->Quit();
+    base::MessageLoop::current()->Quit();
   }
 
   void AddWallpaperResizerObserver() {
diff --git a/ash/desktop_background/desktop_background_view.cc b/ash/desktop_background/desktop_background_view.cc
index 1ae7378..6d6e487 100644
--- a/ash/desktop_background/desktop_background_view.cc
+++ b/ash/desktop_background/desktop_background_view.cc
@@ -11,8 +11,8 @@
 #include "ash/desktop_background/desktop_background_widget_controller.h"
 #include "ash/desktop_background/user_wallpaper_delegate.h"
 #include "ash/root_window_controller.h"
+#include "ash/session_state_delegate.h"
 #include "ash/shell.h"
-#include "ash/shell_delegate.h"
 #include "ash/shell_window_ids.h"
 #include "ash/wm/property_util.h"
 #include "ash/wm/window_animations.h"
@@ -61,7 +61,6 @@
   }
 
   virtual void OnImplicitAnimationsCompleted() OVERRIDE {
-    DCHECK(desktop_widget_);
     GetRootWindowController(root_window_)->HandleDesktopBackgroundVisible();
     ash::Shell::GetInstance()->user_wallpaper_delegate()->
         OnWallpaperAnimationFinished();
@@ -84,8 +83,7 @@
 
   // Overridden from views::WidgetObserver.
   virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE {
-    desktop_widget_->RemoveObserver(this);
-    desktop_widget_ = NULL;
+    delete this;
   }
 
   aura::RootWindow* root_window_;
@@ -203,8 +201,7 @@
   // 4. From an empty background, guest user logged in.
   if (wallpaper_delegate->ShouldShowInitialAnimation() ||
       root_window->GetProperty(kAnimatingDesktopController) ||
-      Shell::GetInstance()->delegate()->IsGuestSession() ||
-      Shell::GetInstance()->delegate()->IsUserLoggedIn()) {
+      Shell::GetInstance()->session_state_delegate()->HasActiveUser()) {
     views::corewm::SetWindowVisibilityAnimationTransition(
         desktop_widget->GetNativeView(), views::corewm::ANIMATE_SHOW);
   } else {
diff --git a/ash/desktop_background/desktop_background_widget_controller.cc b/ash/desktop_background/desktop_background_widget_controller.cc
index 5b93452..98d1ba4 100644
--- a/ash/desktop_background/desktop_background_widget_controller.cc
+++ b/ash/desktop_background/desktop_background_widget_controller.cc
@@ -39,7 +39,7 @@
     widget_->RemoveObserver(this);
     widget_->CloseNow();
     widget_ = NULL;
-  } else if (layer_.get())
+  } else if (layer_)
     layer_.reset(NULL);
 }
 
@@ -52,7 +52,7 @@
 void DesktopBackgroundWidgetController::SetBounds(gfx::Rect bounds) {
   if (widget_)
     widget_->SetBounds(bounds);
-  else if (layer_.get())
+  else if (layer_)
     layer_->SetBounds(bounds);
 }
 
@@ -64,7 +64,7 @@
         root_window->GetChildById(dest_container));
     return true;
   }
-  if (layer_.get()) {
+  if (layer_) {
     ui::Layer* layer = layer_.get();
     root_window->GetChildById(src_container)->layer()->Remove(layer);
     root_window->GetChildById(dest_container)->layer()->Add(layer);
diff --git a/ash/desktop_background/wallpaper_resizer.cc b/ash/desktop_background/wallpaper_resizer.cc
index eb88932..9e2f0ab 100644
--- a/ash/desktop_background/wallpaper_resizer.cc
+++ b/ash/desktop_background/wallpaper_resizer.cc
@@ -34,7 +34,7 @@
                         WallpaperLayout layout,
                         int width,
                         int height,
-                        MessageLoop* origin_loop,
+                        base::MessageLoop* origin_loop,
                         const ResizedCallback& callback) {
   SkBitmap resized_wallpaper = wallpaper;
   if (wallpaper.width() > width || wallpaper.height() > height) {
@@ -95,14 +95,14 @@
     : wallpaper_info_(info),
       wallpaper_image_(*(ui::ResourceBundle::GetSharedInstance().
           GetImageNamed(info.idr).ToImageSkia())),
-      weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
+      weak_ptr_factory_(this) {
 }
 
 WallpaperResizer::WallpaperResizer(const WallpaperInfo& info,
                                    const gfx::ImageSkia& image)
     : wallpaper_info_(info),
       wallpaper_image_(image),
-      weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
+      weak_ptr_factory_(this) {
 }
 
 WallpaperResizer::~WallpaperResizer() {
@@ -122,16 +122,16 @@
   }
 
   if (!BrowserThread::GetBlockingPool()->PostWorkerTaskWithShutdownBehavior(
-      FROM_HERE,
-      base::Bind(&ResizeToFitScreens,
-                 *wallpaper_image_.bitmap(),
-                 wallpaper_info_.layout,
-                 width,
-                 height,
-                 MessageLoop::current(),
-                 base::Bind(&WallpaperResizer::OnResizeFinished,
-                            weak_ptr_factory_.GetWeakPtr())),
-      base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)) {
+          FROM_HERE,
+          base::Bind(&ResizeToFitScreens,
+                     *wallpaper_image_.bitmap(),
+                     wallpaper_info_.layout,
+                     width,
+                     height,
+                     base::MessageLoop::current(),
+                     base::Bind(&WallpaperResizer::OnResizeFinished,
+                                weak_ptr_factory_.GetWeakPtr())),
+          base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)) {
     LOG(WARNING) << "PostSequencedWorkerTask failed. " <<
                     "Wallpaper may not be resized.";
   }
diff --git a/ash/display/display_change_observer_x11.cc b/ash/display/display_change_observer_x11.cc
index 4221be2..90047a1 100644
--- a/ash/display/display_change_observer_x11.cc
+++ b/ash/display/display_change_observer_x11.cc
@@ -124,9 +124,11 @@
     }
   }
   XRRFreeScreenResources(screen_resources);
+  Shell::GetInstance()->AddShellObserver(this);
 }
 
 DisplayChangeObserverX11::~DisplayChangeObserverX11() {
+  Shell::GetInstance()->RemoveShellObserver(this);
 }
 
 chromeos::OutputState DisplayChangeObserverX11::GetStateForOutputs(
@@ -223,5 +225,13 @@
   Shell::GetInstance()->display_manager()->OnNativeDisplaysChanged(displays);
 }
 
+void DisplayChangeObserverX11::OnAppTerminating() {
+#if defined(USE_ASH)
+  // Stop handling display configuration events once the shutdown
+  // process starts. crbug.com/177014.
+  Shell::GetInstance()->output_configurator()->Stop();
+#endif
+}
+
 }  // namespace internal
 }  // namespace ash
diff --git a/ash/display/display_change_observer_x11.h b/ash/display/display_change_observer_x11.h
index 5396afd..137137b 100644
--- a/ash/display/display_change_observer_x11.h
+++ b/ash/display/display_change_observer_x11.h
@@ -10,6 +10,7 @@
 // Xlib.h defines RootWindow.
 #undef RootWindow
 
+#include "ash/shell_observer.h"
 #include "base/basictypes.h"
 #include "chromeos/display/output_configurator.h"
 
@@ -18,19 +19,24 @@
 
 // An object that observes changes in display configuration and
 // update DisplayManagers.
-class DisplayChangeObserverX11 : public chromeos::OutputConfigurator::Delegate,
-                                 public chromeos::OutputConfigurator::Observer {
+class DisplayChangeObserverX11
+    : public chromeos::OutputConfigurator::StateController,
+      public chromeos::OutputConfigurator::Observer,
+      public ShellObserver {
  public:
   DisplayChangeObserverX11();
   virtual ~DisplayChangeObserverX11();
 
-  // chromeos::OutputConfigurator::Delegate overrides:
+  // chromeos::OutputConfigurator::StateController overrides:
   virtual chromeos::OutputState GetStateForOutputs(
       const std::vector<chromeos::OutputInfo>& outputs) const OVERRIDE;
 
   // Overriden from chromeos::OutputConfigurator::Observer:
   virtual void OnDisplayModeChanged() OVERRIDE;
 
+  // Overriden from ShellObserver:
+  virtual void OnAppTerminating() OVERRIDE;
+
  private:
   Display* xdisplay_;
 
diff --git a/ash/display/display_controller.cc b/ash/display/display_controller.cc
index feb3b2a..4be9ca4 100644
--- a/ash/display/display_controller.cc
+++ b/ash/display/display_controller.cc
@@ -5,9 +5,13 @@
 #include "ash/display/display_controller.h"
 
 #include <algorithm>
+#include <cmath>
+#include <map>
 
+#include "ash/ash_root_window_transformer.h"
 #include "ash/ash_switches.h"
 #include "ash/display/display_manager.h"
+#include "ash/display/display_pref_util.h"
 #include "ash/host/root_window_host_factory.h"
 #include "ash/root_window_controller.h"
 #include "ash/screen_ash.h"
@@ -17,23 +21,31 @@
 #include "ash/wm/window_util.h"
 #include "base/command_line.h"
 #include "base/json/json_value_converter.h"
-#include "base/string_piece.h"
 #include "base/stringprintf.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_piece.h"
 #include "base/values.h"
+#include "third_party/skia/include/utils/SkMatrix44.h"
+#include "ui/aura/client/activation_client.h"
+#include "ui/aura/client/capture_client.h"
+#include "ui/aura/client/cursor_client.h"
+#include "ui/aura/client/focus_client.h"
 #include "ui/aura/client/screen_position_client.h"
 #include "ui/aura/env.h"
 #include "ui/aura/root_window.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_property.h"
+#include "ui/aura/window_tracker.h"
+#include "ui/compositor/compositor.h"
 #include "ui/compositor/dip_util.h"
 #include "ui/gfx/display.h"
 #include "ui/gfx/screen.h"
 
 #if defined(OS_CHROMEOS)
-#include "ash/display/output_configurator_animation.h"
 #include "base/chromeos/chromeos_version.h"
-#include "base/string_number_conversions.h"
 #include "base/time.h"
+#if defined(USE_X11)
+#include "ash/display/output_configurator_animation.h"
 #include "chromeos/display/output_configurator.h"
 #include "ui/base/x/x11_util.h"
 
@@ -41,16 +53,12 @@
 // potential conflict with chrome headers.
 #include <X11/extensions/Xrandr.h>
 #undef RootWindow
+#endif  // defined(USE_X11)
 #endif  // defined(OS_CHROMEOS)
 
-DECLARE_WINDOW_PROPERTY_TYPE(gfx::Display::Rotation);
-
 namespace ash {
 namespace {
 
-DEFINE_WINDOW_PROPERTY_KEY(gfx::Display::Rotation, kRotationPropertyKey,
-                           gfx::Display::ROTATE_0);
-
 // Primary display stored in global object as it can be
 // accessed after Shell is deleted. A separate display instance is created
 // during the shutdown instead of always keeping two display instances
@@ -83,98 +91,46 @@
 const char kPositionKey[] = "position";
 const char kOffsetKey[] = "offset";
 const char kMirroredKey[] = "mirrored";
+const char kPrimaryIdKey[] = "primary-id";
+
+typedef std::map<DisplayLayout::Position, std::string> PositionToStringMap;
+
+const PositionToStringMap* GetPositionToStringMap() {
+  static const PositionToStringMap* map = CreateToStringMap(
+      DisplayLayout::TOP, "top",
+      DisplayLayout::BOTTOM, "bottom",
+      DisplayLayout::RIGHT, "right",
+      DisplayLayout::LEFT, "left");
+  return map;
+}
 
 bool GetPositionFromString(const base::StringPiece& position,
                            DisplayLayout::Position* field) {
-  if (position == "top") {
-    *field = DisplayLayout::TOP;
+  if (ReverseFind(GetPositionToStringMap(), position, field))
     return true;
-  } else if (position == "bottom") {
-    *field = DisplayLayout::BOTTOM;
-    return true;
-  } else if (position == "right") {
-    *field = DisplayLayout::RIGHT;
-    return true;
-  } else if (position == "left") {
-    *field = DisplayLayout::LEFT;
-    return true;
-  }
-  LOG(ERROR) << "Invalid position value: " << position;
+  LOG(ERROR) << "Invalid position value:" << position;
   return false;
 }
 
 std::string GetStringFromPosition(DisplayLayout::Position position) {
-  switch (position) {
-    case DisplayLayout::TOP:
-      return std::string("top");
-    case DisplayLayout::BOTTOM:
-      return std::string("bottom");
-    case DisplayLayout::RIGHT:
-      return std::string("right");
-    case DisplayLayout::LEFT:
-      return std::string("left");
-  }
-  return std::string("unknown");
+  const PositionToStringMap* map = GetPositionToStringMap();
+  PositionToStringMap::const_iterator iter = map->find(position);
+  return iter != map->end() ? iter->second : std::string("unknown");
+}
+
+bool GetDisplayIdFromString(const base::StringPiece& position, int64* field) {
+  return base::StringToInt64(position, field);
 }
 
 internal::DisplayManager* GetDisplayManager() {
   return Shell::GetInstance()->display_manager();
 }
 
-void RotateRootWindow(aura::RootWindow* root_window,
-                      const gfx::Display& display,
-                      const internal::DisplayInfo& info) {
-  // TODO(oshima): Add animation. (crossfade+rotation, or just cross-fade)
-#if defined(OS_WIN)
-  // Windows 8 bots refused to resize the host window, and
-  // updating the transform results in incorrectly resizing
-  // the root window. Don't apply the transform unless
-  // necessary so that unit tests pass on win8 bots.
-  if (info.rotation() == root_window->GetProperty(kRotationPropertyKey))
-    return;
-  root_window->SetProperty(kRotationPropertyKey, info.rotation());
-#endif
-  gfx::Transform rotate;
-  // TODO(oshima): Manually complute the inverse of the
-  // rotate+translate matrix to compensate for computation error in
-  // the inverted matrix. Ideally, SkMatrix should have special
-  // case handling for rotate+translate case. crbug.com/222483.
-  gfx::Transform reverse_rotate;
-
-  // The origin is (0, 0), so the translate width/height must be reduced by 1.
-  switch (info.rotation()) {
-    case gfx::Display::ROTATE_0:
-      break;
-    case gfx::Display::ROTATE_90:
-      rotate.Translate(display.bounds().height() - 1, 0);
-      rotate.Rotate(90);
-      // Rotate 270 instead of 90 as it will cause calcuration error.
-      reverse_rotate.Rotate(270);
-      reverse_rotate.Translate(-(display.bounds().height() - 1), 0);
-      break;
-    case gfx::Display::ROTATE_270:
-      rotate.Translate(0, display.bounds().width() - 1);
-      rotate.Rotate(270);
-      reverse_rotate.Rotate(90);
-      reverse_rotate.Translate(0, -(display.bounds().width() - 1));
-      break;
-    case gfx::Display::ROTATE_180:
-      rotate.Translate(display.bounds().width() - 1,
-                       display.bounds().height() - 1);
-      rotate.Rotate(180);
-      reverse_rotate.Rotate(180);
-      reverse_rotate.Translate(-(display.bounds().width() - 1),
-                               -(display.bounds().height() - 1));
-      break;
-  }
-  root_window->SetTransformPair(rotate, reverse_rotate);
-}
-
 void SetDisplayPropertiesOnHostWindow(aura::RootWindow* root,
                                       const gfx::Display& display) {
   internal::DisplayInfo info =
       GetDisplayManager()->GetDisplayInfo(display.id());
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) && defined(USE_X11)
   // Native window property (Atom in X11) that specifies the display's
   // rotation, scale factor and if it's internal display.  They are
   // read and used by touchpad/mouse driver directly on X (contact
@@ -211,11 +167,80 @@
                      kCARDINAL,
                      100 * display.device_scale_factor());
 #endif
-  RotateRootWindow(root, display, info);
+  scoped_ptr<aura::RootWindowTransformer> transformer(
+      new AshRootWindowTransformer(root, display));
+  root->SetRootWindowTransformer(transformer.Pass());
 }
 
 }  // namespace
 
+namespace internal {
+
+// A utility class to store/restore focused/active window
+// when the display configuration has changed.
+class FocusActivationStore {
+ public:
+  FocusActivationStore()
+      : activation_client_(NULL),
+        capture_client_(NULL),
+        focus_client_(NULL),
+        focused_(NULL),
+        active_(NULL) {
+  }
+
+  void Store() {
+    if (!activation_client_) {
+      aura::RootWindow* root = Shell::GetPrimaryRootWindow();
+      activation_client_ = aura::client::GetActivationClient(root);
+      capture_client_ = aura::client::GetCaptureClient(root);
+      focus_client_ = aura::client::GetFocusClient(root);
+    }
+    focused_ = focus_client_->GetFocusedWindow();
+    if (focused_)
+      tracker_.Add(focused_);
+    active_ = activation_client_->GetActiveWindow();
+    if (active_ && focused_ != active_)
+      tracker_.Add(active_);
+
+    // Deactivate the window to close menu / bubble windows.
+    activation_client_->DeactivateWindow(active_);
+    // Release capture if any.
+    capture_client_->SetCapture(NULL);
+    // Clear the focused window if any. This is necessary because a
+    // window may be deleted when losing focus (fullscreen flash for
+    // example).  If the focused window is still alive after move, it'll
+    // be re-focused below.
+    focus_client_->FocusWindow(NULL);
+  }
+
+  void Restore() {
+    // Restore focused or active window if it's still alive.
+    if (focused_ && tracker_.Contains(focused_)) {
+      focus_client_->FocusWindow(focused_);
+    } else if (active_ && tracker_.Contains(active_)) {
+      activation_client_->ActivateWindow(active_);
+    }
+    if (focused_)
+      tracker_.Remove(focused_);
+    if (active_)
+      tracker_.Remove(active_);
+    focused_ = NULL;
+    active_ = NULL;
+  }
+
+ private:
+  aura::client::ActivationClient* activation_client_;
+  aura::client::CaptureClient* capture_client_;
+  aura::client::FocusClient* focus_client_;
+  aura::WindowTracker tracker_;
+  aura::Window* focused_;
+  aura::Window* active_;
+
+  DISALLOW_COPY_AND_ASSIGN(FocusActivationStore);
+};
+
+}  // namespace internal
+
 ////////////////////////////////////////////////////////////////////////////////
 // DisplayLayout
 
@@ -227,12 +252,15 @@
 DisplayLayout::DisplayLayout()
     : position(RIGHT),
       offset(0),
-      mirrored(false) {}
+      mirrored(false),
+      primary_id(gfx::Display::kInvalidDisplayID) {
+}
 
 DisplayLayout::DisplayLayout(DisplayLayout::Position position, int offset)
     : position(position),
       offset(offset),
-      mirrored(false) {
+      mirrored(false),
+      primary_id(gfx::Display::kInvalidDisplayID) {
   DCHECK_LE(TOP, position);
   DCHECK_GE(LEFT, position);
 
@@ -260,7 +288,9 @@
       inverted_position = RIGHT;
       break;
   }
-  return DisplayLayout(inverted_position, -offset);
+  DisplayLayout ret = DisplayLayout(inverted_position, -offset);
+  ret.primary_id = primary_id;
+  return ret;
 }
 
 // static
@@ -281,6 +311,7 @@
   dict_value->SetString(kPositionKey, position_str);
   dict_value->SetInteger(kOffsetKey, layout.offset);
   dict_value->SetBoolean(kMirroredKey, layout.mirrored);
+  dict_value->SetString(kPrimaryIdKey, base::Int64ToString(layout.primary_id));
   return true;
 }
 
@@ -298,6 +329,8 @@
       kPositionKey, &DisplayLayout::position, &GetPositionFromString);
   converter->RegisterIntField(kOffsetKey, &DisplayLayout::offset);
   converter->RegisterBoolField(kMirroredKey, &DisplayLayout::mirrored);
+  converter->RegisterCustomField<int64>(
+      kPrimaryIdKey, &DisplayLayout::primary_id, &GetDisplayIdFromString);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -321,8 +354,9 @@
 // DisplayController
 
 DisplayController::DisplayController()
-    : desired_primary_display_id_(gfx::Display::kInvalidDisplayID),
-      primary_root_window_for_replace_(NULL) {
+    : primary_root_window_for_replace_(NULL),
+      in_bootstrap_(true),
+      focus_activation_store_(new internal::FocusActivationStore()) {
   CommandLine* command_line = CommandLine::ForCurrentProcess();
 #if defined(OS_CHROMEOS)
   if (!command_line->HasSwitch(switches::kAshDisableDisplayChangeLimiter) &&
@@ -360,6 +394,7 @@
 
 void DisplayController::Start() {
   Shell::GetScreen()->AddObserver(this);
+  in_bootstrap_ = false;
 }
 
 void DisplayController::Shutdown() {
@@ -414,12 +449,17 @@
     const gfx::Display* display = display_manager->GetDisplayAt(i);
     if (primary_display_id != display->id()) {
       aura::RootWindow* root = AddRootWindowForDisplay(*display);
-      if (desired_primary_display_id_ == display->id())
-        SetPrimaryDisplay(*display);
       Shell::GetInstance()->InitRootWindowForSecondaryDisplay(root);
     }
   }
-  UpdateDisplayBoundsForLayout();
+  if (display_manager->GetNumDisplays() > 1) {
+    UpdateDisplayBoundsForLayout();
+    DisplayIdPair pair = GetCurrentDisplayIdPair();
+    DisplayLayout layout = GetCurrentDisplayLayout();
+    SetPrimaryDisplayId(
+        layout.primary_id == gfx::Display::kInvalidDisplayID ?
+        pair.first : layout.primary_id);
+  }
 }
 
 void DisplayController::AddObserver(Observer* observer) {
@@ -495,14 +535,8 @@
 
 void DisplayController::SetDefaultDisplayLayout(const DisplayLayout& layout) {
   CommandLine* command_line = CommandLine::ForCurrentProcess();
-  if (!command_line->HasSwitch(switches::kAshSecondaryDisplayLayout) &&
-      (default_display_layout_.position != layout.position ||
-       default_display_layout_.offset != layout.offset)) {
+  if (!command_line->HasSwitch(switches::kAshSecondaryDisplayLayout))
     default_display_layout_ = layout;
-    NotifyDisplayConfigurationChanging();
-    UpdateDisplayBoundsForLayout();
-    NotifyDisplayConfigurationChanged();
-  }
 }
 
 void DisplayController::RegisterLayoutForDisplayIdPair(
@@ -540,6 +574,7 @@
   const DisplayLayout& current_layout = paired_layouts_[pair];
   if (to_set.position != current_layout.position ||
       to_set.offset != current_layout.offset) {
+    to_set.primary_id = primary.id();
     paired_layouts_[pair] = to_set;
     NotifyDisplayConfigurationChanging();
     UpdateDisplayBoundsForLayout();
@@ -586,12 +621,12 @@
 }
 
 void DisplayController::CycleDisplayMode() {
-  if (limiter_.get()) {
+  if (limiter_) {
     if  (limiter_->IsThrottled())
       return;
     limiter_->SetThrottleTimeout(kCycleDisplayThrottleTimeoutMs);
   }
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) && defined(USE_X11)
   Shell* shell = Shell::GetInstance();
   internal::DisplayManager* display_manager = GetDisplayManager();
   if (!base::chromeos::IsRunningOnChromeOS()) {
@@ -610,14 +645,14 @@
 }
 
 void DisplayController::SwapPrimaryDisplay() {
-  if (limiter_.get()) {
+  if (limiter_) {
     if  (limiter_->IsThrottled())
       return;
     limiter_->SetThrottleTimeout(kSwapDisplayThrottleTimeoutMs);
   }
 
   if (Shell::GetScreen()->GetNumDisplays() > 1) {
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) && defined(USE_X11)
     internal::OutputConfiguratorAnimation* animation =
         Shell::GetInstance()->output_configurator_animation();
     if (animation) {
@@ -634,19 +669,13 @@
 }
 
 void DisplayController::SetPrimaryDisplayId(int64 id) {
-  desired_primary_display_id_ = id;
-
-  if (desired_primary_display_id_ == primary_display_id)
+  DCHECK_NE(gfx::Display::kInvalidDisplayID, id);
+  if (id == gfx::Display::kInvalidDisplayID || primary_display_id == id)
     return;
 
-  internal::DisplayManager* display_manager = GetDisplayManager();
-  for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) {
-    gfx::Display* display = display_manager->GetDisplayAt(i);
-    if (display->id() == id) {
-      SetPrimaryDisplay(*display);
-      break;
-    }
-  }
+  const gfx::Display& display = GetDisplayManager()->GetDisplayForId(id);
+  if (display.is_valid())
+    SetPrimaryDisplay(display);
 }
 
 void DisplayController::SetPrimaryDisplay(
@@ -689,7 +718,7 @@
                                 old_primary_display.id());
 
   primary_display_id = new_primary_display.id();
-  desired_primary_display_id_ = primary_display_id;
+  paired_layouts_[GetCurrentDisplayIdPair()].primary_id = primary_display_id;
 
   display_manager->UpdateWorkAreaOfDisplayNearestWindow(
       primary_root, old_primary_display.GetWorkAreaInsets());
@@ -714,8 +743,84 @@
       display_manager->GetDisplayAt(1) : display_manager->GetDisplayAt(0);
 }
 
+void DisplayController::EnsurePointerInDisplays() {
+  // Don't try to move the pointer during the boot/startup.
+  if (!HasPrimaryDisplay())
+    return;
+  gfx::Point location_in_screen = Shell::GetScreen()->GetCursorScreenPoint();
+  gfx::Point target_location;
+  int64 closest_distance_squared = -1;
+  internal::DisplayManager* display_manager = GetDisplayManager();
+
+  aura::RootWindow* dst_root_window = NULL;
+  for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) {
+    const gfx::Display* display = display_manager->GetDisplayAt(i);
+    aura::RootWindow* root_window = GetRootWindowForDisplayId(display->id());
+    if (display->bounds().Contains(location_in_screen)) {
+      dst_root_window = root_window;
+      target_location = location_in_screen;
+      break;
+    }
+    gfx::Point center = display->bounds().CenterPoint();
+    // Use the distance squared from the center of the dislay. This is not
+    // exactly "closest" display, but good enough to pick one
+    // appropriate (and there are at most two displays).
+    // We don't care about actual distance, only relative to other displays, so
+    // using the LengthSquared() is cheaper than Length().
+
+    int64 distance_squared = (center - location_in_screen).LengthSquared();
+    if (closest_distance_squared < 0 ||
+        closest_distance_squared > distance_squared) {
+      dst_root_window = root_window;
+      target_location = center;
+      closest_distance_squared = distance_squared;
+    }
+  }
+  DCHECK(dst_root_window);
+  aura::client::ScreenPositionClient* client =
+      aura::client::GetScreenPositionClient(dst_root_window);
+  client->ConvertPointFromScreen(dst_root_window, &target_location);
+  dst_root_window->MoveCursorTo(target_location);
+}
+
+gfx::Point DisplayController::GetNativeMouseCursorLocation() const {
+  if (in_bootstrap())
+    return gfx::Point();
+
+  gfx::Point location = Shell::GetScreen()->GetCursorScreenPoint();
+  const gfx::Display& display =
+      Shell::GetScreen()->GetDisplayNearestPoint(location);
+  const aura::RootWindow* root_window =
+      root_windows_.find(display.id())->second;
+  aura::client::ScreenPositionClient* client =
+      aura::client::GetScreenPositionClient(root_window);
+  client->ConvertPointFromScreen(root_window, &location);
+  root_window->ConvertPointToNativeScreen(&location);
+  return location;
+}
+
+void DisplayController::UpdateMouseCursor(const gfx::Point& point_in_native) {
+  if (in_bootstrap())
+    return;
+
+  std::vector<aura::RootWindow*> root_windows = GetAllRootWindows();
+  for (std::vector<aura::RootWindow*>::iterator iter = root_windows.begin();
+       iter != root_windows.end();
+       ++iter) {
+    aura::RootWindow* root_window = *iter;
+    gfx::Rect bounds_in_native(root_window->GetHostOrigin(),
+                               root_window->GetHostSize());
+    if (bounds_in_native.Contains(point_in_native)) {
+      gfx::Point point(point_in_native);
+      root_window->ConvertPointFromNativeScreen(&point);
+      root_window->MoveCursorTo(point);
+      break;
+    }
+  }
+}
+
 void DisplayController::OnDisplayBoundsChanged(const gfx::Display& display) {
-  if (limiter_.get())
+  if (limiter_)
     limiter_->SetThrottleTimeout(kAfterDisplayChangeThrottleTimeoutMs);
   const internal::DisplayInfo& display_info =
       GetDisplayManager()->GetDisplayInfo(display.id());
@@ -723,15 +828,12 @@
 
   UpdateDisplayBoundsForLayout();
   aura::RootWindow* root = root_windows_[display.id()];
-  root->SetHostBoundsAndInsetsAndRootWindowScale(
-      display_info.bounds_in_pixel(),
-      display_info.GetOverscanInsetsInPixel(),
-      display_info.ui_scale());
   SetDisplayPropertiesOnHostWindow(root, display);
+  root->SetHostBounds(display_info.bounds_in_pixel());
 }
 
 void DisplayController::OnDisplayAdded(const gfx::Display& display) {
-  if (limiter_.get())
+  if (limiter_)
     limiter_->SetThrottleTimeout(kAfterDisplayChangeThrottleTimeoutMs);
 
   if (primary_root_window_for_replace_) {
@@ -744,22 +846,20 @@
     UpdateDisplayBoundsForLayout();
     const internal::DisplayInfo& display_info =
         GetDisplayManager()->GetDisplayInfo(display.id());
-    root_windows_[display.id()]->SetHostBoundsAndInsetsAndRootWindowScale(
-        display_info.bounds_in_pixel(),
-        display_info.GetOverscanInsetsInPixel(),
-        display_info.ui_scale());
+    root_windows_[display.id()]->SetHostBounds(
+        display_info.bounds_in_pixel());
   } else {
+    if (primary_display_id == gfx::Display::kInvalidDisplayID)
+      primary_display_id = display.id();
     DCHECK(!root_windows_.empty());
     aura::RootWindow* root = AddRootWindowForDisplay(display);
     UpdateDisplayBoundsForLayout();
-    if (desired_primary_display_id_ == display.id())
-      SetPrimaryDisplay(display);
     Shell::GetInstance()->InitRootWindowForSecondaryDisplay(root);
   }
 }
 
 void DisplayController::OnDisplayRemoved(const gfx::Display& display) {
-  if (limiter_.get())
+  if (limiter_)
     limiter_->SetThrottleTimeout(kAfterDisplayChangeThrottleTimeoutMs);
 
   aura::RootWindow* root_to_delete = root_windows_[display.id()];
@@ -801,7 +901,7 @@
   // Delete most of root window related objects, but don't delete
   // root window itself yet because the stack may be using it.
   controller->Shutdown();
-  MessageLoop::current()->DeleteSoon(FROM_HERE, controller);
+  base::MessageLoop::current()->DeleteSoon(FROM_HERE, controller);
 }
 
 aura::RootWindow* DisplayController::CreateRootWindowForDisplay(
@@ -813,12 +913,10 @@
   aura::RootWindow::CreateParams params(bounds_in_pixel);
   params.host = Shell::GetInstance()->root_window_host_factory()->
       CreateRootWindowHost(bounds_in_pixel);
-  params.initial_insets = display_info.GetOverscanInsetsInPixel();
-  params.initial_root_window_scale = display_info.ui_scale();
   aura::RootWindow* root_window = new aura::RootWindow(params);
   root_window->SetName(
       base::StringPrintf("RootWindow-%d", root_window_count++));
-
+  root_window->compositor()->SetBackgroundColor(SK_ColorBLACK);
   // No need to remove RootWindowObserver because
   // the DisplayManager object outlives RootWindow objects.
   root_window->AddRootWindowObserver(GetDisplayManager());
@@ -894,18 +992,33 @@
 }
 
 void DisplayController::NotifyDisplayConfigurationChanging() {
+  if (in_bootstrap())
+    return;
   FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanging());
+  focus_activation_store_->Store();
 }
 
 void DisplayController::NotifyDisplayConfigurationChanged() {
+  if (in_bootstrap())
+    return;
+  focus_activation_store_->Restore();
+
   internal::DisplayManager* display_manager = GetDisplayManager();
   if (display_manager->num_connected_displays() > 1) {
     DisplayIdPair pair = GetCurrentDisplayIdPair();
-    bool exists = paired_layouts_.find(pair) != paired_layouts_.end();
-    if (exists || display_manager->IsMirrored()) {
-      if (!exists)
-        paired_layouts_[pair] = default_display_layout_;
-      paired_layouts_[pair].mirrored = display_manager->IsMirrored();
+    if (paired_layouts_.find(pair) == paired_layouts_.end())
+      paired_layouts_[pair] = default_display_layout_;
+    paired_layouts_[pair].mirrored = display_manager->IsMirrored();
+    if (Shell::GetScreen()->GetNumDisplays() > 1 ) {
+      int64 primary_id = paired_layouts_[pair].primary_id;
+      SetPrimaryDisplayId(
+          primary_id == gfx::Display::kInvalidDisplayID ?
+          pair.first : primary_id);
+      // Update the primary_id in case the above call is
+      // ignored. Happens when a) default layout's primary id
+      // doesn't exist, or b) the primary_id has already been
+      // set to the same and didn't update it.
+      paired_layouts_[pair].primary_id = GetPrimaryDisplay().id();
     }
   }
   FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanged());
@@ -922,7 +1035,7 @@
 }
 
 void DisplayController::OnFadeOutForSwapDisplayFinished() {
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) && defined(USE_X11)
   SetPrimaryDisplay(ScreenAsh::GetSecondaryDisplay());
   Shell::GetInstance()->output_configurator_animation()->StartFadeInAnimation();
 #endif
diff --git a/ash/display/display_controller.h b/ash/display/display_controller.h
index 322630e..ae6e3af 100644
--- a/ash/display/display_controller.h
+++ b/ash/display/display_controller.h
@@ -31,6 +31,7 @@
 namespace ash {
 namespace internal {
 class DisplayManager;
+class FocusActivationStore;
 class RootWindowController;
 }
 
@@ -45,7 +46,8 @@
     LEFT
   };
   // Factory method to create DisplayLayout from ints. The |mirrored| is
-  // set to false. Used for persistence and webui.
+  // set to false and |primary_id| is set to gfx::Display::kInvalidDisplayId.
+  // Used for persistence and webui.
   static DisplayLayout FromInts(int position, int offsets);
 
   DisplayLayout();
@@ -72,6 +74,9 @@
   // True if displays are mirrored.
   bool mirrored;
 
+  // The id of the display used as a primary display.
+  int64 primary_id;
+
   // Returns string representation of the layout for debugging/testing.
   std::string ToString() const;
 };
@@ -187,6 +192,16 @@
   // Returns the display layout registered for the given display id |pair|.
   DisplayLayout GetRegisteredDisplayLayout(const DisplayIdPair& pair) const;
 
+  // Checks if the mouse pointer is on one of displays, and moves to
+  // the center of the nearest display if it's outside of all displays.
+  void EnsurePointerInDisplays();
+
+  gfx::Point GetNativeMouseCursorLocation() const;
+
+  // Update the current cursor image that is sutable for the given
+  // |point_in_native|.
+  void UpdateMouseCursor(const gfx::Point& point_in_native);
+
   // aura::DisplayObserver overrides:
   virtual void OnDisplayBoundsChanged(
       const gfx::Display& display) OVERRIDE;
@@ -219,6 +234,8 @@
 
   void OnFadeOutForSwapDisplayFinished();
 
+  bool in_bootstrap() const { return in_bootstrap_; }
+
   class DisplayChangeLimiter {
    public:
     DisplayChangeLimiter();
@@ -248,16 +265,16 @@
   // Display layout per pair of devices.
   std::map<DisplayIdPair, DisplayLayout> paired_layouts_;
 
-  // The ID of the display which should be primary when connected.
-  // kInvalidDisplayID if no such preference is specified.
-  int64 desired_primary_display_id_;
-
   ObserverList<Observer> observers_;
 
   // Store the primary root window temporarily while replacing
   // display.
   aura::RootWindow* primary_root_window_for_replace_;
 
+  bool in_bootstrap_;
+
+  scoped_ptr<internal::FocusActivationStore> focus_activation_store_;
+
   DISALLOW_COPY_AND_ASSIGN(DisplayController);
 };
 
diff --git a/ash/display/display_controller_unittest.cc b/ash/display/display_controller_unittest.cc
index 02513fa..8ac928d 100644
--- a/ash/display/display_controller_unittest.cc
+++ b/ash/display/display_controller_unittest.cc
@@ -25,6 +25,8 @@
 namespace test {
 namespace {
 
+const char kDesktopBackgroundView[] = "DesktopBackgroundView";
+
 class TestObserver : public DisplayController::Observer {
  public:
   TestObserver() : changing_count_(0), changed_count_(0) {
@@ -71,16 +73,20 @@
                                         int offset) {
   DisplayController* display_controller =
       Shell::GetInstance()->display_controller();
-  DisplayLayout layout = display_controller->default_display_layout();
-  layout.position = position;
-  layout.offset = offset;
-  display_controller->SetDefaultDisplayLayout(layout);
+  DisplayLayout layout(position, offset);
+  ASSERT_GT(Shell::GetScreen()->GetNumDisplays(), 1);
+  display_controller->SetLayoutForCurrentDisplays(layout);
 }
 
 void SetSecondaryDisplayLayout(DisplayLayout::Position position) {
   SetSecondaryDisplayLayoutAndOffset(position, 0);
 }
 
+void SetDefaultDisplayLayout(DisplayLayout::Position position) {
+  Shell::GetInstance()->display_controller()->
+      SetDefaultDisplayLayout(DisplayLayout(position, 0));
+}
+
 class DisplayControllerShutdownTest : public test::AshTestBase {
  public:
   virtual void TearDown() OVERRIDE {
@@ -94,17 +100,48 @@
 
 class TestEventHandler : public ui::EventHandler {
  public:
-  TestEventHandler() : target_root_(NULL) {}
+  TestEventHandler() : target_root_(NULL),
+                       touch_radius_x_(0.0),
+                       touch_radius_y_(0.0),
+                       scroll_x_offset_(0.0),
+                       scroll_y_offset_(0.0),
+                       scroll_x_offset_ordinal_(0.0),
+                       scroll_y_offset_ordinal_(0.0) {}
   virtual ~TestEventHandler() {}
 
   virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
+    if (event->flags() & ui::EF_IS_SYNTHESIZED)
+      return;
+    aura::Window* target = static_cast<aura::Window*>(event->target());
+    mouse_location_ = event->root_location();
+    target_root_ = target->GetRootWindow();
+    event->StopPropagation();
+  }
+
+  virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE {
     aura::Window* target = static_cast<aura::Window*>(event->target());
     // Only record when the target is the background which covers
     // entire root window.
-    if (target->name() != "DesktopBackgroundView")
+    if (target->name() != kDesktopBackgroundView)
       return;
-    mouse_location_ = event->location();
-    target_root_ = target->GetRootWindow();
+    touch_radius_x_ = event->radius_x();
+    touch_radius_y_ = event->radius_y();
+    event->StopPropagation();
+  }
+
+  virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE {
+    aura::Window* target = static_cast<aura::Window*>(event->target());
+    // Only record when the target is the background which covers
+    // entire root window.
+    if (target->name() != kDesktopBackgroundView)
+      return;
+
+    if (event->type() == ui::ET_SCROLL) {
+      scroll_x_offset_ = event->x_offset();
+      scroll_y_offset_ = event->y_offset();
+      scroll_x_offset_ordinal_ = event->x_offset_ordinal();
+      scroll_y_offset_ordinal_ = event->y_offset_ordinal();
+    }
     event->StopPropagation();
   }
 
@@ -115,10 +152,24 @@
     return result;
   }
 
+  float touch_radius_x() { return touch_radius_x_; }
+  float touch_radius_y() { return touch_radius_y_; }
+  float scroll_x_offset() { return scroll_x_offset_; }
+  float scroll_y_offset() { return scroll_y_offset_; }
+  float scroll_x_offset_ordinal() { return scroll_x_offset_ordinal_; }
+  float scroll_y_offset_ordinal() { return scroll_y_offset_ordinal_; }
+
  private:
   gfx::Point mouse_location_;
   aura::RootWindow* target_root_;
 
+  float touch_radius_x_;
+  float touch_radius_y_;
+  float scroll_x_offset_;
+  float scroll_y_offset_;
+  float scroll_x_offset_ordinal_;
+  float scroll_y_offset_ordinal_;
+
   DISALLOW_COPY_AND_ASSIGN(TestEventHandler);
 };
 
@@ -210,9 +261,9 @@
 
 TEST_F(DisplayControllerTest, BoundsUpdated) {
   TestObserver observer;
-  SetSecondaryDisplayLayout(DisplayLayout::BOTTOM);
+  SetDefaultDisplayLayout(DisplayLayout::BOTTOM);
   UpdateDisplay("200x200,300x300");  // layout, resize and add.
-  EXPECT_EQ(2, observer.CountAndReset());
+  EXPECT_EQ(1, observer.CountAndReset());
 
   internal::DisplayManager* display_manager =
       Shell::GetInstance()->display_manager();
@@ -243,14 +294,14 @@
   EXPECT_EQ("0,0 400x400", GetPrimaryDisplay().bounds().ToString());
   EXPECT_EQ(1, Shell::GetScreen()->GetNumDisplays());
 
-  UpdateDisplay("400x500,700x700*2");
+  UpdateDisplay("400x500*2,300x300");
   EXPECT_EQ(1, observer.CountAndReset());
   ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
-  EXPECT_EQ("0,0 400x500", GetPrimaryDisplay().bounds().ToString());
-  EXPECT_EQ("0,500 350x350", GetSecondaryDisplay().bounds().ToString());
+  EXPECT_EQ("0,0 200x250", GetPrimaryDisplay().bounds().ToString());
+  EXPECT_EQ("0,250 300x300", GetSecondaryDisplay().bounds().ToString());
 
   // No change
-  UpdateDisplay("400x500,700x700*2");
+  UpdateDisplay("400x500*2,300x300");
   EXPECT_EQ(0, observer.CountAndReset());
 
   // Rotation
@@ -260,12 +311,16 @@
   display_manager->SetDisplayRotation(primary_id, gfx::Display::ROTATE_90);
   EXPECT_EQ(0, observer.CountAndReset());
 
-  // UI scale
+  // UI scale is eanbled only on internal display.
   int64 secondary_id = GetSecondaryDisplay().id();
   gfx::Display::SetInternalDisplayId(secondary_id);
-  display_manager->SetDisplayUIScale(secondary_id, 1.25f);
+  display_manager->SetDisplayUIScale(secondary_id, 1.125f);
   EXPECT_EQ(1, observer.CountAndReset());
-  display_manager->SetDisplayUIScale(secondary_id, 1.25f);
+  display_manager->SetDisplayUIScale(secondary_id, 1.125f);
+  EXPECT_EQ(0, observer.CountAndReset());
+  display_manager->SetDisplayUIScale(primary_id, 1.125f);
+  EXPECT_EQ(0, observer.CountAndReset());
+  display_manager->SetDisplayUIScale(primary_id, 1.125f);
   EXPECT_EQ(0, observer.CountAndReset());
 }
 
@@ -321,7 +376,13 @@
             DisplayLayout(DisplayLayout::BOTTOM, -80).Invert().ToString());
 }
 
-TEST_F(DisplayControllerTest, SwapPrimary) {
+// Crashes flakily on win8 aura bots: crbug.com/237642
+#if defined(OS_WIN) && defined(USE_AURA)
+#define MAYBE_SwapPrimary DISABLED_SwapPrimary
+#else
+#define MAYBE_SwapPrimary SwapPrimary
+#endif
+TEST_F(DisplayControllerTest, MAYBE_SwapPrimary) {
   DisplayController* display_controller =
       Shell::GetInstance()->display_controller();
 
@@ -365,7 +426,7 @@
   EXPECT_EQ("left, -50", inverted_layout.ToString());
 
   EXPECT_EQ(secondary_display.id(),
-      Shell::GetScreen()->GetPrimaryDisplay().id());
+            Shell::GetScreen()->GetPrimaryDisplay().id());
   EXPECT_EQ(primary_display.id(), ScreenAsh::GetSecondaryDisplay().id());
   EXPECT_EQ(secondary_display.id(),
             Shell::GetScreen()->GetDisplayNearestPoint(
@@ -413,7 +474,13 @@
   EXPECT_TRUE(primary_root->Contains(launcher_window));
 }
 
-TEST_F(DisplayControllerTest, SwapPrimaryById) {
+// Crashes flakily on win8 aura bots: crbug.com/237642
+#if defined(OS_WIN) && defined(USE_AURA)
+#define MAYBE_SwapPrimaryById DISABLED_SwapPrimaryById
+#else
+#define MAYBE_SwapPrimaryById SwapPrimaryById
+#endif
+TEST_F(DisplayControllerTest, MAYBE_SwapPrimaryById) {
   DisplayController* display_controller =
       Shell::GetInstance()->display_controller();
 
@@ -652,7 +719,7 @@
             ScreenAsh::GetSecondaryDisplay().bounds().ToString());
 
   aura::test::EventGenerator generator(root_windows[0]);
-  generator.MoveMouseTo(20, 25);
+  generator.MoveMouseToInHost(20, 25);
   EXPECT_EQ("5,15", event_handler.GetLocationAndReset());
 
   display_controller->ClearCustomOverscanInsets(display1.id());
@@ -660,7 +727,7 @@
   EXPECT_EQ("120,0 150x200",
             ScreenAsh::GetSecondaryDisplay().bounds().ToString());
 
-  generator.MoveMouseTo(30, 20);
+  generator.MoveMouseToInHost(30, 20);
   EXPECT_EQ("30,20", event_handler.GetLocationAndReset());
 
   Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
@@ -671,8 +738,14 @@
 // SetTransform updates the window using the orignal host window
 // size.
 #define MAYBE_Rotate DISABLED_Rotate
+#define MAYBE_ScaleRootWindow DISABLED_ScaleRootWindow
+#define MAYBE_TouchScale DISABLED_TouchScale
+#define MAYBE_ConvertHostToRootCoords DISABLED_ConvertHostToRootCoords
 #else
 #define MAYBE_Rotate Rotate
+#define MAYBE_ScaleRootWindow ScaleRootWindow
+#define MAYBE_TouchScale TouchScale
+#define MAYBE_ConvertHostToRootCoords ConvertHostToRootCoords
 #endif
 
 TEST_F(DisplayControllerTest, MAYBE_Rotate) {
@@ -693,7 +766,7 @@
   EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString());
   EXPECT_EQ("120,0 150x200",
             ScreenAsh::GetSecondaryDisplay().bounds().ToString());
-  generator1.MoveMouseTo(50, 40);
+  generator1.MoveMouseToInHost(50, 40);
   EXPECT_EQ("50,40", event_handler.GetLocationAndReset());
   EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display1.id()));
   EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display2_id));
@@ -704,7 +777,7 @@
   EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString());
   EXPECT_EQ("200,0 150x200",
             ScreenAsh::GetSecondaryDisplay().bounds().ToString());
-  generator1.MoveMouseTo(50, 40);
+  generator1.MoveMouseToInHost(50, 40);
   EXPECT_EQ("40,69", event_handler.GetLocationAndReset());
   EXPECT_EQ(gfx::Display::ROTATE_90, GetStoredRotation(display1.id()));
   EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display2_id));
@@ -724,7 +797,7 @@
   EXPECT_EQ(gfx::Display::ROTATE_270, GetStoredRotation(display2_id));
 
   aura::test::EventGenerator generator2(root_windows[1]);
-  generator2.MoveMouseTo(50, 40);
+  generator2.MoveMouseToInHost(50, 40);
   EXPECT_EQ("179,25", event_handler.GetLocationAndReset());
   display_manager->SetDisplayRotation(display1.id(),
                                       gfx::Display::ROTATE_180);
@@ -737,21 +810,12 @@
   EXPECT_EQ(gfx::Display::ROTATE_180, GetStoredRotation(display1.id()));
   EXPECT_EQ(gfx::Display::ROTATE_270, GetStoredRotation(display2_id));
 
-  generator1.MoveMouseTo(50, 40);
+  generator1.MoveMouseToInHost(50, 40);
   EXPECT_EQ("69,159", event_handler.GetLocationAndReset());
 
   Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
 }
 
-#if defined(OS_WIN)
-// On Win8 bots, the host window can't be resized and
-// SetTransform updates the window using the orignal host window
-// size.
-#define MAYBE_ScaleRootWindow DISABLED_ScaleRootWindow
-#else
-#define MAYBE_ScaleRootWindow ScaleRootWindow
-#endif
-
 TEST_F(DisplayControllerTest, MAYBE_ScaleRootWindow) {
   TestEventHandler event_handler;
   Shell::GetInstance()->AddPreTargetHandler(&event_handler);
@@ -759,6 +823,8 @@
   UpdateDisplay("600x400*2@1.5,500x300");
 
   gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay();
+  gfx::Display::SetInternalDisplayId(display1.id());
+
   gfx::Display display2 = ScreenAsh::GetSecondaryDisplay();
   Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
   EXPECT_EQ("0,0 450x300", display1.bounds().ToString());
@@ -768,12 +834,12 @@
   EXPECT_EQ(1.0f, GetStoredUIScale(display2.id()));
 
   aura::test::EventGenerator generator(root_windows[0]);
-  generator.MoveMouseTo(599, 200);
+  generator.MoveMouseToInHost(599, 200);
   EXPECT_EQ("449,150", event_handler.GetLocationAndReset());
 
   internal::DisplayManager* display_manager =
       Shell::GetInstance()->display_manager();
-  display_manager->SetDisplayUIScale(display1.id(), 1.25);
+  display_manager->SetDisplayUIScale(display1.id(), 1.25f);
   display1 = Shell::GetScreen()->GetPrimaryDisplay();
   display2 = ScreenAsh::GetSecondaryDisplay();
   EXPECT_EQ("0,0 375x250", display1.bounds().ToString());
@@ -785,5 +851,91 @@
   Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
 }
 
+TEST_F(DisplayControllerTest, MAYBE_TouchScale) {
+  TestEventHandler event_handler;
+  Shell::GetInstance()->AddPreTargetHandler(&event_handler);
+
+  UpdateDisplay("200x200*2");
+  gfx::Display display = Shell::GetScreen()->GetPrimaryDisplay();
+  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
+  aura::RootWindow* root_window = root_windows[0];
+  aura::test::EventGenerator generator(root_window);
+
+  generator.PressMoveAndReleaseTouchTo(50, 50);
+  // Default test touches have radius_x/y = 1.0, with device scale
+  // factor = 2, the scaled radius_x/y should be 0.5.
+  EXPECT_EQ(0.5, event_handler.touch_radius_x());
+  EXPECT_EQ(0.5, event_handler.touch_radius_y());
+
+  generator.ScrollSequence(gfx::Point(0,0),
+                           base::TimeDelta::FromMilliseconds(100),
+                           10.0, 1.0, 5, 1);
+
+  // With device scale factor = 2, ordinal_offset * 2 = offset.
+  EXPECT_EQ(event_handler.scroll_x_offset(),
+            event_handler.scroll_x_offset_ordinal() * 2);
+  EXPECT_EQ(event_handler.scroll_y_offset(),
+            event_handler.scroll_y_offset_ordinal() * 2);
+
+  Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
+}
+
+TEST_F(DisplayControllerTest, MAYBE_ConvertHostToRootCoords) {
+  TestEventHandler event_handler;
+  Shell::GetInstance()->AddPreTargetHandler(&event_handler);
+
+  UpdateDisplay("600x400*2/r@1.5");
+
+  gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay();
+  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
+  EXPECT_EQ("0,0 300x450", display1.bounds().ToString());
+  EXPECT_EQ("0,0 300x450", root_windows[0]->bounds().ToString());
+  EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
+
+  aura::test::EventGenerator generator(root_windows[0]);
+  generator.MoveMouseToInHost(0, 0);
+  EXPECT_EQ("0,449", event_handler.GetLocationAndReset());
+  generator.MoveMouseToInHost(599, 0);
+  EXPECT_EQ("0,0", event_handler.GetLocationAndReset());
+  generator.MoveMouseToInHost(599, 399);
+  EXPECT_EQ("299,0", event_handler.GetLocationAndReset());
+  generator.MoveMouseToInHost(0, 399);
+  EXPECT_EQ("299,449", event_handler.GetLocationAndReset());
+
+  UpdateDisplay("600x400*2/u@1.5");
+  display1 = Shell::GetScreen()->GetPrimaryDisplay();
+  root_windows = Shell::GetAllRootWindows();
+  EXPECT_EQ("0,0 450x300", display1.bounds().ToString());
+  EXPECT_EQ("0,0 450x300", root_windows[0]->bounds().ToString());
+  EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
+
+  generator.MoveMouseToInHost(0, 0);
+  EXPECT_EQ("449,299", event_handler.GetLocationAndReset());
+  generator.MoveMouseToInHost(599, 0);
+  EXPECT_EQ("0,299", event_handler.GetLocationAndReset());
+  generator.MoveMouseToInHost(599, 399);
+  EXPECT_EQ("0,0", event_handler.GetLocationAndReset());
+  generator.MoveMouseToInHost(0, 399);
+  EXPECT_EQ("449,0", event_handler.GetLocationAndReset());
+
+  UpdateDisplay("600x400*2/l@1.5");
+  display1 = Shell::GetScreen()->GetPrimaryDisplay();
+  root_windows = Shell::GetAllRootWindows();
+  EXPECT_EQ("0,0 300x450", display1.bounds().ToString());
+  EXPECT_EQ("0,0 300x450", root_windows[0]->bounds().ToString());
+  EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
+
+  generator.MoveMouseToInHost(0, 0);
+  EXPECT_EQ("299,0", event_handler.GetLocationAndReset());
+  generator.MoveMouseToInHost(599, 0);
+  EXPECT_EQ("299,449", event_handler.GetLocationAndReset());
+  generator.MoveMouseToInHost(599, 399);
+  EXPECT_EQ("0,449", event_handler.GetLocationAndReset());
+  generator.MoveMouseToInHost(0, 399);
+  EXPECT_EQ("0,0", event_handler.GetLocationAndReset());
+
+  Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
+}
+
 }  // namespace test
 }  // namespace ash
diff --git a/ash/display/display_error_dialog_unittest.cc b/ash/display/display_error_dialog_unittest.cc
index 196506a..9c5a891 100644
--- a/ash/display/display_error_dialog_unittest.cc
+++ b/ash/display/display_error_dialog_unittest.cc
@@ -42,7 +42,7 @@
 
   DisplayErrorObserver* observer() { return observer_.get(); }
 
-  const string16& GetMessageContents(const DisplayErrorDialog* dialog) {
+  const base::string16& GetMessageContents(const DisplayErrorDialog* dialog) {
     const views::Label* label = static_cast<const views::Label*>(
         static_cast<const views::View*>(dialog)->child_at(0));
     return label->text();
diff --git a/ash/display/display_info.cc b/ash/display/display_info.cc
index 739be89..fa72bdc 100644
--- a/ash/display/display_info.cc
+++ b/ash/display/display_info.cc
@@ -8,9 +8,9 @@
 
 #include "ash/display/display_info.h"
 #include "base/logging.h"
-#include "base/string_number_conversions.h"
 #include "base/string_util.h"
 #include "base/stringprintf.h"
+#include "base/strings/string_number_conversions.h"
 #include "ui/gfx/display.h"
 #include "ui/gfx/size_conversions.h"
 #include "ui/gfx/size_f.h"
@@ -148,13 +148,6 @@
     rotation_ = native_info.rotation_;
     ui_scale_ = native_info.ui_scale_;
   }
-  // It makes little sense to scale beyond the original
-  // resolution. This guard is to protect applying
-  // ui_scale to an external display whose DPI has changed
-  // from 2.0 to 1.0 for some reason.
-  if (ui_scale_ > device_scale_factor_)
-    ui_scale_ = 1.0f;
-
   // Don't copy insets as it may be given by preference.  |rotation_|
   // is treated as a native so that it can be specified in
   // |CreateFromSpec|.
diff --git a/ash/display/display_manager.cc b/ash/display/display_manager.cc
index d0b31c4..81d7b88 100644
--- a/ash/display/display_manager.cc
+++ b/ash/display/display_manager.cc
@@ -4,6 +4,7 @@
 
 #include "ash/display/display_manager.h"
 
+#include <cmath>
 #include <set>
 #include <string>
 #include <vector>
@@ -12,11 +13,12 @@
 #include "ash/display/display_controller.h"
 #include "ash/screen_ash.h"
 #include "ash/shell.h"
+#include "base/auto_reset.h"
 #include "base/command_line.h"
 #include "base/logging.h"
 #include "base/stl_util.h"
-#include "base/string_number_conversions.h"
 #include "base/stringprintf.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
 #include "base/utf_string_conversions.h"
 #include "grit/ash_strings.h"
@@ -37,7 +39,6 @@
 
 #if defined(OS_CHROMEOS)
 #include "base/chromeos/chromeos_version.h"
-#include "chromeos/display/output_configurator.h"
 #endif
 
 #if defined(OS_WIN)
@@ -54,11 +55,13 @@
 
 namespace {
 
-// List of value UI Scale values. These scales are equivalent to 1024,
-// 1280, 1600 and 1920 pixel width respectively on 2560 pixel width 2x
-// density display.
-const float kUIScales[] = {0.8f, 1.0f, 1.25f, 1.5f};
-const size_t kUIScaleTableSize = arraysize(kUIScales);
+// List of value UI Scale values. Scales for 2x are equivalent to 640,
+// 800, 1024, 1280, 1440, 1600 and 1920 pixel width respectively on
+// 2560 pixel width 2x density display. Please see crbug.com/233375
+// for the full list of resolutions.
+const float kUIScalesFor2x[] = {0.5f, 0.625f, 0.8f, 1.0f, 1.125f, 1.25f, 1.5f};
+const float kUIScalesFor1280[] = {0.5f, 0.625f, 0.8f, 1.0f, 1.125f };
+const float kUIScalesFor1366[] = {0.5f, 0.6f, 0.75f, 1.0f, 1.125f };
 
 struct DisplaySortFunctor {
   bool operator()(const gfx::Display& a, const gfx::Display& b) {
@@ -72,19 +75,47 @@
   }
 };
 
+struct ScaleComparator {
+  ScaleComparator(float s) : scale(s) {}
+
+  bool operator()(float s) const {
+    const float kEpsilon = 0.0001f;
+    return std::abs(scale - s) < kEpsilon;
+  }
+  float scale;
+};
+
+std::vector<float> GetScalesForDisplay(const DisplayInfo& info) {
+  std::vector<float> ret;
+  if (info.device_scale_factor() == 2.0f) {
+    ret.assign(kUIScalesFor2x, kUIScalesFor2x + arraysize(kUIScalesFor2x));
+    return ret;
+  }
+  switch (info.bounds_in_pixel().width()) {
+    case 1280:
+      ret.assign(kUIScalesFor1280,
+                 kUIScalesFor1280 + arraysize(kUIScalesFor1280));
+      break;
+    case 1366:
+      ret.assign(kUIScalesFor1366,
+                 kUIScalesFor1366 + arraysize(kUIScalesFor1366));
+      break;
+    default:
+      ret.assign(kUIScalesFor1280,
+                 kUIScalesFor1280 + arraysize(kUIScalesFor1280));
+#if defined(OS_CHROMEOS)
+      if (base::chromeos::IsRunningOnChromeOS())
+        NOTREACHED() << "Unknown resolution:" << info.ToString();
+#endif
+  }
+  return ret;
+}
+
 gfx::Display& GetInvalidDisplay() {
   static gfx::Display* invalid_display = new gfx::Display();
   return *invalid_display;
 }
 
-bool IsValidUIScale(float scale) {
-  for (size_t i = 0; i < kUIScaleTableSize; ++i) {
-    if (kUIScales[i] == scale)
-      return true;
-  }
-  return false;
-}
-
 }  // namespace
 
 using aura::RootWindow;
@@ -121,14 +152,16 @@
 }
 
 // static
-float DisplayManager::GetNextUIScale(float scale, bool up) {
-  for (size_t i = 0; i < kUIScaleTableSize; ++i) {
-    if (kUIScales[i] == scale) {
-      if (up && i != kUIScaleTableSize -1)
-        return kUIScales[i + 1];
+float DisplayManager::GetNextUIScale(const DisplayInfo& info, bool up) {
+  float scale = info.ui_scale();
+  std::vector<float> scales = GetScalesForDisplay(info);
+  for (size_t i = 0; i < scales.size(); ++i) {
+    if (ScaleComparator(scales[i])(scale)) {
+      if (up && i != scales.size() - 1)
+        return scales[i + 1];
       if (!up && i != 0)
-        return kUIScales[i - 1];
-      return kUIScales[i];
+        return scales[i - 1];
+      return scales[i];
     }
   }
   // Fallback to 1.0f if the |scale| wasn't in the list.
@@ -220,8 +253,10 @@
 
 void DisplayManager::SetDisplayUIScale(int64 display_id,
                                        float ui_scale) {
-  if (!IsDisplayUIScalingEnabled() || !IsValidUIScale(ui_scale))
+  if (!IsDisplayUIScalingEnabled() ||
+      gfx::Display::InternalDisplayId() != display_id) {
     return;
+  }
 
   DisplayInfoList display_info_list;
   for (DisplayList::const_iterator iter = displays_.begin();
@@ -230,6 +265,12 @@
     if (info.id() == display_id) {
       if (info.ui_scale() == ui_scale)
         return;
+      std::vector<float> scales = GetScalesForDisplay(info);
+      ScaleComparator comparator(ui_scale);
+      if (std::find_if(scales.begin(), scales.end(), comparator) ==
+          scales.end()) {
+        return;
+      }
       info.set_ui_scale(ui_scale);
     }
     display_info_list.push_back(info);
@@ -248,7 +289,8 @@
   }
 
   display_info_[display_id].set_rotation(rotation);
-  if (IsValidUIScale(ui_scale))
+  // Just in case the preference file was corrupted.
+  if (0.5f <= ui_scale && ui_scale <= 2.0f)
     display_info_[display_id].set_ui_scale(ui_scale);
   if (overscan_insets)
     display_info_[display_id].SetOverscanInsets(true, *overscan_insets);
@@ -265,18 +307,7 @@
       HasSwitch(switches::kAshDisableUIScaling);
   if (!enabled)
     return false;
-  // UI Scaling is effective only when the internal display has
-  // 2x density (currently Pixel).
-  int64 display_id = gfx::Display::InternalDisplayId();
-#if defined(OS_CHROMEOS)
-  // On linux desktop, allow ui scaling on the first dislpay if an internal
-  // display isn't specified.
-  if (display_id == gfx::Display::kInvalidDisplayID &&
-      !base::chromeos::IsRunningOnChromeOS()) {
-    display_id = Shell::GetInstance()->display_manager()->first_display_id();
-  }
-#endif
-  return GetDisplayForId(display_id).device_scale_factor() == 2.0f;
+  return GetDisplayIdForUIScaling() != gfx::Display::kInvalidDisplayID;
 }
 
 gfx::Insets DisplayManager::GetOverscanInsets(int64 display_id) const {
@@ -303,6 +334,14 @@
   }
   first_display_id_ = updated_displays[0].id();
   std::set<int> y_coords;
+  if (updated_displays.size() == 1) {
+    VLOG(1) << "OnNativeDisplaysChanged(1):" << updated_displays[0].ToString();
+  } else {
+    VLOG(1) << "OnNativeDisplaysChanged(" << updated_displays.size()
+            << ") [0]=" << updated_displays[0].ToString()
+            << ", [1]=" << updated_displays[1].ToString();
+  }
+
   bool internal_display_connected = false;
   num_connected_displays_ = updated_displays.size();
   mirrored_display_id_ = gfx::Display::kInvalidDisplayID;
@@ -310,11 +349,8 @@
   for (DisplayInfoList::const_iterator iter = updated_displays.begin();
        iter != updated_displays.end();
        ++iter) {
-    if (!internal_display_connected) {
+    if (!internal_display_connected)
       internal_display_connected = IsInternalDisplayId(iter->id());
-      if (internal_display_connected)
-        internal_display_info_.reset(new DisplayInfo(*iter));
-    }
     // Mirrored monitors have the same y coordinates.
     int y = iter->bounds_in_pixel().y();
     if (y_coords.find(y) != y_coords.end()) {
@@ -325,18 +361,16 @@
       new_display_info_list.push_back(*iter);
     }
   }
-  if (HasInternalDisplay() && !internal_display_connected) {
-    if (!internal_display_info_.get()) {
-      // TODO(oshima): Get has_custom value.
-      internal_display_info_.reset(new DisplayInfo(
-          gfx::Display::InternalDisplayId(),
-          l10n_util::GetStringUTF8(IDS_ASH_INTERNAL_DISPLAY_NAME),
-          false));
-      internal_display_info_->SetBounds(gfx::Rect(0, 0, 800, 600));
-    }
-    new_display_info_list.push_back(*internal_display_info_.get());
-    // An internal display is always considered *connected*.
-    num_connected_displays_++;
+  if (HasInternalDisplay() &&
+      !internal_display_connected &&
+      display_info_.find(gfx::Display::InternalDisplayId()) ==
+      display_info_.end()) {
+    DisplayInfo internal_display_info(
+        gfx::Display::InternalDisplayId(),
+        l10n_util::GetStringUTF8(IDS_ASH_INTERNAL_DISPLAY_NAME),
+        false  /*Internal display must not have overscan */);
+    internal_display_info.SetBounds(gfx::Rect(0, 0, 800, 600));
+    display_info_[gfx::Display::InternalDisplayId()] = internal_display_info;
   }
   UpdateDisplays(new_display_info_list);
 }
@@ -360,14 +394,13 @@
   DisplayList removed_displays;
   std::vector<size_t> changed_display_indices;
   std::vector<size_t> added_display_indices;
-  gfx::Display current_primary;
-  if (DisplayController::HasPrimaryDisplay())
-    current_primary = DisplayController::GetPrimaryDisplay();
 
   DisplayList::iterator curr_iter = displays_.begin();
   DisplayInfoList::const_iterator new_info_iter = new_display_info_list.begin();
 
   DisplayList new_displays;
+  bool update_mouse_location = false;
+
   while (curr_iter != displays_.end() ||
          new_info_iter != new_display_info_list.end()) {
     if (curr_iter == displays_.end()) {
@@ -381,6 +414,7 @@
       // more displays in current list.
       removed_displays.push_back(*curr_iter);
       ++curr_iter;
+      update_mouse_location = true;
     } else if (curr_iter->id() == new_info_iter->id()) {
       const gfx::Display& current_display = *curr_iter;
       // Copy the info because |CreateDisplayFromInfo| updates the instance.
@@ -390,17 +424,27 @@
       gfx::Display new_display =
           CreateDisplayFromDisplayInfoById(new_info_iter->id());
       const DisplayInfo& new_display_info = GetDisplayInfo(new_display.id());
+
+      bool host_window_bounds_changed =
+          current_display_info.bounds_in_pixel() !=
+          new_display_info.bounds_in_pixel();
+
       // TODO(oshima): Rotating square dislay doesn't work as the size
       // won't change. This doesn't cause a problem now as there is no
       // such display. This will be fixed by comparing the rotation as
       // well when the rotation variable is added to gfx::Display.
       if (force_bounds_changed_ ||
-          (current_display_info.bounds_in_pixel() !=
-           new_display_info.bounds_in_pixel()) ||
+          host_window_bounds_changed ||
           (current_display.device_scale_factor() !=
            new_display.device_scale_factor()) ||
           (current_display_info.size_in_pixel() !=
            new_display.GetSizeInPixel())) {
+
+        // Don't update mouse location if the display size has
+        // changed due to rotation or zooming.
+        if (host_window_bounds_changed)
+          update_mouse_location = true;
+
         changed_display_indices.push_back(new_displays.size());
       }
 
@@ -412,6 +456,7 @@
       // more displays in current list between ids, which means it is deleted.
       removed_displays.push_back(*curr_iter);
       ++curr_iter;
+      update_mouse_location = true;
     } else {
       // more displays in new list between ids, which means it is added.
       added_display_indices.push_back(new_displays.size());
@@ -430,17 +475,20 @@
     return;
   }
 
+  DisplayController* display_controller =
+      Shell::GetInstance()->display_controller();
+  gfx::Point mouse_location_in_native;
+  display_controller->NotifyDisplayConfigurationChanging();
+  mouse_location_in_native = display_controller->GetNativeMouseCursorLocation();
+
   displays_ = new_displays;
 
+  base::AutoReset<bool> resetter(&change_display_upon_host_resize_, false);
+
   // Temporarily add displays to be removed because display object
   // being removed are accessed during shutting down the root.
   displays_.insert(displays_.end(), removed_displays.begin(),
                    removed_displays.end());
-  DisplayController* display_controller =
-      Shell::GetInstance()->display_controller();
-  // |display_controller| is NULL during the bootstrap.
-  if (display_controller)
-    display_controller->NotifyDisplayConfigurationChanging();
 
   for (DisplayList::const_reverse_iterator iter = removed_displays.rbegin();
        iter != removed_displays.rend(); ++iter) {
@@ -455,10 +503,12 @@
        iter != changed_display_indices.end(); ++iter) {
     Shell::GetInstance()->screen()->NotifyBoundsChanged(displays_[*iter]);
   }
-  if (display_controller)
-    display_controller->NotifyDisplayConfigurationChanged();
+  display_controller->NotifyDisplayConfigurationChanged();
+  if (update_mouse_location)
+    display_controller->EnsurePointerInDisplays();
+  else
+    display_controller->UpdateMouseCursor(mouse_location_in_native);
 
-  EnsurePointerInDisplays();
 #if defined(USE_X11) && defined(OS_CHROMEOS)
   if (!changed_display_indices.empty() && base::chromeos::IsRunningOnChromeOS())
     ui::ClearX11DefaultRootWindow();
@@ -574,6 +624,15 @@
   }
 }
 
+int64 DisplayManager::GetDisplayIdForUIScaling() const {
+  // UI Scaling is effective only on internal display.
+  int64 display_id = gfx::Display::InternalDisplayId();
+#if defined(OS_WIN)
+  display_id = first_display_id();
+#endif
+  return display_id;
+}
+
 void DisplayManager::Init() {
   // TODO(oshima): Move this logic to DisplayChangeObserver.
   const string size_str = CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
@@ -587,6 +646,9 @@
   if (displays_.empty())
     AddDisplayFromSpec(std::string() /* default */);
   first_display_id_ = displays_[0].id();
+  CommandLine* command_line = CommandLine::ForCurrentProcess();
+  if (command_line->HasSwitch(switches::kAshUseFirstDisplayAsInternal))
+    gfx::Display::SetInternalDisplayId(first_display_id_);
   num_connected_displays_ = displays_.size();
 }
 
@@ -649,44 +711,6 @@
   displays_.push_back(display);
 }
 
-void DisplayManager::EnsurePointerInDisplays() {
-  // Don't try to move the pointer during the boot/startup.
-  if (!DisplayController::HasPrimaryDisplay())
-    return;
-  gfx::Point location_in_screen = Shell::GetScreen()->GetCursorScreenPoint();
-  gfx::Point target_location;
-  int64 closest_distance_squared = -1;
-
-  for (DisplayList::const_iterator iter = displays_.begin();
-       iter != displays_.end(); ++iter) {
-    const gfx::Rect& display_bounds = iter->bounds();
-
-    if (display_bounds.Contains(location_in_screen)) {
-      target_location = location_in_screen;
-      break;
-    }
-    gfx::Point center = display_bounds.CenterPoint();
-    // Use the distance squared from the center of the dislay. This is not
-    // exactly "closest" display, but good enough to pick one
-    // appropriate (and there are at most two displays).
-    // We don't care about actual distance, only relative to other displays, so
-    // using the LengthSquared() is cheaper than Length().
-    int64 distance_squared = (center - location_in_screen).LengthSquared();
-    if (closest_distance_squared < 0 ||
-        closest_distance_squared > distance_squared) {
-      target_location = center;
-      closest_distance_squared = distance_squared;
-    }
-  }
-
-  aura::RootWindow* root_window = Shell::GetPrimaryRootWindow();
-  aura::client::ScreenPositionClient* client =
-      aura::client::GetScreenPositionClient(root_window);
-  client->ConvertPointFromScreen(root_window, &target_location);
-
-  root_window->MoveCursorTo(target_location);
-}
-
 void DisplayManager::InsertAndUpdateDisplayInfo(const DisplayInfo& new_info) {
   std::map<int64, DisplayInfo>::iterator info =
       display_info_.find(new_info.id());
@@ -696,21 +720,6 @@
     display_info_[new_info.id()] = new_info;
     display_info_[new_info.id()].set_native(false);
   }
-  bool on_chromeos = false;
-#if defined(OS_CHROMEOS)
-  on_chromeos = base::chromeos::IsRunningOnChromeOS();
-#endif
-  CommandLine* command_line = CommandLine::ForCurrentProcess();
-  if ((new_info.id() == gfx::Display::InternalDisplayId() || !on_chromeos) &&
-      command_line->HasSwitch(switches::kAshInternalDisplayUIScale)) {
-    double scale_in_double = 1.0;
-    std::string value = CommandLine::ForCurrentProcess()->
-        GetSwitchValueASCII(switches::kAshInternalDisplayUIScale);
-    if (!base::StringToDouble(value, &scale_in_double))
-      LOG(ERROR) << "Failed to parse the display scale:" << value;
-    display_info_[new_info.id()].set_ui_scale(scale_in_double);
-  }
-
   display_info_[new_info.id()].UpdateDisplaySize();
 }
 
diff --git a/ash/display/display_manager.h b/ash/display/display_manager.h
index 679a8ad..ffd4e18 100644
--- a/ash/display/display_manager.h
+++ b/ash/display/display_manager.h
@@ -45,7 +45,7 @@
   static void ToggleDisplayScaleFactor();
 
   // Returns next valid UI scale.
-  static float GetNextUIScale(float scale, bool up);
+  static float GetNextUIScale(const DisplayInfo& info, bool up);
 
   // When set to true, the MonitorManager calls OnDisplayBoundsChanged
   // even if the display's bounds didn't change. Used to swap primary
@@ -156,6 +156,12 @@
   // Returns the human-readable name for the display |id|.
   std::string GetDisplayNameForId(int64 id);
 
+  // Returns the display id that is capable of UI scaling. On device,
+  // this returns internal display's ID if its device scale factor is 2,
+  // or invalid ID if such internal display doesn't exist. On linux
+  // desktop, this returns the first display ID.
+  int64 GetDisplayIdForUIScaling() const;
+
   // RootWindowObserver overrides:
   virtual void OnRootWindowResized(const aura::RootWindow* root,
                                    const gfx::Size& new_size) OVERRIDE;
@@ -187,10 +193,6 @@
   // Refer to |CreateDisplayFromSpec| API for the format of |spec|.
   void AddDisplayFromSpec(const std::string& spec);
 
-  // Checks if the mouse pointer is on one of displays, and moves to
-  // the center of the nearest display if it's outside of all displays.
-  void EnsurePointerInDisplays();
-
   // Inserts and update the DisplayInfo according to the overscan
   // state. Note that The DisplayInfo stored in the |internal_display_info_|
   // can be different from |new_info| (due to overscan state), so
@@ -210,10 +212,6 @@
 
   int num_connected_displays_;
 
-  // An internal display info cache used when the internal display is
-  // disconnectd.
-  scoped_ptr<DisplayInfo> internal_display_info_;
-
   bool force_bounds_changed_;
 
   // The mapping from the display ID to its internal data.
diff --git a/ash/display/display_manager_unittest.cc b/ash/display/display_manager_unittest.cc
index 3f76976..6fe5deb 100644
--- a/ash/display/display_manager_unittest.cc
+++ b/ash/display/display_manager_unittest.cc
@@ -13,6 +13,7 @@
 #include "base/stringprintf.h"
 #include "ui/aura/env.h"
 #include "ui/aura/root_window.h"
+#include "ui/aura/test/event_generator.h"
 #include "ui/aura/window_observer.h"
 #include "ui/gfx/display_observer.h"
 #include "ui/gfx/display.h"
@@ -367,13 +368,15 @@
   const int internal_display_id =
       test::DisplayManagerTestApi(display_manager()).
       SetFirstDisplayAsInternalDisplay();
+  const int external_id = 10;
+  const int mirror_id = 11;
   const int64 invalid_id = gfx::Display::kInvalidDisplayID;
-  const DisplayInfo native_display_info =
+  const DisplayInfo internal_display_info =
       CreateDisplayInfo(internal_display_id, gfx::Rect(0, 0, 500, 500));
   const DisplayInfo external_display_info =
-      CreateDisplayInfo(10, gfx::Rect(1, 1, 100, 100));
+      CreateDisplayInfo(external_id, gfx::Rect(1, 1, 100, 100));
   const DisplayInfo mirrored_display_info =
-      CreateDisplayInfo(11, gfx::Rect(0, 0, 500, 500));
+      CreateDisplayInfo(mirror_id, gfx::Rect(0, 0, 500, 500));
 
   EXPECT_EQ(1U, display_manager()->GetNumDisplays());
   EXPECT_EQ(1U, display_manager()->num_connected_displays());
@@ -392,21 +395,22 @@
   // External connected while primary was disconnected.
   display_info_list.push_back(external_display_info);
   display_manager()->OnNativeDisplaysChanged(display_info_list);
-  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
+  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
 
-  EXPECT_EQ(default_bounds,
-            FindDisplayForId(internal_display_id).bounds().ToString());
+  EXPECT_EQ(invalid_id, FindDisplayForId(internal_display_id).id());
   EXPECT_EQ("1,1 100x100",
-            FindDisplayInfoForId(10).bounds_in_pixel().ToString());
-  EXPECT_EQ(2U, display_manager()->num_connected_displays());
+            FindDisplayInfoForId(external_id).bounds_in_pixel().ToString());
+  EXPECT_EQ(1U, display_manager()->num_connected_displays());
   EXPECT_EQ(invalid_id, display_manager()->mirrored_display_id());
+  EXPECT_EQ(external_id, Shell::GetScreen()->GetPrimaryDisplay().id());
 
   // Primary connected, with different bounds.
   display_info_list.clear();
-  display_info_list.push_back(native_display_info);
+  display_info_list.push_back(internal_display_info);
   display_info_list.push_back(external_display_info);
   display_manager()->OnNativeDisplaysChanged(display_info_list);
   EXPECT_EQ(2U, display_manager()->GetNumDisplays());
+  // need to remember which is primary
   EXPECT_EQ("0,0 500x500",
             FindDisplayForId(internal_display_id).bounds().ToString());
   EXPECT_EQ("1,1 100x100",
@@ -416,18 +420,6 @@
   EXPECT_EQ(StringPrintf("x-%d", internal_display_id),
             display_manager()->GetDisplayNameForId(internal_display_id));
 
-  // Turn off primary.
-  display_info_list.clear();
-  display_info_list.push_back(external_display_info);
-  display_manager()->OnNativeDisplaysChanged(display_info_list);
-  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
-  EXPECT_EQ("0,0 500x500",
-            FindDisplayForId(internal_display_id).bounds().ToString());
-  EXPECT_EQ("1,1 100x100",
-            FindDisplayInfoForId(10).bounds_in_pixel().ToString());
-  EXPECT_EQ(2U, display_manager()->num_connected_displays());
-  EXPECT_EQ(invalid_id, display_manager()->mirrored_display_id());
-
   // Emulate suspend.
   display_info_list.clear();
   display_manager()->OnNativeDisplaysChanged(display_info_list);
@@ -442,7 +434,7 @@
             display_manager()->GetDisplayNameForId(internal_display_id));
 
   // External display has disconnected then resumed.
-  display_info_list.push_back(native_display_info);
+  display_info_list.push_back(internal_display_info);
   display_manager()->OnNativeDisplaysChanged(display_info_list);
   EXPECT_EQ(1U, display_manager()->GetNumDisplays());
   EXPECT_EQ("0,0 500x500",
@@ -465,7 +457,7 @@
   EXPECT_EQ(invalid_id, display_manager()->mirrored_display_id());
 
   // and resume with different external display.
-  display_info_list.push_back(native_display_info);
+  display_info_list.push_back(internal_display_info);
   display_info_list.push_back(CreateDisplayInfo(12, gfx::Rect(1, 1, 100, 100)));
   display_manager()->OnNativeDisplaysChanged(display_info_list);
   EXPECT_EQ(2U, display_manager()->GetNumDisplays());
@@ -475,7 +467,7 @@
 
   // mirrored...
   display_info_list.clear();
-  display_info_list.push_back(native_display_info);
+  display_info_list.push_back(internal_display_info);
   display_info_list.push_back(mirrored_display_info);
   display_manager()->OnNativeDisplaysChanged(display_info_list);
   EXPECT_EQ(1U, display_manager()->GetNumDisplays());
@@ -496,7 +488,7 @@
 
   // and exit mirroring.
   display_info_list.clear();
-  display_info_list.push_back(native_display_info);
+  display_info_list.push_back(internal_display_info);
   display_info_list.push_back(external_display_info);
   display_manager()->OnNativeDisplaysChanged(display_info_list);
   EXPECT_EQ(2U, display_manager()->GetNumDisplays());
@@ -506,6 +498,28 @@
             FindDisplayForId(internal_display_id).bounds().ToString());
   EXPECT_EQ("500,0 100x100",
             FindDisplayForId(10).bounds().ToString());
+
+  // Turn off internal
+  display_info_list.clear();
+  display_info_list.push_back(external_display_info);
+  display_manager()->OnNativeDisplaysChanged(display_info_list);
+  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
+  EXPECT_EQ(invalid_id, FindDisplayForId(internal_display_id).id());
+  EXPECT_EQ("1,1 100x100",
+            FindDisplayInfoForId(external_id).bounds_in_pixel().ToString());
+  EXPECT_EQ(1U, display_manager()->num_connected_displays());
+  EXPECT_EQ(invalid_id, display_manager()->mirrored_display_id());
+
+  // Switched to another display
+  display_info_list.clear();
+  display_info_list.push_back(internal_display_info);
+  display_manager()->OnNativeDisplaysChanged(display_info_list);
+  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
+  EXPECT_EQ(
+      "0,0 500x500",
+      FindDisplayInfoForId(internal_display_id).bounds_in_pixel().ToString());
+  EXPECT_EQ(1U, display_manager()->num_connected_displays());
+  EXPECT_EQ(invalid_id, display_manager()->mirrored_display_id());
 }
 
 #if defined(OS_WIN)
@@ -544,8 +558,10 @@
 
   aura::Env* env = aura::Env::GetInstance();
 
+  aura::test::EventGenerator generator(root_windows[0]);
+
   // Set the initial position.
-  root_windows[0]->MoveCursorTo(gfx::Point(350, 150));
+  generator.MoveMouseToInHost(350, 150);
   EXPECT_EQ("350,150", env->last_mouse_location().ToString());
 
   // A mouse pointer will be inside 2nd display.
@@ -568,7 +584,7 @@
   EXPECT_EQ("150,150", env->last_mouse_location().ToString());
 
   // Move the mouse pointer to the bottom of 1st display.
-  root_windows[0]->MoveCursorTo(gfx::Point(150, 290));
+  generator.MoveMouseToInHost(150, 290);
   EXPECT_EQ("150,290", env->last_mouse_location().ToString());
 
   // The mouse pointer is outside and closest display is 1st one.
@@ -577,9 +593,6 @@
 }
 
 TEST_F(DisplayManagerTest, EnsurePointerInDisplays_2ndOnLeft) {
-  UpdateDisplay("200x200,300x300");
-  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
-
   // Set the 2nd display on the left.
   DisplayController* display_controller =
       Shell::GetInstance()->display_controller();
@@ -587,6 +600,9 @@
   layout.position = DisplayLayout::LEFT;
   display_controller->SetDefaultDisplayLayout(layout);
 
+  UpdateDisplay("200x200,300x300");
+  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
+
   EXPECT_EQ("-300,0 300x300",
             ScreenAsh::GetSecondaryDisplay().bounds().ToString());
 
@@ -700,5 +716,120 @@
             GetDisplayInfoAt(1).size_in_pixel().ToString());
 }
 
+TEST_F(DisplayManagerTest, UIScale) {
+  UpdateDisplay("1280x800");
+  int64 display_id = Shell::GetScreen()->GetPrimaryDisplay().id();
+  display_manager()->SetDisplayUIScale(display_id, 1.125f);
+  EXPECT_EQ(1.0, GetDisplayInfoAt(0).ui_scale());
+  display_manager()->SetDisplayUIScale(display_id, 0.8f);
+  EXPECT_EQ(1.0f, GetDisplayInfoAt(0).ui_scale());
+  display_manager()->SetDisplayUIScale(display_id, 0.75f);
+  EXPECT_EQ(1.0f, GetDisplayInfoAt(0).ui_scale());
+  display_manager()->SetDisplayUIScale(display_id, 0.625f);
+  EXPECT_EQ(1.0f, GetDisplayInfoAt(0).ui_scale());
+
+  gfx::Display::SetInternalDisplayId(display_id);
+
+  display_manager()->SetDisplayUIScale(display_id, 1.5f);
+  EXPECT_EQ(1.0f, GetDisplayInfoAt(0).ui_scale());
+  display_manager()->SetDisplayUIScale(display_id, 1.25f);
+  EXPECT_EQ(1.0f, GetDisplayInfoAt(0).ui_scale());
+  display_manager()->SetDisplayUIScale(display_id, 1.125f);
+  EXPECT_EQ(1.125f, GetDisplayInfoAt(0).ui_scale());
+  display_manager()->SetDisplayUIScale(display_id, 0.8f);
+  EXPECT_EQ(0.8f, GetDisplayInfoAt(0).ui_scale());
+  display_manager()->SetDisplayUIScale(display_id, 0.75f);
+  EXPECT_EQ(0.8f, GetDisplayInfoAt(0).ui_scale());
+  display_manager()->SetDisplayUIScale(display_id, 0.625f);
+  EXPECT_EQ(0.625f, GetDisplayInfoAt(0).ui_scale());
+  display_manager()->SetDisplayUIScale(display_id, 0.6f);
+  EXPECT_EQ(0.625f, GetDisplayInfoAt(0).ui_scale());
+  display_manager()->SetDisplayUIScale(display_id, 0.5f);
+  EXPECT_EQ(0.5f, GetDisplayInfoAt(0).ui_scale());
+
+  UpdateDisplay("1366x768");
+  display_manager()->SetDisplayUIScale(display_id, 1.5f);
+  EXPECT_EQ(1.0f, GetDisplayInfoAt(0).ui_scale());
+  display_manager()->SetDisplayUIScale(display_id, 1.25f);
+  EXPECT_EQ(1.0f, GetDisplayInfoAt(0).ui_scale());
+  display_manager()->SetDisplayUIScale(display_id, 1.125f);
+  EXPECT_EQ(1.125f, GetDisplayInfoAt(0).ui_scale());
+  display_manager()->SetDisplayUIScale(display_id, 0.8f);
+  EXPECT_EQ(1.125f, GetDisplayInfoAt(0).ui_scale());
+  display_manager()->SetDisplayUIScale(display_id, 0.75f);
+  EXPECT_EQ(0.75f, GetDisplayInfoAt(0).ui_scale());
+  display_manager()->SetDisplayUIScale(display_id, 0.6f);
+  EXPECT_EQ(0.6f, GetDisplayInfoAt(0).ui_scale());
+  display_manager()->SetDisplayUIScale(display_id, 0.625f);
+  EXPECT_EQ(0.6f, GetDisplayInfoAt(0).ui_scale());
+  display_manager()->SetDisplayUIScale(display_id, 0.5f);
+  EXPECT_EQ(0.5f, GetDisplayInfoAt(0).ui_scale());
+
+  UpdateDisplay("1280x850*2");
+  EXPECT_EQ(1.0f, GetDisplayInfoAt(0).ui_scale());
+  display_manager()->SetDisplayUIScale(display_id, 1.5f);
+  EXPECT_EQ(1.5f, GetDisplayInfoAt(0).ui_scale());
+  display_manager()->SetDisplayUIScale(display_id, 1.25f);
+  EXPECT_EQ(1.25f, GetDisplayInfoAt(0).ui_scale());
+  display_manager()->SetDisplayUIScale(display_id, 1.125f);
+  EXPECT_EQ(1.125f, GetDisplayInfoAt(0).ui_scale());
+  display_manager()->SetDisplayUIScale(display_id, 0.8f);
+  EXPECT_EQ(0.8f, GetDisplayInfoAt(0).ui_scale());
+  display_manager()->SetDisplayUIScale(display_id, 0.75f);
+  EXPECT_EQ(0.8f, GetDisplayInfoAt(0).ui_scale());
+  display_manager()->SetDisplayUIScale(display_id, 0.625f);
+  EXPECT_EQ(0.625f, GetDisplayInfoAt(0).ui_scale());
+  display_manager()->SetDisplayUIScale(display_id, 0.6f);
+  EXPECT_EQ(0.625f, GetDisplayInfoAt(0).ui_scale());
+  display_manager()->SetDisplayUIScale(display_id, 0.5f);
+  EXPECT_EQ(0.5f, GetDisplayInfoAt(0).ui_scale());
+}
+
+
+#if defined(OS_WIN)
+// TODO(oshima): On Windows, we don't update the origin/size right away.
+#define MAYBE_UpdateMouseCursorAfterRotateZoom DISABLED_UpdateMouseCursorAfterRotateZoom
+#else
+#define MAYBE_UpdateMouseCursorAfterRotateZoom UpdateMouseCursorAfterRotateZoom
+#endif
+
+TEST_F(DisplayManagerTest, MAYBE_UpdateMouseCursorAfterRotateZoom) {
+  // Make sure just rotating will not change native location.
+  UpdateDisplay("300x200,200x150");
+  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
+  aura::Env* env = aura::Env::GetInstance();
+
+  aura::test::EventGenerator generator1(root_windows[0]);
+  aura::test::EventGenerator generator2(root_windows[1]);
+
+  // Test on 1st display.
+  generator1.MoveMouseToInHost(150, 50);
+  EXPECT_EQ("150,50", env->last_mouse_location().ToString());
+  UpdateDisplay("300x200/r,200x150");
+  EXPECT_EQ("50,149", env->last_mouse_location().ToString());
+
+  // Test on 2nd display.
+  generator2.MoveMouseToInHost(50, 100);
+  EXPECT_EQ("250,100", env->last_mouse_location().ToString());
+  UpdateDisplay("300x200/r,200x150/l");
+  EXPECT_EQ("249,50", env->last_mouse_location().ToString());
+
+  // Make sure just zooming will not change native location.
+  UpdateDisplay("600x400*2,400x300");
+
+  // Test on 1st display.
+  generator1.MoveMouseToInHost(200, 300);
+  EXPECT_EQ("100,150", env->last_mouse_location().ToString());
+  UpdateDisplay("600x400*2@1.5,400x300");
+  EXPECT_EQ("150,225", env->last_mouse_location().ToString());
+
+  // Test on 2nd display.
+  UpdateDisplay("600x400,400x300*2");
+  generator2.MoveMouseToInHost(200, 100);
+  EXPECT_EQ("700,50", env->last_mouse_location().ToString());
+  UpdateDisplay("600x400,400x300*2@1.5");
+  EXPECT_EQ("750,75", env->last_mouse_location().ToString());
+}
+
 }  // namespace internal
 }  // namespace ash
diff --git a/ash/display/display_pref_util.h b/ash/display/display_pref_util.h
new file mode 100644
index 0000000..1b44962
--- /dev/null
+++ b/ash/display/display_pref_util.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_DISPLAY_DISPLAY_PREF_UTIL_H
+#define ASH_DISPLAY_DISPLAY_PREF_UTIL_H
+
+#include <map>
+#include <string>
+
+#include "base/strings/string_piece.h"
+
+namespace ash {
+
+// Utility templates to create enum to string map and
+// a function to find an enum value from a string.
+template<typename T>
+std::map<T, std::string>* CreateToStringMap(T k1, const std::string& v1,
+                                            T k2, const std::string& v2,
+                                            T k3, const std::string& v3,
+                                            T k4, const std::string& v4) {
+  std::map<T, std::string>* map = new std::map<T, std::string>();
+  (*map)[k1] = v1;
+  (*map)[k2] = v2;
+  (*map)[k3] = v3;
+  (*map)[k4] = v4;
+  return map;
+}
+
+template<typename T>
+bool ReverseFind(const std::map<T, std::string>* map,
+                 const base::StringPiece& value,
+                 T* key) {
+  typename std::map<T, std::string>::const_iterator iter = map->begin();
+  for (;
+       iter != map->end();
+       ++iter) {
+    if (iter->second == value) {
+      *key = iter->first;
+      return true;
+    }
+  }
+  return false;
+}
+
+}  // namespace ash
+
+#endif  // ASH_DISPLAY_DISPLAY_PREF_UTIL_H
diff --git a/ash/display/event_transformation_handler.cc b/ash/display/event_transformation_handler.cc
index 7ecc634..52cb647 100644
--- a/ash/display/event_transformation_handler.cc
+++ b/ash/display/event_transformation_handler.cc
@@ -4,6 +4,8 @@
 
 #include "ash/display/event_transformation_handler.h"
 
+#include <cmath>
+
 #include "ash/screen_ash.h"
 #include "ash/shell.h"
 #include "ash/wm/coordinate_conversion.h"
@@ -15,6 +17,10 @@
 #include "ui/gfx/display.h"
 #include "ui/gfx/screen.h"
 
+#if defined(OS_CHROMEOS)
+#include "chromeos/display/output_configurator.h"
+#endif  // defined(OS_CHROMEOS)
+
 namespace ash {
 namespace internal {
 namespace {
@@ -50,6 +56,40 @@
   event->Scale(scale);
 }
 
+#if defined(OS_CHROMEOS)
+// This is to scale the TouchEvent's radius when the touch display is in
+// mirror mode. TouchEvent's radius is often reported in the touchscreen's
+// native resolution. In mirror mode, the touch display could be configured
+// at a lower resolution. We scale down the radius using the ratio defined as
+// the sqrt of
+// (mirror_width * mirror_height) / (native_width * native_height)
+void EventTransformationHandler::OnTouchEvent(ui::TouchEvent* event) {
+  using chromeos::OutputConfigurator;
+  OutputConfigurator* output_configurator =
+      ash::Shell::GetInstance()->output_configurator();
+
+  if (output_configurator->output_state() != chromeos::STATE_DUAL_MIRROR)
+    return;
+
+  const std::map<int, float>& area_ratio_map =
+      output_configurator->GetMirroredDisplayAreaRatioMap();
+
+  // TODO(miletus): When there are more than 1 touchscreen (e.g. Link connected
+  // to an external touchscreen), the correct way to do is to have a way
+  // to find out which touchscreen is the event originating from and use the
+  // area ratio of that touchscreen to scale the event's radius.
+  // Tracked here crbug.com/233245
+  if (area_ratio_map.size() != 1) {
+    LOG(ERROR) << "Mirroring mode with " << area_ratio_map.size()
+               << " touch display found";
+    return;
+  }
+
+  float area_ratio_sqrt = std::sqrt(area_ratio_map.begin()->second);
+  event->set_radius_x(event->radius_x() * area_ratio_sqrt);
+  event->set_radius_y(event->radius_y() * area_ratio_sqrt);
+}
+#endif  // defined(OS_CHROMEOS)
+
 }  // namespace internal
 }  // namespace ash
-
diff --git a/ash/display/event_transformation_handler.h b/ash/display/event_transformation_handler.h
index 9cf0add..b2a7167 100644
--- a/ash/display/event_transformation_handler.h
+++ b/ash/display/event_transformation_handler.h
@@ -14,7 +14,7 @@
 namespace internal {
 
 // An event filter that transforms input event properties in extended desktop
-// environment. It currently handles only ScrollEvents.
+// environment.
 class ASH_EXPORT EventTransformationHandler : public ui::EventHandler {
  public:
   enum TransformationMode {
@@ -33,6 +33,9 @@
 
   // Overridden from ui::EventHandler.
   virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE;
+#if defined(OS_CHROMEOS)
+  virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE;
+#endif  // defined(OS_CHROMEOS)
 
  private:
   TransformationMode transformation_mode_;
@@ -44,4 +47,3 @@
 }  // namespace ash
 
 #endif  // ASH_DISPLAY_EVENT_TRANSFORMATION_HANDLER_H_
-
diff --git a/ash/display/mouse_cursor_event_filter.cc b/ash/display/mouse_cursor_event_filter.cc
index 7534ea1..02714a5 100644
--- a/ash/display/mouse_cursor_event_filter.cc
+++ b/ash/display/mouse_cursor_event_filter.cc
@@ -149,10 +149,11 @@
 
 void MouseCursorEventFilter::UpdateHorizontalIndicatorWindowBounds() {
   bool from_primary = Shell::GetPrimaryRootWindow() == drag_source_root_;
-
-  const gfx::Rect& primary_bounds =
+  // GetPrimaryDisplay returns an object on stack, so copy the bounds
+  // instead of using reference.
+  const gfx::Rect primary_bounds =
       Shell::GetScreen()->GetPrimaryDisplay().bounds();
-  const gfx::Rect& secondary_bounds = ScreenAsh::GetSecondaryDisplay().bounds();
+  const gfx::Rect secondary_bounds = ScreenAsh::GetSecondaryDisplay().bounds();
   DisplayLayout::Position position = Shell::GetInstance()->
       display_controller()->GetCurrentDisplayLayout().position;
 
@@ -177,10 +178,11 @@
 
 void MouseCursorEventFilter::UpdateVerticalIndicatorWindowBounds() {
   bool in_primary = Shell::GetPrimaryRootWindow() == drag_source_root_;
-
-  const gfx::Rect& primary_bounds =
+  // GetPrimaryDisplay returns an object on stack, so copy the bounds
+  // instead of using reference.
+  const gfx::Rect primary_bounds =
       Shell::GetScreen()->GetPrimaryDisplay().bounds();
-  const gfx::Rect& secondary_bounds = ScreenAsh::GetSecondaryDisplay().bounds();
+  const gfx::Rect secondary_bounds = ScreenAsh::GetSecondaryDisplay().bounds();
   DisplayLayout::Position position = Shell::GetInstance()->
       display_controller()->GetCurrentDisplayLayout().position;
 
diff --git a/ash/display/mouse_cursor_event_filter_unittest.cc b/ash/display/mouse_cursor_event_filter_unittest.cc
index a53fe76..73f282f 100644
--- a/ash/display/mouse_cursor_event_filter_unittest.cc
+++ b/ash/display/mouse_cursor_event_filter_unittest.cc
@@ -100,8 +100,8 @@
       Shell::GetInstance()->mouse_cursor_filter();
   ASSERT_EQ(
       DisplayLayout::RIGHT,
-      Shell::GetInstance()->
-          display_controller()->default_display_layout().position);
+      Shell::GetInstance()->display_controller()->
+          GetCurrentDisplayLayout().position);
 
   Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
   aura::Env::GetInstance()->set_last_mouse_location(gfx::Point(623, 123));
@@ -132,8 +132,8 @@
       Shell::GetInstance()->mouse_cursor_filter();
   ASSERT_EQ(
       DisplayLayout::RIGHT,
-      Shell::GetInstance()->
-          display_controller()->default_display_layout().position);
+      Shell::GetInstance()->display_controller()->
+          GetCurrentDisplayLayout().position);
 
   Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
   aura::Env::GetInstance()->set_last_mouse_location(gfx::Point(900, 123));
@@ -189,8 +189,8 @@
 
   DisplayController* controller =
       Shell::GetInstance()->display_controller();
-  DisplayLayout default_layout(DisplayLayout::RIGHT, 0);
-  controller->SetDefaultDisplayLayout(default_layout);
+  DisplayLayout layout(DisplayLayout::RIGHT, 0);
+  controller->SetLayoutForCurrentDisplays(layout);
   ash::internal::MouseCursorEventFilter* event_filter =
       Shell::GetInstance()->mouse_cursor_filter();
   event_filter->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
@@ -201,8 +201,8 @@
   EXPECT_EQ("359,0 1x360", event_filter->dst_indicator_bounds_.ToString());
 
   // Move 2nd display downwards a bit.
-  default_layout.offset = 5;
-  controller->SetDefaultDisplayLayout(default_layout);
+  layout.offset = 5;
+  controller->SetLayoutForCurrentDisplays(layout);
   event_filter->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
   // This is same as before because the 2nd display's y is above
   // the indicator's x.
@@ -214,8 +214,8 @@
 
   // Move it down further so that the shared edge is shorter than
   // minimum hole size (160).
-  default_layout.offset = 200;
-  controller->SetDefaultDisplayLayout(default_layout);
+  layout.offset = 200;
+  controller->SetLayoutForCurrentDisplays(layout);
   event_filter->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
   EXPECT_EQ("359,200 1x160", event_filter->src_indicator_bounds_.ToString());
   EXPECT_EQ("360,200 1x160", event_filter->dst_indicator_bounds_.ToString());
@@ -224,8 +224,8 @@
   EXPECT_EQ("359,200 1x160", event_filter->dst_indicator_bounds_.ToString());
 
   // Now move 2nd display upwards
-  default_layout.offset = -5;
-  controller->SetDefaultDisplayLayout(default_layout);
+  layout.offset = -5;
+  controller->SetLayoutForCurrentDisplays(layout);
   event_filter->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
   EXPECT_EQ("359,16 1x344", event_filter->src_indicator_bounds_.ToString());
   EXPECT_EQ("360,0 1x360", event_filter->dst_indicator_bounds_.ToString());
@@ -244,8 +244,8 @@
 
   DisplayController* controller =
       Shell::GetInstance()->display_controller();
-  DisplayLayout default_layout(DisplayLayout::LEFT, 0);
-  controller->SetDefaultDisplayLayout(default_layout);
+  DisplayLayout layout(DisplayLayout::LEFT, 0);
+  controller->SetLayoutForCurrentDisplays(layout);
   ash::internal::MouseCursorEventFilter* event_filter =
       Shell::GetInstance()->mouse_cursor_filter();
   event_filter->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
@@ -255,8 +255,8 @@
   EXPECT_EQ("-1,16 1x344", event_filter->src_indicator_bounds_.ToString());
   EXPECT_EQ("0,0 1x360", event_filter->dst_indicator_bounds_.ToString());
 
-  default_layout.offset = 250;
-  controller->SetDefaultDisplayLayout(default_layout);
+  layout.offset = 250;
+  controller->SetLayoutForCurrentDisplays(layout);
   event_filter->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
   EXPECT_EQ("0,250 1x110", event_filter->src_indicator_bounds_.ToString());
   EXPECT_EQ("-1,250 1x110", event_filter->dst_indicator_bounds_.ToString());
@@ -272,8 +272,8 @@
 
   DisplayController* controller =
       Shell::GetInstance()->display_controller();
-  DisplayLayout default_layout(DisplayLayout::TOP, 0);
-  controller->SetDefaultDisplayLayout(default_layout);
+  DisplayLayout layout(DisplayLayout::TOP, 0);
+  controller->SetLayoutForCurrentDisplays(layout);
   ash::internal::MouseCursorEventFilter* event_filter =
       Shell::GetInstance()->mouse_cursor_filter();
   event_filter->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
@@ -283,8 +283,8 @@
   EXPECT_EQ("0,-1 360x1", event_filter->src_indicator_bounds_.ToString());
   EXPECT_EQ("0,0 360x1", event_filter->dst_indicator_bounds_.ToString());
 
-  default_layout.offset = 250;
-  controller->SetDefaultDisplayLayout(default_layout);
+  layout.offset = 250;
+  controller->SetLayoutForCurrentDisplays(layout);
   event_filter->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
   EXPECT_EQ("250,0 110x1", event_filter->src_indicator_bounds_.ToString());
   EXPECT_EQ("250,-1 110x1", event_filter->dst_indicator_bounds_.ToString());
@@ -292,9 +292,9 @@
   EXPECT_EQ("250,-1 110x1", event_filter->src_indicator_bounds_.ToString());
   EXPECT_EQ("250,0 110x1", event_filter->dst_indicator_bounds_.ToString());
 
-  default_layout.position = DisplayLayout::BOTTOM;
-  default_layout.offset = 0;
-  controller->SetDefaultDisplayLayout(default_layout);
+  layout.position = DisplayLayout::BOTTOM;
+  layout.offset = 0;
+  controller->SetLayoutForCurrentDisplays(layout);
   event_filter->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
   EXPECT_EQ("0,359 360x1", event_filter->src_indicator_bounds_.ToString());
   EXPECT_EQ("0,360 360x1", event_filter->dst_indicator_bounds_.ToString());
@@ -312,8 +312,8 @@
   UpdateDisplay("400x400,800x800*2");
   DisplayController* controller =
       Shell::GetInstance()->display_controller();
-  DisplayLayout default_layout(DisplayLayout::RIGHT, 0);
-  controller->SetDefaultDisplayLayout(default_layout);
+  controller->SetLayoutForCurrentDisplays(
+      DisplayLayout(DisplayLayout::RIGHT, 0));
   Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
   ASSERT_EQ(2U, root_windows.size());
   test::CursorManagerTestApi cursor_test_api(
diff --git a/ash/display/output_configurator_animation.cc b/ash/display/output_configurator_animation.cc
index 6c6d78d..0b57aca 100644
--- a/ash/display/output_configurator_animation.cc
+++ b/ash/display/output_configurator_animation.cc
@@ -44,9 +44,9 @@
   void OnSingleTaskCompleted() {
     completed_counter_++;
     if (completed_counter_ >= observer_list_.size()) {
-      MessageLoopForUI::current()->DeleteSoon(FROM_HERE, this);
+      base::MessageLoopForUI::current()->DeleteSoon(FROM_HERE, this);
       if (!animation_aborted_)
-        MessageLoopForUI::current()->PostTask(FROM_HERE, callback_);
+        base::MessageLoopForUI::current()->PostTask(FROM_HERE, callback_);
     }
   }
 
@@ -216,7 +216,7 @@
 }
 
 void OutputConfiguratorAnimation::ClearHidingLayers() {
-  if (timer_.get()) {
+  if (timer_) {
     timer_->Stop();
     timer_.reset();
   }
diff --git a/ash/display/screen_position_controller_unittest.cc b/ash/display/screen_position_controller_unittest.cc
index 0cd4ca0..3bd0583 100644
--- a/ash/display/screen_position_controller_unittest.cc
+++ b/ash/display/screen_position_controller_unittest.cc
@@ -35,9 +35,9 @@
 void SetSecondaryDisplayLayout(DisplayLayout::Position position) {
   DisplayController* display_controller =
       Shell::GetInstance()->display_controller();
-  DisplayLayout layout = display_controller->default_display_layout();
+  DisplayLayout layout = display_controller->GetCurrentDisplayLayout();
   layout.position = position;
-  display_controller->SetDefaultDisplayLayout(layout);
+  display_controller->SetLayoutForCurrentDisplays(layout);
 }
 
 internal::ScreenPositionController* GetScreenPositionController() {
diff --git a/ash/display/shared_display_edge_indicator.cc b/ash/display/shared_display_edge_indicator.cc
index 2ad597e..5370c3b 100644
--- a/ash/display/shared_display_edge_indicator.cc
+++ b/ash/display/shared_display_edge_indicator.cc
@@ -87,7 +87,7 @@
   src_indicator_ = new IndicatorView;
   dst_indicator_ = new IndicatorView;
   CreateWidget(src_bounds, src_indicator_);
-  CreateWidget(src_bounds, dst_indicator_);
+  CreateWidget(dst_bounds, dst_indicator_);
   animation_.reset(new ui::ThrobAnimation(this));
   animation_->SetThrobDuration(kIndicatorAnimationDurationMs);
   animation_->StartThrobbing(-1 /* infinite */);
diff --git a/ash/drag_drop/drag_drop_controller.cc b/ash/drag_drop/drag_drop_controller.cc
index 1500dae..90d3010 100644
--- a/ash/drag_drop/drag_drop_controller.cc
+++ b/ash/drag_drop/drag_drop_controller.cc
@@ -145,8 +145,7 @@
       drag_window_(NULL),
       drag_source_window_(NULL),
       should_block_during_drag_drop_(true),
-      ALLOW_THIS_IN_INITIALIZER_LIST(
-          drag_drop_window_delegate_(new DragDropTrackerDelegate(this))),
+      drag_drop_window_delegate_(new DragDropTrackerDelegate(this)),
       current_drag_event_source_(ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE),
       weak_factory_(this) {
   Shell::GetInstance()->AddPreTargetHandler(this);
@@ -155,9 +154,9 @@
 DragDropController::~DragDropController() {
   Shell::GetInstance()->RemovePreTargetHandler(this);
   Cleanup();
-  if (cancel_animation_.get())
+  if (cancel_animation_)
     cancel_animation_->End();
-  if (drag_image_.get())
+  if (drag_image_)
     drag_image_.reset();
 }
 
@@ -224,15 +223,21 @@
   drag_window_ = NULL;
 
   // Ends cancel animation if it's in progress.
-  if (cancel_animation_.get())
+  if (cancel_animation_)
     cancel_animation_->End();
 
+  // Become the first event handler since we should get first shot at handling
+  // any events during the drag drop session.
+  Shell::GetInstance()->RemovePreTargetHandler(this);
+  Shell::GetInstance()->PrependPreTargetHandler(this);
+
+
 #if !defined(OS_MACOSX)
   if (should_block_during_drag_drop_) {
     base::RunLoop run_loop(aura::Env::GetInstance()->GetDispatcher());
     quit_closure_ = run_loop.QuitClosure();
-    MessageLoopForUI* loop = MessageLoopForUI::current();
-    MessageLoop::ScopedNestableTaskAllower allow_nested(loop);
+    base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
+    base::MessageLoop::ScopedNestableTaskAllower allow_nested(loop);
     run_loop.Run();
   }
 #endif  // !defined(OS_MACOSX)
@@ -487,15 +492,16 @@
   // started. We do not want to destroy the drag image in that case.
   if (!IsDragDropInProgress())
     drag_image_.reset();
-  if (pending_long_tap_.get()) {
+  if (pending_long_tap_) {
     // If not in a nested message loop, we can forward the long tap right now.
     if (!should_block_during_drag_drop_)
       ForwardPendingLongTap();
     else {
       // See comment about this in OnGestureEvent().
-      MessageLoopForUI::current()->PostTask(
-          FROM_HERE, base::Bind(&DragDropController::ForwardPendingLongTap,
-                                weak_factory_.GetWeakPtr()));
+      base::MessageLoopForUI::current()->PostTask(
+          FROM_HERE,
+          base::Bind(&DragDropController::ForwardPendingLongTap,
+                     weak_factory_.GetWeakPtr()));
     }
   }
 }
diff --git a/ash/drag_drop/drag_drop_controller_unittest.cc b/ash/drag_drop/drag_drop_controller_unittest.cc
index 2b0091f..822dede 100644
--- a/ash/drag_drop/drag_drop_controller_unittest.cc
+++ b/ash/drag_drop/drag_drop_controller_unittest.cc
@@ -207,7 +207,7 @@
   int num_drag_updates_;
   bool drop_received_;
   bool drag_canceled_;
-  string16 drag_string_;
+  base::string16 drag_string_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(TestDragDropController);
@@ -1082,5 +1082,83 @@
   }
 }
 
+class SimpleEventHandler : public ui::EventHandler {
+ public:
+  SimpleEventHandler()
+      : handled_event_received_(false),
+        unhandled_event_received_(false) {
+    ash::Shell::GetInstance()->PrependPreTargetHandler(this);
+  }
+
+  virtual ~SimpleEventHandler() {
+    ash::Shell::GetInstance()->RemovePreTargetHandler(this);
+  }
+
+  bool handled_event_received() { return handled_event_received_; }
+  bool unhandled_event_received() { return unhandled_event_received_; }
+
+  void Reset() {
+    handled_event_received_ = false;
+    unhandled_event_received_ = false;
+  }
+
+ private:
+  // Overridden from ui::EventHandler.
+  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
+    if (event->handled())
+      handled_event_received_ = true;
+    else
+      unhandled_event_received_ = true;
+  }
+
+  bool handled_event_received_;
+  bool unhandled_event_received_;
+
+  DISALLOW_COPY_AND_ASSIGN(SimpleEventHandler);
+};
+
+TEST_F(DragDropControllerTest,
+       DragDropControllerReceivesAllEventsDuringDragDrop) {
+  CommandLine::ForCurrentProcess()->AppendSwitch(
+      switches::kEnableTouchDragDrop);
+  scoped_ptr<views::Widget> widget(CreateNewWidget());
+  DragTestView* drag_view = new DragTestView;
+  AddViewToWidgetAndResize(widget.get(), drag_view);
+  aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
+                                       widget->GetNativeView());
+  ui::OSExchangeData data;
+  data.SetString(UTF8ToUTF16("I am being dragged"));
+  SimpleEventHandler handler;
+
+  // Since we are not in drag/drop, |handler| should receive unhandled events.
+  generator.PressTouch();
+  gfx::Point point = gfx::Rect(drag_view->bounds()).CenterPoint();
+  handler.Reset();
+  DispatchGesture(ui::ET_GESTURE_LONG_PRESS, point);
+  EXPECT_TRUE(handler.unhandled_event_received());
+  EXPECT_FALSE(handler.handled_event_received());
+
+  EXPECT_TRUE(drag_drop_controller_->drag_start_received_);
+
+  // Since dragging has started, |handler| should not receive unhandled events.
+  UpdateDragData(&data);
+  gfx::Point gesture_location = point;
+  int num_drags = drag_view->width();
+  for (int i = 0; i < num_drags; ++i) {
+    gesture_location.Offset(1, 0);
+    handler.Reset();
+    DispatchGesture(ui::ET_GESTURE_SCROLL_UPDATE, gesture_location);
+    EXPECT_TRUE(handler.handled_event_received());
+    EXPECT_FALSE(handler.unhandled_event_received());
+
+    // Execute any scheduled draws to process deferred mouse events.
+    RunAllPendingInMessageLoop();
+  }
+
+  // End dragging.
+  DispatchGesture(ui::ET_GESTURE_SCROLL_END, gesture_location);
+  EXPECT_TRUE(drag_drop_controller_->drop_received_);
+}
+
 }  // namespace test
 }  // namespace aura
diff --git a/ash/extended_desktop_unittest.cc b/ash/extended_desktop_unittest.cc
index 941e83b..d41f28a 100644
--- a/ash/extended_desktop_unittest.cc
+++ b/ash/extended_desktop_unittest.cc
@@ -37,9 +37,9 @@
 void SetSecondaryDisplayLayout(DisplayLayout::Position position) {
   DisplayController* display_controller =
       Shell::GetInstance()->display_controller();
-  DisplayLayout layout = display_controller->default_display_layout();
+  DisplayLayout layout = display_controller->GetCurrentDisplayLayout();
   layout.position = position;
-  display_controller->SetDefaultDisplayLayout(layout);
+  display_controller->SetLayoutForCurrentDisplays(layout);
 }
 
 class ModalWidgetDelegate : public views::WidgetDelegateView {
diff --git a/ash/focus_cycler.cc b/ash/focus_cycler.cc
index 80ef432..81611dc 100644
--- a/ash/focus_cycler.cc
+++ b/ash/focus_cycler.cc
@@ -6,6 +6,7 @@
 
 #include "ash/shell.h"
 #include "ash/wm/window_cycle_controller.h"
+#include "ash/wm/window_util.h"
 #include "ui/aura/client/activation_client.h"
 #include "ui/aura/window.h"
 #include "ui/views/accessible_pane_view.h"
@@ -17,7 +18,7 @@
 namespace {
 
 bool HasFocusableWindow() {
-  return !WindowCycleController::BuildWindowList(NULL).empty();
+  return !WindowCycleController::BuildWindowList(NULL, false).empty();
 }
 
 }  // namespace
@@ -35,6 +36,19 @@
 }
 
 void FocusCycler::RotateFocus(Direction direction) {
+  aura::Window* window = ash::wm::GetActiveWindow();
+  if (window) {
+    views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window);
+    // First try to rotate focus within the active widget. If that succeeds,
+    // we're done.
+    if (widget && widget->GetFocusManager()->RotatePaneFocus(
+            direction == BACKWARD ?
+                views::FocusManager::kBackward : views::FocusManager::kForward,
+            views::FocusManager::kNoWrap)) {
+      return;
+    }
+  }
+
   const bool has_window = HasFocusableWindow();
   int index = 0;
   int count = static_cast<int>(widgets_.size());
@@ -61,12 +75,23 @@
       break;
 
     if (index == browser_index) {
-      // Activate the first window.
-      WindowCycleController::Direction window_direction =
-          direction == FORWARD ? WindowCycleController::FORWARD :
-                                 WindowCycleController::BACKWARD;
+      // Activate the most recently active browser window.
       ash::Shell::GetInstance()->window_cycle_controller()->HandleCycleWindow(
-          window_direction, false);
+          WindowCycleController::FORWARD, false);
+
+      // Rotate pane focus within that window.
+      aura::Window* window = ash::wm::GetActiveWindow();
+      if (!window)
+        break;
+      views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window);
+      if (!widget)
+        break;
+      views::FocusManager* focus_manager = widget->GetFocusManager();
+      focus_manager->ClearFocus();
+      focus_manager->RotatePaneFocus(
+          direction == BACKWARD ?
+              views::FocusManager::kBackward : views::FocusManager::kForward,
+          views::FocusManager::kWrap);
       break;
     } else {
       if (FocusWidget(widgets_[index]))
diff --git a/ash/focus_cycler_unittest.cc b/ash/focus_cycler_unittest.cc
index bb75052..5854f8d 100644
--- a/ash/focus_cycler_unittest.cc
+++ b/ash/focus_cycler_unittest.cc
@@ -15,8 +15,11 @@
 #include "ash/wm/window_util.h"
 #include "ash/test/ash_test_base.h"
 #include "ash/shell_factory.h"
+#include "ui/aura/root_window.h"
+#include "ui/aura/test/event_generator.h"
 #include "ui/aura/test/test_windows.h"
 #include "ui/aura/window.h"
+#include "ui/views/accessible_pane_view.h"
 #include "ui/views/controls/button/menu_button.h"
 #include "ui/views/widget/widget.h"
 
@@ -34,6 +37,31 @@
       widget->GetContentsView());
 }
 
+class PanedWidgetDelegate : public views::WidgetDelegate {
+ public:
+  PanedWidgetDelegate(views::Widget* widget) : widget_(widget) {}
+
+  void SetAccessiblePanes(const std::vector<views::View*>& panes) {
+    accessible_panes_ = panes;
+  }
+
+  // views::WidgetDelegate.
+  virtual void GetAccessiblePanes(std::vector<views::View*>* panes) {
+    std::copy(accessible_panes_.begin(), accessible_panes_.end(),
+              std::back_inserter(*panes));
+  }
+  virtual views::Widget* GetWidget() OVERRIDE {
+    return widget_;
+  };
+  virtual const views::Widget* GetWidget() const OVERRIDE {
+    return widget_;
+  }
+
+ private:
+  views::Widget* widget_;
+  std::vector<views::View*> accessible_panes_;
+};
+
 }  // namespace
 
 class FocusCyclerTest : public AshTestBase {
@@ -49,7 +77,7 @@
   }
 
   virtual void TearDown() OVERRIDE {
-    if (tray_.get()) {
+    if (tray_) {
       GetStatusAreaWidgetDelegate(tray_->GetWidget())->
           SetFocusCyclerForTesting(NULL);
       tray_.reset();
@@ -65,7 +93,7 @@
  protected:
   // Creates the system tray, returning true on success.
   bool CreateTray() {
-    if (tray_.get())
+    if (tray_)
       return false;
     aura::Window* parent = Shell::GetPrimaryRootWindowController()->
         GetContainer(ash::internal::kShellWindowId_StatusContainer);
@@ -261,5 +289,113 @@
   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
 }
 
+TEST_F(FocusCyclerTest, CycleFocusThroughWindowWithPanes) {
+  ASSERT_TRUE(CreateTray());
+
+  InstallFocusCycleOnShelf();
+
+  scoped_ptr<views::Widget> browser_widget(new views::Widget);
+  PanedWidgetDelegate* test_widget_delegate =
+      new PanedWidgetDelegate(browser_widget.get());
+  views::Widget::InitParams widget_params(
+      views::Widget::InitParams::TYPE_WINDOW);
+  widget_params.context = CurrentContext();
+  widget_params.delegate = test_widget_delegate;
+  widget_params.ownership =
+      views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+  browser_widget->Init(widget_params);
+  browser_widget->Show();
+
+  aura::Window* browser_window = browser_widget->GetNativeView();
+
+  views::View* root_view = browser_widget->GetRootView();
+
+  views::AccessiblePaneView* pane1 = new views::AccessiblePaneView();
+  root_view->AddChildView(pane1);
+
+  views::View* view1 = new views::View;
+  view1->set_focusable(true);
+  pane1->AddChildView(view1);
+
+  views::View* view2 = new views::View;
+  view2->set_focusable(true);
+  pane1->AddChildView(view2);
+
+  views::AccessiblePaneView* pane2 = new views::AccessiblePaneView();
+  root_view->AddChildView(pane2);
+
+  views::View* view3 = new views::View;
+  view3->set_focusable(true);
+  pane2->AddChildView(view3);
+
+  views::View* view4 = new views::View;
+  view4->set_focusable(true);
+  pane2->AddChildView(view4);
+
+  std::vector<views::View*> panes;
+  panes.push_back(pane1);
+  panes.push_back(pane2);
+
+  test_widget_delegate->SetAccessiblePanes(panes);
+
+  views::FocusManager* focus_manager = browser_widget->GetFocusManager();
+
+  // Cycle focus to the status area.
+  focus_cycler()->RotateFocus(FocusCycler::FORWARD);
+  EXPECT_TRUE(tray()->GetWidget()->IsActive());
+
+  // Cycle focus to the shelf.
+  focus_cycler()->RotateFocus(FocusCycler::FORWARD);
+  EXPECT_TRUE(shelf_widget()->IsActive());
+
+  // Cycle focus to the first pane in the browser.
+  focus_cycler()->RotateFocus(FocusCycler::FORWARD);
+  EXPECT_TRUE(wm::IsActiveWindow(browser_window));
+  EXPECT_EQ(focus_manager->GetFocusedView(), view1);
+
+  // Cycle focus to the second pane in the browser.
+  focus_cycler()->RotateFocus(FocusCycler::FORWARD);
+  EXPECT_TRUE(wm::IsActiveWindow(browser_window));
+  EXPECT_EQ(focus_manager->GetFocusedView(), view3);
+
+  // Cycle focus back to the status area.
+  focus_cycler()->RotateFocus(FocusCycler::FORWARD);
+  EXPECT_TRUE(tray()->GetWidget()->IsActive());
+
+  // Reverse direction - back to the second pane in the browser.
+  focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
+  EXPECT_TRUE(wm::IsActiveWindow(browser_window));
+  EXPECT_EQ(focus_manager->GetFocusedView(), view3);
+
+  // Back to the first pane in the browser.
+  focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
+  EXPECT_TRUE(wm::IsActiveWindow(browser_window));
+  EXPECT_EQ(focus_manager->GetFocusedView(), view1);
+
+  // Back to the shelf.
+  focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
+  EXPECT_TRUE(shelf_widget()->IsActive());
+
+  // Back to the status area.
+  focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
+  EXPECT_TRUE(tray()->GetWidget()->IsActive());
+
+  // Pressing "Escape" while on the status area should
+  // deactivate it, and activate the browser window.
+  aura::RootWindow* root = Shell::GetPrimaryRootWindow();
+  aura::test::EventGenerator event_generator(root, root);
+  event_generator.PressKey(ui::VKEY_ESCAPE, 0);
+  EXPECT_TRUE(wm::IsActiveWindow(browser_window));
+  EXPECT_EQ(focus_manager->GetFocusedView(), view1);
+
+  // Similarly, pressing "Escape" while on the shelf.
+  // should do the same thing.
+  focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
+  EXPECT_TRUE(shelf_widget()->IsActive());
+  event_generator.PressKey(ui::VKEY_ESCAPE, 0);
+  EXPECT_TRUE(wm::IsActiveWindow(browser_window));
+  EXPECT_EQ(focus_manager->GetFocusedView(), view1);
+}
+
 }  // namespace test
 }  // namespace ash
diff --git a/ash/keyboard_overlay/keyboard_overlay_delegate.cc b/ash/keyboard_overlay/keyboard_overlay_delegate.cc
index d6f7890..b3a925b 100644
--- a/ash/keyboard_overlay/keyboard_overlay_delegate.cc
+++ b/ash/keyboard_overlay/keyboard_overlay_delegate.cc
@@ -62,7 +62,7 @@
 
 namespace ash {
 
-KeyboardOverlayDelegate::KeyboardOverlayDelegate(const string16& title,
+KeyboardOverlayDelegate::KeyboardOverlayDelegate(const base::string16& title,
                                                  const GURL& url)
     : title_(title),
       url_(url),
@@ -99,7 +99,7 @@
   return ui::MODAL_TYPE_SYSTEM;
 }
 
-string16 KeyboardOverlayDelegate::GetDialogTitle() const {
+base::string16 KeyboardOverlayDelegate::GetDialogTitle() const {
   return title_;
 }
 
diff --git a/ash/keyboard_overlay/keyboard_overlay_delegate.h b/ash/keyboard_overlay/keyboard_overlay_delegate.h
index 57dc0d4..cf46aff 100644
--- a/ash/keyboard_overlay/keyboard_overlay_delegate.h
+++ b/ash/keyboard_overlay/keyboard_overlay_delegate.h
@@ -22,7 +22,7 @@
 // Delegate to handle showing the keyboard overlay drawing. Exported for test.
 class ASH_EXPORT KeyboardOverlayDelegate : public ui::WebDialogDelegate {
  public:
-  KeyboardOverlayDelegate(const string16& title, const GURL& url);
+  KeyboardOverlayDelegate(const base::string16& title, const GURL& url);
 
   // Shows the keyboard overlay widget. Returns the widget for testing.
   views::Widget* Show(views::WebDialogView* view);
@@ -37,7 +37,7 @@
 
   // Overridden from ui::WebDialogDelegate:
   virtual ui::ModalType GetDialogModalType() const OVERRIDE;
-  virtual string16 GetDialogTitle() const OVERRIDE;
+  virtual base::string16 GetDialogTitle() const OVERRIDE;
   virtual GURL GetDialogContentURL() const OVERRIDE;
   virtual void GetWebUIMessageHandlers(
       std::vector<content::WebUIMessageHandler*>* handlers) const OVERRIDE;
@@ -50,7 +50,7 @@
       const content::ContextMenuParams& params) OVERRIDE;
 
   // The dialog title.
-  string16 title_;
+  base::string16 title_;
 
   // The URL of the keyboard overlay.
   GURL url_;
diff --git a/ash/launcher/launcher.cc b/ash/launcher/launcher.cc
index 51f68c1..f37b05c 100644
--- a/ash/launcher/launcher.cc
+++ b/ash/launcher/launcher.cc
@@ -13,6 +13,7 @@
 #include "ash/launcher/launcher_navigator.h"
 #include "ash/launcher/launcher_view.h"
 #include "ash/root_window_controller.h"
+#include "ash/screen_ash.h"
 #include "ash/shelf/shelf_layout_manager.h"
 #include "ash/shelf/shelf_widget.h"
 #include "ash/shell.h"
@@ -35,15 +36,10 @@
 #include "ui/views/widget/widget.h"
 #include "ui/views/widget/widget_delegate.h"
 
-namespace {
-// Size of black border at bottom (or side) of launcher.
-const int kNumBlackPixels = 3;
-// Alpha to paint dimming image with.
-const int kDimAlpha = 96;
-}
-
 namespace ash {
 
+const char Launcher::kNativeViewName[] = "LauncherView";
+
 Launcher::Launcher(LauncherModel* launcher_model,
                    LauncherDelegate* launcher_delegate,
                    ShelfWidget* shelf_widget)
@@ -55,12 +51,14 @@
       launcher_model, delegate_, shelf_widget_->shelf_layout_manager());
   launcher_view_->Init();
   shelf_widget_->GetContentsView()->AddChildView(launcher_view_);
-  shelf_widget_->GetNativeView()->SetName("LauncherView");
+  shelf_widget_->GetNativeView()->SetName(kNativeViewName);
   shelf_widget_->GetNativeView()->SetProperty(
       internal::kStayInSameRootWindowKey, true);
+  delegate_->OnLauncherCreated(this);
 }
 
 Launcher::~Launcher() {
+  delegate_->OnLauncherDestroyed(this);
 }
 
 // static
@@ -98,17 +96,36 @@
 void Launcher::UpdateIconPositionForWindow(aura::Window* window) {
   launcher_view_->UpdatePanelIconPosition(
       delegate_->GetIDByWindow(window),
-      window->bounds().CenterPoint());
+      ash::ScreenAsh::ConvertRectFromScreen(
+          shelf_widget()->GetNativeView(),
+          window->GetBoundsInScreen()).CenterPoint());
 }
 
 void Launcher::ActivateLauncherItem(int index) {
+  // We pass in a keyboard event which will then trigger a switch to the
+  // next item if the current one is already active.
+  ui::KeyEvent event(ui::ET_KEY_RELEASED,
+                     ui::VKEY_UNKNOWN,  // The actual key gets ignored.
+                     ui::EF_NONE,
+                     false);
+  // TODO(skuhne): Remove this temporary fix once M28 is out and CL 11596003
+  // has landed. Note that all unit tests which use this function need to remove
+  // the "kChromeItemOffset" as well.
+  // Note: The index gets only decremented for the per app instance of the
+  // launcher. The old per browser launcher does not get impacted here.
+  if (delegate_->IsPerAppLauncher() && --index <= 0) {
+    LauncherItem item;
+    // Create a fake launcher item with an invalid ID so that
+    // our ChromeLauncherControllerPerApp can handle it accordingly. This is
+    // only a temporary fix until CL 11596003 has landed.
+    item.id = ash::kAppIdForBrowserSwitching;
+    delegate_->ItemSelected(item, event);
+    return;
+  }
+
   const ash::LauncherItems& items =
       launcher_view_->model()->items();
-  ui::MouseEvent event(ui::ET_MOUSE_PRESSED,
-                       gfx::Point(),
-                       gfx::Point(),
-                       ui::EF_NONE);
-  delegate_->ItemClicked(items[index], event);
+  delegate_->ItemSelected(items[index], event);
 }
 
 void Launcher::CycleWindowLinear(CycleDirection direction) {
@@ -171,9 +188,10 @@
   // found (which is true when indexes_left is -1) or b.) the last item was
   // requested (which is true when index was passed in as a negative number).
   if (found_index >= 0 && (indexes_left == -1 || window_index < 0) &&
-      (items[found_index].status == ash::STATUS_RUNNING ||
-       items[found_index].status == ash::STATUS_CLOSED)) {
-    // Then set this one as active.
+      (delegate_->IsPerAppLauncher() ||
+       (items[found_index].status == ash::STATUS_RUNNING ||
+        items[found_index].status == ash::STATUS_CLOSED))) {
+    // Then set this one as active (or advance to the next item of its kind).
     ActivateLauncherItem(found_index);
   }
 }
diff --git a/ash/launcher/launcher.h b/ash/launcher/launcher.h
index 8c61ce3..7d7f3cd 100644
--- a/ash/launcher/launcher.h
+++ b/ash/launcher/launcher.h
@@ -40,6 +40,8 @@
 
 class ASH_EXPORT Launcher {
  public:
+  static const char kNativeViewName[];
+
   Launcher(LauncherModel* launcher_model,
            LauncherDelegate* launcher_delegate,
            ShelfWidget* shelf_widget);
diff --git a/ash/launcher/launcher_button.cc b/ash/launcher/launcher_button.cc
index 546a145..78fc815 100644
--- a/ash/launcher/launcher_button.cc
+++ b/ash/launcher/launcher_button.cc
@@ -79,7 +79,7 @@
 
  private:
   LauncherButtonAnimation()
-    : ALLOW_THIS_IN_INITIALIZER_LIST(animation_(this)) {
+      : animation_(this) {
     animation_.SetThrobDuration(kAttentionThrobDurationMS);
     animation_.SetTweenType(ui::Tween::SMOOTH_IN_OUT);
   }
@@ -96,7 +96,7 @@
   }
 
   // ui::AnimationDelegate
-  void AnimationProgressed(const ui::Animation* animation) {
+  virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE {
     if (animation != &animation_)
       return;
     if (!animation_.is_animating())
@@ -126,7 +126,7 @@
         show_attention_(false) {
   }
 
-  ~BarView() {
+  virtual ~BarView() {
     if (show_attention_)
       LauncherButtonAnimation::GetInstance()->RemoveObserver(this);
   }
@@ -392,17 +392,17 @@
 
 void LauncherButton::Layout() {
   const gfx::Rect button_bounds(GetContentsBounds());
-
-  int x_offset = shelf_layout_manager_->SelectValueForShelfAlignment(
-      0, kIconPad, kIconPad, 0);
-  int y_offset = shelf_layout_manager_->SelectValueForShelfAlignment(
-      kIconPad, 0, 0, kIconPad);
-
-  int icon_width = std::min(kIconSize, button_bounds.width() - x_offset);
-  int icon_height = std::min(kIconSize, button_bounds.height() - y_offset);
-
-  x_offset = std::max(x_offset, (button_bounds.width() - icon_width) / 2);
-  y_offset = std::max(y_offset, (button_bounds.height() - icon_height) / 2);
+   int x_offset = 0, y_offset = 0;
+   gfx::Rect icon_bounds;
+   if (shelf_layout_manager_->IsHorizontalAlignment()) {
+    icon_bounds.SetRect(
+        button_bounds.x(), button_bounds.y() + kIconPad,
+        button_bounds.width(), kIconSize);
+  } else {
+    icon_bounds.SetRect(
+        button_bounds.x() + kIconPad, button_bounds.y(),
+        kIconSize, button_bounds.height());
+  }
 
   if (ShouldHop(state_)) {
     x_offset += shelf_layout_manager_->SelectValueForShelfAlignment(
@@ -411,11 +411,7 @@
         -kHopSpacing, 0, 0, kHopSpacing);
   }
 
-  gfx::Rect icon_bounds(
-        button_bounds.x() + x_offset,
-        button_bounds.y() + y_offset,
-        icon_width,
-        icon_height);
+  icon_bounds.Offset(x_offset, y_offset);
   icon_view_->SetBoundsRect(icon_bounds);
   bar_->SetBarBoundsRect(GetContentsBounds());
   UpdateState();
diff --git a/ash/launcher/launcher_button_host.h b/ash/launcher/launcher_button_host.h
index 37ed07a..ecb76a3 100644
--- a/ash/launcher/launcher_button_host.h
+++ b/ash/launcher/launcher_button_host.h
@@ -54,7 +54,7 @@
   virtual void MouseExitedButton(views::View* view) = 0;
 
   // Invoked to get the accessible name of the item.
-  virtual string16 GetAccessibleName(const views::View* view) = 0;
+  virtual base::string16 GetAccessibleName(const views::View* view) = 0;
 
  protected:
   virtual ~LauncherButtonHost() {}
diff --git a/ash/launcher/launcher_delegate.h b/ash/launcher/launcher_delegate.h
index 5ca045e..45109e8 100644
--- a/ash/launcher/launcher_delegate.h
+++ b/ash/launcher/launcher_delegate.h
@@ -19,6 +19,12 @@
 }
 
 namespace ash {
+class Launcher;
+
+// When passed to LauncherDelegate::ItemSelected, the browser item will be
+// addressed for switching.
+// TODO(skuhne): Remove this constant once CL 11596003 has landed.
+const LauncherID kAppIdForBrowserSwitching = -1;
 
 // A special menu model which keeps track of an "active" menu item.
 class ASH_EXPORT LauncherMenuModel : public ui::SimpleMenuModel {
@@ -48,16 +54,18 @@
   // Invoked when the user clicks on a window entry in the launcher.
   // |event| is the click event. The |event| is dispatched by a view
   // and has an instance of |views::View| as the event target
-  // but not |aura::Window|.
-  virtual void ItemClicked(const LauncherItem& item,
-                           const ui::Event& event) = 0;
+  // but not |aura::Window|. If the |event| is of type KeyEvent, it is assumed
+  // that this was triggered by keyboard action (Alt+<number>) and special
+  // handling might happen (PerApp launcher).
+  virtual void ItemSelected(const LauncherItem& item,
+                            const ui::Event& event) = 0;
 
   // Returns the resource id of the image to show on the browser shortcut
   // button.
   virtual int GetBrowserShortcutResourceId() = 0;
 
   // Returns the title to display for the specified launcher item.
-  virtual string16 GetTitle(const LauncherItem& item) = 0;
+  virtual base::string16 GetTitle(const LauncherItem& item) = 0;
 
   // Returns the context menumodel for the specified item on
   // |root_window|.  Return NULL if there should be no context
@@ -87,6 +95,17 @@
 
   // Returns true if a tooltip should be shown for the item.
   virtual bool ShouldShowTooltip(const LauncherItem& item) = 0;
+
+  // Callback used to allow delegate to perform initialization actions that
+  // depend on the Launcher being in a known state.
+  virtual void OnLauncherCreated(Launcher* launcher) = 0;
+
+  // Callback used to inform the delegate that a specific launcher no longer
+  // exists.
+  virtual void OnLauncherDestroyed(Launcher* launcher) = 0;
+
+  // True if the running launcher is the per application launcher.
+  virtual bool IsPerAppLauncher() = 0;
 };
 
 }  // namespace ash
diff --git a/ash/launcher/launcher_model.h b/ash/launcher/launcher_model.h
index 3e2ba59..0d54486 100644
--- a/ash/launcher/launcher_model.h
+++ b/ash/launcher/launcher_model.h
@@ -45,7 +45,7 @@
   void Set(int index, const LauncherItem& item);
 
   // Returns the index of the item by id.
-  int ItemIndexByID(int id) const;
+  int ItemIndexByID(LauncherID id) const;
 
   // Returns the index of the first panel or the index where the first panel
   // would go if there are no panels.
diff --git a/ash/launcher/launcher_tooltip_manager.cc b/ash/launcher/launcher_tooltip_manager.cc
index 12bdf33..0363a0d 100644
--- a/ash/launcher/launcher_tooltip_manager.cc
+++ b/ash/launcher/launcher_tooltip_manager.cc
@@ -50,10 +50,10 @@
     : public views::BubbleDelegateView {
  public:
   LauncherTooltipBubble(views::View* anchor,
-                        views::BubbleBorder::ArrowLocation arrow_location,
+                        views::BubbleBorder::Arrow arrow,
                         LauncherTooltipManager* host);
 
-  void SetText(const string16& text);
+  void SetText(const base::string16& text);
   void Close();
 
  private:
@@ -71,9 +71,9 @@
 
 LauncherTooltipManager::LauncherTooltipBubble::LauncherTooltipBubble(
     views::View* anchor,
-    views::BubbleBorder::ArrowLocation arrow_location,
+    views::BubbleBorder::Arrow arrow,
     LauncherTooltipManager* host)
-    : views::BubbleDelegateView(anchor, arrow_location),
+    : views::BubbleDelegateView(anchor, arrow),
       host_(host) {
   gfx::Insets insets = gfx::Insets(kArrowOffsetTopBottom,
                                    kArrowOffsetLeftRight,
@@ -84,7 +84,7 @@
   if (anchor->border())
     insets += anchor->border()->GetInsets();
 
-  set_anchor_insets(insets);
+  set_anchor_view_insets(insets);
   set_close_on_esc(false);
   set_close_on_deactivate(false);
   set_use_focusless(true);
@@ -109,7 +109,7 @@
 }
 
 void LauncherTooltipManager::LauncherTooltipBubble::SetText(
-    const string16& text) {
+    const base::string16& text) {
   label_->SetText(text);
   SizeToContents();
 }
@@ -160,7 +160,7 @@
 }
 
 void LauncherTooltipManager::ShowDelayed(views::View* anchor,
-                                         const string16& text) {
+                                         const base::string16& text) {
   if (view_) {
     if (timer_.get() && timer_->IsRunning()) {
       return;
@@ -178,7 +178,7 @@
 }
 
 void LauncherTooltipManager::ShowImmediately(views::View* anchor,
-                                             const string16& text) {
+                                             const base::string16& text) {
   if (view_) {
     if (timer_.get() && timer_->IsRunning())
       StopTimer();
@@ -209,7 +209,7 @@
   }
 }
 
-void LauncherTooltipManager::UpdateArrowLocation() {
+void LauncherTooltipManager::UpdateArrow() {
   if (view_) {
     CancelHidingAnimation();
     Close();
@@ -332,7 +332,7 @@
 }
 
 void LauncherTooltipManager::CloseSoon() {
-  MessageLoopForUI::current()->PostTask(
+  base::MessageLoopForUI::current()->PostTask(
       FROM_HERE,
       base::Bind(&LauncherTooltipManager::Close, base::Unretained(this)));
 }
@@ -345,19 +345,19 @@
 }
 
 void LauncherTooltipManager::CreateBubble(views::View* anchor,
-                                          const string16& text) {
+                                          const base::string16& text) {
   DCHECK(!view_);
 
   anchor_ = anchor;
   text_ = text;
-  views::BubbleBorder::ArrowLocation arrow_location =
+  views::BubbleBorder::Arrow arrow =
       shelf_layout_manager_->SelectValueForShelfAlignment(
           views::BubbleBorder::BOTTOM_CENTER,
           views::BubbleBorder::LEFT_CENTER,
           views::BubbleBorder::RIGHT_CENTER,
           views::BubbleBorder::TOP_CENTER);
 
-  view_ = new LauncherTooltipBubble(anchor, arrow_location, this);
+  view_ = new LauncherTooltipBubble(anchor, arrow, this);
   widget_ = view_->GetWidget();
   view_->SetText(text_);
 
diff --git a/ash/launcher/launcher_tooltip_manager.h b/ash/launcher/launcher_tooltip_manager.h
index c2418f5..a880713 100644
--- a/ash/launcher/launcher_tooltip_manager.h
+++ b/ash/launcher/launcher_tooltip_manager.h
@@ -50,17 +50,17 @@
   void OnBubbleClosed(views::BubbleDelegateView* view);
 
   // Shows the tooltip after a delay.  It also has the appearing animation.
-  void ShowDelayed(views::View* anchor, const string16& text);
+  void ShowDelayed(views::View* anchor, const base::string16& text);
 
   // Shows the tooltip immediately.  It omits the appearing animation.
-  void ShowImmediately(views::View* anchor, const string16& text);
+  void ShowImmediately(views::View* anchor, const base::string16& text);
 
   // Closes the tooltip.
   void Close();
 
   // Changes the arrow location of the tooltip in case that the launcher
   // arrangement has changed.
-  void UpdateArrowLocation();
+  void UpdateArrow();
 
   // Resets the timer for the delayed showing |view_|.  If the timer isn't
   // running, it starts a new timer.
@@ -93,12 +93,12 @@
   void CancelHidingAnimation();
   void CloseSoon();
   void ShowInternal();
-  void CreateBubble(views::View* anchor, const string16& text);
+  void CreateBubble(views::View* anchor, const base::string16& text);
 
   LauncherTooltipBubble* view_;
   views::Widget* widget_;
   views::View* anchor_;
-  string16 text_;
+  base::string16 text_;
   scoped_ptr<base::Timer> timer_;
 
   ShelfLayoutManager* shelf_layout_manager_;
diff --git a/ash/launcher/launcher_tooltip_manager_unittest.cc b/ash/launcher/launcher_tooltip_manager_unittest.cc
index 0cdd373..4ceef35 100644
--- a/ash/launcher/launcher_tooltip_manager_unittest.cc
+++ b/ash/launcher/launcher_tooltip_manager_unittest.cc
@@ -54,12 +54,12 @@
 
   void ShowDelayed() {
     CreateWidget();
-    tooltip_manager_->ShowDelayed(dummy_anchor_.get(), string16());
+    tooltip_manager_->ShowDelayed(dummy_anchor_.get(), base::string16());
   }
 
   void ShowImmediately() {
     CreateWidget();
-    tooltip_manager_->ShowImmediately(dummy_anchor_.get(), string16());
+    tooltip_manager_->ShowImmediately(dummy_anchor_.get(), base::string16());
   }
 
   bool TooltipIsVisible() {
diff --git a/ash/launcher/launcher_util.cc b/ash/launcher/launcher_util.cc
index f41ac7d..f7ba77f 100644
--- a/ash/launcher/launcher_util.cc
+++ b/ash/launcher/launcher_util.cc
@@ -6,11 +6,6 @@
 
 #include "ash/launcher/launcher_model.h"
 #include "ash/launcher/launcher_types.h"
-#include "ash/shell.h"
-#include "ui/aura/client/window_types.h"
-#include "ui/aura/window.h"
-#include "ui/views/view.h"
-#include "ui/views/widget/widget.h"
 
 namespace ash {
 namespace launcher {
@@ -23,20 +18,5 @@
   return -1;
 }
 
-void MoveToEventRootIfPanel(aura::Window* maybe_panel,
-                            const ui::Event& event) {
-  if (maybe_panel->type() != aura::client::WINDOW_TYPE_PANEL)
-    return;
-  views::View* target = static_cast<views::View*>(event.target());
-  aura::RootWindow* target_root =
-      target ? target->GetWidget()->GetNativeView()->GetRootWindow() : NULL;
-  if (target_root && target_root != maybe_panel->GetRootWindow()) {
-    aura::Window* panel_container =
-        ash::Shell::GetContainer(target_root, maybe_panel->parent()->id());
-    // Move the panel to the target launcher.
-    panel_container->AddChild(maybe_panel);
-  }
-}
-
 }  // namespace launcher
 }  // namespace ash
diff --git a/ash/launcher/launcher_util.h b/ash/launcher/launcher_util.h
index 7cdd1f2..89551f0 100644
--- a/ash/launcher/launcher_util.h
+++ b/ash/launcher/launcher_util.h
@@ -7,14 +7,6 @@
 
 #include "ash/ash_export.h"
 
-namespace aura {
-class Window;
-}
-
-namespace ui {
-class Event;
-}
-
 namespace ash {
 class LauncherModel;
 
@@ -23,12 +15,6 @@
 // Return the index of the browser item from a given |launcher_model|.
 ASH_EXPORT int GetBrowserItemIndex(const LauncherModel& launcher_model);
 
-// Move the |maybe_panel| to the root window where the |event| occured if
-// |maybe_panel| is of aura::client::WINDOW_TYPE_PANEL and it's not
-// in the same root window.
-ASH_EXPORT void MoveToEventRootIfPanel(aura::Window* maybe_panel,
-                                       const ui::Event& event);
-
 }  // namespace launcher
 }  // namespace ash
 
diff --git a/ash/launcher/launcher_view.cc b/ash/launcher/launcher_view.cc
index a7ff127..32e20ec 100644
--- a/ash/launcher/launcher_view.cc
+++ b/ash/launcher/launcher_view.cc
@@ -376,7 +376,8 @@
       leading_inset_(kDefaultLeadingInset),
       cancelling_drag_model_changed_(false),
       last_hidden_index_(0),
-      closing_event_time_(base::TimeDelta()) {
+      closing_event_time_(base::TimeDelta()),
+      got_deleted_(NULL) {
   DCHECK(model_);
   bounds_animator_.reset(new views::BoundsAnimator(this));
   bounds_animator_->AddObserver(this);
@@ -389,6 +390,10 @@
 LauncherView::~LauncherView() {
   bounds_animator_->RemoveObserver(this);
   model_->RemoveObserver(this);
+  // If we are inside the MenuRunner, we need to know if we were getting
+  // deleted while it was running.
+  if (got_deleted_)
+    *got_deleted_ = true;
 }
 
 void LauncherView::Init() {
@@ -434,8 +439,8 @@
     if (i >= first_visible_index_ && i <= last_visible_index_)
       view_model_->view_at(i)->Layout();
   }
-  tooltip_->UpdateArrowLocation();
-  if (overflow_bubble_.get())
+  tooltip_->UpdateArrow();
+  if (overflow_bubble_)
     overflow_bubble_->Hide();
 }
 
@@ -670,7 +675,7 @@
     if (overflow_bubble_.get() && overflow_bubble_->IsShowing())
       UpdateOverflowRange(overflow_bubble_->launcher_view());
   } else {
-    if (overflow_bubble_.get())
+    if (overflow_bubble_)
       overflow_bubble_->Hide();
   }
 }
@@ -930,7 +935,7 @@
     return;
   }
 
-  if (!overflow_bubble_.get())
+  if (!overflow_bubble_)
     overflow_bubble_.reset(new OverflowBubble());
 
   LauncherView* overflow_view = new LauncherView(
@@ -1279,11 +1284,11 @@
     tooltip_->StopTimer();
 }
 
-string16 LauncherView::GetAccessibleName(const views::View* view) {
+base::string16 LauncherView::GetAccessibleName(const views::View* view) {
   int view_index = view_model_->GetIndexOfView(view);
   // May be -1 while in the process of animating closed.
   if (view_index == -1)
-    return string16();
+    return base::string16();
 
   switch (model_->items()[view_index].type) {
     case TYPE_TABBED:
@@ -1301,7 +1306,7 @@
     case TYPE_BROWSER_SHORTCUT:
       return Shell::GetInstance()->delegate()->GetProductName();
   }
-  return string16();
+  return base::string16();
 }
 
 void LauncherView::ButtonPressed(views::Button* sender,
@@ -1310,6 +1315,8 @@
   if (dragging())
     return;
 
+  tooltip_->Close();
+
   if (sender == overflow_button_) {
     ToggleOverflowBubble();
     return;
@@ -1325,8 +1332,6 @@
   if (!IsUsableEvent(event))
     return;
 
-  tooltip_->Close();
-
   {
     // Slow down activation animations if shift key is pressed.
     scoped_ptr<ui::ScopedAnimationDurationScaleMode> slowing_animations;
@@ -1345,7 +1350,7 @@
       // Fallthrough
     case TYPE_TABBED:
     case TYPE_APP_PANEL:
-      delegate_->ItemClicked(model_->items()[view_index], event);
+      delegate_->ItemSelected(model_->items()[view_index], event);
       break;
 
     case TYPE_APP_LIST:
@@ -1401,7 +1406,7 @@
   scoped_ptr<ui::MenuModel> menu_model(delegate_->CreateContextMenu(
       model_->items()[view_index],
       source->GetWidget()->GetNativeView()->GetRootWindow()));
-  if (!menu_model.get())
+  if (!menu_model)
     return;
   base::AutoReset<LauncherID> reseter(
       &context_menu_id_,
@@ -1428,10 +1433,11 @@
       views::MenuItemView::TOPLEFT;
   gfx::Rect anchor_point = gfx::Rect(click_point, gfx::Size());
 
+  ShelfWidget* shelf = RootWindowController::ForLauncher(
+      GetWidget()->GetNativeView())->shelf();
   if (!context_menu) {
     // Application lists use a bubble.
-    ash::ShelfAlignment align = RootWindowController::ForLauncher(
-        GetWidget()->GetNativeView())->shelf()->GetAlignment();
+    ash::ShelfAlignment align = shelf->GetAlignment();
     anchor_point = source->GetBoundsInScreen();
 
     // Launcher items can have an asymmetrical border for spacing reasons.
@@ -1454,6 +1460,12 @@
         break;
     }
   }
+  // If this gets deleted while we are in the menu, the launcher will be gone
+  // as well.
+  bool got_deleted = false;
+  got_deleted_ = &got_deleted;
+
+  shelf->ForceUndimming(true);
   // NOTE: if you convert to HAS_MNEMONICS be sure and update menu building
   // code.
   if (launcher_menu_runner_->RunMenuAt(
@@ -1461,12 +1473,19 @@
           NULL,
           anchor_point,
           menu_alignment,
-          views::MenuRunner::CONTEXT_MENU) == views::MenuRunner::MENU_DELETED)
+          views::MenuRunner::CONTEXT_MENU) == views::MenuRunner::MENU_DELETED) {
+    if (!got_deleted) {
+      got_deleted_ = NULL;
+      shelf->ForceUndimming(false);
+    }
     return;
+  }
+  got_deleted_ = NULL;
+  shelf->ForceUndimming(false);
 
   // Unpinning an item will reset the |launcher_menu_runner_| before coming
   // here.
-  if (launcher_menu_runner_.get())
+  if (launcher_menu_runner_)
     closing_event_time_ = launcher_menu_runner_->closing_event_time();
   Shell::GetInstance()->UpdateShelfVisibility();
 }
diff --git a/ash/launcher/launcher_view.h b/ash/launcher/launcher_view.h
index a3f209e..3b1f0f3 100644
--- a/ash/launcher/launcher_view.h
+++ b/ash/launcher/launcher_view.h
@@ -205,7 +205,7 @@
   virtual void MouseMovedOverButton(views::View* view) OVERRIDE;
   virtual void MouseEnteredButton(views::View* view) OVERRIDE;
   virtual void MouseExitedButton(views::View* view) OVERRIDE;
-  virtual string16 GetAccessibleName(const views::View* view) OVERRIDE;
+  virtual base::string16 GetAccessibleName(const views::View* view) OVERRIDE;
 
   // Overridden from views::ButtonListener:
   virtual void ButtonPressed(views::Button* sender,
@@ -316,6 +316,10 @@
   // The timestamp of the event which closed the last menu - or 0.
   base::TimeDelta closing_event_time_;
 
+  // When this object gets deleted while a menu is shown, this pointed
+  // element will be set to false.
+  bool* got_deleted_;
+
   DISALLOW_COPY_AND_ASSIGN(LauncherView);
 };
 
diff --git a/ash/launcher/overflow_bubble.cc b/ash/launcher/overflow_bubble.cc
index 1fa7255..09613ca 100644
--- a/ash/launcher/overflow_bubble.cc
+++ b/ash/launcher/overflow_bubble.cc
@@ -54,7 +54,7 @@
   }
 
   // Gets arrow location based on shelf alignment.
-  views::BubbleBorder::ArrowLocation GetBubbleArrowLocation() const {
+  views::BubbleBorder::Arrow GetBubbleArrow() const {
     return GetShelfLayoutManagerForLauncher()->SelectValueForShelfAlignment(
         views::BubbleBorder::BOTTOM_LEFT,
         views::BubbleBorder::LEFT_TOP,
@@ -100,7 +100,7 @@
   // set_anchor_view needs to be called before GetShelfLayoutManagerForLauncher
   // can be called.
   set_anchor_view(anchor);
-  set_arrow_location(GetBubbleArrowLocation());
+  set_arrow(GetBubbleArrow());
   set_background(NULL);
   set_color(SkColorSetARGB(kLauncherBackgroundAlpha, 0, 0, 0));
   set_margins(gfx::Insets(kPadding, kPadding, kPadding, kPadding));
@@ -172,10 +172,14 @@
 }
 
 bool OverflowBubbleView::OnMouseWheel(const ui::MouseWheelEvent& event) {
+  // The MouseWheelEvent was changed to support both X and Y offsets
+  // recently, but the behavior of this function was retained to continue
+  // using Y offsets only. Might be good to simply scroll in both
+  // directions as in OverflowBubbleView::OnScrollEvent.
   if (IsHorizontalAlignment())
-    ScrollByXOffset(-event.offset());
+    ScrollByXOffset(-event.y_offset());
   else
-    ScrollByYOffset(-event.offset());
+    ScrollByYOffset(-event.y_offset());
   Layout();
 
   return true;
@@ -193,7 +197,7 @@
   gfx::Insets bubble_insets = border->GetInsets();
 
   const int border_size =
-      views::BubbleBorder::is_arrow_on_horizontal(arrow_location()) ?
+      views::BubbleBorder::is_arrow_on_horizontal(arrow()) ?
       bubble_insets.left() : bubble_insets.top();
   const int arrow_offset = border_size + kPadding + kLauncherViewLeadingInset +
       kLauncherPreferredSize / 2;
@@ -211,7 +215,7 @@
       anchor_rect.CenterPoint()).work_area();
 
   int offset = 0;
-  if (views::BubbleBorder::is_arrow_on_horizontal(arrow_location())) {
+  if (views::BubbleBorder::is_arrow_on_horizontal(arrow())) {
     if (bubble_rect.x() < monitor_rect.x())
       offset = monitor_rect.x() - bubble_rect.x();
     else if (bubble_rect.right() > monitor_rect.right())
diff --git a/ash/magnifier/magnification_controller.cc b/ash/magnifier/magnification_controller.cc
index ba1de9e..55785c7 100644
--- a/ash/magnifier/magnification_controller.cc
+++ b/ash/magnifier/magnification_controller.cc
@@ -4,12 +4,16 @@
 
 #include "ash/magnifier/magnification_controller.h"
 
+#include "ash/ash_root_window_transformer.h"
 #include "ash/display/display_controller.h"
+#include "ash/display/display_manager.h"
 #include "ash/shell.h"
 #include "ash/shell_delegate.h"
 #include "ash/system/tray/system_tray_delegate.h"
+#include "base/synchronization/waitable_event.h"
 #include "ui/aura/client/cursor_client.h"
 #include "ui/aura/root_window.h"
+#include "ui/aura/root_window_transformer.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_property.h"
 #include "ui/base/events/event.h"
@@ -18,6 +22,7 @@
 #include "ui/compositor/layer.h"
 #include "ui/compositor/layer_animation_observer.h"
 #include "ui/compositor/scoped_layer_animation_settings.h"
+#include "ui/gfx/point3_f.h"
 #include "ui/gfx/point_conversions.h"
 #include "ui/gfx/point_f.h"
 #include "ui/gfx/rect_conversions.h"
@@ -38,6 +43,14 @@
 // |kPanningMergin| from the edge, the view-port moves.
 const int kPanningMergin = 100;
 
+void MoveCursorTo(aura::RootWindow* root_window,
+                  const gfx::Point root_location) {
+  gfx::Point3F host_location_3f(root_location);
+  root_window->layer()->transform().TransformPoint(host_location_3f);
+  root_window->MoveCursorToHostLocation(
+      gfx::ToCeiledPoint(host_location_3f.AsPointF()));
+}
+
 }  // namespace
 
 namespace ash {
@@ -67,6 +80,10 @@
                                    bool animate) OVERRIDE;
   virtual void EnsurePointIsVisible(const gfx::Point& point,
                                     bool animate) OVERRIDE;
+  // For test
+  virtual gfx::Point GetPointOfInterestForTesting() OVERRIDE {
+    return point_of_interest_;
+  }
 
  private:
   // ui::ImplicitAnimationObserver overrides:
@@ -74,6 +91,9 @@
 
   // aura::WindowObserver overrides:
   virtual void OnWindowDestroying(aura::Window* root_window) OVERRIDE;
+  virtual void OnWindowBoundsChanged(aura::Window* window,
+                                     const gfx::Rect& old_bounds,
+                                     const gfx::Rect& new_bounds) OVERRIDE;
 
   // Redraws the magnification window with the given origin position and the
   // given scale. Returns true if the window is changed; otherwise, false.
@@ -251,7 +271,11 @@
   settings.SetTransitionDuration(
       base::TimeDelta::FromMilliseconds(animate ? 100 : 0));
 
-  root_window_->layer()->SetTransform(transform);
+  gfx::Display display =
+      Shell::GetScreen()->GetDisplayNearestWindow(root_window_);
+  scoped_ptr<aura::RootWindowTransformer> transformer(
+      new AshRootWindowTransformer(root_window_, display));
+  root_window_->SetRootWindowTransformer(transformer.Pass());
 
   if (animate)
     is_on_animation_ = true;
@@ -358,7 +382,7 @@
     if (ret) {
       // If the magnified region is moved, hides the mouse cursor and moves it.
       if (x_diff != 0 || y_diff != 0)
-        root_window_->MoveCursorTo(mouse);
+        MoveCursorTo(root_window_, mouse);
     }
   }
 }
@@ -381,14 +405,11 @@
 }
 
 gfx::Size MagnificationControllerImpl::GetHostSizeDIP() const {
-  return ui::ConvertSizeToDIP(root_window_->layer(),
-                              root_window_->GetHostSize());
+  return root_window_->bounds().size();
 }
 
 gfx::RectF MagnificationControllerImpl::GetWindowRectDIP(float scale) const {
-  const gfx::Size size_in_dip =
-      ui::ConvertSizeToDIP(root_window_->layer(),
-                           root_window_->GetHostSize());
+  const gfx::Size size_in_dip = root_window_->bounds().size();
   const float width = size_in_dip.width() / scale;
   const float height = size_in_dip.height() / scale;
 
@@ -418,7 +439,7 @@
     return;
 
   if (move_cursor_after_animation_) {
-    root_window_->MoveCursorTo(position_after_animation_);
+    MoveCursorTo(root_window_, position_after_animation_);
     move_cursor_after_animation_ = false;
 
     aura::client::CursorClient* cursor_client =
@@ -448,6 +469,13 @@
   }
 }
 
+void MagnificationControllerImpl::OnWindowBoundsChanged(
+    aura::Window* window,
+    const gfx::Rect& old_bounds,
+    const gfx::Rect& new_bounds) {
+  // TODO(yoshiki): implement here. crbug.com/230979
+}
+
 void MagnificationControllerImpl::SwitchTargetRootWindow(
     aura::RootWindow* new_root_window,
     bool redraw_original_root_window) {
@@ -526,9 +554,9 @@
     if (is_enabled_ && scale == scale_)
       return;
 
+    is_enabled_ = enabled;
     RedrawKeepingMousePosition(scale, true);
     ash::Shell::GetInstance()->delegate()->SaveScreenMagnifierScale(scale);
-    is_enabled_ = enabled;
   } else {
     // Do nothing, if already disabled.
     if (!is_enabled_)
diff --git a/ash/magnifier/magnification_controller.h b/ash/magnifier/magnification_controller.h
index aa70618..75d1b2f 100644
--- a/ash/magnifier/magnification_controller.h
+++ b/ash/magnifier/magnification_controller.h
@@ -47,6 +47,11 @@
   virtual void EnsureRectIsVisible(const gfx::Rect& rect, bool animate) = 0;
   virtual void EnsurePointIsVisible(const gfx::Point& point, bool animate) = 0;
 
+  // Returns |point_of_interest_| in MagnificationControllerImpl. This is
+  // the internal variable to stores the last mouse cursor (or last touched)
+  // location. This method is only for test purpose.
+  virtual gfx::Point GetPointOfInterestForTesting() = 0;
+
  protected:
   MagnificationController() {}
 };
diff --git a/ash/magnifier/magnification_controller_unittest.cc b/ash/magnifier/magnification_controller_unittest.cc
index 2060df4..5611b98 100644
--- a/ash/magnifier/magnification_controller_unittest.cc
+++ b/ash/magnifier/magnification_controller_unittest.cc
@@ -4,11 +4,14 @@
 
 #include "ash/display/display_controller.h"
 #include "ash/magnifier/magnification_controller.h"
+#include "ash/magnifier/magnifier_constants.h"
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
 #include "base/stringprintf.h"
 #include "ui/aura/client/aura_constants.h"
+#include "ui/aura/env.h"
 #include "ui/aura/root_window.h"
+#include "ui/aura/test/event_generator.h"
 #include "ui/gfx/rect_conversions.h"
 #include "ui/gfx/screen.h"
 
@@ -46,20 +49,37 @@
   }
 
  protected:
-  aura::RootWindow* GetRootWindow() {
+  aura::RootWindow* GetRootWindow() const {
     return Shell::GetPrimaryRootWindow();
   }
 
-  ash::MagnificationController* GetMagnificationController() {
+
+  void MoveCursorWithEvent(gfx::Point point) {
+    aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
+    generator.MoveMouseTo(point.x(), point.y());
+  }
+
+  std::string GetHostMouseLocation() {
+    gfx::Point point;
+    GetRootWindow()->QueryMouseLocationForTest(&point);
+    return point.ToString();
+  }
+
+  ash::MagnificationController* GetMagnificationController() const {
     return ash::Shell::GetInstance()->magnification_controller();
   }
 
-  gfx::Rect GetViewport() {
+  gfx::Rect GetViewport() const {
     gfx::RectF bounds(0, 0, kRootWidth, kRootHeight);
     GetRootWindow()->layer()->transform().TransformRectReverse(&bounds);
     return gfx::ToEnclosingRect(bounds);
   }
 
+  std::string CurrentPointOfInterest() const {
+    return GetMagnificationController()->
+        GetPointOfInterestForTesting().ToString();
+  }
+
  private:
   DISALLOW_COPY_AND_ASSIGN(MagnificationControllerTest);
 };
@@ -95,19 +115,23 @@
   EXPECT_FALSE(GetRootWindow()->layer()->transform().IsIdentity());
   EXPECT_EQ(2.0f, GetMagnificationController()->GetScale());
   EXPECT_EQ("200,150 400x300", GetViewport().ToString());
+  EXPECT_EQ("400,300", CurrentPointOfInterest());
 
   // Changes the scale.
   GetMagnificationController()->SetScale(4.0f, false);
   EXPECT_EQ(4.0f, GetMagnificationController()->GetScale());
   EXPECT_EQ("300,225 200x150", GetViewport().ToString());
+  EXPECT_EQ("400,300", CurrentPointOfInterest());
 
   GetMagnificationController()->SetScale(1.0f, false);
   EXPECT_EQ(1.0f, GetMagnificationController()->GetScale());
   EXPECT_EQ("0,0 800x600", GetViewport().ToString());
+  EXPECT_EQ("400,300", CurrentPointOfInterest());
 
   GetMagnificationController()->SetScale(3.0f, false);
   EXPECT_EQ(3.0f, GetMagnificationController()->GetScale());
-  EXPECT_EQ("266,200 268x200", GetViewport().ToString());
+  EXPECT_EQ("266,200 267x200", GetViewport().ToString());
+  EXPECT_EQ("400,300", CurrentPointOfInterest());
 }
 
 TEST_F(MagnificationControllerTest, MoveWindow) {
@@ -153,5 +177,267 @@
   EXPECT_EQ("400,300 400x300", GetViewport().ToString());
 }
 
+TEST_F(MagnificationControllerTest, PointOfInterest) {
+  MoveCursorWithEvent(gfx::Point(0, 0));
+  EXPECT_EQ("0,0", CurrentPointOfInterest());
+
+  MoveCursorWithEvent(gfx::Point(799, 599));
+  EXPECT_EQ("799,599", CurrentPointOfInterest());
+
+  MoveCursorWithEvent(gfx::Point(400, 300));
+  EXPECT_EQ("400,300", CurrentPointOfInterest());
+
+  GetMagnificationController()->SetEnabled(true);
+  EXPECT_EQ("400,300", CurrentPointOfInterest());
+
+  MoveCursorWithEvent(gfx::Point(500, 400));
+  EXPECT_EQ("450,350", CurrentPointOfInterest());
+}
+
+TEST_F(MagnificationControllerTest, PanWindow2xLeftToRight) {
+  const aura::Env* env = aura::Env::GetInstance();
+
+  MoveCursorWithEvent(gfx::Point(0, 0));
+  EXPECT_EQ(1.f, GetMagnificationController()->GetScale());
+  EXPECT_EQ("0,0 800x600", GetViewport().ToString());
+  EXPECT_EQ("0,0", env->last_mouse_location().ToString());
+
+  // Enables magnifier and confirm the viewport is at center.
+  GetMagnificationController()->SetEnabled(true);
+  EXPECT_EQ(2.0f, GetMagnificationController()->GetScale());
+
+  GetMagnificationController()->MoveWindow(0, 0, false);
+  MoveCursorWithEvent(gfx::Point(0, 0));
+  EXPECT_EQ("0,0", env->last_mouse_location().ToString());
+  EXPECT_EQ("0,0 400x300", GetViewport().ToString());
+
+  MoveCursorWithEvent(gfx::Point(300, 150));
+  EXPECT_EQ("150,75", env->last_mouse_location().ToString());
+  EXPECT_EQ("0,0 400x300", GetViewport().ToString());
+
+  MoveCursorWithEvent(gfx::Point(700, 150));
+  EXPECT_EQ("350,75", env->last_mouse_location().ToString());
+  EXPECT_EQ("0,0 400x300", GetViewport().ToString());
+
+  MoveCursorWithEvent(gfx::Point(701, 150));
+  EXPECT_EQ("350,75", env->last_mouse_location().ToString());
+  EXPECT_EQ("0,0 400x300", GetViewport().ToString());
+
+  MoveCursorWithEvent(gfx::Point(702, 150));
+  EXPECT_EQ("351,75", env->last_mouse_location().ToString());
+  EXPECT_EQ("1,0 400x300", GetViewport().ToString());
+
+  MoveCursorWithEvent(gfx::Point(703, 150));
+  EXPECT_EQ("352,75", env->last_mouse_location().ToString());
+  EXPECT_EQ("2,0 400x300", GetViewport().ToString());
+
+  MoveCursorWithEvent(gfx::Point(704, 150));
+  EXPECT_EQ("354,75", env->last_mouse_location().ToString());
+  EXPECT_EQ("4,0 400x300", GetViewport().ToString());
+
+  MoveCursorWithEvent(gfx::Point(712, 150));
+  EXPECT_EQ("360,75", env->last_mouse_location().ToString());
+  EXPECT_EQ("10,0 400x300", GetViewport().ToString());
+
+  MoveCursorWithEvent(gfx::Point(600, 150));
+  EXPECT_EQ("310,75", env->last_mouse_location().ToString());
+  EXPECT_EQ("10,0 400x300", GetViewport().ToString());
+
+  MoveCursorWithEvent(gfx::Point(720, 150));
+  EXPECT_EQ("370,75", env->last_mouse_location().ToString());
+  EXPECT_EQ("20,0 400x300", GetViewport().ToString());
+
+  MoveCursorWithEvent(gfx::Point(780, 150));
+  EXPECT_EQ("410,75", env->last_mouse_location().ToString());
+  EXPECT_EQ("410,75", CurrentPointOfInterest());
+  EXPECT_EQ("60,0 400x300", GetViewport().ToString());
+
+  MoveCursorWithEvent(gfx::Point(799, 150));
+  EXPECT_EQ("459,75", env->last_mouse_location().ToString());
+  EXPECT_EQ("109,0 400x300", GetViewport().ToString());
+
+  MoveCursorWithEvent(gfx::Point(702, 150));
+  EXPECT_EQ("460,75", env->last_mouse_location().ToString());
+  EXPECT_EQ("110,0 400x300", GetViewport().ToString());
+
+  MoveCursorWithEvent(gfx::Point(780, 150));
+  EXPECT_EQ("500,75", env->last_mouse_location().ToString());
+  EXPECT_EQ("150,0 400x300", GetViewport().ToString());
+
+  MoveCursorWithEvent(gfx::Point(780, 150));
+  EXPECT_EQ("540,75", env->last_mouse_location().ToString());
+  EXPECT_EQ("190,0 400x300", GetViewport().ToString());
+
+  MoveCursorWithEvent(gfx::Point(780, 150));
+  EXPECT_EQ("580,75", env->last_mouse_location().ToString());
+  EXPECT_EQ("230,0 400x300", GetViewport().ToString());
+
+  MoveCursorWithEvent(gfx::Point(780, 150));
+  EXPECT_EQ("620,75", env->last_mouse_location().ToString());
+  EXPECT_EQ("270,0 400x300", GetViewport().ToString());
+
+  MoveCursorWithEvent(gfx::Point(780, 150));
+  EXPECT_EQ("660,75", env->last_mouse_location().ToString());
+  EXPECT_EQ("310,0 400x300", GetViewport().ToString());
+
+  MoveCursorWithEvent(gfx::Point(780, 150));
+  EXPECT_EQ("700,75", env->last_mouse_location().ToString());
+  EXPECT_EQ("350,0 400x300", GetViewport().ToString());
+
+  MoveCursorWithEvent(gfx::Point(780, 150));
+  EXPECT_EQ("740,75", env->last_mouse_location().ToString());
+  EXPECT_EQ("390,0 400x300", GetViewport().ToString());
+
+  MoveCursorWithEvent(gfx::Point(780, 150));
+  EXPECT_EQ("780,75", env->last_mouse_location().ToString());
+  EXPECT_EQ("400,0 400x300", GetViewport().ToString());
+
+  MoveCursorWithEvent(gfx::Point(799, 150));
+  EXPECT_EQ("799,75", env->last_mouse_location().ToString());
+  EXPECT_EQ("400,0 400x300", GetViewport().ToString());
+}
+
+TEST_F(MagnificationControllerTest, PanWindow2xRightToLeft) {
+  const aura::Env* env = aura::Env::GetInstance();
+
+  MoveCursorWithEvent(gfx::Point(799, 300));
+  EXPECT_EQ(1.f, GetMagnificationController()->GetScale());
+  EXPECT_EQ("0,0 800x600", GetViewport().ToString());
+  EXPECT_EQ("799,300", env->last_mouse_location().ToString());
+
+  // Enables magnifier and confirm the viewport is at center.
+  GetMagnificationController()->SetEnabled(true);
+
+  MoveCursorWithEvent(gfx::Point(799, 300));
+  EXPECT_EQ("798,300", env->last_mouse_location().ToString());
+  EXPECT_EQ("400,150 400x300", GetViewport().ToString());
+
+  MoveCursorWithEvent(gfx::Point(0, 300));
+  EXPECT_EQ("400,300", env->last_mouse_location().ToString());
+  EXPECT_EQ("350,150 400x300", GetViewport().ToString());
+
+  MoveCursorWithEvent(gfx::Point(0, 300));
+  EXPECT_EQ("350,300", env->last_mouse_location().ToString());
+  EXPECT_EQ("300,150 400x300", GetViewport().ToString());
+
+  MoveCursorWithEvent(gfx::Point(0, 300));
+  EXPECT_EQ("300,300", env->last_mouse_location().ToString());
+  EXPECT_EQ("250,150 400x300", GetViewport().ToString());
+
+  MoveCursorWithEvent(gfx::Point(0, 300));
+  EXPECT_EQ("250,300", env->last_mouse_location().ToString());
+  EXPECT_EQ("200,150 400x300", GetViewport().ToString());
+
+  MoveCursorWithEvent(gfx::Point(0, 300));
+  EXPECT_EQ("200,300", env->last_mouse_location().ToString());
+  EXPECT_EQ("150,150 400x300", GetViewport().ToString());
+
+  MoveCursorWithEvent(gfx::Point(0, 300));
+  EXPECT_EQ("150,300", env->last_mouse_location().ToString());
+  EXPECT_EQ("100,150 400x300", GetViewport().ToString());
+
+  MoveCursorWithEvent(gfx::Point(0, 300));
+  EXPECT_EQ("100,300", env->last_mouse_location().ToString());
+  EXPECT_EQ("50,150 400x300", GetViewport().ToString());
+
+  MoveCursorWithEvent(gfx::Point(0, 300));
+  EXPECT_EQ("50,300", env->last_mouse_location().ToString());
+  EXPECT_EQ("0,150 400x300", GetViewport().ToString());
+
+  MoveCursorWithEvent(gfx::Point(0, 300));
+  EXPECT_EQ("0,300", env->last_mouse_location().ToString());
+  EXPECT_EQ("0,150 400x300", GetViewport().ToString());
+}
+
+TEST_F(MagnificationControllerTest, PanWindowToRight) {
+  const aura::Env* env = aura::Env::GetInstance();
+
+  MoveCursorWithEvent(gfx::Point(400, 300));
+  EXPECT_EQ(1.f, GetMagnificationController()->GetScale());
+  EXPECT_EQ("0,0 800x600", GetViewport().ToString());
+  EXPECT_EQ("400,300", env->last_mouse_location().ToString());
+
+  float scale = 2.f;
+
+  // Enables magnifier and confirm the viewport is at center.
+  GetMagnificationController()->SetEnabled(true);
+  EXPECT_FLOAT_EQ(2.f, GetMagnificationController()->GetScale());
+
+  scale *= kMagnificationScaleFactor;
+  GetMagnificationController()->SetScale(scale, false);
+  EXPECT_FLOAT_EQ(2.3784142, GetMagnificationController()->GetScale());
+  MoveCursorWithEvent(gfx::Point(400, 300));
+  EXPECT_EQ("400,300", env->last_mouse_location().ToString());
+  MoveCursorWithEvent(gfx::Point(799, 300));
+  EXPECT_EQ("566,299", env->last_mouse_location().ToString());
+  EXPECT_EQ("705,300", GetHostMouseLocation());
+
+  scale *= kMagnificationScaleFactor;
+  GetMagnificationController()->SetScale(scale, false);
+  EXPECT_FLOAT_EQ(2.8284268, GetMagnificationController()->GetScale());
+  MoveCursorWithEvent(gfx::Point(799, 300));
+  EXPECT_EQ("599,299", env->last_mouse_location().ToString());
+  EXPECT_EQ("702,300", GetHostMouseLocation());
+
+  scale *= kMagnificationScaleFactor;
+  GetMagnificationController()->SetScale(scale, false);
+  EXPECT_FLOAT_EQ(3.3635852, GetMagnificationController()->GetScale());
+  MoveCursorWithEvent(gfx::Point(799, 300));
+  EXPECT_EQ("627,298", env->last_mouse_location().ToString());
+  EXPECT_EQ("707,300", GetHostMouseLocation());
+
+  scale *= kMagnificationScaleFactor;
+  GetMagnificationController()->SetScale(scale, false);
+  EXPECT_FLOAT_EQ(4.f, GetMagnificationController()->GetScale());
+  MoveCursorWithEvent(gfx::Point(799, 300));
+  EXPECT_EQ("649,298", env->last_mouse_location().ToString());
+  EXPECT_EQ("704,300", GetHostMouseLocation());
+}
+
+TEST_F(MagnificationControllerTest, PanWindowToLeft) {
+  const aura::Env* env = aura::Env::GetInstance();
+
+  MoveCursorWithEvent(gfx::Point(400, 300));
+  EXPECT_EQ(1.f, GetMagnificationController()->GetScale());
+  EXPECT_EQ("0,0 800x600", GetViewport().ToString());
+  EXPECT_EQ("400,300", env->last_mouse_location().ToString());
+
+  float scale = 2.f;
+
+  // Enables magnifier and confirm the viewport is at center.
+  GetMagnificationController()->SetEnabled(true);
+  EXPECT_FLOAT_EQ(2.f, GetMagnificationController()->GetScale());
+
+  scale *= kMagnificationScaleFactor;
+  GetMagnificationController()->SetScale(scale, false);
+  EXPECT_FLOAT_EQ(2.3784142, GetMagnificationController()->GetScale());
+  MoveCursorWithEvent(gfx::Point(400, 300));
+  EXPECT_EQ("400,300", env->last_mouse_location().ToString());
+  MoveCursorWithEvent(gfx::Point(0, 300));
+  EXPECT_EQ("231,299", env->last_mouse_location().ToString());
+  EXPECT_EQ("100,300", GetHostMouseLocation());
+
+  scale *= kMagnificationScaleFactor;
+  GetMagnificationController()->SetScale(scale, false);
+  EXPECT_FLOAT_EQ(2.8284268, GetMagnificationController()->GetScale());
+  MoveCursorWithEvent(gfx::Point(0, 300));
+  EXPECT_EQ("195,299", env->last_mouse_location().ToString());
+  EXPECT_EQ("99,300", GetHostMouseLocation());
+
+  scale *= kMagnificationScaleFactor;
+  GetMagnificationController()->SetScale(scale, false);
+  EXPECT_FLOAT_EQ(3.3635852, GetMagnificationController()->GetScale());
+  MoveCursorWithEvent(gfx::Point(0, 300));
+  EXPECT_EQ("165,298", env->last_mouse_location().ToString());
+  EXPECT_EQ("98,300", GetHostMouseLocation());
+
+  scale *= kMagnificationScaleFactor;
+  GetMagnificationController()->SetScale(scale, false);
+  EXPECT_FLOAT_EQ(4.f, GetMagnificationController()->GetScale());
+  MoveCursorWithEvent(gfx::Point(0, 300));
+  EXPECT_EQ("140,298", env->last_mouse_location().ToString());
+  EXPECT_EQ("100,300", GetHostMouseLocation());
+}
+
 }  // namespace internal
 }  // namespace ash
diff --git a/ash/magnifier/magnifier_constants.h b/ash/magnifier/magnifier_constants.h
index aa7cac7..b286299 100644
--- a/ash/magnifier/magnifier_constants.h
+++ b/ash/magnifier/magnifier_constants.h
@@ -17,6 +17,11 @@
 
 const MagnifierType kDefaultMagnifierType = MAGNIFIER_FULL;
 
+// Factor of magnification scale. For example, when this value is 1.189, scale
+// value will be changed x1.000, x1.189, x1.414, x1.681, x2.000, ...
+// Note: this value is 2.0 ^ (1 / 4).
+const float kMagnificationScaleFactor = 1.18920712f;
+
 }  // namespace ash
 
 #endif  // ASH_MAGNIFIER_MAGNIFIER_CONSTANTS_H_
diff --git a/ash/resources/ash_resources.grd b/ash/resources/ash_resources.grd
index 47aca7f..d684a34 100644
--- a/ash/resources/ash_resources.grd
+++ b/ash/resources/ash_resources.grd
@@ -114,6 +114,8 @@
       <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_NOTIFICATION_LTE" file="cros/network/notification_lte.png" />
       <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_POWER_SMALL" file="cros/status/status_power_small_all.png" />
       <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_POWER_SMALL_DARK" file="cros/status/status_power_small_all_dark.png" />
+      <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_POWER_SMALL_CHARGING_UNRELIABLE" file="cros/status/status_power_small_all_fluctuating.png" />
+      <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_POWER_SMALL_CHARGING_UNRELIABLE_DARK" file="cros/status/status_power_small_all_dark_fluctuating.png" />
       <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_SESSION_LENGTH_LIMIT_TIMER" file="cros/status/status_session_length_limit_timer.png" />
       <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_SETTINGS" file="cros/status/status_settings.png" />
       <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_SHUTDOWN" file="cros/status/status_shutdown.png" />
@@ -163,11 +165,17 @@
 
       <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_VOLUME_LEVELS" file="cros/status/status_volume_dark.png" />
       <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_VOLUME_MUTE" file="cros/status/status_volume_mute.png" />
+      <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_AUDIO_HEADPHONE" file="cros/status/status_audio_device_headphones.png" />
+      <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_AUDIO_USB" file="cros/status/status_audio_device_usb.png" />
+      <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_AUDIO_BLUETOOTH" file="cros/status/status_audio_device_bluetooth.png" />
+      <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_AUDIO_HDMI" file="cros/status/status_audio_device_hdmi.png" />
+      
       <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_WIFI_DISABLED" file="cros/network/status_wifi_disabled.png" />
       <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_WIFI_DISABLED_HOVER" file="cros/network/status_wifi_disabled_hover.png" />
       <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_WIFI_ENABLED" file="cros/network/status_wifi_enabled.png" />
       <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_WIFI_ENABLED_HOVER" file="cros/network/status_wifi_enabled_hover.png" />
 
+      <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_NOTIFY_BUTTON_ICON" file="common/notification/notification_icon.png" />
       <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_NOTIFY_BUTTON_ACTIVE_NORMAL" file="common/notification/notification_button_active_normal.png" />
       <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_NOTIFY_BUTTON_ACTIVE_HOVER" file="common/notification/notification_button_active_hover.png" />
       <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_NOTIFY_BUTTON_ACTIVE_PRESSED" file="common/notification/notification_button_active_pressed.png" />
diff --git a/ash/resources/default_100_percent/common/notification/notification_button_active_hover.png b/ash/resources/default_100_percent/common/notification/notification_button_active_hover.png
index 99dd7ae..4b39392 100644
--- a/ash/resources/default_100_percent/common/notification/notification_button_active_hover.png
+++ b/ash/resources/default_100_percent/common/notification/notification_button_active_hover.png
Binary files differ
diff --git a/ash/resources/default_100_percent/common/notification/notification_button_active_normal.png b/ash/resources/default_100_percent/common/notification/notification_button_active_normal.png
index b81c965..4b39392 100644
--- a/ash/resources/default_100_percent/common/notification/notification_button_active_normal.png
+++ b/ash/resources/default_100_percent/common/notification/notification_button_active_normal.png
Binary files differ
diff --git a/ash/resources/default_100_percent/common/notification/notification_button_active_pressed.png b/ash/resources/default_100_percent/common/notification/notification_button_active_pressed.png
index fe56d69..ec1b0ef 100644
--- a/ash/resources/default_100_percent/common/notification/notification_button_active_pressed.png
+++ b/ash/resources/default_100_percent/common/notification/notification_button_active_pressed.png
Binary files differ
diff --git a/ash/resources/default_100_percent/common/notification/notification_button_inactive_hover.png b/ash/resources/default_100_percent/common/notification/notification_button_inactive_hover.png
index 9070e91..99dd7ae 100644
--- a/ash/resources/default_100_percent/common/notification/notification_button_inactive_hover.png
+++ b/ash/resources/default_100_percent/common/notification/notification_button_inactive_hover.png
Binary files differ
diff --git a/ash/resources/default_100_percent/common/notification/notification_button_inactive_normal.png b/ash/resources/default_100_percent/common/notification/notification_button_inactive_normal.png
index a090264..b81c965 100644
--- a/ash/resources/default_100_percent/common/notification/notification_button_inactive_normal.png
+++ b/ash/resources/default_100_percent/common/notification/notification_button_inactive_normal.png
Binary files differ
diff --git a/ash/resources/default_100_percent/common/notification/notification_button_inactive_pressed.png b/ash/resources/default_100_percent/common/notification/notification_button_inactive_pressed.png
index 462b0c7..fe56d69 100644
--- a/ash/resources/default_100_percent/common/notification/notification_button_inactive_pressed.png
+++ b/ash/resources/default_100_percent/common/notification/notification_button_inactive_pressed.png
Binary files differ
diff --git a/ash/resources/default_100_percent/common/notification/notification_icon.png b/ash/resources/default_100_percent/common/notification/notification_icon.png
new file mode 100644
index 0000000..47084b9
--- /dev/null
+++ b/ash/resources/default_100_percent/common/notification/notification_icon.png
Binary files differ
diff --git a/ash/resources/default_100_percent/common/window_close_short_black_hover.png b/ash/resources/default_100_percent/common/window_close_short_black_hover.png
index cf9b8bf..414d999 100644
--- a/ash/resources/default_100_percent/common/window_close_short_black_hover.png
+++ b/ash/resources/default_100_percent/common/window_close_short_black_hover.png
Binary files differ
diff --git a/ash/resources/default_100_percent/common/window_close_short_black_normal.png b/ash/resources/default_100_percent/common/window_close_short_black_normal.png
index eb7a270..0735ffa 100644
--- a/ash/resources/default_100_percent/common/window_close_short_black_normal.png
+++ b/ash/resources/default_100_percent/common/window_close_short_black_normal.png
Binary files differ
diff --git a/ash/resources/default_100_percent/common/window_close_short_black_pressed.png b/ash/resources/default_100_percent/common/window_close_short_black_pressed.png
index 92bde89..c991375 100644
--- a/ash/resources/default_100_percent/common/window_close_short_black_pressed.png
+++ b/ash/resources/default_100_percent/common/window_close_short_black_pressed.png
Binary files differ
diff --git a/ash/resources/default_100_percent/common/window_immersive_enter_hover.png b/ash/resources/default_100_percent/common/window_immersive_enter_hover.png
index 8c9fedf..e9c8aef 100644
--- a/ash/resources/default_100_percent/common/window_immersive_enter_hover.png
+++ b/ash/resources/default_100_percent/common/window_immersive_enter_hover.png
Binary files differ
diff --git a/ash/resources/default_100_percent/common/window_immersive_enter_normal.png b/ash/resources/default_100_percent/common/window_immersive_enter_normal.png
index 944acf8..d6e1203 100644
--- a/ash/resources/default_100_percent/common/window_immersive_enter_normal.png
+++ b/ash/resources/default_100_percent/common/window_immersive_enter_normal.png
Binary files differ
diff --git a/ash/resources/default_100_percent/common/window_immersive_enter_pressed.png b/ash/resources/default_100_percent/common/window_immersive_enter_pressed.png
index b625faf..fc99c86 100644
--- a/ash/resources/default_100_percent/common/window_immersive_enter_pressed.png
+++ b/ash/resources/default_100_percent/common/window_immersive_enter_pressed.png
Binary files differ
diff --git a/ash/resources/default_100_percent/common/window_immersive_exit_hover.png b/ash/resources/default_100_percent/common/window_immersive_exit_hover.png
index 3875755..bc8f52b 100644
--- a/ash/resources/default_100_percent/common/window_immersive_exit_hover.png
+++ b/ash/resources/default_100_percent/common/window_immersive_exit_hover.png
Binary files differ
diff --git a/ash/resources/default_100_percent/common/window_immersive_exit_normal.png b/ash/resources/default_100_percent/common/window_immersive_exit_normal.png
index 0cfd7f2..b728735 100644
--- a/ash/resources/default_100_percent/common/window_immersive_exit_normal.png
+++ b/ash/resources/default_100_percent/common/window_immersive_exit_normal.png
Binary files differ
diff --git a/ash/resources/default_100_percent/common/window_immersive_exit_pressed.png b/ash/resources/default_100_percent/common/window_immersive_exit_pressed.png
index 83f4889..f115f8f 100644
--- a/ash/resources/default_100_percent/common/window_immersive_exit_pressed.png
+++ b/ash/resources/default_100_percent/common/window_immersive_exit_pressed.png
Binary files differ
diff --git a/ash/resources/default_100_percent/common/window_size_short_black_hover.png b/ash/resources/default_100_percent/common/window_size_short_black_hover.png
index f639bc4..e19e3c5 100644
--- a/ash/resources/default_100_percent/common/window_size_short_black_hover.png
+++ b/ash/resources/default_100_percent/common/window_size_short_black_hover.png
Binary files differ
diff --git a/ash/resources/default_100_percent/common/window_size_short_black_normal.png b/ash/resources/default_100_percent/common/window_size_short_black_normal.png
index 8181f95..4185ca4 100644
--- a/ash/resources/default_100_percent/common/window_size_short_black_normal.png
+++ b/ash/resources/default_100_percent/common/window_size_short_black_normal.png
Binary files differ
diff --git a/ash/resources/default_100_percent/common/window_size_short_black_pressed.png b/ash/resources/default_100_percent/common/window_size_short_black_pressed.png
index 7bd012d..1b953da 100644
--- a/ash/resources/default_100_percent/common/window_size_short_black_pressed.png
+++ b/ash/resources/default_100_percent/common/window_size_short_black_pressed.png
Binary files differ
diff --git a/ash/resources/default_100_percent/cros/status/status_audio_device_bluetooth.png b/ash/resources/default_100_percent/cros/status/status_audio_device_bluetooth.png
new file mode 100644
index 0000000..016dc38
--- /dev/null
+++ b/ash/resources/default_100_percent/cros/status/status_audio_device_bluetooth.png
Binary files differ
diff --git a/ash/resources/default_100_percent/cros/status/status_audio_device_hdmi.png b/ash/resources/default_100_percent/cros/status/status_audio_device_hdmi.png
new file mode 100644
index 0000000..328d942
--- /dev/null
+++ b/ash/resources/default_100_percent/cros/status/status_audio_device_hdmi.png
Binary files differ
diff --git a/ash/resources/default_100_percent/cros/status/status_audio_device_headphones.png b/ash/resources/default_100_percent/cros/status/status_audio_device_headphones.png
new file mode 100644
index 0000000..8ecce54
--- /dev/null
+++ b/ash/resources/default_100_percent/cros/status/status_audio_device_headphones.png
Binary files differ
diff --git a/ash/resources/default_100_percent/cros/status/status_audio_device_usb.png b/ash/resources/default_100_percent/cros/status/status_audio_device_usb.png
new file mode 100644
index 0000000..8e09852
--- /dev/null
+++ b/ash/resources/default_100_percent/cros/status/status_audio_device_usb.png
Binary files differ
diff --git a/ash/resources/default_100_percent/cros/status/status_power_small_all_dark_discharging.png b/ash/resources/default_100_percent/cros/status/status_power_small_all_dark_discharging.png
new file mode 100644
index 0000000..4088573
--- /dev/null
+++ b/ash/resources/default_100_percent/cros/status/status_power_small_all_dark_discharging.png
Binary files differ
diff --git a/ash/resources/default_100_percent/cros/status/status_power_small_all_dark_fluctuating.png b/ash/resources/default_100_percent/cros/status/status_power_small_all_dark_fluctuating.png
new file mode 100644
index 0000000..c822a4d
--- /dev/null
+++ b/ash/resources/default_100_percent/cros/status/status_power_small_all_dark_fluctuating.png
Binary files differ
diff --git a/ash/resources/default_100_percent/cros/status/status_power_small_all_discharging.png b/ash/resources/default_100_percent/cros/status/status_power_small_all_discharging.png
new file mode 100644
index 0000000..52f127d
--- /dev/null
+++ b/ash/resources/default_100_percent/cros/status/status_power_small_all_discharging.png
Binary files differ
diff --git a/ash/resources/default_100_percent/cros/status/status_power_small_all_fluctuating.png b/ash/resources/default_100_percent/cros/status/status_power_small_all_fluctuating.png
new file mode 100644
index 0000000..d535223
--- /dev/null
+++ b/ash/resources/default_100_percent/cros/status/status_power_small_all_fluctuating.png
Binary files differ
diff --git a/ash/resources/default_200_percent/common/launcher/launcher_underline_bottom_active.png b/ash/resources/default_200_percent/common/launcher/launcher_underline_bottom_active.png
new file mode 100644
index 0000000..2246c96
--- /dev/null
+++ b/ash/resources/default_200_percent/common/launcher/launcher_underline_bottom_active.png
Binary files differ
diff --git a/ash/resources/default_200_percent/common/launcher/launcher_underline_bottom_hover.png b/ash/resources/default_200_percent/common/launcher/launcher_underline_bottom_hover.png
new file mode 100644
index 0000000..4062f82
--- /dev/null
+++ b/ash/resources/default_200_percent/common/launcher/launcher_underline_bottom_hover.png
Binary files differ
diff --git a/ash/resources/default_200_percent/common/launcher/launcher_underline_bottom_running.png b/ash/resources/default_200_percent/common/launcher/launcher_underline_bottom_running.png
new file mode 100644
index 0000000..58d1343
--- /dev/null
+++ b/ash/resources/default_200_percent/common/launcher/launcher_underline_bottom_running.png
Binary files differ
diff --git a/ash/resources/default_200_percent/common/notification/notification_button_active_hover.png b/ash/resources/default_200_percent/common/notification/notification_button_active_hover.png
index aa5b511..c7d173d 100644
--- a/ash/resources/default_200_percent/common/notification/notification_button_active_hover.png
+++ b/ash/resources/default_200_percent/common/notification/notification_button_active_hover.png
Binary files differ
diff --git a/ash/resources/default_200_percent/common/notification/notification_button_active_normal.png b/ash/resources/default_200_percent/common/notification/notification_button_active_normal.png
index 75e80fd..c7d173d 100644
--- a/ash/resources/default_200_percent/common/notification/notification_button_active_normal.png
+++ b/ash/resources/default_200_percent/common/notification/notification_button_active_normal.png
Binary files differ
diff --git a/ash/resources/default_200_percent/common/notification/notification_button_active_pressed.png b/ash/resources/default_200_percent/common/notification/notification_button_active_pressed.png
index 41fdc1f..a5b1f3b 100644
--- a/ash/resources/default_200_percent/common/notification/notification_button_active_pressed.png
+++ b/ash/resources/default_200_percent/common/notification/notification_button_active_pressed.png
Binary files differ
diff --git a/ash/resources/default_200_percent/common/notification/notification_button_inactive_hover.png b/ash/resources/default_200_percent/common/notification/notification_button_inactive_hover.png
index 073667a..aa5b511 100644
--- a/ash/resources/default_200_percent/common/notification/notification_button_inactive_hover.png
+++ b/ash/resources/default_200_percent/common/notification/notification_button_inactive_hover.png
Binary files differ
diff --git a/ash/resources/default_200_percent/common/notification/notification_button_inactive_normal.png b/ash/resources/default_200_percent/common/notification/notification_button_inactive_normal.png
index d7cda64..75e80fd 100644
--- a/ash/resources/default_200_percent/common/notification/notification_button_inactive_normal.png
+++ b/ash/resources/default_200_percent/common/notification/notification_button_inactive_normal.png
Binary files differ
diff --git a/ash/resources/default_200_percent/common/notification/notification_button_inactive_pressed.png b/ash/resources/default_200_percent/common/notification/notification_button_inactive_pressed.png
index 06bf145..41fdc1f 100644
--- a/ash/resources/default_200_percent/common/notification/notification_button_inactive_pressed.png
+++ b/ash/resources/default_200_percent/common/notification/notification_button_inactive_pressed.png
Binary files differ
diff --git a/ash/resources/default_200_percent/common/notification/notification_icon.png b/ash/resources/default_200_percent/common/notification/notification_icon.png
new file mode 100644
index 0000000..468be3c
--- /dev/null
+++ b/ash/resources/default_200_percent/common/notification/notification_icon.png
Binary files differ
diff --git a/ash/resources/default_200_percent/common/window_close_short_black_hover.png b/ash/resources/default_200_percent/common/window_close_short_black_hover.png
index 6f0c586..f8cf312 100644
--- a/ash/resources/default_200_percent/common/window_close_short_black_hover.png
+++ b/ash/resources/default_200_percent/common/window_close_short_black_hover.png
Binary files differ
diff --git a/ash/resources/default_200_percent/common/window_close_short_black_normal.png b/ash/resources/default_200_percent/common/window_close_short_black_normal.png
index 797791c..09c2ca3 100644
--- a/ash/resources/default_200_percent/common/window_close_short_black_normal.png
+++ b/ash/resources/default_200_percent/common/window_close_short_black_normal.png
Binary files differ
diff --git a/ash/resources/default_200_percent/common/window_close_short_black_pressed.png b/ash/resources/default_200_percent/common/window_close_short_black_pressed.png
index 7198461..9becd7f 100644
--- a/ash/resources/default_200_percent/common/window_close_short_black_pressed.png
+++ b/ash/resources/default_200_percent/common/window_close_short_black_pressed.png
Binary files differ
diff --git a/ash/resources/default_200_percent/common/window_immersive_enter_hover.png b/ash/resources/default_200_percent/common/window_immersive_enter_hover.png
index 7ad432d..697cd5f 100644
--- a/ash/resources/default_200_percent/common/window_immersive_enter_hover.png
+++ b/ash/resources/default_200_percent/common/window_immersive_enter_hover.png
Binary files differ
diff --git a/ash/resources/default_200_percent/common/window_immersive_enter_normal.png b/ash/resources/default_200_percent/common/window_immersive_enter_normal.png
index 0c3cd15..e2e0ee2 100644
--- a/ash/resources/default_200_percent/common/window_immersive_enter_normal.png
+++ b/ash/resources/default_200_percent/common/window_immersive_enter_normal.png
Binary files differ
diff --git a/ash/resources/default_200_percent/common/window_immersive_enter_pressed.png b/ash/resources/default_200_percent/common/window_immersive_enter_pressed.png
index 2020e7f..0421788 100644
--- a/ash/resources/default_200_percent/common/window_immersive_enter_pressed.png
+++ b/ash/resources/default_200_percent/common/window_immersive_enter_pressed.png
Binary files differ
diff --git a/ash/resources/default_200_percent/common/window_immersive_exit_hover.png b/ash/resources/default_200_percent/common/window_immersive_exit_hover.png
index 2a84be3..d267969 100644
--- a/ash/resources/default_200_percent/common/window_immersive_exit_hover.png
+++ b/ash/resources/default_200_percent/common/window_immersive_exit_hover.png
Binary files differ
diff --git a/ash/resources/default_200_percent/common/window_immersive_exit_normal.png b/ash/resources/default_200_percent/common/window_immersive_exit_normal.png
index 88a83fd..d972dda 100644
--- a/ash/resources/default_200_percent/common/window_immersive_exit_normal.png
+++ b/ash/resources/default_200_percent/common/window_immersive_exit_normal.png
Binary files differ
diff --git a/ash/resources/default_200_percent/common/window_immersive_exit_pressed.png b/ash/resources/default_200_percent/common/window_immersive_exit_pressed.png
index 64e1653..199b91d 100644
--- a/ash/resources/default_200_percent/common/window_immersive_exit_pressed.png
+++ b/ash/resources/default_200_percent/common/window_immersive_exit_pressed.png
Binary files differ
diff --git a/ash/resources/default_200_percent/common/window_size_short_black_hover.png b/ash/resources/default_200_percent/common/window_size_short_black_hover.png
index 929efff..b90f705 100644
--- a/ash/resources/default_200_percent/common/window_size_short_black_hover.png
+++ b/ash/resources/default_200_percent/common/window_size_short_black_hover.png
Binary files differ
diff --git a/ash/resources/default_200_percent/common/window_size_short_black_normal.png b/ash/resources/default_200_percent/common/window_size_short_black_normal.png
index 5da0f82..918b8e2 100644
--- a/ash/resources/default_200_percent/common/window_size_short_black_normal.png
+++ b/ash/resources/default_200_percent/common/window_size_short_black_normal.png
Binary files differ
diff --git a/ash/resources/default_200_percent/common/window_size_short_black_pressed.png b/ash/resources/default_200_percent/common/window_size_short_black_pressed.png
index 481fc28..5a11ae4 100644
--- a/ash/resources/default_200_percent/common/window_size_short_black_pressed.png
+++ b/ash/resources/default_200_percent/common/window_size_short_black_pressed.png
Binary files differ
diff --git a/ash/resources/default_200_percent/cros/status/status_audio_device_bluetooth.png b/ash/resources/default_200_percent/cros/status/status_audio_device_bluetooth.png
new file mode 100644
index 0000000..f534a7d
--- /dev/null
+++ b/ash/resources/default_200_percent/cros/status/status_audio_device_bluetooth.png
Binary files differ
diff --git a/ash/resources/default_200_percent/cros/status/status_audio_device_hdmi.png b/ash/resources/default_200_percent/cros/status/status_audio_device_hdmi.png
new file mode 100644
index 0000000..58befa7
--- /dev/null
+++ b/ash/resources/default_200_percent/cros/status/status_audio_device_hdmi.png
Binary files differ
diff --git a/ash/resources/default_200_percent/cros/status/status_audio_device_headphones.png b/ash/resources/default_200_percent/cros/status/status_audio_device_headphones.png
new file mode 100644
index 0000000..8adf4aa
--- /dev/null
+++ b/ash/resources/default_200_percent/cros/status/status_audio_device_headphones.png
Binary files differ
diff --git a/ash/resources/default_200_percent/cros/status/status_audio_device_usb.png b/ash/resources/default_200_percent/cros/status/status_audio_device_usb.png
new file mode 100644
index 0000000..6193200
--- /dev/null
+++ b/ash/resources/default_200_percent/cros/status/status_audio_device_usb.png
Binary files differ
diff --git a/ash/resources/default_200_percent/cros/status/status_power_small_all_dark_discharging.png b/ash/resources/default_200_percent/cros/status/status_power_small_all_dark_discharging.png
new file mode 100644
index 0000000..d31c677
--- /dev/null
+++ b/ash/resources/default_200_percent/cros/status/status_power_small_all_dark_discharging.png
Binary files differ
diff --git a/ash/resources/default_200_percent/cros/status/status_power_small_all_dark_fluctuating.png b/ash/resources/default_200_percent/cros/status/status_power_small_all_dark_fluctuating.png
new file mode 100644
index 0000000..e7f5a4e
--- /dev/null
+++ b/ash/resources/default_200_percent/cros/status/status_power_small_all_dark_fluctuating.png
Binary files differ
diff --git a/ash/resources/default_200_percent/cros/status/status_power_small_all_discharging.png b/ash/resources/default_200_percent/cros/status/status_power_small_all_discharging.png
new file mode 100644
index 0000000..b1f8725
--- /dev/null
+++ b/ash/resources/default_200_percent/cros/status/status_power_small_all_discharging.png
Binary files differ
diff --git a/ash/resources/default_200_percent/cros/status/status_power_small_all_fluctuating.png b/ash/resources/default_200_percent/cros/status/status_power_small_all_fluctuating.png
new file mode 100644
index 0000000..555c229
--- /dev/null
+++ b/ash/resources/default_200_percent/cros/status/status_power_small_all_fluctuating.png
Binary files differ
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc
index f216c7a..81117d9 100644
--- a/ash/root_window_controller.cc
+++ b/ash/root_window_controller.cc
@@ -12,6 +12,7 @@
 #include "ash/display/display_controller.h"
 #include "ash/display/display_manager.h"
 #include "ash/focus_cycler.h"
+#include "ash/session_state_delegate.h"
 #include "ash/shelf/shelf_layout_manager.h"
 #include "ash/shelf/shelf_types.h"
 #include "ash/shelf/shelf_widget.h"
@@ -21,6 +22,7 @@
 #include "ash/shell_window_ids.h"
 #include "ash/system/status_area_widget.h"
 #include "ash/system/tray/system_tray_delegate.h"
+#include "ash/touch/touch_observer_hud.h"
 #include "ash/wm/base_layout_manager.h"
 #include "ash/wm/boot_splash_screen.h"
 #include "ash/wm/panels/panel_layout_manager.h"
@@ -33,22 +35,20 @@
 #include "ash/wm/system_modal_container_layout_manager.h"
 #include "ash/wm/toplevel_window_event_handler.h"
 #include "ash/wm/window_properties.h"
+#include "ash/wm/window_util.h"
 #include "ash/wm/workspace_controller.h"
 #include "base/command_line.h"
 #include "base/time.h"
-#include "ui/aura/client/activation_client.h"
 #include "ui/aura/client/aura_constants.h"
-#include "ui/aura/client/capture_client.h"
-#include "ui/aura/client/focus_client.h"
 #include "ui/aura/client/tooltip_client.h"
 #include "ui/aura/root_window.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_observer.h"
-#include "ui/aura/window_tracker.h"
 #include "ui/base/models/menu_model.h"
 #include "ui/gfx/display.h"
 #include "ui/gfx/screen.h"
-#include "ui/views/controls/menu/menu_model_adapter.h"
+#include "ui/keyboard/keyboard_controller.h"
+#include "ui/keyboard/keyboard_util.h"
 #include "ui/views/controls/menu/menu_runner.h"
 #include "ui/views/corewm/visibility_controller.h"
 #include "ui/views/view_model.h"
@@ -167,7 +167,8 @@
     : root_window_(root_window),
       root_window_layout_(NULL),
       shelf_(NULL),
-      panel_layout_manager_(NULL) {
+      panel_layout_manager_(NULL),
+      touch_observer_hud_(NULL) {
   SetRootWindowController(root_window, this);
   screen_dimmer_.reset(new ScreenDimmer(root_window));
 
@@ -201,7 +202,7 @@
 
 void RootWindowController::Shutdown() {
   CloseChildWindows();
-  if (Shell::GetActiveRootWindow() == root_window_.get()) {
+  if (Shell::GetActiveRootWindow() == root_window_) {
     Shell::GetInstance()->set_active_root_window(
         Shell::GetPrimaryRootWindow() == root_window_.get() ?
         NULL : Shell::GetPrimaryRootWindow());
@@ -285,12 +286,20 @@
         new ToplevelWindowEventHandler(panel_container));
     panel_container->SetLayoutManager(panel_layout_manager_);
   }
-  if (Shell::GetInstance()->delegate()->IsUserLoggedIn())
+  if (Shell::GetInstance()->session_state_delegate()->HasActiveUser())
     shelf_->CreateLauncher();
+
+  InitKeyboard();
 }
 
 void RootWindowController::CreateContainers() {
   CreateContainersInRootWindow(root_window_.get());
+
+  // Create touch observer HUD if needed. HUD should be created after the
+  // containers have been created, so that its widget can be added to them.
+  CommandLine* command_line = CommandLine::ForCurrentProcess();
+  if (command_line->HasSwitch(switches::kAshTouchHud))
+    touch_observer_hud_ = new TouchObserverHUD(root_window_.get());
 }
 
 void RootWindowController::CreateSystemBackground(
@@ -330,7 +339,7 @@
 void RootWindowController::OnLoginStateChanged(user::LoginStatus status) {
   // TODO(oshima): remove if when launcher per display is enabled by
   // default.
-  if (shelf_.get())
+  if (shelf_)
     shelf_->shelf_layout_manager()->UpdateVisibilityState();
 }
 
@@ -364,7 +373,7 @@
   }
 
   // TODO(harrym): Remove when Status Area Widget is a child view.
-  if (shelf_.get())
+  if (shelf_)
     shelf_->ShutdownStatusAreaWidget();
 
   if (shelf_.get() && shelf_->shelf_layout_manager())
@@ -388,38 +397,10 @@
 }
 
 void RootWindowController::MoveWindowsTo(aura::RootWindow* dst) {
-  aura::Window* focused = aura::client::GetFocusClient(dst)->GetFocusedWindow();
-  aura::WindowTracker tracker;
-  if (focused)
-    tracker.Add(focused);
-  aura::client::ActivationClient* activation_client =
-      aura::client::GetActivationClient(dst);
-  aura::Window* active = activation_client->GetActiveWindow();
-  if (active && focused != active)
-    tracker.Add(active);
-  // Deactivate the window to close menu / bubble windows.
-  activation_client->DeactivateWindow(active);
-  // Release capture if any.
-  aura::client::GetCaptureClient(root_window_.get())->
-      SetCapture(NULL);
-  // Clear the focused window if any. This is necessary because a
-  // window may be deleted when losing focus (fullscreen flash for
-  // example).  If the focused window is still alive after move, it'll
-  // be re-focused below.
-  aura::client::GetFocusClient(dst)->FocusWindow(NULL);
-
   // Forget the shelf early so that shelf don't update itself using wrong
   // display info.
   workspace_controller_->SetShelf(NULL);
-
   ReparentAllWindows(root_window_.get(), dst);
-
-  // Restore focused or active window if it's still alive.
-  if (focused && tracker.Contains(focused) && dst->Contains(focused)) {
-    aura::client::GetFocusClient(dst)->FocusWindow(focused);
-  } else if (active && tracker.Contains(active) && dst->Contains(active)) {
-    activation_client->ActivateWindow(active);
-  }
 }
 
 ShelfLayoutManager* RootWindowController::GetShelfLayoutManager() {
@@ -440,19 +421,23 @@
   DCHECK(Shell::GetInstance()->delegate());
   scoped_ptr<ui::MenuModel> menu_model(
       Shell::GetInstance()->delegate()->CreateContextMenu(target));
-  if (!menu_model.get())
+  if (!menu_model)
     return;
 
-  views::MenuModelAdapter menu_model_adapter(menu_model.get());
-  views::MenuRunner menu_runner(menu_model_adapter.CreateMenu());
-  views::Widget* widget =
-      root_window_->GetProperty(kDesktopController)->widget();
+  internal::DesktopBackgroundWidgetController* background =
+      root_window_->GetProperty(kDesktopController);
+  // Background controller may not be set yet if user clicked on status are
+  // before initial animation completion. See crbug.com/222218
+  if (!background)
+    return;
 
-  if (menu_runner.RunMenuAt(
-          widget, NULL, gfx::Rect(location_in_screen, gfx::Size()),
+  views::MenuRunner menu_runner(menu_model.get());
+  if (menu_runner.RunMenuAt(background->widget(),
+          NULL, gfx::Rect(location_in_screen, gfx::Size()),
           views::MenuItemView::TOPLEFT, views::MenuRunner::CONTEXT_MENU) ==
-      views::MenuRunner::MENU_DELETED)
+      views::MenuRunner::MENU_DELETED) {
     return;
+  }
 
   Shell::GetInstance()->UpdateShelfVisibility();
 }
@@ -461,16 +446,36 @@
   shelf_->shelf_layout_manager()->UpdateVisibilityState();
 }
 
-bool RootWindowController::IsImmersiveMode() const {
+aura::Window* RootWindowController::GetFullscreenWindow() const {
   aura::Window* container = workspace_controller_->GetActiveWorkspaceWindow();
   for (size_t i = 0; i < container->children().size(); ++i) {
     aura::Window* child = container->children()[i];
-    if (child->IsVisible() && child->GetProperty(kImmersiveModeKey))
-      return true;
+    if (ash::wm::IsWindowFullscreen(child))
+      return child;
   }
-  return false;
+  return NULL;
 }
 
+void RootWindowController::InitKeyboard() {
+  if (keyboard::IsKeyboardEnabled()) {
+    aura::Window* parent = root_window();
+
+    keyboard::KeyboardControllerProxy* proxy =
+        Shell::GetInstance()->delegate()->CreateKeyboardControllerProxy();
+    keyboard_controller_.reset(
+        new keyboard::KeyboardController(proxy));
+
+    keyboard_controller_->AddObserver(shelf()->shelf_layout_manager());
+    keyboard_controller_->AddObserver(panel_layout_manager_);
+
+    aura::Window* keyboard_container =
+        keyboard_controller_->GetContainerWindow();
+    parent->AddChild(keyboard_container);
+    keyboard_container->SetBounds(parent->bounds());
+  }
+}
+
+
 ////////////////////////////////////////////////////////////////////////////////
 // RootWindowController, private:
 
diff --git a/ash/root_window_controller.h b/ash/root_window_controller.h
index d10c6b1..f8855a7 100644
--- a/ash/root_window_controller.h
+++ b/ash/root_window_controller.h
@@ -30,6 +30,10 @@
 }
 }
 
+namespace keyboard {
+class KeyboardController;
+}
+
 namespace ash {
 class StackingController;
 class ShelfWidget;
@@ -46,6 +50,7 @@
 class StatusAreaWidget;
 class SystemBackgroundController;
 class SystemModalContainerLayoutManager;
+class TouchObserverHUD;
 class WorkspaceController;
 
 // This class maintains the per root window state for ash. This class
@@ -84,6 +89,13 @@
   // NULL if no such shelf exists.
   ShelfWidget* shelf() { return shelf_.get(); }
 
+  TouchObserverHUD* touch_observer_hud() { return touch_observer_hud_; }
+
+  // Sets the touch HUD. The RootWindowController will not own this HUD; its
+  // lifetime is managed by itself.
+  void set_touch_observer_hud(TouchObserverHUD* hud) {
+    touch_observer_hud_ = hud;
+  }
   // Access the shelf layout manager associated with this root
   // window controller, NULL if no such shelf exists.
   ShelfLayoutManager* GetShelfLayoutManager();
@@ -157,20 +169,26 @@
   // Force the shelf to query for it's current visibility state.
   void UpdateShelfVisibility();
 
-  // Returns true if the active workspace is in immersive mode. Exposed here
-  // so clients of Ash don't need to know the details of workspace management.
-  bool IsImmersiveMode() const;
+  // Returns the window, if any, which is in fullscreen mode in the active
+  // workspace. Exposed here so clients of Ash don't need to know the details
+  // of workspace management.
+  aura::Window* GetFullscreenWindow() const;
 
  private:
   // Creates each of the special window containers that holds windows of various
   // types in the shell UI.
   void CreateContainersInRootWindow(aura::RootWindow* root_window);
 
+  // Initializes the virtual keyboard.
+  void InitKeyboard();
+
   scoped_ptr<aura::RootWindow> root_window_;
   RootWindowLayoutManager* root_window_layout_;
 
   scoped_ptr<StackingController> stacking_controller_;
 
+  scoped_ptr<keyboard::KeyboardController> keyboard_controller_;
+
   // The shelf for managing the launcher and the status widget.
   scoped_ptr<ShelfWidget> shelf_;
 
@@ -183,6 +201,10 @@
   scoped_ptr<ScreenDimmer> screen_dimmer_;
   scoped_ptr<WorkspaceController> workspace_controller_;
 
+  // Heads-up display for touch events. The RootWindowController does not own
+  // this HUD; its lifetime is managed by itself.
+  TouchObserverHUD* touch_observer_hud_;
+
   // We need to own event handlers for various containers.
   scoped_ptr<ToplevelWindowEventHandler> default_container_handler_;
   scoped_ptr<ToplevelWindowEventHandler> always_on_top_container_handler_;
diff --git a/ash/root_window_controller_unittest.cc b/ash/root_window_controller_unittest.cc
index 55f0763..55b3ed2 100644
--- a/ash/root_window_controller_unittest.cc
+++ b/ash/root_window_controller_unittest.cc
@@ -5,9 +5,9 @@
 #include "ash/root_window_controller.h"
 
 #include "ash/display/display_controller.h"
+#include "ash/session_state_delegate.h"
 #include "ash/shelf/shelf_layout_manager.h"
 #include "ash/shell.h"
-#include "ash/shell_delegate.h"
 #include "ash/shell_window_ids.h"
 #include "ash/system/tray/system_tray_delegate.h"
 #include "ash/test/ash_test_base.h"
@@ -301,7 +301,7 @@
           controller->GetSystemModalLayoutManager(
               session_modal_widget->GetNativeView()));
 
-  shell->delegate()->LockScreen();
+  shell->session_state_delegate()->LockScreen();
   EXPECT_EQ(user::LOGGED_IN_LOCKED,
             shell->system_tray_delegate()->GetUserLoginStatus());
   EXPECT_EQ(Shell::GetContainer(controller->root_window(),
@@ -322,7 +322,7 @@
             controller->GetSystemModalLayoutManager(
                 session_modal_widget->GetNativeView()));
 
-  shell->delegate()->UnlockScreen();
+  shell->session_state_delegate()->UnlockScreen();
 }
 
 TEST_F(RootWindowControllerTest, ModalContainerNotLoggedInLoggedIn) {
@@ -333,8 +333,8 @@
   SetUserLoggedIn(false);
   EXPECT_EQ(user::LOGGED_IN_NONE,
             shell->system_tray_delegate()->GetUserLoginStatus());
-  EXPECT_FALSE(shell->delegate()->IsUserLoggedIn());
-  EXPECT_FALSE(shell->delegate()->IsSessionStarted());
+  EXPECT_FALSE(shell->session_state_delegate()->HasActiveUser());
+  EXPECT_FALSE(shell->session_state_delegate()->IsActiveUserSessionStarted());
 
   internal::RootWindowController* controller =
       shell->GetPrimaryRootWindowController();
@@ -358,8 +358,8 @@
   SetSessionStarted(true);
   EXPECT_EQ(user::LOGGED_IN_USER,
             shell->system_tray_delegate()->GetUserLoginStatus());
-  EXPECT_TRUE(shell->delegate()->IsUserLoggedIn());
-  EXPECT_TRUE(shell->delegate()->IsSessionStarted());
+  EXPECT_TRUE(shell->session_state_delegate()->HasActiveUser());
+  EXPECT_TRUE(shell->session_state_delegate()->IsActiveUserSessionStarted());
   EXPECT_EQ(Shell::GetContainer(controller->root_window(),
       internal::kShellWindowId_SystemModalContainer)->layout_manager(),
           controller->GetSystemModalLayoutManager(NULL));
@@ -372,31 +372,34 @@
               session_modal_widget->GetNativeView()));
 }
 
-// Ensure a workspace with two windows reports immersive mode even if only
-// one has the property set.
-TEST_F(RootWindowControllerTest, ImmersiveMode) {
+// Test that GetFullscreenWindow() returns a fullscreen window only if the
+// fullscreen window is in the active workspace.
+TEST_F(RootWindowControllerTest, GetFullscreenWindow) {
   UpdateDisplay("600x600");
   internal::RootWindowController* controller =
       Shell::GetInstance()->GetPrimaryRootWindowController();
 
-  // Open a maximized window.
-  Widget* w1 = CreateTestWidget(gfx::Rect(0, 1, 250, 251));
+  Widget* w1 = CreateTestWidget(gfx::Rect(0, 0, 100, 100));
   w1->Maximize();
+  Widget* w2 = CreateTestWidget(gfx::Rect(0, 0, 100, 100));
+  w2->SetFullscreen(true);
+  // |w3| is a transient child of |w2|.
+  Widget* w3 = Widget::CreateWindowWithParentAndBounds(NULL,
+      w2->GetNativeWindow(), gfx::Rect(0, 0, 100, 100));
 
-  // Immersive mode off by default.
-  EXPECT_FALSE(controller->IsImmersiveMode());
+  // Test that GetFullscreenWindow() finds the fullscreen window when one of
+  // its transient children is active.
+  w3->Activate();
+  EXPECT_EQ(w2->GetNativeWindow(), controller->GetFullscreenWindow());
 
-  // Enter immersive mode.
-  w1->GetNativeWindow()->SetProperty(ash::internal::kImmersiveModeKey, true);
-  EXPECT_TRUE(controller->IsImmersiveMode());
+  // Activate the maximized window's workspace. GetFullscreenWindow() should
+  // fail because the fullscreen window's workspace is no longer active.
+  w1->Activate();
+  EXPECT_FALSE(controller->GetFullscreenWindow());
 
-  // Add a child, like a print window.  Still in immersive mode.
-  Widget* w2 =
-      Widget::CreateWindowWithParentAndBounds(NULL,
-                                              w1->GetNativeWindow(),
-                                              gfx::Rect(0, 1, 150, 151));
-  w2->Show();
-  EXPECT_TRUE(controller->IsImmersiveMode());
+  // If the fullscreen window is active, GetFullscreenWindow() should find it.
+  w2->Activate();
+  EXPECT_EQ(w2->GetNativeWindow(), controller->GetFullscreenWindow());
 }
 
 }  // namespace test
diff --git a/ash/screen_ash.cc b/ash/screen_ash.cc
index aabd5b6..6155d54 100644
--- a/ash/screen_ash.cc
+++ b/ash/screen_ash.cc
@@ -40,7 +40,7 @@
 
 // static
 gfx::Rect ScreenAsh::GetMaximizedWindowBoundsInParent(aura::Window* window) {
-  if (GetRootWindowController(window->GetRootWindow())->shelf()->launcher())
+  if (GetRootWindowController(window->GetRootWindow())->shelf())
     return GetDisplayWorkAreaBoundsInParent(window);
   else
     return GetDisplayBoundsInParent(window);
diff --git a/ash/screen_ash_unittest.cc b/ash/screen_ash_unittest.cc
index b00eb54..7ef789b 100644
--- a/ash/screen_ash_unittest.cc
+++ b/ash/screen_ash_unittest.cc
@@ -71,6 +71,22 @@
   }
 }
 
+// Test verifies a stable handling of secondary screen widget changes
+// (crbug.com/226132).
+TEST_F(ScreenAshTest, StabilityTest) {
+  UpdateDisplay("600x600,500x500");
+  views::Widget* secondary = views::Widget::CreateWindowWithContextAndBounds(
+      NULL, CurrentContext(), gfx::Rect(610, 10, 100, 100));
+  EXPECT_EQ(Shell::GetAllRootWindows()[1],
+      secondary->GetNativeView()->GetRootWindow());
+  secondary->Show();
+  secondary->Maximize();
+  secondary->Show();
+  secondary->SetFullscreen(true);
+  secondary->Hide();
+  secondary->Close();
+}
+
 TEST_F(ScreenAshTest, ConvertRect) {
   UpdateDisplay("600x600,500x500");
 
diff --git a/ash/session_state_delegate.h b/ash/session_state_delegate.h
new file mode 100644
index 0000000..f5ee359
--- /dev/null
+++ b/ash/session_state_delegate.h
@@ -0,0 +1,41 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_SESSION_STATE_DELEGATE_H_
+#define ASH_SESSION_STATE_DELEGATE_H_
+
+#include "ash/ash_export.h"
+
+namespace ash {
+
+// Delegate for checking and modifying the session state.
+class ASH_EXPORT SessionStateDelegate {
+ public:
+  virtual ~SessionStateDelegate() {};
+
+  // Returns |true| if a session is in progress and there is an active user.
+  virtual bool HasActiveUser() const = 0;
+
+  // Returns |true| if the session has been fully started for the active user.
+  // When a user becomes active, the profile and browser UI are not immediately
+  // available. Only once this method starts returning |true| is the browser
+  // startup complete and both profile and UI are fully available.
+  virtual bool IsActiveUserSessionStarted() const = 0;
+
+  // Returns true if the screen can be locked.
+  virtual bool CanLockScreen() const = 0;
+
+  // Returns true if the screen is currently locked.
+  virtual bool IsScreenLocked() const = 0;
+
+  // Locks the screen. The locking happens asynchronously.
+  virtual void LockScreen() = 0;
+
+  // Unlocks the screen.
+  virtual void UnlockScreen() = 0;
+};
+
+}  // namespace ash
+
+#endif  // ASH_SESSION_STATE_DELEGATE_H_
diff --git a/ash/session_state_delegate_stub.cc b/ash/session_state_delegate_stub.cc
new file mode 100644
index 0000000..b913b5f
--- /dev/null
+++ b/ash/session_state_delegate_stub.cc
@@ -0,0 +1,45 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/session_state_delegate_stub.h"
+
+#include "ash/shell.h"
+#include "ash/shell/example_factory.h"
+
+namespace ash {
+
+SessionStateDelegateStub::SessionStateDelegateStub() : screen_locked_(false) {
+}
+
+SessionStateDelegateStub::~SessionStateDelegateStub() {
+}
+
+bool SessionStateDelegateStub::HasActiveUser() const {
+  return true;
+}
+
+bool SessionStateDelegateStub::IsActiveUserSessionStarted() const {
+  return true;
+}
+
+bool SessionStateDelegateStub::CanLockScreen() const {
+  return true;
+}
+
+bool SessionStateDelegateStub::IsScreenLocked() const {
+  return screen_locked_;
+}
+
+void SessionStateDelegateStub::LockScreen() {
+  shell::CreateLockScreen();
+  screen_locked_ = true;
+  Shell::GetInstance()->UpdateShelfVisibility();
+}
+
+void SessionStateDelegateStub::UnlockScreen() {
+  screen_locked_ = false;
+  Shell::GetInstance()->UpdateShelfVisibility();
+}
+
+}  // namespace ash
diff --git a/ash/session_state_delegate_stub.h b/ash/session_state_delegate_stub.h
new file mode 100644
index 0000000..db9b711
--- /dev/null
+++ b/ash/session_state_delegate_stub.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_SESSION_STATE_DELEGATE_STUB_H_
+#define ASH_SESSION_STATE_DELEGATE_STUB_H_
+
+#include "ash/session_state_delegate.h"
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+
+namespace ash {
+
+// Stub implementation of SessionStateDelegate for testing.
+class SessionStateDelegateStub : public SessionStateDelegate {
+ public:
+  SessionStateDelegateStub();
+  virtual ~SessionStateDelegateStub();
+
+  // SessionStateDelegate:
+  virtual bool HasActiveUser() const OVERRIDE;
+  virtual bool IsActiveUserSessionStarted() const OVERRIDE;
+  virtual bool CanLockScreen() const OVERRIDE;
+  virtual bool IsScreenLocked() const OVERRIDE;
+  virtual void LockScreen() OVERRIDE;
+  virtual void UnlockScreen() OVERRIDE;
+
+ private:
+  bool screen_locked_;
+
+  DISALLOW_COPY_AND_ASSIGN(SessionStateDelegateStub);
+};
+
+}  // namespace ash
+
+#endif  // ASH_SESSION_STATE_DELEGATE_STUB_H_
diff --git a/ash/shelf/background_animator.cc b/ash/shelf/background_animator.cc
index 7b968c8..dedae6f 100644
--- a/ash/shelf/background_animator.cc
+++ b/ash/shelf/background_animator.cc
@@ -21,7 +21,7 @@
     : delegate_(delegate),
       min_alpha_(min_alpha),
       max_alpha_(max_alpha),
-      ALLOW_THIS_IN_INITIALIZER_LIST(animation_(this)),
+      animation_(this),
       paints_background_(false),
       alpha_(min_alpha) {
   animation_.SetSlideDuration(kBackgroundDurationMS);
@@ -30,6 +30,10 @@
 BackgroundAnimator::~BackgroundAnimator() {
 }
 
+void BackgroundAnimator::SetDuration(int time_in_ms) {
+  animation_.SetSlideDuration(time_in_ms);
+}
+
 void BackgroundAnimator::SetPaintsBackground(bool value, ChangeType type) {
   if (paints_background_ == value)
     return;
diff --git a/ash/shelf/background_animator.h b/ash/shelf/background_animator.h
index 7e87fd7..dbe495a 100644
--- a/ash/shelf/background_animator.h
+++ b/ash/shelf/background_animator.h
@@ -36,6 +36,9 @@
                      int max_alpha);
   virtual ~BackgroundAnimator();
 
+  // Sets the transition time in ms.
+  void SetDuration(int time_in_ms);
+
   // Sets whether a background is rendered. Initial value is false. If |type|
   // is |CHANGE_IMMEDIATE| and an animation is not in progress this notifies
   // the delegate immediately (synchronously from this method).
diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc
index 1a11cb6..4cb6af1 100644
--- a/ash/shelf/shelf_layout_manager.cc
+++ b/ash/shelf/shelf_layout_manager.cc
@@ -12,13 +12,15 @@
 #include "ash/launcher/launcher_types.h"
 #include "ash/root_window_controller.h"
 #include "ash/screen_ash.h"
+#include "ash/session_state_delegate.h"
 #include "ash/shelf/shelf_widget.h"
 #include "ash/shell.h"
-#include "ash/shell_delegate.h"
 #include "ash/shell_window_ids.h"
 #include "ash/system/status_area_widget.h"
+#include "ash/wm/gestures/shelf_gesture_handler.h"
 #include "ash/wm/property_util.h"
 #include "ash/wm/window_cycle_controller.h"
+#include "ash/wm/window_properties.h"
 #include "ash/wm/window_util.h"
 #include "ash/wm/workspace_controller.h"
 #include "ash/wm/workspace/workspace_animations.h"
@@ -62,7 +64,10 @@
 }  // namespace
 
 // static
-const int ShelfLayoutManager::kWorkspaceAreaBottomInset = 2;
+const int ShelfLayoutManager::kWorkspaceAreaVisibleInset = 2;
+
+// static
+const int ShelfLayoutManager::kWorkspaceAreaAutoHideInset = 5;
 
 // static
 const int ShelfLayoutManager::kAutoHideSize = 3;
@@ -80,10 +85,12 @@
 
   // Overridden from ui::EventHandler:
   virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE;
+  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
 
  private:
   ShelfLayoutManager* shelf_;
   bool in_mouse_drag_;
+  ShelfGestureHandler gesture_handler_;
 
   DISALLOW_COPY_AND_ASSIGN(AutoHideEventFilter);
 };
@@ -112,6 +119,12 @@
   return;
 }
 
+void ShelfLayoutManager::AutoHideEventFilter::OnGestureEvent(
+    ui::GestureEvent* event) {
+  if (gesture_handler_.ProcessGestureEvent(*event))
+    event->StopPropagation();
+}
+
 // ShelfLayoutManager:UpdateShelfObserver --------------------------------------
 
 // UpdateShelfObserver is used to delay updating the background until the
@@ -180,6 +193,8 @@
   UpdateVisibilityState();
   FOR_EACH_OBSERVER(Observer, observers_,
                     OnAutoHideStateChanged(state_.auto_hide_state));
+  FOR_EACH_OBSERVER(Observer, observers_,
+                    OnAutoHideBehaviorChanged(auto_hide_behavior_));
 }
 
 bool ShelfLayoutManager::IsVisible() const {
@@ -202,8 +217,6 @@
 }
 
 gfx::Rect ShelfLayoutManager::GetIdealBounds() {
-  // TODO(oshima): this is wrong. Figure out what display shelf is on
-  // and everything should be based on it.
   gfx::Rect bounds(
       ScreenAsh::GetDisplayBoundsInParent(shelf_->GetNativeView()));
   int width = 0, height = 0;
@@ -221,7 +234,7 @@
   TargetBounds target_bounds;
   CalculateTargetBounds(state_, &target_bounds);
   GetLayer(shelf_)->SetOpacity(target_bounds.opacity);
-  shelf_->SetBounds(
+  shelf_->SetWidgetBounds(
       ScreenAsh::ConvertRectToScreen(
           shelf_->GetNativeView()->parent(),
           target_bounds.shelf_bounds_in_root));
@@ -270,25 +283,27 @@
 }
 
 void ShelfLayoutManager::UpdateVisibilityState() {
-  ShellDelegate* delegate = Shell::GetInstance()->delegate();
-  if (delegate && delegate->IsScreenLocked()) {
+  if (Shell::GetInstance()->session_state_delegate()->IsScreenLocked()) {
     SetState(SHELF_VISIBLE);
   } else if (gesture_drag_status_ == GESTURE_DRAG_COMPLETE_IN_PROGRESS) {
     // TODO(zelidrag): Verify shelf drag animation still shows on the device
     // when we are in SHELF_AUTO_HIDE_ALWAYS_HIDDEN.
     SetState(CalculateShelfVisibilityWhileDragging());
-  } else if (GetRootWindowController(root_window_)->IsImmersiveMode()) {
-    // The user choosing immersive mode indicates he or she wants to maximize
-    // screen real-estate for content, so always auto-hide the shelf.
-    DCHECK_NE(auto_hide_behavior_, SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
-    SetState(SHELF_AUTO_HIDE);
   } else {
     WorkspaceWindowState window_state(workspace_controller_->GetWindowState());
     switch (window_state) {
       case WORKSPACE_WINDOW_STATE_FULL_SCREEN:
-        SetState(SHELF_HIDDEN);
+      {
+        aura::Window* fullscreen_window =
+            GetRootWindowController(root_window_)->GetFullscreenWindow();
+        if (fullscreen_window->GetProperty(kFullscreenUsesMinimalChromeKey)) {
+          DCHECK_NE(auto_hide_behavior_, SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
+          SetState(SHELF_AUTO_HIDE);
+        } else {
+          SetState(SHELF_HIDDEN);
+        }
         break;
-
+      }
       case WORKSPACE_WINDOW_STATE_MAXIMIZED:
         SetState(CalculateShelfVisibility());
         break;
@@ -441,6 +456,7 @@
     UpdateVisibilityState();
     gesture_drag_status_ = GESTURE_DRAG_NONE;
   }
+  LayoutShelf();
 }
 
 void ShelfLayoutManager::CancelGestureDrag() {
@@ -512,11 +528,14 @@
 ShelfLayoutManager::TargetBounds::~TargetBounds() {}
 
 void ShelfLayoutManager::SetState(ShelfVisibilityState visibility_state) {
-  ShellDelegate* delegate = Shell::GetInstance()->delegate();
+  if (!shelf_->GetNativeView())
+    return;
+
   State state;
   state.visibility_state = visibility_state;
   state.auto_hide_state = CalculateAutoHideState(visibility_state);
-  state.is_screen_locked = delegate && delegate->IsScreenLocked();
+  state.is_screen_locked =
+      Shell::GetInstance()->session_state_delegate()->IsScreenLocked();
 
   // It's possible for SetState() when a window becomes maximized but the state
   // won't have changed value. Do the dimming check before the early exit.
@@ -536,7 +555,7 @@
   if (state.visibility_state == SHELF_AUTO_HIDE) {
     // When state is SHELF_AUTO_HIDE we need to track when the mouse is over the
     // launcher to unhide the shelf. AutoHideEventFilter does that for us.
-    if (!event_filter_.get())
+    if (!event_filter_)
       event_filter_.reset(new AutoHideEventFilter(this));
   } else {
     event_filter_.reset(NULL);
@@ -637,7 +656,7 @@
 void ShelfLayoutManager::CalculateTargetBounds(
     const State& state,
     TargetBounds* target_bounds) {
-  const gfx::Rect& available_bounds(root_window_->bounds());
+  const gfx::Rect available_bounds(GetAvailableBounds());
   gfx::Rect status_size(
       shelf_->status_area_widget()->GetWindowBoundsInScreen().size());
   int shelf_width = 0, shelf_height = 0;
@@ -649,19 +668,21 @@
 
   if (state.visibility_state == SHELF_AUTO_HIDE &&
       state.auto_hide_state == SHELF_AUTO_HIDE_HIDDEN) {
-    // Keep the launcher to its full height when dragging is in progress.
-    if (gesture_drag_status_ == GESTURE_DRAG_NONE) {
-      if (IsHorizontalAlignment())
-        shelf_height = kAutoHideSize;
-      else
-        shelf_width = kAutoHideSize;
-    }
-  } else if (state.visibility_state == SHELF_HIDDEN) {
+    // Auto-hidden shelf always starts with the default size. If a gesture-drag
+    // is in progress, then the call to UpdateTargetBoundsForGesture() below
+    // takes care of setting the height properly.
+    if (IsHorizontalAlignment())
+      shelf_height = kAutoHideSize;
+    else
+      shelf_width = kAutoHideSize;
+  } else if (state.visibility_state == SHELF_HIDDEN ||
+      !keyboard_bounds_.IsEmpty()) {
     if (IsHorizontalAlignment())
       shelf_height = 0;
     else
       shelf_width = 0;
   }
+
   target_bounds->shelf_bounds_in_root = SelectValueForShelfAlignment(
       gfx::Rect(available_bounds.x(), available_bounds.bottom() - shelf_height,
                     available_bounds.width(), shelf_height),
@@ -687,26 +708,40 @@
                     shelf_height - (status_size.height() + status_inset),
                     status_size.width(), status_size.height()));
 
-  target_bounds->launcher_bounds_in_shelf = SelectValueForShelfAlignment(
-      gfx::Rect(base::i18n::IsRTL() ? status_size.width() : 0, 0,
-                    shelf_width - status_size.width(), shelf_height),
-      gfx::Rect(0, 0, shelf_width, shelf_height - status_size.height()),
-      gfx::Rect(0, 0, shelf_width, shelf_height - status_size.height()),
-      gfx::Rect(base::i18n::IsRTL() ? status_size.width() : 0, 0,
-                    shelf_width - status_size.width(), shelf_height));
-
   target_bounds->work_area_insets = SelectValueForShelfAlignment(
       gfx::Insets(0, 0, GetWorkAreaSize(state, shelf_height), 0),
       gfx::Insets(0, GetWorkAreaSize(state, shelf_width), 0, 0),
       gfx::Insets(0, 0, 0, GetWorkAreaSize(state, shelf_width)),
       gfx::Insets(GetWorkAreaSize(state, shelf_height), 0, 0, 0));
 
+  // Also push in the work area inset for the keyboard if it is visible.
+  if (!keyboard_bounds_.IsEmpty()) {
+    target_bounds->work_area_insets.Set(
+        target_bounds->work_area_insets.top(),
+        target_bounds->work_area_insets.left(),
+        target_bounds->work_area_insets.bottom() + keyboard_bounds_.height(),
+        target_bounds->work_area_insets.right());
+  }
+
   target_bounds->opacity =
       (gesture_drag_status_ != GESTURE_DRAG_NONE ||
        state.visibility_state == SHELF_VISIBLE ||
        state.visibility_state == SHELF_AUTO_HIDE) ? 1.0f : 0.0f;
+
   if (gesture_drag_status_ == GESTURE_DRAG_IN_PROGRESS)
     UpdateTargetBoundsForGesture(target_bounds);
+
+  // This needs to happen after calling UpdateTargetBoundsForGesture(), because
+  // that can change the size of the shelf.
+  target_bounds->launcher_bounds_in_shelf = SelectValueForShelfAlignment(
+      gfx::Rect(base::i18n::IsRTL() ? status_size.width() : 0, 0,
+                    shelf_width - status_size.width(),
+                    target_bounds->shelf_bounds_in_root.height()),
+      gfx::Rect(0, 0, shelf_width, shelf_height - status_size.height()),
+      gfx::Rect(0, 0, shelf_width, shelf_height - status_size.height()),
+      gfx::Rect(base::i18n::IsRTL() ? status_size.width() : 0, 0,
+                    shelf_width - status_size.width(),
+                    target_bounds->shelf_bounds_in_root.height()));
 }
 
 void ShelfLayoutManager::UpdateTargetBoundsForGesture(
@@ -746,13 +781,12 @@
 
   if (horizontal) {
     // Move and size the launcher with the gesture.
+    int shelf_height = target_bounds->shelf_bounds_in_root.height() - translate;
+    shelf_height = std::max(shelf_height, kAutoHideSize);
+    target_bounds->shelf_bounds_in_root.set_height(shelf_height);
     if (alignment_ == SHELF_ALIGNMENT_BOTTOM) {
-      target_bounds->shelf_bounds_in_root.Offset(0, translate);
-      target_bounds->shelf_bounds_in_root.set_height(
-          available_bounds.bottom() - target_bounds->shelf_bounds_in_root.y());
-    } else {
-      target_bounds->shelf_bounds_in_root.set_height(
-          target_bounds->shelf_bounds_in_root.height() + translate);
+      target_bounds->shelf_bounds_in_root.set_y(
+          available_bounds.bottom() - shelf_height);
     }
 
     // The statusbar should be in the center of the shelf.
@@ -763,13 +797,12 @@
     target_bounds->status_bounds_in_shelf.set_y(status_y.y());
   } else {
     // Move and size the launcher with the gesture.
+    int shelf_width = target_bounds->shelf_bounds_in_root.width() - translate;
+    shelf_width = std::max(shelf_width, kAutoHideSize);
+    target_bounds->shelf_bounds_in_root.set_width(shelf_width);
     if (alignment_ == SHELF_ALIGNMENT_RIGHT) {
-      target_bounds->shelf_bounds_in_root.Offset(translate, 0);
-      target_bounds->shelf_bounds_in_root.set_width(
-          available_bounds.right() - target_bounds->shelf_bounds_in_root.x());
-    } else {
-      target_bounds->shelf_bounds_in_root.set_width(
-          target_bounds->shelf_bounds_in_root.width() + translate);
+      target_bounds->shelf_bounds_in_root.set_y(
+          available_bounds.right() - shelf_width);
     }
 
     // The statusbar should be in the center of the shelf.
@@ -846,12 +879,13 @@
     return SHELF_AUTO_HIDE_SHOWN;
 
   const std::vector<aura::Window*> windows =
-      ash::WindowCycleController::BuildWindowList(NULL);
+      ash::WindowCycleController::BuildWindowList(NULL, false);
 
   // Process the window list and check if there are any visible windows.
   for (size_t i = 0; i < windows.size(); ++i) {
     if (windows[i] && windows[i]->IsVisible() &&
-        !ash::wm::IsWindowMinimized(windows[i]))
+        !ash::wm::IsWindowMinimized(windows[i]) &&
+        root_window_ == windows[i]->GetRootWindow())
       return SHELF_AUTO_HIDE_HIDDEN;
   }
 
@@ -860,33 +894,23 @@
 }
 
 void ShelfLayoutManager::UpdateHitTestBounds() {
-  gfx::Insets insets;
-  // Only modify the hit test when the shelf is visible, so we don't mess with
-  // hover hit testing in the auto-hide state.
+  gfx::Insets mouse_insets;
+  gfx::Insets touch_insets;
   if (state_.visibility_state == SHELF_VISIBLE) {
     // Let clicks at the very top of the launcher through so windows can be
     // resized with the bottom-right corner and bottom edge.
-    switch (alignment_) {
-      case SHELF_ALIGNMENT_BOTTOM:
-        insets.Set(kWorkspaceAreaBottomInset, 0, 0, 0);
-        break;
-      case SHELF_ALIGNMENT_LEFT:
-        insets.Set(0, 0, 0, kWorkspaceAreaBottomInset);
-        break;
-      case SHELF_ALIGNMENT_RIGHT:
-        insets.Set(0, kWorkspaceAreaBottomInset, 0, 0);
-        break;
-      case SHELF_ALIGNMENT_TOP:
-        insets.Set(0, 0, kWorkspaceAreaBottomInset, 0);
-        break;
-    }
+    mouse_insets = GetInsetsForAlignment(kWorkspaceAreaVisibleInset);
+  } else if (state_.visibility_state == SHELF_AUTO_HIDE) {
+    // Extend the touch hit target out a bit to allow users to drag shelf out
+    // while hidden.
+    touch_insets = GetInsetsForAlignment(-kWorkspaceAreaAutoHideInset);
   }
-  if (shelf_ && shelf_->GetNativeWindow()) {
-    shelf_->GetNativeWindow()->SetHitTestBoundsOverrideOuter(
-        insets, 1);
-  }
-  shelf_->status_area_widget()->GetNativeWindow()->
-      SetHitTestBoundsOverrideOuter(insets, 1);
+
+    if (shelf_ && shelf_->GetNativeWindow())
+      shelf_->GetNativeWindow()->SetHitTestBoundsOverrideOuter(mouse_insets,
+                                                               touch_insets);
+    shelf_->status_area_widget()->GetNativeWindow()->
+        SetHitTestBoundsOverrideOuter(mouse_insets, touch_insets);
 }
 
 bool ShelfLayoutManager::IsShelfWindow(aura::Window* window) {
@@ -905,5 +929,32 @@
   return 0;
 }
 
+gfx::Rect ShelfLayoutManager::GetAvailableBounds() const {
+  gfx::Rect bounds(root_window_->bounds());
+  bounds.set_height(bounds.height() - keyboard_bounds_.height());
+  return bounds;
+}
+
+void ShelfLayoutManager::OnKeyboardBoundsChanging(
+    const gfx::Rect& keyboard_bounds) {
+  keyboard_bounds_ = keyboard_bounds;
+  OnWindowResized();
+}
+
+gfx::Insets ShelfLayoutManager::GetInsetsForAlignment(int distance) const {
+  switch (alignment_) {
+    case SHELF_ALIGNMENT_BOTTOM:
+      return gfx::Insets(distance, 0, 0, 0);
+    case SHELF_ALIGNMENT_LEFT:
+      return gfx::Insets(0, 0, 0, distance);
+    case SHELF_ALIGNMENT_RIGHT:
+      return gfx::Insets(0, distance, 0, 0);
+    case SHELF_ALIGNMENT_TOP:
+      return gfx::Insets(0, 0, distance, 0);
+  }
+  NOTREACHED();
+  return gfx::Insets();
+}
+
 }  // namespace internal
 }  // namespace ash
diff --git a/ash/shelf/shelf_layout_manager.h b/ash/shelf/shelf_layout_manager.h
index 40e59a7..ea86f15 100644
--- a/ash/shelf/shelf_layout_manager.h
+++ b/ash/shelf/shelf_layout_manager.h
@@ -20,6 +20,8 @@
 #include "ui/aura/layout_manager.h"
 #include "ui/gfx/insets.h"
 #include "ui/gfx/rect.h"
+#include "ui/keyboard/keyboard_controller.h"
+#include "ui/keyboard/keyboard_controller_observer.h"
 
 namespace aura {
 class RootWindow;
@@ -34,6 +36,7 @@
 class ShelfWidget;
 namespace internal {
 
+class PanelLayoutManagerTest;
 class ShelfLayoutManagerTest;
 class StatusAreaWidget;
 class WorkspaceController;
@@ -47,8 +50,12 @@
 class ASH_EXPORT ShelfLayoutManager :
     public aura::LayoutManager,
     public ash::ShellObserver,
-    public aura::client::ActivationChangeObserver {
+    public aura::client::ActivationChangeObserver,
+    public keyboard::KeyboardControllerObserver {
  public:
+
+  // TODO(rharrison): Move this observer out of ash::internal::
+  //                  namespace. Tracked in crosbug.com/223936
   class ASH_EXPORT Observer {
    public:
     // Called when the target ShelfLayoutManager will be deleted.
@@ -59,11 +66,19 @@
 
     // Called when the auto hide state is changed.
     virtual void OnAutoHideStateChanged(ShelfAutoHideState new_state) {}
+
+    // Called when the auto hide behavior is changed.
+    virtual void OnAutoHideBehaviorChanged(
+        ShelfAutoHideBehavior new_behavior) {}
   };
 
-  // We reserve a small area at the bottom of the workspace area to ensure that
-  // the bottom-of-window resize handle can be hit.
-  static const int kWorkspaceAreaBottomInset;
+  // We reserve a small area on the edge of the workspace area to ensure that
+  // the resize handle at the edge of the window can be hit.
+  static const int kWorkspaceAreaVisibleInset;
+
+  // When autohidden we extend the touch hit target onto the screen so that the
+  // user can drag the shelf out.
+  static const int kWorkspaceAreaAutoHideInset;
 
   // Size of the shelf when auto-hidden.
   static const int kAutoHideSize;
@@ -194,6 +209,7 @@
   class AutoHideEventFilter;
   class UpdateShelfObserver;
   friend class ash::ScreenAsh;
+  friend class PanelLayoutManagerTest;
   friend class ShelfLayoutManagerTest;
 
   struct TargetBounds {
@@ -270,6 +286,17 @@
 
   int GetWorkAreaSize(const State& state, int size) const;
 
+  // Return the bounds available in the parent, taking into account the bounds
+  // of the keyboard if necessary.
+  gfx::Rect GetAvailableBounds() const;
+
+  // Overridden from keyboard::KeyboardControllerObserver:
+  virtual void OnKeyboardBoundsChanging(
+      const gfx::Rect& keyboard_bounds) OVERRIDE;
+
+  // Generates insets for inward edge based on the current shelf alignment.
+  gfx::Insets GetInsetsForAlignment(int distance) const;
+
   // The RootWindow is cached so that we don't invoke Shell::GetInstance() from
   // our destructor. We avoid that as at the time we're deleted Shell is being
   // deleted too.
@@ -323,6 +350,9 @@
   // Used to delay updating shelf background.
   UpdateShelfObserver* update_shelf_observer_;
 
+  // The bounds of the keyboard.
+  gfx::Rect keyboard_bounds_;
+
   DISALLOW_COPY_AND_ASSIGN(ShelfLayoutManager);
 };
 
diff --git a/ash/shelf/shelf_layout_manager_unittest.cc b/ash/shelf/shelf_layout_manager_unittest.cc
index ded8741..10cf1d0 100644
--- a/ash/shelf/shelf_layout_manager_unittest.cc
+++ b/ash/shelf/shelf_layout_manager_unittest.cc
@@ -13,9 +13,9 @@
 #include "ash/launcher/launcher_view.h"
 #include "ash/root_window_controller.h"
 #include "ash/screen_ash.h"
+#include "ash/session_state_delegate.h"
 #include "ash/shelf/shelf_widget.h"
 #include "ash/shell.h"
-#include "ash/shell_delegate.h"
 #include "ash/shell_window_ids.h"
 #include "ash/system/status_area_widget.h"
 #include "ash/system/tray/system_tray.h"
@@ -66,6 +66,83 @@
   return Shell::GetPrimaryRootWindowController()->GetSystemTray();
 }
 
+class ShelfDragCallback {
+ public:
+  ShelfDragCallback(const gfx::Rect& not_visible, const gfx::Rect& visible)
+      : not_visible_bounds_(not_visible),
+        visible_bounds_(visible),
+        was_visible_on_drag_start_(false) {
+    EXPECT_EQ(not_visible_bounds_.bottom(), visible_bounds_.bottom());
+  }
+
+  virtual ~ShelfDragCallback() {
+  }
+
+  void ProcessScroll(ui::EventType type, const gfx::Vector2dF& delta) {
+    if (GetShelfLayoutManager()->visibility_state() == ash::SHELF_HIDDEN)
+      return;
+
+    if (type == ui::ET_GESTURE_SCROLL_BEGIN) {
+      scroll_ = gfx::Vector2dF();
+      was_visible_on_drag_start_ = GetShelfLayoutManager()->IsVisible();
+      return;
+    }
+
+    // The state of the shelf at the end of the gesture is tested separately.
+    if (type == ui::ET_GESTURE_SCROLL_END)
+      return;
+
+    if (type == ui::ET_GESTURE_SCROLL_UPDATE)
+      scroll_.Add(delta);
+
+    gfx::Rect shelf_bounds = GetShelfWidget()->GetWindowBoundsInScreen();
+    EXPECT_EQ(not_visible_bounds_.bottom(), shelf_bounds.bottom());
+    EXPECT_EQ(visible_bounds_.bottom(), shelf_bounds.bottom());
+
+    // if the shelf is being dimmed test dimmer bounds as well.
+    if (GetShelfWidget()->GetDimsShelf())
+      EXPECT_EQ(GetShelfWidget()->GetWindowBoundsInScreen(),
+                GetShelfWidget()->GetDimmerBoundsForTest());
+
+    // The shelf should never be smaller than the hidden state.
+    EXPECT_GE(shelf_bounds.height(), not_visible_bounds_.height());
+
+    if (was_visible_on_drag_start_) {
+      if (scroll_.y() < 0) {
+        // If dragging up from the visible state, then the shelf should increase
+        // in height, but not as much as the scroll delta.
+        EXPECT_LE(shelf_bounds.y(), visible_bounds_.y());
+        EXPECT_LE(abs(shelf_bounds.y() - visible_bounds_.y()),
+                  abs(scroll_.y()));
+      } else {
+        if (shelf_bounds.height() > not_visible_bounds_.height()) {
+          // If dragging down from the visible state, then the shelf should
+          // decrease in height, until it reaches the minimum height.
+          EXPECT_EQ(shelf_bounds.y(), visible_bounds_.y() + (scroll_.y()));
+        }
+      }
+    } else {
+      if (fabs(scroll_.y()) < not_visible_bounds_.y() - visible_bounds_.y()) {
+        // Tests that the shelf sticks with the touch point during the drag
+        // until the shelf is completely visible.
+        EXPECT_EQ(shelf_bounds.y(), not_visible_bounds_.y() + scroll_.y());
+      } else {
+        // Tests that after the shelf is completely visible, the shelf starts
+        // resisting the drag.
+        EXPECT_GT(shelf_bounds.y(), not_visible_bounds_.y() + scroll_.y());
+      }
+    }
+  }
+
+ private:
+  const gfx::Rect not_visible_bounds_;
+  const gfx::Rect visible_bounds_;
+  gfx::Vector2dF scroll_;
+  bool was_visible_on_drag_start_;
+
+  DISALLOW_COPY_AND_ASSIGN(ShelfDragCallback);
+};
+
 class ShelfLayoutObserverTest : public ShelfLayoutManager::Observer {
  public:
   ShelfLayoutObserverTest()
@@ -425,12 +502,12 @@
   lock_widget->Show();
 
   // Lock the screen.
-  Shell::GetInstance()->delegate()->LockScreen();
+  Shell::GetInstance()->session_state_delegate()->LockScreen();
   shelf->UpdateVisibilityState();
   // Showing a widget in the lock screen should force the shelf to be visibile.
   EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
 
-  Shell::GetInstance()->delegate()->UnlockScreen();
+  Shell::GetInstance()->session_state_delegate()->UnlockScreen();
   shelf->UpdateVisibilityState();
   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
 }
@@ -480,6 +557,150 @@
             widget->GetWorkAreaBoundsInScreen().bottom());
 }
 
+// Basic assertions around the dimming of the shelf.
+TEST_F(ShelfLayoutManagerTest, TestDimmingBehavior) {
+  // 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);
+
+  ShelfLayoutManager* shelf = GetShelfLayoutManager();
+  shelf->shelf_widget()->DisableDimmingAnimationsForTest();
+
+  views::Widget* widget = new views::Widget;
+  views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
+  params.bounds = gfx::Rect(0, 0, 200, 200);
+  params.context = CurrentContext();
+  // Widget is now owned by the parent window.
+  widget->Init(params);
+  widget->Show();
+  aura::Window* window = widget->GetNativeWindow();
+  gfx::Rect display_bounds(
+      Shell::GetScreen()->GetDisplayNearestWindow(window).bounds());
+
+  gfx::Point off_shelf = display_bounds.CenterPoint();
+  gfx::Point on_shelf =
+      shelf->shelf_widget()->GetWindowBoundsInScreen().CenterPoint();
+
+  // Test there is no dimming object active at this point.
+  generator.MoveMouseTo(on_shelf.x(), on_shelf.y());
+  EXPECT_EQ(-1, shelf->shelf_widget()->GetDimmingAlphaForTest());
+  generator.MoveMouseTo(off_shelf.x(), off_shelf.y());
+  EXPECT_EQ(-1, shelf->shelf_widget()->GetDimmingAlphaForTest());
+
+  // After maximization, the shelf should be visible and the dimmer created.
+  widget->Maximize();
+
+  on_shelf = shelf->shelf_widget()->GetWindowBoundsInScreen().CenterPoint();
+  EXPECT_LT(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
+
+  // Moving the mouse off the shelf should dim the bar.
+  generator.MoveMouseTo(off_shelf.x(), off_shelf.y());
+  EXPECT_LT(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
+
+  // Adding touch events outside the shelf should still keep the shelf in
+  // dimmed state.
+  generator.PressTouch();
+  generator.MoveTouch(off_shelf);
+  EXPECT_LT(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
+  // Move the touch into the shelf area should undim.
+  generator.MoveTouch(on_shelf);
+  EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
+  generator.ReleaseTouch();
+  // And a release dims again.
+  EXPECT_LT(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
+
+  // Moving the mouse on the shelf should undim the bar.
+  generator.MoveMouseTo(on_shelf);
+  EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
+
+  // No matter what the touch events do, the shelf should stay undimmed.
+  generator.PressTouch();
+  generator.MoveTouch(off_shelf);
+  EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
+  generator.MoveTouch(on_shelf);
+  EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
+  generator.MoveTouch(off_shelf);
+  EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
+  generator.MoveTouch(on_shelf);
+  generator.ReleaseTouch();
+
+  // After restore, the dimming object should be deleted again.
+  widget->Restore();
+  EXPECT_EQ(-1, shelf->shelf_widget()->GetDimmingAlphaForTest());
+}
+
+// Assertions around the dimming of the shelf in conjunction with menus.
+TEST_F(ShelfLayoutManagerTest, TestDimmingBehaviorWithMenus) {
+  // 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);
+
+  ShelfLayoutManager* shelf = GetShelfLayoutManager();
+  shelf->shelf_widget()->DisableDimmingAnimationsForTest();
+
+  views::Widget* widget = new views::Widget;
+  views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
+  params.bounds = gfx::Rect(0, 0, 200, 200);
+  params.context = CurrentContext();
+  // Widget is now owned by the parent window.
+  widget->Init(params);
+  widget->Show();
+  aura::Window* window = widget->GetNativeWindow();
+  gfx::Rect display_bounds(
+      Shell::GetScreen()->GetDisplayNearestWindow(window).bounds());
+
+  // After maximization, the shelf should be visible and the dimmer created.
+  widget->Maximize();
+
+  gfx::Point off_shelf = display_bounds.CenterPoint();
+  gfx::Point on_shelf =
+      shelf->shelf_widget()->GetWindowBoundsInScreen().CenterPoint();
+
+  // Moving the mouse on the shelf should undim the bar.
+  generator.MoveMouseTo(on_shelf.x(), on_shelf.y());
+  EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
+
+  // Simulate a menu opening.
+  shelf->shelf_widget()->ForceUndimming(true);
+
+  // Moving the mouse off the shelf should not dim the bar.
+  generator.MoveMouseTo(off_shelf.x(), off_shelf.y());
+  EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
+
+  // No matter what the touch events do, the shelf should stay undimmed.
+  generator.PressTouch();
+  generator.MoveTouch(off_shelf);
+  EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
+  generator.MoveTouch(on_shelf);
+  EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
+  generator.MoveTouch(off_shelf);
+  EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
+  generator.ReleaseTouch();
+  EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
+
+  // "Closing the menu" should now turn off the menu since no event is inside
+  // the shelf any longer.
+  shelf->shelf_widget()->ForceUndimming(false);
+  EXPECT_LT(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
+
+  // Moving the mouse again on the shelf which should undim the bar again.
+  // This time we check that the bar stays undimmed when the mouse remains on
+  // the bar and the "menu gets closed".
+  generator.MoveMouseTo(on_shelf.x(), on_shelf.y());
+  EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
+  shelf->shelf_widget()->ForceUndimming(true);
+  generator.MoveMouseTo(off_shelf.x(), off_shelf.y());
+  EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
+  generator.MoveMouseTo(on_shelf.x(), on_shelf.y());
+  EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
+  shelf->shelf_widget()->ForceUndimming(true);
+  EXPECT_EQ(0, shelf->shelf_widget()->GetDimmingAlphaForTest());
+}
+
 // Verifies the shelf is visible when status/launcher is focused.
 TEST_F(ShelfLayoutManagerTest, VisibleWhenStatusOrLauncherFocused) {
   // Since ShelfLayoutManager queries for mouse location, move the mouse so
@@ -741,7 +962,19 @@
   gfx::Rect bounds_shelf = window->bounds();
   EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
 
+  shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
+  shelf->LayoutShelf();
+  EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
+
+  gfx::Rect bounds_noshelf = window->bounds();
+  gfx::Rect shelf_hidden = GetShelfWidget()->GetWindowBoundsInScreen();
+
+  shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
+  shelf->LayoutShelf();
+
   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
+  const int kNumScrollSteps = 10;
+  ShelfDragCallback handler(shelf_hidden, shelf_shown);
 
   // Swipe up on the shelf. This should not change any state.
   gfx::Point start = GetShelfWidget()->GetWindowBoundsInScreen().CenterPoint();
@@ -749,8 +982,10 @@
 
   // Swipe down on the shelf to hide it.
   end.set_y(start.y() + 100);
-  generator.GestureScrollSequence(start, end,
-      base::TimeDelta::FromMilliseconds(10), 1);
+  generator.GestureScrollSequenceWithCallback(start, end,
+      base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
+      base::Bind(&ShelfDragCallback::ProcessScroll,
+                 base::Unretained(&handler)));
   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
@@ -758,22 +993,25 @@
   EXPECT_NE(shelf_shown.ToString(),
             GetShelfWidget()->GetWindowBoundsInScreen().ToString());
 
-  gfx::Rect bounds_noshelf = window->bounds();
-  gfx::Rect shelf_hidden = GetShelfWidget()->GetWindowBoundsInScreen();
-
   // Swipe up to show the shelf.
-  generator.GestureScrollSequence(end, start,
-      base::TimeDelta::FromMilliseconds(10), 1);
+  generator.GestureScrollSequenceWithCallback(end, start,
+      base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
+      base::Bind(&ShelfDragCallback::ProcessScroll,
+                 base::Unretained(&handler)));
   EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
   EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString());
+  EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(),
+            GetShelfWidget()->GetWindowBoundsInScreen());
   EXPECT_EQ(shelf_shown.ToString(),
             GetShelfWidget()->GetWindowBoundsInScreen().ToString());
 
   // Swipe up again. The shelf should hide.
   end.set_y(start.y() - 100);
-  generator.GestureScrollSequence(start, end,
-      base::TimeDelta::FromMilliseconds(10), 1);
+  generator.GestureScrollSequenceWithCallback(start, end,
+      base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
+      base::Bind(&ShelfDragCallback::ProcessScroll,
+                 base::Unretained(&handler)));
   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
@@ -782,13 +1020,17 @@
 
   // Swipe up yet again to show it.
   end.set_y(start.y() + 100);
-  generator.GestureScrollSequence(end, start,
-      base::TimeDelta::FromMilliseconds(10), 1);
+  generator.GestureScrollSequenceWithCallback(end, start,
+      base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
+      base::Bind(&ShelfDragCallback::ProcessScroll,
+                 base::Unretained(&handler)));
 
   // Swipe down very little. It shouldn't change any state.
   end.set_y(start.y() + shelf_shown.height() * 3 / 10);
-  generator.GestureScrollSequence(start, end,
-      base::TimeDelta::FromMilliseconds(100), 1);
+  generator.GestureScrollSequenceWithCallback(start, end,
+      base::TimeDelta::FromMilliseconds(100), 1,
+      base::Bind(&ShelfDragCallback::ProcessScroll,
+                 base::Unretained(&handler)));
   EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
   EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString());
@@ -797,34 +1039,49 @@
 
   // Swipe down again to hide.
   end.set_y(start.y() + 100);
-  generator.GestureScrollSequence(start, end,
-      base::TimeDelta::FromMilliseconds(10), 1);
+  generator.GestureScrollSequenceWithCallback(start, end,
+      base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
+      base::Bind(&ShelfDragCallback::ProcessScroll,
+                 base::Unretained(&handler)));
   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
+  EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(), gfx::Rect());
   EXPECT_EQ(bounds_noshelf.ToString(), window->bounds().ToString());
   EXPECT_EQ(shelf_hidden.ToString(),
             GetShelfWidget()->GetWindowBoundsInScreen().ToString());
 
-  // Swipe up yet again to show it.
+  // Swipe up in extended hit region to show it.
+  gfx::Point extended_start = gfx::Point(
+      (GetShelfWidget()->GetWindowBoundsInScreen().x() +
+       GetShelfWidget()->GetWindowBoundsInScreen().right())/2,
+      GetShelfWidget()->GetWindowBoundsInScreen().y() - 1);
+  end.set_y(extended_start.y() - 100);
+  generator.GestureScrollSequenceWithCallback(extended_start, end,
+      base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
+      base::Bind(&ShelfDragCallback::ProcessScroll,
+                 base::Unretained(&handler)));
+  EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
+  EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
+  EXPECT_EQ(bounds_shelf.ToString(), window->bounds().ToString());
+  EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(),
+            GetShelfWidget()->GetWindowBoundsInScreen());
+  EXPECT_EQ(shelf_shown.ToString(),
+            GetShelfWidget()->GetWindowBoundsInScreen().ToString());
+
+  // Swipe down again to hide.
   end.set_y(start.y() + 100);
-  generator.GestureScrollSequence(end, start,
-      base::TimeDelta::FromMilliseconds(10), 1);
-  EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
-  EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
-
-  // Tap on the shelf itself. This should not change anything.
-  generator.GestureTapAt(start);
-  EXPECT_EQ(SHELF_VISIBLE, shelf->visibility_state());
-  EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
-
-  // Now, tap on the desktop region (above the shelf). This should hide the
-  // shelf.
-  gfx::Point tap = start + gfx::Vector2d(0, -90);
-  generator.GestureTapAt(tap);
+  generator.GestureScrollSequenceWithCallback(start, end,
+      base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
+      base::Bind(&ShelfDragCallback::ProcessScroll,
+                 base::Unretained(&handler)));
   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
+  EXPECT_EQ(GetShelfWidget()->GetDimmerBoundsForTest(), gfx::Rect());
+  EXPECT_EQ(bounds_noshelf.ToString(), window->bounds().ToString());
+  EXPECT_EQ(shelf_hidden.ToString(),
+            GetShelfWidget()->GetWindowBoundsInScreen().ToString());
 
   // Make the window fullscreen.
   widget->SetFullscreen(true);
@@ -834,14 +1091,17 @@
   EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
 
   // Swipe-up. This should not change anything.
-  generator.GestureScrollSequence(end, start,
-      base::TimeDelta::FromMilliseconds(10), 1);
+  generator.GestureScrollSequenceWithCallback(end, start,
+      base::TimeDelta::FromMilliseconds(10), kNumScrollSteps,
+      base::Bind(&ShelfDragCallback::ProcessScroll,
+                 base::Unretained(&handler)));
   EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
   EXPECT_EQ(bounds_fullscreen.ToString(), window->bounds().ToString());
 }
 
 TEST_F(ShelfLayoutManagerTest, WindowVisibilityDisablesAutoHide) {
+  UpdateDisplay("800x600,800x600");
   ShelfLayoutManager* shelf = GetShelfLayoutManager();
   shelf->LayoutShelf();
   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
@@ -855,12 +1115,10 @@
 
   // Window minimized => auto hide disabled.
   dummy->Minimize();
-  shelf->UpdateVisibilityState();
   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
 
   // Window closed => auto hide disabled.
   dummy->CloseNow();
-  shelf->UpdateVisibilityState();
   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
 
   // Multiple window test
@@ -868,22 +1126,28 @@
   views::Widget* window2 = CreateTestWidget();
 
   // both visible => normal autohide
-  shelf->UpdateVisibilityState();
   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
 
   // either minimzed => normal autohide
   window2->Minimize();
-  shelf->UpdateVisibilityState();
   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
   window2->Restore();
   window1->Minimize();
-  shelf->UpdateVisibilityState();
   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
 
   // both minimzed => disable auto hide
   window2->Minimize();
-  shelf->UpdateVisibilityState();
   EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
+
+  // Test moving windows to/from other display.
+  window2->Restore();
+  EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
+  // Move to second display.
+  window2->SetBounds(gfx::Rect(850, 50, 50, 50));
+  EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->auto_hide_state());
+  // Move back to primary display.
+  window2->SetBounds(gfx::Rect(50, 50, 50, 50));
+  EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
 }
 
 #if defined(OS_WIN)
@@ -1092,7 +1356,7 @@
     }
     // Move the pointer over the edge of the shelf.
     generator.MoveMouseTo(
-        center.x(), status_area_widget->GetWindowBoundsInScreen().y() - 8);
+        center.x(), status_area_widget->GetWindowBoundsInScreen().y() - 12);
     shelf->UpdateVisibilityState();
     if (i) {
       EXPECT_TRUE(shelf->IsVisible());
diff --git a/ash/shelf/shelf_widget.cc b/ash/shelf/shelf_widget.cc
index f9d324e..eab771b 100644
--- a/ash/shelf/shelf_widget.cc
+++ b/ash/shelf/shelf_widget.cc
@@ -10,10 +10,10 @@
 #include "ash/launcher/launcher_navigator.h"
 #include "ash/launcher/launcher_view.h"
 #include "ash/root_window_controller.h"
+#include "ash/session_state_delegate.h"
 #include "ash/shelf/shelf_layout_manager.h"
 #include "ash/shelf/shelf_widget.h"
 #include "ash/shell.h"
-#include "ash/shell_delegate.h"
 #include "ash/shell_window_ids.h"
 #include "ash/wm/property_util.h"
 #include "ash/wm/status_area_layout_manager.h"
@@ -24,6 +24,7 @@
 #include "ui/aura/root_window.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_observer.h"
+#include "ui/base/events/event_constants.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/compositor/layer.h"
 #include "ui/gfx/canvas.h"
@@ -38,9 +39,195 @@
 // Size of black border at bottom (or side) of launcher.
 const int kNumBlackPixels = 3;
 // Alpha to paint dimming image with.
-const int kDimAlpha = 96;
+const int kDimAlpha = 128;
+
+// The time to dim and un-dim.
+const int kTimeToDimMs = 3000;  // Slow in dimming.
+const int kTimeToUnDimMs = 200;  // Fast in activating.
+
+// Class used to slightly dim shelf items when maximized and visible.
+class DimmerView : public views::View,
+                   public views::WidgetDelegate,
+                   ash::internal::BackgroundAnimatorDelegate {
+ public:
+  // If |disable_dimming_animations_for_test| is set, all alpha animations will
+  // be performed instantly.
+  DimmerView(ash::ShelfWidget* shelf_widget,
+             bool disable_dimming_animations_for_test);
+  virtual ~DimmerView();
+
+  // Called by |DimmerEventFilter| when the mouse |hovered| state changes.
+  void SetHovered(bool hovered);
+
+  // Force the dimmer to be undimmed.
+  void ForceUndimming(bool force);
+
+  // views::WidgetDelegate overrides:
+  virtual views::Widget* GetWidget() OVERRIDE {
+    return View::GetWidget();
+  }
+  virtual const views::Widget* GetWidget() const OVERRIDE {
+    return View::GetWidget();
+  }
+
+  // ash::internal::BackgroundAnimatorDelegate overrides:
+  virtual void UpdateBackground(int alpha) OVERRIDE {
+    alpha_ = alpha;
+    SchedulePaint();
+  }
+
+  // views::View overrides:
+  virtual void OnPaintBackground(gfx::Canvas* canvas) OVERRIDE;
+
+  // A function to test the current alpha used.
+  int get_dimming_alpha_for_test() { return alpha_; }
+
+ private:
+  // This class monitors mouse events to see if it is on top of the launcher.
+  class DimmerEventFilter : public ui::EventHandler {
+   public:
+    explicit DimmerEventFilter(DimmerView* owner);
+    virtual ~DimmerEventFilter();
+
+    // Overridden from ui::EventHandler:
+    virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE;
+    virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE;
+
+   private:
+    // The owning class.
+    DimmerView* owner_;
+
+    // TRUE if the mouse is inside the shelf.
+    bool mouse_inside_;
+
+    // TRUE if a touch event is inside the shelf.
+    bool touch_inside_;
+
+    DISALLOW_COPY_AND_ASSIGN(DimmerEventFilter);
+  };
+
+  // The owning shelf.
+  ash::ShelfWidget* shelf_;
+
+  // The alpha to use for covering the shelf.
+  int alpha_;
+
+  // True if the event filter claims that we should not be dimmed.
+  bool is_hovered_;
+
+  // True if someone forces us not to be dimmed (e.g. a menu is open).
+  bool force_hovered_;
+
+  // True if animations should be suppressed for a test.
+  bool disable_dimming_animations_for_test_;
+
+  // The animator for the background transitions.
+  ash::internal::BackgroundAnimator background_animator_;
+
+  // Notification of entering / exiting of the shelf area by mouse.
+  scoped_ptr<DimmerEventFilter> event_filter_;
+
+  DISALLOW_COPY_AND_ASSIGN(DimmerView);
+};
+
+DimmerView::DimmerView(ash::ShelfWidget* shelf_widget,
+                       bool disable_dimming_animations_for_test)
+    : shelf_(shelf_widget),
+      alpha_(kDimAlpha),
+      is_hovered_(false),
+      force_hovered_(false),
+      disable_dimming_animations_for_test_(disable_dimming_animations_for_test),
+      background_animator_(this, 0, kDimAlpha) {
+  event_filter_.reset(new DimmerEventFilter(this));
+  // Make sure it is undimmed at the beginning and then fire off the dimming
+  // animation.
+  background_animator_.SetPaintsBackground(false,
+      ash::internal::BackgroundAnimator::CHANGE_IMMEDIATE);
+  SetHovered(false);
 }
 
+DimmerView::~DimmerView() {
+}
+
+void DimmerView::SetHovered(bool hovered) {
+  // Remember the hovered state so that we can correct the state once a
+  // possible force state has disappeared.
+  is_hovered_ = hovered;
+  // Undimm also if we were forced to by e.g. an open menu.
+  hovered |= force_hovered_;
+  background_animator_.SetDuration(hovered ? kTimeToUnDimMs : kTimeToDimMs);
+  background_animator_.SetPaintsBackground(!hovered,
+      disable_dimming_animations_for_test_ ?
+          ash::internal::BackgroundAnimator::CHANGE_IMMEDIATE :
+          ash::internal::BackgroundAnimator::CHANGE_ANIMATE);
+}
+
+void DimmerView::ForceUndimming(bool force) {
+  bool previous = force_hovered_;
+  force_hovered_ = force;
+  // If the forced change does change the result we apply the change.
+  if (is_hovered_ || force_hovered_ != is_hovered_ || previous)
+    SetHovered(is_hovered_);
+}
+
+void DimmerView::OnPaintBackground(gfx::Canvas* canvas) {
+  SkPaint paint;
+  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+  gfx::ImageSkia launcher_background =
+      *rb.GetImageNamed(IDR_AURA_LAUNCHER_DIMMING).ToImageSkia();
+
+  if (shelf_->GetAlignment() != ash::SHELF_ALIGNMENT_BOTTOM) {
+    launcher_background = gfx::ImageSkiaOperations::CreateRotatedImage(
+        launcher_background,
+        shelf_->shelf_layout_manager()->SelectValueForShelfAlignment(
+            SkBitmapOperations::ROTATION_90_CW,
+            SkBitmapOperations::ROTATION_90_CW,
+            SkBitmapOperations::ROTATION_270_CW,
+            SkBitmapOperations::ROTATION_180_CW));
+  }
+  paint.setAlpha(alpha_);
+  canvas->DrawImageInt(
+      launcher_background,
+      0, 0, launcher_background.width(), launcher_background.height(),
+      0, 0, width(), height(),
+      false,
+      paint);
+}
+
+DimmerView::DimmerEventFilter::DimmerEventFilter(DimmerView* owner)
+    : owner_(owner),
+      mouse_inside_(false),
+      touch_inside_(false) {
+  ash::Shell::GetInstance()->AddPreTargetHandler(this);
+}
+
+DimmerView::DimmerEventFilter::~DimmerEventFilter() {
+  ash::Shell::GetInstance()->RemovePreTargetHandler(this);
+}
+
+void DimmerView::DimmerEventFilter::OnMouseEvent(ui::MouseEvent* event) {
+  if (event->type() != ui::ET_MOUSE_MOVED &&
+      event->type() != ui::ET_MOUSE_DRAGGED)
+    return;
+  bool inside = owner_->GetBoundsInScreen().Contains(event->root_location());
+  if (mouse_inside_ || touch_inside_ != inside || touch_inside_)
+    owner_->SetHovered(inside || touch_inside_);
+  mouse_inside_ = inside;
+}
+
+void DimmerView::DimmerEventFilter::OnTouchEvent(ui::TouchEvent* event) {
+  bool touch_inside = false;
+  if (event->type() != ui::ET_TOUCH_RELEASED &&
+      event->type() != ui::ET_TOUCH_CANCELLED)
+    touch_inside = owner_->GetBoundsInScreen().Contains(event->root_location());
+
+  if (mouse_inside_ || touch_inside_ != mouse_inside_ || touch_inside)
+    owner_->SetHovered(mouse_inside_ || touch_inside);
+  touch_inside_ = touch_inside;
+}
+
+}  // namespace
+
 namespace ash {
 
 // The contents view of the Shelf. This view contains LauncherView and
@@ -60,13 +247,11 @@
   }
 
   // Set if the shelf area is dimmed (eg when a window is maximized).
-  void SetDimmed(bool dimmed) {
-    if (dimmed_ != dimmed) {
-      dimmed_ = dimmed;
-      SchedulePaint();
-    }
-  }
-  bool GetDimmed() const { return dimmed_; }
+  void SetDimmed(bool dimmed);
+  bool GetDimmed() const;
+
+  // Set the bounds of the widget.
+  void SetWidgetBounds(const gfx::Rect bounds);
 
   // views::View overrides:
   virtual void OnPaintBackground(gfx::Canvas* canvas) OVERRIDE;
@@ -85,11 +270,34 @@
   // BackgroundAnimatorDelegate overrides:
   virtual void UpdateBackground(int alpha) OVERRIDE;
 
+  // Force the shelf to be presented in an undimmed state.
+  void ForceUndimming(bool force);
+
+  // A function to test the current alpha used by the dimming bar. If there is
+  // no dimmer active, the function will return -1.
+  int GetDimmingAlphaForTest();
+
+  // A function to test the bounds of the dimming bar. Returns gfx::Rect() if
+  // the dimmer is inactive.
+  gfx::Rect GetDimmerBoundsForTest();
+
+  // Disable dimming animations for running tests. This needs to be called
+  // prior to the creation of of the |dimmer_|.
+  void disable_dimming_animations_for_test() {
+    disable_dimming_animations_for_test_ = true;
+  }
+
  private:
   ShelfWidget* shelf_;
+  scoped_ptr<views::Widget> dimmer_;
   internal::FocusCycler* focus_cycler_;
   int alpha_;
-  bool dimmed_;
+
+  // The view which does the dimming.
+  DimmerView* dimmer_view_;
+
+  // True if dimming animations should be turned off.
+  bool disable_dimming_animations_for_test_;
 
   DISALLOW_COPY_AND_ASSIGN(DelegateView);
 };
@@ -98,12 +306,51 @@
     : shelf_(shelf),
       focus_cycler_(NULL),
       alpha_(0),
-      dimmed_(false) {
+      dimmer_view_(NULL),
+      disable_dimming_animations_for_test_(false) {
+  set_allow_deactivate_on_esc(true);
 }
 
 ShelfWidget::DelegateView::~DelegateView() {
 }
 
+void ShelfWidget::DelegateView::SetDimmed(bool value) {
+  if (value == (dimmer_.get() != NULL))
+    return;
+
+  if (value) {
+    dimmer_.reset(new views::Widget);
+    views::Widget::InitParams params(
+        views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
+    params.transparent = true;
+    params.can_activate = false;
+    params.accept_events = false;
+    params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+    params.parent = shelf_->GetNativeView();
+    dimmer_->Init(params);
+    dimmer_->GetNativeWindow()->SetName("ShelfDimmer");
+    dimmer_->SetBounds(shelf_->GetWindowBoundsInScreen());
+    // The launcher should not take focus when it is initially shown.
+    dimmer_->set_focus_on_creation(false);
+    dimmer_view_ = new DimmerView(shelf_, disable_dimming_animations_for_test_);
+    dimmer_->SetContentsView(dimmer_view_);
+    dimmer_->GetNativeView()->SetName("ShelfDimmerView");
+    dimmer_->Show();
+  } else {
+    dimmer_view_ = NULL;
+    dimmer_.reset(NULL);
+  }
+}
+
+bool ShelfWidget::DelegateView::GetDimmed() const {
+  return dimmer_.get() && dimmer_->IsVisible();
+}
+
+void ShelfWidget::DelegateView::SetWidgetBounds(const gfx::Rect bounds) {
+  if (dimmer_)
+    dimmer_->SetBounds(bounds);
+}
+
 void ShelfWidget::DelegateView::OnPaintBackground(gfx::Canvas* canvas) {
   ResourceBundle& rb = ResourceBundle::GetSharedInstance();
   gfx::ImageSkia launcher_background =
@@ -133,28 +380,6 @@
       false,
       paint);
   canvas->FillRect(black_rect, SK_ColorBLACK);
-
-  if (dimmed_) {
-    gfx::ImageSkia background_image =
-        *rb.GetImageSkiaNamed(IDR_AURA_LAUNCHER_DIMMING);
-    if (SHELF_ALIGNMENT_BOTTOM != shelf_->GetAlignment())
-      background_image = gfx::ImageSkiaOperations::CreateRotatedImage(
-          background_image,
-          shelf_->shelf_layout_manager()->SelectValueForShelfAlignment(
-              SkBitmapOperations::ROTATION_90_CW,
-              SkBitmapOperations::ROTATION_90_CW,
-              SkBitmapOperations::ROTATION_270_CW,
-              SkBitmapOperations::ROTATION_180_CW));
-
-    SkPaint paint;
-    paint.setAlpha(kDimAlpha);
-    canvas->DrawImageInt(
-        background_image,
-        0, 0, background_image.width(), background_image.height(),
-        0, 0, width(), height(),
-        false,
-        paint);
-  }
 }
 
 bool ShelfWidget::DelegateView::CanActivate() const {
@@ -180,6 +405,23 @@
   }
 }
 
+void ShelfWidget::DelegateView::ForceUndimming(bool force) {
+  if (GetDimmed())
+    dimmer_view_->ForceUndimming(force);
+}
+
+int ShelfWidget::DelegateView::GetDimmingAlphaForTest() {
+  if (GetDimmed())
+    return dimmer_view_->get_dimming_alpha_for_test();
+  return -1;
+}
+
+gfx::Rect ShelfWidget::DelegateView::GetDimmerBoundsForTest() {
+  if (GetDimmed())
+    return dimmer_view_->GetBoundsInScreen();
+  return gfx::Rect();
+}
+
 void ShelfWidget::DelegateView::UpdateBackground(int alpha) {
   alpha_ = alpha;
   SchedulePaint();
@@ -208,8 +450,10 @@
 
   status_area_widget_ = new internal::StatusAreaWidget(status_container);
   status_area_widget_->CreateTrayViews();
-  if (Shell::GetInstance()->delegate()->IsSessionStarted())
+  if (Shell::GetInstance()->session_state_delegate()->
+          IsActiveUserSessionStarted()) {
     status_area_widget_->Show();
+  }
   Shell::GetInstance()->focus_cycler()->AddWidget(status_area_widget_);
 
   shelf_layout_manager_ = new internal::ShelfLayoutManager(this);
@@ -252,7 +496,7 @@
 }
 
 void ShelfWidget::CreateLauncher() {
-  if (!launcher_.get()) {
+  if (!launcher_) {
     Shell* shell = Shell::GetInstance();
     // This needs to be called before launcher_model().
     shell->GetLauncherDelegate();
@@ -266,9 +510,8 @@
     internal::RootWindowController::ForWindow(window_container_)->
         OnLauncherCreated();
 
-    ShellDelegate* delegate = shell->delegate();
-    if (delegate)
-      launcher_->SetVisible(delegate->IsSessionStarted());
+    launcher_->SetVisible(
+        shell->session_state_delegate()->IsActiveUserSessionStarted());
 
     Show();
   }
@@ -279,7 +522,7 @@
 }
 
 void ShelfWidget::SetLauncherVisibility(bool visible) {
-  if (launcher_.get())
+  if (launcher_)
     launcher_->SetVisible(visible);
 }
 
@@ -293,6 +536,21 @@
   return delegate_view_->focus_cycler();
 }
 
+void ShelfWidget::ShutdownStatusAreaWidget() {
+  if (status_area_widget_)
+    status_area_widget_->Shutdown();
+  status_area_widget_ = NULL;
+}
+
+void ShelfWidget::SetWidgetBounds(const gfx::Rect& rect) {
+  Widget::SetBounds(rect);
+  delegate_view_->SetWidgetBounds(rect);
+}
+
+void ShelfWidget::ForceUndimming(bool force) {
+  delegate_view_->ForceUndimming(force);
+}
+
 void ShelfWidget::OnWidgetActivationChanged(views::Widget* widget,
                                             bool active) {
   activating_as_fallback_ = false;
@@ -302,10 +560,21 @@
     delegate_view_->GetFocusManager()->ClearFocus();
 }
 
-void ShelfWidget::ShutdownStatusAreaWidget() {
-  if (status_area_widget_)
-    status_area_widget_->Shutdown();
-  status_area_widget_ = NULL;
+int ShelfWidget::GetDimmingAlphaForTest() {
+  if (delegate_view_)
+    return delegate_view_->GetDimmingAlphaForTest();
+  return -1;
+}
+
+gfx::Rect ShelfWidget::GetDimmerBoundsForTest() {
+  if (delegate_view_)
+    return delegate_view_->GetDimmerBoundsForTest();
+  return gfx::Rect();
+}
+
+void ShelfWidget::DisableDimmingAnimationsForTest() {
+  DCHECK(delegate_view_);
+  return delegate_view_->disable_dimming_animations_for_test();
 }
 
 }  // namespace ash
diff --git a/ash/shelf/shelf_widget.h b/ash/shelf/shelf_widget.h
index 98b0d19..e7cbcf1 100644
--- a/ash/shelf/shelf_widget.h
+++ b/ash/shelf/shelf_widget.h
@@ -72,15 +72,32 @@
   // when no other windows are visible.
   void WillActivateAsFallback() { activating_as_fallback_ = true; }
 
-  // Overridden from views::WidgetObserver:
-  virtual void OnWidgetActivationChanged(
-      views::Widget* widget, bool active) OVERRIDE;
-
   aura::Window* window_container() { return window_container_; }
 
   // TODO(harrym): Remove when Status Area Widget is a child view.
   void ShutdownStatusAreaWidget();
 
+  // Set the bounds of the widget and the dim shelf overlay.
+  void SetWidgetBounds(const gfx::Rect& rect);
+
+  // Force the shelf to be presented in an undimmed state.
+  void ForceUndimming(bool force);
+
+  // Overridden from views::WidgetObserver:
+  virtual void OnWidgetActivationChanged(
+      views::Widget* widget, bool active) OVERRIDE;
+
+  // A function to test the current alpha used by the dimming bar. If there is
+  // no dimmer active, the function will return -1.
+  int GetDimmingAlphaForTest();
+
+  // A function to test the bounds of the dimming bar. Returns gfx::Rect() if
+  // the dimmer is inactive.
+  gfx::Rect GetDimmerBoundsForTest();
+
+  // Disable dimming animations for running tests.
+  void DisableDimmingAnimationsForTest();
+
  private:
   class DelegateView;
 
diff --git a/ash/shelf/shelf_widget_unittest.cc b/ash/shelf/shelf_widget_unittest.cc
index bea1c64..c0d6119 100644
--- a/ash/shelf/shelf_widget_unittest.cc
+++ b/ash/shelf/shelf_widget_unittest.cc
@@ -76,13 +76,13 @@
     SCOPED_TRACE("Single Right");
     TestLauncherAlignment(Shell::GetPrimaryRootWindow(),
                           SHELF_ALIGNMENT_RIGHT,
-                          "0,0 348x400");
+                          "0,0 352x400");
   }
   {
     SCOPED_TRACE("Single Left");
     TestLauncherAlignment(Shell::GetPrimaryRootWindow(),
                           SHELF_ALIGNMENT_LEFT,
-                          "52,0 348x400");
+                          "48,0 352x400");
   }
   UpdateDisplay("300x300,500x500");
   Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
@@ -96,13 +96,13 @@
     SCOPED_TRACE("Primary Right");
     TestLauncherAlignment(root_windows[0],
                           SHELF_ALIGNMENT_RIGHT,
-                          "0,0 248x300");
+                          "0,0 252x300");
   }
   {
     SCOPED_TRACE("Primary Left");
     TestLauncherAlignment(root_windows[0],
                           SHELF_ALIGNMENT_LEFT,
-                          "52,0 248x300");
+                          "48,0 252x300");
   }
   if (Shell::IsLauncherPerDisplayEnabled()) {
     {
@@ -115,13 +115,13 @@
       SCOPED_TRACE("Secondary Right");
       TestLauncherAlignment(root_windows[1],
                             SHELF_ALIGNMENT_RIGHT,
-                            "300,0 448x500");
+                            "300,0 452x500");
     }
     {
       SCOPED_TRACE("Secondary Left");
       TestLauncherAlignment(root_windows[1],
                             SHELF_ALIGNMENT_LEFT,
-                            "352,0 448x500");
+                            "348,0 452x500");
     }
   }
 }
diff --git a/ash/shell.cc b/ash/shell.cc
index 3db067c..4be78a2 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -28,6 +28,7 @@
 #include "ash/magnifier/partial_magnification_controller.h"
 #include "ash/root_window_controller.h"
 #include "ash/screen_ash.h"
+#include "ash/session_state_delegate.h"
 #include "ash/shelf/shelf_layout_manager.h"
 #include "ash/shelf/shelf_widget.h"
 #include "ash/shell_delegate.h"
@@ -36,7 +37,6 @@
 #include "ash/system/status_area_widget.h"
 #include "ash/system/tray/system_tray_delegate.h"
 #include "ash/system/tray/system_tray_notifier.h"
-#include "ash/touch/touch_observer_hud.h"
 #include "ash/wm/activation_controller.h"
 #include "ash/wm/always_on_top_controller.h"
 #include "ash/wm/app_list_controller.h"
@@ -85,6 +85,8 @@
 #include "ui/gfx/image/image_skia.h"
 #include "ui/gfx/screen.h"
 #include "ui/gfx/size.h"
+#include "ui/keyboard/keyboard.h"
+#include "ui/keyboard/keyboard_util.h"
 #include "ui/message_center/message_center.h"
 #include "ui/views/corewm/compound_event_filter.h"
 #include "ui/views/corewm/corewm_switches.h"
@@ -105,7 +107,7 @@
 #include "ash/accelerators/nested_dispatcher_controller.h"
 #endif
 
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) && defined(USE_X11)
 #include "ash/ash_constants.h"
 #include "ash/display/display_change_observer_x11.h"
 #include "ash/display/display_error_dialog.h"
@@ -199,7 +201,7 @@
       active_root_window_(NULL),
       delegate_(delegate),
       activation_client_(NULL),
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) && defined(USE_X11)
       output_configurator_(new chromeos::OutputConfigurator()),
 #endif  // defined(OS_CHROMEOS)
       native_cursor_manager_(new AshNativeCursorManager),
@@ -214,11 +216,10 @@
   if (!gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE))
     gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_);
   display_controller_.reset(new DisplayController);
-#if defined(OS_CHROMEOS)
-  content::GpuFeatureType blacklisted_features =
-      content::GpuDataManager::GetInstance()->GetBlacklistedFeatures();
+#if defined(OS_CHROMEOS) && defined(USE_X11)
   bool is_panel_fitting_disabled =
-      (blacklisted_features & content::GPU_FEATURE_TYPE_PANEL_FITTING) ||
+      content::GpuDataManager::GetInstance()->IsFeatureBlacklisted(
+          content::GPU_FEATURE_TYPE_PANEL_FITTING) ||
       CommandLine::ForCurrentProcess()->HasSwitch(
           ::switches::kDisablePanelFitting);
 
@@ -247,14 +248,13 @@
   RemovePreTargetHandler(overlay_filter_.get());
   RemovePreTargetHandler(input_method_filter_.get());
   RemovePreTargetHandler(window_modality_controller_.get());
-  if (mouse_cursor_filter_.get())
+  if (mouse_cursor_filter_)
     RemovePreTargetHandler(mouse_cursor_filter_.get());
   RemovePreTargetHandler(system_gesture_filter_.get());
+  RemovePreTargetHandler(event_transformation_handler_.get());
 #if !defined(OS_MACOSX)
   RemovePreTargetHandler(accelerator_filter_.get());
 #endif
-  if (touch_observer_hud_.get())
-    RemovePreTargetHandler(touch_observer_hud_.get());
 
   // TooltipController is deleted with the Shell so removing its references.
   RemovePreTargetHandler(tooltip_controller_.get());
@@ -266,6 +266,7 @@
   app_list_controller_.reset();
 
   // Destroy SystemTrayDelegate before destroying the status area(s).
+  system_tray_delegate_->Shutdown();
   system_tray_delegate_.reset();
 
   // Destroy all child windows including widgets.
@@ -292,6 +293,7 @@
   visibility_controller_.reset();
   launcher_delegate_.reset();
   launcher_model_.reset();
+  video_detector_.reset();
 
   power_button_controller_.reset();
   session_state_controller_.reset();
@@ -307,15 +309,16 @@
   // because they might have registered ActivationChangeObserver.
   activation_controller_.reset();
 
-#if defined(OS_CHROMEOS)
-  if (display_change_observer_.get())
+#if defined(OS_CHROMEOS) && defined(USE_X11)
+   if (display_change_observer_)
     output_configurator_->RemoveObserver(display_change_observer_.get());
-  if (output_configurator_animation_.get())
+  if (output_configurator_animation_)
     output_configurator_->RemoveObserver(output_configurator_animation_.get());
-  if (display_error_observer_.get())
+  if (display_error_observer_)
     output_configurator_->RemoveObserver(display_error_observer_.get());
   base::MessagePumpAuraX11::Current()->RemoveDispatcherForRootWindow(
       output_configurator());
+  display_change_observer_.reset();
 #endif  // defined(OS_CHROMEOS)
 
   DCHECK(instance_ == this);
@@ -416,9 +419,15 @@
   return !command_line->HasSwitch(switches::kAshDisableLauncherPerDisplay);
 }
 
+// static
+bool Shell::IsForcedMaximizeMode() {
+  CommandLine* command_line = CommandLine::ForCurrentProcess();
+  return command_line->HasSwitch(switches::kForcedMaximizeMode);
+}
+
 void Shell::Init() {
   delegate_->PreInit();
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) && defined(USE_X11)
   output_configurator_animation_.reset(
       new internal::OutputConfiguratorAnimation());
   output_configurator_->AddObserver(output_configurator_animation_.get());
@@ -429,7 +438,7 @@
     output_configurator_->AddObserver(display_change_observer_.get());
     display_error_observer_.reset(new internal::DisplayErrorObserver());
     output_configurator_->AddObserver(display_error_observer_.get());
-    output_configurator_->set_delegate(display_change_observer_.get());
+    output_configurator_->set_state_controller(display_change_observer_.get());
     output_configurator_->Start();
     display_change_observer_->OnDisplayModeChanged();
   }
@@ -506,6 +515,11 @@
 
   capture_controller_.reset(new internal::CaptureController);
 
+  // The keyboard system must be initialized before the RootWindowController is
+  // created.
+  if (keyboard::IsKeyboardEnabled())
+    keyboard::InitializeKeyboard();
+
   internal::RootWindowController* root_window_controller =
       new internal::RootWindowController(root_window);
   root_window_controller->CreateContainers();
@@ -522,11 +536,6 @@
       session_state_controller_.get()));
   AddShellObserver(session_state_controller_.get());
 
-  if (command_line->HasSwitch(switches::kAshTouchHud)) {
-    touch_observer_hud_.reset(new internal::TouchObserverHUD);
-    AddPreTargetHandler(touch_observer_hud_.get());
-  }
-
   mouse_cursor_filter_.reset(new internal::MouseCursorEventFilter());
   AddPreTargetHandler(mouse_cursor_filter_.get());
 
@@ -561,12 +570,14 @@
   // This controller needs to be set before SetupManagedWindowMode.
   desktop_background_controller_.reset(new DesktopBackgroundController());
   user_wallpaper_delegate_.reset(delegate_->CreateUserWallpaperDelegate());
-  if (!user_wallpaper_delegate_.get())
+  if (!user_wallpaper_delegate_)
     user_wallpaper_delegate_.reset(new DummyUserWallpaperDelegate());
 
   // StatusAreaWidget uses Shell's CapsLockDelegate.
   caps_lock_delegate_.reset(delegate_->CreateCapsLockDelegate());
 
+  session_state_delegate_.reset(delegate_->CreateSessionStateDelegate());
+
   if (!command_line->HasSwitch(views::corewm::switches::kNoDropShadows)) {
     resize_shadow_controller_.reset(new internal::ResizeShadowController());
     shadow_controller_.reset(
@@ -578,7 +589,7 @@
 
   // Initialize system_tray_delegate_ before initializing StatusAreaWidget.
   system_tray_delegate_.reset(delegate()->CreateSystemTrayDelegate());
-  if (!system_tray_delegate_.get())
+  if (!system_tray_delegate_)
     system_tray_delegate_.reset(SystemTrayDelegate::CreateDummyDelegate());
 
   // Creates StatusAreaWidget.
@@ -610,11 +621,11 @@
 }
 
 void Shell::ShowContextMenu(const gfx::Point& location_in_screen) {
-  // No context menus if user have not logged in.
-  if (!delegate_->IsUserLoggedIn())
+  // No context menus if there is no session with an active user.
+  if (!session_state_delegate_->HasActiveUser())
     return;
   // No context menus when screen is locked.
-  if (IsScreenLocked())
+  if (session_state_delegate_->IsScreenLocked())
     return;
 
   aura::RootWindow* root =
@@ -634,7 +645,7 @@
   // If the context window is not given, show it on the active root window.
   if (!window)
     window = GetActiveRootWindow();
-  if (!app_list_controller_.get())
+  if (!app_list_controller_)
     app_list_controller_.reset(new internal::AppListController);
   app_list_controller_->SetVisible(!app_list_controller_->IsVisible(), window);
 }
@@ -648,14 +659,6 @@
   return app_list_controller_.get() ? app_list_controller_->GetWindow() : NULL;
 }
 
-bool Shell::CanLockScreen() {
-  return delegate_->CanLockScreen();
-}
-
-bool Shell::IsScreenLocked() const {
-  return delegate_->IsScreenLocked();
-}
-
 bool Shell::IsSystemModalWindowOpen() const {
   if (simulate_modal_window_open_for_testing_)
     return true;
@@ -793,7 +796,7 @@
 }
 
 void Shell::CreateModalBackground(aura::Window* window) {
-  if (!modality_filter_.get()) {
+  if (!modality_filter_) {
     modality_filter_.reset(new internal::SystemModalContainerEventFilter(this));
     AddPreTargetHandler(modality_filter_.get());
   }
@@ -835,7 +838,7 @@
 }
 
 LauncherDelegate* Shell::GetLauncherDelegate() {
-  if (!launcher_delegate_.get()) {
+  if (!launcher_delegate_) {
     launcher_model_.reset(new LauncherModel);
     launcher_delegate_.reset(
         delegate_->CreateLauncherDelegate(launcher_model_.get()));
@@ -894,11 +897,11 @@
   aura::client::SetTooltipClient(root_window, tooltip_controller_.get());
   aura::client::SetEventClient(root_window, event_client_.get());
 
-  if (nested_dispatcher_controller_.get()) {
+  if (nested_dispatcher_controller_) {
     aura::client::SetDispatcherClient(root_window,
                                       nested_dispatcher_controller_.get());
   }
-  if (user_action_client_.get())
+  if (user_action_client_)
     aura::client::SetUserActionClient(root_window, user_action_client_.get());
 
   root_window->SetCursor(ui::kCursorPointer);
diff --git a/ash/shell.h b/ash/shell.h
index 7e3fab3..b8a0ce9 100644
--- a/ash/shell.h
+++ b/ash/shell.h
@@ -82,6 +82,7 @@
 class RootWindowHostFactory;
 class ScreenAsh;
 class SessionStateController;
+class SessionStateDelegate;
 class ShellDelegate;
 class ShellObserver;
 class SystemTray;
@@ -149,6 +150,7 @@
 
   // A shell must be explicitly created so that it can call |Init()| with the
   // delegate set. |delegate| can be NULL (if not required for initialization).
+  // Takes ownership of |delegate|.
   static Shell* CreateInstance(ShellDelegate* delegate);
 
   // Should never be called before |CreateInstance()|.
@@ -198,6 +200,10 @@
   // True if "launcher per display" feature  is enabled.
   static bool IsLauncherPerDisplayEnabled();
 
+  // True if an experimental maximize mode is enabled which forces browser and
+  // application windows to be maximized only.
+  static bool IsForcedMaximizeMode();
+
   void set_active_root_window(aura::RootWindow* active_root_window) {
     active_root_window_ = active_root_window;
   }
@@ -217,13 +223,6 @@
   // Returns app list window or NULL if it is not visible.
   aura::Window* GetAppListWindow();
 
-  // Returns true if a user is logged in whose session can be locked (i.e. the
-  // user has a password with which to unlock the session).
-  bool CanLockScreen();
-
-  // Returns true if the screen is locked.
-  bool IsScreenLocked() const;
-
   // Returns true if a system-modal dialog window is currently open.
   bool IsSystemModalWindowOpen() const;
 
@@ -280,15 +279,15 @@
   internal::DisplayManager* display_manager() {
     return display_manager_.get();
   }
+  views::corewm::InputMethodEventFilter* input_method_filter() {
+    return input_method_filter_.get();
+  }
   views::corewm::CompoundEventFilter* env_filter() {
     return env_filter_.get();
   }
   views::corewm::TooltipController* tooltip_controller() {
     return tooltip_controller_.get();
   }
-  internal::TouchObserverHUD* touch_observer_hud() {
-    return touch_observer_hud_.get();
-  }
   internal::EventRewriterEventFilter* event_rewriter_filter() {
     return event_rewriter_filter_.get();
   }
@@ -337,6 +336,10 @@
     return caps_lock_delegate_.get();
   }
 
+  SessionStateDelegate* session_state_delegate() {
+    return session_state_delegate_.get();
+  }
+
   HighContrastController* high_contrast_controller() {
     return high_contrast_controller_.get();
   }
@@ -424,7 +427,7 @@
   // Starts the animation that occurs on first login.
   void DoInitialWorkspaceAnimation();
 
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) && defined(USE_X11)
   // TODO(oshima): Move these objects to DisplayController.
   chromeos::OutputConfigurator* output_configurator() {
     return output_configurator_.get();
@@ -435,7 +438,7 @@
   internal::DisplayErrorObserver* display_error_observer() {
     return display_error_observer_.get();
   }
-#endif  // defined(OS_CHROMEOS)
+#endif  // defined(OS_CHROMEOS) && defined(USE_X11)
 
   RootWindowHostFactory* root_window_host_factory() {
     return root_window_host_factory_.get();
@@ -458,6 +461,7 @@
 
   typedef std::pair<aura::Window*, gfx::Rect> WindowAndBoundsPair;
 
+  // Takes ownership of |delegate|.
   explicit Shell(ShellDelegate* delegate);
   virtual ~Shell();
 
@@ -506,6 +510,7 @@
   scoped_ptr<SystemTrayNotifier> system_tray_notifier_;
   scoped_ptr<UserWallpaperDelegate> user_wallpaper_delegate_;
   scoped_ptr<CapsLockDelegate> caps_lock_delegate_;
+  scoped_ptr<SessionStateDelegate> session_state_delegate_;
   scoped_ptr<LauncherDelegate> launcher_delegate_;
 
   scoped_ptr<LauncherModel> launcher_model_;
@@ -561,13 +566,9 @@
   // An event filter that pre-handles all key events to send them to an IME.
   scoped_ptr<views::corewm::InputMethodEventFilter> input_method_filter_;
 
-  // An event filter that silently keeps track of all touch events and controls
-  // a heads-up display. This is enabled only if --ash-touch-hud flag is used.
-  scoped_ptr<internal::TouchObserverHUD> touch_observer_hud_;
-
   scoped_ptr<internal::DisplayManager> display_manager_;
 
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) && defined(USE_X11)
   // Controls video output device state.
   scoped_ptr<chromeos::OutputConfigurator> output_configurator_;
   scoped_ptr<internal::OutputConfiguratorAnimation>
@@ -576,7 +577,7 @@
 
   // Receives output change events and udpates the display manager.
   scoped_ptr<internal::DisplayChangeObserverX11> display_change_observer_;
-#endif  // defined(OS_CHROMEOS)
+#endif  // defined(OS_CHROMEOS) && defined(USE_X11)
 
   // |native_cursor_manager_| is owned by |cursor_manager_|, but we keep a
   // pointer to vend to test code.
diff --git a/ash/shell/app_list.cc b/ash/shell/app_list.cc
index ebf2f87..7ee4d38 100644
--- a/ash/shell/app_list.cc
+++ b/ash/shell/app_list.cc
@@ -4,10 +4,10 @@
 
 #include <string>
 
+#include "ash/session_state_delegate.h"
 #include "ash/shell.h"
 #include "ash/shell/example_factory.h"
 #include "ash/shell/toplevel_window.h"
-#include "ash/shell_delegate.h"
 #include "base/basictypes.h"
 #include "base/i18n/case_conversion.h"
 #include "base/i18n/string_search.h"
@@ -109,7 +109,7 @@
         break;
       }
       case LOCK_SCREEN: {
-        Shell::GetInstance()->delegate()->LockScreen();
+        Shell::GetInstance()->session_state_delegate()->LockScreen();
         break;
       }
       case WIDGETS_WINDOW: {
@@ -146,11 +146,11 @@
 class ExampleSearchResult : public app_list::SearchResult {
  public:
   ExampleSearchResult(WindowTypeLauncherItem::Type type,
-                      const string16& query)
+                      const base::string16& query)
       : type_(type) {
     SetIcon(WindowTypeLauncherItem::GetIcon(type_));
 
-    string16 title = UTF8ToUTF16(WindowTypeLauncherItem::GetTitle(type_));
+    base::string16 title = UTF8ToUTF16(WindowTypeLauncherItem::GetTitle(type_));
     set_title(title);
 
     Tags title_tags;
@@ -160,7 +160,7 @@
     // Note the following is not a proper way to handle i18n string.
     title = base::i18n::ToLower(title);
     size_t match_start = title.find(query);
-    while (match_start != string16::npos) {
+    while (match_start != base::string16::npos) {
       title_tags.push_back(Tag(Tag::MATCH,
                                match_start,
                                match_start + match_len));
@@ -168,7 +168,8 @@
     }
     set_title_tags(title_tags);
 
-    string16 details = UTF8ToUTF16(WindowTypeLauncherItem::GetDetails(type_));
+    base::string16 details =
+        UTF8ToUTF16(WindowTypeLauncherItem::GetDetails(type_));
     set_details(details);
     Tags details_tags;
     details_tags.push_back(Tag(Tag::DIM, 0, details.length()));
@@ -199,7 +200,7 @@
   }
 
   gfx::ImageSkia CreateSearchBoxIcon() {
-    const string16 icon_text = ASCIIToUTF16("ash");
+    const base::string16 icon_text = ASCIIToUTF16("ash");
     const gfx::Size icon_size(32, 32);
 
     gfx::Canvas canvas(icon_size, ui::SCALE_FACTOR_100P,
@@ -249,7 +250,7 @@
   }
 
   virtual void StartSearch() OVERRIDE {
-    string16 query;
+    base::string16 query;
     TrimWhitespace(model_->search_box()->text(), TRIM_ALL, &query);
     query = base::i18n::ToLower(query);
 
@@ -263,7 +264,8 @@
       WindowTypeLauncherItem::Type type =
           static_cast<WindowTypeLauncherItem::Type>(i);
 
-      string16 title = UTF8ToUTF16(WindowTypeLauncherItem::GetTitle(type));
+      base::string16 title =
+          UTF8ToUTF16(WindowTypeLauncherItem::GetTitle(type));
       if (base::i18n::StringSearchIgnoringCaseAndAccents(
               query, title, NULL, NULL)) {
         model_->results()->Add(new ExampleSearchResult(type, query));
@@ -293,19 +295,19 @@
     return gfx::ImageSkia();
   }
 
-  virtual string16 GetCurrentUserName() {
-    return string16();
+  virtual base::string16 GetCurrentUserName() OVERRIDE {
+    return base::string16();
   }
 
-  virtual string16 GetCurrentUserEmail() {
-    return string16();
+  virtual base::string16 GetCurrentUserEmail() OVERRIDE {
+    return base::string16();
   }
 
-  virtual void OpenSettings() {
+  virtual void OpenSettings() OVERRIDE {
     // Nothing needs to be done.
   }
 
-  virtual void OpenFeedback() {
+  virtual void OpenFeedback() OVERRIDE {
     // Nothing needs to be done.
   }
 
diff --git a/ash/shell/bubble.cc b/ash/shell/bubble.cc
index 649202d..1442bef 100644
--- a/ash/shell/bubble.cc
+++ b/ash/shell/bubble.cc
@@ -13,9 +13,9 @@
 namespace shell {
 
 struct BubbleConfig {
-  string16 label;
+  base::string16 label;
   views::View* anchor_view;
-  views::BubbleBorder::ArrowLocation arrow;
+  views::BubbleBorder::Arrow arrow;
 };
 
 class ExampleBubbleDelegateView : public views::BubbleDelegateView {
@@ -31,7 +31,7 @@
   }
 
  private:
-  string16 label_;
+  base::string16 label_;
 };
 
 void CreatePointyBubble(views::View* anchor_view) {
diff --git a/ash/shell/content_client/shell_browser_main_parts.cc b/ash/shell/content_client/shell_browser_main_parts.cc
index cb5975f..b2393e6 100644
--- a/ash/shell/content_client/shell_browser_main_parts.cc
+++ b/ash/shell/content_client/shell_browser_main_parts.cc
@@ -12,7 +12,7 @@
 #include "base/command_line.h"
 #include "base/i18n/icu_util.h"
 #include "base/message_loop.h"
-#include "base/string_number_conversions.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/threading/thread.h"
 #include "base/threading/thread_restrictions.h"
 #include "content/public/common/content_switches.h"
@@ -35,8 +35,8 @@
 #include "ui/message_center/message_center.h"
 #endif
 
-#if defined(OS_LINUX)
-#include "ui/base/touch/touch_factory.h"
+#if defined(USE_X11)
+#include "ui/base/touch/touch_factory_x11.h"
 #endif
 
 #if defined(OS_CHROMEOS)
@@ -89,7 +89,7 @@
 
 #if !defined(OS_MACOSX)
 void ShellBrowserMainParts::PreMainMessageLoopStart() {
-#if defined(OS_LINUX)
+#if defined(USE_X11)
   ui::TouchFactory::SetTouchDeviceListFromCommandLine();
 #endif
 }
@@ -135,7 +135,6 @@
 }
 
 void ShellBrowserMainParts::PostMainMessageLoopRun() {
-  browser_context_.reset();
   gfx::Screen* screen = Shell::GetInstance()->GetScreen();
   screen->RemoveObserver(window_watcher_.get());
 
@@ -149,10 +148,16 @@
   message_center::MessageCenter::Shutdown();
 #endif
   aura::Env::DeleteInstance();
+
+  // The keyboard may have created a WebContents. The WebContents is destroyed
+  // with the UI, and it needs the BrowserContext to be alive during its
+  // destruction. So destroy all of the UI elements before destroying the
+  // browser context.
+  browser_context_.reset();
 }
 
 bool ShellBrowserMainParts::MainMessageLoopRun(int* result_code) {
-  MessageLoopForUI::current()->Run();
+  base::MessageLoopForUI::current()->Run();
   return true;
 }
 
diff --git a/ash/shell/content_client/shell_content_browser_client.cc b/ash/shell/content_client/shell_content_browser_client.cc
index 629d4b5..93fc834 100644
--- a/ash/shell/content_client/shell_content_browser_client.cc
+++ b/ash/shell/content_client/shell_content_browser_client.cc
@@ -5,6 +5,7 @@
 #include "ash/shell/content_client/shell_content_browser_client.h"
 
 #include "ash/shell/content_client/shell_browser_main_parts.h"
+#include "content/shell/shell_browser_context.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 
 namespace ash {
@@ -23,6 +24,14 @@
   return shell_browser_main_parts_;
 }
 
+net::URLRequestContextGetter* ShellContentBrowserClient::CreateRequestContext(
+    content::BrowserContext* content_browser_context,
+    content::ProtocolHandlerMap* protocol_handlers) {
+  content::ShellBrowserContext* shell_context =
+      static_cast<content::ShellBrowserContext*>(content_browser_context);
+  return shell_context->CreateRequestContext(protocol_handlers);
+}
+
 content::ShellBrowserContext* ShellContentBrowserClient::browser_context() {
   return shell_browser_main_parts_->browser_context();
 }
diff --git a/ash/shell/content_client/shell_content_browser_client.h b/ash/shell/content_client/shell_content_browser_client.h
index f4df45e..d90909a 100644
--- a/ash/shell/content_client/shell_content_browser_client.h
+++ b/ash/shell/content_client/shell_content_browser_client.h
@@ -29,6 +29,9 @@
   // Overridden from content::ContentBrowserClient:
   virtual content::BrowserMainParts* CreateBrowserMainParts(
       const content::MainFunctionParams& parameters) OVERRIDE;
+  virtual net::URLRequestContextGetter* CreateRequestContext(
+      content::BrowserContext* browser_context,
+      content::ProtocolHandlerMap* protocol_handlers) OVERRIDE;
 
   content::ShellBrowserContext* browser_context();
 
diff --git a/ash/shell/content_client/shell_main_delegate.cc b/ash/shell/content_client/shell_main_delegate.cc
index c356e45..014fae1 100644
--- a/ash/shell/content_client/shell_main_delegate.cc
+++ b/ash/shell/content_client/shell_main_delegate.cc
@@ -6,11 +6,8 @@
 
 #include "ash/shell/content_client/shell_content_browser_client.h"
 #include "base/command_line.h"
-#include "base/files/file_path.h"
-#include "base/path_service.h"
 #include "content/public/common/content_switches.h"
 #include "ui/base/resource/resource_bundle.h"
-#include "ui/base/ui_base_paths.h"
 
 namespace ash {
 namespace shell {
diff --git a/ash/shell/launcher_delegate_impl.cc b/ash/shell/launcher_delegate_impl.cc
index fd52c34..b38dee3 100644
--- a/ash/shell/launcher_delegate_impl.cc
+++ b/ash/shell/launcher_delegate_impl.cc
@@ -29,10 +29,11 @@
   ash::shell::ToplevelWindow::CreateToplevelWindow(create_params);
 }
 
-void LauncherDelegateImpl::ItemClicked(const ash::LauncherItem& item,
+void LauncherDelegateImpl::ItemSelected(const ash::LauncherItem& item,
                                        const ui::Event& event) {
   aura::Window* window = watcher_->GetWindowByID(item.id);
-  ash::launcher::MoveToEventRootIfPanel(window, event);
+  if (window->type() == aura::client::WINDOW_TYPE_PANEL)
+    ash::wm::MoveWindowToEventRoot(window, event);
   window->Show();
   ash::wm::ActivateWindow(window);
 }
@@ -41,7 +42,7 @@
   return IDR_AURA_LAUNCHER_BROWSER_SHORTCUT;
 }
 
-string16 LauncherDelegateImpl::GetTitle(const ash::LauncherItem& item) {
+base::string16 LauncherDelegateImpl::GetTitle(const ash::LauncherItem& item) {
   return watcher_->GetWindowByID(item.id)->title();
 }
 
@@ -69,5 +70,15 @@
   return true;
 }
 
+void LauncherDelegateImpl::OnLauncherCreated(Launcher* launcher) {
+}
+
+void LauncherDelegateImpl::OnLauncherDestroyed(Launcher* launcher) {
+}
+
+bool LauncherDelegateImpl::IsPerAppLauncher() {
+  return false;
+}
+
 }  // namespace shell
 }  // namespace ash
diff --git a/ash/shell/launcher_delegate_impl.h b/ash/shell/launcher_delegate_impl.h
index edf58e8..e57b5b4 100644
--- a/ash/shell/launcher_delegate_impl.h
+++ b/ash/shell/launcher_delegate_impl.h
@@ -26,10 +26,10 @@
 
   // LauncherDelegate overrides:
   virtual void OnBrowserShortcutClicked(int event_flags) OVERRIDE;
-  virtual void ItemClicked(const ash::LauncherItem& item,
+  virtual void ItemSelected(const ash::LauncherItem& item,
                            const ui::Event& event) OVERRIDE;
   virtual int GetBrowserShortcutResourceId() OVERRIDE;
-  virtual string16 GetTitle(const ash::LauncherItem& item) OVERRIDE;
+  virtual base::string16 GetTitle(const ash::LauncherItem& item) OVERRIDE;
   virtual ui::MenuModel* CreateContextMenu(
       const ash::LauncherItem& item,
       aura::RootWindow* root) OVERRIDE;
@@ -39,6 +39,9 @@
   virtual ash::LauncherID GetIDByWindow(aura::Window* window) OVERRIDE;
   virtual bool IsDraggable(const ash::LauncherItem& item) OVERRIDE;
   virtual bool ShouldShowTooltip(const LauncherItem& item) OVERRIDE;
+  virtual void OnLauncherCreated(Launcher* launcher) OVERRIDE;
+  virtual void OnLauncherDestroyed(Launcher* launcher) OVERRIDE;
+  virtual bool IsPerAppLauncher() OVERRIDE;
 
  private:
   // Used to update Launcher. Owned by main.
diff --git a/ash/shell/lock_view.cc b/ash/shell/lock_view.cc
index 5390ea7..95691b0 100644
--- a/ash/shell/lock_view.cc
+++ b/ash/shell/lock_view.cc
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "ash/session_state_delegate.h"
 #include "ash/shell.h"
-#include "ash/shell_delegate.h"
 #include "ash/shell_window_ids.h"
 #include "ash/shell/example_factory.h"
 #include "base/utf_string_conversions.h"
@@ -24,8 +24,8 @@
 class LockView : public views::WidgetDelegateView,
                  public views::ButtonListener {
  public:
-  LockView() : unlock_button_(ALLOW_THIS_IN_INITIALIZER_LIST(
-                   new views::LabelButton(this, ASCIIToUTF16("Unlock")))) {
+  LockView()
+      : unlock_button_(new views::LabelButton(this, ASCIIToUTF16("Unlock"))) {
     unlock_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);
     AddChildView(unlock_button_);
     unlock_button_->set_focusable(true);
@@ -41,7 +41,7 @@
   // Overridden from views::View:
   virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
     canvas->FillRect(GetLocalBounds(), SK_ColorYELLOW);
-    string16 text = ASCIIToUTF16("LOCKED!");
+    base::string16 text = ASCIIToUTF16("LOCKED!");
     int string_width = font_.GetStringWidth(text);
     canvas->DrawStringInt(text, font_, SK_ColorRED, (width() - string_width)/ 2,
                           (height() - font_.GetHeight()) / 2,
@@ -64,7 +64,7 @@
 
   // Overridden from views::WidgetDelegateView:
   virtual void WindowClosing() OVERRIDE {
-    Shell::GetInstance()->delegate()->UnlockScreen();
+    Shell::GetInstance()->session_state_delegate()->UnlockScreen();
   }
 
   // Overridden from views::ButtonListener:
diff --git a/ash/shell/panel_window.cc b/ash/shell/panel_window.cc
index 80acf7d..0517b2d 100644
--- a/ash/shell/panel_window.cc
+++ b/ash/shell/panel_window.cc
@@ -65,7 +65,7 @@
   canvas->FillRect(GetLocalBounds(), SK_ColorGREEN);
 }
 
-string16 PanelWindow::GetWindowTitle() const {
+base::string16 PanelWindow::GetWindowTitle() const {
   return ASCIIToUTF16(name_);
 }
 
diff --git a/ash/shell/panel_window.h b/ash/shell/panel_window.h
index 2ac5d68..eefe5e3 100644
--- a/ash/shell/panel_window.h
+++ b/ash/shell/panel_window.h
@@ -37,7 +37,7 @@
   virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
 
   // Overridden from views::WidgetDelegate:
-  virtual string16 GetWindowTitle() const OVERRIDE;
+  virtual base::string16 GetWindowTitle() const OVERRIDE;
   virtual View* GetContentsView() OVERRIDE;
   virtual bool CanResize() const OVERRIDE;
   virtual bool CanMaximize() const OVERRIDE;
diff --git a/ash/shell/shell_delegate_impl.cc b/ash/shell/shell_delegate_impl.cc
index 81b51c6..c5b1332 100644
--- a/ash/shell/shell_delegate_impl.cc
+++ b/ash/shell/shell_delegate_impl.cc
@@ -8,6 +8,8 @@
 
 #include "ash/caps_lock_delegate_stub.h"
 #include "ash/host/root_window_host_factory.h"
+#include "ash/session_state_delegate.h"
+#include "ash/session_state_delegate_stub.h"
 #include "ash/shell/context_menu.h"
 #include "ash/shell/example_factory.h"
 #include "ash/shell/launcher_delegate_impl.h"
@@ -16,14 +18,41 @@
 #include "ash/wm/window_util.h"
 #include "base/message_loop.h"
 #include "ui/aura/window.h"
+#include "ui/keyboard/keyboard_controller_proxy.h"
+#include "ui/views/corewm/input_method_event_filter.h"
 
 namespace ash {
+
+namespace {
+
+class DummyKeyboardControllerProxy : public keyboard::KeyboardControllerProxy {
+ public:
+  DummyKeyboardControllerProxy() {}
+  virtual ~DummyKeyboardControllerProxy() {}
+
+ private:
+  // Overridden from keyboard::KeyboardControllerProxy:
+  virtual content::BrowserContext* GetBrowserContext() OVERRIDE {
+    return Shell::GetInstance()->browser_context();
+  }
+
+  virtual ui::InputMethod* GetInputMethod() OVERRIDE {
+    return Shell::GetInstance()->input_method_filter()->input_method();
+  }
+
+  virtual void OnKeyboardBoundsChanged(const gfx::Rect& new_bounds) OVERRIDE {
+  }
+
+  DISALLOW_COPY_AND_ASSIGN(DummyKeyboardControllerProxy);
+};
+
+}  // namespace
+
 namespace shell {
 
 ShellDelegateImpl::ShellDelegateImpl()
     : watcher_(NULL),
       launcher_delegate_(NULL),
-      locked_(false),
       spoken_feedback_enabled_(false),
       high_contrast_enabled_(false),
       screen_magnifier_enabled_(false),
@@ -39,19 +68,11 @@
     launcher_delegate_->set_watcher(watcher);
 }
 
-bool ShellDelegateImpl::IsUserLoggedIn() const {
-  return true;
-}
-
-bool ShellDelegateImpl::IsSessionStarted() const {
-  return true;
-}
-
-bool ShellDelegateImpl::IsGuestSession() const {
+bool ShellDelegateImpl::IsFirstRunAfterBoot() const {
   return false;
 }
 
-bool ShellDelegateImpl::IsFirstRunAfterBoot() const {
+bool ShellDelegateImpl::IsMultiProfilesEnabled() const {
   return false;
 }
 
@@ -59,25 +80,6 @@
   return false;
 }
 
-bool ShellDelegateImpl::CanLockScreen() const {
-  return true;
-}
-
-void ShellDelegateImpl::LockScreen() {
-  ash::shell::CreateLockScreen();
-  locked_ = true;
-  ash::Shell::GetInstance()->UpdateShelfVisibility();
-}
-
-void ShellDelegateImpl::UnlockScreen() {
-  locked_ = false;
-  ash::Shell::GetInstance()->UpdateShelfVisibility();
-}
-
-bool ShellDelegateImpl::IsScreenLocked() const {
-  return locked_;
-}
-
 void ShellDelegateImpl::PreInit() {
 }
 
@@ -85,7 +87,7 @@
 }
 
 void ShellDelegateImpl::Exit() {
-  MessageLoopForUI::current()->Quit();
+  base::MessageLoopForUI::current()->Quit();
 }
 
 void ShellDelegateImpl::NewTab() {
@@ -98,6 +100,10 @@
   ash::shell::ToplevelWindow::CreateToplevelWindow(create_params);
 }
 
+void ShellDelegateImpl::ToggleFullscreen() {
+  ToggleMaximized();
+}
+
 void ShellDelegateImpl::ToggleMaximized() {
   aura::Window* window = ash::wm::GetActiveWindow();
   if (window)
@@ -116,11 +122,12 @@
 void ShellDelegateImpl::RestoreTab() {
 }
 
-bool ShellDelegateImpl::RotatePaneFocus(Shell::Direction direction) {
-  return true;
+void ShellDelegateImpl::ShowKeyboardOverlay() {
 }
 
-void ShellDelegateImpl::ShowKeyboardOverlay() {
+keyboard::KeyboardControllerProxy*
+    ShellDelegateImpl::CreateKeyboardControllerProxy() {
+  return new DummyKeyboardControllerProxy();
 }
 
 void ShellDelegateImpl::ShowTaskManager() {
@@ -167,6 +174,9 @@
   return false;
 }
 
+void ShellDelegateImpl::SilenceSpokenFeedback() const {
+}
+
 app_list::AppListViewDelegate* ShellDelegateImpl::CreateAppListViewDelegate() {
   return ash::shell::CreateAppListViewDelegate();
 }
@@ -189,6 +199,10 @@
   return new CapsLockDelegateStub;
 }
 
+ash::SessionStateDelegate* ShellDelegateImpl::CreateSessionStateDelegate() {
+  return new SessionStateDelegateStub;
+}
+
 aura::client::UserActionClient* ShellDelegateImpl::CreateUserActionClient() {
   return NULL;
 }
@@ -208,12 +222,14 @@
 void ShellDelegateImpl::HandleMediaPrevTrack() {
 }
 
-string16 ShellDelegateImpl::GetTimeRemainingString(base::TimeDelta delta) {
-  return string16();
+base::string16 ShellDelegateImpl::GetTimeRemainingString(
+    base::TimeDelta delta) {
+  return base::string16();
 }
 
-string16 ShellDelegateImpl::GetTimeDurationLongString(base::TimeDelta delta) {
-  return string16();
+base::string16 ShellDelegateImpl::GetTimeDurationLongString(
+    base::TimeDelta delta) {
+  return base::string16();
 }
 
 void ShellDelegateImpl::SaveScreenMagnifierScale(double scale) {
@@ -231,8 +247,8 @@
   return RootWindowHostFactory::Create();
 }
 
-string16 ShellDelegateImpl::GetProductName() const {
-  return string16();
+base::string16 ShellDelegateImpl::GetProductName() const {
+  return base::string16();
 }
 
 }  // namespace shell
diff --git a/ash/shell/shell_delegate_impl.h b/ash/shell/shell_delegate_impl.h
index 15f61ae..fcb28c8 100644
--- a/ash/shell/shell_delegate_impl.h
+++ b/ash/shell/shell_delegate_impl.h
@@ -10,6 +10,10 @@
 #include "ash/shell_delegate.h"
 #include "base/compiler_specific.h"
 
+namespace keyboard {
+class KeyboardControllerProxy;
+}
+
 namespace ash {
 namespace shell {
 
@@ -23,27 +27,23 @@
 
   void SetWatcher(WindowWatcher* watcher);
 
-  virtual bool IsUserLoggedIn() const OVERRIDE;
-  virtual bool IsSessionStarted() const OVERRIDE;
-  virtual bool IsGuestSession() const OVERRIDE;
   virtual bool IsFirstRunAfterBoot() const OVERRIDE;
+  virtual bool IsMultiProfilesEnabled() const OVERRIDE;
   virtual bool IsRunningInForcedAppMode() const OVERRIDE;
-  virtual bool CanLockScreen() const OVERRIDE;
-  virtual void LockScreen() OVERRIDE;
-  virtual void UnlockScreen() OVERRIDE;
-  virtual bool IsScreenLocked() const OVERRIDE;
   virtual void PreInit() OVERRIDE;
   virtual void Shutdown() OVERRIDE;
   virtual void Exit() OVERRIDE;
   virtual void NewTab() OVERRIDE;
   virtual void NewWindow(bool incognito) OVERRIDE;
+  virtual void ToggleFullscreen() OVERRIDE;
   virtual void ToggleMaximized() OVERRIDE;
   virtual void OpenFileManager(bool as_dialog) OVERRIDE;
   virtual void OpenCrosh() OVERRIDE;
   virtual void OpenMobileSetup(const std::string& service_path) OVERRIDE;
   virtual void RestoreTab() OVERRIDE;
-  virtual bool RotatePaneFocus(Shell::Direction direction) OVERRIDE;
   virtual void ShowKeyboardOverlay() OVERRIDE;
+  virtual keyboard::KeyboardControllerProxy*
+      CreateKeyboardControllerProxy() OVERRIDE;
   virtual void ShowTaskManager() OVERRIDE;
   virtual content::BrowserContext* GetCurrentBrowserContext() OVERRIDE;
   virtual void ToggleSpokenFeedback(
@@ -56,26 +56,29 @@
   virtual bool IsMagnifierEnabled() const OVERRIDE;
   virtual MagnifierType GetMagnifierType() const OVERRIDE;
   virtual bool ShouldAlwaysShowAccessibilityMenu() const OVERRIDE;
+  virtual void SilenceSpokenFeedback() const OVERRIDE;
   virtual app_list::AppListViewDelegate* CreateAppListViewDelegate() OVERRIDE;
   virtual ash::LauncherDelegate* CreateLauncherDelegate(
       ash::LauncherModel* model) OVERRIDE;
   virtual ash::SystemTrayDelegate* CreateSystemTrayDelegate() OVERRIDE;
   virtual ash::UserWallpaperDelegate* CreateUserWallpaperDelegate() OVERRIDE;
   virtual ash::CapsLockDelegate* CreateCapsLockDelegate() OVERRIDE;
+  virtual ash::SessionStateDelegate* CreateSessionStateDelegate() OVERRIDE;
   virtual aura::client::UserActionClient* CreateUserActionClient() OVERRIDE;
   virtual void OpenFeedbackPage() OVERRIDE;
   virtual void RecordUserMetricsAction(UserMetricsAction action) OVERRIDE;
   virtual void HandleMediaNextTrack() OVERRIDE;
   virtual void HandleMediaPlayPause() OVERRIDE;
   virtual void HandleMediaPrevTrack() OVERRIDE;
-  virtual string16 GetTimeRemainingString(base::TimeDelta delta) OVERRIDE;
-  virtual string16 GetTimeDurationLongString(base::TimeDelta delta) OVERRIDE;
+  virtual base::string16 GetTimeRemainingString(base::TimeDelta delta) OVERRIDE;
+  virtual base::string16 GetTimeDurationLongString(
+      base::TimeDelta delta) OVERRIDE;
   virtual void SaveScreenMagnifierScale(double scale) OVERRIDE;
   virtual double GetSavedScreenMagnifierScale() OVERRIDE;
   virtual ui::MenuModel* CreateContextMenu(
       aura::RootWindow* root_window) OVERRIDE;
   virtual RootWindowHostFactory* CreateRootWindowHostFactory() OVERRIDE;
-  virtual string16 GetProductName() const OVERRIDE;
+  virtual base::string16 GetProductName() const OVERRIDE;
 
  private:
   // Used to update Launcher. Owned by main.
@@ -83,7 +86,6 @@
 
   LauncherDelegateImpl* launcher_delegate_;
 
-  bool locked_;
   bool spoken_feedback_enabled_;
   bool high_contrast_enabled_;
   bool screen_magnifier_enabled_;
diff --git a/ash/shell/toplevel_window.cc b/ash/shell/toplevel_window.cc
index 2a104bb..af18151 100644
--- a/ash/shell/toplevel_window.cc
+++ b/ash/shell/toplevel_window.cc
@@ -55,7 +55,7 @@
   canvas->FillRect(GetLocalBounds(), SK_ColorDKGRAY);
 }
 
-string16 ToplevelWindow::GetWindowTitle() const {
+base::string16 ToplevelWindow::GetWindowTitle() const {
   return params_.persist_across_all_workspaces ?
       ASCIIToUTF16("Examples: Toplevel Window (P)") :
       ASCIIToUTF16("Examples: Toplevel Window");
diff --git a/ash/shell/toplevel_window.h b/ash/shell/toplevel_window.h
index ec398c2..22c23d0 100644
--- a/ash/shell/toplevel_window.h
+++ b/ash/shell/toplevel_window.h
@@ -29,7 +29,7 @@
   virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
 
   // Overridden from views::WidgetDelegate:
-  virtual string16 GetWindowTitle() const OVERRIDE;
+  virtual base::string16 GetWindowTitle() const OVERRIDE;
   virtual View* GetContentsView() OVERRIDE;
   virtual bool CanResize() const OVERRIDE;
   virtual bool CanMaximize() const OVERRIDE;
diff --git a/ash/shell/widgets.cc b/ash/shell/widgets.cc
index 234e5e3..9790a02 100644
--- a/ash/shell/widgets.cc
+++ b/ash/shell/widgets.cc
@@ -36,7 +36,7 @@
 
   // Overridden from views::WidgetDelegate:
   virtual views::View* GetContentsView() OVERRIDE;
-  virtual string16 GetWindowTitle() const OVERRIDE;
+  virtual base::string16 GetWindowTitle() const OVERRIDE;
   virtual bool CanResize() const OVERRIDE;
 
  private:
@@ -119,7 +119,7 @@
   return this;
 }
 
-string16 WidgetsWindow::GetWindowTitle() const {
+base::string16 WidgetsWindow::GetWindowTitle() const {
   return ASCIIToUTF16("Examples: Widgets");
 }
 
diff --git a/ash/shell/window_type_launcher.cc b/ash/shell/window_type_launcher.cc
index 7b710bd..9c1a0b4 100644
--- a/ash/shell/window_type_launcher.cc
+++ b/ash/shell/window_type_launcher.cc
@@ -6,12 +6,12 @@
 
 #include "ash/root_window_controller.h"
 #include "ash/screensaver/screensaver_view.h"
+#include "ash/session_state_delegate.h"
 #include "ash/shelf/shelf_widget.h"
 #include "ash/shell.h"
 #include "ash/shell/example_factory.h"
 #include "ash/shell/panel_window.h"
 #include "ash/shell/toplevel_window.h"
-#include "ash/shell_delegate.h"
 #include "ash/shell_window_ids.h"
 #include "ash/system/status_area_widget.h"
 #include "ash/system/web_notification/web_notification_tray.h"
@@ -23,6 +23,7 @@
 #include "ui/aura/window.h"
 #include "ui/compositor/layer.h"
 #include "ui/gfx/canvas.h"
+#include "ui/message_center/message_center.h"
 #include "ui/message_center/notification_types.h"
 #include "ui/views/controls/button/label_button.h"
 #include "ui/views/controls/menu/menu_item_view.h"
@@ -53,8 +54,7 @@
   explicit ModalWindow(ui::ModalType modal_type)
       : modal_type_(modal_type),
         color_(g_colors[g_color_index]),
-        ALLOW_THIS_IN_INITIALIZER_LIST(open_button_(
-            new views::LabelButton(this, ASCIIToUTF16("Moar!")))) {
+        open_button_(new views::LabelButton(this, ASCIIToUTF16("Moar!"))) {
     ++g_color_index %= arraysize(g_colors);
     open_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);
     AddChildView(open_button_);
@@ -92,7 +92,7 @@
   virtual bool CanResize() const OVERRIDE {
     return true;
   }
-  virtual string16 GetWindowTitle() const OVERRIDE {
+  virtual base::string16 GetWindowTitle() const OVERRIDE {
     return ASCIIToUTF16("Modal Window");
   }
   virtual ui::ModalType GetModalType() const OVERRIDE {
@@ -157,7 +157,7 @@
   virtual bool CanResize() const OVERRIDE {
     return true;
   }
-  virtual string16 GetWindowTitle() const OVERRIDE {
+  virtual base::string16 GetWindowTitle() const OVERRIDE {
     return ASCIIToUTF16("Non-Modal Transient");
   }
   virtual void DeleteDelegate() OVERRIDE {
@@ -199,48 +199,36 @@
 }
 
 WindowTypeLauncher::WindowTypeLauncher()
-    : ALLOW_THIS_IN_INITIALIZER_LIST(create_button_(
-          new views::LabelButton(this, ASCIIToUTF16("Create Window")))),
-      ALLOW_THIS_IN_INITIALIZER_LIST(create_persistant_button_(
-          new views::LabelButton(
-              this, ASCIIToUTF16("Create Persistant Window")))),
-      ALLOW_THIS_IN_INITIALIZER_LIST(panel_button_(
-          new views::LabelButton(this, ASCIIToUTF16("Create Panel")))),
-      ALLOW_THIS_IN_INITIALIZER_LIST(create_nonresizable_button_(
-          new views::LabelButton(
-              this, ASCIIToUTF16("Create Non-Resizable Window")))),
-      ALLOW_THIS_IN_INITIALIZER_LIST(bubble_button_(
-          new views::LabelButton(
-              this, ASCIIToUTF16("Create Pointy Bubble")))),
-      ALLOW_THIS_IN_INITIALIZER_LIST(lock_button_(
-          new views::LabelButton(this, ASCIIToUTF16("Lock Screen")))),
-      ALLOW_THIS_IN_INITIALIZER_LIST(widgets_button_(
-          new views::LabelButton(
-              this, ASCIIToUTF16("Show Example Widgets")))),
-      ALLOW_THIS_IN_INITIALIZER_LIST(system_modal_button_(
-          new views::LabelButton(
-              this, ASCIIToUTF16("Open System Modal Window")))),
-      ALLOW_THIS_IN_INITIALIZER_LIST(window_modal_button_(
-          new views::LabelButton(
-              this, ASCIIToUTF16("Open Window Modal Window")))),
-      ALLOW_THIS_IN_INITIALIZER_LIST(child_modal_button_(
-          new views::LabelButton(
-              this, ASCIIToUTF16("Open Child Modal Window")))),
-      ALLOW_THIS_IN_INITIALIZER_LIST(transient_button_(
-          new views::LabelButton(
-              this, ASCIIToUTF16("Open Non-Modal Transient Window")))),
-      ALLOW_THIS_IN_INITIALIZER_LIST(examples_button_(
-          new views::LabelButton(
-              this, ASCIIToUTF16("Open Views Examples Window")))),
-      ALLOW_THIS_IN_INITIALIZER_LIST(show_hide_window_button_(
-          new views::LabelButton(
-              this, ASCIIToUTF16("Show/Hide a Window")))),
-      ALLOW_THIS_IN_INITIALIZER_LIST(show_screensaver_(
-          new views::LabelButton(
-              this, ASCIIToUTF16("Show the Screensaver [for 5 seconds]")))),
-      ALLOW_THIS_IN_INITIALIZER_LIST(show_web_notification_(
-          new views::LabelButton(
-              this, ASCIIToUTF16("Show a web/app notification")))) {
+    : create_button_(new views::LabelButton(
+          this, ASCIIToUTF16("Create Window"))),
+      create_persistant_button_(new views::LabelButton(
+          this, ASCIIToUTF16("Create Persistant Window"))),
+      panel_button_(new views::LabelButton(
+          this, ASCIIToUTF16("Create Panel"))),
+      create_nonresizable_button_(new views::LabelButton(
+          this, ASCIIToUTF16("Create Non-Resizable Window"))),
+      bubble_button_(new views::LabelButton(
+          this, ASCIIToUTF16("Create Pointy Bubble"))),
+      lock_button_(new views::LabelButton(
+          this, ASCIIToUTF16("Lock Screen"))),
+      widgets_button_(new views::LabelButton(
+          this, ASCIIToUTF16("Show Example Widgets"))),
+      system_modal_button_(new views::LabelButton(
+          this, ASCIIToUTF16("Open System Modal Window"))),
+      window_modal_button_(new views::LabelButton(
+          this, ASCIIToUTF16("Open Window Modal Window"))),
+      child_modal_button_(new views::LabelButton(
+          this, ASCIIToUTF16("Open Child Modal Window"))),
+      transient_button_(new views::LabelButton(
+          this, ASCIIToUTF16("Open Non-Modal Transient Window"))),
+      examples_button_(new views::LabelButton(
+          this, ASCIIToUTF16("Open Views Examples Window"))),
+      show_hide_window_button_(new views::LabelButton(
+          this, ASCIIToUTF16("Show/Hide a Window"))),
+      show_screensaver_(new views::LabelButton(
+          this, ASCIIToUTF16("Show the Screensaver [for 5 seconds]"))),
+      show_web_notification_(new views::LabelButton(
+          this, ASCIIToUTF16("Show a web/app notification"))) {
   create_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);
   create_persistant_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);
   panel_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);
@@ -307,7 +295,7 @@
   return true;
 }
 
-string16 WindowTypeLauncher::GetWindowTitle() const {
+base::string16 WindowTypeLauncher::GetWindowTitle() const {
   return ASCIIToUTF16("Examples: Window Builder");
 }
 
@@ -335,7 +323,7 @@
   } else if (sender == bubble_button_) {
     CreatePointyBubble(sender);
   } else if (sender == lock_button_) {
-    Shell::GetInstance()->delegate()->LockScreen();
+    Shell::GetInstance()->session_state_delegate()->LockScreen();
   } else if (sender == widgets_button_) {
     CreateWidgetsWindow();
   } else if (sender == system_modal_button_) {
diff --git a/ash/shell/window_type_launcher.h b/ash/shell/window_type_launcher.h
index 51376e8..de2159e 100644
--- a/ash/shell/window_type_launcher.h
+++ b/ash/shell/window_type_launcher.h
@@ -48,7 +48,7 @@
   // Overridden from views::WidgetDelegate:
   virtual views::View* GetContentsView() OVERRIDE;
   virtual bool CanResize() const OVERRIDE;
-  virtual string16 GetWindowTitle() const OVERRIDE;
+  virtual base::string16 GetWindowTitle() const OVERRIDE;
   virtual bool CanMaximize() const OVERRIDE;
 
   // Overridden from views::ButtonListener:
diff --git a/ash/shell_delegate.h b/ash/shell_delegate.h
index 530291d..2b9992e 100644
--- a/ash/shell_delegate.h
+++ b/ash/shell_delegate.h
@@ -34,6 +34,10 @@
 class Widget;
 }
 
+namespace keyboard {
+class KeyboardControllerProxy;
+}
+
 namespace ash {
 
 class CapsLockDelegate;
@@ -41,6 +45,7 @@
 class LauncherModel;
 struct LauncherItem;
 class RootWindowHostFactory;
+class SessionStateDelegate;
 class SystemTrayDelegate;
 class UserWallpaperDelegate;
 
@@ -50,6 +55,7 @@
   UMA_ACCEL_LOCK_SCREEN_L,
   UMA_ACCEL_LOCK_SCREEN_LOCK_BUTTON,
   UMA_ACCEL_LOCK_SCREEN_POWER_BUTTON,
+  UMA_ACCEL_FULLSCREEN_F4,
   UMA_ACCEL_MAXIMIZE_RESTORE_F4,
   UMA_ACCEL_NEWTAB_T,
   UMA_ACCEL_NEXTWINDOW_F5,
@@ -58,14 +64,10 @@
   UMA_ACCEL_PREVWINDOW_TAB,
   UMA_ACCEL_SEARCH_LWIN,
   UMA_ACCEL_SHUT_DOWN_POWER_BUTTON,
-  UMA_MAXIMIZE_BUTTON_MAXIMIZE,
-  UMA_MAXIMIZE_BUTTON_MAXIMIZE_LEFT,
-  UMA_MAXIMIZE_BUTTON_MAXIMIZE_RIGHT,
-  UMA_MAXIMIZE_BUTTON_MINIMIZE,
-  UMA_MAXIMIZE_BUTTON_RESTORE,
-  UMA_MAXIMIZE_BUTTON_SHOW_BUBBLE,
+  UMA_CLOSE_THROUGH_CONTEXT_MENU,
   UMA_LAUNCHER_CLICK_ON_APP,
   UMA_LAUNCHER_CLICK_ON_APPLIST_BUTTON,
+  UMA_MINIMIZE_PER_KEY,
   UMA_MOUSE_DOWN,
   UMA_TOGGLE_MAXIMIZE_CAPTION_CLICK,
   UMA_TOGGLE_MAXIMIZE_CAPTION_GESTURE,
@@ -73,6 +75,18 @@
   UMA_TRAY_HELP,
   UMA_TRAY_LOCK_SCREEN,
   UMA_TRAY_SHUT_DOWN,
+  UMA_WINDOW_APP_CLOSE_BUTTON_CLICK,
+  UMA_WINDOW_CLOSE_BUTTON_CLICK,
+  UMA_WINDOW_MAXIMIZE_BUTTON_CLICK_EXIT_FULLSCREEN,
+  UMA_WINDOW_MAXIMIZE_BUTTON_CLICK_MAXIMIZE,
+  UMA_WINDOW_MAXIMIZE_BUTTON_CLICK_MINIMIZE,
+  UMA_WINDOW_MAXIMIZE_BUTTON_CLICK_RESTORE,
+  UMA_WINDOW_MAXIMIZE_BUTTON_MAXIMIZE,
+  UMA_WINDOW_MAXIMIZE_BUTTON_MAXIMIZE_LEFT,
+  UMA_WINDOW_MAXIMIZE_BUTTON_MAXIMIZE_RIGHT,
+  UMA_WINDOW_MAXIMIZE_BUTTON_MINIMIZE,
+  UMA_WINDOW_MAXIMIZE_BUTTON_RESTORE,
+  UMA_WINDOW_MAXIMIZE_BUTTON_SHOW_BUBBLE,
 };
 
 enum AccessibilityNotificationVisibility {
@@ -86,36 +100,17 @@
   // The Shell owns the delegate.
   virtual ~ShellDelegate() {}
 
-  // Returns true if user has logged in.
-  virtual bool IsUserLoggedIn() const = 0;
-
-  // Returns true if we're logged in and browser has been started
-  virtual bool IsSessionStarted() const = 0;
-
-  // Returns true if we're logged in as guest.
-  virtual bool IsGuestSession() const = 0;
-
   // Returns true if this is the first time that the shell has been run after
   // the system has booted.  false is returned after the shell has been
   // restarted, typically due to logging in as a guest or logging out.
   virtual bool IsFirstRunAfterBoot() const = 0;
 
+  // Returns true if multi-profiles feature is enabled.
+  virtual bool IsMultiProfilesEnabled() const = 0;
+
   // Returns true if we're running in forced app mode.
   virtual bool IsRunningInForcedAppMode() const = 0;
 
-  // Returns true if a user is logged in whose session can be locked (i.e. the
-  // user has a password with which to unlock the session).
-  virtual bool CanLockScreen() const = 0;
-
-  // Invoked when a user locks the screen.
-  virtual void LockScreen() = 0;
-
-  // Unlock the screen. Currently used only for tests.
-  virtual void UnlockScreen() = 0;
-
-  // Returns true if the screen is currently locked.
-  virtual bool IsScreenLocked() const = 0;
-
   // Called before processing |Shell::Init()| so that the delegate
   // can perform tasks necessary before the shell is initialized.
   virtual void PreInit() = 0;
@@ -132,6 +127,9 @@
   // Invoked when the user uses Ctrl-N or Ctrl-Shift-N to open a new window.
   virtual void NewWindow(bool incognito) = 0;
 
+  // Invoked when the user uses Shift+F4 to toggle the window fullscreen state.
+  virtual void ToggleFullscreen() = 0;
+
   // Invoked when the user uses F4 to toggle window maximized state.
   virtual void ToggleMaximized() = 0;
 
@@ -147,13 +145,13 @@
   // Invoked when the user uses Shift+Ctrl+T to restore the closed tab.
   virtual void RestoreTab() = 0;
 
-  // Moves keyboard focus to the next pane. Returns false if no browser window
-  // is created.
-  virtual bool RotatePaneFocus(Shell::Direction direction) = 0;
-
   // Shows the keyboard shortcut overlay.
   virtual void ShowKeyboardOverlay() = 0;
 
+  // Create a shell-specific keyboard::KeyboardControllerProxy
+  virtual keyboard::KeyboardControllerProxy*
+      CreateKeyboardControllerProxy() = 0;
+
   // Shows the task manager window.
   virtual void ShowTaskManager() = 0;
 
@@ -189,6 +187,9 @@
   // accessibility features are disabled.
   virtual bool ShouldAlwaysShowAccessibilityMenu() const = 0;
 
+  // Cancel all current and queued speech immediately.
+  virtual void SilenceSpokenFeedback() const = 0;
+
   // Invoked to create an AppListViewDelegate. Shell takes the ownership of
   // the created delegate.
   virtual app_list::AppListViewDelegate* CreateAppListViewDelegate() = 0;
@@ -207,6 +208,9 @@
   // Creates a caps lock delegate. Shell takes ownership of the delegate.
   virtual CapsLockDelegate* CreateCapsLockDelegate() = 0;
 
+  // Creates a session state delegate. Shell takes ownership of the delegate.
+  virtual SessionStateDelegate* CreateSessionStateDelegate() = 0;
+
   // Creates a user action client. Shell takes ownership of the object.
   virtual aura::client::UserActionClient* CreateUserActionClient() = 0;
 
@@ -228,10 +232,10 @@
   // Produces l10n-ed text of remaining time, e.g.: "13 minutes left" or
   // "13 Minuten übrig".
   // Used, for example, to display the remaining battery life.
-  virtual string16 GetTimeRemainingString(base::TimeDelta delta) = 0;
+  virtual base::string16 GetTimeRemainingString(base::TimeDelta delta) = 0;
 
   // Produces l10n-ed text for time duration, e.g.: "13 minutes" or "2 hours".
-  virtual string16 GetTimeDurationLongString(base::TimeDelta delta) = 0;
+  virtual base::string16 GetTimeDurationLongString(base::TimeDelta delta) = 0;
 
   // Saves the zoom scale of the full screen magnifier.
   virtual void SaveScreenMagnifierScale(double scale) = 0;
@@ -248,7 +252,7 @@
   virtual RootWindowHostFactory* CreateRootWindowHostFactory() = 0;
 
   // Get the product name.
-  virtual string16 GetProductName() const = 0;
+  virtual base::string16 GetProductName() const = 0;
 };
 
 }  // namespace ash
diff --git a/ash/shell_unittest.cc b/ash/shell_unittest.cc
index 25df2bf..70ca5c2 100644
--- a/ash/shell_unittest.cc
+++ b/ash/shell_unittest.cc
@@ -11,9 +11,9 @@
 #include "ash/desktop_background/desktop_background_widget_controller.h"
 #include "ash/launcher/launcher.h"
 #include "ash/root_window_controller.h"
+#include "ash/session_state_delegate.h"
 #include "ash/shelf/shelf_layout_manager.h"
 #include "ash/shelf/shelf_widget.h"
-#include "ash/shell_delegate.h"
 #include "ash/shell_window_ids.h"
 #include "ash/test/ash_test_base.h"
 #include "ash/wm/root_window_layout_manager.h"
@@ -89,7 +89,7 @@
   virtual bool CanResize() const OVERRIDE {
     return true;
   }
-  virtual string16 GetWindowTitle() const OVERRIDE {
+  virtual base::string16 GetWindowTitle() const OVERRIDE {
     return ASCIIToUTF16("Modal Window");
   }
   virtual ui::ModalType GetModalType() const OVERRIDE {
@@ -219,7 +219,7 @@
   EXPECT_TRUE(GetDefaultContainer()->Contains(
                   widget->GetNativeWindow()->parent()));
 
-  Shell::GetInstance()->delegate()->LockScreen();
+  Shell::GetInstance()->session_state_delegate()->LockScreen();
   // Create a LockScreen window.
   views::Widget* lock_widget = CreateTestWindow(widget_params);
   ash::Shell::GetContainer(
@@ -264,10 +264,12 @@
 }
 
 TEST_F(ShellTest, IsScreenLocked) {
-  ash::Shell::GetInstance()->delegate()->LockScreen();
-  EXPECT_TRUE(Shell::GetInstance()->IsScreenLocked());
-  ash::Shell::GetInstance()->delegate()->UnlockScreen();
-  EXPECT_FALSE(Shell::GetInstance()->IsScreenLocked());
+  SessionStateDelegate* delegate =
+      Shell::GetInstance()->session_state_delegate();
+  delegate->LockScreen();
+  EXPECT_TRUE(delegate->IsScreenLocked());
+  delegate->UnlockScreen();
+  EXPECT_FALSE(delegate->IsScreenLocked());
 }
 
 // Fails on Mac, see http://crbug.com/115662
diff --git a/ash/strings/ash_strings_am.xtb b/ash/strings/ash_strings_am.xtb
index bd69907..0ac7125 100644
--- a/ash/strings/ash_strings_am.xtb
+++ b/ash/strings/ash_strings_am.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">ባትሪ ሙሉ ነው</translation>
 <translation id="5250713215130379958">አስጀማሪን ራስ-ደብቅ</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> እና <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">የመተላለፊያ ሁኔታ</translation>
 <translation id="30155388420722288">የትርፍ ፍሰት አዝራር</translation>
 <translation id="5571066253365925590">ብሉቱዝ ነቅቷል</translation>
 <translation id="9074739597929991885">ብሉቱዝ</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">ተኪ...</translation>
 <translation id="938582441709398163">የቁልፍ ሰሌዳ ተደራቢ</translation>
 <translation id="6979158407327259162">Google Drive</translation>
+<translation id="6943836128787782965">ኤች ቲ ቲ ፒ ማግኘት አልተሳካም</translation>
 <translation id="2297568595583585744">የሁኔታ መሳቢያ</translation>
+<translation id="1661867754829461514">ፒን ይጎድላል</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>፦ በመገናኘት ላይ...</translation>
+<translation id="4237016987259239829">የአውታረመረብ ግንኙነት ስህተት</translation>
 <translation id="2946640296642327832">ብሉቱዝን ያንቁ</translation>
 <translation id="6459472438155181876">ማያ ገጽ ወደ <ph name="DISPLAY_NAME"/> በመቀጠል ላይ</translation>
 <translation id="8206859287963243715">ሴሉላር</translation>
 <translation id="6596816719288285829">IP አድራሻ</translation>
+<translation id="4508265954913339219">ማግበር አልተሳካም</translation>
 <translation id="1812696562331527143">የግብዓት ስልትዎ ወደ <ph name="INPUT_METHOD_ID"/> ተቀይሯል*(<ph name="BEGIN_LINK"/>3ኛ ወገን<ph name="END_LINK"/>)።
 ለመቀየር Shift + Alt ይጫኑ።</translation>
-<translation id="5233638681132016545">አዲስ ትር</translation>
 <translation id="3846575436967432996">ምንም የአውታረ መረብ መረጃ አይገኝም</translation>
 <translation id="3026237328237090306">የተንቀሳቃሽ ስልክ ውሂብ ያዋቅሩ</translation>
 <translation id="785750925697875037">የተንቀሳቃሽ መለያ ይመልከቱ</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">ብሉቱዝን ያሰናክሉ</translation>
 <translation id="3126069444801937830">ለማዘመን ዳግም ያስጀምሩ</translation>
 <translation id="735745346212279324">የቪ ፒ ኤን ግንኙነት ተቋርጧል</translation>
+<translation id="7320906967354320621">ስራ ፈት</translation>
 <translation id="6303423059719347535">ባትሪ <ph name="PERCENTAGE"/>% ሙሉ ነው</translation>
+<translation id="2778346081696727092">በተሰጠው የተጠቃሚ ስም ወይም ይለፍ ቃል ማረጋገጥ አልተቻለም</translation>
 <translation id="3294437725009624529">እንግዳ</translation>
 <translation id="8190698733819146287">ቋንቋዎችን እና ግብአቶችን አብጅ...</translation>
-<translation id="598295083618286569">ብሉቱዝ ተገናኝቷል</translation>
+<translation id="7170041865419449892">ከክልል ውጪ</translation>
+<translation id="4804818685124855865">ግንኙነት አቋርጥ</translation>
 <translation id="5222676887888702881">ዘግተህ ውጣ</translation>
+<translation id="2688477613306174402">ውቅር</translation>
+<translation id="1272079795634619415">አቁም</translation>
 <translation id="4957722034734105353">ተጨማሪ ለመረዳት...</translation>
 <translation id="2964193600955408481">Wi-Fiን አሰናክል</translation>
 <translation id="811680302244032017">መሣሪያ ያክሉ...</translation>
 <translation id="2509468283778169019">CAPS LOCK በርቷል</translation>
 <translation id="3892641579809465218">የውስጥ ማሳያ</translation>
 <translation id="7823564328645135659">ቅንብሮችዎ ከተመሳሰሉ በኋላ ቋንቋው ከ«<ph name="FROM_LOCALE"/> ወደ «<ph name="TO_LOCALE"/>» ተቀይሯል።</translation>
+<translation id="3368922792935385530">ተያይዟል</translation>
 <translation id="8340999562596018839">የተነገረ ግብረ መልስ</translation>
 <translation id="8654520615680304441">Wi-Fi አብራ...</translation>
 <translation id="5825747213122829519">የግቤት ስልትዎ ወደ <ph name="INPUT_METHOD_ID"/> ተቀይሯል።
 ለመቀየር Shift + Alt ይጫኑ።</translation>
 <translation id="2562916301614567480">የግል አውታረ መረብ</translation>
 <translation id="6549021752953852991">ምንም የተንቀሳቃሽ ሞደም አውታረ መረብ አይገኝም</translation>
+<translation id="4379753398862151997">ውድ ማሳያ፣ ልንግባባ አልቻልንም። (ያ ማሳያ አይደገፍም)</translation>
 <translation id="6426039856985689743">የተንቀሳቃሽ ስልክ ውሂብን ያሰናክሉ</translation>
 <translation id="3087734570205094154">ግርጌ</translation>
 <translation id="5271016907025319479">VPN አልተዋቀረም።</translation>
-<translation id="1298695107722797780">ይፋዊ\nክፍለ ጊዜውን አጠናቅቅ</translation>
-<translation id="3232695630852378748">የብሉቱዝ ቅንብሮች...</translation>
+<translation id="6803622936009808957">ምንም የሚደገፉ ጥራቶች ስላልተገኙ ማሳያዎችን ማሳየት አልተቻለም። ይልቁንስ ወደ የተስፋፋ ዴስክቶፕ ሁነታ ተገብቷል።</translation>
 <translation id="1480041086352807611">የማሳያ ሁነታ</translation>
 <translation id="3626637461649818317"><ph name="PERCENTAGE"/>% ይቀራል</translation>
 <translation id="9089416786594320554">የግቤት ስልቶች</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">አጥፋ</translation>
 <translation id="4430019312045809116">ድምፅ</translation>
+<translation id="4442424173763614572">የዲ ኤን ኤስ ፍለጋ አልተሳካም</translation>
 <translation id="6356500677799115505">ባትሪ ሙሉ እና ኃይል እየሞላ ነው።</translation>
 <translation id="7874779702599364982">የድምጸ ተያያዥ ሞደም አውታረ መረቦችን በመፈለግ ላይ...</translation>
+<translation id="583281660410589416">ያልታወቀ</translation>
 <translation id="1383876407941801731">ፈልግ</translation>
+<translation id="7468789844759750875">ተጨማሪ ውሂብ ለመግዛት የ<ph name="NAME"/> ማስገበሪያ መተላለፊያውን ይጎብኙ።</translation>
 <translation id="3901991538546252627">ከ<ph name="NAME"/> ጋር በመገናኘት ላይ</translation>
 <translation id="2204305834655267233">የአውታረ መረብ መረጃ</translation>
 <translation id="1621499497873603021">ባትሪ ባዶ እስኪሆን ድረስ የቀረው ጊዜ፣ <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">ቀዳሚ ምናሌ</translation>
 <translation id="1346748346194534595">ቀኝ</translation>
 <translation id="8528322925433439945">ተንቀሳቃሽ ስልክ ...</translation>
+<translation id="7049357003967926684">ማህበር</translation>
 <translation id="8428213095426709021">ቅንብሮች</translation>
-<translation id="2472320577759310817">ብሉቱዝ ጠፍቷል።</translation>
 <translation id="2372145515558759244">መተግበሪያዎችን በማመሳሰል ላይ...</translation>
+<translation id="7256405249507348194">ያልታወቀ ስህተት፦ <ph name="DESC"/></translation>
+<translation id="7925247922861151263">የAAA ማረጋገጥ አልተሳካም</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>፦ ግንኙነት በማቋረጥ ላይ...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> ሙሉ እስኪሆን ድረስ</translation>
 <translation id="5787281376604286451">የተነገረ ግብረ መልስ ነቅቷል።
 ለማሰናከል Ctrl+Alt+Z ይጫኑ።</translation>
 <translation id="4479639480957787382">ኢተርኔት</translation>
+<translation id="6312403991423642364">ያልታወቀ የአውታረ መረብ ስህተት</translation>
 <translation id="1467432559032391204">ግራ</translation>
 <translation id="5543001071567407895">ኤስ ኤም ኤስ</translation>
+<translation id="2354174487190027830"><ph name="NAME"/>ን በማግበር ላይ</translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">አስፋ</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>፦ በመገናኘት ላይ...</translation>
+<translation id="8639033665604704195">በተሰጠው ቅድሚ የተጋራው ቁልፍ ማረጋገጥ አልተሳካም</translation>
 <translation id="252373100621549798">ያልታወቀ ማሳያ</translation>
 <translation id="1882897271359938046">ወደ <ph name="DISPLAY_NAME"/> በማንጸባረቅ ላይ</translation>
 <translation id="3784455785234192852">ቆልፍ</translation>
 <translation id="2805756323405976993">መተግበሪያዎች</translation>
-<translation id="2482878487686419369">ማስታወቂያዎች</translation>
+<translation id="1512064327686280138">የማግበር አለመሳካት</translation>
+<translation id="5097002363526479830">ከአውታረ መረብ «<ph name="NAME"/>» ጋር መገናኘት አልተሳካም፦ <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi ጠፍቷል።</translation>
-<translation id="2872961005593481000">ዝጋ</translation>
+<translation id="8036518327127111261">በተሰጠው የእውቅና ማረጋገጫ ማረጋገጥ አልተሳካም</translation>
 <translation id="8132793192354020517">ከ<ph name="NAME"/> ጋር ተገናኝቷል</translation>
 <translation id="7052914147756339792">ልጣፍ አዘጋጅ...</translation>
-<translation id="2739500853984626550">ምንም የብሉቱዝ መሣሪያዎች አይገኙም</translation>
-<translation id="2666092431469916601">ላይ</translation>
+<translation id="8678698760965522072">የመስመር ላይ ሁኔታ</translation>
+<translation id="1119447706177454957">ውስጣዊ ስህተት</translation>
 <translation id="3019353588588144572">ባትሪ ሙሉ ኃይል እስኪኖረው ድረስ የሚቀረው ጊዜ፣ <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">የማያ ገጽ ማጉያ</translation>
+<translation id="7005812687360380971">አለመሳካት</translation>
 <translation id="1602076796624386989">የተንቀሳቃሽ ስልክ ውሂብን ያንቁ</translation>
 <translation id="6981982820502123353">ተደራሽነት</translation>
 <translation id="3157931365184549694">እነበረበት መልስ</translation>
+<translation id="4274292172790327596">ያልታወቀ ስህተት</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">መሣሪያዎችን በመቃኘት ላይ...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>፣ <ph name="DATE"/></translation>
 <translation id="4448844063988177157">የWi-Fi አውታረ መረቦችን በመፈለግ ላይ…</translation>
+<translation id="7229570126336867161">ኢቪዲኦ ያስፈልጋል</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> በ<ph name="DOMAIN"/> የሚቀናበር ይፋዊ ክፍለ ጊዜ ነው</translation>
 <translation id="7029814467594812963">ከክፍለ-ጊዜ ውጣ</translation>
 <translation id="8454013096329229812">Wi-Fi በርቷል።</translation>
 <translation id="4872237917498892622">Alt+Search ወይም Shift</translation>
 <translation id="2983818520079887040">ቅንብሮች ...</translation>
-<translation id="5467313780247887226">በተያያዙ ማሳያዎች ላይ ምስሉን ማባዛት አልተቻለም። ምንም ተዛማጅ ጥራት አልተገኘም።</translation>
+<translation id="8927026611342028580">መገናኘት ተጠይቋል</translation>
+<translation id="8300849813060516376">OTASP አልተሳካም</translation>
 <translation id="2792498699870441125">Alt+Search</translation>
 <translation id="8660803626959853127"><ph name="COUNT"/> ፋይል/ፋይሎችን በማመሳሰል ላይ</translation>
 <translation id="639644700271529076">CAPS LOCK ጠፍቷል</translation>
-<translation id="4101192585425716296">የመልዕክት ማዕከል</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>፦ በማግበር ላይ...</translation>
+<translation id="1391854757121130358">የተንቀሳቃሽ ስልክ ውሂብ ገደብዎን ጨርሰው ሊሆን ይችላል።</translation>
 <translation id="4864165860509564259">የአስጀማሪው ቦታ</translation>
 <translation id="7593891976182323525">Search ወይም Shift</translation>
 <translation id="7649070708921625228">እገዛ</translation>
 <translation id="3050422059534974565">CAPS LOCK በርቷል።
 ለመሰረዝ Search ወይም Shift ይጫኑ።</translation>
 <translation id="397105322502079400">በማስላት ላይ...</translation>
+<translation id="158849752021629804">የቤት አውታረ መረብ ያስፈልጋል</translation>
+<translation id="6857811139397017780"><ph name="NETWORKSERVICE"/>ን አግብር</translation>
+<translation id="5864471791310927901">የDHCP ፍለጋ አልተሳካም</translation>
+<translation id="6692173217867674490">መጥፎ የይለፍ ሐረግ</translation>
 <translation id="6165508094623778733">ተጨማሪ ለመረዳት</translation>
+<translation id="9046895021617826162">ማገናኘት አልተሳካም</translation>
+<translation id="973896785707726617">ይህ ክፍለ ጊዜ በ<ph name="SESSION_TIME_REMAINING"/> ጊዜ ውስጥ ያልቃል። በራስ-ሰር እንዲወጡ ይደረጋሉ።</translation>
+<translation id="8372369524088641025">መጥፎ የWEP ቁልፍ</translation>
+<translation id="6636709850131805001">ያልታወቀ ሁኔታ</translation>
 <translation id="3573179567135747900">ወደ «<ph name="FROM_LOCALE"/>» መልሰህ ቀይር (ዳግም ማስጀመር ይፈልጋል)</translation>
 <translation id="8103386449138765447">የኤስ ኤም ኤስ መልዕክቶች፦ <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">የGoogle Drive ቅንብሮች...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">ምንም አውታረ መረብ የለም</translation>
 <translation id="5941711191222866238">አሳንስ</translation>
 <translation id="6911468394164995108">ሌላ ይቀላቀሉ...</translation>
-<translation id="6843725295806269523">ድምጸ-ከል ያድርጉ</translation>
 <translation id="412065659894267608">ሙሉ እስኪሆን ድረስ <ph name="HOUR"/>ሰ <ph name="MINUTE"/>ደ</translation>
 <translation id="6359806961507272919">ኤስ ኤም ኤስ ከ<ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">ድምጸ ተያያዥ ሞደም</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_ar.xtb b/ash/strings/ash_strings_ar.xtb
index df5903d..2fdaa88 100644
--- a/ash/strings/ash_strings_ar.xtb
+++ b/ash/strings/ash_strings_ar.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">البطارية ممتلئة</translation>
 <translation id="5250713215130379958">إخفاء المشغل تلقائيًا</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> و<ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">حالة المدخل</translation>
 <translation id="30155388420722288">زر التدفق</translation>
 <translation id="5571066253365925590">تم تمكين البلوتوث</translation>
 <translation id="9074739597929991885">بلوتوث</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">الخادم الوكيل...</translation>
 <translation id="938582441709398163">تراكب لوحة المفاتيح</translation>
 <translation id="6979158407327259162">Google Drive</translation>
+<translation id="6943836128787782965">أخفق الحصول على HTTP</translation>
 <translation id="2297568595583585744">علبة الحالة</translation>
+<translation id="1661867754829461514">رقم التعريف الشخصي غير موجود</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: جارٍ الاتصال...</translation>
+<translation id="4237016987259239829">خطأ في اتصال الشبكة</translation>
 <translation id="2946640296642327832">تمكين البلوتوث</translation>
 <translation id="6459472438155181876">تمديد الشاشة إلى <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">خلوي</translation>
 <translation id="6596816719288285829">عنوان IP</translation>
+<translation id="4508265954913339219">أخفقت عملية التنشيط</translation>
 <translation id="1812696562331527143">تم تغيير أسلوب الإدخال إلى <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>جهة خارجية<ph name="END_LINK"/>).
 اضغط على Shift + Alt للتبديل.</translation>
-<translation id="5233638681132016545">علامة تبويب جديدة</translation>
 <translation id="3846575436967432996">لا توجد معلومات متاحة حول الشبكة</translation>
 <translation id="3026237328237090306">إعداد بيانات الجوال</translation>
 <translation id="785750925697875037">عرض حساب الجوال</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">تعطيل البلوتوث</translation>
 <translation id="3126069444801937830">إعادة التشغيل للتحديث</translation>
 <translation id="735745346212279324">تم قطع اتصال الشبكة الظاهرية الخاصة</translation>
+<translation id="7320906967354320621">في وضع الخمول</translation>
 <translation id="6303423059719347535">اكتمل شحن <ph name="PERCENTAGE"/>% من البطارية</translation>
+<translation id="2778346081696727092">أخفقت المصادقة باستخدام اسم المستخدم أو كلمة المرور المقدمين</translation>
 <translation id="3294437725009624529">ضيف</translation>
 <translation id="8190698733819146287">تخصيص اللغات والإدخال...</translation>
-<translation id="598295083618286569">تم توصيل البلوتوث</translation>
+<translation id="7170041865419449892">خارج النطاق</translation>
+<translation id="4804818685124855865">قطع الاتصال</translation>
 <translation id="5222676887888702881">الخروج</translation>
+<translation id="2688477613306174402">تهيئة</translation>
+<translation id="1272079795634619415">إيقاف</translation>
 <translation id="4957722034734105353">مزيد من المعلومات...</translation>
 <translation id="2964193600955408481">تعطيل Wi-Fi</translation>
 <translation id="811680302244032017">إضافة جهاز...</translation>
 <translation id="2509468283778169019">مفتاح CAPS LOCK قيد التشغيل</translation>
 <translation id="3892641579809465218">العرض الداخلي</translation>
 <translation id="7823564328645135659">تم تغيير اللغة من &quot;<ph name="FROM_LOCALE"/>&quot; إلى &quot;<ph name="TO_LOCALE"/>&quot; بعد مزامنة إعداداتك.</translation>
+<translation id="3368922792935385530">متصل</translation>
 <translation id="8340999562596018839">التعليقات المنطوقة</translation>
 <translation id="8654520615680304441">تشغيل شبكة Wi-Fi...</translation>
 <translation id="5825747213122829519">تم تغيير أسلوب الإدخال إلى <ph name="INPUT_METHOD_ID"/>.
 اضغط على Shift + Alt للتبديل.</translation>
 <translation id="2562916301614567480">الشبكة الخاصة</translation>
 <translation id="6549021752953852991">لا تتوفر شبكة خلوية</translation>
+<translation id="4379753398862151997">الشاشة لا تعمل. (هذه الشاشة غير متوافقة)</translation>
 <translation id="6426039856985689743">تعطيل بيانات الجوال</translation>
 <translation id="3087734570205094154">أسفل</translation>
 <translation id="5271016907025319479">لم تتم تهيئة الشبكة الظاهرية الخاصة.</translation>
-<translation id="1298695107722797780">إنهاء الجلسة\nالعامة</translation>
-<translation id="3232695630852378748">إعدادات البلوتوث...</translation>
+<translation id="6803622936009808957">تعذر إجراء النسخ المطابق للعروض نظرًا لعدم العثور على درجات دقة متوافقة. تم الدخول إلى سطح المكتب الممتد بدلاً من ذلك.</translation>
 <translation id="1480041086352807611">الوضع التجريبي</translation>
 <translation id="3626637461649818317">باقٍ <ph name="PERCENTAGE"/>%</translation>
 <translation id="9089416786594320554">أساليب الإدخال</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">إيقاف التشغيل</translation>
 <translation id="4430019312045809116">مستوى الصوت</translation>
+<translation id="4442424173763614572">أخفق البحث في نظام أسماء النطاقات</translation>
 <translation id="6356500677799115505">البطارية مملوءة ويتم شحنها.</translation>
 <translation id="7874779702599364982">جارٍ البحث عن شبكات للهاتف الجوال...</translation>
+<translation id="583281660410589416">غير محدّد</translation>
 <translation id="1383876407941801731">البحث</translation>
+<translation id="7468789844759750875">انتقل إلى مدخل التنشيط <ph name="NAME"/> لشراء المزيد من البيانات.</translation>
 <translation id="3901991538546252627">جارٍ الاتصال بـ <ph name="NAME"/></translation>
 <translation id="2204305834655267233">معلومات الشبكة</translation>
 <translation id="1621499497873603021">الوقت المتبقي حتى تصبح البطارية فارغة <ph name="TIME_LEFT"/></translation>
@@ -70,55 +83,74 @@
 <translation id="8308637677604853869">القائمة السابقة</translation>
 <translation id="1346748346194534595">يمين</translation>
 <translation id="8528322925433439945">الجوال ...</translation>
+<translation id="7049357003967926684">اقتران</translation>
 <translation id="8428213095426709021">الإعدادات</translation>
-<translation id="2472320577759310817">تم إيقاف البلوتوث.</translation>
 <translation id="2372145515558759244">جارٍ مزامنة التطبيقات...</translation>
+<translation id="7256405249507348194">خطأ غير معروف: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">أخفق فحص AAA</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: جارٍ إلغاء التوصيل...</translation>
 <translation id="8456362689280298700">حتى الاكتمال: <ph name="HOUR"/>:<ph name="MINUTE"/> ‏</translation>
 <translation id="5787281376604286451">تم تمكين التعليقات المنطوقة.
 يمكنك الضغط على Ctrl+Alt+Z لتعطيلها.</translation>
 <translation id="4479639480957787382">إيثرنت</translation>
+<translation id="6312403991423642364">خطأ غير معروف</translation>
 <translation id="1467432559032391204">اليسار</translation>
 <translation id="5543001071567407895">الرسائل القصيرة SMS</translation>
+<translation id="2354174487190027830">تنشيط <ph name="NAME"/></translation>
 <translation id="8814190375133053267">لاسلكي، Wi-Fi</translation>
 <translation id="1398853756734560583">تكبير</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: جارٍ التوصيل...</translation>
+<translation id="8639033665604704195">أخفقت المصادقة باستخدام المفتاح المشترك مسبقًا المقدم</translation>
 <translation id="252373100621549798">شاشة عرض غير معروفة</translation>
 <translation id="1882897271359938046">نسخ إلى <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">قفل</translation>
 <translation id="2805756323405976993">تطبيقات</translation>
-<translation id="2482878487686419369">التنبيهات</translation>
+<translation id="1512064327686280138">إخفاق في عملية التنشيط</translation>
+<translation id="5097002363526479830">أخفق الاتصال بشبكة &quot;<ph name="NAME"/>&quot;: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">تم إيقاف تشغيل Wi-Fi.</translation>
-<translation id="2872961005593481000">إيقاف التشغيل</translation>
+<translation id="8036518327127111261">أخفقت المصادقة باستخدام الشهادة المقدمة</translation>
 <translation id="8132793192354020517">تم الاتصال بالموقع <ph name="NAME"/></translation>
 <translation id="7052914147756339792">تعيين خلفية...</translation>
-<translation id="2739500853984626550">ليست هناك أجهزة بلوتوث متاحة</translation>
-<translation id="2666092431469916601">أعلى</translation>
+<translation id="8678698760965522072">الحالة متصل</translation>
+<translation id="1119447706177454957">خطأ داخلي</translation>
 <translation id="3019353588588144572">الوقت المتبقي حتى يتم شحن البطارية بالكامل <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">مكبّر الشاشة</translation>
+<translation id="7005812687360380971">إخفاق</translation>
 <translation id="1602076796624386989">تمكين بيانات الجوال</translation>
 <translation id="6981982820502123353">إمكانية الدخول</translation>
 <translation id="3157931365184549694">استعادة</translation>
+<translation id="4274292172790327596">خطأ غير معروف</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">جارٍ البحث عن أجهزة...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>، <ph name="DATE"/></translation>
 <translation id="4448844063988177157">جارِ البحث عن شبكات Wi-Fi...</translation>
+<translation id="7229570126336867161">يلزم توفر EVDO</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> هي جلسة عامة يديرها <ph name="DOMAIN"/></translation>
 <translation id="7029814467594812963">إنهاء الجلسة</translation>
 <translation id="8454013096329229812">تم تشغيل Wi-Fi.</translation>
 <translation id="4872237917498892622">Alt+مفتاح البحث أو Shift</translation>
 <translation id="2983818520079887040">الإعدادات...</translation>
-<translation id="5467313780247887226">لا يمكن تكرار الصورة في الشاشات الموصلة. لم يتم العثور على درجة دقة مطابقة.</translation>
+<translation id="8927026611342028580">الاتصال مطلوب</translation>
+<translation id="8300849813060516376">أخفقت OTASP</translation>
 <translation id="2792498699870441125">Alt+مفتاح البحث</translation>
 <translation id="8660803626959853127">جارٍ مزامنة <ph name="COUNT"/> من الملفات</translation>
 <translation id="639644700271529076">مفتاح CAPS LOCK قيد الإيقاف</translation>
-<translation id="4101192585425716296">مركز الرسائل</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: جارٍ التنشيط...</translation>
+<translation id="1391854757121130358">ربما تكون قد استخدمت حصة بيانات الجوال المخصصة لك.</translation>
 <translation id="4864165860509564259">موضع المشغل</translation>
 <translation id="7593891976182323525">مفتاح البحث أو Shift</translation>
 <translation id="7649070708921625228">مساعدة</translation>
 <translation id="3050422059534974565">المفتاح CAPS LOCK في وضع التشغيل، اضغط على مفتاح البحث أو المفتاح Shift لإلغاء التشغيل.</translation>
 <translation id="397105322502079400">جارٍ الحساب...</translation>
+<translation id="158849752021629804">يلزم توفر الشبكة الرئيسية</translation>
+<translation id="6857811139397017780">تنشيط <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">أخفق بحث DHCP</translation>
+<translation id="6692173217867674490">عبارة مرور غير صالحة</translation>
 <translation id="6165508094623778733">مزيد من المعلومات</translation>
+<translation id="9046895021617826162">أخفق الاتصال</translation>
+<translation id="973896785707726617">ستنتهي هذه الجلسة في <ph name="SESSION_TIME_REMAINING"/>. سيتم الخروج تلقائيًا.</translation>
+<translation id="8372369524088641025">مفتاح WEP غير صالح</translation>
+<translation id="6636709850131805001">حالة غير معروفة</translation>
 <translation id="3573179567135747900">التغيير مرة أخرى إلى &quot;<ph name="FROM_LOCALE"/>&quot; (يتطلب إعادة التشغيل)</translation>
 <translation id="8103386449138765447">الرسائل القصيرة SMS: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">إعدادات Google Drive...</translation>
@@ -128,7 +160,7 @@
 <translation id="8000066093800657092">لا شبكة</translation>
 <translation id="5941711191222866238">تصغير</translation>
 <translation id="6911468394164995108">الانضمام إلى شبكة أخرى...</translation>
-<translation id="6843725295806269523">كتم الصوت</translation>
 <translation id="412065659894267608"><ph name="HOUR"/>س <ph name="MINUTE"/>د حتى الاكتمال</translation>
 <translation id="6359806961507272919">رسالة قصيرة SMS من الهاتف رقم <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">شركة اتصالات</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_bg.xtb b/ash/strings/ash_strings_bg.xtb
index b70b83b..abc2fa5 100644
--- a/ash/strings/ash_strings_bg.xtb
+++ b/ash/strings/ash_strings_bg.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Батерията е заредена</translation>
 <translation id="5250713215130379958">Автоматично скриване на стартовия панел</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> и <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Състояние на портала</translation>
 <translation id="30155388420722288">Бутон „Препълване“</translation>
 <translation id="5571066253365925590">Bluetooth е активиран</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Прокси сървър...</translation>
 <translation id="938582441709398163">Наслагване върху клавиатурата</translation>
 <translation id="6979158407327259162">Google Диск</translation>
+<translation id="6943836128787782965">Получаването на HTTP не бе успешно</translation>
 <translation id="2297568595583585744">Област на състоянието</translation>
+<translation id="1661867754829461514">Липсва PIN</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: Установява се връзка...</translation>
+<translation id="4237016987259239829">Грешка при свързване към мрежата</translation>
 <translation id="2946640296642327832">Активиране на Bluetooth</translation>
 <translation id="6459472438155181876">Екранът се разширява на „<ph name="DISPLAY_NAME"/>“</translation>
 <translation id="8206859287963243715">Клетъчно</translation>
 <translation id="6596816719288285829">IP адрес</translation>
+<translation id="4508265954913339219">Активирането не бе успешно</translation>
 <translation id="1812696562331527143">Методът ви на въвеждане се промени на <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>трета страна<ph name="END_LINK"/>).
 Натиснете „Shift + Alt“, за да превключите.</translation>
-<translation id="5233638681132016545">Нов раздел</translation>
 <translation id="3846575436967432996">Не е налице информация за мрежата</translation>
 <translation id="3026237328237090306">Настройка на мобилните данни</translation>
 <translation id="785750925697875037">Преглед на мобилния профил</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Деактивиране на Bluetooth</translation>
 <translation id="3126069444801937830">Рестартирайте, за да актуализирате</translation>
 <translation id="735745346212279324">Връзката с виртуалната частна мрежа (VPN) е прекъсната</translation>
+<translation id="7320906967354320621">Неактивна</translation>
 <translation id="6303423059719347535">Батерията е <ph name="PERCENTAGE"/>% пълна</translation>
+<translation id="2778346081696727092">Удостоверяването с предоставеното потребителско име или парола не бе успешно</translation>
 <translation id="3294437725009624529">Гост</translation>
 <translation id="8190698733819146287">Персонализиране на езиците и въвеждането...</translation>
-<translation id="598295083618286569">Bluetooth е свързан</translation>
+<translation id="7170041865419449892">Извън обхват</translation>
+<translation id="4804818685124855865">Изключване</translation>
 <translation id="5222676887888702881">Изход</translation>
+<translation id="2688477613306174402">Конфигурация</translation>
+<translation id="1272079795634619415">Стоп</translation>
 <translation id="4957722034734105353">Научете повече...</translation>
 <translation id="2964193600955408481">Деактивиране на Wi-Fi</translation>
 <translation id="811680302244032017">Добавяне на устройство...</translation>
 <translation id="2509468283778169019">„CAPS LOCK“ е включен</translation>
 <translation id="3892641579809465218">Показване на вътрешна информация</translation>
 <translation id="7823564328645135659">Езикът се промени от „<ph name="FROM_LOCALE"/>“ на „<ph name="TO_LOCALE"/>“ след синхронизирането на настройките ви.</translation>
+<translation id="3368922792935385530">Установена е връзка</translation>
 <translation id="8340999562596018839">Обратна връзка с говор</translation>
 <translation id="8654520615680304441">Включване на Wi-Fi...</translation>
 <translation id="5825747213122829519">Методът ви на въвеждане се промени на <ph name="INPUT_METHOD_ID"/>.
 Натиснете „Shift + Alt“, за да превключите.</translation>
 <translation id="2562916301614567480">Частна мрежа</translation>
 <translation id="6549021752953852991">Няма налична клетъчна мрежа</translation>
+<translation id="4379753398862151997">Уважаеми мониторе, нещата между нас не се получават. (Този монитор не се поддържа)</translation>
 <translation id="6426039856985689743">Деактивиране на мобилните данни</translation>
 <translation id="3087734570205094154">Най-долу</translation>
 <translation id="5271016907025319479">Виртуалната частна мрежа (VPN) не е конфигурирана.</translation>
-<translation id="1298695107722797780">Прекратяване на обществената\nсесия</translation>
-<translation id="3232695630852378748">Настройки за Bluetooth...</translation>
+<translation id="6803622936009808957">Дисплеите не можаха да се дублират, тъй като не бяха намерени поддържани разделителни способности. Вместо това влязохте в режима за разширен работен плот.</translation>
 <translation id="1480041086352807611">Демонстрационен режим</translation>
 <translation id="3626637461649818317">Остава/т <ph name="PERCENTAGE"/>%</translation>
 <translation id="9089416786594320554">Методи за въвеждане</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">Изключване</translation>
 <translation id="4430019312045809116">Звук</translation>
+<translation id="4442424173763614572">Търсенето в DNS не бе успешно</translation>
 <translation id="6356500677799115505">Батерията е пълна и се зарежда.</translation>
 <translation id="7874779702599364982">Търсят се мобилни мрежи...</translation>
+<translation id="583281660410589416">Неизвестно</translation>
 <translation id="1383876407941801731">Търсене</translation>
+<translation id="7468789844759750875">Посетете портала за активиране на <ph name="NAME"/>, за да купите още данни.</translation>
 <translation id="3901991538546252627">Установява се връзка със: <ph name="NAME"/></translation>
 <translation id="2204305834655267233">Информация за мрежата</translation>
 <translation id="1621499497873603021">Оставащо време до изразходването на батерията: <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">Предишно меню</translation>
 <translation id="1346748346194534595">Надясно</translation>
 <translation id="8528322925433439945">Мобилни мрежи...</translation>
+<translation id="7049357003967926684">Връзка</translation>
 <translation id="8428213095426709021">Настройки</translation>
-<translation id="2472320577759310817">Bluetooth е изключен.</translation>
 <translation id="2372145515558759244">Приложенията се синхронизират...</translation>
+<translation id="7256405249507348194">Неразпозната грешка: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">Проверката за AAA не бе успешна</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: Връзката се прекъсва...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> до пълно зареждане</translation>
 <translation id="5787281376604286451">Обратната връзка с говор е активирана.
 Натиснете „Ctrl+Alt+Z“, за да я деактивирате.</translation>
 <translation id="4479639480957787382">Ethernet</translation>
+<translation id="6312403991423642364">Неизвестна мрежова грешка</translation>
 <translation id="1467432559032391204">Наляво</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830">„<ph name="NAME"/>“ се активира</translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">Увеличаване</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: Установява се връзка...</translation>
+<translation id="8639033665604704195">Удостоверяването с предоставения предварително споделен ключ не бе успешно</translation>
 <translation id="252373100621549798">Неизвестен дисплей</translation>
 <translation id="1882897271359938046">Дублира се на „<ph name="DISPLAY_NAME"/>“</translation>
 <translation id="3784455785234192852">Заключване</translation>
 <translation id="2805756323405976993">Приложения</translation>
-<translation id="2482878487686419369">Известия</translation>
+<translation id="1512064327686280138">Неуспех при активирането</translation>
+<translation id="5097002363526479830">Свързването с мрежата „<ph name="NAME"/>“ не бе успешно: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi е изключен.</translation>
-<translation id="2872961005593481000">Изключване</translation>
+<translation id="8036518327127111261">Удостоверяването с предоставения сертификат не бе успешно</translation>
 <translation id="8132793192354020517">Установена е връзка с/ъс <ph name="NAME"/></translation>
 <translation id="7052914147756339792">Задаване на тапет...</translation>
-<translation id="2739500853984626550">Няма налични устройства с Bluetooth</translation>
-<translation id="2666092431469916601">Най-горе</translation>
+<translation id="8678698760965522072">Състояние: Онлайн</translation>
+<translation id="1119447706177454957">Вътрешна грешка</translation>
 <translation id="3019353588588144572">Оставащо време до пълното зареждане на батерията: <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">Екранна лупа</translation>
+<translation id="7005812687360380971">Неуспех</translation>
 <translation id="1602076796624386989">Активиране на мобилните данни</translation>
 <translation id="6981982820502123353">Достъпност</translation>
 <translation id="3157931365184549694">Възстановяване</translation>
+<translation id="4274292172790327596">Неразпозната грешка</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Сканира се за устройства...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Търсят се Wi-Fi мрежи...</translation>
+<translation id="7229570126336867161">Необходим е EVDO</translation>
 <translation id="2999742336789313416">„<ph name="DISPLAY_NAME"/>“ е обществена сесия, управлявана от <ph name="DOMAIN"/></translation>
 <translation id="7029814467594812963">Изход от сесията</translation>
 <translation id="8454013096329229812">Wi-Fi е включен.</translation>
 <translation id="4872237917498892622">„Alt + търсене“ или „Shift“</translation>
 <translation id="2983818520079887040">Настройки...</translation>
-<translation id="5467313780247887226">Образът не може да се дублира на свързаните монитори. Не е намерена съответстваща разделителна способност.</translation>
+<translation id="8927026611342028580">Заявено е свързване</translation>
+<translation id="8300849813060516376">Безжичното осигуряване на услуга не бе успешно</translation>
 <translation id="2792498699870441125">Alt + търсене</translation>
 <translation id="8660803626959853127">Синхронизира/т се <ph name="COUNT"/> файл/а</translation>
 <translation id="639644700271529076">„CAPS LOCK“ е изключен</translation>
-<translation id="4101192585425716296">Център за съобщения</translation>
+<translation id="6267036997247669271">„<ph name="NAME"/>“: Активира се...</translation>
+<translation id="1391854757121130358">Може да сте изразходили отпуснатите ви мобилни данни.</translation>
 <translation id="4864165860509564259">Позиция на стартовия панел</translation>
 <translation id="7593891976182323525">„търсене“ или „Shift“</translation>
 <translation id="7649070708921625228">Помощ</translation>
 <translation id="3050422059534974565">„CAPS LOCK“ е включен.
 Натиснете „търсене“ или „Shift“, за да анулирате.</translation>
 <translation id="397105322502079400">Изчислява се...</translation>
+<translation id="158849752021629804">Необходима е собствена мрежа</translation>
+<translation id="6857811139397017780">Активиране на <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">Търсенето на DHCP сървър не бе успешно</translation>
+<translation id="6692173217867674490">Паролата е неправилна</translation>
 <translation id="6165508094623778733">Научете повече</translation>
+<translation id="9046895021617826162">Свързването не бе успешно</translation>
+<translation id="973896785707726617">Тази сесия ще приключи след <ph name="SESSION_TIME_REMAINING"/>. Ще излезете автоматично от нея.</translation>
+<translation id="8372369524088641025">Ключът за WEP е неправилен</translation>
+<translation id="6636709850131805001">Неразпознато състояние</translation>
 <translation id="3573179567135747900">Връщане към „<ph name="FROM_LOCALE"/>“ (изисква рестартиране)</translation>
 <translation id="8103386449138765447">SMS съобщения: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Настройки за Google Диск...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">Няма мрежа</translation>
 <translation id="5941711191222866238">Намаляване</translation>
 <translation id="6911468394164995108">Присъединяване другаде...</translation>
-<translation id="6843725295806269523">заглушаване</translation>
 <translation id="412065659894267608"><ph name="HOUR"/> ч <ph name="MINUTE"/> м до пълно зареждане</translation>
 <translation id="6359806961507272919">SMS от <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Оператор</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_bn.xtb b/ash/strings/ash_strings_bn.xtb
index adbdeb6..355f5f6 100644
--- a/ash/strings/ash_strings_bn.xtb
+++ b/ash/strings/ash_strings_bn.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">ব্যাটারি পূর্ণ</translation>
 <translation id="5250713215130379958">লঞ্চার স্বয়ংক্রিয়ভাবে লুকান</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> এবং <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">পোর্টাল স্থিতি</translation>
 <translation id="30155388420722288">ওভারফ্লো বোতাম</translation>
 <translation id="5571066253365925590">ব্লুটুথ সক্ষমিত</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">প্রক্সি...</translation>
 <translation id="938582441709398163">কীবোর্ড ওভারলে</translation>
 <translation id="6979158407327259162">Google ড্রাইভ</translation>
+<translation id="6943836128787782965">HTTP ব্যর্থ হয়েছে</translation>
 <translation id="2297568595583585744">স্থিতি ট্রে</translation>
+<translation id="1661867754829461514">PIN হারিয়েছে</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: সংযুক্ত হচ্ছে...</translation>
+<translation id="4237016987259239829">নেটওয়ার্ক  সংযোগ ত্রুটি</translation>
 <translation id="2946640296642327832">ব্লুটুথ সক্ষম করুন</translation>
 <translation id="6459472438155181876">স্ক্রীন <ph name="DISPLAY_NAME"/> তে প্রসারিত হচ্ছে</translation>
 <translation id="8206859287963243715">সেলুলার</translation>
 <translation id="6596816719288285829">IP ঠিকানা</translation>
+<translation id="4508265954913339219">সক্রিয়করণ ব্যর্থ</translation>
 <translation id="1812696562331527143">আপনার ইনপুট পদ্ধতি <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>৩য় পক্ষ<ph name="END_LINK"/>) এ পরিবর্তিত হয়েছে৷
 স্যুইচ করতে Shift + Alt টিপুন৷</translation>
-<translation id="5233638681132016545">নতুন ট্যাব</translation>
 <translation id="3846575436967432996">কোনো নেটওয়ার্ক সংক্রান্ত তথ্য উপলব্ধ নেই</translation>
 <translation id="3026237328237090306">মোবাইল ডেটা সেটআপ করুন</translation>
 <translation id="785750925697875037">মোবাইল অ্যাকাউন্ট দেখুন</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">ব্লুটুথ অক্ষম করুন</translation>
 <translation id="3126069444801937830">আপডেট করার জন্য পুনরারম্ভ করুন</translation>
 <translation id="735745346212279324">VPN সংযোগ বিচ্ছিন্ন করা হয়েছে</translation>
+<translation id="7320906967354320621">নিষ্ক্রিয়</translation>
 <translation id="6303423059719347535">ব্যাটারি <ph name="PERCENTAGE"/>% পরিপূর্ণ</translation>
+<translation id="2778346081696727092">সরবরাহ করা ব্যবহারকারীর নাম বা পাসওয়ার্ড সহ প্রমাণীকরণ ব্যর্থ</translation>
 <translation id="3294437725009624529">অতিথি</translation>
 <translation id="8190698733819146287">ভাষা এবং ইনপুট কাস্টমাইজ করুন...</translation>
-<translation id="598295083618286569">ব্লুটুথ সংযুক্ত</translation>
+<translation id="7170041865419449892">সীমার বাইরে</translation>
+<translation id="4804818685124855865">সংযোগ বিচ্ছিন্ন</translation>
 <translation id="5222676887888702881">সাইন আউট</translation>
+<translation id="2688477613306174402">কনফিগারেশন</translation>
+<translation id="1272079795634619415">বন্ধ</translation>
 <translation id="4957722034734105353">আরো জানুন...</translation>
 <translation id="2964193600955408481">Wi-Fi অক্ষম করুন</translation>
 <translation id="811680302244032017">ডিভাইস জুড়ুন...</translation>
 <translation id="2509468283778169019">CAPS LOCK চালু</translation>
 <translation id="3892641579809465218">অভ্যন্তরীণ প্রদর্শন</translation>
 <translation id="7823564328645135659">আপনার সেটিংস সিঙ্ক করার পরে ভাষা &quot;<ph name="FROM_LOCALE"/>&quot; থেকে &quot;<ph name="TO_LOCALE"/>&quot; এ পরিবর্তন করা হয়েছে৷</translation>
+<translation id="3368922792935385530">সংযুক্ত</translation>
 <translation id="8340999562596018839">কথ্য প্রতিক্রিয়া</translation>
 <translation id="8654520615680304441">Wi-Fi চালু করুন...</translation>
 <translation id="5825747213122829519">আপনার ইনপুট পদ্ধতি <ph name="INPUT_METHOD_ID"/> এ পরিবর্তিত হয়েছে৷
 স্যুইচ করতে Shift + Alt টিপুন৷</translation>
 <translation id="2562916301614567480">ব্যক্তিগত নেটওয়ার্ক</translation>
 <translation id="6549021752953852991">কোনো সেলুলার নেটওয়ার্ক উপলব্ধ নেই</translation>
+<translation id="4379753398862151997">Dear Monitor, it's not working out between us. (এই মনিটরটি সমর্থিত নয়)</translation>
 <translation id="6426039856985689743">মোবাইল ডেটা নিষ্ক্রিয় করুন</translation>
 <translation id="3087734570205094154">নীচে</translation>
 <translation id="5271016907025319479">VPN কনফিগার করা নেই৷</translation>
-<translation id="1298695107722797780">সর্বজনীন\nঅধিবেশন শেষ করুন</translation>
-<translation id="3232695630852378748">ব্লুটুথ সেটিংস...</translation>
+<translation id="6803622936009808957">সমর্থিত রেসুলিউশানগুলি খুঁজে না পাওয়ায় মিরর প্রদর্শনগুলি করতে পারেনি৷ পরিবর্তে প্রসারিত ডেস্কটপ সক্ষম করা হয়েছে৷</translation>
 <translation id="1480041086352807611">নমুনা মোড</translation>
 <translation id="3626637461649818317"><ph name="PERCENTAGE"/>% বাকি আছে</translation>
 <translation id="9089416786594320554">ইনপুট পদ্ধতিসমূহ</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">শাটডাউন</translation>
 <translation id="4430019312045809116">ভলিউম</translation>
+<translation id="4442424173763614572">DNS খোঁজ ব্যর্থ হয়েছে</translation>
 <translation id="6356500677799115505">ব্যাটারি পরিপূর্ণ এবং চার্জ হচ্ছে৷</translation>
 <translation id="7874779702599364982">সেলুলার নেটওয়ার্কগুলির জন্য অনুসন্ধান করছে...</translation>
+<translation id="583281660410589416">অজানা</translation>
 <translation id="1383876407941801731">অনুসন্ধান</translation>
+<translation id="7468789844759750875">আরো ডেটা কেনার জন্য <ph name="NAME"/> সক্রিয়করণ পোর্টাল ঘুরে দেখুন৷</translation>
 <translation id="3901991538546252627"><ph name="NAME"/>-এ সংযোগ করা হচ্ছে</translation>
 <translation id="2204305834655267233">নেটওয়ার্ক তথ্য</translation>
 <translation id="1621499497873603021">ব্যাটারি শেষ হতে <ph name="TIME_LEFT"/> সময় বাকি আছে</translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">পূর্ববর্তী মেনু</translation>
 <translation id="1346748346194534595">ডান</translation>
 <translation id="8528322925433439945">মোবাইল ...</translation>
+<translation id="7049357003967926684">সমিতি</translation>
 <translation id="8428213095426709021">সেটিংস</translation>
-<translation id="2472320577759310817">Bluetooth বন্ধ আছে৷</translation>
 <translation id="2372145515558759244">অ্যাপ্লিকেশনগুলি সিঙ্ক হচ্ছে...</translation>
+<translation id="7256405249507348194">অস্বীকৃত ত্রুটি: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">AAA যাচাই ব্যর্থ</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: সংযোগ বিচ্ছিন্ন করা হচ্ছে...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> ইউনিট পূর্ণ</translation>
 <translation id="5787281376604286451">কথ্য প্রতিক্রিয়া সক্ষমিত৷
 অক্ষম করতে Ctrl + Alt + Z টিপুন৷</translation>
 <translation id="4479639480957787382">ইথারনেট</translation>
+<translation id="6312403991423642364">অজানা নেটওয়ার্ক ত্রুটি</translation>
 <translation id="1467432559032391204">বাম</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830"><ph name="NAME"/> সক্রিয় করা হচ্ছে</translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">বড় করুন</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: সংযুক্ত হচ্ছে...</translation>
+<translation id="8639033665604704195">সরবরাহ করা আগে থেকে অংশীদার করা কী সহ প্রমাণীকরণ ব্যর্থ</translation>
 <translation id="252373100621549798">অজানা প্রদর্শন</translation>
 <translation id="1882897271359938046"><ph name="DISPLAY_NAME"/> তে প্রতিবিম্বিত হচ্ছে</translation>
 <translation id="3784455785234192852">লক করুন</translation>
 <translation id="2805756323405976993">Apps</translation>
-<translation id="2482878487686419369">বিজ্ঞপ্তিগুলি</translation>
+<translation id="1512064327686280138">সক্রিয়করণে ব্যর্থতা</translation>
+<translation id="5097002363526479830">নেটওয়ার্কের সাথে সংযোগ করতে ব্যর্থ '<ph name="NAME"/>': <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi বন্ধ আছে৷</translation>
-<translation id="2872961005593481000">শাট ডাউন</translation>
+<translation id="8036518327127111261">সরবরাহ করা শংসাপত্র সহ প্রমাণীকরণ ব্যর্থ</translation>
 <translation id="8132793192354020517"><ph name="NAME"/> তে সংযুক্ত</translation>
 <translation id="7052914147756339792">ওয়ালপেপার সেট করুন...</translation>
-<translation id="2739500853984626550">কোনো bluetooth ডিভাইস উপলব্ধ নেই</translation>
-<translation id="2666092431469916601">শীর্ষ</translation>
+<translation id="8678698760965522072">অনলাইন স্থিতি</translation>
+<translation id="1119447706177454957">অভ্যন্তরীণ ত্রুটি</translation>
 <translation id="3019353588588144572">ব্যাটারি পরিপূর্ণ চার্জ হতে, <ph name="TIME_REMAINING"/> সময় বাকি আছে</translation>
 <translation id="3473479545200714844">স্ক্রীন ম্যাগনিফায়ার</translation>
+<translation id="7005812687360380971">ব্যর্থতা</translation>
 <translation id="1602076796624386989">মোবাইল ডেটা সক্রিয় করুন</translation>
 <translation id="6981982820502123353">অ্যাক্সেযোগ্যতা</translation>
 <translation id="3157931365184549694">পুনরুদ্ধার করুন</translation>
+<translation id="4274292172790327596">অস্বীকৃত ত্রুটি</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">ডিভাইসগুলির জন্য স্ক্যান করা হচ্ছে...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Wi-Fi নেটওয়ার্কগুলির জন্য অনুসন্ধান করুন...</translation>
+<translation id="7229570126336867161">EVDO এর প্রয়োজন</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> হল <ph name="DOMAIN"/> এর দ্বারা পরিচালিত একটি সর্বজনীন সেশন</translation>
 <translation id="7029814467594812963">সেশন থেকে প্রস্থান</translation>
 <translation id="8454013096329229812">Wi-Fi চালু আছে৷</translation>
 <translation id="4872237917498892622">Alt+Search অথবা Shift</translation>
 <translation id="2983818520079887040">সেটিংস...</translation>
-<translation id="5467313780247887226">সংযুক্ত মনিটরগুলিতে চিত্র নকল করা যায় না৷ কোনো মিলে যাওয়া রেসুলিউশান পাওয়া যায়নি৷</translation>
+<translation id="8927026611342028580">সংযুক্ত করার অনুরোধ করা হয়েছে</translation>
+<translation id="8300849813060516376">OTASP ব্যর্থ</translation>
 <translation id="2792498699870441125">Alt+Search</translation>
 <translation id="8660803626959853127"><ph name="COUNT"/>টি ফাইল (গুলি) সিঙ্ক হচ্ছে</translation>
 <translation id="639644700271529076">CAPS LOCK বন্ধ আছে</translation>
-<translation id="4101192585425716296">বার্তা কেন্দ্র</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: সক্রিয় করা হচ্ছে...</translation>
+<translation id="1391854757121130358">আপনি হয়তো আপনার মোবাইল ডেটা অ্যালাউন্স ব্যবহার করেছেন৷</translation>
 <translation id="4864165860509564259">লঞ্চার অবস্থান</translation>
 <translation id="7593891976182323525">Search অথবা Shift</translation>
 <translation id="7649070708921625228">সহায়তা</translation>
 <translation id="3050422059534974565">CAPS LOCK চালু আছে৷
 Search অথবা বাতিল করতে Shift টিপুন৷</translation>
 <translation id="397105322502079400">গণনা করা হচ্ছে...</translation>
+<translation id="158849752021629804">হোম নেটওয়ার্কের প্রয়োজন</translation>
+<translation id="6857811139397017780">সক্রিয় করুন <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">DHCP লুকআপ ব্যর্থ</translation>
+<translation id="6692173217867674490">খারাপ পাসফ্রেজ</translation>
 <translation id="6165508094623778733">আরো জানুন</translation>
+<translation id="9046895021617826162">সংযোগ ব্যর্থ হয়েছে</translation>
+<translation id="973896785707726617">এই সেশনটি <ph name="SESSION_TIME_REMAINING"/> এর মধ্যে সমাপ্ত হবে৷ আপনি স্বয়ংক্রিয়ভাবে সাইন আউট হয়ে যাবেন৷</translation>
+<translation id="8372369524088641025">খারাপ WEP কী</translation>
+<translation id="6636709850131805001">অস্বীকৃত স্থিতি</translation>
 <translation id="3573179567135747900">&quot;<ph name="FROM_LOCALE"/>&quot; তে ফেরান (পুনর্সূচনা প্রয়োজন)</translation>
 <translation id="8103386449138765447">SMS বার্তা: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Google ড্রাইভ সেটিংস ...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">কোনও নেটওয়ার্ক নেই</translation>
 <translation id="5941711191222866238">ছোট করুন</translation>
 <translation id="6911468394164995108">অন্যান্য যোগদান ...</translation>
-<translation id="6843725295806269523">নিঃশব্দ</translation>
 <translation id="412065659894267608"><ph name="HOUR"/>ঘন্টা <ph name="MINUTE"/> মিনিট পর্যন্ত পূর্ণ</translation>
 <translation id="6359806961507272919"><ph name="PHONE_NUMBER"/>-এর থেকে SMS...</translation>
+<translation id="1244147615850840081">কেরিয়ার</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_ca.xtb b/ash/strings/ash_strings_ca.xtb
index f37a62e..96d0a90 100644
--- a/ash/strings/ash_strings_ca.xtb
+++ b/ash/strings/ash_strings_ca.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Bateria carregada.</translation>
 <translation id="5250713215130379958">Oculta automàticament la barra d'execució ràpida</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> i <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Estat del portal</translation>
 <translation id="30155388420722288">Botó de desbordament</translation>
 <translation id="5571066253365925590">S'ha activat el Bluetooth</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Servidor intermediari...</translation>
 <translation id="938582441709398163">Superposició de teclat</translation>
 <translation id="6979158407327259162">Google Drive</translation>
+<translation id="6943836128787782965">La sol·licitud HTTP ha fallat</translation>
 <translation id="2297568595583585744">Safata d'estat</translation>
+<translation id="1661867754829461514">Falta el PIN</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: s'està connectant...</translation>
+<translation id="4237016987259239829">Error de connexió a la xarxa</translation>
 <translation id="2946640296642327832">Activa el Bluetooth</translation>
 <translation id="6459472438155181876">S'està ampliant la pantalla a <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Cel·lular</translation>
 <translation id="6596816719288285829">Adreça IP</translation>
+<translation id="4508265954913339219">S'ha produït un error en l'activació.</translation>
 <translation id="1812696562331527143">El mètode d'entrada ha canviat a <ph name="INPUT_METHOD_ID"/>* (<ph name="BEGIN_LINK"/>tercers<ph name="END_LINK"/>).
 Premeu Maj+Alt per canviar-lo.</translation>
-<translation id="5233638681132016545">Pestanya nova</translation>
 <translation id="3846575436967432996">No hi ha informació de xarxa disponible</translation>
 <translation id="3026237328237090306">Configura les dades mòbils</translation>
 <translation id="785750925697875037">Mostra el compte mòbil</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Desactiva el Bluetooth</translation>
 <translation id="3126069444801937830">Reinicia per actualitzar</translation>
 <translation id="735745346212279324">VPN desconnectada</translation>
+<translation id="7320906967354320621">Inactiu</translation>
 <translation id="6303423059719347535">La bateria està carregada fins al <ph name="PERCENTAGE"/>%</translation>
+<translation id="2778346081696727092">No s'ha pogut autenticar amb el nom d'usuari o amb la contrasenya que heu proporcionat</translation>
 <translation id="3294437725009624529">Convidat</translation>
 <translation id="8190698733819146287">Personalitza els idiomes i l'entrada...</translation>
-<translation id="598295083618286569">S'ha connectat el Bluetooth</translation>
+<translation id="7170041865419449892">Fora de l'interval</translation>
+<translation id="4804818685124855865">Desconnecta</translation>
 <translation id="5222676887888702881">Tanca la sessió</translation>
+<translation id="2688477613306174402">Configuració</translation>
+<translation id="1272079795634619415">Atura</translation>
 <translation id="4957722034734105353">Més informació...</translation>
 <translation id="2964193600955408481">Desactiva la Wi-Fi</translation>
 <translation id="811680302244032017">Afegeix un dispositiu...</translation>
 <translation id="2509468283778169019">BLOQ MAJ està activat.</translation>
 <translation id="3892641579809465218">Pantalla interna</translation>
 <translation id="7823564328645135659">L'idioma ha canviat de &quot;<ph name="FROM_LOCALE"/>&quot; a &quot;<ph name="TO_LOCALE"/>&quot; després de sincronitzar la vostra configuració.</translation>
+<translation id="3368922792935385530">Connectat</translation>
 <translation id="8340999562596018839">Comentaris de veu</translation>
 <translation id="8654520615680304441">Activa la Wi-Fi...</translation>
 <translation id="5825747213122829519">El mètode d'entrada ha canviat a <ph name="INPUT_METHOD_ID"/>.
 Premeu Maj+Alt per canviar-lo.</translation>
 <translation id="2562916301614567480">Xarxa privada</translation>
 <translation id="6549021752953852991">No hi ha cap xarxa mòbil disponible</translation>
+<translation id="4379753398862151997">Estimat monitor, això no funciona. (El monitor no és compatible)</translation>
 <translation id="6426039856985689743">Desactiva les dades mòbils</translation>
 <translation id="3087734570205094154">Part inferior</translation>
 <translation id="5271016907025319479">La VPN no està configurada.</translation>
-<translation id="1298695107722797780">Finalitza la sessió\npública</translation>
-<translation id="3232695630852378748">Configuració de Bluetooth...</translation>
+<translation id="6803622936009808957">No s'han pogut reflectir les pantalles, perquè no s'ha trobat cap resolució compatible. S'està entrant al mode d'escriptori ampliat.</translation>
 <translation id="1480041086352807611">Mode de demostració</translation>
 <translation id="3626637461649818317">Queda un <ph name="PERCENTAGE"/>%</translation>
 <translation id="9089416786594320554">Mètodes d'introducció</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">Aturada</translation>
 <translation id="4430019312045809116">Volum</translation>
+<translation id="4442424173763614572">La cerca de DNS ha fallat</translation>
 <translation id="6356500677799115505">La bateria és plena i s'està carregant.</translation>
 <translation id="7874779702599364982">S'estan cercant xarxes mòbils...</translation>
+<translation id="583281660410589416">Desconegut</translation>
 <translation id="1383876407941801731">Cerca</translation>
+<translation id="7468789844759750875">Visiteu el portal d'activació de <ph name="NAME"/> per comprar més dades.</translation>
 <translation id="3901991538546252627">S'està connectant amb <ph name="NAME"/></translation>
 <translation id="2204305834655267233">Informació de la xarxa</translation>
 <translation id="1621499497873603021">Temps que queda fins que no s'esgoti la bateria: <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">Menú anterior</translation>
 <translation id="1346748346194534595">A la dreta</translation>
 <translation id="8528322925433439945">Xarxes mòbils...</translation>
+<translation id="7049357003967926684">Associació</translation>
 <translation id="8428213095426709021">Configuració</translation>
-<translation id="2472320577759310817">El Bluetooth està desactivat.</translation>
 <translation id="2372145515558759244">S'estan sincronitzant les aplicacions...</translation>
+<translation id="7256405249507348194">Error no reconegut: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">Error en la comprovació d'AAA</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: s'està desconnectant...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> fins que estigui carregat completament</translation>
 <translation id="5787281376604286451">Els comentaris de veu estan activats.
 Premeu Ctrl+Alt+Z per desactivar-los.</translation>
 <translation id="4479639480957787382">Ethernet</translation>
+<translation id="6312403991423642364">Error de xarxa desconegut</translation>
 <translation id="1467432559032391204">A l'esquerra</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830">S'està activant <ph name="NAME"/></translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">Maximitza</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: s'està connectant...</translation>
+<translation id="8639033665604704195">S'ha produït un error en autenticar amb la clau compartida prèviament que heu proporcionat</translation>
 <translation id="252373100621549798">Pantalla desconeguda</translation>
 <translation id="1882897271359938046">S'està replicant <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Bloqueja</translation>
 <translation id="2805756323405976993">Aplicacions</translation>
-<translation id="2482878487686419369">Notificacions</translation>
+<translation id="1512064327686280138">Error d'activació</translation>
+<translation id="5097002363526479830">S'ha produït un error en connectar amb la xarxa &quot;<ph name="NAME"/>&quot;: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">La Wi-Fi està desactivada.</translation>
-<translation id="2872961005593481000">Apaga</translation>
+<translation id="8036518327127111261">S'ha produït un error en autenticar amb el certificat que heu proporcionat</translation>
 <translation id="8132793192354020517">Connectat a <ph name="NAME"/></translation>
 <translation id="7052914147756339792">Defineix l'empaperat...</translation>
-<translation id="2739500853984626550">No hi ha cap dispositiu Bluetooth disponible</translation>
-<translation id="2666092431469916601">Superior</translation>
+<translation id="8678698760965522072">Estat en línia</translation>
+<translation id="1119447706177454957">Error intern</translation>
 <translation id="3019353588588144572">Temps restant fins que la bateria no estigui totalment carregada: <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">Augment de pantalla</translation>
+<translation id="7005812687360380971">Error</translation>
 <translation id="1602076796624386989">Activa les dades mòbils</translation>
 <translation id="6981982820502123353">Accessibilitat</translation>
 <translation id="3157931365184549694">Restaura</translation>
+<translation id="4274292172790327596">Error no reconegut</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">S'estan cercant dispositius...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">S'estan cercant xarxes Wi-Fi...</translation>
+<translation id="7229570126336867161">Es necessita EVDO</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> és una sessió pública gestionada per <ph name="DOMAIN"/>.</translation>
 <translation id="7029814467594812963">Tanca la sessió</translation>
 <translation id="8454013096329229812">La Wi-Fi està activada.</translation>
 <translation id="4872237917498892622">Alt+Cerca o Maj</translation>
 <translation id="2983818520079887040">Configuració...</translation>
-<translation id="5467313780247887226">No es pot duplicar la imatge en monitors connectats. No s'ha trobat cap resolució coincident.</translation>
+<translation id="8927026611342028580">S'ha sol·licitat la connexió</translation>
+<translation id="8300849813060516376">Error d'OTASP</translation>
 <translation id="2792498699870441125">Alt+Cerca</translation>
 <translation id="8660803626959853127">Fitxers que s'estan sincronitzant: <ph name="COUNT"/></translation>
 <translation id="639644700271529076">Bloq Maj està desactivat</translation>
-<translation id="4101192585425716296">Centre de missatges</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: s'està activant...</translation>
+<translation id="1391854757121130358">Pot ser que hàgiu esgotat les dades mòbils.</translation>
 <translation id="4864165860509564259">Posició de la barra d'execució ràpida</translation>
 <translation id="7593891976182323525">Cerca o Maj</translation>
 <translation id="7649070708921625228">Ajuda</translation>
 <translation id="3050422059534974565">Bloq Maj està activat.
 Premeu Cerca o Maj per cancel·lar.</translation>
 <translation id="397105322502079400">S’està calculant...</translation>
+<translation id="158849752021629804">Es necessita una xarxa domèstica</translation>
+<translation id="6857811139397017780">Activa <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">Error en la cerca de DHCP</translation>
+<translation id="6692173217867674490">Contrasenya no vàlida</translation>
 <translation id="6165508094623778733">Més informació</translation>
+<translation id="9046895021617826162">S'ha produït un error en la connexió</translation>
+<translation id="973896785707726617">La sessió finalitzarà d'aquí a <ph name="SESSION_TIME_REMAINING"/>. Es tancarà la sessió automàticament.</translation>
+<translation id="8372369524088641025">Clau WEP no vàlida</translation>
+<translation id="6636709850131805001">Estat no reconegut</translation>
 <translation id="3573179567135747900">Torna a canviar a &quot;<ph name="FROM_LOCALE"/>&quot; (requereix reiniciar)</translation>
 <translation id="8103386449138765447">Missatges SMS: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Configuració de Google Drive...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">No hi ha xarxa</translation>
 <translation id="5941711191222866238">Minimitza</translation>
 <translation id="6911468394164995108">Uneix-te a una altra...</translation>
-<translation id="6843725295806269523">silencia</translation>
 <translation id="412065659894267608">Falten <ph name="HOUR"/> h <ph name="MINUTE"/> min fins que estigui carregada completament</translation>
 <translation id="6359806961507272919">SMS de <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Operador</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_cs.xtb b/ash/strings/ash_strings_cs.xtb
index cddaeec..444faf8 100644
--- a/ash/strings/ash_strings_cs.xtb
+++ b/ash/strings/ash_strings_cs.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Baterie je nabitá.</translation>
 <translation id="5250713215130379958">Automaticky skrýt spouštěč</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> a <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Stav portálu</translation>
 <translation id="30155388420722288">Tlačítko přetečení</translation>
 <translation id="5571066253365925590">Rozhraní Bluetooth aktivováno</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,14 +16,17 @@
 <translation id="5565793151875479467">Server proxy...</translation>
 <translation id="938582441709398163">Překryvná klávesnice</translation>
 <translation id="6979158407327259162">Disk Google</translation>
+<translation id="6943836128787782965">Příkaz GET protokolu HTTP se nezdařil.</translation>
 <translation id="2297568595583585744">Stavový panel</translation>
+<translation id="1661867754829461514">Chybí kód PIN</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: Připojování...</translation>
+<translation id="4237016987259239829">Chyba připojení k síti</translation>
 <translation id="2946640296642327832">Zapnout Bluetooth</translation>
 <translation id="6459472438155181876">Rozšíření obrazovky na displej <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Mobil</translation>
 <translation id="6596816719288285829">Adresa IP</translation>
+<translation id="4508265954913339219">Aktivace se nezdařila</translation>
 <translation id="1812696562331527143">Metoda zadávání se změnila na metodu <ph name="INPUT_METHOD_ID"/>* <ph name="BEGIN_LINK"/>třetí strany<ph name="END_LINK"/>. Přepnout ji můžete stisknutím klávesové zkratky Shift + Alt.</translation>
-<translation id="5233638681132016545">Nová karta</translation>
 <translation id="3846575436967432996">Informace o síti nejsou k dispozici</translation>
 <translation id="3026237328237090306">Nastavení mobilního datového připojení</translation>
 <translation id="785750925697875037">Zobrazit mobilní účet</translation>
@@ -30,36 +34,45 @@
 <translation id="7864539943188674973">Vypnout Bluetooth</translation>
 <translation id="3126069444801937830">Restartovat a aktualizovat</translation>
 <translation id="735745346212279324">Síť VPN je odpojena</translation>
+<translation id="7320906967354320621">Nečinnost</translation>
 <translation id="6303423059719347535">Baterie je nabitá na <ph name="PERCENTAGE"/> %</translation>
+<translation id="2778346081696727092">Ověření prostřednictvím uvedeného uživatelského jména nebo hesla se nepodařilo.</translation>
 <translation id="3294437725009624529">Host</translation>
 <translation id="8190698733819146287">Personalizovat jazyky a zadávání...</translation>
-<translation id="598295083618286569">Rozhraní Bluetooth je připojeno</translation>
+<translation id="7170041865419449892">Mimo dosah</translation>
+<translation id="4804818685124855865">Odpojit</translation>
 <translation id="5222676887888702881">Odhlásit se</translation>
+<translation id="2688477613306174402">Konfigurace</translation>
+<translation id="1272079795634619415">Zastavit</translation>
 <translation id="4957722034734105353">Další informace...</translation>
 <translation id="2964193600955408481">Vypnout Wi-Fi</translation>
 <translation id="811680302244032017">Přidat zařízení...</translation>
 <translation id="2509468283778169019">CAPS LOCK je zapnutý</translation>
 <translation id="3892641579809465218">Interní displej</translation>
 <translation id="7823564328645135659">Jazyk prohlížeče Chrome se po synchronizaci nastavení změnil z jazyka <ph name="FROM_LOCALE"/> na jazyk <ph name="TO_LOCALE"/>.</translation>
+<translation id="3368922792935385530">Připojeno</translation>
 <translation id="8340999562596018839">Hlasová odezva</translation>
 <translation id="8654520615680304441">Zapnout Wi-Fi...</translation>
 <translation id="5825747213122829519">Metoda zadávání se změnila na metodu <ph name="INPUT_METHOD_ID"/>. Přepnout ji můžete stisknutím klávesové zkratky Shift + Alt.</translation>
 <translation id="2562916301614567480">Soukromá síť</translation>
 <translation id="6549021752953852991">Není k dispozici žádná mobilní síť.</translation>
+<translation id="4379753398862151997">Drahý monitore, nějak to mezi námi nefunguje. (Monitor není podporován.)</translation>
 <translation id="6426039856985689743">Zakázat  mobilní datové připojení</translation>
 <translation id="3087734570205094154">Až dolů</translation>
 <translation id="5271016907025319479">Síť VPN není nakonfigurována.</translation>
-<translation id="1298695107722797780">Ukončit veřejnou\nrelaci</translation>
-<translation id="3232695630852378748">Nastavení Bluetooth...</translation>
+<translation id="6803622936009808957">Zobrazení nelze zrcadlit, protože nebyla nalezena podporovaná rozlišení. Místo toho se spustil režim rozšířené pracovní plochy.</translation>
 <translation id="1480041086352807611">Režim ukázky</translation>
 <translation id="3626637461649818317">Zbývá <ph name="PERCENTAGE"/> %</translation>
 <translation id="9089416786594320554">Metody zadávání dat</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/> %</translation>
 <translation id="1895658205118569222">Vypnout počítač</translation>
 <translation id="4430019312045809116">Hlasitost</translation>
+<translation id="4442424173763614572">Nepodařilo se nalézt server DNS.</translation>
 <translation id="6356500677799115505">Baterie je plně nabitá a nabíjí se.</translation>
 <translation id="7874779702599364982">Vyhledávání mobilních sítí...</translation>
+<translation id="583281660410589416">Neznámý</translation>
 <translation id="1383876407941801731">Vyhledávání</translation>
+<translation id="7468789844759750875">Chcete-li koupit více dat, navštivte aktivační portál <ph name="NAME"/>.</translation>
 <translation id="3901991538546252627">Připojování k síti <ph name="NAME"/></translation>
 <translation id="2204305834655267233">Informace o síti</translation>
 <translation id="1621499497873603021">Čas zbývající do vybití baterie: <ph name="TIME_LEFT"/></translation>
@@ -68,55 +81,74 @@
 <translation id="8308637677604853869">Předchozí nabídka</translation>
 <translation id="1346748346194534595">Doprava</translation>
 <translation id="8528322925433439945">Mobilní sítě...</translation>
+<translation id="7049357003967926684">Přidružení</translation>
 <translation id="8428213095426709021">Nastavení</translation>
-<translation id="2472320577759310817">Připojení Bluetooth je vypnuto.</translation>
 <translation id="2372145515558759244">Synchronizace aplikací...</translation>
+<translation id="7256405249507348194">Neznámá chyba: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">Selhala bezpečnostní kontrola AAA</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: Odpojování...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> do úplného nabití</translation>
 <translation id="5787281376604286451">Hlasová odezva je aktivní
 Stiskem kláves Ctrl+Alt+Z ji deaktivujete.</translation>
 <translation id="4479639480957787382">Ethernet</translation>
+<translation id="6312403991423642364">Neznámá chyba sítě</translation>
 <translation id="1467432559032391204">Doleva</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830">Aktivace sítě <ph name="NAME"/></translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">Maximalizovat</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: Připojování...</translation>
+<translation id="8639033665604704195">Ověření pomocí poskytnutého předsdíleného klíče se nezdařilo.</translation>
 <translation id="252373100621549798">Neznámý displej</translation>
 <translation id="1882897271359938046">Zrcadlení na displej <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Uzamknout</translation>
 <translation id="2805756323405976993">Aplikace</translation>
-<translation id="2482878487686419369">Oznámení</translation>
+<translation id="1512064327686280138">Aktivace se nezdařila</translation>
+<translation id="5097002363526479830">Připojení k síti <ph name="NAME"/> se nezdařilo: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Připojení Wi-Fi je vypnuto.</translation>
-<translation id="2872961005593481000">Vypnout</translation>
+<translation id="8036518327127111261">Ověření prostřednictvím uvedeného certifikátu se nezdařilo.</translation>
 <translation id="8132793192354020517">Připojeno k síti <ph name="NAME"/></translation>
 <translation id="7052914147756339792">Nastavení tapety...</translation>
-<translation id="2739500853984626550">Žádná zařízení Bluetooth nejsou k dispozici.</translation>
-<translation id="2666092431469916601">Nahoru</translation>
+<translation id="8678698760965522072">Stav online</translation>
+<translation id="1119447706177454957">Interní chyba</translation>
 <translation id="3019353588588144572">Čas zbývající do úplného nabití baterie: <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">Lupa obrazovky</translation>
+<translation id="7005812687360380971">Selhání</translation>
 <translation id="1602076796624386989">Povolit mobilní datové připojení</translation>
 <translation id="6981982820502123353">Usnadnění</translation>
 <translation id="3157931365184549694">Obnovit</translation>
+<translation id="4274292172790327596">Neznámá chyba</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Vyhledávání zařízení…</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Vyhledávání sítí Wi-Fi...</translation>
+<translation id="7229570126336867161">Je zapotřebí technologie EVDO.</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> je veřejná relace spravovaná doménou <ph name="DOMAIN"/>.</translation>
 <translation id="7029814467594812963">Ukončit relaci</translation>
 <translation id="8454013096329229812">Připojení Wi-Fi je zapnuto.</translation>
 <translation id="4872237917498892622">Alt + Vyhledávání nebo Shift</translation>
 <translation id="2983818520079887040">Nastavení...</translation>
-<translation id="5467313780247887226">Nelze duplikovat obraz na připojené monitory. Nebylo nalezeno odpovídající rozlišení.</translation>
+<translation id="8927026611342028580">Je vyžadováno připojení</translation>
+<translation id="8300849813060516376">Selhání OTASP</translation>
 <translation id="2792498699870441125">Alt + Vyhledávání</translation>
 <translation id="8660803626959853127">Synchronizace souborů (<ph name="COUNT"/>)</translation>
 <translation id="639644700271529076">CAPS LOCK je vypnutý</translation>
-<translation id="4101192585425716296">Centrum zpráv</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: Probíhá aktivace...</translation>
+<translation id="1391854757121130358">Pravděpodobně jste vyčerpali povolený objem mobilních datových přenosů.</translation>
 <translation id="4864165860509564259">Pozice spouštěče</translation>
 <translation id="7593891976182323525">Vyhledávání nebo Shift</translation>
 <translation id="7649070708921625228">Nápověda</translation>
 <translation id="3050422059534974565">CAPS LOCK je zapnutý. Vypnete jej stisknutím klávesy Vyhledávání nebo Shift.</translation>
 <translation id="397105322502079400">Probíhá výpočet…</translation>
+<translation id="158849752021629804">Je potřeba domácí síť</translation>
+<translation id="6857811139397017780">Aktivovat: <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">Vyhledávání serveru DHCP selhalo.</translation>
+<translation id="6692173217867674490">Chybné přístupové heslo</translation>
 <translation id="6165508094623778733">Další informace</translation>
+<translation id="9046895021617826162">Připojení selhalo</translation>
+<translation id="973896785707726617">Relace bude ukončena za <ph name="SESSION_TIME_REMAINING"/>. Poté budete automaticky odhlášeni.</translation>
+<translation id="8372369524088641025">Chybný klíč WEP</translation>
+<translation id="6636709850131805001">Neznámý stav</translation>
 <translation id="3573179567135747900">Změnit zpět na jazyk <ph name="FROM_LOCALE"/> (vyžaduje restart)</translation>
 <translation id="8103386449138765447">Zprávy SMS: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Nastavení Disku Google...</translation>
@@ -127,7 +159,7 @@
 <translation id="8000066093800657092">Žádná síť</translation>
 <translation id="5941711191222866238">Minimalizovat</translation>
 <translation id="6911468394164995108">Připojit k jiné...</translation>
-<translation id="6843725295806269523">ztlumit</translation>
 <translation id="412065659894267608"><ph name="HOUR"/> h <ph name="MINUTE"/> min do nabití</translation>
 <translation id="6359806961507272919">SMS z čísla <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Operátor</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_da.xtb b/ash/strings/ash_strings_da.xtb
index 3fd5f6b..217f773 100644
--- a/ash/strings/ash_strings_da.xtb
+++ b/ash/strings/ash_strings_da.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Batteri fuldt</translation>
 <translation id="5250713215130379958">Skjul automatisk applikationslisten</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> og <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Tilstand for portal</translation>
 <translation id="30155388420722288">Knappen Overflow</translation>
 <translation id="5571066253365925590">Bluetooth er aktiveret</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Proxy...</translation>
 <translation id="938582441709398163">Tastaturoverlejring</translation>
 <translation id="6979158407327259162">Google Drev</translation>
+<translation id="6943836128787782965">Det lykkedes ikke at hente HTTP</translation>
 <translation id="2297568595583585744">Statusbakke</translation>
+<translation id="1661867754829461514">Pinkode mangler</translation>
 <translation id="4508225577814909926"><ph name="NAME"/> : Opretter forbindelse...</translation>
+<translation id="4237016987259239829">Netværkforbindelsesfejl</translation>
 <translation id="2946640296642327832">Aktivér Bluetooth</translation>
 <translation id="6459472438155181876">Udvider skærmen til <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Mobil</translation>
 <translation id="6596816719288285829">IP-adresse</translation>
+<translation id="4508265954913339219">Aktiveringen mislykkedes</translation>
 <translation id="1812696562331527143">Din inputmetode er ændret til <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>tredjepart<ph name="END_LINK"/>).
 Tryk på Shift+Alt for at ændre den.</translation>
-<translation id="5233638681132016545">Ny fane</translation>
 <translation id="3846575436967432996">Der er ingen tilgængelige netværksoplysninger</translation>
 <translation id="3026237328237090306">Konfigurer mobildata</translation>
 <translation id="785750925697875037">Vis mobilkonto</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Deaktiver Bluetooth</translation>
 <translation id="3126069444801937830">Genstart for at opdatere</translation>
 <translation id="735745346212279324">VPN afbrudt</translation>
+<translation id="7320906967354320621">Ikke aktiv</translation>
 <translation id="6303423059719347535">Batteriet er <ph name="PERCENTAGE"/> % fuldt</translation>
+<translation id="2778346081696727092">Der kunne ikke godkendes med det angivne brugernavn eller adgangskoden</translation>
 <translation id="3294437725009624529">Gæst</translation>
 <translation id="8190698733819146287">Tilpas sprog og indtastning...</translation>
-<translation id="598295083618286569">Bluetooth tilsluttet</translation>
+<translation id="7170041865419449892">Intet signal</translation>
+<translation id="4804818685124855865">Afbryd</translation>
 <translation id="5222676887888702881">Log ud</translation>
+<translation id="2688477613306174402">Konfiguration</translation>
+<translation id="1272079795634619415">Stop</translation>
 <translation id="4957722034734105353">Flere oplysninger...</translation>
 <translation id="2964193600955408481">Deaktiver Wi-Fi</translation>
 <translation id="811680302244032017">Tilføj enhed...</translation>
 <translation id="2509468283778169019">CAPS LOCK er slået til</translation>
 <translation id="3892641579809465218">Internt display</translation>
 <translation id="7823564328645135659">Sproget er blevet ændret fra &quot;<ph name="FROM_LOCALE"/>&quot; til &quot;<ph name="TO_LOCALE"/>&quot;, efter at du har synkroniseret dine indstillinger.</translation>
+<translation id="3368922792935385530">Tilsluttet</translation>
 <translation id="8340999562596018839">Talefeedback</translation>
 <translation id="8654520615680304441">Slå Wi-Fi til...</translation>
 <translation id="5825747213122829519">Din inputmetode er ændret til <ph name="INPUT_METHOD_ID"/>.
 Tryk på Shift+Alt for at ændre den.</translation>
 <translation id="2562916301614567480">Privat netværk</translation>
 <translation id="6549021752953852991">Der er ingen tilgængelige mobilnetværk</translation>
+<translation id="4379753398862151997">Kære Skærm. Det fungerer ikke mellem os. (Denne skærm understøttes ikke)</translation>
 <translation id="6426039856985689743">Deaktiver mobildata</translation>
 <translation id="3087734570205094154">Bund</translation>
 <translation id="5271016907025319479">VPN er ikke konfigureret.</translation>
-<translation id="1298695107722797780">Afslut public\nsession</translation>
-<translation id="3232695630852378748">Bluetooth-indstillinger...</translation>
+<translation id="6803622936009808957">Skærmene kunne ikke spejles, da der ikke fandtes en understøttet opløsning. I stedet anvendes Udvidet skrivebord.</translation>
 <translation id="1480041086352807611">Demotilstand</translation>
 <translation id="3626637461649818317"><ph name="PERCENTAGE"/> % tilbage</translation>
 <translation id="9089416786594320554">Indtastningsmetoder</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/> %</translation>
 <translation id="1895658205118569222">Nedlukning</translation>
 <translation id="4430019312045809116">Lydstyrke</translation>
+<translation id="4442424173763614572">DNS-opslag mislykkedes</translation>
 <translation id="6356500677799115505">Batteriet er fuldt opladet og oplader.</translation>
 <translation id="7874779702599364982">Søger efter mobilnetværk...</translation>
+<translation id="583281660410589416">Ukendt</translation>
 <translation id="1383876407941801731">Søgning</translation>
+<translation id="7468789844759750875">Gå til aktiveringsportalen <ph name="NAME"/> for at købe mere data.</translation>
 <translation id="3901991538546252627">Opretter forbindelse til <ph name="NAME"/></translation>
 <translation id="2204305834655267233">Netværksoplysninger</translation>
 <translation id="1621499497873603021">Tid tilbage, indtil batteriet er tomt, <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">Forrige menu</translation>
 <translation id="1346748346194534595">Højre</translation>
 <translation id="8528322925433439945">Mobil...</translation>
+<translation id="7049357003967926684">Tilknytning</translation>
 <translation id="8428213095426709021">Indstillinger</translation>
-<translation id="2472320577759310817">Bluetooth er slået fra.</translation>
 <translation id="2372145515558759244">Synkroniserer apps...</translation>
+<translation id="7256405249507348194">Ukendt fejl: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">AAA-kontrol mislykkedes</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: Afbryder forbindelsen...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> indtil fuldt opladet</translation>
 <translation id="5787281376604286451">Talefeedback er aktiveret.
 Tryk på Ctrl+Alt+Z for at deaktivere dette.</translation>
 <translation id="4479639480957787382">Ethernet</translation>
+<translation id="6312403991423642364">Ukendt netværksfejl</translation>
 <translation id="1467432559032391204">Venstre</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830">Aktiverer <ph name="NAME"/></translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">Maksimer</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: Opretter forbindelse...</translation>
+<translation id="8639033665604704195">Der kunne ikke godkendes med den angivne foruddelte nøgle</translation>
 <translation id="252373100621549798">Ukendt skærm</translation>
 <translation id="1882897271359938046">Spejler mod <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Lås</translation>
 <translation id="2805756323405976993">Applikationer</translation>
-<translation id="2482878487686419369">Meddelelser</translation>
+<translation id="1512064327686280138">Aktiveringsfejl:</translation>
+<translation id="5097002363526479830">Der kunne ikke oprettes forbindelse til netværket &quot;<ph name="NAME"/>&quot;: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi er slået fra.</translation>
-<translation id="2872961005593481000">Luk</translation>
+<translation id="8036518327127111261">Der kunne ikke godkendes med det angivne certifikat</translation>
 <translation id="8132793192354020517">Forbundet til <ph name="NAME"/></translation>
 <translation id="7052914147756339792">Angiv baggrundsbillede...</translation>
-<translation id="2739500853984626550">Ingen Bluetooth-enheder til rådighed</translation>
-<translation id="2666092431469916601">Top</translation>
+<translation id="8678698760965522072">Onlinetilstand</translation>
+<translation id="1119447706177454957">Intern fejl</translation>
 <translation id="3019353588588144572">Resterende tid, indtil batteriet er fuldt opladet, <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">Skærmforstørrer</translation>
+<translation id="7005812687360380971">Fejl:</translation>
 <translation id="1602076796624386989">Aktivér mobildata</translation>
 <translation id="6981982820502123353">Tilgængelighed</translation>
 <translation id="3157931365184549694">Gendan</translation>
+<translation id="4274292172790327596">Fejlen genkendes ikke</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Scanner efter enheder...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/> d. <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Søger efter Wi-Fi-netværk...</translation>
+<translation id="7229570126336867161">EVDO mangler</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> er en offentlig session administreret af <ph name="DOMAIN"/></translation>
 <translation id="7029814467594812963">Afslut session</translation>
 <translation id="8454013096329229812">Wi-Fi er slået til.</translation>
 <translation id="4872237917498892622">Alt+Søg eller Skift</translation>
 <translation id="2983818520079887040">Indstillinger...</translation>
-<translation id="5467313780247887226">Kan ikke kopiere billedet på de tilsluttede skærme. Der blev ikke fundet en matchende opløsning.</translation>
+<translation id="8927026611342028580">Der er anmodet om forbindelse</translation>
+<translation id="8300849813060516376">OTASP mislykkedes</translation>
 <translation id="2792498699870441125">Alt+Søg</translation>
 <translation id="8660803626959853127">Synkroniserer <ph name="COUNT"/> fil(er)</translation>
 <translation id="639644700271529076">CAPS LOCK er deaktiveret</translation>
-<translation id="4101192585425716296">Meddelelsescenter</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: Aktiverer...</translation>
+<translation id="1391854757121130358">Du har muligvis nået din mobildatagrænse.</translation>
 <translation id="4864165860509564259">Applikationslistens placering</translation>
 <translation id="7593891976182323525">Søg eller skift</translation>
 <translation id="7649070708921625228">Hjælp</translation>
 <translation id="3050422059534974565">CAPS LOCK er slået til.
 Tryk på Søg eller Skift for at annullere.</translation>
 <translation id="397105322502079400">Beregner...</translation>
+<translation id="158849752021629804">Hjemmenetværk mangler</translation>
+<translation id="6857811139397017780">Aktiver <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">DHCP-opslag mislykkedes</translation>
+<translation id="6692173217867674490">Ugyldig adgangssætning</translation>
 <translation id="6165508094623778733">Flere oplysninger</translation>
+<translation id="9046895021617826162">Forbindelsen mislykkedes</translation>
+<translation id="973896785707726617">Denne session afsluttes om <ph name="SESSION_TIME_REMAINING"/>. Du logges automatisk ud.</translation>
+<translation id="8372369524088641025">Ugyldig WEP-nøgle</translation>
+<translation id="6636709850131805001">Tilstanden genkendes ikke</translation>
 <translation id="3573179567135747900">Skift tilbage til &quot;<ph name="FROM_LOCALE"/>&quot; (kræver genstart)</translation>
 <translation id="8103386449138765447">SMS-beskeder: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Google Drev-indstillinger...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">Intet netværk</translation>
 <translation id="5941711191222866238">Minimer</translation>
 <translation id="6911468394164995108">Find andre... </translation>
-<translation id="6843725295806269523">slå lyden fra</translation>
 <translation id="412065659894267608"><ph name="HOUR"/> t <ph name="MINUTE"/> m, indtil det er fuldt opladet</translation>
 <translation id="6359806961507272919">Sms fra <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Mobilselskab</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_de.xtb b/ash/strings/ash_strings_de.xtb
index 4a02bfe..f2ab1a8 100644
--- a/ash/strings/ash_strings_de.xtb
+++ b/ash/strings/ash_strings_de.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Akku voll</translation>
 <translation id="5250713215130379958">Übersicht automatisch ausblenden</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> und <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Portal-Status</translation>
 <translation id="30155388420722288">Überlaufschaltfläche</translation>
 <translation id="5571066253365925590">Bluetooth aktiviert</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Proxy...</translation>
 <translation id="938582441709398163">Tastatur-Overlay</translation>
 <translation id="6979158407327259162">Google Drive</translation>
+<translation id="6943836128787782965">HTTP-Abruf fehlgeschlagen</translation>
 <translation id="2297568595583585744">Statusleiste</translation>
+<translation id="1661867754829461514">PIN fehlt</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: Verbindung wird hergestellt...</translation>
+<translation id="4237016987259239829">Fehler bei der Netzwerkverbindung</translation>
 <translation id="2946640296642327832">Bluetooth aktivieren</translation>
 <translation id="6459472438155181876">Bildschirm wird auf <ph name="DISPLAY_NAME"/> erweitert...</translation>
 <translation id="8206859287963243715">Mobil</translation>
 <translation id="6596816719288285829">IP-Adresse</translation>
+<translation id="4508265954913339219">Aktivierung fehlgeschlagen</translation>
 <translation id="1812696562331527143">Ihre Eingabemethode hat sich in <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>Drittanbieter<ph name="END_LINK"/>) geändert.
 Drücken Sie zum Wechseln Umschalt+Alt.</translation>
-<translation id="5233638681132016545">Neuer Tab</translation>
 <translation id="3846575436967432996">Keine Netzwerkinformationen verfügbar</translation>
 <translation id="3026237328237090306">Mobilfunk einrichten</translation>
 <translation id="785750925697875037">Mobiles Konto aufrufen</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Bluetooth deaktivieren</translation>
 <translation id="3126069444801937830">Zum Aktualisieren neu starten</translation>
 <translation id="735745346212279324">VPN-Verbindung getrennt</translation>
+<translation id="7320906967354320621">Inaktiv</translation>
 <translation id="6303423059719347535">Akku ist zu <ph name="PERCENTAGE"/> % geladen.</translation>
+<translation id="2778346081696727092">Fehler beim Authentifizieren mit dem angegebenen Nutzernamen oder Passwort</translation>
 <translation id="3294437725009624529">Gast</translation>
 <translation id="8190698733819146287">Sprache und Eingabe anpassen...</translation>
-<translation id="598295083618286569">Mit Bluetooth verbunden</translation>
+<translation id="7170041865419449892">Außerhalb des Bereichs</translation>
+<translation id="4804818685124855865">Verbindung trennen</translation>
 <translation id="5222676887888702881">Abmelden</translation>
+<translation id="2688477613306174402">Konfiguration</translation>
+<translation id="1272079795634619415">Stopp</translation>
 <translation id="4957722034734105353">Weitere Informationen...</translation>
 <translation id="2964193600955408481">WLAN deaktivieren</translation>
 <translation id="811680302244032017">Gerät hinzufügen...</translation>
 <translation id="2509468283778169019">Feststelltaste An</translation>
 <translation id="3892641579809465218">Interne Anzeige</translation>
 <translation id="7823564328645135659">Nach der Synchronisierung Ihrer Einstellungen wurde die Sprache von &quot;<ph name="FROM_LOCALE"/>&quot; in &quot;<ph name="TO_LOCALE"/>&quot; geändert.</translation>
+<translation id="3368922792935385530">Verbunden</translation>
 <translation id="8340999562596018839">Gesprochenes Feedback</translation>
 <translation id="8654520615680304441">WLAN aktivieren...</translation>
 <translation id="5825747213122829519">Ihre Eingabemethode hat sich in <ph name="INPUT_METHOD_ID"/> geändert.
 Drücken Sie zum Wechseln Umschalt+Alt.</translation>
 <translation id="2562916301614567480">Privates Netzwerk</translation>
 <translation id="6549021752953852991">Kein Mobilfunknetz verfügbar</translation>
+<translation id="4379753398862151997">Der Monitor wird nicht unterstützt.</translation>
 <translation id="6426039856985689743">Mobilfunk deaktivieren</translation>
 <translation id="3087734570205094154">Unten</translation>
 <translation id="5271016907025319479">VPN ist nicht konfiguriert.</translation>
-<translation id="1298695107722797780">Öffentliche\nSitzung beenden</translation>
-<translation id="3232695630852378748">Bluetooth-Einstellungen...</translation>
+<translation id="6803622936009808957">Der Bildschirm konnte nicht gespiegelt werden, da die Auflösung nicht unterstützt wird. Stattdessen wurde der Modus für den erweiterten Desktop gestartet.</translation>
 <translation id="1480041086352807611">Demo-Modus</translation>
 <translation id="3626637461649818317"><ph name="PERCENTAGE"/> % verbleibend</translation>
 <translation id="9089416786594320554">Eingabemethoden</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/> %</translation>
 <translation id="1895658205118569222">Herunterfahren</translation>
 <translation id="4430019312045809116">Lautstärke</translation>
+<translation id="4442424173763614572">DNS-Suche fehlgeschlagen</translation>
 <translation id="6356500677799115505">Akku ist vollständig geladen und wird noch geladen.</translation>
 <translation id="7874779702599364982">Suche nach Mobilfunknetzen läuft...</translation>
+<translation id="583281660410589416">Unbekannt</translation>
 <translation id="1383876407941801731">Suche</translation>
+<translation id="7468789844759750875">Besuchen Sie das <ph name="NAME"/>-Aktivierungsportal, um zusätzliches Datenvolumen zu kaufen.</translation>
 <translation id="3901991538546252627">Verbindung mit <ph name="NAME"/> wird hergestellt.</translation>
 <translation id="2204305834655267233">Netzwerkinformationen</translation>
 <translation id="1621499497873603021">Verbleibende Akku-Laufzeit: <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">Vorheriges Menü</translation>
 <translation id="1346748346194534595">Nach rechts</translation>
 <translation id="8528322925433439945">Mobil...</translation>
+<translation id="7049357003967926684">Verbindung</translation>
 <translation id="8428213095426709021">Einstellungen</translation>
-<translation id="2472320577759310817">Bluetooth ist deaktiviert.</translation>
 <translation id="2372145515558759244">Apps werden synchronisiert...</translation>
+<translation id="7256405249507348194">Unbekannter Fehler: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">AAA-Prüfung fehlgeschlagen</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: Verbindung wird getrennt...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> bis voll aufgeladen</translation>
 <translation id="5787281376604286451">Gesprochenes Feedback ist aktiviert.
 Zum Deaktivieren Strg+Alt+Z drücken</translation>
 <translation id="4479639480957787382">Ethernet</translation>
+<translation id="6312403991423642364">Unbekannter Netzwerkfehler</translation>
 <translation id="1467432559032391204">Nach links</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830"><ph name="NAME"/> wird aktiviert</translation>
 <translation id="8814190375133053267">WLAN</translation>
 <translation id="1398853756734560583">Vergrößern</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: Verbindung wird hergestellt...</translation>
+<translation id="8639033665604704195">Fehler beim Authentifizieren mit dem angegebenen vorinstallierten Schlüssel</translation>
 <translation id="252373100621549798">Display unbekannt</translation>
 <translation id="1882897271359938046">Wird auf <ph name="DISPLAY_NAME"/> gespiegelt...</translation>
 <translation id="3784455785234192852">Sperren</translation>
 <translation id="2805756323405976993">Apps</translation>
-<translation id="2482878487686419369">Benachrichtigungen</translation>
+<translation id="1512064327686280138">Aktivierungsfehler</translation>
+<translation id="5097002363526479830">Fehler beim Herstellen einer Verbindung mit dem Netzwerk &quot;<ph name="NAME"/>&quot;: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">WLAN ist deaktiviert.</translation>
-<translation id="2872961005593481000">Herunterfahren</translation>
+<translation id="8036518327127111261">Fehler beim Authentifizieren mit dem angegebenen Zertifikat</translation>
 <translation id="8132793192354020517">Verbunden mit <ph name="NAME"/></translation>
 <translation id="7052914147756339792">Hintergrund festlegen</translation>
-<translation id="2739500853984626550">Keine Bluetooth-Geräte verfügbar</translation>
-<translation id="2666092431469916601">Oben</translation>
+<translation id="8678698760965522072">Online-Status</translation>
+<translation id="1119447706177454957">Interner Fehler</translation>
 <translation id="3019353588588144572">Verbleibende Zeit, bis der Akku vollständig geladen ist: <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">Lupe</translation>
+<translation id="7005812687360380971">Fehler</translation>
 <translation id="1602076796624386989">Mobilfunk aktivieren</translation>
 <translation id="6981982820502123353">Bedienungshilfen</translation>
 <translation id="3157931365184549694">Wiederherstellen</translation>
+<translation id="4274292172790327596">Unbekannter Fehler</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Nach Geräten wird gesucht...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Suche nach WLAN-Netzwerken läuft...</translation>
+<translation id="7229570126336867161">EVDO erforderlich</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> ist eine öffentliche Sitzung, die von <ph name="DOMAIN"/> verwaltet wird.</translation>
 <translation id="7029814467594812963">Sitzung beenden</translation>
 <translation id="8454013096329229812">WLAN ist aktiviert.</translation>
 <translation id="4872237917498892622">Alt+Such- oder Umschalttaste</translation>
 <translation id="2983818520079887040">Einstellungen...</translation>
-<translation id="5467313780247887226">Das Bild auf angeschlossenen Monitoren kann nicht dupliziert werden. Keine passende Auflösung gefunden.</translation>
+<translation id="8927026611342028580">Verbindung angefordert</translation>
+<translation id="8300849813060516376">OTASP fehlgeschlagen</translation>
 <translation id="2792498699870441125">Alt+Suchtaste</translation>
 <translation id="8660803626959853127"><ph name="COUNT"/> Datei(en) wird bzw. werden synchronisiert.</translation>
 <translation id="639644700271529076">Feststelltaste Aus</translation>
-<translation id="4101192585425716296">Message Center</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: Wird aktiviert...</translation>
+<translation id="1391854757121130358">Sie haben möglicherweise Ihr mobiles Datenvolumen aufgebraucht.</translation>
 <translation id="4864165860509564259">Position der Übersicht</translation>
 <translation id="7593891976182323525">Such- oder Umschalttaste</translation>
 <translation id="7649070708921625228">Hilfe</translation>
 <translation id="3050422059534974565">Die Feststelltaste ist aktiviert.
 Drücken Sie die Such- oder die Umschalttaste, um die Aktivierung aufzuheben.</translation>
 <translation id="397105322502079400">Wird berechnet...</translation>
+<translation id="158849752021629804">Heimnetzwerk erforderlich</translation>
+<translation id="6857811139397017780"><ph name="NETWORKSERVICE"/> aktivieren</translation>
+<translation id="5864471791310927901">DHCP-Suche fehlgeschlagen</translation>
+<translation id="6692173217867674490">Ungültige Passphrase</translation>
 <translation id="6165508094623778733">Weitere Informationen</translation>
+<translation id="9046895021617826162">Verbindungsaufbau fehlgeschlagen</translation>
+<translation id="973896785707726617">Die Sitzung wird in <ph name="SESSION_TIME_REMAINING"/> beendet. Sie werden dann automatisch abgemeldet.</translation>
+<translation id="8372369524088641025">Ungültiger WEP-Schlüssel</translation>
+<translation id="6636709850131805001">Unbekannter Status</translation>
 <translation id="3573179567135747900">Zurücksetzen auf &quot;<ph name="FROM_LOCALE"/>&quot; (Neustart erforderlich)</translation>
 <translation id="8103386449138765447">SMS: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Google Drive-Einstellungen...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">Nicht verbunden</translation>
 <translation id="5941711191222866238">Verkleinern</translation>
 <translation id="6911468394164995108">Andere Netzwerke...</translation>
-<translation id="6843725295806269523">Stumm</translation>
 <translation id="412065659894267608">In <ph name="HOUR"/> Std. <ph name="MINUTE"/> Min. vollständig aufgeladen</translation>
 <translation id="6359806961507272919">SMS von <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Mobilfunkanbieter</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_el.xtb b/ash/strings/ash_strings_el.xtb
index dd772d8..4d744be 100644
--- a/ash/strings/ash_strings_el.xtb
+++ b/ash/strings/ash_strings_el.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Μπαταρία πλήρης</translation>
 <translation id="5250713215130379958">Αυτόματη απόκρυψη της λειτουργίας εκκίνησης</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> και <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Κατάσταση πύλης</translation>
 <translation id="30155388420722288">Κουμπί επιπρόσθετης ροής</translation>
 <translation id="5571066253365925590">Το Bluetooth έχει ενεργοποιηθεί</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Διακομιστής μεσολάβησης...</translation>
 <translation id="938582441709398163">Επικάλυψη πληκτρολογίου</translation>
 <translation id="6979158407327259162">Google Drive</translation>
+<translation id="6943836128787782965">Η λήψη HTTP απέτυχε</translation>
 <translation id="2297568595583585744">Δίσκος κατάστασης</translation>
+<translation id="1661867754829461514">Απουσιάζει το PIN </translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: Σύνδεση…</translation>
+<translation id="4237016987259239829">Σφάλμα σύνδεσης δικτύου</translation>
 <translation id="2946640296642327832">Ενεργοποίηση Bluetooth</translation>
 <translation id="6459472438155181876">Επέκταση οθόνης σε <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Κινητό</translation>
 <translation id="6596816719288285829">Διεύθυνση IP</translation>
+<translation id="4508265954913339219">Η ενεργοποίηση απέτυχε</translation>
 <translation id="1812696562331527143">Η μέθοδος εισαγωγής σας έχει αλλάξει σε <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>τρίτου μέρους<ph name="END_LINK"/>).
 Πατήστε Shift + Alt για εναλλαγή.</translation>
-<translation id="5233638681132016545">Νέα καρτέλα</translation>
 <translation id="3846575436967432996">Δεν υπάρχουν διαθέσιμες πληροφορίες δικτύου</translation>
 <translation id="3026237328237090306">Ρύθμιση δεδομένων κινητής τηλεφωνίας</translation>
 <translation id="785750925697875037">Προβολή λογαριασμού κινητής τηλεφωνίας</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Απενεργοποίηση Bluetooth</translation>
 <translation id="3126069444801937830">Επανεκκίνηση για ενημέρωση</translation>
 <translation id="735745346212279324">Το VPN αποσυνδέθηκε</translation>
+<translation id="7320906967354320621">Αδρανές</translation>
 <translation id="6303423059719347535">Η μπαταρία είναι πλήρης <ph name="PERCENTAGE"/>%</translation>
+<translation id="2778346081696727092">Δεν είναι δυνατός ο έλεγχος ταυτότητας με το όνομα χρήστη ή τον κωδικό πρόσβασης που παρέχεται</translation>
 <translation id="3294437725009624529">Επισκέπτης</translation>
 <translation id="8190698733819146287">Προσαρμογή γλωσσών και εισόδου...</translation>
-<translation id="598295083618286569">Το Bluetooth είναι συνδεδεμένο</translation>
+<translation id="7170041865419449892">Εκτός εύρους τιμών</translation>
+<translation id="4804818685124855865">Αποσύνδεση</translation>
 <translation id="5222676887888702881">Έξοδος</translation>
+<translation id="2688477613306174402">Διαμόρφωση</translation>
+<translation id="1272079795634619415">Διακοπή</translation>
 <translation id="4957722034734105353">Μάθετε περισσότερα…</translation>
 <translation id="2964193600955408481">Απενεργοποίηση Wi-Fi</translation>
 <translation id="811680302244032017">Προσθήκη συσκευής…</translation>
 <translation id="2509468283778169019">Το CAPS LOCK είναι ενεργοποιημένο</translation>
 <translation id="3892641579809465218">Εσωτερική οθόνη</translation>
 <translation id="7823564328645135659">Η γλώσσα του άλλαξε από &quot;<ph name="FROM_LOCALE"/>&quot; σε &quot;<ph name="TO_LOCALE"/>&quot; μετά τον συγχρονισμό των ρυθμίσεών σας.</translation>
+<translation id="3368922792935385530">Σε σύνδεση</translation>
 <translation id="8340999562596018839">Προφορικά σχόλια</translation>
 <translation id="8654520615680304441">Ενεργοποίηση Wi-Fi…</translation>
 <translation id="5825747213122829519">Η μέθοδος εισαγωγής σας έχει αλλάξει σε <ph name="INPUT_METHOD_ID"/>.
 Πατήστε Shift + Alt για εναλλαγή.</translation>
 <translation id="2562916301614567480">Ιδιωτικό δίκτυο</translation>
 <translation id="6549021752953852991">Δεν υπάρχει διαθέσιμο δίκτυο κινητής τηλεφωνίας</translation>
+<translation id="4379753398862151997">Αγαπητή οθόνη, κάτι δεν πάει καλά με εμάς. (Αυτή η οθόνη δεν υποστηρίζεται)</translation>
 <translation id="6426039856985689743">Απενεργοποίηση δεδομένων κινητής τηλεφωνίας</translation>
 <translation id="3087734570205094154">Κάτω</translation>
 <translation id="5271016907025319479">Το VPN δεν έχει διαμορφωθεί.</translation>
-<translation id="1298695107722797780">Λήξη δημόσιας\nπεριόδου σύνδεσης</translation>
-<translation id="3232695630852378748">Ρυθμίσεις Bluetooth…</translation>
+<translation id="6803622936009808957">Δεν ήταν δυνατός ο αντικατοπτρισμός των οθονών καθώς δεν βρέθηκαν υποστηριζόμενες αναλύσεις. Έχει ενεργοποιηθεί εναλλακτικά η εκτεταμένη επιφάνεια εργασίας.</translation>
 <translation id="1480041086352807611">Λειτουργία επίδειξης</translation>
 <translation id="3626637461649818317">Υπολείπεται <ph name="PERCENTAGE"/>%</translation>
 <translation id="9089416786594320554">Μέθοδοι εισαγωγής</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">Τερματισμός λειτουργίας</translation>
 <translation id="4430019312045809116">Ένταση</translation>
+<translation id="4442424173763614572">Η αναζήτηση DNS απέτυχε</translation>
 <translation id="6356500677799115505">Η μπαταρία είναι πλήρης και φορτίζει.</translation>
 <translation id="7874779702599364982">Αναζήτηση για δίκτυα κινητής τηλεφωνίας…</translation>
+<translation id="583281660410589416">Άγνωστο</translation>
 <translation id="1383876407941801731">Αναζήτηση</translation>
+<translation id="7468789844759750875">Επισκεφτείτε την πύλη ενεργοποίησης <ph name="NAME"/> για να αγοράσετε περισσότερα δεδομένα.</translation>
 <translation id="3901991538546252627">Σύνδεση με <ph name="NAME"/></translation>
 <translation id="2204305834655267233">Πληροφορίες δικτύου</translation>
 <translation id="1621499497873603021">Χρόνος που απομένει μέχρι να αδειάσει η μπαταρία, <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">Προηγούμενο μενού</translation>
 <translation id="1346748346194534595">Δεξιά</translation>
 <translation id="8528322925433439945">Κινητή τηλεφωνία...</translation>
+<translation id="7049357003967926684">Συσχετισμός</translation>
 <translation id="8428213095426709021">Ρυθμίσεις</translation>
-<translation id="2472320577759310817">Το Bluetooth είναι απενεργοποιημένο.</translation>
 <translation id="2372145515558759244">Συγχρονισμός εφαρμογών…</translation>
+<translation id="7256405249507348194">Μη αναγνωρίσιμο σφάλμα: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">Ο έλεγχος ΑΑΑ απέτυχε</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: Αποσύνδεση…</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> μέχρι την ολοκλήρωση</translation>
 <translation id="5787281376604286451">Τα προφορικά σχόλια έχουν ενεργοποιηθεί.
 Πατήστε Ctrl+Alt+Z για απενεργοποίηση.</translation>
 <translation id="4479639480957787382">Ethernet</translation>
+<translation id="6312403991423642364">Άγνωστο σφάλμα δικτύου</translation>
 <translation id="1467432559032391204">Αριστερά</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830">Ενεργοποίηση <ph name="NAME"/></translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">Μεγιστοποίηση</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: Σύνδεση…</translation>
+<translation id="8639033665604704195">Δεν ήταν δυνατός ο έλεγχος ταυτότητας με το ήδη κοινόχρηστο κλειδί που παρέχεται</translation>
 <translation id="252373100621549798">Άγνωστη οθόνη</translation>
 <translation id="1882897271359938046">Κατοπτρισμός σε <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Κλείδωμα</translation>
 <translation id="2805756323405976993">Εφαρμογές</translation>
-<translation id="2482878487686419369">Ειδοποιήσεις</translation>
+<translation id="1512064327686280138">Αποτυχία ενεργοποίησης</translation>
+<translation id="5097002363526479830">Δεν ήταν δυνατή η σύνδεση στο δίκτυο '<ph name="NAME"/>': <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Το Wi-Fi έχει απενεργοποιηθεί.</translation>
-<translation id="2872961005593481000">Τερματισμός λειτουργίας</translation>
+<translation id="8036518327127111261">Δεν ήταν δυνατός ο έλεγχος ταυτότητας με το πιστοποιητικό που παρέχεται</translation>
 <translation id="8132793192354020517">Έγινε σύνδεση με το δίκτυο <ph name="NAME"/></translation>
 <translation id="7052914147756339792">Ορισμός ταπετσαρίας...</translation>
-<translation id="2739500853984626550">Δεν υπάρχουν διαθέσιμες συσκευές Bluetooth</translation>
-<translation id="2666092431469916601">Κορυφή</translation>
+<translation id="8678698760965522072">Κατάσταση &quot;Σε σύνδεση&quot;</translation>
+<translation id="1119447706177454957">Εσωτερικό σφάλμα</translation>
 <translation id="3019353588588144572">Χρόνος που απομένει μέχρι να φορτιστεί πλήρως η μπαταρία, <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">Μεγεθυντής οθόνης</translation>
+<translation id="7005812687360380971">Αποτυχία</translation>
 <translation id="1602076796624386989">Ενεργοποίηση δεδομένων κινητής τηλεφωνίας</translation>
 <translation id="6981982820502123353">Προσβασιμότητα</translation>
 <translation id="3157931365184549694">Επαναφορά</translation>
+<translation id="4274292172790327596">Μη αναγνωρίσιμο σφάλμα</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Σάρωση για συσκευές…</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Αναζήτηση για δίκτυα Wi-Fi...</translation>
+<translation id="7229570126336867161">Απαιτείται EVDO</translation>
 <translation id="2999742336789313416">Το <ph name="DISPLAY_NAME"/> είναι μια δημόσια περίοδος σύνδεσης που διαχειρίζεται το <ph name="DOMAIN"/></translation>
 <translation id="7029814467594812963">Έξοδος από συνεδρία</translation>
 <translation id="8454013096329229812">Το Wi-Fi έχει ενεργοποιηθεί.</translation>
 <translation id="4872237917498892622">Alt+Search ή Shift</translation>
 <translation id="2983818520079887040">Ρυθμίσεις...</translation>
-<translation id="5467313780247887226">Δεν είναι δυνατή η δημιουργία διπλότυπου εικόνας σε προσαρτημένες οθόνες. Δεν βρέθηκε ανάλυση που να αντιστοιχεί στα κριτήρια.</translation>
+<translation id="8927026611342028580">Έχει υποβληθεί αίτημα σύνδεσης</translation>
+<translation id="8300849813060516376">Αποτυχία OTASP</translation>
 <translation id="2792498699870441125">Alt+Search</translation>
 <translation id="8660803626959853127">Συγχρονισμός <ph name="COUNT"/> αρχείων</translation>
 <translation id="639644700271529076">Το CAPS LOCK είναι απενεργοποιημένο</translation>
-<translation id="4101192585425716296">Κέντρο μηνυμάτων</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: Ενεργοποίηση…</translation>
+<translation id="1391854757121130358">Ενδέχεται να έχετε χρησιμοποιήσει το πρόγραμμά δεδομένων της κινητής τηλεφωνίας σας.</translation>
 <translation id="4864165860509564259">Θέση λειτουργίας εκκίνησης</translation>
 <translation id="7593891976182323525">Search ή Shift</translation>
 <translation id="7649070708921625228">Βοήθεια</translation>
 <translation id="3050422059534974565">Το πλήκτρο CAPS LOCK έχει ενεργοποιηθεί.
 Πατήστε Search ή Shift για ακύρωση.</translation>
 <translation id="397105322502079400">Υπολογισμός…</translation>
+<translation id="158849752021629804">Απαιτείται εγχώριο δίκτυο</translation>
+<translation id="6857811139397017780">Ενεργοποίηση <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">Αποτυχία αναζήτησης DHCP</translation>
+<translation id="6692173217867674490">Εσφαλμένη κωδική φράση</translation>
 <translation id="6165508094623778733">Μάθετε περισσότερα</translation>
+<translation id="9046895021617826162">Η σύνδεση απέτυχε</translation>
+<translation id="973896785707726617">Αυτή η περίοδος σύνδεσης θα λήξει αυτόματα σε <ph name="SESSION_TIME_REMAINING"/>. Θα αποσυνδεθείτε αυτόματα.</translation>
+<translation id="8372369524088641025">Εσφαλμένο κλειδί WEP</translation>
+<translation id="6636709850131805001">Μη αναγνωρίσιμη κατάσταση</translation>
 <translation id="3573179567135747900">Αλλάξτε το πάλι σε &quot;<ph name="FROM_LOCALE"/>&quot; (απαιτείται επανεκκίνηση)</translation>
 <translation id="8103386449138765447">Μηνύματα SMS: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Ρυθμίσεις Google Drive...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">Κανένα δίκτυο</translation>
 <translation id="5941711191222866238">Ελαχιστοποίηση</translation>
 <translation id="6911468394164995108">Συμμετοχή σε άλλο…</translation>
-<translation id="6843725295806269523">σίγαση</translation>
 <translation id="412065659894267608"><ph name="HOUR"/>ω <ph name="MINUTE"/>λ μέχρι να ολοκληρωθεί η φόρτιση</translation>
 <translation id="6359806961507272919">SMS από <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Εταιρεία κινητής τηλεφωνίας</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_en-GB.xtb b/ash/strings/ash_strings_en-GB.xtb
index bcad51e..ee6b915 100644
--- a/ash/strings/ash_strings_en-GB.xtb
+++ b/ash/strings/ash_strings_en-GB.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Battery full</translation>
 <translation id="5250713215130379958">Auto-hide launcher</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> and <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Portal state</translation>
 <translation id="30155388420722288">Overflow Button</translation>
 <translation id="5571066253365925590">Bluetooth enabled</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Proxy...</translation>
 <translation id="938582441709398163">Keyboard Overlay</translation>
 <translation id="6979158407327259162">Google Drive</translation>
+<translation id="6943836128787782965">HTTP get failed</translation>
 <translation id="2297568595583585744">Status tray</translation>
+<translation id="1661867754829461514">PIN missing</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: Connecting...</translation>
+<translation id="4237016987259239829">Network Connection Error</translation>
 <translation id="2946640296642327832">Enable Bluetooth</translation>
 <translation id="6459472438155181876">Extending screen to <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Mobile</translation>
 <translation id="6596816719288285829">IP Address</translation>
+<translation id="4508265954913339219">Activation failed</translation>
 <translation id="1812696562331527143">Your input method has changed to <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>3rd party<ph name="END_LINK"/>).
 Press Shift + Alt to switch.</translation>
-<translation id="5233638681132016545">New tab</translation>
 <translation id="3846575436967432996">No network information available</translation>
 <translation id="3026237328237090306">Set up mobile data</translation>
 <translation id="785750925697875037">View mobile account</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Disable Bluetooth</translation>
 <translation id="3126069444801937830">Restart to update</translation>
 <translation id="735745346212279324">VPN disconnected</translation>
+<translation id="7320906967354320621">Idle</translation>
 <translation id="6303423059719347535">Battery is <ph name="PERCENTAGE"/>% full</translation>
+<translation id="2778346081696727092">Failed to authenticate with the provided username or password</translation>
 <translation id="3294437725009624529">Guest</translation>
 <translation id="8190698733819146287">Customise languages and input...</translation>
-<translation id="598295083618286569">Bluetooth connected</translation>
+<translation id="7170041865419449892">Out of range</translation>
+<translation id="4804818685124855865">Disconnect</translation>
 <translation id="5222676887888702881">Sign out</translation>
+<translation id="2688477613306174402">Configuration</translation>
+<translation id="1272079795634619415">Stop</translation>
 <translation id="4957722034734105353">Learn more...</translation>
 <translation id="2964193600955408481">Disable Wi-Fi</translation>
 <translation id="811680302244032017">Add device ...</translation>
 <translation id="2509468283778169019">CAPS LOCK is on</translation>
 <translation id="3892641579809465218">Internal Display</translation>
 <translation id="7823564328645135659">The language has changed from &quot;<ph name="FROM_LOCALE"/>&quot; to &quot;<ph name="TO_LOCALE"/>&quot; after syncing your settings.</translation>
+<translation id="3368922792935385530">Connected</translation>
 <translation id="8340999562596018839">Spoken feedback</translation>
 <translation id="8654520615680304441">Turn Wi-Fi on...</translation>
 <translation id="5825747213122829519">Your input method has changed to <ph name="INPUT_METHOD_ID"/>.
 Press Shift + Alt to switch.</translation>
 <translation id="2562916301614567480">Private Network</translation>
 <translation id="6549021752953852991">No mobile network available</translation>
+<translation id="4379753398862151997">Dear Monitor, it's not working out between us. (That monitor is not supported)</translation>
 <translation id="6426039856985689743">Disable mobile data</translation>
 <translation id="3087734570205094154">Bottom</translation>
 <translation id="5271016907025319479">VPN is not configured.</translation>
-<translation id="1298695107722797780">End public\nsession</translation>
-<translation id="3232695630852378748">Bluetooth settings ...</translation>
+<translation id="6803622936009808957">Could not mirror displays since no supported resolutions found. Entered extended desktop instead.</translation>
 <translation id="1480041086352807611">Demo mode</translation>
 <translation id="3626637461649818317"><ph name="PERCENTAGE"/>% remaining</translation>
 <translation id="9089416786594320554">Input methods</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">Shutdown</translation>
 <translation id="4430019312045809116">volume</translation>
+<translation id="4442424173763614572">DNS lookup failed</translation>
 <translation id="6356500677799115505">Battery is full and charging.</translation>
 <translation id="7874779702599364982">Searching for cellular networks...</translation>
+<translation id="583281660410589416">Unknown</translation>
 <translation id="1383876407941801731">Search</translation>
+<translation id="7468789844759750875">Visit the <ph name="NAME"/> activation portal to buy more data.</translation>
 <translation id="3901991538546252627">Connecting to <ph name="NAME"/></translation>
 <translation id="2204305834655267233">Network Info</translation>
 <translation id="1621499497873603021">Time left until battery is empty, <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">Previous menu</translation>
 <translation id="1346748346194534595">Right</translation>
 <translation id="8528322925433439945">Mobile ...</translation>
+<translation id="7049357003967926684">Association</translation>
 <translation id="8428213095426709021">Settings</translation>
-<translation id="2472320577759310817">Bluetooth is turned off.</translation>
 <translation id="2372145515558759244">Syncing apps...</translation>
+<translation id="7256405249507348194">Unrecognised error: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">AAA check failed</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: Disconnecting...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> until full</translation>
 <translation id="5787281376604286451">Spoken feedback is enabled.
 Press Ctrl+Alt+Z to disable.</translation>
 <translation id="4479639480957787382">Ethernet</translation>
+<translation id="6312403991423642364">Unknown network error</translation>
 <translation id="1467432559032391204">Left</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830">Activating <ph name="NAME"/></translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">Maximise</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: Connecting...</translation>
+<translation id="8639033665604704195">Failed to authenticate with the provided pre-shared key</translation>
 <translation id="252373100621549798">Unknown Display</translation>
 <translation id="1882897271359938046">Mirroring to <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Lock</translation>
 <translation id="2805756323405976993">Apps</translation>
-<translation id="2482878487686419369">Notifications</translation>
+<translation id="1512064327686280138">Activation failure</translation>
+<translation id="5097002363526479830">Failed to connect to the network '<ph name="NAME"/>': <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi is turned off.</translation>
-<translation id="2872961005593481000">Shut down</translation>
+<translation id="8036518327127111261">Failed to authenticate with the provided certificate</translation>
 <translation id="8132793192354020517">Connected to <ph name="NAME"/></translation>
 <translation id="7052914147756339792">Set wallpaper...</translation>
-<translation id="2739500853984626550">No bluetooth devices available</translation>
-<translation id="2666092431469916601">Top</translation>
+<translation id="8678698760965522072">Online state</translation>
+<translation id="1119447706177454957">Internal error</translation>
 <translation id="3019353588588144572">Time remaining until battery is fully charged, <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">Screen magnifier</translation>
+<translation id="7005812687360380971">Failure</translation>
 <translation id="1602076796624386989">Enable mobile data</translation>
 <translation id="6981982820502123353">Accessibility</translation>
 <translation id="3157931365184549694">Restore</translation>
+<translation id="4274292172790327596">Unrecognised error</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Scanning for devices...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Searching for Wi-Fi networks...</translation>
+<translation id="7229570126336867161">Need EVDO</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> is a public session managed by <ph name="DOMAIN"/></translation>
 <translation id="7029814467594812963">Exit session</translation>
 <translation id="8454013096329229812">Wi-Fi is turned on.</translation>
 <translation id="4872237917498892622">Alt+Search or Shift</translation>
 <translation id="2983818520079887040">Settings...</translation>
-<translation id="5467313780247887226">Can't duplicate image on attached monitors. No matching resolution found.</translation>
+<translation id="8927026611342028580">Connect Requested</translation>
+<translation id="8300849813060516376">OTASP failed</translation>
 <translation id="2792498699870441125">Alt+Search</translation>
 <translation id="8660803626959853127">Syncing <ph name="COUNT"/> file(s)</translation>
 <translation id="639644700271529076">CAPS LOCK is off</translation>
-<translation id="4101192585425716296">Message Centre</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: Activating...</translation>
+<translation id="1391854757121130358">You may have used up your mobile data allowance.</translation>
 <translation id="4864165860509564259">Launcher position</translation>
 <translation id="7593891976182323525">Search or Shift</translation>
 <translation id="7649070708921625228">Help</translation>
 <translation id="3050422059534974565">CAPS LOCK is on.
 Press Search or Shift to cancel.</translation>
 <translation id="397105322502079400">Calculating...</translation>
+<translation id="158849752021629804">Need home network</translation>
+<translation id="6857811139397017780">Activate <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">DHCP look-up failed</translation>
+<translation id="6692173217867674490">Bad passphrase</translation>
 <translation id="6165508094623778733">Learn more</translation>
+<translation id="9046895021617826162">Connection failed</translation>
+<translation id="973896785707726617">This session will end in <ph name="SESSION_TIME_REMAINING"/>. You will be automatically signed out.</translation>
+<translation id="8372369524088641025">Bad WEP key</translation>
+<translation id="6636709850131805001">Unrecognised state</translation>
 <translation id="3573179567135747900">Change back to &quot;<ph name="FROM_LOCALE"/>&quot; (requires restart)</translation>
 <translation id="8103386449138765447">SMS messages: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Google Drive settings</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">No network</translation>
 <translation id="5941711191222866238">Minimise</translation>
 <translation id="6911468394164995108">Join other ...</translation>
-<translation id="6843725295806269523">mute</translation>
 <translation id="412065659894267608"><ph name="HOUR"/>h <ph name="MINUTE"/>m until full</translation>
 <translation id="6359806961507272919">SMS from <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Operator</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_es-419.xtb b/ash/strings/ash_strings_es-419.xtb
index 7af4376..5276b64 100644
--- a/ash/strings/ash_strings_es-419.xtb
+++ b/ash/strings/ash_strings_es-419.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Batería completa</translation>
 <translation id="5250713215130379958">Ocultar automáticamente la barra de aplicaciones</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> y <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Estado de portal</translation>
 <translation id="30155388420722288">Botón de desbordamiento</translation>
 <translation id="5571066253365925590">Bluetooth activado</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Proxy...</translation>
 <translation id="938582441709398163">Superposición del teclado</translation>
 <translation id="6979158407327259162">Google Drive</translation>
+<translation id="6943836128787782965">Error al obtener HTTP</translation>
 <translation id="2297568595583585744">Bandeja de estado</translation>
+<translation id="1661867754829461514">Falta el número de PIN </translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: Conectando...</translation>
+<translation id="4237016987259239829">Error de conexión de red</translation>
 <translation id="2946640296642327832">Activar Bluetooth</translation>
 <translation id="6459472438155181876">Ampliando pantalla para <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Celular</translation>
 <translation id="6596816719288285829">Dirección IP</translation>
+<translation id="4508265954913339219">Falló la activación</translation>
 <translation id="1812696562331527143">Tu método de introducción cambió a <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>tercero<ph name="END_LINK"/>).
 Para cambiarlo, presiona Shift + Alt.</translation>
-<translation id="5233638681132016545">Nueva pestaña</translation>
 <translation id="3846575436967432996">No hay información de red disponible.</translation>
 <translation id="3026237328237090306">Configurar datos de dispositivos móviles</translation>
 <translation id="785750925697875037">Ver cuenta móvil</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Desactivar Bluetooth</translation>
 <translation id="3126069444801937830">Reinicia para actualizar.</translation>
 <translation id="735745346212279324">VPN desconectada</translation>
+<translation id="7320906967354320621">Inactivo</translation>
 <translation id="6303423059719347535"><ph name="PERCENTAGE"/>% de batería</translation>
+<translation id="2778346081696727092">Error al autenticar con el nombre de usuario o la contraseña proporcionados.</translation>
 <translation id="3294437725009624529">Invitado</translation>
 <translation id="8190698733819146287">Personalizar idiomas y la entrada de datos</translation>
-<translation id="598295083618286569">Bluetooth conectado</translation>
+<translation id="7170041865419449892">Fuera de alcance</translation>
+<translation id="4804818685124855865">Desconectar</translation>
 <translation id="5222676887888702881">Salir</translation>
+<translation id="2688477613306174402">Configuración</translation>
+<translation id="1272079795634619415">Interrumpir</translation>
 <translation id="4957722034734105353">Más información...</translation>
 <translation id="2964193600955408481">Desactivar Wi-Fi</translation>
 <translation id="811680302244032017">Agregar dispositivo...</translation>
 <translation id="2509468283778169019">BLOQ MAYÚS está activado.</translation>
 <translation id="3892641579809465218">Pantalla interna</translation>
 <translation id="7823564328645135659">Después de sincronizar tu configuración, el idioma se cambió de &quot;<ph name="FROM_LOCALE"/>&quot; a &quot;<ph name="TO_LOCALE"/>&quot;.</translation>
+<translation id="3368922792935385530">Conectado</translation>
 <translation id="8340999562596018839">Comentarios por voz</translation>
 <translation id="8654520615680304441">Encender Wi-Fi...</translation>
 <translation id="5825747213122829519">Tu método de introducción cambió a <ph name="INPUT_METHOD_ID"/>.
 Para cambiarlo, presiona Shift + Alt.</translation>
 <translation id="2562916301614567480">Red privada</translation>
 <translation id="6549021752953852991">No hay redes celulares disponibles.</translation>
+<translation id="4379753398862151997">Querido Monitor, lo nuestro no funciona. (Este monitor no es compatible).</translation>
 <translation id="6426039856985689743">Inhabilitar datos de dispositivos móviles</translation>
 <translation id="3087734570205094154">Inferior</translation>
 <translation id="5271016907025319479">La VPN no está configurada.</translation>
-<translation id="1298695107722797780">Finalizar sesión\npública</translation>
-<translation id="3232695630852378748">Configuración de Bluetooth ...</translation>
+<translation id="6803622936009808957">No se pudieron reflejar las pantallas porque no se encontraron resoluciones compatibles. En su lugar, se activó el escritorio extendido.</translation>
 <translation id="1480041086352807611">Modo demo</translation>
 <translation id="3626637461649818317"><ph name="PERCENTAGE"/>% restante</translation>
 <translation id="9089416786594320554">Métodos de entrada</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">Cierre</translation>
 <translation id="4430019312045809116">Volumen</translation>
+<translation id="4442424173763614572">Error al buscar DNS</translation>
 <translation id="6356500677799115505">Batería completa y cargando</translation>
 <translation id="7874779702599364982">Buscando redes para celulares...</translation>
+<translation id="583281660410589416">Desconocido</translation>
 <translation id="1383876407941801731">Buscar</translation>
+<translation id="7468789844759750875">Visita el portal de activación de <ph name="NAME"/> para comprar más datos.</translation>
 <translation id="3901991538546252627">Conectando con: <ph name="NAME"/></translation>
 <translation id="2204305834655267233">Información de red</translation>
 <translation id="1621499497873603021">Tiempo restante hasta que se agote la batería: <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">Menú anterior</translation>
 <translation id="1346748346194534595">Derecha</translation>
 <translation id="8528322925433439945">Dispositivos móviles...</translation>
+<translation id="7049357003967926684">Asociación</translation>
 <translation id="8428213095426709021">Configuración</translation>
-<translation id="2472320577759310817">Bluetooth está desactivado.</translation>
 <translation id="2372145515558759244">Sincronizando aplicaciones...</translation>
+<translation id="7256405249507348194">Error desconocido: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">Falló la verificación de AAA</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: Desconectando...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> hasta completarse</translation>
 <translation id="5787281376604286451">Los comentarios de voz están habilitados.
 Para inhabilitar esta opción, presiona Ctrl+Alt+Z.</translation>
 <translation id="4479639480957787382">Ethernet</translation>
+<translation id="6312403991423642364">Error de red desconocido</translation>
 <translation id="1467432559032391204">Izquierda</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830">Activación de <ph name="NAME"/></translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">Maximizar</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: Conectando...</translation>
+<translation id="8639033665604704195">Error al autenticar con la clave precompartida</translation>
 <translation id="252373100621549798">Pantalla desconocida</translation>
 <translation id="1882897271359938046">Copiando en <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Bloquear</translation>
 <translation id="2805756323405976993">Aplicaciones</translation>
-<translation id="2482878487686419369">Notificaciones</translation>
+<translation id="1512064327686280138">Fallo en la activación</translation>
+<translation id="5097002363526479830">Error al conectar a la red &quot;<ph name="NAME"/>&quot;: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi desactivada</translation>
-<translation id="2872961005593481000">Cerrar</translation>
+<translation id="8036518327127111261">Error al autenticar con el certificado proporcionado.</translation>
 <translation id="8132793192354020517">Conectado a <ph name="NAME"/></translation>
 <translation id="7052914147756339792">Establecer fondo de pantalla...</translation>
-<translation id="2739500853984626550">No hay dispositivos bluetooth disponibles.</translation>
-<translation id="2666092431469916601">Superior</translation>
+<translation id="8678698760965522072">Estado en línea</translation>
+<translation id="1119447706177454957">Error interno</translation>
 <translation id="3019353588588144572">Tiempo restante hasta que la batería esté completamente cargada: <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">Lupa</translation>
+<translation id="7005812687360380971">Fallo</translation>
 <translation id="1602076796624386989">Habilitar datos de dispositivos móviles</translation>
 <translation id="6981982820502123353">Accesibilidad</translation>
 <translation id="3157931365184549694">Restaurar</translation>
+<translation id="4274292172790327596">Error no reconocido</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Buscando dispositivos...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Buscando redes Wi-Fi...</translation>
+<translation id="7229570126336867161">Se necesita EVDO</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> es una sesión pública administrada por <ph name="DOMAIN"/>.</translation>
 <translation id="7029814467594812963">Salir de la sesión</translation>
 <translation id="8454013096329229812">Wi-Fi activada</translation>
 <translation id="4872237917498892622">Alt+tecla de búsqueda o Mayús</translation>
 <translation id="2983818520079887040">Configuración...</translation>
-<translation id="5467313780247887226">No se puede duplicar la imagen en monitores adjuntos. No se encontró una resolución que coincida.</translation>
+<translation id="8927026611342028580">Conexión solicitada</translation>
+<translation id="8300849813060516376">OTASP falló</translation>
 <translation id="2792498699870441125">Alt+tecla de búsqueda</translation>
 <translation id="8660803626959853127">Sincronizando <ph name="COUNT"/> archivo(s)</translation>
 <translation id="639644700271529076">El bloqueo de mayúsculas está desactivado.</translation>
-<translation id="4101192585425716296">Centro de mensajes</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: Activando...</translation>
+<translation id="1391854757121130358">Es posible que hayas agotado tu cuota de datos móviles.</translation>
 <translation id="4864165860509564259">Posición del selector</translation>
 <translation id="7593891976182323525">Tecla de búsqueda o Mayús</translation>
 <translation id="7649070708921625228">Ayuda</translation>
 <translation id="3050422059534974565">El BLOQUEO DE MAYÚSCULAS está activado.
 Presiona Mayús o la tecla de búsqueda para cancelar la operación.</translation>
 <translation id="397105322502079400">Calculando...</translation>
+<translation id="158849752021629804">Se necesita red local</translation>
+<translation id="6857811139397017780">Activar <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">Falló la búsqueda de DHCP</translation>
+<translation id="6692173217867674490">Frase de contraseña no válida</translation>
 <translation id="6165508094623778733">Más información</translation>
+<translation id="9046895021617826162">No se pudo conectar</translation>
+<translation id="973896785707726617">Esta sesión finalizará en <ph name="SESSION_TIME_REMAINING"/>. Saldrás automáticamente.</translation>
+<translation id="8372369524088641025">Clave de WEP no válida</translation>
+<translation id="6636709850131805001">Estado no reconocido</translation>
 <translation id="3573179567135747900">Volver a &quot;<ph name="FROM_LOCALE"/>&quot; (debes reiniciar).</translation>
 <translation id="8103386449138765447">Mensajes SMS: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Configuración de Google Drive...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">Sin red</translation>
 <translation id="5941711191222866238">Minimizar</translation>
 <translation id="6911468394164995108">Conectarte a otra red...</translation>
-<translation id="6843725295806269523">silencio</translation>
 <translation id="412065659894267608"><ph name="HOUR"/>h <ph name="MINUTE"/>min para completar la carga</translation>
 <translation id="6359806961507272919">SMS de <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Proveedor de servicio celular</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_es.xtb b/ash/strings/ash_strings_es.xtb
index e020583..153bfc3 100644
--- a/ash/strings/ash_strings_es.xtb
+++ b/ash/strings/ash_strings_es.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Batería al máximo</translation>
 <translation id="5250713215130379958">Ocultar automáticamente la barra de aplicaciones</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> y <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Conectado vía portal</translation>
 <translation id="30155388420722288">Botón de flujo excesivo</translation>
 <translation id="5571066253365925590">Bluetooth habilitado</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Proxy...</translation>
 <translation id="938582441709398163">Superposición de teclado</translation>
 <translation id="6979158407327259162">Google Drive</translation>
+<translation id="6943836128787782965">Error al obtener HTTP</translation>
 <translation id="2297568595583585744">Bandeja de estado</translation>
+<translation id="1661867754829461514">Falta el PIN.</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: conectando...</translation>
+<translation id="4237016987259239829">Error de conexión de red</translation>
 <translation id="2946640296642327832">Habilitar Bluetooth</translation>
 <translation id="6459472438155181876">Ampliando pantalla para <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Móvil</translation>
 <translation id="6596816719288285829">Dirección IP</translation>
+<translation id="4508265954913339219">Error de activación</translation>
 <translation id="1812696562331527143">Tu método de entrada ha cambiado a <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>externo<ph name="END_LINK"/>).
 Para cambiarlo, pulsa Mayús + Alt.</translation>
-<translation id="5233638681132016545">Nueva pestaña</translation>
 <translation id="3846575436967432996">No hay información de red disponible.</translation>
 <translation id="3026237328237090306">Configurar datos móviles</translation>
 <translation id="785750925697875037">Ver cuenta móvil</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Inhabilitar Bluetooth</translation>
 <translation id="3126069444801937830">Reinicia el sistema para actualizarlo.</translation>
 <translation id="735745346212279324">VPN desconectada</translation>
+<translation id="7320906967354320621">Inactiva</translation>
 <translation id="6303423059719347535"><ph name="PERCENTAGE"/>% de batería</translation>
+<translation id="2778346081696727092">Se ha producido un error al autenticar la contraseña o el nombre de usuario proporcionados.</translation>
 <translation id="3294437725009624529">Invitado</translation>
 <translation id="8190698733819146287">Personalizar idiomas...</translation>
-<translation id="598295083618286569">Bluetooth conectado</translation>
+<translation id="7170041865419449892">Fuera del alcance</translation>
+<translation id="4804818685124855865">Desvincular</translation>
 <translation id="5222676887888702881">Cerrar sesión</translation>
+<translation id="2688477613306174402">Configuración</translation>
+<translation id="1272079795634619415">Interrumpir</translation>
 <translation id="4957722034734105353">Más información...</translation>
 <translation id="2964193600955408481">Inhabilitar Wi-Fi</translation>
 <translation id="811680302244032017">Añadir dispositivo...</translation>
 <translation id="2509468283778169019">Bloqueo de mayúsculas activado</translation>
 <translation id="3892641579809465218">Pantalla interna</translation>
 <translation id="7823564328645135659">El idioma ha cambiado de &quot;<ph name="FROM_LOCALE"/>&quot; a &quot;<ph name="TO_LOCALE"/>&quot; después de sincronizar tu configuración.</translation>
+<translation id="3368922792935385530">Con conexión</translation>
 <translation id="8340999562596018839">Mensajes de voz</translation>
 <translation id="8654520615680304441">Activar Wi-Fi...</translation>
 <translation id="5825747213122829519">Tu método de entrada ha cambiado a <ph name="INPUT_METHOD_ID"/>.
 Para cambiarlo, pulsa Mayús + Alt.</translation>
 <translation id="2562916301614567480">Red privada</translation>
 <translation id="6549021752953852991">No hay ninguna red móvil disponible.</translation>
+<translation id="4379753398862151997">Querido monitor, lo nuestro no funciona... (No se admite el uso de ese monitor).</translation>
 <translation id="6426039856985689743">Inhabilitar datos móviles</translation>
 <translation id="3087734570205094154">Inferior</translation>
 <translation id="5271016907025319479">VPN no configurada</translation>
-<translation id="1298695107722797780">Finalizar sesión\npública</translation>
-<translation id="3232695630852378748">Configuración de Bluetooth...</translation>
+<translation id="6803622936009808957">No se han podido duplicar las pantallas porque no se han encontrado resoluciones compatibles. Se ha utilizado el modo de escritorio ampliado en su lugar.</translation>
 <translation id="1480041086352807611">Modo demo</translation>
 <translation id="3626637461649818317"><ph name="PERCENTAGE"/>% restante</translation>
 <translation id="9089416786594320554">Métodos de entrada</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">Cierre del navegador</translation>
 <translation id="4430019312045809116">Volumen</translation>
+<translation id="4442424173763614572">Error al buscar DNS</translation>
 <translation id="6356500677799115505">Batería completa y cargándose</translation>
 <translation id="7874779702599364982">Buscando redes móviles...</translation>
+<translation id="583281660410589416">Desconocido</translation>
 <translation id="1383876407941801731">Búsqueda</translation>
+<translation id="7468789844759750875">Visita el portal de activación de <ph name="NAME"/> para comprar más datos.</translation>
 <translation id="3901991538546252627">Conectando con: <ph name="NAME"/></translation>
 <translation id="2204305834655267233">Información de red</translation>
 <translation id="1621499497873603021">Tiempo restante hasta que se agote la batería: <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">Menú anterior</translation>
 <translation id="1346748346194534595">Derecha</translation>
 <translation id="8528322925433439945">Redes móviles...</translation>
+<translation id="7049357003967926684">Asociación</translation>
 <translation id="8428213095426709021">Configuración</translation>
-<translation id="2472320577759310817">Bluetooth desactivado</translation>
 <translation id="2372145515558759244">Sincronizando aplicaciones...</translation>
+<translation id="7256405249507348194">Error no reconocido: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">Error de comprobación de AAA</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: desconectando...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/> horas y <ph name="MINUTE"/> minutos para que se complete</translation>
 <translation id="5787281376604286451">Los mensajes de voz están habilitados.
 Para inhabilitar esta opción, pulsa Ctrl+Alt+Z.</translation>
 <translation id="4479639480957787382">Ethernet</translation>
+<translation id="6312403991423642364">Error desconocido de red</translation>
 <translation id="1467432559032391204">Izquierda</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830">Activación de <ph name="NAME"/></translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">Maximizar</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: conectando...</translation>
+<translation id="8639033665604704195">Se ha producido un error al autenticar la clave precompartida facilitada.</translation>
 <translation id="252373100621549798">Pantalla desconocida</translation>
 <translation id="1882897271359938046">Copiando en <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Bloquear</translation>
 <translation id="2805756323405976993">Aplicaciones</translation>
-<translation id="2482878487686419369">Notificaciones</translation>
+<translation id="1512064327686280138">Error de activación</translation>
+<translation id="5097002363526479830">Error al establecer conexión con la red &quot;<ph name="NAME"/>&quot;: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">La conexión Wi-Fi está desactivada.</translation>
-<translation id="2872961005593481000">Apagar</translation>
+<translation id="8036518327127111261">Error de autenticación con el certificado proporcionado</translation>
 <translation id="8132793192354020517">Conectado a <ph name="NAME"/></translation>
 <translation id="7052914147756339792">Establecer fondo de pantalla...</translation>
-<translation id="2739500853984626550">No hay dispositivos Bluetooth disponibles.</translation>
-<translation id="2666092431469916601">Superior</translation>
+<translation id="8678698760965522072">Estado online</translation>
+<translation id="1119447706177454957">Error interno</translation>
 <translation id="3019353588588144572">Tiempo restante hasta que se cargue la batería por completo: <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">Lupa</translation>
+<translation id="7005812687360380971">Error</translation>
 <translation id="1602076796624386989">Habilitar datos móviles</translation>
 <translation id="6981982820502123353">Accesibilidad</translation>
 <translation id="3157931365184549694">Restaurar</translation>
+<translation id="4274292172790327596">Error desconocido</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Buscando dispositivos...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Buscando redes Wi-Fi...</translation>
+<translation id="7229570126336867161">Es necesario el estándar EVDO.</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> es una sesión pública administrada por <ph name="DOMAIN"/>.</translation>
 <translation id="7029814467594812963">Cerrar sesión</translation>
 <translation id="8454013096329229812">La conexión Wi-Fi está activada.</translation>
 <translation id="4872237917498892622">Alt+tecla de búsqueda o Mayús</translation>
 <translation id="2983818520079887040">Configuración...</translation>
-<translation id="5467313780247887226">No se puede duplicar la imagen en los monitores adjuntos. No se ha encontrado ninguna resolución que coincida.</translation>
+<translation id="8927026611342028580">Conexión solicitada</translation>
+<translation id="8300849813060516376">Error de OTASP</translation>
 <translation id="2792498699870441125">Alt+tecla de búsqueda</translation>
 <translation id="8660803626959853127">Sincronizando <ph name="COUNT"/> archivo(s)</translation>
 <translation id="639644700271529076">Bloqueo de mayúsculas desactivado</translation>
-<translation id="4101192585425716296">Centro de mensajes</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: Activando...</translation>
+<translation id="1391854757121130358">Es posible que hayas agotado los datos de tu plan de datos móviles.</translation>
 <translation id="4864165860509564259">Posición de la barra de aplicaciones</translation>
 <translation id="7593891976182323525">Tecla de búsqueda o Mayús</translation>
 <translation id="7649070708921625228">Ayuda</translation>
 <translation id="3050422059534974565">El BLOQUEO DE MAYÚSCULAS está activado.
 Pulsa Mayús o la tecla de búsqueda para cancelar la operación.</translation>
 <translation id="397105322502079400">Calculando...</translation>
+<translation id="158849752021629804">Es necesaria una red doméstica.</translation>
+<translation id="6857811139397017780">Activar <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">Error de búsqueda de DHCP</translation>
+<translation id="6692173217867674490">Frase de contraseña incorrecta</translation>
 <translation id="6165508094623778733">Más información</translation>
+<translation id="9046895021617826162">Error de conexión</translation>
+<translation id="973896785707726617">Esta sesión finalizará en <ph name="SESSION_TIME_REMAINING"/>. La sesión se cerrará automáticamente.</translation>
+<translation id="8372369524088641025">Clave WEP incorrecta</translation>
+<translation id="6636709850131805001">Estado desconocido</translation>
 <translation id="3573179567135747900">Cambiar de nuevo por &quot;<ph name="FROM_LOCALE"/>&quot; (requiere reiniciar)</translation>
 <translation id="8103386449138765447">Mensajes SMS: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Configuración de Google Drive...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">Ninguna red</translation>
 <translation id="5941711191222866238">Minimizar</translation>
 <translation id="6911468394164995108">Conectarse a otra red...</translation>
-<translation id="6843725295806269523">silenciar</translation>
 <translation id="412065659894267608"><ph name="HOUR"/> h y <ph name="MINUTE"/> min para completar la carga</translation>
 <translation id="6359806961507272919">SMS de <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Operador</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_et.xtb b/ash/strings/ash_strings_et.xtb
index ed476cb..b0ae670 100644
--- a/ash/strings/ash_strings_et.xtb
+++ b/ash/strings/ash_strings_et.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Aku on täis</translation>
 <translation id="5250713215130379958">Peida käiviti automaatselt</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> ja <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Portaali olek</translation>
 <translation id="30155388420722288">Ülevoolunupp</translation>
 <translation id="5571066253365925590">Bluetooth on lubatud</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Puhverserver ...</translation>
 <translation id="938582441709398163">Klaviatuuri ülekate</translation>
 <translation id="6979158407327259162">Google Drive</translation>
+<translation id="6943836128787782965">HTTP hankimine nurjus</translation>
 <translation id="2297568595583585744">Olekusalv</translation>
+<translation id="1661867754829461514">PIN-kood puudub</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: ühendamine ...</translation>
+<translation id="4237016987259239829">Võrguühenduse viga</translation>
 <translation id="2946640296642327832">Luba Bluetooth</translation>
 <translation id="6459472438155181876">Ekraani laiendamine seadmesse <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Mobiil</translation>
 <translation id="6596816719288285829">IP-aadress</translation>
+<translation id="4508265954913339219">Aktiveerimine nurjus</translation>
 <translation id="1812696562331527143">Teie sisestusmeetod on nüüd <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>kolmas osapool<ph name="END_LINK"/>).
 Selle muutmiseks vajutage klahve Tõstuklahv + Alt.</translation>
-<translation id="5233638681132016545">Uus vaheleht</translation>
 <translation id="3846575436967432996">Võrguteave ei ole saadaval</translation>
 <translation id="3026237328237090306">Seadista mobiilne andmeside</translation>
 <translation id="785750925697875037">Kuva mobiilikonto</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Keela Bluetooth</translation>
 <translation id="3126069444801937830">Taaskäivitage värskendamiseks</translation>
 <translation id="735745346212279324">VPN-i ühendus on katkestatud</translation>
+<translation id="7320906967354320621">Tegevusetu</translation>
 <translation id="6303423059719347535">Aku on <ph name="PERCENTAGE"/>% täis</translation>
+<translation id="2778346081696727092">Autentimine esitatud kasutajanime või parooliga ebaõnnestus</translation>
 <translation id="3294437725009624529">Külaline</translation>
 <translation id="8190698733819146287">Keelte ja sisendi kohandamine...</translation>
-<translation id="598295083618286569">Bluetooth on ühendatud</translation>
+<translation id="7170041865419449892">Vahemikust väljas</translation>
+<translation id="4804818685124855865">Katkesta ühendus</translation>
 <translation id="5222676887888702881">Logi välja</translation>
+<translation id="2688477613306174402">Konfigureerimine</translation>
+<translation id="1272079795634619415">Peata</translation>
 <translation id="4957722034734105353">Lisateave ...</translation>
 <translation id="2964193600955408481">Keela WiFi</translation>
 <translation id="811680302244032017">Lisa seade ...</translation>
 <translation id="2509468283778169019">SUURTÄHELUKK on sisse lülitatud</translation>
 <translation id="3892641579809465218">Sisemine kuva</translation>
 <translation id="7823564328645135659">Pärast seadete sünkroonimist asendati <ph name="FROM_LOCALE"/> keel <ph name="TO_LOCALE"/> keelega.</translation>
+<translation id="3368922792935385530">Ühendatud</translation>
 <translation id="8340999562596018839">Suuline tagasiside</translation>
 <translation id="8654520615680304441">Lülita WiFi sisse ...</translation>
 <translation id="5825747213122829519">Teie sisestusmeetod on nüüd <ph name="INPUT_METHOD_ID"/>.
 Selle muutmiseks vajutage klahve Tõstuklahv + Alt.</translation>
 <translation id="2562916301614567480">Privaatvõrk</translation>
 <translation id="6549021752953852991">Mobiilivõrk pole saadaval</translation>
+<translation id="4379753398862151997">Monitor, kahjuks ei tule meie koostööst midagi välja. (Seda monitori ei toetata)</translation>
 <translation id="6426039856985689743">Keela mobiilne andmeside</translation>
 <translation id="3087734570205094154">Alaserv</translation>
 <translation id="5271016907025319479">VPN on seadistamata.</translation>
-<translation id="1298695107722797780">Lõpeta avalik\nseanss</translation>
-<translation id="3232695630852378748">Bluetoothi seaded</translation>
+<translation id="6803622936009808957">Ei saanud kuvasid peegeldada, kuna toetatud eraldusvõimeid ei leitud. Selle asemel siseneti laiendatud töölaua režiimi.</translation>
 <translation id="1480041086352807611">Demorežiim</translation>
 <translation id="3626637461649818317"><ph name="PERCENTAGE"/>% on jäänud</translation>
 <translation id="9089416786594320554">Sisestusviisid</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">Sulgemine</translation>
 <translation id="4430019312045809116">Helitugevus</translation>
+<translation id="4442424173763614572">DNS-i otsing nurjus</translation>
 <translation id="6356500677799115505">Aku on täis ja seda laetakse.</translation>
 <translation id="7874779702599364982">Mobiilsidevõrkude otsimine ...</translation>
+<translation id="583281660410589416">Tundmatu</translation>
 <translation id="1383876407941801731">Otsing</translation>
+<translation id="7468789844759750875">Külastage võrgu <ph name="NAME"/> aktiveerimisportaali, et rohkem andmemahtu osta.</translation>
 <translation id="3901991538546252627">Võrguga <ph name="NAME"/> ühenduse loomine</translation>
 <translation id="2204305834655267233">Võrguteave</translation>
 <translation id="1621499497873603021">Aku tühjenemiseni on aega <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">Eelmine menüü</translation>
 <translation id="1346748346194534595">Paremale</translation>
 <translation id="8528322925433439945">Mobiil ...</translation>
+<translation id="7049357003967926684">Sidumine</translation>
 <translation id="8428213095426709021">Seaded</translation>
-<translation id="2472320577759310817">Bluetooth on välja lülitatud.</translation>
 <translation id="2372145515558759244">Rakenduste sünkroonimine ...</translation>
+<translation id="7256405249507348194">Tundmatu viga: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">AAA kontrollimine nurjus</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: ühenduse katkestamine ...</translation>
 <translation id="8456362689280298700">Täielikuks laadimiseks kulub <ph name="HOUR"/>:<ph name="MINUTE"/></translation>
 <translation id="5787281376604286451">Suuline tagasiside on lubatud.
 Keelamiseks vajutage klahvikombinatsiooni Ctrl+Alt+Z.</translation>
 <translation id="4479639480957787382">Ethernet</translation>
+<translation id="6312403991423642364">Tundmatu võrguviga</translation>
 <translation id="1467432559032391204">Vasakule</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830">Võrgu <ph name="NAME"/> aktiveerimine</translation>
 <translation id="8814190375133053267">WiFi</translation>
 <translation id="1398853756734560583">Maksimeeri</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: ühendamine ...</translation>
+<translation id="8639033665604704195">Autentimine esitatud eeljagatud võtmega ebaõnnestus</translation>
 <translation id="252373100621549798">Tundmatu ekraan</translation>
 <translation id="1882897271359938046">Peegeldamine asukohta <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Lukusta</translation>
 <translation id="2805756323405976993">Rakendused</translation>
-<translation id="2482878487686419369">Teatised</translation>
+<translation id="1512064327686280138">Aktiveerimise tõrge</translation>
+<translation id="5097002363526479830">Võrguga „<ph name="NAME"/>” ühenduse loomine ebaõnnestus: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">WiFi on välja lülitatud.</translation>
-<translation id="2872961005593481000">Lülita välja</translation>
+<translation id="8036518327127111261">Autentimine esitatud sertifikaadiga ebaõnnestus</translation>
 <translation id="8132793192354020517">Ühendus <ph name="NAME"/>iga</translation>
 <translation id="7052914147756339792">Määra taustapilt ...</translation>
-<translation id="2739500853984626550">Ühtki Bluetoothi seadet pole saadaval</translation>
-<translation id="2666092431469916601">Üles</translation>
+<translation id="8678698760965522072">Võrguühenduse olek</translation>
+<translation id="1119447706177454957">Sisemine viga</translation>
 <translation id="3019353588588144572">Aku täitumiseni on aega <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">Ekraanisuurendi</translation>
+<translation id="7005812687360380971">Tõrge</translation>
 <translation id="1602076796624386989">Luba mobiilne andmeside</translation>
 <translation id="6981982820502123353">Juurdepääsetavus</translation>
 <translation id="3157931365184549694">Taasta</translation>
+<translation id="4274292172790327596">Tundmatu viga</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Seadmete skannimine ...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">WiFi võrkude otsimine ...</translation>
+<translation id="7229570126336867161">Vajalik EVDO</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> on avalik seanss, mida haldab <ph name="DOMAIN"/></translation>
 <translation id="7029814467594812963">Välju seansist</translation>
 <translation id="8454013096329229812">WiFi on sisse lülitatud.</translation>
 <translation id="4872237917498892622">Alt + otsinguklahv või tõstuklahv</translation>
 <translation id="2983818520079887040">Seaded...</translation>
-<translation id="5467313780247887226">Ei saa ühendatud monitoridel kujutist duplitseerida. Ühtivat eraldusvõimet ei leitud.</translation>
+<translation id="8927026611342028580">Ühenduse taotlus</translation>
+<translation id="8300849813060516376">OTASP nurjus</translation>
 <translation id="2792498699870441125">Alt + otsinguklahv</translation>
 <translation id="8660803626959853127"><ph name="COUNT"/> faili sünkroonimine</translation>
 <translation id="639644700271529076">SUURTÄHELUKK on välja lülitatud</translation>
-<translation id="4101192585425716296">Sõnumikeskus</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: aktiveerimine ...</translation>
+<translation id="1391854757121130358">Tundub, et olete oma mobiilse andmesidemahu ära kasutanud.</translation>
 <translation id="4864165860509564259">Käiviti positsioon</translation>
 <translation id="7593891976182323525">Otsinguklahv või tõstuklahv</translation>
 <translation id="7649070708921625228">Abi</translation>
 <translation id="3050422059534974565">SUURTÄHELUKK on sisse lülitatud.
 Tühistamiseks vajutage otsinguklahvi või tõstuklahvi</translation>
 <translation id="397105322502079400">Arvutamine ...</translation>
+<translation id="158849752021629804">Vajalik koduvõrk</translation>
+<translation id="6857811139397017780">Aktiveeri <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">DHCP otsing nurjus</translation>
+<translation id="6692173217867674490">Halb parool</translation>
 <translation id="6165508094623778733">Lisateave</translation>
+<translation id="9046895021617826162">Ühendamine nurjus</translation>
+<translation id="973896785707726617">Selle seansi lõpuni on jäänud <ph name="SESSION_TIME_REMAINING"/>. Teid logitakse automaatselt välja.</translation>
+<translation id="8372369524088641025">Halb WEP-võti</translation>
+<translation id="6636709850131805001">Tundmatu olek</translation>
 <translation id="3573179567135747900">Muuda tagasi seadele <ph name="FROM_LOCALE"/> (nõuab taaskäivitust)</translation>
 <translation id="8103386449138765447">SMS-id: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Google Drive'i seaded ...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">Võrku pole</translation>
 <translation id="5941711191222866238">Minimeeri</translation>
 <translation id="6911468394164995108">Liitu muu võrguga ...</translation>
-<translation id="6843725295806269523">vaigista</translation>
 <translation id="412065659894267608"><ph name="HOUR"/> h <ph name="MINUTE"/> min aku täitumiseni</translation>
 <translation id="6359806961507272919">SMS numbrilt <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Mobiilioperaator</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_fa.xtb b/ash/strings/ash_strings_fa.xtb
index e9ccbba..02a2e2f 100644
--- a/ash/strings/ash_strings_fa.xtb
+++ b/ash/strings/ash_strings_fa.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">باتری پر است</translation>
 <translation id="5250713215130379958">مخفی کردن خودکار راه انداز</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> و <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">وضعیت سایت</translation>
 <translation id="30155388420722288">دکمه سرریز</translation>
 <translation id="5571066253365925590">بلوتوث فعال شد</translation>
 <translation id="9074739597929991885">بلوتوث</translation>
@@ -15,14 +16,17 @@
 <translation id="5565793151875479467">پراکسی...</translation>
 <translation id="938582441709398163">هم پوشانی صفحه‌کلید</translation>
 <translation id="6979158407327259162">Google Drive</translation>
+<translation id="6943836128787782965">HTTP با خطا مواجه شد</translation>
 <translation id="2297568595583585744">سینی وضعیت</translation>
+<translation id="1661867754829461514">پین جا افتاده</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: در حال اتصال...</translation>
+<translation id="4237016987259239829">خطای اتصال شبکه</translation>
 <translation id="2946640296642327832">فعال کردن بلوتوث</translation>
 <translation id="6459472438155181876">گسترش صفحه به <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">سلولی</translation>
 <translation id="6596816719288285829">آدرس IP</translation>
+<translation id="4508265954913339219">فعالسازی انجام نشد</translation>
 <translation id="1812696562331527143">روش ورودی شما به <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>شخص ثالث<ph name="END_LINK"/>) تغییر یافت. Shift + Alt را برای تعویض فشار دهید.</translation>
-<translation id="5233638681132016545">برگهٔ جدید</translation>
 <translation id="3846575436967432996">اطلاعات شبکه در دسترس نیست</translation>
 <translation id="3026237328237090306">تنظیم اطلاعات تلفن همراه</translation>
 <translation id="785750925697875037">مشاهده حساب تلفن همراه</translation>
@@ -30,36 +34,45 @@
 <translation id="7864539943188674973">غیرفعال کردن بلوتوث</translation>
 <translation id="3126069444801937830">راه‌اندازی مجدد برای به‌روزرسانی</translation>
 <translation id="735745346212279324">VPN قطع شد</translation>
+<translation id="7320906967354320621">بدون فعالیت</translation>
 <translation id="6303423059719347535">باتری <ph name="PERCENTAGE"/> درصد پر است</translation>
+<translation id="2778346081696727092">تأیید اعتبار با نام کاربری و گذرواژه ارائه شده انجام نشد</translation>
 <translation id="3294437725009624529">مهمان</translation>
 <translation id="8190698733819146287">سفارشی کردن زبان‌ها و ورودی...</translation>
-<translation id="598295083618286569">بلوتوث متصل شد</translation>
+<translation id="7170041865419449892">خارج از محدوده</translation>
+<translation id="4804818685124855865">قطع اتصال</translation>
 <translation id="5222676887888702881">خروج از سیستم</translation>
+<translation id="2688477613306174402">پیکربندی</translation>
+<translation id="1272079795634619415">توقف</translation>
 <translation id="4957722034734105353">اطلاعات بیشتر...</translation>
 <translation id="2964193600955408481">غیرفعال کردن Wi-Fi</translation>
 <translation id="811680302244032017">افزودن دستگاه…</translation>
 <translation id="2509468283778169019">CAPS LOCK روشن است</translation>
 <translation id="3892641579809465218">صفحه نمایش داخلی</translation>
 <translation id="7823564328645135659">بعد از همگام‌سازی تنظیمات شما، زبان از «<ph name="FROM_LOCALE"/>» به «<ph name="TO_LOCALE"/>» تغییر کرد.</translation>
+<translation id="3368922792935385530">متصل</translation>
 <translation id="8340999562596018839">بازخورد گفتاری</translation>
 <translation id="8654520615680304441">روشن کردن Wi-Fi در...</translation>
 <translation id="5825747213122829519">روش ورودی شما به <ph name="INPUT_METHOD_ID"/> تغییر یافت. Shift + Alt را برای تعویض فشار دهید.</translation>
 <translation id="2562916301614567480">شبکه خصوصی</translation>
 <translation id="6549021752953852991">هیچ شبکه سلولی دردسترس نیست</translation>
+<translation id="4379753398862151997">نمایشگر عزیز، ما برای هم ساخته نشده‌ایم. (این نمایشگر پشتیبانی نمی‌شود)</translation>
 <translation id="6426039856985689743">غیرفعال کردن اطلاعات تلفن همراه</translation>
 <translation id="3087734570205094154">پایین</translation>
 <translation id="5271016907025319479">VPN پیکربندی نشده است.</translation>
-<translation id="1298695107722797780">پایان جلسه\nعمومی</translation>
-<translation id="3232695630852378748">تنظیمات بلوتوث…</translation>
+<translation id="6803622936009808957">نمایش یک تصویر واحد در چند صفحه نمایش ممکن نیست زیرا وضوح تصویر پشتیبانی شده‌ای وجود ندارد. بجای آن حالت نمایش دسک‌تاپ چند بخشی استفاده می‌شود.</translation>
 <translation id="1480041086352807611">حالت نمایش</translation>
 <translation id="3626637461649818317"><ph name="PERCENTAGE"/>٪ باقیمانده</translation>
 <translation id="9089416786594320554">روش‌های ورودی</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">بسته شدن</translation>
 <translation id="4430019312045809116">میزان صدا</translation>
+<translation id="4442424173763614572">جستجوی DNS انجام نشد</translation>
 <translation id="6356500677799115505">باتری پر است و شارژ می‌شود.</translation>
 <translation id="7874779702599364982">جستجو برای شبکه‌های تلفن همراه ...</translation>
+<translation id="583281660410589416">ناشناخته</translation>
 <translation id="1383876407941801731">جستجو</translation>
+<translation id="7468789844759750875">از پورتال فعال‌سازی <ph name="NAME"/> برای خرید داده‌های بیشتر بازدید کنید.</translation>
 <translation id="3901991538546252627">در حال اتصال به <ph name="NAME"/></translation>
 <translation id="2204305834655267233">اطلاعات شبکه</translation>
 <translation id="1621499497873603021">زمان باقیمانده تا خالی‌شدن شارژ باتری، <ph name="TIME_LEFT"/></translation>
@@ -68,56 +81,75 @@
 <translation id="8308637677604853869">منوی قبلی</translation>
 <translation id="1346748346194534595">راست</translation>
 <translation id="8528322925433439945">تلفن همراه...</translation>
+<translation id="7049357003967926684">همراه کردن</translation>
 <translation id="8428213095426709021">تنظیمات</translation>
-<translation id="2472320577759310817">بلوتوث خاموش است.</translation>
 <translation id="2372145515558759244">در حال همگام‌سازی برنامه‌ها…</translation>
+<translation id="7256405249507348194">خطای نامشخص: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">بررسی AAA انجام نشد</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: در حال قطع اتصال ...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> تا شارژ شود</translation>
 <translation id="5787281376604286451">بازخورد گفتاری فعال است.
 Ctrl+Alt+Z را فشار دید تا غیرفعال شود.</translation>
 <translation id="4479639480957787382">اترنت</translation>
+<translation id="6312403991423642364">خطای شبکه ناشناخته</translation>
 <translation id="1467432559032391204">چپ</translation>
 <translation id="5543001071567407895">پیامک</translation>
+<translation id="2354174487190027830">فعال‌سازی <ph name="NAME"/></translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">بزرگ کردن</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: در حال اتصال...</translation>
+<translation id="8639033665604704195">تأیید اعتبار با کلید از قبل به اشتراک گذاشته شده انجام نشد</translation>
 <translation id="252373100621549798">نمایش ناشناخته</translation>
 <translation id="1882897271359938046">بازتاب به <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">قفل</translation>
 <translation id="2805756323405976993">برنامه‌ها</translation>
-<translation id="2482878487686419369">اعلام ها</translation>
+<translation id="1512064327686280138">نقص در فعالسازی</translation>
+<translation id="5097002363526479830">اتصال ناموفق به شبکه &quot;<ph name="NAME"/>&quot;:<ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi خاموش است.</translation>
-<translation id="2872961005593481000">خاموش کردن</translation>
+<translation id="8036518327127111261">تأیید اعتبار با گواهی ارائه شده انجام نشد</translation>
 <translation id="8132793192354020517">متصل به <ph name="NAME"/></translation>
 <translation id="7052914147756339792">تنظیم کاغذدیواری...</translation>
-<translation id="2739500853984626550">هیچ دستگاه بلوتوثی در دسترس نیست</translation>
-<translation id="2666092431469916601">بالا</translation>
+<translation id="8678698760965522072">حالت آنلاین</translation>
+<translation id="1119447706177454957">خطای داخلی</translation>
 <translation id="3019353588588144572">زمان باقی مانده تا شارژ کامل باتری، <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">ذره‌بین صفحه</translation>
+<translation id="7005812687360380971">نقص</translation>
 <translation id="1602076796624386989">فعال کردن اطلاعات تلفن همراه</translation>
 <translation id="6981982820502123353">قابلیت دسترسی</translation>
 <translation id="3157931365184549694">بازیابی</translation>
+<translation id="4274292172790327596">خطای ناشناس</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">درحال جستجو برای دستگاه‌ها...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>، <ph name="DATE"/></translation>
 <translation id="4448844063988177157">در حال جستجوی شبکه‌های Wi-Fi...</translation>
+<translation id="7229570126336867161">EVDO مورد نیاز است</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> یک جلسه عمومی مدیریت‌شده توسط <ph name="DOMAIN"/> است</translation>
 <translation id="7029814467594812963">خروج از جلسه</translation>
 <translation id="8454013096329229812">Wi-Fi روشن است.</translation>
 <translation id="4872237917498892622">Alt+جستجو یا Shift</translation>
 <translation id="2983818520079887040">تنظیمات...</translation>
-<translation id="5467313780247887226">نمی‌توان تصویر را در مونیتورهای پیوست شده تکرار کرد. وضوح منطبقی یافت نشد.</translation>
+<translation id="8927026611342028580">درخواست اتصال</translation>
+<translation id="8300849813060516376">OTASP انجام نشد</translation>
 <translation id="2792498699870441125">Alt+جستجو</translation>
 <translation id="8660803626959853127">در حال همگام‌سازی فایل(های) <ph name="COUNT"/></translation>
 <translation id="639644700271529076">CAPS LOCK خاموش است</translation>
-<translation id="4101192585425716296">مرکز پیام</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: در حال فعال‌سازی…</translation>
+<translation id="1391854757121130358">ممکن است حجم مجاز داده تلفن همراه خود را مصرف کرده باشید.</translation>
 <translation id="4864165860509564259">موقعیت راه‌انداز</translation>
 <translation id="7593891976182323525">جستجو یا Shift</translation>
 <translation id="7649070708921625228">راهنما</translation>
 <translation id="3050422059534974565">CAPS LOCK روشن است.
 جستجو یا Shift را برای لغو فشار دهید.</translation>
 <translation id="397105322502079400">در حال محاسبه…</translation>
+<translation id="158849752021629804">شبکه خانگی مورد نیاز است</translation>
+<translation id="6857811139397017780">فعال سازی <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">بررسی DHCP انجام نشد</translation>
+<translation id="6692173217867674490">کلمه عبور نادرست</translation>
 <translation id="6165508094623778733">بیشتر بیاموزید</translation>
+<translation id="9046895021617826162">اتصال برقرار نشد</translation>
+<translation id="973896785707726617">این جلسه در <ph name="SESSION_TIME_REMAINING"/> به اتمام خواهد رسید. به طور خودکار از سیستم خارج خواهید شد.</translation>
+<translation id="8372369524088641025">کلید WEP نادرست</translation>
+<translation id="6636709850131805001">حالت ناشناس</translation>
 <translation id="3573179567135747900">به &quot;<ph name="FROM_LOCALE"/>&quot; تغییر دهید (به راه‌اندازی دوباره نیاز دارد)</translation>
 <translation id="8103386449138765447">پیامک‌ها: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">تنظیمات Google Drive...</translation>
@@ -128,7 +160,7 @@
 <translation id="8000066093800657092">بدون شبکه</translation>
 <translation id="5941711191222866238">کوچک کردن</translation>
 <translation id="6911468394164995108">پیوستن به شبکه دیگر…</translation>
-<translation id="6843725295806269523">بیصداکردن</translation>
 <translation id="412065659894267608"><ph name="HOUR"/>ساعت <ph name="MINUTE"/>دقیقه مانده تا باتری شارژ شود</translation>
 <translation id="6359806961507272919">پیامک از <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">شرکت مخابراتی</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_fi.xtb b/ash/strings/ash_strings_fi.xtb
index 5fb175e..aa0ba87 100644
--- a/ash/strings/ash_strings_fi.xtb
+++ b/ash/strings/ash_strings_fi.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Akku täynnä</translation>
 <translation id="5250713215130379958">Piilota käynnistyspalkki</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Portaalitila</translation>
 <translation id="30155388420722288">Overflow-painike</translation>
 <translation id="5571066253365925590">Bluetooth käytössä</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Välityspalvelin...</translation>
 <translation id="938582441709398163">Näppäimistön peitto</translation>
 <translation id="6979158407327259162">Google Drive</translation>
+<translation id="6943836128787782965">HTTP get -toiminto epäonnistui</translation>
 <translation id="2297568595583585744">Tila-alue</translation>
+<translation id="1661867754829461514">PIN-koodi puuttuu</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: Yhdistetään…</translation>
+<translation id="4237016987259239829">Verkon yhteysvirhe</translation>
 <translation id="2946640296642327832">Ota Bluetooth käyttöön</translation>
 <translation id="6459472438155181876">Ruutua laajennetaan: <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Matkapuhelin</translation>
 <translation id="6596816719288285829">IP-osoite</translation>
+<translation id="4508265954913339219">Aktivointi epäonnistui</translation>
 <translation id="1812696562331527143">Syöttötapa on vaihtunut. Uusi syöttötapa on <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>kolmas osapuoli<ph name="END_LINK"/>).
 Vaihda syöttötapaa painamalla Shift + Alt.</translation>
-<translation id="5233638681132016545">Uusi välilehti</translation>
 <translation id="3846575436967432996">Verkon tietoja ei saatavilla</translation>
 <translation id="3026237328237090306">Määritä mobiilitiedonsiirron asetukset</translation>
 <translation id="785750925697875037">Näytä mobiilitili</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Poista Bluetooth käytöstä</translation>
 <translation id="3126069444801937830">Päivitä käynnistämällä uudelleen</translation>
 <translation id="735745346212279324">VPN-yhteys katkaistu</translation>
+<translation id="7320906967354320621">Ei käytössä</translation>
 <translation id="6303423059719347535">Akussa on virtaa <ph name="PERCENTAGE"/> %</translation>
+<translation id="2778346081696727092">Todennus annetulla käyttäjänimellä ja salasanalla epäonnistui.</translation>
 <translation id="3294437725009624529">Vieras</translation>
 <translation id="8190698733819146287">Muokkaa kieliä ja syötettä...</translation>
-<translation id="598295083618286569">Bluetooth yhdistetty</translation>
+<translation id="7170041865419449892">Katvealueella</translation>
+<translation id="4804818685124855865">Katkaise yhteys</translation>
 <translation id="5222676887888702881">Kirjaudu ulos</translation>
+<translation id="2688477613306174402">Määritykset</translation>
+<translation id="1272079795634619415">Pysäytä</translation>
 <translation id="4957722034734105353">Lisätietoja...</translation>
 <translation id="2964193600955408481">Wifi pois käytöstä</translation>
 <translation id="811680302244032017">Lisää laite...</translation>
 <translation id="2509468283778169019">CAPS LOCK on päällä</translation>
 <translation id="3892641579809465218">Sisäinen näyttö</translation>
 <translation id="7823564328645135659">Käyttökieli on muutettu kielestä <ph name="FROM_LOCALE"/> kieleksi <ph name="TO_LOCALE"/> asetustesi synkronoinnin yhteydessä.</translation>
+<translation id="3368922792935385530">Yhdistetty</translation>
 <translation id="8340999562596018839">Äänipalaute</translation>
 <translation id="8654520615680304441">Ota wifi käyttöön…</translation>
 <translation id="5825747213122829519">Syöttötapa on vaihtunut. Uusi syöttötapa on <ph name="INPUT_METHOD_ID"/>.
 Vaihda syöttötapaa painamalla Shift + Alt.</translation>
 <translation id="2562916301614567480">Yksityinen verkko</translation>
 <translation id="6549021752953852991">Matkapuhelinverkkoja ei ole käytettävissä</translation>
+<translation id="4379753398862151997">Arvoisa näyttö, suhteemme ei toimi. (Näyttöä ei tueta)</translation>
 <translation id="6426039856985689743">Poista mobiilitiedonsiirto käytöstä</translation>
 <translation id="3087734570205094154">Alaosa</translation>
 <translation id="5271016907025319479">VPN-verkon asetuksia ei ole määritetty.</translation>
-<translation id="1298695107722797780">Päätä julkinen\nkäyttökerta</translation>
-<translation id="3232695630852378748">Bluetooth-asetukset...</translation>
+<translation id="6803622936009808957">Näyttöjen peilaaminen ei onnistunut, sillä tuettua resoluutiota ei löytynyt. Sen sijaan valittiin työpöydän laajennus.</translation>
 <translation id="1480041086352807611">Esittelytila</translation>
 <translation id="3626637461649818317"><ph name="PERCENTAGE"/> % jäljellä</translation>
 <translation id="9089416786594320554">Syöttötavat</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/> %</translation>
 <translation id="1895658205118569222">Sulkeminen</translation>
 <translation id="4430019312045809116">Äänenvoimakkuus</translation>
+<translation id="4442424173763614572">DNS-haku epäonnistui</translation>
 <translation id="6356500677799115505">Akku on täynnä ja laite on kytketty laturiin.</translation>
 <translation id="7874779702599364982">Haetaan matkapuhelinverkkoja…</translation>
+<translation id="583281660410589416">Tuntematon</translation>
 <translation id="1383876407941801731">Haku</translation>
+<translation id="7468789844759750875">Osta lisää tiedonsiirtoa palvelussa <ph name="NAME"/>.</translation>
 <translation id="3901991538546252627">Yhdistetään verkkoon <ph name="NAME"/></translation>
 <translation id="2204305834655267233">Verkon tiedot</translation>
 <translation id="1621499497873603021">Akku on tyhjä <ph name="TIME_LEFT"/> kuluttua</translation>
@@ -70,55 +83,74 @@
 <translation id="8308637677604853869">Edellinen valikko</translation>
 <translation id="1346748346194534595">Oikealle</translation>
 <translation id="8528322925433439945">Mobiiliverkot...</translation>
+<translation id="7049357003967926684">Yhdistäminen</translation>
 <translation id="8428213095426709021">Asetukset</translation>
-<translation id="2472320577759310817">Bluetooth ei ole käytössä.</translation>
 <translation id="2372145515558759244">Synkronoidaan sovelluksia...</translation>
+<translation id="7256405249507348194">Tunnistamaton virhe: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">AAA-testi epäonnistui</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: Katkaistaan yhteyttä…</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> kunnes akku on ladattu</translation>
 <translation id="5787281376604286451">Äänipalaute on käytössä.
 Poista se käytöstä painamalla Ctrl+Alt+Z.</translation>
 <translation id="4479639480957787382">Ethernet</translation>
+<translation id="6312403991423642364">Tuntematon verkkovirhe</translation>
 <translation id="1467432559032391204">Vasemmalle</translation>
 <translation id="5543001071567407895">Tekstiviesti</translation>
+<translation id="2354174487190027830">Aktivoidaan <ph name="NAME"/></translation>
 <translation id="8814190375133053267">Wifi</translation>
 <translation id="1398853756734560583">Suurenna</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: Yhdistetään…</translation>
+<translation id="8639033665604704195">Todennus annetulla esijaetulla avaimella epäonnistui.</translation>
 <translation id="252373100621549798">Tuntematon näyttö</translation>
 <translation id="1882897271359938046">Peilataan: <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Lukitse</translation>
 <translation id="2805756323405976993">Sovellukset</translation>
-<translation id="2482878487686419369">Ilmoitukset</translation>
+<translation id="1512064327686280138">Aktivointivirhe</translation>
+<translation id="5097002363526479830">Yhteyden muodostaminen verkkoon &quot;<ph name="NAME"/>&quot; epäonnistui: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wifi ei ole käytössä.</translation>
-<translation id="2872961005593481000">Sammuta</translation>
+<translation id="8036518327127111261">Todennus annetulla varmenteella epäonnistui.</translation>
 <translation id="8132793192354020517">Yhteys muodostettu verkkoon <ph name="NAME"/></translation>
 <translation id="7052914147756339792">Aseta taustakuva...</translation>
-<translation id="2739500853984626550">Bluetooth-laitteita ei ole käytettävissä</translation>
-<translation id="2666092431469916601">Yleisin</translation>
+<translation id="8678698760965522072">Online-tila</translation>
+<translation id="1119447706177454957">Sisäinen virhe</translation>
 <translation id="3019353588588144572">Akku on ladattu <ph name="TIME_REMAINING"/> kuluttua</translation>
 <translation id="3473479545200714844">Ruudun suurentaminen</translation>
+<translation id="7005812687360380971">Virhe</translation>
 <translation id="1602076796624386989">Ota mobiilitiedonsiirto käyttöön</translation>
 <translation id="6981982820502123353">Esteettömyys</translation>
 <translation id="3157931365184549694">Palauta</translation>
+<translation id="4274292172790327596">Tunnistamaton virhe</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>.<ph name="MINUTES"/>.<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Etsitään laitteita...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Haetaan wifi-verkkoja...</translation>
+<translation id="7229570126336867161">EVDO tarvitaan</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> on julkinen käyttökerta, jota hallinnoi <ph name="DOMAIN"/></translation>
 <translation id="7029814467594812963">Sulje käyttökerta</translation>
 <translation id="8454013096329229812">Wifi on käytössä.</translation>
 <translation id="4872237917498892622">Alt + haku tai Shift</translation>
 <translation id="2983818520079887040">Asetukset...</translation>
-<translation id="5467313780247887226">Kuvaa ei voi kopioida yhdistetyille näytöille. Sopivaa resoluutiota ei löytynyt.</translation>
+<translation id="8927026611342028580">Yhdistä pyydetyt</translation>
+<translation id="8300849813060516376">OTASP epäonnistui</translation>
 <translation id="2792498699870441125">Alt + haku</translation>
 <translation id="8660803626959853127">Synkronoidaan <ph name="COUNT"/> tiedosto(a)</translation>
 <translation id="639644700271529076">CAPS LOCK on pois päältä</translation>
-<translation id="4101192585425716296">Viestikeskus</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: aktivoidaan…</translation>
+<translation id="1391854757121130358">Olet ehkä käyttänyt mobiilitiedonsiirron kiintiösi.</translation>
 <translation id="4864165860509564259">Käynnistyspalkin sijainti</translation>
 <translation id="7593891976182323525">Haku tai Shift</translation>
 <translation id="7649070708921625228">Ohje</translation>
 <translation id="3050422059534974565">CAPS LOCK on päällä. Peruuta painamalla haku- tai Shift-näppäintä.</translation>
 <translation id="397105322502079400">Lasketaan...</translation>
+<translation id="158849752021629804">Kotiverkko tarvitaan</translation>
+<translation id="6857811139397017780">Aktivoi <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">DHCP-haku epäonnistui</translation>
+<translation id="6692173217867674490">Väärä tunnuslause</translation>
 <translation id="6165508094623778733">Lisätietoja</translation>
+<translation id="9046895021617826162">Yhdistäminen epäonnistui</translation>
+<translation id="973896785707726617">Istunnon loppumiseen on <ph name="SESSION_TIME_REMAINING"/>. Sinut kirjataan automaattisesti ulos.</translation>
+<translation id="8372369524088641025">Väärä WEP-avain</translation>
+<translation id="6636709850131805001">Tunnistamaton tila</translation>
 <translation id="3573179567135747900">Vaihda takaisin kieleksi <ph name="FROM_LOCALE"/> (vaatii uudelleenkäynnistyksen)</translation>
 <translation id="8103386449138765447">Tekstiviestit: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Google Driven asetukset...</translation>
@@ -128,7 +160,7 @@
 <translation id="8000066093800657092">Ei verkkoa</translation>
 <translation id="5941711191222866238">Pienennä</translation>
 <translation id="6911468394164995108">Liity muuhun verkkoon...</translation>
-<translation id="6843725295806269523">äänetön</translation>
 <translation id="412065659894267608">Akku täynnä <ph name="HOUR"/> t <ph name="MINUTE"/> min kuluttua</translation>
 <translation id="6359806961507272919">Tekstiviesti lähettäjältä <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Operaattori</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_fil.xtb b/ash/strings/ash_strings_fil.xtb
index 9e8add1..9ce9743 100644
--- a/ash/strings/ash_strings_fil.xtb
+++ b/ash/strings/ash_strings_fil.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Puno na ang baterya</translation>
 <translation id="5250713215130379958">Awtomatikong itago ang launcher</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> at <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Katayuan ng portal</translation>
 <translation id="30155388420722288">Button na Overflow</translation>
 <translation id="5571066253365925590">Pinapagana ang Bluetooth</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Proxy...</translation>
 <translation id="938582441709398163">Overlay ng Keyboard</translation>
 <translation id="6979158407327259162">Google Drive</translation>
+<translation id="6943836128787782965">Nabigo ang pagkuha ng HTTP</translation>
 <translation id="2297568595583585744">Tray ng katayuan</translation>
+<translation id="1661867754829461514">Nawawala ang PIN</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: Kumokonekta...</translation>
+<translation id="4237016987259239829">Error sa Koneksyon ng Network</translation>
 <translation id="2946640296642327832">Paganahin ang Bluetooth</translation>
 <translation id="6459472438155181876">Pinapalawak ang screen sa <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Cellular</translation>
 <translation id="6596816719288285829">IP Address</translation>
+<translation id="4508265954913339219">Nabigo ang pag-activate</translation>
 <translation id="1812696562331527143">Naging <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>3rd party<ph name="END_LINK"/>) ang iyong pamamaraan ng pag-input.
 Pindutin ang Shift + Alt upang magpalit.</translation>
-<translation id="5233638681132016545">Bagong tab</translation>
 <translation id="3846575436967432996">Walang available na impormasyon sa network</translation>
 <translation id="3026237328237090306">I-setup ang mobile data</translation>
 <translation id="785750925697875037">Tingnan ang account sa mobile</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Huwag Paganahin ang Bluetooth</translation>
 <translation id="3126069444801937830">I-restart upang mag-update</translation>
 <translation id="735745346212279324">Nakadiskonekta ang VPN</translation>
+<translation id="7320906967354320621">Hindi Ginagamit</translation>
 <translation id="6303423059719347535">Ang baterya ay <ph name="PERCENTAGE"/>% na puno</translation>
+<translation id="2778346081696727092">Nabigong patotohanan gamit ang ibinigay na username o password</translation>
 <translation id="3294437725009624529">Bisita</translation>
 <translation id="8190698733819146287">I-customize ang mga wika at input...</translation>
-<translation id="598295083618286569">Nakakonekta ang Bluetooth</translation>
+<translation id="7170041865419449892">Wala sa sakop</translation>
+<translation id="4804818685124855865">I-disconnect</translation>
 <translation id="5222676887888702881">Mag-sign out</translation>
+<translation id="2688477613306174402">Configuration</translation>
+<translation id="1272079795634619415">Stop</translation>
 <translation id="4957722034734105353">Matuto nang higit pa...</translation>
 <translation id="2964193600955408481">Huwag paganahin ang Wi-Fi</translation>
 <translation id="811680302244032017">Magdagdag ng device...</translation>
 <translation id="2509468283778169019">Naka-on ang CAPS LOCK</translation>
 <translation id="3892641579809465218">Panloob na Display</translation>
 <translation id="7823564328645135659">Nagbago ang wika mula &quot;<ph name="FROM_LOCALE"/>&quot; patungong &quot;<ph name="TO_LOCALE"/>&quot; pagkatapos i-sync ang iyong mga setting.</translation>
+<translation id="3368922792935385530">Nakakonekta</translation>
 <translation id="8340999562596018839">Pasalitang feedback</translation>
 <translation id="8654520615680304441">I-on ang Wi-Fi...</translation>
 <translation id="5825747213122829519">Naging <ph name="INPUT_METHOD_ID"/> ang iyong pamamaraan ng pag-input.
 Pindutin ang Shift + Alt upang magpalit.</translation>
 <translation id="2562916301614567480">Pribadong Network</translation>
 <translation id="6549021752953852991">Walang available na cellular na network</translation>
+<translation id="4379753398862151997">Dear Monitor, it's not working out between us. (Hindi sinusuportahan ang monitor na iyan)</translation>
 <translation id="6426039856985689743">Huwag paganahin ang mobile data</translation>
 <translation id="3087734570205094154">Sa ilalim</translation>
 <translation id="5271016907025319479">Hindi naka-configure ang VPN.</translation>
-<translation id="1298695107722797780">Tapusin ang pampublikong\nsession</translation>
-<translation id="3232695630852378748">Mga setting ng Bluetooth...</translation>
+<translation id="6803622936009808957">Hindi ma-mirror ang mga display dahil walang mga sinusuportahang resolusyon na nakita. Pumasok na lang sa pinalawak na desktop.</translation>
 <translation id="1480041086352807611">Mode ng demo</translation>
 <translation id="3626637461649818317"><ph name="PERCENTAGE"/>% ang natitira</translation>
 <translation id="9089416786594320554">Mga pamamaraan ng pag-input</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">Shutdown</translation>
 <translation id="4430019312045809116">Volume</translation>
+<translation id="4442424173763614572">Nabigo ang paghahanap sa DNS</translation>
 <translation id="6356500677799115505">Ang baterya ay puno at nagcha-charge.</translation>
 <translation id="7874779702599364982">Naghahanap ng mga cellular network...</translation>
+<translation id="583281660410589416">Hindi kilala</translation>
 <translation id="1383876407941801731">Paghahanap</translation>
+<translation id="7468789844759750875">Bisitahin ang portal sa pag-activate ng <ph name="NAME"/> upang bumili ng higit pang data.</translation>
 <translation id="3901991538546252627">Kumokonekta sa <ph name="NAME"/></translation>
 <translation id="2204305834655267233">Impormasyon ng Network</translation>
 <translation id="1621499497873603021">Natitirang oras bago maubos ang baterya, <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">Nakaraang menu</translation>
 <translation id="1346748346194534595">Kanan</translation>
 <translation id="8528322925433439945">Mobile ...</translation>
+<translation id="7049357003967926684">Kaugnayan</translation>
 <translation id="8428213095426709021">Mga Setting</translation>
-<translation id="2472320577759310817">Naka-off ang bluetooth.</translation>
 <translation id="2372145515558759244">Nagsi-sync ng apps...</translation>
+<translation id="7256405249507348194">Hindi nakikilalang error: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">Nabigo ang pagsusuri sa AAA</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: Dinidiskonekta...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> hanggang mapuno</translation>
 <translation id="5787281376604286451">Pinagana ang pasalitang feedback.
 Pindutin ang Ctrl+Alt+Z upang huwag paganahin.</translation>
 <translation id="4479639480957787382">Ethernet</translation>
+<translation id="6312403991423642364">Hindi alam na error sa network</translation>
 <translation id="1467432559032391204">Kaliwa</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830">Ina-activate ang <ph name="NAME"/></translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">Maximize</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: Kumokonekta...</translation>
+<translation id="8639033665604704195">Nabigong patotohanan gamit ang ibinigay na paunang naibahaging key</translation>
 <translation id="252373100621549798">Hindi Kilalang Display</translation>
 <translation id="1882897271359938046">Nagmi-mirror sa <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">I-lock</translation>
 <translation id="2805756323405976993">Apps</translation>
-<translation id="2482878487686419369">Mga Abiso</translation>
+<translation id="1512064327686280138">Pagkabigo ng pag-activate</translation>
+<translation id="5097002363526479830">Nabigong kumonekta sa network na '<ph name="NAME"/>': <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Naka-off ang Wi-Fi.</translation>
-<translation id="2872961005593481000">Shut down</translation>
+<translation id="8036518327127111261">Nabigong patotohanan gamit ang ibinigay na certificate</translation>
 <translation id="8132793192354020517">Kumukonekta sa <ph name="NAME"/></translation>
 <translation id="7052914147756339792">Magtakda ng wallpaper...</translation>
-<translation id="2739500853984626550">Walang mga available na bluetooth device</translation>
-<translation id="2666092431469916601">Tuktok</translation>
+<translation id="8678698760965522072">Katayuan online</translation>
+<translation id="1119447706177454957">Panloob na error</translation>
 <translation id="3019353588588144572">Natitirang oras bago ganap na ma-charge ang baterya, <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">Screen magnifier</translation>
+<translation id="7005812687360380971">Bigo</translation>
 <translation id="1602076796624386989">Paganahin ang mobile data</translation>
 <translation id="6981982820502123353">Accessibility</translation>
 <translation id="3157931365184549694">Ipanumbalik</translation>
+<translation id="4274292172790327596">Di-kilalang error</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Nag-i-scan para sa mga device...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Naghahanap ng mga network na Wi-Fi...</translation>
+<translation id="7229570126336867161">Kailangan ng EVDO</translation>
 <translation id="2999742336789313416">Ang <ph name="DISPLAY_NAME"/> ay isang pampublikong session na pinamamahalaan ng <ph name="DOMAIN"/></translation>
 <translation id="7029814467594812963">Lumabas sa session</translation>
 <translation id="8454013096329229812">Naka-on ang Wi-Fi.</translation>
 <translation id="4872237917498892622">Alt+Search o Shift</translation>
 <translation id="2983818520079887040">Mga Setting...</translation>
-<translation id="5467313780247887226">Hindi ma-duplicate ang larawan sa mga nakakabit na monitor. Walang nakitang katugmang resolusyon.</translation>
+<translation id="8927026611342028580">Hiniling ang Koneksyon</translation>
+<translation id="8300849813060516376">Nabigo ang OTASP</translation>
 <translation id="2792498699870441125">Alt+Search</translation>
 <translation id="8660803626959853127">Nagsi-sync ng <ph name="COUNT"/> (na) file</translation>
 <translation id="639644700271529076">Naka-off ang CAPS LOCK</translation>
-<translation id="4101192585425716296">Message Center</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: Ina-activate...</translation>
+<translation id="1391854757121130358">Maaaring naubos mo na ang mobile data na nakalaan sa iyo.</translation>
 <translation id="4864165860509564259">Posisyon ng launcher</translation>
 <translation id="7593891976182323525">Search or Shift</translation>
 <translation id="7649070708921625228">Tulong</translation>
 <translation id="3050422059534974565">Naka-on ang CAPS LOCK.
 Pindutin ang Search o Shift upang kanselahin.</translation>
 <translation id="397105322502079400">Kinakalkula...</translation>
+<translation id="158849752021629804">Kailangan ng home network</translation>
+<translation id="6857811139397017780">I-activate <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">Nabigo ang paghanap ng DHCP</translation>
+<translation id="6692173217867674490">Mahinang passphrase</translation>
 <translation id="6165508094623778733">Matuto nang higit pa</translation>
+<translation id="9046895021617826162">Nabigo ang pagkonekta</translation>
+<translation id="973896785707726617">Magtatapos ang session na ito sa <ph name="SESSION_TIME_REMAINING"/>. Awtomatiko kang masa-sign out.</translation>
+<translation id="8372369524088641025">Mahinang WEP key</translation>
+<translation id="6636709850131805001">Di-kilalang katayuan</translation>
 <translation id="3573179567135747900">Palitan pabalik sa &quot;<ph name="FROM_LOCALE"/>&quot; (kailangang i-restart)</translation>
 <translation id="8103386449138765447">Mga mensaheng SMS: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Mga setting ng Google Drive ...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">Walang network</translation>
 <translation id="5941711191222866238">Minimize</translation>
 <translation id="6911468394164995108">Sumali sa iba...</translation>
-<translation id="6843725295806269523">i-mute</translation>
 <translation id="412065659894267608"><ph name="HOUR"/>o <ph name="MINUTE"/>m hanggang mapuno</translation>
 <translation id="6359806961507272919">SMS mula kay <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Carrier</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_fr.xtb b/ash/strings/ash_strings_fr.xtb
index 244ece8..83da049 100644
--- a/ash/strings/ash_strings_fr.xtb
+++ b/ash/strings/ash_strings_fr.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Batterie pleine</translation>
 <translation id="5250713215130379958">Masquer automatiquement le lanceur d'applications</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> et <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">État du portail</translation>
 <translation id="30155388420722288">Bouton de dépassement de capacité</translation>
 <translation id="5571066253365925590">Bluetooth activé</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Proxy…</translation>
 <translation id="938582441709398163">Clavier en superposition</translation>
 <translation id="6979158407327259162">Google Drive</translation>
+<translation id="6943836128787782965">Échec de l'obtention HTTP.</translation>
 <translation id="2297568595583585744">Barre d'état</translation>
+<translation id="1661867754829461514">Code secret manquant</translation>
 <translation id="4508225577814909926"><ph name="NAME"/> : Connexion en cours…</translation>
+<translation id="4237016987259239829">Erreur de connexion réseau</translation>
 <translation id="2946640296642327832">Activer le Bluetooth</translation>
 <translation id="6459472438155181876">Extension de l'écran pour <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Mobile</translation>
 <translation id="6596816719288285829">Adresse IP</translation>
+<translation id="4508265954913339219">Échec de l'activation</translation>
 <translation id="1812696562331527143">Votre mode de saisie a été remplacé par <ph name="INPUT_METHOD_ID"/>* (<ph name="BEGIN_LINK"/>tiers<ph name="END_LINK"/>).
 Appuyez sur Maj + Alt pour en utiliser un autre.</translation>
-<translation id="5233638681132016545">Nouvel onglet</translation>
 <translation id="3846575436967432996">Aucune information disponible concernant le réseau</translation>
 <translation id="3026237328237090306">Configurer les données mobiles</translation>
 <translation id="785750925697875037">Afficher le compte mobile</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Désactiver le Bluetooth</translation>
 <translation id="3126069444801937830">Redémarrez pour mettre à jour</translation>
 <translation id="735745346212279324">VPN déconnecté</translation>
+<translation id="7320906967354320621">Inactif</translation>
 <translation id="6303423059719347535">La batterie est chargée à <ph name="PERCENTAGE"/> %.</translation>
+<translation id="2778346081696727092">Échec de l'authentification à l'aide du nom d'utilisateur ou du mot de passe indiqués.</translation>
 <translation id="3294437725009624529">Invité</translation>
 <translation id="8190698733819146287">Personnaliser les langues et la saisie...</translation>
-<translation id="598295083618286569">Bluetooth connecté</translation>
+<translation id="7170041865419449892">Hors de portée</translation>
+<translation id="4804818685124855865">Se déconnecter</translation>
 <translation id="5222676887888702881">Déconnexion</translation>
+<translation id="2688477613306174402">Configuration en cours</translation>
+<translation id="1272079795634619415">Arrêter</translation>
 <translation id="4957722034734105353">En savoir plus…</translation>
 <translation id="2964193600955408481">Désactiver le réseau Wi-Fi</translation>
 <translation id="811680302244032017">Ajouter un appareil…</translation>
 <translation id="2509468283778169019">Touche VERR MAJ activée</translation>
 <translation id="3892641579809465218">Affichage interne</translation>
 <translation id="7823564328645135659">La langue utilisée est passée de &quot;<ph name="FROM_LOCALE"/>&quot; à &quot;<ph name="TO_LOCALE"/>&quot; après la synchronisation de vos paramètres.</translation>
+<translation id="3368922792935385530">Connecté</translation>
 <translation id="8340999562596018839">Commentaires audio</translation>
 <translation id="8654520615680304441">Activer le Wi-Fi…</translation>
 <translation id="5825747213122829519">Votre mode de saisie a été remplacé par <ph name="INPUT_METHOD_ID"/>.
 Appuyez sur Maj + Alt pour en utiliser un autre.</translation>
 <translation id="2562916301614567480">Réseau privé</translation>
 <translation id="6549021752953852991">Aucun réseau mobile disponible</translation>
+<translation id="4379753398862151997">Moniteur non compatible.</translation>
 <translation id="6426039856985689743">Désactiver les données mobiles</translation>
 <translation id="3087734570205094154">Bas</translation>
 <translation id="5271016907025319479">VPN non configuré</translation>
-<translation id="1298695107722797780">Mettre fin à la\nsession publique</translation>
-<translation id="3232695630852378748">Paramètres Bluetooth…</translation>
+<translation id="6803622936009808957">Impossible de dupliquer les écrans, car aucune résolution compatible n'a été détectée. Le bureau étendu a été activé à la place.</translation>
 <translation id="1480041086352807611">Mode démonstration</translation>
 <translation id="3626637461649818317"><ph name="PERCENTAGE"/> % restant(s)</translation>
 <translation id="9089416786594320554">Modes de saisie</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/> %</translation>
 <translation id="1895658205118569222">Arrêt.</translation>
 <translation id="4430019312045809116">Volume</translation>
+<translation id="4442424173763614572">Échec de la résolution DNS.</translation>
 <translation id="6356500677799115505">La batterie est pleine et en charge.</translation>
 <translation id="7874779702599364982">Recherche de réseaux cellulaires en cours…</translation>
+<translation id="583281660410589416">Inconnu</translation>
 <translation id="1383876407941801731">Recherche</translation>
+<translation id="7468789844759750875">Pour acheter plus de données, consultez le portail d'activation <ph name="NAME"/>.</translation>
 <translation id="3901991538546252627">Connexion à <ph name="NAME"/> en cours…</translation>
 <translation id="2204305834655267233">Informations réseau</translation>
 <translation id="1621499497873603021">Temps restant avant que la batterie ne soit vide : <ph name="TIME_LEFT"/>.</translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">Menu précédent</translation>
 <translation id="1346748346194534595">Vers la droite</translation>
 <translation id="8528322925433439945">Mobile…</translation>
+<translation id="7049357003967926684">Association</translation>
 <translation id="8428213095426709021">Paramètres</translation>
-<translation id="2472320577759310817">Bluetooth désactivé</translation>
 <translation id="2372145515558759244">Synchronisation des applications…</translation>
+<translation id="7256405249507348194">Erreur non reconnue : <ph name="DESC"/>.</translation>
+<translation id="7925247922861151263">Échec de la vérification AAA</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/> : Déconnexion en cours…</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> de chargement</translation>
 <translation id="5787281376604286451">Les commentaires audio sont activés.
 Appuyez sur les touches Ctrl+Alt+Z pour les désactiver.</translation>
 <translation id="4479639480957787382">Ethernet </translation>
+<translation id="6312403991423642364">Erreur de réseau inconnue.</translation>
 <translation id="1467432559032391204">Vers la gauche</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830">Activation du réseau <ph name="NAME"/> en cours…</translation>
 <translation id="8814190375133053267">Wi-Fi </translation>
 <translation id="1398853756734560583">Agrandir</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/> : Connexion en cours…</translation>
+<translation id="8639033665604704195">Échec de l'authentification à l'aide de la clé pré-partagée fournie.</translation>
 <translation id="252373100621549798">Écran inconnu</translation>
 <translation id="1882897271359938046">Mise en miroir pour <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Verrouiller</translation>
 <translation id="2805756323405976993">Applications</translation>
-<translation id="2482878487686419369">Notifications</translation>
+<translation id="1512064327686280138">Échec de l'activation</translation>
+<translation id="5097002363526479830">Échec de la connexion au réseau &quot;<ph name="NAME"/>&quot; : <ph name="DETAILS"/>.</translation>
 <translation id="1850504506766569011">Le Wi-Fi est désactivé.</translation>
-<translation id="2872961005593481000">Éteindre</translation>
+<translation id="8036518327127111261">Échec de l'authentification à l'aide du certificat fourni.</translation>
 <translation id="8132793192354020517">Connecté à <ph name="NAME"/></translation>
 <translation id="7052914147756339792">Définir un fond d'écran…</translation>
-<translation id="2739500853984626550">Aucun appareil Bluetooth disponible</translation>
-<translation id="2666092431469916601">En haut</translation>
+<translation id="8678698760965522072">En ligne</translation>
+<translation id="1119447706177454957">Erreur interne.</translation>
 <translation id="3019353588588144572">Temps restant avant chargement complet de la batterie : <ph name="TIME_REMAINING"/>.</translation>
 <translation id="3473479545200714844">Loupe</translation>
+<translation id="7005812687360380971">Défaillance</translation>
 <translation id="1602076796624386989">Activer les données mobiles</translation>
 <translation id="6981982820502123353">Accessibilité</translation>
 <translation id="3157931365184549694">Rétablir</translation>
+<translation id="4274292172790327596">Erreur non reconnue</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Recherche d'appareils en cours…</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/> <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Recherche de réseaux Wi-Fi...</translation>
+<translation id="7229570126336867161">Technologie EvDo requise</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> est une session publique gérée par <ph name="DOMAIN"/></translation>
 <translation id="7029814467594812963">Quitter la session</translation>
 <translation id="8454013096329229812">Le Wi-Fi est activé.</translation>
 <translation id="4872237917498892622">Alt + Recherche ou Maj</translation>
 <translation id="2983818520079887040">Paramètres...</translation>
-<translation id="5467313780247887226">Impossible de dupliquer l'image sur les écrans joints. Aucune résolution correspondante trouvée.</translation>
+<translation id="8927026611342028580">Connexion demandée</translation>
+<translation id="8300849813060516376">Échec de l'opération OTASP</translation>
 <translation id="2792498699870441125">Alt + Recherche</translation>
 <translation id="8660803626959853127">Synchronisation de <ph name="COUNT"/> fichier(s) en cours…</translation>
 <translation id="639644700271529076">La touche de verrouillage des majuscules est désactivée.</translation>
-<translation id="4101192585425716296">Centre de messagerie</translation>
+<translation id="6267036997247669271"><ph name="NAME"/> : activation en cours…</translation>
+<translation id="1391854757121130358">Vous avez peut-être épuisé votre forfait de données mobiles.</translation>
 <translation id="4864165860509564259">Position du lanceur</translation>
 <translation id="7593891976182323525">Recherche ou Maj</translation>
 <translation id="7649070708921625228">Aide</translation>
 <translation id="3050422059534974565">Le VERROUILLAGE DES MAJUSCULES est activé.
 Appuyez sur Search ou Maj pour le désactiver.</translation>
 <translation id="397105322502079400">Calcul en cours…</translation>
+<translation id="158849752021629804">Réseau domestique requis</translation>
+<translation id="6857811139397017780">Activer <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">Échec de la vérification DHCP</translation>
+<translation id="6692173217867674490">Mot de passe multiterme erroné</translation>
 <translation id="6165508094623778733">En savoir plus</translation>
+<translation id="9046895021617826162">Échec de la connexion</translation>
+<translation id="973896785707726617">Cette session se terminera dans <ph name="SESSION_TIME_REMAINING"/>. Vous serez automatiquement déconnecté.</translation>
+<translation id="8372369524088641025">Clé WEP incorrecte</translation>
+<translation id="6636709850131805001">État non reconnu</translation>
 <translation id="3573179567135747900">Revenir à &quot;<ph name="FROM_LOCALE"/>&quot; (redémarrage requis)</translation>
 <translation id="8103386449138765447">Messages SMS : <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Paramètres Google Drive…</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">Aucun réseau détecté</translation>
 <translation id="5941711191222866238">Réduire</translation>
 <translation id="6911468394164995108">Autre réseau…</translation>
-<translation id="6843725295806269523">muet</translation>
 <translation id="412065659894267608">Encore <ph name="HOUR"/> h <ph name="MINUTE"/> min de chargement</translation>
 <translation id="6359806961507272919">SMS de <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Opérateur</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_gu.xtb b/ash/strings/ash_strings_gu.xtb
index 1b1b430..a697610 100644
--- a/ash/strings/ash_strings_gu.xtb
+++ b/ash/strings/ash_strings_gu.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">બૅટરી પૂર્ણ ભરાઈ ગઈ</translation>
 <translation id="5250713215130379958">સ્વતઃછુપાવો લૉન્ચર</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> અને <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">પોર્ટલ સ્ટેટ</translation>
 <translation id="30155388420722288">ઓવરફ્લો બટન</translation>
 <translation id="5571066253365925590">Bluetooth સક્ષમ છે</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">પ્રોક્સી...</translation>
 <translation id="938582441709398163">કીબોર્ડ ઓવરલે</translation>
 <translation id="6979158407327259162">Google ડ્રાઇવ</translation>
+<translation id="6943836128787782965">HTTP નિષ્ફળ ગયું</translation>
 <translation id="2297568595583585744">સ્થિતિ ટ્રે</translation>
+<translation id="1661867754829461514">PIN ખૂટે છે</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: કનેક્ટ કરી રહ્યું છે...</translation>
+<translation id="4237016987259239829">નેટવર્ક કનેક્શન ભૂલ</translation>
 <translation id="2946640296642327832">Bluetooth સક્ષમ કરો</translation>
 <translation id="6459472438155181876">સ્ક્રીનને <ph name="DISPLAY_NAME"/> પર વિસ્તૃત કરી રહ્યાં છે</translation>
 <translation id="8206859287963243715">સેલ્યુલર</translation>
 <translation id="6596816719288285829">IP સરનામું</translation>
+<translation id="4508265954913339219">સક્રિયતા નિષ્ફળ</translation>
 <translation id="1812696562331527143">તમારી ઇનપુટ પદ્ધતિ  <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>3જા પક્ષ<ph name="END_LINK"/>)માં બદલાઇ ગયેલ છે.
 સ્વિચ કરવા માટે Shift + Alt દબાવો.</translation>
-<translation id="5233638681132016545">નવું ટૅબ</translation>
 <translation id="3846575436967432996">કોઈ નેટવર્ક માહિતી ઉપલબ્ધ નથી</translation>
 <translation id="3026237328237090306">મોબાઇલ ડેટા સેટ કરો</translation>
 <translation id="785750925697875037">મોબાઇલ એકાઉન્ટ જુઓ</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Bluetooth અક્ષમ કરો</translation>
 <translation id="3126069444801937830">અપડેટ કરવા માટે પુનઃપ્રારંભ કરો</translation>
 <translation id="735745346212279324">VPN ડિસ્કનેક્ટ કર્યું છે</translation>
+<translation id="7320906967354320621">નિષ્ક્રિય</translation>
 <translation id="6303423059719347535">બેટરી <ph name="PERCENTAGE"/> % પૂર્ણ છે</translation>
+<translation id="2778346081696727092">આપેલા વપરાશકર્તાનામ અથવા પાસવર્ડ સાથે અધિકૃત કરવામાં નિષ્ફળ રહ્યું</translation>
 <translation id="3294437725009624529">અતિથિ</translation>
 <translation id="8190698733819146287">ભાષાઓ અને ઇનપુટને કસ્ટમાઇઝ કરો...</translation>
-<translation id="598295083618286569">Bluetooth કનેક્ટ કરેલું છે</translation>
+<translation id="7170041865419449892">પહોંચ બહાર</translation>
+<translation id="4804818685124855865">ડિસ્કનેક્ટ કરો</translation>
 <translation id="5222676887888702881">સાઇન આઉટ</translation>
+<translation id="2688477613306174402">કન્ફિગરેશન</translation>
+<translation id="1272079795634619415">રોકો</translation>
 <translation id="4957722034734105353">વધુ જાણો...</translation>
 <translation id="2964193600955408481">Wi-Fi ને અક્ષમ કરો</translation>
 <translation id="811680302244032017">ઉપકરણ ઉમેરો...</translation>
 <translation id="2509468283778169019">CAPS LOCK ચાલુ છે</translation>
 <translation id="3892641579809465218">આંતરિક પ્રદર્શન</translation>
 <translation id="7823564328645135659">તમારી સેટિંગ્સ સમન્વયિત કર્યા પછી ભાષા &quot;<ph name="FROM_LOCALE"/>&quot; થી &quot;<ph name="TO_LOCALE"/>&quot; માં બદલાઈ ગઈ છે.</translation>
+<translation id="3368922792935385530">કનેક્ટેડ</translation>
 <translation id="8340999562596018839">બોલાયેલ પ્રતિસાદ</translation>
 <translation id="8654520615680304441">Wi-Fi ચાલુ કરો...</translation>
 <translation id="5825747213122829519">તમારી ઇનપુટ પદ્ધતિ <ph name="INPUT_METHOD_ID"/> માં બદલાઇ ગયેલ છે.
 સ્વિચ કરવા માટે Shift + Alt દબાવો.</translation>
 <translation id="2562916301614567480">ખાનગી નેટવર્ક</translation>
 <translation id="6549021752953852991">કોઇ સેલ્યુલર નેટવર્ક ઉપલબ્ધ નથી</translation>
+<translation id="4379753398862151997">પ્રિય મોનિટર, તે અમારી વચ્ચે કાર્ય કરી રહ્યું નથી. (તે મોનિટર સમર્થિત નથી)</translation>
 <translation id="6426039856985689743">મોબાઇલ ડેટાને અક્ષમ કરો</translation>
 <translation id="3087734570205094154">તળિયું</translation>
 <translation id="5271016907025319479">VPN ગોઠવેલું નથી.</translation>
-<translation id="1298695107722797780">જાહેર સત્ર\nસમાપ્ત કરો</translation>
-<translation id="3232695630852378748">Bluetooth સેટિંગ્સ...</translation>
+<translation id="6803622936009808957">કોઈ સમર્થિત રિઝોલ્યૂશન મળ્યું ન હોવાથી, પ્રદર્શનોને પ્રતિબિંબિત કરી શકાયા નથી. તેને બદલે વિસ્તૃત ડેસ્કટૉપ દાખલ કર્યું.</translation>
 <translation id="1480041086352807611">ડેમો મોડ</translation>
 <translation id="3626637461649818317"><ph name="PERCENTAGE"/>% બાકી</translation>
 <translation id="9089416786594320554">ઇનપુટ પદ્ધતિઓ</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">બંધ કરો</translation>
 <translation id="4430019312045809116">વૉલ્યૂમ</translation>
+<translation id="4442424173763614572">DNS લુકઅપ નિષ્ફળ ગયું</translation>
 <translation id="6356500677799115505">બેટરી સંપૂર્ણ છે અને ચાર્જ થઈ રહી છે.</translation>
 <translation id="7874779702599364982">સેલ્યુલર નેટવર્ક્સ માટે શોધી રહ્યું છે...</translation>
+<translation id="583281660410589416">અજ્ઞાત</translation>
 <translation id="1383876407941801731">શોધ</translation>
+<translation id="7468789844759750875">વધુ ડેટા ખરીદવા માટે <ph name="NAME"/> સક્રિયકરણ પોર્ટલની મુલાકાત લો.</translation>
 <translation id="3901991538546252627"><ph name="NAME"/> થી કનેક્ટ કરી રહ્યું છે</translation>
 <translation id="2204305834655267233">નેટવર્ક માહિતી</translation>
 <translation id="1621499497873603021">બેટરી ખાલી થવામાં બાકી સમય, <ph name="TIME_LEFT"/></translation>
@@ -70,55 +83,74 @@
 <translation id="8308637677604853869">પહેલાનું મેનૂ</translation>
 <translation id="1346748346194534595">જમણે</translation>
 <translation id="8528322925433439945">મોબાઇલ ...</translation>
+<translation id="7049357003967926684">સંસ્થા</translation>
 <translation id="8428213095426709021">સેટિંગ્સ</translation>
-<translation id="2472320577759310817">Bluetooth બંધ છે.</translation>
 <translation id="2372145515558759244">એપ્લિકેશન્સને સમન્વયિત કરી રહ્યું છે...</translation>
+<translation id="7256405249507348194">અજ્ઞાત ભૂલ: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">AAA તપાસ નિષ્ફળ</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: ડિસ્કનેક્ટ કરી રહ્યું છે...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> પૂર્ણ થાય ત્યાં સુધી</translation>
 <translation id="5787281376604286451">બોલાયેલ પ્રતિસાદ સક્ષમ છે. અક્ષમ કરવા માટે Ctrl + Alt + Z દબાવો.</translation>
 <translation id="4479639480957787382">ઇથરનેટ</translation>
+<translation id="6312403991423642364">અજ્ઞાત નેટવર્ક ભૂલ</translation>
 <translation id="1467432559032391204">ડાબું</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830"><ph name="NAME"/> ને સક્રિય કરી રહ્યું છે</translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">મોટું કરો</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: કનેક્ટ કરી રહ્યું છે...</translation>
+<translation id="8639033665604704195">આપેલ શેર્ડ કીથી અધિકૃત કરવામાં નિષ્ફળ </translation>
 <translation id="252373100621549798">અજ્ઞાત પ્રદર્શન</translation>
 <translation id="1882897271359938046"><ph name="DISPLAY_NAME"/> પર પ્રતિબિંબિત થઈ રહ્યું છે</translation>
 <translation id="3784455785234192852">લૉક</translation>
 <translation id="2805756323405976993">એપ્લિકેશન્સ</translation>
-<translation id="2482878487686419369">સૂચનાઓ</translation>
+<translation id="1512064327686280138">સક્રિયતા નિષ્ફળ</translation>
+<translation id="5097002363526479830">નેટવર્ક '<ph name="NAME"/>' થી કનેક્ટ કરવામાં નિષ્ફળ: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi બંધ છે.</translation>
-<translation id="2872961005593481000">શટ ડાઉન કરો</translation>
+<translation id="8036518327127111261">આપેલ પ્રમાણપત્રથી અધિકૃત કરવામાં નિષ્ફળ </translation>
 <translation id="8132793192354020517"><ph name="NAME"/> થી કનેક્ટેડ છે</translation>
 <translation id="7052914147756339792">વૉલપેપર સેટ કરો...</translation>
-<translation id="2739500853984626550">કોઈ bluetooth ઉપકરણો ઉપલબ્ધ નથી</translation>
-<translation id="2666092431469916601">ઉપર</translation>
+<translation id="8678698760965522072">ઓનલાઇન સ્ટેટ</translation>
+<translation id="1119447706177454957">આંતરિક ભૂલ</translation>
 <translation id="3019353588588144572">બેટરી સંપૂર્ણપણે ચાર્જ થવામાં બાકી સમય, <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">સ્ક્રીન બૃહદદર્શક</translation>
+<translation id="7005812687360380971">નિષ્ફળતા</translation>
 <translation id="1602076796624386989">મોબાઇલ ડેટા સક્ષમ કરો</translation>
 <translation id="6981982820502123353">ઍક્સેસિબિલિટી</translation>
 <translation id="3157931365184549694">પુનઃસ્થાપિત કરો</translation>
+<translation id="4274292172790327596">અપરિચિત ભૂલ</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/> : <ph name="MINUTES"/> : <ph name="SECONDS"/></translation>
 <translation id="225680501294068881">ઉપકરણો માટે સ્કેન કરી રહ્યું છે...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157"> Wi-Fi નેટવર્ક્સ માટે શોધી રહ્યું છે... </translation>
+<translation id="7229570126336867161">EVDO ની જરૂર છે</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> એ <ph name="DOMAIN"/> દ્વારા સંચાલિત સાર્વજનિક સત્ર છે</translation>
 <translation id="7029814467594812963">સત્રમાંથી બહાર નીકળો</translation>
 <translation id="8454013096329229812">Wi-Fi ચાલુ છે.</translation>
 <translation id="4872237917498892622">Alt+Search અથવા Shift</translation>
 <translation id="2983818520079887040">સેટિંગ્સ...</translation>
-<translation id="5467313780247887226">જોડેલ મોનિટર પર છબીને ડુપ્લિકેટ કરી શકાતી નથી. કોઈ મેળ ખાતું રીઝૉલ્યુશન મળ્યું નથી.</translation>
+<translation id="8927026611342028580">કનેક્ટ કરવાની વિનંતી કરી છે</translation>
+<translation id="8300849813060516376">OTASP નિષ્ફળ</translation>
 <translation id="2792498699870441125">Alt+Search</translation>
 <translation id="8660803626959853127"><ph name="COUNT"/> ફાઇલને સમન્વયિત કરી રહ્યું છે</translation>
 <translation id="639644700271529076">CAPS LOCK બંધ છે</translation>
-<translation id="4101192585425716296">સંદેશ કેન્દ્ર</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: સક્રિય કરી રહ્યું છે...</translation>
+<translation id="1391854757121130358">તમે તમારા મોબાઇલ ડેટા ભથ્થાનો ઉપયોગ કરી લીધો હશે.</translation>
 <translation id="4864165860509564259">લૉન્ચર સ્થિતિ</translation>
 <translation id="7593891976182323525">Search અથવા Shift</translation>
 <translation id="7649070708921625228">સહાય</translation>
 <translation id="3050422059534974565">CAPS LOCK ચાલુ છે. 
 રદ કરવા માટે Search અથવા Shift દબાવો.</translation>
 <translation id="397105322502079400">ગણના કરી રહ્યું છે...</translation>
+<translation id="158849752021629804">હોમ નેટવર્કની આવશ્યકતા છે</translation>
+<translation id="6857811139397017780">સક્રિય કરો <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">DHCP લુકઅપ નિષ્ફળ</translation>
+<translation id="6692173217867674490">ખરાબ પાસફ્રેઝ</translation>
 <translation id="6165508094623778733">વધુ જાણો</translation>
+<translation id="9046895021617826162">કનેક્ટ કરવું નિષ્ફળ</translation>
+<translation id="973896785707726617">આ સત્ર <ph name="SESSION_TIME_REMAINING"/> માં સમાપ્ત થશે. તમને આપમેળે સાઇન આઉટ કરવામાં આવશે.</translation>
+<translation id="8372369524088641025">ખરાબ WEP કી</translation>
+<translation id="6636709850131805001">અપરિચિત સ્થિતિ</translation>
 <translation id="3573179567135747900">&quot;<ph name="FROM_LOCALE"/>&quot; પર પાછાં જાઓ (પુનર્પ્રારંભની જરૂર છે)</translation>
 <translation id="8103386449138765447">SMS સંદેશા: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Google ડ્રાઇવ સેટિંગ્સ...</translation>
@@ -129,7 +161,7 @@
 <translation id="8000066093800657092">નેટવર્ક નથી</translation>
 <translation id="5941711191222866238">નાનું કરો</translation>
 <translation id="6911468394164995108">અન્યથી જોડાઓ...</translation>
-<translation id="6843725295806269523">બંધ કરો</translation>
 <translation id="412065659894267608"><ph name="HOUR"/>ક <ph name="MINUTE"/>મિ સુધીમાં પૂર્ણ</translation>
 <translation id="6359806961507272919"><ph name="PHONE_NUMBER"/> તરફથી SMS</translation>
+<translation id="1244147615850840081">વાહક</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_hi.xtb b/ash/strings/ash_strings_hi.xtb
index 32b80d6..e90f17a 100644
--- a/ash/strings/ash_strings_hi.xtb
+++ b/ash/strings/ash_strings_hi.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">बैटरी पूर्ण</translation>
 <translation id="5250713215130379958">लॉन्चर को स्वत: छिपाएं</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> और <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">पोर्टल स्थिति</translation>
 <translation id="30155388420722288">ओवरफ़्लो बटन</translation>
 <translation id="5571066253365925590">Bluetooth सक्षम किया गया</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">प्रॉक्सी...</translation>
 <translation id="938582441709398163">कीबोर्ड ओवरले</translation>
 <translation id="6979158407327259162">Google डिस्क</translation>
+<translation id="6943836128787782965">HTTP विफल हुआ</translation>
 <translation id="2297568595583585744">स्थिति ट्रे</translation>
+<translation id="1661867754829461514">पिन गुम</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: कनेक्ट हो रहा है...</translation>
+<translation id="4237016987259239829">नेटवर्क कनेक्शन त्रुटि</translation>
 <translation id="2946640296642327832">Bluetooth सक्षम करें</translation>
 <translation id="6459472438155181876"><ph name="DISPLAY_NAME"/> पर स्क्रीन विस्तृत कर रहा है</translation>
 <translation id="8206859287963243715">सेलुलर</translation>
 <translation id="6596816719288285829">IP पता</translation>
+<translation id="4508265954913339219">सक्रियण विफल</translation>
 <translation id="1812696562331527143">आपकी इनपुट विधि <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>तृतीय पक्ष<ph name="END_LINK"/>) में बदल गई है.
 स्विच करने के लिए Shift + Alt दबाएं.</translation>
-<translation id="5233638681132016545">नया टैब</translation>
 <translation id="3846575436967432996">कोई नेटवर्क जानकारी उपलब्ध नहीं</translation>
 <translation id="3026237328237090306">मोबाइल डेटा सेट करें</translation>
 <translation id="785750925697875037">मोबाइल खाते देखें</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Bluetooth अक्षम करें</translation>
 <translation id="3126069444801937830">अपडेट करने के लिए पुनरारंभ करें</translation>
 <translation id="735745346212279324">VPN डिस्कनेक्ट है</translation>
+<translation id="7320906967354320621">निष्क्रिय</translation>
 <translation id="6303423059719347535">बैटरी <ph name="PERCENTAGE"/>% भर गई है</translation>
+<translation id="2778346081696727092">प्रदान किए गए उपयोगकर्तानाम या पासवर्ड से प्रमाणीकृत करने में विफ़ल रहा</translation>
 <translation id="3294437725009624529">अतिथि</translation>
 <translation id="8190698733819146287">भाषाएं और इनपुट कस्टमाइज़ करें...</translation>
-<translation id="598295083618286569">Bluetooth कनेक्ट किया गया</translation>
+<translation id="7170041865419449892">सीमा से बाहर</translation>
+<translation id="4804818685124855865">डिस्कनेक्ट करें</translation>
 <translation id="5222676887888702881">साइन आउट करें</translation>
+<translation id="2688477613306174402">कॉन्फ़िगरेशन</translation>
+<translation id="1272079795634619415">रोकें</translation>
 <translation id="4957722034734105353">और जानें...</translation>
 <translation id="2964193600955408481">Wi-Fi अक्षम करें</translation>
 <translation id="811680302244032017">डिवाइस जोड़ें...</translation>
 <translation id="2509468283778169019">CAPS LOCK चालू है</translation>
 <translation id="3892641579809465218">आंतरिक डिस्प्ले</translation>
 <translation id="7823564328645135659">आपकी सेटिंग समन्वयित करने के बाद भाषा को &quot;<ph name="FROM_LOCALE"/>&quot; से &quot;<ph name="TO_LOCALE"/>&quot; में बदल दिया गया है.</translation>
+<translation id="3368922792935385530">कनेक्टेड</translation>
 <translation id="8340999562596018839">बोला जाने वाला फ़ीडबैक</translation>
 <translation id="8654520615680304441">Wi-Fi चालू करें...</translation>
 <translation id="5825747213122829519">आपकी इनपुट विधि <ph name="INPUT_METHOD_ID"/> में बदल गई है.
 स्विच करने के लिए Shift + Alt दबाएं.</translation>
 <translation id="2562916301614567480">निजी नेटवर्क</translation>
 <translation id="6549021752953852991">कोई सेल्युलर नेटवर्क उपलब्ध नहीं</translation>
+<translation id="4379753398862151997">Dear Monitor, it's not working out between us. (वह मॉनीटर समर्थित नहीं है)</translation>
 <translation id="6426039856985689743">मोबाइल डेटा अक्षम करें</translation>
 <translation id="3087734570205094154">नीचे</translation>
 <translation id="5271016907025319479">VPN कॉन्फ़िगर नहीं किया गया है.</translation>
-<translation id="1298695107722797780">सार्वजनिक\nसत्र समाप्त करें</translation>
-<translation id="3232695630852378748">Bluetooth सेटिंग...</translation>
+<translation id="6803622936009808957">प्रदर्शनों को मिरर नहीं किया जा सका क्योंकि कोई समर्थित रिज़ॉल्यूशन नहीं मिला. इसके बजाय विस्तारित डेस्कटॉप में चला गया है.</translation>
 <translation id="1480041086352807611">डेमो मोड</translation>
 <translation id="3626637461649818317"><ph name="PERCENTAGE"/>% शेष है</translation>
 <translation id="9089416786594320554">इनपुट पद्धतियां</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">बंद करें</translation>
 <translation id="4430019312045809116">मात्रा</translation>
+<translation id="4442424173763614572">DNS लुकअप विफल</translation>
 <translation id="6356500677799115505">बैटरी भर गई है और चार्ज हो रही है.</translation>
 <translation id="7874779702599364982">सेलुलर नेटवर्क खोज रहा है...</translation>
+<translation id="583281660410589416">अज्ञात</translation>
 <translation id="1383876407941801731">खोज</translation>
+<translation id="7468789844759750875">अधिक डेटा खरीदने के लिए <ph name="NAME"/> सक्रियण पोर्टल पर जाएं.</translation>
 <translation id="3901991538546252627"><ph name="NAME"/> से कनेक्‍ट हो रहा है</translation>
 <translation id="2204305834655267233">नेटवर्क जानकारी</translation>
 <translation id="1621499497873603021">बैटरी के खाली होने में शेष समय, <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">पिछला मेनू</translation>
 <translation id="1346748346194534595">दाएं</translation>
 <translation id="8528322925433439945">मोबाइल ...</translation>
+<translation id="7049357003967926684">संबद्धता</translation>
 <translation id="8428213095426709021">सेटिंग</translation>
-<translation id="2472320577759310817">Bluetooth बंद है.</translation>
 <translation id="2372145515558759244">एप्लिकेशन समन्वयित किए जा रहे हैं...</translation>
+<translation id="7256405249507348194">अपरिचित त्रुटि: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">AAA जांच विफल</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: डिस्कनेक्ट हो रहा है...</translation>
 <translation id="8456362689280298700">पूरा होने में <ph name="HOUR"/>:<ph name="MINUTE"/> शेष</translation>
 <translation id="5787281376604286451">बोला जाने वाला फ़ीडबैक सक्षम है.
 अक्षम करने के लिए Ctrl+Alt+Z दबाएं.</translation>
 <translation id="4479639480957787382">इथरनेट</translation>
+<translation id="6312403991423642364">अज्ञात नेटवर्क त्रुटि</translation>
 <translation id="1467432559032391204">बाएं</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830"><ph name="NAME"/> सक्रिय हो रहा है</translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">बड़ा करें</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: कनेक्ट हो रहा है...</translation>
+<translation id="8639033665604704195">प्रदान की गई पहले से साझा की गई कुंजी से प्रमाणीकृत करने में विफ़ल रहा</translation>
 <translation id="252373100621549798">अज्ञात डिस्प्ले</translation>
 <translation id="1882897271359938046"><ph name="DISPLAY_NAME"/> पर मिरर कर रहा है</translation>
 <translation id="3784455785234192852">लॉक करें</translation>
 <translation id="2805756323405976993">एप्लिकेशन</translation>
-<translation id="2482878487686419369">अधिसूचनाएं</translation>
+<translation id="1512064327686280138">सक्रियण विफलता</translation>
+<translation id="5097002363526479830">नेटवर्क से कनेक्ट करने में विफल '<ph name="NAME"/>': <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi बंद है.</translation>
-<translation id="2872961005593481000">शट डाउन करें</translation>
+<translation id="8036518327127111261">प्रदान किए गए प्रमाणपत्र से प्रमाणीकृत करने में विफल रहा</translation>
 <translation id="8132793192354020517"><ph name="NAME"/> से कनेक्ट है</translation>
 <translation id="7052914147756339792">वॉलपेपर सेट करें...</translation>
-<translation id="2739500853984626550">कोई bluetooth उपकरण उपलब्ध नहीं है</translation>
-<translation id="2666092431469916601">शीर्ष</translation>
+<translation id="8678698760965522072">ऑनलाइन स्थिति</translation>
+<translation id="1119447706177454957">आंतरिक त्रुटि</translation>
 <translation id="3019353588588144572">बैटरी के पूरी तरह से चार्ज होने में शेष समय, <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">स्क्रीन आवर्द्धक</translation>
+<translation id="7005812687360380971">विफलता</translation>
 <translation id="1602076796624386989">मोबाइल डेटा सक्षम करें</translation>
 <translation id="6981982820502123353">पहुंच क्षमता</translation>
 <translation id="3157931365184549694">पुनर्स्थापित करें</translation>
+<translation id="4274292172790327596">अपरिचित त्रुटि</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">उपकरण स्कैन किए जा रहे हैं...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Wi-Fi नेटवर्क खोज रहा है...</translation>
+<translation id="7229570126336867161">EVDO की आवश्यकता है</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/>, <ph name="DOMAIN"/> के द्वारा प्रबंधित एक सार्वजनिक सत्र है</translation>
 <translation id="7029814467594812963">सत्र से बाहर निकलें</translation>
 <translation id="8454013096329229812">Wi-Fi चालू है.</translation>
 <translation id="4872237917498892622">Alt+Search या Shift</translation>
 <translation id="2983818520079887040">सेटिंग...</translation>
-<translation id="5467313780247887226">अनुलग्नित मॉनिटर पर चित्र डुप्लिकेट नहीं कर सकते. मिलान करता हुआ कोई रिज़ॉल्यूशन नहीं मिला.</translation>
+<translation id="8927026611342028580">कनेक्ट करने का अनुरोध किया गया</translation>
+<translation id="8300849813060516376">OTASP विफल</translation>
 <translation id="2792498699870441125">Alt+Search</translation>
 <translation id="8660803626959853127"><ph name="COUNT"/> फ़ाइल/फ़ाइलें समन्वयित हो रही है/हो रही हैं</translation>
 <translation id="639644700271529076">CAPS LOCK बंद है</translation>
-<translation id="4101192585425716296">संदेश केंद्र</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: सक्रिय हो रहा है...</translation>
+<translation id="1391854757121130358">संभवत: आपने अपने मोबाइल डेटा सीमा का पूर्ण उपयोग कर लिया है.</translation>
 <translation id="4864165860509564259">लॉन्चर स्थिति</translation>
 <translation id="7593891976182323525">Search या Shift</translation>
 <translation id="7649070708921625228">सहायता</translation>
 <translation id="3050422059534974565">CAPS LOCK चालू है.
 रद्द करने के लिए Search या Shift दबाएं.</translation>
 <translation id="397105322502079400">गणना की जा रही है...</translation>
+<translation id="158849752021629804">होम नेटवर्क की आवश्यकता है</translation>
+<translation id="6857811139397017780"><ph name="NETWORKSERVICE"/> को सक्रिय करें</translation>
+<translation id="5864471791310927901">DHCP लुकअप विफल</translation>
+<translation id="6692173217867674490">ख़राब पासफ़्रेज़</translation>
 <translation id="6165508094623778733">अधिक जानें</translation>
+<translation id="9046895021617826162">कनेक्ट करना विफल</translation>
+<translation id="973896785707726617">यह सत्र <ph name="SESSION_TIME_REMAINING"/> में समाप्त हो जाएगा. आपको स्वचालित रूप से साइन आउट कर दिया जाएगा.</translation>
+<translation id="8372369524088641025">ख़राब WEP कुंजी</translation>
+<translation id="6636709850131805001">अपरिचित अवस्था</translation>
 <translation id="3573179567135747900">&quot;<ph name="FROM_LOCALE"/>&quot; में पुन: बदलें (पुनः आरंभ करने की आवश्यकता है)</translation>
 <translation id="8103386449138765447">SMS संदेश: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Google डिस्क सेटिंग...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">नेटवर्क नहीं है</translation>
 <translation id="5941711191222866238">छोटा करें</translation>
 <translation id="6911468394164995108">अन्य में शामिल हों...</translation>
-<translation id="6843725295806269523">म्यूट करें</translation>
 <translation id="412065659894267608">पूरी तरह से चार्ज होने में <ph name="HOUR"/>घं <ph name="MINUTE"/>मि शेष</translation>
 <translation id="6359806961507272919"><ph name="PHONE_NUMBER"/> से SMS</translation>
+<translation id="1244147615850840081">कैरियर</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_hr.xtb b/ash/strings/ash_strings_hr.xtb
index 940475e..468e3e0 100644
--- a/ash/strings/ash_strings_hr.xtb
+++ b/ash/strings/ash_strings_hr.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Baterija je puna</translation>
 <translation id="5250713215130379958">Automatski sakrij pokretač</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> i <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Stanje mreže: Portal</translation>
 <translation id="30155388420722288">Gumb padajućeg izbornika</translation>
 <translation id="5571066253365925590">Bluetooth omogućen</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Proxy...</translation>
 <translation id="938582441709398163">Preklapanje tipkovnice</translation>
 <translation id="6979158407327259162">Google disk</translation>
+<translation id="6943836128787782965">HTTP GET neuspješan</translation>
 <translation id="2297568595583585744">Ladica statusa</translation>
+<translation id="1661867754829461514">Nedostaje PIN</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: povezivanje...</translation>
+<translation id="4237016987259239829">Pogreška mrežne veze</translation>
 <translation id="2946640296642327832">Omogući Bluetooth</translation>
 <translation id="6459472438155181876">Proširivanje zaslona na zaslon <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Mobitel</translation>
 <translation id="6596816719288285829">IP adresa</translation>
+<translation id="4508265954913339219">Aktivacija nije uspjela</translation>
 <translation id="1812696562331527143">Vaš je način unosa promijenjen u <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>treća strana<ph name="END_LINK"/>).
 Pritisnite Shift + Alt za promjenu.</translation>
-<translation id="5233638681132016545">Nova kartica</translation>
 <translation id="3846575436967432996">Informacije o mreži nisu dostupne</translation>
 <translation id="3026237328237090306">Postavi mobilne podatke</translation>
 <translation id="785750925697875037">Prikaz mobilnog računa</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Onemogući Bluetooth</translation>
 <translation id="3126069444801937830">Ponovo pokrenite za ažuriranje</translation>
 <translation id="735745346212279324">Veza s VPN-om prekinuta</translation>
+<translation id="7320906967354320621">U mirovanju</translation>
 <translation id="6303423059719347535">Baterija je <ph name="PERCENTAGE"/>% puna</translation>
+<translation id="2778346081696727092">Autentifikacija s priloženim korisničkim imenom i zaporkom nije uspjela</translation>
 <translation id="3294437725009624529">Gost</translation>
 <translation id="8190698733819146287">Prilagodi jezike i unos...</translation>
-<translation id="598295083618286569">Bluetooth povezan</translation>
+<translation id="7170041865419449892">Izvan raspona</translation>
+<translation id="4804818685124855865">Prekini vezu</translation>
 <translation id="5222676887888702881">Odjava</translation>
+<translation id="2688477613306174402">Konfiguracija</translation>
+<translation id="1272079795634619415">Zaustavi</translation>
 <translation id="4957722034734105353">Saznajte više...</translation>
 <translation id="2964193600955408481">Onemogući Wi-Fi</translation>
 <translation id="811680302244032017">Dodajte uređaj...</translation>
 <translation id="2509468283778169019">Opcija CAPS LOCK uključena</translation>
 <translation id="3892641579809465218">Unutarnji zaslon</translation>
 <translation id="7823564328645135659">Jezik je promijenjen iz: &quot;<ph name="FROM_LOCALE"/>&quot; u: &quot;<ph name="TO_LOCALE"/>&quot; nakon sinkronizacije vaših postavki.</translation>
+<translation id="3368922792935385530">Spojeno</translation>
 <translation id="8340999562596018839">Govorne povratne informacije</translation>
 <translation id="8654520615680304441">Uključite Wi-Fi...</translation>
 <translation id="5825747213122829519">Vaš je način unosa promijenjen u <ph name="INPUT_METHOD_ID"/>.
 Pritisnite Shift + Alt za promjenu.</translation>
 <translation id="2562916301614567480">Privatna mreža</translation>
 <translation id="6549021752953852991">Mobilne mreže nisu dostupne</translation>
+<translation id="4379753398862151997">Dragi monitoru, naša veza neće uspjeti. (Taj monitor nije podržan)</translation>
 <translation id="6426039856985689743">Onemogući mobilne podatke</translation>
 <translation id="3087734570205094154">Donji</translation>
 <translation id="5271016907025319479">VPN nije konfiguriran.</translation>
-<translation id="1298695107722797780">Završi javnu\nsesiju</translation>
-<translation id="3232695630852378748">Postavke Bluetootha...</translation>
+<translation id="6803622936009808957">Nije bilo moguće zrcaliti zaslone jer nije pronađena nijedna podržana razlučivost. Umjesto toga proširena je radna površina.</translation>
 <translation id="1480041086352807611">Demonstracijski način</translation>
 <translation id="3626637461649818317">Preostalo <ph name="PERCENTAGE"/> %</translation>
 <translation id="9089416786594320554">Načini unosa</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">Isključivanje</translation>
 <translation id="4430019312045809116">Glasnoća</translation>
+<translation id="4442424173763614572">Nije uspjelo pretraživanje DNS poslužitelja</translation>
 <translation id="6356500677799115505">Baterija je puna i puni se.</translation>
 <translation id="7874779702599364982">Traženje mobilnih mreža...</translation>
+<translation id="583281660410589416">Nepoznato</translation>
 <translation id="1383876407941801731">Pretraživanje</translation>
+<translation id="7468789844759750875">Posjetite aktivacijski portal <ph name="NAME"/> da biste kupili više podataka.</translation>
 <translation id="3901991538546252627">Povezivanje s mrežom <ph name="NAME"/></translation>
 <translation id="2204305834655267233">Podaci o mreži</translation>
 <translation id="1621499497873603021">Baterija će se isprazniti za <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">Prethodni izbornik</translation>
 <translation id="1346748346194534595">Udesno</translation>
 <translation id="8528322925433439945">Mobilne mreže...</translation>
+<translation id="7049357003967926684">Udruživanje</translation>
 <translation id="8428213095426709021">Postavke</translation>
-<translation id="2472320577759310817">Bluetooth je isključen.</translation>
 <translation id="2372145515558759244">Sinkroniziranje aplikacija...</translation>
+<translation id="7256405249507348194">Neprepoznata pogreška: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">Provjera AAA nije uspjela</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: prekidanje veze...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> do potpune napunjenosti</translation>
 <translation id="5787281376604286451">Omogućene su govorne povratne informacije.
 Pritisnite Ctrl + Alt + Z da biste ih onemogućili.</translation>
 <translation id="4479639480957787382">Eternet</translation>
+<translation id="6312403991423642364">Nepoznata mrežna pogreška</translation>
 <translation id="1467432559032391204">Ulijevo</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830">Aktiviranje mreže <ph name="NAME"/></translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">Maksimiziraj</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: povezivanje...</translation>
+<translation id="8639033665604704195">Autentifikacija s priloženim unaprijed dijeljenim ključem nije uspjela</translation>
 <translation id="252373100621549798">Nepoznati zaslon</translation>
 <translation id="1882897271359938046">Zrcaljenje na zaslon <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Zaključaj</translation>
 <translation id="2805756323405976993">Apps</translation>
-<translation id="2482878487686419369">Obavijesti</translation>
+<translation id="1512064327686280138">Neuspjela aktivacija</translation>
+<translation id="5097002363526479830">Neuspješno povezivanje s mrežom &quot;<ph name="NAME"/>&quot;: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi je isključen.</translation>
-<translation id="2872961005593481000">Isključi</translation>
+<translation id="8036518327127111261">Autentifikacija s priloženim certifikatom nije uspjela</translation>
 <translation id="8132793192354020517">Povezano s <ph name="NAME"/></translation>
 <translation id="7052914147756339792">Postavljanje pozadinske slike...</translation>
-<translation id="2739500853984626550">Nema dostupnih bluetooth uređaja</translation>
-<translation id="2666092431469916601">Gornji</translation>
+<translation id="8678698760965522072">Stanje na mreži</translation>
+<translation id="1119447706177454957">Interna pogreška</translation>
 <translation id="3019353588588144572">Baterija će se napuniti za <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">Povećalo</translation>
+<translation id="7005812687360380971">Neuspjeh</translation>
 <translation id="1602076796624386989">Omogući mobilne podatke</translation>
 <translation id="6981982820502123353">Dostupnost</translation>
 <translation id="3157931365184549694">Vrati</translation>
+<translation id="4274292172790327596">Neprepoznata pogreška</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Pretraživanje uređaja...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Traženje Wi-Fi mreža...</translation>
+<translation id="7229570126336867161">Potreban je EVDO</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> predstavlja javnu sesiju kojom upravlja domena <ph name="DOMAIN"/></translation>
 <translation id="7029814467594812963">Izlazak iz sesije</translation>
 <translation id="8454013096329229812">Wi-Fi je uključen.</translation>
 <translation id="4872237917498892622">Alt + Pretraživanje ili Shift</translation>
 <translation id="2983818520079887040">Postavke...</translation>
-<translation id="5467313780247887226">Kopiranje slike na priključenim zaslonima nije moguće. Nije pronađena odgovarajuća razlučivost.</translation>
+<translation id="8927026611342028580">Podnesen je zahtjev za povezivanje</translation>
+<translation id="8300849813060516376">OTASP nije uspio</translation>
 <translation id="2792498699870441125">Alt + Pretraživanje</translation>
 <translation id="8660803626959853127">Sinkroniziranje datoteka (<ph name="COUNT"/>)</translation>
 <translation id="639644700271529076">Tipka CAPS LOCK isključena</translation>
-<translation id="4101192585425716296">Centar za poruke</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: aktiviranje...</translation>
+<translation id="1391854757121130358">Možda ste potrošili dopuštenu količinu mobilnih podataka.</translation>
 <translation id="4864165860509564259">Položaj pokretača</translation>
 <translation id="7593891976182323525">Pretraživanje ili Shift</translation>
 <translation id="7649070708921625228">Pomoć</translation>
 <translation id="3050422059534974565">Uključena je opcija CAPS LOCK.
 Pritisnite tipke Pretraživanje ili Shift da biste ju isključili.</translation>
 <translation id="397105322502079400">Izračunavanje...</translation>
+<translation id="158849752021629804">Potrebna je matična mreža</translation>
+<translation id="6857811139397017780">Aktiviraj <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">DHCP pretraživanje nije uspjelo</translation>
+<translation id="6692173217867674490">Pogrešna zaporka</translation>
 <translation id="6165508094623778733">Saznajte više</translation>
+<translation id="9046895021617826162">Neuspjelo povezivanje</translation>
+<translation id="973896785707726617">Sesija će završiti za <ph name="SESSION_TIME_REMAINING"/>. Bit ćete automatski odjavljeni.</translation>
+<translation id="8372369524088641025">Neispravan WEP ključ</translation>
+<translation id="6636709850131805001">Neprepoznato stanje</translation>
 <translation id="3573179567135747900">Vratite na &quot;<ph name="FROM_LOCALE"/>&quot; (zahtijeva ponovno pokretanje)</translation>
 <translation id="8103386449138765447">SMS poruke: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Postavke Google diska...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">Nema mreže</translation>
 <translation id="5941711191222866238">Minimiziraj</translation>
 <translation id="6911468394164995108">Pridruži se drugoj...</translation>
-<translation id="6843725295806269523">isključi ton</translation>
 <translation id="412065659894267608"><ph name="HOUR"/> h <ph name="MINUTE"/> min do završetka punjenja</translation>
 <translation id="6359806961507272919">SMS šalje <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Davatelj usluge</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_hu.xtb b/ash/strings/ash_strings_hu.xtb
index bd51d0f..24fcfa6 100644
--- a/ash/strings/ash_strings_hu.xtb
+++ b/ash/strings/ash_strings_hu.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Akkumulátor feltöltve</translation>
 <translation id="5250713215130379958">Indító automatikus elrejtése</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> és <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Portál állapota</translation>
 <translation id="30155388420722288">Túlcsordulás gomb</translation>
 <translation id="5571066253365925590">Bluetooth engedélyezve</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Proxy...</translation>
 <translation id="938582441709398163">Billentyűzetkiosztás</translation>
 <translation id="6979158407327259162">Google Drive</translation>
+<translation id="6943836128787782965">A HTTP-lekérés nem sikerült</translation>
 <translation id="2297568595583585744">Állapottálca</translation>
+<translation id="1661867754829461514">Hiányzó PIN kód</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: csatlakozás...</translation>
+<translation id="4237016987259239829">Hálózati kapcsolat hibája</translation>
 <translation id="2946640296642327832">Bluetooth engedélyezése</translation>
 <translation id="6459472438155181876">Képernyő kiterjesztése erre: <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Mobil</translation>
 <translation id="6596816719288285829">IP-cím</translation>
+<translation id="4508265954913339219">Aktiválás sikertelen</translation>
 <translation id="1812696562331527143">A beviteli mód a következőre változott: <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>harmadik fél<ph name="END_LINK"/>).
 A váltáshoz nyomja meg a Shift + Alt billentyűkódot.</translation>
-<translation id="5233638681132016545">Új lap</translation>
 <translation id="3846575436967432996">Nem áll rendelkezésre hálózati információ</translation>
 <translation id="3026237328237090306">Mobiladatok beállítása</translation>
 <translation id="785750925697875037">Mobil fiók megtekintése</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Bluetooth letiltása</translation>
 <translation id="3126069444801937830">Indítsa újra a frissítéshez</translation>
 <translation id="735745346212279324">A VPN nincs csatlakoztatva</translation>
+<translation id="7320906967354320621">Tétlen</translation>
 <translation id="6303423059719347535">Az akkumulátor töltöttsége: <ph name="PERCENTAGE"/>%</translation>
+<translation id="2778346081696727092">A hitelesítés nem sikerült a megadott felhasználónévvel vagy jelszóval</translation>
 <translation id="3294437725009624529">Vendég</translation>
 <translation id="8190698733819146287">Nyelvek és beviteli módok személyre szabása...</translation>
-<translation id="598295083618286569">Bluetooth csatlakoztatva</translation>
+<translation id="7170041865419449892">Tartományon kívül</translation>
+<translation id="4804818685124855865">Kapcsolat bontása</translation>
 <translation id="5222676887888702881">Kijelentkezés</translation>
+<translation id="2688477613306174402">Konfiguráció</translation>
+<translation id="1272079795634619415">Leállítás</translation>
 <translation id="4957722034734105353">További információ...</translation>
 <translation id="2964193600955408481">Wi-Fi letiltása</translation>
 <translation id="811680302244032017">Eszköz hozzáadása...</translation>
 <translation id="2509468283778169019">A CAPS LOCK be van kapcsolva</translation>
 <translation id="3892641579809465218">Belső kijelző</translation>
 <translation id="7823564328645135659">A beállítások szinkronizálását követően &quot;<ph name="FROM_LOCALE"/>&quot; nyelvről &quot;<ph name="TO_LOCALE"/>&quot; nyelvre változott a nyelvi beállítás.</translation>
+<translation id="3368922792935385530">Kapcsolódva</translation>
 <translation id="8340999562596018839">Hangos visszajelzés</translation>
 <translation id="8654520615680304441">Wi-Fi bekapcsolása...</translation>
 <translation id="5825747213122829519">A beviteli mód a következőre változott: <ph name="INPUT_METHOD_ID"/>.
 A váltáshoz nyomja meg a Shift + Alt billentyűkódot.</translation>
 <translation id="2562916301614567480">Magánhálózat</translation>
 <translation id="6549021752953852991">Nem érhető el mobilhálózat</translation>
+<translation id="4379753398862151997">Kedves Monitor, mi nem illünk össze. (A monitor nem támogatott.)</translation>
 <translation id="6426039856985689743">Mobiladatok letiltása</translation>
 <translation id="3087734570205094154">Alja</translation>
 <translation id="5271016907025319479">Nincs konfigurálva VPN.</translation>
-<translation id="1298695107722797780">Nyilvános munkamenet\nbefejezése</translation>
-<translation id="3232695630852378748">Bluetooth-beállítások...</translation>
+<translation id="6803622936009808957">A kijelzők tükrözése sikertelen, mivel nem található támogatott felbontás. Ehelyett kiterjesztett asztal módba váltott a rendszer.</translation>
 <translation id="1480041086352807611">Demó üzemmód</translation>
 <translation id="3626637461649818317"><ph name="PERCENTAGE"/>% maradt</translation>
 <translation id="9089416786594320554">Beviteli módszerek</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">Kikapcsolás</translation>
 <translation id="4430019312045809116">Hangerő</translation>
+<translation id="4442424173763614572">A DNS keresése sikertelen</translation>
 <translation id="6356500677799115505">Az akkumulátor teljesen fel van töltve, és töltődik.</translation>
 <translation id="7874779702599364982">Mobilhálózatok keresése...</translation>
+<translation id="583281660410589416">Ismeretlen</translation>
 <translation id="1383876407941801731">Keresés</translation>
+<translation id="7468789844759750875">Látogasson el a(z) <ph name="NAME"/> aktivációs portálra további adatforgalom vásárlásához.</translation>
 <translation id="3901991538546252627">Csatlakozás a következőhöz: <ph name="NAME"/></translation>
 <translation id="2204305834655267233">Hálózatinformáció</translation>
 <translation id="1621499497873603021">Akkumulátor lemerüléséig hátralévő idő: <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">Előző menü</translation>
 <translation id="1346748346194534595">Jobbra</translation>
 <translation id="8528322925433439945">Mobil...</translation>
+<translation id="7049357003967926684">Társaság</translation>
 <translation id="8428213095426709021">Beállítások</translation>
-<translation id="2472320577759310817">A Bluetooth ki van kapcsolva.</translation>
 <translation id="2372145515558759244">Alkalmazások szinkronizálása...</translation>
+<translation id="7256405249507348194">Ismeretlen hiba: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">AAA-ellenőrzés sikertelen</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: kapcsolat bontása...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> a teljes feltöltésig</translation>
 <translation id="5787281376604286451">Hangos visszajelzés engedélyezett.
 A tiltásához nyomja le a Ctrl+Alt+Z billentyűkombinációt.</translation>
 <translation id="4479639480957787382">Ethernet</translation>
+<translation id="6312403991423642364">Ismeretlen hálózati hiba</translation>
 <translation id="1467432559032391204">Balra</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830"><ph name="NAME"/> aktiválása</translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">Teljes méret</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: csatlakozás...</translation>
+<translation id="8639033665604704195">A hitelesítés nem sikerült az előre megosztott kulccsal</translation>
 <translation id="252373100621549798">Ismeretlen kijelző</translation>
 <translation id="1882897271359938046">Tükrözés: <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Zárolás</translation>
 <translation id="2805756323405976993">Programok</translation>
-<translation id="2482878487686419369">Értesítések</translation>
+<translation id="1512064327686280138">Aktiválási hiba</translation>
+<translation id="5097002363526479830">Nem sikerült csatlakozni a(z) <ph name="NAME"/> hálózathoz: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi kikapcsolva.</translation>
-<translation id="2872961005593481000">Leállítás</translation>
+<translation id="8036518327127111261">A hitelesítés nem sikerült a megadott tanúsítvánnyal</translation>
 <translation id="8132793192354020517">Csatlakozás a következőhöz megtörtént: <ph name="NAME"/></translation>
 <translation id="7052914147756339792">Háttérkép beállítása...</translation>
-<translation id="2739500853984626550">Nincs elérhető Bluetooth-eszköz</translation>
-<translation id="2666092431469916601">Felülre</translation>
+<translation id="8678698760965522072">Online</translation>
+<translation id="1119447706177454957">Belső hiba</translation>
 <translation id="3019353588588144572">Akkumulátor teljes feltöltéséig hátralévő idő: <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">Képernyőnagyító</translation>
+<translation id="7005812687360380971">Sikertelen</translation>
 <translation id="1602076796624386989">Mobiladatok engedélyezése</translation>
 <translation id="6981982820502123353">Kisegítő lehetőségek</translation>
 <translation id="3157931365184549694">Visszaállítás</translation>
+<translation id="4274292172790327596">Azonosítatlan hiba</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Eszközök keresése...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Wi-Fi hálózatok keresése...</translation>
+<translation id="7229570126336867161">EVDO szükséges</translation>
 <translation id="2999742336789313416">A(z) <ph name="DISPLAY_NAME"/> egy <ph name="DOMAIN"/> által kezelt nyilvános munkamenet</translation>
 <translation id="7029814467594812963">Kilépés a munkamenetből</translation>
 <translation id="8454013096329229812">Wi-Fi bekapcsolva.</translation>
 <translation id="4872237917498892622">Alt + Keresés vagy Shift</translation>
 <translation id="2983818520079887040">Beállítások...</translation>
-<translation id="5467313780247887226">Nem lehet megjeleníteni a kép másolatát a csatlakoztatott monitorokon. Nem található egyező felbontás.</translation>
+<translation id="8927026611342028580">Csatlakozás kérelmezve</translation>
+<translation id="8300849813060516376">OTASP sikertelen</translation>
 <translation id="2792498699870441125">Alt + Keresés</translation>
 <translation id="8660803626959853127"><ph name="COUNT"/> fájl szinkronizálása</translation>
 <translation id="639644700271529076">A CAPS LOCK ki van kapcsolva</translation>
-<translation id="4101192585425716296">Üzenetközpont</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: aktiválás...</translation>
+<translation id="1391854757121130358">Elképzelhető, hogy mobil adatforgalmi kerete elfogyott.</translation>
 <translation id="4864165860509564259">Pozíció az Indítóban</translation>
 <translation id="7593891976182323525">Keresés vagy Shift</translation>
 <translation id="7649070708921625228">Súgó</translation>
 <translation id="3050422059534974565">A CAPS LOCK be van kapcsolva.
 Kikapcsolásához nyomja meg a Keresés vagy a Shift billentyűt.</translation>
 <translation id="397105322502079400">Számítás…</translation>
+<translation id="158849752021629804">Otthoni hálózat szükséges</translation>
+<translation id="6857811139397017780"><ph name="NETWORKSERVICE"/> aktiválása</translation>
+<translation id="5864471791310927901">DHCP-keresés sikertelen</translation>
+<translation id="6692173217867674490">Rossz összetett jelszó</translation>
 <translation id="6165508094623778733">További információ</translation>
+<translation id="9046895021617826162">Csatlakozás sikertelen</translation>
+<translation id="973896785707726617">A munkamenet <ph name="SESSION_TIME_REMAINING"/> múlva véget ér. Ekkor a rendszer automatikusan kijelentkezteti.</translation>
+<translation id="8372369524088641025">Hibás WEP kulcs</translation>
+<translation id="6636709850131805001">Azonosítatlan állam</translation>
 <translation id="3573179567135747900">Visszatérés ehhez: &quot;<ph name="FROM_LOCALE"/>&quot; (újraindítás szükséges)</translation>
 <translation id="8103386449138765447">SMS-üzenetek: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">A Google Drive beállításai...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">Nincs hálózat</translation>
 <translation id="5941711191222866238">Kicsinyítés</translation>
 <translation id="6911468394164995108">Csatlakozás másik hálózathoz...</translation>
-<translation id="6843725295806269523">némítás</translation>
 <translation id="412065659894267608"><ph name="HOUR"/> ó <ph name="MINUTE"/> p a teljes feltöltésig</translation>
 <translation id="6359806961507272919">SMS innen: <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Szállító</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_id.xtb b/ash/strings/ash_strings_id.xtb
index 5472e22..d7178a8 100644
--- a/ash/strings/ash_strings_id.xtb
+++ b/ash/strings/ash_strings_id.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Baterai penuh</translation>
 <translation id="5250713215130379958">Sembunyikan peluncur secara otomatis</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> dan <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Status portal</translation>
 <translation id="30155388420722288">Tombol Luapan</translation>
 <translation id="5571066253365925590">Bluetooth diaktifkan</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Proxy...</translation>
 <translation id="938582441709398163">Hamparan Keyboard</translation>
 <translation id="6979158407327259162">Google Drive</translation>
+<translation id="6943836128787782965">HTTP gagal</translation>
 <translation id="2297568595583585744">Baki status</translation>
+<translation id="1661867754829461514">PIN hilang</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: Menyambung...</translation>
+<translation id="4237016987259239829">Kesalahan Koneksi Jaringan</translation>
 <translation id="2946640296642327832">Aktifkan Bluetooth</translation>
 <translation id="6459472438155181876">Memperpanjang layar ke <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Seluler</translation>
 <translation id="6596816719288285829">Alamat IP</translation>
+<translation id="4508265954913339219">Aktivasi gagal</translation>
 <translation id="1812696562331527143">Metode masukan Anda telah berubah menjadi <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>pihak ketiga<ph name="END_LINK"/>).
 Tekan Shift + Alt untuk beralih.</translation>
-<translation id="5233638681132016545">Tab baru</translation>
 <translation id="3846575436967432996">Tidak tersedia informasi jaringan</translation>
 <translation id="3026237328237090306">Siapkan data seluler</translation>
 <translation id="785750925697875037">Lihat akun seluler</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Nonaktifkan Bluetooth</translation>
 <translation id="3126069444801937830">Mulai ulang untuk memperbarui</translation>
 <translation id="735745346212279324">VPN terputus</translation>
+<translation id="7320906967354320621">Menganggur</translation>
 <translation id="6303423059719347535">Baterai terisi <ph name="PERCENTAGE"/>%</translation>
+<translation id="2778346081696727092">Gagal mengautentikasi dengan nama pengguna atau sandi yang diberikan</translation>
 <translation id="3294437725009624529">Tamu</translation>
 <translation id="8190698733819146287">Sesuaikan bahasa dan masukan...</translation>
-<translation id="598295083618286569">Bluetooth tersambung</translation>
+<translation id="7170041865419449892">Di luar jangkauan</translation>
+<translation id="4804818685124855865">Putuskan</translation>
 <translation id="5222676887888702881">Keluar</translation>
+<translation id="2688477613306174402">Konfigurasi</translation>
+<translation id="1272079795634619415">Berhenti</translation>
 <translation id="4957722034734105353">Pelajari selengkapnya...</translation>
 <translation id="2964193600955408481">Nonaktifkan Wi-Fi</translation>
 <translation id="811680302244032017">Tambahkan perangkat...</translation>
 <translation id="2509468283778169019">CAPS LOCK aktif</translation>
 <translation id="3892641579809465218">Tampilan Internal</translation>
 <translation id="7823564328645135659">Bahasa telah diubah dari &quot;<ph name="FROM_LOCALE"/>&quot; menjadi &quot;<ph name="TO_LOCALE"/>&quot; setelah menyinkronkan setelan Anda.</translation>
+<translation id="3368922792935385530">Tersambung</translation>
 <translation id="8340999562596018839">Masukan lisan</translation>
 <translation id="8654520615680304441">Aktifkan Wi-Fi...</translation>
 <translation id="5825747213122829519">Metode masukan Anda telah berubah menjadi <ph name="INPUT_METHOD_ID"/>.
 Tekan Shift + Alt untuk beralih.</translation>
 <translation id="2562916301614567480">Jaringan Pribadi</translation>
 <translation id="6549021752953852991">Jaringan seluler tidak tersedia</translation>
+<translation id="4379753398862151997">Monitor, sayang sekali kita tidak bisa bekerja sama. (Monitor tersebut tidak didukung)</translation>
 <translation id="6426039856985689743">Nonaktifkan data seluler</translation>
 <translation id="3087734570205094154">Bawah</translation>
 <translation id="5271016907025319479">VPN belum dikonfigurasi.</translation>
-<translation id="1298695107722797780">Akhiri sesi\npublik</translation>
-<translation id="3232695630852378748">Setelan Bluetooth...</translation>
+<translation id="6803622936009808957">Tidak dapat menggandakan tampilan karena tidak ditemukan resolusi yang didukung. Memasuki desktop yang diperluas sebagai gantinya.</translation>
 <translation id="1480041086352807611">Mode demo</translation>
 <translation id="3626637461649818317">Sisa <ph name="PERCENTAGE"/>%</translation>
 <translation id="9089416786594320554">Metode masukan</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">Mati</translation>
 <translation id="4430019312045809116">Volume</translation>
+<translation id="4442424173763614572">Pencarian DNS gagal</translation>
 <translation id="6356500677799115505">Baterai sudah penuh dan masih mengisi.</translation>
 <translation id="7874779702599364982">Menelusuri jaringan seluler...</translation>
+<translation id="583281660410589416">Tidak diketahui</translation>
 <translation id="1383876407941801731">Penelusuran</translation>
+<translation id="7468789844759750875">Kunjungi portal pengaktifan <ph name="NAME"/> untuk membeli lebih banyak data.</translation>
 <translation id="3901991538546252627">Menyambung ke <ph name="NAME"/></translation>
 <translation id="2204305834655267233">Info Jaringan</translation>
 <translation id="1621499497873603021">Waktu yang tersisa hingga baterai kosong, <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">Menu sebelumnya</translation>
 <translation id="1346748346194534595">Kanan</translation>
 <translation id="8528322925433439945">Seluler ...</translation>
+<translation id="7049357003967926684">Kaitan</translation>
 <translation id="8428213095426709021">Setelan</translation>
-<translation id="2472320577759310817">Bluetooth dinonaktifkan.</translation>
 <translation id="2372145515558759244">Menyinkronkan aplikasi...</translation>
+<translation id="7256405249507348194">Kesalahan tidak dikenal: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">Pemeriksaan AAA gagal</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: Terputus...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>.<ph name="MINUTE"/> hingga penuh</translation>
 <translation id="5787281376604286451">Masukan lisan diaktifkan.
 Tekan Ctrl+Alt+Z untuk menonaktifkan.</translation>
 <translation id="4479639480957787382">Ethernet</translation>
+<translation id="6312403991423642364">Kesalahan jaringan tidak dikenal</translation>
 <translation id="1467432559032391204">Kiri</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830">Mengaktifkan <ph name="NAME"/></translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">Perbesar</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: Menyambung...</translation>
+<translation id="8639033665604704195">Gagal mengautentikasi dengan kunci yang dibagikan sebelumnya</translation>
 <translation id="252373100621549798">Tampilan yang Tidak Diketahui</translation>
 <translation id="1882897271359938046">Mencerminkan ke <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Kunci</translation>
 <translation id="2805756323405976993">Apl</translation>
-<translation id="2482878487686419369">Pemberitahuan</translation>
+<translation id="1512064327686280138">Kegagalan aktivasi</translation>
+<translation id="5097002363526479830">Gagal menyambung ke jaringan '<ph name="NAME"/>': <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi dinonaktifkan.</translation>
-<translation id="2872961005593481000">Matikan</translation>
+<translation id="8036518327127111261">Gagal mengautentikasi dengan sertifikat yang diberikan</translation>
 <translation id="8132793192354020517">Tersambung ke <ph name="NAME"/></translation>
 <translation id="7052914147756339792">Setel wallpaper...</translation>
-<translation id="2739500853984626550">Tidak ada perangkat bluetooth yang tersedia</translation>
-<translation id="2666092431469916601">Atas</translation>
+<translation id="8678698760965522072">Status online</translation>
+<translation id="1119447706177454957">Kesalahan internal</translation>
 <translation id="3019353588588144572">Waktu yang tersisa hingga baterai terisi penuh, <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">Kaca pembesar layar</translation>
+<translation id="7005812687360380971">Kegagalan</translation>
 <translation id="1602076796624386989">Aktifkan data seluler</translation>
 <translation id="6981982820502123353">Aksesibilitas</translation>
 <translation id="3157931365184549694">Kembalikan</translation>
+<translation id="4274292172790327596">Kesalahan tak dikenal</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>.<ph name="MINUTES"/>.<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Memindai perangkat...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Menelusuri jaringan Wi-Fi...</translation>
+<translation id="7229570126336867161">Memerlukan EVDO</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> adalah sesi publik yang dikelola oleh <ph name="DOMAIN"/></translation>
 <translation id="7029814467594812963">Keluar dari sesi</translation>
 <translation id="8454013096329229812">Wi-Fi diaktifkan.</translation>
 <translation id="4872237917498892622">Alt+Telusuri atau Shift</translation>
 <translation id="2983818520079887040">Setelan...</translation>
-<translation id="5467313780247887226">Tidak dapat menggandakan gambar di monitor terlampir. Tidak ditemukan resolusi yang cocok.</translation>
+<translation id="8927026611342028580">Sambungan Diminta</translation>
+<translation id="8300849813060516376">OTASP gagal</translation>
 <translation id="2792498699870441125">Alt+Telusuri</translation>
 <translation id="8660803626959853127">Menyinkronkan <ph name="COUNT"/> file</translation>
 <translation id="639644700271529076">CAPS LOCK tidak aktif</translation>
-<translation id="4101192585425716296">Pusat Pesan</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: Mengaktifkan...</translation>
+<translation id="1391854757121130358">Anda mungkin telah menghabiskan jatah data seluler.</translation>
 <translation id="4864165860509564259">Posisi peluncur</translation>
 <translation id="7593891976182323525">Telusuri atau Shift</translation>
 <translation id="7649070708921625228">Bantuan</translation>
 <translation id="3050422059534974565">CAPS LOCK aktif.
 Tekan Telusuri atau Shift untuk membatalkan.</translation>
 <translation id="397105322502079400">Menghitung...</translation>
+<translation id="158849752021629804">Memerlukan jaringan rumah</translation>
+<translation id="6857811139397017780">Aktifkan <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">Pencarian DHCP gagal</translation>
+<translation id="6692173217867674490">Frasa sandi yang buruk</translation>
 <translation id="6165508094623778733">Pelajari lebih lanjut</translation>
+<translation id="9046895021617826162">Gagal menyambung</translation>
+<translation id="973896785707726617">Sesi ini akan berakhir dalam <ph name="SESSION_TIME_REMAINING"/>. Anda akan otomatis dikeluarkan.</translation>
+<translation id="8372369524088641025">Kunci WEP yang buruk</translation>
+<translation id="6636709850131805001">Keadaan yang tidak dikenal</translation>
 <translation id="3573179567135747900">Ubah kembali ke &quot;<ph name="FROM_LOCALE"/>&quot; (harus dinyalakan ulang)</translation>
 <translation id="8103386449138765447">Pesan SMS: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Setelan Google Drive...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">Tidak ada jaringan</translation>
 <translation id="5941711191222866238">Perkecil</translation>
 <translation id="6911468394164995108">Bergabung dengan lainnya...</translation>
-<translation id="6843725295806269523">bisukan</translation>
 <translation id="412065659894267608"><ph name="HOUR"/>j <ph name="MINUTE"/>m sampai penuh</translation>
 <translation id="6359806961507272919">SMS dari <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Operator</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_it.xtb b/ash/strings/ash_strings_it.xtb
index 0eb4459..0f95411 100644
--- a/ash/strings/ash_strings_it.xtb
+++ b/ash/strings/ash_strings_it.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Batteria carica</translation>
 <translation id="5250713215130379958">Nascondi automaticamente Avvio applicazioni</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> e <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Stato portale</translation>
 <translation id="30155388420722288">Pulsante Overflow</translation>
 <translation id="5571066253365925590">Bluetooth attivo</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Proxy...</translation>
 <translation id="938582441709398163">Overlay tastiera</translation>
 <translation id="6979158407327259162">Google Drive</translation>
+<translation id="6943836128787782965">Recupero HTTP non riuscito</translation>
 <translation id="2297568595583585744">Barra di stato</translation>
+<translation id="1661867754829461514">PIN mancante</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: connessione...</translation>
+<translation id="4237016987259239829">Errore di connessione di rete</translation>
 <translation id="2946640296642327832">Attiva Bluetooth</translation>
 <translation id="6459472438155181876">Estensione dello schermo su <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Cellulare</translation>
 <translation id="6596816719288285829">Indirizzo IP</translation>
+<translation id="4508265954913339219">Attivazione non riuscita</translation>
 <translation id="1812696562331527143">Il metodo di immissione è stato cambiato in <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>3a parte<ph name="END_LINK"/>).
 Premi Maiusc+Alt per cambiare metodo.</translation>
-<translation id="5233638681132016545">Nuova scheda</translation>
 <translation id="3846575436967432996">Nessuna informazione di rete disponibile</translation>
 <translation id="3026237328237090306">Configura dati mobili</translation>
 <translation id="785750925697875037">Visualizza account per cellulari</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Disattiva Bluetooth</translation>
 <translation id="3126069444801937830">Riavvia per aggiornare</translation>
 <translation id="735745346212279324">VPN scollegata</translation>
+<translation id="7320906967354320621">In pausa</translation>
 <translation id="6303423059719347535">La batteria è carica al <ph name="PERCENTAGE"/>%</translation>
+<translation id="2778346081696727092">Autenticazione non riuscita con il nome utente o la password forniti</translation>
 <translation id="3294437725009624529">Ospite</translation>
 <translation id="8190698733819146287">Personalizza lingue e immissione...</translation>
-<translation id="598295083618286569">Bluetooth collegato</translation>
+<translation id="7170041865419449892">Fuori dal raggio d'azione</translation>
+<translation id="4804818685124855865">Disconnetti</translation>
 <translation id="5222676887888702881">Esci</translation>
+<translation id="2688477613306174402">Configurazione</translation>
+<translation id="1272079795634619415">Interrompi</translation>
 <translation id="4957722034734105353">Ulteriori informazioni...</translation>
 <translation id="2964193600955408481">Disattiva Wi-Fi</translation>
 <translation id="811680302244032017">Aggiungi dispositivo...</translation>
 <translation id="2509468283778169019">BLOC MAIUSC è attivo</translation>
 <translation id="3892641579809465218">Display interno</translation>
 <translation id="7823564328645135659">La lingua è stata modificata da &quot;<ph name="FROM_LOCALE"/>&quot; a &quot;<ph name="TO_LOCALE"/>&quot; dopo la sincronizzazione delle impostazioni.</translation>
+<translation id="3368922792935385530">Connessa</translation>
 <translation id="8340999562596018839">Feedback vocale</translation>
 <translation id="8654520615680304441">Attiva Wi-Fi...</translation>
 <translation id="5825747213122829519">Il metodo di immissione è stato cambiato in <ph name="INPUT_METHOD_ID"/>.
 Premi Maiusc+Alt per cambiare metodo.</translation>
 <translation id="2562916301614567480">Rete privata</translation>
 <translation id="6549021752953852991">Nessuna rete cellulare disponibile</translation>
+<translation id="4379753398862151997">Caro monitor, non funziona tra di noi (il monitor non è supportato).</translation>
 <translation id="6426039856985689743">Disattiva dati mobili</translation>
 <translation id="3087734570205094154">In basso</translation>
 <translation id="5271016907025319479">VPN non configurata.</translation>
-<translation id="1298695107722797780">Termina sessione\npubblica</translation>
-<translation id="3232695630852378748">Impostazioni Bluetooth...</translation>
+<translation id="6803622936009808957">Impossibile duplicare i display perché non sono state trovate risoluzioni supportate. È stato attivato il desktop esteso.</translation>
 <translation id="1480041086352807611">Modalità Demo</translation>
 <translation id="3626637461649818317"><ph name="PERCENTAGE"/>% rimanente</translation>
 <translation id="9089416786594320554">Metodi di immissione</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">Chiusura</translation>
 <translation id="4430019312045809116">Volume</translation>
+<translation id="4442424173763614572">Ricerca DNS non riuscita</translation>
 <translation id="6356500677799115505">La batteria è carica e in ricarica.</translation>
 <translation id="7874779702599364982">Ricerca reti cellulari...</translation>
+<translation id="583281660410589416">Sconosciuto</translation>
 <translation id="1383876407941801731">Ricerca</translation>
+<translation id="7468789844759750875">Visita il portale di attivazione <ph name="NAME"/> per acquistare altri dati.</translation>
 <translation id="3901991538546252627">Connessione a: <ph name="NAME"/></translation>
 <translation id="2204305834655267233">Informazioni di rete</translation>
 <translation id="1621499497873603021">Tempo rimanente all'esaurimento della batteria: <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">Menu precedente</translation>
 <translation id="1346748346194534595">Destra</translation>
 <translation id="8528322925433439945">Reti mobili...</translation>
+<translation id="7049357003967926684">Associazione</translation>
 <translation id="8428213095426709021">Impostazioni</translation>
-<translation id="2472320577759310817">Bluetooth disattivato.</translation>
 <translation id="2372145515558759244">Sincronizzazione applicazioni...</translation>
+<translation id="7256405249507348194">Errore non riconosciuto: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">Controllo AAA non riuscito</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: disconnessione...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> rimanenti al completamento della ricarica</translation>
 <translation id="5787281376604286451">Feedback vocale attivato.
 Premi Ctrl+Alt+Z per disattivarlo.</translation>
 <translation id="4479639480957787382">Ethernet</translation>
+<translation id="6312403991423642364">Errore di rete sconosciuto</translation>
 <translation id="1467432559032391204">Sinistra</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830">Attivazione di <ph name="NAME"/></translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">Ingrandisci</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: connessione...</translation>
+<translation id="8639033665604704195">Autenticazione non riuscita con la chiave precondivisa fornita</translation>
 <translation id="252373100621549798">Display sconosciuto</translation>
 <translation id="1882897271359938046">Mirroring su <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Blocca</translation>
 <translation id="2805756323405976993">Applicazioni</translation>
-<translation id="2482878487686419369">Notifiche</translation>
+<translation id="1512064327686280138">Errore di attivazione</translation>
+<translation id="5097002363526479830">Connessione alla rete &quot;<ph name="NAME"/>&quot; non riuscita: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi non attivo.</translation>
-<translation id="2872961005593481000">Spegni</translation>
+<translation id="8036518327127111261">Autenticazione non riuscita con il certificato fornito</translation>
 <translation id="8132793192354020517">Connesso a <ph name="NAME"/></translation>
 <translation id="7052914147756339792">Imposta sfondo...</translation>
-<translation id="2739500853984626550">Nessun dispositivo Bluetooth disponibile</translation>
-<translation id="2666092431469916601">In alto</translation>
+<translation id="8678698760965522072">Stato online</translation>
+<translation id="1119447706177454957">Errore interno</translation>
 <translation id="3019353588588144572">Tempo rimanente al caricamento completo della batteria: <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">Ingrandimento dello schermo</translation>
+<translation id="7005812687360380971">Errore</translation>
 <translation id="1602076796624386989">Attiva dati mobili</translation>
 <translation id="6981982820502123353">Accessibilità</translation>
 <translation id="3157931365184549694">Ripristina</translation>
+<translation id="4274292172790327596">Errore non riconosciuto</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Ricerca dispositivi in corso...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Ricerca di reti Wi-Fi in corso...</translation>
+<translation id="7229570126336867161">Occorre EVDO</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> è una sessione pubblica gestita da <ph name="DOMAIN"/></translation>
 <translation id="7029814467594812963">Esci da sessione</translation>
 <translation id="8454013096329229812">Wi-Fi attivo.</translation>
 <translation id="4872237917498892622">Alt+tasto per la ricerca o Maiusc</translation>
 <translation id="2983818520079887040">Impostazioni...</translation>
-<translation id="5467313780247887226">Impossibile duplicare l'immagine su monitor collegati. Nessuna risoluzione corrispondente trovata.</translation>
+<translation id="8927026611342028580">Connessione richiesta</translation>
+<translation id="8300849813060516376">OTASP non riuscito</translation>
 <translation id="2792498699870441125">Alt+tasto per la ricerca</translation>
 <translation id="8660803626959853127">Sincronizzazione di <ph name="COUNT"/> file in corso</translation>
 <translation id="639644700271529076">Funzione BLOC MAIUSC non attiva</translation>
-<translation id="4101192585425716296">Centro messaggi</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: attivazione in corso...</translation>
+<translation id="1391854757121130358">Potresti avere esaurito la tua quota di dati mobili.</translation>
 <translation id="4864165860509564259">Posizione Avvio applicazioni</translation>
 <translation id="7593891976182323525">Tasto per la ricerca o Maiusc</translation>
 <translation id="7649070708921625228">Guida</translation>
 <translation id="3050422059534974565">La funzione BLOC MAIUSC è attiva.
 Premi il tasto per la ricerca o Maiusc per annullare.</translation>
 <translation id="397105322502079400">Calcolo in corso...</translation>
+<translation id="158849752021629804">Occorre una rete domestica</translation>
+<translation id="6857811139397017780">Attiva <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">Ricerca DHCP non riuscita</translation>
+<translation id="6692173217867674490">Passphrase non valida</translation>
 <translation id="6165508094623778733">Ulteriori informazioni</translation>
+<translation id="9046895021617826162">Connessione non riuscita</translation>
+<translation id="973896785707726617">Questa sessione terminerà fra <ph name="SESSION_TIME_REMAINING"/>. Verrà eseguita automaticamente la disconnessione.</translation>
+<translation id="8372369524088641025">Chiave WEP non valida</translation>
+<translation id="6636709850131805001">Stato non riconosciuto</translation>
 <translation id="3573179567135747900">Torna a &quot;<ph name="FROM_LOCALE"/>&quot; (è necessario riavviare)</translation>
 <translation id="8103386449138765447">Messaggi SMS: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Impostazioni Google Drive...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">Nessuna rete</translation>
 <translation id="5941711191222866238">Riduci a icona</translation>
 <translation id="6911468394164995108">Connetti a un'altra...</translation>
-<translation id="6843725295806269523">disattiva audio</translation>
 <translation id="412065659894267608"><ph name="HOUR"/> ore e <ph name="MINUTE"/> min rimanenti al completamento della ricarica</translation>
 <translation id="6359806961507272919">SMS da <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Gestore</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_iw.xtb b/ash/strings/ash_strings_iw.xtb
index 3348ce7..be318ef 100644
--- a/ash/strings/ash_strings_iw.xtb
+++ b/ash/strings/ash_strings_iw.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">סוללה מלאה</translation>
 <translation id="5250713215130379958">הסתר אוטומטית את המפעיל</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> ו-<ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">מצב הפורטל</translation>
 <translation id="30155388420722288">לחצן גלישה</translation>
 <translation id="5571066253365925590">Bluetooth מופעל</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">שרת proxy...</translation>
 <translation id="938582441709398163">שכבת על של מקלדת</translation>
 <translation id="6979158407327259162">Google Drive</translation>
+<translation id="6943836128787782965">פעולת get של HTTP נכשלה</translation>
 <translation id="2297568595583585744">מגש סטטוס</translation>
+<translation id="1661867754829461514">חסר PIN</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: מתחבר...</translation>
+<translation id="4237016987259239829">שגיאת חיבור רשת</translation>
 <translation id="2946640296642327832">הפעל Bluetooth</translation>
 <translation id="6459472438155181876">מרחיב את המסך אל <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">סלולארי</translation>
 <translation id="6596816719288285829">כתובת IP</translation>
+<translation id="4508265954913339219">ההפעלה נכשלה</translation>
 <translation id="1812696562331527143">שיטת הקלט שלך השתנתה ל-‏<ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>צד שלישי<ph name="END_LINK"/>)‎.
         הקש Shift + Alt כדי להחליף.</translation>
-<translation id="5233638681132016545">כרטיסייה חדשה</translation>
 <translation id="3846575436967432996">אין מידע רשת זמין</translation>
 <translation id="3026237328237090306">הגדר נתונים לנייד</translation>
 <translation id="785750925697875037">הצג את חשבון הנייד</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">השבת Bluetooth</translation>
 <translation id="3126069444801937830">הפעל מחדש כדי לעדכן</translation>
 <translation id="735745346212279324">VPN מנותק</translation>
+<translation id="7320906967354320621">לא פעילה</translation>
 <translation id="6303423059719347535">הסוללה טעונה ב-‎<ph name="PERCENTAGE"/>%‎</translation>
+<translation id="2778346081696727092">האימות נכשל עם שם המשתמש או הסיסמה שסופקו</translation>
 <translation id="3294437725009624529">אורח</translation>
 <translation id="8190698733819146287">התאם אישית שפה וקלט...</translation>
-<translation id="598295083618286569">Bluetooth מחובר</translation>
+<translation id="7170041865419449892">מחוץ לטווח</translation>
+<translation id="4804818685124855865">נתק</translation>
 <translation id="5222676887888702881">יציאה</translation>
+<translation id="2688477613306174402">תצורה</translation>
+<translation id="1272079795634619415">הפסק</translation>
 <translation id="4957722034734105353">למידע נוסף...</translation>
 <translation id="2964193600955408481">השבת Wi-Fi</translation>
 <translation id="811680302244032017">הוסף את המכשיר...</translation>
 <translation id="2509468283778169019">CAPS LOCK מופעל</translation>
 <translation id="3892641579809465218">תצוגה פנימית</translation>
 <translation id="7823564328645135659">שפת Chrome השתנתה מ&quot;<ph name="FROM_LOCALE"/>&quot; ל&quot;<ph name="TO_LOCALE"/>&quot; לאחר סנכרון ההגדרות.</translation>
+<translation id="3368922792935385530">מחובר</translation>
 <translation id="8340999562596018839">משוב קולי</translation>
 <translation id="8654520615680304441">הפעל את ה-Wi-Fi...</translation>
 <translation id="5825747213122829519">שיטת הקלט שלך השתנתה ל-<ph name="INPUT_METHOD_ID"/>.
         הקש Shift + Alt כדי להחליף.</translation>
 <translation id="2562916301614567480">רשת פרטית</translation>
 <translation id="6549021752953852991">אין רשת סלולרית זמינה</translation>
+<translation id="4379753398862151997">צג יקר, זה לא עובד בינינו. (הצג אינו נתמך)</translation>
 <translation id="6426039856985689743">השבת נתונים לנייד</translation>
 <translation id="3087734570205094154">תחתית</translation>
 <translation id="5271016907025319479">לא הוגדר VPN.</translation>
-<translation id="1298695107722797780">סיים פעילות\nציבורית</translation>
-<translation id="3232695630852378748">הגדרות Bluetooth...</translation>
+<translation id="6803622936009808957">לא ניתן היה לשקף מסכים מכיוון שלא נמצאה רזולוציה נתמכת. במקום זאת התצוגה עברה למצב שולחן עבודה מורחב.</translation>
 <translation id="1480041086352807611">מצב הדגמה</translation>
 <translation id="3626637461649818317"><ph name="PERCENTAGE"/>%‎ נותרו</translation>
 <translation id="9089416786594320554">שיטות קלט</translation>
 <translation id="6247708409970142803">%<ph name="PERCENTAGE"/></translation>
 <translation id="1895658205118569222">כיבוי</translation>
 <translation id="4430019312045809116">עוצמת קול</translation>
+<translation id="4442424173763614572">חיפוש ה-DNS נכשל</translation>
 <translation id="6356500677799115505">הסוללה מלאה ובטעינה.</translation>
 <translation id="7874779702599364982">מחפש רשתות סלולריות...</translation>
+<translation id="583281660410589416">לא ידוע</translation>
 <translation id="1383876407941801731">חיפוש</translation>
+<translation id="7468789844759750875">בקר בפורטל ההפעלה של <ph name="NAME"/> כדי לקנות עוד נתונים.</translation>
 <translation id="3901991538546252627">מתחבר אל: <ph name="NAME"/></translation>
 <translation id="2204305834655267233">פרטי רשת</translation>
 <translation id="1621499497873603021">הזמן שנותר עד להתרוקנות הסוללה, <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">התפריט הקודם</translation>
 <translation id="1346748346194534595">ימינה</translation>
 <translation id="8528322925433439945">נייד ...</translation>
+<translation id="7049357003967926684">שיוך</translation>
 <translation id="8428213095426709021">הגדרות</translation>
-<translation id="2472320577759310817">ה-Bluetooth כבוי.</translation>
 <translation id="2372145515558759244">מסנכרן יישומים...</translation>
+<translation id="7256405249507348194">שגיאה לא מזוהה: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">בדיקת AAA נכשלה</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: מתנתק...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> עד שמתמלא</translation>
 <translation id="5787281376604286451">משוב קולי מופעל.
 הקש Ctrl+Alt+Z כדי להשבית אותו.</translation>
 <translation id="4479639480957787382">אתרנט</translation>
+<translation id="6312403991423642364">שגיאת רשת לא ידועה</translation>
 <translation id="1467432559032391204">שמאלה</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830">מפעיל את <ph name="NAME"/></translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">הגדל</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: מתחבר...</translation>
+<translation id="8639033665604704195">האימות נכשל עם המפתח המשותף מראש שסופק</translation>
 <translation id="252373100621549798">תצוגה לא ידועה</translation>
 <translation id="1882897271359938046">משקף אל <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">נעילה</translation>
 <translation id="2805756323405976993">יישומים</translation>
-<translation id="2482878487686419369">התראות</translation>
+<translation id="1512064327686280138">כשל בהפעלה</translation>
+<translation id="5097002363526479830">ההתחברות לרשת נכשלה '<ph name="NAME"/>': <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi כבוי.</translation>
-<translation id="2872961005593481000">כיבוי</translation>
+<translation id="8036518327127111261">האימות נכשל עם האישור שסופק</translation>
 <translation id="8132793192354020517">מחובר ל<ph name="NAME"/></translation>
 <translation id="7052914147756339792">הגדר טפט...</translation>
-<translation id="2739500853984626550">אין מכשירי Bluetooth זמינים</translation>
-<translation id="2666092431469916601">למעלה</translation>
+<translation id="8678698760965522072">מצב מקוון</translation>
+<translation id="1119447706177454957">שגיאה פנימית</translation>
 <translation id="3019353588588144572">הזמן שנותר עד לטעינה מלאה של הסוללה, <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">מגדיל התצוגה</translation>
+<translation id="7005812687360380971">כשל</translation>
 <translation id="1602076796624386989">הפעל נתונים לנייד</translation>
 <translation id="6981982820502123353">נגישות</translation>
 <translation id="3157931365184549694">שחזר</translation>
+<translation id="4274292172790327596">שגיאה לא מזוהה</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">סורק לאיתור מכשירים...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">מחפש רשתות Wi-Fi...</translation>
+<translation id="7229570126336867161">יש צורך ב-EVDO</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> היא הפעלה ציבורית המנוהלת על ידי <ph name="DOMAIN"/></translation>
 <translation id="7029814467594812963">צא מההפעלה</translation>
 <translation id="8454013096329229812">Wi-Fi מופעל.</translation>
 <translation id="4872237917498892622">Alt + חיפוש או Shift</translation>
 <translation id="2983818520079887040">הגדרות...</translation>
-<translation id="5467313780247887226">לא ניתן לשכפל את התמונה בצגים המצורפים. לא נמצאה רזולוציה מתאימה.</translation>
+<translation id="8927026611342028580">נשלחה בקשה לחיבור</translation>
+<translation id="8300849813060516376">OTASP נכשל</translation>
 <translation id="2792498699870441125">Alt + חיפוש</translation>
 <translation id="8660803626959853127">מסנכרן <ph name="COUNT"/> קבצים</translation>
 <translation id="639644700271529076">CAPS LOCK כבוי</translation>
-<translation id="4101192585425716296">מרכז הודעות</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: מפעיל...</translation>
+<translation id="1391854757121130358">ייתכן שכבר השתמשת בכל הקצבת הנתונים לנייד.</translation>
 <translation id="4864165860509564259">מיקום המפעיל</translation>
 <translation id="7593891976182323525">חיפוש או Shift</translation>
 <translation id="7649070708921625228">עזרה</translation>
 <translation id="3050422059534974565">CAPS LOCK פועל.
 הקש על 'חיפוש' או על Shift כדי לבטל.</translation>
 <translation id="397105322502079400">מחשב...</translation>
+<translation id="158849752021629804">יש צורך ברשת ביתית</translation>
+<translation id="6857811139397017780">הפעל את <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">חיפוש DHCP נכשל</translation>
+<translation id="6692173217867674490">משפט-סיסמה גרוע</translation>
 <translation id="6165508094623778733">למידע נוסף</translation>
+<translation id="9046895021617826162">החיבור נכשל</translation>
+<translation id="973896785707726617">הפעילות הזו באתר תסתיים בעוד <ph name="SESSION_TIME_REMAINING"/>. תנותק אוטומטית.</translation>
+<translation id="8372369524088641025">מקש WEP גרוע</translation>
+<translation id="6636709850131805001">מצב לא מזוהה</translation>
 <translation id="3573179567135747900">שנה בחזרה ל&quot;<ph name="FROM_LOCALE"/>&quot; (דורש הפעלה מחדש)</translation>
 <translation id="8103386449138765447">הודעות SMS‏: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">הגדרות Google Drive...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">אין רשת</translation>
 <translation id="5941711191222866238">מזער</translation>
 <translation id="6911468394164995108">הצטרף לרשת אחרת...</translation>
-<translation id="6843725295806269523">השתק</translation>
 <translation id="412065659894267608"><ph name="HOUR"/> שעות ו-<ph name="MINUTE"/> דקות עד לטעינה מלאה</translation>
 <translation id="6359806961507272919">SMS מאת <ph name="PHONE_NUMBER"/> </translation>
+<translation id="1244147615850840081">ספק</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_ja.xtb b/ash/strings/ash_strings_ja.xtb
index 7333e65..8c8a306 100644
--- a/ash/strings/ash_strings_ja.xtb
+++ b/ash/strings/ash_strings_ja.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">バッテリー残量: 満</translation>
 <translation id="5250713215130379958">ランチャーを自動的に隠す</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">ポータル状態</translation>
 <translation id="30155388420722288">オーバーフロー ボタン</translation>
 <translation id="5571066253365925590">Bluetooth オン</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">プロキシ...</translation>
 <translation id="938582441709398163">キーボード オーバーレイ</translation>
 <translation id="6979158407327259162">Google ドライブ</translation>
+<translation id="6943836128787782965">HTTP を取得できませんでした</translation>
 <translation id="2297568595583585744">ステータス トレイ</translation>
+<translation id="1661867754829461514">PIN がありません</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: 接続しています...</translation>
+<translation id="4237016987259239829">ネットワーク接続エラー</translation>
 <translation id="2946640296642327832">Bluetooth を有効にする</translation>
 <translation id="6459472438155181876"><ph name="DISPLAY_NAME"/> へ画面を拡張しています</translation>
 <translation id="8206859287963243715">携帯電話</translation>
 <translation id="6596816719288285829">IP アドレス</translation>
+<translation id="4508265954913339219">起動に失敗しました</translation>
 <translation id="1812696562331527143">入力方法を <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>サードパーティ<ph name="END_LINK"/>)に変更しました。
 切り替えるには Shift+Alt キーを押します。</translation>
-<translation id="5233638681132016545">新しいタブ</translation>
 <translation id="3846575436967432996">利用可能なネットワーク情報がありません</translation>
 <translation id="3026237328237090306">モバイル データをセットアップ</translation>
 <translation id="785750925697875037">モバイル アカウントを表示</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Bluetooth を無効にする</translation>
 <translation id="3126069444801937830">再起動して更新</translation>
 <translation id="735745346212279324">VPN が切断されました</translation>
+<translation id="7320906967354320621">待機中</translation>
 <translation id="6303423059719347535">バッテリー残量: <ph name="PERCENTAGE"/>%</translation>
+<translation id="2778346081696727092">入力されたユーザー名またはパスワードで認証できませんでした</translation>
 <translation id="3294437725009624529">ゲスト</translation>
 <translation id="8190698733819146287">言語と入力方法をカスタマイズ...</translation>
-<translation id="598295083618286569">Bluetooth に接続済み</translation>
+<translation id="7170041865419449892">圏外</translation>
+<translation id="4804818685124855865">切断</translation>
 <translation id="5222676887888702881">ログアウト</translation>
+<translation id="2688477613306174402">設定</translation>
+<translation id="1272079795634619415">中止</translation>
 <translation id="4957722034734105353">詳細...</translation>
 <translation id="2964193600955408481">Wi-Fi を無効にする</translation>
 <translation id="811680302244032017">デバイスを追加...</translation>
 <translation id="2509468283778169019">Caps Lock がオンになっています</translation>
 <translation id="3892641579809465218">内蔵ディスプレイ</translation>
 <translation id="7823564328645135659">設定の同期後に言語が「<ph name="FROM_LOCALE"/>」から「<ph name="TO_LOCALE"/>」に変更されました。</translation>
+<translation id="3368922792935385530">接続済み</translation>
 <translation id="8340999562596018839">音声フィードバック</translation>
 <translation id="8654520615680304441">Wi-Fi をオンにしています...</translation>
 <translation id="5825747213122829519">入力方法を <ph name="INPUT_METHOD_ID"/> に変更しました。
 切り替えるには Shift+Alt キーを押します。</translation>
 <translation id="2562916301614567480">プライベート ネットワーク</translation>
 <translation id="6549021752953852991">利用可能なセルラー ネットワークがありません</translation>
+<translation id="4379753398862151997">Dear Monitor, it's not working out between us.(このモニターはサポートされていません)</translation>
 <translation id="6426039856985689743">モバイル データを無効にする</translation>
 <translation id="3087734570205094154">一番下</translation>
 <translation id="5271016907025319479">VPN が設定されていません。</translation>
-<translation id="1298695107722797780">公開セッションを\n終了</translation>
-<translation id="3232695630852378748">Bluetooth の設定...</translation>
+<translation id="6803622936009808957">サポートされている解像度が見つからなかったため、ディスプレイをミラーリングできませんでした。代わりに拡張デスクトップ モードに切り替えました。</translation>
 <translation id="1480041086352807611">デモ モード</translation>
 <translation id="3626637461649818317">残り <ph name="PERCENTAGE"/>%</translation>
 <translation id="9089416786594320554">入力方法</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">シャットダウン</translation>
 <translation id="4430019312045809116">音量</translation>
+<translation id="4442424173763614572">DNS を検索できませんでした</translation>
 <translation id="6356500677799115505">バッテリー残量: 満、充電しています。</translation>
 <translation id="7874779702599364982">携帯電話ネットワークを検索しています...</translation>
+<translation id="583281660410589416">不明</translation>
 <translation id="1383876407941801731">検索</translation>
+<translation id="7468789844759750875">データを追加購入するには、<ph name="NAME"/> の有効化ポータルにアクセスしてください。</translation>
 <translation id="3901991538546252627"><ph name="NAME"/> に接続しています</translation>
 <translation id="2204305834655267233">ネットワーク情報</translation>
 <translation id="1621499497873603021">バッテリーが空になるまであと: <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">前のメニュー</translation>
 <translation id="1346748346194534595">右</translation>
 <translation id="8528322925433439945">モバイル...</translation>
+<translation id="7049357003967926684">アソシエーション</translation>
 <translation id="8428213095426709021">設定</translation>
-<translation id="2472320577759310817">Bluetooth が無効です。</translation>
 <translation id="2372145515558759244">アプリの同期...</translation>
+<translation id="7256405249507348194">不明なエラー: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">AAA を確認できませんでした</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: 切断しています...</translation>
 <translation id="8456362689280298700">フル充電まで <ph name="HOUR"/> 時間 <ph name="MINUTE"/> 分</translation>
 <translation id="5787281376604286451">音声フィードバックが有効です。
 無効にするには Ctrl+Alt+Z を押してください。</translation>
 <translation id="4479639480957787382">イーサネット</translation>
+<translation id="6312403991423642364">ネットワークが不明なためエラーが発生しました</translation>
 <translation id="1467432559032391204">左</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830"><ph name="NAME"/> を有効にしています</translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">最大化</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: 接続しています...</translation>
+<translation id="8639033665604704195">提示された事前共有キーで認証できませんでした</translation>
 <translation id="252373100621549798">不明なディスプレイ</translation>
 <translation id="1882897271359938046"><ph name="DISPLAY_NAME"/> へミラーリング</translation>
 <translation id="3784455785234192852">ロック</translation>
 <translation id="2805756323405976993">アプリ</translation>
-<translation id="2482878487686419369">通知</translation>
+<translation id="1512064327686280138">起動失敗</translation>
+<translation id="5097002363526479830">ネットワーク「<ph name="NAME"/>」に接続できませんでした: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi が無効になりました。</translation>
-<translation id="2872961005593481000">終了</translation>
+<translation id="8036518327127111261">提示された証明書で認証できませんでした</translation>
 <translation id="8132793192354020517"><ph name="NAME"/> に接続しました</translation>
 <translation id="7052914147756339792">壁紙を設定...</translation>
-<translation id="2739500853984626550">使用できる Bluetooth デバイスはありません</translation>
-<translation id="2666092431469916601">一番上</translation>
+<translation id="8678698760965522072">オンライン状態</translation>
+<translation id="1119447706177454957">内部エラー</translation>
 <translation id="3019353588588144572">バッテリーがフル充電されるまであと: <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">画面拡大鏡</translation>
+<translation id="7005812687360380971">失敗</translation>
 <translation id="1602076796624386989">モバイル データを有効にする</translation>
 <translation id="6981982820502123353">アクセシビリティ</translation>
 <translation id="3157931365184549694">復元</translation>
+<translation id="4274292172790327596">不明なエラー</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">デバイスをスキャンしています...</translation>
-<translation id="5597451508971090205"><ph name="DATE"/>、<ph name="SHORT_WEEKDAY"/></translation>
+<translation id="5597451508971090205"><ph name="DATE"/> (<ph name="SHORT_WEEKDAY"/>)</translation>
 <translation id="4448844063988177157">Wi-Fi ネットワークを検出しています...</translation>
+<translation id="7229570126336867161">EVDO が必要です</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> は <ph name="DOMAIN"/> が管理する公開セッションです</translation>
 <translation id="7029814467594812963">セッションを終了</translation>
 <translation id="8454013096329229812">Wi-Fi が有効になりました。</translation>
 <translation id="4872237917498892622">Alt+ 検索/Shift</translation>
 <translation id="2983818520079887040">設定...</translation>
-<translation id="5467313780247887226">接続されているモニターでは画像を複製できません。対応する解像度が見つかりませんでした。</translation>
+<translation id="8927026611342028580">接続をリクエスト済み</translation>
+<translation id="8300849813060516376">OTASP に失敗しました</translation>
 <translation id="2792498699870441125">Alt+ 検索</translation>
 <translation id="8660803626959853127"><ph name="COUNT"/> 個のファイルを同期中</translation>
 <translation id="639644700271529076">CapsLock 機能はオフになっています</translation>
-<translation id="4101192585425716296">メッセージ センター</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: 有効にしています...</translation>
+<translation id="1391854757121130358">モバイル データの使用量上限に達した可能性があります。</translation>
 <translation id="4864165860509564259">ランチャーの位置</translation>
 <translation id="7593891976182323525">検索/Shift</translation>
 <translation id="7649070708921625228">ヘルプ</translation>
 <translation id="3050422059534974565">CapsLock がオンになっています。
 検索/Shift キーを押すと解除されます。</translation>
 <translation id="397105322502079400">計算しています...</translation>
+<translation id="158849752021629804">ホーム ネットワークが必要です</translation>
+<translation id="6857811139397017780"><ph name="NETWORKSERVICE"/> を有効にする</translation>
+<translation id="5864471791310927901">DHCP を検索できませんでした</translation>
+<translation id="6692173217867674490">パスフレーズが正しくありません</translation>
 <translation id="6165508094623778733">詳しく見る</translation>
+<translation id="9046895021617826162">接続に失敗しました</translation>
+<translation id="973896785707726617">このセッションはあと <ph name="SESSION_TIME_REMAINING"/>で終了します。終了すると、自動的にログアウトします。</translation>
+<translation id="8372369524088641025">WEP キーが正しくありません</translation>
+<translation id="6636709850131805001">不明な状態</translation>
 <translation id="3573179567135747900">「<ph name="FROM_LOCALE"/>」に戻します(再起動が必要です)</translation>
 <translation id="8103386449138765447">SMS メッセージ: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Google ドライブの設定...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">ネットワーク接続なし</translation>
 <translation id="5941711191222866238">最小化</translation>
 <translation id="6911468394164995108">他のネットワークに接続...</translation>
-<translation id="6843725295806269523">ミュート</translation>
 <translation id="412065659894267608">フル充電まで <ph name="HOUR"/> 時間 <ph name="MINUTE"/> 分</translation>
 <translation id="6359806961507272919"><ph name="PHONE_NUMBER"/> の SMS</translation>
+<translation id="1244147615850840081">通信会社</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_kn.xtb b/ash/strings/ash_strings_kn.xtb
index f7d277d..7be79ae 100644
--- a/ash/strings/ash_strings_kn.xtb
+++ b/ash/strings/ash_strings_kn.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">ಬ್ಯಾಟರಿ ಪೂರ್ಣವಾಗಿದೆ</translation>
 <translation id="5250713215130379958">ಲಾಂಚರ್ ಅನ್ನು ಸ್ವಯಂಮರೆಮಾಡಿ</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> ಮತ್ತು <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">ಪೋರ್ಟಲ್ ಸ್ಥಿತಿ</translation>
 <translation id="30155388420722288">ಅತ್ಯಧಿಕ ಬಟನ್</translation>
 <translation id="5571066253365925590">Bluetooth ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">ಪ್ರಾಕ್ಸಿ...</translation>
 <translation id="938582441709398163">ಕೀಬೋರ್ಡ್ ಒವರ್‌ಲೇ</translation>
 <translation id="6979158407327259162">Google ಡ್ರೈವ್‌‌</translation>
+<translation id="6943836128787782965">HTTP ವಿಫಲವಾಗಿದೆ</translation>
 <translation id="2297568595583585744">ಸ್ಥಿತಿ ಟ್ರೆ</translation>
+<translation id="1661867754829461514">PIN ಕಾಣೆಯಾಗಿದೆ</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: ಸಂಪರ್ಕಿಸಲಾಗುತ್ತಿದೆ...</translation>
+<translation id="4237016987259239829">ನೆಟ್‌ವರ್ಕ್ ಸಂಪರ್ಕದ ದೋಷ</translation>
 <translation id="2946640296642327832">bluetooth ಸಕ್ರಿಯಗೊಳಿಸಿ</translation>
 <translation id="6459472438155181876"><ph name="DISPLAY_NAME"/> ಗೆ ಪರದೆಯನ್ನು ವಿಸ್ತರಿಸಲಾಗುತ್ತಿದೆ</translation>
 <translation id="8206859287963243715">ಸೆಲ್ಯುಲಾರ್</translation>
 <translation id="6596816719288285829">IP ವಿಳಾಸ</translation>
+<translation id="4508265954913339219">ಸಕ್ರಿಯಗೊಳಿಸುವಿಕೆ ವಿಫಲವಾಗಿದೆ</translation>
 <translation id="1812696562331527143">ನಿಮ್ಮ ಇನ್‌ಪುಟ್ ವಿಧಾನವನ್ನು <ph name="INPUT_METHOD_ID"/>* ಗೆ ಬದಲಾಯಿಸಲಾಗಿದೆ (<ph name="BEGIN_LINK"/>3ನೇ ವ್ಯಕ್ತಿ<ph name="END_LINK"/>).
 ಬದಲಿಸಲು Shift + Alt ಅನ್ನು ಒತ್ತಿರಿ.</translation>
-<translation id="5233638681132016545">ಹೊಸ ಟ್ಯಾಬ್</translation>
 <translation id="3846575436967432996">ನೆಟ್‌ವರ್ಕ್ ಮಾಹಿತಿ ಲಭ್ಯವಿಲ್ಲ</translation>
 <translation id="3026237328237090306">ಮೊಬೈಲ್ ಡೇಟಾವನ್ನು ಹೊಂದಿಸಿ</translation>
 <translation id="785750925697875037">ಮೊಬೈಲ್ ಖಾತೆಯನ್ನು ವೀಕ್ಷಿಸಿ</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">bluetooth ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ</translation>
 <translation id="3126069444801937830">ನವೀಕರಿಸಲು ಮರುಪ್ರಾರಂಭಿಸಿ</translation>
 <translation id="735745346212279324">VPN ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಲಾಗಿದೆ</translation>
+<translation id="7320906967354320621">ಕಾರ್ಯನಿರತವಾಗಿಲ್ಲ</translation>
 <translation id="6303423059719347535">ಬ್ಯಾಟರಿ <ph name="PERCENTAGE"/>% ಪೂರ್ಣವಾಗಿದೆ</translation>
+<translation id="2778346081696727092">ಒದಗಿಸಲಾದ ಬಳಕೆದಾರಹೆಸರು ಅಥವಾ ಪಾಸ್‌ವರ್ಡ್‌ನೊಂದಿಗಿನ ದೃಢೀಕರಣವು ವಿಫಲಗೊಂಡಿದೆ</translation>
 <translation id="3294437725009624529">ಅತಿಥಿ</translation>
 <translation id="8190698733819146287">ಭಾಷೆಗಳು ಮತ್ತು ಇನ್‌ಪುಟ್ ಅನ್ನು ಕಸ್ಟಮೈಸ್ ಮಾಡಿ...</translation>
-<translation id="598295083618286569">Bluetooth ಸಂಪರ್ಕಗೊಳಿಸಲಾಗಿದೆ</translation>
+<translation id="7170041865419449892">ವ್ಯಾಪ್ತಿಯ ಹೊರಗೆ</translation>
+<translation id="4804818685124855865">ಡಿಸ್‌ಕನೆಕ್ಟ್</translation>
 <translation id="5222676887888702881">ಸೈನ್ ಔಟ್</translation>
+<translation id="2688477613306174402">ಕಾನ್ಫಿಗರೇಶನ್</translation>
+<translation id="1272079795634619415">ನಿಲ್ಲಿಸು</translation>
 <translation id="4957722034734105353">ಇನ್ನಷ್ಟು ತಿಳಿದುಕೊಳ್ಳಿ...</translation>
 <translation id="2964193600955408481">Wi-Fi ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ</translation>
 <translation id="811680302244032017">ಸಾಧನ ಸೇರಿಸಿ...</translation>
 <translation id="2509468283778169019">CAPS LOCK ಆನ್ ಆಗಿದೆ</translation>
 <translation id="3892641579809465218">ಆಂತರಿಕ ಪ್ರದರ್ಶನ</translation>
 <translation id="7823564328645135659">ನಿಮ್ಮ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಸಿಂಕ್ ಮಾಡಿದ ನಂತರ ಭಾಷೆಯನ್ನು &quot;<ph name="FROM_LOCALE"/>&quot; ನಿಂದ &quot;<ph name="TO_LOCALE"/>&quot; ಗೆ ಬದಲಾಯಿಸಲಾಗಿದೆ.</translation>
+<translation id="3368922792935385530">ಸಂಪರ್ಕಿಸಲಾಗಿದೆ</translation>
 <translation id="8340999562596018839">ಮಾತನಾಡುವ ಪ್ರತಿಕ್ರಿಯೆ</translation>
 <translation id="8654520615680304441">Wi-Fi ಆನ್ ಮಾಡಿ...</translation>
 <translation id="5825747213122829519"><ph name="INPUT_METHOD_ID"/> ಗೆ ನಿಮ್ಮ ಇನ್‌ಪುಟ್ ವಿಧಾನವನ್ನು ಬದಲಾಯಿಸಲಾಗಿದೆ.
         ಬದಲಿಸಲು Shift + Alt ಕೀಲಿಯನ್ನು ಒತ್ತಿರಿ.</translation>
 <translation id="2562916301614567480">ಖಾಸಗಿ ನೆಟ್‌ವರ್ಕ್‌</translation>
 <translation id="6549021752953852991">ಯಾವುದೇ ಸೆಲ್ಯುಲಾರ್ ನೆಟ್‌ವರ್ಕ್ ಲಭ್ಯವಿಲ್ಲ</translation>
+<translation id="4379753398862151997">ಆತ್ಮೀಯ ಮಾನಿಟರ್, ನಮ್ಮ ನಡುವೆ ಸರಿಹೊಂದುತ್ತಿಲ್ಲ. (ಆ ಮಾನಿಟರ್ ಬೆಂಬಲಿಸುವುದಿಲ್ಲ)</translation>
 <translation id="6426039856985689743">ಮೊಬೈಲ್ ಡೇಟಾವನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ</translation>
 <translation id="3087734570205094154">ಕೆಳಗೆ</translation>
 <translation id="5271016907025319479">VPN ಕಾನ್ಫಿಗರ್ ಮಾಡಲಾಗಿಲ್ಲ.</translation>
-<translation id="1298695107722797780">ಸಾರ್ವಜನಿಕ\nಸೆಶನ್ ಮುಕ್ತಾಯ</translation>
-<translation id="3232695630852378748">Bluetooth ಸೆಟ್ಟಿಂಗ್‌ಗಳು...</translation>
+<translation id="6803622936009808957">ಯಾವುದೇ ಬೆಂಬಲಿತ ಪರಿಹಾರಗಳು ಕಂಡುಬರದ ಕಾರಣ ಪ್ರದರ್ಶನಗಳನ್ನು ಪ್ರತಿಬಿಂಬಿಸಲಾಗಲಿಲ್ಲ. ಬದಲಿಗೆ ವಿಸ್ತರಿತ ಡೆಸ್ಕ್‌ಟಾಪ್ ಅನ್ನು ನಮೂದಿಸಲಾಗಿದೆ.</translation>
 <translation id="1480041086352807611">ಡೆಮೋ ಮೋಡ್</translation>
 <translation id="3626637461649818317"><ph name="PERCENTAGE"/>% ಉಳಿದಿದೆ</translation>
 <translation id="9089416786594320554">ಇನ್‌ಪುಟ್ ವಿಧಾನಗಳು</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">ಶಟ್‌ಡೌನ್</translation>
 <translation id="4430019312045809116">ವಾಲ್ಯೂಮ್</translation>
+<translation id="4442424173763614572">DNS ಲುಕಪ್ ವಿಫಲವಾಗಿದೆ</translation>
 <translation id="6356500677799115505">ಬ್ಯಾಟರಿ ಪೂರ್ಣಗೊಂಡಿದೆ ಮತ್ತು ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ.</translation>
 <translation id="7874779702599364982">ಸೆಲ್ಯುಲರ್ ನೆಟ್‌ವರ್ಕ್‌ಗಳಿಗಾಗಿ ಹುಡುಕುತ್ತಿದೆ...</translation>
+<translation id="583281660410589416">ಅಜ್ಞಾತ</translation>
 <translation id="1383876407941801731">ಹುಡುಕಾಟ</translation>
+<translation id="7468789844759750875">ಹೆಚ್ಚಿನ ಡೇಟಾವನ್ನು ಖರೀದಿಸಲು <ph name="NAME"/> ಸಕ್ರಿಯ ಪೋರ್ಟಲ್ ಅನ್ನು ಭೇಟಿ ಮಾಡಿ.</translation>
 <translation id="3901991538546252627"><ph name="NAME"/> ಗೆ ಸಂಪರ್ಕಿಸಲಾಗುತ್ತಿದೆ</translation>
 <translation id="2204305834655267233">ನೆಟ್‌ವರ್ಕ್ ಮಾಹಿತಿ</translation>
 <translation id="1621499497873603021">ಬ್ಯಾಟರಿ ಖಾಲಿ ಆಗುವವರೆಗೆ ಉಳಿದಿರುವ ಸಮಯ, <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">ಹಿಂದಿನ ಮೆನು</translation>
 <translation id="1346748346194534595">ಬಲಕ್ಕೆ</translation>
 <translation id="8528322925433439945">ಮೊಬೈಲ್...</translation>
+<translation id="7049357003967926684">ಅಸೋಸಿಯೇಷನ್</translation>
 <translation id="8428213095426709021">ಸೆಟ್ಟಿಂಗ್‌ಗಳು</translation>
-<translation id="2472320577759310817">Bluetooth ಆಫ್ ಮಾಡಲಾಗಿದೆ.</translation>
 <translation id="2372145515558759244">ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಸಿಂಕ್ ಮಾಡಲಾಗುತ್ತಿದೆ...</translation>
+<translation id="7256405249507348194">ಗುರುತಿಸದಿರುವ ದೋಷ: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">AAA ಪರಿಶೀಲನೆ ವಿಫಲವಾಗಿದೆ</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಲಾಗುತ್ತಿದೆ...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> ಪೂರ್ಣಗೊಳ್ಳುವವರೆಗೆ</translation>
 <translation id="5787281376604286451">ಮಾತನಾಡುವ ಪ್ರತಿಕ್ರಿಯೆ ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ.
 ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು Ctrl+Alt+Z ಒತ್ತಿರಿ.</translation>
 <translation id="4479639480957787382">ಈಥರ್ನೆಟ್</translation>
+<translation id="6312403991423642364">ಅಜ್ಞಾತ ನೆಟ್‌ವರ್ಕ್ ದೋಷ</translation>
 <translation id="1467432559032391204">ಎಡಕ್ಕೆ</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830"><ph name="NAME"/> ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾಗುತ್ತಿದೆ</translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">ಗರಿಷ್ಠಗೊಳಿಸು</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: ಸಂಪರ್ಕಿಸಲಾಗುತ್ತಿದೆ...</translation>
+<translation id="8639033665604704195">ಒದಗಿಸಲಾದ ಪೂರ್ವ ಹಂಚಿತ ಕೀಲಿಯೊಂದಿಗೆ ದೃಢೀಕರಿಸಲುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ</translation>
 <translation id="252373100621549798">ಅಜ್ಞಾತ ಪ್ರದರ್ಶನ</translation>
 <translation id="1882897271359938046"><ph name="DISPLAY_NAME"/> ಗೆ ಪ್ರತಿಬಿಂಬಿಸುತ್ತಿದೆ</translation>
 <translation id="3784455785234192852">ಲಾಕ್ ಮಾಡಿ</translation>
 <translation id="2805756323405976993">ಅಪ್ಲಿಕೇಶನ್‌ಗಳು</translation>
-<translation id="2482878487686419369">ಸೂಚನೆಗಳು</translation>
+<translation id="1512064327686280138">ಸಕ್ರಿಯಗೊಳಿಸುವಿಕೆ ವಿಫಲವಾಗಿದೆ</translation>
+<translation id="5097002363526479830">'<ph name="NAME"/>' ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸಂಪರ್ಕಿಸಲು ವಿಫಲವಾಗಿದೆ: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi ಆಫ್ ಮಾಡಲಾಗಿದೆ.</translation>
-<translation id="2872961005593481000">ಮುಚ್ಚಿಬಿಡಿ </translation>
+<translation id="8036518327127111261">ಒದಗಿಸಲಾದ ಪ್ರಮಾಣಪತ್ರದೊಂದಿಗೆ ದೃಢೀಕರಣವು ವಿಫಲವಾಗಿದೆ</translation>
 <translation id="8132793192354020517"><ph name="NAME"/> ಗೆ ಸಂಪರ್ಕಗೊಂಡಿದೆ</translation>
 <translation id="7052914147756339792">ವಾಲ್‌ಪೇಪರ್ ಅನ್ನು ಹೊಂದಿಸಿ...</translation>
-<translation id="2739500853984626550">ಯಾವುದೇ bluetooth ಸಾಧನಗಳು ಲಭ್ಯವಿಲ್ಲ</translation>
-<translation id="2666092431469916601">ಮೇಲೆ</translation>
+<translation id="8678698760965522072">ಆನ್‌ಲೈನ್ ಸ್ಥಿತಿ</translation>
+<translation id="1119447706177454957">ಆಂತರಿಕ ದೋಷ</translation>
 <translation id="3019353588588144572">ಬ್ಯಾಟರಿ ಪೂರ್ಣವಾಗಿ ಚಾರ್ಜ್ ಆಗುವವರೆಗೆ ಉಳಿದಿರುವ ಸಮಯ, <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">ಪರದೆ ವರ್ಧಕ</translation>
+<translation id="7005812687360380971">ವೈಫಲ್ಯ</translation>
 <translation id="1602076796624386989">ಮೊಬೈಲ್ ಡೇಟಾವನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ</translation>
 <translation id="6981982820502123353">ಪ್ರವೇಶಿಸುವಿಕೆ</translation>
 <translation id="3157931365184549694">ಪುನಃಸ್ಥಾಪನೆ</translation>
+<translation id="4274292172790327596">ಗುರುತಿಸದೆ ಇರುವ ದೋಷ</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">ಸಾಧನಗಳಿಗಾಗಿ ಸ್ಕ್ಯಾನ್ ಮಾಡಲಾಗುತ್ತಿದೆ...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Wi-Fi ನೆಟ್‌ವರ್ಕ್‌ಗಳಿಗಾಗಿ ಹುಡುಕಲಾಗುತ್ತಿದೆ...</translation>
+<translation id="7229570126336867161">EVDO ಅಗತ್ಯವಿದೆ</translation>
 <translation id="2999742336789313416"><ph name="DOMAIN"/> ಮೂಲಕ ನಿರ್ವಹಿಸಲಾದ ಸಾರ್ವಜನಿಕ ಸೆಶನ್ <ph name="DISPLAY_NAME"/> ಆಗಿದೆ</translation>
 <translation id="7029814467594812963">ಸೆಶನ್‌ನಿಂದ ನಿರ್ಗಮಿಸು</translation>
 <translation id="8454013096329229812">Wi-Fi ಆನ್ ಮಾಡಲಾಗಿದೆ.</translation>
 <translation id="4872237917498892622">Alt+ಹುಡುಕಾಟ ಅಥವಾ Shift</translation>
 <translation id="2983818520079887040">ಸೆಟ್ಟಿಂಗ್‌ಗಳು...</translation>
-<translation id="5467313780247887226">ಲಗತ್ತಿಸಿದ ಮಾನಿಟರ್‌ಗಳಲ್ಲಿ ಚಿತ್ರವನ್ನು ನಕಲಿ ಇರಿಸಲಾಗುವುದಿಲ್ಲ. ಯಾವುದೇ ಹೊಂದಾಣಿಕೆಯ ರೆಸಲ್ಯೂಶನ್ ಕಂಡುಬಂದಿಲ್ಲ.</translation>
+<translation id="8927026611342028580">ಸಂಪರ್ಕವನ್ನು ವಿನಂತಿಸಲಾಗಿದೆ</translation>
+<translation id="8300849813060516376">OTASP ವಿಫಲವಾಗಿದೆ</translation>
 <translation id="2792498699870441125">Alt+ಹುಡುಕಾಟ</translation>
 <translation id="8660803626959853127"><ph name="COUNT"/> ಫೈಲ್‌(ಗಳ) ಅನ್ನು ಸಿಂಕ್ ಮಾಡಲಾಗುತ್ತಿದೆ</translation>
 <translation id="639644700271529076">CAPS LOCK ಆಫ್ ಆಗಿದೆ</translation>
-<translation id="4101192585425716296">ಸಂದೇಶ ಕೇಂದ್ರ</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: ಸಕ್ರಿಯಗೊಳಿಸಲಾಗುತ್ತಿದೆ...</translation>
+<translation id="1391854757121130358">ನಿಮ್ಮ ಮೊಬೈಲ್ ಡೇಟಾ ಭತ್ಯೆಯನ್ನು ನೀವು ಬಳಸಿರಬಹುದು.</translation>
 <translation id="4864165860509564259">ಲಾಂಚರ್ ಸ್ಥಾನ</translation>
 <translation id="7593891976182323525">ಹುಡುಕಾಟ ಅಥವಾ Shift</translation>
 <translation id="7649070708921625228">ಸಹಾಯ</translation>
 <translation id="3050422059534974565">CAPS LOCK ಆನ್ ಆಗಿದೆ.
 ರದ್ದುಗೊಳಿಸಲು ಹುಡುಕಾಟ ಅಥವಾ Shift ಕೀಲಿಯನ್ನು ಒತ್ತಿರಿ.</translation>
 <translation id="397105322502079400">ಎಣಿಕೆ ಮಾಡಲಾಗುತ್ತಿದೆ...</translation>
+<translation id="158849752021629804">ಹೋಮ್ ನೆಟ್‌ವರ್ಕ್ ಅಗತ್ಯವಿದೆ</translation>
+<translation id="6857811139397017780">ಸಕ್ರಿಯಗೊಳಿಸಿ<ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">DHCP ಲುಕಪ್ ವಿಫಲವಾಗಿದೆ</translation>
+<translation id="6692173217867674490">ಕೆಟ್ಟ ಪಾಸ್‌ಫ್ರೇಸ್</translation>
 <translation id="6165508094623778733">ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ</translation>
+<translation id="9046895021617826162">ಸಂಪರ್ಕವು ವಿಫಲವಾಗಿದೆ</translation>
+<translation id="973896785707726617">ಈ ಸೆಷನ್ <ph name="SESSION_TIME_REMAINING"/> ರಲ್ಲಿ ಮುಕ್ತಾಯಗೊಳ್ಳುತ್ತದೆ. ನಿಮ್ಮನ್ನು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸೈನ್ ಔಟ್ ಮಾಡಲಾಗುತ್ತದೆ.</translation>
+<translation id="8372369524088641025">ಕೆಟ್ಟ WEP ಕೀ</translation>
+<translation id="6636709850131805001">ಅಂಗೀಕಾರವಲ್ಲದ ರಾಜ್ಯ</translation>
 <translation id="3573179567135747900">&quot;<ph name="FROM_LOCALE"/>&quot; ಗೆ ಮರುಬದಲಾಯಿಸಿ (ಮರುಪ್ರಾರಂಭಿಸುವ ಅಗತ್ಯವಿದೆ)</translation>
 <translation id="8103386449138765447">SMS ಸಂದೇಶಗಳು: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Google ಡ್ರೈವ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">ನೆಟ್‌ವರ್ಕ್ ಇಲ್ಲ</translation>
 <translation id="5941711191222866238">ಕುಗ್ಗಿಸು</translation>
 <translation id="6911468394164995108">ಇತರರನ್ನು ಸೇರಿ...</translation>
-<translation id="6843725295806269523">ಮ್ಯೂಟ್</translation>
 <translation id="412065659894267608">ಪೂರ್ಣವಾಗುವವರಗೆ <ph name="HOUR"/>ಗಂ <ph name="MINUTE"/>ನಿ</translation>
 <translation id="6359806961507272919"><ph name="PHONE_NUMBER"/> ನಿಂದ SMS</translation>
+<translation id="1244147615850840081">ವಾಹಕ</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_ko.xtb b/ash/strings/ash_strings_ko.xtb
index 7d7188c..f81050d 100644
--- a/ash/strings/ash_strings_ko.xtb
+++ b/ash/strings/ash_strings_ko.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">배터리 충전 완료</translation>
 <translation id="5250713215130379958">실행기 자동으로 숨기기</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/>시간 <ph name="MINUTE"/>분</translation>
+<translation id="7880025619322806991">포털 상태</translation>
 <translation id="30155388420722288">오버플로 버튼</translation>
 <translation id="5571066253365925590">블루투스를 사용함</translation>
 <translation id="9074739597929991885">블루투스</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">프록시...</translation>
 <translation id="938582441709398163">키보드 오버레이</translation>
 <translation id="6979158407327259162">Google 드라이브</translation>
+<translation id="6943836128787782965">HTTP 실패</translation>
 <translation id="2297568595583585744">상태 표시줄</translation>
+<translation id="1661867754829461514">PIN이 없습니다.</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: 연결하는 중...</translation>
+<translation id="4237016987259239829">네트워크 연결 오류</translation>
 <translation id="2946640296642327832">블루투스 사용</translation>
 <translation id="6459472438155181876">화면을 <ph name="DISPLAY_NAME"/>(으)로 확장</translation>
 <translation id="8206859287963243715">휴대전화</translation>
 <translation id="6596816719288285829">IP 주소</translation>
+<translation id="4508265954913339219">활성화 실패</translation>
 <translation id="1812696562331527143">입력 방법이 <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>타사<ph name="END_LINK"/>)(으)로 변경되었습니다.
 전환하려면 Shift+Alt를 누르세요.</translation>
-<translation id="5233638681132016545">새 탭</translation>
 <translation id="3846575436967432996">네트워크 정보 없음</translation>
 <translation id="3026237328237090306">모바일 데이터 설정</translation>
 <translation id="785750925697875037">모바일 계정 표시</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">블루투스 사용 안 함</translation>
 <translation id="3126069444801937830">업데이트하려면 다시 시작</translation>
 <translation id="735745346212279324">VPN 연결 끊김</translation>
+<translation id="7320906967354320621">대기</translation>
 <translation id="6303423059719347535">배터리가 <ph name="PERCENTAGE"/>% 충전됨</translation>
+<translation id="2778346081696727092">제공한 사용자 이름 또는 비밀번호로 인증하지 못했습니다.</translation>
 <translation id="3294437725009624529">손님</translation>
 <translation id="8190698733819146287">언어 및 입력 설정...</translation>
-<translation id="598295083618286569">블루투스가 연결됨</translation>
+<translation id="7170041865419449892">범위를 벗어났습니다.</translation>
+<translation id="4804818685124855865">연결 해제</translation>
 <translation id="5222676887888702881">로그아웃</translation>
+<translation id="2688477613306174402">설정</translation>
+<translation id="1272079795634619415">중지</translation>
 <translation id="4957722034734105353">자세히 알아보기...</translation>
 <translation id="2964193600955408481">Wi-Fi 사용 안 함</translation>
 <translation id="811680302244032017">기기 추가...</translation>
 <translation id="2509468283778169019">CAPS LOCK이 켜져 있습니다.</translation>
 <translation id="3892641579809465218">내부 디스플레이</translation>
 <translation id="7823564328645135659">설정을 동기화한 뒤 Chrome의 언어가 '<ph name="FROM_LOCALE"/>'에서 '<ph name="TO_LOCALE"/>'(으)로 변경되었습니다.</translation>
+<translation id="3368922792935385530">연결됨</translation>
 <translation id="8340999562596018839">음성 피드백</translation>
 <translation id="8654520615680304441">Wi-Fi 사용...</translation>
 <translation id="5825747213122829519">입력 방법이 <ph name="INPUT_METHOD_ID"/>(으)로 변경되었습니다.
 전환하려면 Shift+Alt를 누르세요.</translation>
 <translation id="2562916301614567480">사설 네트워크</translation>
 <translation id="6549021752953852991">사용 가능한 휴대전화 네트워크가 없음</translation>
+<translation id="4379753398862151997">확장 데스크톱에 어울리지 않는 모니터네요. (지원되지 않는 모니터입니다.)</translation>
 <translation id="6426039856985689743">모바일 데이터 사용 안함</translation>
 <translation id="3087734570205094154">맨 아래</translation>
 <translation id="5271016907025319479">VPN이 구성되지 않았습니다.</translation>
-<translation id="1298695107722797780">공개\n세션 종료</translation>
-<translation id="3232695630852378748">블루투스 설정</translation>
+<translation id="6803622936009808957">지원되는 해상도가 없으므로 디스플레이를 그대로 반영할 수 없습니다. 대신 확장 데스크톱을 시작했습니다.</translation>
 <translation id="1480041086352807611">데모 모드</translation>
 <translation id="3626637461649818317"><ph name="PERCENTAGE"/>% 남음</translation>
 <translation id="9089416786594320554">입력 방법</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">종료</translation>
 <translation id="4430019312045809116">볼륨</translation>
+<translation id="4442424173763614572">DNS 조회 실패</translation>
 <translation id="6356500677799115505">배터리 충전이 완료되었으며 충전 중입니다.</translation>
 <translation id="7874779702599364982">휴대전화 네트워크를 검색하는 중...</translation>
+<translation id="583281660410589416">알 수 없음</translation>
 <translation id="1383876407941801731">검색</translation>
+<translation id="7468789844759750875">추가 데이터를 구입하려면 <ph name="NAME"/> 활성화 포탈을 방문하세요.</translation>
 <translation id="3901991538546252627"><ph name="NAME"/>에 연결 중</translation>
 <translation id="2204305834655267233">네트워크 정보</translation>
 <translation id="1621499497873603021">남은 배터리 사용 시간은 <ph name="TIME_LEFT"/>입니다.</translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">이전 메뉴</translation>
 <translation id="1346748346194534595">오른쪽</translation>
 <translation id="8528322925433439945">모바일 ...</translation>
+<translation id="7049357003967926684">연결</translation>
 <translation id="8428213095426709021">설정</translation>
-<translation id="2472320577759310817">블루투스가 꺼져 있습니다.</translation>
 <translation id="2372145515558759244">앱 동기화...</translation>
+<translation id="7256405249507348194">알 수 없는 오류(<ph name="DESC"/>)입니다.</translation>
+<translation id="7925247922861151263">AAA 확인 실패</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: 연결을 끊는 중...</translation>
 <translation id="8456362689280298700">충전 완료까지 <ph name="HOUR"/>:<ph name="MINUTE"/> 남음</translation>
 <translation id="5787281376604286451">음성 피드백을 사용할 수 있습니다.
 사용중지하려면 Ctrl+Alt+Z를 누르세요.</translation>
 <translation id="4479639480957787382">이더넷</translation>
+<translation id="6312403991423642364">알려지지 않은 네트워크 오류</translation>
 <translation id="1467432559032391204">왼쪽</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830"><ph name="NAME"/> 활성화 중</translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">최대화</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: 연결하는 중...</translation>
+<translation id="8639033665604704195">제공된 사전 공유 키로 인증하지 못했습니다.</translation>
 <translation id="252373100621549798">알 수 없는 디스플레이</translation>
 <translation id="1882897271359938046"><ph name="DISPLAY_NAME"/>에 미러링</translation>
 <translation id="3784455785234192852">잠금</translation>
 <translation id="2805756323405976993">애플리케이션</translation>
-<translation id="2482878487686419369">알림</translation>
+<translation id="1512064327686280138">활성화 실패</translation>
+<translation id="5097002363526479830">'<ph name="NAME"/>' 네트워크에 연결하지 못했습니다: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi가 꺼져 있습니다.</translation>
-<translation id="2872961005593481000">종료</translation>
+<translation id="8036518327127111261">제공된 인증서로 인증하지 못했습니다.</translation>
 <translation id="8132793192354020517"><ph name="NAME"/>에 연결됨</translation>
 <translation id="7052914147756339792">배경화면 설정...</translation>
-<translation id="2739500853984626550">사용 가능한 블루투스 기기가 없습니다.</translation>
-<translation id="2666092431469916601">맨 위</translation>
+<translation id="8678698760965522072">온라인 상태</translation>
+<translation id="1119447706177454957">내부 오류</translation>
 <translation id="3019353588588144572">배터리 충전이 완료될 때까지 남은 시간은 <ph name="TIME_REMAINING"/>입니다.</translation>
 <translation id="3473479545200714844">화면 돋보기</translation>
+<translation id="7005812687360380971">실패</translation>
 <translation id="1602076796624386989">모바일 데이터 사용</translation>
 <translation id="6981982820502123353">접근성</translation>
 <translation id="3157931365184549694">복구</translation>
+<translation id="4274292172790327596">인식할 수 없는 오류</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">기기 검색 중...</translation>
 <translation id="5597451508971090205"><ph name="DATE"/> <ph name="SHORT_WEEKDAY"/></translation>
 <translation id="4448844063988177157">Wi-Fi 네트워크를 검색하는 중...</translation>
+<translation id="7229570126336867161">EVDO가 필요합니다.</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/>은(는) <ph name="DOMAIN"/>에서 관리하는 공개 세션입니다.</translation>
 <translation id="7029814467594812963">세션 종료</translation>
 <translation id="8454013096329229812">Wi-Fi가 켜져 있습니다.</translation>
 <translation id="4872237917498892622">Alt+검색 또는 Shift 키</translation>
 <translation id="2983818520079887040">설정...</translation>
-<translation id="5467313780247887226">연결된 모니터에 이미지를 복제할 수 없습니다. 일치하는 해상도가 없습니다.</translation>
+<translation id="8927026611342028580">연결 요청됨</translation>
+<translation id="8300849813060516376">OTASP 실패</translation>
 <translation id="2792498699870441125">Alt+검색 키</translation>
 <translation id="8660803626959853127">파일 <ph name="COUNT"/>개를 동기화 중</translation>
 <translation id="639644700271529076">CAPS LOCK이 꺼져 있음</translation>
-<translation id="4101192585425716296">메시지 센터</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: 활성화 중...</translation>
+<translation id="1391854757121130358">모바일 데이터 사용량을 모두 사용했을 수 있습니다.</translation>
 <translation id="4864165860509564259">실행기 위치</translation>
 <translation id="7593891976182323525">검색 또는 Shift 키</translation>
 <translation id="7649070708921625228">도움말</translation>
 <translation id="3050422059534974565">CAPS LOCK이 켜져 있습니다.
 취소하려면 검색 또는 Shift 키를 누릅니다.</translation>
 <translation id="397105322502079400">계산 중...</translation>
+<translation id="158849752021629804">홈 네크워크가 필요합니다.</translation>
+<translation id="6857811139397017780"><ph name="NETWORKSERVICE"/> 활성화</translation>
+<translation id="5864471791310927901">DHCP 조회 실패</translation>
+<translation id="6692173217867674490">잘못된 암호</translation>
 <translation id="6165508094623778733">자세히 알아보기</translation>
+<translation id="9046895021617826162">연결 실패</translation>
+<translation id="973896785707726617">이 세션은 <ph name="SESSION_TIME_REMAINING"/> 후에 종료되어 자동으로 로그아웃됩니다.</translation>
+<translation id="8372369524088641025">잘못된 WEP 키</translation>
+<translation id="6636709850131805001">인식할 수 없는 상태</translation>
 <translation id="3573179567135747900">'<ph name="FROM_LOCALE"/>'(으)로 다시 변경(다시 시작해야 함)</translation>
 <translation id="8103386449138765447">SMS 메시지: <ph name="MESSAGE_COUNT"/>개</translation>
 <translation id="5045002648206642691">Google 문서함 설정...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">네트워크 없음</translation>
 <translation id="5941711191222866238">최소화</translation>
 <translation id="6911468394164995108">다른 네트워크에 연결</translation>
-<translation id="6843725295806269523">음소거</translation>
 <translation id="412065659894267608">충전 완료까지 <ph name="HOUR"/>시간 <ph name="MINUTE"/>분 남음</translation>
 <translation id="6359806961507272919"><ph name="PHONE_NUMBER"/>에서 전송된 SMS</translation>
+<translation id="1244147615850840081">네트워크 사업자</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_lt.xtb b/ash/strings/ash_strings_lt.xtb
index f3533eb..fb57b24 100644
--- a/ash/strings/ash_strings_lt.xtb
+++ b/ash/strings/ash_strings_lt.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Akumuliatorius įkrautas</translation>
 <translation id="5250713215130379958">Automatiškai slėpti paleidimo priemonę</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/>:<ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Portalo būsena</translation>
 <translation id="30155388420722288">Perpildymo mygtukas</translation>
 <translation id="5571066253365925590">„Bluetooth“ įgalinta</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Įgaliotasis serveris...</translation>
 <translation id="938582441709398163">Klaviatūros perdanga</translation>
 <translation id="6979158407327259162">„Google“ diskas</translation>
+<translation id="6943836128787782965">Įvyko HTTP klaida</translation>
 <translation id="2297568595583585744">Būsenos dėklas</translation>
+<translation id="1661867754829461514">Trūksta PIN kodo</translation>
 <translation id="4508225577814909926">„<ph name="NAME"/>“: jungiamasi...</translation>
+<translation id="4237016987259239829">Tinklo ryšio klaida</translation>
 <translation id="2946640296642327832">Įgalinti „Bluetooth“</translation>
 <translation id="6459472438155181876">Ekranas išplečiamas į <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Mobilusis</translation>
 <translation id="6596816719288285829">IP adresas</translation>
+<translation id="4508265954913339219">Nepavyko suaktyvinti</translation>
 <translation id="1812696562331527143">Įvesties metodas pakeistas į <ph name="INPUT_METHOD_ID"/>* (<ph name="BEGIN_LINK"/>trečioji šalis<ph name="END_LINK"/>).
         Jei norite perjungti, paspauskite „Shift“ + „Alt“.</translation>
-<translation id="5233638681132016545">Naujas skirtukas</translation>
 <translation id="3846575436967432996">Nėra tinklo informacijos</translation>
 <translation id="3026237328237090306">Nustatyti duomenis mobiliesiems</translation>
 <translation id="785750925697875037">Žiūrėti paskyrą mobiliesiems</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Neleisti „Bluetooth“</translation>
 <translation id="3126069444801937830">Paleisti iš naujo, kad būtų atnaujinta</translation>
 <translation id="735745346212279324">VPN atjungtas</translation>
+<translation id="7320906967354320621">Neveikia</translation>
 <translation id="6303423059719347535">Likusi akumuliatoriaus įkrova: <ph name="PERCENTAGE"/> %</translation>
+<translation id="2778346081696727092">Nepavyko autentifikuoti naudojant pateiktą naudotojo vardą ar slaptažodį</translation>
 <translation id="3294437725009624529">Svečias</translation>
 <translation id="8190698733819146287">Tinkinti kalbas ir įvestį...</translation>
-<translation id="598295083618286569">„Bluetooth“ prijungta</translation>
+<translation id="7170041865419449892">Nepasiekiama</translation>
+<translation id="4804818685124855865">Atsijungti</translation>
 <translation id="5222676887888702881">Atsijungti</translation>
+<translation id="2688477613306174402">Konfigūracija</translation>
+<translation id="1272079795634619415">Sustabdyti</translation>
 <translation id="4957722034734105353">Sužinokite daugiau...</translation>
 <translation id="2964193600955408481">Neleisti „Wi-Fi“</translation>
 <translation id="811680302244032017">Pridėti įrenginį...</translation>
 <translation id="2509468283778169019">DIDŽIŲJŲ RAIDŽIŲ RAŠYMAS įjungtas</translation>
 <translation id="3892641579809465218">Vidinė pateiktis</translation>
 <translation id="7823564328645135659">Po nustatymų sinchronizavimo kalba pakeista iš <ph name="FROM_LOCALE"/> į <ph name="TO_LOCALE"/>.</translation>
+<translation id="3368922792935385530">Prijungta</translation>
 <translation id="8340999562596018839">Žodiniai atsiliepimai</translation>
 <translation id="8654520615680304441">Įjungti „Wi-Fi“...</translation>
 <translation id="5825747213122829519">Įvesties metodas pakeistas į <ph name="INPUT_METHOD_ID"/>.
         Jei norite perjungti, paspauskite „Shift“ + „Alt“.</translation>
 <translation id="2562916301614567480">Privatus tinklas</translation>
 <translation id="6549021752953852991">Nėra jokių pasiekiamų korinio ryšio tinklų</translation>
+<translation id="4379753398862151997">Mielas monitoriau, mums nepavyksta bendradarbiauti. (Tas monitorius nepalaikomas)</translation>
 <translation id="6426039856985689743">Neleisti duomenų mobiliesiems</translation>
 <translation id="3087734570205094154">Apačia</translation>
 <translation id="5271016907025319479">VPN nesukonfigūruotas.</translation>
-<translation id="1298695107722797780">Baigti viešąją\nsesiją</translation>
-<translation id="3232695630852378748">„Bluetooth“ nustatymai...</translation>
+<translation id="6803622936009808957">Nepavyko dubliuoti vaizdų, nes nepavyko rasti palaikomų skyrų. Vietoje to įjungtas išplėstinio darbalaukio režimas.</translation>
 <translation id="1480041086352807611">Demonstracinės versijos režimas</translation>
 <translation id="3626637461649818317">Liko <ph name="PERCENTAGE"/> proc.</translation>
 <translation id="9089416786594320554">Įvesties metodai</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/> %</translation>
 <translation id="1895658205118569222">Išjungimas</translation>
 <translation id="4430019312045809116">Apimtis</translation>
+<translation id="4442424173763614572">Įvyko DNS paieškos klaida</translation>
 <translation id="6356500677799115505">Akumuliatorius įkrautas ir vis įkraunamas.</translation>
 <translation id="7874779702599364982">Ieškoma korinio ryšio tinklų...</translation>
+<translation id="583281660410589416">Nežinoma</translation>
 <translation id="1383876407941801731">Ieškoti</translation>
+<translation id="7468789844759750875">Apsilankykite „<ph name="NAME"/>“ aktyvinimo portale, kad nusipirktumėte daugiau duomenų.</translation>
 <translation id="3901991538546252627">Jungiamasi prie „<ph name="NAME"/>“</translation>
 <translation id="2204305834655267233">Tinklo informacija</translation>
 <translation id="1621499497873603021">Laikas, likęs iki akumuliatoriaus išsikrovimo: <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">Ankstesnis meniu</translation>
 <translation id="1346748346194534595">Dešinė</translation>
 <translation id="8528322925433439945">Mobilusis...</translation>
+<translation id="7049357003967926684">Bendrovė</translation>
 <translation id="8428213095426709021">Nustatymai</translation>
-<translation id="2472320577759310817">„Bluetooth“ išjungtas.</translation>
 <translation id="2372145515558759244">Sinchronizuojamos programos...</translation>
+<translation id="7256405249507348194">Neatpažinta klaida: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">AAA patikra nepavyko</translation>
 <translation id="3227723743333276085">„<ph name="BLUETOOTH"/>“: atjungiama...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>.<ph name="MINUTE"/> iki visiško įkrovimo</translation>
 <translation id="5787281376604286451">Žodiniai atsiliepimai įgalinti.
 Jei norite neleisti, paspauskite „Ctrl“ + „Alt“ + Z.</translation>
 <translation id="4479639480957787382">Eternetas</translation>
+<translation id="6312403991423642364">Nežinoma tinklo klaida</translation>
 <translation id="1467432559032391204">Kairė</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830">Aktyvinamas „<ph name="NAME"/>“</translation>
 <translation id="8814190375133053267">WI-Fi</translation>
 <translation id="1398853756734560583">Išskleisti</translation>
 <translation id="2692809339924654275">„<ph name="BLUETOOTH"/>“: jungiamasi...</translation>
+<translation id="8639033665604704195">Nepavyko autentifikuoti naudojant pateiktą iš anksto bendrinamą raktą</translation>
 <translation id="252373100621549798">Nežinoma pateiktis</translation>
 <translation id="1882897271359938046">Dubliuojama <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Užrakinti</translation>
 <translation id="2805756323405976993">Programos</translation>
-<translation id="2482878487686419369">Pranešimai</translation>
+<translation id="1512064327686280138">Aktyvinimo triktis</translation>
+<translation id="5097002363526479830">Nepavyko prisijungti prie tinklo „<ph name="NAME"/>“: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">„Wi-Fi“ ryšys išjungtas.</translation>
-<translation id="2872961005593481000">Stabdyti</translation>
+<translation id="8036518327127111261">Nepavyko autentifikuoti naudojant pateiktą sertifikatą</translation>
 <translation id="8132793192354020517">Prisijungta prie „<ph name="NAME"/>“</translation>
 <translation id="7052914147756339792">Nustatyti darbalaukio foną...</translation>
-<translation id="2739500853984626550">Nėra pasiekiamų „Bluetooth“ įrenginių</translation>
-<translation id="2666092431469916601">Į viršų</translation>
+<translation id="8678698760965522072">Būsena „Prisijungus“</translation>
+<translation id="1119447706177454957">Vidinė klaida</translation>
 <translation id="3019353588588144572">Laikas, likęs iki akumuliatoriaus įkrovimo: <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">Ekrano didintuvas</translation>
+<translation id="7005812687360380971">Nepavyko</translation>
 <translation id="1602076796624386989">Įgalinti duomenis mobiliesiems</translation>
 <translation id="6981982820502123353">Pritaikymas neįgaliesiems</translation>
 <translation id="3157931365184549694">Atkurti</translation>
+<translation id="4274292172790327596">Neatpažįstama klaida</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Ieškoma įrenginių...</translation>
 <translation id="5597451508971090205"><ph name="DATE"/>, <ph name="SHORT_WEEKDAY"/></translation>
 <translation id="4448844063988177157">Ieškoma „Wi-Fi“ tinklų...</translation>
+<translation id="7229570126336867161">Reikia EVDO</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> yra vieša sesija, valdoma <ph name="DOMAIN"/></translation>
 <translation id="7029814467594812963">Išeiti iš sesijos</translation>
 <translation id="8454013096329229812">„Wi-Fi“ ryšys įjungtas.</translation>
 <translation id="4872237917498892622">„Alt“ + paieškos arba antrojo lygio klavišas</translation>
 <translation id="2983818520079887040">Nustatymai...</translation>
-<translation id="5467313780247887226">Negalima kurti vaizdų kopijų prijungtuose monitoriuose. Nerasta atitinkančios skyros.</translation>
+<translation id="8927026611342028580">Pateikta prisijungimo užklausa</translation>
+<translation id="8300849813060516376">OTASP nepavyko</translation>
 <translation id="2792498699870441125">„Alt“ + paieškos klavišas</translation>
 <translation id="8660803626959853127">Sinchronizuojamas (-i) <ph name="COUNT"/> failas (-ai)</translation>
 <translation id="639644700271529076">DIDŽIŲJŲ RAIDŽIŲ RAŠYMAS išjungtas</translation>
-<translation id="4101192585425716296">Pranešimų centras</translation>
+<translation id="6267036997247669271">„<ph name="NAME"/>“: aktyvinama...</translation>
+<translation id="1391854757121130358">Galbūt išnaudojote savo mobiliojo ryšio duomenų normą.</translation>
 <translation id="4864165860509564259">Paleidiklio pozicija</translation>
 <translation id="7593891976182323525">Paieškos arba antrojo lygio klavišas</translation>
 <translation id="7649070708921625228">Žinynas</translation>
 <translation id="3050422059534974565">DIDŽIŲJŲ RAIDŽIŲ RAŠYMAS įjungtas.
 Jei norite atšaukti, paspauskite paieškos arba antrojo lygio klavišą.</translation>
 <translation id="397105322502079400">Skaičiuojama...</translation>
+<translation id="158849752021629804">Reikalingas namų tinklas</translation>
+<translation id="6857811139397017780">Suaktyvinti „<ph name="NETWORKSERVICE"/>“</translation>
+<translation id="5864471791310927901">DHCP paieška nepavyko</translation>
+<translation id="6692173217867674490">Netinkama slaptafrazė</translation>
 <translation id="6165508094623778733">Sužinokite daugiau</translation>
+<translation id="9046895021617826162">Nepavyko prisijungti</translation>
+<translation id="973896785707726617">Ši sesija baigsis po <ph name="SESSION_TIME_REMAINING"/>. Būsite automatiškai atjungti.</translation>
+<translation id="8372369524088641025">Netinkamas WEP raktas</translation>
+<translation id="6636709850131805001">Neatpažinta būsena</translation>
 <translation id="3573179567135747900">Pakeisti atgal į „<ph name="FROM_LOCALE"/>“ (reikia paleisti iš naujo)</translation>
 <translation id="8103386449138765447">SMS pranešimų: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">„Google“ disko nustatymai...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">Tinklo nėra</translation>
 <translation id="5941711191222866238">Sumažinti</translation>
 <translation id="6911468394164995108">Prisijungti prie kito...</translation>
-<translation id="6843725295806269523">nutildyti</translation>
 <translation id="412065659894267608"><ph name="HOUR"/> val. <ph name="MINUTE"/> min. iki visiško įkrovimo</translation>
 <translation id="6359806961507272919">SMS iš <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Operatorius</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_lv.xtb b/ash/strings/ash_strings_lv.xtb
index e593f62..8d3cb23 100644
--- a/ash/strings/ash_strings_lv.xtb
+++ b/ash/strings/ash_strings_lv.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Akumulators ir pilnībā uzlādēts</translation>
 <translation id="5250713215130379958">Automātiski paslēpt palaišanas lapu</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> un <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Portāla statuss</translation>
 <translation id="30155388420722288">Pārpildes poga</translation>
 <translation id="5571066253365925590">Bluetooth iespējots</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Starpniekserveris...</translation>
 <translation id="938582441709398163">Tastatūras pārklājums</translation>
 <translation id="6979158407327259162">Google disks</translation>
+<translation id="6943836128787782965">Neizdevās iegūt HTTP</translation>
 <translation id="2297568595583585744">Statusa tekne</translation>
+<translation id="1661867754829461514">Trūkst PIN koda</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: notiek savienojuma izveide...</translation>
+<translation id="4237016987259239829">Tīkla savienojuma kļūda</translation>
 <translation id="2946640296642327832">Iespējot Bluetooth</translation>
 <translation id="6459472438155181876">Paplašina ekrānu uz: <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Mobilais tālrunis</translation>
 <translation id="6596816719288285829">IP adrese</translation>
+<translation id="4508265954913339219">Aktivizācija neizdevās</translation>
 <translation id="1812696562331527143">Ievades metode ir mainīta uz <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>trešā puse<ph name="END_LINK"/>).
 Lai to pārslēgtu, nospiediet taustiņu kombināciju Shift+Alt.</translation>
-<translation id="5233638681132016545">Jauna cilne</translation>
 <translation id="3846575436967432996">Tīkla informācija nav pieejama.</translation>
 <translation id="3026237328237090306">Iestatīt mobilo datu pārraidi</translation>
 <translation id="785750925697875037">Skatīt mobilo kontu</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Atspējot Bluetooth</translation>
 <translation id="3126069444801937830">Restartēt, lai atjauninātu</translation>
 <translation id="735745346212279324">VPN ir atvienots</translation>
+<translation id="7320906967354320621">Dīkstāve</translation>
 <translation id="6303423059719347535">Akumulatora uzlādes līmenis: <ph name="PERCENTAGE"/>%</translation>
+<translation id="2778346081696727092">Neizdevās autentificēt ievadīto lietotājvārdu un paroli</translation>
 <translation id="3294437725009624529">Viesis</translation>
 <translation id="8190698733819146287">Pielāgot valodas un ievadi...</translation>
-<translation id="598295083618286569">Bluetooth savienojums ir izveidots</translation>
+<translation id="7170041865419449892">Ārpus diapazona</translation>
+<translation id="4804818685124855865">Atvienot</translation>
 <translation id="5222676887888702881">Izrakstīties</translation>
+<translation id="2688477613306174402">Konfigurācija</translation>
+<translation id="1272079795634619415">Apturēt</translation>
 <translation id="4957722034734105353">Uzzināt vairāk...</translation>
 <translation id="2964193600955408481">Atspējot Wi-Fi</translation>
 <translation id="811680302244032017">Pievienot ierīci...</translation>
 <translation id="2509468283778169019">Funkcija Caps Lock ir ieslēgta</translation>
 <translation id="3892641579809465218">Iekšējais displejs</translation>
 <translation id="7823564328645135659">Pēc jūsu iestatījumu sinhronizēšanas valoda ir mainīta no <ph name="FROM_LOCALE"/> uz <ph name="TO_LOCALE"/>.</translation>
+<translation id="3368922792935385530">pievienots</translation>
 <translation id="8340999562596018839">Balss komentāri</translation>
 <translation id="8654520615680304441">Ieslēgt Wi-Fi...</translation>
 <translation id="5825747213122829519">Ievades metode ir mainīta uz <ph name="INPUT_METHOD_ID"/>.
 Lai to pārslēgtu, nospiediet taustiņu kombināciju Shift+Alt.</translation>
 <translation id="2562916301614567480">Privāts tīkls</translation>
 <translation id="6549021752953852991">Mobilais tīkls nav pieejams.</translation>
+<translation id="4379753398862151997">Diemžēl monitoru nevar izmantot (tas netiek atbalstīts).</translation>
 <translation id="6426039856985689743">Atspējot mobilo datu pārraidi</translation>
 <translation id="3087734570205094154">Apakša</translation>
 <translation id="5271016907025319479">VPN nav konfigurēts.</translation>
-<translation id="1298695107722797780">Pabeigt publisko\nsesiju</translation>
-<translation id="3232695630852378748">Bluetooth iestatījumi...</translation>
+<translation id="6803622936009808957">Nevarēja spoguļot displejus, jo netika atrasta atbalstīta izšķirtspēja. Tā vietā tika aktivizēts paplašinātās darbvirsmas režīms.</translation>
 <translation id="1480041086352807611">Demonstrācijas režīms</translation>
 <translation id="3626637461649818317">Atlikums: <ph name="PERCENTAGE"/>%</translation>
 <translation id="9089416786594320554">Ievades metodes</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">Izslēgšana</translation>
 <translation id="4430019312045809116">Skaļums</translation>
+<translation id="4442424173763614572">DNS uzmeklēšana neizdevās</translation>
 <translation id="6356500677799115505">Akumulators ir pilnībā uzlādēts, un tiek turpināta tā uzlāde.</translation>
 <translation id="7874779702599364982">Notiek mobilo sakaru tīklu meklēšana...</translation>
+<translation id="583281660410589416">Nezināms</translation>
 <translation id="1383876407941801731">Meklēšana</translation>
+<translation id="7468789844759750875">Lai iegādātos citus datus, apmeklējiet <ph name="NAME"/> aktivizācijas portālu.</translation>
 <translation id="3901991538546252627">Notiek savienojuma izveide ar <ph name="NAME"/></translation>
 <translation id="2204305834655267233">Tīkla informācija</translation>
 <translation id="1621499497873603021">Atlikušais akumulatora darbības laiks: <ph name="TIME_LEFT"/>.</translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">Iepriekšējā izvēlne</translation>
 <translation id="1346748346194534595">Pa labi</translation>
 <translation id="8528322925433439945">Mobilās ierīces...</translation>
+<translation id="7049357003967926684">Saistība</translation>
 <translation id="8428213095426709021">Iestatījumi</translation>
-<translation id="2472320577759310817">Bluetooth savienojums ir izslēgts.</translation>
 <translation id="2372145515558759244">Notiek lietotņu sinhronizēšana...</translation>
+<translation id="7256405249507348194">Neatpazīta kļūda: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">AAA pārbaude neizdevās</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: notiek atvienošana...</translation>
 <translation id="8456362689280298700">Atlikušais uzlādes laiks: <ph name="HOUR"/>:<ph name="MINUTE"/></translation>
 <translation id="5787281376604286451">Balss komentāri ir iespējoti.
 Nospiediet Ctrl+Alt+Z, lai tos atspējotu.</translation>
 <translation id="4479639480957787382">tīkls Ethernet</translation>
+<translation id="6312403991423642364">Nezināma tīkla kļūda</translation>
 <translation id="1467432559032391204">Pa kreisi</translation>
 <translation id="5543001071567407895">Īsziņa</translation>
+<translation id="2354174487190027830">Notiek <ph name="NAME"/> aktivizēšana.</translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">Maksimizēt</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: notiek savienojuma izveide...</translation>
+<translation id="8639033665604704195">Neizdevās autentificēt, izmantojot ievadīto iepriekš kopīgoto atslēgu</translation>
 <translation id="252373100621549798">Nezināms displejs</translation>
 <translation id="1882897271359938046">Spoguļo šeit: <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Bloķēt</translation>
 <translation id="2805756323405976993">Lietotnes</translation>
-<translation id="2482878487686419369">Paziņojumi</translation>
+<translation id="1512064327686280138">Aktivizācijas kļūme</translation>
+<translation id="5097002363526479830">Neizdevās izveidot savienojumu ar tīklu <ph name="NAME"/>: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi tīkls ir izslēgts.</translation>
-<translation id="2872961005593481000">Beidzēt</translation>
+<translation id="8036518327127111261">Neizdevās autentificēt, izmantojot norādīto sertifikātu</translation>
 <translation id="8132793192354020517">Savienots ar <ph name="NAME"/></translation>
 <translation id="7052914147756339792">Iestatīt fona tapeti...</translation>
-<translation id="2739500853984626550">Nav pieejama neviena Bluetooth ierīce.</translation>
-<translation id="2666092431469916601">Augša</translation>
+<translation id="8678698760965522072">Tiešsaistes statuss</translation>
+<translation id="1119447706177454957">Iekšēja kļūda</translation>
 <translation id="3019353588588144572">Pilnīgais uzlādei nepieciešamais laiks: <ph name="TIME_REMAINING"/>.</translation>
 <translation id="3473479545200714844">Ekrāna lupa</translation>
+<translation id="7005812687360380971">Kļūme</translation>
 <translation id="1602076796624386989">Iespējot mobilo datu pārraidi</translation>
 <translation id="6981982820502123353">Pieejamība</translation>
 <translation id="3157931365184549694">Atjaunot</translation>
+<translation id="4274292172790327596">Neatpazīta kļūda</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Notiek ierīču meklēšana...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Notiek Wi-Fi tīklu meklēšana...</translation>
+<translation id="7229570126336867161">Nepieciešams EVDO</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> ir publiska sesija, kas tiek pārvaldīta domēnā <ph name="DOMAIN"/>.</translation>
 <translation id="7029814467594812963">Iziet no sesijas</translation>
 <translation id="8454013096329229812">Wi-Fi tīkls ir ieslēgts.</translation>
 <translation id="4872237917498892622">Alt+Meklēt vai Shift</translation>
 <translation id="2983818520079887040">Iestatījumi...</translation>
-<translation id="5467313780247887226">Pievienotajos monitoros nevar dublēt attēlu. Nav atrasta atbilstoša izšķirtspēja.</translation>
+<translation id="8927026611342028580">Ir pieprasīta savienojuma izveide.</translation>
+<translation id="8300849813060516376">OTASP neizdevās</translation>
 <translation id="2792498699870441125">Alt+Meklēt</translation>
 <translation id="8660803626959853127">Notiek <ph name="COUNT"/> faila(-u) sinhronizēšana</translation>
 <translation id="639644700271529076">Funkcija CAPS LOCK ir izslēgta.</translation>
-<translation id="4101192585425716296">Ziņojumu centrs</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: notiek aktivizēšana...</translation>
+<translation id="1391854757121130358">Iespējams, esat jau izmantojis savu mobilo datu atļauju.</translation>
 <translation id="4864165860509564259">Palaidēja novietojums</translation>
 <translation id="7593891976182323525">Meklēt vai Shift</translation>
 <translation id="7649070708921625228">Palīdzība</translation>
 <translation id="3050422059534974565">Ir ieslēgts BURTSLĒGS.
 Lai atceltu tā funkcionalitāti, nospiediet Meklēt vai Shift.</translation>
 <translation id="397105322502079400">Notiek aprēķināšana...</translation>
+<translation id="158849752021629804">Nepieciešams mājas tīkls</translation>
+<translation id="6857811139397017780">Aktivizēt <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">DHCP uzmeklēšana neizdevās</translation>
+<translation id="6692173217867674490">Neatbilstoša ieejas frāze</translation>
 <translation id="6165508094623778733">Uzziniet vairāk</translation>
+<translation id="9046895021617826162">Savienojums neizdevās</translation>
+<translation id="973896785707726617">Atlikušais laiks līdz šīs sesijas beigām: <ph name="SESSION_TIME_REMAINING"/>. Jūs tiksiet automātiski izrakstīts.</translation>
+<translation id="8372369524088641025">Neatbilstoša WEP atslēga</translation>
+<translation id="6636709850131805001">Neatpazīts stāvoklis</translation>
 <translation id="3573179567135747900">Mainīt atpakaļ uz <ph name="FROM_LOCALE"/> (nepieciešama restartēšana)</translation>
 <translation id="8103386449138765447">Īsziņas: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Google diska iestatījumi...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">Nav tīkla</translation>
 <translation id="5941711191222866238">Minimizēt</translation>
 <translation id="6911468394164995108">Pievienoties citam...</translation>
-<translation id="6843725295806269523">izslēgt skaņu</translation>
 <translation id="412065659894267608">Līdz pilnīgai uzlādei atlikušais laiks: <ph name="HOUR"/> h <ph name="MINUTE"/> min</translation>
 <translation id="6359806961507272919">SMS no <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Mobilo sakaru operators</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_ml.xtb b/ash/strings/ash_strings_ml.xtb
index 6924139..0238794 100644
--- a/ash/strings/ash_strings_ml.xtb
+++ b/ash/strings/ash_strings_ml.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">ബാറ്ററി നിറഞ്ഞു</translation>
 <translation id="5250713215130379958">ലോഞ്ചർ യാന്ത്രികമായി മറയ്‌ക്കുക</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/>, <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">പോര്‍ട്ടല്‍ അവസ്ഥ</translation>
 <translation id="30155388420722288">ഓവർഫ്ലോ ബട്ടൺ</translation>
 <translation id="5571066253365925590">Bluetooth പ്രാപ്‌തമാക്കി</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">പ്രോക്‌സി...</translation>
 <translation id="938582441709398163">കീബോര്‍ഡ് ഓവര്‍ലേ</translation>
 <translation id="6979158407327259162">Google ഡ്രൈവ്</translation>
+<translation id="6943836128787782965">HTTP പരാജയപ്പെട്ടു</translation>
 <translation id="2297568595583585744">സ്റ്റാറ്റസ് ട്രേ</translation>
+<translation id="1661867754829461514">PIN കാണാനില്ല</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: കണക്റ്റുചെയ്യുന്നു...</translation>
+<translation id="4237016987259239829">നെറ്റ്വര്‍ക്ക് കണക്ഷന്‍ പിശക്</translation>
 <translation id="2946640296642327832">Bluetooth പ്രാപ്‌തമാക്കുക</translation>
 <translation id="6459472438155181876">സ്‌ക്രീൻ <ph name="DISPLAY_NAME"/> എന്നതിലേക്ക് വികസിപ്പിക്കുന്നു</translation>
 <translation id="8206859287963243715">സെല്ലുലാര്‍‌</translation>
 <translation id="6596816719288285829">IP വിലാസം</translation>
+<translation id="4508265954913339219">സജീവമാക്കല്‍ പരാജയപ്പെട്ടു</translation>
 <translation id="1812696562331527143">നിങ്ങളുടെ ഇൻപുട്ട് രീതി <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>മൂന്നാം കക്ഷി<ph name="END_LINK"/>) എന്നതിലേയ്‌ക്ക് മാറ്റി.
 സ്വിച്ചുചെയ്യുന്നതിന് Shift + Alt അമർത്തുക.</translation>
-<translation id="5233638681132016545">പുതിയ ടാബ്</translation>
 <translation id="3846575436967432996">നെറ്റ്‌വർക്ക് വിവരങ്ങളൊന്നും ലഭ്യമല്ല</translation>
 <translation id="3026237328237090306">മൊബൈൽ ഡാറ്റ സജ്ജമാക്കുക</translation>
 <translation id="785750925697875037">മൊബൈൽ അക്കൗണ്ട് കാണുക</translation>
@@ -31,36 +35,45 @@
 <translation id="7864539943188674973">Bluetooth അപ്രാപ്‌തമാക്കുക</translation>
 <translation id="3126069444801937830">അപ്‌ഡേറ്റുചെയ്യുന്നതിന് പുനരാരംഭിക്കുക</translation>
 <translation id="735745346212279324">VPN വിച്ഛേദിച്ചു</translation>
+<translation id="7320906967354320621">നിഷ്ക്രിയം</translation>
 <translation id="6303423059719347535">ബാറ്ററി <ph name="PERCENTAGE"/>% പൂർണ്ണമാണ്</translation>
+<translation id="2778346081696727092">നൽകിയ ഉപയോക്തൃനാമം അല്ലെങ്കിൽ പാസ്‌വേഡ് ഉപയോഗിച്ച് പ്രാമാണീകരിക്കുന്നത് പരാജയപ്പെട്ടു</translation>
 <translation id="3294437725009624529">അതിഥി</translation>
 <translation id="8190698733819146287">ഭാഷകള്‍‌ ഇച്ഛാനുസൃതമാക്കി നല്‍‌കുക...</translation>
-<translation id="598295083618286569">Bluetooth കണക്‌റ്റുചെയ്‌തു</translation>
+<translation id="7170041865419449892">പരിധിയ്ക്ക് പുറത്താണ്</translation>
+<translation id="4804818685124855865">വിച്ഛേദിക്കുക</translation>
 <translation id="5222676887888702881">പുറത്തുകടക്കുക</translation>
+<translation id="2688477613306174402">ക്രമീകരണം</translation>
+<translation id="1272079795634619415">നിര്‍ത്തുക</translation>
 <translation id="4957722034734105353">കൂടുതലറിയുക...</translation>
 <translation id="2964193600955408481">Wi-Fi അപ്രാപ്‌തമാക്കുക</translation>
 <translation id="811680302244032017">ഉപകരണം ചേർക്കുക...</translation>
 <translation id="2509468283778169019">CAPS LOCK ഓൺ ആണ്</translation>
 <translation id="3892641579809465218">ആന്തരിക പ്രദർശനം</translation>
 <translation id="7823564328645135659">നിങ്ങളുടെ ക്രമീകരണങ്ങള്‍ സമന്വയിപ്പിച്ചതിന് ശേഷം ഭാഷ &quot;<ph name="FROM_LOCALE"/>&quot; എന്നതില്‍ നിന്ന് &quot;<ph name="TO_LOCALE"/>&quot; എന്നതിലേക്ക് മാറി.</translation>
+<translation id="3368922792935385530">ബന്ധിപ്പിച്ചു</translation>
 <translation id="8340999562596018839">സംഭാഷണ ഫീഡ്‌ബാക്ക്</translation>
 <translation id="8654520615680304441">Wi-Fi ഓണാക്കുക...</translation>
 <translation id="5825747213122829519">നിങ്ങളുടെ ഇൻപുട്ട് രീതി <ph name="INPUT_METHOD_ID"/> എന്നതിലേയ്‌ക്ക് മാറ്റി. സ്വിച്ചുചെയ്യുന്നതിന് Shift + Alt അമർത്തുക.</translation>
 <translation id="2562916301614567480">സ്വകാര്യ നെറ്റ്‌വർക്ക്</translation>
 <translation id="6549021752953852991">സെല്ലുലാർ നെറ്റ്‌വർക്കൊന്നും ലഭ്യമല്ല</translation>
+<translation id="4379753398862151997">പ്രിയ മോണിറ്റർ, ഇത് നമുക്കിടയിൽ പ്രവർത്തിക്കുന്നില്ല. (ആ മോണിറ്റർ പിന്തുണയ്‌ക്കുന്നില്ല)</translation>
 <translation id="6426039856985689743">മൊബൈൽ ഡാറ്റ അപ്രാപ്‌തമാക്കുക</translation>
 <translation id="3087734570205094154">താഴെ</translation>
 <translation id="5271016907025319479">VPN കോൺഫിഗർ ചെയ്‌തില്ല.</translation>
-<translation id="1298695107722797780">എല്ലാവർക്കുമുള്ള\nസെഷൻ അവസാനിപ്പിക്കുക</translation>
-<translation id="3232695630852378748">Bluetooth ക്രമീകരണങ്ങൾ...</translation>
+<translation id="6803622936009808957">പിന്തുണയ്‌ക്കുന്ന മിഴിവുകൾ കണ്ടെത്താത്തതിനാൽ പ്രദർശനങ്ങൾ പ്രതിഫലിപ്പിക്കാനായില്ല. പകരം വിപുലീകൃത ഡെസ്‌ക്‌ടോപ്പ് നൽകി.</translation>
 <translation id="1480041086352807611">ഡെമോ മോഡ്</translation>
 <translation id="3626637461649818317"><ph name="PERCENTAGE"/>% ശേഷിക്കുന്നു</translation>
 <translation id="9089416786594320554">ഇൻപുട്ട്  രീതികൾ</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">ഷട്ട്‌ഡൗൺ ചെയ്യുക</translation>
 <translation id="4430019312045809116">അളവ്</translation>
+<translation id="4442424173763614572">DNS തിരയല്‍ പരാജയപ്പെട്ടു</translation>
 <translation id="6356500677799115505">ബാറ്ററി പൂർണ്ണവും ചാർജ്ജ് ചെയ്യുകയുമാണ്.</translation>
 <translation id="7874779702599364982">സെല്ലുലാർ നെറ്റ്‌വർക്കുകൾക്കായി തിരയുന്നു...</translation>
+<translation id="583281660410589416">അജ്ഞാതം</translation>
 <translation id="1383876407941801731">തിരയൂ</translation>
+<translation id="7468789844759750875">കൂടുതൽ ഡാറ്റ വാങ്ങുന്നതിനായി <ph name="NAME"/> സജീവമാക്കൽ പോർട്ടൽ സന്ദർശിക്കുക.</translation>
 <translation id="3901991538546252627"><ph name="NAME"/> എന്നതിലേക്ക് കണക്റ്റുചെയ്യുന്നു</translation>
 <translation id="2204305834655267233">നെറ്റ്‌വർക്ക് വിവരം</translation>
 <translation id="1621499497873603021">ബാറ്ററി ശൂന്യമാകുന്നതിന് ശേഷിക്കുന്ന സമയം, <ph name="TIME_LEFT"/></translation>
@@ -69,56 +82,75 @@
 <translation id="8308637677604853869">മുൻ മെനു</translation>
 <translation id="1346748346194534595">ശരി</translation>
 <translation id="8528322925433439945">മൊബൈൽ ...</translation>
+<translation id="7049357003967926684">അസ്സോസിയേഷന്‍</translation>
 <translation id="8428213095426709021">ക്രമീകരണങ്ങള്‍</translation>
-<translation id="2472320577759310817">Bluetooth ഓഫുചെയ്‌തു.</translation>
 <translation id="2372145515558759244">അപ്ലിക്കേഷനുകൾ സമന്വയിപ്പിക്കുന്നു...</translation>
+<translation id="7256405249507348194">തിരിച്ചറിയാനാകാത്ത പിശക്: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">AAA പരിശോധന പരാജയപ്പെട്ടു</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: വിച്ഛേദിക്കുന്നു...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> പൂര്‍‌ണ്ണമാകുന്നതുവരെ</translation>
 <translation id="5787281376604286451">സംഭാഷണ ഫീഡ്‌ബാക്ക് പ്രാപ്‌തമാക്കിയിരിക്കുന്നു.
 ഇത് അപ്രാപ്‌തമാക്കാൻ Ctrl+Alt+Z അമർത്തുക.</translation>
 <translation id="4479639480957787382">എതെര്‍‌നെറ്റ്</translation>
+<translation id="6312403991423642364">അറിയാത്ത നെറ്റ്‌വര്‍ക്ക് പിശക്</translation>
 <translation id="1467432559032391204">ഇടത്</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830"><ph name="NAME"/> സജീവമാക്കുന്നു</translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">വലുതാക്കുക</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: കണക്റ്റുചെയ്യുന്നു...</translation>
+<translation id="8639033665604704195">നൽകിയ നേരത്തെ പങ്കിട്ട കീ ഉപയോഗിച്ച് പ്രാമാണീകരിക്കുന്നത് പരാജയപ്പെട്ടു</translation>
 <translation id="252373100621549798">അജ്ഞാത പ്രദർശനം</translation>
 <translation id="1882897271359938046"><ph name="DISPLAY_NAME"/> എന്നതിലേക്ക് മിറർചെയ്യുന്നു</translation>
 <translation id="3784455785234192852">ലോക്കുചെയ്യുക</translation>
 <translation id="2805756323405976993">അപ്ലിക്കേഷനുകള്‍</translation>
-<translation id="2482878487686419369">വിജ്ഞാപനങ്ങള്‍‌</translation>
+<translation id="1512064327686280138">സജീവമാക്കല്‍ പരാജയപ്പെട്ടു</translation>
+<translation id="5097002363526479830">'<ph name="NAME"/>' നെറ്റ്‌വര്‍‌ക്കിലേക്ക് ബന്ധിപ്പിക്കുന്നതിൽ പരാജയപ്പെട്ടു: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi ഓഫുചെയ്‌തു.</translation>
-<translation id="2872961005593481000">അടയ്ക്കുക</translation>
+<translation id="8036518327127111261">നൽകിയ സർട്ടിഫിക്കറ്റ് ഉപയോഗിച്ച് പ്രാമാണീകരിക്കുന്നതിൽ പരാജയപ്പെട്ടു</translation>
 <translation id="8132793192354020517"><ph name="NAME"/> എന്നതിലേക്ക് ബന്ധിപ്പിച്ചു</translation>
 <translation id="7052914147756339792">വാൾപേപ്പർ സജ്ജമാക്കുക...</translation>
-<translation id="2739500853984626550">Bluetooth ഉപകരണങ്ങളൊന്നും ലഭ്യമല്ല</translation>
-<translation id="2666092431469916601">മുകളിലേക്ക്</translation>
+<translation id="8678698760965522072">ഓണ്‍ലൈന്‍ അവസ്ഥ</translation>
+<translation id="1119447706177454957">ആന്തരിക പിശക്</translation>
 <translation id="3019353588588144572">ബാറ്ററി പൂർണ്ണമായി ചാർജ്ജാകുന്നതിന് ശേഷിക്കുന്ന സമയം, <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">സ്‌ക്രീൻ മാഗ്‌നിഫയർ</translation>
+<translation id="7005812687360380971">പരാജയം</translation>
 <translation id="1602076796624386989">മൊബൈൽ ഡാറ്റ പ്രാപ്‌തമാക്കുക</translation>
 <translation id="6981982820502123353">പ്രവേശനക്ഷമത</translation>
 <translation id="3157931365184549694">പുനസ്ഥാപിക്കുക</translation>
+<translation id="4274292172790327596">തിരിച്ചറിയാത്ത പിശക്</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">ഉപകരണങ്ങൾക്കായി സ്‌കാൻ ചെയ്യുന്നു...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Wi-Fi ശൃംഖലകള്‍ക്കായി തിരയുന്നു...</translation>
+<translation id="7229570126336867161">EVDO ആവശ്യമുണ്ട്</translation>
 <translation id="2999742336789313416"><ph name="DOMAIN"/> നിയന്ത്രിക്കുന്ന എല്ലാവർക്കുമുള്ള ഒരു സെഷനാണ് <ph name="DISPLAY_NAME"/></translation>
 <translation id="7029814467594812963">സെഷനിൽ നിന്ന് പുറത്തുകടക്കുക</translation>
 <translation id="8454013096329229812">Wi-Fi ഓൺ ചെയ്‌തു.</translation>
 <translation id="4872237917498892622">Alt+തിരയൽ അല്ലെങ്കിൽ Shift</translation>
 <translation id="2983818520079887040">ക്രമീകരണങ്ങള്‍...</translation>
-<translation id="5467313780247887226">അറ്റാച്ചുചെയ്‌ത മോണിറ്ററിൽ ചിത്രത്തിന്റെ തനിപ്പകർപ്പ് കാണിക്കാൻ കഴിയില്ല. പൊരുത്തമുള്ള മിഴിവൊന്നും കണ്ടെത്തിയില്ല.</translation>
+<translation id="8927026611342028580">കണക്റ്റുചെയ്യാൻ അഭ്യർത്ഥിച്ചു</translation>
+<translation id="8300849813060516376">OTASP പരാജയപ്പെട്ടു</translation>
 <translation id="2792498699870441125">Alt+തിരയൽ</translation>
 <translation id="8660803626959853127"><ph name="COUNT"/> ഫയൽ(കൾ) സമന്വയിപ്പിക്കുന്നു</translation>
 <translation id="639644700271529076">CAPS LOCK ഓഫാണ്</translation>
-<translation id="4101192585425716296">സന്ദേശ കേന്ദ്രം</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: സജീവമാക്കുന്നു...</translation>
+<translation id="1391854757121130358">നിങ്ങൾ മൊബൈൽ ഡാറ്റ അലവൻസ് ഉപയോഗിച്ചിരിക്കാനിടയുണ്ട്.</translation>
 <translation id="4864165860509564259">ലോഞ്ചറിന്റെ സ്ഥാനം</translation>
 <translation id="7593891976182323525">തിരയൽ അല്ലെങ്കിൽ Shift</translation>
 <translation id="7649070708921625228">സഹായം</translation>
 <translation id="3050422059534974565">CAPS LOCK ഓൺ ആണ്.
 റദ്ദാക്കുന്നതിന് തിരയൽ അല്ലെങ്കിൽ Shift അമർത്തുക.</translation>
 <translation id="397105322502079400">കണക്കാക്കുന്നു...</translation>
+<translation id="158849752021629804">ഹോം നെറ്റ്‍വര്‍ക്ക് ആവശ്യമുണ്ട്</translation>
+<translation id="6857811139397017780"><ph name="NETWORKSERVICE"/> സജീവമാക്കുക</translation>
+<translation id="5864471791310927901">DHCP തിരയല്‍ പരാജയപ്പെട്ടു</translation>
+<translation id="6692173217867674490">മോശം പാസ്ഫ്രെയ്സ്</translation>
 <translation id="6165508094623778733">കൂടുതല്‍ മനസിലാക്കുക</translation>
+<translation id="9046895021617826162">ബന്ധിപ്പിക്കല്‍ പരാജയപ്പെട്ടു</translation>
+<translation id="973896785707726617"><ph name="SESSION_TIME_REMAINING"/> ആകുമ്പോൾ ഈ സെഷൻ അവസാനിക്കും. നിങ്ങൾ യാന്ത്രികമായി സൈൻ ഔട്ടാകും.</translation>
+<translation id="8372369524088641025">മോശം WEP കീ</translation>
+<translation id="6636709850131805001">തിരിച്ചറിയാത്ത അവസ്ഥ</translation>
 <translation id="3573179567135747900">&quot;<ph name="FROM_LOCALE"/>&quot; എന്നതിലേക്ക് തിരികെ മാറുക (റീസ്റ്റാര്‍ട്ട് ആവശ്യമാണ്)</translation>
 <translation id="8103386449138765447">SMS സന്ദേശങ്ങൾ: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Google ഡ്രൈവ് ക്രമീകരണങ്ങൾ...</translation>
@@ -129,7 +161,7 @@
 <translation id="8000066093800657092">നെറ്റ്‍വര്‍ക്ക് ഇല്ല</translation>
 <translation id="5941711191222866238">ചെറുതാക്കുക‍</translation>
 <translation id="6911468394164995108">മറ്റുള്ളവ ചേർക്കുക...</translation>
-<translation id="6843725295806269523">നിശബ്‌ദമാക്കുക</translation>
 <translation id="412065659894267608">പൂർണ്ണമായും ചാർജാകുന്നതിന് <ph name="HOUR"/>മ <ph name="MINUTE"/>മി</translation>
 <translation id="6359806961507272919"><ph name="PHONE_NUMBER"/> എന്നതില്‍ നിന്നുള്ള SMS</translation>
+<translation id="1244147615850840081">കാരിയര്‍</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_mr.xtb b/ash/strings/ash_strings_mr.xtb
index 1bebb44..b1002d9 100644
--- a/ash/strings/ash_strings_mr.xtb
+++ b/ash/strings/ash_strings_mr.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">बॅटरी भरली</translation>
 <translation id="5250713215130379958">लाँचर स्वयं लपवा</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> आणि <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">पोर्टल राज्य</translation>
 <translation id="30155388420722288">ओव्हरफ्लो बटण</translation>
 <translation id="5571066253365925590">Bluetooth सक्षम</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">प्रॉक्सी...</translation>
 <translation id="938582441709398163">कीबोर्ड आच्छादन</translation>
 <translation id="6979158407327259162">Google ड्राइव्ह</translation>
+<translation id="6943836128787782965">HTTP अयशस्वी झाले</translation>
 <translation id="2297568595583585744">स्थिती ट्रे</translation>
+<translation id="1661867754829461514">PIN गहाळ आहे </translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: कनेक्ट करत आहे...</translation>
+<translation id="4237016987259239829">नेटवर्क कनेक्शन त्रुटी</translation>
 <translation id="2946640296642327832">Bluetooth सक्षम करा</translation>
 <translation id="6459472438155181876"><ph name="DISPLAY_NAME"/> मध्ये स्क्रीन विस्तृत करत आहे</translation>
 <translation id="8206859287963243715">सेल्यूलर</translation>
 <translation id="6596816719288285829">IP पत्ता</translation>
+<translation id="4508265954913339219">सक्रियन अयशस्वी</translation>
 <translation id="1812696562331527143">आपली इनपुट पद्धत <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>तृतीय पक्षावर<ph name="END_LINK"/>)बदलली.
 स्‍विच करण्‍यासाठी Shift + Alt दाबा.</translation>
-<translation id="5233638681132016545">नवीन टॅब</translation>
 <translation id="3846575436967432996">कोणतीही नेटवर्क माहिती उपलब्ध नाही</translation>
 <translation id="3026237328237090306">मोबाइल डेटा सेटअप करा</translation>
 <translation id="785750925697875037">मोबाइल खाते पहा</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Bluetooth अक्षम करा</translation>
 <translation id="3126069444801937830">अद्यतनासाठी पुनर्प्रारंभ करा</translation>
 <translation id="735745346212279324">VPN डिस्कनेक्ट केले</translation>
+<translation id="7320906967354320621">निष्क्रिय</translation>
 <translation id="6303423059719347535">बॅटरी <ph name="PERCENTAGE"/>% भरली आहे</translation>
+<translation id="2778346081696727092">प्रदान केलेल्या वापरकर्तानाव किंवा संकेतशब्दासह प्रमाणिकरण करण्‍यात अयशस्वी झाले</translation>
 <translation id="3294437725009624529">अतिथी</translation>
 <translation id="8190698733819146287">भाषा आणि इनपुट सानुकूलित करा...</translation>
-<translation id="598295083618286569">Bluetooth कनेक्ट केले</translation>
+<translation id="7170041865419449892">परिक्षेत्राबाहेर</translation>
+<translation id="4804818685124855865">‍डिस्कनेक्ट</translation>
 <translation id="5222676887888702881">साइन आउट करा</translation>
+<translation id="2688477613306174402">कॉन्फिगरेशन</translation>
+<translation id="1272079795634619415">थांबा</translation>
 <translation id="4957722034734105353">अधिक जाणून घ्या...</translation>
 <translation id="2964193600955408481">Wi-Fi अक्षम करा</translation>
 <translation id="811680302244032017">डिव्हाइस जोडा...</translation>
 <translation id="2509468283778169019">CAPS LOCK सुरु आहे</translation>
 <translation id="3892641579809465218">अंतर्गत डिस्प्ले</translation>
 <translation id="7823564328645135659">आपली सेटिंग्ज समक्रमित केल्यानंतर भाषा &quot;<ph name="FROM_LOCALE"/>&quot; मधून &quot;<ph name="TO_LOCALE"/>&quot; मध्ये बदलली आहे.</translation>
+<translation id="3368922792935385530">कनेक्ट केले</translation>
 <translation id="8340999562596018839">संभाषण अभिप्राय</translation>
 <translation id="8654520615680304441">Wi-Fi चालू करा...</translation>
 <translation id="5825747213122829519">आपली इनपुट पद्धत <ph name="INPUT_METHOD_ID"/> मध्ये बदलली आहे.
 स्विच करण्यासाठी Shift + Alt दाबा.</translation>
 <translation id="2562916301614567480">खाजगी नेटवर्क</translation>
 <translation id="6549021752953852991">कोणतेही सेल्युलर नेटवर्क उपलब्ध नाही</translation>
+<translation id="4379753398862151997">प्रिय मॉनिटर, हे आपल्या दरम्यान कार्य करत नाही. (तो मॉनिटर समर्थित नाही)</translation>
 <translation id="6426039856985689743">मोबाइल डेटा अक्षम करा</translation>
 <translation id="3087734570205094154">तळाकडील</translation>
 <translation id="5271016907025319479">VPN कॉन्फिगर केलेले नाही.</translation>
-<translation id="1298695107722797780">सार्वजनिक\nसत्र समाप्त करा</translation>
-<translation id="3232695630852378748">Bluetooth सेटिंग्ज...</translation>
+<translation id="6803622936009808957">समर्थित रिजोल्यूशन न आढळल्यामुळे प्रदर्शने मिरर करू शकली नाहीत. त्याऐवजी विस्तारित डेस्कटॉप प्रविष्ट केला.</translation>
 <translation id="1480041086352807611">डेमो मोड</translation>
 <translation id="3626637461649818317"><ph name="PERCENTAGE"/>% उर्वरित</translation>
 <translation id="9089416786594320554">इनपुट पद्धती</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">बंद करा</translation>
 <translation id="4430019312045809116">व्हॉल्यूम</translation>
+<translation id="4442424173763614572">DNS लुकअप अयश्सवी</translation>
 <translation id="6356500677799115505">बॅटरी भरली आहे आणि चार्ज होत आहे</translation>
 <translation id="7874779702599364982">सेल्यूलर नेटवर्कसाठी शोधत आहे...</translation>
+<translation id="583281660410589416">अज्ञात</translation>
 <translation id="1383876407941801731">शोध</translation>
+<translation id="7468789844759750875">अधिक डेटा विकत घेण्यासाठी <ph name="NAME"/> सक्रियण पोर्टलला भेट द्या.</translation>
 <translation id="3901991538546252627"><ph name="NAME"/> वर कनेक्ट करीत आहे</translation>
 <translation id="2204305834655267233">नेटवर्क माहिती</translation>
 <translation id="1621499497873603021">बॅटरी रिक्त होईपर्यंत शिल्लक वेळ, <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">मागील मेनू</translation>
 <translation id="1346748346194534595">उजवे</translation>
 <translation id="8528322925433439945">मोबाइल ...</translation>
+<translation id="7049357003967926684">संघटना</translation>
 <translation id="8428213095426709021">सेटिंग्ज</translation>
-<translation id="2472320577759310817">Bluetooth बंद आहे.</translation>
 <translation id="2372145515558759244">अ‍ॅप्स समक्रमित करत आहे...</translation>
+<translation id="7256405249507348194">अपरिचित त्रुटी: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">AAA तपास अयशस्वी</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: डिस्कनेक्ट करत आहे...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> पूर्ण होईपर्यंत</translation>
 <translation id="5787281376604286451">संभाषण अभिप्राय सक्षम केला आहे.
 अक्षम करण्‍यासाठी Ctrl+Alt+Z दाबा.</translation>
 <translation id="4479639480957787382">इथरनेट</translation>
+<translation id="6312403991423642364">अज्ञात नेटवर्क त्रुटी</translation>
 <translation id="1467432559032391204">डावे</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830"><ph name="NAME"/> सक्रिय करत आहे</translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">वाढवा</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: कनेक्ट करत आहे...</translation>
+<translation id="8639033665604704195">मागे सामयिक केलेल्या की सह प्रमाणिकरण करण्‍यात अयशस्वी</translation>
 <translation id="252373100621549798">अज्ञात प्रदर्शन</translation>
 <translation id="1882897271359938046"><ph name="DISPLAY_NAME"/> वर मिरर करत आहे</translation>
 <translation id="3784455785234192852">लॉक करा</translation>
 <translation id="2805756323405976993">अनुप्रयोग</translation>
-<translation id="2482878487686419369">सूचना</translation>
+<translation id="1512064327686280138">सक्रियन अयशस्वी</translation>
+<translation id="5097002363526479830">'<ph name="NAME"/>': नेटवर्कशी कनेक्ट करण्यात अयशस्वी. <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi बंद आहे.</translation>
-<translation id="2872961005593481000">बंद करा</translation>
+<translation id="8036518327127111261">प्रदान केलेल्या प्रमाणपत्रासह प्रमाणिकृत करण्‍यात अयशस्‍वी</translation>
 <translation id="8132793192354020517"><ph name="NAME"/> शी कनेक्ट केलेले</translation>
 <translation id="7052914147756339792">वॉलपेपर सेट करा...</translation>
-<translation id="2739500853984626550">कोणतेही bluetooth डिव्हाइसेस उपलब्ध नाहीत</translation>
-<translation id="2666092431469916601">शीर्ष</translation>
+<translation id="8678698760965522072">ऑनलाइन राज्य</translation>
+<translation id="1119447706177454957">अंतर्गत त्रुटी</translation>
 <translation id="3019353588588144572">बॅटरी पूर्णपणे चार्ज होईपर्यंत उर्वरित वेळ, <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">स्क्रीन भिंग</translation>
+<translation id="7005812687360380971">बिघाड</translation>
 <translation id="1602076796624386989">मोबाइल डेटा सक्षम करा</translation>
 <translation id="6981982820502123353">प्रवेशयोग्यता</translation>
 <translation id="3157931365184549694">पुनर्संचयित करा</translation>
+<translation id="4274292172790327596">अपरिचित त्रुटी</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">डिव्हाइसेससाठी स्कॅन करत आहे...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Wi-Fi नेटवर्कचा शोधत आहे...</translation>
+<translation id="7229570126336867161">EVDO आवश्यक आहे</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> हे <ph name="DOMAIN"/> द्वारे व्यवस्थापित कलेले एक सावर्जनिक सत्र आहे</translation>
 <translation id="7029814467594812963">सत्र निर्गमन करा</translation>
 <translation id="8454013096329229812">Wi-Fi चालू आहे.</translation>
 <translation id="4872237917498892622">Alt+Search किंवा Shift</translation>
 <translation id="2983818520079887040">सेटिंग्ज...</translation>
-<translation id="5467313780247887226">संलग्न केलेल्या मॉनिटरवर प्रतिमा डुप्लिकेट करू शकत नाही. कोणतेही जुळणारे रिजोल्यूशन आढळले नाही.</translation>
+<translation id="8927026611342028580">विनंती केलेले कनेक्ट करा</translation>
+<translation id="8300849813060516376">OTASP बिघडले</translation>
 <translation id="2792498699870441125">Alt+Search</translation>
 <translation id="8660803626959853127"><ph name="COUNT"/> फाईल(ली) समक्रमित करीत आहे</translation>
 <translation id="639644700271529076">CAPS LOCK बंद आहे</translation>
-<translation id="4101192585425716296">संदेश केंद्र</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: सक्रिय करत आहे...</translation>
+<translation id="1391854757121130358">आपण आपल्या मोबाईल डेटा भत्त्याचा वापर केला असेल.</translation>
 <translation id="4864165860509564259">लाँचर स्थिती</translation>
 <translation id="7593891976182323525">Search किंवा Shift</translation>
 <translation id="7649070708921625228">मदत</translation>
 <translation id="3050422059534974565">CAPS LOCK चालू आहे.
 रद्द करण्यासाठी Search किंवा Shift दाबा.</translation>
 <translation id="397105322502079400">गणना करत आहे...</translation>
+<translation id="158849752021629804">मुख्यपृष्ठ नेटवर्क आवश्यक</translation>
+<translation id="6857811139397017780">सक्रिय करा<ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">DHCP लुकअप अयशस्वी</translation>
+<translation id="6692173217867674490">चुकीचा सांकेतिक वाक्यांश</translation>
 <translation id="6165508094623778733">अधिक जाणून घ्या</translation>
+<translation id="9046895021617826162">कनेक्ट करण्यात अयशस्वी</translation>
+<translation id="973896785707726617">हे सत्र <ph name="SESSION_TIME_REMAINING"/> मध्ये समाप्त होईल. आपल्याला स्वयंचलितपणे साइन आउट केले जाईल.</translation>
+<translation id="8372369524088641025">खराब WEP की</translation>
+<translation id="6636709850131805001">अपरिचित राज्य</translation>
 <translation id="3573179567135747900">&quot;<ph name="FROM_LOCALE"/>&quot; मध्ये परत बदला (रीस्टार्ट करणे आवश्यक)</translation>
 <translation id="8103386449138765447">SMS संदेश: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Google ड्राइव्ह सेटिंग्ज...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">कोणतेही नेटवर्क नाही</translation>
 <translation id="5941711191222866238">लहान करा</translation>
 <translation id="6911468394164995108">दुसरीकडे सामील व्हा...</translation>
-<translation id="6843725295806269523">नि:शब्द करा</translation>
 <translation id="412065659894267608">पूर्ण होईपर्यंत  <ph name="HOUR"/>ता <ph name="MINUTE"/>मि</translation>
 <translation id="6359806961507272919"><ph name="PHONE_NUMBER"/> कडून SMS</translation>
+<translation id="1244147615850840081">कॅरियर</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_ms.xtb b/ash/strings/ash_strings_ms.xtb
index 4d9de51..6870312 100644
--- a/ash/strings/ash_strings_ms.xtb
+++ b/ash/strings/ash_strings_ms.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Bateri penuh</translation>
 <translation id="5250713215130379958">Autosembunyi pelancar</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> dan <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Keadaan portal</translation>
 <translation id="30155388420722288">Butang Limpahan</translation>
 <translation id="5571066253365925590">Bluetooth didayakan</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Proksi...</translation>
 <translation id="938582441709398163">Tindihan Papan Kekunci</translation>
 <translation id="6979158407327259162">Google Drive</translation>
+<translation id="6943836128787782965">HTTP gagal</translation>
 <translation id="2297568595583585744">Dulang status</translation>
+<translation id="1661867754829461514">PIN tiada</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: Menyambung...</translation>
+<translation id="4237016987259239829">Ralat Sambungan Rangkaian</translation>
 <translation id="2946640296642327832">Dayakan Bluetooth</translation>
 <translation id="6459472438155181876">Melanjutkan skrin ke <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Selular</translation>
 <translation id="6596816719288285829">Alamat IP</translation>
+<translation id="4508265954913339219">Pengaktifan gagal</translation>
 <translation id="1812696562331527143">Kaedah masukan anda telah ditukar kepada <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>pihak ke-3<ph name="END_LINK"/>).
 Tekan Shift + Alt untuk menukar.</translation>
-<translation id="5233638681132016545">Tab baharu</translation>
 <translation id="3846575436967432996">Tiada maklumat rangkaian tersedia</translation>
 <translation id="3026237328237090306">Sediakan data mudah alih</translation>
 <translation id="785750925697875037">Lihat akaun mudah alih</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Lumpuhkan Bluetooth</translation>
 <translation id="3126069444801937830">Mulakan semula untuk mengemas kini</translation>
 <translation id="735745346212279324">VPN diputuskan sambungan</translation>
+<translation id="7320906967354320621">Melahu</translation>
 <translation id="6303423059719347535">Bateri <ph name="PERCENTAGE"/>% penuh</translation>
+<translation id="2778346081696727092">Gagal untuk mengesahkan dengan nama pengguna atau kata laluan yang disediakan</translation>
 <translation id="3294437725009624529">Tetamu</translation>
 <translation id="8190698733819146287">Sesuaikan bahasa dan input...</translation>
-<translation id="598295083618286569">Bluetooth disambungkan</translation>
+<translation id="7170041865419449892">Di luar lingkungan</translation>
+<translation id="4804818685124855865">Putuskan sambungan</translation>
 <translation id="5222676887888702881">Log keluar</translation>
+<translation id="2688477613306174402">Konfigurasi</translation>
+<translation id="1272079795634619415">Berhenti</translation>
 <translation id="4957722034734105353">Ketahui lebih lanjut...</translation>
 <translation id="2964193600955408481">Lumpuhkan Wi-Fi</translation>
 <translation id="811680302244032017">Tambah peranti...</translation>
 <translation id="2509468283778169019">Kekunci CAPS LOCK dihidupkan</translation>
 <translation id="3892641579809465218">Paparan Dalaman</translation>
 <translation id="7823564328645135659">Bahasa telah ditukar daripada &quot;<ph name="FROM_LOCALE"/>&quot; kepada &quot;<ph name="TO_LOCALE"/>&quot; selepas menyegerakkan tetapan anda.</translation>
+<translation id="3368922792935385530">Disambungkan</translation>
 <translation id="8340999562596018839">Maklum balas dituturkan</translation>
 <translation id="8654520615680304441">Hidupkan Wi-Fi...</translation>
 <translation id="5825747213122829519">Kaedah masukan anda telah ditukar kepada <ph name="INPUT_METHOD_ID"/>.
 Tekan Shift + Alt untuk menukar.</translation>
 <translation id="2562916301614567480">Rangkaian Persendirian</translation>
 <translation id="6549021752953852991">Tiada rangkaian selular tersedia</translation>
+<translation id="4379753398862151997">Malang sekali, tidak wujud keserasian antara kita, Monitor. (Monitor itu tidak disokong)</translation>
 <translation id="6426039856985689743">Lumpuhkan data mudah alih</translation>
 <translation id="3087734570205094154">Bawah</translation>
 <translation id="5271016907025319479">VPN tidak dikonfigurasi.</translation>
-<translation id="1298695107722797780">Tamatkan\nsesi awam</translation>
-<translation id="3232695630852378748">Tetapan Bluetooth...</translation>
+<translation id="6803622936009808957">Tidak dapat membalikkan paparan memandangkan tiada peleraian disokong ditemui. Sebaliknya, memasuki mod desktop yang dilanjutkan.</translation>
 <translation id="1480041086352807611">Mod tunjuk cara</translation>
 <translation id="3626637461649818317">Tinggal <ph name="PERCENTAGE"/>%</translation>
 <translation id="9089416786594320554">Kaedah input</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">Tutup</translation>
 <translation id="4430019312045809116">Kelantangan</translation>
+<translation id="4442424173763614572">Carian DNS gagal</translation>
 <translation id="6356500677799115505">Bateri penuh dan sedang dicas.</translation>
 <translation id="7874779702599364982">Mencari rangkaian selular...</translation>
+<translation id="583281660410589416">Tidak diketahui</translation>
 <translation id="1383876407941801731">Cari</translation>
+<translation id="7468789844759750875">Lawati portal pengaktifan <ph name="NAME"/> untuk membeli lagi data.</translation>
 <translation id="3901991538546252627">Menyambung ke <ph name="NAME"/></translation>
 <translation id="2204305834655267233">Maklumat Rangkaian</translation>
 <translation id="1621499497873603021">Masa yang tinggal sehingga bateri kosong, <ph name="TIME_LEFT"/></translation>
@@ -70,55 +83,74 @@
 <translation id="8308637677604853869">Menu sebelumnya</translation>
 <translation id="1346748346194534595">Kanan</translation>
 <translation id="8528322925433439945">Mudah alih ...</translation>
+<translation id="7049357003967926684">Persekutuan</translation>
 <translation id="8428213095426709021">Tetapan</translation>
-<translation id="2472320577759310817">Bluetooth dimatikan.</translation>
 <translation id="2372145515558759244">Menyegerakkan aplikasi...</translation>
+<translation id="7256405249507348194">Ralat yang tidak dikenal pasti: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">Gagal periksa AAA</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: Memutuskan sambungan...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> sehingga penuh</translation>
 <translation id="5787281376604286451">Maklum balas dituturkan didayakan.
 Tekan Ctrl+Alt+Z untuk melumpuhkan.</translation>
 <translation id="4479639480957787382">Ethernet</translation>
+<translation id="6312403991423642364">Ralat rangkaian tidak diketahui</translation>
 <translation id="1467432559032391204">Kiri</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830">Mengaktifkan <ph name="NAME"/></translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">Maksimumkan</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: Menyambung...</translation>
+<translation id="8639033665604704195">Gagal untuk mengesahkan dengan kekunci pra-kongsi yang disediakan</translation>
 <translation id="252373100621549798">Paparan Tidak Diketahui</translation>
 <translation id="1882897271359938046">Mencerminkan <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Kunci</translation>
 <translation id="2805756323405976993">Apl</translation>
-<translation id="2482878487686419369">Pemberitahuan</translation>
+<translation id="1512064327686280138">Gagal pengaktifan</translation>
+<translation id="5097002363526479830">Gagal untuk bersambung ke rangkaian '<ph name="NAME"/>': <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi dimatikan.</translation>
-<translation id="2872961005593481000">Mematikan</translation>
+<translation id="8036518327127111261">Gagal untuk mengesahkan dengan sijil yang diberikan</translation>
 <translation id="8132793192354020517">Disambungkan ke <ph name="NAME"/></translation>
 <translation id="7052914147756339792">Tetapkan kertas dinding...</translation>
-<translation id="2739500853984626550">Tiada peranti bluetooth yang tersedia</translation>
-<translation id="2666092431469916601">Atas</translation>
+<translation id="8678698760965522072">Keadaan dalam talian</translation>
+<translation id="1119447706177454957">Ralat dalaman</translation>
 <translation id="3019353588588144572">Masa yang tinggal sehingga bateri dicas sepenuhnya, <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">Penggadang skrin</translation>
+<translation id="7005812687360380971">Kegagalan</translation>
 <translation id="1602076796624386989">Dayakan data mudah alih</translation>
 <translation id="6981982820502123353">Kebolehcapaian</translation>
 <translation id="3157931365184549694">Pulihkan</translation>
+<translation id="4274292172790327596">Ralat tidak dikenali</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Mengimbas untuk peranti...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Mencari rangkaian Wi-Fi...</translation>
+<translation id="7229570126336867161">Perlukan EVDO</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> ialah sesi awam yang diurus oleh <ph name="DOMAIN"/></translation>
 <translation id="7029814467594812963">Keluar dari sesi</translation>
 <translation id="8454013096329229812">Wi-Fi dihidupkan.</translation>
 <translation id="4872237917498892622">Alt+Search atau Shift</translation>
 <translation id="2983818520079887040">Tetapan...</translation>
-<translation id="5467313780247887226">Tidak boleh menduplikasikan imej pada monitor yang dipasang. Tiada peleraian sepadan ditemui.</translation>
+<translation id="8927026611342028580">Sambungan Diminta</translation>
+<translation id="8300849813060516376">OTASP gagal</translation>
 <translation id="2792498699870441125">Alt+Search</translation>
 <translation id="8660803626959853127">Menyegerakkan <ph name="COUNT"/> fail</translation>
 <translation id="639644700271529076">Kekunci CAPS LOCK dimatikan</translation>
-<translation id="4101192585425716296">Pusat Mesej</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: Mengaktifkan...</translation>
+<translation id="1391854757121130358">Anda mungkin telah menghabiskan peruntukan data mudah alih anda.</translation>
 <translation id="4864165860509564259">Kedudukan pelancar</translation>
 <translation id="7593891976182323525">Search atau Shift</translation>
 <translation id="7649070708921625228">Bantuan</translation>
 <translation id="3050422059534974565">CAPS LOCK dihidupkan. Tekan Search atau Shift untuk membatalkan.</translation>
 <translation id="397105322502079400">Mengira...</translation>
+<translation id="158849752021629804">Perlukan rangkaian rumah</translation>
+<translation id="6857811139397017780">Aktifkan <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">Carian DHCP gagal</translation>
+<translation id="6692173217867674490">Frasa laluan teruk</translation>
 <translation id="6165508094623778733">Ketahui lebih lanjut</translation>
+<translation id="9046895021617826162">Gagal disambungkan</translation>
+<translation id="973896785707726617">Sesi ini akan berakhir dalam <ph name="SESSION_TIME_REMAINING"/>. Anda akan dilog keluar secara automatik.</translation>
+<translation id="8372369524088641025">Kekunci WEP teruk</translation>
+<translation id="6636709850131805001">Keadaan tidak dikenali</translation>
 <translation id="3573179567135747900">Tukar kembali kepada &quot;<ph name="FROM_LOCALE"/>&quot; (perlu dimulakan semula)</translation>
 <translation id="8103386449138765447">Mesej SMS: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Tetapan Google Drive</translation>
@@ -129,7 +161,7 @@
 <translation id="8000066093800657092">Tiada rangkaian</translation>
 <translation id="5941711191222866238">Minimumkan</translation>
 <translation id="6911468394164995108">Sertai yang lain...</translation>
-<translation id="6843725295806269523">redam</translation>
 <translation id="412065659894267608"><ph name="HOUR"/>j <ph name="MINUTE"/>m sehingga penuh</translation>
 <translation id="6359806961507272919">SMS daripada <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Pembawa</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_nl.xtb b/ash/strings/ash_strings_nl.xtb
index 1cd8373..48b019c 100644
--- a/ash/strings/ash_strings_nl.xtb
+++ b/ash/strings/ash_strings_nl.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Accu is vol</translation>
 <translation id="5250713215130379958">Opstartprogramma automatisch verbergen</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> en <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Status van portal</translation>
 <translation id="30155388420722288">Overloopknop</translation>
 <translation id="5571066253365925590">Bluetooth ingeschakeld</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Proxy...</translation>
 <translation id="938582441709398163">Overlay voor toetsenbord</translation>
 <translation id="6979158407327259162">Google Drive</translation>
+<translation id="6943836128787782965">Ophalen van HTTP mislukt</translation>
 <translation id="2297568595583585744">Statussysteemvak</translation>
+<translation id="1661867754829461514">Pincode ontbreekt</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: verbinden...</translation>
+<translation id="4237016987259239829">Fout bij netwerkverbinding</translation>
 <translation id="2946640296642327832">Bluetooth inschakelen</translation>
 <translation id="6459472438155181876">Scherm uitbreiden naar <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Mobiel</translation>
 <translation id="6596816719288285829">IP-adres</translation>
+<translation id="4508265954913339219">Activering mislukt</translation>
 <translation id="1812696562331527143">Uw invoermethode is gewijzigd in <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>derden<ph name="END_LINK"/>).
 Druk op Shift + Alt om te schakelen.j</translation>
-<translation id="5233638681132016545">Nieuw tabblad</translation>
 <translation id="3846575436967432996">Geen netwerkinformatie beschikbaar</translation>
 <translation id="3026237328237090306">Mobiele gegevens instellen</translation>
 <translation id="785750925697875037">Mobiel account weergeven</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Bluetooth uitschakelen</translation>
 <translation id="3126069444801937830">Opnieuw starten voor bijwerken</translation>
 <translation id="735745346212279324">Verbinding met VPN verbroken</translation>
+<translation id="7320906967354320621">Inactief</translation>
 <translation id="6303423059719347535">De accu is <ph name="PERCENTAGE"/>% vol</translation>
+<translation id="2778346081696727092">Kan niet verifiëren met deze gebruikersnaam of dit wachtwoord</translation>
 <translation id="3294437725009624529">Gast</translation>
 <translation id="8190698733819146287">Talen en invoer aanpassen...</translation>
-<translation id="598295083618286569">Bluetooth-verbinding ingesteld</translation>
-<translation id="5222676887888702881">Afmelden</translation>
+<translation id="7170041865419449892">Geen bereik</translation>
+<translation id="4804818685124855865">Verbinding verbreken</translation>
+<translation id="5222676887888702881">Uitloggen</translation>
+<translation id="2688477613306174402">Configuratie</translation>
+<translation id="1272079795634619415">Stop</translation>
 <translation id="4957722034734105353">Meer informatie...</translation>
 <translation id="2964193600955408481">Wifi uitschakelen</translation>
 <translation id="811680302244032017">Apparaat toevoegen...</translation>
 <translation id="2509468283778169019">CAPS LOCK is ingeschakeld</translation>
 <translation id="3892641579809465218">Interne display</translation>
 <translation id="7823564328645135659">Na het synchroniseren met uw instellingen, is de taal gewijzigd van '<ph name="FROM_LOCALE"/>' in '<ph name="TO_LOCALE"/>'.</translation>
+<translation id="3368922792935385530">Verbonden</translation>
 <translation id="8340999562596018839">Gesproken feedback</translation>
 <translation id="8654520615680304441">Wifi inschakelen...</translation>
 <translation id="5825747213122829519">Uw invoermethode is gewijzigd in <ph name="INPUT_METHOD_ID"/>.
 Druk op Shift + Alt om te schakelen.</translation>
 <translation id="2562916301614567480">Privénetwerk</translation>
 <translation id="6549021752953852991">Geen mobiel netwerk beschikbaar</translation>
+<translation id="4379753398862151997">Het lijkt erop dat dit niet werkt. Het beeldscherm wordt niet ondersteund.</translation>
 <translation id="6426039856985689743">Mobiele gegevens uitschakelen</translation>
 <translation id="3087734570205094154">Onderaan</translation>
 <translation id="5271016907025319479">VPN is niet geconfigureerd.</translation>
-<translation id="1298695107722797780">Openbare sessie\nbeëindigen</translation>
-<translation id="3232695630852378748">Bluetooth-instellingen...</translation>
+<translation id="6803622936009808957">Kan schermen niet spiegelen, omdat er geen ondersteunde resoluties zijn gevonden. Het uitgebreide bureaublad is geactiveerd.</translation>
 <translation id="1480041086352807611">Demomodus</translation>
 <translation id="3626637461649818317"><ph name="PERCENTAGE"/>% resterend</translation>
 <translation id="9089416786594320554">Invoermethoden</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">Uitschakeling</translation>
 <translation id="4430019312045809116">Volume</translation>
+<translation id="4442424173763614572">DNS-lookup mislukt</translation>
 <translation id="6356500677799115505">De accu is vol en wordt opgeladen.</translation>
 <translation id="7874779702599364982">Zoeken naar mobiele netwerken...</translation>
+<translation id="583281660410589416">Onbekend</translation>
 <translation id="1383876407941801731">Zoeken</translation>
+<translation id="7468789844759750875">Ga naar de activeringsportal <ph name="NAME"/> om meer gegevens te kopen.</translation>
 <translation id="3901991538546252627">Verbinding maken met <ph name="NAME"/></translation>
 <translation id="2204305834655267233">Netwerkinfo</translation>
 <translation id="1621499497873603021">Resterende tijd totdat de accu leeg is: <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">Vorig menu</translation>
 <translation id="1346748346194534595">Rechts</translation>
 <translation id="8528322925433439945">Mobiel...</translation>
+<translation id="7049357003967926684">Verbinding</translation>
 <translation id="8428213095426709021">Instellingen</translation>
-<translation id="2472320577759310817">Bluetooth is uitgeschakeld.</translation>
 <translation id="2372145515558759244">Apps synchroniseren...</translation>
+<translation id="7256405249507348194">Onbekende fout: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">AAA-controle mislukt</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: verbinding verbreken...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> tot vol</translation>
 <translation id="5787281376604286451">Gesproken feedback is ingeschakeld.
 Druk op Ctrl+Alt+Z om uit te schakelen.</translation>
 <translation id="4479639480957787382">Ethernet</translation>
+<translation id="6312403991423642364">Onbekende netwerkfout</translation>
 <translation id="1467432559032391204">Links</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830"><ph name="NAME"/> activeren</translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">Maximaliseren</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: verbinden...</translation>
+<translation id="8639033665604704195">Kan niet verifiëren met deze van tevoren gedeelde sleutel</translation>
 <translation id="252373100621549798">Onbekend display</translation>
 <translation id="1882897271359938046">Spiegelen naar <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Vergrendelen</translation>
 <translation id="2805756323405976993">Applicaties</translation>
-<translation id="2482878487686419369">Meldingen</translation>
+<translation id="1512064327686280138">Activering mislukt</translation>
+<translation id="5097002363526479830">Kan geen verbinding maken met het netwerk '<ph name="NAME"/>': <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wifi is uitgeschakeld.</translation>
-<translation id="2872961005593481000">Afsluiten</translation>
+<translation id="8036518327127111261">Kan niet verifiëren met dit certificaat</translation>
 <translation id="8132793192354020517">Verbonden met <ph name="NAME"/></translation>
 <translation id="7052914147756339792">Achtergrond instellen...</translation>
-<translation id="2739500853984626550">Er zijn geen Bluetooth-apparaten beschikbaar</translation>
-<translation id="2666092431469916601">Boven</translation>
+<translation id="8678698760965522072">Online status</translation>
+<translation id="1119447706177454957">Interne fout</translation>
 <translation id="3019353588588144572">Resterende tijd totdat de accu volledig is opgeladen: <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">Vergrootglas</translation>
+<translation id="7005812687360380971">Mislukt</translation>
 <translation id="1602076796624386989">Mobiele gegevens inschakelen</translation>
 <translation id="6981982820502123353">Toegankelijkheid</translation>
 <translation id="3157931365184549694">Herstellen</translation>
+<translation id="4274292172790327596">Onbekende fout</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Scannen naar apparaten...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Zoeken naar Wi-Fi-netwerken...</translation>
+<translation id="7229570126336867161">EVDO vereist</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> is een openbare sessie die wordt beheerd door <ph name="DOMAIN"/></translation>
 <translation id="7029814467594812963">Sessie sluiten</translation>
 <translation id="8454013096329229812">Wifi is ingeschakeld.</translation>
 <translation id="4872237917498892622">Alt+Zoeken of Shift</translation>
 <translation id="2983818520079887040">Instellingen...</translation>
-<translation id="5467313780247887226">Kan afbeelding niet kopiëren naar gekoppeld beeldschermen. Er is geen overeenkomende resolutie gevonden.</translation>
+<translation id="8927026611342028580">Verbinding aangevraagd</translation>
+<translation id="8300849813060516376">OTASP mislukt</translation>
 <translation id="2792498699870441125">Alt+Zoeken</translation>
 <translation id="8660803626959853127"><ph name="COUNT"/> bestand(en) synchroniseren</translation>
 <translation id="639644700271529076">CAPS LOCK is uitgeschakeld</translation>
-<translation id="4101192585425716296">Berichtencentrum</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: activeren...</translation>
+<translation id="1391854757121130358">U heeft mogelijk uw quotum voor mobiele gegevens verbruikt.</translation>
 <translation id="4864165860509564259">Positie van launcher</translation>
 <translation id="7593891976182323525">Zoeken of Shift</translation>
 <translation id="7649070708921625228">Help</translation>
 <translation id="3050422059534974565">CAPS LOCK is ingeschakeld.
 Druk op Zoeken of Shift om te annuleren.</translation>
 <translation id="397105322502079400">Berekenen...</translation>
+<translation id="158849752021629804">Thuisnetwerk vereist</translation>
+<translation id="6857811139397017780"><ph name="NETWORKSERVICE"/> activeren</translation>
+<translation id="5864471791310927901">Opzoeken van DHCP mislukt</translation>
+<translation id="6692173217867674490">Slechte wachtwoordzin</translation>
 <translation id="6165508094623778733">Meer informatie</translation>
+<translation id="9046895021617826162">Verbinding mislukt</translation>
+<translation id="973896785707726617">Deze sessie loopt af over <ph name="SESSION_TIME_REMAINING"/>. U wordt automatisch uitgelogd.</translation>
+<translation id="8372369524088641025">Slechte WEP-sleutel</translation>
+<translation id="6636709850131805001">Niet-herkende staat</translation>
 <translation id="3573179567135747900">Teruggaan naar '<ph name="FROM_LOCALE"/>' (opnieuw starten vereist)</translation>
 <translation id="8103386449138765447">SMS-berichten: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Instellingen voor Google Drive...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">Geen netwerk</translation>
 <translation id="5941711191222866238">Minimaliseren</translation>
 <translation id="6911468394164995108">Verbinding met ander netwerk maken...</translation>
-<translation id="6843725295806269523">dempen</translation>
 <translation id="412065659894267608"><ph name="HOUR"/>u <ph name="MINUTE"/>m tot volledig opgeladen</translation>
 <translation id="6359806961507272919">Sms van <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Provider</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_no.xtb b/ash/strings/ash_strings_no.xtb
index a9854c8..359e333 100644
--- a/ash/strings/ash_strings_no.xtb
+++ b/ash/strings/ash_strings_no.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Batteriet er fullt</translation>
 <translation id="5250713215130379958">Skjul programlisten automatisk</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> og <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Portaltilstand</translation>
 <translation id="30155388420722288">Overflyt-knappen</translation>
 <translation id="5571066253365925590">Bluetooth er aktivert</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Mellomtjener</translation>
 <translation id="938582441709398163">Tastaturbelegg</translation>
 <translation id="6979158407327259162">Google Disk</translation>
+<translation id="6943836128787782965">Henting av HTTP mislyktes</translation>
 <translation id="2297568595583585744">Status-felt</translation>
+<translation id="1661867754829461514">Personlig kode mangler</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: kobler til ...</translation>
+<translation id="4237016987259239829">Feil i nettverkstilkobling</translation>
 <translation id="2946640296642327832">Aktiver Bluetooth</translation>
 <translation id="6459472438155181876">Utvider skjermen til <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Mobil</translation>
 <translation id="6596816719288285829">IP-adresse</translation>
+<translation id="4508265954913339219">Aktiveringen mislyktes</translation>
 <translation id="1812696562331527143">Inndatametoden din er endret til <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>tredjepart<ph name="END_LINK"/>).
 Trykk på Shift + Alt for å bytte.</translation>
-<translation id="5233638681132016545">Ny fane</translation>
 <translation id="3846575436967432996">Ingen nettverksinformasjon tilgjengelig</translation>
 <translation id="3026237328237090306">Konfigurer mobildata</translation>
 <translation id="785750925697875037">Se mobilkontoen</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Deaktiver Bluetooth</translation>
 <translation id="3126069444801937830">Start på nytt for å oppdatere</translation>
 <translation id="735745346212279324">VPN frakoblet</translation>
+<translation id="7320906967354320621">Ikke aktiv</translation>
 <translation id="6303423059719347535">Batteriet er <ph name="PERCENTAGE"/> % fullt</translation>
+<translation id="2778346081696727092">Kunne ikke autentisere med oppgitt brukernavn eller passord</translation>
 <translation id="3294437725009624529">Gjest</translation>
 <translation id="8190698733819146287">Tilpass språk og inndata</translation>
-<translation id="598295083618286569">Bluetooth-tilkobling</translation>
+<translation id="7170041865419449892">Utenfor rekkevidde</translation>
+<translation id="4804818685124855865">Koble fra</translation>
 <translation id="5222676887888702881">Logg av</translation>
+<translation id="2688477613306174402">Konfigurasjon</translation>
+<translation id="1272079795634619415">Stopp</translation>
 <translation id="4957722034734105353">Finn ut mer</translation>
 <translation id="2964193600955408481">Deaktiver Wi-Fi</translation>
 <translation id="811680302244032017">Legg til enhet</translation>
 <translation id="2509468283778169019">Caps Lock er på</translation>
 <translation id="3892641579809465218">Innebygd skjerm</translation>
 <translation id="7823564328645135659">Språket er endret fra <ph name="FROM_LOCALE"/> til <ph name="TO_LOCALE"/> etter synkronisering av innstillingene dine.</translation>
+<translation id="3368922792935385530">Tilkoblet</translation>
 <translation id="8340999562596018839">Talerespons</translation>
 <translation id="8654520615680304441">Slå på Wi-Fi</translation>
 <translation id="5825747213122829519">Inndatametoden din er endret til <ph name="INPUT_METHOD_ID"/>.
 Trykk på Shift + Alt for å bytte.</translation>
 <translation id="2562916301614567480">Privat nettverk</translation>
 <translation id="6549021752953852991">Ingen tilgjengelige mobilnettverk.</translation>
+<translation id="4379753398862151997">Kjære skjerm, det går ikke så bra mellom oss. (Skjermen støttes ikke)</translation>
 <translation id="6426039856985689743">Deaktiver mobildata</translation>
 <translation id="3087734570205094154">Bunn</translation>
 <translation id="5271016907025319479">VPN er ikke konfigurert.</translation>
-<translation id="1298695107722797780">Avslutt offentlig økt</translation>
-<translation id="3232695630852378748">Bluetooth-innstillinger</translation>
+<translation id="6803622936009808957">Kunne ikke speile skjermene fordi ingen støttede oppløsninger ble funnet. Utvidet skrivebord ble brukt i stedet.</translation>
 <translation id="1480041086352807611">Demo-modus</translation>
 <translation id="3626637461649818317"><ph name="PERCENTAGE"/>% igjen</translation>
 <translation id="9089416786594320554">Inndatametoder</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/> %</translation>
 <translation id="1895658205118569222">Avslutning</translation>
 <translation id="4430019312045809116">Volum</translation>
+<translation id="4442424173763614572">DNS-søk mislyktes</translation>
 <translation id="6356500677799115505">Batteriet er fullt og til lading.</translation>
 <translation id="7874779702599364982">Søker etter mobilnettverk ...</translation>
+<translation id="583281660410589416">Ukjent</translation>
 <translation id="1383876407941801731">Søk</translation>
+<translation id="7468789844759750875">Gå til <ph name="NAME"/>-aktiveringsportalen for å kjøpe mer mobildata.</translation>
 <translation id="3901991538546252627">Kobler til <ph name="NAME"/></translation>
 <translation id="2204305834655267233">Nettverksinformasjon</translation>
 <translation id="1621499497873603021">Gjenværende tid til batteriet er tomt – <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">Forrige meny</translation>
 <translation id="1346748346194534595">Høyre</translation>
 <translation id="8528322925433439945">Mobil</translation>
+<translation id="7049357003967926684">Tilknytning</translation>
 <translation id="8428213095426709021">Innstillinger</translation>
-<translation id="2472320577759310817">Bluetooth er slått av.</translation>
 <translation id="2372145515558759244">Synkroniserer programmer …</translation>
+<translation id="7256405249507348194">Ukjent feil: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">AAA-kontroll mislyktes</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: kobler fra ...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>.<ph name="MINUTE"/> til fulladet</translation>
 <translation id="5787281376604286451">Talerespons er aktivert.
 Trykk på Ctrl+Alt+Z for å deaktivere.</translation>
 <translation id="4479639480957787382">Ethernet</translation>
+<translation id="6312403991423642364">Ukjent nettverksfeil</translation>
 <translation id="1467432559032391204">Venstre</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830">Aktiverer <ph name="NAME"/></translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">Maksimer</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: kobler til ...</translation>
+<translation id="8639033665604704195">Kunne ikke autentisere med angitt forhåndsdelt nøkkel</translation>
 <translation id="252373100621549798">Ukjent skjerm</translation>
 <translation id="1882897271359938046">Speiler <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Lås</translation>
 <translation id="2805756323405976993">Programmer</translation>
-<translation id="2482878487686419369">Varslinger</translation>
+<translation id="1512064327686280138">Aktiveringen mislyktes</translation>
+<translation id="5097002363526479830">Kunne ikke koble til nettverket «<ph name="NAME"/>»: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi er slått av.</translation>
-<translation id="2872961005593481000">Avslutt</translation>
+<translation id="8036518327127111261">Kunne ikke autentisere med oppgitt sertifikat</translation>
 <translation id="8132793192354020517">Tilkoblet <ph name="NAME"/></translation>
 <translation id="7052914147756339792">Angi bakgrunnsbilde</translation>
-<translation id="2739500853984626550">Ingen Bluetooth-enheter tilgjengelig</translation>
-<translation id="2666092431469916601">Topp</translation>
+<translation id="8678698760965522072">Tilkoblet tilstand</translation>
+<translation id="1119447706177454957">Intern feil</translation>
 <translation id="3019353588588144572">Tid som gjenstår til batteriet er fulladet – <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">Skjermforstørrer</translation>
+<translation id="7005812687360380971">Feil</translation>
 <translation id="1602076796624386989">Aktivér mobildata</translation>
 <translation id="6981982820502123353">Tilgjengelighet</translation>
 <translation id="3157931365184549694">Gjenopprett</translation>
+<translation id="4274292172790327596">Ukjent feil</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Leter etter enheter ...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/> <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Søker etter Wi-Fi-nettverk ...</translation>
+<translation id="7229570126336867161">Krever EVDO</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> er en offentlig økt administrert av <ph name="DOMAIN"/></translation>
 <translation id="7029814467594812963">Avslutt økten</translation>
 <translation id="8454013096329229812">Wi-Fi er slått på.</translation>
 <translation id="4872237917498892622">Alt + Søk eller Shift</translation>
 <translation id="2983818520079887040">Innstillinger</translation>
-<translation id="5467313780247887226">Kan ikke duplisere bildet på de tilkoblede skjermene. Ingen samsvarende oppløsning funnet.</translation>
+<translation id="8927026611342028580">Tilkobling har blitt forespurt</translation>
+<translation id="8300849813060516376">OTASP mislyktes</translation>
 <translation id="2792498699870441125">Alt + Søk</translation>
 <translation id="8660803626959853127">Synkroniserer <ph name="COUNT"/> fil(er)</translation>
 <translation id="639644700271529076">CAPS LOCK er av</translation>
-<translation id="4101192585425716296">Meldingssenter</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: aktiveres …</translation>
+<translation id="1391854757121130358">Du kan ha brukt opp mobildatakvoten din.</translation>
 <translation id="4864165860509564259">Programlisteplassering</translation>
 <translation id="7593891976182323525">Søk eller Shift</translation>
 <translation id="7649070708921625228">Hjelp</translation>
 <translation id="3050422059534974565">Caps Lock er på.
 Trykk på Søk eller Shift for å avbryte.</translation>
 <translation id="397105322502079400">Beregner …</translation>
+<translation id="158849752021629804">Trenger hjemmenettverk</translation>
+<translation id="6857811139397017780">Aktiver <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">DHCP-oppslag mislyktes</translation>
+<translation id="6692173217867674490">Feil passordfrase</translation>
 <translation id="6165508094623778733">Les mer</translation>
+<translation id="9046895021617826162">Tilkoblingen mislyktes</translation>
+<translation id="973896785707726617">Denne økten slutter om <ph name="SESSION_TIME_REMAINING"/>. Du logges ut automatisk.</translation>
+<translation id="8372369524088641025">Feil WEP-nøkkel</translation>
+<translation id="6636709850131805001">Ikke gjenkjent tilstand</translation>
 <translation id="3573179567135747900">Endre tilbake til <ph name="FROM_LOCALE"/> (krever omstart)</translation>
 <translation id="8103386449138765447">SMS-meldinger: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Innstillinger for Google Disk</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">Ingen nettverk</translation>
 <translation id="5941711191222866238">Minimer</translation>
 <translation id="6911468394164995108">Koble til annet</translation>
-<translation id="6843725295806269523">kutt lyd</translation>
 <translation id="412065659894267608"><ph name="HOUR"/> t og <ph name="MINUTE"/> m til batteriet er ferdigladet</translation>
 <translation id="6359806961507272919">Tekstmelding fra <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Operatør</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_pl.xtb b/ash/strings/ash_strings_pl.xtb
index 8e597eb..a257bfd 100644
--- a/ash/strings/ash_strings_pl.xtb
+++ b/ash/strings/ash_strings_pl.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Bateria naładowana</translation>
 <translation id="5250713215130379958">Automatycznie ukrywaj program uruchamiający</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> i <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Stan portalu</translation>
 <translation id="30155388420722288">Przycisk akcji</translation>
 <translation id="5571066253365925590">Bluetooth włączony</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Serwer proxy...</translation>
 <translation id="938582441709398163">Nakładka klawiatury</translation>
 <translation id="6979158407327259162">Dysk Google</translation>
+<translation id="6943836128787782965">Wykonanie metody GET protokołu HTTP nie powiodło się.</translation>
 <translation id="2297568595583585744">Zasobnik stanu</translation>
+<translation id="1661867754829461514">Brak kodu PIN</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: łączę...</translation>
+<translation id="4237016987259239829">Błąd połączenia z siecią</translation>
 <translation id="2946640296642327832">Włącz Bluetooth</translation>
 <translation id="6459472438155181876">Rozszerzanie ekranu na <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Komórka</translation>
 <translation id="6596816719288285829">Adres IP</translation>
+<translation id="4508265954913339219">Aktywacja nie powiodła się</translation>
 <translation id="1812696562331527143">Metoda wprowadzania została zmieniona na <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>innej firmy<ph name="END_LINK"/>).
 Naciśnij Shift + Alt, by ją przełączyć.</translation>
-<translation id="5233638681132016545">Nowa karta</translation>
 <translation id="3846575436967432996">Brak informacji o sieciach</translation>
 <translation id="3026237328237090306">Skonfiguruj komórkową transmisję danych</translation>
 <translation id="785750925697875037">Wyświetl konto dla telefonów komórkowych</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Wyłącz Bluetooth</translation>
 <translation id="3126069444801937830">Uruchom ponownie i zaktualizuj</translation>
 <translation id="735745346212279324">VPN odłączona</translation>
+<translation id="7320906967354320621">Bezczynna</translation>
 <translation id="6303423059719347535">Naładowanie baterii: <ph name="PERCENTAGE"/>%</translation>
+<translation id="2778346081696727092">Nie powiodło się uwierzytelnienie przy użyciu podanej nazwy użytkownika i hasła.</translation>
 <translation id="3294437725009624529">Gość</translation>
 <translation id="8190698733819146287">Dostosuj języki i metody wprowadzania</translation>
-<translation id="598295083618286569">Bluetooth połączony</translation>
+<translation id="7170041865419449892">Poza zasięgiem</translation>
+<translation id="4804818685124855865">Rozłącz</translation>
 <translation id="5222676887888702881">Wyloguj się</translation>
+<translation id="2688477613306174402">Konfiguracja</translation>
+<translation id="1272079795634619415">Zatrzymaj</translation>
 <translation id="4957722034734105353">Więcej informacji...</translation>
 <translation id="2964193600955408481">Wyłącz Wi-Fi</translation>
 <translation id="811680302244032017">Dodaj urządzenie...</translation>
 <translation id="2509468283778169019">CAPS LOCK jest włączony.</translation>
 <translation id="3892641579809465218">Wyświetlacz wewnętrzny</translation>
 <translation id="7823564328645135659">Po zsynchronizowaniu ustawień zmieniono język z „<ph name="FROM_LOCALE"/>” na „<ph name="TO_LOCALE"/>”.</translation>
+<translation id="3368922792935385530">Połączone</translation>
 <translation id="8340999562596018839">Potwierdzenia głosowe</translation>
 <translation id="8654520615680304441">Włącz Wi-Fi...</translation>
 <translation id="5825747213122829519">Metoda wprowadzania została zmieniona na <ph name="INPUT_METHOD_ID"/>.
 Naciśnij Shift + Alt, by ją przełączyć.</translation>
 <translation id="2562916301614567480">Sieć prywatna</translation>
 <translation id="6549021752953852991">Brak dostępnych sieci komórkowych</translation>
+<translation id="4379753398862151997">Drogi monitorze, nie układa się między nami. (Ten monitor jest nieobsługiwany)</translation>
 <translation id="6426039856985689743">Wyłącz komórkową transmisję danych</translation>
 <translation id="3087734570205094154">Na dół</translation>
 <translation id="5271016907025319479">Sieć VPN jest nieskonfigurowana.</translation>
-<translation id="1298695107722797780">Zakończ sesję\npubliczną</translation>
-<translation id="3232695630852378748">Ustawienia Bluetooth...</translation>
+<translation id="6803622936009808957">Nie można wyświetlić odbicia lustrzanego, ponieważ nie znaleziono obsługiwanych rozdzielczości. Zamiast tego został włączony pulpit rozszerzony.</translation>
 <translation id="1480041086352807611">Tryb demo</translation>
 <translation id="3626637461649818317">Pozostało <ph name="PERCENTAGE"/>%</translation>
 <translation id="9089416786594320554">Wprowadzanie tekstu</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">Wyłączenie</translation>
 <translation id="4430019312045809116">Głośność</translation>
+<translation id="4442424173763614572">Wyszukiwanie DNS nie powiodło się.</translation>
 <translation id="6356500677799115505">Bateria jest pełna i trwa ładowanie.</translation>
 <translation id="7874779702599364982">Szukam sieci komórkowych...</translation>
+<translation id="583281660410589416">Nieznany</translation>
 <translation id="1383876407941801731">Wyszukiwanie</translation>
+<translation id="7468789844759750875">Odwiedź portal aktywacji <ph name="NAME"/>, aby wykupić więcej transferu danych.</translation>
 <translation id="3901991538546252627">Łączę z: <ph name="NAME"/></translation>
 <translation id="2204305834655267233">Informacje o sieci</translation>
 <translation id="1621499497873603021">Czas pozostały do wyczerpania baterii: <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">Poprzednie menu</translation>
 <translation id="1346748346194534595">W prawo</translation>
 <translation id="8528322925433439945">Komórkowe...</translation>
+<translation id="7049357003967926684">Powiązanie</translation>
 <translation id="8428213095426709021">Ustawienia</translation>
-<translation id="2472320577759310817">Bluetooth wyłączony.</translation>
 <translation id="2372145515558759244">Synchronizuję aplikacje...</translation>
+<translation id="7256405249507348194">Nierozpoznany błąd: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">Sprawdzenie AAA nie powiodło się</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: rozłączam...</translation>
 <translation id="8456362689280298700">Do naładowania: <ph name="HOUR"/>:<ph name="MINUTE"/></translation>
 <translation id="5787281376604286451">Potwierdzenia głosowe są włączone.
 Aby wyłączyć, naciśnij Ctrl+Alt+Z.</translation>
 <translation id="4479639480957787382">Ethernet</translation>
+<translation id="6312403991423642364">Nieznany błąd sieci</translation>
 <translation id="1467432559032391204">W lewo</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830">Aktywuję <ph name="NAME"/></translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">Maksymalizuj</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: łączę...</translation>
+<translation id="8639033665604704195">Nie powiodło się uwierzytelnianie przy użyciu podanego klucza wstępnego.</translation>
 <translation id="252373100621549798">Nieznany wyświetlacz</translation>
 <translation id="1882897271359938046">Kopia na <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Zablokuj</translation>
 <translation id="2805756323405976993">Aplikacje</translation>
-<translation id="2482878487686419369">Powiadomienia</translation>
+<translation id="1512064327686280138">Niepowodzenie aktywacji</translation>
+<translation id="5097002363526479830">Nie udało się połączyć z siecią „<ph name="NAME"/>”: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi wyłączone.</translation>
-<translation id="2872961005593481000">Wyłącz</translation>
+<translation id="8036518327127111261">Nie powiodło się uwierzytelnienie przy użyciu podanego certyfikatu.</translation>
 <translation id="8132793192354020517">Połączono z <ph name="NAME"/></translation>
 <translation id="7052914147756339792">Ustaw tapetę...</translation>
-<translation id="2739500853984626550">Brak dostępnych urządzeń Bluetooth</translation>
-<translation id="2666092431469916601">Do góry</translation>
+<translation id="8678698760965522072">Online</translation>
+<translation id="1119447706177454957">Błąd wewnętrzny</translation>
 <translation id="3019353588588144572">Czas pozostały do pełnego naładowania baterii: <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">Lupa</translation>
+<translation id="7005812687360380971">Niepowodzenie</translation>
 <translation id="1602076796624386989">Włącz komórkową transmisję danych</translation>
 <translation id="6981982820502123353">Ułatwienia dostępu</translation>
 <translation id="3157931365184549694">Przywróć</translation>
+<translation id="4274292172790327596">Nierozpoznany błąd</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Skanowanie w poszukiwaniu urządzeń...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Trwa wyszukiwanie sieci Wi-Fi...</translation>
+<translation id="7229570126336867161">Wymagana technologia EVDO</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> jest publiczną sesją zarządzaną przez <ph name="DOMAIN"/></translation>
 <translation id="7029814467594812963">Zakończ sesję</translation>
 <translation id="8454013096329229812">Wi-Fi włączone.</translation>
 <translation id="4872237917498892622">Alt+Szukaj lub Shift</translation>
 <translation id="2983818520079887040">Ustawienia</translation>
-<translation id="5467313780247887226">Nie można powielić obrazu na podłączonych monitorach. Brak zgodnych rozdzielczości.</translation>
+<translation id="8927026611342028580">Poproszono o połączenie</translation>
+<translation id="8300849813060516376">Dostarczanie OTASP nie powiodło się</translation>
 <translation id="2792498699870441125">Alt+Szukaj</translation>
 <translation id="8660803626959853127">Synchronizacja: <ph name="COUNT"/> pliki(ów)</translation>
 <translation id="639644700271529076">CAPS LOCK jest wyłączony</translation>
-<translation id="4101192585425716296">Centrum wiadomości</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: aktywuję...</translation>
+<translation id="1391854757121130358">Być może został wyczerpany limit komórkowej transmisji danych.</translation>
 <translation id="4864165860509564259">Pozycja programu uruchamiającego</translation>
 <translation id="7593891976182323525">Szukaj lub Shift</translation>
 <translation id="7649070708921625228">Pomoc</translation>
 <translation id="3050422059534974565">CAPS LOCK jest włączony.
 Naciśnij Szukaj lub Shift, by anulować.</translation>
 <translation id="397105322502079400">Przeliczanie...</translation>
+<translation id="158849752021629804">Wymagana sieć macierzysta</translation>
+<translation id="6857811139397017780">Aktywuj usługę <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">Wyszukiwanie DHCP nie powiodło się</translation>
+<translation id="6692173217867674490">Błędne hasło</translation>
 <translation id="6165508094623778733">Więcej informacji</translation>
+<translation id="9046895021617826162">Łączenie nie powiodło się</translation>
+<translation id="973896785707726617">Ta sesja zakończy się za <ph name="SESSION_TIME_REMAINING"/>. Nastąpi automatyczne wylogowanie.</translation>
+<translation id="8372369524088641025">Błędny klucz WEP</translation>
+<translation id="6636709850131805001">Nierozpoznany stan</translation>
 <translation id="3573179567135747900">Zmień z powrotem na „<ph name="FROM_LOCALE"/>” (wymaga ponownego uruchomienia)</translation>
 <translation id="8103386449138765447">SMS-y: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Ustawienia Dysku Google...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">Brak sieci</translation>
 <translation id="5941711191222866238">Minimalizuj</translation>
 <translation id="6911468394164995108">Połącz z inną...</translation>
-<translation id="6843725295806269523">wyciszenie</translation>
 <translation id="412065659894267608"><ph name="HOUR"/> godz. <ph name="MINUTE"/> min do pełnego naładowania</translation>
 <translation id="6359806961507272919">Wiadomość SMS z numeru <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Operator</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_pt-BR.xtb b/ash/strings/ash_strings_pt-BR.xtb
index 3815042..844e203 100644
--- a/ash/strings/ash_strings_pt-BR.xtb
+++ b/ash/strings/ash_strings_pt-BR.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Bateria carregada</translation>
 <translation id="5250713215130379958">Ocultar automaticamente o iniciador</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> e <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Estado do portal</translation>
 <translation id="30155388420722288">Botão de estouro</translation>
 <translation id="5571066253365925590">Bluetooth ativado</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Proxy...</translation>
 <translation id="938582441709398163">Sobreposição do teclado</translation>
 <translation id="6979158407327259162">Google Drive</translation>
+<translation id="6943836128787782965">HTTP falhou</translation>
 <translation id="2297568595583585744">Bandeja de status</translation>
+<translation id="1661867754829461514">PIN ausente</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: conectando...</translation>
+<translation id="4237016987259239829">Erro de conexão da rede</translation>
 <translation id="2946640296642327832">Ativar bluetooth</translation>
 <translation id="6459472438155181876">Estendendo tela para <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Celular</translation>
 <translation id="6596816719288285829">Endereço IP</translation>
+<translation id="4508265954913339219">Falha na ativação</translation>
 <translation id="1812696562331527143">Seu método de entrada mudou para <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>terceiros<ph name="END_LINK"/>). 
 Pressione Shift + Alt para alternar.</translation>
-<translation id="5233638681132016545">Nova guia</translation>
 <translation id="3846575436967432996">Não há informações de rede disponíveis</translation>
 <translation id="3026237328237090306">Configurar dados móveis</translation>
 <translation id="785750925697875037">Exibir conta de celular</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Desativar bluetooth</translation>
 <translation id="3126069444801937830">Reiniciar para atualizar</translation>
 <translation id="735745346212279324">VPN desconectada</translation>
+<translation id="7320906967354320621">Inativo</translation>
 <translation id="6303423059719347535">A bateria está <ph name="PERCENTAGE"/>% cheia</translation>
+<translation id="2778346081696727092">Falha na autenticação com nome de usuário ou senha fornecidos</translation>
 <translation id="3294437725009624529">Visitante</translation>
 <translation id="8190698733819146287">Personalizar idiomas e entrada...</translation>
-<translation id="598295083618286569">Bluetooth conectado</translation>
+<translation id="7170041865419449892">Fora de alcance</translation>
+<translation id="4804818685124855865">Desconectar</translation>
 <translation id="5222676887888702881">Sair</translation>
+<translation id="2688477613306174402">Configuração</translation>
+<translation id="1272079795634619415">Parar</translation>
 <translation id="4957722034734105353">Saiba mais...</translation>
 <translation id="2964193600955408481">Desativar Wi-Fi</translation>
 <translation id="811680302244032017">Adicionar dispositivo...</translation>
 <translation id="2509468283778169019">CAPS LOCK está ativado</translation>
 <translation id="3892641579809465218">Display interno</translation>
 <translation id="7823564328645135659">O idioma foi alterado de &quot;<ph name="FROM_LOCALE"/>&quot; para &quot;<ph name="TO_LOCALE"/>&quot; após a sincronização de suas configurações.</translation>
+<translation id="3368922792935385530">Conectado</translation>
 <translation id="8340999562596018839">Feedback falado</translation>
 <translation id="8654520615680304441">Ativar Wi-Fi...</translation>
 <translation id="5825747213122829519">Seu método de entrada mudou para <ph name="INPUT_METHOD_ID"/>.
 Pressione Shift + Alt para alternar.</translation>
 <translation id="2562916301614567480">Rede privada</translation>
 <translation id="6549021752953852991">Nenhuma rede celular disponível</translation>
+<translation id="4379753398862151997">Prezado monitor, as coisas não estão dando certo entre nós (este monitor não é suportado).</translation>
 <translation id="6426039856985689743">Desativar dados móveis</translation>
 <translation id="3087734570205094154">Parte inferior</translation>
 <translation id="5271016907025319479">A VPN não está configurada.</translation>
-<translation id="1298695107722797780">Encerrar sessão\npública</translation>
-<translation id="3232695630852378748">Configurações de bluetooth...</translation>
+<translation id="6803622936009808957">Não foi possível espelhar os displays porque não foram encontradas resoluções suportadas. Em vez disso, foi ativada a área de trabalho estendida.</translation>
 <translation id="1480041086352807611">Modo de demonstração</translation>
 <translation id="3626637461649818317"><ph name="PERCENTAGE"/>% restante</translation>
 <translation id="9089416786594320554">Métodos de entrada</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">Encerramento</translation>
 <translation id="4430019312045809116">Volume</translation>
+<translation id="4442424173763614572">A busca de DNS falhou</translation>
 <translation id="6356500677799115505">A bateria está cheia e carregando.</translation>
 <translation id="7874779702599364982">Procurando redes de celular...</translation>
+<translation id="583281660410589416">Desconhecido</translation>
 <translation id="1383876407941801731">Pesquisa</translation>
+<translation id="7468789844759750875">Visite o portal de ativação do <ph name="NAME"/> para adquirir mais dados.</translation>
 <translation id="3901991538546252627">Conectando-se a <ph name="NAME"/></translation>
 <translation id="2204305834655267233">Informações de rede</translation>
 <translation id="1621499497873603021">O tempo restante até que a bateria se esgote é de <ph name="TIME_LEFT"/></translation>
@@ -70,55 +83,74 @@
 <translation id="8308637677604853869">Menu anterior</translation>
 <translation id="1346748346194534595">Para a direita</translation>
 <translation id="8528322925433439945">Celular...</translation>
+<translation id="7049357003967926684">Associação</translation>
 <translation id="8428213095426709021">Configurações</translation>
-<translation id="2472320577759310817">O Bluetooth está desligado.</translation>
 <translation id="2372145515558759244">Sincronizando aplicativos...</translation>
+<translation id="7256405249507348194">Erro não reconhecido: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">Falha ao verificar AAA</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: desconectando...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> para carga completa</translation>
 <translation id="5787281376604286451">O feedback falado está ativado.
 Pressione Ctrl+Alt+Z para desativá-lo.</translation>
 <translation id="4479639480957787382">Ethernet</translation>
+<translation id="6312403991423642364">Erro de rede desconhecido</translation>
 <translation id="1467432559032391204">Para a esquerda</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830">Ativando <ph name="NAME"/></translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">Maximizar</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: conectando...</translation>
+<translation id="8639033665604704195">Falha na autenticação com chave pré-compartilhada fornecida</translation>
 <translation id="252373100621549798">Exibição desconhecida</translation>
 <translation id="1882897271359938046">Espelhamento de <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Bloquear</translation>
 <translation id="2805756323405976993">Aplicativos</translation>
-<translation id="2482878487686419369">Notificações</translation>
+<translation id="1512064327686280138">Falha na ativação</translation>
+<translation id="5097002363526479830">Falha na conexão à rede &quot;<ph name="NAME"/>&quot;: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">O Wi-Fi está desligado.</translation>
-<translation id="2872961005593481000">Encerrar</translation>
+<translation id="8036518327127111261">Falha ao autenticar com certificado fornecido</translation>
 <translation id="8132793192354020517">Conectado à <ph name="NAME"/></translation>
 <translation id="7052914147756339792">Definir papel de parede...</translation>
-<translation id="2739500853984626550">Não há dispositivos Bluetooth disponíveis</translation>
-<translation id="2666092431469916601">Parte superior</translation>
+<translation id="8678698760965522072">Estado on-line</translation>
+<translation id="1119447706177454957">Erro interno</translation>
 <translation id="3019353588588144572">O tempo restante até que a bateria esteja totalmente carregada é de <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">Lupa</translation>
+<translation id="7005812687360380971">Falha</translation>
 <translation id="1602076796624386989">Ativar dados móveis</translation>
 <translation id="6981982820502123353">Acessibilidade</translation>
 <translation id="3157931365184549694">Restaurar</translation>
+<translation id="4274292172790327596">Erro desconhecido</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Procurando dispositivos...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Procurando redes Wi-Fi...</translation>
+<translation id="7229570126336867161">EVDO ausente</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> é uma sessão pública gerenciada por <ph name="DOMAIN"/></translation>
 <translation id="7029814467594812963">Sair da sessão</translation>
 <translation id="8454013096329229812">O Wi-Fi está ligado.</translation>
 <translation id="4872237917498892622">Alt + Pesquisar ou Shift</translation>
 <translation id="2983818520079887040">Configurações...</translation>
-<translation id="5467313780247887226">Não é possível duplicar imagem em monitores acoplados. Nenhuma resolução correspondente foi encontrada.</translation>
+<translation id="8927026611342028580">Conexão solicitada</translation>
+<translation id="8300849813060516376">Falha no OTASP</translation>
 <translation id="2792498699870441125">Alt + Pesquisar</translation>
 <translation id="8660803626959853127">Sincronizando <ph name="COUNT"/> arquivos</translation>
 <translation id="639644700271529076">CAPS LOCK está desativado</translation>
-<translation id="4101192585425716296">Central de mensagens</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: Ativando...</translation>
+<translation id="1391854757121130358">Você pode ter esgotado sua permissão de dados móveis.</translation>
 <translation id="4864165860509564259">Posição do iniciador</translation>
 <translation id="7593891976182323525">Pesquisar ou Shift</translation>
 <translation id="7649070708921625228">Ajuda</translation>
 <translation id="3050422059534974565">A tecla CAPS LOCK está ativada. Pressione Pesquisar ou Shift para cancelar.</translation>
 <translation id="397105322502079400">Calculando...</translation>
+<translation id="158849752021629804">Rede doméstica ausente</translation>
+<translation id="6857811139397017780">Ativar <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">Falha ao procurar DHCP</translation>
+<translation id="6692173217867674490">Senha incorreta</translation>
 <translation id="6165508094623778733">Saiba mais</translation>
+<translation id="9046895021617826162">Falha na conexão</translation>
+<translation id="973896785707726617">Esta sessão terminará em <ph name="SESSION_TIME_REMAINING"/>. Você será automaticamente desconectado.</translation>
+<translation id="8372369524088641025">Chave WEP incorreta</translation>
+<translation id="6636709850131805001">Estado não reconhecido</translation>
 <translation id="3573179567135747900">Voltar a &quot;<ph name="FROM_LOCALE"/>&quot; (exige reinicialização)</translation>
 <translation id="8103386449138765447">Mensagens SMS: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Configurações do Google Drive...</translation>
@@ -128,7 +160,7 @@
 <translation id="8000066093800657092">Sem rede</translation>
 <translation id="5941711191222866238">Minimizar</translation>
 <translation id="6911468394164995108">Conectar-se a outra...</translation>
-<translation id="6843725295806269523">sem som</translation>
 <translation id="412065659894267608"><ph name="HOUR"/>h<ph name="MINUTE"/>m até a carga total</translation>
 <translation id="6359806961507272919">SMS de <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Operadora</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_pt-PT.xtb b/ash/strings/ash_strings_pt-PT.xtb
index 69fb682..81297e2 100644
--- a/ash/strings/ash_strings_pt-PT.xtb
+++ b/ash/strings/ash_strings_pt-PT.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Bateria carregada</translation>
 <translation id="5250713215130379958">Ocultar automaticamente iniciador</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> e <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Estado do portal</translation>
 <translation id="30155388420722288">Botão de Sobrecarga</translation>
 <translation id="5571066253365925590">Bluetooth ativado</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Proxy...</translation>
 <translation id="938582441709398163">Sobreposição do teclado</translation>
 <translation id="6979158407327259162">Google Drive</translation>
+<translation id="6943836128787782965">A obtenção de HTTP falhou</translation>
 <translation id="2297568595583585744">Tabuleiro de estado</translation>
+<translation id="1661867754829461514">Falta o PIN</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: A ligar...</translation>
+<translation id="4237016987259239829">Erro de ligação à rede</translation>
 <translation id="2946640296642327832">Ativar Bluetooth</translation>
 <translation id="6459472438155181876">A prolongar ecrã para <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Telemóvel</translation>
 <translation id="6596816719288285829">Endereço IP</translation>
+<translation id="4508265954913339219">A activação falhou</translation>
 <translation id="1812696562331527143">O seu método de introdução foi alterado para <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>terceiros<ph name="END_LINK"/>).
 Prima Shift + Alt para mudar.</translation>
-<translation id="5233638681132016545">Novo separador</translation>
 <translation id="3846575436967432996">Não existem informações de rede disponíveis</translation>
 <translation id="3026237328237090306">Configurar dados móveis</translation>
 <translation id="785750925697875037">Ver conta do telemóvel</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Desativar Bluetooth</translation>
 <translation id="3126069444801937830">Reiniciar para atualizar</translation>
 <translation id="735745346212279324">VPN desligado</translation>
+<translation id="7320906967354320621">Inactiva</translation>
 <translation id="6303423059719347535">A bateria está <ph name="PERCENTAGE"/>% cheia</translation>
+<translation id="2778346081696727092">Falha ao autenticar com o nome de utilizador ou palavra-passe fornecidos</translation>
 <translation id="3294437725009624529">Convidado</translation>
 <translation id="8190698733819146287">Personalizar idiomas e introdução...</translation>
-<translation id="598295083618286569">Bluetooth ligado</translation>
+<translation id="7170041865419449892">Fora de alcance</translation>
+<translation id="4804818685124855865">Desligar</translation>
 <translation id="5222676887888702881">Terminar sessão</translation>
+<translation id="2688477613306174402">Configuração</translation>
+<translation id="1272079795634619415">Parar</translation>
 <translation id="4957722034734105353">Saiba mais...</translation>
 <translation id="2964193600955408481">Desativar Wi-Fi</translation>
 <translation id="811680302244032017">Adicionar aparelho...</translation>
 <translation id="2509468283778169019">CAPS LOCK está ativado</translation>
 <translation id="3892641579809465218">Apresentação Interna</translation>
 <translation id="7823564328645135659">O idioma foi alterado de <ph name="FROM_LOCALE"/> para <ph name="TO_LOCALE"/> depois de sincronizar as suas definições.</translation>
+<translation id="3368922792935385530">Ligado</translation>
 <translation id="8340999562596018839">Respostas faladas</translation>
 <translation id="8654520615680304441">Ligar Wi-Fi...</translation>
 <translation id="5825747213122829519">O seu método de introdução foi alterado para <ph name="INPUT_METHOD_ID"/>.
 Prima Shift + Alt para mudar.</translation>
 <translation id="2562916301614567480">Rede Privada</translation>
 <translation id="6549021752953852991">Sem rede celular disponível</translation>
+<translation id="4379753398862151997">Caro Monitor, não está a resultar entre nós. (Esse monitor não é suportado)</translation>
 <translation id="6426039856985689743">Desativar dados móveis</translation>
 <translation id="3087734570205094154">Parte inferior</translation>
 <translation id="5271016907025319479">A VPN não está configurada.</translation>
-<translation id="1298695107722797780">Terminar sessão\npública</translation>
-<translation id="3232695630852378748">Definições de Bluetooth...</translation>
+<translation id="6803622936009808957">Não foi possível espelhar os ecrãs, porque não foram encontradas resoluções suportadas. Em vez disso, entrou no ambiente de trabalho expandido.</translation>
 <translation id="1480041086352807611">Modo de demonstração</translation>
 <translation id="3626637461649818317"><ph name="PERCENTAGE"/> % restante</translation>
 <translation id="9089416786594320554">Métodos de introdução</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">Encerrar</translation>
 <translation id="4430019312045809116">Volume</translation>
+<translation id="4442424173763614572">A procura de DNS falhou</translation>
 <translation id="6356500677799115505">A bateria está cheia e a carregar.</translation>
 <translation id="7874779702599364982">A procurar redes celulares...</translation>
+<translation id="583281660410589416">Desconhecido</translation>
 <translation id="1383876407941801731">Pesquisa</translation>
+<translation id="7468789844759750875">Visite o portal de ativação de <ph name="NAME"/> para comprar mais dados.</translation>
 <translation id="3901991538546252627">A ligar a <ph name="NAME"/></translation>
 <translation id="2204305834655267233">Informações da Rede</translation>
 <translation id="1621499497873603021">Tempo restante até a bateria terminar, <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">Menu anterior</translation>
 <translation id="1346748346194534595">Direita</translation>
 <translation id="8528322925433439945">Telemóvel...</translation>
+<translation id="7049357003967926684">Associação</translation>
 <translation id="8428213095426709021">Definições</translation>
-<translation id="2472320577759310817">O Bluetooth está desativado.</translation>
 <translation id="2372145515558759244">A sincronizar aplicações...</translation>
+<translation id="7256405249507348194">Erro não reconhecido: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">A verificação AAA falhou</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: A desligar...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> até estar carregada</translation>
 <translation id="5787281376604286451">As respostas faladas estão ativadas.
 Prima Ctrl+Alt+Z para desativar.</translation>
 <translation id="4479639480957787382">Ethernet</translation>
+<translation id="6312403991423642364">Erro de rede desconhecido</translation>
 <translation id="1467432559032391204">Esquerda</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830">A ativar <ph name="NAME"/></translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">Maximizar</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: A ligar...</translation>
+<translation id="8639033665604704195">Falha ao autenticar com a chave pré-partilhada fornecida</translation>
 <translation id="252373100621549798">Apresentação Desconhecida</translation>
 <translation id="1882897271359938046">A espelhar para <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Bloquear</translation>
 <translation id="2805756323405976993">Aplicações</translation>
-<translation id="2482878487686419369">Notificações</translation>
+<translation id="1512064327686280138">Falha na activação</translation>
+<translation id="5097002363526479830">Falha ao ligar à rede &quot;<ph name="NAME"/>&quot;: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">A ligação Wi-Fi está desativada.</translation>
-<translation id="2872961005593481000">Encerrar</translation>
+<translation id="8036518327127111261">Falha ao autenticar com o certificado fornecido</translation>
 <translation id="8132793192354020517">Ligado a <ph name="NAME"/></translation>
 <translation id="7052914147756339792">Definir imagem de fundo...</translation>
-<translation id="2739500853984626550">Não existem dispositivos bluetooth disponíveis</translation>
-<translation id="2666092431469916601">Parte superior</translation>
+<translation id="8678698760965522072">Estado on-line</translation>
+<translation id="1119447706177454957">Erro interno</translation>
 <translation id="3019353588588144572">Tempo restante até a bateria estar totalmente carregada: <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">Lupa</translation>
+<translation id="7005812687360380971">Falha</translation>
 <translation id="1602076796624386989">Ativar dados móveis</translation>
 <translation id="6981982820502123353">Acessibilidade</translation>
 <translation id="3157931365184549694">Restaurar</translation>
+<translation id="4274292172790327596">Erro não reconhecido</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">A procurar dispositivos...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">A pesquisar redes Wi-Fi...</translation>
+<translation id="7229570126336867161">Requer EVDO</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> é uma sessão pública gerida por <ph name="DOMAIN"/></translation>
 <translation id="7029814467594812963">Sair da sessão</translation>
 <translation id="8454013096329229812">A ligação Wi-Fi está ativada.</translation>
 <translation id="4872237917498892622">Alt + Pesquisar ou Shift</translation>
 <translation id="2983818520079887040">Definições...</translation>
-<translation id="5467313780247887226">Não é possível duplicar a imagem em monitores anexados. Não foi encontrada qualquer resolução correspondente.</translation>
+<translation id="8927026611342028580">Ligação Solicitada</translation>
+<translation id="8300849813060516376">O OTASP falhou</translation>
 <translation id="2792498699870441125">Alt + Pesquisar</translation>
 <translation id="8660803626959853127">A sincronizar <ph name="COUNT"/> ficheiro(s)</translation>
 <translation id="639644700271529076">CAPS LOCK está desativado</translation>
-<translation id="4101192585425716296">Centro de Mensagens</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: a ativar...</translation>
+<translation id="1391854757121130358">Poderá ter utilizado toda a sua bonificação de dados móveis.</translation>
 <translation id="4864165860509564259">Posição do iniciador</translation>
 <translation id="7593891976182323525">Pesquisar ou Shift</translation>
 <translation id="7649070708921625228">Ajuda</translation>
 <translation id="3050422059534974565">CAPS LOCK ativado.
 Prima Pesquisar ou Shift para cancelar.</translation>
 <translation id="397105322502079400">A calcular...</translation>
+<translation id="158849752021629804">Requer rede doméstica</translation>
+<translation id="6857811139397017780">Activar <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">A procura DHCP falhou</translation>
+<translation id="6692173217867674490">Frase de acesso incorrecta</translation>
 <translation id="6165508094623778733">Saiba mais</translation>
+<translation id="9046895021617826162">A ligação falhou</translation>
+<translation id="973896785707726617">Esta sessão irá terminar em <ph name="SESSION_TIME_REMAINING"/>. A sua sessão será automaticamente terminada.</translation>
+<translation id="8372369524088641025">Chave WEP incorrecta</translation>
+<translation id="6636709850131805001">Estado não reconhecido</translation>
 <translation id="3573179567135747900">Reverter alteração para <ph name="FROM_LOCALE"/> (requer reinicio)</translation>
 <translation id="8103386449138765447">Mensagens SMS: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Definições do Google Drive...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">Sem rede</translation>
 <translation id="5941711191222866238">Minimizar</translation>
 <translation id="6911468394164995108">Aderir a outra...</translation>
-<translation id="6843725295806269523">desativar som</translation>
 <translation id="412065659894267608"><ph name="HOUR"/>h <ph name="MINUTE"/>m até ficar completa</translation>
 <translation id="6359806961507272919">SMS de <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Operador</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_ro.xtb b/ash/strings/ash_strings_ro.xtb
index aa506ca..697e97f 100644
--- a/ash/strings/ash_strings_ro.xtb
+++ b/ash/strings/ash_strings_ro.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Baterie încărcată complet</translation>
 <translation id="5250713215130379958">Ascundeți automat lansatorul</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/>:<ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Stare portal</translation>
 <translation id="30155388420722288">Butonul Overflow</translation>
 <translation id="5571066253365925590">Bluetooth activat</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Proxy...</translation>
 <translation id="938582441709398163">Suprapunere a tastaturii</translation>
 <translation id="6979158407327259162">Disc Google</translation>
+<translation id="6943836128787782965">Metoda GET a protocolului HTTP a eșuat</translation>
 <translation id="2297568595583585744">Bara de stare</translation>
+<translation id="1661867754829461514">Codul PIN lipsește</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: se conectează...</translation>
+<translation id="4237016987259239829">Eroare de conectare la rețea</translation>
 <translation id="2946640296642327832">Activați Bluetooth</translation>
 <translation id="6459472438155181876">Se extinde ecranul pe <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Celular</translation>
 <translation id="6596816719288285829">Adresă IP</translation>
+<translation id="4508265954913339219">Activarea nu a reușit</translation>
 <translation id="1812696562331527143">Metoda de introducere s-a schimbat la <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>terță parte<ph name="END_LINK"/>).
         Apăsați pe Shift + Alt pentru a comuta.</translation>
-<translation id="5233638681132016545">Filă nouă</translation>
 <translation id="3846575436967432996">Nu sunt disponibile informații despre rețele</translation>
 <translation id="3026237328237090306">Configurați datele mobile</translation>
 <translation id="785750925697875037">Afișați contul mobil</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Dezactivați Bluetooth</translation>
 <translation id="3126069444801937830">Reporniți pentru a actualiza</translation>
 <translation id="735745346212279324">Rețea VPN deconectată</translation>
+<translation id="7320906967354320621">Inactivă</translation>
 <translation id="6303423059719347535">Nivelul bateriei este de <ph name="PERCENTAGE"/> %</translation>
+<translation id="2778346081696727092">Autentificarea cu numele de utilizator sau parola furnizate a eșuat</translation>
 <translation id="3294437725009624529">Invitat</translation>
 <translation id="8190698733819146287">Personalizați limbile și modul de introducere...</translation>
-<translation id="598295083618286569">Conectat prin Bluetooth</translation>
+<translation id="7170041865419449892">Fără acoperire</translation>
+<translation id="4804818685124855865">Deconectați-vă</translation>
 <translation id="5222676887888702881">Deconectați-vă</translation>
+<translation id="2688477613306174402">Configurare</translation>
+<translation id="1272079795634619415">Opriți</translation>
 <translation id="4957722034734105353">Aflați mai multe...</translation>
 <translation id="2964193600955408481">Dezactivați Wi-Fi</translation>
 <translation id="811680302244032017">Adăugați un dispozitiv...</translation>
 <translation id="2509468283778169019">Tasta CAPS LOCK este activată</translation>
 <translation id="3892641579809465218">Afișaj intern</translation>
 <translation id="7823564328645135659">După sincronizarea setărilor, limba a fost modificată de la „<ph name="FROM_LOCALE"/>” la „<ph name="TO_LOCALE"/>”.</translation>
+<translation id="3368922792935385530">Conectat</translation>
 <translation id="8340999562596018839">Feedback vocal</translation>
 <translation id="8654520615680304441">Activați Wi-Fi...</translation>
 <translation id="5825747213122829519">Metoda de introducere s-a schimbat la <ph name="INPUT_METHOD_ID"/>.
         Apăsați pe Shift + Alt pentru a comuta.</translation>
 <translation id="2562916301614567480">Rețea privată</translation>
 <translation id="6549021752953852991">Nicio rețea mobilă disponibilă</translation>
+<translation id="4379753398862151997">Dear Monitor, it's not working out between us. (Monitorul respectiv nu este acceptat)</translation>
 <translation id="6426039856985689743">Dezactivați datele mobile</translation>
 <translation id="3087734570205094154">Jos</translation>
 <translation id="5271016907025319479">Rețeaua VPN nu este configurată.</translation>
-<translation id="1298695107722797780">Încheiați sesiunea\npublică</translation>
-<translation id="3232695630852378748">Setări Bluetooth...</translation>
+<translation id="6803622936009808957">Afișajele nu au putut fi oglindite, deoarece nu au fost găsite rezoluții acceptate. Ați intrat, în schimb, în modul monitor extins.</translation>
 <translation id="1480041086352807611">Modul demonstrativ</translation>
 <translation id="3626637461649818317">Nivel disponibil: <ph name="PERCENTAGE"/>%</translation>
 <translation id="9089416786594320554">Metode de introducere</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/> %</translation>
 <translation id="1895658205118569222">Închideți</translation>
 <translation id="4430019312045809116">Volum</translation>
+<translation id="4442424173763614572">Căutarea DNS a eșuat</translation>
 <translation id="6356500677799115505">Bateria este plină și se încarcă.</translation>
 <translation id="7874779702599364982">Se caută rețele mobile...</translation>
+<translation id="583281660410589416">Necunoscut</translation>
 <translation id="1383876407941801731">Căutați</translation>
+<translation id="7468789844759750875">Accesați portalul de activare <ph name="NAME"/> pentru a achiziționa mai multe date.</translation>
 <translation id="3901991538546252627">Se conectează la <ph name="NAME"/></translation>
 <translation id="2204305834655267233">Informații despre rețea</translation>
 <translation id="1621499497873603021">Timp rămas până la descărcarea bateriei: <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">Meniul anterior</translation>
 <translation id="1346748346194534595">Dreapta</translation>
 <translation id="8528322925433439945">Rețele mobile...</translation>
+<translation id="7049357003967926684">Asociație</translation>
 <translation id="8428213095426709021">Setări</translation>
-<translation id="2472320577759310817">Bluetooth oprit.</translation>
 <translation id="2372145515558759244">Se sincronizează aplicațiile...</translation>
+<translation id="7256405249507348194">Eroare nerecunoscută: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">Verificarea AAA a eșuat</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: se deconectează...</translation>
 <translation id="8456362689280298700">Timp până la finalizare: <ph name="HOUR"/>:<ph name="MINUTE"/></translation>
 <translation id="5787281376604286451">Este activat feedbackul vocal.
 Apăsați Ctrl+Alt+Z pentru a-l dezactiva.</translation>
 <translation id="4479639480957787382">Ethernet</translation>
+<translation id="6312403991423642364">Eroare de rețea necunoscută</translation>
 <translation id="1467432559032391204">Stânga</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830">Se activează <ph name="NAME"/></translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">Maximizați</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: se conectează...</translation>
+<translation id="8639033665604704195">Autentificarea cu cheia predistribuită furnizată a eșuat</translation>
 <translation id="252373100621549798">Afișaj necunoscut</translation>
 <translation id="1882897271359938046">Se oglindește pe <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Blocați</translation>
 <translation id="2805756323405976993">Aplicații</translation>
-<translation id="2482878487686419369">Notificări</translation>
+<translation id="1512064327686280138">Activare nereușită</translation>
+<translation id="5097002363526479830">A eșuat conectarea la rețeaua „<ph name="NAME"/>”: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Conexiunea Wi-Fi este dezactivată.</translation>
-<translation id="2872961005593481000">Închideți</translation>
+<translation id="8036518327127111261">Autentificarea cu certificatul furnizat a eșuat</translation>
 <translation id="8132793192354020517">Conectat la <ph name="NAME"/></translation>
 <translation id="7052914147756339792">Setați o imagine de fundal...</translation>
-<translation id="2739500853984626550">Nu sunt disponibile gadgeturi bluetooth</translation>
-<translation id="2666092431469916601">Sus</translation>
+<translation id="8678698760965522072">Stare online</translation>
+<translation id="1119447706177454957">Eroare internă</translation>
 <translation id="3019353588588144572">Timp rămas până la încărcarea completă a bateriei: <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">Lupă de ecran</translation>
+<translation id="7005812687360380971">Nereușit</translation>
 <translation id="1602076796624386989">Activați datele mobile</translation>
 <translation id="6981982820502123353">Accesibilitate</translation>
 <translation id="3157931365184549694">Restabiliți</translation>
+<translation id="4274292172790327596">Eroare nerecunoscută</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Se caută gadgeturi...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Se caută rețele Wi-Fi...</translation>
+<translation id="7229570126336867161">Este necesar EVDO</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> este o sesiune publică gestionată de <ph name="DOMAIN"/></translation>
 <translation id="7029814467594812963">Ieșiți din sesiune</translation>
 <translation id="8454013096329229812">Conexiunea Wi-Fi este activată.</translation>
 <translation id="4872237917498892622">Alt+Căutare sau Shift</translation>
 <translation id="2983818520079887040">Setări...</translation>
-<translation id="5467313780247887226">Nu se poate reda imaginea pe monitoarele conectate. Nu a fost găsită nicio rezoluție potrivită.</translation>
+<translation id="8927026611342028580">Conectare solicitată</translation>
+<translation id="8300849813060516376">OTASP a eșuat</translation>
 <translation id="2792498699870441125">Alt+Căutare</translation>
 <translation id="8660803626959853127">Se sincronizează <ph name="COUNT"/> (de) fișiere</translation>
 <translation id="639644700271529076">Tasta CAPS LOCK este dezactivată</translation>
-<translation id="4101192585425716296">Centrul de mesaje</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: se activează...</translation>
+<translation id="1391854757121130358">Este posibil să fi consumat complet alocarea datelor mobile.</translation>
 <translation id="4864165860509564259">Poziția lansatorului</translation>
 <translation id="7593891976182323525">Căutare sau Shift</translation>
 <translation id="7649070708921625228">Ajutor</translation>
 <translation id="3050422059534974565">Tasta CAPS LOCK este activată.
 Apăsați Căutare sau Shift pentru a anula.</translation>
 <translation id="397105322502079400">Se calculează...</translation>
+<translation id="158849752021629804">Este necesară rețeaua de domiciliu</translation>
+<translation id="6857811139397017780">Activați <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">Căutarea DHCP a eșuat</translation>
+<translation id="6692173217867674490">Expresie de acces greșită</translation>
 <translation id="6165508094623778733">Aflați mai multe</translation>
+<translation id="9046895021617826162">Conectarea a eșuat</translation>
+<translation id="973896785707726617">Această sesiune se va încheia în <ph name="SESSION_TIME_REMAINING"/>. Veți fi deconectat(ă) automat.</translation>
+<translation id="8372369524088641025">Cheie WEP greșită</translation>
+<translation id="6636709850131805001">Stare nerecunoscută</translation>
 <translation id="3573179567135747900">Modificați înapoi la „<ph name="FROM_LOCALE"/>” (este necesară repornirea)</translation>
 <translation id="8103386449138765447">Mesaje SMS: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Setări Disc Google...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">Nicio rețea</translation>
 <translation id="5941711191222866238">Minimizați</translation>
 <translation id="6911468394164995108">Conectați-vă la altă rețea...</translation>
-<translation id="6843725295806269523">dezactivați sunetul</translation>
 <translation id="412065659894267608"><ph name="HOUR"/> h. <ph name="MINUTE"/> min. până la încărcare completă</translation>
 <translation id="6359806961507272919">SMS de la <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Operator</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_ru.xtb b/ash/strings/ash_strings_ru.xtb
index 67a8538..f7eb81d 100644
--- a/ash/strings/ash_strings_ru.xtb
+++ b/ash/strings/ash_strings_ru.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Аккумулятор заряжен.</translation>
 <translation id="5250713215130379958">Автоматически скрывать панель запуска</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Состояние портала</translation>
 <translation id="30155388420722288">Кнопка переполнения</translation>
 <translation id="5571066253365925590">Bluetooth включен</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,110 +16,141 @@
 <translation id="5565793151875479467">Прокси-сервер…</translation>
 <translation id="938582441709398163">Накладка на клавиатуру</translation>
 <translation id="6979158407327259162">Диск Google</translation>
+<translation id="6943836128787782965">Произошла ошибка запроса HTTP GET</translation>
 <translation id="2297568595583585744">Строка состояния</translation>
+<translation id="1661867754829461514">PIN-код отсутствует</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: соединение...</translation>
+<translation id="4237016987259239829">Ошибка сетевого подключения</translation>
 <translation id="2946640296642327832">Включить Bluetooth</translation>
 <translation id="6459472438155181876">Расширение экрана на <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Сотовый</translation>
 <translation id="6596816719288285829">IP-адрес</translation>
+<translation id="4508265954913339219">Активация завершилась со сбоем</translation>
 <translation id="1812696562331527143">Способ ввода изменен на <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>независимый разработчик<ph name="END_LINK"/>).
 Для переключения нажмите Shift + Alt.</translation>
-<translation id="5233638681132016545">Новая вкладка</translation>
 <translation id="3846575436967432996">Информация о сетях недоступна</translation>
 <translation id="3026237328237090306">Настроить мобильную передачу данных</translation>
 <translation id="785750925697875037">Просмотр мобильного аккаунта</translation>
 <translation id="153454903766751181">Инициализация сотового модема…</translation>
 <translation id="7864539943188674973">Отключить Bluetooth</translation>
-<translation id="3126069444801937830">Перезагрузите, чтобы выполнить обновление</translation>
+<translation id="3126069444801937830">Перезагрузите, чтобы обновить</translation>
 <translation id="735745346212279324">VPN-соединение прервано</translation>
+<translation id="7320906967354320621">Не активно</translation>
 <translation id="6303423059719347535">Батарея заряжена на <ph name="PERCENTAGE"/>%.</translation>
+<translation id="2778346081696727092">Не удалось выполнить аутентификацию</translation>
 <translation id="3294437725009624529">Гость</translation>
 <translation id="8190698733819146287">Настройка языков и ввода...</translation>
-<translation id="598295083618286569">Bluetooth подключен</translation>
+<translation id="7170041865419449892">Выход за рамки диапазона</translation>
+<translation id="4804818685124855865">Отключиться</translation>
 <translation id="5222676887888702881">Выйти</translation>
+<translation id="2688477613306174402">Конфигурация</translation>
+<translation id="1272079795634619415">Остановить</translation>
 <translation id="4957722034734105353">Подробнее…</translation>
 <translation id="2964193600955408481">Отключить Wi-Fi</translation>
 <translation id="811680302244032017">Добавить устройство</translation>
 <translation id="2509468283778169019">Включен режим CAPS LOCK</translation>
 <translation id="3892641579809465218">Встроенный дисплей</translation>
 <translation id="7823564328645135659">В результате синхронизации настроек язык изменен. Теперь используется <ph name="TO_LOCALE"/>, а не <ph name="FROM_LOCALE"/>.</translation>
+<translation id="3368922792935385530">Подключено</translation>
 <translation id="8340999562596018839">Голосовое сопровождение</translation>
 <translation id="8654520615680304441">Включение Wi-Fi...</translation>
 <translation id="5825747213122829519">Способ ввода изменен на <ph name="INPUT_METHOD_ID"/>.
 Для переключения нажмите Shift + Alt.</translation>
 <translation id="2562916301614567480">Частная сеть</translation>
 <translation id="6549021752953852991">Сеть не найдена</translation>
+<translation id="4379753398862151997">Не удалось выполнить операцию.</translation>
 <translation id="6426039856985689743">Отключить мобильную передачу данных</translation>
 <translation id="3087734570205094154">Низ</translation>
 <translation id="5271016907025319479">VPN не настроена.</translation>
-<translation id="1298695107722797780">Завершить\nобщий сеанс</translation>
-<translation id="3232695630852378748">Настройки Bluetooth</translation>
+<translation id="6803622936009808957">Не удалось дублировать изображение экрана, т. к. указанное разрешение не поддерживается. Включен режим расширенного рабочего стола.</translation>
 <translation id="1480041086352807611">Демонстрационный режим</translation>
 <translation id="3626637461649818317">Осталось <ph name="PERCENTAGE"/>%</translation>
 <translation id="9089416786594320554">Методы ввода</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">Завершение работы</translation>
 <translation id="4430019312045809116">Объем</translation>
+<translation id="4442424173763614572">Произошла ошибка при поиске сервера DNS</translation>
 <translation id="6356500677799115505">Батарея заряжена и подключена к источнику питания.</translation>
 <translation id="7874779702599364982">Поиск сетей мобильной связи...</translation>
+<translation id="583281660410589416">неизвестно</translation>
 <translation id="1383876407941801731">Поиск</translation>
+<translation id="7468789844759750875">Чтобы приобрести дополнительный пакет данных, перейдите на портал активации <ph name="NAME"/>.</translation>
 <translation id="3901991538546252627">Подключение к <ph name="NAME"/></translation>
 <translation id="2204305834655267233">Информация о сети</translation>
 <translation id="1621499497873603021">Оставшееся время работы от батареи: <ph name="TIME_LEFT"/>.</translation>
-<translation id="5980301590375426705">Завершить гостевой сеанс</translation>
+<translation id="5980301590375426705">Выйти из гостевого режима</translation>
 <translation id="4471417012762451363">Батарея заряжена на <ph name="PERCENTAGE"/>% и подключена к источнику питания.</translation>
 <translation id="8308637677604853869">Предыдущее меню</translation>
 <translation id="1346748346194534595">Вправо</translation>
 <translation id="8528322925433439945">Мобильные сети…</translation>
+<translation id="7049357003967926684">Связь</translation>
 <translation id="8428213095426709021">Настройки</translation>
-<translation id="2472320577759310817">Bluetooth отключен.</translation>
 <translation id="2372145515558759244">Синхронизация приложений…</translation>
+<translation id="7256405249507348194">Неопознанная ошибка: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">Сбой при проверке AAA</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: отключение...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> до заполнения</translation>
 <translation id="5787281376604286451">Голосовое сопровождение включено. Чтобы отключить его, нажмите Ctrl + Alt + Z.</translation>
 <translation id="4479639480957787382">Ethernet</translation>
+<translation id="6312403991423642364">Неизвестная ошибка сети</translation>
 <translation id="1467432559032391204">Влево</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830">Активация <ph name="NAME"/></translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">Развернуть</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: соединение...</translation>
+<translation id="8639033665604704195">Не удалось выполнить аутентификацию</translation>
 <translation id="252373100621549798">Неизвестный дисплей</translation>
 <translation id="1882897271359938046">Дублирование экрана в <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Заблокировать</translation>
 <translation id="2805756323405976993">Приложения</translation>
-<translation id="2482878487686419369">Оповещения</translation>
+<translation id="1512064327686280138">Сбой активации</translation>
+<translation id="5097002363526479830">Не удалось подключиться к сети <ph name="NAME"/>: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi отключен</translation>
-<translation id="2872961005593481000">Завершить работу</translation>
+<translation id="8036518327127111261">Не удалось выполнить аутентификацию</translation>
 <translation id="8132793192354020517">Подключено к сети <ph name="NAME"/></translation>
 <translation id="7052914147756339792">Выбрать обои</translation>
-<translation id="2739500853984626550">Устройства Bluetooth недоступны</translation>
-<translation id="2666092431469916601">Наверх</translation>
+<translation id="8678698760965522072">Состояние &quot;В сети&quot;</translation>
+<translation id="1119447706177454957">Внутренняя ошибка</translation>
 <translation id="3019353588588144572">Оставшееся время до полной зарядки батареи: <ph name="TIME_REMAINING"/>.</translation>
 <translation id="3473479545200714844">Лупа</translation>
+<translation id="7005812687360380971">Сбой</translation>
 <translation id="1602076796624386989">Включить мобильную передачу данных</translation>
 <translation id="6981982820502123353">Специальные возможности</translation>
 <translation id="3157931365184549694">Восстановить</translation>
+<translation id="4274292172790327596">Нераспознанная ошибка</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Поиск устройств…</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Поиск сетей Wi-Fi...</translation>
+<translation id="7229570126336867161">Необходимо наличие EV-DO</translation>
 <translation id="2999742336789313416">Открытый сеанс <ph name="DISPLAY_NAME"/> выполняется в домене <ph name="DOMAIN"/></translation>
 <translation id="7029814467594812963">Завершить сеанс</translation>
 <translation id="8454013096329229812">Wi-Fi включен</translation>
 <translation id="4872237917498892622">Alt + Search или Shift</translation>
 <translation id="2983818520079887040">Настройки...</translation>
-<translation id="5467313780247887226">Не удается дублировать изображение на подключенных мониторах. Подходящее разрешение не обнаружено.</translation>
+<translation id="8927026611342028580">Запрос на подключение отправлен</translation>
+<translation id="8300849813060516376">Сбой OTASP</translation>
 <translation id="2792498699870441125">Alt + Search</translation>
 <translation id="8660803626959853127">Синхронизация файлов (<ph name="COUNT"/>)</translation>
 <translation id="639644700271529076">CAPS LOCK отключен</translation>
-<translation id="4101192585425716296">Центр сообщений</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: выполняется активация...</translation>
+<translation id="1391854757121130358">Вероятно, вы использовали весь объем данных, предусмотренный тарифным планом.</translation>
 <translation id="4864165860509564259">Положение панели запуска</translation>
 <translation id="7593891976182323525">Search или Shift</translation>
 <translation id="7649070708921625228">Справка</translation>
 <translation id="3050422059534974565">Включен режим CAPS LOCK.
 Чтобы отключить его, нажмите Search или Shift.</translation>
 <translation id="397105322502079400">Вычисление…</translation>
+<translation id="158849752021629804">Необходима домашняя сеть</translation>
+<translation id="6857811139397017780">Активировать <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">Поиск DHCP завершен со сбоем</translation>
+<translation id="6692173217867674490">Неправильная кодовая фраза</translation>
 <translation id="6165508094623778733">Подробнее...</translation>
+<translation id="9046895021617826162">Сбой подключения</translation>
+<translation id="973896785707726617">Сеанс будет завершен через <ph name="SESSION_TIME_REMAINING"/>. Произойдет автоматический выход из системы.</translation>
+<translation id="8372369524088641025">Недопустимый ключ WEP</translation>
+<translation id="6636709850131805001">Нераспознанное состояние</translation>
 <translation id="3573179567135747900">Вернуться к языку: &quot;<ph name="FROM_LOCALE"/>&quot; (потребуется перезагрузка)</translation>
 <translation id="8103386449138765447">SMS: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Настройки Диска Google…</translation>
@@ -129,7 +161,7 @@
 <translation id="8000066093800657092">Нет сети</translation>
 <translation id="5941711191222866238">Свернуть</translation>
 <translation id="6911468394164995108">Подключиться к другой сети...</translation>
-<translation id="6843725295806269523">отключить звук</translation>
 <translation id="412065659894267608">До полной зарядки: <ph name="HOUR"/> ч <ph name="MINUTE"/> мин</translation>
 <translation id="6359806961507272919">SMS от <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Оператор связи</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_sk.xtb b/ash/strings/ash_strings_sk.xtb
index c0d2fc2..ae3a8a9 100644
--- a/ash/strings/ash_strings_sk.xtb
+++ b/ash/strings/ash_strings_sk.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Batéria je nabitá</translation>
 <translation id="5250713215130379958">Automaticky skryť spúšťač</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> a <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Stav portálu</translation>
 <translation id="30155388420722288">Tlačidlo pretečenia</translation>
 <translation id="5571066253365925590">Rozhranie Bluetooth je povolené</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Server proxy...</translation>
 <translation id="938582441709398163">Prekryvná vrstva klávesnice</translation>
 <translation id="6979158407327259162">Disk Google</translation>
+<translation id="6943836128787782965">Príkaz get protokolu HTTP zlyhal</translation>
 <translation id="2297568595583585744">Stavový panel</translation>
+<translation id="1661867754829461514">Chýba kód PIN</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: pripája sa...</translation>
+<translation id="4237016987259239829">Chyba sieťového pripojenia</translation>
 <translation id="2946640296642327832">Povoliť rozhranie Bluetooth</translation>
 <translation id="6459472438155181876">Rozšírenie obrazovky na displej <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Mobilné</translation>
 <translation id="6596816719288285829">Adresa IP</translation>
+<translation id="4508265954913339219">Aktivácia zlyhala</translation>
 <translation id="1812696562331527143">Metóda vstupu sa zmenila na <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>tretia strana<ph name="END_LINK"/>).
         Prepnete ju stlačením klávesov Shift + Alt.</translation>
-<translation id="5233638681132016545">Nová karta</translation>
 <translation id="3846575436967432996">Informácie o sieti nie sú k dispozícii</translation>
 <translation id="3026237328237090306">Nastavenie mobilného dátového pripojenia</translation>
 <translation id="785750925697875037">Zobraziť mobilný účet</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Zakázať rozhranie Bluetooth</translation>
 <translation id="3126069444801937830">Reštartovaním vykonáte aktualizáciu</translation>
 <translation id="735745346212279324">Sieť VPN je odpojená</translation>
+<translation id="7320906967354320621">Nečinná</translation>
 <translation id="6303423059719347535">Batéria je nabitá na <ph name="PERCENTAGE"/> %</translation>
+<translation id="2778346081696727092">Overenie totožnosti pomocou zadaného používateľského mena a hesla zlyhalo</translation>
 <translation id="3294437725009624529">Hosť</translation>
 <translation id="8190698733819146287">Prebieha prispôsobenie jazykov a vstupu...</translation>
-<translation id="598295083618286569">Rozhranie Bluetooth je pripojené</translation>
+<translation id="7170041865419449892">Mimo rozsah</translation>
+<translation id="4804818685124855865">Odpojiť</translation>
 <translation id="5222676887888702881">Odhlásiť sa</translation>
+<translation id="2688477613306174402">Konfigurácia</translation>
+<translation id="1272079795634619415">Zastaviť</translation>
 <translation id="4957722034734105353">Viac informácií...</translation>
 <translation id="2964193600955408481">Zakázať sieť Wi-Fi</translation>
 <translation id="811680302244032017">Pridať zariadenie ...</translation>
 <translation id="2509468283778169019">Kláves CAPS LOCK je zapnutý</translation>
 <translation id="3892641579809465218">Interný displej</translation>
 <translation id="7823564328645135659">Po synchronizácii vašich nastavení bol zmenený jazyk „<ph name="FROM_LOCALE"/>“ na jazyk „<ph name="TO_LOCALE"/>“.</translation>
+<translation id="3368922792935385530">Pripojené</translation>
 <translation id="8340999562596018839">Hlasová odozva</translation>
 <translation id="8654520615680304441">Zapnúť sieť Wi-Fi...</translation>
 <translation id="5825747213122829519">Metóda vstupu sa zmenila na <ph name="INPUT_METHOD_ID"/>.
         Prepnete ju stlačením klávesov Shift + Alt.</translation>
 <translation id="2562916301614567480">Súkromná sieť</translation>
 <translation id="6549021752953852991">K dispozícii nie je žiadna mobilná sieť</translation>
+<translation id="4379753398862151997">Milý monitor, medzi nami to nefunguje. (Tento monitor sa nepodporuje)</translation>
 <translation id="6426039856985689743">Zakázať mobilné dátové pripojenie</translation>
 <translation id="3087734570205094154">Spodok</translation>
 <translation id="5271016907025319479">Sieť VPN nie je nakonfigurovaná.</translation>
-<translation id="1298695107722797780">Ukončiť verejnú\nreláciu</translation>
-<translation id="3232695630852378748">Nastavenia rozhrania Bluetooth...</translation>
+<translation id="6803622936009808957">Obraz na monitoroch sa nedá zrkadliť, pretože sa nenašli podporované rozlíšenia. Namiesto toho sa spustil režim rozšírenej pracovnej plochy.</translation>
 <translation id="1480041086352807611">Režim ukážky</translation>
 <translation id="3626637461649818317">Zostáva <ph name="PERCENTAGE"/> %</translation>
 <translation id="9089416786594320554">Metódy vstupu</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/> %</translation>
 <translation id="1895658205118569222">Vypnúť</translation>
 <translation id="4430019312045809116">Hlasitosť</translation>
+<translation id="4442424173763614572">Vyhľadanie DNS zlyhalo</translation>
 <translation id="6356500677799115505">Batéria je úplne nabitá a nabíja sa.</translation>
 <translation id="7874779702599364982">Prebieha vyhľadávanie mobilných sietí...</translation>
+<translation id="583281660410589416">Neznámy</translation>
 <translation id="1383876407941801731">Vyhľadávanie</translation>
+<translation id="7468789844759750875">Ak chcete kúpiť ďalšie dáta, navštívte aktivačný portál <ph name="NAME"/>.</translation>
 <translation id="3901991538546252627">Pripája sa k sieti <ph name="NAME"/></translation>
 <translation id="2204305834655267233">Informácie o sieti</translation>
 <translation id="1621499497873603021">Čas zostávajúci do vybitia batérie: <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">Predchádzajúca ponuka</translation>
 <translation id="1346748346194534595">Doprava</translation>
 <translation id="8528322925433439945">Mobilné siete...</translation>
+<translation id="7049357003967926684">Asociácia</translation>
 <translation id="8428213095426709021">Nastavenia</translation>
-<translation id="2472320577759310817">Pripojenie Bluetooth je vypnuté.</translation>
 <translation id="2372145515558759244">Prebieha synchronizácia aplikácií...</translation>
+<translation id="7256405249507348194">Nerozpoznaná chyba: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">Kontrola AAA zlyhala</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: odpája sa...</translation>
 <translation id="8456362689280298700">Čas do úplného nabitia: <ph name="HOUR"/>:<ph name="MINUTE"/></translation>
 <translation id="5787281376604286451">Hlasová odozva je povolená.
 Zakážete ju stlačením klávesov Ctrl+Alt+Z.</translation>
 <translation id="4479639480957787382">Ethernet</translation>
+<translation id="6312403991423642364">Neznáma chyba siete</translation>
 <translation id="1467432559032391204">Doľava</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830">Aktivujte sa sieť <ph name="NAME"/></translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">Maximalizovať</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: pripája sa...</translation>
+<translation id="8639033665604704195">Overenie totožnosti pomocou zadaného predzdieľaného kľúča zlyhalo</translation>
 <translation id="252373100621549798">Neznáma obrazovka</translation>
 <translation id="1882897271359938046">Zrkadlenie na displej <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Uzamknúť</translation>
 <translation id="2805756323405976993">Aplikácie</translation>
-<translation id="2482878487686419369">Upozornenia</translation>
+<translation id="1512064327686280138">Zlyhanie aktivácie</translation>
+<translation id="5097002363526479830">K sieti „<ph name="NAME"/>“ sa nepodarilo pripojiť: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Pripojenie Wi-Fi je vypnuté.</translation>
-<translation id="2872961005593481000">Vypnúť</translation>
+<translation id="8036518327127111261">Overenie totožnosti pomocou zadaného certifikátu zlyhalo</translation>
 <translation id="8132793192354020517">Pripojené k stránke <ph name="NAME"/></translation>
 <translation id="7052914147756339792">Nastavenie tapety...</translation>
-<translation id="2739500853984626550">K dispozícii nie sú žiadne zariadenia s technológiou Bluetooth.</translation>
-<translation id="2666092431469916601">Vrch</translation>
+<translation id="8678698760965522072">Stav online</translation>
+<translation id="1119447706177454957">Interná chyba</translation>
 <translation id="3019353588588144572">Čas zostávajúci do úplného nabitia batérie: <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">Lupa</translation>
+<translation id="7005812687360380971">Zlyhanie</translation>
 <translation id="1602076796624386989">Povoliť mobilné dátové pripojenie</translation>
 <translation id="6981982820502123353">Dostupnosť</translation>
 <translation id="3157931365184549694">Obnoviť</translation>
+<translation id="4274292172790327596">Nerozpoznaná chyba</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Hľadajú sa zariadenia...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Prebieha vyhľadávanie sietí Wi-Fi...</translation>
+<translation id="7229570126336867161">Je potrebné pripojenie EVDO</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> je verejná relácia spravovaná stránkami <ph name="DOMAIN"/></translation>
 <translation id="7029814467594812963">Ukončiť reláciu</translation>
 <translation id="8454013096329229812">Pripojenie Wi-Fi je zapnuté.</translation>
 <translation id="4872237917498892622">Alt + Hľadať alebo Shift</translation>
 <translation id="2983818520079887040">Nastavenia...</translation>
-<translation id="5467313780247887226">Na pripojených monitoroch sa nepodarilo duplikovať obraz. Nenašlo sa žiadne zodpovedajúce rozlíšenie.</translation>
+<translation id="8927026611342028580">Vyžaduje sa pripojenie</translation>
+<translation id="8300849813060516376">Zlyhanie služby OTASP</translation>
 <translation id="2792498699870441125">Alt + Hľadať</translation>
 <translation id="8660803626959853127">Synchronizácia súborov (<ph name="COUNT"/>)</translation>
 <translation id="639644700271529076">CAPS LOCK je vypnutý</translation>
-<translation id="4101192585425716296">Centrum správ</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: Aktivuje sa...</translation>
+<translation id="1391854757121130358">Možno ste dosiahli limit povolených mobilných dát.</translation>
 <translation id="4864165860509564259">Pozícia spúťača</translation>
 <translation id="7593891976182323525">Hľadať alebo Shift</translation>
 <translation id="7649070708921625228">Pomocník</translation>
 <translation id="3050422059534974565">Kláves CAPS LOCK je zapnutý.
 Ak ho chcete zrušiť, stlačte klávesy Hľadať alebo Shift.</translation>
 <translation id="397105322502079400">Prebieha výpočet...</translation>
+<translation id="158849752021629804">Je potrebná domáca sieť</translation>
+<translation id="6857811139397017780">Aktivovať zariadenie <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">Vyhľadanie servera DHCP zlyhalo</translation>
+<translation id="6692173217867674490">Zlá prístupová fráza</translation>
 <translation id="6165508094623778733">Viac informácií</translation>
+<translation id="9046895021617826162">Zlyhanie pripojenia</translation>
+<translation id="973896785707726617">Relácia sa ukončí o <ph name="SESSION_TIME_REMAINING"/>. Automaticky dôjde k odhláseniu.</translation>
+<translation id="8372369524088641025">Zlý kľúč WEP</translation>
+<translation id="6636709850131805001">Nerozpoznaný stav</translation>
 <translation id="3573179567135747900">Zmeniť späť na miestne nastavenie „<ph name="FROM_LOCALE"/>“ (vyžaduje sa reštart)</translation>
 <translation id="8103386449138765447">Správy SMS: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Nastavenia služby Disk Google...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">Žiadna sieť</translation>
 <translation id="5941711191222866238">Minimalizovať</translation>
 <translation id="6911468394164995108">Pripojiť k ďalšej...</translation>
-<translation id="6843725295806269523">stlmiť</translation>
 <translation id="412065659894267608"><ph name="HOUR"/>h <ph name="MINUTE"/>min do nabitia</translation>
 <translation id="6359806961507272919">SMS z č. <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Operátor</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_sl.xtb b/ash/strings/ash_strings_sl.xtb
index 3aa3e04..973bca7 100644
--- a/ash/strings/ash_strings_sl.xtb
+++ b/ash/strings/ash_strings_sl.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Baterija je polna</translation>
 <translation id="5250713215130379958">Samodejno skrij zaganjalnik</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> in <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Stanje portala</translation>
 <translation id="30155388420722288">Gumb za presežek</translation>
 <translation id="5571066253365925590">Bluetooth omogočen</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Proxy ...</translation>
 <translation id="938582441709398163">Prekrivna tipkovnica</translation>
 <translation id="6979158407327259162">Google Drive</translation>
+<translation id="6943836128787782965">Ukaz HTTP get ni uspel</translation>
 <translation id="2297568595583585744">Pladenj stanja</translation>
+<translation id="1661867754829461514">Manjka PIN</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: vzpostavljanje povezave ...</translation>
+<translation id="4237016987259239829">Napaka omrežne povezave</translation>
 <translation id="2946640296642327832">Omogoči Bluetooth</translation>
 <translation id="6459472438155181876">Razširitev zaslon na <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Prenosni</translation>
 <translation id="6596816719288285829">Naslov IP</translation>
+<translation id="4508265954913339219">Aktiviranje ni uspelo</translation>
 <translation id="1812696562331527143">Način vnosa se je spremenil v <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>drug ponudnik<ph name="END_LINK"/>).
 Pritisnite Shift + Alt, da ga preklopite.</translation>
-<translation id="5233638681132016545">Nov zavihek</translation>
 <translation id="3846575436967432996">Ni podatkov o omrežju</translation>
 <translation id="3026237328237090306">Nastavitev mobilne podatkovne povezave</translation>
 <translation id="785750925697875037">Prikaz mobilnega računa</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Onemogoči Bluetooth</translation>
 <translation id="3126069444801937830">Znova zaženite za posodobitev</translation>
 <translation id="735745346212279324">Povezava z navideznim zasebnim omrežjem je prekinjena</translation>
+<translation id="7320906967354320621">Nedejavno</translation>
 <translation id="6303423059719347535">Napolnjenost akumulatorja: <ph name="PERCENTAGE"/> %</translation>
+<translation id="2778346081696727092">Preverjanje pristnosti vnesenega uporabniškega imena ali gesla ni uspelo</translation>
 <translation id="3294437725009624529">Gost</translation>
 <translation id="8190698733819146287">Prilagajanje jezikov in vnosa ...</translation>
-<translation id="598295083618286569">Povezava Bluetooth vzpostavljena</translation>
+<translation id="7170041865419449892">Zunaj dosega</translation>
+<translation id="4804818685124855865">Prekini povezavo</translation>
 <translation id="5222676887888702881">Odjava</translation>
+<translation id="2688477613306174402">Konfiguracija</translation>
+<translation id="1272079795634619415">Ustavi</translation>
 <translation id="4957722034734105353">Več o tem ...</translation>
 <translation id="2964193600955408481">Onemogoči Wi-Fi</translation>
 <translation id="811680302244032017">Dodaj napravo ...</translation>
 <translation id="2509468283778169019">Tipka CAPS LOCK je vklopljena</translation>
 <translation id="3892641579809465218">Notranji zaslon</translation>
 <translation id="7823564328645135659">Po sinhronizaciji nastavitev se je jezik spremenil iz jezika »<ph name="FROM_LOCALE"/>« v jezik »<ph name="TO_LOCALE"/>«.</translation>
+<translation id="3368922792935385530">Povezano</translation>
 <translation id="8340999562596018839">Glasovni odziv</translation>
 <translation id="8654520615680304441">Vklop omrežja Wi-Fi ...</translation>
 <translation id="5825747213122829519">Način vnosa se je spremenil v <ph name="INPUT_METHOD_ID"/>.
 Pritisnite Shift + Alt, da ga preklopite.</translation>
 <translation id="2562916301614567480">Zasebno omrežje</translation>
 <translation id="6549021752953852991">Mobilno omrežje ni na voljo</translation>
+<translation id="4379753398862151997">Dragi monitor, med nama se ne bo obneslo. (Ta monitor ni podprt)</translation>
 <translation id="6426039856985689743">Onemogoči mobilno podatkovno povezavo</translation>
 <translation id="3087734570205094154">Na dno</translation>
 <translation id="5271016907025319479">VPN ni konfiguriran.</translation>
-<translation id="1298695107722797780">Končaj javno\nsejo</translation>
-<translation id="3232695630852378748">Nastavitve za Bluetooth ...</translation>
+<translation id="6803622936009808957">Zaslonov ni bilo mogoče zrcaliti, ker ni bilo najdene nobene podprte ločljivosti. Uporabljeno je razširjeno namizje.</translation>
 <translation id="1480041086352807611">Predstavitveni način</translation>
 <translation id="3626637461649818317">Preostane še <ph name="PERCENTAGE"/> %</translation>
 <translation id="9089416786594320554">Načini vnosa</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/> %</translation>
 <translation id="1895658205118569222">Zaprt</translation>
 <translation id="4430019312045809116">Glasnost</translation>
+<translation id="4442424173763614572">Iskanje DNS ni uspelo</translation>
 <translation id="6356500677799115505">Akumulator je poln in se polni.</translation>
 <translation id="7874779702599364982">Iskanje mobilnih omrežij ...</translation>
+<translation id="583281660410589416">Neznano</translation>
 <translation id="1383876407941801731">Iskanje</translation>
+<translation id="7468789844759750875">Če želite kupiti dodatne podatke, obiščite aktivacijski portal <ph name="NAME"/>.</translation>
 <translation id="3901991538546252627">Vzpostavljanje povezave z omrežjem <ph name="NAME"/></translation>
 <translation id="2204305834655267233">Podatki o omrežju</translation>
 <translation id="1621499497873603021">Preostali čas do izpraznitve akumulatorja, <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">Prejšnji meni</translation>
 <translation id="1346748346194534595">V desno</translation>
 <translation id="8528322925433439945">Mobilna ...</translation>
+<translation id="7049357003967926684">Povezava</translation>
 <translation id="8428213095426709021">Nastavitve</translation>
-<translation id="2472320577759310817">Bluetooth je izklopljen.</translation>
 <translation id="2372145515558759244">Sinhronizacija aplikacij ...</translation>
+<translation id="7256405249507348194">Neprepoznana napaka: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">Preverjanje AAA ni uspelo</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: prekinjanje povezave ...</translation>
 <translation id="8456362689280298700">Čas polnjenja: še <ph name="HOUR"/>:<ph name="MINUTE"/></translation>
 <translation id="5787281376604286451">Glasovni odziv je omogočen.
 Če ga želite onemogočiti, pritisnite Ctrl + Alt + Z.</translation>
 <translation id="4479639480957787382">Ethernet</translation>
+<translation id="6312403991423642364">Neznana napaka v omrežju</translation>
 <translation id="1467432559032391204">V levo</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830">Aktiviranje omrežja <ph name="NAME"/></translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">Povečaj</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: vzpostavljanje povezave ...</translation>
+<translation id="8639033665604704195">Preverjanje pristnosti vnesenega ključa v vnaprejšnji skupni rabi ni uspelo</translation>
 <translation id="252373100621549798">Neznan prikaz</translation>
 <translation id="1882897271359938046">Zrcaljenje na <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Zakleni</translation>
 <translation id="2805756323405976993">Google Apps</translation>
-<translation id="2482878487686419369">Obvestila</translation>
+<translation id="1512064327686280138">Napaka pri aktiviranju</translation>
+<translation id="5097002363526479830">Povezava z omrežjem »<ph name="NAME"/>« ni uspela: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi je izklopljen.</translation>
-<translation id="2872961005593481000">Zaustavitev</translation>
+<translation id="8036518327127111261">Preverjanje pristnosti z vnesenim potrdilom ni uspelo</translation>
 <translation id="8132793192354020517">Povezava z <ph name="NAME"/> je vzpostavljena </translation>
 <translation id="7052914147756339792">Nastavi sliko za ozadje ...</translation>
-<translation id="2739500853984626550">Na voljo ni nobena naprava Bluetooth</translation>
-<translation id="2666092431469916601">Na vrh</translation>
+<translation id="8678698760965522072">Stanje s povezavo</translation>
+<translation id="1119447706177454957">Notranja napaka</translation>
 <translation id="3019353588588144572">Preostali čas do napolnitve akumulatorja, <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">Lupa</translation>
+<translation id="7005812687360380971">Napaka</translation>
 <translation id="1602076796624386989">Omogoči mobilno podatkovno povezavo</translation>
 <translation id="6981982820502123353">Pripomočki za osebe s posebnimi potrebami</translation>
 <translation id="3157931365184549694">Obnovi</translation>
+<translation id="4274292172790327596">Neprepoznana napaka</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Iskanje naprav ...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Iskanje omrežij Wi-Fi</translation>
+<translation id="7229570126336867161">Potreben je EVDO</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> je javna seja, ki jo upravlja <ph name="DOMAIN"/></translation>
 <translation id="7029814467594812963">Zapusti sejo</translation>
 <translation id="8454013096329229812">Wi-Fi je vklopljen.</translation>
 <translation id="4872237917498892622">Alt + iskanje ali Shift</translation>
 <translation id="2983818520079887040">Nastavitve ...</translation>
-<translation id="5467313780247887226">Slike ni mogoče podvojiti na povezanih monitorjih. Ustrezne ločljivosti ni mogoče najti.</translation>
+<translation id="8927026611342028580">Povezava zahtevana</translation>
+<translation id="8300849813060516376">Storitev OTASP ni uspela</translation>
 <translation id="2792498699870441125">Alt + iskanje</translation>
 <translation id="8660803626959853127">Sinhroniziranje toliko datotek: <ph name="COUNT"/> ...</translation>
 <translation id="639644700271529076">Tipka CAPS LOCK je izklopljena</translation>
-<translation id="4101192585425716296">Center za sporočanje</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: Aktiviranje ...</translation>
+<translation id="1391854757121130358">Morda ste porabili dovoljeno količino mobilnih podatkov.</translation>
 <translation id="4864165860509564259">Položaj zaganjalnika</translation>
 <translation id="7593891976182323525">Iskanje ali Shift</translation>
 <translation id="7649070708921625228">Pomoč</translation>
 <translation id="3050422059534974565">Tipka CAPS LOCK je vklopljena.
 Pritisnite tipko za iskanje ali Shift, da jo prekličete.</translation>
 <translation id="397105322502079400">Izračunavanje ...</translation>
+<translation id="158849752021629804">Potrebno je domače omrežje</translation>
+<translation id="6857811139397017780">Aktiviraj <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">Iskanje DHCP-ja ni uspelo</translation>
+<translation id="6692173217867674490">Napačno geslo</translation>
 <translation id="6165508094623778733">Več o tem</translation>
+<translation id="9046895021617826162">Vzpostavljanje povezave ni uspelo</translation>
+<translation id="973896785707726617">Ta seja se bo končala čez <ph name="SESSION_TIME_REMAINING"/>. Samodejno boste odjavljeni.</translation>
+<translation id="8372369524088641025">Napačen ključ WEP</translation>
+<translation id="6636709850131805001">Neprepoznano stanje</translation>
 <translation id="3573179567135747900">Spremeni nazaj v jezik »<ph name="FROM_LOCALE"/>« (potreben vnovični zagon)</translation>
 <translation id="8103386449138765447">Sporočila SMS: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Nastavitve za Google Drive ...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">Ni omrežja</translation>
 <translation id="5941711191222866238">Pomanjšaj</translation>
 <translation id="6911468394164995108">Pridružite se drugemu ...</translation>
-<translation id="6843725295806269523">nemo</translation>
 <translation id="412065659894267608"><ph name="HOUR"/> h <ph name="MINUTE"/> min do napolnjenosti</translation>
 <translation id="6359806961507272919">SMS od <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Operater</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_sr.xtb b/ash/strings/ash_strings_sr.xtb
index 964e20d..ad06321 100644
--- a/ash/strings/ash_strings_sr.xtb
+++ b/ash/strings/ash_strings_sr.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Батерија је пуна</translation>
 <translation id="5250713215130379958">Аутоматски сакриј покретач</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> и <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Стање Портал</translation>
 <translation id="30155388420722288">Дугме за додатне опције</translation>
 <translation id="5571066253365925590">Bluetooth је омогућен</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Прокси...</translation>
 <translation id="938582441709398163">Постављени елемент тастатуре</translation>
 <translation id="6979158407327259162">Google диск</translation>
+<translation id="6943836128787782965">HTTP get није успео</translation>
 <translation id="2297568595583585744">Палета статуса</translation>
+<translation id="1661867754829461514">Недостаје PIN</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: Повезивање...</translation>
+<translation id="4237016987259239829">Грешка мрежне везе</translation>
 <translation id="2946640296642327832">Омогући Bluetooth</translation>
 <translation id="6459472438155181876">Проширивање екрана у <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Мобилни уређај</translation>
 <translation id="6596816719288285829">IP адреса</translation>
+<translation id="4508265954913339219">Активација није успела</translation>
 <translation id="1812696562331527143">Метод уноса је промењен у <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>трећа страна<ph name="END_LINK"/>).
 Притисните Shift + Alt да бисте пребацили.</translation>
-<translation id="5233638681132016545">Нова картица</translation>
 <translation id="3846575436967432996">Нису доступне информације о мрежи</translation>
 <translation id="3026237328237090306">Подеси податке за мобилне уређаје</translation>
 <translation id="785750925697875037">Прикажи налог за мобилне уређаје</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Онемогући Bluetooth</translation>
 <translation id="3126069444801937830">Покрените поново да бисте ажурирали</translation>
 <translation id="735745346212279324">Веза са VPN-ом је прекинута</translation>
+<translation id="7320906967354320621">Неактивно</translation>
 <translation id="6303423059719347535">Батерија је <ph name="PERCENTAGE"/>% пуна</translation>
+<translation id="2778346081696727092">Потврда аутентичности помоћу наведеног корисничког имена или лозинке није успела</translation>
 <translation id="3294437725009624529">Гост</translation>
 <translation id="8190698733819146287">Прилагоди језике и унос...</translation>
-<translation id="598295083618286569">Успостављена је веза са Bluetooth-ом</translation>
+<translation id="7170041865419449892">Изван опсега</translation>
+<translation id="4804818685124855865">Прекини везу</translation>
 <translation id="5222676887888702881">Одјави ме</translation>
+<translation id="2688477613306174402">Конфигурација</translation>
+<translation id="1272079795634619415">Заустави</translation>
 <translation id="4957722034734105353">Сазнајте више...</translation>
 <translation id="2964193600955408481">Онемогући Wi-Fi</translation>
 <translation id="811680302244032017">Додај уређај...</translation>
 <translation id="2509468283778169019">CAPS LOCK је укључен</translation>
 <translation id="3892641579809465218">Интерни екран</translation>
 <translation id="7823564328645135659">Језик је промењен са језика „<ph name="FROM_LOCALE"/>“ на „<ph name="TO_LOCALE"/>“ након синхронизације подешавања.</translation>
+<translation id="3368922792935385530">Повезан</translation>
 <translation id="8340999562596018839">Говорне повратне информације</translation>
 <translation id="8654520615680304441">Укључи Wi-Fi...</translation>
 <translation id="5825747213122829519">Метод уноса је промењен у <ph name="INPUT_METHOD_ID"/>.
 Притисните Shift + Alt да бисте пребацили.</translation>
 <translation id="2562916301614567480">Приватна мрежа</translation>
 <translation id="6549021752953852991">Није доступна ниједна мобилна мрежа</translation>
+<translation id="4379753398862151997">Драги мониторе, не иде нам. (Тај монитор није подржан)</translation>
 <translation id="6426039856985689743">Онемогући податке за мобилне уређаје</translation>
 <translation id="3087734570205094154">Дно</translation>
 <translation id="5271016907025319479">VPN није конфигурисан.</translation>
-<translation id="1298695107722797780">Заврши јавну\nсесију</translation>
-<translation id="3232695630852378748">Подешавања за Bluetooth...</translation>
+<translation id="6803622936009808957">Није могуће пресликати екране зато што није пронађена ниједна подржана резолуција. Уместо тога, приказује се проширена радна површина.</translation>
 <translation id="1480041086352807611">Режим демонстрације</translation>
 <translation id="3626637461649818317">Преостало је <ph name="PERCENTAGE"/>%</translation>
 <translation id="9089416786594320554">Методи уноса</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">Затварање</translation>
 <translation id="4430019312045809116">Јачина звука</translation>
+<translation id="4442424173763614572">DNS претрага није успела</translation>
 <translation id="6356500677799115505">Батерија је пуна и још увек се пуни.</translation>
 <translation id="7874779702599364982">Претраживање мобилних мрежа...</translation>
+<translation id="583281660410589416">Непознато</translation>
 <translation id="1383876407941801731">Претрага</translation>
+<translation id="7468789844759750875">Посетите активациони портал <ph name="NAME"/> да бисте купили још података.</translation>
 <translation id="3901991538546252627">Повезивање са мрежом <ph name="NAME"/></translation>
 <translation id="2204305834655267233">Информације о мрежи</translation>
 <translation id="1621499497873603021">Време које је преостало док се батерија не испразни, <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">Претходни мени</translation>
 <translation id="1346748346194534595">Удесно</translation>
 <translation id="8528322925433439945">Мобилни ...</translation>
+<translation id="7049357003967926684">Повезивање</translation>
 <translation id="8428213095426709021">Подешавања</translation>
-<translation id="2472320577759310817">Bluetooth је искључен.</translation>
 <translation id="2372145515558759244">Синхронизовање апликација...</translation>
+<translation id="7256405249507348194">Непозната грешка: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">Провера потврде идентитета, овлашћења и приступа није успела</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: Прекидање везе...</translation>
 <translation id="8456362689280298700">Још <ph name="HOUR"/>:<ph name="MINUTE"/> док се не напуни</translation>
 <translation id="5787281376604286451">Говорне повратне информације су омогућене.
 Притисните Ctrl+Alt+Z да бисте их онемогућили.</translation>
 <translation id="4479639480957787382">Етернет</translation>
+<translation id="6312403991423642364">Непозната грешка на мрежи</translation>
 <translation id="1467432559032391204">Улево</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830">Активирање мреже <ph name="NAME"/></translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">Увећај</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: Повезивање...</translation>
+<translation id="8639033665604704195">Потврда аутентичности помоћу наведеног тајног кључа није успела</translation>
 <translation id="252373100621549798">Непознати приказ</translation>
 <translation id="1882897271359938046">Пресликавање у <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Закључај</translation>
 <translation id="2805756323405976993">Apps</translation>
-<translation id="2482878487686419369">Обавештења</translation>
+<translation id="1512064327686280138">Активација није успела</translation>
+<translation id="5097002363526479830">Повезивање са мрежом „<ph name="NAME"/>“ није успело: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi је искључен.</translation>
-<translation id="2872961005593481000">Искључи</translation>
+<translation id="8036518327127111261">Потврда аутентичности помоћу наведеног сертификата није успела</translation>
 <translation id="8132793192354020517">Успостављена је веза са <ph name="NAME"/></translation>
 <translation id="7052914147756339792">Подеси позадину...</translation>
-<translation id="2739500853984626550">Нема доступних Bluetooth уређаја</translation>
-<translation id="2666092431469916601">Врх</translation>
+<translation id="8678698760965522072">Стање На мрежи</translation>
+<translation id="1119447706177454957">Интерна грешка</translation>
 <translation id="3019353588588144572">Време које је преостало док се батерија у потпуности не напуни, <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">Лупа екрана</translation>
+<translation id="7005812687360380971">Није успело</translation>
 <translation id="1602076796624386989">Омогући податке за мобилне уређаје</translation>
 <translation id="6981982820502123353">Приступачност</translation>
 <translation id="3157931365184549694">Поново отвори</translation>
+<translation id="4274292172790327596">Непозната грешка</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Скенирање уређаја...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/> <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Тражење Wi-Fi мрежа...</translation>
+<translation id="7229570126336867161">Потребан је EVDO</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> је јавна сесија којом управља <ph name="DOMAIN"/></translation>
 <translation id="7029814467594812963">Изађи из сесије</translation>
 <translation id="8454013096329229812">Wi-Fi је укључен.</translation>
 <translation id="4872237917498892622">Alt + тастер за претрагу или Shift</translation>
 <translation id="2983818520079887040">Подешавања...</translation>
-<translation id="5467313780247887226">Није могуће дуплирати слику на повезаним мониторима. Нема подударања резолуције.</translation>
+<translation id="8927026611342028580">Захтева се повезивање</translation>
+<translation id="8300849813060516376">OTASP није успео</translation>
 <translation id="2792498699870441125">Alt + тастер за претрагу</translation>
 <translation id="8660803626959853127">Синхронизовање <ph name="COUNT"/> датотеке(а)</translation>
 <translation id="639644700271529076">CAPS LOCK је искључен</translation>
-<translation id="4101192585425716296">Центар за поруке</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: Активирање...</translation>
+<translation id="1391854757121130358">Можда сте искористили додељени пакет података за мобилне уређаје.</translation>
 <translation id="4864165860509564259">Положај покретача</translation>
 <translation id="7593891976182323525">Тастер за претрагу или Shift</translation>
 <translation id="7649070708921625228">Помоћ</translation>
 <translation id="3050422059534974565">CAPS LOCK је укључен.
 Притисните тастер за претрагу или Shift да бисте га отказали.</translation>
 <translation id="397105322502079400">Израчунавање...</translation>
+<translation id="158849752021629804">Потребна је матична мрежа</translation>
+<translation id="6857811139397017780">Активирај <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">Проналажење DHCP-а није успело</translation>
+<translation id="6692173217867674490">Неисправна приступна фраза</translation>
 <translation id="6165508094623778733">Сазнајте више</translation>
+<translation id="9046895021617826162">Повезивање није успело</translation>
+<translation id="973896785707726617">Ова сесија ће се завршити за <ph name="SESSION_TIME_REMAINING"/>. Бићете аутоматски одјављени.</translation>
+<translation id="8372369524088641025">Неисправна WEP шифра</translation>
+<translation id="6636709850131805001">Непознато стање</translation>
 <translation id="3573179567135747900">Врати на „<ph name="FROM_LOCALE"/>“ (потребно је поновно покретање)</translation>
 <translation id="8103386449138765447">SMS поруке: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Подешавања Google диска...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">Нема мреже</translation>
 <translation id="5941711191222866238">Смањи</translation>
 <translation id="6911468394164995108">Придружи ме другој...</translation>
-<translation id="6843725295806269523">искључи звук</translation>
 <translation id="412065659894267608"><ph name="HOUR"/> с <ph name="MINUTE"/> м до краја пуњења</translation>
 <translation id="6359806961507272919">SMS са броја <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Мобилни оператер</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_sv.xtb b/ash/strings/ash_strings_sv.xtb
index c1adac0..46dd23c 100644
--- a/ash/strings/ash_strings_sv.xtb
+++ b/ash/strings/ash_strings_sv.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Batteriet är fulladdat</translation>
 <translation id="5250713215130379958">Dölj startfältet automatiskt</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> och <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Portalläge</translation>
 <translation id="30155388420722288">Överflödsknapp</translation>
 <translation id="5571066253365925590">Bluetooth aktiverad</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Proxy ...</translation>
 <translation id="938582441709398163">Tangentbordsöverlägg</translation>
 <translation id="6979158407327259162">Google Drive</translation>
+<translation id="6943836128787782965">HTTP GET misslyckades</translation>
 <translation id="2297568595583585744">Statusfält</translation>
+<translation id="1661867754829461514">PIN saknas</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: ansluter ...</translation>
+<translation id="4237016987259239829">Fel vid nätverksanslutning</translation>
 <translation id="2946640296642327832">Aktivera Bluetooth</translation>
 <translation id="6459472438155181876">Utöka skärmen till <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Mobil</translation>
 <translation id="6596816719288285829">IP-adress</translation>
+<translation id="4508265954913339219">Aktiveringen misslyckades</translation>
 <translation id="1812696562331527143">Inmatningsmetoden har ändrats till <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>tredje part<ph name="END_LINK"/>).
         Tryck på Skift + Alt om du vill byta.</translation>
-<translation id="5233638681132016545">Ny flik</translation>
 <translation id="3846575436967432996">Det finns ingen nätverksinformation</translation>
 <translation id="3026237328237090306">Konfigurera mobildata</translation>
 <translation id="785750925697875037">Visa mobilkonto</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Inaktivera Bluetooth</translation>
 <translation id="3126069444801937830">Starta om för att uppdatera</translation>
 <translation id="735745346212279324">VPN frånkopplat</translation>
+<translation id="7320906967354320621">Inaktiv</translation>
 <translation id="6303423059719347535">Batteriet är fullt till <ph name="PERCENTAGE"/> %</translation>
+<translation id="2778346081696727092">Det gick inte att autentisera med användarnamnet eller lösenordet som angavs</translation>
 <translation id="3294437725009624529">Gäst</translation>
 <translation id="8190698733819146287">Anpassa språk och inmatning...</translation>
-<translation id="598295083618286569">Bluetooth ansluten</translation>
+<translation id="7170041865419449892">Utanför intervallet</translation>
+<translation id="4804818685124855865">Koppla från</translation>
 <translation id="5222676887888702881">Logga ut</translation>
+<translation id="2688477613306174402">Konfiguration</translation>
+<translation id="1272079795634619415">Stopp</translation>
 <translation id="4957722034734105353">Läs mer ...</translation>
 <translation id="2964193600955408481">Inaktivera Wi-Fi</translation>
 <translation id="811680302244032017">Lägg till enhet ...</translation>
 <translation id="2509468283778169019">CAPS LOCK är på</translation>
 <translation id="3892641579809465218">Intern bildskärm</translation>
 <translation id="7823564328645135659">Chromes språk har ändrats från <ph name="FROM_LOCALE"/> till <ph name="TO_LOCALE"/> efter synkronisering av dina inställningar.</translation>
+<translation id="3368922792935385530">Ansluten</translation>
 <translation id="8340999562596018839">Talad feedback</translation>
 <translation id="8654520615680304441">Aktivera Wi-Fi ...</translation>
 <translation id="5825747213122829519">Inmatningsmetoden har ändrats till <ph name="INPUT_METHOD_ID"/>.
         Tryck på Skift + Alt om du vill byta.</translation>
 <translation id="2562916301614567480">Privat nätverk</translation>
 <translation id="6549021752953852991">Det finns inget tillgängligt mobilt nätverk</translation>
+<translation id="4379753398862151997">Det fungerar inte med den här skärmen. (Skärmen stöds inte.)</translation>
 <translation id="6426039856985689743">Inaktivera mobildata</translation>
 <translation id="3087734570205094154">Nederst</translation>
 <translation id="5271016907025319479">VPN är inte konfigurerat.</translation>
-<translation id="1298695107722797780">Avsluta offentlig\nsession</translation>
-<translation id="3232695630852378748">Bluetooth-inställningar ...</translation>
+<translation id="6803622936009808957">Det gick inte att spegla visningar eftersom inga upplösningar som stöds hittades. Utökat skrivbordsläge används i stället.</translation>
 <translation id="1480041086352807611">Demoläge</translation>
 <translation id="3626637461649818317"><ph name="PERCENTAGE"/> % återstår</translation>
 <translation id="9089416786594320554">Inmatningsmetoder</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/> %</translation>
 <translation id="1895658205118569222">Stängning</translation>
 <translation id="4430019312045809116">Volym</translation>
+<translation id="4442424173763614572">DNS-sökning misslyckades</translation>
 <translation id="6356500677799115505">Batteriet är fullt och laddas.</translation>
 <translation id="7874779702599364982">Söker efter mobilnätverk ...</translation>
+<translation id="583281660410589416">Okänt</translation>
 <translation id="1383876407941801731">Sökning</translation>
+<translation id="7468789844759750875">Besök aktiveringsportalen för <ph name="NAME"/> om du vill köpa mer data.</translation>
 <translation id="3901991538546252627">Ansluter till <ph name="NAME"/></translation>
 <translation id="2204305834655267233">Nätverksinformation</translation>
 <translation id="1621499497873603021">Tid som återstår tills batteriet är tomt: <ph name="TIME_LEFT"/></translation>
@@ -70,55 +83,74 @@
 <translation id="8308637677604853869">Föregående meny</translation>
 <translation id="1346748346194534595">Höger</translation>
 <translation id="8528322925433439945">Mobil ...</translation>
+<translation id="7049357003967926684">Association</translation>
 <translation id="8428213095426709021">Inställningar</translation>
-<translation id="2472320577759310817">Bluetooth är inaktiverat.</translation>
 <translation id="2372145515558759244">Synkronisera appar ...</translation>
+<translation id="7256405249507348194">Okänt fel: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">Kontroll med AAA misslyckades</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: kopplar från ...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> tills batteriet är fulladdat</translation>
 <translation id="5787281376604286451">Talad feedback är aktiverad.
 Inaktivera genom att trycka Ctrl+Alt+Z.</translation>
 <translation id="4479639480957787382">Ethernet</translation>
+<translation id="6312403991423642364">Okänt nätverksfel</translation>
 <translation id="1467432559032391204">Vänster</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830">Aktiverar <ph name="NAME"/></translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">Maximera</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: ansluter ...</translation>
+<translation id="8639033665604704195">Det gick inte att autentisera med den i förväg delade nyckeln som angavs</translation>
 <translation id="252373100621549798">Okänd visning</translation>
 <translation id="1882897271359938046">Spegling av <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Lås</translation>
 <translation id="2805756323405976993">Appar</translation>
-<translation id="2482878487686419369">Aviseringar</translation>
+<translation id="1512064327686280138">Aktiveringsfel</translation>
+<translation id="5097002363526479830">Det gick inte att ansluta till nätverket <ph name="NAME"/>: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi är inaktiverat.</translation>
-<translation id="2872961005593481000">Stäng av</translation>
+<translation id="8036518327127111261">Det gick inte att autentisera med certifikatet som angavs</translation>
 <translation id="8132793192354020517">Ansluten till <ph name="NAME"/></translation>
 <translation id="7052914147756339792">Ange bakgrund ...</translation>
-<translation id="2739500853984626550">Det finns inga tillgängliga Bluetooth-enheter</translation>
-<translation id="2666092431469916601">Överst</translation>
+<translation id="8678698760965522072">Onlineläge</translation>
+<translation id="1119447706177454957">Internt fel</translation>
 <translation id="3019353588588144572">Tid som återstår tills batteriet är fulladdat: <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">Skärmförstorare</translation>
+<translation id="7005812687360380971">Misslyckades</translation>
 <translation id="1602076796624386989">Aktivera mobildata</translation>
 <translation id="6981982820502123353">Tillgänglighet</translation>
 <translation id="3157931365184549694">Återställ</translation>
+<translation id="4274292172790327596">Okänt fel</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Söker efter enheter ...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Söker efter Wi-Fi-nätverk...</translation>
+<translation id="7229570126336867161">Behöver EVDO</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> är en offentlig session som hanteras av <ph name="DOMAIN"/></translation>
 <translation id="7029814467594812963">Avsluta session</translation>
 <translation id="8454013096329229812">Wi-Fi är aktiverat.</translation>
 <translation id="4872237917498892622">Alt + Sök eller Skift</translation>
 <translation id="2983818520079887040">Inställningar...</translation>
-<translation id="5467313780247887226">Det går inte att duplicera bilden på de anslutna bildskärmarna. Ingen passande upplösning hittades.</translation>
+<translation id="8927026611342028580">Anslutning begärd</translation>
+<translation id="8300849813060516376">Det gick inte att etablera tjänsten over-the-air.</translation>
 <translation id="2792498699870441125">Alt + Sök</translation>
 <translation id="8660803626959853127">Synkroniserar <ph name="COUNT"/> filer</translation>
 <translation id="639644700271529076">CAPS LOCK är av</translation>
-<translation id="4101192585425716296">Meddelandecenter</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: Aktiverar ...</translation>
+<translation id="1391854757121130358">Du kanske har slut på mobildata.</translation>
 <translation id="4864165860509564259">Startfältets position</translation>
 <translation id="7593891976182323525">Sök eller Skift</translation>
 <translation id="7649070708921625228">Hjälp</translation>
 <translation id="3050422059534974565">CAPS LOCK är på. Avbryt genom att trycka på Sök eller Shift.</translation>
 <translation id="397105322502079400">Beräknar ...</translation>
+<translation id="158849752021629804">Behöver hemnätverk</translation>
+<translation id="6857811139397017780">Aktivera <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">DHCP-förfrågan misslyckades</translation>
+<translation id="6692173217867674490">Ogiltig lösenfras</translation>
 <translation id="6165508094623778733">Läs mer</translation>
+<translation id="9046895021617826162">Kunde inte ansluta</translation>
+<translation id="973896785707726617">Sessionen avslutas om <ph name="SESSION_TIME_REMAINING"/>. Du kommer att loggas ut automatiskt.</translation>
+<translation id="8372369524088641025">Felaktig WEP-nyckel</translation>
+<translation id="6636709850131805001">Okänt tillstånd</translation>
 <translation id="3573179567135747900">Byt tillbaka till &quot;<ph name="FROM_LOCALE"/>&quot; (kräver omstart)</translation>
 <translation id="8103386449138765447">SMS-meddelanden: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Inställningar för Google Drive ...</translation>
@@ -128,7 +160,7 @@
 <translation id="8000066093800657092">Inget nätverk</translation>
 <translation id="5941711191222866238">Minimera</translation>
 <translation id="6911468394164995108">Anslut till andra ...</translation>
-<translation id="6843725295806269523">ljud av</translation>
 <translation id="412065659894267608"><ph name="HOUR"/> h <ph name="MINUTE"/> m till fulladdat</translation>
 <translation id="6359806961507272919">SMS från <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Operatör</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_sw.xtb b/ash/strings/ash_strings_sw.xtb
index 10915d8..8d87c1c 100644
--- a/ash/strings/ash_strings_sw.xtb
+++ b/ash/strings/ash_strings_sw.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Betri imejaa</translation>
 <translation id="5250713215130379958">Kizinduzi cha Kuficha otomatiki</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> na <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Hali ya lango</translation>
 <translation id="30155388420722288">Kitufe Jalizi</translation>
 <translation id="5571066253365925590">Bluetooth imewezeshwa</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Proksi...</translation>
 <translation id="938582441709398163">Mtandazo wa Kibodi</translation>
 <translation id="6979158407327259162">Hifadhi ya Google</translation>
+<translation id="6943836128787782965">HTTP imeshindikana</translation>
 <translation id="2297568595583585744">Treya ya hali</translation>
+<translation id="1661867754829461514">PIN inakosekana</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: Inaunganisha...</translation>
+<translation id="4237016987259239829">Hitilafu ya Muunganisho wa Mtandao</translation>
 <translation id="2946640296642327832">Wezesha Bluetooth</translation>
 <translation id="6459472438155181876">Inapanua skrini kwenye <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Simu ya Mkononi</translation>
 <translation id="6596816719288285829">Anwani ya IP</translation>
+<translation id="4508265954913339219">Uamilisho umeshindikana</translation>
 <translation id="1812696562331527143">Mbinu yako ingizo imebadilika hadi <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>mhusika mwingine<ph name="END_LINK"/>).
 Bonyeza Shift + Alt ili kubadilisha.</translation>
-<translation id="5233638681132016545">Kichupo kipya</translation>
 <translation id="3846575436967432996">Hakuna maelezo ya mtandao yanayopatikana</translation>
 <translation id="3026237328237090306">Sanidi data ya simu</translation>
 <translation id="785750925697875037">Ona akaunti ya simu ya mkononi</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Lemaza Bluetooth</translation>
 <translation id="3126069444801937830">Anzisha upya ili kusasisha</translation>
 <translation id="735745346212279324">VPN imekatwa muunganisho</translation>
+<translation id="7320906967354320621">Tulivu</translation>
 <translation id="6303423059719347535">Betri imejaa <ph name="PERCENTAGE"/>%</translation>
+<translation id="2778346081696727092">Imeshindwa kuthibitisha kwa jina la mtumiaji au nenosiri lililotolewa</translation>
 <translation id="3294437725009624529">Mgeni</translation>
 <translation id="8190698733819146287">Geuza lugha na uingizaji kukufaa...</translation>
-<translation id="598295083618286569">Bluetooth imeunganishwa</translation>
+<translation id="7170041865419449892">Nje ya eneo</translation>
+<translation id="4804818685124855865">Tenganisha</translation>
 <translation id="5222676887888702881">Ondoka</translation>
+<translation id="2688477613306174402">Usanidi</translation>
+<translation id="1272079795634619415">Simamisha</translation>
 <translation id="4957722034734105353">Pata maelezo zaidi...</translation>
 <translation id="2964193600955408481">Lemaza Wi-Fi</translation>
 <translation id="811680302244032017">Ongeza kifaa...</translation>
 <translation id="2509468283778169019">Caps Lock imewashwa.</translation>
 <translation id="3892641579809465218">Onyesho la Ndani</translation>
 <translation id="7823564328645135659">Lugha imebadilika kutoka &quot;<ph name="FROM_LOCALE"/> &quot;na kuwa&quot; <ph name="TO_LOCALE"/>&quot; baada ya kulinganisha mipangilio yako.</translation>
+<translation id="3368922792935385530">Umeunganishwa</translation>
 <translation id="8340999562596018839">Maoni ya yaliyotamkwa</translation>
 <translation id="8654520615680304441">Washa Wi-Fi...</translation>
 <translation id="5825747213122829519">Mbinu ingizo yako imebadilika hadi <ph name="INPUT_METHOD_ID"/>.
 Bonyeza Shift + Alt ili kubadili.</translation>
 <translation id="2562916301614567480">Mtandao Binafsi</translation>
 <translation id="6549021752953852991">Hakuna mtandao wa simu za mkononi unaopatikana</translation>
+<translation id="4379753398862151997">Mpendwa Kionyeshi, hali sio nzuri kati yetu. (Kionyeshi hiki hakiwezi kutumiwa)</translation>
 <translation id="6426039856985689743">Lemaza data ya simu</translation>
 <translation id="3087734570205094154">Chini</translation>
 <translation id="5271016907025319479">VPN haijasanidiwa.</translation>
-<translation id="1298695107722797780">Kamilisha kipindi cha\kila mtu</translation>
-<translation id="3232695630852378748">Mipangilio ya Bluetooth...</translation>
+<translation id="6803622936009808957">Haikuweza kuakisi maonyesho kwa kuwa hakuna misongo inayoweza kutumiwa iliyopatikana. Badala yake imeingia eneo-kazi lililopanuliwa.</translation>
 <translation id="1480041086352807611">Modi ya kuonyesha</translation>
 <translation id="3626637461649818317"><ph name="PERCENTAGE"/>% inayobaki</translation>
 <translation id="9089416786594320554">Mbinu Ingizo</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">Funga</translation>
 <translation id="4430019312045809116">Kiwango</translation>
+<translation id="4442424173763614572">Mwonekano wa DNS umeshindikana</translation>
 <translation id="6356500677799115505">Betri imejaa na inachajiwa.</translation>
 <translation id="7874779702599364982">Inatafuta mitandao ya simu za mkononi...</translation>
+<translation id="583281660410589416">Siojulikana</translation>
 <translation id="1383876407941801731">Tafuta</translation>
+<translation id="7468789844759750875">Tembelea tovuti kuu ya kuwezesha ya <ph name="NAME"/> ili ununue data zaidi.</translation>
 <translation id="3901991538546252627">Inaunganisha kwenye <ph name="NAME"/></translation>
 <translation id="2204305834655267233">Maelezo ya Mtandao</translation>
 <translation id="1621499497873603021">Muda unaosalia mpaka betri inapoisha, <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">Menyu ya awali</translation>
 <translation id="1346748346194534595">Kulia</translation>
 <translation id="8528322925433439945">Simu ya mkononi ...</translation>
+<translation id="7049357003967926684">Muungano</translation>
 <translation id="8428213095426709021">Mipangilio</translation>
-<translation id="2472320577759310817">Bluetooth imezimwa.</translation>
 <translation id="2372145515558759244">Inalandanisha programu...</translation>
+<translation id="7256405249507348194">Hitilafu isiyotambulika: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">Ukaguzi wa AAA umeshindikana</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: Inakata muunganisho...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> mpaka ijae</translation>
 <translation id="5787281376604286451">Maoni yaliyotamkwa yamewashwa.
 Bonyeza Ctrl+Alt+Z ili ufunge.</translation>
 <translation id="4479639480957787382">Ethernet</translation>
+<translation id="6312403991423642364">Hitilafu isiyojulikana ya mtandao</translation>
 <translation id="1467432559032391204">Kushoto</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830">Inaanza kutumia <ph name="NAME"/></translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">Tanua</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: Inaunganisha...</translation>
+<translation id="8639033665604704195">Imeshindwa kuthibitisha kwa kitufe kilichopo kilichotolewa awali</translation>
 <translation id="252373100621549798">Onyesho Lisilojulikana</translation>
 <translation id="1882897271359938046">Inaakisi kwenye <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Funga</translation>
 <translation id="2805756323405976993">Programu</translation>
-<translation id="2482878487686419369">Arifa</translation>
+<translation id="1512064327686280138">Kushindwa kwa uamilishaji</translation>
+<translation id="5097002363526479830">Imeshindwa kuunganisha kwenye mtandao '<ph name="NAME"/>': <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi imezimwa.</translation>
-<translation id="2872961005593481000">Zima</translation>
+<translation id="8036518327127111261">Imeshindwa kuthibitisha kwa cheti kilichotolewa</translation>
 <translation id="8132793192354020517">Imeunganishwa kwenye <ph name="NAME"/></translation>
 <translation id="7052914147756339792">Weka Mandhari...</translation>
-<translation id="2739500853984626550">Hakuna vifaa vya bluetooth vinavyopatikana</translation>
-<translation id="2666092431469916601">Ya Juu</translation>
+<translation id="8678698760965522072">Hali ya mtandaoni</translation>
+<translation id="1119447706177454957">Hitilafu ya ndani</translation>
 <translation id="3019353588588144572">Muda unaosalia hadi betri itakapochajiwa kikamilifu, <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">Kikuza skrini</translation>
+<translation id="7005812687360380971">Imeshindwa</translation>
 <translation id="1602076796624386989">Wezesha data ya simu</translation>
 <translation id="6981982820502123353">Ufikiaji</translation>
 <translation id="3157931365184549694">Rejesha</translation>
+<translation id="4274292172790327596">Hitilafu Isiyotambulika</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Inatambazaa vifaa...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Inatafuta mitandao ya Wi-Fi…</translation>
+<translation id="7229570126336867161">Inahitaji EVDO</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> ni kipindi cha kila mtu kinachodhibitiwa na <ph name="DOMAIN"/></translation>
 <translation id="7029814467594812963">Toka kwenye kipindi</translation>
 <translation id="8454013096329229812">Wi-Fi imewashwa.</translation>
 <translation id="4872237917498892622">Alt + Utafutaji au Hama</translation>
 <translation id="2983818520079887040">Mipangilio...</translation>
-<translation id="5467313780247887226">Haiwezi kurudufisha picha kwenye viwambo vilivyoambatishwa. Hakuna msongo unaopatikana.</translation>
+<translation id="8927026611342028580">Muunganisho Umeombwa</translation>
+<translation id="8300849813060516376">OTASP imeshindikana</translation>
 <translation id="2792498699870441125">Alt + Utafutaji</translation>
 <translation id="8660803626959853127">Inalinganisha faili <ph name="COUNT"/></translation>
 <translation id="639644700271529076">CAPS LOCK imezimwa</translation>
-<translation id="4101192585425716296">Kituo cha Ujumbe</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: Inaanza kutumia...</translation>
+<translation id="1391854757121130358">Inawezekana umemaliza mgawo wako wa data ya simu ya mkononi.</translation>
 <translation id="4864165860509564259">Sehemu ya kizinduzi</translation>
 <translation id="7593891976182323525">Utafutaji au Hama</translation>
 <translation id="7649070708921625228">Usaidizi</translation>
 <translation id="3050422059534974565">CAPS LOCK imeamilishwa. 
 Bonyeza Alt + Utafutaji au Hama ili kughairi.</translation>
 <translation id="397105322502079400">Inakokotoa...</translation>
+<translation id="158849752021629804">Inahitaji mtandao wa nyumbani</translation>
+<translation id="6857811139397017780">Amilisha <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">Mwonekano wa DHCP umeshindikana</translation>
+<translation id="6692173217867674490">Kaulisiri mbovu</translation>
 <translation id="6165508094623778733">Pata maelezo zaidi</translation>
+<translation id="9046895021617826162">Muunganisho umeshindikana</translation>
+<translation id="973896785707726617">Kipindi hiki kitaisha katika <ph name="SESSION_TIME_REMAINING"/>. Utaondolewa kiotomatiki.</translation>
+<translation id="8372369524088641025">Kitufe kibovu cha WEP</translation>
+<translation id="6636709850131805001">Hali isiyotambulika</translation>
 <translation id="3573179567135747900">Badilisha hadi &quot;<ph name="FROM_LOCALE"/>&quot; (inahitaji uzime na uwashe)</translation>
 <translation id="8103386449138765447">Ujumbe wa SMS: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Mipangilio ya Hifadhi ya Google...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">Hakuna mtandao</translation>
 <translation id="5941711191222866238">Punguza</translation>
 <translation id="6911468394164995108">Jiunge na mwingine...</translation>
-<translation id="6843725295806269523">nyamazisha</translation>
 <translation id="412065659894267608">Saa<ph name="HOUR"/> dakika<ph name="MINUTE"/> ili ijae</translation>
 <translation id="6359806961507272919">SMS kutoka <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Mtoa huduma</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_ta.xtb b/ash/strings/ash_strings_ta.xtb
index 3bf23c2..10706a7 100644
--- a/ash/strings/ash_strings_ta.xtb
+++ b/ash/strings/ash_strings_ta.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">பேட்டரி நிரம்பியது</translation>
 <translation id="5250713215130379958">தொடக்கத்தை தானாக மறை</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> மற்றும் <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">போர்ட்டல் நிலை</translation>
 <translation id="30155388420722288">மிகைப்படுத்தி பொத்தான்</translation>
 <translation id="5571066253365925590">Bluetooth இயக்கப்பட்டது</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">ப்ராக்ஸி...</translation>
 <translation id="938582441709398163">விசைப்பலகை மேல்தோற்றம்</translation>
 <translation id="6979158407327259162">Google இயக்ககம்</translation>
+<translation id="6943836128787782965">HTTP தோல்வியடைந்தது</translation>
 <translation id="2297568595583585744">நிலைத் தட்டு</translation>
+<translation id="1661867754829461514">PIN இல்லை</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: இணைக்கிறது...</translation>
+<translation id="4237016987259239829">பிணைய இணைப்புப் பிழை</translation>
 <translation id="2946640296642327832">Bluetooth ஐ இயக்கு</translation>
 <translation id="6459472438155181876"><ph name="DISPLAY_NAME"/> க்கு திரை விரிவாக்கப்படுகிறது</translation>
 <translation id="8206859287963243715">செல்லுலர்</translation>
 <translation id="6596816719288285829">IP முகவரி</translation>
+<translation id="4508265954913339219">செயலாக்கம் தோல்வியுற்றது</translation>
 <translation id="1812696562331527143">உங்கள் உள்ளீட்டு முறையானது <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>மூன்றாம் தரப்பு<ph name="END_LINK"/>) க்கு மாற்றப்பட்டது.
 மாற்ற Shift + Alt ஐ அழுத்தவும்.</translation>
-<translation id="5233638681132016545">புதிய தாவல்</translation>
 <translation id="3846575436967432996">நெட்வொர்க் தகவல் எதுவும் இல்லை</translation>
 <translation id="3026237328237090306">மொபைல் தரவை அமை</translation>
 <translation id="785750925697875037">மொபைல் கணக்கைப் பார்க்கவும்</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Bluetooth ஐ முடக்கு</translation>
 <translation id="3126069444801937830">புதுப்பிக்க மீண்டும் தொடங்குக</translation>
 <translation id="735745346212279324">VPN துண்டிக்கப்பட்டது</translation>
+<translation id="7320906967354320621">செயலின்றி</translation>
 <translation id="6303423059719347535"><ph name="PERCENTAGE"/>% பேட்டரி நிரம்பியது</translation>
+<translation id="2778346081696727092">வழங்கப்பட்ட பயனர் பெயர் அல்லது கடவுச்சொல்லை அங்கீகரிப்பதில் தோல்வி</translation>
 <translation id="3294437725009624529">விருந்தினர்</translation>
 <translation id="8190698733819146287">மொழிகள் மற்றும்  உள்ளீடைத் தனிப்பயனாக்கு...</translation>
-<translation id="598295083618286569">Bluetooth இணைக்கப்பட்டது</translation>
+<translation id="7170041865419449892">வரம்புக்கு வெளியே</translation>
+<translation id="4804818685124855865">தொடர்பைத் துண்டி</translation>
 <translation id="5222676887888702881">வெளியேறு</translation>
+<translation id="2688477613306174402">உள்ளமைவு</translation>
+<translation id="1272079795634619415">நிறுத்து</translation>
 <translation id="4957722034734105353">மேலும் அறிக...</translation>
 <translation id="2964193600955408481">Wi-Fi ஐ முடக்கு</translation>
 <translation id="811680302244032017">சாதனத்தைச் சேர்க்கவும்...</translation>
 <translation id="2509468283778169019">CAPS LOCK இயக்கத்தில்</translation>
 <translation id="3892641579809465218">இணையக் காட்சி</translation>
 <translation id="7823564328645135659">உங்கள் அமைப்புகளை ஒத்திசைத்த பிறகு, மொழியானது &quot;<ph name="FROM_LOCALE"/>&quot; இலிருந்து &quot;<ph name="TO_LOCALE"/>&quot; க்கு மாற்றப்பட்டுள்ளது.</translation>
+<translation id="3368922792935385530">இணைக்கப்பட்டது</translation>
 <translation id="8340999562596018839">பேச்சுவடிவ கருத்து</translation>
 <translation id="8654520615680304441">Wi-Fi ஐ இயக்கு...</translation>
 <translation id="5825747213122829519">உங்கள் உள்ளீட்டு முறையானது <ph name="INPUT_METHOD_ID"/> க்கு மாற்றப்பட்டது.
 மாற்ற Shift + Alt ஐ அழுத்தவும்.</translation>
 <translation id="2562916301614567480">தனிப்பட்ட நெட்வொர்க்</translation>
 <translation id="6549021752953852991">செல்லுலார் நெட்வொர்க் இல்லை</translation>
+<translation id="4379753398862151997">அந்த மானிட்டர் ஆதரிக்கப்படவில்லை.</translation>
 <translation id="6426039856985689743">மொபைல் தரவை முடக்கு</translation>
 <translation id="3087734570205094154">கீழே</translation>
 <translation id="5271016907025319479">VPN உள்ளமைக்கப்படவில்லை.</translation>
-<translation id="1298695107722797780">பொது\nஅமர்வை முடி</translation>
-<translation id="3232695630852378748">Bluetooth அமைப்புகள்...</translation>
+<translation id="6803622936009808957">ஆதரிக்கும் தெளிவுகள் கிடைக்காததால் காட்சிகளைப் பிரதிபலிக்க முடியவில்லை. பதிலாக நீட்டிக்கப்பட்ட டெஸ்க்டாப்பிற்குச் சென்றது.</translation>
 <translation id="1480041086352807611">டெமோ பயன்முறை</translation>
 <translation id="3626637461649818317"><ph name="PERCENTAGE"/>% மீதமுள்ளது</translation>
 <translation id="9089416786594320554">உள்ளீட்டு முறைகள்</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">நிறுத்தம்</translation>
 <translation id="4430019312045809116">அளவு</translation>
+<translation id="4442424173763614572">DNS தேடுதல் தோல்வி</translation>
 <translation id="6356500677799115505">பேட்டரி நிரம்பியது மேலும் சார்ஜ் ஆகிறது.</translation>
 <translation id="7874779702599364982">செல்லுலார் நெட்வொர்க்குகளைத் தேடுகிறது...</translation>
+<translation id="583281660410589416">அறியப்படாத</translation>
 <translation id="1383876407941801731">தேடு</translation>
+<translation id="7468789844759750875">கூடுதல் தரவை வாங்குவதற்கு <ph name="NAME"/> செயல்படுத்தல் போர்ட்டலைப் பார்வையிடவும்.</translation>
 <translation id="3901991538546252627"><ph name="NAME"/> க்கு இணைக்கிறது</translation>
 <translation id="2204305834655267233">பிணைய தகவல்</translation>
 <translation id="1621499497873603021">இன்னும் <ph name="TIME_LEFT"/> இல் பேட்டரி காலியாகிவிடும்</translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">முந்தைய மெனு</translation>
 <translation id="1346748346194534595">வலது</translation>
 <translation id="8528322925433439945">மொபைல் ...</translation>
+<translation id="7049357003967926684">சங்கம்</translation>
 <translation id="8428213095426709021">அமைப்புகள்</translation>
-<translation id="2472320577759310817">Bluetooth முடக்கப்பட்டது.</translation>
 <translation id="2372145515558759244">பயன்பாடுகளை ஒத்திசைக்கிறது...</translation>
+<translation id="7256405249507348194">அறியப்படாத பிழை: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">AAA சோதனை தோல்வியுற்றது</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: துண்டிக்கப்படுகிறது...</translation>
 <translation id="8456362689280298700">முழுதாக வரும்வரை <ph name="HOUR"/>:<ph name="MINUTE"/></translation>
 <translation id="5787281376604286451">பேச்சுவடிவ கருத்து செயலாக்கப்பட்டது.
 முடக்க Ctrl+Alt+Z அழுத்தவும்.</translation>
 <translation id="4479639480957787382">ஈத்தர்நெட்</translation>
+<translation id="6312403991423642364">அறியப்படாத பிணையப் பிழை</translation>
 <translation id="1467432559032391204">இடது</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830"><ph name="NAME"/> ஐச் செயல்படுத்துகிறது</translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">பெரிதாக்கு</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: இணைக்கிறது...</translation>
+<translation id="8639033665604704195">வழங்கப்பட்ட முன்பகிர்வு விசையை அங்கீகரிப்பதில் தோல்வி</translation>
 <translation id="252373100621549798">அறியாதது</translation>
 <translation id="1882897271359938046"><ph name="DISPLAY_NAME"/> ஐப் பிரதிபலிக்கிறது</translation>
 <translation id="3784455785234192852">பூட்டு</translation>
 <translation id="2805756323405976993">ஆப்ஸ்</translation>
-<translation id="2482878487686419369">அறிவிக்கைகள்</translation>
+<translation id="1512064327686280138">செயலாக்கம் தோல்வி</translation>
+<translation id="5097002363526479830">'<ph name="NAME"/>' நெட்வொர்க்குடன் இணைப்பதில் தோல்வி: <ph name="DETAILS"/> </translation>
 <translation id="1850504506766569011">Wi-Fi முடக்கத்தில் உள்ளது.</translation>
-<translation id="2872961005593481000">நிறுத்து</translation>
+<translation id="8036518327127111261">வழங்கப்பட்ட சான்றிதழை அங்கீகரிப்பதில் தோல்வி</translation>
 <translation id="8132793192354020517"><ph name="NAME"/> உடன் இணைக்கப்பட்டது</translation>
 <translation id="7052914147756339792">வால்பேப்பரை அமை...</translation>
-<translation id="2739500853984626550">Bluetooth சாதனங்கள் எதுவும் இல்லை</translation>
-<translation id="2666092431469916601">மேலே</translation>
+<translation id="8678698760965522072">ஆன்லைன் நிலை</translation>
+<translation id="1119447706177454957">அகப் பிழை</translation>
 <translation id="3019353588588144572"><ph name="TIME_REMAINING"/> இல் பேட்டரி முழுவதும் சார்ஜ் ஆகிவிடும்</translation>
 <translation id="3473479545200714844">திரை உருப்பெருக்கி</translation>
+<translation id="7005812687360380971">தோல்வி</translation>
 <translation id="1602076796624386989">மொபைல் தரவை இயக்கு</translation>
 <translation id="6981982820502123353">அணுகல்தன்மை</translation>
 <translation id="3157931365184549694">மீட்டமை</translation>
+<translation id="4274292172790327596">அறியப்படாத பிழை</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">சாதனங்களைக் கண்டறிகிறது...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Wi-Fi பிணையங்களைத் தேடுகிறது...</translation>
+<translation id="7229570126336867161">EVDO தேவை</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> ஆனது <ph name="DOMAIN"/> ஆல் நிர்வகிக்கப்படும் பொது அமர்வாகும்</translation>
 <translation id="7029814467594812963">அமர்விலிருந்து வெளியேறவும்</translation>
 <translation id="8454013096329229812">Wi-Fi இயக்கத்தில் உள்ளது.</translation>
 <translation id="4872237917498892622">Alt+Search அல்லது Shift</translation>
 <translation id="2983818520079887040">அமைப்புகள்...</translation>
-<translation id="5467313780247887226">இணைக்கப்பட்ட திரைகளில் படத்தை பிரதியெடுக்க முடியாது. பொருத்தமான தெளிவுத்திறன் இல்லை.</translation>
+<translation id="8927026611342028580">இணைக்க கோரப்பட்டது</translation>
+<translation id="8300849813060516376">OTASP தோல்வியுற்றது</translation>
 <translation id="2792498699870441125">Alt+Search</translation>
 <translation id="8660803626959853127"><ph name="COUNT"/> கோப்பு(களை) ஒத்திசைக்கிறது</translation>
 <translation id="639644700271529076">CAPS LOCK முடக்கப்பட்டுள்ளது</translation>
-<translation id="4101192585425716296">செய்தி மையம்</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: செயல்படுத்துகிறது...</translation>
+<translation id="1391854757121130358">உங்களின் அனுமதிக்கப்பட்ட மொபைல் தரவை நீங்கள் பயன்படுத்தி இருக்கலாம்.</translation>
 <translation id="4864165860509564259">துவக்கி நிலை</translation>
 <translation id="7593891976182323525">Search அல்லது Shift</translation>
 <translation id="7649070708921625228">உதவி</translation>
 <translation id="3050422059534974565">CAPS LOCK இயக்கத்தில் உள்ளது.
 ரத்துசெய்ய Search அல்லது Shift ஐ அழுத்தவும்.</translation>
 <translation id="397105322502079400">கணக்கிடுகிறது...</translation>
+<translation id="158849752021629804">உள்ளூர் பிணையம் தேவை</translation>
+<translation id="6857811139397017780"><ph name="NETWORKSERVICE"/> ஐ செயல்படுத்து</translation>
+<translation id="5864471791310927901">DHCP பார்வையிடுதல் தோல்வி</translation>
+<translation id="6692173217867674490">மோசமான கடவுச்சொற்றொடர்</translation>
 <translation id="6165508094623778733">மேலும் அறிக</translation>
+<translation id="9046895021617826162">இணைப்பு தோல்வியடைந்தது</translation>
+<translation id="973896785707726617">இந்த அமர்வு <ph name="SESSION_TIME_REMAINING"/> நிமிடங்களில் முடியும். நீங்கள் தானாகவே வெளியேற்றப்படுவீர்கள்.</translation>
+<translation id="8372369524088641025">மோசமான WEP விசை</translation>
+<translation id="6636709850131805001">அறியப்படாத நிலை</translation>
 <translation id="3573179567135747900">&quot;<ph name="FROM_LOCALE"/>&quot; க்கு மீண்டும் மாற்று (மறுதொடக்கம் தேவை)</translation>
 <translation id="8103386449138765447">SMS செய்திகள்: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Google இயக்கக அமைப்புகள்...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">நெட்வொர்க் இல்லை</translation>
 <translation id="5941711191222866238">சிறிதாக்கு</translation>
 <translation id="6911468394164995108">மற்றொன்றில் சேர்...</translation>
-<translation id="6843725295806269523">ஒலியடக்கு</translation>
 <translation id="412065659894267608">முழுவதும் சார்ஜ் ஆகும் நேரம் - <ph name="HOUR"/>ம <ph name="MINUTE"/>நி</translation>
 <translation id="6359806961507272919"><ph name="PHONE_NUMBER"/> என்ற எண்ணிலிருந்து வந்த SMS</translation>
+<translation id="1244147615850840081">சேவை வழங்குநர்</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_te.xtb b/ash/strings/ash_strings_te.xtb
index f201692..504e052 100644
--- a/ash/strings/ash_strings_te.xtb
+++ b/ash/strings/ash_strings_te.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">బ్యాటరీ  నిండింది</translation>
 <translation id="5250713215130379958">లాంచర్‌ను స్వయంచాలకంగా దాచు</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> మరియు <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">పోర్టల్ స్థితి</translation>
 <translation id="30155388420722288">అతివ్యాప్తి బటన్</translation>
 <translation id="5571066253365925590">Bluetooth ప్రారంభించబడింది</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">ప్రాక్సీ...</translation>
 <translation id="938582441709398163">కీబోర్డ్ అవలోకనం</translation>
 <translation id="6979158407327259162">Google డిస్క్</translation>
+<translation id="6943836128787782965">HTTP పొందడంలో విఫలమైంది</translation>
 <translation id="2297568595583585744">స్థితి ట్రే</translation>
+<translation id="1661867754829461514">PIN లేదు</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: కనెక్ట్ అవుతోంది...</translation>
+<translation id="4237016987259239829">నెట్‌వర్క్ కనెక్షన్ లోపం</translation>
 <translation id="2946640296642327832">Bluetoothని ప్రారంభించు</translation>
 <translation id="6459472438155181876"><ph name="DISPLAY_NAME"/>కు స్క్రీన్‌ను విస్తరిస్తోంది</translation>
 <translation id="8206859287963243715">సెల్యులార్</translation>
 <translation id="6596816719288285829">IP చిరునామా</translation>
+<translation id="4508265954913339219">సక్రియం  చేయడం విఫలమైంది</translation>
 <translation id="1812696562331527143">మీ ఇన్‌పుట్ పద్ధతి <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>3వ పక్షం<ph name="END_LINK"/>)కు మార్చబడింది.
 మారడానికి Shift + Altను నొక్కండి.</translation>
-<translation id="5233638681132016545">క్రొత్త టాబ్</translation>
 <translation id="3846575436967432996">నెట్‌వర్క్ సమాచారం అందుబాటులో లేదు</translation>
 <translation id="3026237328237090306">మొబైల్ డేటాను సెటప్ చేయి</translation>
 <translation id="785750925697875037">మొబైల్ ఖాతాని వీక్షించండి</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Bluetoothని నిలిపివేయి</translation>
 <translation id="3126069444801937830">నవీకరించడానికి పునఃప్రారంభించండి</translation>
 <translation id="735745346212279324">VPN డిస్‌కనెక్ట్ చేయబడింది</translation>
+<translation id="7320906967354320621">ఖాళీగా ఉంది</translation>
 <translation id="6303423059719347535">బ్యాటరీ <ph name="PERCENTAGE"/>% నిండింది</translation>
+<translation id="2778346081696727092">అందించిన వినియోగదారు పేరుతో లేదా పాస్‌వర్డ్‌తో ప్రామాణీకరించడం విఫలమైంది</translation>
 <translation id="3294437725009624529">అతిథి</translation>
 <translation id="8190698733819146287">భాషలను అనుకూలీకరించి, ఇన్‌పుట్ చెయ్యి...</translation>
-<translation id="598295083618286569">Bluetooth కనెక్ట్ చేయబడింది</translation>
+<translation id="7170041865419449892">పరిధిని దాటింది</translation>
+<translation id="4804818685124855865">డిస్‌కనెక్ట్ చెయ్యి</translation>
 <translation id="5222676887888702881">సైన్ ఔట్</translation>
+<translation id="2688477613306174402">కాన్ఫిగరేషన్</translation>
+<translation id="1272079795634619415">ఆపు</translation>
 <translation id="4957722034734105353">మరింత తెలుసుకోండి...</translation>
 <translation id="2964193600955408481">Wi-Fiని నిలిపివేయి</translation>
 <translation id="811680302244032017">పరికరాన్ని జోడించు...</translation>
 <translation id="2509468283778169019">CAPS LOCK ఆన్‌లో ఉంది</translation>
 <translation id="3892641579809465218">అంతర్గత ప్రదర్శన</translation>
 <translation id="7823564328645135659">మీ సెట్టింగ్‌లను సమకాలీకరించిన తర్వాత Chrome యొక్క భాష &quot;<ph name="FROM_LOCALE"/>&quot; నుండి &quot;<ph name="TO_LOCALE"/>&quot;కి మార్చబడింది.</translation>
+<translation id="3368922792935385530">కనెక్ట్ అయింది</translation>
 <translation id="8340999562596018839">చదవబడే అభిప్రాయం</translation>
 <translation id="8654520615680304441">Wi-Fiని ప్రారంభించు...</translation>
 <translation id="5825747213122829519">మీ ఇన్‌పుట్ పద్ధతి <ph name="INPUT_METHOD_ID"/>కు మార్చబడింది.
 మారడానికి Shift + Altను నొక్కండి.</translation>
 <translation id="2562916301614567480">ప్రైవేట్ నెట్‌వర్క్</translation>
 <translation id="6549021752953852991">సెల్యులార్ నెట్‌వర్క్ అందుబాటులో లేదు</translation>
+<translation id="4379753398862151997">ప్రియమైన మానిటర్, ఇది మన మధ్య పని చేయడం లేదు. (ఆ మానిటర్‌కు మద్దతు లేదు)</translation>
 <translation id="6426039856985689743">మొబైల్ డేటాను నిలిపివేయి</translation>
 <translation id="3087734570205094154">దిగువ</translation>
 <translation id="5271016907025319479">VPN కాన్ఫిగర్ చేయబడలేదు.</translation>
-<translation id="1298695107722797780">పబ్లిక్\nసెషన్‌ను ముగించు</translation>
-<translation id="3232695630852378748">Bluetooth సెట్టింగ్‌లు...</translation>
+<translation id="6803622936009808957">మద్దతు ఉన్న రిజల్యూషన్‌లు కనుగొనబడనందున ప్రదర్శనలను ప్రతిబింబించడం సాధ్యపడలేదు. దానికి బదులుగా విస్తారిత డెస్క్‌టాప్‌కు మారారు.</translation>
 <translation id="1480041086352807611">డెమో మోడ్</translation>
 <translation id="3626637461649818317"><ph name="PERCENTAGE"/>% మిగిలి ఉంది</translation>
 <translation id="9089416786594320554">ఇన్‌పుట్ పద్ధతులు</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">షట్‌డౌన్</translation>
 <translation id="4430019312045809116">వాల్యూమ్</translation>
+<translation id="4442424173763614572">DNS శోధన విఫలమైంది</translation>
 <translation id="6356500677799115505">బ్యాటరీ నిండింది మరియు చార్జ్ అవుతోంది.</translation>
 <translation id="7874779702599364982">సెల్యులార్ నెట్‌వర్క్‌ల కోసం శోధిస్తోంది...</translation>
+<translation id="583281660410589416">తెలియనిది</translation>
 <translation id="1383876407941801731">శోధన</translation>
+<translation id="7468789844759750875">మరింత డేటాను కొనుగోలు చేయడానికి <ph name="NAME"/> సక్రియ పోర్టల్‌ను సందర్శించండి.</translation>
 <translation id="3901991538546252627"><ph name="NAME"/>కి కనెక్ట్ చేస్తోంది</translation>
 <translation id="2204305834655267233">నెట్‌వర్క్ సమాచారం</translation>
 <translation id="1621499497873603021">బ్యాటరీ ఖాళీ కావడానికి మిగిలి ఉన్న సమయం, <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">మునుపటి మెను</translation>
 <translation id="1346748346194534595">కుడి</translation>
 <translation id="8528322925433439945">మొబైల్ ...</translation>
+<translation id="7049357003967926684">అసోసియేషన్</translation>
 <translation id="8428213095426709021">సెట్టింగ్‌లు</translation>
-<translation id="2472320577759310817">Bluetooth ఆపివేయబడింది.</translation>
 <translation id="2372145515558759244">అనువర్తనాలను సమకాలీకరిస్తోంది...</translation>
+<translation id="7256405249507348194">గుర్తించబడని లోపం: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">AAA తనిఖీ విఫలమైంది</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: డిస్‌కనెక్ట్ అవుతోంది...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> పూర్తి అయ్యేవరకు</translation>
 <translation id="5787281376604286451">చదవబడే అభిప్రాయం ప్రారంభించబడింది.
 నిలిపివేయడానికి Ctrl+Alt+Zను నొక్కండి.</translation>
 <translation id="4479639480957787382">ఈథర్నెట్</translation>
+<translation id="6312403991423642364">తెలియని నెట్‌వర్క్ లోపం</translation>
 <translation id="1467432559032391204">ఎడమ</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830"><ph name="NAME"/>ని సక్రియం చేస్తోంది</translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">గరిష్ఠీకరించు</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: కనెక్ట్ అవుతోంది...</translation>
+<translation id="8639033665604704195">అందించిన ముందే భాగస్వామ్యం చేయబడిన కీతో ప్రామాణీకరించడం విఫలమైంది</translation>
 <translation id="252373100621549798">తెలియని ప్రదర్శన</translation>
 <translation id="1882897271359938046"><ph name="DISPLAY_NAME"/>కు దర్పణం చేస్తోంది</translation>
 <translation id="3784455785234192852">లాక్ చేయి</translation>
 <translation id="2805756323405976993">Apps</translation>
-<translation id="2482878487686419369">ప్రకటనలు</translation>
+<translation id="1512064327686280138">సక్రియా విఫలం</translation>
+<translation id="5097002363526479830">'<ph name="NAME"/>'కు నెట్‌వర్క్‌కు కనెక్ట్ చేయడానికి విఫలమైంది: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi నిలిపివేయబడింది.</translation>
-<translation id="2872961005593481000">షట్ డౌన్ చెయ్యండి</translation>
+<translation id="8036518327127111261">అందించిన ప్రమాణపత్రంతో ప్రామాణీకరిచడం విఫలమైంది</translation>
 <translation id="8132793192354020517"><ph name="NAME"/>కు కనెక్ట్ చేయబడింది</translation>
 <translation id="7052914147756339792">వాల్‌పేపర్‌ను సెట్ చేయి...</translation>
-<translation id="2739500853984626550">Bluetooth పరికరాలు అందుబాటులో లేవు</translation>
-<translation id="2666092431469916601">పైన</translation>
+<translation id="8678698760965522072">ఆన్‌లైన్ స్థితి</translation>
+<translation id="1119447706177454957">అంతర్గత లోపం</translation>
 <translation id="3019353588588144572">బ్యాటరీ నిండటానికి పట్టే సమయం, <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">స్క్రీన్ మాగ్నిఫైయర్</translation>
+<translation id="7005812687360380971">విఫలం</translation>
 <translation id="1602076796624386989">మొబైల్ డేటాను ప్రారంభించు</translation>
 <translation id="6981982820502123353">ప్రాప్యత</translation>
 <translation id="3157931365184549694">పునరుద్ధరించు</translation>
+<translation id="4274292172790327596">గుర్తించబడని లోపం</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">పరికరాల కోసం స్కాన్ చేస్తోంది...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Wi-Fi నెట్‌వర్క్‌ల కోసం శోధిస్తోంది...</translation>
+<translation id="7229570126336867161">EVDO అవసరం</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> అనేది <ph name="DOMAIN"/> ద్వారా నిర్వహించబడుతున్న పబ్లిక్ సెషన్</translation>
 <translation id="7029814467594812963">సెషన్‌ని నిష్క్రమించు</translation>
 <translation id="8454013096329229812">Wi-Fi ప్రారంభించబడింది.</translation>
 <translation id="4872237917498892622">Alt+Search లేదా Shift</translation>
 <translation id="2983818520079887040">సెట్టింగ్‌లు...</translation>
-<translation id="5467313780247887226">జోడించబడిన మానిటర్‌ల్లో చిత్రాన్ని నకిలీ చేయలేదు. సరిపోలే రిజల్యూషన్ కనుగొనబడలేదు.</translation>
+<translation id="8927026611342028580">కనెక్ట్ చేయడం అభ్యర్థించబడింది</translation>
+<translation id="8300849813060516376">OTASP విఫలమైంది</translation>
 <translation id="2792498699870441125">Alt+Search</translation>
 <translation id="8660803626959853127"><ph name="COUNT"/> ఫైల్(ల)ను సమకాలీకరిస్తోంది</translation>
 <translation id="639644700271529076">CAPS LOCK ఆపివేయబడింది</translation>
-<translation id="4101192585425716296">సందేశ కేంద్రం</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: సక్రియం చేస్తోంది...</translation>
+<translation id="1391854757121130358">మీరు మీ మొబైల్ డేటా కేటాయింపును ఉపయోగించి ఉండవచ్చు.</translation>
 <translation id="4864165860509564259">లాంచర్ స్థానం</translation>
 <translation id="7593891976182323525">Search లేదా Shift</translation>
 <translation id="7649070708921625228">సహాయం</translation>
 <translation id="3050422059534974565">CAPS LOCK ఆన్‌లో ఉంది.
 రద్దు చేయడానికి Search లేదా Shiftని నొక్కండి.</translation>
 <translation id="397105322502079400">గణిస్తోంది...</translation>
+<translation id="158849752021629804"> హోమ్  నెట్‌వర్క్ అవసరం</translation>
+<translation id="6857811139397017780"><ph name="NETWORKSERVICE"/>ని సక్రియం చెయ్యి</translation>
+<translation id="5864471791310927901">DHCP లుక్‌అప్ విఫలమైంది</translation>
+<translation id="6692173217867674490">తప్పుడు పాస్‌ఫ్రేజ్</translation>
 <translation id="6165508094623778733">మరింత తెలుసుకోండి</translation>
+<translation id="9046895021617826162">కనెక్ట్ విఫలమైంది</translation>
+<translation id="973896785707726617">ఈ సెషన్ <ph name="SESSION_TIME_REMAINING"/> తర్వాత ముగుస్తుంది. మీరు స్వయంచాలకంగా సైన్ అవుట్ చేయబడతారు.</translation>
+<translation id="8372369524088641025">తప్పుడు WEP కీ</translation>
+<translation id="6636709850131805001">గుర్తించబడని రాష్ట్రం</translation>
 <translation id="3573179567135747900">&quot;<ph name="FROM_LOCALE"/>&quot;కు వెనుకకి మార్చండి (పునఃప్రారంభం అవసరం)</translation>
 <translation id="8103386449138765447">SMS సందేశాలు: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Google డిస్క్ సెట్టింగ్‌లు...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">ఏ నెట్‌వర్క్ లేదు</translation>
 <translation id="5941711191222866238">కనిష్టీకరించు</translation>
 <translation id="6911468394164995108">మరొక దానిలో చేరండి...</translation>
-<translation id="6843725295806269523">మ్యూట్ చేయి</translation>
 <translation id="412065659894267608">నిండే వరకు <ph name="HOUR"/>h <ph name="MINUTE"/>m అవుతుంది</translation>
 <translation id="6359806961507272919"><ph name="PHONE_NUMBER"/> నుండి SMS</translation>
+<translation id="1244147615850840081">కారియర్</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_th.xtb b/ash/strings/ash_strings_th.xtb
index 73d853d..bc5d948 100644
--- a/ash/strings/ash_strings_th.xtb
+++ b/ash/strings/ash_strings_th.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">แบตเตอรี่เต็ม</translation>
 <translation id="5250713215130379958">ตัวเรียกใช้งานแบบซ่อนอัตโนมัติ</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> กับ <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">สถานะพอร์ทัล</translation>
 <translation id="30155388420722288">ปุ่มแบบโอเวอร์โฟลว์</translation>
 <translation id="5571066253365925590">เปิดใช้งานบลูทูธแล้ว</translation>
 <translation id="9074739597929991885">บลูทูธ</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">พร็อกซี...</translation>
 <translation id="938582441709398163">การวางซ้อนแป้นพิมพ์</translation>
 <translation id="6979158407327259162">Google ไดรฟ์</translation>
+<translation id="6943836128787782965">การรับ HTTP ล้มเหลว</translation>
 <translation id="2297568595583585744">ถาดสถานะ</translation>
+<translation id="1661867754829461514">ไม่พบ PIN</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: กำลังเชื่อมต่อ...</translation>
+<translation id="4237016987259239829">ข้อผิดพลาดการเชื่อมต่อเครือข่าย</translation>
 <translation id="2946640296642327832">เปิดใช้งานบลูทูธ</translation>
 <translation id="6459472438155181876">ขยายหน้าจอไปยัง <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">โทรศัพท์มือถือ</translation>
 <translation id="6596816719288285829">ที่อยู่ IP</translation>
+<translation id="4508265954913339219">การเปิดใช้งานล้มเหลว</translation>
 <translation id="1812696562331527143">วิธีการป้อนข้อมูลของคุณเปลี่ยนแปลงเป็น <ph name="INPUT_METHOD_ID"/>* (<ph name="BEGIN_LINK"/>บุคคลที่สาม<ph name="END_LINK"/>)
 กด Shift + Alt เพื่อสลับ</translation>
-<translation id="5233638681132016545">แท็บใหม่</translation>
 <translation id="3846575436967432996">ไม่มีข้อมูลเครือข่ายที่สามารถใช้งานได้</translation>
 <translation id="3026237328237090306">ตั้งค่าข้อมูลมือถือ</translation>
 <translation id="785750925697875037">ดูบัญชีมือถือ</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">ปิดใช้งานบลูทูธ</translation>
 <translation id="3126069444801937830">รีสตาร์ทเพื่ออัปเดต</translation>
 <translation id="735745346212279324">ยกเลิกการเชื่อมต่อ VPN แล้ว</translation>
+<translation id="7320906967354320621">ไม่ทำงาน</translation>
 <translation id="6303423059719347535">มีแบตเตอรี่ <ph name="PERCENTAGE"/>%</translation>
+<translation id="2778346081696727092">ไม่สามารถตรวจสอบสิทธิ์ชื่อผู้ใช้หรือรหัสผ่านที่ให้มาได้</translation>
 <translation id="3294437725009624529">ผู้มาเยือน</translation>
 <translation id="8190698733819146287">กำหนดค่าภาษาและการป้อนข้อมูล... </translation>
-<translation id="598295083618286569">เชื่อมต่อบลูทูธแล้ว</translation>
+<translation id="7170041865419449892">อยู่นอกระยะสัญญาณ</translation>
+<translation id="4804818685124855865">ตัดการเชื่อมต่อ</translation>
 <translation id="5222676887888702881">ออกจากระบบ</translation>
+<translation id="2688477613306174402">การกำหนดค่า</translation>
+<translation id="1272079795634619415">หยุด</translation>
 <translation id="4957722034734105353">เรียนรู้เพิ่มเติม...</translation>
 <translation id="2964193600955408481">ปิดใช้งาน WiFi</translation>
 <translation id="811680302244032017">เพิ่มอุปกรณ์...</translation>
 <translation id="2509468283778169019">Caps Lock เปิดอยู่</translation>
 <translation id="3892641579809465218">จอแสดงผลภายใน</translation>
 <translation id="7823564328645135659">เปลี่ยนภาษาจาก &quot;<ph name="FROM_LOCALE"/>&quot; เป็น &quot;<ph name="TO_LOCALE"/>&quot; หลังจากซิงค์การตั้งค่าของคุณ</translation>
+<translation id="3368922792935385530">เชื่อมต่อแล้ว</translation>
 <translation id="8340999562596018839">การตอบสนองด้วยเสียง</translation>
 <translation id="8654520615680304441">เปิด WiFi...</translation>
 <translation id="5825747213122829519">วิธีการป้อนข้อมูลของคุณเปลี่ยนแปลงเป็น <ph name="INPUT_METHOD_ID"/> แล้ว
 กด Shift + Alt เพื่อสลับ</translation>
 <translation id="2562916301614567480">เครือข่ายส่วนบุคคล</translation>
 <translation id="6549021752953852991">ไม่มีเครือข่ายมือถือที่ใช้งานได้</translation>
+<translation id="4379753398862151997">จอภาพเอ๋ย เราร่วมงานกันไม่ได้ (จอภาพนั้นไม่ได้รับการสนับสนุน)</translation>
 <translation id="6426039856985689743">ปิดการใช้งานข้อมูลมือถือ</translation>
 <translation id="3087734570205094154">ด้านล่าง</translation>
 <translation id="5271016907025319479">ไม่ได้กำหนดค่า VPN</translation>
-<translation id="1298695107722797780">สิ้นสุดเซสชัน\nสาธารณะ</translation>
-<translation id="3232695630852378748">การตั้งค่าบลูทูธ...</translation>
+<translation id="6803622936009808957">ไม่สามารถแสดงผลคู่ขนานได้เนื่องจากไม่พบความละเอียดที่สนับสนุน เข้าสู่เดสก์ท็อปแบบขยายแทน</translation>
 <translation id="1480041086352807611">โหมดสาธิต</translation>
 <translation id="3626637461649818317">เหลืออีก <ph name="PERCENTAGE"/>%</translation>
 <translation id="9089416786594320554">วิธีการป้อนข้อมูล</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">ปิด</translation>
 <translation id="4430019312045809116">ระดับเสียง</translation>
+<translation id="4442424173763614572">การค้นหา DNS ล้มเหลว</translation>
 <translation id="6356500677799115505">แบตเตอรี่เต็มและกำลังชาร์จ</translation>
 <translation id="7874779702599364982">กำลังค้นหาเครือข่ายโทรศัพท์มือถือ...</translation>
+<translation id="583281660410589416">ไม่รู้จัก</translation>
 <translation id="1383876407941801731">เครื่องมือค้นหา</translation>
+<translation id="7468789844759750875">ไปที่พอร์ทัลการเปิดใช้งาน <ph name="NAME"/> เพื่อซื้อข้อมูลเพิ่มเติม</translation>
 <translation id="3901991538546252627">กำลังเชื่อมต่อกับ <ph name="NAME"/></translation>
 <translation id="2204305834655267233">ข้อมูลเครือข่าย</translation>
 <translation id="1621499497873603021">เวลาที่เหลือกว่าแบตเตอรี่จะหมด, <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">เมนูก่อนหน้า</translation>
 <translation id="1346748346194534595">ขวา</translation>
 <translation id="8528322925433439945">มือถือ ...</translation>
+<translation id="7049357003967926684">การเชื่อมโยง</translation>
 <translation id="8428213095426709021">การตั้งค่า</translation>
-<translation id="2472320577759310817">บลูทูธปิดอยู่</translation>
 <translation id="2372145515558759244">กำลังซิงค์แอปพลิเคชัน...</translation>
+<translation id="7256405249507348194">ข้อผิดพลาดที่ไม่รู้จัก: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">การตรวจสอบ AAA ล้มเหลว</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: กำลังยกเลิกการเชื่อมต่อ...</translation>
 <translation id="8456362689280298700">อีก <ph name="HOUR"/>:<ph name="MINUTE"/> จึงจะเต็ม</translation>
 <translation id="5787281376604286451">เปิดใช้งานการตอบสนองด้วยเสียงอยู่
 กด Ctrl+Alt+Z เพื่อปิดใช้งาน</translation>
 <translation id="4479639480957787382">อีเทอร์เน็ต</translation>
+<translation id="6312403991423642364">ข้อผิดพลาดเครือข่ายที่ไม่รู้จัก</translation>
 <translation id="1467432559032391204">ซ้าย</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830">กำลังเปิดใช้งาน <ph name="NAME"/></translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">ย่อ</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: กำลังเชื่อมต่อ...</translation>
+<translation id="8639033665604704195">ไม่สามารถตรวจสอบสิทธิ์ด้วยคีย์ที่แบ่งปันไว้ล่วงหน้าที่ให้มาได้</translation>
 <translation id="252373100621549798">หน้าจอที่ไม่รู้จัก</translation>
 <translation id="1882897271359938046">กำลังแสดงผลไปที่ <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">ล็อก</translation>
 <translation id="2805756323405976993">Apps</translation>
-<translation id="2482878487686419369">การแจ้งเตือน</translation>
+<translation id="1512064327686280138">การเปิดใช้งานล้มเหลว</translation>
+<translation id="5097002363526479830">ไม่สามารถเชื่อมต่อเครือข่าย &quot;<ph name="NAME"/>&quot;: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">WiFi ปิดอยู่</translation>
-<translation id="2872961005593481000">ปิด</translation>
+<translation id="8036518327127111261">ไม่สามารถตรวจสอบสิทธิ์ด้วยใบรับรองที่ให้มาได้</translation>
 <translation id="8132793192354020517">เชื่อมต่อกับ <ph name="NAME"/></translation>
 <translation id="7052914147756339792">ตั้งค่าวอลเปเปอร์...</translation>
-<translation id="2739500853984626550">ไม่มีอุปกรณ์บลูทูธที่ใช้ได้</translation>
-<translation id="2666092431469916601">ด้านบน</translation>
+<translation id="8678698760965522072">สถานะออนไลน์</translation>
+<translation id="1119447706177454957">ข้อผิดพลาดภายใน</translation>
 <translation id="3019353588588144572">เวลาที่เหลือกว่าจะชาร์จแบตเตอรี่เต็ม, <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">แว่นขยายหน้าจอ</translation>
+<translation id="7005812687360380971">ล้มเหลว</translation>
 <translation id="1602076796624386989">เปิดใช้งานข้อมูลมือถือ</translation>
 <translation id="6981982820502123353">การเข้าถึง</translation>
 <translation id="3157931365184549694">คืนสภาพ</translation>
+<translation id="4274292172790327596">ข้อผิดพลาดที่ไม่รู้จัก</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">กำลังสแกนหาอุปกรณ์...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">กำลังค้นหาเครือข่าย Wi-Fi...</translation>
+<translation id="7229570126336867161">ต้องใช้ EVDO</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> เป็นเซสชันสาธารณะซึ่งจัดการโดย <ph name="DOMAIN"/></translation>
 <translation id="7029814467594812963">ออกจากเซสชัน</translation>
 <translation id="8454013096329229812">WiFi เปิดอยู่</translation>
 <translation id="4872237917498892622">Alt+ค้นหา หรือ Shift</translation>
 <translation id="2983818520079887040">การตั้งค่า...</translation>
-<translation id="5467313780247887226">ไม่สามารถแสดงภาพเหมือนในหน้าจอที่เชื่อมต่อ ไม่พบความละเอียดที่ตรงกัน</translation>
+<translation id="8927026611342028580">ขอเชื่อมต่อ</translation>
+<translation id="8300849813060516376">OTASP ล้มเหลว</translation>
 <translation id="2792498699870441125">Alt+ค้นหา</translation>
 <translation id="8660803626959853127">กำลังซิงค์ <ph name="COUNT"/> ไฟล์</translation>
 <translation id="639644700271529076">CAPS LOCK ปิดอยู่</translation>
-<translation id="4101192585425716296">ศูนย์ข้อความ</translation>
+<translation id="6267036997247669271"><ph name="NAME"/> กำลังเปิดใช้งาน...</translation>
+<translation id="1391854757121130358">คุณอาจใช้ข้อมูลมือถือถึงขีดจำกัดแล้ว</translation>
 <translation id="4864165860509564259">ตำแหน่งของตัวเรียกใช้งาน</translation>
 <translation id="7593891976182323525">ค้นหาหรือ Shift</translation>
 <translation id="7649070708921625228">ช่วยเหลือ</translation>
 <translation id="3050422059534974565">CAPS LOCK เปิดอยู่
 กด &quot;ค้นหา&quot; หรือ Shift เพื่อยกเิลิก</translation>
 <translation id="397105322502079400">กำลังคำนวณ...</translation>
+<translation id="158849752021629804">ต้องใช้เครือข่ายในประเทศ</translation>
+<translation id="6857811139397017780">เปิดใช้งาน <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">การค้นหา DHCP ล้มเหลว</translation>
+<translation id="6692173217867674490">ข้อความรหัสผ่านไม่ถูกต้อง</translation>
 <translation id="6165508094623778733">เรียนรู้เพิ่มเติม</translation>
+<translation id="9046895021617826162">การเชื่อมต่อล้มเหลว</translation>
+<translation id="973896785707726617">เซสชันนี้จะสิ้นสุดใน <ph name="SESSION_TIME_REMAINING"/> ระบบจะลงชื่อออกให้คุณโดยอัตโนมัติ</translation>
+<translation id="8372369524088641025">คีย์ WEP ไม่ถูกต้อง</translation>
+<translation id="6636709850131805001">สถานะที่ไม่รู้จัก</translation>
 <translation id="3573179567135747900">เปลี่ยนกลับเป็น &quot;<ph name="FROM_LOCALE"/>&quot; (จำเป็นต้องรีสตาร์ต)</translation>
 <translation id="8103386449138765447">ข้อความ SMS: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">การตั้งค่า Google ไดรฟ์...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">ไม่มีเครือข่าย</translation>
 <translation id="5941711191222866238">ย่อ</translation>
 <translation id="6911468394164995108">เชื่อมต่อเครือข่ายอื่น...</translation>
-<translation id="6843725295806269523">ปิดเสียง</translation>
 <translation id="412065659894267608">อีก <ph name="HOUR"/>ชม. <ph name="MINUTE"/>นาทีจึงจะเต็ม</translation>
 <translation id="6359806961507272919">SMS จาก <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">ผู้ให้บริการ</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_tr.xtb b/ash/strings/ash_strings_tr.xtb
index e2af2a2..f08ec9c 100644
--- a/ash/strings/ash_strings_tr.xtb
+++ b/ash/strings/ash_strings_tr.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Pil tam dolu</translation>
 <translation id="5250713215130379958">Başlatıcıyı otomatik gizle</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> ve <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Portal durumu</translation>
 <translation id="30155388420722288">Taşma Düğmesi</translation>
 <translation id="5571066253365925590">Bluetooth etkin</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Proxy...</translation>
 <translation id="938582441709398163">Klavye Yer Paylaşımı</translation>
 <translation id="6979158407327259162">Google Drive</translation>
+<translation id="6943836128787782965">HTTP get işlevi başarısız oldu</translation>
 <translation id="2297568595583585744">Durum tepsisi</translation>
+<translation id="1661867754829461514">PIN eksik</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: Bağlanıyor...</translation>
+<translation id="4237016987259239829">Ağ Bağlantısı Hatası</translation>
 <translation id="2946640296642327832">Bluetooth'u etkinleştir</translation>
 <translation id="6459472438155181876">Ekran şuraya genişletiliyor: <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Cep telefonu</translation>
 <translation id="6596816719288285829">IP Adresi</translation>
+<translation id="4508265954913339219">Etkinleştirme başarısız oldu</translation>
 <translation id="1812696562331527143">Giriş yönteminiz <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>3. taraf<ph name="END_LINK"/>) olarak değiştirildi.
 Geçiş yapmak için ÜstKrktr + Alt tuşlarına basın.</translation>
-<translation id="5233638681132016545">Yeni sekme</translation>
 <translation id="3846575436967432996">Hiçbir ağ bilgisi yok</translation>
 <translation id="3026237328237090306">Mobil verileri ayarla</translation>
 <translation id="785750925697875037">Mobil hesabı görüntüle</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Bluetooth'u devre dışı bırak</translation>
 <translation id="3126069444801937830">Güncellemek için yeniden başlat</translation>
 <translation id="735745346212279324">VPN bağlantısı kesildi</translation>
+<translation id="7320906967354320621">Boşta</translation>
 <translation id="6303423059719347535">Pil %<ph name="PERCENTAGE"/> dolu</translation>
+<translation id="2778346081696727092">Sağlanan kullanıcı adı ve şifreyle kimlik doğrulanamadı</translation>
 <translation id="3294437725009624529">Konuk</translation>
 <translation id="8190698733819146287">Dilleri ve girişi özelleştir...</translation>
-<translation id="598295083618286569">Bluetooth bağlandı</translation>
+<translation id="7170041865419449892">Aralık dışında</translation>
+<translation id="4804818685124855865">Bağlantıyı kes</translation>
 <translation id="5222676887888702881">Çıkış</translation>
+<translation id="2688477613306174402">Yapılandırma</translation>
+<translation id="1272079795634619415">Durdur</translation>
 <translation id="4957722034734105353">Daha fazla bilgi edinin...</translation>
 <translation id="2964193600955408481">Kablosuz bağlantıyı devre dışı bırak</translation>
 <translation id="811680302244032017">Cihaz ekle...</translation>
 <translation id="2509468283778169019">CAPS LOCK açık</translation>
 <translation id="3892641579809465218">Dahili Ekran</translation>
 <translation id="7823564328645135659">Ayarlarınız senkronize edildikten sonra &quot;<ph name="FROM_LOCALE"/>&quot; olan dil &quot;<ph name="TO_LOCALE"/>&quot; olarak değiştirildi.</translation>
+<translation id="3368922792935385530">Bağlı</translation>
 <translation id="8340999562596018839">Sesli geri bildirim</translation>
 <translation id="8654520615680304441">Kablosuz'u aç...</translation>
 <translation id="5825747213122829519">Giriş yönteminiz <ph name="INPUT_METHOD_ID"/> olarak değiştirildi.
 Geçiş yapmak için ÜstKrktr + Alt tuşlarına basın.</translation>
 <translation id="2562916301614567480">Özel Ağ</translation>
 <translation id="6549021752953852991">Kullanılabilir hücresel ağ yok</translation>
+<translation id="4379753398862151997">Sevgili Monitör, aramızdaki bu ilişki yürümüyor. (Bu monitör desteklenmiyor)</translation>
 <translation id="6426039856985689743">Mobil verileri devre dışı bırak</translation>
 <translation id="3087734570205094154">Alt</translation>
 <translation id="5271016907025319479">VPN yapılandırılmadı.</translation>
-<translation id="1298695107722797780">Herkese açık\noturumu sonlandır</translation>
-<translation id="3232695630852378748">Bluetooth ayarları...</translation>
+<translation id="6803622936009808957">Desteklenen bir çözünürlük bulunamadığı için ekranlar yansıtılamıyor. Bunun yerine genişletilmiş masaüstüne geçiliyor.</translation>
 <translation id="1480041086352807611">Demo modu</translation>
 <translation id="3626637461649818317">%<ph name="PERCENTAGE"/> kaldı</translation>
 <translation id="9089416786594320554">Giriş yöntemleri</translation>
 <translation id="6247708409970142803">%<ph name="PERCENTAGE"/></translation>
 <translation id="1895658205118569222">Kapat</translation>
 <translation id="4430019312045809116">Ses</translation>
+<translation id="4442424173763614572">DNS arama başarısız oldu</translation>
 <translation id="6356500677799115505">Pil dolu ve şarj oluyor.</translation>
 <translation id="7874779702599364982">Hücresel ağlar aranıyor...</translation>
+<translation id="583281660410589416">Bilinmiyor</translation>
 <translation id="1383876407941801731">Arama</translation>
+<translation id="7468789844759750875">Daha fazla veri satın almak için <ph name="NAME"/> etkinleştirme portalını ziyaret edin.</translation>
 <translation id="3901991538546252627"><ph name="NAME"/> ağına bağlanılıyor</translation>
 <translation id="2204305834655267233">Ağ Bilgisi</translation>
 <translation id="1621499497873603021">Pilin boşalması için kalan süre, <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">Önceki menü</translation>
 <translation id="1346748346194534595">Sağa</translation>
 <translation id="8528322925433439945">Mobile...</translation>
+<translation id="7049357003967926684">İlişki</translation>
 <translation id="8428213095426709021">Ayarlar</translation>
-<translation id="2472320577759310817">Bluetooth kapalı.</translation>
 <translation id="2372145515558759244">Uygulamalar senkronize ediliyor...</translation>
+<translation id="7256405249507348194">Tanınmayan hata: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">AAA kontrolü başarısız oldu</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: Bağlantı kesiliyor...</translation>
 <translation id="8456362689280298700">Dolması için gereken süre: <ph name="HOUR"/>:<ph name="MINUTE"/> </translation>
 <translation id="5787281376604286451">Sesli geri bildirim etkin.
 Devre dışı bırakmak için Ctrl+Alt+Z tuşlarına basın.</translation>
 <translation id="4479639480957787382">Ethernet</translation>
+<translation id="6312403991423642364">Bilinmeyen ağ hatası</translation>
 <translation id="1467432559032391204">Sola</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830"><ph name="NAME"/> etkinleştiriliyor</translation>
 <translation id="8814190375133053267">Kablosuz</translation>
 <translation id="1398853756734560583">Büyüt</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: Bağlanıyor...</translation>
+<translation id="8639033665604704195">Sağlanan önceden paylaşılan anahtarla kimlik doğrulanamadı</translation>
 <translation id="252373100621549798">Bilinmeyen Görünüm</translation>
 <translation id="1882897271359938046">Şuraya yansıtılıyor: <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Kilitle</translation>
 <translation id="2805756323405976993">Uygulamalar</translation>
-<translation id="2482878487686419369">Bildirimler</translation>
+<translation id="1512064327686280138">Etkinleştirme hatası</translation>
+<translation id="5097002363526479830">'<ph name="NAME"/>' ağına bağlanamadı: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Kablosuz kapalı.</translation>
-<translation id="2872961005593481000">Kapat</translation>
+<translation id="8036518327127111261">Sağlanan sertifikayla kimlik doğrulanamadı</translation>
 <translation id="8132793192354020517"><ph name="NAME"/> ağına bağlanıldı</translation>
 <translation id="7052914147756339792">Duvar kağıdını ayarla...</translation>
-<translation id="2739500853984626550">Kullanılabilir bluetooth cihazı yok</translation>
-<translation id="2666092431469916601">Üst</translation>
+<translation id="8678698760965522072">Çevrimiçi durumu</translation>
+<translation id="1119447706177454957">Dahili hata</translation>
 <translation id="3019353588588144572">Pilin tam olarak şarj olması için kalan süre, <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">Ekran büyüteci</translation>
+<translation id="7005812687360380971">Hata</translation>
 <translation id="1602076796624386989">Mobil verileri etkinleştir</translation>
 <translation id="6981982820502123353">Erişilebilirlik</translation>
 <translation id="3157931365184549694">Geri yükle</translation>
+<translation id="4274292172790327596">Tanınmayan hata</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Cihazlar taranıyor...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Kablosuz ağlar aranıyor...</translation>
+<translation id="7229570126336867161">EVDO gerekli</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/>, <ph name="DOMAIN"/> tarafından yönetilen herkese açık bir oturumdur</translation>
 <translation id="7029814467594812963">Oturumdan çık</translation>
 <translation id="8454013096329229812">Kablosuz açık.</translation>
 <translation id="4872237917498892622">Alt+Arama veya Üst Karakter</translation>
 <translation id="2983818520079887040">Ayarlar...</translation>
-<translation id="5467313780247887226">Görüntü bağlı monitörlere yansıtılamıyor. Eşleşen çözünürlük bulunamadı.</translation>
+<translation id="8927026611342028580">Bağlantı İstendi</translation>
+<translation id="8300849813060516376">OTASP başarısız oldu</translation>
 <translation id="2792498699870441125">Alt+Arama</translation>
 <translation id="8660803626959853127"><ph name="COUNT"/> dosya senkronize ediliyor</translation>
 <translation id="639644700271529076">CAPS LOCK kapalı</translation>
-<translation id="4101192585425716296">Mesaj Merkezi</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: Etkinleştiriliyor...</translation>
+<translation id="1391854757121130358">Mobil veri hakkınızı bitirmiş olabilirsiniz.</translation>
 <translation id="4864165860509564259">Başlatıcı konumu</translation>
 <translation id="7593891976182323525">Arama veya Üst Karakter</translation>
 <translation id="7649070708921625228">Yardım</translation>
 <translation id="3050422059534974565">CAPS LOCK açık.
 İptal için Arama veya Üst Karakter tuşlarına basın.</translation>
 <translation id="397105322502079400">Hesaplanııyor...</translation>
+<translation id="158849752021629804">Ev ağı gerekli</translation>
+<translation id="6857811139397017780">Şunu etkinleştir: <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">DHCP araması başarısız oldu</translation>
+<translation id="6692173217867674490">Hatalı parola</translation>
 <translation id="6165508094623778733">Daha fazla bilgi edinin</translation>
+<translation id="9046895021617826162">Bağlantı başarısız oldu</translation>
+<translation id="973896785707726617">Bu oturum <ph name="SESSION_TIME_REMAINING"/> içinde sona erecek. Oturumunuz otomatik olarak kapatılacaktır.</translation>
+<translation id="8372369524088641025">Hatalı WEP anahtarı</translation>
+<translation id="6636709850131805001">Tanınmayan durum</translation>
 <translation id="3573179567135747900">Tekrar &quot;<ph name="FROM_LOCALE"/>&quot; ayarına dön (yeniden başlatmak gerekir)</translation>
 <translation id="8103386449138765447">SMS mesajları: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Google Drive ayarları...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">Ağ yok</translation>
 <translation id="5941711191222866238">Simge durumuna küçült</translation>
 <translation id="6911468394164995108">Başka ağa katıl...</translation>
-<translation id="6843725295806269523">sesi kapat</translation>
 <translation id="412065659894267608">Tam dolana kadar <ph name="HOUR"/> sa <ph name="MINUTE"/> dk var</translation>
 <translation id="6359806961507272919"><ph name="PHONE_NUMBER"/> numaradan SMS alındı</translation>
+<translation id="1244147615850840081">Operatör</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_uk.xtb b/ash/strings/ash_strings_uk.xtb
index 3a30465..f5c7877 100644
--- a/ash/strings/ash_strings_uk.xtb
+++ b/ash/strings/ash_strings_uk.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Повний заряд акумулятора</translation>
 <translation id="5250713215130379958">Автоматично ховати панель запуску</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> і <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Стан порталу</translation>
 <translation id="30155388420722288">Кнопка переповнення</translation>
 <translation id="5571066253365925590">Bluetooth увімкнено</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Проксі-сервер...</translation>
 <translation id="938582441709398163">Розкладка клавіатури</translation>
 <translation id="6979158407327259162">Диск Google</translation>
+<translation id="6943836128787782965">Помилка HTTP</translation>
 <translation id="2297568595583585744">Контейтер стану</translation>
+<translation id="1661867754829461514">Відсутній PIN-код</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: Під’єднання…</translation>
+<translation id="4237016987259239829">Помилка з'єднання з мережею</translation>
 <translation id="2946640296642327832">Увімкнути Bluetooth</translation>
 <translation id="6459472438155181876">Розширення екрана на <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Мобільний</translation>
 <translation id="6596816719288285829">ІР-адреса</translation>
+<translation id="4508265954913339219">Помилка активації</translation>
 <translation id="1812696562331527143">Метод введення змінено на <ph name="INPUT_METHOD_ID"/>* (<ph name="BEGIN_LINK"/>третя сторона<ph name="END_LINK"/>).
 Щоб переключитися, натисніть Shift + Alt.</translation>
-<translation id="5233638681132016545">Нова вкладка</translation>
 <translation id="3846575436967432996">Інформація про мережу не доступна</translation>
 <translation id="3026237328237090306">Налаштувати передавання мобільних даних</translation>
 <translation id="785750925697875037">Переглянути обліковий запис для мобільних пристроїв</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Вимкнути Bluetooth</translation>
 <translation id="3126069444801937830">Перезапустіть, щоб оновити</translation>
 <translation id="735745346212279324">VPN від’єднано</translation>
+<translation id="7320906967354320621">Простій</translation>
 <translation id="6303423059719347535">Акумулятор заряджений на <ph name="PERCENTAGE"/>%</translation>
+<translation id="2778346081696727092">Помилка автентифікації за допомогою введеного імені користувача чи пароля</translation>
 <translation id="3294437725009624529">Гість</translation>
 <translation id="8190698733819146287">Налаштувати мови та введення тексту...</translation>
-<translation id="598295083618286569">Bluetooth під’єднано</translation>
+<translation id="7170041865419449892">За межами досяжності</translation>
+<translation id="4804818685124855865">Від'єднатися</translation>
 <translation id="5222676887888702881">Вийти</translation>
+<translation id="2688477613306174402">Конфігурація</translation>
+<translation id="1272079795634619415">Зупинити</translation>
 <translation id="4957722034734105353">Докладніше...</translation>
 <translation id="2964193600955408481">Вимкнути Wi-Fi</translation>
 <translation id="811680302244032017">Додати пристрій...</translation>
 <translation id="2509468283778169019">Режим CAPS LOCK увімкнено</translation>
 <translation id="3892641579809465218">Внутрішній екран</translation>
 <translation id="7823564328645135659">Після синхронізації налаштувань мову змінено. Попередня: <ph name="FROM_LOCALE"/>, нова: <ph name="TO_LOCALE"/>.</translation>
+<translation id="3368922792935385530">Підключено</translation>
 <translation id="8340999562596018839">Голосові підказки</translation>
 <translation id="8654520615680304441">Увімкнення Wi-Fi…</translation>
 <translation id="5825747213122829519">Метод введення змінено на <ph name="INPUT_METHOD_ID"/>.
 Щоб переключитися, натисніть Shift + Alt.</translation>
 <translation id="2562916301614567480">Приватна мережа</translation>
 <translation id="6549021752953852991">Мобільна мережа недоступна</translation>
+<translation id="4379753398862151997">Прикро, але контакту з монітором немає. (Цей монітор не підтримується)</translation>
 <translation id="6426039856985689743">Вимкнути передавання мобільних даних</translation>
 <translation id="3087734570205094154">Низ</translation>
 <translation id="5271016907025319479">VPN не налаштовано.</translation>
-<translation id="1298695107722797780">Закінчити загальнодоступний\nсеанс</translation>
-<translation id="3232695630852378748">Налаштування Bluetooth...</translation>
+<translation id="6803622936009808957">Не вдалося дублювати зображення екранів, оскільки не знайдено підтримувані значення роздільної здатності. Натомість запущено режим розширеного робочого столу.</translation>
 <translation id="1480041086352807611">Демонстраційний режим</translation>
 <translation id="3626637461649818317">Залишилося <ph name="PERCENTAGE"/>%</translation>
 <translation id="9089416786594320554">Методи введення</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">Завершення роботи</translation>
 <translation id="4430019312045809116">Гучність</translation>
+<translation id="4442424173763614572">Помилка пошуку DNS</translation>
 <translation id="6356500677799115505">Акумулятор заряджений і продовжує заряджатися.</translation>
 <translation id="7874779702599364982">Пошук мобільних мереж…</translation>
+<translation id="583281660410589416">Невідомо</translation>
 <translation id="1383876407941801731">Пошук</translation>
+<translation id="7468789844759750875">Перейти на портал активації <ph name="NAME"/>, щоб придбати більший обсяг даних.</translation>
 <translation id="3901991538546252627">Під’єднання до <ph name="NAME"/></translation>
 <translation id="2204305834655267233">Інформація про мережу</translation>
 <translation id="1621499497873603021">До розрядження акумулятора залишилося <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">Попереднє меню</translation>
 <translation id="1346748346194534595">Праворуч</translation>
 <translation id="8528322925433439945">Мобільні ...</translation>
+<translation id="7049357003967926684">Пов'язування</translation>
 <translation id="8428213095426709021">Налаштування</translation>
-<translation id="2472320577759310817">Bluetooth вимкнено.</translation>
 <translation id="2372145515558759244">Синхронізація програм...</translation>
+<translation id="7256405249507348194">Нерозпізнана помилка: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">Помилка перевірки AAA</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: Від’єднання…</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> до повного зарядження</translation>
 <translation id="5787281376604286451">Голосові підказки ввімкнено.
 Натисніть Ctrl+Alt+Z, щоб вимкнути.</translation>
 <translation id="4479639480957787382">Ethernet</translation>
+<translation id="6312403991423642364">Невідома помилка мережі</translation>
 <translation id="1467432559032391204">Ліворуч</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830">Активація <ph name="NAME"/></translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">Збільшити</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: Під’єднання…</translation>
+<translation id="8639033665604704195">Помилка автентифікації за допомогою введеного спільного ключа</translation>
 <translation id="252373100621549798">Невідомий дисплей</translation>
 <translation id="1882897271359938046">Дзеркалювання на <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Заблокувати</translation>
 <translation id="2805756323405976993">Програми</translation>
-<translation id="2482878487686419369">Сповіщення</translation>
+<translation id="1512064327686280138">Помилка активації</translation>
+<translation id="5097002363526479830">Не вдалося під’єднатися до мережі &quot;<ph name="NAME"/>&quot;: <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi вимкнено.</translation>
-<translation id="2872961005593481000">Завершити роботу</translation>
+<translation id="8036518327127111261">Помилка автентифікації за допомогою наданого сертифіката</translation>
 <translation id="8132793192354020517">З'єднано з <ph name="NAME"/></translation>
 <translation id="7052914147756339792">Установити фоновий малюнок...</translation>
-<translation id="2739500853984626550">Немає доступних пристроїв Bluetooth</translation>
-<translation id="2666092431469916601">Верх</translation>
+<translation id="8678698760965522072">Статус онлайн</translation>
+<translation id="1119447706177454957">Внутрішня помилка</translation>
 <translation id="3019353588588144572">До повного зарядження акумулятора залишилося <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">Лупа</translation>
+<translation id="7005812687360380971">Помилка</translation>
 <translation id="1602076796624386989">Увімкнути передавання мобільних даних</translation>
 <translation id="6981982820502123353">Доступність</translation>
 <translation id="3157931365184549694">Відновити</translation>
+<translation id="4274292172790327596">Нерозпізнана помилка</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Пошук пристроїв...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Пошук Wi-Fi мереж...</translation>
+<translation id="7229570126336867161">Потрібна мережа EVDO</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> – загальнодоступний сеанс, керований доменом <ph name="DOMAIN"/></translation>
 <translation id="7029814467594812963">Завершити сеанс</translation>
 <translation id="8454013096329229812">Wi-Fi увімкнено.</translation>
 <translation id="4872237917498892622">Alt+клавіша пошуку або Shift</translation>
 <translation id="2983818520079887040">Налаштування...</translation>
-<translation id="5467313780247887226">Не вдалося дублювати зображення на приєднаних моніторах. Не знайдено відповідну роздільну здатність.</translation>
+<translation id="8927026611342028580">Подано запит на під’єднання</translation>
+<translation id="8300849813060516376">Помилка OTASP</translation>
 <translation id="2792498699870441125">Alt+клавіша пошуку</translation>
 <translation id="8660803626959853127">Синхронізація файлів (<ph name="COUNT"/>)</translation>
 <translation id="639644700271529076">Режим CAPS LOCK вимкнено</translation>
-<translation id="4101192585425716296">Центр повідомлень</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: активація…</translation>
+<translation id="1391854757121130358">Можливо, ви використали свій ліміт мобільного передавання даних.</translation>
 <translation id="4864165860509564259">Положення панелі запуску</translation>
 <translation id="7593891976182323525">Клавіша пошуку або Shift</translation>
 <translation id="7649070708921625228">Довідка</translation>
 <translation id="3050422059534974565">Клавішу CAPS LOCK увімкнено.
 Натисніть клавішу пошуку або Shift, щоб скасувати.</translation>
 <translation id="397105322502079400">Обчислення...</translation>
+<translation id="158849752021629804">Потрібна домашня мережа</translation>
+<translation id="6857811139397017780">Активувати <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">Помилка пошуку DHCP</translation>
+<translation id="6692173217867674490">Погана парольна фраза</translation>
 <translation id="6165508094623778733">Докладніше</translation>
+<translation id="9046895021617826162">Помилка з'єднання</translation>
+<translation id="973896785707726617">Сеанс закінчиться за <ph name="SESSION_TIME_REMAINING"/>. Ви вийдете автоматично.</translation>
+<translation id="8372369524088641025">Поганий WEP-ключ</translation>
+<translation id="6636709850131805001">Нерозпізнаний стан</translation>
 <translation id="3573179567135747900">Повернутися до мови &quot;<ph name="FROM_LOCALE"/>&quot; (потрібно перезавантажитися)</translation>
 <translation id="8103386449138765447">SMS повідомлень: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Налаштування Диска Google...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">Немає мережі</translation>
 <translation id="5941711191222866238">Зменшити</translation>
 <translation id="6911468394164995108">Під’єднатися до іншої...</translation>
-<translation id="6843725295806269523">вимкнути звук</translation>
 <translation id="412065659894267608"><ph name="HOUR"/> год. <ph name="MINUTE"/> хв. до повного зарядження</translation>
 <translation id="6359806961507272919">SMS-повідомлення від <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Постачальник</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_vi.xtb b/ash/strings/ash_strings_vi.xtb
index b0b494f..c8f5876 100644
--- a/ash/strings/ash_strings_vi.xtb
+++ b/ash/strings/ash_strings_vi.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">Pin đầy</translation>
 <translation id="5250713215130379958">Tự động ẩn trình khởi chạy</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> và <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">Trạng thái cổng</translation>
 <translation id="30155388420722288">Nút tràn</translation>
 <translation id="5571066253365925590">Đã bật bluetooth</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Proxy...</translation>
 <translation id="938582441709398163">Lớp phủ bàn phím</translation>
 <translation id="6979158407327259162">Google Drive</translation>
+<translation id="6943836128787782965">HTTP gặp lỗi</translation>
 <translation id="2297568595583585744">Khay trạng thái</translation>
+<translation id="1661867754829461514">Thiếu PIN</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>: Đang kết nối...</translation>
+<translation id="4237016987259239829">Lỗi Kết nối Mạng</translation>
 <translation id="2946640296642327832">Bật bluetooth</translation>
 <translation id="6459472438155181876">Đang mở rộng màn hình tới <ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">Di động</translation>
 <translation id="6596816719288285829">Địa chỉ IP</translation>
+<translation id="4508265954913339219">Kích hoạt không thành công</translation>
 <translation id="1812696562331527143">Phương thức nhập của bạn đã thay đổi thành <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>bên thứ ba<ph name="END_LINK"/>).
 Nhấn Shift + Alt để chuyển đổi.</translation>
-<translation id="5233638681132016545">Tab mới</translation>
 <translation id="3846575436967432996">Không có thông tin mạng</translation>
 <translation id="3026237328237090306">Thiết lập dữ liệu di động</translation>
 <translation id="785750925697875037">Xem tài khoản di động</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">Tắt bluetooth</translation>
 <translation id="3126069444801937830">Khởi động lại để cập nhật</translation>
 <translation id="735745346212279324">Đã ngắt kết nối VPN</translation>
+<translation id="7320906967354320621">Rảnh</translation>
 <translation id="6303423059719347535">Pin <ph name="PERCENTAGE"/>% đầy</translation>
+<translation id="2778346081696727092">Không thể xác thực với tên người dùng và mật khẩu đã cung cấp</translation>
 <translation id="3294437725009624529">Khách</translation>
 <translation id="8190698733819146287">Tùy chỉnh ngôn ngữ và dữ liệu nhập...</translation>
-<translation id="598295083618286569">Đã kết nối bluetooth</translation>
+<translation id="7170041865419449892">Ngoài vùng phủ sóng</translation>
+<translation id="4804818685124855865">Ngắt kết nối</translation>
 <translation id="5222676887888702881">Đăng xuất</translation>
+<translation id="2688477613306174402">Cấu hình</translation>
+<translation id="1272079795634619415">Dừng</translation>
 <translation id="4957722034734105353">Tìm hiểu thêm...</translation>
 <translation id="2964193600955408481">Tắt Wi-Fi</translation>
 <translation id="811680302244032017">Thêm thiết bị...</translation>
 <translation id="2509468283778169019">Đang bật CAPS LOCK</translation>
 <translation id="3892641579809465218">Màn hình nội bộ</translation>
 <translation id="7823564328645135659">Ngôn ngữ đã chuyển từ &quot;<ph name="FROM_LOCALE"/>&quot; thành &quot;<ph name="TO_LOCALE"/>&quot; sau khi đồng bộ hóa cài đặt của bạn.</translation>
+<translation id="3368922792935385530">Đã kết nối</translation>
 <translation id="8340999562596018839">Phản hồi nói</translation>
 <translation id="8654520615680304441">Bật Wi-Fi...</translation>
 <translation id="5825747213122829519">Phương thức nhập của bạn đã thay đổi thành <ph name="INPUT_METHOD_ID"/>.
 Nhấn Shift + Alt để chuyển đổi.</translation>
 <translation id="2562916301614567480">Mạng riêng</translation>
 <translation id="6549021752953852991">Không có mạng di động nào</translation>
+<translation id="4379753398862151997">Rất tiếc, hệ thống không hoạt động giữa hai màn hình. (Màn hình đó không được hỗ trợ)</translation>
 <translation id="6426039856985689743">Tắt dữ liệu di động</translation>
 <translation id="3087734570205094154">Bên dưới</translation>
 <translation id="5271016907025319479">Mạng riêng ảo không được định cấu hình.</translation>
-<translation id="1298695107722797780">Kết thúc phiên công khai</translation>
-<translation id="3232695630852378748">Cài đặt bluetooth...</translation>
+<translation id="6803622936009808957">Không thể phản chiếu màn hình do không tìm thấy độ phân giải được hỗ trợ. Thay vào đó, đã chuyển sang chế độ màn hình mở rộng.</translation>
 <translation id="1480041086352807611">Chế độ trình diễn</translation>
 <translation id="3626637461649818317">Còn lại <ph name="PERCENTAGE"/>%</translation>
 <translation id="9089416786594320554">Phương thức nhập</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">Tắt</translation>
 <translation id="4430019312045809116">Âm lượng</translation>
+<translation id="4442424173763614572">Tìm kiếm DNS không thành công</translation>
 <translation id="6356500677799115505">Pin đầy và đang sạc.</translation>
 <translation id="7874779702599364982">Đang tìm kiếm mạng di động...</translation>
+<translation id="583281660410589416">Không biết</translation>
 <translation id="1383876407941801731">Tìm kiếm</translation>
+<translation id="7468789844759750875">Truy cập cổng kích hoạt <ph name="NAME"/> để mua thêm dữ liệu.</translation>
 <translation id="3901991538546252627">Đang kết nối với <ph name="NAME"/></translation>
 <translation id="2204305834655267233">Thông tin mạng</translation>
 <translation id="1621499497873603021">Thời gian còn lại cho đến khi pin hết, <ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">Trình đơn trước</translation>
 <translation id="1346748346194534595">Phải</translation>
 <translation id="8528322925433439945">Di động ...</translation>
+<translation id="7049357003967926684">Liên kết</translation>
 <translation id="8428213095426709021">Cài đặt</translation>
-<translation id="2472320577759310817">Bluetooth tắt.</translation>
 <translation id="2372145515558759244">Đang đồng bộ hóa ứng dụng...</translation>
+<translation id="7256405249507348194">Lỗi không xác định: <ph name="DESC"/></translation>
+<translation id="7925247922861151263">Không thể kiểm tra AAA</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>: Đang ngắt kết nối...</translation>
 <translation id="8456362689280298700"><ph name="HOUR"/>:<ph name="MINUTE"/> cho tới khi pin được sạc đầy</translation>
 <translation id="5787281376604286451">Phản hồi nói được bật.
 Nhấn Ctrl+Alt+Z để tắt.</translation>
 <translation id="4479639480957787382">Ethernet</translation>
+<translation id="6312403991423642364">Lỗi mạng không xác định</translation>
 <translation id="1467432559032391204">Trái</translation>
 <translation id="5543001071567407895">SMS</translation>
+<translation id="2354174487190027830">Kích hoạt <ph name="NAME"/></translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">Phóng to</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>: Đang kết nối...</translation>
+<translation id="8639033665604704195">Không thể xác thực với khóa chia sẻ trước đã cung cấp</translation>
 <translation id="252373100621549798">Màn hình không xác định</translation>
 <translation id="1882897271359938046">Đang phản chiếu tới <ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">Khóa</translation>
 <translation id="2805756323405976993">Ứng dụng</translation>
-<translation id="2482878487686419369">Thông báo</translation>
+<translation id="1512064327686280138">Lỗi kích hoạt</translation>
+<translation id="5097002363526479830">Không thể kết nối với mạng '<ph name="NAME"/>': <ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi đang tắt.</translation>
-<translation id="2872961005593481000">Tắt</translation>
+<translation id="8036518327127111261">Không thể xác thực với chứng chỉ đã cung cấp</translation>
 <translation id="8132793192354020517">Đã kết nối với <ph name="NAME"/></translation>
 <translation id="7052914147756339792">Đặt hình nền...</translation>
-<translation id="2739500853984626550">Hiện không có thiết bị Bluetooth nào</translation>
-<translation id="2666092431469916601">Hàng đầu</translation>
+<translation id="8678698760965522072">Trạng thái trực tuyến</translation>
+<translation id="1119447706177454957">Lỗi nội bộ</translation>
 <translation id="3019353588588144572">Thời gian còn lại cho đến khi pin được sạc đầy, <ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">Phóng to màn hình</translation>
+<translation id="7005812687360380971">Lỗi</translation>
 <translation id="1602076796624386989">Bật dữ liệu di động</translation>
 <translation id="6981982820502123353">Khả năng truy cập</translation>
 <translation id="3157931365184549694">Khôi phục</translation>
+<translation id="4274292172790327596">Lỗi chưa được xác định</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">Đang quét tìm thiết bị...</translation>
 <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY"/>, <ph name="DATE"/></translation>
 <translation id="4448844063988177157">Đang tìm kiếm mạng Wi-Fi...</translation>
+<translation id="7229570126336867161">Cần có EVDO</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> là phiên công khai được quản lý bởi <ph name="DOMAIN"/></translation>
 <translation id="7029814467594812963">Thoát khỏi phiên</translation>
 <translation id="8454013096329229812">Wi-Fi đang bật.</translation>
 <translation id="4872237917498892622">Alt+Search hoặc Shift</translation>
 <translation id="2983818520079887040">Cài đặt...</translation>
-<translation id="5467313780247887226">Không thể sao chép hình ảnh trên màn hình đính kèm. Không tìm thấy độ phân giải phù hợp.</translation>
+<translation id="8927026611342028580">Yêu cầu kết nối</translation>
+<translation id="8300849813060516376">OTASP không thành công</translation>
 <translation id="2792498699870441125">Alt+Search</translation>
 <translation id="8660803626959853127">Đang đồng bộ hóa <ph name="COUNT"/> tệp</translation>
 <translation id="639644700271529076">CAPS LOCK tắt</translation>
-<translation id="4101192585425716296">Trung tâm thông báo</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>: Đang kích hoạt...</translation>
+<translation id="1391854757121130358">Có thể bạn đã sử dụng hết dữ liệu di động được phép.</translation>
 <translation id="4864165860509564259">Vị trí trình khởi chạy</translation>
 <translation id="7593891976182323525">Search hoặc Shift</translation>
 <translation id="7649070708921625228">Trợ giúp</translation>
 <translation id="3050422059534974565">CAPS LOCK đang bật.
 Nhấn Search hoặc Shift để hủy.</translation>
 <translation id="397105322502079400">Đang tính...</translation>
+<translation id="158849752021629804">Cần mạng gia đình</translation>
+<translation id="6857811139397017780">Kích hoạt <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">Không thể tra cứu DHCP</translation>
+<translation id="6692173217867674490">Cụm mật khẩu sai</translation>
 <translation id="6165508094623778733">Tìm hiểu thêm</translation>
+<translation id="9046895021617826162">Kết nối không thành công</translation>
+<translation id="973896785707726617">Phiên này sẽ kết thúc sau <ph name="SESSION_TIME_REMAINING"/>. Bạn sẽ tự động bị đăng xuất.</translation>
+<translation id="8372369524088641025">Khóa WEP sai</translation>
+<translation id="6636709850131805001">Trạng thái không xác định</translation>
 <translation id="3573179567135747900">Thay đổi lại thành &quot;<ph name="FROM_LOCALE"/>&quot; (yêu cầu khởi động lại)</translation>
 <translation id="8103386449138765447">Tin nhắn SMS: <ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Cài đặt Google Drive...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">Không có mạng nào</translation>
 <translation id="5941711191222866238">Thu nhỏ</translation>
 <translation id="6911468394164995108">Tham gia mạng khác...</translation>
-<translation id="6843725295806269523">tắt tiếng</translation>
 <translation id="412065659894267608"><ph name="HOUR"/>g <ph name="MINUTE"/>p cho đến khi đầy</translation>
 <translation id="6359806961507272919">SMS từ <ph name="PHONE_NUMBER"/></translation>
+<translation id="1244147615850840081">Nhà cung cấp</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_zh-CN.xtb b/ash/strings/ash_strings_zh-CN.xtb
index d3d4ac0..65b0c07 100644
--- a/ash/strings/ash_strings_zh-CN.xtb
+++ b/ash/strings/ash_strings_zh-CN.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">电池已充满</translation>
 <translation id="5250713215130379958">自动隐藏启动程序</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> <ph name="MINUTE"/></translation>
+<translation id="7880025619322806991">“门户网站”状态</translation>
 <translation id="30155388420722288">溢出按钮</translation>
 <translation id="5571066253365925590">蓝牙已启用</translation>
 <translation id="9074739597929991885">蓝牙</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">代理...</translation>
 <translation id="938582441709398163">Overlay 键盘</translation>
 <translation id="6979158407327259162">Google 云端硬盘</translation>
+<translation id="6943836128787782965">HTTP 获取请求失败</translation>
 <translation id="2297568595583585744">状态栏</translation>
+<translation id="1661867754829461514">缺少 PIN</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>:正在连接...</translation>
+<translation id="4237016987259239829">网络连接错误</translation>
 <translation id="2946640296642327832">启用蓝牙</translation>
 <translation id="6459472438155181876">正在将屏幕扩展到<ph name="DISPLAY_NAME"/></translation>
 <translation id="8206859287963243715">蜂窝网络设备</translation>
 <translation id="6596816719288285829">IP 地址</translation>
+<translation id="4508265954913339219">激活失败</translation>
 <translation id="1812696562331527143">您的输入法已更改为“<ph name="INPUT_METHOD_ID"/>”*(<ph name="BEGIN_LINK"/>第三方<ph name="END_LINK"/>)。
 按 Shift + Alt 键可切换。</translation>
-<translation id="5233638681132016545">打开新的标签页</translation>
 <translation id="3846575436967432996">没有可用的网络信息</translation>
 <translation id="3026237328237090306">设置移动数据</translation>
 <translation id="785750925697875037">查看移动帐户</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">停用蓝牙</translation>
 <translation id="3126069444801937830">重新启动以进行更新</translation>
 <translation id="735745346212279324">VPN 连接已断开</translation>
+<translation id="7320906967354320621">空闲</translation>
 <translation id="6303423059719347535">电池电量为 <ph name="PERCENTAGE"/>%</translation>
+<translation id="2778346081696727092">无法使用提供的用户名或密码进行身份验证</translation>
 <translation id="3294437725009624529">访客</translation>
 <translation id="8190698733819146287">自定义语言和输入法...</translation>
-<translation id="598295083618286569">蓝牙已连接</translation>
+<translation id="7170041865419449892">超出范围</translation>
+<translation id="4804818685124855865">断开连接</translation>
 <translation id="5222676887888702881">退出</translation>
+<translation id="2688477613306174402">配置</translation>
+<translation id="1272079795634619415">停止</translation>
 <translation id="4957722034734105353">了解详情...</translation>
 <translation id="2964193600955408481">停用 Wi-Fi</translation>
 <translation id="811680302244032017">添加设备...</translation>
 <translation id="2509468283778169019">CAPS LOCK 已打开</translation>
 <translation id="3892641579809465218">内部显示</translation>
 <translation id="7823564328645135659">同步了您的设置后,该语言已由“<ph name="FROM_LOCALE"/>”更改为“<ph name="TO_LOCALE"/>”。</translation>
+<translation id="3368922792935385530">已连接</translation>
 <translation id="8340999562596018839">语音反馈</translation>
 <translation id="8654520615680304441">启用 Wi-Fi...</translation>
 <translation id="5825747213122829519">您的输入法已更改为“<ph name="INPUT_METHOD_ID"/>”。
 按 Shift + Alt 键可进行切换。</translation>
 <translation id="2562916301614567480">专用网</translation>
 <translation id="6549021752953852991">没有可用的蜂窝网络</translation>
+<translation id="4379753398862151997">嗨!显示器,咱们合不来。(系统不支持该显示器)</translation>
 <translation id="6426039856985689743">停用移动数据</translation>
 <translation id="3087734570205094154">底部</translation>
 <translation id="5271016907025319479">未配置 VPN。</translation>
-<translation id="1298695107722797780">终止公共会话</translation>
-<translation id="3232695630852378748">蓝牙设置...</translation>
+<translation id="6803622936009808957">找不到系统支持的分辨率,因此无法镜像显示屏。已改为进入扩展桌面。</translation>
 <translation id="1480041086352807611">演示模式</translation>
 <translation id="3626637461649818317">剩余电量:<ph name="PERCENTAGE"/>%</translation>
 <translation id="9089416786594320554">输入法</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">关闭</translation>
 <translation id="4430019312045809116">音量</translation>
+<translation id="4442424173763614572">DNS 查找失败</translation>
 <translation id="6356500677799115505">电池电量已满并处于充电状态。</translation>
 <translation id="7874779702599364982">正在搜索蜂窝网络...</translation>
+<translation id="583281660410589416">未知</translation>
 <translation id="1383876407941801731">搜索</translation>
+<translation id="7468789844759750875">访问“<ph name="NAME"/>”激活门户网站,购买更多数据。</translation>
 <translation id="3901991538546252627">正在连接:<ph name="NAME"/></translation>
 <translation id="2204305834655267233">网络信息</translation>
 <translation id="1621499497873603021">电池电量将在 <ph name="TIME_LEFT"/>后耗尽</translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">上一菜单</translation>
 <translation id="1346748346194534595">向右</translation>
 <translation id="8528322925433439945">移动...</translation>
+<translation id="7049357003967926684">联盟</translation>
 <translation id="8428213095426709021">设置</translation>
-<translation id="2472320577759310817">蓝牙已关闭。</translation>
 <translation id="2372145515558759244">正在同步应用...</translation>
+<translation id="7256405249507348194">无法识别的错误:<ph name="DESC"/></translation>
+<translation id="7925247922861151263">AAA 检查失败</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>:正在断开连接...</translation>
 <translation id="8456362689280298700">还需 <ph name="HOUR"/>:<ph name="MINUTE"/> 才能充满电</translation>
 <translation id="5787281376604286451">已启用语音反馈。
 按 Ctrl+Alt+Z 停用。</translation>
 <translation id="4479639480957787382">以太网</translation>
+<translation id="6312403991423642364">未知网络错误</translation>
 <translation id="1467432559032391204">向左</translation>
 <translation id="5543001071567407895">短信</translation>
+<translation id="2354174487190027830">正在激活“<ph name="NAME"/>”</translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">最大化</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>:正在连接...</translation>
+<translation id="8639033665604704195">无法使用提供的预共享密钥进行身份验证</translation>
 <translation id="252373100621549798">未知展示广告</translation>
 <translation id="1882897271359938046">正在镜像到<ph name="DISPLAY_NAME"/></translation>
 <translation id="3784455785234192852">锁定</translation>
 <translation id="2805756323405976993">应用</translation>
-<translation id="2482878487686419369">通知</translation>
+<translation id="1512064327686280138">激活失败</translation>
+<translation id="5097002363526479830">无法连接到网络“<ph name="NAME"/>”:<ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi 已关闭。</translation>
-<translation id="2872961005593481000">关闭</translation>
+<translation id="8036518327127111261">无法使用提供的证书进行身份验证</translation>
 <translation id="8132793192354020517">已连接到 <ph name="NAME"/></translation>
 <translation id="7052914147756339792">设置壁纸...</translation>
-<translation id="2739500853984626550">没有可用的蓝牙设备</translation>
-<translation id="2666092431469916601">顶部</translation>
+<translation id="8678698760965522072">“在线”状态</translation>
+<translation id="1119447706177454957">内部错误</translation>
 <translation id="3019353588588144572">电池电量将在 <ph name="TIME_REMAINING"/>后充满</translation>
 <translation id="3473479545200714844">屏幕放大镜</translation>
+<translation id="7005812687360380971">失败</translation>
 <translation id="1602076796624386989">启用移动数据</translation>
 <translation id="6981982820502123353">辅助功能</translation>
 <translation id="3157931365184549694">恢复</translation>
+<translation id="4274292172790327596">未识别的错误</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">正在查找设备...</translation>
 <translation id="5597451508971090205"><ph name="DATE"/><ph name="SHORT_WEEKDAY"/></translation>
 <translation id="4448844063988177157">正在搜索 Wi-Fi 网络...</translation>
+<translation id="7229570126336867161">需要 EVDO</translation>
 <translation id="2999742336789313416">“<ph name="DISPLAY_NAME"/>”是由 <ph name="DOMAIN"/> 管理的公开会话</translation>
 <translation id="7029814467594812963">退出会话</translation>
 <translation id="8454013096329229812">Wi-Fi 已打开。</translation>
 <translation id="4872237917498892622">Alt + 搜索键或 Shift</translation>
 <translation id="2983818520079887040">设置...</translation>
-<translation id="5467313780247887226">找不到匹配的分辨率,无法在连接的显示器上显示相同的图片。</translation>
+<translation id="8927026611342028580">连接请求已发送</translation>
+<translation id="8300849813060516376">OTASP 失败</translation>
 <translation id="2792498699870441125">Alt + 搜索键</translation>
 <translation id="8660803626959853127">正在同步 <ph name="COUNT"/> 个文件</translation>
 <translation id="639644700271529076">CAPS LOCK 已关闭</translation>
-<translation id="4101192585425716296">消息中心</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>:正在激活…</translation>
+<translation id="1391854757121130358">您可能已用尽移动数据配额。</translation>
 <translation id="4864165860509564259">启动器位置</translation>
 <translation id="7593891976182323525">搜索键或 Shift</translation>
 <translation id="7649070708921625228">帮助</translation>
 <translation id="3050422059534974565">CAPS LOCK 已开启。
 按搜索键或 Shift 可取消。</translation>
 <translation id="397105322502079400">正在计算...</translation>
+<translation id="158849752021629804">需要家庭网络</translation>
+<translation id="6857811139397017780">激活 <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">DHCP 查找失败</translation>
+<translation id="6692173217867674490">密码错误</translation>
 <translation id="6165508094623778733">了解详情</translation>
+<translation id="9046895021617826162">连接失败</translation>
+<translation id="973896785707726617">该会话将在 <ph name="SESSION_TIME_REMAINING"/>后结束,到时您将自动退出。</translation>
+<translation id="8372369524088641025">WEP 密钥错误</translation>
+<translation id="6636709850131805001">未知状态</translation>
 <translation id="3573179567135747900">重新更改为“<ph name="FROM_LOCALE"/>”(需要重启)</translation>
 <translation id="8103386449138765447">短信数:<ph name="MESSAGE_COUNT"/> 条</translation>
 <translation id="5045002648206642691">Google 云端硬盘设置...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">未连接任何网络</translation>
 <translation id="5941711191222866238">最小化</translation>
 <translation id="6911468394164995108">连接其他...</translation>
-<translation id="6843725295806269523">静音</translation>
 <translation id="412065659894267608">还需要 <ph name="HOUR"/> 小时 <ph name="MINUTE"/> 分钟才能充满电</translation>
 <translation id="6359806961507272919"><ph name="PHONE_NUMBER"/> 发来的短信</translation>
+<translation id="1244147615850840081">运营商</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/strings/ash_strings_zh-TW.xtb b/ash/strings/ash_strings_zh-TW.xtb
index b9be13b..40d4592 100644
--- a/ash/strings/ash_strings_zh-TW.xtb
+++ b/ash/strings/ash_strings_zh-TW.xtb
@@ -4,6 +4,7 @@
 <translation id="3595596368722241419">電池已充滿</translation>
 <translation id="5250713215130379958">自動隱藏啟動器</translation>
 <translation id="7814236020522506259"><ph name="HOUR"/> 小時 <ph name="MINUTE"/> 分鐘</translation>
+<translation id="7880025619322806991">入口網站狀態</translation>
 <translation id="30155388420722288">溢位按鈕</translation>
 <translation id="5571066253365925590">藍牙已啟用</translation>
 <translation id="9074739597929991885">藍牙</translation>
@@ -15,15 +16,18 @@
 <translation id="5565793151875479467">Proxy...</translation>
 <translation id="938582441709398163">鍵盤自訂快速鍵</translation>
 <translation id="6979158407327259162">Google 雲端硬碟</translation>
+<translation id="6943836128787782965">HTTP 擷取失敗</translation>
 <translation id="2297568595583585744">狀態匣</translation>
+<translation id="1661867754829461514">找不到 PIN</translation>
 <translation id="4508225577814909926"><ph name="NAME"/>:正在連線...</translation>
+<translation id="4237016987259239829">網路連線錯誤</translation>
 <translation id="2946640296642327832">啟用藍牙</translation>
 <translation id="6459472438155181876">正在擴充 <ph name="DISPLAY_NAME"/> 畫面</translation>
 <translation id="8206859287963243715">手機</translation>
 <translation id="6596816719288285829">IP 位址</translation>
+<translation id="4508265954913339219">啟用失敗</translation>
 <translation id="1812696562331527143">您的輸入法已變更為 <ph name="INPUT_METHOD_ID"/>*(<ph name="BEGIN_LINK"/>第三方<ph name="END_LINK"/>)。
 按下 Shift + Alt 鍵即可切換。</translation>
-<translation id="5233638681132016545">新分頁</translation>
 <translation id="3846575436967432996">沒有可用的網路資訊</translation>
 <translation id="3026237328237090306">設定行動數據</translation>
 <translation id="785750925697875037">查看行動帳戶</translation>
@@ -31,37 +35,46 @@
 <translation id="7864539943188674973">停用藍牙</translation>
 <translation id="3126069444801937830">重新啟用即可更新</translation>
 <translation id="735745346212279324">已中斷 VPN 連線</translation>
+<translation id="7320906967354320621">閒置</translation>
 <translation id="6303423059719347535">電池電量為 <ph name="PERCENTAGE"/>%</translation>
+<translation id="2778346081696727092">無法使用您所提供的使用者名稱或密碼進行驗證</translation>
 <translation id="3294437725009624529">訪客</translation>
 <translation id="8190698733819146287">自訂語言與輸入法...</translation>
-<translation id="598295083618286569">已連線至藍牙</translation>
+<translation id="7170041865419449892">超出範圍</translation>
+<translation id="4804818685124855865">中斷連線</translation>
 <translation id="5222676887888702881">登出</translation>
+<translation id="2688477613306174402">設定</translation>
+<translation id="1272079795634619415">停止</translation>
 <translation id="4957722034734105353">瞭解詳情...</translation>
 <translation id="2964193600955408481">停用 WiFi</translation>
 <translation id="811680302244032017">新增裝置...</translation>
 <translation id="2509468283778169019">大寫鍵已啟用</translation>
 <translation id="3892641579809465218">內部畫面</translation>
 <translation id="7823564328645135659">同步處理您的設定後,系統已將語言從「<ph name="FROM_LOCALE"/>」變更為「<ph name="TO_LOCALE"/>」。</translation>
+<translation id="3368922792935385530">已連線</translation>
 <translation id="8340999562596018839">互動朗讀</translation>
 <translation id="8654520615680304441">開啟 Wi-Fi...</translation>
 <translation id="5825747213122829519">您的輸入法已變更為 <ph name="INPUT_METHOD_ID"/>。
 按下 Shift + Alt 鍵即可切換。</translation>
 <translation id="2562916301614567480">私人網路</translation>
 <translation id="6549021752953852991">沒有可用的行動網路</translation>
+<translation id="4379753398862151997">Dear Monitor, it's not working out between us. (系統無法支援該顯示器)</translation>
 <translation id="6426039856985689743">停用行動數據</translation>
 <translation id="3087734570205094154">置底</translation>
 <translation id="5271016907025319479">尚未設定 VPN。</translation>
-<translation id="1298695107722797780">結束公開\n工作階段</translation>
-<translation id="3232695630852378748">藍牙設定...</translation>
+<translation id="6803622936009808957">找不到系統支援的解析度,因此無法顯示鏡像。已改為進入延伸桌面。</translation>
 <translation id="1480041086352807611">示範模式</translation>
 <translation id="3626637461649818317">剩餘電量:<ph name="PERCENTAGE"/>%</translation>
 <translation id="9089416786594320554">輸入法</translation>
 <translation id="6247708409970142803"><ph name="PERCENTAGE"/>%</translation>
 <translation id="1895658205118569222">關閉</translation>
 <translation id="4430019312045809116">音量</translation>
+<translation id="4442424173763614572">DNS 查詢失敗</translation>
 <translation id="6356500677799115505">電池電量已滿 (充電中)。</translation>
 <translation id="7874779702599364982">正在搜尋行動網路...</translation>
+<translation id="583281660410589416">不明</translation>
 <translation id="1383876407941801731">搜尋</translation>
+<translation id="7468789844759750875">造訪 <ph name="NAME"/> 啟用入口網站即可購買更多數據量。</translation>
 <translation id="3901991538546252627">正在連線至:<ph name="NAME"/></translation>
 <translation id="2204305834655267233">網路資訊</translation>
 <translation id="1621499497873603021">電池剩餘使用時間:<ph name="TIME_LEFT"/></translation>
@@ -70,56 +83,75 @@
 <translation id="8308637677604853869">前一個選單</translation>
 <translation id="1346748346194534595">向右</translation>
 <translation id="8528322925433439945">行動服務 ...</translation>
+<translation id="7049357003967926684">關聯</translation>
 <translation id="8428213095426709021">設定</translation>
-<translation id="2472320577759310817">藍牙已關閉。</translation>
 <translation id="2372145515558759244">正在同步處理應用程式...</translation>
+<translation id="7256405249507348194">無法辨識的錯誤:<ph name="DESC"/></translation>
+<translation id="7925247922861151263">AAA 檢查失敗</translation>
 <translation id="3227723743333276085"><ph name="BLUETOOTH"/>:正在中斷連線...</translation>
 <translation id="8456362689280298700">完成充電尚需 <ph name="HOUR"/> 小時 <ph name="MINUTE"/> 分鐘</translation>
 <translation id="5787281376604286451">互動朗讀功能已啟用。
 按下 Ctrl+Alt+Z 鍵即可停用。</translation>
 <translation id="4479639480957787382">乙太網路</translation>
+<translation id="6312403991423642364">不明的網路錯誤</translation>
 <translation id="1467432559032391204">向左</translation>
 <translation id="5543001071567407895">簡訊</translation>
+<translation id="2354174487190027830">正在啟用 <ph name="NAME"/></translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="1398853756734560583">放到最大</translation>
 <translation id="2692809339924654275"><ph name="BLUETOOTH"/>:正在連線...</translation>
+<translation id="8639033665604704195">無法使用您所提供的預先共用金鑰進行驗證</translation>
 <translation id="252373100621549798">顯示器不明</translation>
 <translation id="1882897271359938046">正在建立 <ph name="DISPLAY_NAME"/> 鏡像</translation>
 <translation id="3784455785234192852">鎖定</translation>
 <translation id="2805756323405976993">應用程式</translation>
-<translation id="2482878487686419369">通知</translation>
+<translation id="1512064327686280138">啟用失敗</translation>
+<translation id="5097002363526479830">無法連線至「<ph name="NAME"/>」:<ph name="DETAILS"/></translation>
 <translation id="1850504506766569011">Wi-Fi 已關閉。</translation>
-<translation id="2872961005593481000">關閉</translation>
+<translation id="8036518327127111261">無法使用您所提供的憑證進行驗證</translation>
 <translation id="8132793192354020517">已連線至 <ph name="NAME"/></translation>
 <translation id="7052914147756339792">設定桌布...</translation>
-<translation id="2739500853984626550">找不到藍牙裝置</translation>
-<translation id="2666092431469916601">置頂</translation>
+<translation id="8678698760965522072">線上狀態</translation>
+<translation id="1119447706177454957">內部錯誤</translation>
 <translation id="3019353588588144572">電池剩餘充電時間:<ph name="TIME_REMAINING"/></translation>
 <translation id="3473479545200714844">畫面放大鏡</translation>
+<translation id="7005812687360380971">失敗</translation>
 <translation id="1602076796624386989">啟用行動數據</translation>
 <translation id="6981982820502123353">協助工具</translation>
 <translation id="3157931365184549694">還原</translation>
+<translation id="4274292172790327596">不明錯誤</translation>
 <translation id="4032485810211612751"><ph name="HOURS"/>:<ph name="MINUTES"/>:<ph name="SECONDS"/></translation>
 <translation id="225680501294068881">正在掃描裝置...</translation>
 <translation id="5597451508971090205"><ph name="DATE"/><ph name="SHORT_WEEKDAY"/></translation>
 <translation id="4448844063988177157">正在搜尋 Wi-Fi 網路...</translation>
+<translation id="7229570126336867161">需要 EVDO</translation>
 <translation id="2999742336789313416"><ph name="DISPLAY_NAME"/> 是受 <ph name="DOMAIN"/> 管理的公開工作階段</translation>
 <translation id="7029814467594812963">結束工作階段</translation>
 <translation id="8454013096329229812">Wi-Fi 已開啟。</translation>
 <translation id="4872237917498892622">Alt + 搜尋鍵或 Shift 鍵</translation>
 <translation id="2983818520079887040">設定...</translation>
-<translation id="5467313780247887226">解析度不合,無法在連接的螢幕上顯示相同的圖片。</translation>
+<translation id="8927026611342028580">已要求連線</translation>
+<translation id="8300849813060516376">OTASP 失敗</translation>
 <translation id="2792498699870441125">Alt + 搜尋鍵</translation>
 <translation id="8660803626959853127">正在同步處理 <ph name="COUNT"/> 個檔案</translation>
 <translation id="639644700271529076">大寫鍵已關閉</translation>
-<translation id="4101192585425716296">郵件中心</translation>
+<translation id="6267036997247669271"><ph name="NAME"/>:正在啟用...</translation>
+<translation id="1391854757121130358">您可能已用盡行動數據配額。</translation>
 <translation id="4864165860509564259">啟動器位置</translation>
 <translation id="7593891976182323525">搜尋鍵或 Shift 鍵</translation>
 <translation id="7649070708921625228">說明</translation>
 <translation id="3050422059534974565">大寫鍵已啟用。
 按下搜尋鍵或 Shift 鍵即可取消。</translation>
 <translation id="397105322502079400">計算中…</translation>
+<translation id="158849752021629804">需要家用網路</translation>
+<translation id="6857811139397017780">啟用 <ph name="NETWORKSERVICE"/></translation>
+<translation id="5864471791310927901">DHCP 查閱失敗</translation>
+<translation id="6692173217867674490">通關密語有誤</translation>
 <translation id="6165508094623778733">瞭解詳情</translation>
+<translation id="9046895021617826162">連線失敗</translation>
+<translation id="973896785707726617">這個工作階段將在 <ph name="SESSION_TIME_REMAINING"/>後結束,系統會自動將您登出。</translation>
+<translation id="8372369524088641025">WEP 金鑰有誤</translation>
+<translation id="6636709850131805001">不明狀態</translation>
 <translation id="3573179567135747900">改回「<ph name="FROM_LOCALE"/>」(需要重新啟動)</translation>
 <translation id="8103386449138765447">簡訊數:<ph name="MESSAGE_COUNT"/></translation>
 <translation id="5045002648206642691">Google 雲端硬碟設定...</translation>
@@ -130,7 +162,7 @@
 <translation id="8000066093800657092">沒有網路</translation>
 <translation id="5941711191222866238">縮到最小</translation>
 <translation id="6911468394164995108">加入其他網路...</translation>
-<translation id="6843725295806269523">忽略的項目</translation>
 <translation id="412065659894267608">尚需 <ph name="HOUR"/> 小時 <ph name="MINUTE"/> 分鐘才能充滿電</translation>
 <translation id="6359806961507272919">來自 <ph name="PHONE_NUMBER"/> 的簡訊</translation>
+<translation id="1244147615850840081">通訊業者</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ash/system/audio/tray_volume.cc b/ash/system/audio/tray_volume.cc
deleted file mode 100644
index ff9c979..0000000
--- a/ash/system/audio/tray_volume.cc
+++ /dev/null
@@ -1,288 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/system/audio/tray_volume.h"
-
-#include <cmath>
-
-#include "ash/ash_constants.h"
-#include "ash/shell.h"
-#include "ash/system/tray/system_tray_delegate.h"
-#include "ash/system/tray/system_tray_notifier.h"
-#include "ash/system/tray/tray_bar_button_with_title.h"
-#include "ash/system/tray/tray_constants.h"
-#include "ash/volume_control_delegate.h"
-#include "base/utf_string_conversions.h"
-#include "grit/ash_resources.h"
-#include "grit/ash_strings.h"
-#include "third_party/skia/include/core/SkCanvas.h"
-#include "third_party/skia/include/core/SkPaint.h"
-#include "third_party/skia/include/core/SkRect.h"
-#include "third_party/skia/include/effects/SkGradientShader.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/gfx/canvas.h"
-#include "ui/gfx/image/image.h"
-#include "ui/gfx/image/image_skia_operations.h"
-#include "ui/views/controls/button/image_button.h"
-#include "ui/views/controls/image_view.h"
-#include "ui/views/controls/label.h"
-#include "ui/views/controls/slider.h"
-#include "ui/views/layout/box_layout.h"
-#include "ui/views/view.h"
-
-namespace ash {
-namespace internal {
-
-namespace {
-const int kVolumeImageWidth = 25;
-const int kVolumeImageHeight = 25;
-
-// IDR_AURA_UBER_TRAY_VOLUME_LEVELS contains 5 images,
-// The one for mute is at the 0 index and the other
-// four are used for ascending volume levels.
-const int kVolumeLevels = 4;
-
-bool IsAudioMuted() {
-  return Shell::GetInstance()->system_tray_delegate()->
-      GetVolumeControlDelegate()->IsAudioMuted();
-}
-
-float GetVolumeLevel() {
-  return Shell::GetInstance()->system_tray_delegate()->
-      GetVolumeControlDelegate()->GetVolumeLevel();
-}
-
-}  // namespace
-
-namespace tray {
-
-class VolumeButton : public views::ToggleImageButton {
- public:
-  explicit VolumeButton(views::ButtonListener* listener)
-      : views::ToggleImageButton(listener),
-        image_index_(-1) {
-    SetImageAlignment(ALIGN_CENTER, ALIGN_MIDDLE);
-    image_ = ui::ResourceBundle::GetSharedInstance().GetImageNamed(
-        IDR_AURA_UBER_TRAY_VOLUME_LEVELS);
-    SetPreferredSize(gfx::Size(kTrayPopupItemHeight, kTrayPopupItemHeight));
-    Update();
-  }
-
-  virtual ~VolumeButton() {}
-
-  void Update() {
-    float level = GetVolumeLevel();
-    int image_index = IsAudioMuted() ?
-        0 : (level == 1.0 ?
-             kVolumeLevels :
-             std::max(1, int(std::ceil(level * (kVolumeLevels - 1)))));
-    if (image_index != image_index_) {
-      gfx::Rect region(0, image_index * kVolumeImageHeight,
-                       kVolumeImageWidth, kVolumeImageHeight);
-      gfx::ImageSkia image_skia = gfx::ImageSkiaOperations::ExtractSubset(
-          *(image_.ToImageSkia()), region);
-      SetImage(views::CustomButton::STATE_NORMAL, &image_skia);
-      image_index_ = image_index;
-    }
-    SchedulePaint();
-  }
-
- private:
-  // Overridden from views::View.
-  virtual gfx::Size GetPreferredSize() OVERRIDE {
-    gfx::Size size = views::ToggleImageButton::GetPreferredSize();
-    size.set_height(kTrayPopupItemHeight);
-    return size;
-  }
-
-  gfx::Image image_;
-  int image_index_;
-
-  DISALLOW_COPY_AND_ASSIGN(VolumeButton);
-};
-
-class MuteButton : public TrayBarButtonWithTitle {
- public:
-  explicit MuteButton(views::ButtonListener* listener)
-      : TrayBarButtonWithTitle(listener,
-                               -1,    // no title under mute button
-                               kTrayBarButtonWidth) {
-    Update();
-  }
-  virtual ~MuteButton() {}
-
-  void Update() {
-    UpdateButton(IsAudioMuted());
-    SchedulePaint();
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MuteButton);
-};
-
-class VolumeSlider : public views::Slider {
- public:
-  explicit VolumeSlider(views::SliderListener* listener)
-      : views::Slider(listener, views::Slider::HORIZONTAL) {
-    set_focus_border_color(kFocusBorderColor);
-    SetValue(GetVolumeLevel());
-    SetAccessibleName(
-            ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
-                IDS_ASH_STATUS_TRAY_VOLUME));
-    Update();
-  }
-  virtual ~VolumeSlider() {}
-
-  void Update() {
-    UpdateState(!IsAudioMuted());
-  }
-
-  DISALLOW_COPY_AND_ASSIGN(VolumeSlider);
-};
-
-class VolumeView : public views::View,
-                   public views::ButtonListener,
-                   public views::SliderListener {
- public:
-  VolumeView() {
-    SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal,
-          kTrayPopupPaddingHorizontal, 0, kTrayPopupPaddingBetweenItems));
-
-    icon_ = new VolumeButton(this);
-    AddChildView(icon_);
-
-    mute_ = new MuteButton(this);
-    AddChildView(mute_);
-
-    slider_ = new VolumeSlider(this);
-    AddChildView(slider_);
-  }
-
-  virtual ~VolumeView() {}
-
-  void Update() {
-    icon_->Update();
-    mute_->Update();
-    slider_->Update();
-  }
-
-  void SetVolumeLevel(float percent) {
-    // The change in volume will be reflected via accessibility system events,
-    // so we prevent the UI event from being sent here.
-    slider_->set_enable_accessibility_events(false);
-    slider_->SetValue(percent);
-    // It is possible that the volume was (un)muted, but the actual volume level
-    // did not change. In that case, setting the value of the slider won't
-    // trigger an update. So explicitly trigger an update.
-    Update();
-    slider_->set_enable_accessibility_events(true);
-  }
-
- private:
-  // Overridden from views::View.
-  virtual void OnBoundsChanged(const gfx::Rect& old_bounds) OVERRIDE {
-    int w = width() - slider_->x();
-    slider_->SetSize(gfx::Size(w, slider_->height()));
-  }
-
-  // Overridden from views::ButtonListener.
-  virtual void ButtonPressed(views::Button* sender,
-                             const ui::Event& event) OVERRIDE {
-    CHECK(sender == icon_ || sender == mute_);
-    ash::Shell::GetInstance()->system_tray_delegate()->
-        GetVolumeControlDelegate()->SetAudioMuted(!IsAudioMuted());
-  }
-
-  // Overridden from views:SliderListener.
-  virtual void SliderValueChanged(views::Slider* sender,
-                                  float value,
-                                  float old_value,
-                                  views::SliderChangeReason reason) OVERRIDE {
-    if (reason == views::VALUE_CHANGED_BY_USER) {
-      ash::Shell::GetInstance()->system_tray_delegate()->
-          GetVolumeControlDelegate()->SetVolumeLevel(value);
-    }
-    icon_->Update();
-  }
-
-  VolumeButton* icon_;
-  MuteButton* mute_;
-  VolumeSlider* slider_;
-
-  DISALLOW_COPY_AND_ASSIGN(VolumeView);
-};
-
-}  // namespace tray
-
-TrayVolume::TrayVolume(SystemTray* system_tray)
-    : TrayImageItem(system_tray, IDR_AURA_UBER_TRAY_VOLUME_MUTE),
-      volume_view_(NULL),
-      is_default_view_(false) {
-  Shell::GetInstance()->system_tray_notifier()->AddAudioObserver(this);
-}
-
-TrayVolume::~TrayVolume() {
-  Shell::GetInstance()->system_tray_notifier()->RemoveAudioObserver(this);
-}
-
-bool TrayVolume::GetInitialVisibility() {
-  return IsAudioMuted();
-}
-
-views::View* TrayVolume::CreateDefaultView(user::LoginStatus status) {
-  volume_view_ = new tray::VolumeView;
-  is_default_view_ = true;
-  return volume_view_;
-}
-
-views::View* TrayVolume::CreateDetailedView(user::LoginStatus status) {
-  volume_view_ = new tray::VolumeView;
-  is_default_view_ = false;
-  return volume_view_;
-}
-
-void TrayVolume::DestroyDefaultView() {
-  if (is_default_view_)
-    volume_view_ = NULL;
-}
-
-void TrayVolume::DestroyDetailedView() {
-  if (!is_default_view_)
-    volume_view_ = NULL;
-}
-
-bool TrayVolume::ShouldHideArrow() const {
-  return true;
-}
-
-bool TrayVolume::ShouldShowLauncher() const {
-  return false;
-}
-
-void TrayVolume::OnVolumeChanged(float percent) {
-  if (tray_view())
-    tray_view()->SetVisible(GetInitialVisibility());
-
-  if (volume_view_) {
-    if (IsAudioMuted())
-      percent = 0.0;
-    volume_view_->SetVolumeLevel(percent);
-    SetDetailedViewCloseDelay(kTrayPopupAutoCloseDelayInSeconds);
-    return;
-  }
-  PopupDetailedView(kTrayPopupAutoCloseDelayInSeconds, false);
-}
-
-void TrayVolume::OnMuteToggled() {
-  if (tray_view())
-      tray_view()->SetVisible(GetInitialVisibility());
-
-  if (volume_view_)
-    volume_view_->Update();
-  else
-    PopupDetailedView(kTrayPopupAutoCloseDelayInSeconds, false);
-}
-
-}  // namespace internal
-}  // namespace ash
diff --git a/ash/system/audio/tray_volume.h b/ash/system/audio/tray_volume.h
deleted file mode 100644
index ec04943..0000000
--- a/ash/system/audio/tray_volume.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ASH_SYSTEM_AUDIO_TRAY_VOLUME_H_
-#define ASH_SYSTEM_AUDIO_TRAY_VOLUME_H_
-
-#include "ash/system/audio/audio_observer.h"
-#include "ash/system/tray/tray_image_item.h"
-
-namespace ash {
-namespace internal {
-
-namespace tray {
-class VolumeView;
-}
-
-class TrayVolume : public TrayImageItem,
-                   public AudioObserver {
- public:
-  explicit TrayVolume(SystemTray* system_tray);
-  virtual ~TrayVolume();
-
- private:
-  // Overridden from TrayImageItem.
-  virtual bool GetInitialVisibility() OVERRIDE;
-
-  // Overridden from SystemTrayItem.
-  virtual views::View* CreateDefaultView(user::LoginStatus status) OVERRIDE;
-  virtual views::View* CreateDetailedView(user::LoginStatus status) OVERRIDE;
-  virtual void DestroyDefaultView() OVERRIDE;
-  virtual void DestroyDetailedView() OVERRIDE;
-  virtual bool ShouldHideArrow() const OVERRIDE;
-  virtual bool ShouldShowLauncher() const OVERRIDE;
-
-  // Overridden from AudioObserver.
-  virtual void OnVolumeChanged(float percent) OVERRIDE;
-  virtual void OnMuteToggled() OVERRIDE;
-
-  tray::VolumeView* volume_view_;
-
-  // Was |volume_view_| created for CreateDefaultView() rather than
-  // CreateDetailedView()?  Used to avoid resetting |volume_view_|
-  // inappropriately in DestroyDefaultView() or DestroyDetailedView().
-  bool is_default_view_;
-
-  DISALLOW_COPY_AND_ASSIGN(TrayVolume);
-};
-
-}  // namespace internal
-}  // namespace ash
-
-#endif  // ASH_SYSTEM_AUDIO_TRAY_VOLUME_H_
diff --git a/ash/system/bluetooth/tray_bluetooth.cc b/ash/system/bluetooth/tray_bluetooth.cc
index 16a8001..2b7eb56 100644
--- a/ash/system/bluetooth/tray_bluetooth.cc
+++ b/ash/system/bluetooth/tray_bluetooth.cc
@@ -14,6 +14,7 @@
 #include "ash/system/tray/tray_constants.h"
 #include "ash/system/tray/tray_details_view.h"
 #include "ash/system/tray/tray_item_more.h"
+#include "ash/system/tray/tray_popup_header_button.h"
 #include "grit/ash_resources.h"
 #include "grit/ash_strings.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -48,7 +49,7 @@
         ash::Shell::GetInstance()->system_tray_delegate();
     if (delegate->GetBluetoothAvailable()) {
       ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
-      const string16 label =
+      const base::string16 label =
           rb.GetLocalizedString(delegate->GetBluetoothEnabled() ?
               IDS_ASH_STATUS_TRAY_BLUETOOTH_ENABLED :
               IDS_ASH_STATUS_TRAY_BLUETOOTH_DISABLED);
@@ -106,12 +107,13 @@
         ash::Shell::GetInstance()->system_tray_delegate();
     bool bluetooth_enabled = delegate->GetBluetoothEnabled();
     if (!bluetooth_discovering_ && bluetooth_enabled) {
+      bluetooth_discovering_ = true;
       delegate->BluetoothStartDiscovering();
       throbber_->Start();
     } else if(!bluetooth_enabled) {
+      bluetooth_discovering_ = false;
       throbber_->Stop();
     }
-    bluetooth_discovering_ = bluetooth_enabled;
   }
 
   void BluetoothStopDiscovering() {
@@ -126,18 +128,24 @@
 
   void UpdateBlueToothDeviceList() {
     connected_devices_.clear();
+    connecting_devices_.clear();
     paired_not_connected_devices_.clear();
     discovered_not_paired_devices_.clear();
     BluetoothDeviceList list;
     Shell::GetInstance()->system_tray_delegate()->
         GetAvailableBluetoothDevices(&list);
     for (size_t i = 0; i < list.size(); ++i) {
-      if (list[i].connected)
+      if (list[i].connecting) {
+        list[i].display_name = l10n_util::GetStringFUTF16(
+            IDS_ASH_STATUS_TRAY_BLUETOOTH_CONNECTING, list[i].display_name);
+        connecting_devices_.push_back(list[i]);
+      } else if (list[i].connected) {
         connected_devices_.push_back(list[i]);
-      else if (list[i].paired)
+      } else if (list[i].paired) {
         paired_not_connected_devices_.push_back(list[i]);
-      else if (list[i].visible)
+      } else {
         discovered_not_paired_devices_.push_back(list[i]);
+      }
     }
   }
 
@@ -197,6 +205,8 @@
     AppendSameTypeDevicesToScrollList(
         connected_devices_, true, true, bluetooth_enabled);
     AppendSameTypeDevicesToScrollList(
+        connecting_devices_, true, false, bluetooth_enabled);
+    AppendSameTypeDevicesToScrollList(
         paired_not_connected_devices_, false, false, bluetooth_enabled);
     if (discovered_not_paired_devices_.size() > 0)
       AddScrollSeparator();
@@ -230,7 +240,7 @@
     }
   }
 
-  HoverHighlightView* AddScrollListItem(const string16& text,
+  HoverHighlightView* AddScrollListItem(const base::string16& text,
                                         gfx::Font::FontStyle style,
                                         bool checked,
                                         bool enabled) {
@@ -262,13 +272,15 @@
   }
 
   // Returns true if the device with |device_id| is found in |device_list|,
-  // and the display_name of the device will be returned in |display_name|.
+  // and the display_name of the device will be returned in |display_name| if
+  // it's not NULL.
   bool FoundDevice(const std::string& device_id,
                    const BluetoothDeviceList& device_list,
-                   string16* display_name) {
+                   base::string16* display_name) {
     for (size_t i = 0; i < device_list.size(); ++i) {
       if (device_list[i].address == device_id) {
-        *display_name = device_list[i].display_name;
+        if (display_name)
+          *display_name = device_list[i].display_name;
         return true;
       }
     }
@@ -278,16 +290,12 @@
   // Updates UI of the clicked bluetooth device to show it is being connected
   // or disconnected if such an operation is going to be performed underway.
   void UpdateClickedDevice(std::string device_id, views::View* item_container) {
-    string16 display_name;
-    if (FoundDevice(device_id, connected_devices_, &display_name)) {
-      display_name = l10n_util::GetStringFUTF16(
-          IDS_ASH_STATUS_TRAY_BLUETOOTH_DISCONNECTING, display_name);
-    } else if (FoundDevice(device_id, paired_not_connected_devices_,
+    base::string16 display_name;
+    if (FoundDevice(device_id, paired_not_connected_devices_,
                            &display_name)) {
       display_name = l10n_util::GetStringFUTF16(
           IDS_ASH_STATUS_TRAY_BLUETOOTH_CONNECTING, display_name);
-    }
-    if (display_name.length() > 0) {
+
       item_container->RemoveAllChildViews(true);
       static_cast<HoverHighlightView*>(item_container)->
           AddCheckableLabel(display_name, gfx::Font::BOLD, false);
@@ -309,13 +317,17 @@
     } else if (sender == enable_bluetooth_) {
       delegate->ToggleBluetooth();
     } else {
+      if (!delegate->GetBluetoothEnabled())
+        return;
       std::map<views::View*, std::string>::iterator find;
       find = device_map_.find(sender);
-      if (find != device_map_.end()) {
-        std::string device_id = find->second;
-        UpdateClickedDevice(device_id, sender);
-        delegate->ToggleBluetoothConnection(device_id);
-      }
+      if (find == device_map_.end())
+        return;
+      std::string device_id = find->second;
+      if (FoundDevice(device_id, connecting_devices_, NULL))
+        return;
+      UpdateClickedDevice(device_id, sender);
+      delegate->ConnectToBluetoothDevice(device_id);
     }
   }
 
@@ -338,6 +350,7 @@
   TrayPopupHeaderButton* toggle_bluetooth_;
   HoverHighlightView* enable_bluetooth_;
   BluetoothDeviceList connected_devices_;
+  BluetoothDeviceList connecting_devices_;
   BluetoothDeviceList paired_not_connected_devices_;
   BluetoothDeviceList discovered_not_paired_devices_;
   bool bluetooth_discovering_;
diff --git a/ash/system/brightness/tray_brightness.cc b/ash/system/brightness/tray_brightness.cc
index 12fad9f..9ad54e7 100644
--- a/ash/system/brightness/tray_brightness.cc
+++ b/ash/system/brightness/tray_brightness.cc
@@ -12,7 +12,6 @@
 #include "ash/system/tray/system_tray_delegate.h"
 #include "ash/system/tray/system_tray_notifier.h"
 #include "ash/system/tray/tray_constants.h"
-#include "ash/system/tray/tray_views.h"
 #include "base/bind.h"
 #include "base/message_loop.h"
 #include "base/utf_string_conversions.h"
@@ -134,7 +133,7 @@
       got_current_percent_(false) {
   // Post a task to get the initial brightness; the BrightnessControlDelegate
   // isn't created yet.
-  MessageLoopForUI::current()->PostTask(
+  base::MessageLoopForUI::current()->PostTask(
       FROM_HERE,
       base::Bind(&TrayBrightness::GetInitialBrightness,
                  weak_ptr_factory_.GetWeakPtr()));
diff --git a/ash/system/audio/audio_observer.h b/ash/system/chromeos/audio/audio_observer.h
similarity index 61%
rename from ash/system/audio/audio_observer.h
rename to ash/system/chromeos/audio/audio_observer.h
index d0ff405..0c3f5d7 100644
--- a/ash/system/audio/audio_observer.h
+++ b/ash/system/chromeos/audio/audio_observer.h
@@ -2,13 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ASH_SYSTEM_AUDIO_AUDIO_OBSERVER_H_
-#define ASH_SYSTEM_AUDIO_AUDIO_OBSERVER_H_
+#ifndef ASH_SYSTEM_CHROMEOS_AUDIO_AUDIO_OBSERVER_H_
+#define ASH_SYSTEM_CHROMEOS_AUDIO_AUDIO_OBSERVER_H_
 
 #include "ash/ash_export.h"
 
 namespace ash {
 
+// TODO(jennyz): crbug.com/233310. Remove this file when new audio handler
+// stabilized.
 class ASH_EXPORT AudioObserver {
  public:
   virtual ~AudioObserver() {}
@@ -19,4 +21,4 @@
 
 }  // namespace ash
 
-#endif  //ASH_SYSTEM_AUDIO_AUDIO_OBSERVER_H_
+#endif  //ASH_SYSTEM_CHROMEOS_AUDIO_AUDIO_OBSERVER_H_
diff --git a/ash/system/chromeos/audio/tray_audio.cc b/ash/system/chromeos/audio/tray_audio.cc
new file mode 100644
index 0000000..246b082
--- /dev/null
+++ b/ash/system/chromeos/audio/tray_audio.cc
@@ -0,0 +1,619 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/system/chromeos/audio/tray_audio.h"
+
+#include <cmath>
+
+#include "ash/ash_constants.h"
+#include "ash/ash_switches.h"
+#include "ash/shell.h"
+#include "ash/system/tray/actionable_view.h"
+#include "ash/system/tray/fixed_sized_scroll_view.h"
+#include "ash/system/tray/hover_highlight_view.h"
+#include "ash/system/tray/system_tray.h"
+#include "ash/system/tray/system_tray_delegate.h"
+#include "ash/system/tray/system_tray_notifier.h"
+#include "ash/system/tray/tray_constants.h"
+#include "ash/volume_control_delegate.h"
+#include "base/command_line.h"
+#include "base/utf_string_conversions.h"
+#include "chromeos/audio/cras_audio_handler.h"
+#include "grit/ash_resources.h"
+#include "grit/ash_strings.h"
+#include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/core/SkPaint.h"
+#include "third_party/skia/include/core/SkRect.h"
+#include "third_party/skia/include/effects/SkGradientShader.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/gfx/canvas.h"
+#include "ui/gfx/image/image.h"
+#include "ui/gfx/image/image_skia_operations.h"
+#include "ui/views/controls/button/image_button.h"
+#include "ui/views/controls/image_view.h"
+#include "ui/views/controls/label.h"
+#include "ui/views/controls/slider.h"
+#include "ui/views/layout/box_layout.h"
+#include "ui/views/view.h"
+
+namespace ash {
+namespace internal {
+
+namespace {
+const int kVolumeImageWidth = 25;
+const int kVolumeImageHeight = 25;
+const int kBarSeparatorWidth = 25;
+const int kBarSeparatorHeight = 30;
+const int kSliderRightPaddingToVolumeViewEdge = 17;
+const int kExtraPaddingBetweenBarAndMore = 10;
+
+const int kNoAudioDeviceIcon = -1;
+
+// IDR_AURA_UBER_TRAY_VOLUME_LEVELS contains 5 images,
+// The one for mute is at the 0 index and the other
+// four are used for ascending volume levels.
+const int kVolumeLevels = 4;
+
+bool UseNewAudioHandler() {
+  return !CommandLine::ForCurrentProcess()->
+      HasSwitch(ash::switches::kAshDisableNewAudioHandler);
+}
+
+// Returns true if we should show the audio device switching UI.
+bool ShowAudioDeviceMenu() {
+  return UseNewAudioHandler() &&
+      CommandLine::ForCurrentProcess()->
+          HasSwitch(ash::switches::kAshEnableAudioDeviceMenu);
+}
+
+bool IsAudioMuted() {
+  if(UseNewAudioHandler()) {
+    return chromeos::CrasAudioHandler::Get()->IsOutputMuted();
+  } else {
+    return Shell::GetInstance()->system_tray_delegate()->
+        GetVolumeControlDelegate()->IsAudioMuted();
+  }
+}
+
+float GetVolumeLevel() {
+  if (UseNewAudioHandler()) {
+    return chromeos::CrasAudioHandler::Get()->GetOutputVolumePercent() / 100.0f;
+  } else {
+    return Shell::GetInstance()->system_tray_delegate()->
+        GetVolumeControlDelegate()->GetVolumeLevel();
+  }
+}
+
+int GetAudioDeviceIconId(chromeos::AudioDeviceType type) {
+  if (type == chromeos::AUDIO_TYPE_HEADPHONE)
+    return IDR_AURA_UBER_TRAY_AUDIO_HEADPHONE;
+  else if (type == chromeos::AUDIO_TYPE_USB)
+    return IDR_AURA_UBER_TRAY_AUDIO_USB;
+  else if (type == chromeos::AUDIO_TYPE_BLUETOOTH)
+    return IDR_AURA_UBER_TRAY_AUDIO_BLUETOOTH;
+  else if (type == chromeos::AUDIO_TYPE_HDMI)
+    return IDR_AURA_UBER_TRAY_AUDIO_HDMI;
+  else
+    return kNoAudioDeviceIcon;
+}
+
+}  // namespace
+
+namespace tray {
+
+class VolumeButton : public views::ToggleImageButton {
+ public:
+  explicit VolumeButton(views::ButtonListener* listener)
+      : views::ToggleImageButton(listener),
+        image_index_(-1) {
+    SetImageAlignment(ALIGN_CENTER, ALIGN_MIDDLE);
+    image_ = ui::ResourceBundle::GetSharedInstance().GetImageNamed(
+        IDR_AURA_UBER_TRAY_VOLUME_LEVELS);
+    SetPreferredSize(gfx::Size(kTrayPopupItemHeight, kTrayPopupItemHeight));
+    Update();
+  }
+
+  virtual ~VolumeButton() {}
+
+  void Update() {
+    float level = GetVolumeLevel();
+    int image_index = IsAudioMuted() ?
+        0 : (level == 1.0 ?
+             kVolumeLevels :
+             std::max(1, int(std::ceil(level * (kVolumeLevels - 1)))));
+    if (image_index != image_index_) {
+      gfx::Rect region(0, image_index * kVolumeImageHeight,
+                       kVolumeImageWidth, kVolumeImageHeight);
+      gfx::ImageSkia image_skia = gfx::ImageSkiaOperations::ExtractSubset(
+          *(image_.ToImageSkia()), region);
+      SetImage(views::CustomButton::STATE_NORMAL, &image_skia);
+      image_index_ = image_index;
+    }
+    SchedulePaint();
+  }
+
+ private:
+  // Overridden from views::View.
+  virtual gfx::Size GetPreferredSize() OVERRIDE {
+    gfx::Size size = views::ToggleImageButton::GetPreferredSize();
+    size.set_height(kTrayPopupItemHeight);
+    return size;
+  }
+
+  gfx::Image image_;
+  int image_index_;
+
+  DISALLOW_COPY_AND_ASSIGN(VolumeButton);
+};
+
+class VolumeSlider : public views::Slider {
+ public:
+  explicit VolumeSlider(views::SliderListener* listener)
+      : views::Slider(listener, views::Slider::HORIZONTAL) {
+    set_focus_border_color(kFocusBorderColor);
+    SetValue(GetVolumeLevel());
+    SetAccessibleName(
+            ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
+                IDS_ASH_STATUS_TRAY_VOLUME));
+    Update();
+  }
+  virtual ~VolumeSlider() {}
+
+  void Update() {
+    UpdateState(!IsAudioMuted());
+  }
+
+  DISALLOW_COPY_AND_ASSIGN(VolumeSlider);
+};
+
+// Vertical bar separator that can be placed on the VolumeView.
+class BarSeparator : public views::View {
+ public:
+  BarSeparator() {}
+  virtual ~BarSeparator() {}
+
+ private:
+  // Overriden from views::View.
+  virtual gfx::Size GetPreferredSize() OVERRIDE {
+    return gfx::Size(kBarSeparatorWidth, kBarSeparatorHeight);
+  }
+
+  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
+    canvas->FillRect(gfx::Rect(width() / 2, 0, 1, height()),
+                     kButtonStrokeColor);
+  }
+
+  DISALLOW_COPY_AND_ASSIGN(BarSeparator);
+};
+
+class VolumeView : public ActionableView,
+                   public views::ButtonListener,
+                   public views::SliderListener {
+ public:
+  VolumeView(SystemTrayItem* owner, bool is_default_view)
+      : owner_(owner),
+        icon_(NULL),
+        slider_(NULL),
+        bar_(NULL),
+        device_type_(NULL),
+        more_(NULL),
+        is_default_view_(is_default_view) {
+    SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal,
+          kTrayPopupPaddingHorizontal, 0, kTrayPopupPaddingBetweenItems));
+
+    icon_ = new VolumeButton(this);
+    AddChildView(icon_);
+
+    slider_ = new VolumeSlider(this);
+    AddChildView(slider_);
+
+    device_type_ = new views::ImageView;
+    AddChildView(device_type_);
+
+    bar_ = new BarSeparator;
+    AddChildView(bar_);
+
+    more_ = new views::ImageView;
+    more_->EnableCanvasFlippingForRTLUI(true);
+    more_->SetImage(ui::ResourceBundle::GetSharedInstance().GetImageNamed(
+        IDR_AURA_UBER_TRAY_MORE).ToImageSkia());
+    AddChildView(more_);
+
+    Update();
+  }
+
+  virtual ~VolumeView() {}
+
+  void Update() {
+    icon_->Update();
+    slider_->Update();
+    UpdateDeviceTypeAndMore();
+    Layout();
+  }
+
+  void SetVolumeLevel(float percent) {
+    // The change in volume will be reflected via accessibility system events,
+    // so we prevent the UI event from being sent here.
+    slider_->set_enable_accessibility_events(false);
+    slider_->SetValue(percent);
+    // It is possible that the volume was (un)muted, but the actual volume level
+    // did not change. In that case, setting the value of the slider won't
+    // trigger an update. So explicitly trigger an update.
+    Update();
+    slider_->set_enable_accessibility_events(true);
+  }
+
+ private:
+  // Updates bar_, device_type_ icon, and more_ buttons.
+  void UpdateDeviceTypeAndMore() {
+    if (!ShowAudioDeviceMenu() || !is_default_view_) {
+      more_->SetVisible(false);
+      bar_->SetVisible(false);
+      device_type_->SetVisible(false);
+      return;
+    }
+
+    chromeos::CrasAudioHandler* audio_handler =
+        chromeos::CrasAudioHandler::Get();
+    bool show_more = audio_handler->has_alternative_output() ||
+                     audio_handler->has_alternative_input();
+    more_->SetVisible(show_more);
+
+    // Show output device icon if necessary.
+    chromeos::AudioDevice device;
+    audio_handler->GetActiveOutputDevice(&device);
+    int device_icon = GetAudioDeviceIconId(device.type);
+    if (device_icon != kNoAudioDeviceIcon) {
+      device_type_->SetVisible(true);
+      device_type_->SetImage(
+          ui::ResourceBundle::GetSharedInstance().GetImageNamed(
+              device_icon).ToImageSkia());
+      bar_->SetVisible(false);
+    } else {
+      device_type_->SetVisible(false);
+      bar_->SetVisible(show_more);
+    }
+  }
+
+  // Overridden from views::View.
+  virtual void Layout() OVERRIDE {
+    views::View::Layout();
+
+    if (!more_->visible()) {
+      int w = width() - slider_->bounds().x() -
+              kSliderRightPaddingToVolumeViewEdge;
+      slider_->SetSize(gfx::Size(w, slider_->height()));
+      return;
+    }
+
+    // Make sure the chevron always has the full size.
+    gfx::Size size = more_->GetPreferredSize();
+    gfx::Rect bounds(size);
+    bounds.set_x(width() - size.width() - kTrayPopupPaddingBetweenItems);
+    bounds.set_y((height() - size.height()) / 2);
+    more_->SetBoundsRect(bounds);
+
+    // Layout bar_ or device_type_ at the left of the more_ button.
+    views::View* view_left_to_more;
+    if (bar_->visible())
+      view_left_to_more = bar_;
+    else
+      view_left_to_more = device_type_;
+    gfx::Size bar_size = view_left_to_more->GetPreferredSize();
+    gfx::Rect bar_bounds(bar_size);
+    bar_bounds.set_x(more_->bounds().x() - bar_size.width() -
+                     kExtraPaddingBetweenBarAndMore);
+    bar_bounds.set_y((height() - bar_size.height()) / 2);
+    view_left_to_more->SetBoundsRect(bar_bounds);
+
+
+    // Layout slider, calculate slider width.
+    gfx::Rect slider_bounds = slider_->bounds();
+    slider_bounds.set_width(
+        view_left_to_more->bounds().x() - kTrayPopupPaddingBetweenItems
+        - slider_bounds.x());
+    slider_->SetBoundsRect(slider_bounds);
+  }
+
+  // Overridden from views::ButtonListener.
+  virtual void ButtonPressed(views::Button* sender,
+                             const ui::Event& event) OVERRIDE {
+    CHECK(sender == icon_);
+    if (UseNewAudioHandler()) {
+      chromeos::CrasAudioHandler::Get()->SetOutputMute(!IsAudioMuted());
+    } else {
+      ash::Shell::GetInstance()->system_tray_delegate()->
+          GetVolumeControlDelegate()->SetAudioMuted(!IsAudioMuted());
+    }
+  }
+
+  // Overridden from views:SliderListener.
+  virtual void SliderValueChanged(views::Slider* sender,
+                                  float value,
+                                  float old_value,
+                                  views::SliderChangeReason reason) OVERRIDE {
+    if (reason == views::VALUE_CHANGED_BY_USER) {
+      if (UseNewAudioHandler()) {
+        chromeos::CrasAudioHandler::Get()->
+            SetOutputVolumePercent(value * 100.0f);
+      }
+      else {
+        ash::Shell::GetInstance()->system_tray_delegate()->
+            GetVolumeControlDelegate()->SetVolumeLevel(value);
+      }
+    }
+    icon_->Update();
+  }
+
+  // Overriden from ActinableView.
+  virtual bool PerformAction(const ui::Event& event) OVERRIDE {
+    if (!more_->visible())
+      return false;
+    owner_->TransitionDetailedView();
+    return true;
+  }
+
+  SystemTrayItem* owner_;
+  VolumeButton* icon_;
+  VolumeSlider* slider_;
+  BarSeparator* bar_;
+  views::ImageView* device_type_;
+  views::ImageView* more_;
+  bool is_default_view_;
+
+  DISALLOW_COPY_AND_ASSIGN(VolumeView);
+};
+
+class AudioDetailedView : public TrayDetailsView,
+                          public ViewClickListener {
+ public:
+  AudioDetailedView(SystemTrayItem* owner, user::LoginStatus login)
+      : TrayDetailsView(owner),
+        login_(login) {
+    CreateItems();
+    Update();
+  }
+
+  virtual ~AudioDetailedView() {
+  }
+
+  void Update() {
+    UpdateAudioDevices();
+    Layout();
+  }
+
+ private:
+  void CreateItems() {
+    CreateScrollableList();
+    CreateHeaderEntry();
+  }
+
+  void CreateHeaderEntry() {
+    CreateSpecialRow(IDS_ASH_STATUS_TRAY_AUDIO, this);
+  }
+
+  void UpdateAudioDevices() {
+    output_devices_.clear();
+    input_devices_.clear();
+    chromeos::AudioDeviceList devices;
+    chromeos::CrasAudioHandler::Get()->GetAudioDevices(&devices);
+    for (size_t i = 0; i < devices.size(); ++i) {
+      if (devices[i].is_input)
+        input_devices_.push_back(devices[i]);
+      else
+        output_devices_.push_back(devices[i]);
+    }
+    UpdateScrollableList();
+  }
+
+  void UpdateScrollableList() {
+    scroll_content()->RemoveAllChildViews(true);
+    device_map_.clear();
+
+    // Add audio output devices.
+    AddScrollListItem(
+        l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_AUDIO_OUTPUT),
+        gfx::Font::BOLD,
+        false);  /* no checkmark */
+    for (size_t i = 0; i < output_devices_.size(); ++i) {
+      HoverHighlightView* container = AddScrollListItem(
+          output_devices_[i].display_name,
+          gfx::Font::NORMAL,
+          output_devices_[i].active);  /* checkmark if active */
+      device_map_[container] = output_devices_[i];
+    }
+
+    AddScrollSeparator();
+
+    // Add audio input devices.
+    AddScrollListItem(
+        l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_AUDIO_INPUT),
+        gfx::Font::BOLD,
+        false);  /* no checkmark */
+    for (size_t i = 0; i < input_devices_.size(); ++i) {
+      HoverHighlightView* container = AddScrollListItem(
+          input_devices_[i].display_name,
+          gfx::Font::NORMAL,
+          input_devices_[i].active);  /* checkmark if active */
+      device_map_[container] = input_devices_[i];
+    }
+
+    scroll_content()->SizeToPreferredSize();
+    scroller()->Layout();
+  }
+
+  HoverHighlightView* AddScrollListItem(const string16& text,
+                                        gfx::Font::FontStyle style,
+                                        bool checked) {
+    HoverHighlightView* container = new HoverHighlightView(this);
+    container->AddCheckableLabel(text, style, checked);
+    scroll_content()->AddChildView(container);
+    return container;
+  }
+
+  // Overridden from ViewClickListener.
+  virtual void OnViewClicked(views::View* sender) OVERRIDE {
+    if (sender == footer()->content()) {
+      owner()->system_tray()->ShowDefaultView(BUBBLE_USE_EXISTING);
+    } else {
+      AudioDeviceMap::iterator iter = device_map_.find(sender);
+      if (iter == device_map_.end())
+        return;
+      chromeos::AudioDevice& device = iter->second;
+      if (device.is_input)
+        chromeos::CrasAudioHandler::Get()->SetActiveInputNode(device.id);
+      else
+        chromeos::CrasAudioHandler::Get()->SetActiveOutputNode(device.id);
+    }
+  }
+
+  typedef std::map<views::View*, chromeos::AudioDevice> AudioDeviceMap;
+
+  user::LoginStatus login_;
+  chromeos::AudioDeviceList output_devices_;
+  chromeos::AudioDeviceList input_devices_;
+  AudioDeviceMap device_map_;
+
+  DISALLOW_COPY_AND_ASSIGN(AudioDetailedView);
+};
+
+}  // namespace tray
+
+TrayAudio::TrayAudio(SystemTray* system_tray)
+    : TrayImageItem(system_tray, IDR_AURA_UBER_TRAY_VOLUME_MUTE),
+      volume_view_(NULL),
+      audio_detail_(NULL),
+      pop_up_volume_view_(false) {
+  if (UseNewAudioHandler())
+    chromeos::CrasAudioHandler::Get()->AddAudioObserver(this);
+  else
+    Shell::GetInstance()->system_tray_notifier()->AddAudioObserver(this);
+}
+
+TrayAudio::~TrayAudio() {
+  if (UseNewAudioHandler()) {
+    if (chromeos::CrasAudioHandler::IsInitialized())
+      chromeos::CrasAudioHandler::Get()->RemoveAudioObserver(this);
+  } else {
+    Shell::GetInstance()->system_tray_notifier()->RemoveAudioObserver(this);
+  }
+}
+
+bool TrayAudio::GetInitialVisibility() {
+  return IsAudioMuted();
+}
+
+views::View* TrayAudio::CreateDefaultView(user::LoginStatus status) {
+  volume_view_ = new tray::VolumeView(this, true);
+  return volume_view_;
+}
+
+views::View* TrayAudio::CreateDetailedView(user::LoginStatus status) {
+  if (!ShowAudioDeviceMenu() || pop_up_volume_view_) {
+    volume_view_ = new tray::VolumeView(this, false);
+    return volume_view_;
+  } else {
+    audio_detail_ = new tray::AudioDetailedView(this, status);
+    return audio_detail_;
+  }
+}
+
+void TrayAudio::DestroyDefaultView() {
+  volume_view_ = NULL;
+}
+
+void TrayAudio::DestroyDetailedView() {
+  if (audio_detail_) {
+    audio_detail_ = NULL;
+  } else if (volume_view_) {
+    volume_view_ = NULL;
+    pop_up_volume_view_ = false;
+  }
+}
+
+bool TrayAudio::ShouldHideArrow() const {
+  return true;
+}
+
+bool TrayAudio::ShouldShowLauncher() const {
+  return false;
+}
+
+void TrayAudio::OnVolumeChanged(float percent) {
+  DCHECK(!UseNewAudioHandler());
+  if (tray_view())
+    tray_view()->SetVisible(GetInitialVisibility());
+
+  if (volume_view_) {
+    if (IsAudioMuted())
+      percent = 0.0;
+    volume_view_->SetVolumeLevel(percent);
+    SetDetailedViewCloseDelay(kTrayPopupAutoCloseDelayInSeconds);
+    return;
+  }
+  PopupDetailedView(kTrayPopupAutoCloseDelayInSeconds, false);
+}
+
+void TrayAudio::OnMuteToggled() {
+  DCHECK(!UseNewAudioHandler());
+  if (tray_view())
+      tray_view()->SetVisible(GetInitialVisibility());
+
+  if (volume_view_)
+    volume_view_->Update();
+  else
+    PopupDetailedView(kTrayPopupAutoCloseDelayInSeconds, false);
+}
+
+
+void TrayAudio::OnOutputVolumeChanged() {
+  DCHECK(UseNewAudioHandler());
+  float percent = GetVolumeLevel();
+  if (tray_view())
+    tray_view()->SetVisible(GetInitialVisibility());
+
+  if (volume_view_) {
+    volume_view_->SetVolumeLevel(percent);
+    SetDetailedViewCloseDelay(kTrayPopupAutoCloseDelayInSeconds);
+    return;
+  }
+  pop_up_volume_view_ = true;
+  PopupDetailedView(kTrayPopupAutoCloseDelayInSeconds, false);
+}
+
+void TrayAudio::OnOutputMuteChanged() {
+  DCHECK(UseNewAudioHandler());
+  if (tray_view())
+      tray_view()->SetVisible(GetInitialVisibility());
+
+  if (volume_view_)
+    volume_view_->Update();
+  else {
+    pop_up_volume_view_ = true;
+    PopupDetailedView(kTrayPopupAutoCloseDelayInSeconds, false);
+  }
+}
+
+void TrayAudio::OnAudioNodesChanged() {
+  Update();
+}
+
+void TrayAudio::OnActiveOutputNodeChanged() {
+  Update();
+}
+
+void TrayAudio::OnActiveInputNodeChanged() {
+  Update();
+}
+
+void TrayAudio::Update() {
+  if (audio_detail_)
+    audio_detail_->Update();
+  if (volume_view_)
+    volume_view_->Update();
+}
+
+}  // namespace internal
+}  // namespace ash
diff --git a/ash/system/chromeos/audio/tray_audio.h b/ash/system/chromeos/audio/tray_audio.h
new file mode 100644
index 0000000..af8f7a9
--- /dev/null
+++ b/ash/system/chromeos/audio/tray_audio.h
@@ -0,0 +1,65 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_SYSTEM_CHROMEOS_AUDIO_TRAY_AUDIO_H_
+#define ASH_SYSTEM_CHROMEOS_AUDIO_TRAY_AUDIO_H_
+
+#include "ash/system/chromeos/audio/audio_observer.h"
+#include "ash/system/tray/tray_image_item.h"
+#include "chromeos/audio/cras_audio_handler.h"
+
+namespace ash {
+namespace internal {
+
+namespace tray {
+class VolumeView;
+class AudioDetailedView;
+}
+
+class TrayAudio : public TrayImageItem,
+                  public chromeos::CrasAudioHandler::AudioObserver,
+                  public AudioObserver {
+ public:
+  explicit TrayAudio(SystemTray* system_tray);
+  virtual ~TrayAudio();
+
+ private:
+  // Overridden from TrayImageItem.
+  virtual bool GetInitialVisibility() OVERRIDE;
+
+  // Overridden from SystemTrayItem.
+  virtual views::View* CreateDefaultView(user::LoginStatus status) OVERRIDE;
+  virtual views::View* CreateDetailedView(user::LoginStatus status) OVERRIDE;
+  virtual void DestroyDefaultView() OVERRIDE;
+  virtual void DestroyDetailedView() OVERRIDE;
+  virtual bool ShouldHideArrow() const OVERRIDE;
+  virtual bool ShouldShowLauncher() const OVERRIDE;
+
+  // Overridden from AudioObserver.
+  virtual void OnVolumeChanged(float percent) OVERRIDE;
+  virtual void OnMuteToggled() OVERRIDE;
+
+  // Overridden from chromeos::CrasAudioHandler::AudioObserver.
+  virtual void OnOutputVolumeChanged() OVERRIDE;
+  virtual void OnOutputMuteChanged() OVERRIDE;
+  virtual void OnAudioNodesChanged() OVERRIDE;
+  virtual void OnActiveOutputNodeChanged() OVERRIDE;
+  virtual void OnActiveInputNodeChanged() OVERRIDE;
+
+  void Update();
+
+  tray::VolumeView* volume_view_;
+  tray::AudioDetailedView* audio_detail_;
+
+  // True if VolumeView should be created for accelerator pop up;
+  // Otherwise, it should be created for detailed view in ash tray bubble.
+  bool pop_up_volume_view_;
+
+  DISALLOW_COPY_AND_ASSIGN(TrayAudio);
+};
+
+}  // namespace internal
+}  // namespace ash
+
+#endif  // ASH_SYSTEM_CHROMEOS_AUDIO_TRAY_AUDIO_H_
diff --git a/ash/system/chromeos/enterprise/tray_enterprise.cc b/ash/system/chromeos/enterprise/tray_enterprise.cc
index 368cec3..05ff799 100644
--- a/ash/system/chromeos/enterprise/tray_enterprise.cc
+++ b/ash/system/chromeos/enterprise/tray_enterprise.cc
@@ -4,77 +4,18 @@
 
 #include "ash/system/chromeos/enterprise/tray_enterprise.h"
 
-#include "ash/system/tray/hover_highlight_view.h"
+#include "ash/system/chromeos/label_tray_view.h"
 #include "ash/system/tray/system_tray_notifier.h"
-#include "ash/system/tray/tray_constants.h"
-#include "ash/system/tray/tray_views.h"
 #include "ash/system/user/login_status.h"
 #include "base/logging.h"
 #include "grit/ash_resources.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/gfx/font.h"
-#include "ui/views/layout/fill_layout.h"
 
 namespace ash {
 namespace internal {
 
-class EnterpriseDefaultView : public views::View {
- public:
-  explicit EnterpriseDefaultView(ViewClickListener* click_listener);
-  virtual ~EnterpriseDefaultView();
-  void SetMessage(const string16& message);
- private:
-  views::View* CreateChildView(const string16& message) const;
-
-  ViewClickListener* click_listener_;
-  string16 message_;
-
-  DISALLOW_COPY_AND_ASSIGN(EnterpriseDefaultView);
-};
-
-EnterpriseDefaultView::EnterpriseDefaultView(
-    ViewClickListener* click_listener)
-    : click_listener_(click_listener) {
-  SetLayoutManager(new views::FillLayout());
-  SetVisible(false);
-}
-
-EnterpriseDefaultView::~EnterpriseDefaultView() {
-}
-
-void EnterpriseDefaultView::SetMessage(const string16& message) {
-  if (message_ == message)
-    return;
-
-  message_ = message;
-  RemoveAllChildViews(true);
-  if (!message_.empty()) {
-    AddChildView(CreateChildView(message_));
-    SetVisible(true);
-  } else {
-    SetVisible(false);
-  }
-}
-
-views::View* EnterpriseDefaultView::CreateChildView(
-    const string16& message) const {
-  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
-  const gfx::ImageSkia* icon =
-      rb.GetImageSkiaNamed(IDR_AURA_UBER_TRAY_ENTERPRISE_DARK);
-  HoverHighlightView* child = new HoverHighlightView(click_listener_);
-  child->AddIconAndLabel(*icon, message, gfx::Font::NORMAL);
-  child->text_label()->SetMultiLine(true);
-  child->text_label()->SetAllowCharacterBreak(true);
-  child->set_border(views::Border::CreateEmptyBorder(0,
-      kTrayPopupPaddingHorizontal, 0, kTrayPopupPaddingHorizontal));
-  child->SetExpandable(true);
-  child->SetVisible(true);
-  return child;
-}
-
 TrayEnterprise::TrayEnterprise(SystemTray* system_tray)
     : SystemTrayItem(system_tray),
-      default_view_(NULL) {
+      tray_view_(NULL) {
   Shell::GetInstance()->system_tray_notifier()->
       AddEnterpriseDomainObserver(this);
 }
@@ -85,25 +26,25 @@
 }
 
 void TrayEnterprise::UpdateEnterpriseMessage() {
-  string16 message = Shell::GetInstance()->system_tray_delegate()->
+  base::string16 message = Shell::GetInstance()->system_tray_delegate()->
       GetEnterpriseMessage();
-  if (default_view_)
-    default_view_->SetMessage(message);
+  if (tray_view_)
+    tray_view_->SetMessage(message);
 }
 
 views::View* TrayEnterprise::CreateDefaultView(user::LoginStatus status) {
-  CHECK(default_view_ == NULL);
+  CHECK(tray_view_ == NULL);
   // For public accounts, enterprise ownership is indicated in the user details
   // instead.
   if (status == ash::user::LOGGED_IN_PUBLIC)
     return NULL;
-  default_view_ = new EnterpriseDefaultView(this);
+  tray_view_ = new LabelTrayView(this, IDR_AURA_UBER_TRAY_ENTERPRISE_DARK);
   UpdateEnterpriseMessage();
-  return default_view_;
+  return tray_view_;
 }
 
 void TrayEnterprise::DestroyDefaultView() {
-  default_view_ = NULL;
+  tray_view_ = NULL;
 }
 
 void TrayEnterprise::OnEnterpriseDomainChanged() {
diff --git a/ash/system/chromeos/enterprise/tray_enterprise.h b/ash/system/chromeos/enterprise/tray_enterprise.h
index 050c0f0..697dfcd 100644
--- a/ash/system/chromeos/enterprise/tray_enterprise.h
+++ b/ash/system/chromeos/enterprise/tray_enterprise.h
@@ -16,7 +16,7 @@
 namespace ash {
 namespace internal {
 
-class EnterpriseDefaultView;
+class LabelTrayView;
 
 class TrayEnterprise : public SystemTrayItem,
                        public ViewClickListener,
@@ -40,7 +40,7 @@
   virtual void OnViewClicked(views::View* sender) OVERRIDE;
 
  private:
-  EnterpriseDefaultView* default_view_;
+  LabelTrayView* tray_view_;
 
   DISALLOW_COPY_AND_ASSIGN(TrayEnterprise);
 };
diff --git a/ash/system/chromeos/label_tray_view.cc b/ash/system/chromeos/label_tray_view.cc
new file mode 100644
index 0000000..65f4146
--- /dev/null
+++ b/ash/system/chromeos/label_tray_view.cc
@@ -0,0 +1,59 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/system/chromeos/label_tray_view.h"
+
+#include "ash/system/tray/hover_highlight_view.h"
+#include "ash/system/tray/tray_constants.h"
+#include "ash/system/tray/view_click_listener.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/gfx/font.h"
+#include "ui/views/controls/label.h"
+#include "ui/views/layout/fill_layout.h"
+
+namespace ash {
+namespace internal {
+
+LabelTrayView::LabelTrayView(ViewClickListener* click_listener,
+                             int icon_resource_id)
+    : click_listener_(click_listener),
+      icon_resource_id_(icon_resource_id) {
+  SetLayoutManager(new views::FillLayout());
+  SetVisible(false);
+}
+
+LabelTrayView::~LabelTrayView() {
+}
+
+void LabelTrayView::SetMessage(const base::string16& message) {
+  if (message_ == message)
+    return;
+
+  message_ = message;
+  RemoveAllChildViews(true);
+  if (!message_.empty()) {
+    AddChildView(CreateChildView(message_));
+    SetVisible(true);
+  } else {
+    SetVisible(false);
+  }
+}
+
+views::View* LabelTrayView::CreateChildView(
+    const base::string16& message) const {
+  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+  const gfx::ImageSkia* icon = rb.GetImageSkiaNamed(icon_resource_id_);
+  HoverHighlightView* child = new HoverHighlightView(click_listener_);
+  child->AddIconAndLabel(*icon, message, gfx::Font::NORMAL);
+  child->text_label()->SetMultiLine(true);
+  child->text_label()->SetAllowCharacterBreak(true);
+  child->set_border(views::Border::CreateEmptyBorder(0,
+      kTrayPopupPaddingHorizontal, 0, kTrayPopupPaddingHorizontal));
+  child->SetExpandable(true);
+  child->SetVisible(true);
+  return child;
+}
+
+}  // namespace internal
+}  // namespace ash
diff --git a/ash/system/chromeos/label_tray_view.h b/ash/system/chromeos/label_tray_view.h
new file mode 100644
index 0000000..402f5c3
--- /dev/null
+++ b/ash/system/chromeos/label_tray_view.h
@@ -0,0 +1,37 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_SYSTEM_CHROMEOS_LABEL_TRAY_VIEW_H_
+#define ASH_SYSTEM_CHROMEOS_LABEL_TRAY_VIEW_H_
+
+#include "base/string16.h"
+#include "ui/views/view.h"
+
+namespace ash {
+namespace internal {
+
+class ViewClickListener;
+
+// View for simple information in tray. Automatically hides when message is
+// empty. Supports multiline messages.
+
+class LabelTrayView : public views::View {
+ public:
+  LabelTrayView(ViewClickListener* click_listener, int icon_resource_id);
+  virtual ~LabelTrayView();
+  void SetMessage(const base::string16& message);
+ private:
+  views::View* CreateChildView(const base::string16& message) const;
+
+  ViewClickListener* click_listener_;
+  int icon_resource_id_;
+  base::string16 message_;
+
+  DISALLOW_COPY_AND_ASSIGN(LabelTrayView);
+};
+
+}  // namespace internal
+}  // namespace ash
+
+#endif  // ASH_SYSTEM_CHROMEOS_LABEL_TRAY_VIEW_H_
diff --git a/ash/system/chromeos/managed/tray_locally_managed_user.cc b/ash/system/chromeos/managed/tray_locally_managed_user.cc
new file mode 100644
index 0000000..b610f5b
--- /dev/null
+++ b/ash/system/chromeos/managed/tray_locally_managed_user.cc
@@ -0,0 +1,53 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/system/chromeos/managed/tray_locally_managed_user.h"
+
+#include "ash/system/chromeos/label_tray_view.h"
+#include "ash/system/tray/system_tray_notifier.h"
+#include "ash/system/user/login_status.h"
+#include "base/logging.h"
+#include "grit/ash_resources.h"
+
+namespace ash {
+namespace internal {
+
+TrayLocallyManagedUser::TrayLocallyManagedUser(SystemTray* system_tray)
+    : SystemTrayItem(system_tray),
+      tray_view_(NULL) {
+}
+
+TrayLocallyManagedUser::~TrayLocallyManagedUser() {
+}
+
+void TrayLocallyManagedUser::UpdateMessage() {
+  base::string16 message = Shell::GetInstance()->system_tray_delegate()->
+      GetLocallyManagedUserMessage();
+  if (tray_view_)
+    tray_view_->SetMessage(message);
+}
+
+views::View* TrayLocallyManagedUser::CreateDefaultView(
+    user::LoginStatus status) {
+  CHECK(tray_view_ == NULL);
+  if (status != ash::user::LOGGED_IN_LOCALLY_MANAGED)
+    return NULL;
+
+  // TODO(antrim): replace to appropriate icon when there is one.
+  tray_view_ = new LabelTrayView(this, IDR_AURA_UBER_TRAY_ENTERPRISE_DARK);
+  UpdateMessage();
+  return tray_view_;
+}
+
+void TrayLocallyManagedUser::DestroyDefaultView() {
+  tray_view_ = NULL;
+}
+
+void TrayLocallyManagedUser::OnViewClicked(views::View* sender) {
+  Shell::GetInstance()->system_tray_delegate()->ShowLocallyManagedUserInfo();
+}
+
+} // namespace internal
+} // namespace ash
+
diff --git a/ash/system/chromeos/managed/tray_locally_managed_user.h b/ash/system/chromeos/managed/tray_locally_managed_user.h
new file mode 100644
index 0000000..17f24ba
--- /dev/null
+++ b/ash/system/chromeos/managed/tray_locally_managed_user.h
@@ -0,0 +1,47 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_SYSTEM_CHROMEOS_LOCALLY_MANAGED_TRAY_LOCALLY_MANAGED_USER_H
+#define ASH_SYSTEM_CHROMEOS_LOCALLY_MANAGED_TRAY_LOCALLY_MANAGED_USER_H
+
+#include "ash/system/tray/system_tray_item.h"
+#include "ash/system/tray/view_click_listener.h"
+
+namespace ash {
+class SystemTray;
+}
+
+namespace ash {
+namespace internal {
+
+class LabelTrayView;
+
+class TrayLocallyManagedUser : public SystemTrayItem,
+                               public ViewClickListener {
+ public:
+  explicit TrayLocallyManagedUser(SystemTray* system_tray);
+  virtual ~TrayLocallyManagedUser();
+
+  // If message is not empty updates content of default view, otherwise hides
+  // tray items.
+  void UpdateMessage();
+
+  // Overridden from SystemTrayItem.
+  virtual views::View* CreateDefaultView(user::LoginStatus status) OVERRIDE;
+  virtual void DestroyDefaultView() OVERRIDE;
+
+  // Overridden from ViewClickListener.
+  virtual void OnViewClicked(views::View* sender) OVERRIDE;
+
+ private:
+  LabelTrayView* tray_view_;
+
+  DISALLOW_COPY_AND_ASSIGN(TrayLocallyManagedUser);
+};
+
+} // namespace internal
+} // namespace ash
+
+#endif  // ASH_SYSTEM_CHROMEOS_LOCALLY_MANAGED_TRAY_LOCALLY_MANAGED_USER_H
+
diff --git a/ash/system/chromeos/network/network_icon.cc b/ash/system/chromeos/network/network_icon.cc
index f241eb1..6ac05a7 100644
--- a/ash/system/chromeos/network/network_icon.cc
+++ b/ash/system/chromeos/network/network_icon.cc
@@ -252,9 +252,9 @@
 }
 
 ImageType ImageTypeForNetworkType(const std::string& type) {
-  if (type == flimflam::kTypeWifi || type == flimflam::kTypeWimax)
+  if (type == flimflam::kTypeWifi)
     return ARCS;
-  else if (type == flimflam::kTypeCellular)
+  else if (type == flimflam::kTypeCellular || type == flimflam::kTypeWimax)
     return BARS;
   return NONE;
 }
@@ -571,7 +571,7 @@
           IDR_AURA_UBER_TRAY_NETWORK_SECURE_DARK);
     }
   } else if (type == flimflam::kTypeWimax) {
-    badges->top_left = rb.GetImageSkiaNamed(
+    technology_badge_ = rb.GetImageSkiaNamed(
         IconTypeIsDark(icon_type_) ?
         IDR_AURA_UBER_TRAY_NETWORK_4G_DARK :
         IDR_AURA_UBER_TRAY_NETWORK_4G_LIGHT);
@@ -611,11 +611,8 @@
                                   IconType icon_type) {
   DCHECK(network);
   // Handle connecting icons.
-  if (network->IsConnectingState()) {
-    NetworkIconAnimation::GetInstance()->AddNetwork(network->path());
+  if (network->IsConnectingState())
     return GetConnectingImage(network->type(), icon_type);
-  }
-  NetworkIconAnimation::GetInstance()->RemoveNetwork(network->path());
 
   // Find or add the icon.
   NetworkIconMap* icon_map = GetIconMap(icon_type);
@@ -643,8 +640,8 @@
   return GetDisconnectedImage(network_type, icon_type);
 }
 
-string16 GetLabelForNetwork(const chromeos::NetworkState* network,
-                            IconType icon_type) {
+base::string16 GetLabelForNetwork(const chromeos::NetworkState* network,
+                                  IconType icon_type) {
   DCHECK(network);
   std::string activation_state = network->activation_state();
   if (icon_type == ICON_TYPE_LIST) {
@@ -695,8 +692,8 @@
   static int s_uninitialized_msg(0);
 
   NetworkStateHandler* handler = NetworkStateHandler::Get();
-  if (handler->TechnologyUninitialized(
-          NetworkStateHandler::kMatchTypeMobile)) {
+  if (handler->GetTechnologyState(NetworkStateHandler::kMatchTypeMobile)
+      == NetworkStateHandler::TECHNOLOGY_UNINITIALIZED) {
     s_uninitialized_msg = IDS_ASH_STATUS_TRAY_INITIALIZING_CELLULAR;
     s_uninitialized_state_time = base::Time::Now();
     return s_uninitialized_msg;
diff --git a/ash/system/chromeos/network/network_icon.h b/ash/system/chromeos/network/network_icon.h
index 9ea5b7f..bc265d5 100644
--- a/ash/system/chromeos/network/network_icon.h
+++ b/ash/system/chromeos/network/network_icon.h
@@ -41,8 +41,8 @@
                                               const std::string& network_type);
 
 // Returns the label for |network| based on |icon_type|. |network| can be NULL.
-string16 GetLabelForNetwork(const chromeos::NetworkState* network,
-                            IconType icon_type);
+base::string16 GetLabelForNetwork(const chromeos::NetworkState* network,
+                                  IconType icon_type);
 
 // Updates and returns the appropriate message id if the cellular network
 // is uninitialized.
diff --git a/ash/system/chromeos/network/network_icon_animation.cc b/ash/system/chromeos/network/network_icon_animation.cc
index 55da41e..1169c67 100644
--- a/ash/system/chromeos/network/network_icon_animation.cc
+++ b/ash/system/chromeos/network/network_icon_animation.cc
@@ -14,7 +14,7 @@
 namespace network_icon {
 
 NetworkIconAnimation::NetworkIconAnimation()
-    : ALLOW_THIS_IN_INITIALIZER_LIST(animation_(this)) {
+    : animation_(this) {
   // Set up the animation throbber.
   animation_.SetThrobDuration(kThrobDurationMs);
   animation_.SetTweenType(ui::Tween::LINEAR);
@@ -39,24 +39,14 @@
 }
 
 void NetworkIconAnimation::AddObserver(AnimationObserver* observer) {
-  observers_.AddObserver(observer);
+  if (!observers_.HasObserver(observer))
+    observers_.AddObserver(observer);
 }
 
 void NetworkIconAnimation::RemoveObserver(AnimationObserver* observer) {
   observers_.RemoveObserver(observer);
   if (observers_.size() == 0)
-    animation_.Stop();
-}
-
-void NetworkIconAnimation::AddNetwork(const std::string& network_id) {
-  networks_.insert(network_id);
-  // Animation will start (if stopped) when GetAnimation is called.
-}
-
-void NetworkIconAnimation::RemoveNetwork(const std::string& network_id) {
-  networks_.erase(network_id);
-  if (networks_.empty())
-    animation_.Reset();
+    animation_.Reset();  // Stops the animation and resets the current value.
 }
 
 // static
diff --git a/ash/system/chromeos/network/network_icon_animation.h b/ash/system/chromeos/network/network_icon_animation.h
index fd47af8..e784f7d 100644
--- a/ash/system/chromeos/network/network_icon_animation.h
+++ b/ash/system/chromeos/network/network_icon_animation.h
@@ -27,10 +27,10 @@
   // Returns the current animation value, [0-1].
   double GetAnimation();
 
+  // The animation stops when all observers have been removed.
+  // Be sure to remove observers when no associated icons are animating.
   void AddObserver(AnimationObserver* observer);
   void RemoveObserver(AnimationObserver* observer);
-  void AddNetwork(const std::string& network_id);
-  void RemoveNetwork(const std::string& network_id);
 
   // ui::AnimationDelegate implementation.
   virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE;
@@ -40,7 +40,6 @@
  private:
   ui::ThrobAnimation animation_;
   ObserverList<AnimationObserver> observers_;
-  std::set<std::string> networks_;
 };
 
 }  // namespace network_icon
diff --git a/ash/system/chromeos/network/network_list_detailed_view.cc b/ash/system/chromeos/network/network_list_detailed_view.cc
index 61d7dac..68bcc3e 100644
--- a/ash/system/chromeos/network/network_list_detailed_view.cc
+++ b/ash/system/chromeos/network/network_list_detailed_view.cc
@@ -8,7 +8,8 @@
 #include "ash/system/tray/hover_highlight_view.h"
 #include "ash/system/tray/system_tray_delegate.h"
 #include "ash/system/tray/tray_constants.h"
-#include "ash/system/tray/tray_views.h"
+#include "ash/system/tray/tray_popup_header_button.h"
+#include "ash/system/tray/tray_popup_label_button.h"
 #include "grit/ash_resources.h"
 #include "grit/ash_strings.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -233,7 +234,7 @@
   else if (!have_cellular_network && delegate->GetMobileEnabled())
     status_message_id = IDS_ASH_STATUS_TRAY_NO_CELLULAR_NETWORKS;
   if (status_message_id) {
-    string16 text = rb.GetLocalizedString(status_message_id);
+    base::string16 text = rb.GetLocalizedString(status_message_id);
     if (CreateOrUpdateInfoLabel(index++, text, &no_cellular_networks_view_))
       needs_relayout = true;
   } else if (no_cellular_networks_view_) {
@@ -247,7 +248,7 @@
     int message_id = delegate->GetWifiEnabled() ?
         IDS_ASH_STATUS_TRAY_NETWORK_WIFI_ENABLED :
         IDS_ASH_STATUS_TRAY_NETWORK_WIFI_DISABLED;
-    string16 text = rb.GetLocalizedString(message_id);
+    base::string16 text = rb.GetLocalizedString(message_id);
     if (CreateOrUpdateInfoLabel(index++, text, &no_wifi_networks_view_))
       needs_relayout = true;
   } else if (no_wifi_networks_view_) {
@@ -258,7 +259,7 @@
 
   // "Wifi Scanning"
   if (delegate->GetWifiScanning()) {
-    string16 text =
+    base::string16 text =
         rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_WIFI_SCANNING_MESSAGE);
     if (CreateOrUpdateInfoLabel(index++, text, &scanning_view_))
       needs_relayout = true;
diff --git a/ash/system/chromeos/network/network_list_detailed_view_base.cc b/ash/system/chromeos/network/network_list_detailed_view_base.cc
index 34708be..787da1f 100644
--- a/ash/system/chromeos/network/network_list_detailed_view_base.cc
+++ b/ash/system/chromeos/network/network_list_detailed_view_base.cc
@@ -12,6 +12,8 @@
 #include "ash/system/tray/system_tray_delegate.h"
 #include "ash/system/tray/system_tray_item.h"
 #include "ash/system/tray/tray_constants.h"
+#include "ash/system/tray/tray_popup_header_button.h"
+#include "ash/system/tray/tray_popup_label_button.h"
 #include "base/utf_string_conversions.h"
 #include "grit/ash_resources.h"
 #include "grit/ash_strings.h"
@@ -27,7 +29,7 @@
 namespace {
 
 // Create a label with the font size and color used in the network info bubble.
-views::Label* CreateInfoBubbleLabel(const string16& text) {
+views::Label* CreateInfoBubbleLabel(const base::string16& text) {
   views::Label* label = new views::Label(text);
   ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
   label->SetFont(rb.GetFont(ui::ResourceBundle::SmallFont));
@@ -36,7 +38,7 @@
 }
 
 // Create a label formatted for info items in the menu
-views::Label* CreateMenuInfoLabel(const string16& text) {
+views::Label* CreateMenuInfoLabel(const base::string16& text) {
   views::Label* label = new views::Label(text);
   label->set_border(views::Border::CreateEmptyBorder(
       ash::kTrayPopupPaddingBetweenItems,
@@ -48,7 +50,7 @@
 }
 
 // Create a row of labels for the network info bubble.
-views::View* CreateInfoBubbleLine(const string16& text_label,
+views::View* CreateInfoBubbleLine(const base::string16& text_label,
                                   const std::string& text_string) {
   views::View* view = new views::View;
   view->SetLayoutManager(
@@ -212,7 +214,7 @@
 }
 
 bool NetworkListDetailedViewBase::CreateOrUpdateInfoLabel(
-    int index, const string16& text, views::Label** label) {
+    int index, const base::string16& text, views::Label** label) {
   if (*label == NULL) {
     *label = CreateMenuInfoLabel(text);
     scroll_content()->AddChildViewAt(*label, index);
@@ -231,7 +233,8 @@
       service_path_map_.find(info->service_path);
   gfx::Font::FontStyle font =
       info->highlight() ? gfx::Font::BOLD : gfx::Font::NORMAL;
-  string16 desc = info->description.empty() ? info->name : info->description;
+  base::string16 desc = info->description.empty() ? info->name
+                                                  : info->description;
   if (found == service_path_map_.end()) {
     container = new HoverHighlightView(this);
     container->AddIconAndLabel(info->image, desc, font);
diff --git a/ash/system/chromeos/network/network_list_detailed_view_base.h b/ash/system/chromeos/network/network_list_detailed_view_base.h
index 1d1c648..cfea043 100644
--- a/ash/system/chromeos/network/network_list_detailed_view_base.h
+++ b/ash/system/chromeos/network/network_list_detailed_view_base.h
@@ -50,7 +50,7 @@
   user::LoginStatus login() const { return login_; }
   bool IsNetworkListEmpty() const;
   bool CreateOrUpdateInfoLabel(
-      int index, const string16& text, views::Label** label);
+      int index, const base::string16& text, views::Label** label);
   bool UpdateNetworkChild(int index, const NetworkIconInfo* info);
 
   const std::vector<NetworkIconInfo>& network_list() const {
diff --git a/ash/system/chromeos/network/network_observer.h b/ash/system/chromeos/network/network_observer.h
index b5dbc29..45011c2 100644
--- a/ash/system/chromeos/network/network_observer.h
+++ b/ash/system/chromeos/network/network_observer.h
@@ -45,9 +45,9 @@
   virtual void SetNetworkMessage(NetworkTrayDelegate* delegate,
                                  MessageType message_type,
                                  NetworkType network_type,
-                                 const string16& title,
-                                 const string16& message,
-                                 const std::vector<string16>& links) = 0;
+                                 const base::string16& title,
+                                 const base::string16& message,
+                                 const std::vector<base::string16>& links) = 0;
   // Clears the message notification for |message_type|.
   virtual void ClearNetworkMessage(MessageType message_type) = 0;
 
diff --git a/ash/system/chromeos/network/network_state_list_detailed_view.cc b/ash/system/chromeos/network/network_state_list_detailed_view.cc
index 167c83a..296e356 100644
--- a/ash/system/chromeos/network/network_state_list_detailed_view.cc
+++ b/ash/system/chromeos/network/network_state_list_detailed_view.cc
@@ -16,7 +16,11 @@
 #include "ash/system/tray/system_tray_delegate.h"
 #include "ash/system/tray/tray_constants.h"
 #include "ash/system/tray/tray_details_view.h"
+#include "ash/system/tray/tray_popup_header_button.h"
+#include "ash/system/tray/tray_popup_label_button.h"
 #include "base/command_line.h"
+#include "base/message_loop.h"
+#include "base/time.h"
 #include "base/utf_string_conversions.h"
 #include "chromeos/chromeos_switches.h"
 #include "chromeos/network/device_state.h"
@@ -35,6 +39,7 @@
 #include "ui/views/layout/fill_layout.h"
 #include "ui/views/widget/widget.h"
 
+using chromeos::DeviceState;
 using chromeos::NetworkState;
 using chromeos::NetworkStateHandler;
 
@@ -47,8 +52,11 @@
 // Height of the list of networks in the popup.
 const int kNetworkListHeight = 203;
 
+// Delay between scan requests.
+const int kRequestScanDelaySeconds = 10;
+
 // Create a label with the font size and color used in the network info bubble.
-views::Label* CreateInfoBubbleLabel(const string16& text) {
+views::Label* CreateInfoBubbleLabel(const base::string16& text) {
   views::Label* label = new views::Label(text);
   ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
   label->SetFont(rb.GetFont(ui::ResourceBundle::SmallFont));
@@ -57,7 +65,7 @@
 }
 
 // Create a label formatted for info items in the menu
-views::Label* CreateMenuInfoLabel(const string16& text) {
+views::Label* CreateMenuInfoLabel(const base::string16& text) {
   views::Label* label = new views::Label(text);
   label->set_border(views::Border::CreateEmptyBorder(
       ash::kTrayPopupPaddingBetweenItems,
@@ -69,7 +77,7 @@
 }
 
 // Create a row of labels for the network info bubble.
-views::View* CreateInfoBubbleLine(const string16& text_label,
+views::View* CreateInfoBubbleLine(const base::string16& text_label,
                                   const std::string& text_string) {
   views::View* view = new views::View;
   view->SetLayoutManager(
@@ -114,7 +122,7 @@
   }
 
   std::string service_path;
-  string16 label;
+  base::string16 label;
   gfx::ImageSkia image;
   bool disable;
   bool highlight;
@@ -133,8 +141,6 @@
       info_icon_(NULL),
       button_wifi_(NULL),
       button_mobile_(NULL),
-      view_mobile_account_(NULL),
-      setup_mobile_account_(NULL),
       other_wifi_(NULL),
       turn_on_wifi_(NULL),
       other_mobile_(NULL),
@@ -145,7 +151,6 @@
       no_wifi_networks_view_(NULL),
       no_cellular_networks_view_(NULL),
       info_bubble_(NULL) {
-  network_icon::NetworkIconAnimation::GetInstance()->AddObserver(this);
 }
 
 NetworkStateListDetailedView::~NetworkStateListDetailedView() {
@@ -157,7 +162,6 @@
 void NetworkStateListDetailedView::ManagerChanged() {
   UpdateNetworkList();
   UpdateHeaderButtons();
-  UpdateMobileAccount();
   UpdateNetworkExtra();
   Layout();
 }
@@ -168,7 +172,6 @@
   UpdateNetworks(network_list);
   UpdateNetworkList();
   UpdateHeaderButtons();
-  UpdateMobileAccount();
   UpdateNetworkExtra();
   Layout();
 }
@@ -191,16 +194,14 @@
   CreateNetworkExtra();
   CreateHeaderEntry();
   CreateHeaderButtons();
-  CreateMobileAccount();
-  NetworkStateHandler* handler = NetworkStateHandler::Get();
+
   NetworkStateList network_list;
-  handler->RequestScan();
-  handler->GetNetworkList(&network_list);
+  NetworkStateHandler::Get()->GetNetworkList(&network_list);
   UpdateNetworks(network_list);
   UpdateNetworkList();
   UpdateHeaderButtons();
-  UpdateMobileAccount();
   UpdateNetworkExtra();
+  CallRequestScan();
 }
 
 NetworkDetailedView::DetailedViewType
@@ -224,7 +225,7 @@
   ash::SystemTrayDelegate* delegate =
       ash::Shell::GetInstance()->system_tray_delegate();
   if (sender == button_wifi_) {
-    bool enabled = handler->TechnologyEnabled(flimflam::kTypeWifi);
+    bool enabled = handler->IsTechnologyEnabled(flimflam::kTypeWifi);
     handler->SetTechnologyEnabled(
         flimflam::kTypeWifi, !enabled,
         chromeos::network_handler::ErrorCallback());
@@ -233,12 +234,7 @@
         flimflam::kTypeWifi, true,
         chromeos::network_handler::ErrorCallback());
   } else if (sender == button_mobile_) {
-    // TODO: This needs to be fixed to use
-    // NetworkStateHandler::SetTechnologyEnabled instead. Currently
-    // ToggleMobile has code to handle the locked SIM case, which cannot
-    // be moved here yet due to dependencies on src/chrome/* - see,
-    // crbug.com/222540.
-    delegate->ToggleMobile();
+    ToggleMobile();
   } else if (sender == settings_) {
     delegate->ShowNetworkSettings();
   } else if (sender == proxy_settings_) {
@@ -267,18 +263,10 @@
   if (login_ == user::LOGGED_IN_LOCKED)
     return;
 
-  ash::SystemTrayDelegate* delegate =
-      ash::Shell::GetInstance()->system_tray_delegate();
-  if (sender == view_mobile_account_) {
-    delegate->ShowCellularURL(topup_url_);
-  } else if (sender == setup_mobile_account_) {
-    delegate->ShowCellularURL(setup_url_);
-  } else {
-    std::map<views::View*, std::string>::iterator found =
-        network_map_.find(sender);
-    if (found != network_map_.end())
-      ConnectToNetwork(found->second);
-  }
+  std::map<views::View*, std::string>::iterator found =
+      network_map_.find(sender);
+  if (found != network_map_.end())
+    ConnectToNetwork(found->second);
 }
 
 // Create UI components.
@@ -328,26 +316,6 @@
   footer()->AddButton(info_icon_);
 }
 
-void NetworkStateListDetailedView::CreateMobileAccount() {
-  if (list_type_ != LIST_TYPE_NETWORK)
-    return;
-
-  HoverHighlightView* container = new HoverHighlightView(this);
-  container->AddLabel(
-      ui::ResourceBundle::GetSharedInstance().
-      GetLocalizedString(IDS_ASH_STATUS_TRAY_MOBILE_VIEW_ACCOUNT),
-      gfx::Font::NORMAL);
-  AddChildView(container);
-  view_mobile_account_ = container;
-
-  container = new HoverHighlightView(this);
-  container->AddLabel(ui::ResourceBundle::GetSharedInstance().
-                      GetLocalizedString(IDS_ASH_STATUS_TRAY_SETUP_MOBILE),
-                      gfx::Font::NORMAL);
-  AddChildView(container);
-  setup_mobile_account_ = container;
-}
-
 void NetworkStateListDetailedView::CreateNetworkExtra() {
   if (login_ == user::LOGGED_IN_LOCKED)
     return;
@@ -394,15 +362,11 @@
 
 void NetworkStateListDetailedView::UpdateHeaderButtons() {
   NetworkStateHandler* handler = NetworkStateHandler::Get();
-  if (button_wifi_) {
-    button_wifi_->SetToggled(
-        !handler->TechnologyEnabled(flimflam::kTypeWifi));
-  }
+  if (button_wifi_)
+    UpdateTechnologyButton(button_wifi_, flimflam::kTypeWifi);
   if (button_mobile_) {
-    button_mobile_->SetToggled(!handler->TechnologyEnabled(
-        NetworkStateHandler::kMatchTypeMobile));
-    button_mobile_->SetVisible(handler->TechnologyAvailable(
-        NetworkStateHandler::kMatchTypeMobile));
+    UpdateTechnologyButton(
+        button_mobile_, NetworkStateHandler::kMatchTypeMobile);
   }
   if (proxy_settings_)
     proxy_settings_->SetEnabled(handler->DefaultNetwork() != NULL);
@@ -410,6 +374,31 @@
   static_cast<views::View*>(footer())->Layout();
 }
 
+void NetworkStateListDetailedView::UpdateTechnologyButton(
+    TrayPopupHeaderButton* button,
+    const std::string& technology) {
+  NetworkStateHandler::TechnologyState state =
+      NetworkStateHandler::Get()->GetTechnologyState(technology);
+  if (state == NetworkStateHandler::TECHNOLOGY_UNAVAILABLE) {
+    button->SetVisible(false);
+    return;
+  }
+  button->SetVisible(true);
+  if (state == NetworkStateHandler::TECHNOLOGY_AVAILABLE) {
+    button->SetEnabled(true);
+    button->SetToggled(true);
+  } else if (state == NetworkStateHandler::TECHNOLOGY_ENABLED) {
+    button->SetEnabled(true);
+    button->SetToggled(false);
+  } else if (state == NetworkStateHandler::TECHNOLOGY_ENABLING) {
+    button->SetEnabled(false);
+    button->SetToggled(false);
+  } else {  // Initializing
+    button->SetEnabled(false);
+    button->SetToggled(true);
+  }
+}
+
 void NetworkStateListDetailedView::UpdateNetworks(
     const NetworkStateList& networks) {
   network_list_.clear();
@@ -430,6 +419,7 @@
   NetworkStateHandler* handler = NetworkStateHandler::Get();
 
   // First, update state for all networks
+  bool animating = false;
   for (size_t i = 0; i < network_list_.size(); ++i) {
     NetworkInfo* info = network_list_[i];
     const NetworkState* network =
@@ -444,7 +434,13 @@
         network->IsConnectedState() || network->IsConnectingState();
     info->disable =
         network->activation_state() == flimflam::kActivationStateActivating;
+    if (!animating && network->IsConnectingState())
+      animating = true;
   }
+  if (animating)
+    network_icon::NetworkIconAnimation::GetInstance()->AddObserver(this);
+  else
+    network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this);
 
   // Get the updated list entries
   network_map_.clear();
@@ -486,7 +482,7 @@
 }
 
 bool NetworkStateListDetailedView::CreateOrUpdateInfoLabel(
-    int index, const string16& text, views::Label** label) {
+    int index, const base::string16& text, views::Label** label) {
   if (*label == NULL) {
     *label = CreateMenuInfoLabel(text);
     scroll_content()->AddChildViewAt(*label, index);
@@ -558,12 +554,12 @@
     // Cellular initializing
     int status_message_id = network_icon::GetCellularUninitializedMsg();
     if (!status_message_id &&
-        handler->TechnologyEnabled(NetworkStateHandler::kMatchTypeMobile) &&
+        handler->IsTechnologyEnabled(NetworkStateHandler::kMatchTypeMobile) &&
         !handler->FirstNetworkByType(NetworkStateHandler::kMatchTypeMobile)) {
       status_message_id = IDS_ASH_STATUS_TRAY_NO_CELLULAR_NETWORKS;
     }
     if (status_message_id) {
-      string16 text = rb.GetLocalizedString(status_message_id);
+      base::string16 text = rb.GetLocalizedString(status_message_id);
       if (CreateOrUpdateInfoLabel(index++, text, &no_cellular_networks_view_))
         needs_relayout = true;
     } else if (no_cellular_networks_view_) {
@@ -574,10 +570,10 @@
 
     // "Wifi Enabled / Disabled"
     if (network_list_.empty()) {
-      int message_id = handler->TechnologyEnabled(flimflam::kTypeWifi) ?
+      int message_id = handler->IsTechnologyEnabled(flimflam::kTypeWifi) ?
           IDS_ASH_STATUS_TRAY_NETWORK_WIFI_ENABLED :
           IDS_ASH_STATUS_TRAY_NETWORK_WIFI_DISABLED;
-      string16 text = rb.GetLocalizedString(message_id);
+      base::string16 text = rb.GetLocalizedString(message_id);
       if (CreateOrUpdateInfoLabel(index++, text, &no_wifi_networks_view_))
         needs_relayout = true;
     } else if (no_wifi_networks_view_) {
@@ -588,7 +584,7 @@
 
     // "Wifi Scanning"
     if (handler->GetScanningByType(flimflam::kTypeWifi)) {
-      string16 text =
+      base::string16 text =
           rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_WIFI_SCANNING_MESSAGE);
       if (CreateOrUpdateInfoLabel(index++, text, &scanning_view_))
         needs_relayout = true;
@@ -611,7 +607,11 @@
 
   // No networks or other messages (fallback)
   if (index == 0) {
-    string16 text = rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_NO_NETWORKS);
+    base::string16 text;
+    if (list_type_ == LIST_TYPE_VPN)
+      text = rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_NETWORK_NO_VPN);
+    else
+      text = rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_NO_NETWORKS);
     if (CreateOrUpdateInfoLabel(index++, text, &scanning_view_))
       needs_relayout = true;
   }
@@ -619,36 +619,6 @@
   return needs_relayout;
 }
 
-void NetworkStateListDetailedView::UpdateMobileAccount() {
-  if (list_type_ != LIST_TYPE_NETWORK)
-    return;
-
-  view_mobile_account_->SetVisible(false);
-  setup_mobile_account_->SetVisible(false);
-
-  if (login_ == user::LOGGED_IN_NONE)
-    return;
-
-  // TODO(stevenjb): Migrate this code to src/chromeos.
-  std::string carrier_id, topup_url, setup_url;
-  if (Shell::GetInstance()->system_tray_delegate()->
-      GetCellularCarrierInfo(&carrier_id, &topup_url, &setup_url)) {
-    if (carrier_id != carrier_id_) {
-      carrier_id_ = carrier_id;
-      if (!topup_url.empty())
-        topup_url_ = topup_url;
-    }
-
-    if (!setup_url.empty())
-      setup_url_ = setup_url;
-
-    if (!topup_url_.empty())
-      view_mobile_account_->SetVisible(true);
-    if (!setup_url_.empty())
-      setup_mobile_account_->SetVisible(true);
-  }
-}
-
 void NetworkStateListDetailedView::UpdateNetworkExtra() {
   if (login_ == user::LOGGED_IN_LOCKED)
     return;
@@ -657,22 +627,34 @@
   NetworkStateHandler* handler = NetworkStateHandler::Get();
   if (other_wifi_) {
     DCHECK(turn_on_wifi_);
-    if (!handler->TechnologyAvailable(flimflam::kTypeWifi)) {
+    NetworkStateHandler::TechnologyState state =
+        handler->GetTechnologyState(flimflam::kTypeWifi);
+    if (state == NetworkStateHandler::TECHNOLOGY_UNAVAILABLE) {
       turn_on_wifi_->SetVisible(false);
       other_wifi_->SetVisible(false);
-    } else if (!handler->TechnologyEnabled(flimflam::kTypeWifi)) {
-      turn_on_wifi_->SetVisible(true);
-      other_wifi_->SetVisible(false);
     } else {
-      turn_on_wifi_->SetVisible(false);
-      other_wifi_->SetVisible(true);
+      if (state == NetworkStateHandler::TECHNOLOGY_AVAILABLE) {
+        turn_on_wifi_->SetVisible(true);
+        turn_on_wifi_->SetEnabled(true);
+        other_wifi_->SetVisible(false);
+      } else if (state == NetworkStateHandler::TECHNOLOGY_ENABLED) {
+        turn_on_wifi_->SetVisible(false);
+        other_wifi_->SetVisible(true);
+      } else {
+        // Initializing or Enabling
+        turn_on_wifi_->SetVisible(true);
+        turn_on_wifi_->SetEnabled(false);
+        other_wifi_->SetVisible(false);
+      }
     }
     layout_parent = other_wifi_->parent();
   }
 
   if (other_mobile_) {
     bool show_other_mobile = false;
-    if (handler->TechnologyAvailable(NetworkStateHandler::kMatchTypeMobile)) {
+    NetworkStateHandler::TechnologyState state =
+        handler->GetTechnologyState(NetworkStateHandler::kMatchTypeMobile);
+    if (state != NetworkStateHandler::TECHNOLOGY_UNAVAILABLE) {
       const chromeos::DeviceState* device =
           handler->GetDeviceStateByType(NetworkStateHandler::kMatchTypeMobile);
       show_other_mobile = (device && device->support_network_scan());
@@ -680,7 +662,7 @@
     if (show_other_mobile) {
       other_mobile_->SetVisible(true);
       other_mobile_->SetEnabled(
-          handler->TechnologyEnabled(NetworkStateHandler::kMatchTypeMobile));
+          state == NetworkStateHandler::TECHNOLOGY_ENABLED);
     } else {
       other_mobile_->SetVisible(false);
     }
@@ -784,7 +766,7 @@
   if (CommandLine::ForCurrentProcess()->HasSwitch(
           chromeos::switches::kUseNewNetworkConfigurationHandlers) &&
       !network->IsConnectedState()) {
-    handler->set_connecting_network(service_path);
+    handler->SetConnectingNetwork(service_path);
     chromeos::NetworkConfigurationHandler::Get()->Connect(
         service_path,
         base::Bind(&base::DoNothing),
@@ -797,6 +779,42 @@
   }
 }
 
+void NetworkStateListDetailedView::CallRequestScan() {
+  VLOG(1) << "Requesting Network Scan.";
+  NetworkStateHandler::Get()->RequestScan();
+  // Periodically request a scan while this UI is open.
+  base::MessageLoopForUI::current()->PostDelayedTask(
+      FROM_HERE,
+      base::Bind(&NetworkStateListDetailedView::CallRequestScan, AsWeakPtr()),
+      base::TimeDelta::FromSeconds(kRequestScanDelaySeconds));
+}
+
+void NetworkStateListDetailedView::ToggleMobile() {
+  NetworkStateHandler* handler = NetworkStateHandler::Get();
+  bool enabled =
+      handler->IsTechnologyEnabled(NetworkStateHandler::kMatchTypeMobile);
+  if (enabled) {
+    handler->SetTechnologyEnabled(
+        NetworkStateHandler::kMatchTypeMobile, false,
+        chromeos::network_handler::ErrorCallback());
+  } else {
+    const DeviceState* mobile =
+        handler->GetDeviceStateByType(NetworkStateHandler::kMatchTypeMobile);
+    if (!mobile) {
+      LOG(ERROR) << "Mobile device not found.";
+      return;
+    }
+    if (!mobile->sim_lock_type().empty() || mobile->IsSimAbsent()) {
+      // TODO(stevenjb): Rename ToggleMobile() to ShowMobileSimDialog()
+      // when NetworkListDetailedView is deprecated. crbug.com/222540.
+      ash::Shell::GetInstance()->system_tray_delegate()->ToggleMobile();
+    } else {
+      handler->SetTechnologyEnabled(
+          NetworkStateHandler::kMatchTypeMobile, true,
+          chromeos::network_handler::ErrorCallback());
+    }
+  }
+}
 
 }  // namespace tray
 }  // namespace internal
diff --git a/ash/system/chromeos/network/network_state_list_detailed_view.h b/ash/system/chromeos/network/network_state_list_detailed_view.h
index 212f699..b176dde 100644
--- a/ash/system/chromeos/network/network_state_list_detailed_view.h
+++ b/ash/system/chromeos/network/network_state_list_detailed_view.h
@@ -15,6 +15,7 @@
 #include "ash/system/tray/view_click_listener.h"
 #include "ash/system/user/login_status.h"
 #include "base/memory/scoped_vector.h"
+#include "base/memory/weak_ptr.h"
 #include "ui/views/controls/button/button.h"
 
 namespace chromeos {
@@ -38,10 +39,12 @@
 
 struct NetworkInfo;
 
-class NetworkStateListDetailedView : public NetworkDetailedView,
-                                     public views::ButtonListener,
-                                     public ViewClickListener,
-                                     public network_icon::AnimationObserver {
+class NetworkStateListDetailedView
+    : public NetworkDetailedView,
+      public views::ButtonListener,
+      public ViewClickListener,
+      public network_icon::AnimationObserver,
+      public base::SupportsWeakPtr<NetworkStateListDetailedView> {
  public:
   enum ListType {
     LIST_TYPE_NETWORK,
@@ -79,20 +82,20 @@
   // Create UI components.
   void CreateHeaderEntry();
   void CreateHeaderButtons();
-  void CreateMobileAccount();
   void CreateNetworkExtra();
 
   // Update UI components.
   void UpdateHeaderButtons();
+  void UpdateTechnologyButton(TrayPopupHeaderButton* button,
+                              const std::string& technology);
 
   void UpdateNetworks(const NetworkStateList& networks);
   void UpdateNetworkList();
   bool CreateOrUpdateInfoLabel(
-      int index, const string16& text, views::Label** label);
+      int index, const base::string16& text, views::Label** label);
   bool UpdateNetworkChild(int index, const NetworkInfo* info);
   bool OrderChild(views::View* view, int index);
   bool UpdateNetworkListEntries(std::set<std::string>* new_service_paths);
-  void UpdateMobileAccount();
   void UpdateNetworkExtra();
 
   // Adds a settings entry when logged in, and an entry for changing proxy
@@ -104,9 +107,15 @@
   bool ResetInfoBubble();
   views::View* CreateNetworkInfoView();
 
-  // Handle click (connect) action
+  // Handle click (connect) action.
   void ConnectToNetwork(const std::string& service_path);
 
+  // Periodically request a network scan.
+  void CallRequestScan();
+
+  // Handle toggile mobile action
+  void ToggleMobile();
+
   // Type of list (all networks or vpn)
   ListType list_type_;
 
@@ -122,17 +131,10 @@
   // An owned list of network info.
   ScopedVector<NetworkInfo> network_list_;
 
-  // Cached cellular carrier state info.
-  std::string carrier_id_;
-  std::string topup_url_;
-  std::string setup_url_;
-
   // Child views.
   TrayPopupHeaderButton* info_icon_;
   TrayPopupHeaderButton* button_wifi_;
   TrayPopupHeaderButton* button_mobile_;
-  views::View* view_mobile_account_;
-  views::View* setup_mobile_account_;
   TrayPopupLabelButton* other_wifi_;
   TrayPopupLabelButton* turn_on_wifi_;
   TrayPopupLabelButton* other_mobile_;
diff --git a/ash/system/chromeos/network/network_state_notifier.cc b/ash/system/chromeos/network/network_state_notifier.cc
index ba42c90..da4dec0 100644
--- a/ash/system/chromeos/network/network_state_notifier.cc
+++ b/ash/system/chromeos/network/network_state_notifier.cc
@@ -123,8 +123,13 @@
 }
 
 void NetworkStateNotifier::DefaultNetworkChanged(const NetworkState* network) {
-  if (network)
-    last_default_network_ = network->path();
+  if (!network || !network->IsConnectedState())
+    return;
+  if (network->path() != last_active_network_) {
+    last_active_network_ = network->path();
+    // Reset state for new connected network
+    cellular_out_of_credits_ = false;
+  }
 }
 
 void NetworkStateNotifier::NetworkConnectionStateChanged(
@@ -146,21 +151,13 @@
     cached_state_[network->path()] = new_state;
     return;  // New network, no state change
   }
-  bool notify_failure = false;
-  if (new_state == flimflam::kStateFailure &&
-      prev_state != flimflam::kStateIdle) {
-    // Note: Idle -> Failure sometimes happens on resume when the network
-    // device is not ready yet, but is not an actual failure.
-    notify_failure = true;
-  } else if (new_state == flimflam::kStateIdle &&
-             NetworkState::StateIsConnecting(prev_state) &&
-             network->path() == handler->connecting_network()) {
-    // Connecting -> Idle without an error shouldn't happen but sometimes does.
-    notify_failure = true;
-  }
-  if (!notify_failure)
+
+  if (new_state != flimflam::kStateFailure)
     return;
 
+  if (network->path() != handler->connecting_network())
+    return;  // Only show notifications for explicitly connected networks
+
   chromeos::network_event_log::AddEntry(
       kLogModule, "ConnectionFailure", network->path());
 
@@ -186,7 +183,7 @@
   // Trigger "Out of credits" notification if the cellular network is the most
   // recent default network (i.e. we have not switched to another network).
   if (network->type() == flimflam::kTypeCellular &&
-      network->path() == last_default_network_) {
+      network->path() == last_active_network_) {
     cellular_network_ = network->path();
     if (network->cellular_out_of_credits() &&
         !cellular_out_of_credits_) {
@@ -207,9 +204,6 @@
                 l10n_util::GetStringUTF16(IDS_NETWORK_OUT_OF_CREDITS_BODY),
                 links);
       }
-    } else if (!network->cellular_out_of_credits() &&
-               cellular_out_of_credits_) {
-      cellular_out_of_credits_ = false;
     }
   }
 }
@@ -241,8 +235,8 @@
   }
   const NetworkState* default_network =
       NetworkStateHandler::Get()->DefaultNetwork();
-  if (default_network)
-    last_default_network_ = default_network->path();
+  if (default_network && default_network->IsConnectedState())
+    last_active_network_ = default_network->path();
 }
 
 }  // namespace internal
diff --git a/ash/system/chromeos/network/network_state_notifier.h b/ash/system/chromeos/network/network_state_notifier.h
index 0832184..68a6eee 100644
--- a/ash/system/chromeos/network/network_state_notifier.h
+++ b/ash/system/chromeos/network/network_state_notifier.h
@@ -45,7 +45,7 @@
   void InitializeNetworks();
 
   CachedStateMap cached_state_;
-  std::string last_default_network_;
+  std::string last_active_network_;
   std::string cellular_network_;
   bool cellular_out_of_credits_;
   base::Time out_of_credits_notify_time_;
diff --git a/ash/system/chromeos/network/network_state_notifier_unittest.cc b/ash/system/chromeos/network/network_state_notifier_unittest.cc
index 3c3a386..fde1ad0 100644
--- a/ash/system/chromeos/network/network_state_notifier_unittest.cc
+++ b/ash/system/chromeos/network/network_state_notifier_unittest.cc
@@ -6,6 +6,7 @@
 
 #include "ash/root_window_controller.h"
 #include "ash/shelf/shelf_widget.h"
+#include "ash/shell.h"
 #include "ash/system/status_area_widget.h"
 #include "ash/system/tray/system_tray.h"
 #include "ash/test/ash_test_base.h"
@@ -90,7 +91,12 @@
 
 TEST_F(NetworkStateNotifierTest, ConnectionFailure) {
   EXPECT_FALSE(GetSystemTray()->HasNotificationBubble());
-  // Connected -> Failure should spawn a notification
+  // State -> Failure for non connecting network should not spawn a notification
+  SetServiceState("wifi1", flimflam::kStateFailure);
+  EXPECT_FALSE(GetSystemTray()->CloseNotificationBubbleForTest());
+  // State -> Failure for connecting network should spawn a notification
+  SetServiceState("wifi1", flimflam::kStateAssociation);
+  NetworkStateHandler::Get()->SetConnectingNetwork("wifi1");
   SetServiceState("wifi1", flimflam::kStateFailure);
   EXPECT_TRUE(GetSystemTray()->CloseNotificationBubbleForTest());
   // Failure -> Idle should not spawn a notification
diff --git a/ash/system/chromeos/network/tray_network.cc b/ash/system/chromeos/network/tray_network.cc
index 90e66b1..eabb74d 100644
--- a/ash/system/chromeos/network/tray_network.cc
+++ b/ash/system/chromeos/network/tray_network.cc
@@ -19,6 +19,7 @@
 #include "ash/system/tray/tray_item_more.h"
 #include "ash/system/tray/tray_item_view.h"
 #include "ash/system/tray/tray_notification_view.h"
+#include "ash/system/tray/tray_utils.h"
 #include "base/command_line.h"
 #include "base/utf_string_conversions.h"
 #include "chromeos/network/network_state.h"
@@ -29,6 +30,7 @@
 #include "ui/base/accessibility/accessible_view_state.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
+#include "ui/views/controls/image_view.h"
 #include "ui/views/controls/link.h"
 #include "ui/views/controls/link_listener.h"
 #include "ui/views/layout/box_layout.h"
@@ -79,9 +81,9 @@
     Message() : delegate(NULL) {}
     Message(NetworkTrayDelegate* in_delegate,
             NetworkObserver::NetworkType network_type,
-            const string16& in_title,
-            const string16& in_message,
-            const std::vector<string16>& in_links) :
+            const base::string16& in_title,
+            const base::string16& in_message,
+            const std::vector<base::string16>& in_links) :
         delegate(in_delegate),
         network_type_(network_type),
         title(in_title),
@@ -89,9 +91,9 @@
         links(in_links) {}
     NetworkTrayDelegate* delegate;
     NetworkObserver::NetworkType network_type_;
-    string16 title;
-    string16 message;
-    std::vector<string16> links;
+    base::string16 title;
+    base::string16 message;
+    std::vector<base::string16> links;
   };
   typedef std::map<NetworkObserver::MessageType, Message> MessageMap;
 
@@ -117,7 +119,6 @@
     NetworkIconInfo info;
     if (UseNewNetworkHandlers()) {
       UpdateNetworkStateHandlerIcon();
-      network_icon::NetworkIconAnimation::GetInstance()->AddObserver(this);
     } else {
       Shell::GetInstance()->system_tray_delegate()->
           GetMostRelevantNetworkIcon(&info, false);
@@ -130,6 +131,8 @@
       network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this);
   }
 
+  std::string GetClassName() const { return "NetworkTrayView"; }
+
   void Update(const NetworkIconInfo& info) {
     if (UseNewNetworkHandlers())
       return;
@@ -141,17 +144,23 @@
     DCHECK(UseNewNetworkHandlers());
     NetworkStateHandler* handler = NetworkStateHandler::Get();
     gfx::ImageSkia image;
-    string16 name;
+    base::string16 name;
+    bool animating = false;
     network_tray_->GetNetworkStateHandlerImageAndLabel(
-        network_icon::ICON_TYPE_TRAY, &image, &name);
+        network_icon::ICON_TYPE_TRAY, &image, &name, &animating);
     bool show_in_tray = !image.isNull();
     UpdateIcon(show_in_tray, image);
+    if (animating)
+      network_icon::NetworkIconAnimation::GetInstance()->AddObserver(this);
+    else
+      network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this);
+    // Update accessibility.
     const NetworkState* connected_network = handler->ConnectedNetworkByType(
         NetworkStateHandler::kMatchTypeNonVirtual);
     if (connected_network)
       UpdateConnectionStatus(UTF8ToUTF16(connected_network->name()), true);
     else
-      UpdateConnectionStatus(string16(), false);
+      UpdateConnectionStatus(base::string16(), false);
   }
 
   // views::View override.
@@ -168,18 +177,17 @@
 
  private:
   // Updates connection status and notifies accessibility event when necessary.
-  void UpdateConnectionStatus(const string16& network_name, bool connected) {
-    string16 new_connection_status_string;
+  void UpdateConnectionStatus(const base::string16& network_name,
+                              bool connected) {
+    base::string16 new_connection_status_string;
     if (connected) {
       new_connection_status_string = l10n_util::GetStringFUTF16(
           IDS_ASH_STATUS_TRAY_NETWORK_CONNECTED, network_name);
     }
     if (new_connection_status_string != connection_status_string_) {
       connection_status_string_ = new_connection_status_string;
-      if(!connection_status_string_.empty()) {
-        GetWidget()->NotifyAccessibilityEvent(
-            this, ui::AccessibilityTypes::EVENT_ALERT, true);
-      }
+      if(!connection_status_string_.empty())
+        NotifyAccessibilityEvent(ui::AccessibilityTypes::EVENT_ALERT, true);
     }
   }
 
@@ -191,7 +199,7 @@
 
   TrayNetwork* network_tray_;
   views::ImageView* image_view_;
-  string16 connection_status_string_;
+  base::string16 connection_status_string_;
 
   DISALLOW_COPY_AND_ASSIGN(NetworkTrayView);
 };
@@ -203,8 +211,6 @@
       : TrayItemMore(network_tray, show_more),
         network_tray_(network_tray) {
     Update();
-    if (UseNewNetworkHandlers())
-      network_icon::NetworkIconAnimation::GetInstance()->AddObserver(this);
   }
 
   virtual ~NetworkDefaultView() {
@@ -215,9 +221,14 @@
   void Update() {
     if (UseNewNetworkHandlers()) {
       gfx::ImageSkia image;
-      string16 label;
+      base::string16 label;
+      bool animating = false;
       network_tray_->GetNetworkStateHandlerImageAndLabel(
-          network_icon::ICON_TYPE_DEFAULT_VIEW, &image, &label);
+          network_icon::ICON_TYPE_DEFAULT_VIEW, &image, &label, &animating);
+      if (animating)
+        network_icon::NetworkIconAnimation::GetInstance()->AddObserver(this);
+      else
+        network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this);
       SetImage(&image);
       SetLabel(label);
       SetAccessibleName(label);
@@ -501,9 +512,9 @@
 void TrayNetwork::SetNetworkMessage(NetworkTrayDelegate* delegate,
                                     MessageType message_type,
                                     NetworkType network_type,
-                                    const string16& title,
-                                    const string16& message,
-                                    const std::vector<string16>& links) {
+                                    const base::string16& title,
+                                    const base::string16& message,
+                                    const std::vector<base::string16>& links) {
   messages_->messages()[message_type] = tray::NetworkMessages::Message(
       delegate, network_type, title, message, links);
   if (!Shell::GetInstance()->system_tray_delegate()->IsOobeCompleted())
@@ -556,7 +567,8 @@
 void TrayNetwork::GetNetworkStateHandlerImageAndLabel(
     network_icon::IconType icon_type,
     gfx::ImageSkia* image,
-    string16* label) {
+    base::string16* label,
+    bool* animating) {
   NetworkStateHandler* handler = NetworkStateHandler::Get();
   const NetworkState* connected_network = handler->ConnectedNetworkByType(
       NetworkStateHandler::kMatchTypeNonVirtual);
@@ -581,6 +593,7 @@
   if (icon_type == network_icon::ICON_TYPE_TRAY &&
       network && network->type() == flimflam::kTypeEthernet) {
     *image = gfx::ImageSkia();
+    *animating = false;
     return;
   }
 
@@ -601,6 +614,7 @@
           icon_type, flimflam::kTypeCellular);
       if (label)
         *label = l10n_util::GetStringUTF16(uninitialized_msg);
+      *animating = true;
     } else {
       // Otherwise show the disconnected wifi icon.
       *image = network_icon::GetImageForDisconnectedNetwork(
@@ -609,9 +623,11 @@
         *label = l10n_util::GetStringUTF16(
             IDS_ASH_STATUS_TRAY_NETWORK_NOT_CONNECTED);
       }
+      *animating = false;
     }
     return;
   }
+  *animating = network->IsConnectingState();
   // Get icon and label for connected or connecting network.
   *image = network_icon::GetImageForNetwork(network, icon_type);
   if (label)
diff --git a/ash/system/chromeos/network/tray_network.h b/ash/system/chromeos/network/tray_network.h
index 241154e..42aefc4 100644
--- a/ash/system/chromeos/network/tray_network.h
+++ b/ash/system/chromeos/network/tray_network.h
@@ -59,12 +59,13 @@
 
   // NetworkObserver
   virtual void OnNetworkRefresh(const NetworkIconInfo& info) OVERRIDE;
-  virtual void SetNetworkMessage(NetworkTrayDelegate* delegate,
-                                 MessageType message_type,
-                                 NetworkType network_type,
-                                 const string16& title,
-                                 const string16& message,
-                                 const std::vector<string16>& links) OVERRIDE;
+  virtual void SetNetworkMessage(
+      NetworkTrayDelegate* delegate,
+      MessageType message_type,
+      NetworkType network_type,
+      const base::string16& title,
+      const base::string16& message,
+      const std::vector<base::string16>& links) OVERRIDE;
   virtual void ClearNetworkMessage(MessageType message_type) OVERRIDE;
   virtual void OnWillToggleWifi() OVERRIDE;
 
@@ -73,12 +74,14 @@
   virtual void NetworkServiceChanged(
       const chromeos::NetworkState* network) OVERRIDE;
 
-  // Gets the correct icon and label for |icon_type|.
+  // Gets the correct icon and label for |icon_type|. Also sets |animating|
+  // based on whether or not the icon is animating (i.e. connecting).
   void GetNetworkStateHandlerImageAndLabel(network_icon::IconType icon_type,
                                            gfx::ImageSkia* image,
-                                           string16* label);
+                                           base::string16* label,
+                                           bool* animating);
 
-private:
+ private:
   friend class tray::NetworkMessageView;
   friend class tray::NetworkNotificationView;
 
diff --git a/ash/system/chromeos/network/tray_network_state_observer.cc b/ash/system/chromeos/network/tray_network_state_observer.cc
index 2b94540..d829a23 100644
--- a/ash/system/chromeos/network/tray_network_state_observer.cc
+++ b/ash/system/chromeos/network/tray_network_state_observer.cc
@@ -42,6 +42,8 @@
 
 void TrayNetworkStateObserver::NetworkPropertiesUpdated(
     const chromeos::NetworkState* network) {
+  if (network == chromeos::NetworkStateHandler::Get()->DefaultNetwork())
+    delegate_->NetworkStateChanged(true);
   delegate_->NetworkServiceChanged(network);
 }
 
diff --git a/ash/system/chromeos/network/tray_sms.cc b/ash/system/chromeos/network/tray_sms.cc
index 57d9ce6..2eabe71 100644
--- a/ash/system/chromeos/network/tray_sms.cc
+++ b/ash/system/chromeos/network/tray_sms.cc
@@ -16,7 +16,7 @@
 #include "ash/system/tray/tray_item_view.h"
 #include "ash/system/tray/tray_notification_view.h"
 #include "base/command_line.h"
-#include "base/string_number_conversions.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/utf_string_conversions.h"
 #include "grit/ash_resources.h"
 #include "grit/ash_strings.h"
@@ -65,7 +65,7 @@
 
   void Update() {
     int message_count = static_cast<TraySms*>(owner())->messages().GetSize();
-    string16 label = l10n_util::GetStringFUTF16(
+    base::string16 label = l10n_util::GetStringFUTF16(
         IDS_ASH_STATUS_TRAY_SMS_MESSAGES, base::IntToString16(message_count));
     SetLabel(label);
     SetAccessibleName(label);
diff --git a/ash/system/chromeos/network/tray_vpn.cc b/ash/system/chromeos/network/tray_vpn.cc
index 8f93b78..05f0596 100644
--- a/ash/system/chromeos/network/tray_vpn.cc
+++ b/ash/system/chromeos/network/tray_vpn.cc
@@ -14,6 +14,7 @@
 #include "ash/system/tray/system_tray_notifier.h"
 #include "ash/system/tray/tray_constants.h"
 #include "ash/system/tray/tray_item_more.h"
+#include "ash/system/tray/tray_popup_label_button.h"
 #include "base/command_line.h"
 #include "chromeos/network/network_state.h"
 #include "chromeos/network/network_state_handler.h"
@@ -46,8 +47,6 @@
   VpnDefaultView(SystemTrayItem* owner, bool show_more)
       : TrayItemMore(owner, show_more) {
     Update();
-    if (UseNewNetworkHandlers())
-      network_icon::NetworkIconAnimation::GetInstance()->AddObserver(this);
   }
 
   virtual ~VpnDefaultView() {
@@ -72,8 +71,13 @@
   void Update() {
     if (UseNewNetworkHandlers()) {
       gfx::ImageSkia image;
-      string16 label;
-      GetNetworkStateHandlerImageAndLabel(&image, &label);
+      base::string16 label;
+      bool animating = false;
+      GetNetworkStateHandlerImageAndLabel(&image, &label, &animating);
+      if (animating)
+        network_icon::NetworkIconAnimation::GetInstance()->AddObserver(this);
+      else
+        network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this);
       SetImage(&image);
       SetLabel(label);
       SetAccessibleName(label);
@@ -94,7 +98,8 @@
 
  private:
   void GetNetworkStateHandlerImageAndLabel(gfx::ImageSkia* image,
-                                           string16* label) {
+                                           base::string16* label,
+                                           bool* animating) {
     NetworkStateHandler* handler = NetworkStateHandler::Get();
     const NetworkState* vpn = handler->FirstNetworkByType(
         flimflam::kTypeVPN);
@@ -105,8 +110,10 @@
         *label = l10n_util::GetStringUTF16(
             IDS_ASH_STATUS_TRAY_VPN_DISCONNECTED);
       }
+      *animating = false;
       return;
     }
+    *animating = vpn->IsConnectingState();
     *image = network_icon::GetImageForNetwork(
         vpn, network_icon::ICON_TYPE_DEFAULT_VIEW);
     if (label) {
@@ -303,9 +310,9 @@
 void TrayVPN::SetNetworkMessage(NetworkTrayDelegate* delegate,
                                    MessageType message_type,
                                    NetworkType network_type,
-                                   const string16& title,
-                                   const string16& message,
-                                   const std::vector<string16>& links) {
+                                   const base::string16& title,
+                                   const base::string16& message,
+                                   const std::vector<base::string16>& links) {
 }
 
 void TrayVPN::ClearNetworkMessage(MessageType message_type) {
diff --git a/ash/system/chromeos/network/tray_vpn.h b/ash/system/chromeos/network/tray_vpn.h
index 446f693..052c52e 100644
--- a/ash/system/chromeos/network/tray_vpn.h
+++ b/ash/system/chromeos/network/tray_vpn.h
@@ -44,12 +44,13 @@
 
   // NetworkObserver
   virtual void OnNetworkRefresh(const NetworkIconInfo& info) OVERRIDE;
-  virtual void SetNetworkMessage(NetworkTrayDelegate* delegate,
-                                 MessageType message_type,
-                                 NetworkType network_type,
-                                 const string16& title,
-                                 const string16& message,
-                                 const std::vector<string16>& links) OVERRIDE;
+  virtual void SetNetworkMessage(
+      NetworkTrayDelegate* delegate,
+      MessageType message_type,
+      NetworkType network_type,
+      const base::string16& title,
+      const base::string16& message,
+      const std::vector<base::string16>& links) OVERRIDE;
   virtual void ClearNetworkMessage(MessageType message_type) OVERRIDE;
   virtual void OnWillToggleWifi() OVERRIDE;
 
diff --git a/ash/system/chromeos/screen_capture/screen_capture_observer.h b/ash/system/chromeos/screen_capture/screen_capture_observer.h
index 2b22d64..9d1efd3 100644
--- a/ash/system/chromeos/screen_capture/screen_capture_observer.h
+++ b/ash/system/chromeos/screen_capture/screen_capture_observer.h
@@ -13,8 +13,9 @@
 class ScreenCaptureObserver {
  public:
   // Called when screen capture is started.
-  virtual void OnScreenCaptureStart(const base::Closure& stop_callback,
-                                    const string16& screen_capture_status) = 0;
+  virtual void OnScreenCaptureStart(
+      const base::Closure& stop_callback,
+      const base::string16& screen_capture_status) = 0;
   // Called when screen capture is stopped.
   virtual void OnScreenCaptureStop() = 0;
 
diff --git a/ash/system/chromeos/screen_capture/tray_screen_capture.cc b/ash/system/chromeos/screen_capture/tray_screen_capture.cc
index a05db79..660199c 100644
--- a/ash/system/chromeos/screen_capture/tray_screen_capture.cc
+++ b/ash/system/chromeos/screen_capture/tray_screen_capture.cc
@@ -11,7 +11,7 @@
 #include "ash/system/tray/tray_constants.h"
 #include "ash/system/tray/tray_item_view.h"
 #include "ash/system/tray/tray_notification_view.h"
-#include "ash/system/tray/tray_views.h"
+#include "ash/system/tray/tray_popup_label_button.h"
 #include "grit/ash_resources.h"
 #include "grit/ash_strings.h"
 #include "ui/base/resource/resource_bundle.h"
@@ -250,7 +250,7 @@
 
 void TrayScreenCapture::OnScreenCaptureStart(
     const base::Closure& stop_callback,
-    const string16& screen_capture_status) {
+    const base::string16& screen_capture_status) {
   stop_callback_ = stop_callback;
   screen_capture_status_ = screen_capture_status;
   set_screen_capture_on(true);
diff --git a/ash/system/chromeos/screen_capture/tray_screen_capture.h b/ash/system/chromeos/screen_capture/tray_screen_capture.h
index cb5b91f..3fc0b2f 100644
--- a/ash/system/chromeos/screen_capture/tray_screen_capture.h
+++ b/ash/system/chromeos/screen_capture/tray_screen_capture.h
@@ -30,7 +30,7 @@
   void Update();
   bool screen_capture_on() const { return screen_capture_on_; }
   void set_screen_capture_on(bool value) { screen_capture_on_ = value; }
-  const string16& screen_capture_status() const {
+  const base::string16& screen_capture_status() const {
     return screen_capture_status_;
   }
   void StopScreenCapture();
@@ -48,13 +48,13 @@
   // Overridden from ScreenCaptureObserver.
   virtual void OnScreenCaptureStart(
       const base::Closure& stop_callback,
-      const string16& screen_capture_status) OVERRIDE;
+      const base::string16& screen_capture_status) OVERRIDE;
   virtual void OnScreenCaptureStop() OVERRIDE;
 
   tray::ScreenCaptureTrayView* tray_;
   tray::ScreenCaptureStatusView* default_;
   tray::ScreenCaptureNotificationView* notification_;
-  string16 screen_capture_status_;
+  base::string16 screen_capture_status_;
   bool screen_capture_on_;
   base::Closure stop_callback_;
 
diff --git a/ash/system/chromeos/tray_display.cc b/ash/system/chromeos/tray_display.cc
index cbe35a0..5c19dfb 100644
--- a/ash/system/chromeos/tray_display.cc
+++ b/ash/system/chromeos/tray_display.cc
@@ -12,7 +12,6 @@
 #include "ash/system/tray/system_tray.h"
 #include "ash/system/tray/system_tray_delegate.h"
 #include "ash/system/tray/tray_constants.h"
-#include "ash/system/tray/tray_views.h"
 #include "base/chromeos/chromeos_version.h"
 #include "base/utf_string_conversions.h"
 #include "grit/ash_resources.h"
@@ -58,6 +57,9 @@
   virtual ~DisplayView() {}
 
   void Update() {
+#if !defined(USE_X11)
+     SetVisible(false);
+#else
     chromeos::OutputState state =
         base::chromeos::IsRunningOnChromeOS() ?
         Shell::GetInstance()->output_configurator()->output_state() :
@@ -68,22 +70,19 @@
       case chromeos::STATE_SINGLE:
         SetVisible(false);
         return;
-      case chromeos::STATE_DUAL_MIRROR: {
+      case chromeos::STATE_DUAL_MIRROR:
         label_->SetText(l10n_util::GetStringFUTF16(
             IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING, GetExternalDisplayName()));
         SetVisible(true);
         return;
-      }
       case chromeos::STATE_DUAL_EXTENDED:
-      case chromeos::STATE_DUAL_UNKNOWN: {
         label_->SetText(l10n_util::GetStringFUTF16(
             IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED, GetExternalDisplayName()));
         SetVisible(true);
         return;
-      }
-      default:
-        NOTREACHED();
     }
+    NOTREACHED() << "Unhandled state " << state;
+#endif
   }
 
   chromeos::OutputState InferOutputState() const {
@@ -93,7 +92,7 @@
 
  private:
   // Returns the name of the currently connected external display.
-  string16 GetExternalDisplayName() const {
+  base::string16 GetExternalDisplayName() const {
     DisplayManager* display_manager = Shell::GetInstance()->display_manager();
     int64 external_id = display_manager->mirrored_display_id();
 
@@ -142,12 +141,16 @@
     : SystemTrayItem(system_tray),
       default_(NULL) {
   Shell::GetScreen()->AddObserver(this);
+#if defined(USE_X11)
   Shell::GetInstance()->output_configurator()->AddObserver(this);
+#endif
 }
 
 TrayDisplay::~TrayDisplay() {
   Shell::GetScreen()->RemoveObserver(this);
+#if defined(USE_X11)
   Shell::GetInstance()->output_configurator()->RemoveObserver(this);
+#endif
 }
 
 views::View* TrayDisplay::CreateDefaultView(user::LoginStatus status) {
diff --git a/ash/system/date/date_view.cc b/ash/system/date/date_view.cc
index 8de730c..4eabea8 100644
--- a/ash/system/date/date_view.cc
+++ b/ash/system/date/date_view.cc
@@ -7,7 +7,7 @@
 #include "ash/shell.h"
 #include "ash/system/tray/system_tray_delegate.h"
 #include "ash/system/tray/tray_constants.h"
-#include "ash/system/tray/tray_views.h"
+#include "ash/system/tray/tray_utils.h"
 #include "base/i18n/time_formatting.h"
 #include "base/time.h"
 #include "base/utf_string_conversions.h"
@@ -34,16 +34,16 @@
 // Top number text color of vertical clock.
 const SkColor kVerticalClockHourColor = SkColorSetRGB(0xBA, 0xBA, 0xBA);
 
-string16 FormatDate(const base::Time& time) {
+base::string16 FormatDate(const base::Time& time) {
   icu::UnicodeString date_string;
   scoped_ptr<icu::DateFormat> formatter(
       icu::DateFormat::createDateInstance(icu::DateFormat::kMedium));
   formatter->format(static_cast<UDate>(time.ToDoubleT() * 1000), date_string);
-  return string16(date_string.getBuffer(),
+  return base::string16(date_string.getBuffer(),
                   static_cast<size_t>(date_string.length()));
 }
 
-string16 FormatDayOfWeek(const base::Time& time) {
+base::string16 FormatDayOfWeek(const base::Time& time) {
   UErrorCode status = U_ZERO_ERROR;
   scoped_ptr<icu::DateTimePatternGenerator> generator(
       icu::DateTimePatternGenerator::createInstance(status));
@@ -58,7 +58,7 @@
   simple_formatter.format(
       static_cast<UDate>(time.ToDoubleT() * 1000), date_string, status);
   DCHECK(U_SUCCESS(status));
-  return string16(
+  return base::string16(
       date_string.getBuffer(), static_cast<size_t>(date_string.length()));
 }
 
@@ -196,15 +196,15 @@
     return;
   }
 
-  string16 current_time = base::TimeFormatTimeOfDayWithHourClockType(
+  base::string16 current_time = base::TimeFormatTimeOfDayWithHourClockType(
       now, hour_type_, base::kDropAmPm);
   label_->SetText(current_time);
   label_->SetTooltipText(base::TimeFormatFriendlyDate(now));
 
   // Calculate vertical clock layout labels.
   size_t colon_pos = current_time.find(ASCIIToUTF16(":"));
-  string16 hour = current_time.substr(0, colon_pos);
-  string16 minute = current_time.substr(colon_pos + 1);
+  base::string16 hour = current_time.substr(0, colon_pos);
+  base::string16 minute = current_time.substr(colon_pos + 1);
   label_hour_left_->SetText(hour.substr(0, 1));
   label_hour_right_->SetText(hour.length() == 2 ?
       hour.substr(1,1) : ASCIIToUTF16(":"));
diff --git a/ash/system/date/tray_date.cc b/ash/system/date/tray_date.cc
index 8c69ece..34edabb 100644
--- a/ash/system/date/tray_date.cc
+++ b/ash/system/date/tray_date.cc
@@ -4,6 +4,7 @@
 
 #include "ash/system/date/tray_date.h"
 
+#include "ash/session_state_delegate.h"
 #include "ash/shell.h"
 #include "ash/shell_delegate.h"
 #include "ash/system/date/date_view.h"
@@ -12,7 +13,7 @@
 #include "ash/system/tray/system_tray_notifier.h"
 #include "ash/system/tray/tray_constants.h"
 #include "ash/system/tray/tray_item_view.h"
-#include "ash/system/tray/tray_views.h"
+#include "ash/system/tray/tray_popup_header_button.h"
 #include "base/i18n/time_formatting.h"
 #include "base/stringprintf.h"
 #include "base/time.h"
@@ -89,7 +90,7 @@
       view->AddButton(shutdown_);
     }
 
-    if (ash::Shell::GetInstance()->CanLockScreen()) {
+    if (ash::Shell::GetInstance()->session_state_delegate()->CanLockScreen()) {
       lock_ = new ash::internal::TrayPopupHeaderButton(this,
           IDR_AURA_UBER_TRAY_LOCKSCREEN,
           IDR_AURA_UBER_TRAY_LOCKSCREEN,
diff --git a/ash/system/drive/drive_observer.h b/ash/system/drive/drive_observer.h
index 0b9598a..a721dd4 100644
--- a/ash/system/drive/drive_observer.h
+++ b/ash/system/drive/drive_observer.h
@@ -11,7 +11,7 @@
 
 class DriveObserver {
  public:
-  virtual void OnDriveRefresh(const DriveOperationStatusList& list) = 0;
+  virtual void OnDriveJobUpdated(const DriveOperationStatus& status) = 0;
 
  protected:
   virtual ~DriveObserver() {}
diff --git a/ash/system/drive/tray_drive.cc b/ash/system/drive/tray_drive.cc
index a12345a..ed68395 100644
--- a/ash/system/drive/tray_drive.cc
+++ b/ash/system/drive/tray_drive.cc
@@ -18,7 +18,7 @@
 #include "ash/system/tray/tray_item_view.h"
 #include "base/logging.h"
 #include "base/stl_util.h"
-#include "base/string_number_conversions.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/utf_string_conversions.h"
 #include "grit/ash_resources.h"
 #include "grit/ash_strings.h"
@@ -27,6 +27,7 @@
 #include "ui/gfx/font.h"
 #include "ui/gfx/image/image.h"
 #include "ui/views/controls/button/image_button.h"
+#include "ui/views/controls/image_view.h"
 #include "ui/views/controls/label.h"
 #include "ui/views/controls/progress_bar.h"
 #include "ui/views/layout/box_layout.h"
@@ -48,17 +49,18 @@
 const int kProgressBarHeight = 11;
 const int64 kHideDelayInMs = 1000;
 
-string16 GetTrayLabel(const ash::DriveOperationStatusList& list) {
+base::string16 GetTrayLabel(const ash::DriveOperationStatusList& list) {
   return l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_DRIVE_SYNCING,
       base::IntToString16(static_cast<int>(list.size())));
 }
 
-ash::DriveOperationStatusList* GetCurrentOperationList() {
+scoped_ptr<ash::DriveOperationStatusList> GetCurrentOperationList() {
   ash::SystemTrayDelegate* delegate =
       ash::Shell::GetInstance()->system_tray_delegate();
-  ash::DriveOperationStatusList* list = new ash::DriveOperationStatusList();
-  delegate->GetDriveOperationStatusList(list);
-  return list;
+  scoped_ptr<ash::DriveOperationStatusList> list(
+      new ash::DriveOperationStatusList);
+  delegate->GetDriveOperationStatusList(list.get());
+  return list.Pass();
 }
 
 }
@@ -80,7 +82,7 @@
 
   void Update(const DriveOperationStatusList* list) {
     DCHECK(list);
-    string16 label = GetTrayLabel(*list);
+    base::string16 label = GetTrayLabel(*list);
     SetLabel(label);
     SetAccessibleName(label);
   }
@@ -142,14 +144,15 @@
     RowView(DriveDetailedView* parent,
             ash::DriveOperationStatus::OperationState state,
             double progress,
-            const base::FilePath& file_path)
+            const base::FilePath& file_path,
+            int32 operation_id)
         : HoverHighlightView(parent),
           container_(parent),
           status_img_(NULL),
           label_container_(NULL),
           progress_bar_(NULL),
           cancel_button_(NULL),
-          file_path_(file_path) {
+          operation_id_(operation_id) {
       // Status image.
       status_img_ = new views::ImageView();
       AddChildView(status_img_);
@@ -158,11 +161,9 @@
       label_container_->SetLayoutManager(new views::BoxLayout(
           views::BoxLayout::kVertical, 0, 0, kVerticalPadding));
 #if defined(OS_POSIX)
-      string16 file_label =
-          UTF8ToUTF16(file_path.BaseName().value());
+      base::string16 file_label = UTF8ToUTF16(file_path.BaseName().value());
 #elif defined(OS_WIN)
-      string16 file_label =
-          WideToUTF16(file_path.BaseName().value());
+      base::string16 file_label = WideToUTF16(file_path.BaseName().value());
 #endif
       views::Label* label = new views::Label(file_label);
       label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
@@ -190,8 +191,8 @@
       status_img_->SetImage(container_->GetImageForState(state));
       progress_bar_->SetValue(progress);
       cancel_button_->SetVisible(
-          state == ash::DriveOperationStatus::OPERATION_IN_PROGRESS ||
-          state == ash::DriveOperationStatus::OPERATION_SUSPENDED);
+          state == ash::DriveOperationStatus::OPERATION_NOT_STARTED ||
+          state == ash::DriveOperationStatus::OPERATION_IN_PROGRESS);
     }
 
    private:
@@ -252,7 +253,7 @@
     virtual void ButtonPressed(views::Button* sender,
                                const ui::Event& event) OVERRIDE {
       DCHECK(sender == cancel_button_);
-      container_->OnCancelOperation(file_path_);
+      container_->OnCancelOperation(operation_id_);
     }
 
     DriveDetailedView* container_;
@@ -260,7 +261,7 @@
     views::View* label_container_;
     views::ProgressBar* progress_bar_;
     views::ImageButton* cancel_button_;
-    base::FilePath file_path_;
+    int32 operation_id_;
 
     DISALLOW_COPY_AND_ASSIGN(RowView);
   };
@@ -275,9 +276,7 @@
       ash::DriveOperationStatus::OperationState state) {
     switch (state) {
       case ash::DriveOperationStatus::OPERATION_NOT_STARTED:
-      case ash::DriveOperationStatus::OPERATION_STARTED:
       case ash::DriveOperationStatus::OPERATION_IN_PROGRESS:
-      case ash::DriveOperationStatus::OPERATION_SUSPENDED:
         return in_progress_img_;
       case ash::DriveOperationStatus::OPERATION_COMPLETED:
         return done_img_;
@@ -287,9 +286,9 @@
     return failed_img_;
   }
 
-  virtual void OnCancelOperation(const base::FilePath& file_path) {
+  void OnCancelOperation(int32 operation_id) {
     SystemTrayDelegate* delegate = Shell::GetInstance()->system_tray_delegate();
-    delegate->CancelDriveOperation(file_path);
+    delegate->CancelDriveOperation(operation_id);
   }
 
   void AppendOperationList(const DriveOperationStatusList* list) {
@@ -314,7 +313,8 @@
         RowView* row_view = new RowView(this,
                                         operation.state,
                                         operation.progress,
-                                        operation.file_path);
+                                        operation.file_path,
+                                        operation.id);
 
         update_map_[operation.file_path] = row_view;
         scroll_content()->AddChildView(row_view);
@@ -447,9 +447,39 @@
   DestroyDetailedView();
 }
 
-void TrayDrive::OnDriveRefresh(const DriveOperationStatusList& list) {
-  if (list.empty()) {
-    // If the list becomes empty, the tray item will be hidden after a certain
+void TrayDrive::OnDriveJobUpdated(const DriveOperationStatus& status) {
+  // The Drive job list manager changed its notification interface *not* to send
+  // the whole list of operations each time, to clarify which operation is
+  // updated and to reduce redundancy.
+  //
+  // TrayDrive should be able to benefit from the change, but for now, to
+  // incrementally migrate to the new way with minimum diffs, we still get the
+  // list of operations each time the event is fired.
+  // TODO(kinaba) http://crbug.com/128079 clean it up.
+  scoped_ptr<DriveOperationStatusList> list(GetCurrentOperationList());
+  bool is_new_item = true;
+  for (size_t i = 0; i < list->size(); ++i) {
+    if ((*list)[i].id == status.id) {
+      (*list)[i] = status;
+      is_new_item = false;
+      break;
+    }
+  }
+  if (is_new_item)
+    list->push_back(status);
+
+  // Check if all the operations are in the finished state.
+  bool all_jobs_finished = true;
+  for (size_t i = 0; i < list->size(); ++i) {
+    if ((*list)[i].state != DriveOperationStatus::OPERATION_COMPLETED &&
+        (*list)[i].state != DriveOperationStatus::OPERATION_FAILED) {
+      all_jobs_finished = false;
+      break;
+    }
+  }
+
+  if (all_jobs_finished) {
+    // If all the jobs ended, the tray item will be hidden after a certain
     // amount of delay. This is to avoid flashes between sequentially executed
     // Drive operations (see crbug/165679).
     hide_timer_.Start(FROM_HERE,
@@ -464,9 +494,9 @@
 
   tray_view()->SetVisible(true);
   if (default_)
-    default_->Update(&list);
+    default_->Update(list.get());
   if (detailed_)
-    detailed_->Update(&list);
+    detailed_->Update(list.get());
 }
 
 void TrayDrive::HideIfNoOperations() {
diff --git a/ash/system/drive/tray_drive.h b/ash/system/drive/tray_drive.h
index f451800..9680c99 100644
--- a/ash/system/drive/tray_drive.h
+++ b/ash/system/drive/tray_drive.h
@@ -40,7 +40,7 @@
   virtual void UpdateAfterLoginStatusChange(user::LoginStatus status) OVERRIDE;
 
   // Overridden from DriveObserver.
-  virtual void OnDriveRefresh(const DriveOperationStatusList& list) OVERRIDE;
+  virtual void OnDriveJobUpdated(const DriveOperationStatus& status) OVERRIDE;
 
   // Delayed hiding of the tray item after encountering an empty operation list.
   void HideIfNoOperations();
diff --git a/ash/system/ime/tray_ime.cc b/ash/system/ime/tray_ime.cc
index c931f46..272f974 100644
--- a/ash/system/ime/tray_ime.cc
+++ b/ash/system/ime/tray_ime.cc
@@ -18,6 +18,7 @@
 #include "ash/system/tray/tray_item_more.h"
 #include "ash/system/tray/tray_item_view.h"
 #include "ash/system/tray/tray_notification_view.h"
+#include "ash/system/tray/tray_utils.h"
 #include "base/logging.h"
 #include "base/timer.h"
 #include "base/utf_string_conversions.h"
diff --git a/ash/system/locale/tray_locale.cc b/ash/system/locale/tray_locale.cc
index 0e25216..3972b2e 100644
--- a/ash/system/locale/tray_locale.cc
+++ b/ash/system/locale/tray_locale.cc
@@ -8,7 +8,6 @@
 #include "ash/system/tray/system_tray_notifier.h"
 #include "ash/system/tray/tray_constants.h"
 #include "ash/system/tray/tray_notification_view.h"
-#include "ash/system/tray/tray_views.h"
 #include "base/string16.h"
 #include "grit/ash_resources.h"
 #include "grit/ash_strings.h"
@@ -36,9 +35,9 @@
     SetLayoutManager(
         new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1));
 
-    string16 from = l10n_util::GetDisplayNameForLocale(
+    base::string16 from = l10n_util::GetDisplayNameForLocale(
         from_locale, cur_locale, true);
-    string16 to = l10n_util::GetDisplayNameForLocale(
+    base::string16 to = l10n_util::GetDisplayNameForLocale(
         to_locale, cur_locale, true);
 
     views::Label* message = new views::Label(
diff --git a/ash/system/logout_button/tray_logout_button.cc b/ash/system/logout_button/tray_logout_button.cc
index bd15712..f7c6d1d 100644
--- a/ash/system/logout_button/tray_logout_button.cc
+++ b/ash/system/logout_button/tray_logout_button.cc
@@ -79,7 +79,7 @@
     set_border(views::Border::CreateEmptyBorder(
         0, kTrayLabelItemHorizontalPaddingBottomAlignment, 0, 0));
 
-    button_ = new views::LabelButton(this, string16());
+    button_ = new views::LabelButton(this, base::string16());
     for (size_t state = 0; state < views::Button::STATE_COUNT; ++state) {
       button_->SetTextColor(
           static_cast<views::Button::ButtonState>(state), SK_ColorWHITE);
@@ -100,8 +100,8 @@
 
   void OnLoginStatusChanged(user::LoginStatus status) {
     login_status_ = status;
-    const string16 title = GetLocalizedSignOutStringForStatus(login_status_,
-                                                              false);
+    const base::string16 title = GetLocalizedSignOutStringForStatus(
+        login_status_, false);
     button_->SetText(title);
     button_->SetAccessibleName(title);
     UpdateVisibility();
diff --git a/ash/system/monitor/tray_monitor.cc b/ash/system/monitor/tray_monitor.cc
index e34ffb5..cc46b0f 100644
--- a/ash/system/monitor/tray_monitor.cc
+++ b/ash/system/monitor/tray_monitor.cc
@@ -5,7 +5,6 @@
 #include "ash/system/monitor/tray_monitor.h"
 
 #include "ash/system/tray/tray_item_view.h"
-#include "ash/system/tray/tray_views.h"
 #include "base/process_util.h"
 #include "base/stringprintf.h"
 #include "base/utf_string_conversions.h"
@@ -63,11 +62,11 @@
   base::SystemMemoryInfoKB mem_info;
   base::GetSystemMemoryInfo(&mem_info);
   std::string output;
-  string16 free_bytes =
+  base::string16 free_bytes =
       ui::FormatBytes(static_cast<int64>(mem_info.free) * 1024);
   output = base::StringPrintf("free: %s", UTF16ToUTF8(free_bytes).c_str());
   if (mem_info.gem_size != -1) {
-    string16 gem_size = ui::FormatBytes(mem_info.gem_size);
+    base::string16 gem_size = ui::FormatBytes(mem_info.gem_size);
     output += base::StringPrintf("  gmem: %s", UTF16ToUTF8(gem_size).c_str());
     if (mem_info.gem_objects != -1)
       output += base::StringPrintf("  gobjects: %d", mem_info.gem_objects);
@@ -82,8 +81,8 @@
     total_shared_bytes += shared_bytes;
     delete pm;
   }
-  string16 private_size = ui::FormatBytes(total_private_bytes);
-  string16 shared_size = ui::FormatBytes(total_shared_bytes);
+  base::string16 private_size = ui::FormatBytes(total_private_bytes);
+  base::string16 shared_size = ui::FormatBytes(total_shared_bytes);
 
   output += base::StringPrintf("\nGPU private: %s  shared: %s",
                                UTF16ToUTF8(private_size).c_str(),
diff --git a/ash/system/power/power_status_view.cc b/ash/system/power/power_status_view.cc
index a268d3a..7566d1c 100644
--- a/ash/system/power/power_status_view.cc
+++ b/ash/system/power/power_status_view.cc
@@ -9,8 +9,7 @@
 #include "ash/system/power/tray_power.h"
 #include "ash/system/tray/fixed_sized_image_view.h"
 #include "ash/system/tray/tray_constants.h"
-#include "ash/system/tray/tray_views.h"
-#include "base/string_number_conversions.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/utf_string_conversions.h"
 #include "grit/ash_strings.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -44,6 +43,8 @@
       percentage_label_(NULL),
       icon_(NULL),
       icon_image_index_(-1),
+      icon_image_offset_(0),
+      battery_charging_unreliable_(false),
       view_type_(view_type) {
   if (view_type == VIEW_DEFAULT) {
     time_status_label_ = new views::Label;
@@ -108,71 +109,58 @@
 void PowerStatusView::UpdateText() {
   view_type_ == VIEW_DEFAULT ?
       UpdateTextForDefaultView() : UpdateTextForNotificationView();
+  accessible_name_ = TrayPower::GetAccessibleNameString(supply_status_);
 }
 
 void PowerStatusView::UpdateTextForDefaultView() {
   ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
-  string16 battery_percentage = string16();
-  string16 battery_time_status = string16();
+  base::string16 battery_percentage;
+  base::string16 battery_time_status;
+  bool is_charging_unreliable =
+      TrayPower::IsBatteryChargingUnreliable(supply_status_);
   if (supply_status_.line_power_on && supply_status_.battery_is_full) {
     battery_time_status =
         rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_BATTERY_FULL);
-    accessible_name_ = rb.GetLocalizedString(
-        IDS_ASH_STATUS_TRAY_BATTERY_FULL_CHARGE_ACCESSIBLE);
   } else if (supply_status_.battery_percentage < 0.0f) {
     battery_time_status =
+        is_charging_unreliable ?
+        rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_BATTERY_CHARGING_UNRELIABLE) :
         rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_BATTERY_CALCULATING);
-    accessible_name_ = rb.GetLocalizedString(
-        IDS_ASH_STATUS_TRAY_BATTERY_CALCULATING_ACCESSIBLE);
   } else {
     battery_percentage = l10n_util::GetStringFUTF16(
         IDS_ASH_STATUS_TRAY_BATTERY_PERCENT_ONLY,
-        base::IntToString16(GetRoundedBatteryPercentage()));
-    string16 battery_percentage_accessbile = l10n_util::GetStringFUTF16(
-        supply_status_.line_power_on ?
-            IDS_ASH_STATUS_TRAY_BATTERY_PERCENT_CHARGING_ACCESSIBLE:
-            IDS_ASH_STATUS_TRAY_BATTERY_PERCENT_ACCESSIBLE ,
-        base::IntToString16(GetRoundedBatteryPercentage()));
-    string16 battery_time_accessible = string16();
-    int hour = 0;
-    int min = 0;
-    if (supply_status_.is_calculating_battery_time) {
-      battery_time_status =
-          rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_BATTERY_CALCULATING);
-      battery_time_accessible = rb.GetLocalizedString(
-          IDS_ASH_STATUS_TRAY_BATTERY_CALCULATING_ACCESSIBLE);
+        base::IntToString16(TrayPower::GetRoundedBatteryPercentage(
+            supply_status_.battery_percentage)));
+    if (is_charging_unreliable) {
+      battery_time_status = rb.GetLocalizedString(
+          IDS_ASH_STATUS_TRAY_BATTERY_CHARGING_UNRELIABLE);
     } else {
-      base::TimeDelta time = base::TimeDelta::FromSeconds(
-          supply_status_.line_power_on ?
-              supply_status_.averaged_battery_time_to_full :
-              supply_status_.averaged_battery_time_to_empty);
-      hour = time.InHours();
-      min = (time - base::TimeDelta::FromHours(hour)).InMinutes();
-      if (hour || min) {
-        string16 minute = min < 10 ?
-            ASCIIToUTF16("0") + base::IntToString16(min) :
-            base::IntToString16(min);
+      if (supply_status_.is_calculating_battery_time) {
         battery_time_status =
-            l10n_util::GetStringFUTF16(
-                supply_status_.line_power_on ?
-                    IDS_ASH_STATUS_TRAY_BATTERY_TIME_UNTIL_FULL_SHORT :
-                    IDS_ASH_STATUS_TRAY_BATTERY_TIME_LEFT_SHORT,
-                base::IntToString16(hour),
-                minute);
-        battery_time_accessible =
-            l10n_util::GetStringFUTF16(
-                supply_status_.line_power_on ?
-                    IDS_ASH_STATUS_TRAY_BATTERY_TIME_UNTIL_FULL_ACCESSIBLE :
-                    IDS_ASH_STATUS_TRAY_BATTERY_TIME_LEFT_ACCESSIBLE,
-                GetBatteryTimeAccessibilityString(hour, min));
+            rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_BATTERY_CALCULATING);
+      } else {
+        base::TimeDelta time = base::TimeDelta::FromSeconds(
+            supply_status_.line_power_on ?
+            supply_status_.battery_seconds_to_full :
+            supply_status_.battery_seconds_to_empty);
+        int hour = time.InHours();
+        int min = (time - base::TimeDelta::FromHours(hour)).InMinutes();
+        if (hour || min) {
+          base::string16 minute = min < 10 ?
+              ASCIIToUTF16("0") + base::IntToString16(min) :
+              base::IntToString16(min);
+          battery_time_status =
+              l10n_util::GetStringFUTF16(
+                  supply_status_.line_power_on ?
+                  IDS_ASH_STATUS_TRAY_BATTERY_TIME_UNTIL_FULL_SHORT :
+                  IDS_ASH_STATUS_TRAY_BATTERY_TIME_LEFT_SHORT,
+                  base::IntToString16(hour),
+                  minute);
+        }
       }
     }
     battery_percentage = battery_time_status.empty() ?
         battery_percentage : battery_percentage + ASCIIToUTF16(" - ");
-    accessible_name_ = battery_time_accessible.empty() ?
-        battery_percentage_accessbile :
-        battery_percentage_accessbile + ASCIIToUTF16(". ")
-            + battery_time_accessible;
   }
   percentage_label_->SetVisible(!battery_percentage.empty());
   percentage_label_->SetText(battery_percentage);
@@ -186,30 +174,42 @@
   if (!supply_status_.is_calculating_battery_time) {
     base::TimeDelta time = base::TimeDelta::FromSeconds(
         supply_status_.line_power_on ?
-        supply_status_.averaged_battery_time_to_full :
-        supply_status_.averaged_battery_time_to_empty);
+        supply_status_.battery_seconds_to_full :
+        supply_status_.battery_seconds_to_empty);
     hour = time.InHours();
     min = (time - base::TimeDelta::FromHours(hour)).InMinutes();
   }
-
+  bool is_charging_unreliable =
+      TrayPower::IsBatteryChargingUnreliable(supply_status_);
   if (supply_status_.line_power_on && supply_status_.battery_is_full) {
     status_label_->SetText(
         ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
             IDS_ASH_STATUS_TRAY_BATTERY_FULL));
   } else {
     if (supply_status_.battery_percentage < 0.0f) {
-        status_label_->SetText(
-            ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
-                IDS_ASH_STATUS_TRAY_BATTERY_CALCULATING));
+      // If charging is unreliable and no percentage available, we
+      // leave the top field, |staus_label|, blank. We do not want to
+      // show "Calculating". The user is informed in the bottom field,
+      // |time_label|, that "Charging not reliable".
+      status_label_->SetText(
+          is_charging_unreliable ?
+          base::string16() :
+          ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
+              IDS_ASH_STATUS_TRAY_BATTERY_CALCULATING));
     } else {
       status_label_->SetText(
           l10n_util::GetStringFUTF16(
               IDS_ASH_STATUS_TRAY_BATTERY_PERCENT,
-              base::IntToString16(GetRoundedBatteryPercentage())));
+              base::IntToString16(TrayPower::GetRoundedBatteryPercentage(
+                  supply_status_.battery_percentage))));
     }
   }
 
-  if (supply_status_.is_calculating_battery_time) {
+  if (is_charging_unreliable) {
+    time_label_->SetText(
+        ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
+            IDS_ASH_STATUS_TRAY_BATTERY_CHARGING_UNRELIABLE));
+  } else if (supply_status_.is_calculating_battery_time) {
     time_label_->SetText(
         ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
             IDS_ASH_STATUS_TRAY_BATTERY_CALCULATING));
@@ -229,21 +229,15 @@
         time_label_->SetText(delegate->GetTimeRemainingString(
             base::TimeDelta::FromMinutes(min)));
       } else {
-        time_label_->SetText(string16());
+        time_label_->SetText(base::string16());
       }
     }
   } else {
-    time_label_->SetText(string16());
+    time_label_->SetText(base::string16());
   }
 }
 
-int PowerStatusView::GetRoundedBatteryPercentage() const {
-  DCHECK(supply_status_.battery_percentage >= 0.0f);
-  return std::max(kMinBatteryPercent,
-      static_cast<int>(supply_status_.battery_percentage));
-}
-
-string16 PowerStatusView::GetBatteryTimeAccessibilityString(
+base::string16 PowerStatusView::GetBatteryTimeAccessibilityString(
     int hour, int min) {
   DCHECK(hour || min);
   if (hour && !min) {
@@ -265,11 +259,21 @@
 void PowerStatusView::UpdateIcon() {
   if (icon_) {
     int index = TrayPower::GetBatteryImageIndex(supply_status_);
-    if (icon_image_index_ != index) {
+    int offset = TrayPower::GetBatteryImageOffset(supply_status_);
+    bool charging_unreliable =
+        TrayPower::IsBatteryChargingUnreliable(supply_status_);
+    if (icon_image_index_ != index ||
+        icon_image_offset_ != offset ||
+        battery_charging_unreliable_ != charging_unreliable) {
       icon_image_index_ = index;
+      icon_image_offset_ = offset;
+      battery_charging_unreliable_ = charging_unreliable;
       if (icon_image_index_ != -1) {
         icon_->SetImage(
-            TrayPower::GetBatteryImage(icon_image_index_, ICON_DARK));
+            TrayPower::GetBatteryImage(icon_image_index_,
+                                       icon_image_offset_,
+                                       battery_charging_unreliable_,
+                                       ICON_DARK));
       }
     }
     icon_->SetVisible(true);
@@ -290,6 +294,10 @@
   return gfx::Size(size.width(), kTrayPopupItemHeight);
 }
 
+int PowerStatusView::GetHeightForWidth(int width) {
+  return kTrayPopupItemHeight;
+}
+
 void PowerStatusView::Layout() {
   views::View::Layout();
 
diff --git a/ash/system/power/power_status_view.h b/ash/system/power/power_status_view.h
index f394b06..4454e5c 100644
--- a/ash/system/power/power_status_view.h
+++ b/ash/system/power/power_status_view.h
@@ -27,10 +27,11 @@
   virtual ~PowerStatusView() {}
 
   void UpdatePowerStatus(const PowerSupplyStatus& status);
-  const string16& accessible_name() const { return accessible_name_; }
+  const base::string16& accessible_name() const { return accessible_name_; }
 
   // Overridden from views::View.
   virtual gfx::Size GetPreferredSize() OVERRIDE;
+  virtual int GetHeightForWidth(int width) OVERRIDE;
   virtual void Layout() OVERRIDE;
 
  private:
@@ -41,8 +42,7 @@
   void Update();
   void UpdateTextForDefaultView();
   void UpdateTextForNotificationView();
-  int GetRoundedBatteryPercentage() const;
-  string16 GetBatteryTimeAccessibilityString(int hour, int min);
+  base::string16 GetBatteryTimeAccessibilityString(int hour, int min);
 
   // Overridden from views::View.
   virtual void ChildPreferredSizeChanged(views::View* child) OVERRIDE;
@@ -65,11 +65,20 @@
   // Index of the current icon in the icon array image, or -1 if unknown.
   int icon_image_index_;
 
+  // Horizontal offset of the current icon in the icon array image.
+  int icon_image_offset_;
+
+  // Battery charging may be unreliable for non-standard power supplies.
+  // It may change from charging to discharging frequently depending on
+  // charger power and current power consumption. We show different UIs
+  // when in this state. See TrayPower::IsBatteryChargingUnreliable.
+  bool battery_charging_unreliable_;
+
   ViewType view_type_;
 
   PowerSupplyStatus supply_status_;
 
-  string16 accessible_name_;
+  base::string16 accessible_name_;
 
   DISALLOW_COPY_AND_ASSIGN(PowerStatusView);
 };
diff --git a/ash/system/power/power_supply_status.cc b/ash/system/power/power_supply_status.cc
index 37a9fcf..fef327b 100644
--- a/ash/system/power/power_supply_status.cc
+++ b/ash/system/power/power_supply_status.cc
@@ -16,11 +16,9 @@
       battery_is_full(false),
       battery_seconds_to_empty(0),
       battery_seconds_to_full(0),
-      averaged_battery_time_to_empty(0),
-      averaged_battery_time_to_full(0),
       battery_percentage(0),
       is_calculating_battery_time(false),
-      battery_energy_rate(0) {}
+      battery_state(CHARGING) {}
 
 std::string PowerSupplyStatus::ToString() const {
   std::string result;
@@ -43,17 +41,11 @@
                       "battery_seconds_to_full = %"PRId64" ",
                       battery_seconds_to_full);
   base::StringAppendF(&result,
-                      "averaged_battery_time_to_empty = %"PRId64" ",
-                      averaged_battery_time_to_empty);
-  base::StringAppendF(&result,
-                      "averaged_battery_time_to_full = %"PRId64" ",
-                      averaged_battery_time_to_full);
-  base::StringAppendF(&result,
                       "is_calculating_battery_time = %s ",
                       is_calculating_battery_time ? "true" : "false");
   base::StringAppendF(&result,
-                      "battery_energy_rate = %f ",
-                      battery_energy_rate);
+                      "battery_state = %d ",
+                      battery_state);
   return result;
 }
 #endif  // !defined(OS_CHROMEOS)
diff --git a/ash/system/power/power_supply_status.h b/ash/system/power/power_supply_status.h
index 4ae2e2e..fd25643 100644
--- a/ash/system/power/power_supply_status.h
+++ b/ash/system/power/power_supply_status.h
@@ -21,6 +21,24 @@
 #else
 // Define local struct when not building for Chrome OS.
 struct ASH_EXPORT PowerSupplyStatus {
+  enum BatteryState {
+    // Line power is connected and the battery is full or being charged.
+    CHARGING = 0,
+
+    // Line power is disconnected.
+    DISCHARGING = 1,
+
+    // Line power is connected and the battery isn't full, but it also
+    // isn't charging (or discharging).  This can occur if the EC believes
+    // that the battery isn't authentic and chooses to run directly off
+    // line power.
+    NEITHER_CHARGING_NOR_DISCHARGING = 2,
+
+    // A USB power source (DCP, CDP, or ACA) is connected.  The battery may
+    // be charging or discharging depending on the negotiated current.
+    CONNECTED_TO_USB = 3,
+  };
+
   bool line_power_on;
 
   bool battery_is_present;
@@ -29,15 +47,12 @@
   // Time in seconds until the battery is empty or full, 0 for unknown.
   int64 battery_seconds_to_empty;
   int64 battery_seconds_to_full;
-  int64 averaged_battery_time_to_empty;
-  int64 averaged_battery_time_to_full;
 
   double battery_percentage;
 
   bool is_calculating_battery_time;
 
-  // Rate of charge/discharge of the battery, in W.
-  double battery_energy_rate;
+  BatteryState battery_state;
 
   PowerSupplyStatus();
   std::string ToString() const;
diff --git a/ash/system/power/tray_power.cc b/ash/system/power/tray_power.cc
index 024ccef..f7c6a33 100644
--- a/ash/system/power/tray_power.cc
+++ b/ash/system/power/tray_power.cc
@@ -13,16 +13,17 @@
 #include "ash/system/tray/system_tray_notifier.h"
 #include "ash/system/tray/tray_constants.h"
 #include "ash/system/tray/tray_notification_view.h"
-#include "ash/system/tray/tray_views.h"
+#include "ash/system/tray/tray_utils.h"
 #include "base/command_line.h"
-#include "base/string_number_conversions.h"
 #include "base/stringprintf.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/utf_string_conversions.h"
 #include "grit/ash_resources.h"
 #include "grit/ash_strings.h"
 #include "third_party/icu/public/i18n/unicode/fieldpos.h"
 #include "third_party/icu/public/i18n/unicode/fmtable.h"
 #include "third_party/skia/include/core/SkRect.h"
+#include "ui/base/accessibility/accessible_view_state.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/image/image.h"
@@ -55,6 +56,26 @@
 const int kCriticalSeconds = 5 * 60;
 const int kLowPowerSeconds = 15 * 60;
 const int kNoWarningSeconds = 30 * 60;
+// Minimum battery percentage rendered in UI.
+const int kMinBatteryPercent = 1;
+
+base::string16 GetBatteryTimeAccessibilityString(int hour, int min) {
+  DCHECK(hour || min);
+  if (hour && !min) {
+    return Shell::GetInstance()->delegate()->GetTimeDurationLongString(
+        base::TimeDelta::FromHours(hour));
+  }
+  if (min && !hour) {
+    return Shell::GetInstance()->delegate()->GetTimeDurationLongString(
+        base::TimeDelta::FromMinutes(min));
+  }
+  return l10n_util::GetStringFUTF16(
+      IDS_ASH_STATUS_TRAY_BATTERY_TIME_ACCESSIBLE,
+      Shell::GetInstance()->delegate()->GetTimeDurationLongString(
+          base::TimeDelta::FromHours(hour)),
+      Shell::GetInstance()->delegate()->GetTimeDurationLongString(
+          base::TimeDelta::FromMinutes(min)));
+}
 
 }  // namespace
 
@@ -63,14 +84,23 @@
 // This view is used only for the tray.
 class PowerTrayView : public views::ImageView {
  public:
-  PowerTrayView() : battery_icon_index_(-1) {
+  PowerTrayView()
+      : battery_icon_index_(-1),
+        battery_icon_offset_(0),
+        battery_charging_unreliable_(false) {
     UpdateImage();
   }
 
   virtual ~PowerTrayView() {
   }
 
-  void UpdatePowerStatus(const PowerSupplyStatus& status) {
+  // Overriden from views::View.
+  virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE {
+    state->name = accessible_name_;
+    state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON;
+  }
+
+  void UpdatePowerStatus(const PowerSupplyStatus& status, bool battery_alert) {
     supply_status_ = status;
     // Sanitize.
     if (supply_status_.battery_is_full)
@@ -78,22 +108,40 @@
 
     UpdateImage();
     SetVisible(status.battery_is_present);
+
+    if (battery_alert) {
+      accessible_name_ = TrayPower::GetAccessibleNameString(status);
+      NotifyAccessibilityEvent(ui::AccessibilityTypes::EVENT_ALERT, true);
+    }
   }
 
  private:
   void UpdateImage() {
     int index = TrayPower::GetBatteryImageIndex(supply_status_);
-    if (battery_icon_index_ != index) {
+    int offset = TrayPower::GetBatteryImageOffset(supply_status_);
+    bool charging_unreliable =
+        TrayPower::IsBatteryChargingUnreliable(supply_status_);
+    if (battery_icon_index_ != index ||
+        battery_icon_offset_ != offset ||
+        battery_charging_unreliable_ != charging_unreliable) {
       battery_icon_index_ = index;
+      battery_icon_offset_ = offset;
+      battery_charging_unreliable_ = charging_unreliable;
       if (battery_icon_index_ != -1)
-        SetImage(TrayPower::GetBatteryImage(battery_icon_index_, ICON_LIGHT));
+        SetImage(TrayPower::GetBatteryImage(battery_icon_index_,
+                                            battery_icon_offset_,
+                                            battery_charging_unreliable_,
+                                            ICON_LIGHT));
     }
   }
 
   PowerSupplyStatus supply_status_;
+  base::string16 accessible_name_;
 
   // Index of the current icon in the icon array image, or -1 if unknown.
   int battery_icon_index_;
+  int battery_icon_offset_;
+  bool battery_charging_unreliable_;
 
   DISALLOW_COPY_AND_ASSIGN(PowerTrayView);
 };
@@ -102,7 +150,9 @@
  public:
   explicit PowerNotificationView(TrayPower* owner)
       : TrayNotificationView(owner, 0),
-        battery_icon_index_(-1) {
+        battery_icon_index_(-1),
+        battery_icon_offset_(0),
+        battery_charging_unreliable_(false) {
     power_status_view_ =
         new PowerStatusView(PowerStatusView::VIEW_NOTIFICATION, true);
     InitView(power_status_view_);
@@ -110,11 +160,20 @@
 
   void UpdatePowerStatus(const PowerSupplyStatus& status) {
     int index = TrayPower::GetBatteryImageIndex(status);
-    if (battery_icon_index_ != index) {
+    int offset = TrayPower::GetBatteryImageOffset(status);
+    bool charging_unreliable = TrayPower::IsBatteryChargingUnreliable(status);
+    if (battery_icon_index_ != index ||
+        battery_icon_offset_ != offset ||
+        battery_charging_unreliable_ != charging_unreliable) {
       battery_icon_index_ = index;
+      battery_icon_offset_ = offset;
+      battery_charging_unreliable_ = charging_unreliable;
       if (battery_icon_index_ != -1) {
-        SetIconImage(TrayPower::GetBatteryImage(battery_icon_index_,
-                                                ICON_DARK));
+        SetIconImage(TrayPower::GetBatteryImage(
+                         battery_icon_index_,
+                         battery_icon_offset_,
+                         battery_charging_unreliable_,
+                         ICON_DARK));
       }
     }
     power_status_view_->UpdatePowerStatus(status);
@@ -125,6 +184,8 @@
 
   // Index of the current icon in the icon array image, or -1 if unknown.
   int battery_icon_index_;
+  int battery_icon_offset_;
+  bool battery_charging_unreliable_;
 
   DISALLOW_COPY_AND_ASSIGN(PowerNotificationView);
 };
@@ -146,6 +207,15 @@
 }
 
 // static
+bool TrayPower::IsBatteryChargingUnreliable(
+    const PowerSupplyStatus& supply_status) {
+  return
+      supply_status.battery_state ==
+      PowerSupplyStatus::NEITHER_CHARGING_NOR_DISCHARGING ||
+      supply_status.battery_state == PowerSupplyStatus::CONNECTED_TO_USB;
+}
+
+// static
 int TrayPower::GetBatteryImageIndex(const PowerSupplyStatus& supply_status) {
   int image_index = 0;
   if (supply_status.battery_percentage >= 100) {
@@ -154,25 +224,108 @@
     image_index = kNumPowerImages;
   } else {
     image_index = static_cast<int>(supply_status.battery_percentage /
-                  100.0 * (kNumPowerImages - 1));
+                                   100.0 * (kNumPowerImages - 1));
     image_index = std::max(std::min(image_index, kNumPowerImages - 2), 0);
   }
-  return (image_index << 1) | (supply_status.line_power_on ? 1 : 0);
+  return image_index;
 }
 
 // static
-gfx::ImageSkia TrayPower::GetBatteryImage(int image_index, IconSet icon_set) {
-  gfx::Image all = ui::ResourceBundle::GetSharedInstance().GetImageNamed(
-      icon_set == ICON_DARK ?
-      IDR_AURA_UBER_TRAY_POWER_SMALL_DARK : IDR_AURA_UBER_TRAY_POWER_SMALL);
+int TrayPower::GetBatteryImageOffset(const PowerSupplyStatus& supply_status) {
+  if (IsBatteryChargingUnreliable(supply_status) ||
+      !supply_status.line_power_on)
+    return 0;
+  return 1;
+}
 
+// static
+gfx::ImageSkia TrayPower::GetBatteryImage(int image_index,
+                                          int image_offset,
+                                          bool charging_unreliable,
+                                          IconSet icon_set) {
+  gfx::Image all;
+  if (charging_unreliable) {
+    all = ui::ResourceBundle::GetSharedInstance().GetImageNamed(
+        icon_set == ICON_DARK ?
+        IDR_AURA_UBER_TRAY_POWER_SMALL_CHARGING_UNRELIABLE_DARK :
+        IDR_AURA_UBER_TRAY_POWER_SMALL_CHARGING_UNRELIABLE);
+  } else {
+    all = ui::ResourceBundle::GetSharedInstance().GetImageNamed(
+        icon_set == ICON_DARK ?
+        IDR_AURA_UBER_TRAY_POWER_SMALL_DARK : IDR_AURA_UBER_TRAY_POWER_SMALL);
+  }
   gfx::Rect region(
-      (image_index & 0x1) ? kBatteryImageWidth : 0,
-      (image_index >> 1) * kBatteryImageHeight,
+      image_offset * kBatteryImageWidth,
+      image_index * kBatteryImageHeight,
       kBatteryImageWidth, kBatteryImageHeight);
   return gfx::ImageSkiaOperations::ExtractSubset(*all.ToImageSkia(), region);
 }
 
+// static
+base::string16 TrayPower::GetAccessibleNameString(
+    const PowerSupplyStatus& supply_status) {
+  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+  if (supply_status.line_power_on && supply_status.battery_is_full) {
+    return rb.GetLocalizedString(
+        IDS_ASH_STATUS_TRAY_BATTERY_FULL_CHARGE_ACCESSIBLE);
+  }
+  bool charging_unreliable =
+      IsBatteryChargingUnreliable(supply_status);
+  if (supply_status.battery_percentage < 0.0f) {
+    if (charging_unreliable) {
+      return rb.GetLocalizedString(
+          IDS_ASH_STATUS_TRAY_BATTERY_CHARGING_UNRELIABLE_ACCESSIBLE);
+    }
+    return rb.GetLocalizedString(
+        IDS_ASH_STATUS_TRAY_BATTERY_CALCULATING_ACCESSIBLE);
+  }
+  base::string16 battery_percentage_accessbile = l10n_util::GetStringFUTF16(
+      supply_status.line_power_on ?
+      IDS_ASH_STATUS_TRAY_BATTERY_PERCENT_CHARGING_ACCESSIBLE:
+      IDS_ASH_STATUS_TRAY_BATTERY_PERCENT_ACCESSIBLE ,
+      base::IntToString16(GetRoundedBatteryPercentage(
+          supply_status.battery_percentage)));
+  base::string16 battery_time_accessible = base::string16();
+  if (charging_unreliable) {
+    battery_time_accessible = rb.GetLocalizedString(
+        IDS_ASH_STATUS_TRAY_BATTERY_CHARGING_UNRELIABLE_ACCESSIBLE);
+  } else {
+    if (supply_status.is_calculating_battery_time) {
+      battery_time_accessible = rb.GetLocalizedString(
+          IDS_ASH_STATUS_TRAY_BATTERY_CALCULATING_ACCESSIBLE);
+    } else {
+      base::TimeDelta time = base::TimeDelta::FromSeconds(
+          supply_status.line_power_on ?
+          supply_status.battery_seconds_to_full :
+          supply_status.battery_seconds_to_empty);
+      int hour = time.InHours();
+      int min = (time - base::TimeDelta::FromHours(hour)).InMinutes();
+      if (hour || min) {
+        base::string16 minute = min < 10 ?
+            ASCIIToUTF16("0") + base::IntToString16(min) :
+            base::IntToString16(min);
+        battery_time_accessible =
+            l10n_util::GetStringFUTF16(
+                supply_status.line_power_on ?
+                IDS_ASH_STATUS_TRAY_BATTERY_TIME_UNTIL_FULL_ACCESSIBLE :
+                IDS_ASH_STATUS_TRAY_BATTERY_TIME_LEFT_ACCESSIBLE,
+                GetBatteryTimeAccessibilityString(hour, min));
+      }
+    }
+  }
+  return battery_time_accessible.empty() ?
+      battery_percentage_accessbile :
+      battery_percentage_accessbile + ASCIIToUTF16(". ")
+      + battery_time_accessible;
+}
+
+// static
+int TrayPower::GetRoundedBatteryPercentage(double battery_percentage) {
+  DCHECK(battery_percentage >= 0.0);
+  return std::max(kMinBatteryPercent,
+      static_cast<int>(battery_percentage + 0.5));
+}
+
 views::View* TrayPower::CreateTrayView(user::LoginStatus status) {
   // There may not be enough information when this is created about whether
   // there is a battery or not. So always create this, and adjust visibility as
@@ -181,7 +334,7 @@
       ash::Shell::GetInstance()->system_tray_delegate()->GetPowerSupplyStatus();
   CHECK(power_tray_ == NULL);
   power_tray_ = new tray::PowerTrayView();
-  power_tray_->UpdatePowerStatus(power_status);
+  power_tray_->UpdatePowerStatus(power_status, false);
   return power_tray_;
 }
 
@@ -223,12 +376,13 @@
 }
 
 void TrayPower::OnPowerStatusChanged(const PowerSupplyStatus& status) {
+  bool battery_alert = UpdateNotificationState(status);
   if (power_tray_)
-    power_tray_->UpdatePowerStatus(status);
+    power_tray_->UpdatePowerStatus(status, battery_alert);
   if (notification_view_)
     notification_view_->UpdatePowerStatus(status);
 
-  if (UpdateNotificationState(status))
+  if (battery_alert)
     ShowNotificationView();
   else if (notification_state_ == NOTIFICATION_NONE)
     HideNotificationView();
@@ -242,7 +396,7 @@
     return false;
   }
 
-  int remaining_seconds = status.averaged_battery_time_to_empty;
+  int remaining_seconds = status.battery_seconds_to_empty;
   if (remaining_seconds >= kNoWarningSeconds) {
     notification_state_ = NOTIFICATION_NONE;
     return false;
diff --git a/ash/system/power/tray_power.h b/ash/system/power/tray_power.h
index 61687ab..7865b1a 100644
--- a/ash/system/power/tray_power.h
+++ b/ash/system/power/tray_power.h
@@ -33,13 +33,35 @@
   explicit TrayPower(SystemTray* system_tray);
   virtual ~TrayPower();
 
+  // Gets whether battery charging is unreliable for |supply_status|.
+  // When a non-standard power supply is connected, the battery may
+  // change from being charged to discharged frequently depending on the
+  // charger power and power consumption, i.e usage. In this case we
+  // do not want to show either a charging or discharging state.
+  static bool IsBatteryChargingUnreliable(
+      const PowerSupplyStatus& supply_status);
+
   // Gets the icon index in the battery icon array image based on
   // |supply_status|.  If |supply_status| is uncertain about the power state,
   // returns -1.
   static int GetBatteryImageIndex(const PowerSupplyStatus& supply_status);
 
+  // Gets the horizontal offset in the battery icon array image based on
+  // |supply_status|.
+  static int GetBatteryImageOffset(const PowerSupplyStatus& supply_status);
+
   // Looks up the actual icon in the icon array image for |image_index|.
-  static gfx::ImageSkia GetBatteryImage(int image_index, IconSet icon_set);
+  static gfx::ImageSkia GetBatteryImage(int image_index,
+                                        int image_offset,
+                                        bool charging_unreliable,
+                                        IconSet icon_set);
+
+  // Gets the battery accessible string for |supply_status|.
+  static base::string16 GetAccessibleNameString(
+      const PowerSupplyStatus& supply_status);
+
+  // Gets rounded battery percentage for |battery_percentage|.
+  static int GetRoundedBatteryPercentage(double battery_percentage);
 
  private:
   enum NotificationState {
diff --git a/ash/system/session_length_limit/tray_session_length_limit.cc b/ash/system/session_length_limit/tray_session_length_limit.cc
index 4982658..d80f652 100644
--- a/ash/system/session_length_limit/tray_session_length_limit.cc
+++ b/ash/system/session_length_limit/tray_session_length_limit.cc
@@ -13,11 +13,11 @@
 #include "ash/system/tray/system_tray_notifier.h"
 #include "ash/system/tray/tray_constants.h"
 #include "ash/system/tray/tray_notification_view.h"
-#include "ash/system/tray/tray_views.h"
+#include "ash/system/tray/tray_utils.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/string16.h"
-#include "base/string_number_conversions.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/utf_string_conversions.h"
 #include "grit/ash_resources.h"
 #include "grit/ash_strings.h"
@@ -54,7 +54,7 @@
   return label;
 }
 
-string16 IntToTwoDigitString(int value) {
+base::string16 IntToTwoDigitString(int value) {
   DCHECK_GE(value, 0);
   DCHECK_LE(value, 99);
   if (value < 10)
@@ -62,7 +62,7 @@
   return base::IntToString16(value);
 }
 
-string16 FormatRemainingSessionTimeNotification(
+base::string16 FormatRemainingSessionTimeNotification(
     const base::TimeDelta& remaining_session_time) {
   return l10n_util::GetStringFUTF16(
       IDS_ASH_STATUS_TRAY_REMAINING_SESSION_TIME_NOTIFICATION,
@@ -234,9 +234,9 @@
   const int hours = minutes / 60;
   minutes %= 60;
 
-  const string16 hours_str = IntToTwoDigitString(hours);
-  const string16 minutes_str = IntToTwoDigitString(minutes);
-  const string16 seconds_str = IntToTwoDigitString(seconds);
+  const base::string16 hours_str = IntToTwoDigitString(hours);
+  const base::string16 minutes_str = IntToTwoDigitString(minutes);
+  const base::string16 seconds_str = IntToTwoDigitString(seconds);
   const SkColor color =
       limit_state == TraySessionLengthLimit::LIMIT_EXPIRING_SOON ?
           kRemainingTimeExpiringSoonColor : kRemainingTimeColor;
diff --git a/ash/system/settings/tray_settings.cc b/ash/system/settings/tray_settings.cc
index 2580f24..a142ae0 100644
--- a/ash/system/settings/tray_settings.cc
+++ b/ash/system/settings/tray_settings.cc
@@ -50,7 +50,7 @@
           rb.GetImageNamed(IDR_AURA_UBER_TRAY_SETTINGS).ToImageSkia());
       AddChildView(icon);
 
-      string16 text = rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_SETTINGS);
+      base::string16 text = rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_SETTINGS);
       label_ = new views::Label(text);
       AddChildView(label_);
       SetAccessibleName(text);
@@ -74,7 +74,7 @@
     if (!power_status_view_)
       return;
     power_status_view_->UpdatePowerStatus(status);
-    string16 accessible_name = label_ ?
+    base::string16 accessible_name = label_ ?
         label_->text() + ASCIIToUTF16(", ") +
             power_status_view_->accessible_name() :
         power_status_view_->accessible_name();
diff --git a/ash/system/status_area_widget.cc b/ash/system/status_area_widget.cc
index 0701097..1430bd1 100644
--- a/ash/system/status_area_widget.cc
+++ b/ash/system/status_area_widget.cc
@@ -24,6 +24,8 @@
 
 namespace internal {
 
+const char StatusAreaWidget::kNativeViewName[] = "StatusAreaWidget";
+
 StatusAreaWidget::StatusAreaWidget(aura::Window* status_container)
     : status_area_widget_delegate_(new internal::StatusAreaWidgetDelegate),
       system_tray_(NULL),
@@ -37,7 +39,7 @@
   Init(params);
   set_focus_on_creation(false);
   SetContentsView(status_area_widget_delegate_);
-  GetNativeView()->SetName("StatusAreaWidget");
+  GetNativeView()->SetName(kNativeViewName);
   GetNativeView()->SetProperty(internal::kStayInSameRootWindowKey, true);
 }
 
@@ -90,6 +92,12 @@
            web_notification_tray_->IsMessageCenterBubbleVisible()));
 }
 
+void StatusAreaWidget::OnNativeWidgetActivationChanged(bool active) {
+  Widget::OnNativeWidgetActivationChanged(active);
+  if (active)
+    status_area_widget_delegate_->SetPaneFocusAndFocusDefault();
+}
+
 void StatusAreaWidget::AddSystemTray() {
   system_tray_ = new SystemTray(this);
   status_area_widget_delegate_->AddTray(system_tray_);
diff --git a/ash/system/status_area_widget.h b/ash/system/status_area_widget.h
index 03a78a4..4056710 100644
--- a/ash/system/status_area_widget.h
+++ b/ash/system/status_area_widget.h
@@ -22,6 +22,8 @@
 
 class ASH_EXPORT StatusAreaWidget : public views::Widget {
  public:
+  static const char kNativeViewName[];
+
   explicit StatusAreaWidget(aura::Window* status_container);
   virtual ~StatusAreaWidget();
 
@@ -67,6 +69,9 @@
   // True if any message bubble is shown.
   bool IsMessageBubbleShown() const;
 
+  // Overridden from views::Widget:
+  virtual void OnNativeWidgetActivationChanged(bool active) OVERRIDE;
+
  private:
   void AddSystemTray();
   void AddWebNotificationTray();
diff --git a/ash/system/status_area_widget_delegate.cc b/ash/system/status_area_widget_delegate.cc
index 99eeb20..f4a7b5a 100644
--- a/ash/system/status_area_widget_delegate.cc
+++ b/ash/system/status_area_widget_delegate.cc
@@ -41,16 +41,6 @@
   return child_at(0);
 }
 
-bool StatusAreaWidgetDelegate::AcceleratorPressed(
-    const ui::Accelerator& accelerator) {
-  if (accelerator.key_code() == ui::VKEY_ESCAPE) {
-    RemovePaneFocus();
-    GetFocusManager()->ClearFocus();
-    return true;
-  }
-  return false;
-}
-
 views::Widget* StatusAreaWidgetDelegate::GetWidget() {
   return View::GetWidget();
 }
diff --git a/ash/system/status_area_widget_delegate.h b/ash/system/status_area_widget_delegate.h
index c7820ea..eaa7253 100644
--- a/ash/system/status_area_widget_delegate.h
+++ b/ash/system/status_area_widget_delegate.h
@@ -38,7 +38,6 @@
   virtual View* GetDefaultFocusableChild() OVERRIDE;
 
   // Overridden from views::View:
-  virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE;
   virtual views::Widget* GetWidget() OVERRIDE;
   virtual const views::Widget* GetWidget() const OVERRIDE;
 
diff --git a/ash/system/tray/actionable_view.cc b/ash/system/tray/actionable_view.cc
index b879881..2fbd09c 100644
--- a/ash/system/tray/actionable_view.cc
+++ b/ash/system/tray/actionable_view.cc
@@ -48,7 +48,7 @@
   has_capture_ = false;
 }
 
-void ActionableView::SetAccessibleName(const string16& name) {
+void ActionableView::SetAccessibleName(const base::string16& name) {
   accessible_name_ = name;
 }
 
diff --git a/ash/system/tray/actionable_view.h b/ash/system/tray/actionable_view.h
index 74f516c..1ffbfe8 100644
--- a/ash/system/tray/actionable_view.h
+++ b/ash/system/tray/actionable_view.h
@@ -25,8 +25,8 @@
 
   virtual ~ActionableView();
 
-  void SetAccessibleName(const string16& name);
-  const string16& accessible_name() const { return accessible_name_; }
+  void SetAccessibleName(const base::string16& name);
+  const base::string16& accessible_name() const { return accessible_name_; }
 
  protected:
   void DrawBorder(gfx::Canvas* canvas, const gfx::Rect& bounds);
@@ -48,7 +48,7 @@
   virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
 
  private:
-  string16 accessible_name_;
+  base::string16 accessible_name_;
   bool has_capture_;
 
   DISALLOW_COPY_AND_ASSIGN(ActionableView);
diff --git a/ash/system/tray/hover_highlight_view.cc b/ash/system/tray/hover_highlight_view.cc
index e826ef6..3a511a2 100644
--- a/ash/system/tray/hover_highlight_view.cc
+++ b/ash/system/tray/hover_highlight_view.cc
@@ -6,7 +6,6 @@
 
 #include "ash/system/tray/fixed_sized_image_view.h"
 #include "ash/system/tray/tray_constants.h"
-#include "ash/system/tray/tray_views.h"
 #include "ash/system/tray/view_click_listener.h"
 #include "grit/ui_resources.h"
 #include "ui/base/resource/resource_bundle.h"
@@ -42,7 +41,7 @@
 }
 
 void HoverHighlightView::AddIconAndLabel(const gfx::ImageSkia& image,
-                                         const string16& text,
+                                         const base::string16& text,
                                          gfx::Font::FontStyle style) {
   SetLayoutManager(new views::BoxLayout(
       views::BoxLayout::kHorizontal, 0, 3, kTrayPopupPaddingBetweenItems));
@@ -61,7 +60,7 @@
   SetAccessibleName(text);
 }
 
-views::Label* HoverHighlightView::AddLabel(const string16& text,
+views::Label* HoverHighlightView::AddLabel(const base::string16& text,
                                            gfx::Font::FontStyle style) {
   SetLayoutManager(new views::FillLayout());
   text_label_ = new views::Label(text);
@@ -87,7 +86,7 @@
   return text_label_;
 }
 
-views::Label* HoverHighlightView::AddCheckableLabel(const string16& text,
+views::Label* HoverHighlightView::AddCheckableLabel(const base::string16& text,
                                                     gfx::Font::FontStyle style,
                                                     bool checked) {
   if (checked) {
@@ -138,6 +137,10 @@
   return size;
 }
 
+int HoverHighlightView::GetHeightForWidth(int width) {
+  return GetPreferredSize().height();
+}
+
 void HoverHighlightView::OnMouseEntered(const ui::MouseEvent& event) {
   hover_ = true;
   if (text_highlight_color_ && text_label_)
diff --git a/ash/system/tray/hover_highlight_view.h b/ash/system/tray/hover_highlight_view.h
index 75a63d5..13630ca 100644
--- a/ash/system/tray/hover_highlight_view.h
+++ b/ash/system/tray/hover_highlight_view.h
@@ -30,18 +30,19 @@
   // Convenience function for adding an icon and a label.  This also sets the
   // accessible name.
   void AddIconAndLabel(const gfx::ImageSkia& image,
-                       const string16& text,
+                       const base::string16& text,
                        gfx::Font::FontStyle style);
 
   // Convenience function for adding a label with padding on the left for a
   // blank icon.  This also sets the accessible name.
   // Returns label after parenting it.
-  views::Label* AddLabel(const string16& text, gfx::Font::FontStyle style);
+  views::Label* AddLabel(const base::string16& text,
+                         gfx::Font::FontStyle style);
 
   // Convenience function for adding an optional check and a label.  In the
   // absence of a check, padding is added to align with checked items.
   // Returns label after parenting it.
-  views::Label* AddCheckableLabel(const string16& text,
+  views::Label* AddCheckableLabel(const base::string16& text,
                                   gfx::Font::FontStyle style,
                                   bool checked);
 
@@ -64,6 +65,7 @@
 
   // Overridden from views::View.
   virtual gfx::Size GetPreferredSize() OVERRIDE;
+  virtual int GetHeightForWidth(int width) OVERRIDE;
   virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE;
   virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE;
   virtual void OnEnabledChanged() OVERRIDE;
diff --git a/ash/system/tray/special_popup_row.cc b/ash/system/tray/special_popup_row.cc
index 29c697b..896d151 100644
--- a/ash/system/tray/special_popup_row.cc
+++ b/ash/system/tray/special_popup_row.cc
@@ -7,7 +7,7 @@
 #include "ash/system/tray/hover_highlight_view.h"
 #include "ash/system/tray/throbber_view.h"
 #include "ash/system/tray/tray_constants.h"
-#include "ash/system/tray/tray_views.h"
+#include "ash/system/tray/tray_popup_header_button.h"
 #include "grit/ash_resources.h"
 #include "grit/ash_strings.h"
 #include "ui/base/resource/resource_bundle.h"
@@ -103,6 +103,10 @@
   return size;
 }
 
+int SpecialPopupRow::GetHeightForWidth(int width) {
+  return kSpecialPopupRowHeight;
+}
+
 void SpecialPopupRow::Layout() {
   views::View::Layout();
   gfx::Rect content_bounds = GetContentsBounds();
diff --git a/ash/system/tray/special_popup_row.h b/ash/system/tray/special_popup_row.h
index 32821f5..ee068e4 100644
--- a/ash/system/tray/special_popup_row.h
+++ b/ash/system/tray/special_popup_row.h
@@ -38,6 +38,7 @@
  private:
   // Overridden from views::View.
   virtual gfx::Size GetPreferredSize() OVERRIDE;
+  virtual int GetHeightForWidth(int width) OVERRIDE;
   virtual void Layout() OVERRIDE;
 
   views::View* content_;
diff --git a/ash/system/tray/system_tray.cc b/ash/system/tray/system_tray.cc
index e669fd2..ce3a81a 100644
--- a/ash/system/tray/system_tray.cc
+++ b/ash/system/tray/system_tray.cc
@@ -9,7 +9,6 @@
 #include "ash/shell.h"
 #include "ash/shell/panel_window.h"
 #include "ash/shell_window_ids.h"
-#include "ash/system/audio/tray_volume.h"
 #include "ash/system/bluetooth/tray_bluetooth.h"
 #include "ash/system/brightness/tray_brightness.h"
 #include "ash/system/date/tray_date.h"
@@ -51,7 +50,9 @@
 #include "ui/views/view.h"
 
 #if defined(OS_CHROMEOS)
+#include "ash/system/chromeos/audio/tray_audio.h"
 #include "ash/system/chromeos/enterprise/tray_enterprise.h"
+#include "ash/system/chromeos/managed/tray_locally_managed_user.h"
 #include "ash/system/chromeos/network/tray_network.h"
 #include "ash/system/chromeos/network/tray_sms.h"
 #include "ash/system/chromeos/network/tray_vpn.h"
@@ -135,31 +136,40 @@
 }
 
 void SystemTray::CreateItems(SystemTrayDelegate* delegate) {
+#if !defined(OS_WIN)
   AddTrayItem(new internal::TraySessionLengthLimit(this));
   AddTrayItem(new internal::TrayLogoutButton(this));
   AddTrayItem(new internal::TrayUser(this));
+#endif
 #if defined(OS_CHROMEOS)
   AddTrayItem(new internal::TrayEnterprise(this));
+  AddTrayItem(new internal::TrayLocallyManagedUser(this));
 #endif
   AddTrayItem(new internal::TrayIME(this));
   tray_accessibility_ = new internal::TrayAccessibility(this);
   AddTrayItem(tray_accessibility_);
+#if !defined(OS_WIN)
   AddTrayItem(new internal::TrayPower(this));
+#endif
 #if defined(OS_CHROMEOS)
   AddTrayItem(new internal::TrayNetwork(this));
   AddTrayItem(new internal::TrayVPN(this));
   AddTrayItem(new internal::TraySms(this));
 #endif
+#if !defined(OS_WIN)
   AddTrayItem(new internal::TrayBluetooth(this));
+#endif
   AddTrayItem(new internal::TrayDrive(this));
   AddTrayItem(new internal::TrayLocale(this));
 #if defined(OS_CHROMEOS)
   AddTrayItem(new internal::TrayDisplay(this));
   AddTrayItem(new internal::TrayScreenCapture(this));
+  AddTrayItem(new internal::TrayAudio(this));
 #endif
-  AddTrayItem(new internal::TrayVolume(this));
+#if !defined(OS_WIN)
   AddTrayItem(new internal::TrayBrightness(this));
   AddTrayItem(new internal::TrayCapsLock(this));
+#endif
   AddTrayItem(new internal::TraySettings(this));
   AddTrayItem(new internal::TrayUpdate(this));
   AddTrayItem(new internal::TrayDate(this));
@@ -205,7 +215,7 @@
   std::vector<SystemTrayItem*> items;
   items.push_back(item);
   ShowItems(items, true, activate, creation_type, GetTrayXOffset(item));
-  if (system_bubble_.get())
+  if (system_bubble_)
     system_bubble_->bubble()->StartAutoCloseTimer(close_delay);
 }
 
@@ -236,12 +246,13 @@
     return;
   notification_items_.erase(found_iter);
   // Only update the notification bubble if visible (i.e. don't create one).
-  if (notification_bubble_.get())
+  if (notification_bubble_)
     UpdateNotificationBubble();
 }
 
 void SystemTray::UpdateAfterLoginStatusChange(user::LoginStatus login_status) {
   DestroySystemBubble();
+  UpdateNotificationBubble();
 
   for (std::vector<SystemTrayItem*>::iterator it = items_.begin();
       it != items_.end();
@@ -262,7 +273,7 @@
 }
 
 void SystemTray::SetHideNotifications(bool hide_notifications) {
-  if (notification_bubble_.get())
+  if (notification_bubble_)
     notification_bubble_->bubble()->SetVisible(!hide_notifications);
   hide_notifications_ = hide_notifications;
 }
@@ -280,7 +291,7 @@
 }
 
 internal::SystemTrayBubble* SystemTray::GetSystemBubble() {
-  if (!system_bubble_.get())
+  if (!system_bubble_)
     return NULL;
   return system_bubble_->bubble();
 }
@@ -293,21 +304,21 @@
 }
 
 bool SystemTray::IsMouseInNotificationBubble() const {
-  if (!notification_bubble_.get())
+  if (!notification_bubble_)
     return false;
   return notification_bubble_->bubble_view()->GetBoundsInScreen().Contains(
       Shell::GetScreen()->GetCursorScreenPoint());
 }
 
 bool SystemTray::CloseSystemBubbleForTest() const {
-  if (!system_bubble_.get())
+  if (!system_bubble_)
     return false;
   system_bubble_->bubble()->Close();
   return true;
 }
 
 bool SystemTray::CloseNotificationBubbleForTest() const {
-  if (!notification_bubble_.get())
+  if (!notification_bubble_)
     return false;
   notification_bubble_->bubble()->Close();
   return true;
@@ -465,26 +476,26 @@
   // Destroy any existing bubble so that it is rebuilt correctly.
   system_bubble_.reset();
   // Rebuild any notification bubble.
-  if (notification_bubble_.get()) {
+  if (notification_bubble_) {
     notification_bubble_.reset();
     UpdateNotificationBubble();
   }
 }
 
 void SystemTray::AnchorUpdated() {
-  if (notification_bubble_.get()) {
+  if (notification_bubble_) {
     notification_bubble_->bubble_view()->UpdateBubble();
     // Ensure that the notification buble is above the launcher/status area.
     notification_bubble_->bubble_view()->GetWidget()->StackAtTop();
     UpdateBubbleViewArrow(notification_bubble_->bubble_view());
   }
-  if (system_bubble_.get()) {
+  if (system_bubble_) {
     system_bubble_->bubble_view()->UpdateBubble();
     UpdateBubbleViewArrow(system_bubble_->bubble_view());
   }
 }
 
-string16 SystemTray::GetAccessibleNameForTray() {
+base::string16 SystemTray::GetAccessibleNameForTray() {
   return l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_ACCESSIBLE_NAME);
 }
 
@@ -500,30 +511,30 @@
 }
 
 bool SystemTray::ClickedOutsideBubble() {
-  if (!system_bubble_.get())
+  if (!system_bubble_)
     return false;
   HideBubbleWithView(system_bubble_->bubble_view());
   return true;
 }
 
 void SystemTray::BubbleViewDestroyed() {
-  if (system_bubble_.get()) {
+  if (system_bubble_) {
     system_bubble_->bubble()->DestroyItemViews();
     system_bubble_->bubble()->BubbleViewDestroyed();
   }
 }
 
 void SystemTray::OnMouseEnteredView() {
-  if (system_bubble_.get())
+  if (system_bubble_)
     system_bubble_->bubble()->StopAutoCloseTimer();
 }
 
 void SystemTray::OnMouseExitedView() {
-  if (system_bubble_.get())
+  if (system_bubble_)
     system_bubble_->bubble()->RestartAutoCloseTimer();
 }
 
-string16 SystemTray::GetAccessibleNameForBubble() {
+base::string16 SystemTray::GetAccessibleNameForBubble() {
   return GetAccessibleNameForTray();
 }
 
diff --git a/ash/system/tray/system_tray.h b/ash/system/tray/system_tray.h
index 0988524..0f91367 100644
--- a/ash/system/tray/system_tray.h
+++ b/ash/system/tray/system_tray.h
@@ -9,7 +9,6 @@
 #include "ash/system/power/power_supply_status.h"
 #include "ash/system/tray/system_tray_bubble.h"
 #include "ash/system/tray/tray_background_view.h"
-#include "ash/system/tray/tray_views.h"
 #include "ash/system/user/login_status.h"
 #include "base/basictypes.h"
 #include "base/compiler_specific.h"
@@ -136,7 +135,7 @@
   // Overridden from TrayBackgroundView.
   virtual void SetShelfAlignment(ShelfAlignment alignment) OVERRIDE;
   virtual void AnchorUpdated() OVERRIDE;
-  virtual string16 GetAccessibleNameForTray() OVERRIDE;
+  virtual base::string16 GetAccessibleNameForTray() OVERRIDE;
   virtual void HideBubbleWithView(
       const views::TrayBubbleView* bubble_view) OVERRIDE;
   virtual bool ClickedOutsideBubble() OVERRIDE;
@@ -145,7 +144,7 @@
   virtual void BubbleViewDestroyed() OVERRIDE;
   virtual void OnMouseEnteredView() OVERRIDE;
   virtual void OnMouseExitedView() OVERRIDE;
-  virtual string16 GetAccessibleNameForBubble() OVERRIDE;
+  virtual base::string16 GetAccessibleNameForBubble() OVERRIDE;
   virtual gfx::Rect GetAnchorRect(views::Widget* anchor_widget,
                                   AnchorType anchor_type,
                                   AnchorAlignment anchor_alignment) OVERRIDE;
@@ -174,6 +173,8 @@
                                  int x_offset);
 
   // Constructs or re-constructs |system_bubble_| and populates it with |items|.
+  // Specify |change_tray_status| to true if want to change the tray background
+  // status.
   void ShowItems(const std::vector<SystemTrayItem*>& items,
                  bool details,
                  bool activate,
diff --git a/ash/system/tray/system_tray_bubble.cc b/ash/system/tray/system_tray_bubble.cc
index 95cbffb..a88a40b 100644
--- a/ash/system/tray/system_tray_bubble.cc
+++ b/ash/system/tray/system_tray_bubble.cc
@@ -116,7 +116,7 @@
   }
 
   virtual void OnImplicitAnimationsCompleted() OVERRIDE {
-    MessageLoopForUI::current()->DeleteSoon(FROM_HERE, this);
+    base::MessageLoopForUI::current()->DeleteSoon(FROM_HERE, this);
   }
 
  private:
@@ -225,7 +225,7 @@
     bubble_view_->SetMaxHeight(0);  // Clear max height limit.
   }
 
-  if (scoped_layer.get()) {
+  if (scoped_layer) {
     // When transitioning from default view to detailed view, animate the new
     // view (slide in from the right).
     if (bubble_type == BUBBLE_TYPE_DETAILED) {
@@ -262,6 +262,11 @@
       tray_->GetBubbleWindowContainer(), anchor, tray_, init_params);
   bubble_view_->set_adjust_if_offscreen(false);
   CreateItemViews(login_status);
+
+  if (bubble_view_->CanActivate()) {
+    bubble_view_->NotifyAccessibilityEvent(
+        ui::AccessibilityTypes::EVENT_ALERT, true);
+  }
 }
 
 void SystemTrayBubble::DestroyItemViews() {
diff --git a/ash/system/tray/system_tray_delegate.cc b/ash/system/tray/system_tray_delegate.cc
index 8f44a7b..f31e314 100644
--- a/ash/system/tray/system_tray_delegate.cc
+++ b/ash/system/tray/system_tray_delegate.cc
@@ -19,14 +19,19 @@
 }
 
 BluetoothDeviceInfo::BluetoothDeviceInfo()
-    : connected(false) {
+    : connected(false),
+      connecting(false),
+      paired(false) {
 }
 
 BluetoothDeviceInfo::~BluetoothDeviceInfo() {
 }
 
 DriveOperationStatus::DriveOperationStatus()
-    : progress(0.0), type(OPERATION_OTHER), state(OPERATION_NOT_STARTED) {
+    : id(-1),
+      progress(0.0),
+      type(OPERATION_DOWNLOAD),
+      state(OPERATION_NOT_STARTED) {
 }
 
 DriveOperationStatus::~DriveOperationStatus() {
diff --git a/ash/system/tray/system_tray_delegate.h b/ash/system/tray/system_tray_delegate.h
index 2e05dc7..e5f25ec 100644
--- a/ash/system/tray/system_tray_delegate.h
+++ b/ash/system/tray/system_tray_delegate.h
@@ -34,8 +34,8 @@
   bool connected;
   bool tray_icon_visible;
   gfx::ImageSkia image;
-  string16 name;
-  string16 description;
+  base::string16 name;
+  base::string16 description;
   std::string service_path;
   bool is_cellular;
 };
@@ -45,10 +45,10 @@
   ~BluetoothDeviceInfo();
 
   std::string address;
-  string16 display_name;
+  base::string16 display_name;
   bool connected;
+  bool connecting;
   bool paired;
-  bool visible;
 };
 
 typedef std::vector<BluetoothDeviceInfo> BluetoothDeviceList;
@@ -57,22 +57,22 @@
 struct ASH_EXPORT DriveOperationStatus {
   enum OperationType {
     OPERATION_UPLOAD,
-    OPERATION_DOWNLOAD,
-    OPERATION_OTHER,
+    OPERATION_DOWNLOAD
   };
 
   enum OperationState {
     OPERATION_NOT_STARTED,
-    OPERATION_STARTED,
     OPERATION_IN_PROGRESS,
     OPERATION_COMPLETED,
     OPERATION_FAILED,
-    OPERATION_SUSPENDED,
   };
 
   DriveOperationStatus();
   ~DriveOperationStatus();
 
+  // Unique ID for the operation.
+  int32 id;
+
   // File path.
   base::FilePath file_path;
   // Current operation completion progress [0.0 - 1.0].
@@ -90,7 +90,7 @@
 
   bool selected;
   std::string key;
-  string16 name;
+  base::string16 name;
 };
 
 typedef std::vector<IMEPropertyInfo> IMEPropertyInfoList;
@@ -102,15 +102,17 @@
   bool selected;
   bool third_party;
   std::string id;
-  string16 name;
-  string16 medium_name;
-  string16 short_name;
+  base::string16 name;
+  base::string16 medium_name;
+  base::string16 short_name;
 };
 
 typedef std::vector<IMEInfo> IMEInfoList;
 
 class VolumeControlDelegate;
 
+typedef std::vector<std::string> UserEmailList;
+
 class SystemTrayDelegate {
  public:
   virtual ~SystemTrayDelegate() {}
@@ -118,16 +120,25 @@
   // Called after SystemTray has been instantiated.
   virtual void Initialize() = 0;
 
+  // Called before SystemTray is destroyed.
+  virtual void Shutdown() = 0;
+
   // Returns true if system tray should be visible on startup.
   virtual bool GetTrayVisibilityOnStartup() = 0;
 
-  // Gets information about the logged in user.
-  virtual const string16 GetUserDisplayName() const = 0;
+  // Gets information about the active user.
+  virtual const base::string16 GetUserDisplayName() const = 0;
   virtual const std::string GetUserEmail() const = 0;
   virtual const gfx::ImageSkia& GetUserImage() const = 0;
   virtual user::LoginStatus GetUserLoginStatus() const = 0;
   virtual bool IsOobeCompleted() const = 0;
 
+  // Returns a list of all logged in users.
+  virtual void GetLoggedInUsers(UserEmailList* users) = 0;
+
+  // Switches to another active user (if that user has already signed in).
+  virtual void SwitchActiveUser(const std::string& email) = 0;
+
   // Shows UI for changing user's profile picture.
   virtual void ChangeProfilePicture() = 0;
 
@@ -135,7 +146,13 @@
   virtual const std::string GetEnterpriseDomain() const = 0;
 
   // Returns notification for enterprise enrolled devices.
-  virtual const string16 GetEnterpriseMessage() const = 0;
+  virtual const base::string16 GetEnterpriseMessage() const = 0;
+
+  // Returns the email of user that manages current locally managed user.
+  virtual const std::string GetLocallyManagedUserManager() const = 0;
+
+  // Returns notification for locally managed users.
+  virtual const base::string16 GetLocallyManagedUserMessage() const = 0;
 
   // Returns whether a system upgrade is available.
   virtual bool SystemShouldUpgrade() const = 0;
@@ -182,6 +199,12 @@
   // Shows information about enterprise enrolled devices.
   virtual void ShowEnterpriseInfo() = 0;
 
+  // Shows information about locally managed users.
+  virtual void ShowLocallyManagedUserInfo() = 0;
+
+  // Shows login UI to add other users to this session.
+  virtual void ShowUserLogin() = 0;
+
   // Attempts to shut down the system.
   virtual void ShutDown() = 0;
 
@@ -203,8 +226,8 @@
   // Requests bluetooth stop discovering devices.
   virtual void BluetoothStopDiscovering() = 0;
 
-  // Toggles connection to a specific bluetooth device.
-  virtual void ToggleBluetoothConnection(const std::string& address) = 0;
+  // Connect to a specific bluetooth device.
+  virtual void ConnectToBluetoothDevice(const std::string& address) = 0;
 
   // Returns true if bluetooth adapter is discovering bluetooth devices.
   virtual bool IsBluetoothDiscovering() = 0;
@@ -225,7 +248,7 @@
   virtual void ActivateIMEProperty(const std::string& key) = 0;
 
   // Cancels ongoing drive operation.
-  virtual void CancelDriveOperation(const base::FilePath& file_path) = 0;
+  virtual void CancelDriveOperation(int32 operation_id) = 0;
 
   // Returns information about the ongoing drive operations.
   virtual void GetDriveOperationStatusList(
@@ -343,7 +366,8 @@
   // Returns the duration formatted as a localized string.
   // TODO(stevenjb): Move TimeFormat from src/chrome to src/ui so that it can be
   // accessed without going through the delegate. crbug.com/222697
-  virtual string16 FormatTimeDuration(const base::TimeDelta& delta) const = 0;
+  virtual base::string16 FormatTimeDuration(
+      const base::TimeDelta& delta) const = 0;
 
   // Speaks the given text if spoken feedback is enabled.
   virtual void MaybeSpeak(const std::string& utterance) const = 0;
diff --git a/ash/system/tray/system_tray_notifier.cc b/ash/system/tray/system_tray_notifier.cc
index 070f8f3..a6a9d98 100644
--- a/ash/system/tray/system_tray_notifier.cc
+++ b/ash/system/tray/system_tray_notifier.cc
@@ -22,14 +22,6 @@
   accessibility_observers_.RemoveObserver(observer);
 }
 
-void SystemTrayNotifier::AddAudioObserver(AudioObserver* observer) {
-  audio_observers_.AddObserver(observer);
-}
-
-void SystemTrayNotifier::RemoveAudioObserver(AudioObserver* observer) {
-  audio_observers_.RemoveObserver(observer);
-}
-
 void SystemTrayNotifier::AddBluetoothObserver(BluetoothObserver* observer) {
   bluetooth_observers_.AddObserver(observer);
 }
@@ -134,6 +126,15 @@
 }
 
 #if defined(OS_CHROMEOS)
+
+void SystemTrayNotifier::AddAudioObserver(AudioObserver* observer) {
+  audio_observers_.AddObserver(observer);
+}
+
+void SystemTrayNotifier::RemoveAudioObserver(AudioObserver* observer) {
+  audio_observers_.RemoveObserver(observer);
+}
+
 void SystemTrayNotifier::AddNetworkObserver(NetworkObserver* observer) {
   network_observers_.AddObserver(observer);
 }
@@ -188,18 +189,6 @@
       OnAccessibilityModeChanged(notify));
 }
 
-void SystemTrayNotifier::NotifyVolumeChanged(float level) {
-  FOR_EACH_OBSERVER(AudioObserver,
-                    audio_observers_,
-                    OnVolumeChanged(level));
-}
-
-void SystemTrayNotifier::NotifyMuteToggled() {
-  FOR_EACH_OBSERVER(AudioObserver,
-                    audio_observers_,
-                    OnMuteToggled());
-}
-
 void SystemTrayNotifier::NotifyRefreshBluetooth() {
   FOR_EACH_OBSERVER(BluetoothObserver,
                     bluetooth_observers_,
@@ -244,10 +233,11 @@
                     OnSystemClockTimeUpdated());
 }
 
-void SystemTrayNotifier::NotifyRefreshDrive(DriveOperationStatusList& list) {
+void SystemTrayNotifier::NotifyDriveJobUpdated(
+    const DriveOperationStatus& status) {
   FOR_EACH_OBSERVER(DriveObserver,
                     drive_observers_,
-                    OnDriveRefresh(list));
+                    OnDriveJobUpdated(status));
 }
 
 void SystemTrayNotifier::NotifyRefreshIME(bool show_message) {
@@ -307,6 +297,18 @@
 
 #if defined(OS_CHROMEOS)
 
+void SystemTrayNotifier::NotifyVolumeChanged(float level) {
+  FOR_EACH_OBSERVER(AudioObserver,
+                    audio_observers_,
+                    OnVolumeChanged(level));
+}
+
+void SystemTrayNotifier::NotifyMuteToggled() {
+  FOR_EACH_OBSERVER(AudioObserver,
+                    audio_observers_,
+                    OnMuteToggled());
+}
+
 void SystemTrayNotifier::NotifyRefreshNetwork(const NetworkIconInfo &info) {
   FOR_EACH_OBSERVER(NetworkObserver,
                     network_observers_,
@@ -317,9 +319,9 @@
     NetworkTrayDelegate* delegate,
     NetworkObserver::MessageType message_type,
     NetworkObserver::NetworkType network_type,
-    const string16& title,
-    const string16& message,
-    const std::vector<string16>& links) {
+    const base::string16& title,
+    const base::string16& message,
+    const std::vector<base::string16>& links) {
   FOR_EACH_OBSERVER(NetworkObserver,
                     network_observers_,
                     SetNetworkMessage(
@@ -362,7 +364,7 @@
 
 void SystemTrayNotifier::NotifyScreenCaptureStart(
     const base::Closure& stop_callback,
-    const string16& sharing_app_name) {
+    const base::string16& sharing_app_name) {
   FOR_EACH_OBSERVER(ScreenCaptureObserver, screen_capture_observers_,
                     OnScreenCaptureStart(stop_callback, sharing_app_name));
 }
diff --git a/ash/system/tray/system_tray_notifier.h b/ash/system/tray/system_tray_notifier.h
index efc0251..1f7becf 100644
--- a/ash/system/tray/system_tray_notifier.h
+++ b/ash/system/tray/system_tray_notifier.h
@@ -9,7 +9,6 @@
 #include <vector>
 
 #include "ash/ash_export.h"
-#include "ash/system/audio/audio_observer.h"
 #include "ash/system/bluetooth/bluetooth_observer.h"
 #include "ash/system/brightness/brightness_observer.h"
 #include "ash/system/chromeos/enterprise/enterprise_domain_observer.h"
@@ -29,6 +28,7 @@
 #include "base/observer_list.h"
 
 #if defined(OS_CHROMEOS)
+#include "ash/system/chromeos/audio/audio_observer.h"
 #include "ash/system/chromeos/network/network_observer.h"
 #include "ash/system/chromeos/network/sms_observer.h"
 #include "ash/system/chromeos/screen_capture/screen_capture_observer.h"
@@ -44,9 +44,6 @@
   void AddAccessibilityObserver(AccessibilityObserver* observer);
   void RemoveAccessibilityObserver(AccessibilityObserver* observer);
 
-  void AddAudioObserver(AudioObserver* observer);
-  void RemoveAudioObserver(AudioObserver* observer);
-
   void AddBluetoothObserver(BluetoothObserver* observer);
   void RemoveBluetoothObserver(BluetoothObserver* observer);
 
@@ -84,6 +81,9 @@
   void RemoveUserObserver(UserObserver* observer);
 
 #if defined(OS_CHROMEOS)
+  void AddAudioObserver(AudioObserver* observer);
+  void RemoveAudioObserver(AudioObserver* observer);
+
   void AddNetworkObserver(NetworkObserver* observer);
   void RemoveNetworkObserver(NetworkObserver* observer);
 
@@ -102,8 +102,6 @@
 
   void NotifyAccessibilityModeChanged(
       AccessibilityNotificationVisibility notify);
-  void NotifyVolumeChanged(float level);
-  void NotifyMuteToggled();
   void NotifyRefreshBluetooth();
   void NotifyBluetoothDiscoveringChanged();
   void NotifyBrightnessChanged(double level, bool user_initialted);
@@ -111,7 +109,7 @@
   void NotifyRefreshClock();
   void NotifyDateFormatChanged();
   void NotifySystemClockTimeUpdated();
-  void NotifyRefreshDrive(DriveOperationStatusList& list);
+  void NotifyDriveJobUpdated(const DriveOperationStatus& status);
   void NotifyRefreshIME(bool show_message);
   void NotifyShowLoginButtonChanged(bool show_login_button);
   void NotifyLocaleChanged(LocaleObserver::Delegate* delegate,
@@ -124,26 +122,27 @@
   void NotifyUpdateRecommended(UpdateObserver::UpdateSeverity severity);
   void NotifyUserUpdate();
 #if defined(OS_CHROMEOS)
+  void NotifyVolumeChanged(float level);
+  void NotifyMuteToggled();
   void NotifyRefreshNetwork(const NetworkIconInfo &info);
   void NotifySetNetworkMessage(NetworkTrayDelegate* delegate,
                                NetworkObserver::MessageType message_type,
                                NetworkObserver::NetworkType network_type,
-                               const string16& title,
-                               const string16& message,
-                               const std::vector<string16>& links);
+                               const base::string16& title,
+                               const base::string16& message,
+                               const std::vector<base::string16>& links);
   void NotifyClearNetworkMessage(NetworkObserver::MessageType message_type);
   void NotifyVpnRefreshNetwork(const NetworkIconInfo &info);
   void NotifyWillToggleWifi();
   void NotifyAddSmsMessage(const base::DictionaryValue& message);
   void NotifyEnterpriseDomainChanged();
   void NotifyScreenCaptureStart(const base::Closure& stop_callback,
-                                const string16& sharing_app_name);
+                                const base::string16& sharing_app_name);
   void NotifyScreenCaptureStop();
 #endif
 
  private:
   ObserverList<AccessibilityObserver> accessibility_observers_;
-  ObserverList<AudioObserver> audio_observers_;
   ObserverList<BluetoothObserver> bluetooth_observers_;
   ObserverList<BrightnessObserver> brightness_observers_;
   ObserverList<CapsLockObserver> caps_lock_observers_;
@@ -157,6 +156,7 @@
   ObserverList<UpdateObserver> update_observers_;
   ObserverList<UserObserver> user_observers_;
 #if defined(OS_CHROMEOS)
+  ObserverList<AudioObserver> audio_observers_;
   ObserverList<NetworkObserver> network_observers_;
   ObserverList<NetworkObserver> vpn_observers_;
   ObserverList<SmsObserver> sms_observers_;
diff --git a/ash/system/tray/system_tray_unittest.cc b/ash/system/tray/system_tray_unittest.cc
index 8ec6c9e..0e61a1e 100644
--- a/ash/system/tray/system_tray_unittest.cc
+++ b/ash/system/tray/system_tray_unittest.cc
@@ -8,6 +8,7 @@
 
 #include "ash/root_window_controller.h"
 #include "ash/shelf/shelf_widget.h"
+#include "ash/shell.h"
 #include "ash/system/status_area_widget.h"
 #include "ash/system/tray/system_tray_item.h"
 #include "ash/test/ash_test_base.h"
diff --git a/ash/system/tray/test_system_tray_delegate.cc b/ash/system/tray/test_system_tray_delegate.cc
index afc5f82..a832732 100644
--- a/ash/system/tray/test_system_tray_delegate.cc
+++ b/ash/system/tray/test_system_tray_delegate.cc
@@ -6,8 +6,8 @@
 
 #include <string>
 
+#include "ash/session_state_delegate.h"
 #include "ash/shell.h"
-#include "ash/shell_delegate.h"
 #include "ash/volume_control_delegate.h"
 #include "base/utf_string_conversions.h"
 #include "base/message_loop.h"
@@ -57,8 +57,7 @@
       cellular_enabled_(true),
       bluetooth_enabled_(true),
       caps_lock_enabled_(false),
-      volume_control_delegate_(
-          ALLOW_THIS_IN_INITIALIZER_LIST(new TestVolumeControlDelegate)) {
+      volume_control_delegate_(new TestVolumeControlDelegate) {
 }
 
 TestSystemTrayDelegate::~TestSystemTrayDelegate() {
@@ -67,12 +66,15 @@
 void TestSystemTrayDelegate::Initialize() {
 }
 
+void TestSystemTrayDelegate::Shutdown() {
+}
+
 bool TestSystemTrayDelegate::GetTrayVisibilityOnStartup() {
   return true;
 }
 
 // Overridden from SystemTrayDelegate:
-const string16 TestSystemTrayDelegate::GetUserDisplayName() const {
+const base::string16 TestSystemTrayDelegate::GetUserDisplayName() const {
   return UTF8ToUTF16("Über tray Über tray Über tray Über tray");
 }
 
@@ -87,9 +89,12 @@
 user::LoginStatus TestSystemTrayDelegate::GetUserLoginStatus() const {
   // At new user image screen manager->IsUserLoggedIn() would return true
   // but there's no browser session available yet so use SessionStarted().
-  if (!Shell::GetInstance()->delegate()->IsSessionStarted())
+  SessionStateDelegate* delegate =
+      Shell::GetInstance()->session_state_delegate();
+
+  if (!delegate->IsActiveUserSessionStarted())
     return ash::user::LOGGED_IN_NONE;
-  if (Shell::GetInstance()->IsScreenLocked())
+  if (delegate->IsScreenLocked())
     return user::LOGGED_IN_LOCKED;
   // TODO(nkostylev): Support LOGGED_IN_OWNER, LOGGED_IN_GUEST, LOGGED_IN_KIOSK,
   //                  LOGGED_IN_PUBLIC.
@@ -100,6 +105,12 @@
   return true;
 }
 
+void TestSystemTrayDelegate::GetLoggedInUsers(UserEmailList* users) {
+}
+
+void TestSystemTrayDelegate::SwitchActiveUser(const std::string& email) {
+}
+
 void TestSystemTrayDelegate::ChangeProfilePicture() {
 }
 
@@ -107,7 +118,16 @@
   return std::string();
 }
 
-const string16 TestSystemTrayDelegate::GetEnterpriseMessage() const {
+const base::string16 TestSystemTrayDelegate::GetEnterpriseMessage() const {
+  return string16();
+}
+
+const std::string TestSystemTrayDelegate::GetLocallyManagedUserManager() const {
+  return std::string();
+}
+
+const base::string16 TestSystemTrayDelegate::GetLocallyManagedUserMessage()
+    const {
   return string16();
 }
 
@@ -159,12 +179,18 @@
 void TestSystemTrayDelegate::ShowEnterpriseInfo() {
 }
 
+void TestSystemTrayDelegate::ShowLocallyManagedUserInfo() {
+}
+
+void TestSystemTrayDelegate::ShowUserLogin() {
+}
+
 void TestSystemTrayDelegate::ShutDown() {
-  MessageLoop::current()->Quit();
+  base::MessageLoop::current()->Quit();
 }
 
 void TestSystemTrayDelegate::SignOut() {
-  MessageLoop::current()->Quit();
+  base::MessageLoop::current()->Quit();
 }
 
 void TestSystemTrayDelegate::RequestLockScreen() {
@@ -183,7 +209,7 @@
 void TestSystemTrayDelegate::BluetoothStopDiscovering() {
 }
 
-void TestSystemTrayDelegate::ToggleBluetoothConnection(
+void TestSystemTrayDelegate::ConnectToBluetoothDevice(
     const std::string& address) {
 }
 
@@ -203,7 +229,7 @@
 void TestSystemTrayDelegate::ActivateIMEProperty(const std::string& key) {
 }
 
-void TestSystemTrayDelegate::CancelDriveOperation(const base::FilePath&) {
+void TestSystemTrayDelegate::CancelDriveOperation(int32 operation_id) {
 }
 
 void TestSystemTrayDelegate::GetDriveOperationStatusList(
@@ -348,9 +374,9 @@
   return 300;
 }
 
-string16 TestSystemTrayDelegate::FormatTimeDuration(
+base::string16 TestSystemTrayDelegate::FormatTimeDuration(
     const base::TimeDelta& delta) const {
-  return string16();
+  return base::string16();
 }
 
 void TestSystemTrayDelegate::MaybeSpeak(const std::string& utterance) const {
diff --git a/ash/system/tray/test_system_tray_delegate.h b/ash/system/tray/test_system_tray_delegate.h
index ee859a2..58c9825 100644
--- a/ash/system/tray/test_system_tray_delegate.h
+++ b/ash/system/tray/test_system_tray_delegate.h
@@ -22,17 +22,22 @@
 
  public:
   virtual void Initialize() OVERRIDE;
+  virtual void Shutdown() OVERRIDE;
   virtual bool GetTrayVisibilityOnStartup() OVERRIDE;
 
   // Overridden from SystemTrayDelegate:
-  virtual const string16 GetUserDisplayName() const OVERRIDE;
+  virtual const base::string16 GetUserDisplayName() const OVERRIDE;
   virtual const std::string GetUserEmail() const OVERRIDE;
   virtual const gfx::ImageSkia& GetUserImage() const OVERRIDE;
   virtual user::LoginStatus GetUserLoginStatus() const OVERRIDE;
   virtual bool IsOobeCompleted() const OVERRIDE;
+  virtual void GetLoggedInUsers(UserEmailList* users) OVERRIDE;
+  virtual void SwitchActiveUser(const std::string& email) OVERRIDE;
   virtual void ChangeProfilePicture() OVERRIDE;
   virtual const std::string GetEnterpriseDomain() const OVERRIDE;
-  virtual const string16 GetEnterpriseMessage() const OVERRIDE;
+  virtual const base::string16 GetEnterpriseMessage() const OVERRIDE;
+  virtual const std::string GetLocallyManagedUserManager() const OVERRIDE;
+  virtual const base::string16 GetLocallyManagedUserMessage() const OVERRIDE;
   virtual bool SystemShouldUpgrade() const OVERRIDE;
   virtual base::HourClockType GetHourClockType() const OVERRIDE;
   virtual PowerSupplyStatus GetPowerSupplyStatus() const OVERRIDE;
@@ -48,6 +53,8 @@
   virtual void ShowAccessibilityHelp() OVERRIDE;
   virtual void ShowPublicAccountInfo() OVERRIDE;
   virtual void ShowEnterpriseInfo() OVERRIDE;
+  virtual void ShowLocallyManagedUserInfo() OVERRIDE;
+  virtual void ShowUserLogin() OVERRIDE;
   virtual void ShutDown() OVERRIDE;
   virtual void SignOut() OVERRIDE;
   virtual void RequestLockScreen() OVERRIDE;
@@ -55,13 +62,13 @@
   virtual void GetAvailableBluetoothDevices(BluetoothDeviceList* list) OVERRIDE;
   virtual void BluetoothStartDiscovering() OVERRIDE;
   virtual void BluetoothStopDiscovering() OVERRIDE;
-  virtual void ToggleBluetoothConnection(const std::string& address) OVERRIDE;
+  virtual void ConnectToBluetoothDevice(const std::string& address) OVERRIDE;
   virtual void GetCurrentIME(IMEInfo* info) OVERRIDE;
   virtual void GetAvailableIMEList(IMEInfoList* list) OVERRIDE;
   virtual void GetCurrentIMEProperties(IMEPropertyInfoList* list) OVERRIDE;
   virtual void SwitchIME(const std::string& ime_id) OVERRIDE;
   virtual void ActivateIMEProperty(const std::string& key) OVERRIDE;
-  virtual void CancelDriveOperation(const base::FilePath&) OVERRIDE;
+  virtual void CancelDriveOperation(int32 operation_id) OVERRIDE;
   virtual void GetDriveOperationStatusList(
       ash::DriveOperationStatusList*) OVERRIDE;
   virtual void GetMostRelevantNetworkIcon(NetworkIconInfo* info,
@@ -107,7 +114,7 @@
   virtual bool GetSessionLengthLimit(
       base::TimeDelta* session_length_limit) OVERRIDE;
   virtual int GetSystemTrayMenuWidth() OVERRIDE;
-  virtual string16 FormatTimeDuration(
+  virtual base::string16 FormatTimeDuration(
       const base::TimeDelta& delta) const OVERRIDE;
   virtual void MaybeSpeak(const std::string& utterance) const OVERRIDE;
 
diff --git a/ash/system/tray/throbber_view.cc b/ash/system/tray/throbber_view.cc
index 89d4ed4..2c2cc20 100644
--- a/ash/system/tray/throbber_view.cc
+++ b/ash/system/tray/throbber_view.cc
@@ -30,12 +30,12 @@
 SystemTrayThrobber::~SystemTrayThrobber() {
 }
 
-void SystemTrayThrobber::SetTooltipText(const string16& tooltip_text) {
+void SystemTrayThrobber::SetTooltipText(const base::string16& tooltip_text) {
   tooltip_text_ = tooltip_text;
 }
 
 bool SystemTrayThrobber::GetTooltipText(const gfx::Point& p,
-                                        string16* tooltip) const {
+                                        base::string16* tooltip) const {
   if (tooltip_text_.empty())
     return false;
 
@@ -72,7 +72,7 @@
 }
 
 bool ThrobberView::GetTooltipText(const gfx::Point& p,
-                                  string16* tooltip) const {
+                                  base::string16* tooltip) const {
   if (tooltip_text_.empty())
     return false;
 
@@ -90,7 +90,7 @@
   throbber_->Stop();
 }
 
-void ThrobberView::SetTooltipText(const string16& tooltip_text) {
+void ThrobberView::SetTooltipText(const base::string16& tooltip_text) {
   tooltip_text_ = tooltip_text;
   throbber_->SetTooltipText(tooltip_text);
 }
diff --git a/ash/system/tray/throbber_view.h b/ash/system/tray/throbber_view.h
index 4297df4..0f26632 100644
--- a/ash/system/tray/throbber_view.h
+++ b/ash/system/tray/throbber_view.h
@@ -18,15 +18,15 @@
   SystemTrayThrobber(int frame_delay_ms);
   virtual ~SystemTrayThrobber();
 
-  void SetTooltipText(const string16& tooltip_text);
+  void SetTooltipText(const base::string16& tooltip_text);
 
   // Overriden from views::View.
   virtual bool GetTooltipText(
-        const gfx::Point& p, string16* tooltip) const OVERRIDE;
+        const gfx::Point& p, base::string16* tooltip) const OVERRIDE;
 
  private:
   // The current tooltip text.
-  string16 tooltip_text_;
+  base::string16 tooltip_text_;
 
   DISALLOW_COPY_AND_ASSIGN(SystemTrayThrobber);
 };
@@ -39,13 +39,13 @@
 
   void Start();
   void Stop();
-  void SetTooltipText(const string16& tooltip_text);
+  void SetTooltipText(const base::string16& tooltip_text);
 
   // Overriden from views::View.
   virtual gfx::Size GetPreferredSize() OVERRIDE;
   virtual void Layout() OVERRIDE;
   virtual bool GetTooltipText(
-      const gfx::Point& p, string16* tooltip) const OVERRIDE;
+      const gfx::Point& p, base::string16* tooltip) const OVERRIDE;
 
  private:
   // Schedules animation for starting/stopping throbber.
@@ -54,7 +54,7 @@
   SystemTrayThrobber* throbber_;
 
   // The current tooltip text.
-  string16 tooltip_text_;
+  base::string16 tooltip_text_;
 
   DISALLOW_COPY_AND_ASSIGN(ThrobberView);
 };
diff --git a/ash/system/tray/tray_background_view.cc b/ash/system/tray/tray_background_view.cc
index 68c6b62..3f51d62 100644
--- a/ash/system/tray/tray_background_view.cc
+++ b/ash/system/tray/tray_background_view.cc
@@ -27,7 +27,9 @@
 
 namespace {
 
-const SkColor kTrayBackgroundHoverAlpha = 150;
+const int kTrayBackgroundAlpha = 100;
+const int kTrayBackgroundHoverAlpha = 150;
+const SkColor kTrayBackgroundPressedColor = SkColorSetRGB(66, 129, 244);
 
 // Adjust the size of TrayContainer with additional padding.
 const int kTrayContainerVerticalPaddingBottomAlignment  = 1;
@@ -70,10 +72,15 @@
 
 class TrayBackground : public views::Background {
  public:
-  TrayBackground() : alpha_(0) {}
+  TrayBackground() {
+    set_alpha(kTrayBackgroundAlpha);
+  }
+
   virtual ~TrayBackground() {}
 
-  void set_alpha(int alpha) { alpha_ = alpha; }
+  SkColor color() { return color_; }
+  void set_color(SkColor color) { color_ = color; }
+  void set_alpha(int alpha) { color_ = SkColorSetARGB(alpha, 0, 0, 0); }
 
  private:
   // Overridden from views::Background.
@@ -81,7 +88,7 @@
     SkPaint paint;
     paint.setAntiAlias(true);
     paint.setStyle(SkPaint::kFill_Style);
-    paint.setColor(SkColorSetARGB(alpha_, 0, 0, 0));
+    paint.setColor(color_);
     SkPath path;
     gfx::Rect bounds(view->GetLocalBounds());
     SkScalar radius = SkIntToScalar(kTrayRoundedBorderRadius);
@@ -89,7 +96,7 @@
     canvas->DrawPath(path, paint);
   }
 
-  int alpha_;
+  SkColor color_;
 
   DISALLOW_COPY_AND_ASSIGN(TrayBackground);
 };
@@ -165,13 +172,16 @@
       tray_container_(NULL),
       shelf_alignment_(SHELF_ALIGNMENT_BOTTOM),
       background_(NULL),
-      ALLOW_THIS_IN_INITIALIZER_LIST(hover_background_animator_(
-          this, 0, kTrayBackgroundHoverAlpha)),
-      ALLOW_THIS_IN_INITIALIZER_LIST(widget_observer_(
-          new TrayWidgetObserver(this))) {
+      hide_background_animator_(this, 0, kTrayBackgroundAlpha),
+      hover_background_animator_(
+          this, 0, kTrayBackgroundHoverAlpha - kTrayBackgroundAlpha),
+      hovered_(false),
+      pressed_(false),
+      widget_observer_(new TrayWidgetObserver(this)) {
   set_notify_enter_exit_on_child(true);
 
   // Initially we want to paint the background, but without the hover effect.
+  SetPaintsBackground(true, internal::BackgroundAnimator::CHANGE_IMMEDIATE);
   hover_background_animator_.SetPaintsBackground(false,
       internal::BackgroundAnimator::CHANGE_IMMEDIATE);
 
@@ -191,11 +201,23 @@
 }
 
 void TrayBackgroundView::OnMouseEntered(const ui::MouseEvent& event) {
+  hovered_ = true;
+  if (!background_)
+    return;
+  if (pressed_)
+    return;
+
   hover_background_animator_.SetPaintsBackground(true,
       internal::BackgroundAnimator::CHANGE_ANIMATE);
 }
 
 void TrayBackgroundView::OnMouseExited(const ui::MouseEvent& event) {
+  hovered_ = false;
+  if (!background_)
+    return;
+  if (pressed_)
+    return;
+
   hover_background_animator_.SetPaintsBackground(false,
       internal::BackgroundAnimator::CHANGE_ANIMATE);
 }
@@ -229,9 +251,13 @@
 }
 
 void TrayBackgroundView::UpdateBackground(int alpha) {
-  if (background_) {
-    background_->set_alpha(hover_background_animator_.alpha());
-  }
+  if (!background_)
+    return;
+  if (pressed_)
+    return;
+
+  background_->set_alpha(hide_background_animator_.alpha() +
+                         hover_background_animator_.alpha());
   SchedulePaint();
 }
 
@@ -240,6 +266,12 @@
   AddChildView(contents);
 }
 
+void TrayBackgroundView::SetPaintsBackground(
+    bool value,
+    internal::BackgroundAnimator::ChangeType change_type) {
+  hide_background_animator_.SetPaintsBackground(value, change_type);
+}
+
 void TrayBackgroundView::SetContentsBackground() {
   background_ = new internal::TrayBackground;
   tray_container_->set_background(background_);
@@ -369,6 +401,21 @@
   return TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM;
 }
 
+void TrayBackgroundView::SetBubbleVisible(bool visible) {
+  pressed_ = visible;
+  if (!background_)
+    return;
+
+  // Do not change gradually, changing color between grey and blue is weird.
+  if (pressed_)
+    background_->set_color(kTrayBackgroundPressedColor);
+  else if (hovered_)
+    background_->set_alpha(kTrayBackgroundHoverAlpha);
+  else
+    background_->set_alpha(kTrayBackgroundAlpha);
+  SchedulePaint();
+}
+
 void TrayBackgroundView::UpdateBubbleViewArrow(
     views::TrayBubbleView* bubble_view) {
   aura::RootWindow* root_window =
diff --git a/ash/system/tray/tray_background_view.h b/ash/system/tray/tray_background_view.h
index 39f2a4c..15597ba 100644
--- a/ash/system/tray/tray_background_view.h
+++ b/ash/system/tray/tray_background_view.h
@@ -84,7 +84,7 @@
   virtual void AnchorUpdated() {}
 
   // Called from GetAccessibleState, must return a valid accessible name.
-  virtual string16 GetAccessibleNameForTray() = 0;
+  virtual base::string16 GetAccessibleNameForTray() = 0;
 
   // Hides the bubble associated with |bubble_view|. Called when the widget
   // is closed.
@@ -100,6 +100,12 @@
   // Creates and sets contents background to |background_|.
   void SetContentsBackground();
 
+  // Sets whether the tray paints a background. Default is true, but is set to
+  // false if a window overlaps the shelf.
+  void SetPaintsBackground(
+      bool value,
+      internal::BackgroundAnimator::ChangeType change_type);
+
   // Initializes animations for the bubble.
   void InitializeBubbleAnimations(views::Widget* bubble_widget);
 
@@ -115,6 +121,9 @@
   // Returns the bubble anchor alignment based on |shelf_alignment_|.
   views::TrayBubbleView::AnchorAlignment GetAnchorAlignment() const;
 
+  // Updates the view visual based on the visibility of the bubble.
+  void SetBubbleVisible(bool visible);
+
   StatusAreaWidget* status_area_widget() {
     return status_area_widget_;
   }
@@ -149,7 +158,10 @@
   // Owned by the view passed to SetContents().
   internal::TrayBackground* background_;
 
+  internal::BackgroundAnimator hide_background_animator_;
   internal::BackgroundAnimator hover_background_animator_;
+  bool hovered_;
+  bool pressed_;
   scoped_ptr<TrayWidgetObserver> widget_observer_;
   scoped_ptr<TrayEventFilter> tray_event_filter_;
 
diff --git a/ash/system/tray/tray_bar_button_with_title.cc b/ash/system/tray/tray_bar_button_with_title.cc
index d8b6895..0fd94d8 100644
--- a/ash/system/tray/tray_bar_button_with_title.cc
+++ b/ash/system/tray/tray_bar_button_with_title.cc
@@ -71,7 +71,7 @@
   if (title_id != -1) {
     title_ = new views::Label;
     ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
-    string16 text = rb.GetLocalizedString(title_id);
+    base::string16 text = rb.GetLocalizedString(title_id);
     title_->SetText(text);
     AddChildView(title_);
   }
diff --git a/ash/system/tray/tray_image_item.cc b/ash/system/tray/tray_image_item.cc
index f5a3e89..d4ff904 100644
--- a/ash/system/tray/tray_image_item.cc
+++ b/ash/system/tray/tray_image_item.cc
@@ -5,7 +5,7 @@
 #include "ash/system/tray/tray_image_item.h"
 
 #include "ash/system/tray/tray_item_view.h"
-#include "ash/system/tray/tray_views.h"
+#include "ash/system/tray/tray_utils.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/image/image.h"
 #include "ui/views/controls/image_view.h"
diff --git a/ash/system/tray/tray_item_more.cc b/ash/system/tray/tray_item_more.cc
index f13b2f1..9284b47 100644
--- a/ash/system/tray/tray_item_more.cc
+++ b/ash/system/tray/tray_item_more.cc
@@ -7,7 +7,6 @@
 #include "ash/system/tray/fixed_sized_image_view.h"
 #include "ash/system/tray/system_tray_item.h"
 #include "ash/system/tray/tray_constants.h"
-#include "ash/system/tray/tray_views.h"
 #include "grit/ash_resources.h"
 #include "ui/base/accessibility/accessible_view_state.h"
 #include "ui/base/resource/resource_bundle.h"
@@ -47,7 +46,7 @@
 TrayItemMore::~TrayItemMore() {
 }
 
-void TrayItemMore::SetLabel(const string16& label) {
+void TrayItemMore::SetLabel(const base::string16& label) {
   label_->SetText(label);
   Layout();
   SchedulePaint();
@@ -58,7 +57,7 @@
   SchedulePaint();
 }
 
-void TrayItemMore::SetAccessibleName(const string16& name) {
+void TrayItemMore::SetAccessibleName(const base::string16& name) {
   accessible_name_ = name;
 }
 
diff --git a/ash/system/tray/tray_item_more.h b/ash/system/tray/tray_item_more.h
index 85839ad..4928724 100644
--- a/ash/system/tray/tray_item_more.h
+++ b/ash/system/tray/tray_item_more.h
@@ -29,9 +29,9 @@
 
   SystemTrayItem* owner() const { return owner_; }
 
-  void SetLabel(const string16& label);
+  void SetLabel(const base::string16& label);
   void SetImage(const gfx::ImageSkia* image_skia);
-  void SetAccessibleName(const string16& name);
+  void SetAccessibleName(const base::string16& name);
 
  protected:
   // Replaces the default icon (on the left of the label), and allows a custom
@@ -53,7 +53,7 @@
   views::ImageView* icon_;
   views::Label* label_;
   views::ImageView* more_;
-  string16 accessible_name_;
+  base::string16 accessible_name_;
 
   DISALLOW_COPY_AND_ASSIGN(TrayItemMore);
 };
diff --git a/ash/system/tray/tray_item_view.cc b/ash/system/tray/tray_item_view.cc
index 426ff52..632dcbf 100644
--- a/ash/system/tray/tray_item_view.cc
+++ b/ash/system/tray/tray_item_view.cc
@@ -51,7 +51,7 @@
     return;
   }
 
-  if (!animation_.get()) {
+  if (!animation_) {
     animation_.reset(new ui::SlideAnimation(this));
     animation_->SetSlideDuration(GetAnimationDurationMS());
     animation_->SetTweenType(ui::Tween::LINEAR);
@@ -90,6 +90,10 @@
   return size;
 }
 
+int TrayItemView::GetHeightForWidth(int width) {
+  return GetPreferredSize().height();
+}
+
 void TrayItemView::ChildPreferredSizeChanged(views::View* child) {
   PreferredSizeChanged();
 }
diff --git a/ash/system/tray/tray_item_view.h b/ash/system/tray/tray_item_view.h
index 00c5297..ca260cf 100644
--- a/ash/system/tray/tray_item_view.h
+++ b/ash/system/tray/tray_item_view.h
@@ -43,6 +43,7 @@
   // Overridden from views::View.
   virtual void SetVisible(bool visible) OVERRIDE;
   virtual gfx::Size GetPreferredSize() OVERRIDE;
+  virtual int GetHeightForWidth(int width) OVERRIDE;
 
  protected:
   // Makes sure the widget relayouts after the size/visibility of the view
diff --git a/ash/system/tray/tray_popup_header_button.cc b/ash/system/tray/tray_popup_header_button.cc
new file mode 100644
index 0000000..dac6f9a
--- /dev/null
+++ b/ash/system/tray/tray_popup_header_button.cc
@@ -0,0 +1,64 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/system/tray/tray_popup_header_button.h"
+
+#include "ash/ash_constants.h"
+#include "ash/system/tray/tray_constants.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/gfx/canvas.h"
+
+namespace ash {
+namespace internal {
+
+TrayPopupHeaderButton::TrayPopupHeaderButton(views::ButtonListener* listener,
+                                             int enabled_resource_id,
+                                             int disabled_resource_id,
+                                             int enabled_resource_id_hover,
+                                             int disabled_resource_id_hover,
+                                             int accessible_name_id)
+    : views::ToggleImageButton(listener) {
+  ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
+  SetImage(views::Button::STATE_NORMAL,
+      bundle.GetImageNamed(enabled_resource_id).ToImageSkia());
+  SetToggledImage(views::Button::STATE_NORMAL,
+      bundle.GetImageNamed(disabled_resource_id).ToImageSkia());
+  SetImage(views::Button::STATE_HOVERED,
+      bundle.GetImageNamed(enabled_resource_id_hover).ToImageSkia());
+  SetToggledImage(views::Button::STATE_HOVERED,
+      bundle.GetImageNamed(disabled_resource_id_hover).ToImageSkia());
+  SetImageAlignment(views::ImageButton::ALIGN_CENTER,
+                    views::ImageButton::ALIGN_MIDDLE);
+  SetAccessibleName(bundle.GetLocalizedString(accessible_name_id));
+  set_focusable(true);
+  set_request_focus_on_press(false);
+}
+
+TrayPopupHeaderButton::~TrayPopupHeaderButton() {}
+
+gfx::Size TrayPopupHeaderButton::GetPreferredSize() {
+  return gfx::Size(ash::kTrayPopupItemHeight, ash::kTrayPopupItemHeight);
+}
+
+void TrayPopupHeaderButton::OnPaintBorder(gfx::Canvas* canvas) {
+  // Just the left border.
+  const int kBorderHeight = 25;
+  int padding = (height() - kBorderHeight) / 2;
+  canvas->FillRect(gfx::Rect(0, padding, 1, height() - padding * 2),
+      ash::kBorderDarkColor);
+}
+
+void TrayPopupHeaderButton::OnPaintFocusBorder(gfx::Canvas* canvas) {
+  if (HasFocus() && (focusable() || IsAccessibilityFocusable())) {
+    canvas->DrawRect(gfx::Rect(2, 1, width() - 4, height() - 3),
+                     kFocusBorderColor);
+  }
+}
+
+void TrayPopupHeaderButton::StateChanged() {
+  SchedulePaint();
+}
+
+}  // namespace internal
+}  // namespace ash
diff --git a/ash/system/tray/tray_popup_header_button.h b/ash/system/tray/tray_popup_header_button.h
new file mode 100644
index 0000000..707953c
--- /dev/null
+++ b/ash/system/tray/tray_popup_header_button.h
@@ -0,0 +1,42 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_SYSTEM_TRAY_TRAY_POPUP_HEADER_BUTTON_H_
+#define ASH_SYSTEM_TRAY_TRAY_POPUP_HEADER_BUTTON_H_
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "ui/views/controls/button/image_button.h"
+
+namespace ash {
+namespace internal {
+
+// A ToggleImageButton with fixed size, paddings and hover effects. These
+// buttons are used in the header.
+class TrayPopupHeaderButton : public views::ToggleImageButton {
+ public:
+  TrayPopupHeaderButton(views::ButtonListener* listener,
+                        int enabled_resource_id,
+                        int disabled_resource_id,
+                        int enabled_resource_id_hover,
+                        int disabled_resource_id_hover,
+                        int accessible_name_id);
+  virtual ~TrayPopupHeaderButton();
+
+ private:
+  // Overridden from views::View:
+  virtual gfx::Size GetPreferredSize() OVERRIDE;
+  virtual void OnPaintBorder(gfx::Canvas* canvas) OVERRIDE;
+  virtual void OnPaintFocusBorder(gfx::Canvas* canvas) OVERRIDE;
+
+  // Overridden from views::CustomButton:
+  virtual void StateChanged() OVERRIDE;
+
+  DISALLOW_COPY_AND_ASSIGN(TrayPopupHeaderButton);
+};
+
+}  // namespace internal
+}  // namespace ash
+
+#endif  // ASH_SYSTEM_TRAY_TRAY_POPUP_HEADER_BUTTON_H_
diff --git a/ash/system/tray/tray_popup_label_button.cc b/ash/system/tray/tray_popup_label_button.cc
new file mode 100644
index 0000000..c8e7a6a
--- /dev/null
+++ b/ash/system/tray/tray_popup_label_button.cc
@@ -0,0 +1,35 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/system/tray/tray_popup_label_button.h"
+
+#include "ash/ash_constants.h"
+#include "ash/system/tray/tray_popup_label_button_border.h"
+#include "ui/gfx/canvas.h"
+#include "ui/gfx/rect.h"
+
+namespace ash {
+namespace internal {
+
+TrayPopupLabelButton::TrayPopupLabelButton(views::ButtonListener* listener,
+                                           const base::string16& text)
+    : views::LabelButton(listener, text) {
+  set_border(new TrayPopupLabelButtonBorder);
+  set_focusable(true);
+  set_request_focus_on_press(false);
+  set_animate_on_state_change(false);
+  SetHorizontalAlignment(gfx::ALIGN_CENTER);
+}
+
+TrayPopupLabelButton::~TrayPopupLabelButton() {}
+
+void TrayPopupLabelButton::OnPaintFocusBorder(gfx::Canvas* canvas) {
+  if (HasFocus() && (focusable() || IsAccessibilityFocusable())) {
+    canvas->DrawRect(gfx::Rect(1, 1, width() - 3, height() - 3),
+                     ash::kFocusBorderColor);
+  }
+}
+
+}  // namespace internal
+}  // namespace ash
diff --git a/ash/system/tray/tray_popup_label_button.h b/ash/system/tray/tray_popup_label_button.h
new file mode 100644
index 0000000..9f4d262
--- /dev/null
+++ b/ash/system/tray/tray_popup_label_button.h
@@ -0,0 +1,33 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_SYSTEM_TRAY_TRAY_POPUP_LABEL_BUTTON_H_
+#define ASH_SYSTEM_TRAY_TRAY_POPUP_LABEL_BUTTON_H_
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/string16.h"
+#include "ui/views/controls/button/label_button.h"
+
+namespace ash {
+namespace internal {
+
+// A label button with custom alignment, border and focus border.
+class TrayPopupLabelButton : public views::LabelButton {
+ public:
+  TrayPopupLabelButton(views::ButtonListener* listener,
+                       const base::string16& text);
+  virtual ~TrayPopupLabelButton();
+
+ private:
+  // Overridden from views::LabelButton:
+  virtual void OnPaintFocusBorder(gfx::Canvas* canvas) OVERRIDE;
+
+  DISALLOW_COPY_AND_ASSIGN(TrayPopupLabelButton);
+};
+
+}  // namespace internal
+}  // namespace ash
+
+#endif  // ASH_SYSTEM_TRAY_TRAY_POPUP_LABEL_BUTTON_H_
diff --git a/ash/system/tray/tray_popup_label_button_border.cc b/ash/system/tray/tray_popup_label_button_border.cc
new file mode 100644
index 0000000..275457d
--- /dev/null
+++ b/ash/system/tray/tray_popup_label_button_border.cc
@@ -0,0 +1,109 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/system/tray/tray_popup_label_button_border.h"
+
+#include "base/i18n/rtl.h"
+#include "grit/ash_resources.h"
+#include "ui/gfx/canvas.h"
+#include "ui/gfx/vector2d.h"
+#include "ui/native_theme/native_theme.h"
+#include "ui/views/controls/button/label_button.h"
+#include "ui/views/native_theme_delegate.h"
+
+namespace ash {
+namespace internal {
+
+namespace {
+
+const int kTrayPopupLabelButtonPaddingHorizontal = 16;
+const int kTrayPopupLabelButtonPaddingVertical = 8;
+
+const int kTrayPopupLabelButtonBorderImagesNormal[] = {
+    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_BORDER,
+    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND,
+    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND,
+    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_BORDER,
+    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND,
+    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND,
+    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_BORDER,
+    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND,
+    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND,
+};
+
+const int kTrayPopupLabelButtonBorderImagesHovered[] = {
+    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_BORDER,
+    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_BORDER,
+    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_BORDER,
+    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_BORDER,
+    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_HOVER_BACKGROUND,
+    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_BORDER,
+    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_BORDER,
+    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_BORDER,
+    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_BORDER,
+};
+
+}  // namespace
+
+TrayPopupLabelButtonBorder::TrayPopupLabelButtonBorder()
+    : LabelButtonBorder(views::Button::STYLE_TEXTBUTTON) {
+  SetPainter(false, views::Button::STATE_NORMAL,
+             views::Painter::CreateImageGridPainter(
+                 kTrayPopupLabelButtonBorderImagesNormal));
+  SetPainter(false, views::Button::STATE_DISABLED,
+             views::Painter::CreateImageGridPainter(
+                 kTrayPopupLabelButtonBorderImagesNormal));
+  SetPainter(false, views::Button::STATE_HOVERED,
+             views::Painter::CreateImageGridPainter(
+                 kTrayPopupLabelButtonBorderImagesHovered));
+  SetPainter(false, views::Button::STATE_PRESSED,
+             views::Painter::CreateImageGridPainter(
+                 kTrayPopupLabelButtonBorderImagesHovered));
+}
+
+TrayPopupLabelButtonBorder::~TrayPopupLabelButtonBorder() {}
+
+void TrayPopupLabelButtonBorder::Paint(const views::View& view,
+                                       gfx::Canvas* canvas) {
+  const views::NativeThemeDelegate* native_theme_delegate =
+      static_cast<const views::LabelButton*>(&view);
+  ui::NativeTheme::ExtraParams extra;
+  const ui::NativeTheme::State state =
+      native_theme_delegate->GetThemeState(&extra);
+  if (state == ui::NativeTheme::kNormal ||
+      state == ui::NativeTheme::kDisabled) {
+    // In normal and disabled state, the border is a vertical bar separating the
+    // button from the preceding sibling. If this button is its parent's first
+    // visible child, the separator bar should be omitted.
+    const views::View* first_visible_child = NULL;
+    for (int i = 0; i < view.parent()->child_count(); ++i) {
+      const views::View* child = view.parent()->child_at(i);
+      if (child->visible()) {
+        first_visible_child = child;
+        break;
+      }
+    }
+    if (first_visible_child == &view)
+      return;
+  }
+  if (base::i18n::IsRTL()) {
+    canvas->Save();
+    canvas->Translate(gfx::Vector2d(view.width(), 0));
+    canvas->Scale(-1, 1);
+    LabelButtonBorder::Paint(view, canvas);
+    canvas->Restore();
+  } else {
+    LabelButtonBorder::Paint(view, canvas);
+  }
+}
+
+gfx::Insets TrayPopupLabelButtonBorder::GetInsets() const {
+  return gfx::Insets(kTrayPopupLabelButtonPaddingVertical,
+                     kTrayPopupLabelButtonPaddingHorizontal,
+                     kTrayPopupLabelButtonPaddingVertical,
+                     kTrayPopupLabelButtonPaddingHorizontal);
+}
+
+}  // namespace internal
+}  // namespace ash
diff --git a/ash/system/tray/tray_popup_label_button_border.h b/ash/system/tray/tray_popup_label_button_border.h
new file mode 100644
index 0000000..abfe793
--- /dev/null
+++ b/ash/system/tray/tray_popup_label_button_border.h
@@ -0,0 +1,33 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_SYSTEM_TRAY_TRAY_POPUP_LABEL_BUTTON_BORDER_H_
+#define ASH_SYSTEM_TRAY_TRAY_POPUP_LABEL_BUTTON_BORDER_H_
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "ui/views/controls/button/label_button_border.h"
+
+namespace ash {
+namespace internal {
+
+// A border for label buttons that paints a vertical separator in normal state
+// and a custom hover effect in hovered or pressed state.
+class TrayPopupLabelButtonBorder : public views::LabelButtonBorder {
+ public:
+  TrayPopupLabelButtonBorder();
+  virtual ~TrayPopupLabelButtonBorder();
+
+  // Overridden from views::LabelButtonBorder.
+  virtual void Paint(const views::View& view, gfx::Canvas* canvas) OVERRIDE;
+  virtual gfx::Insets GetInsets() const OVERRIDE;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TrayPopupLabelButtonBorder);
+};
+
+}  // namespace internal
+}  // namespace ash
+
+#endif  // ASH_SYSTEM_TRAY_TRAY_POPUP_LABEL_BUTTON_BORDER_H_
diff --git a/ash/system/tray/tray_utils.cc b/ash/system/tray/tray_utils.cc
new file mode 100644
index 0000000..5f29a2e
--- /dev/null
+++ b/ash/system/tray/tray_utils.cc
@@ -0,0 +1,65 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/system/tray/tray_utils.h"
+
+#include "ash/system/tray/tray_constants.h"
+#include "ash/system/tray/tray_item_view.h"
+#include "ui/gfx/font.h"
+#include "ui/views/border.h"
+#include "ui/views/controls/label.h"
+
+namespace ash {
+namespace internal {
+
+void SetupLabelForTray(views::Label* label) {
+  // Making label_font static to avoid the time penalty of DeriveFont for
+  // all but the first call.
+  static const gfx::Font label_font(gfx::Font().DeriveFont(1, gfx::Font::BOLD));
+  label->SetFont(label_font);
+  label->SetAutoColorReadabilityEnabled(false);
+  label->SetEnabledColor(SK_ColorWHITE);
+  label->SetBackgroundColor(SkColorSetARGB(0, 255, 255, 255));
+  label->SetShadowColors(SkColorSetARGB(64, 0, 0, 0),
+                         SkColorSetARGB(64, 0, 0, 0));
+  label->SetShadowOffset(0, 1);
+}
+
+void SetTrayImageItemBorder(views::View* tray_view,
+                            ShelfAlignment alignment) {
+  if (alignment == SHELF_ALIGNMENT_BOTTOM ||
+      alignment == SHELF_ALIGNMENT_TOP) {
+    tray_view->set_border(views::Border::CreateEmptyBorder(
+        0, kTrayImageItemHorizontalPaddingBottomAlignment,
+        0, kTrayImageItemHorizontalPaddingBottomAlignment));
+  } else {
+    tray_view->set_border(views::Border::CreateEmptyBorder(
+        kTrayImageItemVerticalPaddingVerticalAlignment,
+        kTrayImageItemHorizontalPaddingVerticalAlignment,
+        kTrayImageItemVerticalPaddingVerticalAlignment,
+        kTrayImageItemHorizontalPaddingVerticalAlignment));
+  }
+}
+
+void SetTrayLabelItemBorder(TrayItemView* tray_view,
+                            ShelfAlignment alignment) {
+  if (alignment == SHELF_ALIGNMENT_BOTTOM ||
+      alignment == SHELF_ALIGNMENT_TOP) {
+    tray_view->set_border(views::Border::CreateEmptyBorder(
+        0, kTrayLabelItemHorizontalPaddingBottomAlignment,
+        0, kTrayLabelItemHorizontalPaddingBottomAlignment));
+  } else {
+    // Center the label for vertical launcher alignment.
+    int horizontal_padding = (tray_view->GetPreferredSize().width() -
+        tray_view->label()->GetPreferredSize().width()) / 2;
+    tray_view->set_border(views::Border::CreateEmptyBorder(
+        kTrayLabelItemVerticalPaddingVeriticalAlignment,
+        horizontal_padding,
+        kTrayLabelItemVerticalPaddingVeriticalAlignment,
+        horizontal_padding));
+  }
+}
+
+}  // namespace internal
+}  // namespace ash
diff --git a/ash/system/tray/tray_utils.h b/ash/system/tray/tray_utils.h
new file mode 100644
index 0000000..412fb97
--- /dev/null
+++ b/ash/system/tray/tray_utils.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_SYSTEM_TRAY_TRAY_UTILS_H_
+#define ASH_SYSTEM_TRAY_TRAY_UTILS_H_
+
+#include "ash/shelf/shelf_types.h"
+
+namespace views {
+class Label;
+class View;
+}
+
+namespace ash {
+namespace internal {
+
+class TrayItemView;
+
+// Sets up a Label properly for the tray (sets color, font etc.).
+void SetupLabelForTray(views::Label* label);
+
+// TODO(jennyz): refactor these two functions to SystemTrayItem.
+// Sets the empty border of an image tray item for adjusting the space
+// around it.
+void SetTrayImageItemBorder(views::View* tray_view, ShelfAlignment alignment);
+// Sets the empty border around a label tray item for adjusting the space
+// around it.
+void SetTrayLabelItemBorder(TrayItemView* tray_view,
+                            ShelfAlignment alignment);
+
+}  // namespace internal
+}  // namespace ash
+
+#endif  // ASH_SYSTEM_TRAY_TRAY_UTILS_H_
diff --git a/ash/system/tray/tray_views.cc b/ash/system/tray/tray_views.cc
deleted file mode 100644
index c18ee82..0000000
--- a/ash/system/tray/tray_views.cc
+++ /dev/null
@@ -1,249 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/system/tray/tray_views.h"
-
-#include "ash/ash_constants.h"
-#include "ash/system/tray/fixed_sized_image_view.h"
-#include "ash/system/tray/tray_constants.h"
-#include "ash/system/tray/tray_item_view.h"
-#include "base/i18n/rtl.h"
-#include "grit/ash_resources.h"
-#include "grit/ash_strings.h"
-#include "grit/ui_resources.h"
-#include "ui/base/accessibility/accessible_view_state.h"
-#include "ui/base/events/event.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/gfx/canvas.h"
-#include "ui/gfx/image/image.h"
-#include "ui/gfx/image/image_skia.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/text_constants.h"
-#include "ui/gfx/vector2d.h"
-#include "ui/native_theme/native_theme.h"
-#include "ui/views/border.h"
-#include "ui/views/controls/button/image_button.h"
-#include "ui/views/controls/label.h"
-#include "ui/views/layout/box_layout.h"
-#include "ui/views/layout/fill_layout.h"
-#include "ui/views/layout/grid_layout.h"
-#include "ui/views/painter.h"
-
-namespace ash {
-namespace internal {
-
-namespace {
-const int kTrayPopupLabelButtonPaddingHorizontal = 16;
-const int kTrayPopupLabelButtonPaddingVertical = 8;
-
-const int kTrayPopupLabelButtonBorderImagesNormal[] = {
-    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_BORDER,
-    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND,
-    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND,
-    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_BORDER,
-    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND,
-    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND,
-    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_BORDER,
-    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND,
-    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND,
-};
-const int kTrayPopupLabelButtonBorderImagesHovered[] = {
-    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_BORDER,
-    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_BORDER,
-    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_BORDER,
-    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_BORDER,
-    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_HOVER_BACKGROUND,
-    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_BORDER,
-    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_BORDER,
-    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_BORDER,
-    IDR_AURA_TRAY_POPUP_LABEL_BUTTON_BORDER,
-};
-
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// TrayPopupLabelButtonBorder
-
-TrayPopupLabelButtonBorder::TrayPopupLabelButtonBorder()
-    : LabelButtonBorder(views::Button::STYLE_TEXTBUTTON) {
-  SetPainter(false, views::Button::STATE_NORMAL,
-             views::Painter::CreateImageGridPainter(
-                 kTrayPopupLabelButtonBorderImagesNormal));
-  SetPainter(false, views::Button::STATE_DISABLED,
-             views::Painter::CreateImageGridPainter(
-                 kTrayPopupLabelButtonBorderImagesNormal));
-  SetPainter(false, views::Button::STATE_HOVERED,
-             views::Painter::CreateImageGridPainter(
-                 kTrayPopupLabelButtonBorderImagesHovered));
-  SetPainter(false, views::Button::STATE_PRESSED,
-             views::Painter::CreateImageGridPainter(
-                 kTrayPopupLabelButtonBorderImagesHovered));
-}
-
-TrayPopupLabelButtonBorder::~TrayPopupLabelButtonBorder() {}
-
-void TrayPopupLabelButtonBorder::Paint(const views::View& view,
-                                       gfx::Canvas* canvas) {
-  const views::NativeThemeDelegate* native_theme_delegate =
-      static_cast<const views::LabelButton*>(&view);
-  ui::NativeTheme::ExtraParams extra;
-  const ui::NativeTheme::State state =
-      native_theme_delegate->GetThemeState(&extra);
-  if (state == ui::NativeTheme::kNormal ||
-      state == ui::NativeTheme::kDisabled) {
-    // In normal and disabled state, the border is a vertical bar separating the
-    // button from the preceding sibling. If this button is its parent's first
-    // visible child, the separator bar should be omitted.
-    const views::View* first_visible_child = NULL;
-    for (int i = 0; i < view.parent()->child_count(); ++i) {
-      const views::View* child = view.parent()->child_at(i);
-      if (child->visible()) {
-        first_visible_child = child;
-        break;
-      }
-    }
-    if (first_visible_child == &view)
-      return;
-  }
-  if (base::i18n::IsRTL()) {
-    canvas->Save();
-    canvas->Translate(gfx::Vector2d(view.width(), 0));
-    canvas->Scale(-1, 1);
-    LabelButtonBorder::Paint(view, canvas);
-    canvas->Restore();
-  } else {
-    LabelButtonBorder::Paint(view, canvas);
-  }
-}
-
-gfx::Insets TrayPopupLabelButtonBorder::GetInsets() const {
-  return gfx::Insets(kTrayPopupLabelButtonPaddingVertical,
-                     kTrayPopupLabelButtonPaddingHorizontal,
-                     kTrayPopupLabelButtonPaddingVertical,
-                     kTrayPopupLabelButtonPaddingHorizontal);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// TrayPopupLabelButton
-
-TrayPopupLabelButton::TrayPopupLabelButton(views::ButtonListener* listener,
-                                           const string16& text)
-    : views::LabelButton(listener, text) {
-  set_border(new TrayPopupLabelButtonBorder);
-  set_focusable(true);
-  set_request_focus_on_press(false);
-  set_animate_on_state_change(false);
-  SetHorizontalAlignment(gfx::ALIGN_CENTER);
-}
-
-TrayPopupLabelButton::~TrayPopupLabelButton() {}
-
-void TrayPopupLabelButton::OnPaintFocusBorder(gfx::Canvas* canvas) {
-  if (HasFocus() && (focusable() || IsAccessibilityFocusable())) {
-    canvas->DrawRect(gfx::Rect(1, 1, width() - 3, height() - 3),
-                     ash::kFocusBorderColor);
-  }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// TrayPopupHeaderButton
-
-TrayPopupHeaderButton::TrayPopupHeaderButton(views::ButtonListener* listener,
-                                             int enabled_resource_id,
-                                             int disabled_resource_id,
-                                             int enabled_resource_id_hover,
-                                             int disabled_resource_id_hover,
-                                             int accessible_name_id)
-    : views::ToggleImageButton(listener) {
-  ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
-  SetImage(views::Button::STATE_NORMAL,
-      bundle.GetImageNamed(enabled_resource_id).ToImageSkia());
-  SetToggledImage(views::Button::STATE_NORMAL,
-      bundle.GetImageNamed(disabled_resource_id).ToImageSkia());
-  SetImage(views::Button::STATE_HOVERED,
-      bundle.GetImageNamed(enabled_resource_id_hover).ToImageSkia());
-  SetToggledImage(views::Button::STATE_HOVERED,
-      bundle.GetImageNamed(disabled_resource_id_hover).ToImageSkia());
-  SetImageAlignment(views::ImageButton::ALIGN_CENTER,
-                    views::ImageButton::ALIGN_MIDDLE);
-  SetAccessibleName(bundle.GetLocalizedString(accessible_name_id));
-  set_focusable(true);
-  set_request_focus_on_press(false);
-}
-
-TrayPopupHeaderButton::~TrayPopupHeaderButton() {}
-
-gfx::Size TrayPopupHeaderButton::GetPreferredSize() {
-  return gfx::Size(ash::kTrayPopupItemHeight, ash::kTrayPopupItemHeight);
-}
-
-void TrayPopupHeaderButton::OnPaintBorder(gfx::Canvas* canvas) {
-  // Just the left border.
-  const int kBorderHeight = 25;
-  int padding = (height() - kBorderHeight) / 2;
-  canvas->FillRect(gfx::Rect(0, padding, 1, height() - padding * 2),
-      ash::kBorderDarkColor);
-}
-
-void TrayPopupHeaderButton::OnPaintFocusBorder(gfx::Canvas* canvas) {
-  if (HasFocus() && (focusable() || IsAccessibilityFocusable())) {
-    canvas->DrawRect(gfx::Rect(2, 1, width() - 4, height() - 3),
-                     kFocusBorderColor);
-  }
-}
-
-void TrayPopupHeaderButton::StateChanged() {
-  SchedulePaint();
-}
-
-void SetupLabelForTray(views::Label* label) {
-  // Making label_font static to avoid the time penalty of DeriveFont for
-  // all but the first call.
-  static const gfx::Font label_font(gfx::Font().DeriveFont(1, gfx::Font::BOLD));
-  label->SetFont(label_font);
-  label->SetAutoColorReadabilityEnabled(false);
-  label->SetEnabledColor(SK_ColorWHITE);
-  label->SetBackgroundColor(SkColorSetARGB(0, 255, 255, 255));
-  label->SetShadowColors(SkColorSetARGB(64, 0, 0, 0),
-                         SkColorSetARGB(64, 0, 0, 0));
-  label->SetShadowOffset(0, 1);
-}
-
-void SetTrayImageItemBorder(views::View* tray_view,
-                            ShelfAlignment alignment) {
-  if (alignment == SHELF_ALIGNMENT_BOTTOM ||
-      alignment == SHELF_ALIGNMENT_TOP) {
-    tray_view->set_border(views::Border::CreateEmptyBorder(
-        0, kTrayImageItemHorizontalPaddingBottomAlignment,
-        0, kTrayImageItemHorizontalPaddingBottomAlignment));
-  } else {
-    tray_view->set_border(views::Border::CreateEmptyBorder(
-        kTrayImageItemVerticalPaddingVerticalAlignment,
-        kTrayImageItemHorizontalPaddingVerticalAlignment,
-        kTrayImageItemVerticalPaddingVerticalAlignment,
-        kTrayImageItemHorizontalPaddingVerticalAlignment));
-  }
-}
-
-void SetTrayLabelItemBorder(TrayItemView* tray_view,
-                            ShelfAlignment alignment) {
-  if (alignment == SHELF_ALIGNMENT_BOTTOM ||
-      alignment == SHELF_ALIGNMENT_TOP) {
-    tray_view->set_border(views::Border::CreateEmptyBorder(
-        0, kTrayLabelItemHorizontalPaddingBottomAlignment,
-        0, kTrayLabelItemHorizontalPaddingBottomAlignment));
-  } else {
-    // Center the label for vertical launcher alignment.
-    int horizontal_padding = (tray_view->GetPreferredSize().width() -
-        tray_view->label()->GetPreferredSize().width()) / 2;
-    tray_view->set_border(views::Border::CreateEmptyBorder(
-        kTrayLabelItemVerticalPaddingVeriticalAlignment,
-        horizontal_padding,
-        kTrayLabelItemVerticalPaddingVeriticalAlignment,
-        horizontal_padding));
-  }
-}
-
-}  // namespace internal
-}  // namespace ash
diff --git a/ash/system/tray/tray_views.h b/ash/system/tray/tray_views.h
deleted file mode 100644
index e3e50bc..0000000
--- a/ash/system/tray/tray_views.h
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ASH_SYSTEM_TRAY_TRAY_VIEWS_H_
-#define ASH_SYSTEM_TRAY_TRAY_VIEWS_H_
-
-#include "ash/ash_export.h"
-#include "ash/shelf/shelf_types.h"
-#include "ui/gfx/font.h"
-#include "ui/gfx/size.h"
-#include "ui/views/controls/button/image_button.h"
-#include "ui/views/controls/button/label_button.h"
-#include "ui/views/controls/button/label_button_border.h"
-#include "ui/views/controls/image_view.h"
-#include "ui/views/controls/slider.h"
-#include "ui/views/view.h"
-
-typedef unsigned int SkColor;
-
-namespace gfx {
-class ImageSkia;
-}
-
-namespace views {
-class Label;
-}
-
-namespace ash {
-namespace internal {
-
-class TrayItemView;
-
-// A border for label buttons that paints a vertical separator in normal state
-// and a custom hover effect in hovered or pressed state.
-class TrayPopupLabelButtonBorder : public views::LabelButtonBorder {
- public:
-  TrayPopupLabelButtonBorder();
-  virtual ~TrayPopupLabelButtonBorder();
-
-  // Overridden from views::LabelButtonBorder.
-  virtual void Paint(const views::View& view, gfx::Canvas* canvas) OVERRIDE;
-  virtual gfx::Insets GetInsets() const OVERRIDE;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(TrayPopupLabelButtonBorder);
-};
-
-// A label button with custom alignment, border and focus border.
-class TrayPopupLabelButton : public views::LabelButton {
- public:
-  TrayPopupLabelButton(views::ButtonListener* listener, const string16& text);
-  virtual ~TrayPopupLabelButton();
-
- private:
-  // Overridden from views::LabelButton.
-  virtual void OnPaintFocusBorder(gfx::Canvas* canvas) OVERRIDE;
-
-  DISALLOW_COPY_AND_ASSIGN(TrayPopupLabelButton);
-};
-
-// A ToggleImageButton with fixed size, paddings and hover effects. These
-// buttons are used in the header.
-class TrayPopupHeaderButton : public views::ToggleImageButton {
- public:
-  TrayPopupHeaderButton(views::ButtonListener* listener,
-                        int enabled_resource_id,
-                        int disabled_resource_id,
-                        int enabled_resource_id_hover,
-                        int disabled_resource_id_hover,
-                        int accessible_name_id);
-  virtual ~TrayPopupHeaderButton();
-
- private:
-  // Overridden from views::View.
-  virtual gfx::Size GetPreferredSize() OVERRIDE;
-  virtual void OnPaintBorder(gfx::Canvas* canvas) OVERRIDE;
-  virtual void OnPaintFocusBorder(gfx::Canvas* canvas) OVERRIDE;
-
-  // Overridden from views::CustomButton.
-  virtual void StateChanged() OVERRIDE;
-
-  DISALLOW_COPY_AND_ASSIGN(TrayPopupHeaderButton);
-};
-
-// Sets up a Label properly for the tray (sets color, font etc.).
-void SetupLabelForTray(views::Label* label);
-
-// TODO(jennyz): refactor these two functions to SystemTrayItem.
-// Sets the empty border of an image tray item for adjusting the space
-// around it.
-void SetTrayImageItemBorder(views::View* tray_view, ShelfAlignment alignment);
-// Sets the empty border around a label tray item for adjusting the space
-// around it.
-void SetTrayLabelItemBorder(TrayItemView* tray_view,
-                            ShelfAlignment alignment);
-
-}  // namespace internal
-}  // namespace ash
-
-#endif  // ASH_SYSTEM_TRAY_TRAY_VIEWS_H_
diff --git a/ash/system/tray_accessibility.cc b/ash/system/tray_accessibility.cc
index 5b79eb9..44fdc8e 100644
--- a/ash/system/tray_accessibility.cc
+++ b/ash/system/tray_accessibility.cc
@@ -14,6 +14,7 @@
 #include "ash/system/tray/tray_details_view.h"
 #include "ash/system/tray/tray_item_more.h"
 #include "ash/system/tray/tray_notification_view.h"
+#include "ash/system/tray/tray_popup_label_button.h"
 #include "grit/ash_resources.h"
 #include "grit/ash_strings.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -64,7 +65,7 @@
     ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
     SetImage(bundle.GetImageNamed(IDR_AURA_UBER_TRAY_ACCESSIBILITY_DARK).
                     ToImageSkia());
-    string16 label = bundle.GetLocalizedString(
+    base::string16 label = bundle.GetLocalizedString(
         IDS_ASH_STATUS_TRAY_ACCESSIBILITY);
     SetLabel(label);
     SetAccessibleName(label);
@@ -178,7 +179,7 @@
 }
 
 HoverHighlightView* AccessibilityDetailedView::AddScrollListItem(
-    const string16& text,
+    const base::string16& text,
     gfx::Font::FontStyle style,
     bool checked) {
   HoverHighlightView* container = new HoverHighlightView(this);
diff --git a/ash/system/tray_accessibility.h b/ash/system/tray_accessibility.h
index 629cf51..cd2d729 100644
--- a/ash/system/tray_accessibility.h
+++ b/ash/system/tray_accessibility.h
@@ -61,7 +61,7 @@
   // Add help entries.
   void AppendHelpEntries();
 
-  HoverHighlightView* AddScrollListItem(const string16& text,
+  HoverHighlightView* AddScrollListItem(const base::string16& text,
                                         gfx::Font::FontStyle style,
                                         bool checked);
   // Overridden from ViewClickListener.
diff --git a/ash/system/tray_update.cc b/ash/system/tray_update.cc
index e56d8c1..902354d 100644
--- a/ash/system/tray_update.cc
+++ b/ash/system/tray_update.cc
@@ -14,7 +14,6 @@
 #include "ash/system/tray/system_tray_delegate.h"
 #include "ash/system/tray/system_tray_notifier.h"
 #include "ash/system/tray/tray_constants.h"
-#include "ash/system/tray/tray_views.h"
 #include "base/time.h"
 #include "base/timer.h"
 #include "grit/ash_resources.h"
@@ -181,7 +180,7 @@
 }
 
 void TrayUpdate::DestroyDetailedView() {
-  if (nagger_.get()) {
+  if (nagger_) {
     // The nagger was being displayed. Now that the detailed view is being
     // closed, that means either the user clicks on it to restart, or the user
     // didn't click on it to restart. In either case, start the timer to show
diff --git a/ash/system/user/login_status.cc b/ash/system/user/login_status.cc
index fc02e38..77fc04a 100644
--- a/ash/system/user/login_status.cc
+++ b/ash/system/user/login_status.cc
@@ -12,8 +12,8 @@
 namespace ash {
 namespace user {
 
-string16 GetLocalizedSignOutStringForStatus(LoginStatus status,
-                                            bool multiline) {
+base::string16 GetLocalizedSignOutStringForStatus(LoginStatus status,
+                                                  bool multiline) {
   int message_id;
   switch (status) {
     case LOGGED_IN_GUEST:
@@ -29,13 +29,13 @@
       message_id = IDS_ASH_STATUS_TRAY_SIGN_OUT;
       break;
   }
-  string16 message =
+  base::string16 message =
       ui::ResourceBundle::GetSharedInstance().GetLocalizedString(message_id);
   // Desirable line breaking points are marked using \n. As the resource
   // framework does not evaluate escape sequences, the \n need to be explicitly
   // handled. Depending on the value of |multiline|, actual line breaks or
   // spaces are substituted.
-  string16 newline = multiline ? ASCIIToUTF16("\n") : ASCIIToUTF16(" ");
+  base::string16 newline = multiline ? ASCIIToUTF16("\n") : ASCIIToUTF16(" ");
   ReplaceSubstringsAfterOffset(&message, 0, ASCIIToUTF16("\\n"), newline);
   return message;
 }
diff --git a/ash/system/user/login_status.h b/ash/system/user/login_status.h
index c1e54f8..c5be026 100644
--- a/ash/system/user/login_status.h
+++ b/ash/system/user/login_status.h
@@ -11,18 +11,19 @@
 namespace user {
 
 enum LoginStatus {
-  LOGGED_IN_LOCKED,           // A user has locked the screen.
-  LOGGED_IN_USER,             // A normal user is logged in.
-  LOGGED_IN_OWNER,            // The owner of the device is logged in.
+  LOGGED_IN_NONE,             // Not logged in
+  LOGGED_IN_LOCKED,           // A user has locked the screen
+  LOGGED_IN_USER,             // A regular user is logged in
+  LOGGED_IN_OWNER,            // The owner of the device is logged in
   LOGGED_IN_GUEST,            // A guest is logged in (i.e. incognito)
-  LOGGED_IN_RETAIL_MODE,      // Is in retail mode.
-  LOGGED_IN_PUBLIC,           // A public account is logged in.
-  LOGGED_IN_LOCALLY_MANAGED,  // A locally managed user is logged in.
-  LOGGED_IN_KIOSK_APP,        // Is in kiosk app mode.
-  LOGGED_IN_NONE,             // Not logged in.
+  LOGGED_IN_RETAIL_MODE,      // Is in retail mode
+  LOGGED_IN_PUBLIC,           // A public account is logged in
+  LOGGED_IN_LOCALLY_MANAGED,  // A locally managed user is logged in
+  LOGGED_IN_KIOSK_APP         // Is in kiosk app mode
 };
 
-string16 GetLocalizedSignOutStringForStatus(LoginStatus status, bool multiline);
+base::string16 GetLocalizedSignOutStringForStatus(LoginStatus status,
+                                                  bool multiline);
 
 }  // namespace user
 }  // namespace ash
diff --git a/ash/system/user/tray_user.cc b/ash/system/user/tray_user.cc
index 60b0063..fe54d9a 100644
--- a/ash/system/user/tray_user.cc
+++ b/ash/system/user/tray_user.cc
@@ -9,12 +9,15 @@
 #include <vector>
 
 #include "ash/shell.h"
+#include "ash/shell_delegate.h"
 #include "ash/system/tray/system_tray.h"
 #include "ash/system/tray/system_tray_delegate.h"
 #include "ash/system/tray/system_tray_notifier.h"
 #include "ash/system/tray/tray_constants.h"
 #include "ash/system/tray/tray_item_view.h"
-#include "ash/system/tray/tray_views.h"
+#include "ash/system/tray/tray_popup_label_button.h"
+#include "ash/system/tray/tray_popup_label_button_border.h"
+#include "ash/system/tray/tray_utils.h"
 #include "base/i18n/rtl.h"
 #include "base/logging.h"
 #include "base/memory/scoped_vector.h"
@@ -153,7 +156,7 @@
   // if possible.
   void CalculatePreferredSize(SystemTrayItem* owner, int used_width);
 
-  string16 text_;
+  base::string16 text_;
   views::Link* learn_more_;
   gfx::Size preferred_size_;
   ScopedVector<gfx::RenderText> lines_;
@@ -170,6 +173,7 @@
  private:
   // Overridden from views::View.
   virtual gfx::Size GetPreferredSize() OVERRIDE;
+  virtual int GetHeightForWidth(int width) OVERRIDE;
   virtual void Layout() OVERRIDE;
 
   // Overridden from views::ButtonListener.
@@ -251,11 +255,11 @@
   ash::SystemTrayDelegate* delegate =
       ash::Shell::GetInstance()->system_tray_delegate();
   // Retrieve the user's display name and wrap it with markers.
-  string16 display_name = delegate->GetUserDisplayName();
+  base::string16 display_name = delegate->GetUserDisplayName();
   RemoveChars(display_name, kDisplayNameMark, &display_name);
   display_name = kDisplayNameMark[0] + display_name + kDisplayNameMark[0];
   // Retrieve the domain managing the device and wrap it with markers.
-  string16 domain = UTF8ToUTF16(delegate->GetEnterpriseDomain());
+  base::string16 domain = UTF8ToUTF16(delegate->GetEnterpriseDomain());
   RemoveChars(domain, kDisplayNameMark, &domain);
   base::i18n::WrapStringWithLTRFormatting(&domain);
   // Retrieve the label text, inserting the display name and domain.
@@ -280,13 +284,13 @@
 
   // Word-wrap the label text.
   const gfx::Font font;
-  std::vector<string16> lines;
+  std::vector<base::string16> lines;
   ui::ElideRectangleText(text_, font, contents_area.width(),
                          contents_area.height(), ui::ELIDE_LONG_WORDS, &lines);
   // Loop through the lines, creating a renderer for each.
   gfx::Point position = contents_area.origin();
   ui::Range display_name(ui::Range::InvalidRange());
-  for (std::vector<string16>::const_iterator it = lines.begin();
+  for (std::vector<base::string16>::const_iterator it = lines.begin();
        it != lines.end(); ++it) {
     gfx::RenderText* line = gfx::RenderText::CreateInstance();
     line->SetDirectionalityMode(gfx::DIRECTIONALITY_FROM_UI);
@@ -375,7 +379,7 @@
   // width and the width of the link (as no wrapping is permitted inside the
   // link). The upper bound is the maximum of the largest allowed bubble width
   // and the sum of the label text and link widths when put on a single line.
-  std::vector<string16> lines;
+  std::vector<base::string16> lines;
   while (min_width < max_width) {
     lines.clear();
     const int width = (min_width + max_width) / 2;
@@ -441,6 +445,10 @@
   return size;
 }
 
+int UserView::GetHeightForWidth(int width) {
+  return GetPreferredSize().height();
+}
+
 void UserView::Layout() {
   gfx::Rect contents_area(GetContentsBounds());
   if (user_card_ && logout_button_) {
@@ -464,12 +472,16 @@
 }
 
 void UserView::ButtonPressed(views::Button* sender, const ui::Event& event) {
-  if (sender == logout_button_)
+  if (sender == logout_button_) {
     ash::Shell::GetInstance()->system_tray_delegate()->SignOut();
-  else if (sender == profile_picture_)
-    ash::Shell::GetInstance()->system_tray_delegate()->ChangeProfilePicture();
-  else
+  } else if (sender == profile_picture_) {
+    if (ash::Shell::GetInstance()->delegate()->IsMultiProfilesEnabled())
+      ash::Shell::GetInstance()->system_tray_delegate()->ShowUserLogin();
+    else
+      ash::Shell::GetInstance()->system_tray_delegate()->ChangeProfilePicture();
+  } else {
     NOTREACHED();
+  }
 }
 
 void UserView::AddLogoutButton(ash::user::LoginStatus login) {
@@ -478,8 +490,8 @@
   if (login == ash::user::LOGGED_IN_LOCKED)
     return;
 
-  const string16 title = ash::user::GetLocalizedSignOutStringForStatus(login,
-                                                                       true);
+  const base::string16 title = ash::user::GetLocalizedSignOutStringForStatus(
+      login, true);
   TrayPopupLabelButton* logout_button = new TrayPopupLabelButton(this, title);
   logout_button->SetAccessibleName(title);
   logout_button_ = logout_button;
@@ -542,12 +554,18 @@
   username->SetHorizontalAlignment(gfx::ALIGN_LEFT);
   details->AddChildView(username);
 
-  views::Label* email = new views::Label(UTF8ToUTF16(delegate->GetUserEmail()));
   ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
-  email->SetFont(bundle.GetFont(ui::ResourceBundle::SmallFont));
-  email->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-  email->SetEnabled(false);
-  details->AddChildView(email);
+
+  views::Label* additional = new views::Label();
+
+  additional->SetText(login == ash::user::LOGGED_IN_LOCALLY_MANAGED ?
+      bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_LOCALLY_MANAGED_LABEL) :
+      UTF8ToUTF16(delegate->GetUserEmail()));
+
+  additional->SetFont(bundle.GetFont(ui::ResourceBundle::SmallFont));
+  additional->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+  additional->SetEnabled(false);
+  details->AddChildView(additional);
   user_card_->AddChildView(details);
 }
 
diff --git a/ash/system/web_notification/web_notification_tray.cc b/ash/system/web_notification/web_notification_tray.cc
index 395d58c..2207ba9 100644
--- a/ash/system/web_notification/web_notification_tray.cc
+++ b/ash/system/web_notification/web_notification_tray.cc
@@ -9,10 +9,16 @@
 #include "ash/shell.h"
 #include "ash/shell_window_ids.h"
 #include "ash/system/status_area_widget.h"
+#include "ash/system/tray/system_tray.h"
 #include "ash/system/tray/tray_background_view.h"
 #include "ash/system/tray/tray_bubble_wrapper.h"
 #include "ash/system/tray/tray_constants.h"
+#include "ash/system/tray/tray_utils.h"
+#include "base/auto_reset.h"
+#include "base/i18n/number_formatting.h"
+#include "base/utf_string_conversions.h"
 #include "grit/ash_resources.h"
+#include "grit/ash_strings.h"
 #include "grit/ui_strings.h"
 #include "ui/aura/root_window.h"
 #include "ui/aura/window.h"
@@ -26,8 +32,9 @@
 #include "ui/message_center/views/message_popup_bubble.h"
 #include "ui/message_center/views/message_popup_collection.h"
 #include "ui/views/bubble/tray_bubble_view.h"
-#include "ui/views/controls/button/image_button.h"
-#include "ui/views/controls/menu/menu_model_adapter.h"
+#include "ui/views/controls/button/custom_button.h"
+#include "ui/views/controls/image_view.h"
+#include "ui/views/controls/label.h"
 #include "ui/views/controls/menu/menu_runner.h"
 
 #if defined(OS_CHROMEOS)
@@ -45,8 +52,12 @@
 #endif  // defined(OS_CHROMEOS)
 
 namespace ash {
-
 namespace internal {
+namespace {
+
+const int kWebNotificationIconSize = 31;
+
+}
 
 // Class to initialize and manage the WebNotificationBubble and
 // TrayBubbleWrapper instances for a bubble.
@@ -81,6 +92,79 @@
  private:
   scoped_ptr<message_center::MessageBubbleBase> bubble_;
   scoped_ptr<internal::TrayBubbleWrapper> bubble_wrapper_;
+
+  DISALLOW_COPY_AND_ASSIGN(WebNotificationBubbleWrapper);
+};
+
+class WebNotificationButton : public views::CustomButton {
+ public:
+  WebNotificationButton(views::ButtonListener* listener)
+      : views::CustomButton(listener),
+        is_bubble_visible_(false),
+        unread_count_(0) {
+    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+
+    icon_ = new views::ImageView();
+    icon_->SetImage(rb.GetImageSkiaNamed(
+        IDR_AURA_UBER_TRAY_NOTIFY_BUTTON_ICON));
+    AddChildView(icon_);
+
+    unread_label_ = new views::Label();
+    SetupLabelForTray(unread_label_);
+    AddChildView(unread_label_);
+    unread_label_->SetVisible(false);
+  }
+
+  void SetBubbleVisible(bool visible) {
+    if (visible == is_bubble_visible_)
+      return;
+
+    is_bubble_visible_ = visible;
+    UpdateIconVisibility();
+  }
+
+  void SetUnreadCount(int unread_count) {
+    // base::FormatNumber doesn't convert to arabic numeric characters.
+    // TODO(mukai): use ICU to support conversion for such locales.
+    unread_count_ = unread_count;
+    unread_label_->SetText((unread_count > 9) ?
+        l10n_util::GetStringUTF16(IDS_ASH_NOTIFICATION_UNREAD_COUNT_NINE_PLUS) :
+        base::FormatNumber(unread_count));
+    UpdateIconVisibility();
+  }
+
+ protected:
+  // Overridden from views::ImageButton:
+  virtual void Layout() OVERRIDE {
+    views::CustomButton::Layout();
+    icon_->SetBoundsRect(bounds());
+    unread_label_->SetBoundsRect(bounds());
+  }
+
+  virtual gfx::Size GetPreferredSize() OVERRIDE {
+    return gfx::Size(kWebNotificationIconSize, kWebNotificationIconSize);
+  }
+
+ private:
+  void UpdateIconVisibility() {
+    if (!is_bubble_visible_ && unread_count_ > 0) {
+      icon_->SetVisible(false);
+      unread_label_->SetVisible(true);
+    } else {
+      icon_->SetVisible(true);
+      unread_label_->SetVisible(false);
+    }
+    InvalidateLayout();
+    SchedulePaint();
+  }
+
+  bool is_bubble_visible_;
+  int unread_count_;
+
+  views::ImageView* icon_;
+  views::Label* unread_label_;
+
+  DISALLOW_COPY_AND_ASSIGN(WebNotificationButton);
 };
 
 }  // namespace internal
@@ -89,11 +173,15 @@
     internal::StatusAreaWidget* status_area_widget)
     : TrayBackgroundView(status_area_widget),
       button_(NULL),
-      show_message_center_on_unlock_(false) {
-  button_ = new views::ImageButton(this);
+      show_message_center_on_unlock_(false),
+      should_update_tray_content_(false),
+      should_block_shelf_auto_hide_(false) {
+  button_ = new internal::WebNotificationButton(this);
   button_->set_triggerable_event_flags(
       ui::EF_LEFT_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON);
   tray_container()->AddChildView(button_);
+  SetContentsBackground();
+  tray_container()->set_border(NULL);
   SetVisible(false);
   message_center_tray_.reset(new message_center::MessageCenterTray(
       this,
@@ -114,6 +202,7 @@
   if (!ShouldShowMessageCenter())
     return false;
 
+  should_block_shelf_auto_hide_ = true;
   message_center::MessageCenterBubble* message_center_bubble =
       new message_center::MessageCenterBubble(message_center());
 
@@ -147,24 +236,24 @@
   message_center_bubble->SetMaxHeight(max_height);
   message_center_bubble_.reset(
       new internal::WebNotificationBubbleWrapper(this, message_center_bubble));
+  SetBubbleVisible(true);
 
   status_area_widget()->SetHideSystemNotifications(true);
   GetShelfLayoutManager()->UpdateAutoHideState();
+  button_->SetBubbleVisible(true);
   return true;
 }
 
-void WebNotificationTray::UpdateMessageCenter() {
-  if (message_center_bubble())
-    message_center_bubble()->bubble()->ScheduleUpdate();
-}
-
 void WebNotificationTray::HideMessageCenter() {
   if (!message_center_bubble())
     return;
   message_center_bubble_.reset();
+  should_block_shelf_auto_hide_ = false;
+  SetBubbleVisible(false);
   show_message_center_on_unlock_ = false;
   status_area_widget()->SetHideSystemNotifications(false);
   GetShelfLayoutManager()->UpdateAutoHideState();
+  button_->SetBubbleVisible(false);
 }
 
 void WebNotificationTray::SetHidePopupBubble(bool hide) {
@@ -184,7 +273,10 @@
     // No bubble wrappers here, since |popup_collection_| is not a bubble but a
     // collection of widgets.
     popup_collection_.reset(new message_center::MessagePopupCollection(
-        GetWidget()->GetNativeView(), message_center()));
+        ash::Shell::GetContainer(
+            GetWidget()->GetNativeView()->GetRootWindow(),
+            internal::kShellWindowId_StatusContainer),
+        message_center()));
   } else {
     message_center::MessagePopupBubble* popup_bubble =
         new message_center::MessagePopupBubble(message_center());
@@ -197,8 +289,6 @@
 void WebNotificationTray::UpdatePopups() {
   if (popup_bubble())
     popup_bubble()->bubble()->ScheduleUpdate();
-  if (popup_collection_.get())
-    popup_collection_->UpdatePopups();
 };
 
 void WebNotificationTray::HidePopups() {
@@ -210,22 +300,25 @@
 
 bool WebNotificationTray::ShouldShowMessageCenter() {
   return status_area_widget()->login_status() != user::LOGGED_IN_LOCKED &&
-      status_area_widget()->ShouldShowWebNotifications();
+      !(status_area_widget()->system_tray() &&
+        status_area_widget()->system_tray()->HasNotificationBubble());
 }
 
 void WebNotificationTray::ShowQuietModeMenu() {
-  views::MenuModelAdapter menu_model_adapter(
+  base::AutoReset<bool> reset(&should_block_shelf_auto_hide_, true);
+  scoped_ptr<ui::MenuModel> menu_model(
       message_center_tray_->CreateQuietModeMenu());
-  quiet_mode_menu_runner_.reset(
-      new views::MenuRunner(menu_model_adapter.CreateMenu()));
+  quiet_mode_menu_runner_.reset(new views::MenuRunner(menu_model.get()));
   gfx::Point point;
   views::View::ConvertPointToScreen(this, &point);
-  ignore_result(quiet_mode_menu_runner_->RunMenuAt(
+  if (quiet_mode_menu_runner_->RunMenuAt(
       GetWidget(),
       NULL,
       gfx::Rect(point, bounds().size()),
       views::MenuItemView::BUBBLE_ABOVE,
-      views::MenuRunner::HAS_MNEMONICS));
+      views::MenuRunner::HAS_MNEMONICS) == views::MenuRunner::MENU_DELETED)
+    return;
+
   quiet_mode_menu_runner_.reset();
   GetShelfLayoutManager()->UpdateAutoHideState();
 }
@@ -243,14 +336,6 @@
 
 void WebNotificationTray::UpdateAfterLoginStatusChange(
     user::LoginStatus login_status) {
-  if (message_center::IsRichNotificationEnabled()) {
-    // The status icon should be always visible except for lock screen / login
-    // screen, to allow quiet mode and settings. This is valid only when rich
-    // notification is enabled, since old UI doesn't have settings.
-    SetVisible((login_status != user::LOGGED_IN_NONE) &&
-               (login_status != user::LOGGED_IN_LOCKED));
-  }
-
   if (login_status == user::LOGGED_IN_LOCKED) {
     show_message_center_on_unlock_ =
         message_center_tray_->HideMessageCenterBubble();
@@ -262,11 +347,11 @@
       message_center_tray_->ShowMessageCenterBubble();
     show_message_center_on_unlock_ = false;
   }
+  OnMessageCenterTrayChanged();
 }
 
 bool WebNotificationTray::ShouldBlockLauncherAutoHide() const {
-  return IsMessageCenterBubbleVisible() ||
-      (quiet_mode_menu_runner_.get() && quiet_mode_menu_runner_->IsRunning());
+  return should_block_shelf_auto_hide_;
 }
 
 bool WebNotificationTray::IsMessageCenterBubbleVisible() const {
@@ -290,6 +375,7 @@
   if (alignment == shelf_alignment())
     return;
   internal::TrayBackgroundView::SetShelfAlignment(alignment);
+  tray_container()->set_border(NULL);
   // Destroy any existing bubble so that it will be rebuilt correctly.
   message_center_tray_->HideMessageCenterBubble();
   message_center_tray_->HidePopupBubble();
@@ -302,15 +388,13 @@
     popup_bubble()->bubble_view()->GetWidget()->StackAtTop();
     UpdateBubbleViewArrow(popup_bubble()->bubble_view());
   }
-  if (popup_collection_.get())
-    popup_collection_->UpdatePopups();
   if (message_center_bubble()) {
     message_center_bubble()->bubble_view()->UpdateBubble();
     UpdateBubbleViewArrow(message_center_bubble()->bubble_view());
   }
 }
 
-string16 WebNotificationTray::GetAccessibleNameForTray() {
+base::string16 WebNotificationTray::GetAccessibleNameForTray() {
   return l10n_util::GetStringUTF16(
       IDS_MESSAGE_CENTER_ACCESSIBLE_NAME);
 }
@@ -356,7 +440,7 @@
     popup_bubble()->bubble()->OnMouseExitedView();
 }
 
-string16 WebNotificationTray::GetAccessibleNameForBubble() {
+base::string16 WebNotificationTray::GetAccessibleNameForBubble() {
   return GetAccessibleNameForTray();
 }
 
@@ -378,39 +462,30 @@
 }
 
 void WebNotificationTray::OnMessageCenterTrayChanged() {
-  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+  // Do not update the tray contents directly. Multiple change events can happen
+  // consecutively, and calling Update in the middle of those events will show
+  // intermediate unread counts for a moment.
+  should_update_tray_content_ = true;
+  MessageLoop::current()->PostTask(
+      FROM_HERE,
+      base::Bind(&WebNotificationTray::UpdateTrayContent, AsWeakPtr()));
+}
+
+void WebNotificationTray::UpdateTrayContent() {
+  if (!should_update_tray_content_)
+    return;
+  should_update_tray_content_ = false;
+
   message_center::MessageCenter* message_center =
       message_center_tray_->message_center();
-  if (message_center->UnreadNotificationCount() > 0) {
-    button_->SetImage(views::CustomButton::STATE_NORMAL, rb.GetImageSkiaNamed(
-        IDR_AURA_UBER_TRAY_NOTIFY_BUTTON_ACTIVE_NORMAL));
-    button_->SetImage(views::CustomButton::STATE_HOVERED, rb.GetImageSkiaNamed(
-        IDR_AURA_UBER_TRAY_NOTIFY_BUTTON_ACTIVE_HOVER));
-    button_->SetImage(views::CustomButton::STATE_PRESSED, rb.GetImageSkiaNamed(
-        IDR_AURA_UBER_TRAY_NOTIFY_BUTTON_ACTIVE_PRESSED));
-  } else {
-    button_->SetImage(views::CustomButton::STATE_NORMAL, rb.GetImageSkiaNamed(
-        IDR_AURA_UBER_TRAY_NOTIFY_BUTTON_INACTIVE_NORMAL));
-    button_->SetImage(views::CustomButton::STATE_HOVERED, rb.GetImageSkiaNamed(
-        IDR_AURA_UBER_TRAY_NOTIFY_BUTTON_INACTIVE_HOVER));
-    button_->SetImage(views::CustomButton::STATE_PRESSED, rb.GetImageSkiaNamed(
-        IDR_AURA_UBER_TRAY_NOTIFY_BUTTON_INACTIVE_PRESSED));
-  }
+  button_->SetUnreadCount(message_center->UnreadNotificationCount());
   if (IsMessageCenterBubbleVisible())
     button_->SetState(views::CustomButton::STATE_PRESSED);
   else
     button_->SetState(views::CustomButton::STATE_NORMAL);
-  // Change the visibility of the buttons here when rich notifications are not
-  // enabled. If rich notifications are enabled, the visibility is changed at
-  // UpdateAfterLoginStatusChange() since the visibility won't depend on the
-  // number of notifications.
-  if (!message_center::IsRichNotificationEnabled()) {
-    bool is_visible =
-        (status_area_widget()->login_status() != user::LOGGED_IN_NONE) &&
-        (status_area_widget()->login_status() != user::LOGGED_IN_LOCKED) &&
-        (message_center->NotificationCount() > 0);
-    SetVisible(is_visible);
-  }
+  SetVisible((status_area_widget()->login_status() != user::LOGGED_IN_NONE) &&
+             (status_area_widget()->login_status() != user::LOGGED_IN_LOCKED) &&
+             (message_center->NotificationCount() > 0));
   Layout();
   SchedulePaint();
 }
diff --git a/ash/system/web_notification/web_notification_tray.h b/ash/system/web_notification/web_notification_tray.h
index ed3e45d..8b3aff8 100644
--- a/ash/system/web_notification/web_notification_tray.h
+++ b/ash/system/web_notification/web_notification_tray.h
@@ -10,6 +10,7 @@
 #include "ash/system/user/login_status.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
 #include "ui/message_center/message_center_tray.h"
 #include "ui/message_center/message_center_tray_delegate.h"
 #include "ui/views/bubble/tray_bubble_view.h"
@@ -41,13 +42,15 @@
 namespace internal {
 class StatusAreaWidget;
 class WebNotificationBubbleWrapper;
+class WebNotificationButton;
 }
 
 class ASH_EXPORT WebNotificationTray
     : public internal::TrayBackgroundView,
       public views::TrayBubbleView::Delegate,
       public message_center::MessageCenterTrayDelegate,
-      public views::ButtonListener {
+      public views::ButtonListener,
+      public base::SupportsWeakPtr<WebNotificationTray> {
  public:
   explicit WebNotificationTray(
       internal::StatusAreaWidget* status_area_widget);
@@ -74,7 +77,7 @@
   // Overridden from TrayBackgroundView.
   virtual void SetShelfAlignment(ShelfAlignment alignment) OVERRIDE;
   virtual void AnchorUpdated() OVERRIDE;
-  virtual string16 GetAccessibleNameForTray() OVERRIDE;
+  virtual base::string16 GetAccessibleNameForTray() OVERRIDE;
   virtual void HideBubbleWithView(
       const views::TrayBubbleView* bubble_view) OVERRIDE;
   virtual bool ClickedOutsideBubble() OVERRIDE;
@@ -86,7 +89,7 @@
   virtual void BubbleViewDestroyed() OVERRIDE;
   virtual void OnMouseEnteredView() OVERRIDE;
   virtual void OnMouseExitedView() OVERRIDE;
-  virtual string16 GetAccessibleNameForBubble() OVERRIDE;
+  virtual base::string16 GetAccessibleNameForBubble() OVERRIDE;
   virtual gfx::Rect GetAnchorRect(views::Widget* anchor_widget,
                                   AnchorType anchor_type,
                                   AnchorAlignment anchor_alignment) OVERRIDE;
@@ -99,7 +102,6 @@
   // Overridden from MessageCenterTrayDelegate.
   virtual void OnMessageCenterTrayChanged() OVERRIDE;
   virtual bool ShowMessageCenter() OVERRIDE;
-  virtual void UpdateMessageCenter() OVERRIDE;
   virtual void HideMessageCenter() OVERRIDE;
   virtual bool ShowPopups() OVERRIDE;
   virtual void UpdatePopups() OVERRIDE;
@@ -114,6 +116,8 @@
                            ManyMessageCenterNotifications);
   FRIEND_TEST_ALL_PREFIXES(WebNotificationTrayTest, ManyPopupNotifications);
 
+  void UpdateTrayContent();
+
   // Queries login status and the status area widget to determine visibility of
   // the message center.
   bool ShouldShowMessageCenter();
@@ -142,10 +146,18 @@
   scoped_ptr<internal::WebNotificationBubbleWrapper> popup_bubble_;
   scoped_ptr<message_center::MessagePopupCollection> popup_collection_;
   scoped_ptr<views::MenuRunner> quiet_mode_menu_runner_;
-  views::ImageButton* button_;
+  internal::WebNotificationButton* button_;
 
   bool show_message_center_on_unlock_;
 
+  bool should_update_tray_content_;
+
+  // True when the shelf auto hide behavior has to be blocked. Previously
+  // this was done by checking |message_center_bubble_| but actually
+  // the check can be called when creating this object, so it would cause
+  // flickers of the shelf from hidden to shown. See: crbug.com/181213
+  bool should_block_shelf_auto_hide_;
+
   DISALLOW_COPY_AND_ASSIGN(WebNotificationTray);
 };
 
diff --git a/ash/system/web_notification/web_notification_tray_unittest.cc b/ash/system/web_notification/web_notification_tray_unittest.cc
index d5aba2d..509e057 100644
--- a/ash/system/web_notification/web_notification_tray_unittest.cc
+++ b/ash/system/web_notification/web_notification_tray_unittest.cc
@@ -8,11 +8,13 @@
 
 #include "ash/root_window_controller.h"
 #include "ash/shelf/shelf_widget.h"
+#include "ash/shell.h"
 #include "ash/system/status_area_widget.h"
 #include "ash/system/tray/system_tray_item.h"
 #include "ash/test/ash_test_base.h"
 #include "base/stringprintf.h"
 #include "base/utf_string_conversions.h"
+#include "ui/message_center/message_center_constants.h"
 #include "ui/message_center/message_center_tray.h"
 #include "ui/message_center/message_center_util.h"
 #include "ui/message_center/notification_list.h"
@@ -33,55 +35,28 @@
 
 namespace {
 
-WebNotificationTray* GetWebNotificationTray() {
+WebNotificationTray* GetTray() {
   return Shell::GetPrimaryRootWindowController()->shelf()->
       status_area_widget()->web_notification_tray();
 }
 
-message_center::MessageCenter* get_message_center() {
-  return GetWebNotificationTray()->message_center();
+message_center::MessageCenter* GetMessageCenter() {
+  return GetTray()->message_center();
 }
 
-class TestDelegate : public message_center::MessageCenter::Delegate {
+class WebNotificationTrayTest : public test::AshTestBase {
  public:
-  TestDelegate(message_center::MessageCenter* message_center)
-    : message_center_(message_center) {
-    message_center_->SetDelegate(this);
-  }
-  virtual ~TestDelegate() {
-    message_center_->SetDelegate(NULL);
-    message_center_->notification_list()->RemoveAllNotifications();
+  WebNotificationTrayTest() {}
+  virtual ~WebNotificationTrayTest() {}
+
+  virtual void TearDown() OVERRIDE {
+    GetMessageCenter()->RemoveAllNotifications(false);
+    test::AshTestBase::TearDown();
   }
 
-  // WebNotificationTray::Delegate overrides.
-  virtual void NotificationRemoved(const std::string& notifcation_id,
-                                   bool by_user) OVERRIDE {
-    notification_ids_.erase(notifcation_id);
-  }
-
-  virtual void DisableExtension(const std::string& notifcation_id) OVERRIDE {
-  }
-
-  virtual void DisableNotificationsFromSource(
-      const std::string& notifcation_id) OVERRIDE {
-  }
-
-  virtual void ShowSettings(const std::string& notifcation_id) OVERRIDE {
-  }
-
-  virtual void ShowSettingsDialog(gfx::NativeView context) OVERRIDE {
-  }
-
-  virtual void OnClicked(const std::string& notifcation_id) OVERRIDE {
-  }
-
-  virtual void OnButtonClicked(const std::string& id,
-                               int button_index) OVERRIDE {
-  }
-
-  void AddNotification(WebNotificationTray* tray, const std::string& id) {
-    notification_ids_.insert(id);
-    get_message_center()->AddNotification(
+ protected:
+  void AddNotification(const std::string& id) {
+    GetMessageCenter()->AddNotification(
         message_center::NOTIFICATION_TYPE_SIMPLE,
         id,
         ASCIIToUTF16("Test Web Notification"),
@@ -91,151 +66,127 @@
         NULL /* optional_fields */);
   }
 
-  void UpdateNotification(WebNotificationTray* tray,
-                          const std::string& old_id,
+  void UpdateNotification(const std::string& old_id,
                           const std::string& new_id) {
-    notification_ids_.erase(old_id);
-    notification_ids_.insert(new_id);
-    get_message_center()->UpdateNotification(
+    GetMessageCenter()->UpdateNotification(
         old_id, new_id,
         ASCIIToUTF16("Updated Web Notification"),
         ASCIIToUTF16("Updated message body."),
         NULL);
   }
 
-  void RemoveNotification(WebNotificationTray* tray, const std::string& id) {
-    get_message_center()->RemoveNotification(id);
-    notification_ids_.erase(id);
+  void RemoveNotification(const std::string& id) {
+    GetMessageCenter()->RemoveNotification(id, false);
   }
 
-  bool HasNotificationId(const std::string& id) {
-    return notification_ids_.find(id) != notification_ids_.end();
+  views::Widget* GetWidget() {
+    return GetTray()->GetWidget();
   }
 
  private:
-  std::set<std::string> notification_ids_;
-  message_center::MessageCenter* message_center_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestDelegate);
+  DISALLOW_COPY_AND_ASSIGN(WebNotificationTrayTest);
 };
 
 }  // namespace
 
-typedef test::AshTestBase WebNotificationTrayTest;
-
 TEST_F(WebNotificationTrayTest, WebNotifications) {
-  WebNotificationTray* tray = GetWebNotificationTray();
-  message_center::MessageCenter* message_center = tray->message_center();
-  scoped_ptr<TestDelegate> delegate(new TestDelegate(message_center));
-  ASSERT_TRUE(tray->GetWidget());
+  // TODO(mukai): move this test case to ui/message_center.
+  ASSERT_TRUE(GetWidget());
 
   // Add a notification.
-  delegate->AddNotification(tray, "test_id1");
-  EXPECT_EQ(1u, get_message_center()->NotificationCount());
-  EXPECT_TRUE(message_center->notification_list()->HasNotification("test_id1"));
-  delegate->AddNotification(tray, "test_id2");
-  delegate->AddNotification(tray, "test_id2");
-  EXPECT_EQ(2u, get_message_center()->NotificationCount());
-  EXPECT_TRUE(message_center->notification_list()->HasNotification("test_id2"));
+  AddNotification("test_id1");
+  EXPECT_EQ(1u, GetMessageCenter()->NotificationCount());
+  EXPECT_TRUE(GetMessageCenter()->HasNotification("test_id1"));
+  AddNotification("test_id2");
+  AddNotification("test_id2");
+  EXPECT_EQ(2u, GetMessageCenter()->NotificationCount());
+  EXPECT_TRUE(GetMessageCenter()->HasNotification("test_id2"));
 
   // Ensure that updating a notification does not affect the count.
-  delegate->UpdateNotification(tray, "test_id2", "test_id3");
-  delegate->UpdateNotification(tray, "test_id3", "test_id3");
-  EXPECT_EQ(2u, get_message_center()->NotificationCount());
-  EXPECT_FALSE(delegate->HasNotificationId("test_id2"));
-  EXPECT_FALSE(message_center->notification_list()->HasNotification(
-      "test_id2"));
-  EXPECT_TRUE(delegate->HasNotificationId("test_id3"));
+  UpdateNotification("test_id2", "test_id3");
+  UpdateNotification("test_id3", "test_id3");
+  EXPECT_EQ(2u, GetMessageCenter()->NotificationCount());
+  EXPECT_FALSE(GetMessageCenter()->HasNotification("test_id2"));
 
   // Ensure that Removing the first notification removes it from the tray.
-  delegate->RemoveNotification(tray, "test_id1");
-  EXPECT_FALSE(delegate->HasNotificationId("test_id1"));
-  EXPECT_FALSE(message_center->notification_list()->HasNotification(
-      "test_id1"));
-  EXPECT_EQ(1u, get_message_center()->NotificationCount());
+  RemoveNotification("test_id1");
+  EXPECT_FALSE(GetMessageCenter()->HasNotification("test_id1"));
+  EXPECT_EQ(1u, GetMessageCenter()->NotificationCount());
 
   // Remove the remianing notification.
-  delegate->RemoveNotification(tray, "test_id3");
-  EXPECT_EQ(0u, get_message_center()->NotificationCount());
-  EXPECT_FALSE(message_center->notification_list()->HasNotification(
-      "test_id3"));
+  RemoveNotification("test_id3");
+  EXPECT_EQ(0u, GetMessageCenter()->NotificationCount());
+  EXPECT_FALSE(GetMessageCenter()->HasNotification("test_id3"));
 }
 
 TEST_F(WebNotificationTrayTest, WebNotificationPopupBubble) {
-  WebNotificationTray* tray = GetWebNotificationTray();
-  scoped_ptr<TestDelegate> delegate(new TestDelegate(get_message_center()));
-
-  ASSERT_TRUE(tray->GetWidget());
+  // TODO(mukai): move this test case to ui/message_center.
+  ASSERT_TRUE(GetWidget());
 
   // Adding a notification should show the popup bubble.
-  delegate->AddNotification(tray, "test_id1");
-  EXPECT_TRUE(tray->IsPopupVisible());
+  AddNotification("test_id1");
+  EXPECT_TRUE(GetTray()->IsPopupVisible());
 
   // Updating a notification should not hide the popup bubble.
-  delegate->AddNotification(tray, "test_id2");
-  delegate->UpdateNotification(tray, "test_id2", "test_id3");
-  EXPECT_TRUE(tray->IsPopupVisible());
+  AddNotification("test_id2");
+  UpdateNotification("test_id2", "test_id3");
+  EXPECT_TRUE(GetTray()->IsPopupVisible());
 
   // Removing the first notification should not hide the popup bubble.
-  delegate->RemoveNotification(tray, "test_id1");
-  EXPECT_TRUE(tray->IsPopupVisible());
+  RemoveNotification("test_id1");
+  EXPECT_TRUE(GetTray()->IsPopupVisible());
 
   // Removing the visible notification should hide the popup bubble.
-  delegate->RemoveNotification(tray, "test_id3");
-  EXPECT_FALSE(tray->IsPopupVisible());
+  RemoveNotification("test_id3");
+  EXPECT_FALSE(GetTray()->IsPopupVisible());
 }
 
 using message_center::NotificationList;
 
 
-TEST_F(WebNotificationTrayTest, ManyMessageCenterNotifications) {
-  WebNotificationTray* tray = GetWebNotificationTray();
-  scoped_ptr<TestDelegate> delegate(new TestDelegate(get_message_center()));
-
+// Flakily fails. http://crbug.com/229791
+TEST_F(WebNotificationTrayTest, DISABLED_ManyMessageCenterNotifications) {
   // Add the max visible notifications +1, ensure the correct visible number.
   size_t notifications_to_add =
-      NotificationList::kMaxVisibleMessageCenterNotifications + 1;
+      message_center::kMaxVisibleMessageCenterNotifications + 1;
   for (size_t i = 0; i < notifications_to_add; ++i) {
     std::string id = base::StringPrintf("test_id%d", static_cast<int>(i));
-    delegate->AddNotification(tray, id);
+    AddNotification(id);
   }
-  bool shown = tray->message_center_tray_->ShowMessageCenterBubble();
+  bool shown = GetTray()->message_center_tray_->ShowMessageCenterBubble();
   EXPECT_TRUE(shown);
   RunAllPendingInMessageLoop();
-  EXPECT_TRUE(tray->message_center_bubble() != NULL);
+  EXPECT_TRUE(GetTray()->message_center_bubble() != NULL);
   EXPECT_EQ(notifications_to_add,
-            get_message_center()->NotificationCount());
-  EXPECT_EQ(NotificationList::kMaxVisibleMessageCenterNotifications,
-            tray->GetMessageCenterBubbleForTest()->NumMessageViewsForTest());
+            GetMessageCenter()->NotificationCount());
+  EXPECT_EQ(message_center::kMaxVisibleMessageCenterNotifications,
+            GetTray()->GetMessageCenterBubbleForTest()->
+                NumMessageViewsForTest());
 }
 
-TEST_F(WebNotificationTrayTest, ManyPopupNotifications) {
-  WebNotificationTray* tray = GetWebNotificationTray();
-  scoped_ptr<TestDelegate> delegate(new TestDelegate(get_message_center()));
-
+// Flakily times out. http://crbug.com/229792
+TEST_F(WebNotificationTrayTest, DISABLED_ManyPopupNotifications) {
   // Add the max visible popup notifications +1, ensure the correct num visible.
   size_t notifications_to_add =
-      NotificationList::kMaxVisiblePopupNotifications + 1;
+      message_center::kMaxVisiblePopupNotifications + 1;
   for (size_t i = 0; i < notifications_to_add; ++i) {
     std::string id = base::StringPrintf("test_id%d", static_cast<int>(i));
-    delegate->AddNotification(tray, id);
+    AddNotification(id);
   }
   // Hide and reshow the bubble so that it is updated immediately, not delayed.
-  tray->SetHidePopupBubble(true);
-  tray->SetHidePopupBubble(false);
-  EXPECT_TRUE(tray->IsPopupVisible());
+  GetTray()->SetHidePopupBubble(true);
+  GetTray()->SetHidePopupBubble(false);
+  EXPECT_TRUE(GetTray()->IsPopupVisible());
   EXPECT_EQ(notifications_to_add,
-            get_message_center()->NotificationCount());
+            GetMessageCenter()->NotificationCount());
   if (message_center::IsRichNotificationEnabled()) {
     NotificationList::PopupNotifications popups =
-        get_message_center()->notification_list()->GetPopupNotifications();
-    EXPECT_EQ(NotificationList::kMaxVisiblePopupNotifications, popups.size());
+        GetMessageCenter()->GetPopupNotifications();
+    EXPECT_EQ(message_center::kMaxVisiblePopupNotifications, popups.size());
   } else {
-    EXPECT_EQ(NotificationList::kMaxVisiblePopupNotifications,
-              tray->GetPopupBubbleForTest()->NumMessageViewsForTest());
+    EXPECT_EQ(message_center::kMaxVisiblePopupNotifications,
+              GetTray()->GetPopupBubbleForTest()->NumMessageViewsForTest());
   }
-  get_message_center()->SetDelegate(NULL);
-  get_message_center()->notification_list()->RemoveAllNotifications();
 }
 
 }  // namespace ash
diff --git a/ash/test/ash_test_base.cc b/ash/test/ash_test_base.cc
index 942f549..99105e1 100644
--- a/ash/test/ash_test_base.cc
+++ b/ash/test/ash_test_base.cc
@@ -10,38 +10,33 @@
 #include "ash/ash_switches.h"
 #include "ash/display/display_controller.h"
 #include "ash/display/display_manager.h"
-#include "ash/screen_ash.h"
 #include "ash/shell.h"
+#include "ash/test/ash_test_helper.h"
 #include "ash/test/display_manager_test_api.h"
-#include "ash/test/shell_test_api.h"
+#include "ash/test/test_session_state_delegate.h"
 #include "ash/test/test_shell_delegate.h"
 #include "ash/wm/coordinate_conversion.h"
 #include "base/command_line.h"
-#include "base/run_loop.h"
 #include "content/public/test/web_contents_tester.h"
 #include "ui/aura/client/aura_constants.h"
 #include "ui/aura/client/screen_position_client.h"
-#include "ui/aura/env.h"
 #include "ui/aura/root_window.h"
 #include "ui/aura/test/event_generator.h"
 #include "ui/aura/test/test_window_delegate.h"
+#include "ui/aura/window.h"
 #include "ui/aura/window_delegate.h"
-#include "ui/base/ime/text_input_test_support.h"
-#include "ui/compositor/layer_animator.h"
-#include "ui/compositor/scoped_animation_duration_scale_mode.h"
 #include "ui/gfx/display.h"
+#include "ui/gfx/point.h"
 #include "ui/gfx/screen.h"
 
-#if defined(ENABLE_MESSAGE_CENTER)
-#include "ui/message_center/message_center.h"
-#endif
-
 #if defined(OS_WIN)
 #include "ash/test/test_metro_viewer_process_host.h"
 #include "base/test/test_process_killer_win.h"
+#include "base/win/metro.h"
 #include "base/win/windows_version.h"
 #include "ui/aura/remote_root_window_host_win.h"
 #include "ui/aura/root_window_host_win.h"
+#include "ui/base/ime/win/tsf_bridge.h"
 #include "win8/test/test_registrar_constants.h"
 #endif
 
@@ -81,63 +76,61 @@
                                                            site_instance);
 }
 
+/////////////////////////////////////////////////////////////////////////////
+
 AshTestBase::AshTestBase()
-    : test_shell_delegate_(NULL) {
+    : setup_called_(false),
+      teardown_called_(false) {
+  // Must initialize |ash_test_helper_| here because some tests rely on
+  // AshTestBase methods before they call AshTestBase::SetUp().
+  ash_test_helper_.reset(new AshTestHelper(&message_loop_));
 }
 
 AshTestBase::~AshTestBase() {
+  CHECK(setup_called_)
+      << "You have overridden SetUp but never called AshTestBase::SetUp";
+  CHECK(teardown_called_)
+      << "You have overridden TearDown but never called AshTestBase::TearDown";
 }
 
 void AshTestBase::SetUp() {
+  setup_called_ = true;
+  // TODO(jamescook): Can we do this without changing command line?
   // Use the origin (1,1) so that it doesn't over
   // lap with the native mouse cursor.
   CommandLine::ForCurrentProcess()->AppendSwitchASCII(
       switches::kAshHostWindowBounds, "1+1-800x600");
 #if defined(OS_WIN)
   aura::test::SetUsePopupAsRootWindowForTest(true);
+  if (base::win::IsTSFAwareRequired())
+    ui::TSFBridge::Initialize();
 #endif
-  // Disable animations during tests.
-  zero_duration_mode_.reset(new ui::ScopedAnimationDurationScaleMode(
-      ui::ScopedAnimationDurationScaleMode::ZERO_DURATION));
-  ui::TextInputTestSupport::Initialize();
 
-  // Creates Shell and hook with Desktop.
-  test_shell_delegate_ = new TestShellDelegate;
-
-#if defined(ENABLE_MESSAGE_CENTER)
-  // Creates MessageCenter since g_browser_process is not created in AshTestBase
-  // tests.
-  message_center::MessageCenter::Initialize();
-#endif
-  ash::Shell::CreateInstance(test_shell_delegate_);
-  Shell* shell = Shell::GetInstance();
-  test::DisplayManagerTestApi(shell->display_manager()).
-      DisableChangeDisplayUponHostResize();
+  ash_test_helper_->SetUp();
 
   Shell::GetPrimaryRootWindow()->Show();
   Shell::GetPrimaryRootWindow()->ShowRootWindow();
   // Move the mouse cursor to far away so that native events doesn't
   // interfere test expectations.
   Shell::GetPrimaryRootWindow()->MoveCursorTo(gfx::Point(-1000, -1000));
-  shell->cursor_manager()->EnableMouseEvents();
-  ShellTestApi(shell).DisableOutputConfiguratorAnimation();
+  ash::Shell::GetInstance()->cursor_manager()->EnableMouseEvents();
 
 #if defined(OS_WIN)
   if (base::win::GetVersion() >= base::win::VERSION_WIN8 &&
       !CommandLine::ForCurrentProcess()->HasSwitch(
           ash::switches::kForceAshToDesktop)) {
     metro_viewer_host_.reset(new TestMetroViewerProcessHost("viewer"));
-    ASSERT_TRUE(
-        metro_viewer_host_->LaunchViewerAndWaitForConnection(
-            win8::test::kDefaultTestAppUserModelId));
+    CHECK(metro_viewer_host_->LaunchViewerAndWaitForConnection(
+        win8::test::kDefaultTestAppUserModelId));
     aura::RemoteRootWindowHostWin* root_window_host =
         aura::RemoteRootWindowHostWin::Instance();
-    ASSERT_TRUE(root_window_host != NULL);
+    CHECK(root_window_host != NULL);
   }
 #endif
 }
 
 void AshTestBase::TearDown() {
+  teardown_called_ = true;
   // Flush the message loop to finish pending release tasks.
   RunAllPendingInMessageLoop();
 
@@ -146,20 +139,11 @@
       !CommandLine::ForCurrentProcess()->HasSwitch(
           ash::switches::kForceAshToDesktop)) {
     // Check that our viewer connection is still established.
-    ASSERT_FALSE(metro_viewer_host_->closed_unexpectedly());
+    CHECK(!metro_viewer_host_->closed_unexpectedly());
   }
 #endif
 
-  // Tear down the shell.
-  Shell::DeleteInstance();
-
-#if defined(ENABLE_MESSAGE_CENTER)
-  // Remove global message center state.
-  message_center::MessageCenter::Shutdown();
-#endif
-
-  aura::Env::DeleteInstance();
-  ui::TextInputTestSupport::Shutdown();
+  ash_test_helper_->TearDown();
 
 #if defined(OS_WIN)
   aura::test::SetUsePopupAsRootWindowForTest(false);
@@ -182,7 +166,7 @@
 }
 
 aura::test::EventGenerator& AshTestBase::GetEventGenerator() {
-  if (!event_generator_.get()) {
+  if (!event_generator_) {
     event_generator_.reset(
         new aura::test::EventGenerator(new AshEventGeneratorDelegate()));
   }
@@ -196,11 +180,7 @@
 }
 
 aura::RootWindow* AshTestBase::CurrentContext() {
-  aura::RootWindow* root_window = Shell::GetActiveRootWindow();
-  if (!root_window)
-    root_window = Shell::GetPrimaryRootWindow();
-  DCHECK(root_window);
-  return root_window;
+  return ash_test_helper_->CurrentContext();
 }
 
 aura::Window* AshTestBase::CreateTestWindowInShellWithId(int id) {
@@ -263,23 +243,22 @@
 }
 
 void AshTestBase::RunAllPendingInMessageLoop() {
-#if !defined(OS_MACOSX)
-  DCHECK(MessageLoopForUI::current() == &message_loop_);
-  base::RunLoop run_loop(aura::Env::GetInstance()->GetDispatcher());
-  run_loop.RunUntilIdle();
-#endif
+  ash_test_helper_->RunAllPendingInMessageLoop();
 }
 
 void AshTestBase::SetSessionStarted(bool session_started) {
-  test_shell_delegate_->SetSessionStarted(session_started);
+  ash_test_helper_->test_shell_delegate()->test_session_state_delegate()->
+      SetActiveUserSessionStarted(session_started);
 }
 
 void AshTestBase::SetUserLoggedIn(bool user_logged_in) {
-  test_shell_delegate_->SetUserLoggedIn(user_logged_in);
+  ash_test_helper_->test_shell_delegate()->test_session_state_delegate()->
+      SetHasActiveUser(user_logged_in);
 }
 
 void AshTestBase::SetCanLockScreen(bool can_lock_screen) {
-  test_shell_delegate_->SetCanLockScreen(can_lock_screen);
+  ash_test_helper_->test_shell_delegate()->test_session_state_delegate()->
+      SetCanLockScreen(can_lock_screen);
 }
 
 }  // namespace test
diff --git a/ash/test/ash_test_base.h b/ash/test/ash_test_base.h
index 5b0438c..dd65bf4 100644
--- a/ash/test/ash_test_base.h
+++ b/ash/test/ash_test_base.h
@@ -7,7 +7,6 @@
 
 #include <string>
 
-#include "ash/shell.h"
 #include "base/compiler_specific.h"
 #include "base/message_loop.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -16,10 +15,11 @@
 #include "ui/views/test/test_views_delegate.h"
 
 #if defined(OS_WIN)
-#include "base/memory/scoped_ptr.h"
+#include "ui/base/win/scoped_ole_initializer.h"
 #endif
 
 namespace aura {
+class RootWindow;
 class Window;
 class WindowDelegate;
 
@@ -28,10 +28,6 @@
 }  // namespace test
 }  // namespace aura
 
-namespace ui {
-class ScopedAnimationDurationScaleMode;
-}  // namespace ui
-
 namespace ash {
 namespace internal {
 class DisplayManager;
@@ -39,8 +35,10 @@
 
 namespace test {
 
+class AshTestHelper;
+#if defined(OS_WIN)
 class TestMetroViewerProcessHost;
-class TestShellDelegate;
+#endif
 
 class AshTestViewsDelegate : public views::TestViewsDelegate {
  public:
@@ -55,7 +53,7 @@
   AshTestBase();
   virtual ~AshTestBase();
 
-  MessageLoopForUI* message_loop() { return &message_loop_; }
+  base::MessageLoopForUI* message_loop() { return &message_loop_; }
 
   // testing::Test:
   virtual void SetUp() OVERRIDE;
@@ -105,17 +103,16 @@
   void SetCanLockScreen(bool can_lock_screen);
 
  private:
-  MessageLoopForUI message_loop_;
-
-  TestShellDelegate* test_shell_delegate_;
-
+  bool setup_called_;
+  bool teardown_called_;
+  base::MessageLoopForUI message_loop_;
+  scoped_ptr<AshTestHelper> ash_test_helper_;
   scoped_ptr<aura::test::EventGenerator> event_generator_;
 #if defined(OS_WIN)
   scoped_ptr<TestMetroViewerProcessHost> metro_viewer_host_;
+  ui::ScopedOleInitializer ole_initializer_;
 #endif
 
-  scoped_ptr<ui::ScopedAnimationDurationScaleMode> zero_duration_mode_;
-
   DISALLOW_COPY_AND_ASSIGN(AshTestBase);
 };
 
diff --git a/ash/test/ash_test_helper.cc b/ash/test/ash_test_helper.cc
new file mode 100644
index 0000000..c95fe28
--- /dev/null
+++ b/ash/test/ash_test_helper.cc
@@ -0,0 +1,93 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/test/ash_test_helper.h"
+
+#include "ash/ash_switches.h"
+#include "ash/shell.h"
+#include "ash/test/display_manager_test_api.h"
+#include "ash/test/shell_test_api.h"
+#include "ash/test/test_shell_delegate.h"
+#include "base/command_line.h"
+#include "base/run_loop.h"
+#include "ui/aura/env.h"
+#include "ui/base/ime/text_input_test_support.h"
+#include "ui/compositor/scoped_animation_duration_scale_mode.h"
+
+
+#if defined(ENABLE_MESSAGE_CENTER)
+#include "ui/message_center/message_center.h"
+#endif
+
+namespace ash {
+namespace test {
+
+AshTestHelper::AshTestHelper(base::MessageLoopForUI* message_loop)
+    : message_loop_(message_loop),
+      test_shell_delegate_(NULL) {
+  CHECK(message_loop_);
+}
+
+AshTestHelper::~AshTestHelper() {
+}
+
+void AshTestHelper::SetUp() {
+  // TODO(jennyz): Create mock or test AudioHandler so we can instantiate
+  // an ash::Shell with the new CrasAudioHandler. crbug.com/233266
+  CommandLine::ForCurrentProcess()->AppendSwitch(
+      ash::switches::kAshDisableNewAudioHandler);
+  // Disable animations during tests.
+  zero_duration_mode_.reset(new ui::ScopedAnimationDurationScaleMode(
+      ui::ScopedAnimationDurationScaleMode::ZERO_DURATION));
+  ui::TextInputTestSupport::Initialize();
+
+  // Creates Shell and hook with Desktop.
+  test_shell_delegate_ = new TestShellDelegate;
+
+#if defined(ENABLE_MESSAGE_CENTER)
+  // Creates MessageCenter since g_browser_process is not created in AshTestBase
+  // tests.
+  message_center::MessageCenter::Initialize();
+#endif
+  ash::Shell::CreateInstance(test_shell_delegate_);
+  Shell* shell = Shell::GetInstance();
+  test::DisplayManagerTestApi(shell->display_manager()).
+      DisableChangeDisplayUponHostResize();
+  ShellTestApi(shell).DisableOutputConfiguratorAnimation();
+
+}
+
+void AshTestHelper::TearDown() {
+  // Tear down the shell.
+  Shell::DeleteInstance();
+
+#if defined(ENABLE_MESSAGE_CENTER)
+  // Remove global message center state.
+  message_center::MessageCenter::Shutdown();
+#endif
+
+  aura::Env::DeleteInstance();
+  ui::TextInputTestSupport::Shutdown();
+
+  zero_duration_mode_.reset();
+}
+
+void AshTestHelper::RunAllPendingInMessageLoop() {
+#if !defined(OS_MACOSX)
+  DCHECK(MessageLoopForUI::current() == message_loop_);
+  base::RunLoop run_loop(aura::Env::GetInstance()->GetDispatcher());
+  run_loop.RunUntilIdle();
+#endif
+}
+
+aura::RootWindow* AshTestHelper::CurrentContext() {
+  aura::RootWindow* root_window = Shell::GetActiveRootWindow();
+  if (!root_window)
+    root_window = Shell::GetPrimaryRootWindow();
+  DCHECK(root_window);
+  return root_window;
+}
+
+}  // namespace test
+}  // namespace ash
diff --git a/ash/test/ash_test_helper.h b/ash/test/ash_test_helper.h
new file mode 100644
index 0000000..669ec29
--- /dev/null
+++ b/ash/test/ash_test_helper.h
@@ -0,0 +1,62 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_TEST_ASH_TEST_HELPER_H_
+#define ASH_TEST_ASH_TEST_HELPER_H_
+
+#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+
+namespace aura {
+class RootWindow;
+}  // namespace aura
+
+namespace base {
+class MessageLoopForUI;
+}  // namespace base
+
+namespace ui {
+class ScopedAnimationDurationScaleMode;
+}  // namespace ui
+
+namespace ash {
+namespace test {
+
+class TestShellDelegate;
+
+// A helper class that does common initialization required for Ash. Creates a
+// root window and an ash::Shell instance with a test delegate.
+class AshTestHelper {
+ public:
+  explicit AshTestHelper(base::MessageLoopForUI* message_loop);
+  ~AshTestHelper();
+
+  // Creates the ash::Shell and performs associated initialization.
+  void SetUp();
+
+  // Destroys the ash::Shell and performs associated cleanup.
+  void TearDown();
+
+  // Returns a RootWindow. Usually this is the active RootWindow, but that
+  // method can return NULL sometimes, and in those cases, we fall back on the
+  // primary RootWindow.
+  aura::RootWindow* CurrentContext();
+
+  void RunAllPendingInMessageLoop();
+
+  base::MessageLoopForUI* message_loop() { return message_loop_; }
+  TestShellDelegate* test_shell_delegate() { return test_shell_delegate_; }
+
+ private:
+  base::MessageLoopForUI* message_loop_;  // Not owned.
+  TestShellDelegate* test_shell_delegate_;  // Owned by ash::Shell.
+  scoped_ptr<ui::ScopedAnimationDurationScaleMode> zero_duration_mode_;
+
+  DISALLOW_COPY_AND_ASSIGN(AshTestHelper);
+};
+
+}  // namespace test
+}  // namespace ash
+
+#endif  // ASH_TEST_ASH_TEST_HELPER_H_
diff --git a/ash/test/ash_test_helper_unittest.cc b/ash/test/ash_test_helper_unittest.cc
new file mode 100644
index 0000000..fdb27f9
--- /dev/null
+++ b/ash/test/ash_test_helper_unittest.cc
@@ -0,0 +1,57 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/test/ash_test_helper.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/aura/root_window.h"
+#include "ui/views/widget/widget.h"
+
+// Tests for AshTestHelper. Who will watch the watchers? And who will test
+// the tests?
+class AshTestHelperTest : public testing::Test {
+ public:
+  AshTestHelperTest() {}
+  virtual ~AshTestHelperTest() {}
+
+  virtual void SetUp() OVERRIDE {
+    testing::Test::SetUp();
+    ash_test_helper_.reset(new ash::test::AshTestHelper(&message_loop_));
+    ash_test_helper_->SetUp();
+  }
+
+  virtual void TearDown() OVERRIDE {
+    ash_test_helper_->TearDown();
+    testing::Test::TearDown();
+  }
+
+  ash::test::AshTestHelper* ash_test_helper() {
+    return ash_test_helper_.get();
+  }
+
+ private:
+  base::MessageLoopForUI message_loop_;
+  scoped_ptr<ash::test::AshTestHelper> ash_test_helper_;
+
+  DISALLOW_COPY_AND_ASSIGN(AshTestHelperTest);
+};
+
+// Ensure that we have initialized enough of Ash to create and show a window.
+TEST_F(AshTestHelperTest, AshTestHelper) {
+  // Check initial state.
+  EXPECT_TRUE(ash_test_helper()->message_loop());
+  EXPECT_TRUE(ash_test_helper()->test_shell_delegate());
+  EXPECT_TRUE(ash_test_helper()->CurrentContext());
+
+  // Enough state is initialized to create a window.
+  using views::Widget;
+  scoped_ptr<Widget> w1(new Widget);
+  Widget::InitParams params;
+  params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+  params.context = ash_test_helper()->CurrentContext();
+  w1->Init(params);
+  w1->Show();
+  EXPECT_TRUE(w1->IsActive());
+  EXPECT_TRUE(w1->IsVisible());
+}
diff --git a/ash/test/display_manager_test_api.cc b/ash/test/display_manager_test_api.cc
index f057765..2b0957a 100644
--- a/ash/test/display_manager_test_api.cc
+++ b/ash/test/display_manager_test_api.cc
@@ -84,8 +84,6 @@
 int64 DisplayManagerTestApi::SetFirstDisplayAsInternalDisplay() {
   const gfx::Display& internal = display_manager_->displays_[0];
   gfx::Display::SetInternalDisplayId(internal.id());
-  display_manager_->internal_display_info_.reset(new DisplayInfo(
-      display_manager_->GetDisplayInfo(internal.id())));
   return gfx::Display::InternalDisplayId();
 }
 
diff --git a/ash/test/launcher_view_test_api.cc b/ash/test/launcher_view_test_api.cc
index 1e1da4a..094ef89 100644
--- a/ash/test/launcher_view_test_api.cc
+++ b/ash/test/launcher_view_test_api.cc
@@ -24,7 +24,7 @@
   virtual void OnBoundsAnimatorProgressed(
       views::BoundsAnimator* animator) OVERRIDE {}
   virtual void OnBoundsAnimatorDone(views::BoundsAnimator* animator) OVERRIDE {
-    MessageLoop::current()->Quit();
+    base::MessageLoop::current()->Quit();
   }
 
  private:
@@ -90,7 +90,7 @@
 
   // This nested loop will quit when TestAPIAnimationObserver's
   // OnBoundsAnimatorDone is called.
-  MessageLoop::current()->Run();
+  base::MessageLoop::current()->Run();
 
   launcher_view_->bounds_animator_->RemoveObserver(observer.get());
 }
diff --git a/ash/test/shell_test_api.cc b/ash/test/shell_test_api.cc
index 72b869a..126beab 100644
--- a/ash/test/shell_test_api.cc
+++ b/ash/test/shell_test_api.cc
@@ -50,7 +50,7 @@
 
 void ShellTestApi::DisableOutputConfiguratorAnimation() {
 #if defined(OS_CHROMEOS)
-  if (shell_->output_configurator_animation_.get()) {
+  if (shell_->output_configurator_animation_) {
     shell_->output_configurator_->RemoveObserver(
         shell_->output_configurator_animation_.get());
     shell_->output_configurator_animation_.reset();
diff --git a/ash/test/test_launcher_delegate.cc b/ash/test/test_launcher_delegate.cc
index 13ab706..16422e3 100644
--- a/ash/test/test_launcher_delegate.cc
+++ b/ash/test/test_launcher_delegate.cc
@@ -66,10 +66,11 @@
 void TestLauncherDelegate::OnBrowserShortcutClicked(int event_flags) {
 }
 
-void TestLauncherDelegate::ItemClicked(const ash::LauncherItem& item,
+void TestLauncherDelegate::ItemSelected(const ash::LauncherItem& item,
                                        const ui::Event& event) {
   aura::Window* window = GetWindowByID(item.id);
-  launcher::MoveToEventRootIfPanel(window, event);
+  if (window->type() == aura::client::WINDOW_TYPE_PANEL)
+    ash::wm::MoveWindowToEventRoot(window, event);
   window->Show();
   ash::wm::ActivateWindow(window);
 }
@@ -78,9 +79,9 @@
   return IDR_AURA_LAUNCHER_BROWSER_SHORTCUT;
 }
 
-string16 TestLauncherDelegate::GetTitle(const ash::LauncherItem& item) {
+base::string16 TestLauncherDelegate::GetTitle(const ash::LauncherItem& item) {
   aura::Window* window = GetWindowByID(item.id);
-  return window ? window->title() : string16();
+  return window ? window->title() : base::string16();
 }
 
 ui::MenuModel* TestLauncherDelegate::CreateContextMenu(
@@ -120,5 +121,15 @@
   return true;
 }
 
+void TestLauncherDelegate::OnLauncherCreated(Launcher* launcher) {
+}
+
+void TestLauncherDelegate::OnLauncherDestroyed(Launcher* launcher) {
+}
+
+bool TestLauncherDelegate::IsPerAppLauncher() {
+  return true;
+}
+
 }  // namespace test
 }  // namespace ash
diff --git a/ash/test/test_launcher_delegate.h b/ash/test/test_launcher_delegate.h
index f249bee..b86b1e1 100644
--- a/ash/test/test_launcher_delegate.h
+++ b/ash/test/test_launcher_delegate.h
@@ -36,10 +36,10 @@
 
   // LauncherDelegate implementation.
   virtual void OnBrowserShortcutClicked(int event_flags) OVERRIDE;
-  virtual void ItemClicked(const LauncherItem& item,
+  virtual void ItemSelected(const LauncherItem& item,
                            const ui::Event& event) OVERRIDE;
   virtual int GetBrowserShortcutResourceId() OVERRIDE;
-  virtual string16 GetTitle(const LauncherItem& item) OVERRIDE;
+  virtual base::string16 GetTitle(const LauncherItem& item) OVERRIDE;
   virtual ui::MenuModel* CreateContextMenu(const LauncherItem& item,
                                            aura::RootWindow* root) OVERRIDE;
   virtual ash::LauncherMenuModel* CreateApplicationMenu(
@@ -48,6 +48,9 @@
   virtual ash::LauncherID GetIDByWindow(aura::Window* window) OVERRIDE;
   virtual bool IsDraggable(const ash::LauncherItem& item) OVERRIDE;
   virtual bool ShouldShowTooltip(const LauncherItem& item) OVERRIDE;
+  virtual void OnLauncherCreated(Launcher* launcher) OVERRIDE;
+  virtual void OnLauncherDestroyed(Launcher* launcher) OVERRIDE;
+  virtual bool IsPerAppLauncher() OVERRIDE;
 
  private:
   typedef std::map<aura::Window*, ash::LauncherID> WindowToID;
diff --git a/ash/test/test_metro_viewer_process_host.cc b/ash/test/test_metro_viewer_process_host.cc
index 3d58f6f..277864f 100644
--- a/ash/test/test_metro_viewer_process_host.cc
+++ b/ash/test/test_metro_viewer_process_host.cc
@@ -40,7 +40,7 @@
           closed_unexpectedly_(false) {
 
   base::Thread::Options options;
-  options.message_loop_type = MessageLoop::TYPE_IO;
+  options.message_loop_type = base::MessageLoop::TYPE_IO;
   ipc_thread_.StartWithOptions(options);
 
   channel_.reset(new IPC::ChannelProxy(
@@ -62,7 +62,7 @@
 }
 
 bool TestMetroViewerProcessHost::LaunchViewerAndWaitForConnection(
-    const string16& app_user_model_id) {
+    const base::string16& app_user_model_id) {
   // Activate the viewer process. NOTE: This assumes that the viewer process is
   // registered as the default browser using the provided |app_user_model_id|.
 
diff --git a/ash/test/test_metro_viewer_process_host.h b/ash/test/test_metro_viewer_process_host.h
index de0969e..f52230b 100644
--- a/ash/test/test_metro_viewer_process_host.h
+++ b/ash/test/test_metro_viewer_process_host.h
@@ -32,7 +32,8 @@
   // and blocks until that viewer process connects or until a timeout is
   // reached. Returns true if the viewer process connects before the timeout is
   // reached.
-  bool LaunchViewerAndWaitForConnection(const string16& app_user_model_id);
+  bool LaunchViewerAndWaitForConnection(
+      const base::string16& app_user_model_id);
 
   // IPC::Sender implementation:
   virtual bool Send(IPC::Message* msg) OVERRIDE;
diff --git a/ash/test/test_session_state_delegate.cc b/ash/test/test_session_state_delegate.cc
new file mode 100644
index 0000000..881f498
--- /dev/null
+++ b/ash/test/test_session_state_delegate.cc
@@ -0,0 +1,63 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/test/test_session_state_delegate.h"
+
+namespace ash {
+namespace test {
+
+TestSessionStateDelegate::TestSessionStateDelegate()
+    : has_active_user_(true),
+      active_user_session_started_(true),
+      can_lock_screen_(true),
+      screen_locked_(false) {
+}
+
+TestSessionStateDelegate::~TestSessionStateDelegate() {
+}
+
+bool TestSessionStateDelegate::HasActiveUser() const {
+  return has_active_user_;
+}
+
+bool TestSessionStateDelegate::IsActiveUserSessionStarted() const {
+  return active_user_session_started_;
+}
+
+bool TestSessionStateDelegate::CanLockScreen() const {
+  return has_active_user_ && can_lock_screen_;
+}
+
+bool TestSessionStateDelegate::IsScreenLocked() const {
+  return screen_locked_;
+}
+
+void TestSessionStateDelegate::LockScreen() {
+  if (CanLockScreen())
+    screen_locked_ = true;
+}
+
+void TestSessionStateDelegate::UnlockScreen() {
+  screen_locked_ = false;
+}
+
+void TestSessionStateDelegate::SetHasActiveUser(bool has_active_user) {
+  has_active_user_ = has_active_user;
+  if (!has_active_user)
+    active_user_session_started_ = false;
+}
+
+void TestSessionStateDelegate::SetActiveUserSessionStarted(
+    bool active_user_session_started) {
+  active_user_session_started_ = active_user_session_started;
+  if (active_user_session_started)
+    has_active_user_ = true;
+}
+
+void TestSessionStateDelegate::SetCanLockScreen(bool can_lock_screen) {
+  can_lock_screen_ = can_lock_screen;
+}
+
+}  // namespace test
+}  // namespace ash
diff --git a/ash/test/test_session_state_delegate.h b/ash/test/test_session_state_delegate.h
new file mode 100644
index 0000000..807e335
--- /dev/null
+++ b/ash/test/test_session_state_delegate.h
@@ -0,0 +1,67 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_TEST_TEST_SESSION_STATE_DELEGATE_H_
+#define ASH_TEST_TEST_SESSION_STATE_DELEGATE_H_
+
+#include "ash/session_state_delegate.h"
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+
+namespace ash {
+namespace test {
+
+class TestSessionStateDelegate : public SessionStateDelegate {
+ public:
+  TestSessionStateDelegate();
+  virtual ~TestSessionStateDelegate();
+
+  // SessionStateDelegate:
+  virtual bool HasActiveUser() const OVERRIDE;
+  virtual bool IsActiveUserSessionStarted() const OVERRIDE;
+  virtual bool CanLockScreen() const OVERRIDE;
+  virtual bool IsScreenLocked() const OVERRIDE;
+  virtual void LockScreen() OVERRIDE;
+  virtual void UnlockScreen() OVERRIDE;
+
+  // Updates the internal state that indicates whether a session is in progress
+  // and there is an active user. If |has_active_user| is |false|,
+  // |active_user_session_started_| is reset to |false| as well (see below for
+  // the difference between these two flags).
+  void SetHasActiveUser(bool has_active_user);
+
+  // Updates the internal state that indicates whether the session has been
+  // fully started for the active user. If |active_user_session_started| is
+  // |true|, |has_active_user_| is set to |true| as well (see below for the
+  // difference between these two flags).
+  void SetActiveUserSessionStarted(bool active_user_session_started);
+
+  // Updates the internal state that indicates whether the screen can be locked.
+  // Locking will only actually be allowed when this value is |true| and there
+  // is an active user.
+  void SetCanLockScreen(bool can_lock_screen);
+
+ private:
+  // Whether a session is in progress and there is an active user.
+  bool has_active_user_;
+
+  // When a user becomes active, the profile and browser UI are not immediately
+  // available. Only once this flag becomes |true| is the browser startup
+  // complete and both profile and UI are fully available.
+  bool active_user_session_started_;
+
+  // Whether the screen can be locked. Locking will only actually be allowed
+  // when this is |true| and there is an active user.
+  bool can_lock_screen_;
+
+  // Whether the screen is currently locked.
+  bool screen_locked_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestSessionStateDelegate);
+};
+
+}  // namespace test
+}  // namespace ash
+
+#endif  // ASH_TEST_TEST_SESSION_STATE_DELEGATE_H_
diff --git a/ash/test/test_shell_delegate.cc b/ash/test/test_shell_delegate.cc
index e644d62..e0403a7 100644
--- a/ash/test/test_shell_delegate.cc
+++ b/ash/test/test_shell_delegate.cc
@@ -8,10 +8,13 @@
 
 #include "ash/caps_lock_delegate_stub.h"
 #include "ash/host/root_window_host_factory.h"
+#include "ash/session_state_delegate.h"
 #include "ash/shell.h"
 #include "ash/shell_window_ids.h"
 #include "ash/test/test_launcher_delegate.h"
+#include "ash/test/test_session_state_delegate.h"
 #include "ash/wm/window_util.h"
+#include "base/logging.h"
 #include "content/public/test/test_browser_context.h"
 #include "ui/aura/window.h"
 
@@ -19,54 +22,27 @@
 namespace test {
 
 TestShellDelegate::TestShellDelegate()
-    : locked_(false),
-      session_started_(true),
-      spoken_feedback_enabled_(false),
+    : spoken_feedback_enabled_(false),
       high_contrast_enabled_(false),
       screen_magnifier_enabled_(false),
       screen_magnifier_type_(kDefaultMagnifierType),
-      user_logged_in_(true),
-      can_lock_screen_(true),
-      num_exit_requests_(0) {
+      num_exit_requests_(0),
+      test_session_state_delegate_(NULL) {
 }
 
 TestShellDelegate::~TestShellDelegate() {
 }
 
-bool TestShellDelegate::IsUserLoggedIn() const {
-  return user_logged_in_;
-}
-
-bool TestShellDelegate::IsSessionStarted() const {
-  return session_started_;
-}
-
-bool TestShellDelegate::IsGuestSession() const {
-  return false;
-}
-
 bool TestShellDelegate::IsFirstRunAfterBoot() const {
   return false;
 }
 
-bool TestShellDelegate::IsRunningInForcedAppMode() const {
+bool TestShellDelegate::IsMultiProfilesEnabled() const {
   return false;
 }
 
-bool TestShellDelegate::CanLockScreen() const {
-  return user_logged_in_ && can_lock_screen_;
-}
-
-void TestShellDelegate::LockScreen() {
-  locked_ = true;
-}
-
-void TestShellDelegate::UnlockScreen() {
-  locked_ = false;
-}
-
-bool TestShellDelegate::IsScreenLocked() const {
-  return locked_;
+bool TestShellDelegate::IsRunningInForcedAppMode() const {
+  return false;
 }
 
 void TestShellDelegate::PreInit() {
@@ -91,6 +67,9 @@
     ash::wm::ToggleMaximizedWindow(window);
 }
 
+void TestShellDelegate::ToggleFullscreen() {
+}
+
 void TestShellDelegate::OpenFileManager(bool as_dialog) {
 }
 
@@ -103,11 +82,12 @@
 void TestShellDelegate::RestoreTab() {
 }
 
-bool TestShellDelegate::RotatePaneFocus(Shell::Direction direction) {
-  return true;
+void TestShellDelegate::ShowKeyboardOverlay() {
 }
 
-void TestShellDelegate::ShowKeyboardOverlay() {
+keyboard::KeyboardControllerProxy*
+    TestShellDelegate::CreateKeyboardControllerProxy() {
+  return NULL;
 }
 
 void TestShellDelegate::ShowTaskManager() {
@@ -155,6 +135,9 @@
   return false;
 }
 
+void TestShellDelegate::SilenceSpokenFeedback() const {
+}
+
 app_list::AppListViewDelegate* TestShellDelegate::CreateAppListViewDelegate() {
   return NULL;
 }
@@ -176,6 +159,12 @@
   return new CapsLockDelegateStub;
 }
 
+SessionStateDelegate* TestShellDelegate::CreateSessionStateDelegate() {
+  DCHECK(!test_session_state_delegate_);
+  test_session_state_delegate_ = new TestSessionStateDelegate();
+  return test_session_state_delegate_;
+}
+
 aura::client::UserActionClient* TestShellDelegate::CreateUserActionClient() {
   return NULL;
 }
@@ -195,12 +184,14 @@
 void TestShellDelegate::HandleMediaPrevTrack() {
 }
 
-string16 TestShellDelegate::GetTimeRemainingString(base::TimeDelta delta) {
-  return string16();
+base::string16 TestShellDelegate::GetTimeRemainingString(
+    base::TimeDelta delta) {
+  return base::string16();
 }
 
-string16 TestShellDelegate::GetTimeDurationLongString(base::TimeDelta delta) {
-  return string16();
+base::string16 TestShellDelegate::GetTimeDurationLongString(
+    base::TimeDelta delta) {
+  return base::string16();
 }
 
 void TestShellDelegate::SaveScreenMagnifierScale(double scale) {
@@ -218,26 +209,13 @@
   return RootWindowHostFactory::Create();
 }
 
-void TestShellDelegate::SetSessionStarted(bool session_started) {
-  session_started_ = session_started;
-  if (session_started)
-    user_logged_in_ = true;
+base::string16 TestShellDelegate::GetProductName() const {
+  return base::string16();
 }
 
-void TestShellDelegate::SetUserLoggedIn(bool user_logged_in) {
-  user_logged_in_ = user_logged_in;
-  if (!user_logged_in)
-    session_started_ = false;
+TestSessionStateDelegate* TestShellDelegate::test_session_state_delegate() {
+  return test_session_state_delegate_;
 }
 
-void TestShellDelegate::SetCanLockScreen(bool can_lock_screen) {
-  can_lock_screen_ = can_lock_screen;
-}
-
-string16 TestShellDelegate::GetProductName() const {
-  return string16();
-}
-
-
 }  // namespace test
 }  // namespace ash
diff --git a/ash/test/test_shell_delegate.h b/ash/test/test_shell_delegate.h
index a5c2e91..d110535 100644
--- a/ash/test/test_shell_delegate.h
+++ b/ash/test/test_shell_delegate.h
@@ -11,10 +11,14 @@
 #include "base/compiler_specific.h"
 #include "base/memory/scoped_ptr.h"
 
+namespace keyboard {
+class KeyboardControllerProxy;
+}
+
 namespace ash {
 namespace test {
 
-class AshTestBase;
+class TestSessionStateDelegate;
 
 class TestShellDelegate : public ShellDelegate {
  public:
@@ -22,27 +26,23 @@
   virtual ~TestShellDelegate();
 
   // Overridden from ShellDelegate:
-  virtual bool IsUserLoggedIn() const OVERRIDE;
-  virtual bool IsSessionStarted() const OVERRIDE;
-  virtual bool IsGuestSession() const OVERRIDE;
   virtual bool IsFirstRunAfterBoot() const OVERRIDE;
+  virtual bool IsMultiProfilesEnabled() const OVERRIDE;
   virtual bool IsRunningInForcedAppMode() const OVERRIDE;
-  virtual bool CanLockScreen() const OVERRIDE;
-  virtual void LockScreen() OVERRIDE;
-  virtual void UnlockScreen() OVERRIDE;
-  virtual bool IsScreenLocked() const OVERRIDE;
   virtual void PreInit() OVERRIDE;
   virtual void Shutdown() OVERRIDE;
   virtual void Exit() OVERRIDE;
   virtual void NewTab() OVERRIDE;
   virtual void NewWindow(bool incognito) OVERRIDE;
+  virtual void ToggleFullscreen() OVERRIDE;
   virtual void ToggleMaximized() OVERRIDE;
   virtual void OpenFileManager(bool as_dialog) OVERRIDE;
   virtual void OpenCrosh() OVERRIDE;
   virtual void OpenMobileSetup(const std::string& service_path) OVERRIDE;
   virtual void RestoreTab() OVERRIDE;
-  virtual bool RotatePaneFocus(Shell::Direction direction) OVERRIDE;
   virtual void ShowKeyboardOverlay() OVERRIDE;
+  virtual keyboard::KeyboardControllerProxy*
+      CreateKeyboardControllerProxy() OVERRIDE;
   virtual void ShowTaskManager() OVERRIDE;
   virtual content::BrowserContext* GetCurrentBrowserContext() OVERRIDE;
   virtual void ToggleSpokenFeedback(
@@ -55,61 +55,44 @@
   virtual bool IsMagnifierEnabled() const OVERRIDE;
   virtual MagnifierType GetMagnifierType() const OVERRIDE;
   virtual bool ShouldAlwaysShowAccessibilityMenu() const OVERRIDE;
+  virtual void SilenceSpokenFeedback() const OVERRIDE;
   virtual app_list::AppListViewDelegate* CreateAppListViewDelegate() OVERRIDE;
   virtual LauncherDelegate* CreateLauncherDelegate(
       ash::LauncherModel* model) OVERRIDE;
   virtual SystemTrayDelegate* CreateSystemTrayDelegate() OVERRIDE;
   virtual UserWallpaperDelegate* CreateUserWallpaperDelegate() OVERRIDE;
   virtual CapsLockDelegate* CreateCapsLockDelegate() OVERRIDE;
+  virtual SessionStateDelegate* CreateSessionStateDelegate() OVERRIDE;
   virtual aura::client::UserActionClient* CreateUserActionClient() OVERRIDE;
   virtual void OpenFeedbackPage() OVERRIDE;
   virtual void RecordUserMetricsAction(UserMetricsAction action) OVERRIDE;
   virtual void HandleMediaNextTrack() OVERRIDE;
   virtual void HandleMediaPlayPause() OVERRIDE;
   virtual void HandleMediaPrevTrack() OVERRIDE;
-  virtual string16 GetTimeRemainingString(base::TimeDelta delta) OVERRIDE;
-  virtual string16 GetTimeDurationLongString(base::TimeDelta delta) OVERRIDE;
+  virtual base::string16 GetTimeRemainingString(base::TimeDelta delta) OVERRIDE;
+  virtual base::string16 GetTimeDurationLongString(
+      base::TimeDelta delta) OVERRIDE;
   virtual void SaveScreenMagnifierScale(double scale) OVERRIDE;
   virtual double GetSavedScreenMagnifierScale() OVERRIDE;
   virtual ui::MenuModel* CreateContextMenu(aura::RootWindow* root) OVERRIDE;
   virtual RootWindowHostFactory* CreateRootWindowHostFactory() OVERRIDE;
-  virtual string16 GetProductName() const OVERRIDE;
+  virtual base::string16 GetProductName() const OVERRIDE;
 
   int num_exit_requests() const { return num_exit_requests_; }
 
+  TestSessionStateDelegate* test_session_state_delegate();
+
  private:
-  friend class ash::test::AshTestBase;
-
-  // Given |session_started| will update internal state.
-  // If |session_started| is true this method will also set
-  // |user_logged_in_| to true.
-  // When session is started it always means that user has logged in.
-  // Possible situation is that user has already logged in but session has not
-  // been started (user selects avatar and login window is still open).
-  void SetSessionStarted(bool session_started);
-
-  // Given |user_logged_in| will update internal state.
-  // If |user_logged_in| is false this method will also set |session_started_|
-  // to false. When user is not logged in it always means that session
-  // hasn't been started too.
-  void SetUserLoggedIn(bool user_logged_in);
-
-  // Sets the internal state that indicates whether the user can lock the
-  // screen.
-  void SetCanLockScreen(bool can_lock_screen);
-
-  bool locked_;
-  bool session_started_;
   bool spoken_feedback_enabled_;
   bool high_contrast_enabled_;
   bool screen_magnifier_enabled_;
   MagnifierType screen_magnifier_type_;
-  bool user_logged_in_;
-  bool can_lock_screen_;
   int num_exit_requests_;
 
   scoped_ptr<content::BrowserContext> current_browser_context_;
 
+  TestSessionStateDelegate* test_session_state_delegate_;  // Not owned.
+
   DISALLOW_COPY_AND_ASSIGN(TestShellDelegate);
 };
 
diff --git a/ash/test/test_suite.cc b/ash/test/test_suite.cc
index a42a685..458aaeb 100644
--- a/ash/test/test_suite.cc
+++ b/ash/test/test_suite.cc
@@ -47,7 +47,7 @@
 
     ui::win::CreateATLModuleIfNeeded();
 
-    std::vector<string16> choices;
+    std::vector<base::string16> choices;
     win8::OpenWithDialogController controller;
     controller.RunSynchronously(NULL, L"http", win8::test::kDefaultTestExeName,
                                 &choices);
diff --git a/ash/tooltips/tooltip_controller_unittest.cc b/ash/tooltips/tooltip_controller_unittest.cc
index 4cc07b8..18ceb17 100644
--- a/ash/tooltips/tooltip_controller_unittest.cc
+++ b/ash/tooltips/tooltip_controller_unittest.cc
@@ -99,7 +99,7 @@
 TEST_F(TooltipControllerTest, NonNullTooltipClient) {
   EXPECT_TRUE(aura::client::GetTooltipClient(Shell::GetPrimaryRootWindow())
               != NULL);
-  EXPECT_EQ(string16(), helper_->GetTooltipText());
+  EXPECT_EQ(base::string16(), helper_->GetTooltipText());
   EXPECT_EQ(NULL, helper_->GetTooltipWindow());
   EXPECT_FALSE(helper_->IsTooltipVisible());
 }
@@ -109,13 +109,13 @@
   TooltipTestView* view = new TooltipTestView;
   AddViewToWidgetAndResize(widget.get(), view);
   view->set_tooltip_text(ASCIIToUTF16("Tooltip Text"));
-  EXPECT_EQ(string16(), helper_->GetTooltipText());
+  EXPECT_EQ(base::string16(), helper_->GetTooltipText());
   EXPECT_EQ(NULL, helper_->GetTooltipWindow());
 
   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
   generator.MoveMouseRelativeTo(widget->GetNativeView(),
                                 view->bounds().CenterPoint());
-  string16 expected_tooltip = ASCIIToUTF16("Tooltip Text");
+  base::string16 expected_tooltip = ASCIIToUTF16("Tooltip Text");
 
   // Fire tooltip timer so tooltip becomes visible.
   helper_->FireTooltipTimer();
diff --git a/ash/touch/touch_observer_hud.cc b/ash/touch/touch_observer_hud.cc
index cb615f7..2d99ef0 100644
--- a/ash/touch/touch_observer_hud.cc
+++ b/ash/touch/touch_observer_hud.cc
@@ -4,14 +4,22 @@
 
 #include "ash/touch/touch_observer_hud.h"
 
+#include "ash/display/display_controller.h"
+#include "ash/display/display_manager.h"
+#include "ash/root_window_controller.h"
 #include "ash/shell_window_ids.h"
+#include "ash/wm/property_util.h"
 #include "base/json/json_string_value_serializer.h"
 #include "base/stringprintf.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/utf_string_conversions.h"
-#include "base/values.h"
 #include "third_party/skia/include/core/SkPath.h"
 #include "third_party/skia/include/core/SkXfermode.h"
+#include "third_party/skia/include/effects/SkGradientShader.h"
+#include "ui/aura/root_window.h"
 #include "ui/aura/window.h"
+#include "ui/base/animation/animation_delegate.h"
+#include "ui/base/animation/linear_animation.h"
 #include "ui/base/events/event.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/display.h"
@@ -35,20 +43,28 @@
 namespace internal {
 
 const int kPointRadius = 20;
-const int kColors[] = {
-  static_cast<int>(SK_ColorYELLOW),
-  static_cast<int>(SK_ColorGREEN),
-  static_cast<int>(SK_ColorRED),
-  static_cast<int>(SK_ColorBLUE),
-  static_cast<int>(SK_ColorGRAY),
-  static_cast<int>(SK_ColorMAGENTA),
-  static_cast<int>(SK_ColorCYAN),
-  static_cast<int>(SK_ColorWHITE),
-  static_cast<int>(SK_ColorBLACK)
+const SkColor kColors[] = {
+  SK_ColorYELLOW,
+  SK_ColorGREEN,
+  SK_ColorRED,
+  SK_ColorBLUE,
+  SK_ColorGRAY,
+  SK_ColorMAGENTA,
+  SK_ColorCYAN,
+  SK_ColorWHITE,
+  SK_ColorBLACK,
+  SkColorSetRGB(0xFF, 0x8C, 0x00),
+  SkColorSetRGB(0x8B, 0x45, 0x13),
+  SkColorSetRGB(0xFF, 0xDE, 0xAD),
 };
 const int kAlpha = 0x60;
+const SkColor kProjectionFillColor = SkColorSetRGB(0xF5, 0xF5, 0xDC);
+const SkColor kProjectionStrokeColor = SK_ColorGRAY;
+const int kProjectionAlpha = 0xB0;
 const int kMaxPaths = arraysize(kColors);
 const int kReducedScale = 10;
+const int kFadeoutDurationInMs = 250;
+const int kFadeoutFrameRate = 60;
 
 const char* GetTouchEventLabel(ui::EventType type) {
   switch (type) {
@@ -141,6 +157,12 @@
 // (starting from a touch-press and ending at touch-release).
 class TouchTrace {
  public:
+  typedef std::vector<TouchPointLog>::iterator iterator;
+  typedef std::vector<TouchPointLog>::const_iterator const_iterator;
+  typedef std::vector<TouchPointLog>::reverse_iterator reverse_iterator;
+  typedef std::vector<TouchPointLog>::const_reverse_iterator
+      const_reverse_iterator;
+
   TouchTrace() {
   }
 
@@ -148,16 +170,18 @@
     log_.push_back(TouchPointLog(touch));
   }
 
-  bool empty() const { return log_.empty(); }
+  const std::vector<TouchPointLog>& log() const { return log_; }
+
+  bool active() const {
+    return !log_.empty() && log_.back().type != ui::ET_TOUCH_RELEASED &&
+        log_.back().type != ui::ET_TOUCH_CANCELLED;
+  }
 
   // Returns a list containing data from all events for the touch point.
   scoped_ptr<ListValue> GetAsList() const {
     scoped_ptr<ListValue> list(new ListValue());
-    for (std::vector<TouchPointLog>::const_iterator i = log_.begin();
-        i != log_.end(); ++i) {
+    for (const_iterator i = log_.begin(); i != log_.end(); ++i)
       list->Append((*i).GetAsDictionary().release());
-    }
-
     return list.Pass();
   }
 
@@ -171,17 +195,81 @@
   DISALLOW_COPY_AND_ASSIGN(TouchTrace);
 };
 
+// A TouchLog keeps track of all touch events of all touch points.
+class TouchLog {
+ public:
+  TouchLog() : next_trace_index_(0) {
+  }
+
+  void AddTouchPoint(const ui::TouchEvent& touch) {
+    if (touch.type() == ui::ET_TOUCH_PRESSED)
+      StartTrace(touch);
+    AddToTrace(touch);
+  }
+
+  void Reset() {
+    next_trace_index_ = 0;
+    for (int i = 0; i < kMaxPaths; ++i)
+      traces_[i].Reset();
+  }
+
+  scoped_ptr<ListValue> GetAsList() const {
+    scoped_ptr<ListValue> list(new ListValue());
+    for (int i = 0; i < kMaxPaths; ++i) {
+      if (!traces_[i].log().empty())
+        list->Append(traces_[i].GetAsList().release());
+    }
+    return list.Pass();
+  }
+
+  int GetTraceIndex(int touch_id) const {
+    return touch_id_to_trace_index_.at(touch_id);
+  }
+
+  const TouchTrace* traces() const {
+    return traces_;
+  }
+
+ private:
+  void StartTrace(const ui::TouchEvent& touch) {
+    // Find the first inactive spot; otherwise, overwrite the one
+    // |next_trace_index_| is pointing to.
+    int old_trace_index = next_trace_index_;
+    do {
+      if (!traces_[next_trace_index_].active())
+        break;
+      next_trace_index_ = (next_trace_index_ + 1) % kMaxPaths;
+    } while (next_trace_index_ != old_trace_index);
+    int touch_id = touch.touch_id();
+    traces_[next_trace_index_].Reset();
+    touch_id_to_trace_index_[touch_id] = next_trace_index_;
+    next_trace_index_ = (next_trace_index_ + 1) % kMaxPaths;
+  }
+
+  void AddToTrace(const ui::TouchEvent& touch) {
+    int touch_id = touch.touch_id();
+    int trace_index = touch_id_to_trace_index_[touch_id];
+    traces_[trace_index].AddTouchPoint(touch);
+  }
+
+  TouchTrace traces_[kMaxPaths];
+  int next_trace_index_;
+
+  std::map<int, int> touch_id_to_trace_index_;
+
+  DISALLOW_COPY_AND_ASSIGN(TouchLog);
+};
+
+// TouchHudCanvas draws touch traces in |FULLSCREEN| and |REDUCED_SCALE| modes.
 class TouchHudCanvas : public views::View {
  public:
-  explicit TouchHudCanvas(TouchObserverHUD* owner)
-      : owner_(owner),
-        path_index_(0),
-        color_index_(0),
+  explicit TouchHudCanvas(const TouchLog& touch_log)
+      : touch_log_(touch_log),
         scale_(1) {
-    gfx::Display display = Shell::GetScreen()->GetPrimaryDisplay();
-    gfx::Rect bounds = display.bounds();
     SetPaintToLayer(true);
     SetFillsBoundsOpaquely(false);
+
+    paint_.setStyle(SkPaint::kFill_Style);
   }
 
   virtual ~TouchHudCanvas() {}
@@ -197,99 +285,195 @@
 
   int scale() const { return scale_; }
 
-  void Start(const ui::TouchEvent& touch) {
-    int id = touch.touch_id();
-    paths_[path_index_].reset();
-    traces_[path_index_].Reset();
-    colors_[path_index_] = SkColorSetA(kColors[color_index_], kAlpha);
-    color_index_ = (color_index_ + 1) % arraysize(kColors);
-    touch_id_to_path_[id] = path_index_;
-    path_index_ = (path_index_ + 1) % kMaxPaths;
-    AddPoint(touch);
-    SchedulePaint();
-  }
-
-  void AddPoint(const ui::TouchEvent& touch) {
-    int id = touch.touch_id();
-    const gfx::Point& point = touch.root_location();
-    int path_id = touch_id_to_path_[id];
-    SkScalar x = SkIntToScalar(point.x());
-    SkScalar y = SkIntToScalar(point.y());
-    SkPoint last;
-    if (!paths_[path_id].getLastPt(&last) || x != last.x() || y != last.y()) {
-      paths_[path_id].addCircle(x, y, SkIntToScalar(kPointRadius));
-      traces_[path_id].AddTouchPoint(touch);
-    }
-    SchedulePaint();
+  void TouchPointAdded(int touch_id) {
+    int trace_index = touch_log_.GetTraceIndex(touch_id);
+    const TouchTrace& trace = touch_log_.traces()[trace_index];
+    const TouchPointLog& point = trace.log().back();
+    if (point.type == ui::ET_TOUCH_PRESSED)
+      StartedTrace(trace_index);
+    if (point.type != ui::ET_TOUCH_CANCELLED)
+      AddedPointToTrace(trace_index);
   }
 
   void Clear() {
-    path_index_ = 0;
-    color_index_ = 0;
-    for (size_t i = 0; i < arraysize(paths_); ++i) {
+    for (int i = 0; i < kMaxPaths; ++i)
       paths_[i].reset();
-      traces_[i].Reset();
-    }
 
     SchedulePaint();
   }
 
-  scoped_ptr<ListValue> GetAsList() const {
-    scoped_ptr<ListValue> list(new ListValue());
-    for (size_t i = 0; i < arraysize(traces_); ++i) {
-      if (!traces_[i].empty())
-        list->Append(traces_[i].GetAsList().release());
-    }
-    return list.Pass();
+ private:
+  void StartedTrace(int trace_index) {
+    paths_[trace_index].reset();
+    colors_[trace_index] = SkColorSetA(kColors[trace_index], kAlpha);
   }
 
- private:
+  void AddedPointToTrace(int trace_index) {
+    const TouchTrace& trace = touch_log_.traces()[trace_index];
+    const TouchPointLog& point = trace.log().back();
+    const gfx::Point& location = point.location;
+    SkScalar x = SkIntToScalar(location.x());
+    SkScalar y = SkIntToScalar(location.y());
+    SkPoint last;
+    if (!paths_[trace_index].getLastPt(&last) || x != last.x() ||
+        y != last.y()) {
+      paths_[trace_index].addCircle(x, y, SkIntToScalar(kPointRadius));
+      SchedulePaint();
+    }
+  }
+
   // Overridden from views::View.
   virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
-    canvas->DrawColor(SK_ColorBLACK, SkXfermode::kClear_Mode);
-    canvas->DrawColor(SkColorSetARGB(0, 0, 0, 0));
-
-    SkPaint paint;
-    paint.setStyle(SkPaint::kFill_Style);
-    for (size_t i = 0; i < arraysize(paths_); ++i) {
+    for (int i = 0; i < kMaxPaths; ++i) {
       if (paths_[i].countPoints() == 0)
         continue;
-      paint.setColor(colors_[i]);
-      canvas->DrawPath(paths_[i], paint);
+      paint_.setColor(colors_[i]);
+      canvas->DrawPath(paths_[i], paint_);
     }
   }
 
-  TouchObserverHUD* owner_;
+  SkPaint paint_;
+
+  const TouchLog& touch_log_;
   SkPath paths_[kMaxPaths];
   SkColor colors_[kMaxPaths];
-  TouchTrace traces_[kMaxPaths];
 
-  int path_index_;
-  int color_index_;
   int scale_;
 
-  std::map<int, int> touch_id_to_path_;
-
   DISALLOW_COPY_AND_ASSIGN(TouchHudCanvas);
 };
 
-TouchObserverHUD::TouchObserverHUD() {
+// TouchPointView draws a single touch point in |PROJECTION| mode. This object
+// manages its own lifetime and deletes itself upon fade-out completion or
+// whenever |Remove()| is explicitly called.
+class TouchPointView : public views::View,
+                       public ui::AnimationDelegate,
+                       public views::WidgetObserver {
+ public:
+  explicit TouchPointView(views::Widget* parent_widget)
+      : circle_center_(kPointRadius + 1, kPointRadius + 1),
+        gradient_center_(SkPoint::Make(kPointRadius + 1,
+                                       kPointRadius + 1)) {
+    SetPaintToLayer(true);
+    SetFillsBoundsOpaquely(false);
+
+    SetSize(gfx::Size(2 * kPointRadius + 2, 2 * kPointRadius + 2));
+
+    stroke_paint_.setStyle(SkPaint::kStroke_Style);
+    stroke_paint_.setColor(kProjectionStrokeColor);
+
+    gradient_colors_[0] = kProjectionFillColor;
+    gradient_colors_[1] = kProjectionStrokeColor;
+
+    gradient_pos_[0] = SkFloatToScalar(0.9f);
+    gradient_pos_[1] = SkFloatToScalar(1.0f);
+
+    parent_widget->GetContentsView()->AddChildView(this);
+
+    parent_widget->AddObserver(this);
+  }
+
+  void UpdateTouch(const ui::TouchEvent& touch) {
+    if (touch.type() == ui::ET_TOUCH_RELEASED ||
+        touch.type() == ui::ET_TOUCH_CANCELLED) {
+      fadeout_.reset(new ui::LinearAnimation(kFadeoutDurationInMs,
+                                             kFadeoutFrameRate,
+                                             this));
+      fadeout_->Start();
+    } else {
+      SetX(touch.root_location().x() - kPointRadius - 1);
+      SetY(touch.root_location().y() - kPointRadius - 1);
+    }
+  }
+
+  void Remove() {
+    delete this;
+  }
+
+ private:
+  virtual ~TouchPointView() {
+    GetWidget()->RemoveObserver(this);
+    parent()->RemoveChildView(this);
+  }
+
+  // Overridden from views::View.
+  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
+    int alpha = kProjectionAlpha;
+    if (fadeout_)
+      alpha = static_cast<int>(fadeout_->CurrentValueBetween(alpha, 0));
+    fill_paint_.setAlpha(alpha);
+    stroke_paint_.setAlpha(alpha);
+    SkShader* shader = SkGradientShader::CreateRadial(
+        gradient_center_,
+        SkIntToScalar(kPointRadius),
+        gradient_colors_,
+        gradient_pos_,
+        arraysize(gradient_colors_),
+        SkShader::kMirror_TileMode,
+        NULL);
+    fill_paint_.setShader(shader);
+    shader->unref();
+    canvas->DrawCircle(circle_center_, SkIntToScalar(kPointRadius),
+                       fill_paint_);
+    canvas->DrawCircle(circle_center_, SkIntToScalar(kPointRadius),
+                       stroke_paint_);
+  }
+
+  // Overridden from ui::AnimationDelegate.
+  virtual void AnimationEnded(const ui::Animation* animation) OVERRIDE {
+    DCHECK_EQ(fadeout_.get(), animation);
+    delete this;
+  }
+
+  virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE {
+    DCHECK_EQ(fadeout_.get(), animation);
+    SchedulePaint();
+  }
+
+  virtual void AnimationCanceled(const ui::Animation* animation) OVERRIDE {
+    AnimationEnded(animation);
+  }
+
+  // Overridden from views::WidgetObserver.
+  virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE {
+    fadeout_->Stop();
+  }
+
+  const gfx::Point circle_center_;
+  const SkPoint gradient_center_;
+
+  SkPaint fill_paint_;
+  SkPaint stroke_paint_;
+  SkColor gradient_colors_[2];
+  SkScalar gradient_pos_[2];
+
+  scoped_ptr<ui::Animation> fadeout_;
+
+  DISALLOW_COPY_AND_ASSIGN(TouchPointView);
+};
+
+TouchObserverHUD::TouchObserverHUD(aura::RootWindow* initial_root)
+    : display_id_(initial_root->GetProperty(kDisplayIdKey)),
+      root_window_(initial_root),
+      mode_(FULLSCREEN),
+      touch_log_(new TouchLog()) {
+  const gfx::Display& display =
+      Shell::GetInstance()->display_manager()->GetDisplayForId(display_id_);
+
   views::View* content = new views::View;
 
-  canvas_ = new TouchHudCanvas(this);
+  canvas_ = new TouchHudCanvas(*touch_log_);
   content->AddChildView(canvas_);
 
-  gfx::Display display = Shell::GetScreen()->GetPrimaryDisplay();
-  gfx::Rect display_bounds = display.bounds();
-  canvas_->SetBoundsRect(display_bounds);
-  content->SetBoundsRect(display_bounds);
+  const gfx::Size& display_size = display.size();
+  canvas_->SetSize(display_size);
+  content->SetSize(display_size);
 
   label_container_ = new views::View;
   label_container_->SetLayoutManager(new views::BoxLayout(
       views::BoxLayout::kVertical, 0, 0, 0));
 
   for (int i = 0; i < kMaxTouchPoints; ++i) {
-    touch_status_[i] = ui::ET_UNKNOWN;
     touch_labels_[i] = new views::Label;
     touch_labels_[i]->SetBackgroundColor(SkColorSetARGB(0, 255, 255, 255));
     touch_labels_[i]->SetShadowColors(SK_ColorWHITE,
@@ -298,7 +482,7 @@
     label_container_->AddChildView(touch_labels_[i]);
   }
   label_container_->SetX(0);
-  label_container_->SetY(display_bounds.height() / kReducedScale);
+  label_container_->SetY(display_size.height() / kReducedScale);
   label_container_->SetSize(label_container_->GetPreferredSize());
   label_container_->SetVisible(false);
   content->AddChildView(label_container_);
@@ -309,58 +493,138 @@
   params.transparent = true;
   params.can_activate = false;
   params.accept_events = false;
-  params.bounds = display_bounds;
+  params.bounds = gfx::Rect(display_size);
   params.parent = Shell::GetContainer(
-      Shell::GetPrimaryRootWindow(),
+      root_window_,
       internal::kShellWindowId_OverlayContainer);
   widget_->Init(params);
   widget_->SetContentsView(content);
   widget_->StackAtTop();
   widget_->Show();
 
-  // The TouchObserverHUD's lifetime is always more than |widget_|. The
-  // |widget_| is unset from the OnWidgetDestroying callback.
   widget_->AddObserver(this);
+
+  // Observe changes in display size and mode to update touch HUD.
+  Shell::GetScreen()->AddObserver(this);
+#if defined(OS_CHROMEOS)
+  Shell::GetInstance()->output_configurator()->AddObserver(this);
+#endif  // defined(OS_CHROMEOS)
+
+  Shell::GetInstance()->display_controller()->AddObserver(this);
+  root_window_->AddPreTargetHandler(this);
 }
 
 TouchObserverHUD::~TouchObserverHUD() {
-  // The widget should have already been destroyed.
-  DCHECK(!widget_);
+  Shell::GetInstance()->display_controller()->RemoveObserver(this);
+
+#if defined(OS_CHROMEOS)
+  Shell::GetInstance()->output_configurator()->RemoveObserver(this);
+#endif  // defined(OS_CHROMEOS)
+  Shell::GetScreen()->RemoveObserver(this);
+
+  widget_->RemoveObserver(this);
+}
+
+// static
+scoped_ptr<DictionaryValue> TouchObserverHUD::GetAllAsDictionary() {
+  scoped_ptr<DictionaryValue> value(new DictionaryValue());
+  Shell::RootWindowList roots = Shell::GetInstance()->GetAllRootWindows();
+  for (Shell::RootWindowList::iterator iter = roots.begin();
+      iter != roots.end(); ++iter) {
+    internal::RootWindowController* controller = GetRootWindowController(*iter);
+    if (controller->touch_observer_hud()) {
+      int64 display_id = (*iter)->GetProperty(kDisplayIdKey);
+      scoped_ptr<ListValue> list =
+          controller->touch_observer_hud()->GetLogAsList();
+      if (!list->empty())
+        value->Set(base::Int64ToString(display_id), list.release());
+    }
+  }
+  return value.Pass();
 }
 
 void TouchObserverHUD::ChangeToNextMode() {
-  if (widget_->IsVisible()) {
-    if (canvas_->scale() == kReducedScale) {
-      widget_->Hide();
-    } else {
-      label_container_->SetVisible(true);
-      canvas_->SetScale(kReducedScale);
-    }
-  } else {
-    canvas_->SetScale(1);
-    label_container_->SetVisible(false);
-    widget_->Show();
+  switch (mode_) {
+    case FULLSCREEN:
+      SetMode(REDUCED_SCALE);
+      break;
+    case REDUCED_SCALE:
+      SetMode(PROJECTION);
+      break;
+    case PROJECTION:
+      SetMode(INVISIBLE);
+      break;
+    case INVISIBLE:
+      SetMode(FULLSCREEN);
+      break;
   }
 }
 
 void TouchObserverHUD::Clear() {
   if (widget_->IsVisible())
     canvas_->Clear();
+  for (int i = 0; i < kMaxTouchPoints; ++i)
+    touch_labels_[i]->SetText(string16());
+  label_container_->SetSize(label_container_->GetPreferredSize());
 }
 
-std::string TouchObserverHUD::GetLogAsString() const {
-  std::string string;
-  scoped_ptr<ListValue> list = canvas_->GetAsList();
-  JSONStringValueSerializer json(&string);
-  json.set_pretty_print(true);
-  return json.Serialize(*list) ? string : std::string();
+scoped_ptr<ListValue> TouchObserverHUD::GetLogAsList() const {
+  return touch_log_->GetAsList();
+}
+
+void TouchObserverHUD::SetMode(Mode mode) {
+  if (mode_ == mode)
+    return;
+  // When going out of projection mode, hide all active touch points.
+  if (mode_ == PROJECTION) {
+    for (std::map<int, TouchPointView*>::iterator iter = points_.begin();
+        iter != points_.end(); ++iter)
+      iter->second->Remove();
+    points_.clear();
+  }
+  mode_ = mode;
+  switch (mode) {
+    case FULLSCREEN:
+      label_container_->SetVisible(false);
+      canvas_->SetVisible(true);
+      canvas_->SetScale(1);
+      canvas_->SchedulePaint();
+      widget_->Show();
+      break;
+    case REDUCED_SCALE:
+      label_container_->SetVisible(true);
+      canvas_->SetVisible(true);
+      canvas_->SetScale(kReducedScale);
+      canvas_->SchedulePaint();
+      widget_->Show();
+      break;
+    case PROJECTION:
+      label_container_->SetVisible(false);
+      canvas_->SetVisible(false);
+      widget_->Show();
+      break;
+    case INVISIBLE:
+      widget_->Hide();
+      break;
+  }
 }
 
 void TouchObserverHUD::UpdateTouchPointLabel(int index) {
+  int trace_index = touch_log_->GetTraceIndex(index);
+  const TouchTrace& trace = touch_log_->traces()[trace_index];
+  TouchTrace::const_reverse_iterator point = trace.log().rbegin();
+  ui::EventType touch_status = point->type;
+  float touch_radius = std::max(point->radius_x, point->radius_y);
+  while (point != trace.log().rend() && point->type == ui::ET_TOUCH_CANCELLED)
+    point++;
+  DCHECK(point != trace.log().rend());
+  gfx::Point touch_position = point->location;
+
   std::string string = base::StringPrintf("%2d: %s %s (%.4f)",
-      index, GetTouchEventLabel(touch_status_[index]),
-      touch_positions_[index].ToString().c_str(),
-      touch_radius_[index]);
+                                          index,
+                                          GetTouchEventLabel(touch_status),
+                                          touch_position.ToString().c_str(),
+                                          touch_radius);
   touch_labels_[index]->SetText(UTF8ToUTF16(string));
 }
 
@@ -368,17 +632,32 @@
   if (event->touch_id() >= kMaxTouchPoints)
     return;
 
-  if (event->type() != ui::ET_TOUCH_CANCELLED)
-    touch_positions_[event->touch_id()] = event->root_location();
+  touch_log_->AddTouchPoint(*event);
+  canvas_->TouchPointAdded(event->touch_id());
 
-  touch_radius_[event->touch_id()] = std::max(event->radius_x(),
-                                              event->radius_y());
-
-  if (event->type() == ui::ET_TOUCH_PRESSED)
-    canvas_->Start(*event);
-  else if (event->type() != ui::ET_TOUCH_CANCELLED)
-    canvas_->AddPoint(*event);
-  touch_status_[event->touch_id()] = event->type();
+  if (mode_ == PROJECTION) {
+    if (event->type() == ui::ET_TOUCH_PRESSED) {
+      TouchPointView* point = new TouchPointView(widget_);
+      point->UpdateTouch(*event);
+      std::pair<std::map<int, TouchPointView*>::iterator, bool> result =
+          points_.insert(std::make_pair(event->touch_id(), point));
+      // If a |TouchPointView| is already mapped to the touch id, remove it and
+      // replace it with the new one.
+      if (!result.second) {
+        result.first->second->Remove();
+        result.first->second = point;
+      }
+    } else {
+      std::map<int, TouchPointView*>::iterator iter =
+          points_.find(event->touch_id());
+      if (iter != points_.end()) {
+        iter->second->UpdateTouch(*event);
+        if (event->type() == ui::ET_TOUCH_RELEASED ||
+            event->type() == ui::ET_TOUCH_CANCELLED)
+          points_.erase(iter);
+      }
+    }
+  }
 
   UpdateTouchPointLabel(event->touch_id());
   label_container_->SetSize(label_container_->GetPreferredSize());
@@ -386,7 +665,67 @@
 
 void TouchObserverHUD::OnWidgetDestroying(views::Widget* widget) {
   DCHECK_EQ(widget, widget_);
-  widget_ = NULL;
+  delete this;
+}
+
+void TouchObserverHUD::OnDisplayBoundsChanged(const gfx::Display& display) {
+  if (display.id() != display_id_)
+    return;
+  const gfx::Size& size = display.size();
+  widget_->SetSize(size);
+  canvas_->SetSize(size);
+  label_container_->SetY(size.height() / kReducedScale);
+}
+
+void TouchObserverHUD::OnDisplayAdded(const gfx::Display& new_display) {}
+
+void TouchObserverHUD::OnDisplayRemoved(const gfx::Display& old_display) {
+  if (old_display.id() != display_id_)
+    return;
+  widget_->CloseNow();
+}
+
+#if defined(OS_CHROMEOS)
+void TouchObserverHUD::OnDisplayModeChanged() {
+  // Clear touch HUD for any change in display mode (single, dual extended, dual
+  // mirrored, ...).
+  Clear();
+}
+#endif  // defined(OS_CHROMEOS)
+
+void TouchObserverHUD::OnDisplayConfigurationChanging() {
+  if (!root_window_)
+    return;
+
+  root_window_->RemovePreTargetHandler(this);
+
+  RootWindowController* controller = GetRootWindowController(root_window_);
+  controller->set_touch_observer_hud(NULL);
+
+  views::Widget::ReparentNativeView(
+      widget_->GetNativeView(),
+      Shell::GetContainer(root_window_,
+                          internal::kShellWindowId_UnparentedControlContainer));
+
+  root_window_ = NULL;
+}
+
+void TouchObserverHUD::OnDisplayConfigurationChanged() {
+  if (root_window_)
+    return;
+
+  root_window_ = Shell::GetInstance()->display_controller()->
+      GetRootWindowForDisplayId(display_id_);
+
+  views::Widget::ReparentNativeView(
+      widget_->GetNativeView(),
+      Shell::GetContainer(root_window_,
+                          internal::kShellWindowId_OverlayContainer));
+
+  RootWindowController* controller = GetRootWindowController(root_window_);
+  controller->set_touch_observer_hud(this);
+
+  root_window_->AddPreTargetHandler(this);
 }
 
 }  // namespace internal
diff --git a/ash/touch/touch_observer_hud.h b/ash/touch/touch_observer_hud.h
index 9851cac..d1c65eb 100644
--- a/ash/touch/touch_observer_hud.h
+++ b/ash/touch/touch_observer_hud.h
@@ -5,16 +5,30 @@
 #ifndef ASH_TOUCH_TOUCH_OBSERVER_HUD_H_
 #define ASH_TOUCH_TOUCH_OBSERVER_HUD_H_
 
+#include <map>
+
 #include "ash/ash_export.h"
+#include "ash/display/display_controller.h"
 #include "ash/shell.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/values.h"
 #include "ui/base/events/event_handler.h"
+#include "ui/gfx/display_observer.h"
 #include "ui/gfx/point.h"
 #include "ui/views/widget/widget_observer.h"
 
+#if defined(OS_CHROMEOS)
+#include "chromeos/display/output_configurator.h"
+#endif  // defined(OS_CHROMEOS)
+
 namespace aura {
 class Window;
 }
 
+namespace gfx {
+class Display;
+}
+
 namespace views {
 class Label;
 class View;
@@ -25,13 +39,32 @@
 namespace internal {
 
 class TouchHudCanvas;
+class TouchLog;
+class TouchPointView;
 
-// An event filter which handles system level gesture events.
-class ASH_EXPORT TouchObserverHUD : public ui::EventHandler,
-                                    public views::WidgetObserver {
+// An event filter which handles system level gesture events. Objects of this
+// class manage their own lifetime.
+class ASH_EXPORT TouchObserverHUD
+    : public ui::EventHandler,
+      public views::WidgetObserver,
+      public gfx::DisplayObserver,
+#if defined(OS_CHROMEOS)
+      public chromeos::OutputConfigurator::Observer,
+#endif  // defined(OS_CHROMEOS)
+      public DisplayController::Observer {
  public:
-  TouchObserverHUD();
-  virtual ~TouchObserverHUD();
+  enum Mode {
+    FULLSCREEN,
+    REDUCED_SCALE,
+    PROJECTION,
+    INVISIBLE,
+  };
+
+  explicit TouchObserverHUD(aura::RootWindow* initial_root);
+
+  // Returns the log of touch events as a dictionary mapping id of each display
+  // to its touch log.
+  static scoped_ptr<DictionaryValue> GetAllAsDictionary();
 
   // Changes the display mode (e.g. scale, visibility). Calling this repeatedly
   // cycles between a fixed number of display modes.
@@ -41,9 +74,19 @@
   // visible).
   void Clear();
 
-  std::string GetLogAsString() const;
+  // Returns log of touch events as a list value. Each item in the list is a
+  // trace of one touch point.
+  scoped_ptr<ListValue> GetLogAsList() const;
+
+  Mode mode() const { return mode_; }
 
  private:
+  friend class TouchHudTest;
+
+  virtual ~TouchObserverHUD();
+
+  void SetMode(Mode mode);
+
   void UpdateTouchPointLabel(int index);
 
   // Overriden from ui::EventHandler:
@@ -52,15 +95,34 @@
   // Overridden from views::WidgetObserver:
   virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE;
 
+  // Overridden from gfx::DisplayObserver:
+  virtual void OnDisplayBoundsChanged(const gfx::Display& display) OVERRIDE;
+  virtual void OnDisplayAdded(const gfx::Display& new_display) OVERRIDE;
+  virtual void OnDisplayRemoved(const gfx::Display& old_display) OVERRIDE;
+
+#if defined(OS_CHROMEOS)
+  // Overriden from chromeos::OutputConfigurator::Observer:
+  virtual void OnDisplayModeChanged() OVERRIDE;
+#endif  // defined(OS_CHROMEOS)
+
+  // Overriden form DisplayController::Observer:
+  virtual void OnDisplayConfigurationChanging() OVERRIDE;
+  virtual void OnDisplayConfigurationChanged() OVERRIDE;
+
   static const int kMaxTouchPoints = 32;
 
+  const int64 display_id_;
+  aura::RootWindow* root_window_;
+
+  Mode mode_;
+
+  scoped_ptr<TouchLog> touch_log_;
+
   views::Widget* widget_;
   TouchHudCanvas* canvas_;
+  std::map<int, TouchPointView*> points_;
   views::View* label_container_;
   views::Label* touch_labels_[kMaxTouchPoints];
-  gfx::Point touch_positions_[kMaxTouchPoints];
-  float touch_radius_[kMaxTouchPoints];
-  ui::EventType touch_status_[kMaxTouchPoints];
 
   DISALLOW_COPY_AND_ASSIGN(TouchObserverHUD);
 };
diff --git a/ash/touch/touch_observer_hud_unittest.cc b/ash/touch/touch_observer_hud_unittest.cc
new file mode 100644
index 0000000..2e86990
--- /dev/null
+++ b/ash/touch/touch_observer_hud_unittest.cc
@@ -0,0 +1,395 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/touch/touch_observer_hud.h"
+
+#include "ash/ash_switches.h"
+#include "ash/display/display_manager.h"
+#include "ash/root_window_controller.h"
+#include "ash/test/ash_test_base.h"
+#include "ash/test/display_manager_test_api.h"
+#include "ash/wm/property_util.h"
+#include "base/command_line.h"
+#include "base/format_macros.h"
+#include "base/stringprintf.h"
+
+namespace ash {
+namespace internal {
+
+class TouchHudTest : public test::AshTestBase {
+ public:
+  TouchHudTest() {}
+  virtual ~TouchHudTest() {}
+
+  virtual void SetUp() OVERRIDE {
+    // Add ash-touch-hud flag to enable touch HUD. This flag should be set
+    // before Ash environment is set up, i.e., before
+    // test::AshTestBase::SetUp().
+    CommandLine::ForCurrentProcess()->AppendSwitch(
+        ash::switches::kAshTouchHud);
+
+    test::AshTestBase::SetUp();
+
+    // Initialize display infos. They should be initialized after Ash
+    // environment is set up, i.e., after test::AshTestBase::SetUp().
+    internal_display_id_ = test::DisplayManagerTestApi(GetDisplayManager()).
+        SetFirstDisplayAsInternalDisplay();
+    external_display_id_ = 10;
+    mirrored_display_id_ = 11;
+
+    internal_display_info_ =
+        CreateDisplayInfo(internal_display_id_, gfx::Rect(0, 0, 500, 500));
+    external_display_info_ =
+        CreateDisplayInfo(external_display_id_, gfx::Rect(1, 1, 100, 100));
+    mirrored_display_info_ =
+        CreateDisplayInfo(mirrored_display_id_, gfx::Rect(0, 0, 100, 100));
+  }
+
+  const gfx::Display& GetPrimaryDisplay() {
+    return GetDisplayController()->GetPrimaryDisplay();
+  }
+
+  const gfx::Display& GetSecondaryDisplay() {
+    return *GetDisplayController()->GetSecondaryDisplay();
+  }
+
+  void SetupSingleDisplay() {
+    display_info_list_.clear();
+    display_info_list_.push_back(internal_display_info_);
+    GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
+  }
+
+  void SetupDualDisplays() {
+    display_info_list_.clear();
+    display_info_list_.push_back(internal_display_info_);
+    display_info_list_.push_back(external_display_info_);
+    GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
+  }
+
+  void SetInternalAsPrimary() {
+    const gfx::Display& internal_display =
+        GetDisplayManager()->GetDisplayForId(internal_display_id_);
+    GetDisplayController()->SetPrimaryDisplay(internal_display);
+  }
+
+  void SetExternalAsPrimary() {
+    const gfx::Display& external_display =
+        GetDisplayManager()->GetDisplayForId(external_display_id_);
+    GetDisplayController()->SetPrimaryDisplay(external_display);
+  }
+
+  void MirrorDisplays() {
+    DCHECK_EQ(2U, display_info_list_.size());
+    DCHECK_EQ(internal_display_id_, display_info_list_[0].id());
+    DCHECK_EQ(external_display_id_, display_info_list_[1].id());
+    display_info_list_[1] = mirrored_display_info_;
+    GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
+  }
+
+  void UnmirrorDisplays() {
+    DCHECK_EQ(2U, display_info_list_.size());
+    DCHECK_EQ(internal_display_id_, display_info_list_[0].id());
+    DCHECK_EQ(mirrored_display_id_, display_info_list_[1].id());
+    display_info_list_[1] = external_display_info_;
+    GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
+  }
+
+  void RemoveInternalDisplay() {
+    DCHECK_LT(0U, display_info_list_.size());
+    DCHECK_EQ(internal_display_id_, display_info_list_[0].id());
+    display_info_list_.erase(display_info_list_.begin());
+    GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
+  }
+
+  void RemoveExternalDisplay() {
+    DCHECK_EQ(2U, display_info_list_.size());
+    display_info_list_.pop_back();
+    GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
+  }
+
+  void AddInternalDisplay() {
+    DCHECK_EQ(0U, display_info_list_.size());
+    display_info_list_.push_back(internal_display_info_);
+    GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
+  }
+
+  void AddExternalDisplay() {
+    DCHECK_EQ(1U, display_info_list_.size());
+    display_info_list_.push_back(external_display_info_);
+    GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
+  }
+
+  int64 internal_display_id() const {
+    return internal_display_id_;
+  }
+
+  int64 external_display_id() const {
+    return external_display_id_;
+  }
+
+  void CheckInternalDisplay() {
+    EXPECT_NE(static_cast<internal::TouchObserverHUD*>(NULL),
+              GetInternalTouchHud());
+    EXPECT_EQ(internal_display_id(), GetInternalTouchHud()->display_id_);
+    EXPECT_EQ(GetInternalRootWindow(), GetInternalTouchHud()->root_window_);
+    EXPECT_EQ(GetInternalRootWindow(),
+              GetInternalTouchHud()->widget_->GetNativeView()->GetRootWindow());
+    EXPECT_EQ(GetInternalDisplay().size(),
+              GetInternalTouchHud()->widget_->GetWindowBoundsInScreen().size());
+  }
+
+  void CheckExternalDisplay() {
+    EXPECT_NE(static_cast<internal::TouchObserverHUD*>(NULL),
+              GetExternalTouchHud());
+    EXPECT_EQ(external_display_id(), GetExternalTouchHud()->display_id_);
+    EXPECT_EQ(GetExternalRootWindow(), GetExternalTouchHud()->root_window_);
+    EXPECT_EQ(GetExternalRootWindow(),
+              GetExternalTouchHud()->widget_->GetNativeView()->GetRootWindow());
+    EXPECT_EQ(GetExternalDisplay().size(),
+              GetExternalTouchHud()->widget_->GetWindowBoundsInScreen().size());
+  }
+
+ private:
+  DisplayManager* GetDisplayManager() {
+    return Shell::GetInstance()->display_manager();
+  }
+
+  DisplayController* GetDisplayController() {
+    return Shell::GetInstance()->display_controller();
+  }
+
+  const gfx::Display& GetInternalDisplay() {
+    return GetDisplayManager()->GetDisplayForId(internal_display_id_);
+  }
+
+  const gfx::Display& GetExternalDisplay() {
+    return GetDisplayManager()->GetDisplayForId(external_display_id_);
+  }
+
+  aura::RootWindow* GetInternalRootWindow() {
+    return GetDisplayController()->GetRootWindowForDisplayId(
+        internal_display_id_);
+  }
+
+  aura::RootWindow* GetExternalRootWindow() {
+    return GetDisplayController()->GetRootWindowForDisplayId(
+        external_display_id_);
+  }
+
+  aura::RootWindow* GetPrimaryRootWindow() {
+    const gfx::Display& display = GetPrimaryDisplay();
+    return GetDisplayController()->GetRootWindowForDisplayId(display.id());
+  }
+
+  aura::RootWindow* GetSecondaryRootWindow() {
+    const gfx::Display& display = GetSecondaryDisplay();
+    return GetDisplayController()->GetRootWindowForDisplayId(display.id());
+  }
+
+  internal::RootWindowController* GetInternalRootController() {
+    aura::RootWindow* root = GetInternalRootWindow();
+    return GetRootWindowController(root);
+  }
+
+  internal::RootWindowController* GetExternalRootController() {
+    aura::RootWindow* root = GetExternalRootWindow();
+    return GetRootWindowController(root);
+  }
+
+  internal::RootWindowController* GetPrimaryRootController() {
+    aura::RootWindow* root = GetPrimaryRootWindow();
+    return GetRootWindowController(root);
+  }
+
+  internal::RootWindowController* GetSecondaryRootController() {
+    aura::RootWindow* root = GetSecondaryRootWindow();
+    return GetRootWindowController(root);
+  }
+
+  internal::TouchObserverHUD* GetInternalTouchHud() {
+    return GetInternalRootController()->touch_observer_hud();
+  }
+
+  internal::TouchObserverHUD* GetExternalTouchHud() {
+    return GetExternalRootController()->touch_observer_hud();
+  }
+
+  internal::TouchObserverHUD* GetPrimaryTouchHud() {
+    return GetPrimaryRootController()->touch_observer_hud();
+  }
+
+  internal::TouchObserverHUD* GetSecondaryTouchHud() {
+    return GetSecondaryRootController()->touch_observer_hud();
+  }
+
+  DisplayInfo CreateDisplayInfo(int64 id, const gfx::Rect& bounds) {
+    DisplayInfo info(id, base::StringPrintf("x-%"PRId64, id), false);
+    info.SetBounds(bounds);
+    return info;
+  }
+
+  int64 internal_display_id_;
+  int64 external_display_id_;
+  int64 mirrored_display_id_;
+  DisplayInfo internal_display_info_;
+  DisplayInfo external_display_info_;
+  DisplayInfo mirrored_display_info_;
+
+  std::vector<DisplayInfo> display_info_list_;
+
+  DISALLOW_COPY_AND_ASSIGN(TouchHudTest);
+};
+
+// Checks if touch HUDs are correctly initialized for displays.
+TEST_F(TouchHudTest, Basic) {
+  // Setup a dual display setting.
+  SetupDualDisplays();
+
+  // Check if touch HUDs are set correctly and associated with appropriate
+  // displays.
+  CheckInternalDisplay();
+  CheckExternalDisplay();
+}
+
+// Checks if touch HUDs are correctly handled when primary display is changed.
+TEST_F(TouchHudTest, SwapPrimaryDisplay) {
+  // Setup a dual display setting.
+  SetupDualDisplays();
+
+  // Set the primary display to the external one.
+  SetExternalAsPrimary();
+
+  // Check if displays' touch HUDs are not swapped as root windows are.
+  EXPECT_EQ(external_display_id(), GetPrimaryDisplay().id());
+  EXPECT_EQ(internal_display_id(), GetSecondaryDisplay().id());
+  CheckInternalDisplay();
+  CheckExternalDisplay();
+
+  // Set the primary display back to the internal one.
+  SetInternalAsPrimary();
+
+  // Check if displays' touch HUDs are not swapped back as root windows are.
+  EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
+  EXPECT_EQ(external_display_id(), GetSecondaryDisplay().id());
+  CheckInternalDisplay();
+  CheckExternalDisplay();
+}
+
+// Checks if touch HUDs are correctly handled when displays are mirrored.
+TEST_F(TouchHudTest, MirrorDisplays) {
+  // Setup a dual display setting.
+  SetupDualDisplays();
+
+  // Mirror displays.
+  MirrorDisplays();
+
+  // Check if the internal display is intact.
+  EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
+  CheckInternalDisplay();
+
+  // Unmirror displays.
+  UnmirrorDisplays();
+
+  // Check if external display is added back correctly.
+  EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
+  EXPECT_EQ(external_display_id(), GetSecondaryDisplay().id());
+  CheckInternalDisplay();
+  CheckExternalDisplay();
+}
+
+// Checks if touch HUDs are correctly handled when displays are mirrored after
+// setting the external display as the primary one.
+TEST_F(TouchHudTest, SwapPrimaryThenMirrorDisplays) {
+  // Setup a dual display setting.
+  SetupDualDisplays();
+
+  // Set the primary display to the external one.
+  SetExternalAsPrimary();
+
+  // Mirror displays.
+  MirrorDisplays();
+
+  // Check if the internal display is set as the primary one.
+  EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
+  CheckInternalDisplay();
+
+  // Unmirror displays.
+  UnmirrorDisplays();
+
+  // Check if the external display is added back as the primary display and
+  // touch HUDs are set correctly.
+  EXPECT_EQ(external_display_id(), GetPrimaryDisplay().id());
+  EXPECT_EQ(internal_display_id(), GetSecondaryDisplay().id());
+  CheckInternalDisplay();
+  CheckExternalDisplay();
+}
+
+// Checks if touch HUDs are correctly handled when the external display, which
+// is the secondary one, is removed.
+TEST_F(TouchHudTest, RemoveSecondaryDisplay) {
+  // Setup a dual display setting.
+  SetupDualDisplays();
+
+  // Remove external display which is the secondary one.
+  RemoveExternalDisplay();
+
+  // Check if the internal display is intact.
+  EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
+  CheckInternalDisplay();
+
+  // Add external display back.
+  AddExternalDisplay();
+
+  // Check if displays' touch HUDs are set correctly.
+  EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
+  EXPECT_EQ(external_display_id(), GetSecondaryDisplay().id());
+  CheckInternalDisplay();
+  CheckExternalDisplay();
+}
+
+// Checks if touch HUDs are correctly handled when the external display, which
+// is set as the primary display, is removed.
+TEST_F(TouchHudTest, RemovePrimaryDisplay) {
+  // Setup a dual display setting.
+  SetupDualDisplays();
+
+  // Set the primary display to the external one.
+  SetExternalAsPrimary();
+
+  // Remove the external display which is the primary display.
+  RemoveExternalDisplay();
+
+  // Check if the internal display is set as the primary one.
+  EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
+  CheckInternalDisplay();
+
+  // Add the external display back.
+  AddExternalDisplay();
+
+  // Check if the external display is set as primary and touch HUDs are set
+  // correctly.
+  EXPECT_EQ(external_display_id(), GetPrimaryDisplay().id());
+  EXPECT_EQ(internal_display_id(), GetSecondaryDisplay().id());
+  CheckInternalDisplay();
+  CheckExternalDisplay();
+}
+
+// Checks if touch HUDs are correctly handled when all displays are removed.
+TEST_F(TouchHudTest, Headless) {
+  // Setup a single display setting.
+  SetupSingleDisplay();
+
+  // Remove the only display which is the internal one.
+  RemoveInternalDisplay();
+
+  // Add the internal display back.
+  AddInternalDisplay();
+
+  // Check if the display's touch HUD is set correctly.
+  EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
+  CheckInternalDisplay();
+}
+
+}  // namespace internal
+}  // namespace ash
diff --git a/ash/touch/touch_uma.cc b/ash/touch/touch_uma.cc
index 0853241..8279bf6 100644
--- a/ash/touch/touch_uma.cc
+++ b/ash/touch/touch_uma.cc
@@ -306,8 +306,10 @@
   // Record the location of the touch points.
   const int kBucketCountForLocation = 100;
   const gfx::Rect bounds = target->GetRootWindow()->bounds();
-  const int bucket_size_x = bounds.width() / kBucketCountForLocation;
-  const int bucket_size_y = bounds.height() / kBucketCountForLocation;
+  const int bucket_size_x = std::max(1,
+                                     bounds.width() / kBucketCountForLocation);
+  const int bucket_size_y = std::max(1,
+                                     bounds.height() / kBucketCountForLocation);
 
   gfx::Point position = event.root_location();
 
diff --git a/ash/wm/activation_controller.cc b/ash/wm/activation_controller.cc
index 196043a..8c48346 100644
--- a/ash/wm/activation_controller.cc
+++ b/ash/wm/activation_controller.cc
@@ -149,7 +149,7 @@
     : focus_client_(focus_client),
       updating_activation_(false),
       active_window_(NULL),
-      ALLOW_THIS_IN_INITIALIZER_LIST(observer_manager_(this)),
+      observer_manager_(this),
       delegate_(delegate) {
   aura::Env::GetInstance()->AddObserver(this);
   focus_client_->AddObserver(this);
diff --git a/ash/wm/activation_controller_unittest.cc b/ash/wm/activation_controller_unittest.cc
index 14fc4f5..33f6a07 100644
--- a/ash/wm/activation_controller_unittest.cc
+++ b/ash/wm/activation_controller_unittest.cc
@@ -411,7 +411,7 @@
       &wd, -51, gfx::Rect(50, 50)));
   w5->AddTransientChild(w51.get());
   w51->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_SYSTEM);
-  EXPECT_TRUE(wm::CanActivateWindow(w5.get()));
+  EXPECT_FALSE(wm::CanActivateWindow(w5.get()));
   EXPECT_TRUE(wm::CanActivateWindow(w51.get()));
 }
 
diff --git a/ash/wm/app_list_controller.cc b/ash/wm/app_list_controller.cc
index 37aff49..7fcf76c 100644
--- a/ash/wm/app_list_controller.cc
+++ b/ash/wm/app_list_controller.cc
@@ -42,8 +42,7 @@
 }
 
 // Gets arrow location based on shelf alignment.
-views::BubbleBorder::ArrowLocation GetBubbleArrowLocation(
-    aura::Window* window) {
+views::BubbleBorder::Arrow GetBubbleArrow(aura::Window* window) {
   DCHECK(Shell::HasInstance());
   return ShelfLayoutManager::ForLauncher(window)->
       SelectValueForShelfAlignment(
@@ -126,7 +125,7 @@
         pagination_model_.get(),
         Launcher::ForWindow(container)->GetAppListButtonView(),
         gfx::Point(),
-        GetBubbleArrowLocation(container),
+        GetBubbleArrow(container),
         true /* border_accepts_events */);
     SetView(view);
   }
@@ -288,10 +287,8 @@
 ////////////////////////////////////////////////////////////////////////////////
 // AppListController, ShellObserver implementation:
 void AppListController::OnShelfAlignmentChanged(aura::RootWindow* root_window) {
-  if (view_) {
-    view_->SetBubbleArrowLocation(GetBubbleArrowLocation(
-        view_->GetWidget()->GetNativeView()));
-  }
+  if (view_)
+    view_->SetBubbleArrow(GetBubbleArrow(view_->GetWidget()->GetNativeView()));
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/ash/wm/ash_native_cursor_manager.cc b/ash/wm/ash_native_cursor_manager.cc
index 885f95b..dd72af1 100644
--- a/ash/wm/ash_native_cursor_manager.cc
+++ b/ash/wm/ash_native_cursor_manager.cc
@@ -13,10 +13,6 @@
 
 namespace  {
 
-// The coordinate of the cursor used when the mouse events are disabled.
-const int kDisabledCursorLocationX = -10000;
-const int kDisabledCursorLocationY = -10000;
-
 void SetCursorOnAllRootWindows(gfx::NativeCursor cursor) {
   ash::Shell::RootWindowList root_windows =
       ash::Shell::GetInstance()->GetAllRootWindows();
@@ -99,8 +95,6 @@
         disabled_cursor_location_);
   } else {
     disabled_cursor_location_ = aura::Env::GetInstance()->last_mouse_location();
-    aura::Env::GetInstance()->set_last_mouse_location(
-        gfx::Point(kDisabledCursorLocationX, kDisabledCursorLocationY));
   }
 
   SetVisibility(delegate->GetCurrentVisibility(), delegate);
@@ -108,7 +102,7 @@
 }
 
 void AshNativeCursorManager::SetCursorResourceModule(
-    const string16& module_name) {
+    const base::string16& module_name) {
   image_cursors_->SetCursorResourceModule(module_name);
 }
 
diff --git a/ash/wm/ash_native_cursor_manager.h b/ash/wm/ash_native_cursor_manager.h
index 506d381..5df8062 100644
--- a/ash/wm/ash_native_cursor_manager.h
+++ b/ash/wm/ash_native_cursor_manager.h
@@ -49,7 +49,8 @@
   virtual void SetMouseEventsEnabled(
       bool enabled,
       views::corewm::NativeCursorManagerDelegate* delegate) OVERRIDE;
-  virtual void SetCursorResourceModule(const string16& module_name) OVERRIDE;
+  virtual void SetCursorResourceModule(
+      const base::string16& module_name) OVERRIDE;
 
   // The cursor location where the cursor was disabled.
   gfx::Point disabled_cursor_location_;
diff --git a/ash/wm/ash_native_cursor_manager_unittest.cc b/ash/wm/ash_native_cursor_manager_unittest.cc
index e907b4c..c8f6b8e 100644
--- a/ash/wm/ash_native_cursor_manager_unittest.cc
+++ b/ash/wm/ash_native_cursor_manager_unittest.cc
@@ -118,16 +118,11 @@
   EXPECT_EQ(gfx::Display::ROTATE_270, test_api.GetDisplay().rotation());
 }
 
-#if defined(OS_WIN)
-// Temporarily disabled for windows. See crbug.com/112222.
-#define MAYBE_DisabledMouseEventsLocation DISABLED_DisabledMouseEventsLocation
-#else
-#define MAYBE_DisabledMouseEventsLocation DisabledMouseEventsLocation
-#endif  // defined(OS_WIN)
-
+// Disabled for Windows. See crbug.com/112222.
+// Disabled for ChromeOS. See crbug.com/237659
 // Verifies that RootWindow generates a mouse event located outside of a window
 // when mouse events are disabled.
-TEST_F(AshNativeCursorManagerTest, MAYBE_DisabledMouseEventsLocation) {
+TEST_F(AshNativeCursorManagerTest, DISABLED_DisabledMouseEventsLocation) {
   scoped_ptr<MouseEventLocationDelegate> delegate(
       new MouseEventLocationDelegate());
   const int kWindowWidth = 123;
diff --git a/ash/wm/capture_controller.cc b/ash/wm/capture_controller.cc
index 7a91d2f..4e17054 100644
--- a/ash/wm/capture_controller.cc
+++ b/ash/wm/capture_controller.cc
@@ -32,13 +32,21 @@
   DCHECK(!capture_window_ || capture_window_->GetRootWindow());
 
   aura::Window* old_capture_window = capture_window_;
-
   Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
-  for (Shell::RootWindowList::iterator iter = root_windows.begin();
-       iter != root_windows.end(); ++iter) {
-    aura::RootWindow* root_window = *iter;
-    root_window->gesture_recognizer()->
-        TransferEventsTo(old_capture_window, new_capture_window);
+
+  // If we're actually starting capture, then cancel any touches/gestures
+  // that aren't already locked to the new window, and transfer any on the
+  // old capture window to the new one.  When capture is released we have no
+  // distinction between the touches/gestures that were in the window all
+  // along (and so shouldn't be canceled) and those that got moved, so
+  // just leave them all where they are.
+  if (new_capture_window) {
+    for (Shell::RootWindowList::iterator iter = root_windows.begin();
+         iter != root_windows.end(); ++iter) {
+      aura::RootWindow* root_window = *iter;
+      root_window->gesture_recognizer()->
+          TransferEventsTo(old_capture_window, new_capture_window);
+    }
   }
 
   capture_window_ = new_capture_window;
diff --git a/ash/wm/custom_frame_view_ash.cc b/ash/wm/custom_frame_view_ash.cc
index 6350e9a..72c62ee 100644
--- a/ash/wm/custom_frame_view_ash.cc
+++ b/ash/wm/custom_frame_view_ash.cc
@@ -4,6 +4,7 @@
 
 #include "ash/wm/custom_frame_view_ash.h"
 
+#include "ash/shell_delegate.h"
 #include "ash/wm/frame_painter.h"
 #include "ash/wm/workspace/frame_maximize_button.h"
 #include "grit/ash_resources.h"
@@ -170,17 +171,28 @@
     slow_duration_mode.reset(new ui::ScopedAnimationDurationScaleMode(
         ui::ScopedAnimationDurationScaleMode::SLOW_DURATION));
   }
+
+  ash::UserMetricsAction action =
+      ash::UMA_WINDOW_MAXIMIZE_BUTTON_CLICK_MAXIMIZE;
+
   if (sender == maximize_button_) {
     // The maximize button may move out from under the cursor.
     ResetWindowControls();
-    if (frame_->IsMaximized())
+    if (frame_->IsMaximized()) {
+      action = ash::UMA_WINDOW_MAXIMIZE_BUTTON_CLICK_RESTORE;
       frame_->Restore();
-    else
+    } else {
       frame_->Maximize();
+    }
     // |this| may be deleted - some windows delete their frames on maximize.
   } else if (sender == close_button_) {
+    action = ash::UMA_WINDOW_CLOSE_BUTTON_CLICK;
     frame_->Close();
+  } else {
+    return;
   }
+
+  ash::Shell::GetInstance()->delegate()->RecordUserMetricsAction(action);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/ash/wm/custom_frame_view_ash_unittest.cc b/ash/wm/custom_frame_view_ash_unittest.cc
index 721c959..5d12b11 100644
--- a/ash/wm/custom_frame_view_ash_unittest.cc
+++ b/ash/wm/custom_frame_view_ash_unittest.cc
@@ -29,6 +29,37 @@
 
 namespace {
 
+
+class CancelCallbackHandler {
+ public:
+  CancelCallbackHandler(int update_events_before_cancel,
+                        FrameMaximizeButton* maximize_button) :
+      update_events_before_cancel_(update_events_before_cancel),
+      maximize_button_(maximize_button) {}
+  virtual ~CancelCallbackHandler() {}
+
+  void CountedCancelCallback(ui::EventType event_type,
+                             const gfx::Vector2dF& pos) {
+    if (event_type == ui::ET_GESTURE_SCROLL_UPDATE &&
+        !(--update_events_before_cancel_)) {
+      // Make sure that we are in the middle of a resizing operation, cancel it
+      // and then test that it is exited.
+      EXPECT_TRUE(maximize_button_->is_snap_enabled());
+      maximize_button_->DestroyMaximizeMenu();
+      EXPECT_FALSE(maximize_button_->is_snap_enabled());
+    }
+  }
+
+ private:
+  // When this counter reaches 0, the gesture maximize action gets cancelled.
+  int update_events_before_cancel_;
+
+  // The maximize button which needs to get informed of the gesture termination.
+  FrameMaximizeButton* maximize_button_;
+
+  DISALLOW_COPY_AND_ASSIGN(CancelCallbackHandler);
+};
+
 class ShellViewsDelegate : public views::TestViewsDelegate {
  public:
   ShellViewsDelegate() {}
@@ -85,7 +116,7 @@
     return widget;
   }
 
-  CustomFrameViewAsh* custom_frame_view_ash(views::Widget* widget) const {
+  CustomFrameViewAsh* GetCustomFrameViewAsh(views::Widget* widget) const {
     return static_cast<CustomFrameViewAsh*>(widget->non_client_view()->
         frame_view());
   }
@@ -99,7 +130,7 @@
   }
 
   virtual void TearDown() OVERRIDE {
-    if (views_delegate_.get()) {
+    if (views_delegate_) {
       views::ViewsDelegate::views_delegate = NULL;
       views_delegate_.reset();
     }
@@ -117,7 +148,7 @@
 TEST_F(CustomFrameViewAshTest, ResizeButtonToggleMaximize) {
   views::Widget* widget = CreateWidget();
   aura::Window* window = widget->GetNativeWindow();
-  CustomFrameViewAsh* frame = custom_frame_view_ash(widget);
+  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
   CustomFrameViewAsh::TestApi test(frame);
   views::View* view = test.maximize_button();
   gfx::Point center = view->GetBoundsInScreen().CenterPoint();
@@ -162,7 +193,7 @@
 TEST_F(CustomFrameViewAshTest, MAYBE_ResizeButtonDrag) {
   views::Widget* widget = CreateWidget();
   aura::Window* window = widget->GetNativeWindow();
-  CustomFrameViewAsh* frame = custom_frame_view_ash(widget);
+  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
   CustomFrameViewAsh::TestApi test(frame);
   views::View* view = test.maximize_button();
   gfx::Point center = view->GetBoundsInScreen().CenterPoint();
@@ -287,7 +318,7 @@
        MAYBE_TouchDragResizeCloseToCornerDiffersFromMouse) {
   views::Widget* widget = CreateWidget();
   aura::Window* window = widget->GetNativeWindow();
-  CustomFrameViewAsh* frame = custom_frame_view_ash(widget);
+  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
   CustomFrameViewAsh::TestApi test(frame);
   views::View* view = test.maximize_button();
 
@@ -343,7 +374,7 @@
 TEST_F(CustomFrameViewAshTest, MaximizeButtonExternalShutDown) {
   views::Widget* widget = CreateWidget();
   aura::Window* window = widget->GetNativeWindow();
-  CustomFrameViewAsh* frame = custom_frame_view_ash(widget);
+  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
   CustomFrameViewAsh::TestApi test(frame);
   ash::FrameMaximizeButton* maximize_button = test.maximize_button();
   maximize_button->set_bubble_appearance_delay_ms(0);
@@ -368,7 +399,7 @@
 TEST_F(CustomFrameViewAshTest, MaximizeOnHoverThenClick) {
   views::Widget* widget = CreateWidget();
   aura::Window* window = widget->GetNativeWindow();
-  CustomFrameViewAsh* frame = custom_frame_view_ash(widget);
+  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
   CustomFrameViewAsh::TestApi test(frame);
   ash::FrameMaximizeButton* maximize_button = test.maximize_button();
   maximize_button->set_bubble_appearance_delay_ms(0);
@@ -393,7 +424,7 @@
 TEST_F(CustomFrameViewAshTest, MaximizeLeftButtonDragOut) {
   views::Widget* widget = CreateWidget();
   aura::Window* window = widget->GetNativeWindow();
-  CustomFrameViewAsh* frame = custom_frame_view_ash(widget);
+  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
   CustomFrameViewAsh::TestApi test(frame);
   ash::FrameMaximizeButton* maximize_button = test.maximize_button();
   maximize_button->set_bubble_appearance_delay_ms(0);
@@ -440,7 +471,7 @@
 TEST_F(CustomFrameViewAshTest, MaximizeLeftByButton) {
   views::Widget* widget = CreateWidget();
   aura::Window* window = widget->GetNativeWindow();
-  CustomFrameViewAsh* frame = custom_frame_view_ash(widget);
+  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
   CustomFrameViewAsh::TestApi test(frame);
   ash::FrameMaximizeButton* maximize_button = test.maximize_button();
   maximize_button->set_bubble_appearance_delay_ms(0);
@@ -479,7 +510,7 @@
 TEST_F(CustomFrameViewAshTest, MaximizeKeepFocus) {
   views::Widget* widget = CreateWidget();
   aura::Window* window = widget->GetNativeWindow();
-  CustomFrameViewAsh* frame = custom_frame_view_ash(widget);
+  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
   CustomFrameViewAsh::TestApi test(frame);
   ash::FrameMaximizeButton* maximize_button = test.maximize_button();
   maximize_button->set_bubble_appearance_delay_ms(0);
@@ -505,7 +536,7 @@
   views::Widget* widget = CreateWidget();
   aura::Window* window = widget->GetNativeWindow();
   aura::RootWindow* root_window = window->GetRootWindow();
-  CustomFrameViewAsh* frame = custom_frame_view_ash(widget);
+  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
   CustomFrameViewAsh::TestApi test(frame);
   ash::FrameMaximizeButton* maximize_button = test.maximize_button();
   gfx::Point button_pos = maximize_button->GetBoundsInScreen().CenterPoint();
@@ -536,7 +567,7 @@
 TEST_F(CustomFrameViewAshTest, OnlyLeftButtonMaximizes) {
   views::Widget* widget = CreateWidget();
   aura::Window* window = widget->GetNativeWindow();
-  CustomFrameViewAsh* frame = custom_frame_view_ash(widget);
+  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
   CustomFrameViewAsh::TestApi test(frame);
   ash::FrameMaximizeButton* maximize_button = test.maximize_button();
   maximize_button->set_bubble_appearance_delay_ms(0);
@@ -628,7 +659,7 @@
   aura::Window* window = widget->GetNativeWindow();
   widget->SetBounds(gfx::Rect(10, 10, 100, 100));
   gfx::Rect initial_bounds = widget->GetWindowBoundsInScreen();
-  CustomFrameViewAsh* frame = custom_frame_view_ash(widget);
+  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
   CustomFrameViewAsh::TestApi test(frame);
   ash::FrameMaximizeButton* maximize_button = test.maximize_button();
   maximize_button->set_bubble_appearance_delay_ms(0);
@@ -659,7 +690,7 @@
   aura::Window* window = widget->GetNativeWindow();
   widget->SetBounds(gfx::Rect(10, 10, 100, 100));
   gfx::Rect initial_bounds = widget->GetWindowBoundsInScreen();
-  CustomFrameViewAsh* frame = custom_frame_view_ash(widget);
+  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
   CustomFrameViewAsh::TestApi test(frame);
   ash::FrameMaximizeButton* maximize_button = test.maximize_button();
   maximize_button->set_bubble_appearance_delay_ms(0);
@@ -692,7 +723,7 @@
   aura::Window* window = widget->GetNativeWindow();
   widget->SetBounds(gfx::Rect(10, 10, 100, 100));
   gfx::Rect initial_bounds = widget->GetWindowBoundsInScreen();
-  CustomFrameViewAsh* frame = custom_frame_view_ash(widget);
+  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
   CustomFrameViewAsh::TestApi test(frame);
   ash::FrameMaximizeButton* maximize_button = test.maximize_button();
   maximize_button->set_bubble_appearance_delay_ms(0);
@@ -714,12 +745,40 @@
   EXPECT_EQ(NULL, GetRestoreBoundsInScreen(window));
 }
 
+// Starting with a window which has no restore bounds, maximize then left/right
+// maximize should not be centered but left/right maximized.
+TEST_F(CustomFrameViewAshTest, MaximizeThenLeftMaximize) {
+  views::Widget* widget = CreateWidget();
+  aura::Window* window = widget->GetNativeWindow();
+  widget->SetBounds(gfx::Rect(10, 10, 100, 100));
+  gfx::Rect initial_bounds = widget->GetWindowBoundsInScreen();
+  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
+  CustomFrameViewAsh::TestApi test(frame);
+  ash::FrameMaximizeButton* maximize_button = test.maximize_button();
+  maximize_button->set_bubble_appearance_delay_ms(0);
+  // Make sure that there is no restore rectangle.
+  EXPECT_EQ(NULL, GetRestoreBoundsInScreen(window));
+
+  ClickMaxButton(maximize_button, window, SNAP_NONE);
+  EXPECT_TRUE(ash::wm::IsWindowMaximized(window));
+
+  ClickMaxButton(maximize_button, window, SNAP_LEFT);
+  EXPECT_FALSE(ash::wm::IsWindowMaximized(window));
+
+  gfx::Rect new_bounds = widget->GetWindowBoundsInScreen();
+  EXPECT_EQ(new_bounds.x(), 0);
+  EXPECT_EQ(new_bounds.y(), 0);
+  // Make sure that the restore rectangle is the original rectangle.
+  EXPECT_EQ(initial_bounds.ToString(),
+            GetRestoreBoundsInScreen(window)->ToString());
+}
+
 // Test that minimizing the window per keyboard closes the maximize bubble.
 TEST_F(CustomFrameViewAshTest, MinimizePerKeyClosesBubble) {
   views::Widget* widget = CreateWidget();
   aura::Window* window = widget->GetNativeWindow();
   widget->SetBounds(gfx::Rect(10, 10, 100, 100));
-  CustomFrameViewAsh* frame = custom_frame_view_ash(widget);
+  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
   CustomFrameViewAsh::TestApi test(frame);
   ash::FrameMaximizeButton* maximize_button = test.maximize_button();
 
@@ -746,7 +805,7 @@
   views::Widget* widget = CreateWidget();
   aura::Window* window = widget->GetNativeWindow();
   widget->SetBounds(gfx::Rect(10, 10, 100, 100));
-  CustomFrameViewAsh* frame = custom_frame_view_ash(widget);
+  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
   CustomFrameViewAsh::TestApi test(frame);
   FrameMaximizeButton* maximize_button = test.maximize_button();
 
@@ -774,5 +833,36 @@
   EXPECT_FALSE(maximize_button->maximizer());
 }
 
+// Tests that dragging Left and pressing ESC does properly abort.
+TEST_F(CustomFrameViewAshTest, MaximizeButtonDragLeftEscapeExits) {
+  views::Widget* widget = CreateWidget();
+  aura::Window* window = widget->GetNativeWindow();
+  gfx::Rect window_position = gfx::Rect(10, 10, 100, 100);
+  widget->SetBounds(window_position);
+  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
+  CustomFrameViewAsh::TestApi test(frame);
+  FrameMaximizeButton* maximize_button = test.maximize_button();
+
+  gfx::Point button_pos = maximize_button->GetBoundsInScreen().CenterPoint();
+  gfx::Point off_pos(button_pos.x() - button_pos.x() / 2, button_pos.y());
+
+  const int kGestureSteps = 10;
+  CancelCallbackHandler cancel_handler(kGestureSteps / 2, maximize_button);
+  aura::test::EventGenerator generator(window->GetRootWindow());
+  generator.GestureScrollSequenceWithCallback(
+      button_pos,
+      off_pos,
+      base::TimeDelta::FromMilliseconds(0),
+      kGestureSteps,
+      base::Bind(&CancelCallbackHandler::CountedCancelCallback,
+                 base::Unretained(&cancel_handler)));
+
+  // Check that there was no size change.
+  EXPECT_EQ(widget->GetWindowBoundsInScreen().size().ToString(),
+            window_position.size().ToString());
+  // Check that there is no phantom window left open.
+  EXPECT_FALSE(maximize_button->phantom_window_open());
+}
+
 }  // namespace internal
 }  // namespace ash
diff --git a/ash/wm/drag_window_resizer.cc b/ash/wm/drag_window_resizer.cc
index b34e931..d0f9775 100644
--- a/ash/wm/drag_window_resizer.cc
+++ b/ash/wm/drag_window_resizer.cc
@@ -57,19 +57,23 @@
 }
 
 // static
-DragWindowResizer* DragWindowResizer::Create(WindowResizer* window_resizer,
+DragWindowResizer* DragWindowResizer::Create(WindowResizer* next_window_resizer,
                                              aura::Window* window,
                                              const gfx::Point& location,
                                              int window_component) {
   Details details(window, location, window_component);
   return details.is_resizable ?
-      new DragWindowResizer(window_resizer, details) : NULL;
+      new DragWindowResizer(next_window_resizer, details) : NULL;
 }
 
 void DragWindowResizer::Drag(const gfx::Point& location, int event_flags) {
   bool destroyed = false;
   destroyed_ = &destroyed;
-  window_resizer_->Drag(location, event_flags);
+  next_window_resizer_->Drag(location, event_flags);
+
+  // TODO(flackr): Refactor the way WindowResizer calls into other window
+  // resizers to avoid the awkward pattern here for checking if
+  // next_window_resizer_ destroys the resizer object.
   if (destroyed)
     return;
   destroyed_ = NULL;
@@ -88,7 +92,7 @@
 }
 
 void DragWindowResizer::CompleteDrag(int event_flags) {
-  window_resizer_->CompleteDrag(event_flags);
+  next_window_resizer_->CompleteDrag(event_flags);
 
   GetTarget()->layer()->SetOpacity(details_.initial_opacity);
   drag_window_controller_.reset();
@@ -111,19 +115,19 @@
 }
 
 void DragWindowResizer::RevertDrag() {
-  window_resizer_->RevertDrag();
+  next_window_resizer_->RevertDrag();
 
   drag_window_controller_.reset();
   GetTarget()->layer()->SetOpacity(details_.initial_opacity);
 }
 
 aura::Window* DragWindowResizer::GetTarget() {
-  return window_resizer_->GetTarget();
+  return next_window_resizer_->GetTarget();
 }
 
-DragWindowResizer::DragWindowResizer(WindowResizer* window_resizer,
+DragWindowResizer::DragWindowResizer(WindowResizer* next_window_resizer,
                                      const Details& details)
-    : window_resizer_(window_resizer),
+    : next_window_resizer_(next_window_resizer),
       details_(details),
       destroyed_(NULL) {
   // The pointer should be confined in one display during resizing a window
@@ -160,7 +164,7 @@
       static_cast<float>(bounds.width() * bounds.height());
 
   if (fraction_in_another_window > 0) {
-    if (!drag_window_controller_.get()) {
+    if (!drag_window_controller_) {
       drag_window_controller_.reset(
           new DragWindowController(GetTarget()));
       // Always show the drag phantom on the |another_root| window.
@@ -187,7 +191,8 @@
 bool DragWindowResizer::ShouldAllowMouseWarp() {
   return (details_.window_component == HTCAPTION) &&
       !GetTarget()->transient_parent() &&
-      (GetTarget()->type() == aura::client::WINDOW_TYPE_NORMAL);
+      (GetTarget()->type() == aura::client::WINDOW_TYPE_NORMAL ||
+       GetTarget()->type() == aura::client::WINDOW_TYPE_PANEL);
 }
 
 }  // namespace internal
diff --git a/ash/wm/drag_window_resizer.h b/ash/wm/drag_window_resizer.h
index 3705bac..8175882 100644
--- a/ash/wm/drag_window_resizer.h
+++ b/ash/wm/drag_window_resizer.h
@@ -22,9 +22,9 @@
   virtual ~DragWindowResizer();
 
   // Creates a new DragWindowResizer. The caller takes ownership of the
-  // returned object. The ownership of |window_resizer| is taken by the
+  // returned object. The ownership of |next_window_resizer| is taken by the
   // returned object. Returns NULL if not resizable.
-  static DragWindowResizer* Create(WindowResizer* window_resizer,
+  static DragWindowResizer* Create(WindowResizer* next_window_resizer,
                                    aura::Window* window,
                                    const gfx::Point& location,
                                    int window_component);
@@ -43,9 +43,9 @@
   FRIEND_TEST_ALL_PREFIXES(DragWindowResizerTest, DragWindowController);
 
   // Creates DragWindowResizer that adds the ability of dragging windows across
-  // displays to |window_resizer|. This object takes the ownership of
-  // |window_resizer|.
-  explicit DragWindowResizer(WindowResizer* window_resizer,
+  // displays to |next_window_resizer|. This object takes the ownership of
+  // |next_window_resizer|.
+  explicit DragWindowResizer(WindowResizer* next_window_resizer,
                              const Details& details);
 
   // Updates the bounds of the phantom window for window dragging. Set true on
@@ -55,7 +55,7 @@
   // Returns true if we should allow the mouse pointer to warp.
   bool ShouldAllowMouseWarp();
 
-  scoped_ptr<WindowResizer> window_resizer_;
+  scoped_ptr<WindowResizer> next_window_resizer_;
 
   // Shows a semi-transparent image of the window being dragged.
   scoped_ptr<DragWindowController> drag_window_controller_;
diff --git a/ash/wm/drag_window_resizer_unittest.cc b/ash/wm/drag_window_resizer_unittest.cc
index 49fe58e..d95fcba 100644
--- a/ash/wm/drag_window_resizer_unittest.cc
+++ b/ash/wm/drag_window_resizer_unittest.cc
@@ -77,6 +77,11 @@
     SetDefaultParentByPrimaryRootWindow(transient_parent_.get());
     transient_parent_->AddTransientChild(transient_child_);
     transient_parent_->set_id(5);
+
+    panel_window_.reset(new aura::Window(&delegate6_));
+    panel_window_->SetType(aura::client::WINDOW_TYPE_PANEL);
+    panel_window_->Init(ui::LAYER_NOT_DRAWN);
+    SetDefaultParentByPrimaryRootWindow(panel_window_.get());
   }
 
   virtual void TearDown() OVERRIDE {
@@ -84,6 +89,7 @@
     always_on_top_window_.reset();
     system_modal_window_.reset();
     transient_parent_.reset();
+    panel_window_.reset();
     AshTestBase::TearDown();
   }
 
@@ -114,10 +120,12 @@
   aura::test::TestWindowDelegate delegate3_;
   aura::test::TestWindowDelegate delegate4_;
   aura::test::TestWindowDelegate delegate5_;
+  aura::test::TestWindowDelegate delegate6_;
 
   scoped_ptr<aura::Window> window_;
   scoped_ptr<aura::Window> always_on_top_window_;
   scoped_ptr<aura::Window> system_modal_window_;
+  scoped_ptr<aura::Window> panel_window_;
   aura::Window* transient_child_;
   scoped_ptr<aura::Window> transient_parent_;
 
@@ -478,6 +486,21 @@
                                                          gfx::Point(399, 200)));
     resizer->CompleteDrag(0);
   }
+
+  // Panel window can be moved across display.
+  {
+    aura::Window* window = panel_window_.get();
+    window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
+                              Shell::GetScreen()->GetPrimaryDisplay());
+    // Grab (0, 0) of the window.
+    scoped_ptr<DragWindowResizer> resizer(CreateDragWindowResizer(
+        window, gfx::Point(), HTCAPTION));
+    ASSERT_TRUE(resizer.get());
+    resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0);
+    EXPECT_TRUE(event_filter->WarpMouseCursorIfNecessary(root_windows[0],
+                                                         gfx::Point(399, 200)));
+    resizer->CompleteDrag(0);
+  }
 }
 
 }  // namespace internal
diff --git a/ash/wm/event_client_impl.cc b/ash/wm/event_client_impl.cc
index 241f514..ab62f68 100644
--- a/ash/wm/event_client_impl.cc
+++ b/ash/wm/event_client_impl.cc
@@ -4,6 +4,7 @@
 
 #include "ash/wm/event_client_impl.h"
 
+#include "ash/session_state_delegate.h"
 #include "ash/shell.h"
 #include "ash/shell_window_ids.h"
 #include "ui/aura/window.h"
@@ -21,7 +22,8 @@
     const aura::Window* window) const {
   const aura::RootWindow* root_window =
       window ? window->GetRootWindow() : NULL;
-  if (Shell::GetInstance()->IsScreenLocked() && root_window) {
+  if (Shell::GetInstance()->session_state_delegate()->IsScreenLocked() &&
+      root_window) {
     const aura::Window* lock_screen_containers = Shell::GetContainer(
         root_window,
         kShellWindowId_LockScreenContainersContainer);
diff --git a/ash/wm/event_rewriter_event_filter.cc b/ash/wm/event_rewriter_event_filter.cc
index 8f204e0..2ef4853 100644
--- a/ash/wm/event_rewriter_event_filter.cc
+++ b/ash/wm/event_rewriter_event_filter.cc
@@ -21,7 +21,7 @@
 }
 
 void EventRewriterEventFilter::OnKeyEvent(ui::KeyEvent* event) {
-  if (!delegate_.get())
+  if (!delegate_)
     return;
 
   // Do not consume a translated key event which is generated by an IME.
@@ -40,7 +40,7 @@
 }
 
 void EventRewriterEventFilter::OnMouseEvent(ui::MouseEvent* event) {
-  if (!delegate_.get())
+  if (!delegate_)
     return;
 
   switch (delegate_->RewriteOrFilterLocatedEvent(event)) {
diff --git a/ash/wm/frame_painter.cc b/ash/wm/frame_painter.cc
index 4371a53..d23a6df 100644
--- a/ash/wm/frame_painter.cc
+++ b/ash/wm/frame_painter.cc
@@ -106,7 +106,8 @@
   canvas->DrawImageInPath(image, -image_inset_x, 0, path, paint);
 }
 
-// Returns true if |child| and all ancestors are visible.
+// Returns true if |child| and all ancestors are visible. Useful to ensure that
+// a window is individually visible and is not part of a hidden workspace.
 bool IsVisibleToRoot(Window* child) {
   for (Window* window = child; window; window = window->parent()) {
     // We must use TargetVisibility() because windows animate in and out and
@@ -117,13 +118,14 @@
   return true;
 }
 
-// Returns true if |window| is a visible, normal window.
-bool IsVisibleNormalWindow(aura::Window* window) {
-  // Test visibility up to root in case the whole workspace is hidden.
+// Returns true if |window| is a "normal" window for purposes of solo window
+// computations.
+bool IsSoloWindowHeaderCandidate(aura::Window* window) {
+  // A normal, non-modal, non-constrained window.
   return window &&
-    IsVisibleToRoot(window) &&
-    (window->type() == aura::client::WINDOW_TYPE_NORMAL ||
-     window->type() == aura::client::WINDOW_TYPE_PANEL);
+      window->type() == aura::client::WINDOW_TYPE_NORMAL &&
+      window->GetProperty(aura::client::kModalKey) == ui::MODAL_TYPE_NONE &&
+      !window->GetProperty(ash::kConstrainedWindowKey);
 }
 
 // Returns a list of windows in |root_window|| that potentially could have
@@ -225,15 +227,16 @@
       rb.GetImageNamed(IDR_AURA_WINDOW_HEADER_SHADE_RIGHT).ToImageSkia();
 
   window_ = frame->GetNativeWindow();
-  // Ensure we get resize cursors for a few pixels outside our bounds.
-  window_->SetHitTestBoundsOverrideOuter(
-      gfx::Insets(-kResizeOutsideBoundsSize, -kResizeOutsideBoundsSize,
-                  -kResizeOutsideBoundsSize, -kResizeOutsideBoundsSize),
+  gfx::Insets mouse_insets = gfx::Insets(-kResizeOutsideBoundsSize,
+                                         -kResizeOutsideBoundsSize,
+                                         -kResizeOutsideBoundsSize,
+                                         -kResizeOutsideBoundsSize);
+  gfx::Insets touch_insets = mouse_insets.Scale(
       kResizeOutsideBoundsScaleForTouch);
+  // Ensure we get resize cursors for a few pixels outside our bounds.
+  window_->SetHitTestBoundsOverrideOuter(mouse_insets, touch_insets);
   // Ensure we get resize cursors just inside our bounds as well.
-  window_->set_hit_test_bounds_override_inner(
-      gfx::Insets(kResizeInsideBoundsSize, kResizeInsideBoundsSize,
-                  kResizeInsideBoundsSize, kResizeInsideBoundsSize));
+  window_->set_hit_test_bounds_override_inner(mouse_insets);
 
   // Watch for maximize/restore/fullscreen state changes.  Observer removes
   // itself in OnWindowDestroying() below, or in the destructor if we go away
@@ -671,7 +674,7 @@
 
   // TODO(sky): this isn't quite right. What we really want is a method that
   // returns bounds ignoring transforms on certain windows (such as workspaces).
-  if (!frame_->IsMaximized() &&
+  if ((!frame_->IsMaximized() && !frame_->IsFullscreen()) &&
       ((old_bounds.y() == 0 && new_bounds.y() != 0) ||
        (old_bounds.y() != 0 && new_bounds.y() == 0))) {
     SchedulePaintForHeader();
@@ -750,11 +753,12 @@
   if (theme_frame_overlay)
     return kFullyOpaque;
 
-  // Maximized windows with workspaces are totally transparent, except:
+  // Maximized and fullscreen windows with workspaces are totally transparent,
+  // except:
   // - For windows whose workspace is not tracked by the workspace code (which
   //   are used for tab dragging).
   // - When the user is cycling through workspaces.
-  if (frame_->IsMaximized() &&
+  if ((frame_->IsMaximized() || frame_->IsFullscreen()) &&
       GetTrackedByWorkspace(frame_->GetNativeWindow()) &&
       !IsCyclingThroughWorkspaces()) {
     return 0;
@@ -813,6 +817,9 @@
 }
 
 bool FramePainter::UseSoloWindowHeader() {
+  // Don't use transparent headers for panels, pop-ups, etc.
+  if (!IsSoloWindowHeaderCandidate(window_))
+    return false;
   aura::RootWindow* root = window_->GetRootWindow();
   if (!root || root->GetProperty(internal::kIgnoreSoloWindowFramePainterPolicy))
     return false;
@@ -832,8 +839,8 @@
     Window* window = *it;
     // Various sorts of windows "don't count" for this computation.
     if (ignore_window == window ||
-        !IsVisibleNormalWindow(window) ||
-        window->GetProperty(kConstrainedWindowKey))
+        !IsSoloWindowHeaderCandidate(window) ||
+        !IsVisibleToRoot(window))
       continue;
     if (wm::IsWindowMaximized(window))
       return false;
diff --git a/ash/wm/frame_painter.h b/ash/wm/frame_painter.h
index 1f67ca5..5b8f3df 100644
--- a/ash/wm/frame_painter.h
+++ b/ash/wm/frame_painter.h
@@ -141,6 +141,9 @@
   FRIEND_TEST_ALL_PREFIXES(FramePainterTest, CreateAndDeleteSingleWindow);
   FRIEND_TEST_ALL_PREFIXES(FramePainterTest, UseSoloWindowHeader);
   FRIEND_TEST_ALL_PREFIXES(FramePainterTest, UseSoloWindowHeaderWithApp);
+  FRIEND_TEST_ALL_PREFIXES(FramePainterTest, UseSoloWindowHeaderWithPanel);
+  FRIEND_TEST_ALL_PREFIXES(FramePainterTest, UseSoloWindowHeaderModal);
+  FRIEND_TEST_ALL_PREFIXES(FramePainterTest, UseSoloWindowHeaderConstrained);
   FRIEND_TEST_ALL_PREFIXES(FramePainterTest, UseSoloWindowHeaderMultiDisplay);
   FRIEND_TEST_ALL_PREFIXES(FramePainterTest, GetHeaderOpacity);
 
diff --git a/ash/wm/frame_painter_unittest.cc b/ash/wm/frame_painter_unittest.cc
index 66055a3..275c484 100644
--- a/ash/wm/frame_painter_unittest.cc
+++ b/ash/wm/frame_painter_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "ash/wm/frame_painter.h"
 
+#include "ash/ash_constants.h"
 #include "ash/shell.h"
 #include "ash/shell_window_ids.h"
 #include "ash/test/ash_test_base.h"
@@ -13,6 +14,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "grit/ash_resources.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/aura/client/aura_constants.h"
 #include "ui/aura/root_window.h"
 #include "ui/aura/window_observer.h"
 #include "ui/base/hit_test.h"
@@ -152,6 +154,16 @@
     return widget;
   }
 
+  Widget* CreatePanelWidget() {
+    Widget* widget = new Widget;
+    Widget::InitParams params;
+    params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+    params.context = CurrentContext();
+    params.type = Widget::InitParams::TYPE_PANEL;
+    widget->Init(params);
+    return widget;
+  }
+
   Widget* CreateResizableWidget() {
     Widget* widget = new Widget;
     Widget::InitParams params;
@@ -357,6 +369,102 @@
   EXPECT_FALSE(p1.UseSoloWindowHeader());
 }
 
+// Panels should not "count" for computing solo window headers, and the panel
+// itself should always have an opaque header.
+TEST_F(FramePainterTest, UseSoloWindowHeaderWithPanel) {
+  // Create a widget and a painter for it.
+  scoped_ptr<Widget> w1(CreateTestWidget());
+  FramePainter p1;
+  ImageButton size1(NULL);
+  ImageButton close1(NULL);
+  p1.Init(w1.get(), NULL, &size1, &close1, FramePainter::SIZE_BUTTON_MAXIMIZES);
+  w1->Show();
+
+  // We only have one window, so it should use a solo header.
+  EXPECT_TRUE(p1.UseSoloWindowHeader());
+
+  // Create a panel and a painter for it.
+  scoped_ptr<Widget> w2(CreatePanelWidget());
+  FramePainter p2;
+  ImageButton size2(NULL);
+  ImageButton close2(NULL);
+  p2.Init(w2.get(), NULL, &size2, &close2, FramePainter::SIZE_BUTTON_MAXIMIZES);
+  w2->Show();
+
+  // Despite two windows, the first window should still be considered "solo"
+  // because panels aren't included in the computation.
+  EXPECT_TRUE(p1.UseSoloWindowHeader());
+
+  // The panel itself is not considered solo.
+  EXPECT_FALSE(p2.UseSoloWindowHeader());
+
+  // Even after closing the first window, the panel is still not considered
+  // solo.
+  w1.reset();
+  EXPECT_FALSE(p2.UseSoloWindowHeader());
+}
+
+// Modal dialogs should not use solo headers.
+TEST_F(FramePainterTest, UseSoloWindowHeaderModal) {
+  // Create a widget and a painter for it.
+  scoped_ptr<Widget> w1(CreateTestWidget());
+  FramePainter p1;
+  ImageButton size1(NULL);
+  ImageButton close1(NULL);
+  p1.Init(w1.get(), NULL, &size1, &close1, FramePainter::SIZE_BUTTON_MAXIMIZES);
+  w1->Show();
+
+  // We only have one window, so it should use a solo header.
+  EXPECT_TRUE(p1.UseSoloWindowHeader());
+
+  // Create a fake modal window.
+  scoped_ptr<Widget> w2(CreateTestWidget());
+  w2->GetNativeWindow()->SetProperty(aura::client::kModalKey,
+                                     ui::MODAL_TYPE_WINDOW);
+  FramePainter p2;
+  ImageButton size2(NULL);
+  ImageButton close2(NULL);
+  p2.Init(w2.get(), NULL, &size2, &close2, FramePainter::SIZE_BUTTON_MAXIMIZES);
+  w2->Show();
+
+  // Despite two windows, the first window should still be considered "solo"
+  // because modal windows aren't included in the computation.
+  EXPECT_TRUE(p1.UseSoloWindowHeader());
+
+  // The modal window itself is not considered solo.
+  EXPECT_FALSE(p2.UseSoloWindowHeader());
+}
+
+// Constrained windows should not use solo headers.
+TEST_F(FramePainterTest, UseSoloWindowHeaderConstrained) {
+  // Create a widget and a painter for it.
+  scoped_ptr<Widget> w1(CreateTestWidget());
+  FramePainter p1;
+  ImageButton size1(NULL);
+  ImageButton close1(NULL);
+  p1.Init(w1.get(), NULL, &size1, &close1, FramePainter::SIZE_BUTTON_MAXIMIZES);
+  w1->Show();
+
+  // We only have one window, so it should use a solo header.
+  EXPECT_TRUE(p1.UseSoloWindowHeader());
+
+  // Create a fake constrained window.
+  scoped_ptr<Widget> w2(CreateTestWidget());
+  w2->GetNativeWindow()->SetProperty(ash::kConstrainedWindowKey, true);
+  FramePainter p2;
+  ImageButton size2(NULL);
+  ImageButton close2(NULL);
+  p2.Init(w2.get(), NULL, &size2, &close2, FramePainter::SIZE_BUTTON_MAXIMIZES);
+  w2->Show();
+
+  // Despite two windows, the first window should still be considered "solo"
+  // because constrained windows aren't included in the computation.
+  EXPECT_TRUE(p1.UseSoloWindowHeader());
+
+  // The constrained window itself is not considered solo.
+  EXPECT_FALSE(p2.UseSoloWindowHeader());
+}
+
 #if defined(OS_WIN)
 // Multiple displays are not supported on Windows Ash. http://crbug.com/165962
 #define MAYBE_UseSoloWindowHeaderMultiDisplay \
diff --git a/ash/wm/gestures/bezel_gesture_handler.cc b/ash/wm/gestures/bezel_gesture_handler.cc
deleted file mode 100644
index a306f6f..0000000
--- a/ash/wm/gestures/bezel_gesture_handler.cc
+++ /dev/null
@@ -1,292 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/wm/gestures/bezel_gesture_handler.h"
-
-#include "ash/accelerators/accelerator_controller.h"
-#include "ash/accelerators/accelerator_table.h"
-#include "ash/ash_switches.h"
-#include "ash/launcher/launcher.h"
-#include "ash/root_window_controller.h"
-#include "ash/shell.h"
-#include "ash/shell_delegate.h"
-#include "ash/system/brightness/brightness_control_delegate.h"
-#include "ash/system/tray/system_tray_delegate.h"
-#include "ash/volume_control_delegate.h"
-#include "base/command_line.h"
-#include "ui/aura/root_window.h"
-#include "ui/base/events/event.h"
-#include "ui/base/ui_base_switches.h"
-#include "ui/gfx/screen.h"
-
-namespace {
-
-// Device bezel operation constants (volume/brightness slider).
-
-// This is the minimal brightness value allowed for the display.
-const double kMinBrightnessPercent = 5.0;
-// For device operation, the finger is not allowed to enter the screen more
-// then this fraction of the size of the screen.
-const double kAllowableScreenOverlapForDeviceCommand = 0.0005;
-
-// TODO(skuhne): The noise reduction can be removed when / if we are adding a
-// more general reduction.
-// To avoid unwanted noise activation, the first 'n' events are being ignored
-// for bezel device gestures.
-const int kIgnoreFirstBezelDeviceEvents = 10;
-// Within these 'n' huge coordinate changes are not allowed. The threshold is
-// given in fraction of screen resolution changes.
-const double kBezelNoiseDeltaFilter = 0.1;
-// To avoid the most frequent noise (extreme locations) the bezel percent
-// sliders will not cover the entire screen. We scale therefore the percent
-// value by this many percent for minima and maxima extension.
-// (Range extends to -kMinMaxInsetPercent .. 100 + kMinMaxInsetPercent).
-const double kMinMaxInsetPercent = 5.0;
-// To make it possible to reach minimas and maximas easily a range extension
-// of -kMinMaxCutOffPercent .. 100 + kMinMaxCutOffPercent will be clamped to
-// 0..100%. Everything beyond that will be ignored.
-const double kMinMaxCutOffPercent = 2.0;
-
-}  // namespace
-
-namespace ash {
-namespace internal {
-
-BezelGestureHandler::BezelGestureHandler()
-    : overlap_percent_(0),
-      start_location_(BEZEL_START_UNSET),
-      orientation_(SCROLL_ORIENTATION_UNSET),
-      is_scrubbing_(false),
-      initiation_delay_events_(0) {
-  enable_bezel_device_control_ =
-      CommandLine::ForCurrentProcess()->HasSwitch(
-                ::switches::kEnableBezelTouch);
-}
-
-BezelGestureHandler::~BezelGestureHandler() {
-}
-
-void BezelGestureHandler::ProcessGestureEvent(aura::Window* target,
-                                              const ui::GestureEvent& event) {
-  switch (event.type()) {
-    case ui::ET_GESTURE_SCROLL_BEGIN:
-      HandleBezelGestureStart(target, event);
-
-      // TODO(sad|skuhne): Fix the bezel gestures for when the shelf is on the
-      //                   left/right of the screen. Also fix the
-      //                   overlay_percent_ at that time (currently just set to
-      //                   0 because left/right bezel gestures dont work).
-      if (start_location_ == BEZEL_START_BOTTOM)
-        shelf_handler_.ProcessGestureEvent(event);
-      break;
-    case ui::ET_GESTURE_SCROLL_UPDATE:
-      // Check if a valid start position has been set.
-      if (start_location_ == BEZEL_START_UNSET)
-        break;
-
-      if (DetermineGestureOrientation(event))
-        HandleBezelGestureUpdate(target, event);
-      break;
-    case ui::ET_GESTURE_SCROLL_END:
-    case ui::ET_SCROLL_FLING_START:
-      if (start_location_ == BEZEL_START_BOTTOM)
-        shelf_handler_.ProcessGestureEvent(event);
-      HandleBezelGestureEnd();
-      break;
-    default:
-      break;
-  }
-}
-
-bool BezelGestureHandler::HandleDeviceControl(
-    const gfx::Rect& screen,
-    const ui::GestureEvent& event) {
-  // Get the slider position as value from the absolute position.
-  // Note that the highest value is at the top.
-  double percent = 100.0 - 100.0 * (event.y() - screen.y()) / screen.height();
-  if (!DeNoiseBezelSliderPosition(&percent)) {
-    // Note: Even though this particular event might be noise, the gesture
-    // itself is still valid and should not get cancelled.
-    return false;
-  }
-  ash::AcceleratorController* accelerator =
-      ash::Shell::GetInstance()->accelerator_controller();
-  if (start_location_ == BEZEL_START_LEFT) {
-    ash::BrightnessControlDelegate* delegate =
-        accelerator->brightness_control_delegate();
-    if (delegate)
-      delegate->SetBrightnessPercent(
-          LimitBezelBrightnessFromSlider(percent), true);
-  } else if (start_location_ == BEZEL_START_RIGHT) {
-    Shell::GetInstance()->system_tray_delegate()->GetVolumeControlDelegate()->
-        SetVolumePercent(percent);
-  } else {
-    // No further events are necessary.
-    return true;
-  }
-
-  // More notifications can be send.
-  return false;
-}
-
-bool BezelGestureHandler::HandleLauncherControl(const ui::GestureEvent& event) {
-  CHECK_EQ(BEZEL_START_BOTTOM, start_location_);
-  shelf_handler_.ProcessGestureEvent(event);
-  return event.type() == ui::ET_GESTURE_SCROLL_END ||
-         event.type() == ui::ET_SCROLL_FLING_START;
-}
-
-bool BezelGestureHandler::HandleApplicationControl(
-    const ui::GestureEvent& event) {
-  ash::AcceleratorController* accelerator =
-      ash::Shell::GetInstance()->accelerator_controller();
-  if (start_location_ == BEZEL_START_LEFT && event.details().scroll_x() > 0) {
-    accelerator->PerformAction(CYCLE_BACKWARD_LINEAR, ui::Accelerator());
-  } else if (start_location_ == BEZEL_START_RIGHT &&
-      event.details().scroll_x() < 0) {
-    accelerator->PerformAction(CYCLE_FORWARD_LINEAR, ui::Accelerator());
-  } else {
-    return false;
-  }
-
-  // No further notifications for this gesture.
-  return true;
-}
-
-void BezelGestureHandler::HandleBezelGestureStart(
-    aura::Window* target,
-    const ui::GestureEvent& event) {
-  gfx::Rect screen =
-      Shell::GetScreen()->GetDisplayNearestWindow(target).bounds();
-  int overlap_area = screen.width() * overlap_percent_ / 100;
-  orientation_ = SCROLL_ORIENTATION_UNSET;
-
-  if (event.x() <= screen.x() + overlap_area) {
-    start_location_ = BEZEL_START_LEFT;
-  } else if (event.x() >= screen.right() - overlap_area) {
-    start_location_ = BEZEL_START_RIGHT;
-  } else if (event.y() >= screen.bottom()) {
-    start_location_ = BEZEL_START_BOTTOM;
-  }
-}
-
-bool BezelGestureHandler::DetermineGestureOrientation(
-    const ui::GestureEvent& event) {
-  if (orientation_ == SCROLL_ORIENTATION_UNSET) {
-    if (!event.details().scroll_x() && !event.details().scroll_y())
-      return false;
-
-    // For left and right the scroll angle needs to be much steeper to
-    // be accepted for a 'device configuration' gesture.
-    if (start_location_ == BEZEL_START_LEFT ||
-        start_location_ == BEZEL_START_RIGHT) {
-      orientation_ = abs(event.details().scroll_y()) >
-                     abs(event.details().scroll_x()) * 3 ?
-          SCROLL_ORIENTATION_VERTICAL : SCROLL_ORIENTATION_HORIZONTAL;
-    } else {
-      orientation_ = abs(event.details().scroll_y()) >
-                     abs(event.details().scroll_x()) ?
-          SCROLL_ORIENTATION_VERTICAL : SCROLL_ORIENTATION_HORIZONTAL;
-    }
-
-    // Reset the delay counter for noise event filtering.
-    initiation_delay_events_ = 0;
-  }
-  return true;
-}
-
-void BezelGestureHandler::HandleBezelGestureUpdate(
-    aura::Window* target,
-    const ui::GestureEvent& event) {
-  if (orientation_ == SCROLL_ORIENTATION_HORIZONTAL) {
-    if (HandleApplicationControl(event))
-      start_location_ = BEZEL_START_UNSET;
-  } else {
-    if (start_location_ == BEZEL_START_BOTTOM) {
-      if (HandleLauncherControl(event))
-        start_location_ = BEZEL_START_UNSET;
-    } else {
-      // Check if device gestures should be performed or not.
-      if (!enable_bezel_device_control_) {
-        start_location_ = BEZEL_START_UNSET;
-        return;
-      }
-      gfx::Rect screen =
-          Shell::GetScreen()->GetDisplayNearestWindow(target).bounds();
-      // Limit the user gesture "mostly" to the off screen area and check for
-      // noise invocation.
-      if (!GestureInBezelArea(screen, event) ||
-          BezelGestureMightBeNoise(screen, event))
-        return;
-      if (HandleDeviceControl(screen, event))
-        start_location_ = BEZEL_START_UNSET;
-    }
-  }
-}
-
-void BezelGestureHandler::HandleBezelGestureEnd() {
-  // All which is needed is to set the gesture start location to undefined.
-  start_location_ = BEZEL_START_UNSET;
-}
-
-bool BezelGestureHandler::GestureInBezelArea(
-    const gfx::Rect& screen,
-    const ui::GestureEvent& event) {
-  // Limit the gesture mostly to the off screen.
-  double allowable_offset =
-      screen.width() * kAllowableScreenOverlapForDeviceCommand;
-  if ((start_location_ == BEZEL_START_LEFT &&
-       event.x() > allowable_offset) ||
-      (start_location_ == BEZEL_START_RIGHT &&
-       event.x() < screen.width() - allowable_offset)) {
-    start_location_ = BEZEL_START_UNSET;
-    return false;
-  }
-  return true;
-}
-
-bool BezelGestureHandler::BezelGestureMightBeNoise(
-    const gfx::Rect& screen,
-    const ui::GestureEvent& event) {
-  // The first events will not trigger an action.
-  if (initiation_delay_events_++ < kIgnoreFirstBezelDeviceEvents) {
-    // When the values are too far apart we ignore it since it might
-    // be random noise.
-    double delta_y = event.details().scroll_y();
-    double span_y = screen.height();
-    if (abs(delta_y / span_y) > kBezelNoiseDeltaFilter)
-      start_location_ = BEZEL_START_UNSET;
-    return true;
-  }
-  return false;
-}
-
-bool BezelGestureHandler::DeNoiseBezelSliderPosition(double* percent) {
-  // The range gets passed as 0..100% and is extended to the range of
-  // (-kMinMaxInsetPercent) .. (100 + kMinMaxInsetPercent). This way we can
-  // cut off the extreme upper and lower values which are prone to noise.
-  // It additionally adds a "security buffer" which can then be clamped to the
-  // extremes to empower the user to get to these values (0% and 100%).
-  *percent = *percent * (100.0 + 2 * kMinMaxInsetPercent) / 100 -
-      kMinMaxInsetPercent;
-  // Values which fall outside of the acceptable inner range area get ignored.
-  if (*percent < -kMinMaxCutOffPercent ||
-      *percent > 100.0 + kMinMaxCutOffPercent)
-    return false;
-  // Excessive values get then clamped to the 0..100% range.
-  *percent = std::max(std::min(*percent, 100.0), 0.0);
-  return true;
-}
-
-double BezelGestureHandler::LimitBezelBrightnessFromSlider(double percent) {
-  // Turning off the display makes no sense, so we map the accessible range to
-  // kMinimumBrightness .. 100%.
-  percent = (percent + kMinBrightnessPercent) * 100.0 /
-      (100.0 + kMinBrightnessPercent);
-  // Clamp to avoid rounding issues.
-  return std::min(percent, 100.0);
-}
-
-}  // namespace internal
-}  // namespace ash
diff --git a/ash/wm/gestures/bezel_gesture_handler.h b/ash/wm/gestures/bezel_gesture_handler.h
deleted file mode 100644
index db8163e..0000000
--- a/ash/wm/gestures/bezel_gesture_handler.h
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ASH_WM_GESTURES_BEZEL_GESTURE_HANDLER_H_
-#define ASH_WM_GESTURES_BEZEL_GESTURE_HANDLER_H_
-
-#include "base/basictypes.h"
-
-#include "ash/wm/gestures/shelf_gesture_handler.h"
-
-namespace aura {
-class Window;
-}
-
-namespace gfx {
-class Point;
-class Rect;
-}
-
-namespace ui {
-class GestureEvent;
-}
-
-namespace ash {
-namespace internal {
-
-enum BezelStart {
-  BEZEL_START_UNSET = 0,
-  BEZEL_START_TOP,
-  BEZEL_START_LEFT,
-  BEZEL_START_RIGHT,
-  BEZEL_START_BOTTOM
-};
-
-enum ScrollOrientation {
-  SCROLL_ORIENTATION_UNSET = 0,
-  SCROLL_ORIENTATION_HORIZONTAL,
-  SCROLL_ORIENTATION_VERTICAL
-};
-
-class BezelGestureHandler {
- public:
-  BezelGestureHandler();
-  virtual ~BezelGestureHandler();
-
-  void ProcessGestureEvent(aura::Window* target, const ui::GestureEvent& event);
-
- private:
-  // Handle events meant for volume / brightness. Returns true when no further
-  // events from this gesture should be sent.
-  bool HandleDeviceControl(const gfx::Rect& screen,
-                           const ui::GestureEvent& event);
-
-  // Handle events meant for showing the launcher. Returns true when no further
-  // events from this gesture should be sent.
-  bool HandleLauncherControl(const ui::GestureEvent& event);
-
-  // Handle events meant to switch through applications. Returns true when no
-  // further events from this gesture should be sent.
-  bool HandleApplicationControl(const ui::GestureEvent& event);
-
-  // Handle a gesture begin event.
-  void HandleBezelGestureStart(aura::Window* target,
-                               const ui::GestureEvent& event);
-
-  // Determine the gesture orientation (if not yet done).
-  // Returns true when the orientation has been successfully determined.
-  bool DetermineGestureOrientation(const ui::GestureEvent& event);
-
-  // Handles a gesture update once the orientation has been found.
-  void HandleBezelGestureUpdate(aura::Window* target,
-                                const ui::GestureEvent& event);
-
-  // End a bezel gesture.
-  void HandleBezelGestureEnd();
-
-  // Check if a bezel slider gesture is still within the bezel area.
-  // If it is not, it will abort the gesture, otherwise it will return true.
-  bool GestureInBezelArea(const gfx::Rect& screen,
-                          const ui::GestureEvent& event);
-
-  // Check if the bezel gesture for noise artifacts. If it is no noise
-  // it will return false. If noise is detected it will abort the gesture.
-  bool BezelGestureMightBeNoise(const gfx::Rect& screen,
-                                const ui::GestureEvent& event);
-
-  // Most noise events are showing up at the upper and lower extremes. To
-  // filter them out, a few percent get cut off at the top and at the bottom.
-  // A return value of false indicates possible noise and no further action
-  // should be performed with the event.
-  // The returned |percent| value is between 0.0 and 100.0.
-  bool DeNoiseBezelSliderPosition(double* percent);
-
-  // Determine the brightness value from the slider position.
-  double LimitBezelBrightnessFromSlider(double percent);
-
-  // The percentage of the screen to the left and right which belongs to
-  // device gestures.
-  const int overlap_percent_;
-
-  // Which bezel corner are we on.
-  BezelStart start_location_;
-
-  // Which orientation are we moving.
-  ScrollOrientation orientation_;
-
-  // A device swipe gesture is in progress.
-  bool is_scrubbing_;
-
-  // To suppress random noise in the bezel area, the stroke needs to have at
-  // least a certain amount of events in close proximity before it gets used.
-  // This is the counter which keeps track of the number of events passed.
-  int initiation_delay_events_;
-
-  // True if device control bezel operations (brightness, volume) are enabled.
-  bool enable_bezel_device_control_;
-
-  ShelfGestureHandler shelf_handler_;
-
-  DISALLOW_COPY_AND_ASSIGN(BezelGestureHandler);
-};
-
-}  // namespace internal
-}  // namespace ash
-
-#endif  // ASH_WM_GESTURES_BEZEL_GESTURE_HANDLER_H_
diff --git a/ash/wm/gestures/border_gesture_handler.cc b/ash/wm/gestures/border_gesture_handler.cc
new file mode 100644
index 0000000..5124ff1
--- /dev/null
+++ b/ash/wm/gestures/border_gesture_handler.cc
@@ -0,0 +1,171 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/wm/gestures/border_gesture_handler.h"
+
+#include "ash/root_window_controller.h"
+#include "ash/shelf/shelf_layout_manager.h"
+#include "ash/shelf/shelf_types.h"
+#include "ash/shelf/shelf_widget.h"
+#include "ash/shell.h"
+#include "base/command_line.h"
+#include "base/string_util.h"
+#include "base/strings/string_number_conversions.h"
+#include "ui/aura/root_window.h"
+#include "ui/base/events/event.h"
+#include "ui/base/ui_base_switches.h"
+#include "ui/gfx/screen.h"
+
+namespace ash {
+namespace internal {
+
+BorderGestureHandler::BorderGestureHandler()
+    : orientation_(BORDER_SCROLL_ORIENTATION_UNSET) {
+}
+
+BorderGestureHandler::~BorderGestureHandler() {
+}
+
+bool BorderGestureHandler::ProcessGestureEvent(aura::Window* target,
+                                               const ui::GestureEvent& event) {
+  switch (event.type()) {
+    case ui::ET_GESTURE_SCROLL_BEGIN:
+      return HandleBorderGestureStart(target, event);
+    case ui::ET_GESTURE_SCROLL_UPDATE:
+      if (start_location_.any() &&
+          DetermineGestureOrientation(event))
+        return HandleBorderGestureUpdate(target, event);
+      break;
+    case ui::ET_GESTURE_SCROLL_END:
+    case ui::ET_SCROLL_FLING_START:
+      return HandleBorderGestureEnd(target, event);
+    default:
+      break;
+  }
+  // If the event is outside of the display region and targetted at the root
+  // window then it is on a bezel and not in another window. All bezel events
+  // should be consumed here since no other part of the stack handles them.
+  gfx::Rect screen =
+      Shell::GetScreen()->GetDisplayNearestWindow(target).bounds();
+  if (!screen.Contains(event.location()) &&
+      target == target->GetRootWindow())
+    return true;
+  return false;
+}
+
+bool BorderGestureHandler::HandleLauncherControl(
+    const ui::GestureEvent& event) {
+  ShelfLayoutManager* shelf =
+      Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager();
+  switch (shelf->GetAlignment()) {
+    case SHELF_ALIGNMENT_BOTTOM:
+      if (start_location_.test(BORDER_LOCATION_BOTTOM))
+        return shelf_handler_.ProcessGestureEvent(event);
+      break;
+    case SHELF_ALIGNMENT_LEFT:
+      if (start_location_.test(BORDER_LOCATION_LEFT))
+        return shelf_handler_.ProcessGestureEvent(event);
+      break;
+    case SHELF_ALIGNMENT_TOP:
+      if (start_location_.test(BORDER_LOCATION_TOP))
+        return shelf_handler_.ProcessGestureEvent(event);
+      break;
+    case SHELF_ALIGNMENT_RIGHT:
+      if (start_location_.test(BORDER_LOCATION_RIGHT))
+        return shelf_handler_.ProcessGestureEvent(event);
+      break;
+  }
+  return false;
+}
+
+bool BorderGestureHandler::HandleBorderGestureStart(
+    aura::Window* target,
+    const ui::GestureEvent& event) {
+  orientation_ = BORDER_SCROLL_ORIENTATION_UNSET;
+  start_location_.reset();
+
+  gfx::Rect screen =
+      Shell::GetScreen()->GetDisplayNearestWindow(target).bounds();
+  GestureStartInTargetArea(screen, event);
+
+  if (start_location_.any())
+    return HandleLauncherControl(event);
+  return false;
+}
+
+bool BorderGestureHandler::HandleBorderGestureUpdate(
+    aura::Window* target,
+    const ui::GestureEvent& event) {
+  if (IsGestureInLauncherOrientation(event))
+    return HandleLauncherControl(event);
+  return false;
+}
+
+bool BorderGestureHandler::HandleBorderGestureEnd(
+    aura::Window* target,
+    const ui::GestureEvent& event) {
+  bool ret_val = HandleLauncherControl(event);
+  start_location_.reset();
+  return ret_val;
+}
+
+void BorderGestureHandler::GestureStartInTargetArea(
+    const gfx::Rect& screen,
+    const ui::GestureEvent& event) {
+  if (event.y() > screen.bottom())
+    start_location_[BORDER_LOCATION_BOTTOM] = 1;
+  if (event.x() < screen.x())
+    start_location_[BORDER_LOCATION_LEFT] = 1;
+  if (event.y() < screen.y())
+    start_location_[BORDER_LOCATION_TOP] = 1;
+  if (event.x() > screen.right())
+    start_location_[BORDER_LOCATION_RIGHT] = 1;
+}
+
+bool BorderGestureHandler::DetermineGestureOrientation(
+    const ui::GestureEvent& event) {
+  if (orientation_ == BORDER_SCROLL_ORIENTATION_UNSET) {
+    if (!event.details().scroll_x() && !event.details().scroll_y())
+      return false;
+    orientation_ = abs(event.details().scroll_y()) >
+        abs(event.details().scroll_x()) ?
+        BORDER_SCROLL_ORIENTATION_VERTICAL :
+        BORDER_SCROLL_ORIENTATION_HORIZONTAL;
+  }
+  return true;
+}
+
+bool BorderGestureHandler::IsGestureInLauncherOrientation(
+    const ui::GestureEvent& event) {
+  BorderScrollOrientation  new_orientation = abs(event.details().scroll_y()) >
+      abs(event.details().scroll_x()) ?
+      BORDER_SCROLL_ORIENTATION_VERTICAL : BORDER_SCROLL_ORIENTATION_HORIZONTAL;
+  if (new_orientation != orientation_)
+    return false;
+
+  ShelfLayoutManager* shelf =
+      Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager();
+  switch (shelf->GetAlignment()) {
+    case SHELF_ALIGNMENT_BOTTOM:
+      if (orientation_ == BORDER_SCROLL_ORIENTATION_VERTICAL)
+        return true;
+      break;
+    case SHELF_ALIGNMENT_LEFT:
+      if (orientation_ == BORDER_SCROLL_ORIENTATION_HORIZONTAL)
+        return true;
+      break;
+    case SHELF_ALIGNMENT_TOP:
+      if (orientation_ == BORDER_SCROLL_ORIENTATION_VERTICAL)
+        return true;
+      break;
+    case SHELF_ALIGNMENT_RIGHT:
+      if (orientation_ == BORDER_SCROLL_ORIENTATION_HORIZONTAL)
+        return true;
+      break;
+  }
+  return false;
+}
+
+}  // namespace internal
+}  // namespace ash
diff --git a/ash/wm/gestures/border_gesture_handler.h b/ash/wm/gestures/border_gesture_handler.h
new file mode 100644
index 0000000..fe188f2
--- /dev/null
+++ b/ash/wm/gestures/border_gesture_handler.h
@@ -0,0 +1,103 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_WM_GESTURES_BORDER_GESTURE_HANDLER_H_
+#define ASH_WM_GESTURES_BORDER_GESTURE_HANDLER_H_
+
+#include <bitset>
+
+#include "ash/shelf/shelf_types.h"
+#include "ash/wm/gestures/shelf_gesture_handler.h"
+#include "base/basictypes.h"
+
+namespace aura {
+class Window;
+}
+
+namespace gfx {
+class Point;
+class Rect;
+}
+
+namespace ui {
+class GestureEvent;
+}
+
+namespace ash {
+namespace internal {
+
+enum BorderScrollOrientation {
+  BORDER_SCROLL_ORIENTATION_UNSET = 0,
+  BORDER_SCROLL_ORIENTATION_HORIZONTAL,
+  BORDER_SCROLL_ORIENTATION_VERTICAL
+};
+
+// Bit positions of border location flags
+enum BorderLocation {
+  BORDER_LOCATION_BOTTOM = 0,
+  BORDER_LOCATION_LEFT = 1,
+  BORDER_LOCATION_TOP = 2,
+  BORDER_LOCATION_RIGHT = 3,
+  NUM_BORDER_LOCATIONS
+};
+
+typedef std::bitset<NUM_BORDER_LOCATIONS> BorderFlags;
+
+// Handles touch gestures that occur around the border of the display area that
+// might have actions associated with them. It handles both gestures that
+// require a bezel sensor (bezel gestures) and those that do not (edge
+// gestures).
+class BorderGestureHandler {
+ public:
+  BorderGestureHandler();
+  ~BorderGestureHandler();
+
+  // Returns true of the gesture has been handled and it should not be processed
+  // any farther, false otherwise.
+  bool ProcessGestureEvent(aura::Window* target, const ui::GestureEvent& event);
+
+ private:
+  // Handle events meant for showing the launcher. Returns true when no further
+  // events from this gesture should be sent.
+  bool HandleLauncherControl(const ui::GestureEvent& event);
+
+  bool HandleBorderGestureStart(aura::Window* target,
+                                const ui::GestureEvent& event);
+
+  // Handles a gesture update once the orientation has been found.
+  bool HandleBorderGestureUpdate(aura::Window* target,
+                                 const ui::GestureEvent& event);
+
+  bool HandleBorderGestureEnd(aura::Window* target,
+                              const ui::GestureEvent& event);
+
+  // Check that gesture starts on a bezel or in the edge region of the
+  // screen. If so, set bits in |start_location_|.
+  void GestureStartInTargetArea(const gfx::Rect& screen,
+                                const ui::GestureEvent& event);
+
+  // Determine the gesture orientation (if not yet done).
+  // Returns true when the orientation has been successfully determined.
+  bool DetermineGestureOrientation(const ui::GestureEvent& event);
+
+  // Test if the gesture orientation makes sense to be dragging in or out the
+  // launcher.
+  bool IsGestureInLauncherOrientation(const ui::GestureEvent& event);
+
+  // Which bezel/edges the gesture started in. In the case that a gesture begins
+  // in a corner of the screen more then one flag may be set and the orientation
+  // of the gesture will be needed to disambiguate.
+  BorderFlags start_location_;
+
+  // Orientation relative to the screen that the gesture is moving in
+  BorderScrollOrientation orientation_;
+
+  ShelfGestureHandler shelf_handler_;
+
+  DISALLOW_COPY_AND_ASSIGN(BorderGestureHandler);
+};
+
+}  // namespace internal
+}  // namespace ash
+#endif  // ASH_WM_GESTURES_BORDER_GESTURE_HANDLER_H_
diff --git a/ash/wm/gestures/shelf_gesture_handler.cc b/ash/wm/gestures/shelf_gesture_handler.cc
index d000eb5..847820d 100644
--- a/ash/wm/gestures/shelf_gesture_handler.cc
+++ b/ash/wm/gestures/shelf_gesture_handler.cc
@@ -5,11 +5,11 @@
 #include "ash/wm/gestures/shelf_gesture_handler.h"
 
 #include "ash/root_window_controller.h"
+#include "ash/session_state_delegate.h"
 #include "ash/shelf/shelf_layout_manager.h"
 #include "ash/shelf/shelf_types.h"
 #include "ash/shelf/shelf_widget.h"
 #include "ash/shell.h"
-#include "ash/shell_delegate.h"
 #include "ash/system/status_area_widget.h"
 #include "ash/wm/gestures/tray_gesture_handler.h"
 #include "ash/wm/window_util.h"
@@ -19,96 +19,6 @@
 #include "ui/gfx/transform.h"
 #include "ui/views/widget/widget.h"
 
-namespace {
-
-// A ShelfResetHandler auto-hides the shelf as soon as the user interacts with
-// any non-shelf part of the system. The ShelfResetHandler manages its own
-// lifetime.
-class ShelfResetHandler : public ui::EventHandler,
-                          public ash::internal::ShelfLayoutManager::Observer {
- public:
-  explicit ShelfResetHandler(ash::internal::ShelfLayoutManager* shelf)
-      : shelf_(shelf) {
-    shelf_->AddObserver(this);
-    ash::Shell::GetInstance()->AddPreTargetHandler(this);
-  }
-
- private:
-  virtual ~ShelfResetHandler() {
-    ash::Shell::GetInstance()->RemovePreTargetHandler(this);
-    shelf_->RemoveObserver(this);
-  }
-
-  void ResetShelfState() {
-    shelf_->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
-    delete this;
-  }
-
-  bool ShelfIsEventTarget(const ui::Event& event) {
-    aura::Window* target = static_cast<aura::Window*>(event.target());
-    views::Widget* widget = shelf_->shelf_widget();
-    if (widget && widget->GetNativeWindow() == target)
-      return true;
-    widget = shelf_->shelf_widget()->status_area_widget();
-    if (widget && widget->GetNativeWindow() == target)
-      return true;
-    return false;
-  }
-
-  void DecideShelfVisibility(const gfx::Point& location) {
-    // For the rest of the mouse events, ignore if the event happens inside the
-    // shelf.
-    views::Widget* widget = shelf_->shelf_widget();
-    if (widget &&
-        widget->GetWindowBoundsInScreen().Contains(location)) {
-      return;
-    }
-
-    widget = shelf_->shelf_widget()->status_area_widget();
-    if (widget &&
-        widget->GetWindowBoundsInScreen().Contains(location)) {
-      return;
-    }
-
-    ResetShelfState();
-  }
-
-  // Overridden from ui::EventHandler:
-  virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE {
-    if (!ShelfIsEventTarget(*event))
-      ResetShelfState();
-  }
-
-  virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
-    // Ignore all mouse move events.
-    if (event->type() == ui::ET_MOUSE_PRESSED ||
-        event->type() == ui::ET_MOUSE_RELEASED) {
-      DecideShelfVisibility(event->root_location());
-    }
-  }
-
-  virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE {
-    if (!ShelfIsEventTarget(*event))
-      DecideShelfVisibility(event->root_location());
-  }
-
-  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
-    if (!ShelfIsEventTarget(*event))
-      DecideShelfVisibility(event->root_location());
-  }
-
-  // Overridden from ash::internal::ShelfLayoutManager::Observer:
-  virtual void WillDeleteShelf() OVERRIDE {
-    delete this;
-  }
-
-  ash::internal::ShelfLayoutManager* shelf_;
-
-  DISALLOW_COPY_AND_ASSIGN(ShelfResetHandler);
-};
-
-}  // namespace
-
 namespace ash {
 namespace internal {
 
@@ -121,8 +31,8 @@
 
 bool ShelfGestureHandler::ProcessGestureEvent(const ui::GestureEvent& event) {
   Shell* shell = Shell::GetInstance();
-  if (!shell->delegate()->IsUserLoggedIn() ||
-      shell->delegate()->IsScreenLocked()) {
+  if (!shell->session_state_delegate()->HasActiveUser() ||
+      shell->session_state_delegate()->IsScreenLocked()) {
     // The gestures are disabled in the lock/login screen.
     return false;
   }
@@ -145,7 +55,7 @@
     return false;
 
   if (event.type() == ui::ET_GESTURE_SCROLL_UPDATE) {
-    if (tray_handler_.get()) {
+    if (tray_handler_) {
       if (!tray_handler_->UpdateGestureDrag(event))
         tray_handler_.reset();
     } else if (shelf->UpdateGestureDrag(event) ==
@@ -160,16 +70,12 @@
 
   if (event.type() == ui::ET_GESTURE_SCROLL_END ||
       event.type() == ui::ET_SCROLL_FLING_START) {
-    if (tray_handler_.get()) {
+    if (tray_handler_) {
       tray_handler_->CompleteGestureDrag(event);
       tray_handler_.reset();
     }
 
-    ShelfVisibilityState old_state = shelf->visibility_state();
     shelf->CompleteGestureDrag(event);
-    ShelfVisibilityState new_state = shelf->visibility_state();
-    if (new_state != old_state && new_state == SHELF_VISIBLE)
-      new ShelfResetHandler(shelf);
     return true;
   }
 
diff --git a/ash/wm/gestures/two_finger_drag_handler.cc b/ash/wm/gestures/two_finger_drag_handler.cc
index 9decd47..53475fe 100644
--- a/ash/wm/gestures/two_finger_drag_handler.cc
+++ b/ash/wm/gestures/two_finger_drag_handler.cc
@@ -107,7 +107,7 @@
     return false;
   }
 
-  if (!window_resizer_.get()) {
+  if (!window_resizer_) {
     // Consume all two-finger gestures on a normal window.
     return event.details().touch_points() == 2 &&
            target->type() == aura::client::WINDOW_TYPE_NORMAL &&
diff --git a/ash/wm/image_cursors.cc b/ash/wm/image_cursors.cc
index 1792c6c..3d8e4ab 100644
--- a/ash/wm/image_cursors.cc
+++ b/ash/wm/image_cursors.cc
@@ -6,84 +6,54 @@
 
 #include "base/logging.h"
 #include "base/string16.h"
-#include "ui/base/cursor/cursor_loader.h"
 #include "ui/base/cursor/cursor.h"
+#include "ui/base/cursor/cursor_loader.h"
+#include "ui/base/cursor/cursors_aura.h"
 #include "ui/gfx/display.h"
 #include "ui/gfx/point.h"
-#include "grit/ash_resources.h"
-#include "grit/ui_resources.h"
-
-namespace {
-
-const int kAnimatedCursorFrameDelayMs = 25;
-
-struct HotPoint {
-  int x;
-  int y;
-};
-
-struct CursorData {
-  int id;
-  int resource_id;
-  HotPoint hot_1x;
-  HotPoint hot_2x;
-};
-
-// TODO(oshima): Remove this comment (http://crbug.com/141586).
-// The cursor's hot points are defined in chromeos cursor images at:
-// http://folder/kuscher/projects/Chrome_OS/Pointers/focuspoint
-const CursorData kImageCursors[] = {
-  {ui::kCursorNull, IDR_AURA_CURSOR_PTR, {4, 4}, {8, 9}},
-  {ui::kCursorPointer, IDR_AURA_CURSOR_PTR, {4, 4}, {8, 9}},
-  {ui::kCursorNoDrop, IDR_AURA_CURSOR_NO_DROP, {9, 9}, {18, 18}},
-  {ui::kCursorNotAllowed, IDR_AURA_CURSOR_NO_DROP, {9, 9}, {18, 18}},
-  {ui::kCursorCopy, IDR_AURA_CURSOR_COPY, {9, 9}, {18, 18}},
-  {ui::kCursorHand, IDR_AURA_CURSOR_HAND, {9, 4}, {19, 8}},
-  {ui::kCursorMove, IDR_AURA_CURSOR_MOVE, {11, 11}, {23, 23}},
-  {ui::kCursorNorthEastResize, IDR_AURA_CURSOR_NORTH_EAST_RESIZE,
-   {12, 11}, {25, 23}},
-  {ui::kCursorSouthWestResize, IDR_AURA_CURSOR_SOUTH_WEST_RESIZE,
-   {12, 11}, {25, 23}},
-  {ui::kCursorSouthEastResize, IDR_AURA_CURSOR_SOUTH_EAST_RESIZE,
-   {11, 11}, {24, 23}},
-  {ui::kCursorNorthWestResize, IDR_AURA_CURSOR_NORTH_WEST_RESIZE,
-   {11, 11}, {24, 23}},
-  {ui::kCursorNorthResize, IDR_AURA_CURSOR_NORTH_RESIZE, {11, 12}, {23, 23}},
-  {ui::kCursorSouthResize, IDR_AURA_CURSOR_SOUTH_RESIZE, {11, 12}, {23, 23}},
-  {ui::kCursorEastResize, IDR_AURA_CURSOR_EAST_RESIZE, {12, 11}, {25, 23}},
-  {ui::kCursorWestResize, IDR_AURA_CURSOR_WEST_RESIZE, {12, 11}, {25, 23}},
-  {ui::kCursorIBeam, IDR_AURA_CURSOR_IBEAM, {12, 12}, {24, 25}},
-  {ui::kCursorAlias, IDR_AURA_CURSOR_ALIAS, {8, 6}, {15, 11}},
-  {ui::kCursorCell, IDR_AURA_CURSOR_CELL, {11, 11}, {24, 23}},
-  {ui::kCursorContextMenu, IDR_AURA_CURSOR_CONTEXT_MENU, {4, 4}, {8, 9}},
-  {ui::kCursorCross, IDR_AURA_CURSOR_CROSSHAIR, {12, 12}, {25, 23}},
-  {ui::kCursorHelp, IDR_AURA_CURSOR_HELP, {4, 4}, {8, 9}},
-  {ui::kCursorVerticalText, IDR_AURA_CURSOR_XTERM_HORIZ, {12, 11}, {26, 23}},
-  {ui::kCursorZoomIn, IDR_AURA_CURSOR_ZOOM_IN, {10, 10}, {20, 20}},
-  {ui::kCursorZoomOut, IDR_AURA_CURSOR_ZOOM_OUT, {10, 10}, {20, 20}},
-  {ui::kCursorRowResize, IDR_AURA_CURSOR_ROW_RESIZE, {11, 12}, {23, 23}},
-  {ui::kCursorColumnResize, IDR_AURA_CURSOR_COL_RESIZE, {12, 11}, {25, 23}},
-  {ui::kCursorEastWestResize, IDR_AURA_CURSOR_EAST_WEST_RESIZE,
-   {12, 11}, {25, 23}},
-  {ui::kCursorNorthSouthResize, IDR_AURA_CURSOR_NORTH_SOUTH_RESIZE,
-   {11, 12}, {23, 23}},
-  {ui::kCursorNorthEastSouthWestResize,
-   IDR_AURA_CURSOR_NORTH_EAST_SOUTH_WEST_RESIZE, {12, 11}, {25, 23}},
-  {ui::kCursorNorthWestSouthEastResize,
-   IDR_AURA_CURSOR_NORTH_WEST_SOUTH_EAST_RESIZE, {11, 11}, {24, 23}},
-  {ui::kCursorGrab, IDR_AURA_CURSOR_GRAB, {8, 5}, {16, 10}},
-  {ui::kCursorGrabbing, IDR_AURA_CURSOR_GRABBING, {9, 9}, {18, 18}},
-};
-
-const CursorData kAnimatedCursors[] = {
-  {ui::kCursorWait, IDR_THROBBER, {7, 7}, {14, 14}},
-  {ui::kCursorProgress, IDR_THROBBER, {7, 7}, {14, 14}},
-};
-
-}  // namespace
 
 namespace ash {
 
+const int kImageCursorIds[] = {
+  ui::kCursorNull,
+  ui::kCursorPointer,
+  ui::kCursorNoDrop,
+  ui::kCursorNotAllowed,
+  ui::kCursorCopy,
+  ui::kCursorHand,
+  ui::kCursorMove,
+  ui::kCursorNorthEastResize,
+  ui::kCursorSouthWestResize,
+  ui::kCursorSouthEastResize,
+  ui::kCursorNorthWestResize,
+  ui::kCursorNorthResize,
+  ui::kCursorSouthResize,
+  ui::kCursorEastResize,
+  ui::kCursorWestResize,
+  ui::kCursorIBeam,
+  ui::kCursorAlias,
+  ui::kCursorCell,
+  ui::kCursorContextMenu,
+  ui::kCursorCross,
+  ui::kCursorHelp,
+  ui::kCursorVerticalText,
+  ui::kCursorZoomIn,
+  ui::kCursorZoomOut,
+  ui::kCursorRowResize,
+  ui::kCursorColumnResize,
+  ui::kCursorEastWestResize,
+  ui::kCursorNorthSouthResize,
+  ui::kCursorNorthEastSouthWestResize,
+  ui::kCursorNorthWestSouthEastResize,
+  ui::kCursorGrab,
+  ui::kCursorGrabbing,
+};
+
+const int kAnimatedCursorIds[] = {
+  ui::kCursorWait,
+  ui::kCursorProgress
+};
+
 ImageCursors::ImageCursors() {
 }
 
@@ -91,7 +61,7 @@
 }
 
 gfx::Display ImageCursors::GetDisplay() const {
-  if (!cursor_loader_.get()) {
+  if (!cursor_loader_) {
     NOTREACHED();
     // Returning default on release build as it's not serious enough to crash
     // even if this ever happens.
@@ -102,7 +72,7 @@
 
 bool ImageCursors::SetDisplay(const gfx::Display& display) {
   float device_scale_factor = display.device_scale_factor();
-  if (!cursor_loader_.get()) {
+  if (!cursor_loader_) {
     cursor_loader_.reset(ui::CursorLoader::Create());
   } else if (cursor_loader_->display().rotation() == display.rotation() &&
              cursor_loader_->display().device_scale_factor() ==
@@ -113,20 +83,28 @@
   cursor_loader_->UnloadAll();
   cursor_loader_->set_display(display);
 
-  for (size_t i = 0; i < arraysize(kImageCursors); ++i) {
-    const HotPoint& hot = device_scale_factor == 1.0f ?
-        kImageCursors[i].hot_1x : kImageCursors[i].hot_2x;
-    cursor_loader_->LoadImageCursor(kImageCursors[i].id,
-                                    kImageCursors[i].resource_id,
-                                    gfx::Point(hot.x, hot.y));
+  for (size_t i = 0; i < arraysize(kImageCursorIds); ++i) {
+    int resource_id = -1;
+    gfx::Point hot_point;
+    bool success = ui::GetCursorDataFor(kImageCursorIds[i],
+                                        device_scale_factor,
+                                        &resource_id,
+                                        &hot_point);
+    DCHECK(success);
+    cursor_loader_->LoadImageCursor(kImageCursorIds[i], resource_id, hot_point);
   }
-  for (size_t i = 0; i < arraysize(kAnimatedCursors); ++i) {
-    const HotPoint& hot = device_scale_factor == 1.0f ?
-        kAnimatedCursors[i].hot_1x : kAnimatedCursors[i].hot_2x;
-    cursor_loader_->LoadAnimatedCursor(kAnimatedCursors[i].id,
-                                       kAnimatedCursors[i].resource_id,
-                                       gfx::Point(hot.x, hot.y),
-                                       kAnimatedCursorFrameDelayMs);
+  for (size_t i = 0; i < arraysize(kAnimatedCursorIds); ++i) {
+    int resource_id = -1;
+    gfx::Point hot_point;
+    bool success = ui::GetAnimatedCursorDataFor(kAnimatedCursorIds[i],
+                                                device_scale_factor,
+                                                &resource_id,
+                                                &hot_point);
+    DCHECK(success);
+    cursor_loader_->LoadAnimatedCursor(kAnimatedCursorIds[i],
+                                       resource_id,
+                                       hot_point,
+                                       ui::kAnimatedCursorFrameDelayMs);
   }
   return true;
 }
@@ -135,7 +113,7 @@
   cursor_loader_->SetPlatformCursor(cursor);
 }
 
-void ImageCursors::SetCursorResourceModule(const string16& module_name) {
+void ImageCursors::SetCursorResourceModule(const base::string16& module_name) {
   cursor_loader_->SetCursorResourceModule(module_name);
 }
 
diff --git a/ash/wm/image_cursors.h b/ash/wm/image_cursors.h
index 3f1e609..f7bcfd6 100644
--- a/ash/wm/image_cursors.h
+++ b/ash/wm/image_cursors.h
@@ -41,7 +41,7 @@
   void SetPlatformCursor(gfx::NativeCursor* cursor);
 
   // Sets the cursor resource module name for non system cursors.
-  void SetCursorResourceModule(const string16& module_name);
+  void SetCursorResourceModule(const base::string16& module_name);
 
  private:
   scoped_ptr<ui::CursorLoader> cursor_loader_;
diff --git a/ash/wm/maximize_bubble_controller.cc b/ash/wm/maximize_bubble_controller.cc
index fa5b2ed..f2e3acb 100644
--- a/ash/wm/maximize_bubble_controller.cc
+++ b/ash/wm/maximize_bubble_controller.cc
@@ -429,7 +429,7 @@
     StartFade(true);
 
   ash::Shell::GetInstance()->delegate()->RecordUserMetricsAction(
-      ash::UMA_MAXIMIZE_BUTTON_SHOW_BUBBLE);
+      ash::UMA_WINDOW_MAXIMIZE_BUTTON_SHOW_BUBBLE);
 
   mouse_watcher_.reset(new views::MouseWatcher(
       new BubbleMouseWatcherHost(this),
@@ -798,7 +798,7 @@
 
 void MaximizeBubbleController::RequestDestructionThroughOwner() {
   // Tell the parent to destroy us (if this didn't happen yet).
-  if (timer_.get()) {
+  if (timer_) {
     timer_.reset(NULL);
     // Informs the owner that the menu is gone and requests |this| destruction.
     frame_maximize_button_->DestroyMaximizeMenu();
diff --git a/ash/wm/panels/panel_frame_view.cc b/ash/wm/panels/panel_frame_view.cc
index 176547b..c2fc6ca 100644
--- a/ash/wm/panels/panel_frame_view.cc
+++ b/ash/wm/panels/panel_frame_view.cc
@@ -58,8 +58,14 @@
                        FramePainter::SIZE_BUTTON_MINIMIZES);
 }
 
+gfx::Size PanelFrameView::GetMinimumSize() {
+  if (!frame_painter_)
+    return gfx::Size();
+  return frame_painter_->GetMinimumSize(this);
+}
+
 void PanelFrameView::Layout() {
-  if (!frame_painter_.get())
+  if (!frame_painter_)
     return;
   frame_painter_->LayoutHeader(this, true);
 }
@@ -80,7 +86,7 @@
 }
 
 void PanelFrameView::UpdateWindowTitle() {
-  if (!frame_painter_.get())
+  if (!frame_painter_)
     return;
   frame_painter_->SchedulePaintForTitle(this, title_font_);
 }
@@ -90,13 +96,13 @@
 }
 
 int PanelFrameView::NonClientHitTest(const gfx::Point& point) {
-  if (!frame_painter_.get())
+  if (!frame_painter_)
     return HTNOWHERE;
   return frame_painter_->NonClientHitTest(this, point);
 }
 
 void PanelFrameView::OnPaint(gfx::Canvas* canvas) {
-  if (!frame_painter_.get())
+  if (!frame_painter_)
     return;
   bool paint_as_active = ShouldPaintAsActive();
   int theme_image_id = paint_as_active ? IDR_AURA_WINDOW_HEADER_BASE_ACTIVE :
@@ -112,7 +118,7 @@
 }
 
 gfx::Rect PanelFrameView::GetBoundsForClientView() const {
-  if (!frame_painter_.get())
+  if (!frame_painter_)
     return bounds();
   return frame_painter_->GetBoundsForClientView(
       close_button_->bounds().bottom(),
@@ -121,7 +127,7 @@
 
 gfx::Rect PanelFrameView::GetWindowBoundsForClientBounds(
     const gfx::Rect& client_bounds) const {
-  if (!frame_painter_.get())
+  if (!frame_painter_)
     return client_bounds;
   return frame_painter_->GetWindowBoundsForClientBounds(
       close_button_->bounds().bottom(), client_bounds);
diff --git a/ash/wm/panels/panel_frame_view.h b/ash/wm/panels/panel_frame_view.h
index eaab9f1..1ce6f26 100644
--- a/ash/wm/panels/panel_frame_view.h
+++ b/ash/wm/panels/panel_frame_view.h
@@ -46,6 +46,7 @@
   virtual void UpdateWindowTitle() OVERRIDE;
 
   // Overridden from views::View:
+  virtual gfx::Size GetMinimumSize() OVERRIDE;
   virtual void Layout() OVERRIDE;
   virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
 
diff --git a/ash/wm/panels/panel_layout_manager.cc b/ash/wm/panels/panel_layout_manager.cc
index 11f443b..d28b77c 100644
--- a/ash/wm/panels/panel_layout_manager.cc
+++ b/ash/wm/panels/panel_layout_manager.cc
@@ -27,8 +27,10 @@
 #include "ui/aura/focus_manager.h"
 #include "ui/aura/root_window.h"
 #include "ui/aura/window.h"
+#include "ui/compositor/scoped_layer_animation_settings.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/rect.h"
+#include "ui/gfx/vector2d.h"
 #include "ui/views/background.h"
 #include "ui/views/widget/widget.h"
 
@@ -43,9 +45,17 @@
 const float kMaxHeightFactor = .80f;
 const float kMaxWidthFactor = .50f;
 
+// Duration for panel animations.
+const int kPanelSlideDurationMilliseconds = 50;
+const int kCalloutFadeDurationMilliseconds = 50;
+
+// Offset used when sliding panel in/out of the launcher. Used for minimizing,
+// restoring and the initial showing of a panel.
+const int kPanelSlideInOffset = 20;
+
 // Callout arrow dimensions.
-const int kArrowWidth = 20;
-const int kArrowHeight = 10;
+const int kArrowWidth = 18;
+const int kArrowHeight = 9;
 
 class CalloutWidgetBackground : public views::Background {
  public:
@@ -78,11 +88,10 @@
         path.lineTo(SkIntToScalar(0), SkIntToScalar(kArrowWidth));
         break;
     }
-    // Use the same opacity and colors as the header for now.
+    // Hard code the arrow color for now.
     SkPaint paint;
     paint.setStyle(SkPaint::kFill_Style);
-    paint.setColor(
-        SkColorSetARGB(FramePainter::kActiveWindowOpacity, 189, 189, 189));
+    paint.setColor(SkColorSetARGB(0xff, 0xe5, 0xe5, 0xe5));
     canvas->DrawPath(path, paint);
   }
 
@@ -102,13 +111,15 @@
         max_major(0),
         major_pos(0),
         major_length(0),
-        window(NULL) {}
+        window(NULL),
+        slide_in(false) {}
 
   int min_major;
   int max_major;
   int major_pos;
   int major_length;
   aura::Window* window;
+  bool slide_in;
 };
 
 bool CompareWindowMajor(const VisiblePanelPositionInfo& win1,
@@ -119,6 +130,10 @@
 void FanOutPanels(std::vector<VisiblePanelPositionInfo>::iterator first,
                   std::vector<VisiblePanelPositionInfo>::iterator last) {
   int num_panels = last - first;
+  if (num_panels == 1) {
+    (*first).major_pos = std::max((*first).min_major, std::min(
+        (*first).max_major, (*first).major_pos));
+  }
   if (num_panels <= 1)
     return;
 
@@ -152,6 +167,32 @@
   }
 }
 
+bool BoundsAdjacent(const gfx::Rect& bounds1, const gfx::Rect& bounds2) {
+  return bounds1.x() == bounds2.right() ||
+         bounds1.y() == bounds2.bottom() ||
+         bounds1.right() == bounds2.x() ||
+         bounds1.bottom() == bounds2.y();
+}
+
+gfx::Vector2d GetSlideInAnimationOffset(ShelfAlignment alignment) {
+  gfx::Vector2d offset;
+  switch (alignment) {
+    case SHELF_ALIGNMENT_BOTTOM:
+      offset.set_y(kPanelSlideInOffset);
+      break;
+    case SHELF_ALIGNMENT_LEFT:
+      offset.set_x(-kPanelSlideInOffset);
+      break;
+    case SHELF_ALIGNMENT_RIGHT:
+      offset.set_x(kPanelSlideInOffset);
+      break;
+    case SHELF_ALIGNMENT_TOP:
+      offset.set_y(-kPanelSlideInOffset);
+      break;
+  }
+  return offset;
+}
+
 }  // namespace
 
 class PanelCalloutWidget : public views::Widget {
@@ -195,6 +236,7 @@
     background_ = new CalloutWidgetBackground;
     content_view->set_background(background_);
     SetContentsView(content_view);
+    GetNativeWindow()->layer()->SetOpacity(0);
   }
 
   // Weak pointer owned by this widget's content view.
@@ -210,6 +252,8 @@
       in_layout_(false),
       dragged_panel_(NULL),
       launcher_(NULL),
+      shelf_layout_manager_(NULL),
+      shelf_hidden_(false),
       last_active_panel_(NULL),
       weak_factory_(this) {
   DCHECK(panel_container);
@@ -219,6 +263,10 @@
 }
 
 PanelLayoutManager::~PanelLayoutManager() {
+  if (launcher_)
+    launcher_->RemoveIconObserver(this);
+  if (shelf_layout_manager_)
+    shelf_layout_manager_->RemoveObserver(this);
   Shutdown();
   aura::client::GetActivationClient(Shell::GetPrimaryRootWindow())->
       RemoveObserver(this);
@@ -248,8 +296,16 @@
 }
 
 void PanelLayoutManager::SetLauncher(ash::Launcher* launcher) {
+  DCHECK(!launcher_);
+  DCHECK(!shelf_layout_manager_);
   launcher_ = launcher;
   launcher_->AddIconObserver(this);
+  if (launcher_->shelf_widget()) {
+    shelf_layout_manager_ = ash::internal::ShelfLayoutManager::ForLauncher(
+        launcher_->shelf_widget()->GetNativeWindow());
+    WillChangeVisibilityState(shelf_layout_manager_->visibility_state());
+    shelf_layout_manager_->AddObserver(this);
+  }
 }
 
 void PanelLayoutManager::ToggleMinimize(aura::Window* panel) {
@@ -274,6 +330,12 @@
   PanelInfo panel_info;
   panel_info.window = child;
   panel_info.callout_widget = new PanelCalloutWidget(panel_container_);
+  if (child != dragged_panel_) {
+    // Set the panel to 0 opacity until it has been positioned to prevent it
+    // from flashing briefly at position (0, 0).
+    child->layer()->SetOpacity(0);
+    panel_info.slide_in = true;
+  }
   panel_windows_.push_back(panel_info);
   child->AddObserver(this);
   Relayout();
@@ -368,6 +430,10 @@
                                                  intptr_t old) {
   if (key != aura::client::kShowStateKey)
     return;
+  // The window property will still be set, but no actual change will occur
+  // until WillChangeVisibilityState is called when the shelf is visible again.
+  if (shelf_hidden_)
+    return;
   ui::WindowShowState new_state =
       window->GetProperty(aura::client::kShowStateKey);
   if (new_state == ui::SHOW_STATE_MINIMIZED)
@@ -397,12 +463,52 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
+// PanelLayoutManager, ShelfLayoutManager::Observer implementation:
+
+void PanelLayoutManager::WillChangeVisibilityState(
+    ShelfVisibilityState new_state) {
+  // On entering / leaving full screen mode the shelf visibility state is
+  // changed to / from SHELF_HIDDEN. In this state, panel windows should hide
+  // to allow the full-screen application to use the full screen.
+  shelf_hidden_ = new_state == ash::SHELF_HIDDEN;
+  for (PanelList::iterator iter = panel_windows_.begin();
+       iter != panel_windows_.end(); ++iter) {
+    if (shelf_hidden_) {
+      if (iter->window->IsVisible())
+        MinimizePanel(iter->window);
+    } else {
+      if (iter->window->GetProperty(aura::client::kShowStateKey) !=
+              ui::SHOW_STATE_MINIMIZED) {
+        RestorePanel(iter->window);
+      }
+    }
+  }
+}
+
+////////////////////////////////////////////////////////////////////////////////
 // PanelLayoutManager private implementation:
 
 void PanelLayoutManager::MinimizePanel(aura::Window* panel) {
   views::corewm::SetWindowVisibilityAnimationType(
       panel, WINDOW_VISIBILITY_ANIMATION_TYPE_MINIMIZE);
+  ui::Layer* layer = panel->layer();
+  ui::ScopedLayerAnimationSettings panel_slide_settings(layer->GetAnimator());
+  panel_slide_settings.SetPreemptionStrategy(
+      ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+  panel_slide_settings.SetTransitionDuration(
+      base::TimeDelta::FromMilliseconds(kPanelSlideDurationMilliseconds));
+  gfx::Rect bounds(panel->bounds());
+  bounds.Offset(GetSlideInAnimationOffset(
+      launcher_->shelf_widget()->GetAlignment()));
+  SetChildBoundsDirect(panel, bounds);
   panel->Hide();
+  PanelList::iterator found =
+      std::find(panel_windows_.begin(), panel_windows_.end(), panel);
+  if (found != panel_windows_.end()) {
+    layer->SetOpacity(0);
+    // The next time the window is visible it should slide into place.
+    found->slide_in = true;
+  }
   if (wm::IsActiveWindow(panel))
     wm::DeactivateWindow(panel);
   Relayout();
@@ -424,8 +530,8 @@
   ShelfAlignment alignment = launcher_->shelf_widget()->GetAlignment();
   bool horizontal = alignment == SHELF_ALIGNMENT_TOP ||
                     alignment == SHELF_ALIGNMENT_BOTTOM;
-  gfx::Rect launcher_bounds = launcher_->shelf_widget()->
-      GetWindowBoundsInScreen();
+  gfx::Rect launcher_bounds = ash::ScreenAsh::ConvertRectFromScreen(
+      panel_container_, launcher_->shelf_widget()->GetWindowBoundsInScreen());
   int panel_start_bounds = kPanelIdealSpacing;
   int panel_end_bounds = horizontal ?
       panel_container_->bounds().width() - kPanelIdealSpacing :
@@ -436,16 +542,32 @@
        iter != panel_windows_.end(); ++iter) {
     aura::Window* panel = iter->window;
     iter->callout_widget->SetAlignment(alignment);
-    if (!panel->IsVisible() || panel == dragged_panel_)
+
+    // Consider the dragged panel as part of the layout as long as it is
+    // touching the launcher.
+    if (!panel->IsVisible() ||
+        (panel == dragged_panel_ &&
+         !BoundsAdjacent(panel->bounds(), launcher_bounds))) {
       continue;
+    }
+
+    // If the shelf is currently hidden (full-screen mode), hide panel until
+    // full-screen mode is exited.
+    if (shelf_hidden_) {
+      // The call to Hide does not set the minimize property, so the window will
+      // be restored when the shelf becomes visible again.
+      panel->Hide();
+      continue;
+    }
 
     gfx::Rect icon_bounds =
         launcher_->GetScreenBoundsOfItemIconForWindow(panel);
 
-    // An empty rect indicates that there is no icon for the panel in the
-    // launcher. Just use the current bounds, as there's no icon to draw the
-    // panel above.
-    if (icon_bounds.IsEmpty())
+    // If both the icon width and height are 0 then there is no icon in the
+    // launcher. If the launcher is hidden, one of the height or width will be
+    // 0 but the position in the launcher and major dimension is still reported
+    // correctly and the panel can be aligned above where the hidden icon is.
+    if (icon_bounds.width() == 0 && icon_bounds.height() == 0)
       continue;
 
     if (panel->HasFocus() ||
@@ -471,6 +593,8 @@
         panel_end_bounds - position_info.major_length / 2);
     position_info.major_pos = (icon_start + icon_end) / 2;
     position_info.window = panel;
+    position_info.slide_in = iter->slide_in;
+    iter->slide_in = false;
     visible_panels.push_back(position_info);
   }
 
@@ -494,13 +618,10 @@
                visible_panels.end());
 
   for (size_t i = 0; i < visible_panels.size(); ++i) {
-    gfx::Rect bounds = visible_panels[i].window->bounds();
-    if (horizontal)
-      bounds.set_x(visible_panels[i].major_pos -
-                   visible_panels[i].major_length / 2);
-    else
-      bounds.set_y(visible_panels[i].major_pos -
-                   visible_panels[i].major_length / 2);
+    if (visible_panels[i].window == dragged_panel_)
+      continue;
+    bool slide_in = visible_panels[i].slide_in;
+    gfx::Rect bounds = visible_panels[i].window->GetTargetBounds();
     switch (alignment) {
       case SHELF_ALIGNMENT_BOTTOM:
         bounds.set_y(launcher_bounds.y() - bounds.height());
@@ -515,7 +636,41 @@
         bounds.set_y(launcher_bounds.bottom());
         break;
     }
-    SetChildBoundsDirect(visible_panels[i].window, bounds);
+    bool on_launcher = visible_panels[i].window->GetTargetBounds() == bounds;
+
+    if (horizontal) {
+      bounds.set_x(visible_panels[i].major_pos -
+                   visible_panels[i].major_length / 2);
+    } else {
+      bounds.set_y(visible_panels[i].major_pos -
+                   visible_panels[i].major_length / 2);
+    }
+
+    ui::Layer* layer = visible_panels[i].window->layer();
+    if (slide_in) {
+      // New windows shift up from the launcher  into position.
+      gfx::Rect initial_bounds(bounds);
+      initial_bounds.Offset(GetSlideInAnimationOffset(alignment));
+      SetChildBoundsDirect(visible_panels[i].window, initial_bounds);
+      // Set on launcher so that the panel animates into its target position.
+      on_launcher = true;
+    }
+
+    if (on_launcher) {
+      ui::ScopedLayerAnimationSettings panel_slide_settings(
+          layer->GetAnimator());
+      panel_slide_settings.SetPreemptionStrategy(
+          ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+      panel_slide_settings.SetTransitionDuration(
+          base::TimeDelta::FromMilliseconds(kPanelSlideDurationMilliseconds));
+      SetChildBoundsDirect(visible_panels[i].window, bounds);
+      if (slide_in)
+        layer->SetOpacity(1);
+    } else {
+      // If the launcher moved don't animate, move immediately to the new
+      // target location.
+      SetChildBoundsDirect(visible_panels[i].window, bounds);
+    }
   }
 
   UpdateStacking(active_panel);
@@ -580,23 +735,35 @@
     aura::Window* panel = iter->window;
     views::Widget* callout_widget = iter->callout_widget;
 
-    gfx::Rect bounds = panel->GetBoundsInRootWindow();
+    gfx::Rect current_bounds = panel->GetBoundsInScreen();
+    gfx::Rect bounds = ScreenAsh::ConvertRectToScreen(panel->parent(),
+                                                      panel->GetTargetBounds());
     gfx::Rect icon_bounds =
         launcher_->GetScreenBoundsOfItemIconForWindow(panel);
-    if (icon_bounds.IsEmpty() || !panel->IsVisible() ||
+    if (icon_bounds.IsEmpty() || !panel->layer()->GetTargetVisibility() ||
         panel == dragged_panel_) {
       callout_widget->Hide();
+      callout_widget->GetNativeWindow()->layer()->SetOpacity(0);
       continue;
     }
 
     gfx::Rect callout_bounds = callout_widget->GetWindowBoundsInScreen();
+    gfx::Vector2d slide_vector = bounds.origin() - current_bounds.origin();
+    int slide_distance = horizontal ? slide_vector.x() : slide_vector.y();
+    int distance_until_over_panel = 0;
     if (horizontal) {
       callout_bounds.set_x(
           icon_bounds.x() + (icon_bounds.width() - callout_bounds.width()) / 2);
+      distance_until_over_panel = std::max(
+          current_bounds.x() - callout_bounds.x(),
+          callout_bounds.right() - current_bounds.right());
     } else {
       callout_bounds.set_y(
           icon_bounds.y() + (icon_bounds.height() -
                              callout_bounds.height()) / 2);
+      distance_until_over_panel = std::max(
+          current_bounds.y() - callout_bounds.y(),
+          callout_bounds.bottom() - current_bounds.bottom());
     }
     switch (alignment) {
       case SHELF_ALIGNMENT_BOTTOM:
@@ -620,8 +787,46 @@
     panel_container_->StackChildAbove(callout_widget->GetNativeWindow(),
                                       panel);
     callout_widget->Show();
+
+    ui::Layer* layer = callout_widget->GetNativeWindow()->layer();
+    // If the panel is not over the callout position or has just become visible
+    // then fade in the callout.
+    if (distance_until_over_panel > 0 || layer->GetTargetOpacity() < 1) {
+      if (distance_until_over_panel > 0 &&
+          slide_distance >= distance_until_over_panel) {
+        layer->SetOpacity(0);
+        // If the panel is not yet over the callout, then delay fading in
+        // the callout until after the panel should be over it.
+        int delay = kPanelSlideDurationMilliseconds *
+            distance_until_over_panel / slide_distance;
+        layer->SetOpacity(0);
+        layer->GetAnimator()->StopAnimating();
+        layer->GetAnimator()->SchedulePauseForProperties(
+            base::TimeDelta::FromMilliseconds(delay),
+            ui::LayerAnimationElement::OPACITY);
+      }
+      {
+        ui::ScopedLayerAnimationSettings callout_settings(layer->GetAnimator());
+        callout_settings.SetPreemptionStrategy(
+            ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS);
+        callout_settings.SetTransitionDuration(
+            base::TimeDelta::FromMilliseconds(
+                kCalloutFadeDurationMilliseconds));
+        layer->SetOpacity(1);
+      }
+    }
   }
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// keyboard::KeyboardControllerObserver implementation:
+
+void PanelLayoutManager::OnKeyboardBoundsChanging(
+    const gfx::Rect& keyboard_bounds) {
+  // This bounds change will have caused a change to the Shelf which does not
+  // propogate automatically to this class, so manually recalculate bounds.
+  OnWindowResized();
+}
+
 }  // namespace internal
 }  // namespace ash
diff --git a/ash/wm/panels/panel_layout_manager.h b/ash/wm/panels/panel_layout_manager.h
index 41a894a..7407bd9 100644
--- a/ash/wm/panels/panel_layout_manager.h
+++ b/ash/wm/panels/panel_layout_manager.h
@@ -9,6 +9,7 @@
 
 #include "ash/ash_export.h"
 #include "ash/launcher/launcher_icon_observer.h"
+#include "ash/shelf/shelf_layout_manager.h"
 #include "ash/shell_observer.h"
 #include "base/basictypes.h"
 #include "base/compiler_specific.h"
@@ -17,6 +18,8 @@
 #include "ui/aura/client/activation_change_observer.h"
 #include "ui/aura/layout_manager.h"
 #include "ui/aura/window_observer.h"
+#include "ui/keyboard/keyboard_controller.h"
+#include "ui/keyboard/keyboard_controller_observer.h"
 
 namespace aura {
 class Window;
@@ -50,7 +53,9 @@
       public ash::LauncherIconObserver,
       public ash::ShellObserver,
       public aura::WindowObserver,
-      public aura::client::ActivationChangeObserver {
+      public aura::client::ActivationChangeObserver,
+      public keyboard::KeyboardControllerObserver,
+      public ShelfLayoutManager::Observer {
  public:
   explicit PanelLayoutManager(aura::Window* panel_container);
   virtual ~PanelLayoutManager();
@@ -93,6 +98,10 @@
   virtual void OnWindowActivated(aura::Window* gained_active,
                                  aura::Window* lost_active) OVERRIDE;
 
+  // Overridden from ShelfLayoutManager::Observer
+  virtual void WillChangeVisibilityState(
+      ShelfVisibilityState new_state) OVERRIDE;
+
  private:
   friend class PanelLayoutManagerTest;
   friend class PanelWindowResizerTest;
@@ -100,7 +109,7 @@
   views::Widget* CreateCalloutWidget();
 
   struct PanelInfo{
-    PanelInfo() : window(NULL), callout_widget(NULL) {}
+    PanelInfo() : window(NULL), callout_widget(NULL), slide_in(false) {}
 
     bool operator==(const aura::Window* other_window) const {
       return window == other_window;
@@ -112,6 +121,11 @@
     // manually as this structure is used in a std::list. See
     // http://www.chromium.org/developers/smart-pointer-guidelines
     PanelCalloutWidget* callout_widget;
+
+    // True on new and restored panel windows until the panel has been
+    // positioned. The first time Relayout is called the panel will slide into
+    // position and this will be set to false.
+    bool slide_in;
   };
 
   typedef std::list<PanelInfo> PanelList;
@@ -129,6 +143,10 @@
   // Update the callout arrows for all managed panels.
   void UpdateCallouts();
 
+  // Overridden from keyboard::KeyboardControllerObserver:
+  virtual void OnKeyboardBoundsChanging(
+      const gfx::Rect& keyboard_bounds) OVERRIDE;
+
   // Parent window associated with this layout manager.
   aura::Window* panel_container_;
   // Protect against recursive calls to Relayout().
@@ -139,6 +157,11 @@
   aura::Window* dragged_panel_;
   // The launcher we are observing for launcher icon changes.
   Launcher* launcher_;
+  // The shelf layout manager being observed for visibility changes.
+  ShelfLayoutManager* shelf_layout_manager_;
+  // Tracks the visibility of the shelf. Defaults to false when there is no
+  // shelf.
+  bool shelf_hidden_;
   // The last active panel. Used to maintain stacking even if no panels are
   // currently focused.
   aura::Window* last_active_panel_;
diff --git a/ash/wm/panels/panel_layout_manager_unittest.cc b/ash/wm/panels/panel_layout_manager_unittest.cc
index 4c0ca2f..f05e093 100644
--- a/ash/wm/panels/panel_layout_manager_unittest.cc
+++ b/ash/wm/panels/panel_layout_manager_unittest.cc
@@ -11,6 +11,7 @@
 #include "ash/launcher/launcher_view.h"
 #include "ash/root_window_controller.h"
 #include "ash/screen_ash.h"
+#include "ash/shelf/shelf_layout_manager.h"
 #include "ash/shelf/shelf_types.h"
 #include "ash/shelf/shelf_widget.h"
 #include "ash/shell.h"
@@ -65,20 +66,21 @@
         test::TestLauncherDelegate::instance();
     launcher_delegate->AddLauncherItem(window);
     PanelLayoutManager* manager =
-        static_cast<PanelLayoutManager*>(GetPanelContainer()->layout_manager());
+        static_cast<PanelLayoutManager*>(GetPanelContainer(window)->
+                                         layout_manager());
     manager->Relayout();
     return window;
   }
 
-  aura::Window* GetPanelContainer() {
-    return Shell::GetContainer(
-        Shell::GetPrimaryRootWindow(),
-        internal::kShellWindowId_PanelContainer);
+  aura::Window* GetPanelContainer(aura::Window* panel) {
+    return Shell::GetContainer(panel->GetRootWindow(),
+                               internal::kShellWindowId_PanelContainer);
   }
 
   views::Widget* GetCalloutWidgetForPanel(aura::Window* panel) {
     PanelLayoutManager* manager =
-        static_cast<PanelLayoutManager*>(GetPanelContainer()->layout_manager());
+        static_cast<PanelLayoutManager*>(GetPanelContainer(panel)->
+                                         layout_manager());
     DCHECK(manager);
     PanelLayoutManager::PanelList::iterator found = std::find(
         manager->panel_windows_.begin(), manager->panel_windows_.end(),
@@ -117,14 +119,15 @@
     // Waits until all launcher view animations are done.
     launcher_view_test()->RunMessageLoopUntilAnimationsDone();
 
-    Launcher* launcher = Launcher::ForPrimaryDisplay();
+    Launcher* launcher =
+        RootWindowController::ForLauncher(panel)->shelf()->launcher();
     gfx::Rect icon_bounds = launcher->GetScreenBoundsOfItemIconForWindow(panel);
-    ASSERT_FALSE(icon_bounds.IsEmpty());
+    ASSERT_FALSE(icon_bounds.width() == 0 && icon_bounds.height() == 0);
 
-    gfx::Rect window_bounds = panel->GetBoundsInRootWindow();
+    gfx::Rect window_bounds = panel->GetBoundsInScreen();
     gfx::Rect launcher_bounds = launcher->shelf_widget()->
         GetWindowBoundsInScreen();
-    ShelfAlignment alignment = GetAlignment();
+    ShelfAlignment alignment = GetAlignment(panel->GetRootWindow());
 
     if (IsHorizontal(alignment)) {
       // The horizontal bounds of the panel window should contain the bounds of
@@ -159,15 +162,18 @@
     base::RunLoop().RunUntilIdle();
     views::Widget* widget = GetCalloutWidgetForPanel(panel);
 
-    Launcher* launcher = Launcher::ForPrimaryDisplay();
+    Launcher* launcher =
+        RootWindowController::ForLauncher(panel)->shelf()->launcher();
     gfx::Rect icon_bounds = launcher->GetScreenBoundsOfItemIconForWindow(panel);
-    gfx::Rect panel_bounds = panel->GetBoundsInRootWindow();
+    ASSERT_FALSE(icon_bounds.IsEmpty());
+
+    gfx::Rect panel_bounds = panel->GetBoundsInScreen();
     gfx::Rect callout_bounds = widget->GetWindowBoundsInScreen();
     ASSERT_FALSE(icon_bounds.IsEmpty());
 
     EXPECT_TRUE(widget->IsVisible());
 
-    ShelfAlignment alignment = GetAlignment();
+    ShelfAlignment alignment = GetAlignment(panel->GetRootWindow());
     switch (alignment) {
       case SHELF_ALIGNMENT_BOTTOM:
         EXPECT_EQ(panel_bounds.bottom(), callout_bounds.y());
@@ -210,7 +216,6 @@
     test::LauncherViewTestAPI test_api(launcher_view);
     test_api.SetAnimationDuration(1);
     test_api.RunMessageLoopUntilAnimationsDone();
-
     LauncherModel* model =
         test::ShellTestApi(Shell::GetInstance()).launcher_model();
     test::TestLauncherDelegate* launcher_delegate =
@@ -225,14 +230,31 @@
     test_api.RunMessageLoopUntilAnimationsDone();
   }
 
-  void SetAlignment(ShelfAlignment alignment) {
+  void SetAlignment(aura::RootWindow* root_window, ShelfAlignment alignment) {
     ash::Shell* shell = ash::Shell::GetInstance();
-    shell->SetShelfAlignment(alignment, shell->GetPrimaryRootWindow());
+    shell->SetShelfAlignment(alignment, root_window);
   }
 
-  ShelfAlignment GetAlignment() {
+  ShelfAlignment GetAlignment(aura::RootWindow* root_window) {
     ash::Shell* shell = ash::Shell::GetInstance();
-    return shell->GetShelfAlignment(shell->GetPrimaryRootWindow());
+    return shell->GetShelfAlignment(root_window);
+  }
+
+  void SetShelfAutoHideBehavior(aura::Window* window,
+                                ShelfAutoHideBehavior behavior) {
+    internal::ShelfLayoutManager* shelf =
+        RootWindowController::ForWindow(window)->shelf()->
+        shelf_layout_manager();
+    shelf->SetAutoHideBehavior(behavior);
+    shelf->UpdateAutoHideState();
+  }
+
+  void SetShelfVisibilityState(aura::Window* window,
+                               ShelfVisibilityState visibility_state) {
+    internal::ShelfLayoutManager* shelf =
+        RootWindowController::ForWindow(window)->shelf()->
+        shelf_layout_manager();
+    shelf->SetState(visibility_state);
   }
 
  private:
@@ -251,7 +273,19 @@
 TEST_F(PanelLayoutManagerTest, AddOnePanel) {
   gfx::Rect bounds(0, 0, 201, 201);
   scoped_ptr<aura::Window> window(CreatePanelWindow(bounds));
-  EXPECT_EQ(GetPanelContainer(), window->parent());
+  EXPECT_EQ(GetPanelContainer(window.get()), window->parent());
+  EXPECT_NO_FATAL_FAILURE(IsPanelAboveLauncherIcon(window.get()));
+}
+
+// Tests that a created panel window is successfully aligned over a hidden
+// launcher icon.
+TEST_F(PanelLayoutManagerTest, PanelAlignsToHiddenLauncherIcon) {
+  gfx::Rect bounds(0, 0, 201, 201);
+  SetShelfAutoHideBehavior(Shell::GetPrimaryRootWindow(),
+                           SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
+  RunAllPendingInMessageLoop();
+  scoped_ptr<aura::Window> window(CreatePanelWindow(bounds));
+  EXPECT_EQ(GetPanelContainer(window.get()), window->parent());
   EXPECT_NO_FATAL_FAILURE(IsPanelAboveLauncherIcon(window.get()));
 }
 
@@ -472,13 +506,19 @@
 // http://crbug.com/165962
 #define MAYBE_PanelMoveBetweenMultipleDisplays \
         DISABLED_PanelMoveBetweenMultipleDisplays
+#define MAYBE_PanelAttachPositionMultipleDisplays \
+        DISABLED_PanelAttachPositionMultipleDisplays
+#define MAYBE_PanelAlignmentSecondDisplay DISABLED_PanelAlignmentSecondDisplay
 #else
 #define MAYBE_PanelMoveBetweenMultipleDisplays PanelMoveBetweenMultipleDisplays
+#define MAYBE_PanelAttachPositionMultipleDisplays \
+        PanelAttachPositionMultipleDisplays
+#define MAYBE_PanelAlignmentSecondDisplay PanelAlignmentSecondDisplay
 #endif
 
 TEST_F(PanelLayoutManagerTest, MAYBE_PanelMoveBetweenMultipleDisplays) {
   // Keep the displays wide so that launchers have enough
-  // spaces for launcher buttons.
+  // space for launcher buttons.
   UpdateDisplay("600x400,600x400");
   Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
 
@@ -543,10 +583,50 @@
       p1_d2->GetBoundsInScreen()));
 }
 
+TEST_F(PanelLayoutManagerTest, MAYBE_PanelAttachPositionMultipleDisplays) {
+  // Keep the displays wide so that launchers have enough space for launcher
+  // buttons. Use differently sized displays so the launcher is in a different
+  // position on second display.
+  UpdateDisplay("600x400,600x600");
+  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
+
+  scoped_ptr<aura::Window> p1_d1(CreatePanelWindow(gfx::Rect(0, 0, 50, 50)));
+  scoped_ptr<aura::Window> p1_d2(CreatePanelWindow(gfx::Rect(600, 0, 50, 50)));
+
+  EXPECT_EQ(root_windows[0], p1_d1->GetRootWindow());
+  EXPECT_EQ(root_windows[1], p1_d2->GetRootWindow());
+
+  IsPanelAboveLauncherIcon(p1_d1.get());
+  IsCalloutAboveLauncherIcon(p1_d1.get());
+  IsPanelAboveLauncherIcon(p1_d2.get());
+  IsCalloutAboveLauncherIcon(p1_d2.get());
+}
+
+TEST_F(PanelLayoutManagerTest, MAYBE_PanelAlignmentSecondDisplay) {
+  UpdateDisplay("600x400,600x400");
+  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
+
+  scoped_ptr<aura::Window> p1_d2(CreatePanelWindow(gfx::Rect(600, 0, 50, 50)));
+  EXPECT_EQ(root_windows[1], p1_d2->GetRootWindow());
+
+  IsPanelAboveLauncherIcon(p1_d2.get());
+  IsCalloutAboveLauncherIcon(p1_d2.get());
+
+  SetAlignment(root_windows[1], SHELF_ALIGNMENT_RIGHT);
+  IsPanelAboveLauncherIcon(p1_d2.get());
+  IsCalloutAboveLauncherIcon(p1_d2.get());
+  SetAlignment(root_windows[1], SHELF_ALIGNMENT_LEFT);
+  IsPanelAboveLauncherIcon(p1_d2.get());
+  IsCalloutAboveLauncherIcon(p1_d2.get());
+  SetAlignment(root_windows[1], SHELF_ALIGNMENT_TOP);
+  IsPanelAboveLauncherIcon(p1_d2.get());
+  IsCalloutAboveLauncherIcon(p1_d2.get());
+}
+
 TEST_F(PanelLayoutManagerTest, AlignmentLeft) {
   gfx::Rect bounds(0, 0, 201, 201);
   scoped_ptr<aura::Window> w(CreatePanelWindow(bounds));
-  SetAlignment(SHELF_ALIGNMENT_LEFT);
+  SetAlignment(Shell::GetPrimaryRootWindow(), SHELF_ALIGNMENT_LEFT);
   IsPanelAboveLauncherIcon(w.get());
   IsCalloutAboveLauncherIcon(w.get());
 }
@@ -554,7 +634,7 @@
 TEST_F(PanelLayoutManagerTest, AlignmentRight) {
   gfx::Rect bounds(0, 0, 201, 201);
   scoped_ptr<aura::Window> w(CreatePanelWindow(bounds));
-  SetAlignment(SHELF_ALIGNMENT_RIGHT);
+  SetAlignment(Shell::GetPrimaryRootWindow(), SHELF_ALIGNMENT_RIGHT);
   IsPanelAboveLauncherIcon(w.get());
   IsCalloutAboveLauncherIcon(w.get());
 }
@@ -562,10 +642,45 @@
 TEST_F(PanelLayoutManagerTest, AlignmentTop) {
   gfx::Rect bounds(0, 0, 201, 201);
   scoped_ptr<aura::Window> w(CreatePanelWindow(bounds));
-  SetAlignment(SHELF_ALIGNMENT_TOP);
+  SetAlignment(Shell::GetPrimaryRootWindow(), SHELF_ALIGNMENT_TOP);
   IsPanelAboveLauncherIcon(w.get());
   IsCalloutAboveLauncherIcon(w.get());
 }
 
+// Tests that panels will hide and restore their state with the shelf visibility
+// state. This ensures that entering full-screen mode will hide your panels
+// until you leave it.
+TEST_F(PanelLayoutManagerTest, PanelsHideAndRestoreWithShelf) {
+  gfx::Rect bounds(0, 0, 201, 201);
+
+  scoped_ptr<aura::Window> w1(CreatePanelWindow(bounds));
+  scoped_ptr<aura::Window> w2(CreatePanelWindow(bounds));
+  scoped_ptr<aura::Window> w3;
+  // Minimize w2.
+  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
+  RunAllPendingInMessageLoop();
+  EXPECT_TRUE(w1->IsVisible());
+  EXPECT_FALSE(w2->IsVisible());
+
+  SetShelfVisibilityState(Shell::GetPrimaryRootWindow(), SHELF_HIDDEN);
+  RunAllPendingInMessageLoop();
+
+  // w3 is created while in full-screen mode, should only become visible when
+  // we exit fullscreen mode.
+  w3.reset(CreatePanelWindow(bounds));
+
+  EXPECT_FALSE(w1->IsVisible());
+  EXPECT_FALSE(w2->IsVisible());
+  EXPECT_FALSE(w3->IsVisible());
+
+  SetShelfVisibilityState(Shell::GetPrimaryRootWindow(), SHELF_VISIBLE);
+  RunAllPendingInMessageLoop();
+
+  // Windows should be restored to their prior state.
+  EXPECT_TRUE(w1->IsVisible());
+  EXPECT_FALSE(w2->IsVisible());
+  EXPECT_TRUE(w3->IsVisible());
+}
+
 }  // namespace internal
 }  // namespace ash
diff --git a/ash/wm/panels/panel_window_resizer.cc b/ash/wm/panels/panel_window_resizer.cc
index 6e22118..947cf90 100644
--- a/ash/wm/panels/panel_window_resizer.cc
+++ b/ash/wm/panels/panel_window_resizer.cc
@@ -4,12 +4,15 @@
 
 #include "ash/wm/panels/panel_window_resizer.h"
 
+#include "ash/display/display_controller.h"
 #include "ash/launcher/launcher.h"
 #include "ash/root_window_controller.h"
+#include "ash/screen_ash.h"
 #include "ash/shelf/shelf_types.h"
 #include "ash/shelf/shelf_widget.h"
 #include "ash/shell.h"
 #include "ash/shell_window_ids.h"
+#include "ash/wm/coordinate_conversion.h"
 #include "ash/wm/panels/panel_layout_manager.h"
 #include "ash/wm/property_util.h"
 #include "ash/wm/window_properties.h"
@@ -27,114 +30,152 @@
 
 namespace {
 const int kPanelSnapToLauncherDistance = 30;
+
+internal::PanelLayoutManager* GetPanelLayoutManager(
+    aura::Window* panel_container) {
+  DCHECK(panel_container->id() == internal::kShellWindowId_PanelContainer);
+  return static_cast<internal::PanelLayoutManager*>(
+      panel_container->layout_manager());
+}
+
 }  // namespace
 
 PanelWindowResizer::~PanelWindowResizer() {
-  ash::Shell::GetInstance()->cursor_manager()->UnlockCursor();
+  if (destroyed_)
+    *destroyed_ = true;
 }
 
 // static
 PanelWindowResizer*
-PanelWindowResizer::Create(aura::Window* window,
+PanelWindowResizer::Create(WindowResizer* next_window_resizer,
+                           aura::Window* window,
                            const gfx::Point& location,
                            int window_component) {
   Details details(window, location, window_component);
-  return details.is_resizable ? new PanelWindowResizer(details) : NULL;
+  return details.is_resizable ?
+      new PanelWindowResizer(next_window_resizer, details) : NULL;
 }
 
 void PanelWindowResizer::Drag(const gfx::Point& location, int event_flags) {
-  gfx::Rect bounds(CalculateBoundsForDrag(details_, location));
-  if (bounds != details_.window->bounds()) {
-    if (!did_move_or_resize_) {
-      if (!details_.restore_bounds.IsEmpty())
-        ClearRestoreBounds(details_.window);
-      StartedDragging();
-    }
+  bool destroyed = false;
+  if (!did_move_or_resize_) {
     did_move_or_resize_ = true;
-    should_attach_ = AttachToLauncher(&bounds);
-    details_.window->SetBounds(bounds);
-    if (should_attach_)
-      UpdateLauncherPosition();
+    StartedDragging();
+  }
+  gfx::Point location_in_screen = location;
+  wm::ConvertPointToScreen(GetTarget()->parent(), &location_in_screen);
+
+  // Check if the destination has changed displays.
+  gfx::Screen* screen = Shell::GetScreen();
+  const gfx::Display dst_display =
+      screen->GetDisplayNearestPoint(location_in_screen);
+  if (dst_display.id() !=
+      screen->GetDisplayNearestWindow(panel_container_->GetRootWindow()).id()) {
+    // The panel is being dragged to a new display. If the previous container is
+    // the current parent of the panel it will be informed of the end of drag
+    // when the panel is reparented, otherwise let the previous container know
+    // the drag is complete. If we told the panel's parent that the drag was
+    // complete it would begin positioning the panel.
+    if (GetTarget()->parent() != panel_container_)
+      GetPanelLayoutManager(panel_container_)->FinishDragging();
+    aura::RootWindow* dst_root = Shell::GetInstance()->display_controller()->
+        GetRootWindowForDisplayId(dst_display.id());
+    panel_container_ = Shell::GetContainer(
+        dst_root, internal::kShellWindowId_PanelContainer);
+
+    // The panel's parent already knows that the drag is in progress for this
+    // panel.
+    if (panel_container_ && GetTarget()->parent() != panel_container_)
+      GetPanelLayoutManager(panel_container_)->StartDragging(GetTarget());
+  }
+  gfx::Point offset;
+  gfx::Rect bounds(CalculateBoundsForDrag(details_, location));
+  should_attach_ = AttachToLauncher(bounds, &offset);
+  gfx::Point modified_location(location.x() + offset.x(),
+                               location.y() + offset.y());
+  destroyed_ = &destroyed;
+  next_window_resizer_->Drag(modified_location, event_flags);
+
+  // TODO(flackr): Refactor the way WindowResizer calls into other window
+  // resizers to avoid the awkward pattern here for checking if
+  // next_window_resizer_ destroys the resizer object.
+  if (destroyed)
+    return;
+  destroyed_ = NULL;
+  if (should_attach_ &&
+      !(details_.bounds_change & WindowResizer::kBoundsChange_Resizes)) {
+    UpdateLauncherPosition();
   }
 }
 
 void PanelWindowResizer::CompleteDrag(int event_flags) {
-  if (details_.window->GetProperty(internal::kPanelAttachedKey) !=
-      should_attach_) {
-    details_.window->SetProperty(internal::kPanelAttachedKey, should_attach_);
-    details_.window->SetDefaultParentByRootWindow(
-            details_.window->GetRootWindow(),
-            details_.window->bounds());
-  }
+  // The root window can change when dragging into a different screen.
+  next_window_resizer_->CompleteDrag(event_flags);
   FinishDragging();
 }
 
 void PanelWindowResizer::RevertDrag() {
-  if (!did_move_or_resize_)
-    return;
-
-  details_.window->SetBounds(details_.initial_bounds_in_parent);
-
-  if (!details_.restore_bounds.IsEmpty())
-    SetRestoreBoundsInScreen(details_.window, details_.restore_bounds);
+  next_window_resizer_->RevertDrag();
+  should_attach_ = was_attached_;
   FinishDragging();
 }
 
 aura::Window* PanelWindowResizer::GetTarget() {
-  return details_.window;
+  return next_window_resizer_->GetTarget();
 }
 
-PanelWindowResizer::PanelWindowResizer(const Details& details)
+PanelWindowResizer::PanelWindowResizer(WindowResizer* next_window_resizer,
+                                       const Details& details)
     : details_(details),
+      next_window_resizer_(next_window_resizer),
       panel_container_(NULL),
-      panel_layout_manager_(NULL),
       did_move_or_resize_(false),
-      was_attached_(details_.window->GetProperty(internal::kPanelAttachedKey)),
-      should_attach_(was_attached_) {
+      was_attached_(GetTarget()->GetProperty(internal::kPanelAttachedKey)),
+      should_attach_(was_attached_),
+      destroyed_(NULL) {
   DCHECK(details_.is_resizable);
-  ash::internal::RootWindowController* root_window_controller =
-      GetRootWindowController(details.window->GetRootWindow());
-  panel_container_ = root_window_controller->GetContainer(
+  panel_container_ = Shell::GetContainer(
+      details.window->GetRootWindow(),
       internal::kShellWindowId_PanelContainer);
-  if (panel_container_) {
-    panel_layout_manager_ = static_cast<internal::PanelLayoutManager*>(
-        panel_container_->layout_manager());
-  }
-  ash::Shell::GetInstance()->cursor_manager()->LockCursor();
 }
 
-bool PanelWindowResizer::AttachToLauncher(gfx::Rect* bounds) {
+bool PanelWindowResizer::AttachToLauncher(const gfx::Rect& bounds,
+                                          gfx::Point* offset) {
   bool should_attach = false;
-  if (panel_layout_manager_) {
-    gfx::Rect launcher_bounds = panel_layout_manager_->launcher()->
-        shelf_widget()->GetWindowBoundsInScreen();
-    switch (panel_layout_manager_->launcher()->alignment()) {
+  if (panel_container_) {
+    internal::PanelLayoutManager* panel_layout_manager =
+        GetPanelLayoutManager(panel_container_);
+    gfx::Rect launcher_bounds = ScreenAsh::ConvertRectFromScreen(
+        GetTarget()->parent(),
+        panel_layout_manager->launcher()->
+        shelf_widget()->GetWindowBoundsInScreen());
+    switch (panel_layout_manager->launcher()->alignment()) {
       case SHELF_ALIGNMENT_BOTTOM:
-        if (bounds->bottom() >= (launcher_bounds.y() -
-                                 kPanelSnapToLauncherDistance)) {
+        if (bounds.bottom() >= (launcher_bounds.y() -
+                                kPanelSnapToLauncherDistance)) {
           should_attach = true;
-          bounds->set_y(launcher_bounds.y() - bounds->height());
+          offset->set_y(launcher_bounds.y() - bounds.height() - bounds.y());
         }
         break;
       case SHELF_ALIGNMENT_LEFT:
-        if (bounds->x() <= (launcher_bounds.right() +
-                            kPanelSnapToLauncherDistance)) {
+        if (bounds.x() <= (launcher_bounds.right() +
+                           kPanelSnapToLauncherDistance)) {
           should_attach = true;
-          bounds->set_x(launcher_bounds.right());
+          offset->set_x(launcher_bounds.right() - bounds.x());
         }
         break;
       case SHELF_ALIGNMENT_RIGHT:
-        if (bounds->right() >= (launcher_bounds.x() -
-                                kPanelSnapToLauncherDistance)) {
+        if (bounds.right() >= (launcher_bounds.x() -
+                               kPanelSnapToLauncherDistance)) {
           should_attach = true;
-          bounds->set_x(launcher_bounds.x() - bounds->width());
+          offset->set_x(launcher_bounds.x() - bounds.width() - bounds.x());
         }
         break;
       case SHELF_ALIGNMENT_TOP:
-        if (bounds->y() <= (launcher_bounds.bottom() +
-                            kPanelSnapToLauncherDistance)) {
+        if (bounds.y() <= (launcher_bounds.bottom() +
+                           kPanelSnapToLauncherDistance)) {
           should_attach = true;
-          bounds->set_y(launcher_bounds.bottom());
+          offset->set_y(launcher_bounds.bottom() - bounds.y());
         }
         break;
     }
@@ -145,24 +186,37 @@
 void PanelWindowResizer::StartedDragging() {
   // Tell the panel layout manager that we are dragging this panel before
   // attaching it so that it does not get repositioned.
-  panel_layout_manager_->StartDragging(details_.window);
+  if (panel_container_)
+    GetPanelLayoutManager(panel_container_)->StartDragging(GetTarget());
   if (!was_attached_) {
     // Attach the panel while dragging placing it in front of other panels.
-    details_.window->SetProperty(internal::kContinueDragAfterReparent, true);
-    details_.window->SetProperty(internal::kPanelAttachedKey, true);
-    details_.window->SetDefaultParentByRootWindow(
-            details_.window->GetRootWindow(),
-            details_.window->bounds());
+    GetTarget()->SetProperty(internal::kContinueDragAfterReparent, true);
+    GetTarget()->SetProperty(internal::kPanelAttachedKey, true);
+    GetTarget()->SetDefaultParentByRootWindow(
+        GetTarget()->GetRootWindow(),
+        GetTarget()->GetBoundsInScreen());
   }
 }
 
 void PanelWindowResizer::FinishDragging() {
-  panel_layout_manager_->FinishDragging();
+  if (!did_move_or_resize_)
+    return;
+  if (GetTarget()->GetProperty(internal::kPanelAttachedKey) !=
+      should_attach_) {
+    GetTarget()->SetProperty(internal::kPanelAttachedKey, should_attach_);
+    GetTarget()->SetDefaultParentByRootWindow(
+        GetTarget()->GetRootWindow(),
+        GetTarget()->GetBoundsInScreen());
+  }
+  if (panel_container_)
+    GetPanelLayoutManager(panel_container_)->FinishDragging();
 }
 
 void PanelWindowResizer::UpdateLauncherPosition() {
-  panel_layout_manager_->launcher()->UpdateIconPositionForWindow(
-      details_.window);
+  if (panel_container_) {
+    GetPanelLayoutManager(panel_container_)->launcher()->
+        UpdateIconPositionForWindow(GetTarget());
+  }
 }
 
 }  // namespace aura
diff --git a/ash/wm/panels/panel_window_resizer.h b/ash/wm/panels/panel_window_resizer.h
index 5f3cc16..5dbc32d 100644
--- a/ash/wm/panels/panel_window_resizer.h
+++ b/ash/wm/panels/panel_window_resizer.h
@@ -10,14 +10,11 @@
 
 namespace gfx {
 class Rect;
+class Point;
 }
 
 namespace ash {
 
-namespace internal {
-class PanelLayoutManager;
-}
-
 // PanelWindowResizer is used by ToplevelWindowEventFilter to handle dragging,
 // moving or resizing panel window. These can be attached and detached from the
 // launcher.
@@ -26,18 +23,13 @@
   virtual ~PanelWindowResizer();
 
   // Creates a new PanelWindowResizer. The caller takes ownership of the
+  // returned object. The ownership of |next_window_resizer| is taken by the
   // returned object. Returns NULL if not resizable.
-  static PanelWindowResizer* Create(aura::Window* window,
+  static PanelWindowResizer* Create(WindowResizer* next_window_resizer,
+                                    aura::Window* window,
                                     const gfx::Point& location,
                                     int window_component);
 
-  // Returns true if the drag will result in changing the window in anyway.
-  bool is_resizable() const { return details_.is_resizable; }
-
-  bool changed_size() const {
-    return !(details_.bounds_change & kBoundsChange_Repositions);
-  }
-
   // WindowResizer overides:
   virtual void Drag(const gfx::Point& location, int event_flags) OVERRIDE;
   virtual void CompleteDrag(int event_flags) OVERRIDE;
@@ -49,11 +41,16 @@
   }
 
  private:
-  explicit PanelWindowResizer(const Details& details);
+  // Creates PanelWindowResizer that adds the ability to attach / detach panel
+  // windows as well as reparenting them to the panel layer while dragging to
+  // |next_window_resizer|. This object takes ownership of
+  // |next_window_resizer|.
+  PanelWindowResizer(WindowResizer* next_window_resizer,
+                     const Details& details);
 
   // Checks if the provided window bounds should attach to the launcher. If true
-  // the bounds are modified to snap the window to the launcher.
-  bool AttachToLauncher(gfx::Rect* bounds);
+  // the offset gives the necessary adjustment to snap to the launcher.
+  bool AttachToLauncher(const gfx::Rect& bounds, gfx::Point* offset);
 
   // Tracks the panel's initial position and attachment at the start of a drag
   // and informs the PanelLayoutManager that a drag has started if necessary.
@@ -68,12 +65,13 @@
 
   const Details details_;
 
+  // Wraps a window resizer and adds panel detaching / reattaching and snapping
+  // to launcher behavior during drags.
+  scoped_ptr<WindowResizer> next_window_resizer_;
+
   // Panel container window.
   aura::Window* panel_container_;
 
-  // Weak pointer, owned by panel container.
-  internal::PanelLayoutManager* panel_layout_manager_;
-
   // Set to true once Drag() is invoked and the bounds of the window change.
   bool did_move_or_resize_;
 
@@ -83,6 +81,10 @@
   // True if the window should attach to the launcher after releasing.
   bool should_attach_;
 
+  // If non-NULL the destructor sets this to true. Used to determine if this has
+  // been deleted.
+  bool* destroyed_;
+
   DISALLOW_COPY_AND_ASSIGN(PanelWindowResizer);
 };
 
diff --git a/ash/wm/panels/panel_window_resizer_unittest.cc b/ash/wm/panels/panel_window_resizer_unittest.cc
index 829516e..9039de2 100644
--- a/ash/wm/panels/panel_window_resizer_unittest.cc
+++ b/ash/wm/panels/panel_window_resizer_unittest.cc
@@ -7,6 +7,7 @@
 #include "ash/launcher/launcher.h"
 #include "ash/launcher/launcher_model.h"
 #include "ash/root_window_controller.h"
+#include "ash/shelf/shelf_layout_manager.h"
 #include "ash/shelf/shelf_types.h"
 #include "ash/shelf/shelf_widget.h"
 #include "ash/shell.h"
@@ -15,6 +16,7 @@
 #include "ash/test/cursor_manager_test_api.h"
 #include "ash/test/shell_test_api.h"
 #include "ash/test/test_launcher_delegate.h"
+#include "ash/wm/drag_window_resizer.h"
 #include "ash/wm/panels/panel_layout_manager.h"
 #include "ash/wm/window_properties.h"
 #include "ui/aura/client/aura_constants.h"
@@ -35,11 +37,6 @@
     AshTestBase::SetUp();
     test::ShellTestApi test_api(Shell::GetInstance());
     model_ = test_api.launcher_model();
-
-    panel_layout_manager_ = static_cast<internal::PanelLayoutManager*>(
-        GetPanelContainer()->layout_manager());
-    launcher_bounds_ = panel_layout_manager_->launcher()->shelf_widget()->
-        GetWindowBoundsInScreen();
   }
 
   virtual void TearDown() OVERRIDE {
@@ -66,17 +63,14 @@
         test::TestLauncherDelegate::instance();
     launcher_delegate->AddLauncherItem(window);
     PanelLayoutManager* manager =
-        static_cast<PanelLayoutManager*>(GetPanelContainer()->layout_manager());
+        static_cast<PanelLayoutManager*>(
+            Shell::GetContainer(window->GetRootWindow(),
+                                internal::kShellWindowId_PanelContainer)->
+                layout_manager());
     manager->Relayout();
     return window;
   }
 
-  aura::Window* GetPanelContainer() {
-    return Shell::GetContainer(
-        Shell::GetPrimaryRootWindow(),
-        internal::kShellWindowId_PanelContainer);
-  }
-
   static PanelWindowResizer* CreatePanelWindowResizer(
       aura::Window* window,
       const gfx::Point& point_in_parent,
@@ -86,7 +80,8 @@
   }
 
   void DragStart(aura::Window* window) {
-    resizer_.reset(CreatePanelWindowResizer(window, gfx::Point(), HTCAPTION));
+    resizer_.reset(CreatePanelWindowResizer(window, window->bounds().origin(),
+                                            HTCAPTION));
     ASSERT_TRUE(resizer_.get());
   }
 
@@ -99,34 +94,40 @@
     resizer_.reset();
   }
 
+  void DragRevert() {
+    resizer_->RevertDrag();
+    resizer_.reset();
+  }
+
   // Test dragging the panel slightly, then detaching, and then reattaching
   // dragging out by the vector (dx, dy).
-  void DetachReattachTest(int dx, int dy) {
-    scoped_ptr<aura::Window> window(
-        CreatePanelWindow(gfx::Rect(0, 0, 201, 201)));
+  void DetachReattachTest(aura::Window* window, int dx, int dy) {
     EXPECT_TRUE(window->GetProperty(kPanelAttachedKey));
+    aura::RootWindow* root_window = window->GetRootWindow();
     EXPECT_EQ(internal::kShellWindowId_PanelContainer, window->parent()->id());
-    DragStart(window.get());
-    gfx::Rect initial_bounds = window->bounds();
+    DragStart(window);
+    gfx::Rect initial_bounds = window->GetBoundsInScreen();
 
     // Drag the panel slightly. The window should still be snapped to the
     // launcher.
     DragMove(dx * 5, dy * 5);
-    EXPECT_EQ(initial_bounds.x(), window->bounds().x());
-    EXPECT_EQ(initial_bounds.y(), window->bounds().y());
+    EXPECT_EQ(initial_bounds.x(), window->GetBoundsInScreen().x());
+    EXPECT_EQ(initial_bounds.y(), window->GetBoundsInScreen().y());
 
     // Drag further out and the window should now move to the cursor.
     DragMove(dx * 100, dy * 100);
-    EXPECT_EQ(initial_bounds.x() + dx * 100, window->bounds().x());
-    EXPECT_EQ(initial_bounds.y() + dy * 100, window->bounds().y());
+    EXPECT_EQ(initial_bounds.x() + dx * 100, window->GetBoundsInScreen().x());
+    EXPECT_EQ(initial_bounds.y() + dy * 100, window->GetBoundsInScreen().y());
 
     // The panel should be detached when the drag completes.
     DragEnd();
+
     EXPECT_FALSE(window->GetProperty(kPanelAttachedKey));
     EXPECT_EQ(internal::kShellWindowId_WorkspaceContainer,
               window->parent()->id());
+    EXPECT_EQ(root_window, window->GetRootWindow());
 
-    DragStart(window.get());
+    DragStart(window);
     // Drag the panel down.
     DragMove(dx * -95, dy * -95);
     // Release the mouse and the panel should be reattached.
@@ -134,8 +135,8 @@
 
     // The panel should be reattached and have snapped to the launcher.
     EXPECT_TRUE(window->GetProperty(kPanelAttachedKey));
-    EXPECT_EQ(initial_bounds.x(), window->bounds().x());
-    EXPECT_EQ(initial_bounds.y(), window->bounds().y());
+    EXPECT_EQ(initial_bounds.x(), window->GetBoundsInScreen().x());
+    EXPECT_EQ(initial_bounds.y(), window->GetBoundsInScreen().y());
     EXPECT_EQ(internal::kShellWindowId_PanelContainer, window->parent()->id());
   }
 
@@ -168,6 +169,7 @@
     // Drag window #2 to the beginning of the shelf.
     DragStart(w2.get());
     DragMove(400 * dx, 400 * dy);
+    TestWindowOrder(window_order_swapped);
     DragEnd();
 
     // Expect swapped window order.
@@ -176,6 +178,7 @@
     // Drag window #2 back to the end.
     DragStart(w2.get());
     DragMove(-400 * dx, -400 * dy);
+    TestWindowOrder(window_order_original);
     DragEnd();
 
     // Expect original order.
@@ -184,9 +187,7 @@
 
  private:
   scoped_ptr<PanelWindowResizer> resizer_;
-  aura::Window* panel_container_;
   internal::PanelLayoutManager* panel_layout_manager_;
-  gfx::Rect launcher_bounds_;
   LauncherModel* model_;
 
   DISALLOW_COPY_AND_ASSIGN(PanelWindowResizerTest);
@@ -195,13 +196,17 @@
 // Verifies a window can be dragged from the panel and detached and then
 // reattached.
 TEST_F(PanelWindowResizerTest, PanelDetachReattachBottom) {
-  DetachReattachTest(0, -1);
+  scoped_ptr<aura::Window> window(
+      CreatePanelWindow(gfx::Rect(0, 0, 201, 201)));
+  DetachReattachTest(window.get(), 0, -1);
 }
 
 TEST_F(PanelWindowResizerTest, PanelDetachReattachLeft) {
   ash::Shell* shell = ash::Shell::GetInstance();
   shell->SetShelfAlignment(SHELF_ALIGNMENT_LEFT, shell->GetPrimaryRootWindow());
-  DetachReattachTest(1, 0);
+  scoped_ptr<aura::Window> window(
+      CreatePanelWindow(gfx::Rect(0, 0, 201, 201)));
+  DetachReattachTest(window.get(), 1, 0);
 }
 
 #if defined(OS_WIN)
@@ -216,13 +221,174 @@
   ash::Shell* shell = ash::Shell::GetInstance();
   shell->SetShelfAlignment(SHELF_ALIGNMENT_RIGHT,
                            shell->GetPrimaryRootWindow());
-  DetachReattachTest(-1, 0);
+  scoped_ptr<aura::Window> window(
+      CreatePanelWindow(gfx::Rect(0, 0, 201, 201)));
+  DetachReattachTest(window.get(), -1, 0);
 }
 
 TEST_F(PanelWindowResizerTest, PanelDetachReattachTop) {
   ash::Shell* shell = ash::Shell::GetInstance();
   shell->SetShelfAlignment(SHELF_ALIGNMENT_TOP, shell->GetPrimaryRootWindow());
-  DetachReattachTest(0, 1);
+  scoped_ptr<aura::Window> window(
+      CreatePanelWindow(gfx::Rect(0, 0, 201, 201)));
+  DetachReattachTest(window.get(), 0, 1);
+}
+
+#if defined(OS_WIN)
+// Multiple displays aren't supported on Windows Metro/Ash.
+// http://crbug.com/165962
+#define MAYBE_PanelDetachReattachMultipleDisplays \
+        DISABLED_PanelDetachReattachMultipleDisplays
+#define MAYBE_DetachThenDragAcrossDisplays DISABLED_DetachThenDragAcrossDisplays
+#define MAYBE_DetachAcrossDisplays DISABLED_DetachAcrossDisplays
+#define MAYBE_DetachThenAttachToSecondDisplay \
+        DISABLED_DetachThenAttachToSecondDisplay
+#define MAYBE_AttachToSecondDisplay DISABLED_AttachToSecondDisplay
+#else
+#define MAYBE_PanelDetachReattachMultipleDisplays \
+        PanelDetachReattachMultipleDisplays
+#define MAYBE_DetachThenDragAcrossDisplays DetachThenDragAcrossDisplays
+#define MAYBE_DetachAcrossDisplays DetachAcrossDisplays
+#define MAYBE_DetachThenAttachToSecondDisplay DetachThenAttachToSecondDisplay
+#define MAYBE_AttachToSecondDisplay AttachToSecondDisplay
+#endif
+
+TEST_F(PanelWindowResizerTest, MAYBE_PanelDetachReattachMultipleDisplays) {
+  UpdateDisplay("600x400,600x400");
+  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
+  scoped_ptr<aura::Window> window(
+      CreatePanelWindow(gfx::Rect(600, 0, 201, 201)));
+  EXPECT_EQ(root_windows[1], window->GetRootWindow());
+  DetachReattachTest(window.get(), 0, -1);
+}
+
+TEST_F(PanelWindowResizerTest, MAYBE_DetachThenDragAcrossDisplays) {
+  UpdateDisplay("400x400,400x400");
+  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
+  scoped_ptr<aura::Window> window(
+      CreatePanelWindow(gfx::Rect(0, 0, 201, 201)));
+  gfx::Rect initial_bounds = window->GetBoundsInScreen();
+  EXPECT_EQ(root_windows[0], window->GetRootWindow());
+  DragStart(window.get());
+  DragMove(0, -100);
+  DragEnd();
+  EXPECT_EQ(root_windows[0], window->GetRootWindow());
+  EXPECT_EQ(initial_bounds.x(), window->GetBoundsInScreen().x());
+  EXPECT_EQ(initial_bounds.y() - 100, window->GetBoundsInScreen().y());
+  EXPECT_FALSE(window->GetProperty(kPanelAttachedKey));
+  EXPECT_EQ(internal::kShellWindowId_WorkspaceContainer,
+            window->parent()->id());
+
+  DragStart(window.get());
+  DragMove(500, 0);
+  DragEnd();
+  EXPECT_EQ(root_windows[1], window->GetRootWindow());
+  EXPECT_EQ(initial_bounds.x() + 500, window->GetBoundsInScreen().x());
+  EXPECT_EQ(initial_bounds.y() - 100, window->GetBoundsInScreen().y());
+  EXPECT_FALSE(window->GetProperty(kPanelAttachedKey));
+  EXPECT_EQ(internal::kShellWindowId_WorkspaceContainer,
+            window->parent()->id());
+}
+
+TEST_F(PanelWindowResizerTest, MAYBE_DetachAcrossDisplays) {
+  UpdateDisplay("400x400,400x400");
+  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
+  scoped_ptr<aura::Window> window(
+      CreatePanelWindow(gfx::Rect(0, 0, 201, 201)));
+  gfx::Rect initial_bounds = window->GetBoundsInScreen();
+  EXPECT_EQ(root_windows[0], window->GetRootWindow());
+  DragStart(window.get());
+  DragMove(500, -100);
+  DragEnd();
+  EXPECT_EQ(root_windows[1], window->GetRootWindow());
+  EXPECT_EQ(initial_bounds.x() + 500, window->GetBoundsInScreen().x());
+  EXPECT_EQ(initial_bounds.y() - 100, window->GetBoundsInScreen().y());
+  EXPECT_FALSE(window->GetProperty(kPanelAttachedKey));
+  EXPECT_EQ(internal::kShellWindowId_WorkspaceContainer,
+            window->parent()->id());
+}
+
+TEST_F(PanelWindowResizerTest, MAYBE_DetachThenAttachToSecondDisplay) {
+  UpdateDisplay("400x400,400x600");
+  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
+  scoped_ptr<aura::Window> window(
+      CreatePanelWindow(gfx::Rect(0, 0, 201, 201)));
+  gfx::Rect initial_bounds = window->GetBoundsInScreen();
+  EXPECT_EQ(root_windows[0], window->GetRootWindow());
+
+  // Detach the window.
+  DragStart(window.get());
+  DragMove(0, -100);
+  DragEnd();
+  EXPECT_EQ(root_windows[0], window->GetRootWindow());
+  EXPECT_FALSE(window->GetProperty(kPanelAttachedKey));
+
+  // Drag the window just above the other display's launcher.
+  DragStart(window.get());
+  DragMove(500, 295);
+  EXPECT_EQ(initial_bounds.x() + 500, window->GetBoundsInScreen().x());
+
+  // Should stick to other launcher.
+  EXPECT_EQ(initial_bounds.y() + 200, window->GetBoundsInScreen().y());
+  DragEnd();
+
+  // When dropped should move to second display's panel container.
+  EXPECT_EQ(root_windows[1], window->GetRootWindow());
+  EXPECT_TRUE(window->GetProperty(kPanelAttachedKey));
+  EXPECT_EQ(internal::kShellWindowId_PanelContainer, window->parent()->id());
+}
+
+TEST_F(PanelWindowResizerTest, MAYBE_AttachToSecondDisplay) {
+  UpdateDisplay("400x400,400x600");
+  Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
+  scoped_ptr<aura::Window> window(
+      CreatePanelWindow(gfx::Rect(0, 0, 201, 201)));
+  gfx::Rect initial_bounds = window->GetBoundsInScreen();
+  EXPECT_EQ(root_windows[0], window->GetRootWindow());
+
+  // Drag the window just above the other display's launcher.
+  DragStart(window.get());
+  DragMove(500, 195);
+  EXPECT_EQ(initial_bounds.x() + 500, window->GetBoundsInScreen().x());
+
+  // Should stick to other launcher.
+  EXPECT_EQ(initial_bounds.y() + 200, window->GetBoundsInScreen().y());
+  DragEnd();
+
+  // When dropped should move to second display's panel container.
+  EXPECT_EQ(root_windows[1], window->GetRootWindow());
+  EXPECT_TRUE(window->GetProperty(kPanelAttachedKey));
+  EXPECT_EQ(internal::kShellWindowId_PanelContainer, window->parent()->id());
+}
+
+TEST_F(PanelWindowResizerTest, RevertDragRestoresAttachment) {
+  scoped_ptr<aura::Window> window(
+      CreatePanelWindow(gfx::Rect(0, 0, 201, 201)));
+  EXPECT_TRUE(window->GetProperty(kPanelAttachedKey));
+  EXPECT_EQ(internal::kShellWindowId_PanelContainer, window->parent()->id());
+  DragStart(window.get());
+  DragMove(0, -100);
+  DragRevert();
+  EXPECT_TRUE(window->GetProperty(kPanelAttachedKey));
+  EXPECT_EQ(internal::kShellWindowId_PanelContainer, window->parent()->id());
+
+  // Detach panel.
+  DragStart(window.get());
+  DragMove(0, -100);
+  DragEnd();
+  EXPECT_FALSE(window->GetProperty(kPanelAttachedKey));
+  EXPECT_EQ(internal::kShellWindowId_WorkspaceContainer,
+            window->parent()->id());
+
+  // Drag back to launcher.
+  DragStart(window.get());
+  DragMove(0, 100);
+
+  // When the drag is reverted it should remain detached.
+  DragRevert();
+  EXPECT_FALSE(window->GetProperty(kPanelAttachedKey));
+  EXPECT_EQ(internal::kShellWindowId_WorkspaceContainer,
+            window->parent()->id());
 }
 
 TEST_F(PanelWindowResizerTest, DragMovesToPanelLayer) {
diff --git a/ash/wm/partial_screenshot_view.cc b/ash/wm/partial_screenshot_view.cc
index 03116e7..032c91b 100644
--- a/ash/wm/partial_screenshot_view.cc
+++ b/ash/wm/partial_screenshot_view.cc
@@ -79,8 +79,10 @@
 };
 
 // static
-void PartialScreenshotView::StartPartialScreenshot(
+std::vector<PartialScreenshotView*>
+PartialScreenshotView::StartPartialScreenshot(
     ScreenshotDelegate* screenshot_delegate) {
+  std::vector<PartialScreenshotView*> views;
   OverlayDelegate* overlay_delegate = new OverlayDelegate();
   Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
   for (Shell::RootWindowList::iterator it = root_windows.begin();
@@ -88,7 +90,9 @@
     PartialScreenshotView* new_view = new PartialScreenshotView(
         overlay_delegate, screenshot_delegate);
     new_view->Init(*it);
+    views.push_back(new_view);
   }
+  return views;
 }
 
 PartialScreenshotView::PartialScreenshotView(
@@ -140,6 +144,33 @@
   return gfx::Rect(left, top, width, height);
 }
 
+void PartialScreenshotView::OnSelectionStarted(const gfx::Point& position) {
+  start_position_ = position;
+}
+
+void PartialScreenshotView::OnSelectionChanged(const gfx::Point& position) {
+  if (is_dragging_ && current_position_ == position)
+    return;
+  current_position_ = position;
+  SchedulePaint();
+  is_dragging_ = true;
+}
+
+void PartialScreenshotView::OnSelectionFinished() {
+  overlay_delegate_->Cancel();
+  if (!is_dragging_)
+    return;
+
+  is_dragging_ = false;
+  if (screenshot_delegate_) {
+    aura::RootWindow *root_window =
+        GetWidget()->GetNativeWindow()->GetRootWindow();
+    screenshot_delegate_->HandleTakePartialScreenshot(
+        root_window,
+        gfx::IntersectRects(root_window->bounds(), GetScreenshotRect()));
+  }
+}
+
 gfx::NativeCursor PartialScreenshotView::GetCursor(
     const ui::MouseEvent& event) {
   // Always use "crosshair" cursor.
@@ -167,14 +198,12 @@
       Shell::GetInstance()->mouse_cursor_filter();
   mouse_cursor_filter->set_mouse_warp_mode(
       internal::MouseCursorEventFilter::WARP_NONE);
-  start_position_ = event.location();
+  OnSelectionStarted(event.location());
   return true;
 }
 
 bool PartialScreenshotView::OnMouseDragged(const ui::MouseEvent& event) {
-  current_position_ = event.location();
-  SchedulePaint();
-  is_dragging_ = true;
+  OnSelectionChanged(event.location());
   return true;
 }
 
@@ -184,18 +213,31 @@
 }
 
 void PartialScreenshotView::OnMouseReleased(const ui::MouseEvent& event) {
-  overlay_delegate_->Cancel();
-  if (!is_dragging_)
-    return;
+  OnSelectionFinished();
+}
 
+void PartialScreenshotView::OnMouseCaptureLost() {
   is_dragging_ = false;
-  if (screenshot_delegate_) {
-    aura::RootWindow *root_window =
-        GetWidget()->GetNativeWindow()->GetRootWindow();
-    screenshot_delegate_->HandleTakePartialScreenshot(
-        root_window,
-        gfx::IntersectRects(root_window->bounds(), GetScreenshotRect()));
+  OnSelectionFinished();
+}
+
+void PartialScreenshotView::OnGestureEvent(ui::GestureEvent* event) {
+  switch(event->type()) {
+    case ui::ET_GESTURE_TAP_DOWN:
+      OnSelectionStarted(event->location());
+      break;
+    case ui::ET_GESTURE_SCROLL_UPDATE:
+      OnSelectionChanged(event->location());
+      break;
+    case ui::ET_GESTURE_SCROLL_END:
+    case ui::ET_SCROLL_FLING_START:
+      OnSelectionFinished();
+      break;
+    default:
+      break;
   }
+
+  event->SetHandled();
 }
 
 }  // namespace ash
diff --git a/ash/wm/partial_screenshot_view.h b/ash/wm/partial_screenshot_view.h
index a2ca607..85b9f81 100644
--- a/ash/wm/partial_screenshot_view.h
+++ b/ash/wm/partial_screenshot_view.h
@@ -5,8 +5,11 @@
 #ifndef ASH_WM_PARTIAL_SCREENSHOT_VIEW_H_
 #define ASH_WM_PARTIAL_SCREENSHOT_VIEW_H_
 
+#include <vector>
+
 #include "ash/ash_export.h"
 #include "base/compiler_specific.h"
+#include "base/gtest_prod_util.h"
 #include "ui/gfx/point.h"
 #include "ui/views/widget/widget_delegate.h"
 
@@ -23,9 +26,15 @@
 class ASH_EXPORT PartialScreenshotView : public views::WidgetDelegateView {
  public:
   // Starts the UI for taking partial screenshot; dragging to select a region.
-  static void StartPartialScreenshot(ScreenshotDelegate* screenshot_delegate);
+  // PartialScreenshotViews manage their own lifetime so caller must not delete
+  // the returned PartialScreenshotViews.
+  static std::vector<PartialScreenshotView*>
+      StartPartialScreenshot(ScreenshotDelegate* screenshot_delegate);
 
  private:
+  FRIEND_TEST_ALL_PREFIXES(PartialScreenshotViewTest, BasicMouse);
+  FRIEND_TEST_ALL_PREFIXES(PartialScreenshotViewTest, BasicTouch);
+
   class OverlayDelegate;
 
   PartialScreenshotView(OverlayDelegate* overlay_delegate,
@@ -38,6 +47,10 @@
   // Returns the currently selected region.
   gfx::Rect GetScreenshotRect() const;
 
+  void OnSelectionStarted(const gfx::Point& position);
+  void OnSelectionChanged(const gfx::Point& position);
+  void OnSelectionFinished();
+
   // Overridden from views::View:
   virtual gfx::NativeCursor GetCursor(const ui::MouseEvent& event) OVERRIDE;
   virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
@@ -45,6 +58,8 @@
   virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE;
   virtual bool OnMouseWheel(const ui::MouseWheelEvent& event) OVERRIDE;
   virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE;
+  virtual void OnMouseCaptureLost() OVERRIDE;
+  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
 
   bool is_dragging_;
   gfx::Point start_position_;
diff --git a/ash/wm/partial_screenshot_view_unittest.cc b/ash/wm/partial_screenshot_view_unittest.cc
new file mode 100644
index 0000000..a763577
--- /dev/null
+++ b/ash/wm/partial_screenshot_view_unittest.cc
@@ -0,0 +1,103 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/wm/partial_screenshot_view.h"
+
+#include "ash/screenshot_delegate.h"
+#include "ash/shell.h"
+#include "ash/shell_window_ids.h"
+#include "ash/test/ash_test_base.h"
+#include "ui/aura/root_window.h"
+#include "ui/aura/test/event_generator.h"
+
+namespace ash {
+
+class FakeScreenshotDelegate : public ScreenshotDelegate {
+ public:
+  FakeScreenshotDelegate() : screenshot_count_(0) {}
+
+  virtual void HandleTakeScreenshotForAllRootWindows() OVERRIDE {}
+  virtual void HandleTakePartialScreenshot(aura::Window* window,
+                                           const gfx::Rect& rect) OVERRIDE {
+    rect_ = rect;
+    screenshot_count_++;
+  }
+
+  virtual bool CanTakeScreenshot() OVERRIDE {
+    return true;
+  }
+
+  const gfx::Rect& rect() const { return rect_; };
+  int screenshot_count() const { return screenshot_count_; };
+
+ private:
+  gfx::Rect rect_;
+  int screenshot_count_;
+
+  DISALLOW_COPY_AND_ASSIGN(FakeScreenshotDelegate);
+};
+
+class PartialScreenshotViewTest : public test::AshTestBase {
+ public:
+  PartialScreenshotViewTest() : view_(NULL) {}
+  virtual ~PartialScreenshotViewTest() {}
+
+  virtual void SetUp() OVERRIDE {
+    test::AshTestBase::SetUp();
+    delegate_.reset(new FakeScreenshotDelegate());
+    std::vector<PartialScreenshotView*> views =
+        PartialScreenshotView::StartPartialScreenshot(delegate_.get());
+    ASSERT_EQ(1u, views.size());
+    view_ = views[0];
+  }
+
+ protected:
+  PartialScreenshotView* view_;
+  scoped_ptr<FakeScreenshotDelegate> delegate_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(PartialScreenshotViewTest);
+};
+
+TEST_F(PartialScreenshotViewTest, BasicMouse) {
+  aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
+
+  generator.MoveMouseTo(100, 100);
+  generator.PressLeftButton();
+  EXPECT_FALSE(view_->is_dragging_);
+  EXPECT_EQ("100,100", view_->start_position_.ToString());
+
+  generator.MoveMouseTo(200, 200);
+  EXPECT_TRUE(view_->is_dragging_);
+  EXPECT_EQ("200,200", view_->current_position_.ToString());
+
+  generator.ReleaseLeftButton();
+  EXPECT_FALSE(view_->is_dragging_);
+  EXPECT_EQ("100,100 100x100", delegate_->rect().ToString());
+  EXPECT_EQ(1, delegate_->screenshot_count());
+}
+
+TEST_F(PartialScreenshotViewTest, BasicTouch) {
+  aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
+
+  generator.set_current_location(gfx::Point(100,100));
+  generator.GestureTapDownAndUp(gfx::Point(100,100));
+  EXPECT_FALSE(view_->is_dragging_);
+  EXPECT_EQ(0, delegate_->screenshot_count());
+
+  generator.PressTouch();
+  EXPECT_FALSE(view_->is_dragging_);
+  EXPECT_EQ("100,100", view_->start_position_.ToString());
+
+  generator.MoveTouch(gfx::Point(200, 200));
+  EXPECT_TRUE(view_->is_dragging_);
+  EXPECT_EQ("200,200", view_->current_position_.ToString());
+
+  generator.ReleaseTouch();
+  EXPECT_FALSE(view_->is_dragging_);
+  EXPECT_EQ(1, delegate_->screenshot_count());
+  EXPECT_EQ("100,100 100x100", delegate_->rect().ToString());
+}
+
+}  // namespace ash
diff --git a/ash/wm/power_button_controller.cc b/ash/wm/power_button_controller.cc
index 9359b8a..6850608 100644
--- a/ash/wm/power_button_controller.cc
+++ b/ash/wm/power_button_controller.cc
@@ -5,8 +5,8 @@
 #include "ash/wm/power_button_controller.h"
 
 #include "ash/ash_switches.h"
+#include "ash/session_state_delegate.h"
 #include "ash/shell.h"
-#include "ash/shell_delegate.h"
 #include "ash/shell_window_ids.h"
 #include "ash/wm/session_state_animator.h"
 #include "ash/wm/session_state_controller.h"
@@ -45,13 +45,15 @@
   if (screen_is_off_)
     return;
 
-  Shell* shell = Shell::GetInstance();
+  const SessionStateDelegate* session_state_delegate =
+      Shell::GetInstance()->session_state_delegate();
   if (has_legacy_power_button_) {
     // If power button releases won't get reported correctly because we're not
     // running on official hardware, just lock the screen or shut down
     // immediately.
     if (down) {
-      if (shell->CanLockScreen() && !shell->IsScreenLocked() &&
+      if (session_state_delegate->CanLockScreen() &&
+          !session_state_delegate->IsScreenLocked() &&
           !controller_->LockRequested()) {
         controller_->StartLockAnimationAndLockImmediately();
       } else {
@@ -64,10 +66,12 @@
       if (controller_->LockRequested())
         return;
 
-      if (shell->CanLockScreen() && !shell->IsScreenLocked())
+      if (session_state_delegate->CanLockScreen() &&
+          !session_state_delegate->IsScreenLocked()) {
         controller_->StartLockAnimation(true);
-      else
+      } else {
         controller_->StartShutdownAnimation();
+      }
     } else {  // Button is up.
       if (controller_->CanCancelLockAnimation())
         controller_->CancelLockAnimation();
@@ -81,9 +85,12 @@
     bool down, const base::TimeTicks& timestamp) {
   lock_button_down_ = down;
 
-  Shell* shell = Shell::GetInstance();
-  if (!shell->CanLockScreen() || shell->IsScreenLocked() ||
-      controller_->LockRequested() || controller_->ShutdownRequested()) {
+  const SessionStateDelegate* session_state_delegate =
+      Shell::GetInstance()->session_state_delegate();
+  if (!session_state_delegate->CanLockScreen() ||
+      session_state_delegate->IsScreenLocked() ||
+      controller_->LockRequested() ||
+      controller_->ShutdownRequested()) {
     return;
   }
 
diff --git a/ash/wm/power_button_controller_unittest.cc b/ash/wm/power_button_controller_unittest.cc
index a989644..7dbdf73 100644
--- a/ash/wm/power_button_controller_unittest.cc
+++ b/ash/wm/power_button_controller_unittest.cc
@@ -8,6 +8,7 @@
 #include "ash/wm/session_state_controller_impl.h"
 
 #include "ash/ash_switches.h"
+#include "ash/session_state_delegate.h"
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
 #include "ash/test/test_shell_delegate.h"
@@ -77,6 +78,7 @@
             animator_.get()));
     shell_delegate_ = reinterpret_cast<TestShellDelegate*>(
         ash::Shell::GetInstance()->delegate());
+    state_delegate_ = Shell::GetInstance()->session_state_delegate();
   }
 
  protected:
@@ -95,6 +97,7 @@
   SessionStateControllerImpl* state_controller_;  // not owned
   TestPowerButtonControllerDelegate* delegate_;  // not owned
   TestShellDelegate* shell_delegate_;  // not owned
+  SessionStateDelegate* state_delegate_;  // not owned
 
   scoped_ptr<SessionStateControllerImpl::TestApi> test_api_;
   scoped_ptr<internal::SessionStateAnimator::TestApi> animator_api_;
@@ -139,7 +142,7 @@
 
   // Notify that the lock window is visible.  We should make it fade in.
   state_controller_->OnLockStateChanged(true);
-  shell_delegate_->LockScreen();
+  state_delegate_->LockScreen();
   EXPECT_TRUE(
       animator_api_->ContainersAreAnimated(
           internal::SessionStateAnimator::kAllLockScreenContainersMask,
@@ -305,7 +308,7 @@
 
   // Notify that the lock window is visible.  We should make it fade in.
   state_controller_->OnLockStateChanged(true);
-  shell_delegate_->LockScreen();
+  state_delegate_->LockScreen();
   EXPECT_TRUE(
       animator_api_->ContainersAreAnimated(
           internal::SessionStateAnimator::kAllLockScreenContainersMask,
@@ -320,7 +323,7 @@
   // Notify that the screen has been unlocked.  We should show the
   // non-screen-locker windows.
   state_controller_->OnLockStateChanged(false);
-  shell_delegate_->UnlockScreen();
+  state_delegate_->UnlockScreen();
   EXPECT_TRUE(
       animator_api_->ContainersAreAnimated(
           internal::SessionStateAnimator::DESKTOP_BACKGROUND |
@@ -341,7 +344,7 @@
   test_api_->trigger_lock_timeout();
   state_controller_->OnStartingLock();
   state_controller_->OnLockStateChanged(true);
-  shell_delegate_->LockScreen();
+  state_delegate_->LockScreen();
 
   // When the lock-to-shutdown timeout fires, we should start the shutdown
   // timer.
@@ -379,7 +382,7 @@
   // Power button is released while system attempts to lock.
   controller_->OnPowerButtonEvent(false, base::TimeTicks::Now());
   state_controller_->OnLockStateChanged(true);
-  shell_delegate_->LockScreen();
+  state_delegate_->LockScreen();
 
   EXPECT_FALSE(state_controller_->ShutdownRequested());
   EXPECT_FALSE(test_api_->lock_to_shutdown_timer_is_running());
@@ -479,7 +482,7 @@
   // Pressing the button also shouldn't do anything after the screen is locked.
   state_controller_->OnStartingLock();
   state_controller_->OnLockStateChanged(true);
-  shell_delegate_->LockScreen();
+  state_delegate_->LockScreen();
   controller_->OnLockButtonEvent(true, base::TimeTicks::Now());
   EXPECT_FALSE(test_api_->lock_timer_is_running());
   controller_->OnLockButtonEvent(false, base::TimeTicks::Now());
@@ -568,7 +571,7 @@
 TEST_F(PowerButtonControllerTest, RequestShutdownFromLockScreen) {
   state_controller_->OnLoginStateChanged(user::LOGGED_IN_USER);
   state_controller_->OnLockStateChanged(true);
-  shell_delegate_->LockScreen();
+  state_delegate_->LockScreen();
   state_controller_->RequestShutdown();
   EXPECT_TRUE(
       animator_api_->ContainersAreAnimated(
@@ -590,7 +593,7 @@
 TEST_F(PowerButtonControllerTest, RequestAndCancelShutdownFromLockScreen) {
   state_controller_->OnLoginStateChanged(user::LOGGED_IN_USER);
   state_controller_->OnLockStateChanged(true);
-  shell_delegate_->LockScreen();
+  state_delegate_->LockScreen();
 
   // Press the power button and check that we start the shutdown timer.
   controller_->OnPowerButtonEvent(true, base::TimeTicks::Now());
diff --git a/ash/wm/screen_dimmer.cc b/ash/wm/screen_dimmer.cc
index 7a01164..3cb4e96 100644
--- a/ash/wm/screen_dimmer.cc
+++ b/ash/wm/screen_dimmer.cc
@@ -39,7 +39,7 @@
   if (should_dim == currently_dimming_)
     return;
 
-  if (!dimming_layer_.get()) {
+  if (!dimming_layer_) {
     dimming_layer_.reset(new ui::Layer(ui::LAYER_SOLID_COLOR));
     dimming_layer_->SetColor(SK_ColorBLACK);
     dimming_layer_->SetOpacity(0.0f);
@@ -60,7 +60,7 @@
 
 void ScreenDimmer::OnRootWindowResized(const aura::RootWindow* root,
                                        const gfx::Size& old_size) {
-  if (dimming_layer_.get())
+  if (dimming_layer_)
     dimming_layer_->SetBounds(gfx::Rect(root->bounds().size()));
 }
 
diff --git a/ash/wm/session_state_animator.cc b/ash/wm/session_state_animator.cc
index a1ac9ac..35ac4cc 100644
--- a/ash/wm/session_state_animator.cc
+++ b/ash/wm/session_state_animator.cc
@@ -614,7 +614,7 @@
 }
 
 void SessionStateAnimator::CreateForeground() {
-  if (foreground_.get())
+  if (foreground_)
     return;
   aura::Window* window = Shell::GetContainer(
       Shell::GetPrimaryRootWindow(),
diff --git a/ash/wm/session_state_controller_impl2.cc b/ash/wm/session_state_controller_impl2.cc
index bb5c68e..f21a8d7 100644
--- a/ash/wm/session_state_controller_impl2.cc
+++ b/ash/wm/session_state_controller_impl2.cc
@@ -263,6 +263,7 @@
     shutdown_after_lock_ = false;
     return;
   }
+
   animator_->StartGlobalAnimation(
       internal::SessionStateAnimator::ANIMATION_UNDO_GRAYSCALE_BRIGHTNESS,
       internal::SessionStateAnimator::ANIMATION_SPEED_REVERT_SHUTDOWN);
@@ -311,6 +312,11 @@
 }
 
 void SessionStateControllerImpl2::StartCancellableShutdownAnimation() {
+  Shell* shell = ash::Shell::GetInstance();
+  // Hide cursor, but let it reappear if the mouse moves.
+  shell->env_filter()->set_cursor_hidden_by_filter(true);
+  shell->cursor_manager()->HideCursor();
+
   animator_->StartGlobalAnimation(
       internal::SessionStateAnimator::ANIMATION_GRAYSCALE_BRIGHTNESS,
       internal::SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);
@@ -581,7 +587,7 @@
 }
 
 void SessionStateControllerImpl2::StoreUnlockedProperties() {
-  if (!unlocked_properties_.get()) {
+  if (!unlocked_properties_) {
     unlocked_properties_.reset(new UnlockedStateProperties());
     unlocked_properties_->background_is_hidden = IsBackgroundHidden();
   }
@@ -596,7 +602,7 @@
 }
 
 void SessionStateControllerImpl2::RestoreUnlockedProperties() {
-  if (!unlocked_properties_.get())
+  if (!unlocked_properties_)
     return;
   if (unlocked_properties_->background_is_hidden) {
     HideBackground();
diff --git a/ash/wm/session_state_controller_impl2_unittest.cc b/ash/wm/session_state_controller_impl2_unittest.cc
index 08032e6..d5aec41 100644
--- a/ash/wm/session_state_controller_impl2_unittest.cc
+++ b/ash/wm/session_state_controller_impl2_unittest.cc
@@ -5,6 +5,7 @@
 #include "ash/wm/session_state_controller_impl2.h"
 
 #include "ash/ash_switches.h"
+#include "ash/session_state_delegate.h"
 #include "ash/shell.h"
 #include "ash/shell_window_ids.h"
 #include "ash/test/ash_test_base.h"
@@ -137,6 +138,7 @@
             animator_.get()));
     shell_delegate_ = reinterpret_cast<TestShellDelegate*>(
         ash::Shell::GetInstance()->delegate());
+    state_delegate_ = Shell::GetInstance()->session_state_delegate();
   }
 
   virtual void TearDown() {
@@ -310,7 +312,7 @@
 
   void ExpectUnlockedState() {
     //TODO (antrim) : restore EXPECT_FALSE(animator_helper_->IsAnimating());
-    EXPECT_FALSE(shell_delegate_->IsScreenLocked());
+    EXPECT_FALSE(state_delegate_->IsScreenLocked());
 
     aura::Window::Windows containers;
 
@@ -331,7 +333,7 @@
 
   void ExpectLockedState() {
     //TODO (antrim) : restore EXPECT_FALSE(animator_helper_->IsAnimating());
-    EXPECT_TRUE(shell_delegate_->IsScreenLocked());
+    EXPECT_TRUE(state_delegate_->IsScreenLocked());
 
     aura::Window::Windows containers;
 
@@ -370,7 +372,7 @@
 
   void SystemLocks() {
     state_controller_->OnLockStateChanged(true);
-    shell_delegate_->LockScreen();
+    state_delegate_->LockScreen();
     //TODO (antrim) : restore animator_helper_->Advance(base::TimeDelta());
   }
 
@@ -382,7 +384,7 @@
 
   void SystemUnlocks() {
     state_controller_->OnLockStateChanged(false);
-    shell_delegate_->UnlockScreen();
+    state_delegate_->UnlockScreen();
     //TODO (antrim) : restore animator_helper_->Advance(base::TimeDelta());
   }
 
@@ -399,6 +401,7 @@
   SessionStateControllerImpl2* state_controller_;  // not owned
   TestSessionStateControllerDelegate* delegate_;  // not owned
   TestShellDelegate* shell_delegate_;  // not owned
+  SessionStateDelegate* state_delegate_;  // not owned
 
   scoped_ptr<ui::ScopedAnimationDurationScaleMode> animation_duration_mode_;
   scoped_ptr<SessionStateControllerImpl2::TestApi> test_api_;
diff --git a/ash/wm/stacking_controller.cc b/ash/wm/stacking_controller.cc
index bbafab4..3802440 100644
--- a/ash/wm/stacking_controller.cc
+++ b/ash/wm/stacking_controller.cc
@@ -5,8 +5,8 @@
 #include "ash/wm/stacking_controller.h"
 
 #include "ash/display/display_controller.h"
+#include "ash/session_state_delegate.h"
 #include "ash/shell.h"
-#include "ash/shell_delegate.h"
 #include "ash/shell_window_ids.h"
 #include "ash/wm/always_on_top_controller.h"
 #include "ash/wm/coordinate_conversion.h"
@@ -119,8 +119,9 @@
 
   // If screen lock is not active and user session is active,
   // all modal windows are placed into the normal modal container.
-  if (!Shell::GetInstance()->delegate()->IsScreenLocked() &&
-      Shell::GetInstance()->delegate()->IsSessionStarted()) {
+  if (!Shell::GetInstance()->session_state_delegate()->IsScreenLocked() &&
+      Shell::GetInstance()->session_state_delegate()->
+          IsActiveUserSessionStarted()) {
     return GetContainerById(root,
                             internal::kShellWindowId_SystemModalContainer);
   }
diff --git a/ash/wm/system_gesture_event_filter.cc b/ash/wm/system_gesture_event_filter.cc
index 8dceaa0..aff065b 100644
--- a/ash/wm/system_gesture_event_filter.cc
+++ b/ash/wm/system_gesture_event_filter.cc
@@ -11,7 +11,7 @@
 #include "ash/shell.h"
 #include "ash/shell_delegate.h"
 #include "ash/shell_window_ids.h"
-#include "ash/wm/gestures/bezel_gesture_handler.h"
+#include "ash/wm/gestures/border_gesture_handler.h"
 #include "ash/wm/gestures/long_press_affordance_handler.h"
 #include "ash/wm/gestures/system_pinch_handler.h"
 #include "ash/wm/gestures/two_finger_drag_handler.h"
@@ -23,7 +23,7 @@
 #include "ui/base/ui_base_switches.h"
 
 #if defined(OS_CHROMEOS)
-#include "ui/base/touch/touch_factory.h"
+#include "ui/base/touch/touch_factory_x11.h"
 #endif
 
 namespace {
@@ -45,7 +45,7 @@
 SystemGestureEventFilter::SystemGestureEventFilter()
     : system_gestures_enabled_(CommandLine::ForCurrentProcess()->
           HasSwitch(ash::switches::kAshEnableAdvancedGestures)),
-      bezel_gestures_(new BezelGestureHandler),
+      border_gestures_(new BorderGestureHandler),
       long_press_affordance_(new LongPressAffordanceHandler),
       two_finger_drag_(new TwoFingerDragHandler) {
 }
@@ -54,7 +54,8 @@
 }
 
 void SystemGestureEventFilter::OnMouseEvent(ui::MouseEvent* event) {
-#if defined(OS_CHROMEOS)
+// TODO(rjkroege): Remove USE_MESSAGEPUMP_LINUX guard once mice are supported.
+#if defined(OS_CHROMEOS) && !defined(USE_MESSAGEPUMP_LINUX)
   if (event->type() == ui::ET_MOUSE_PRESSED && event->native_event() &&
       ui::TouchFactory::GetInstance()->IsTouchDevicePresent() &&
       Shell::GetInstance()->delegate()) {
@@ -76,8 +77,7 @@
   long_press_affordance_->ProcessEvent(target, event,
       event->GetLowestTouchId());
 
-  if (!target || target == target->GetRootWindow()) {
-    bezel_gestures_->ProcessGestureEvent(target, *event);
+  if (border_gestures_->ProcessGestureEvent(target, *event)) {
     event->StopPropagation();
     return;
   }
diff --git a/ash/wm/system_gesture_event_filter.h b/ash/wm/system_gesture_event_filter.h
index ee3b786..ed0a283 100644
--- a/ash/wm/system_gesture_event_filter.h
+++ b/ash/wm/system_gesture_event_filter.h
@@ -31,7 +31,7 @@
 }
 
 namespace internal {
-class BezelGestureHandler;
+class BorderGestureHandler;
 class LongPressAffordanceHandler;
 class SystemPinchHandler;
 class TouchUMA;
@@ -67,7 +67,7 @@
 
   bool system_gestures_enabled_;
 
-  scoped_ptr<BezelGestureHandler> bezel_gestures_;
+  scoped_ptr<BorderGestureHandler> border_gestures_;
   scoped_ptr<LongPressAffordanceHandler> long_press_affordance_;
   scoped_ptr<TwoFingerDragHandler> two_finger_drag_;
 
diff --git a/ash/wm/system_gesture_event_filter_unittest.cc b/ash/wm/system_gesture_event_filter_unittest.cc
index 17ea958..47954a0 100644
--- a/ash/wm/system_gesture_event_filter_unittest.cc
+++ b/ash/wm/system_gesture_event_filter_unittest.cc
@@ -253,7 +253,7 @@
   root_window->AsRootWindowHostDelegate()->OnHostTouchEvent(&press);
 
   scoped_ptr<ui::GestureEvent> event(CreateGesture(
-      ui::ET_GESTURE_TAP, 0, 0, 1, 0, kTouchId));
+      ui::ET_GESTURE_TAP, -10, -10, 1, 0, kTouchId));
   bool consumed = root_window->DispatchGestureEvent(event.get());
 
   EXPECT_TRUE(consumed);
@@ -325,213 +325,6 @@
   EXPECT_EQ(expected_value, delegate->handle_percent());
 }
 
-// Ensure that the device control operation gets properly handled.
-TEST_F(SystemGestureEventFilterTest, DeviceControl) {
-  aura::RootWindow* root_window = Shell::GetPrimaryRootWindow();
-
-  gfx::Rect screen = Shell::GetScreen()->GetPrimaryDisplay().bounds();
-  int ypos_half = screen.height() / 2;
-
-  ash::AcceleratorController* accelerator =
-       ash::Shell::GetInstance()->accelerator_controller();
-
-  DummyBrightnessControlDelegate* delegateBrightness =
-      new DummyBrightnessControlDelegate();
-  accelerator->SetBrightnessControlDelegate(
-      scoped_ptr<BrightnessControlDelegate>(delegateBrightness).Pass());
-
-  DummyVolumeControlDelegate* delegateVolume =
-      new DummyVolumeControlDelegate();
-  ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
-      scoped_ptr<VolumeControlDelegate>(delegateVolume).Pass());
-
-  const int kTouchId = 5;
-
-  for (int pass = 0; pass < 2; pass++) {
-    DelegatePercentTracker* delegate =
-        static_cast<DelegatePercentTracker*>(delegateBrightness);
-    int xpos = screen.x() - 10;
-    int invalid_xpos_direction = 1;
-    int ypos = screen.y();
-    // The expected (middle) value. Note that brightness (first pass) is
-    // slightly higher then 50% since its slider range is 4%..100%.
-    double value = 52.0;
-    if (pass) {
-      // On the second pass the volume will be tested.
-      delegate = static_cast<DelegatePercentTracker*>(delegateVolume);
-      xpos = screen.right() + 10;  // Make sure it is out of the screen.
-      invalid_xpos_direction = -1;
-      value = 50.0;
-    }
-    MoveToDeviceControlBezelStartPosition(
-        root_window, delegate, value, xpos, ypos, ypos_half, kTouchId);
-
-    // A move towards the screen is fine as long as we do not go inside it.
-    scoped_ptr<ui::GestureEvent> event4(CreateGesture(
-        ui::ET_GESTURE_SCROLL_UPDATE,
-        xpos + invalid_xpos_direction,
-        ypos + ypos_half,
-        invalid_xpos_direction, 0, kTouchId));
-    bool consumed = root_window->DispatchGestureEvent(event4.get());
-
-    EXPECT_TRUE(consumed);
-    EXPECT_EQ(2, delegate->handle_percent_count());
-
-    // A move into the screen will cancel the gesture.
-    scoped_ptr<ui::GestureEvent> event5(CreateGesture(
-        ui::ET_GESTURE_SCROLL_UPDATE,
-        xpos + 20 * invalid_xpos_direction,
-        ypos + ypos_half,
-        20 * invalid_xpos_direction, 0, kTouchId));
-    consumed = root_window->DispatchGestureEvent(event5.get());
-
-    EXPECT_TRUE(consumed);
-    EXPECT_EQ(2, delegate->handle_percent_count());
-
-    // Finishing the gesture should not change anything.
-    scoped_ptr<ui::GestureEvent> event6(CreateGesture(
-        ui::ET_GESTURE_SCROLL_END, xpos, ypos + ypos_half,
-        0, 0, kTouchId));
-    consumed = root_window->DispatchGestureEvent(event6.get());
-
-    EXPECT_TRUE(consumed);
-    EXPECT_EQ(2, delegate->handle_percent_count());
-
-    // Another event after this one should get ignored.
-    scoped_ptr<ui::GestureEvent> event7(CreateGesture(
-        ui::ET_GESTURE_SCROLL_UPDATE, xpos, ypos_half,
-        0, 0, kTouchId));
-    consumed = root_window->DispatchGestureEvent(event7.get());
-
-    EXPECT_TRUE(consumed);
-    EXPECT_EQ(2, delegate->handle_percent_count());
-
-    ui::TouchEvent release(ui::ET_TOUCH_RELEASED,
-                           gfx::Point(2 * xpos, ypos + ypos_half),
-                           kTouchId,
-                           ui::EventTimeForNow());
-    root_window->AsRootWindowHostDelegate()->OnHostTouchEvent(&release);
-
-    // Check that huge changes will be interpreted as noise as well.
-    MoveToDeviceControlBezelStartPosition(
-        root_window, delegate, value, xpos, ypos, ypos_half, kTouchId);
-    // Note: The counter is with this call at 3.
-
-    scoped_ptr<ui::GestureEvent> event8(CreateGesture(
-        ui::ET_GESTURE_SCROLL_UPDATE, xpos, ypos / 10,
-        0, ypos / 10 - ypos, kTouchId));
-    consumed = root_window->DispatchGestureEvent(event8.get());
-
-    EXPECT_TRUE(consumed);
-    EXPECT_EQ(3, delegate->handle_percent_count());
-
-    // Release the system.
-    root_window->AsRootWindowHostDelegate()->OnHostTouchEvent(&release);
-  }
-}
-
-// Ensure that the application control operations gets properly handled.
-TEST_F(SystemGestureEventFilterTest, ApplicationControl) {
-  aura::RootWindow* root_window = Shell::GetPrimaryRootWindow();
-
-  gfx::Rect screen = Shell::GetScreen()->GetPrimaryDisplay().bounds();
-  int ypos_half = screen.height() / 2;
-
-  aura::test::TestWindowDelegate delegate;
-  scoped_ptr<aura::Window> window0(
-      aura::test::CreateTestWindowWithDelegate(
-          &delegate, 9, gfx::Rect(0, 0, 100, 100), root_window));
-  scoped_ptr<aura::Window> window1(
-      aura::test::CreateTestWindowWithDelegate(
-          &delegate, 10, gfx::Rect(0, 0, 100, 100), window0.get()));
-  scoped_ptr<aura::Window> window2(
-      aura::test::CreateTestWindowWithDelegate(
-          &delegate, 11, gfx::Rect(0, 0, 100, 100), window0.get()));
-
-  const int kTouchId = 5;
-
-  for (int pass = 0; pass < 2; pass++) {
-    // Add the launcher items and make sure the first item is the active one.
-    TestLauncherDelegate::instance()->AddLauncherItem(window1.get(),
-                                                      ash::STATUS_ACTIVE);
-    TestLauncherDelegate::instance()->AddLauncherItem(window2.get(),
-                                                      ash::STATUS_RUNNING);
-    ash::wm::ActivateWindow(window1.get());
-
-    int xpos = screen.x() - 10;
-    int delta_x = 100;
-    int ypos = screen.y();
-    if (pass) {
-      xpos = screen.right() + 40;  // Make sure the touch is out of the screen.
-      delta_x = -100;
-    }
-
-    aura::Window* active_window = ash::wm::GetActiveWindow();
-
-    // Get a target for kTouchId
-    ui::TouchEvent press(ui::ET_TOUCH_PRESSED,
-                         gfx::Point(-10, ypos + ypos_half),
-                         kTouchId,
-                         ui::EventTimeForNow());
-    root_window->AsRootWindowHostDelegate()->OnHostTouchEvent(&press);
-
-    scoped_ptr<ui::GestureEvent> event1(CreateGesture(
-        ui::ET_GESTURE_SCROLL_BEGIN, xpos, ypos,
-        0, 0, kTouchId));
-    bool consumed = root_window->DispatchGestureEvent(event1.get());
-
-    EXPECT_TRUE(consumed);
-    EXPECT_EQ(ash::wm::GetActiveWindow(), active_window);
-
-    // No move at the beginning will produce no events.
-    scoped_ptr<ui::GestureEvent> event2(CreateGesture(
-        ui::ET_GESTURE_SCROLL_UPDATE,
-        xpos, ypos, 0, 0, kTouchId));
-    consumed = root_window->DispatchGestureEvent(event2.get());
-
-    EXPECT_TRUE(consumed);
-    EXPECT_EQ(ash::wm::GetActiveWindow(), active_window);
-
-    // A move further to the outside will not trigger an action.
-    scoped_ptr<ui::GestureEvent> event3(CreateGesture(
-        ui::ET_GESTURE_SCROLL_UPDATE, xpos - delta_x, ypos,
-        -delta_x, 0, kTouchId));
-    consumed = root_window->DispatchGestureEvent(event3.get());
-
-    EXPECT_TRUE(consumed);
-    EXPECT_EQ(ash::wm::GetActiveWindow(), active_window);
-
-    // A move to the proper side will trigger an action.
-    scoped_ptr<ui::GestureEvent> event4(CreateGesture(
-        ui::ET_GESTURE_SCROLL_UPDATE, xpos + delta_x, ypos,
-        2 * delta_x, 0, kTouchId));
-    consumed = root_window->DispatchGestureEvent(event4.get());
-
-    EXPECT_TRUE(consumed);
-    EXPECT_NE(ash::wm::GetActiveWindow(), active_window);
-    active_window = ash::wm::GetActiveWindow();
-
-    // A second move to the proper side will not trigger an action.
-    scoped_ptr<ui::GestureEvent>  event5(CreateGesture(
-        ui::ET_GESTURE_SCROLL_UPDATE, xpos + 2 * delta_x, ypos,
-        delta_x, 0, kTouchId));
-    consumed = root_window->DispatchGestureEvent(event5.get());
-
-    EXPECT_TRUE(consumed);
-    EXPECT_EQ(ash::wm::GetActiveWindow(), active_window);
-
-    ui::TouchEvent release(ui::ET_TOUCH_RELEASED,
-                           gfx::Point(2 * xpos, ypos + ypos_half),
-                           kTouchId,
-                           ui::EventTimeForNow());
-    root_window->AsRootWindowHostDelegate()->OnHostTouchEvent(&release);
-
-    // Remove the launcher items again.
-    TestLauncherDelegate::instance()->OnWillRemoveWindow(window1.get());
-    TestLauncherDelegate::instance()->OnWillRemoveWindow(window2.get());
-  }
-}
-
 TEST_F(SystemGestureEventFilterTest, LongPressAffordanceStateOnCaptureLoss) {
   aura::RootWindow* root_window = Shell::GetPrimaryRootWindow();
 
@@ -594,16 +387,16 @@
 TEST_F(SystemGestureEventFilterTest, MultiFingerSwipeGestures) {
   aura::RootWindow* root_window = Shell::GetPrimaryRootWindow();
   views::Widget* toplevel = views::Widget::CreateWindowWithContextAndBounds(
-      new ResizableWidgetDelegate, root_window, gfx::Rect(0, 0, 100, 100));
+      new ResizableWidgetDelegate, root_window, gfx::Rect(0, 0, 600, 600));
   toplevel->Show();
 
   const int kSteps = 15;
   const int kTouchPoints = 4;
   gfx::Point points[kTouchPoints] = {
-    gfx::Point(10, 30),
-    gfx::Point(30, 20),
-    gfx::Point(50, 30),
-    gfx::Point(80, 50)
+    gfx::Point(250, 250),
+    gfx::Point(250, 350),
+    gfx::Point(350, 250),
+    gfx::Point(350, 350)
   };
 
   aura::test::EventGenerator generator(root_window,
@@ -647,7 +440,7 @@
 }
 
 TEST_F(SystemGestureEventFilterTest, TwoFingerDrag) {
-  gfx::Rect bounds(0, 0, 100, 100);
+  gfx::Rect bounds(0, 0, 600, 600);
   aura::RootWindow* root_window = Shell::GetPrimaryRootWindow();
   views::Widget* toplevel = views::Widget::CreateWindowWithContextAndBounds(
       new ResizableWidgetDelegate, root_window, bounds);
@@ -656,8 +449,8 @@
   const int kSteps = 15;
   const int kTouchPoints = 2;
   gfx::Point points[kTouchPoints] = {
-    gfx::Point(10, 30),
-    gfx::Point(30, 20),
+    gfx::Point(250, 250),
+    gfx::Point(350, 350),
   };
 
   aura::test::EventGenerator generator(root_window,
diff --git a/ash/wm/system_modal_container_layout_manager.cc b/ash/wm/system_modal_container_layout_manager.cc
index 192d5ab..d35aaa6 100644
--- a/ash/wm/system_modal_container_layout_manager.cc
+++ b/ash/wm/system_modal_container_layout_manager.cc
@@ -4,8 +4,8 @@
 
 #include "ash/wm/system_modal_container_layout_manager.h"
 
+#include "ash/session_state_delegate.h"
 #include "ash/shell.h"
-#include "ash/shell_delegate.h"
 #include "ash/shell_window_ids.h"
 #include "ash/wm/system_modal_container_event_filter.h"
 #include "ash/wm/window_animations.h"
@@ -67,8 +67,9 @@
          child->type() == aura::client::WINDOW_TYPE_POPUP);
   DCHECK(
       container_->id() != internal::kShellWindowId_LockSystemModalContainer ||
-      Shell::GetInstance()->delegate()->IsScreenLocked() ||
-      !Shell::GetInstance()->delegate()->IsSessionStarted());
+      Shell::GetInstance()->session_state_delegate()->IsScreenLocked() ||
+      !Shell::GetInstance()->session_state_delegate()->
+          IsActiveUserSessionStarted());
 
   child->AddObserver(this);
   if (child->GetProperty(aura::client::kModalKey) != ui::MODAL_TYPE_NONE)
@@ -138,7 +139,7 @@
     return true;
   // This container can not handle events if the screen is locked and it is not
   // above the lock screen layer (crbug.com/110920).
-  if (ash::Shell::GetInstance()->IsScreenLocked() &&
+  if (Shell::GetInstance()->session_state_delegate()->IsScreenLocked() &&
       container_->id() < ash::internal::kShellWindowId_LockScreenContainer)
     return true;
   return wm::GetActivatableWindow(window) == modal_window();
diff --git a/ash/wm/system_modal_container_layout_manager_unittest.cc b/ash/wm/system_modal_container_layout_manager_unittest.cc
index f7d7373..15107a4 100644
--- a/ash/wm/system_modal_container_layout_manager_unittest.cc
+++ b/ash/wm/system_modal_container_layout_manager_unittest.cc
@@ -5,8 +5,8 @@
 #include "ash/wm/system_modal_container_layout_manager.h"
 
 #include "ash/root_window_controller.h"
+#include "ash/session_state_delegate.h"
 #include "ash/shell.h"
-#include "ash/shell_delegate.h"
 #include "ash/shell_window_ids.h"
 #include "ash/test/ash_test_base.h"
 #include "ash/wm/window_util.h"
@@ -313,7 +313,7 @@
 
   // Create a window in the lock screen container and ensure that it receives
   // the mouse event instead of the modal window (crbug.com/110920).
-  Shell::GetInstance()->delegate()->LockScreen();
+  Shell::GetInstance()->session_state_delegate()->LockScreen();
   EventTestWindow* lock_delegate = new EventTestWindow(false);
   scoped_ptr<aura::Window> lock(lock_delegate->OpenTestWindowWithParent(
       Shell::GetPrimaryRootWindowController()->GetContainer(
@@ -337,7 +337,7 @@
   EXPECT_EQ(1, lock_delegate->mouse_presses());
   EXPECT_EQ(1, lock_modal_delegate->mouse_presses());
 
-  Shell::GetInstance()->delegate()->UnlockScreen();
+  Shell::GetInstance()->session_state_delegate()->UnlockScreen();
 }
 
 // Makes sure we don't crash if a modal window is shown while the parent window
@@ -409,7 +409,7 @@
 
   // Normal system modal window while locked.  Shows locked system modal
   // background.
-  Shell::GetInstance()->delegate()->LockScreen();
+  Shell::GetInstance()->session_state_delegate()->LockScreen();
   scoped_ptr<aura::Window> lock_parent(OpenTestWindowWithParent(
       Shell::GetPrimaryRootWindowController()->GetContainer(
           ash::internal::kShellWindowId_LockScreenContainer),
diff --git a/ash/wm/toplevel_window_event_handler.cc b/ash/wm/toplevel_window_event_handler.cc
index e62631f..f2b9d9b 100644
--- a/ash/wm/toplevel_window_event_handler.cc
+++ b/ash/wm/toplevel_window_event_handler.cc
@@ -90,13 +90,13 @@
     : handler_(handler),
       resizer_(resizer),
       target_container_(NULL) {
-  if (resizer_.get())
+  if (resizer_)
     resizer_->GetTarget()->AddObserver(this);
 }
 
 ToplevelWindowEventHandler::ScopedWindowResizer::~ScopedWindowResizer() {
   RemoveHandlers();
-  if (resizer_.get())
+  if (resizer_)
     resizer_->GetTarget()->RemoveObserver(this);
 }
 
@@ -331,8 +331,8 @@
   bool destroyed = false;
   destroyed_ = &destroyed;
 #if !defined(OS_MACOSX)
-  MessageLoopForUI* loop = MessageLoopForUI::current();
-  MessageLoop::ScopedNestableTaskAllower allow_nested(loop);
+  base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
+  base::MessageLoop::ScopedNestableTaskAllower allow_nested(loop);
   base::RunLoop run_loop(aura::Env::GetInstance()->GetDispatcher());
   quit_closure_ = run_loop.QuitClosure();
   run_loop.Run();
@@ -350,7 +350,7 @@
     return;
 
   in_move_loop_ = false;
-  if (window_resizer_.get()) {
+  if (window_resizer_) {
     window_resizer_->resizer()->RevertDrag();
     window_resizer_.reset();
   }
@@ -361,7 +361,7 @@
   if (in_move_loop_) {
     move_cancelled_ = true;
     EndMoveLoop();
-  } else if (window_resizer_.get()) {
+  } else if (window_resizer_) {
     window_resizer_->resizer()->RevertDrag();
     window_resizer_.reset();
   }
@@ -381,7 +381,7 @@
 void ToplevelWindowEventHandler::CompleteDrag(DragCompletionStatus status,
                                               int event_flags) {
   scoped_ptr<ScopedWindowResizer> resizer(window_resizer_.release());
-  if (resizer.get()) {
+  if (resizer) {
     if (status == DRAG_COMPLETE)
       resizer->resizer()->CompleteDrag(event_flags);
     else
@@ -451,7 +451,7 @@
   if (event->phase() != ui::EP_PRETARGET)
     return;
 
-  if (!window_resizer_.get())
+  if (!window_resizer_)
     return;
   window_resizer_->resizer()->Drag(
       ConvertPointToParent(target, event->location()), event->flags());
diff --git a/ash/wm/video_detector.cc b/ash/wm/video_detector.cc
index 4c04247..330885d 100644
--- a/ash/wm/video_detector.cc
+++ b/ash/wm/video_detector.cc
@@ -53,11 +53,14 @@
 };
 
 VideoDetector::VideoDetector()
-    : ALLOW_THIS_IN_INITIALIZER_LIST(observer_manager_(this)) {
+    : observer_manager_(this),
+      is_shutting_down_(false) {
   aura::Env::GetInstance()->AddObserver(this);
+  Shell::GetInstance()->AddShellObserver(this);
 }
 
 VideoDetector::~VideoDetector() {
+  Shell::GetInstance()->RemoveShellObserver(this);
   aura::Env::GetInstance()->RemoveObserver(this);
 }
 
@@ -75,6 +78,8 @@
 
 void VideoDetector::OnWindowPaintScheduled(aura::Window* window,
                                            const gfx::Rect& region) {
+  if (is_shutting_down_)
+    return;
   linked_ptr<WindowInfo>& info = window_infos_[window];
   if (!info.get())
     info.reset(new WindowInfo);
@@ -90,6 +95,12 @@
   observer_manager_.Remove(window);
 }
 
+void VideoDetector::OnAppTerminating() {
+  // Stop checking video activity once the shutdown
+  // process starts. crbug.com/231696.
+  is_shutting_down_ = true;
+}
+
 void VideoDetector::MaybeNotifyObservers(aura::Window* window,
                                          base::TimeTicks now) {
   if (!last_observer_notification_time_.is_null() &&
diff --git a/ash/wm/video_detector.h b/ash/wm/video_detector.h
index 7b7de79..81fd2da 100644
--- a/ash/wm/video_detector.h
+++ b/ash/wm/video_detector.h
@@ -8,6 +8,7 @@
 #include <map>
 
 #include "ash/ash_export.h"
+#include "ash/shell_observer.h"
 #include "base/basictypes.h"
 #include "base/compiler_specific.h"
 #include "base/memory/linked_ptr.h"
@@ -40,7 +41,8 @@
 // We err on the side of false positives and can be fooled by things like
 // continuous scrolling of a page.
 class ASH_EXPORT VideoDetector : public aura::EnvObserver,
-                                 public aura::WindowObserver {
+                                 public aura::WindowObserver,
+                                 public ShellObserver  {
  public:
   // Minimum dimensions in pixels that a window update must have to be
   // considered a potential video frame.
@@ -71,6 +73,9 @@
                                       const gfx::Rect& region) OVERRIDE;
   virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE;
 
+  // ShellObserver overrides.
+  virtual void OnAppTerminating() OVERRIDE;
+
  private:
   class WindowInfo;
   typedef std::map<aura::Window*, linked_ptr<WindowInfo> > WindowInfoMap;
@@ -94,6 +99,8 @@
 
   ScopedObserver<aura::Window, aura::WindowObserver> observer_manager_;
 
+  bool is_shutting_down_;
+
   DISALLOW_COPY_AND_ASSIGN(VideoDetector);
 };
 
diff --git a/ash/wm/video_detector_unittest.cc b/ash/wm/video_detector_unittest.cc
index ea9db70..187742c 100644
--- a/ash/wm/video_detector_unittest.cc
+++ b/ash/wm/video_detector_unittest.cc
@@ -143,6 +143,22 @@
   EXPECT_EQ(0, observer_->num_invocations());
 }
 
+TEST_F(VideoDetectorTest, Shutdown) {
+  gfx::Rect window_bounds(gfx::Point(), gfx::Size(1024, 768));
+  scoped_ptr<aura::Window> window(
+      CreateTestWindowInShell(SK_ColorRED, 12345, window_bounds));
+  gfx::Rect update_region(
+      gfx::Point(),
+      gfx::Size(VideoDetector::kMinUpdateWidth,
+                VideoDetector::kMinUpdateHeight));
+
+  // It should not detect video during the shutdown.
+  Shell::GetInstance()->OnAppTerminating();
+  for (int i = 0; i < VideoDetector::kMinFramesPerSecond; ++i)
+    detector_->OnWindowPaintScheduled(window.get(), update_region);
+  EXPECT_EQ(0, observer_->num_invocations());
+}
+
 TEST_F(VideoDetectorTest, WindowNotVisible) {
   gfx::Rect window_bounds(gfx::Point(), gfx::Size(1024, 768));
   scoped_ptr<aura::Window> window(
diff --git a/ash/wm/window_cycle_controller.cc b/ash/wm/window_cycle_controller.cc
index 2aae2a6..89af6c1 100644
--- a/ash/wm/window_cycle_controller.cc
+++ b/ash/wm/window_cycle_controller.cc
@@ -6,7 +6,8 @@
 
 #include <algorithm>
 
-#include "ash/shell_delegate.h"
+#include "ash/session_state_delegate.h"
+#include "ash/shell.h"
 #include "ash/shell_window_ids.h"
 #include "ash/wm/activation_controller.h"
 #include "ash/wm/window_cycle_list.h"
@@ -121,7 +122,7 @@
 bool WindowCycleController::CanCycle() {
   // Don't allow window cycling if the screen is locked or a modal dialog is
   // open.
-  return !Shell::GetInstance()->IsScreenLocked() &&
+  return !Shell::GetInstance()->session_state_delegate()->IsScreenLocked() &&
          !Shell::GetInstance()->IsSystemModalWindowOpen();
 }
 
@@ -149,13 +150,24 @@
   }
 }
 
+void WindowCycleController::HandleLinearCycleWindow() {
+  if (!CanCycle() || IsCycling())
+    return;
+
+  // Use the reversed list of windows to prevent a 2-cycle of the most recent
+  // windows occurring.
+  WindowCycleList cycle_list(BuildWindowList(NULL,true));
+  cycle_list.Step(WindowCycleList::FORWARD);
+}
+
 void WindowCycleController::AltKeyReleased() {
   StopCycling();
 }
 
 // static
 std::vector<aura::Window*> WindowCycleController::BuildWindowList(
-    const std::list<aura::Window*>* mru_windows) {
+    const std::list<aura::Window*>* mru_windows,
+    bool top_most_at_end) {
   WindowCycleList::WindowList windows;
   Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
 
@@ -198,7 +210,8 @@
   }
 
   // Window cycling expects the topmost window at the front of the list.
-  std::reverse(windows.begin(), windows.end());
+  if (!top_most_at_end)
+    std::reverse(windows.begin(), windows.end());
 
   return windows;
 }
@@ -225,7 +238,7 @@
 // WindowCycleController, private:
 
 void WindowCycleController::StartCycling() {
-  windows_.reset(new WindowCycleList(BuildWindowList(&mru_windows_)));
+  windows_.reset(new WindowCycleList(BuildWindowList(&mru_windows_, false)));
 }
 
 void WindowCycleController::Step(Direction direction) {
@@ -237,7 +250,7 @@
 void WindowCycleController::StopCycling() {
   windows_.reset();
   // Remove our key event filter.
-  if (event_handler_.get()) {
+  if (event_handler_) {
     Shell::GetInstance()->RemovePreTargetHandler(event_handler_.get());
     event_handler_.reset();
   }
diff --git a/ash/wm/window_cycle_controller.h b/ash/wm/window_cycle_controller.h
index e673892..9f5b8be 100644
--- a/ash/wm/window_cycle_controller.h
+++ b/ash/wm/window_cycle_controller.h
@@ -58,6 +58,10 @@
   // installs a key filter to watch for alt being released.
   void HandleCycleWindow(Direction direction, bool is_alt_down);
 
+  // Cycles between windows without maintaining a multi-step cycle sequence
+  // (see above).
+  void HandleLinearCycleWindow();
+
   // Informs the controller that the Alt key has been released and it can
   // terminate the existing multi-step cycle.
   void AltKeyReleased();
@@ -78,8 +82,11 @@
   // windows being iterated over.
   // If |mru_windows| is not NULL, windows in this list are put at the head of
   // the window list.
+  // If |top_most_at_end| the window list will return in ascending order instead
+  // of the default descending.
   static std::vector<aura::Window*> BuildWindowList(
-      const std::list<aura::Window*>* mru_windows);
+      const std::list<aura::Window*>* mru_windows,
+      bool top_most_at_end);
 
  private:
   // Call to start cycling windows.  You must call StopCycling() when done.
diff --git a/ash/wm/window_cycle_controller_unittest.cc b/ash/wm/window_cycle_controller_unittest.cc
index fabd9d9..186e2bd 100644
--- a/ash/wm/window_cycle_controller_unittest.cc
+++ b/ash/wm/window_cycle_controller_unittest.cc
@@ -8,6 +8,7 @@
 
 #include "ash/display/display_controller.h"
 #include "ash/display/display_manager.h"
+#include "ash/session_state_delegate.h"
 #include "ash/shell.h"
 #include "ash/shell_window_ids.h"
 #include "ash/test/ash_test_base.h"
@@ -145,14 +146,14 @@
   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
 
   // When the screen is locked, cycling window does not take effect.
-  Shell::GetInstance()->delegate()->LockScreen();
+  Shell::GetInstance()->session_state_delegate()->LockScreen();
   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
   controller->HandleCycleWindow(WindowCycleController::FORWARD, false);
   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
   controller->HandleCycleWindow(WindowCycleController::BACKWARD, false);
   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
 
-  Shell::GetInstance()->delegate()->UnlockScreen();
+  Shell::GetInstance()->session_state_delegate()->UnlockScreen();
   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
   controller->HandleCycleWindow(WindowCycleController::FORWARD, false);
   EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
diff --git a/ash/wm/window_manager_unittest.cc b/ash/wm/window_manager_unittest.cc
index 2fd6e67..936b29a 100644
--- a/ash/wm/window_manager_unittest.cc
+++ b/ash/wm/window_manager_unittest.cc
@@ -11,6 +11,7 @@
 #include "ash/wm/window_util.h"
 #include "ui/aura/client/activation_client.h"
 #include "ui/aura/client/activation_delegate.h"
+#include "ui/aura/client/cursor_client_observer.h"
 #include "ui/aura/client/focus_client.h"
 #include "ui/aura/env.h"
 #include "ui/aura/root_window.h"
@@ -30,6 +31,28 @@
 
 namespace {
 
+class TestingCursorClientObserver : public aura::client::CursorClientObserver {
+ public:
+  TestingCursorClientObserver()
+      : cursor_visibility_(false),
+        did_visibility_change_(false) {}
+  void reset() { cursor_visibility_ = did_visibility_change_ = false; }
+  bool is_cursor_visible() const { return cursor_visibility_; }
+  bool did_visibility_change() const { return did_visibility_change_; }
+
+  // Overridden from aura::client::CursorClientObserver:
+  virtual void OnCursorVisibilityChanged(bool is_visible) OVERRIDE {
+    cursor_visibility_ = is_visible;
+    did_visibility_change_ = true;
+  }
+
+ private:
+  bool cursor_visibility_;
+  bool did_visibility_change_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestingCursorClientObserver);
+};
+
 base::TimeDelta getTime() {
   return ui::EventTimeForNow();
 }
@@ -347,6 +370,44 @@
   }
 }
 
+TEST_F(WindowManagerTest, PanelActivation) {
+  aura::test::TestWindowDelegate wd;
+  scoped_ptr<aura::Window> w1(CreateTestWindowInShellWithDelegate(
+      &wd, -1, gfx::Rect(10, 10, 50, 50)));
+  aura::test::TestWindowDelegate pd;
+  scoped_ptr<aura::Window> p1(CreateTestWindowInShellWithDelegateAndType(
+      &pd, aura::client::WINDOW_TYPE_PANEL, -1, gfx::Rect(10, 10, 50, 50)));
+  aura::client::FocusClient* focus_client =
+      aura::client::GetFocusClient(w1.get());
+
+  // Activate w1.
+  wm::ActivateWindow(w1.get());
+  EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
+
+  // Activate p1.
+  wm::ActivateWindow(p1.get());
+  EXPECT_TRUE(wm::IsActiveWindow(p1.get()));
+  EXPECT_EQ(p1.get(), focus_client->GetFocusedWindow());
+
+  // Activate w1.
+  wm::ActivateWindow(w1.get());
+  EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
+  EXPECT_EQ(w1.get(), focus_client->GetFocusedWindow());
+
+  // Clicking on a non-activatable window should not change the active window.
+  {
+    NonFocusableDelegate nfd;
+    scoped_ptr<aura::Window> w3(CreateTestWindowInShellWithDelegate(
+          &nfd, -1, gfx::Rect(70, 70, 50, 50)));
+    aura::test::EventGenerator generator3(Shell::GetPrimaryRootWindow(),
+                                         w3.get());
+    wm::ActivateWindow(p1.get());
+    EXPECT_TRUE(wm::IsActiveWindow(p1.get()));
+    generator3.ClickLeftButton();
+    EXPECT_TRUE(wm::IsActiveWindow(p1.get()));
+  }
+}
+
 // Essentially the same as ActivateOnMouse, but for touch events.
 TEST_F(WindowManagerTest, ActivateOnTouch) {
   aura::RootWindow* root_window = Shell::GetPrimaryRootWindow();
@@ -715,4 +776,65 @@
   EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
 }
 
+TEST_F(WindowManagerTest, TestCursorClientObserver) {
+  aura::test::EventGenerator& generator = GetEventGenerator();
+  views::corewm::CursorManager* cursor_manager =
+      ash::Shell::GetInstance()->cursor_manager();
+
+  scoped_ptr<aura::Window> w1(CreateTestWindowInShell(
+      SK_ColorWHITE, -1, gfx::Rect(0, 0, 100, 100)));
+  wm::ActivateWindow(w1.get());
+
+  // Add two observers. Both should have OnCursorVisibilityChanged()
+  // invoked when an event changes the visibility of the cursor.
+  TestingCursorClientObserver observer_a;
+  TestingCursorClientObserver observer_b;
+  cursor_manager->AddObserver(&observer_a);
+  cursor_manager->AddObserver(&observer_b);
+
+  // Initial state before any events have been sent.
+  observer_a.reset();
+  observer_b.reset();
+  EXPECT_FALSE(observer_a.did_visibility_change());
+  EXPECT_FALSE(observer_b.did_visibility_change());
+  EXPECT_FALSE(observer_a.is_cursor_visible());
+  EXPECT_FALSE(observer_b.is_cursor_visible());
+
+  // Keypress should hide the cursor.
+  generator.PressKey(ui::VKEY_A, ui::EF_NONE);
+  EXPECT_TRUE(observer_a.did_visibility_change());
+  EXPECT_TRUE(observer_b.did_visibility_change());
+  EXPECT_FALSE(observer_a.is_cursor_visible());
+  EXPECT_FALSE(observer_b.is_cursor_visible());
+
+  // Mouse move should show the cursor.
+  observer_a.reset();
+  observer_b.reset();
+  generator.MoveMouseTo(50, 50);
+  EXPECT_TRUE(observer_a.did_visibility_change());
+  EXPECT_TRUE(observer_b.did_visibility_change());
+  EXPECT_TRUE(observer_a.is_cursor_visible());
+  EXPECT_TRUE(observer_b.is_cursor_visible());
+
+  // Remove observer_b. Its OnCursorVisibilityChanged() should
+  // not be invoked past this point.
+  cursor_manager->RemoveObserver(&observer_b);
+
+  // Gesture tap should hide the cursor.
+  observer_a.reset();
+  observer_b.reset();
+  generator.GestureTapAt(gfx::Point(25, 25));
+  EXPECT_TRUE(observer_a.did_visibility_change());
+  EXPECT_FALSE(observer_b.did_visibility_change());
+  EXPECT_FALSE(observer_a.is_cursor_visible());
+
+  // Mouse move should show the cursor.
+  observer_a.reset();
+  observer_b.reset();
+  generator.MoveMouseTo(50, 50);
+  EXPECT_TRUE(observer_a.did_visibility_change());
+  EXPECT_FALSE(observer_b.did_visibility_change());
+  EXPECT_TRUE(observer_a.is_cursor_visible());
+}
+
 }  // namespace ash
diff --git a/ash/wm/window_properties.cc b/ash/wm/window_properties.cc
index 8b0ed34..21f205a 100644
--- a/ash/wm/window_properties.cc
+++ b/ash/wm/window_properties.cc
@@ -22,9 +22,9 @@
                                  NULL);
 DEFINE_WINDOW_PROPERTY_KEY(bool, kContinueDragAfterReparent, false);
 DEFINE_WINDOW_PROPERTY_KEY(bool, kCyclingThroughWorkspacesKey, false);
+DEFINE_WINDOW_PROPERTY_KEY(bool, kFullscreenUsesMinimalChromeKey, false);
 DEFINE_WINDOW_PROPERTY_KEY(bool, kIgnoreSoloWindowFramePainterPolicy, false);
 DEFINE_WINDOW_PROPERTY_KEY(bool, kIgnoredByShelfKey, false);
-DEFINE_WINDOW_PROPERTY_KEY(bool, kImmersiveModeKey, false);
 DEFINE_WINDOW_PROPERTY_KEY(bool, kPanelAttachedKey, true);
 DEFINE_WINDOW_PROPERTY_KEY(
     ui::WindowShowState, kRestoreShowStateKey, ui::SHOW_STATE_DEFAULT);
diff --git a/ash/wm/window_properties.h b/ash/wm/window_properties.h
index 21d7ae9..7847b62 100644
--- a/ash/wm/window_properties.h
+++ b/ash/wm/window_properties.h
@@ -38,6 +38,12 @@
 ASH_EXPORT extern const aura::WindowProperty<bool>* const
     kCyclingThroughWorkspacesKey;
 
+// A property key to indicate whether there is any chrome at all that cannot be
+// hidden when the window is fullscreen. This is unrelated to whether the full
+// chrome can be revealed by hovering the mouse at the top of the screen.
+ASH_EXPORT extern const aura::WindowProperty<bool>* const
+    kFullscreenUsesMinimalChromeKey;
+
 // A property key to disable the frame painter policy for solo windows.
 // It is only available for root windows.
 ASH_EXPORT extern const aura::WindowProperty<bool>* const
@@ -48,9 +54,6 @@
 extern const aura::WindowProperty<bool>* const
     kIgnoredByShelfKey;
 
-// True if this is a browser window in immersive mode.
-ASH_EXPORT extern const aura::WindowProperty<bool>* const kImmersiveModeKey;
-
 // True if this window is an attached panel.
 ASH_EXPORT extern const aura::WindowProperty<bool>* const kPanelAttachedKey;
 
diff --git a/ash/wm/window_util.cc b/ash/wm/window_util.cc
index 6f591a4..f11b3bc 100644
--- a/ash/wm/window_util.cc
+++ b/ash/wm/window_util.cc
@@ -22,6 +22,8 @@
 #include "ui/gfx/rect.h"
 #include "ui/gfx/screen.h"
 #include "ui/views/corewm/window_util.h"
+#include "ui/views/view.h"
+#include "ui/views/widget/widget.h"
 
 namespace ash {
 namespace wm {
@@ -48,18 +50,6 @@
   return views::corewm::GetActivatableWindow(window);
 }
 
-bool IsActiveWindowFullscreen() {
-  aura::Window* window = GetActiveWindow();
-  while (window) {
-    if (window->GetProperty(aura::client::kShowStateKey) ==
-        ui::SHOW_STATE_FULLSCREEN) {
-      return true;
-    }
-    window = window->parent();
-  }
-  return false;
-}
-
 bool CanActivateWindow(aura::Window* window) {
   return views::corewm::CanActivateWindow(window);
 }
@@ -140,7 +130,7 @@
       Shell::GetScreen()->GetDisplayNearestWindow(window);
   gfx::Rect center = display.work_area();
   center.ClampToCenteredSize(window->bounds().size());
-  window->SetBounds(center);
+  window->SetBoundsInScreen(center, display);
 }
 
 bool IsWindowPositionManaged(const aura::Window* window) {
@@ -201,5 +191,20 @@
   }
 }
 
+bool MoveWindowToEventRoot(aura::Window* window, const ui::Event& event) {
+  views::View* target = static_cast<views::View*>(event.target());
+  if (!target)
+    return false;
+  aura::RootWindow* target_root =
+      target->GetWidget()->GetNativeView()->GetRootWindow();
+  if (!target_root || target_root == window->GetRootWindow())
+    return false;
+  aura::Window* window_container =
+      ash::Shell::GetContainer(target_root, window->parent()->id());
+  // Move the window to the target launcher.
+  window_container->AddChild(window);
+  return true;
+}
+
 }  // namespace wm
 }  // namespace ash
diff --git a/ash/wm/window_util.h b/ash/wm/window_util.h
index 3eac811..1ffeb7d 100644
--- a/ash/wm/window_util.h
+++ b/ash/wm/window_util.h
@@ -19,6 +19,7 @@
 }
 
 namespace ui {
+class Event;
 class Layer;
 }
 
@@ -42,9 +43,6 @@
 // this is probably what you're looking for.
 ASH_EXPORT aura::Window* GetActivatableWindow(aura::Window* window);
 
-// Returns true if the active window or one its ancestors is fullscreen.
-ASH_EXPORT bool IsActiveWindowFullscreen();
-
 // Returns true if |window| can be maximized.
 ASH_EXPORT bool CanMaximizeWindow(const aura::Window* window);
 
@@ -124,6 +122,11 @@
     int min_height,
     gfx::Rect* bounds);
 
+// Moves |window| to the root window where the |event| occured if it is not
+// already in the same root window. Returns true if |window| was moved.
+ASH_EXPORT bool MoveWindowToEventRoot(aura::Window* window,
+                                      const ui::Event& event);
+
 }  // namespace wm
 }  // namespace ash
 
diff --git a/ash/wm/window_util_unittest.cc b/ash/wm/window_util_unittest.cc
new file mode 100644
index 0000000..930b658
--- /dev/null
+++ b/ash/wm/window_util_unittest.cc
@@ -0,0 +1,29 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/wm/window_util.h"
+
+#include "ash/screen_ash.h"
+#include "ash/test/ash_test_base.h"
+#include "ui/aura/window.h"
+
+namespace ash {
+
+typedef test::AshTestBase WindowUtilTest;
+
+TEST_F(WindowUtilTest, CenterWindow) {
+  UpdateDisplay("500x400, 600x400");
+  scoped_ptr<aura::Window> window(
+      CreateTestWindowInShellWithBounds(gfx::Rect(12, 20, 100, 100)));
+  wm::CenterWindow(window.get());
+  EXPECT_EQ("200,126 100x100", window->bounds().ToString());
+  EXPECT_EQ("200,126 100x100", window->GetBoundsInScreen().ToString());
+  window->SetBoundsInScreen(gfx::Rect(600, 0, 100, 100),
+                            ScreenAsh::GetSecondaryDisplay());
+  wm::CenterWindow(window.get());
+  EXPECT_EQ("250,126 100x100", window->bounds().ToString());
+  EXPECT_EQ("750,126 100x100", window->GetBoundsInScreen().ToString());
+}
+
+}  // namespace ash
diff --git a/ash/wm/workspace/colored_window_controller.cc b/ash/wm/workspace/colored_window_controller.cc
index 3ecfe29..08c3dc0 100644
--- a/ash/wm/workspace/colored_window_controller.cc
+++ b/ash/wm/workspace/colored_window_controller.cc
@@ -53,7 +53,7 @@
 
 ColoredWindowController::ColoredWindowController(aura::Window* parent,
                                                  const std::string& window_name)
-    : ALLOW_THIS_IN_INITIALIZER_LIST(view_(new View(this))) {
+    : view_(new View(this)) {
   views::Widget* widget = new views::Widget;
   views::Widget::InitParams params(
       views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
diff --git a/ash/wm/workspace/frame_maximize_button.cc b/ash/wm/workspace/frame_maximize_button.cc
index f47e470..0329e3f 100644
--- a/ash/wm/workspace/frame_maximize_button.cc
+++ b/ash/wm/workspace/frame_maximize_button.cc
@@ -11,6 +11,8 @@
 #include "ash/shell_delegate.h"
 #include "ash/wm/maximize_bubble_controller.h"
 #include "ash/wm/property_util.h"
+#include "ash/wm/window_properties.h"
+#include "ash/wm/window_util.h"
 #include "ash/wm/workspace/phantom_window_controller.h"
 #include "ash/wm/workspace/snap_sizer.h"
 #include "grit/ash_strings.h"
@@ -89,6 +91,9 @@
       bubble_appearance_delay_ms_(kBubbleAppearanceDelayMS) {
   // TODO(sky): nuke this. It's temporary while we don't have good images.
   SetImageAlignment(ALIGN_LEFT, ALIGN_BOTTOM);
+
+  if (ash::Shell::IsForcedMaximizeMode())
+    views::View::SetVisible(false);
 }
 
 FrameMaximizeButton::~FrameMaximizeButton() {
@@ -102,7 +107,7 @@
 void FrameMaximizeButton::SnapButtonHovered(SnapType type) {
   // Make sure to only show hover operations when no button is pressed and
   // a similar snap operation in progress does not get re-applied.
-  if (is_snap_enabled_ || (type == snap_type_ && snap_sizer_.get()))
+  if (is_snap_enabled_ || (type == snap_type_ && snap_sizer_))
     return;
   // Prime the mouse location with the center of the (local) button.
   press_location_ = gfx::Point(width() / 2, height() / 2);
@@ -165,7 +170,11 @@
 void FrameMaximizeButton::OnWindowPropertyChanged(aura::Window* window,
                                                   const void* key,
                                                   intptr_t old) {
-  Cancel(false);
+  // Changing the window position is managed status should not Cancel.
+  // Note that this case might happen when a non user managed window
+  // transitions from maximized to L/R maximized.
+  if (key != ash::internal::kWindowPositionManagedKey)
+    Cancel(false);
 }
 
 void FrameMaximizeButton::OnWindowDestroying(aura::Window* window) {
@@ -181,7 +190,7 @@
 void FrameMaximizeButton::OnWidgetActivationChanged(views::Widget* widget,
                                                     bool active) {
   // Upon losing focus, the control bubble should hide.
-  if (!active && maximizer_.get())
+  if (!active && maximizer_)
     maximizer_.reset();
 }
 
@@ -201,7 +210,7 @@
 
 void FrameMaximizeButton::OnMouseEntered(const ui::MouseEvent& event) {
   ImageButton::OnMouseEntered(event);
-  if (!maximizer_.get()) {
+  if (!maximizer_) {
     DCHECK(GetWidget());
     if (!widget_) {
       widget_ = frame_->GetWidget();
@@ -219,7 +228,7 @@
   ImageButton::OnMouseExited(event);
   // Remove the bubble menu when the button is not pressed and the mouse is not
   // within the bubble.
-  if (!is_snap_enabled_ && maximizer_.get()) {
+  if (!is_snap_enabled_ && maximizer_) {
     if (maximizer_->GetBubbleWindow()) {
       gfx::Point screen_location = Shell::GetScreen()->GetCursorScreenPoint();
       if (!maximizer_->GetBubbleWindow()->GetBoundsInScreen().Contains(
@@ -264,7 +273,7 @@
   }
 
   if (event->type() == ui::ET_GESTURE_TAP ||
-      event->type() == ui::ET_GESTURE_SCROLL_END ||
+      (event->type() == ui::ET_GESTURE_SCROLL_END && is_snap_enabled_) ||
       event->type() == ui::ET_SCROLL_FLING_START) {
     // The position of the event may have changed from the previous event (both
     // for TAP and SCROLL_END). So it is necessary to update the snap-state for
@@ -300,10 +309,18 @@
   ImageButton::OnGestureEvent(event);
 }
 
+void FrameMaximizeButton::SetVisible(bool visible) {
+  // In the enforced maximized mode we do not allow to be made visible.
+  if (ash::Shell::IsForcedMaximizeMode())
+    return;
+
+  views::View::SetVisible(visible);
+}
+
 void FrameMaximizeButton::ProcessStartEvent(const ui::LocatedEvent& event) {
   DCHECK(is_snap_enabled_);
   // Prepare the help menu.
-  if (!maximizer_.get()) {
+  if (!maximizer_) {
     maximizer_.reset(new MaximizeBubbleController(
         this,
         GetMaximizeBubbleFrameState(),
@@ -373,7 +390,7 @@
 }
 
 void FrameMaximizeButton::InstallEventFilter() {
-  if (escape_event_filter_.get())
+  if (escape_event_filter_)
     return;
 
   escape_event_filter_.reset(new EscapeEventFilter(this));
@@ -396,7 +413,7 @@
                                      bool is_touch) {
   SnapType type = SnapTypeForLocation(location);
   if (type == snap_type_) {
-    if (snap_sizer_.get()) {
+    if (snap_sizer_) {
       snap_sizer_->Update(LocationForSnapSizer(location));
       phantom_window_->Show(ScreenAsh::ConvertRectToScreen(
           frame_->GetWidget()->GetNativeView()->parent(),
@@ -427,11 +444,11 @@
     if (select_default)
       snap_sizer_->SelectDefaultSizeAndDisableResize();
   }
-  if (!phantom_window_.get()) {
+  if (!phantom_window_) {
     phantom_window_.reset(new internal::PhantomWindowController(
                               frame_->GetWidget()->GetNativeWindow()));
   }
-  if (maximizer_.get()) {
+  if (maximizer_) {
     phantom_window_->set_phantom_below_window(maximizer_->GetBubbleWindow());
     maximizer_->SetSnapType(snap_type_);
   }
@@ -508,20 +525,35 @@
     case SNAP_LEFT:
     case SNAP_RIGHT: {
       shell->delegate()->RecordUserMetricsAction(
-          snap_type_ == SNAP_LEFT ? ash::UMA_MAXIMIZE_BUTTON_MAXIMIZE_LEFT :
-                                    ash::UMA_MAXIMIZE_BUTTON_MAXIMIZE_RIGHT);
+          snap_type_ == SNAP_LEFT ?
+              ash::UMA_WINDOW_MAXIMIZE_BUTTON_MAXIMIZE_LEFT :
+              ash::UMA_WINDOW_MAXIMIZE_BUTTON_MAXIMIZE_RIGHT);
       // Get the bounds in screen coordinates for restore purposes.
       gfx::Rect restore = widget->GetWindowBoundsInScreen();
-      if (widget->IsMaximized()) {
+      if (widget->IsMaximized() || widget->IsFullscreen()) {
+        aura::Window* window = widget->GetNativeWindow();
         // In case of maximized we have a restore boundary.
-        DCHECK(ash::GetRestoreBoundsInScreen(widget->GetNativeWindow()));
+        DCHECK(ash::GetRestoreBoundsInScreen(window));
         // If it was maximized we need to recover the old restore set.
-        restore = *ash::GetRestoreBoundsInScreen(widget->GetNativeWindow());
+        restore = *ash::GetRestoreBoundsInScreen(window);
+
+        // The auto position manager will kick in when this is the only window.
+        // To avoid interference with it we tell it temporarily to not change
+        // the coordinates of this window.
+        bool is_managed = ash::wm::IsWindowPositionManaged(window);
+        if (is_managed)
+          ash::wm::SetWindowPositionManaged(window, false);
+
         // Set the restore size we want to restore to.
-        ash::SetRestoreBoundsInScreen(widget->GetNativeWindow(),
+        ash::SetRestoreBoundsInScreen(window,
                                       ScreenBoundsForType(snap_type_,
                                                           snap_sizer));
         widget->Restore();
+
+        // After the window is where we want it to be we allow the window to be
+        // auto managed again.
+        if (is_managed)
+          ash::wm::SetWindowPositionManaged(window, true);
       } else {
         // Others might also have set up a restore rectangle already. If so,
         // we should not overwrite the restore rectangle.
@@ -538,17 +570,17 @@
     case SNAP_MAXIMIZE:
       widget->Maximize();
       shell->delegate()->RecordUserMetricsAction(
-          ash::UMA_MAXIMIZE_BUTTON_MAXIMIZE);
+          ash::UMA_WINDOW_MAXIMIZE_BUTTON_MAXIMIZE);
       break;
     case SNAP_MINIMIZE:
       widget->Minimize();
       shell->delegate()->RecordUserMetricsAction(
-          ash::UMA_MAXIMIZE_BUTTON_MINIMIZE);
+          ash::UMA_WINDOW_MAXIMIZE_BUTTON_MINIMIZE);
       break;
     case SNAP_RESTORE:
       widget->Restore();
       shell->delegate()->RecordUserMetricsAction(
-          ash::UMA_MAXIMIZE_BUTTON_RESTORE);
+          ash::UMA_WINDOW_MAXIMIZE_BUTTON_RESTORE);
       break;
     case SNAP_NONE:
       NOTREACHED();
@@ -556,7 +588,7 @@
 }
 
 MaximizeBubbleFrameState
-   FrameMaximizeButton::GetMaximizeBubbleFrameState() const {
+FrameMaximizeButton::GetMaximizeBubbleFrameState() const {
   // When there are no restore bounds, we are in normal mode.
   if (!ash::GetRestoreBoundsInScreen(
            frame_->GetWidget()->GetNativeWindow()))
diff --git a/ash/wm/workspace/frame_maximize_button.h b/ash/wm/workspace/frame_maximize_button.h
index b6aa1fa..6429aed 100644
--- a/ash/wm/workspace/frame_maximize_button.h
+++ b/ash/wm/workspace/frame_maximize_button.h
@@ -74,6 +74,9 @@
   // ui::EventHandler overrides:
   virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
 
+  // views::View overwrite:
+  virtual void SetVisible(bool visible) OVERRIDE;
+
   // Unit test overwrite: Change the UI delay used for the bubble show up.
   void set_bubble_appearance_delay_ms(int bubble_appearance_delay_ms) {
     bubble_appearance_delay_ms_ = bubble_appearance_delay_ms;
diff --git a/ash/wm/workspace/multi_window_resize_controller.cc b/ash/wm/workspace/multi_window_resize_controller.cc
index 1dea17d..798b5c4 100644
--- a/ash/wm/workspace/multi_window_resize_controller.cc
+++ b/ash/wm/workspace/multi_window_resize_controller.cc
@@ -162,7 +162,7 @@
   // only care about mouse movements from MouseWatcher. This is necessary as
   // WorkspaceEventHandler only sees mouse movements over the windows, not all
   // windows or over the desktop.
-  if (resize_widget_.get())
+  if (resize_widget_)
     return;
 
   ResizeWindows windows(DetermineWindows(window, component, point_in_window));
@@ -190,7 +190,7 @@
 
 void MultiWindowResizeController::Hide() {
   hide_timer_.Stop();
-  if (window_resizer_.get())
+  if (window_resizer_)
     return;  // Ignore hides while actively resizing.
 
   if (windows_.window1) {
@@ -204,7 +204,7 @@
 
   show_timer_.Stop();
 
-  if (!resize_widget_.get())
+  if (!resize_widget_)
     return;
 
   for (size_t i = 0; i < windows_.other_windows.size(); ++i)
@@ -473,7 +473,7 @@
 }
 
 void MultiWindowResizeController::CancelResize() {
-  if (!window_resizer_.get())
+  if (!window_resizer_)
     return;  // Happens if window was destroyed and we nuked the WindowResizer.
   window_resizer_->RevertDrag();
   window_resizer_.reset();
@@ -504,7 +504,7 @@
 
 bool MultiWindowResizeController::IsOverWindows(
     const gfx::Point& location_in_screen) const {
-  if (window_resizer_.get())
+  if (window_resizer_)
     return true;  // Ignore hides while actively resizing.
 
   if (resize_widget_->GetWindowBoundsInScreen().Contains(location_in_screen))
diff --git a/ash/wm/workspace/workspace.cc b/ash/wm/workspace/workspace.cc
index 6513dea..142414d 100644
--- a/ash/wm/workspace/workspace.cc
+++ b/ash/wm/workspace/workspace.cc
@@ -78,15 +78,11 @@
     if (!child->TargetVisibility() || wm::IsWindowMinimized(child))
       continue;
 
-    if (!GetTrackedByWorkspace(child)) {
-      // If we have a maximized window that isn't tracked don't move to
-      // pending. This handles the case of dragging a maximized window.
-      if (WorkspaceManager::IsMaximized(child))
-        return false;
-      continue;
-    }
+    // If we have a maximized window don't move to pending.
+    if (WorkspaceManager::IsMaximized(child))
+      return false;
 
-    if (!GetPersistsAcrossAllWorkspaces(child))
+    if (GetTrackedByWorkspace(child) && !GetPersistsAcrossAllWorkspaces(child))
       return false;
   }
   return true;
diff --git a/ash/wm/workspace/workspace_cycler.cc b/ash/wm/workspace/workspace_cycler.cc
index 6731993..7f88fc3 100644
--- a/ash/wm/workspace/workspace_cycler.cc
+++ b/ash/wm/workspace/workspace_cycler.cc
@@ -6,6 +6,7 @@
 
 #include <cmath>
 
+#include "ash/session_state_delegate.h"
 #include "ash/shell.h"
 #include "ash/wm/workspace/workspace_cycler_configuration.h"
 #include "ash/wm/workspace/workspace_manager.h"
@@ -22,7 +23,7 @@
 // Returns true if cycling is allowed.
 bool IsCyclingAllowed() {
   // Cycling is disabled if the screen is locked or a modal dialog is open.
-  return !Shell::GetInstance()->IsScreenLocked() &&
+  return !Shell::GetInstance()->session_state_delegate()->IsScreenLocked() &&
          !Shell::GetInstance()->IsSystemModalWindowOpen();
 }
 
@@ -61,12 +62,12 @@
         animator_.get());
     animator_->AnimateStartingCycler();
   } else if (new_state == STOPPING_CYCLING) {
-    if (animator_.get())
+    if (animator_)
       animator_->AnimateStoppingCycler();
   } else if (new_state == NOT_CYCLING) {
     scroll_x_ = 0.0f;
     scroll_y_ = 0.0f;
-    if (animator_.get()) {
+    if (animator_) {
       animator_->AbortAnimations();
       animator_.reset();
     }
diff --git a/ash/wm/workspace/workspace_cycler_animator.cc b/ash/wm/workspace/workspace_cycler_animator.cc
index b02aa8b..1a0c3c3 100644
--- a/ash/wm/workspace/workspace_cycler_animator.cc
+++ b/ash/wm/workspace/workspace_cycler_animator.cc
@@ -725,7 +725,7 @@
       completed_animation == CYCLER_END) {
     // Post a task to notify the delegate of the animation completion because
     // the delegate may delete |this| as a result of getting notified.
-    MessageLoopForUI::current()->PostTask(
+    base::MessageLoopForUI::current()->PostTask(
         FROM_HERE,
         base::Bind(&WorkspaceCyclerAnimator::NotifyDelegate,
                    AsWeakPtr(),
diff --git a/ash/wm/workspace/workspace_event_handler.cc b/ash/wm/workspace/workspace_event_handler.cc
index 5839e21..16d86ca 100644
--- a/ash/wm/workspace/workspace_event_handler.cc
+++ b/ash/wm/workspace/workspace_event_handler.cc
@@ -91,7 +91,8 @@
 
       if (event->flags() & ui::EF_IS_DOUBLE_CLICK &&
           target->delegate()->GetNonClientComponent(event->location()) ==
-          HTCAPTION) {
+          HTCAPTION &&
+          !ash::Shell::IsForcedMaximizeMode()) {
         bool destroyed = false;
         destroyed_ = &destroyed;
         ash::Shell::GetInstance()->delegate()->RecordUserMetricsAction(
diff --git a/ash/wm/workspace/workspace_event_handler_unittest.cc b/ash/wm/workspace/workspace_event_handler_unittest.cc
index 376f547..91a6557 100644
--- a/ash/wm/workspace/workspace_event_handler_unittest.cc
+++ b/ash/wm/workspace/workspace_event_handler_unittest.cc
@@ -216,10 +216,11 @@
   wd.set_window_component(HTCAPTION);
 
   ASSERT_TRUE(aura::client::GetWindowMoveClient(window->parent()));
-  MessageLoop::current()->DeleteSoon(FROM_HERE, window.get());
-  aura::client::GetWindowMoveClient(window->parent())->RunMoveLoop(
-      window.release(), gfx::Vector2d(),
-      aura::client::WINDOW_MOVE_SOURCE_MOUSE);
+  base::MessageLoop::current()->DeleteSoon(FROM_HERE, window.get());
+  aura::client::GetWindowMoveClient(window->parent())
+      ->RunMoveLoop(window.release(),
+                    gfx::Vector2d(),
+                    aura::client::WINDOW_MOVE_SOURCE_MOUSE);
 }
 
 }  // namespace internal
diff --git a/ash/wm/workspace/workspace_layout_manager.cc b/ash/wm/workspace/workspace_layout_manager.cc
index 1b052d2..65ed116 100644
--- a/ash/wm/workspace/workspace_layout_manager.cc
+++ b/ash/wm/workspace/workspace_layout_manager.cc
@@ -6,6 +6,7 @@
 
 #include "ash/ash_switches.h"
 #include "ash/screen_ash.h"
+#include "ash/session_state_delegate.h"
 #include "ash/shell.h"
 #include "ash/wm/always_on_top_controller.h"
 #include "ash/wm/base_layout_manager.h"
@@ -190,7 +191,7 @@
         GetRestoreBoundsInScreen(window) &&
         !GetWindowAlwaysRestoresToRestoreBounds(window)) {
       restore = *GetRestoreBoundsInScreen(window);
-      SetRestoreBoundsInScreen(window, window->bounds());
+      SetRestoreBoundsInScreen(window, window->GetBoundsInScreen());
     }
 
     // If maximizing or restoring, clone the layer. WorkspaceManager will use it
@@ -288,7 +289,7 @@
   // This would happen if the launcher was auto hidden before the login screen
   // was shown and then gets shown when the login screen gets presented.
   if (reason == ADJUST_WINDOW_DISPLAY_INSETS_CHANGED &&
-      Shell::GetInstance()->IsScreenLocked())
+      Shell::GetInstance()->session_state_delegate()->IsScreenLocked())
     return;
   work_area_ = ScreenAsh::GetDisplayWorkAreaBoundsInParent(
       workspace_->window()->parent());
diff --git a/ash/wm/workspace/workspace_layout_manager_unittest.cc b/ash/wm/workspace/workspace_layout_manager_unittest.cc
index 6b33d5e..07a6ecd 100644
--- a/ash/wm/workspace/workspace_layout_manager_unittest.cc
+++ b/ash/wm/workspace/workspace_layout_manager_unittest.cc
@@ -5,6 +5,7 @@
 #include "ash/wm/workspace/workspace_layout_manager.h"
 
 #include "ash/root_window_controller.h"
+#include "ash/screen_ash.h"
 #include "ash/shelf/shelf_layout_manager.h"
 #include "ash/shelf/shelf_widget.h"
 #include "ash/shell.h"
@@ -31,11 +32,31 @@
       CreateTestWindowInShellWithBounds(gfx::Rect(1, 2, 3, 4)));
   gfx::Rect bounds(10, 15, 25, 35);
   window->SetBounds(bounds);
+  // This will not be used for un-minimizing window.
   SetRestoreBoundsInScreen(window.get(), gfx::Rect(0, 0, 100, 100));
   wm::MinimizeWindow(window.get());
   wm::RestoreWindow(window.get());
   EXPECT_EQ("0,0 100x100", GetRestoreBoundsInScreen(window.get())->ToString());
   EXPECT_EQ("10,15 25x35", window.get()->bounds().ToString());
+
+  UpdateDisplay("400x300,500x400");
+  window->SetBoundsInScreen(gfx::Rect(600, 0, 100, 100),
+                            ScreenAsh::GetSecondaryDisplay());
+  EXPECT_EQ(Shell::GetAllRootWindows()[1], window->GetRootWindow());
+  wm::MinimizeWindow(window.get());
+  // This will not be used for un-minimizing window.
+  SetRestoreBoundsInScreen(window.get(), gfx::Rect(0, 0, 100, 100));
+  wm::RestoreWindow(window.get());
+  EXPECT_EQ("600,0 100x100", window->GetBoundsInScreen().ToString());
+
+  // Make sure the unminimized window moves inside the display when
+  // 2nd display is disconnected.
+  wm::MinimizeWindow(window.get());
+  UpdateDisplay("400x300");
+  wm::RestoreWindow(window.get());
+  EXPECT_EQ(Shell::GetPrimaryRootWindow(), window->GetRootWindow());
+  EXPECT_TRUE(
+      Shell::GetPrimaryRootWindow()->bounds().Intersects(window->bounds()));
 }
 
 // WindowObserver implementation used by DontClobberRestoreBoundsWindowObserver.
diff --git a/ash/wm/workspace/workspace_manager.cc b/ash/wm/workspace/workspace_manager.cc
index 106dbff..69413fe 100644
--- a/ash/wm/workspace/workspace_manager.cc
+++ b/ash/wm/workspace/workspace_manager.cc
@@ -76,11 +76,12 @@
 // Workspace -------------------------------------------------------------------
 
 // LayoutManager installed on the parent window of all the Workspace window (eg
-// |WorkspaceManager::contents_view_|).
+// |WorkspaceManager::contents_window_|).
 class WorkspaceManager::LayoutManagerImpl : public BaseLayoutManager {
  public:
   explicit LayoutManagerImpl(WorkspaceManager* workspace_manager)
-      : BaseLayoutManager(workspace_manager->contents_view_->GetRootWindow()),
+      : BaseLayoutManager(
+            workspace_manager->contents_window_->GetRootWindow()),
         workspace_manager_(workspace_manager) {
   }
   virtual ~LayoutManagerImpl() {}
@@ -98,7 +99,7 @@
   }
 
  private:
-  aura::Window* window() { return workspace_manager_->contents_view_; }
+  aura::Window* window() { return workspace_manager_->contents_window_; }
 
   WorkspaceManager* workspace_manager_;
 
@@ -107,21 +108,20 @@
 
 // WorkspaceManager -----------------------------------------------------------
 
-WorkspaceManager::WorkspaceManager(Window* contents_view)
-    : contents_view_(contents_view),
+WorkspaceManager::WorkspaceManager(Window* contents_window)
+    : contents_window_(contents_window),
       active_workspace_(NULL),
       shelf_(NULL),
       in_move_(false),
-      ALLOW_THIS_IN_INITIALIZER_LIST(
-          clear_unminimizing_workspace_factory_(this)),
+      clear_unminimizing_workspace_factory_(this),
       unminimizing_workspace_(NULL),
       app_terminating_(false),
       creating_fade_(false),
       workspace_cycler_(NULL) {
   // Clobber any existing event filter.
-  contents_view->SetEventFilter(NULL);
-  // |contents_view| takes ownership of LayoutManagerImpl.
-  contents_view->SetLayoutManager(new LayoutManagerImpl(this));
+  contents_window->SetEventFilter(NULL);
+  // |contents_window| takes ownership of LayoutManagerImpl.
+  contents_window->SetLayoutManager(new LayoutManagerImpl(this));
   active_workspace_ = CreateWorkspace(false);
   workspaces_.push_back(active_workspace_);
   active_workspace_->window()->Show();
@@ -133,7 +133,7 @@
 
 WorkspaceManager::~WorkspaceManager() {
   Shell::GetInstance()->RemoveShellObserver(this);
-  // Release the windows, they'll be destroyed when |contents_view_| is
+  // Release the windows, they'll be destroyed when |contents_window_| is
   // destroyed.
   std::for_each(workspaces_.begin(), workspaces_.end(),
                 std::mem_fun(&Workspace::ReleaseWindow));
@@ -301,7 +301,7 @@
 void WorkspaceManager::DoInitialAnimation() {
   if (active_workspace_->is_maximized()) {
     RootWindowController* root_controller = GetRootWindowController(
-        contents_view_->GetRootWindow());
+        contents_window_->GetRootWindow());
     if (root_controller) {
       aura::Window* background = root_controller->GetContainer(
           kShellWindowId_DesktopBackgroundContainer);
@@ -341,7 +341,7 @@
 
   // It is possible for a user to use accelerator keys to restore windows etc
   // while the user is cycling through workspaces.
-  if (workspace_cycler_.get())
+  if (workspace_cycler_)
     workspace_cycler_->AbortCycling();
 
   pending_workspaces_.erase(workspace);
@@ -350,8 +350,8 @@
   // it always stays at the bottom.
   if (workspace != desktop_workspace() &&
       FindWorkspace(workspace) == workspaces_.end()) {
-    contents_view_->StackChildAbove(workspace->window(),
-                                    workspaces_.back()->window());
+    contents_window_->StackChildAbove(workspace->window(),
+                                      workspaces_.back()->window());
     workspaces_.push_back(workspace);
   }
 
@@ -369,13 +369,15 @@
   if (is_unminimizing_maximized_window) {
     // If we're unminimizing a window it needs to be on the top, otherwise you
     // won't see the animation.
-    contents_view_->StackChildAtTop(active_workspace_->window());
-  } else if (active_workspace_->is_maximized() && last_active->is_maximized()) {
+    contents_window_->StackChildAtTop(active_workspace_->window());
+  } else if (active_workspace_->is_maximized() &&
+             last_active->is_maximized() &&
+             reason != SWITCH_MAXIMIZED_FROM_MAXIMIZED_WORKSPACE) {
     // When switching between maximized windows we need the last active
     // workspace on top of the new, otherwise the animations won't look
     // right. Since only one workspace is visible at a time stacking order of
     // the workspace windows ultimately doesn't matter.
-    contents_view_->StackChildAtTop(last_active->window());
+    contents_window_->StackChildAtTop(last_active->window());
   }
 
   UpdateShelfVisibility();
@@ -385,7 +387,7 @@
   ShowWorkspace(workspace, last_active, reason);
 
   RootWindowController* root_controller = GetRootWindowController(
-      contents_view_->GetRootWindow());
+      contents_window_->GetRootWindow());
   if (root_controller) {
     aura::Window* background = root_controller->GetContainer(
         kShellWindowId_DesktopBackgroundContainer);
@@ -398,7 +400,7 @@
 
   // Showing or hiding a workspace may change the "solo window" status of
   // a window, requiring the header to be updated.
-  FramePainter::UpdateSoloWindowHeader(contents_view_->GetRootWindow());
+  FramePainter::UpdateSoloWindowHeader(contents_window_->GetRootWindow());
 }
 
 WorkspaceManager::Workspaces::iterator
@@ -407,7 +409,7 @@
 }
 
 Workspace* WorkspaceManager::CreateWorkspace(bool maximized) {
-  return new Workspace(this, contents_view_, maximized);
+  return new Workspace(this, contents_window_, maximized);
 }
 
 void WorkspaceManager::MoveWorkspaceToPendingOrDelete(
@@ -422,7 +424,7 @@
 
   // The user may have closed or minimized a window via accelerator keys while
   // cycling through workspaces.
-  if (workspace_cycler_.get())
+  if (workspace_cycler_)
     workspace_cycler_->AbortCycling();
 
   if (workspace == active_workspace_)
@@ -499,7 +501,7 @@
   // the process unminimizing and can do the right animation.
   unminimizing_workspace_ = workspace;
   if (unminimizing_workspace_) {
-    MessageLoop::current()->PostTask(
+    base::MessageLoop::current()->PostTask(
         FROM_HERE,
         base::Bind(&WorkspaceManager::SetUnminimizingWorkspace,
                    clear_unminimizing_workspace_factory_.GetWeakPtr(),
@@ -524,7 +526,7 @@
     stack_above = window;
   } else {
     direction = DesktopBackgroundFadeController::FADE_OUT;
-    parent = contents_view_;
+    parent = contents_window_;
     stack_above = desktop_workspace()->window();
     DCHECK_EQ(kCrossFadeSwitchTimeMS,
               static_cast<int>(duration.InMilliseconds()));
@@ -549,6 +551,7 @@
       // The workspace cycler has already animated the desktop background's
       // opacity. Do not do any further animation.
       break;
+    case SWITCH_MAXIMIZED_FROM_MAXIMIZED_WORKSPACE:
     case SWITCH_MAXIMIZED_OR_RESTORED:
       // FadeDesktop() fades the desktop background by animating the opacity of
       // a black window immediately above the desktop background. Set the
@@ -628,6 +631,7 @@
       details.animate_scale = true;
       break;
 
+    case SWITCH_MAXIMIZED_FROM_MAXIMIZED_WORKSPACE:
     case SWITCH_MAXIMIZED_OR_RESTORED:
       if (active_workspace_->is_maximized()) {
         // Delay the hide until the animation is done.
@@ -688,6 +692,7 @@
                                                     Window* child) {
   if (workspace->ShouldMoveToPending())
     MoveWorkspaceToPendingOrDelete(workspace, NULL, SWITCH_WINDOW_REMOVED);
+  UpdateShelfVisibility();
 }
 
 void WorkspaceManager::OnWorkspaceChildWindowVisibilityChanged(
@@ -765,7 +770,10 @@
       // WorkspaceLayoutManager::OnWindowPropertyChanged() the window is made
       // active.
       if (old_layer) {
-        SetActiveWorkspace(new_workspace, SWITCH_MAXIMIZED_OR_RESTORED,
+        SetActiveWorkspace(new_workspace,
+                           max_count >= 2 ?
+                               SWITCH_MAXIMIZED_FROM_MAXIMIZED_WORKSPACE :
+                               SWITCH_MAXIMIZED_OR_RESTORED,
                            duration);
         CrossFadeWindowBetweenWorkspaces(new_workspace->window(), child,
                                          old_layer);
diff --git a/ash/wm/workspace/workspace_manager.h b/ash/wm/workspace/workspace_manager.h
index cb827a7..d3a7389 100644
--- a/ash/wm/workspace/workspace_manager.h
+++ b/ash/wm/workspace/workspace_manager.h
@@ -118,6 +118,8 @@
     SWITCH_VISIBILITY_CHANGED,
     SWITCH_MINIMIZED,
     SWITCH_MAXIMIZED_OR_RESTORED,
+    // Switch a normal window in a maximized workspace to maximized.
+    SWITCH_MAXIMIZED_FROM_MAXIMIZED_WORKSPACE,
     SWITCH_TRACKED_BY_WORKSPACE_CHANGED,
 
     // Switch as the result of DoInitialAnimation(). This isn't a real switch,
@@ -221,7 +223,7 @@
   void OnTrackedByWorkspaceChanged(Workspace* workspace,
                                    aura::Window* window);
 
-  aura::Window* contents_view_;
+  aura::Window* contents_window_;
 
   Workspace* active_workspace_;
 
@@ -231,7 +233,7 @@
 
   // The set of workspaces not currently active. Workspaces ended up here in
   // two scenarios:
-  // . Prior to adding a window a new worskpace is created for it. The
+  // . Prior to adding a window a new workspace is created for it. The
   //   Workspace is added to this set.
   // . When the maximized window is minimized the workspace is added here.
   // Once any window in the workspace is activated the workspace is moved to
diff --git a/ash/wm/workspace/workspace_manager_unittest.cc b/ash/wm/workspace/workspace_manager_unittest.cc
index 2607251..a5e9796 100644
--- a/ash/wm/workspace/workspace_manager_unittest.cc
+++ b/ash/wm/workspace/workspace_manager_unittest.cc
@@ -23,7 +23,7 @@
 #include "ash/wm/workspace/workspace.h"
 #include "ash/wm/workspace_controller_test_helper.h"
 #include "base/command_line.h"
-#include "base/string_number_conversions.h"
+#include "base/strings/string_number_conversions.h"
 #include "ui/aura/client/aura_constants.h"
 #include "ui/aura/root_window.h"
 #include "ui/aura/test/event_generator.h"
@@ -35,6 +35,7 @@
 #include "ui/compositor/layer.h"
 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
 #include "ui/gfx/screen.h"
+#include "ui/views/corewm/window_animations.h"
 #include "ui/views/widget/widget.h"
 
 using aura::Window;
@@ -102,6 +103,18 @@
     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);
@@ -366,6 +379,88 @@
   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());
@@ -452,6 +547,30 @@
   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());
@@ -1668,5 +1787,24 @@
   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
diff --git a/ash/wm/workspace/workspace_window_resizer.cc b/ash/wm/workspace/workspace_window_resizer.cc
index 6c23c9f..2543093 100644
--- a/ash/wm/workspace/workspace_window_resizer.cc
+++ b/ash/wm/workspace/workspace_window_resizer.cc
@@ -9,6 +9,7 @@
 #include <utility>
 #include <vector>
 
+#include "ash/ash_switches.h"
 #include "ash/display/display_controller.h"
 #include "ash/screen_ash.h"
 #include "ash/shell.h"
@@ -18,9 +19,11 @@
 #include "ash/wm/drag_window_resizer.h"
 #include "ash/wm/panels/panel_window_resizer.h"
 #include "ash/wm/property_util.h"
+#include "ash/wm/window_properties.h"
 #include "ash/wm/window_util.h"
 #include "ash/wm/workspace/phantom_window_controller.h"
 #include "ash/wm/workspace/snap_sizer.h"
+#include "base/command_line.h"
 #include "ui/aura/client/aura_constants.h"
 #include "ui/aura/client/window_types.h"
 #include "ui/aura/root_window.h"
@@ -42,10 +45,7 @@
     return scoped_ptr<WindowResizer>();
 
   WindowResizer* window_resizer = NULL;
-  if (window->type() == aura::client::WINDOW_TYPE_PANEL) {
-    window_resizer = PanelWindowResizer::Create(
-        window, point_in_parent, window_component);
-  } else if (window->parent() &&
+  if (window->parent() &&
       window->parent()->id() == internal::kShellWindowId_WorkspaceContainer) {
     // Allow dragging maximized windows if it's not tracked by workspace. This
     // is set by tab dragging code.
@@ -65,6 +65,10 @@
     window_resizer = internal::DragWindowResizer::Create(
         window_resizer, window, point_in_parent, window_component);
   }
+  if (window_resizer && window->type() == aura::client::WINDOW_TYPE_PANEL) {
+    window_resizer = PanelWindowResizer::Create(
+        window_resizer, window, point_in_parent, window_component);
+  }
   return make_scoped_ptr<WindowResizer>(window_resizer);
 }
 
@@ -72,13 +76,19 @@
 
 namespace {
 
-// Duration of the animation when snapping the window into place.
-const int kSnapDurationMS = 100;
+// Distance in pixels that the cursor must move past an edge for a window
+// to move or resize beyond that edge.
+const int kStickyDistancePixels = 64;
 
-// Returns true if should snap to the edge.
-bool ShouldSnapToEdge(int distance_from_edge, int grid_size) {
-  return distance_from_edge < grid_size &&
-      distance_from_edge > -grid_size * 2;
+// Returns true if the window should stick to the edge.
+bool ShouldStickToEdge(int distance_from_edge, int sticky_size) {
+  if (CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kAshEnableStickyEdges)) {
+    return distance_from_edge < 0 &&
+           distance_from_edge > -sticky_size;
+  }
+  return distance_from_edge < sticky_size &&
+                              distance_from_edge > -sticky_size * 2;
 }
 
 // Returns the coordinate along the secondary axis to snap to.
@@ -185,7 +195,7 @@
   return gfx::Rect(x, y, w, h);
 }
 
-// Converts a window comopnent edge to the magnetic edge to snap to.
+// Converts a window component edge to the magnetic edge to snap to.
 uint32 WindowComponentToMagneticEdge(int window_component) {
   switch (window_component) {
     case HTTOPLEFT:
@@ -310,13 +320,20 @@
                                   int event_flags) {
   last_mouse_location_ = location_in_parent;
 
-  const int snap_size =
-      event_flags & ui::EF_CONTROL_DOWN ? 0 : kScreenEdgeInset;
+  int sticky_size;
+  if (event_flags & ui::EF_CONTROL_DOWN) {
+    sticky_size = 0;
+  } else if (CommandLine::ForCurrentProcess()->HasSwitch(
+      switches::kAshEnableStickyEdges)) {
+    sticky_size = kStickyDistancePixels;
+  } else {
+    sticky_size = kScreenEdgeInset;
+  }
   // |bounds| is in |window()->parent()|'s coordinates.
   gfx::Rect bounds = CalculateBoundsForDrag(details_, location_in_parent);
 
   if (wm::IsWindowNormal(window()))
-    AdjustBoundsForMainWindow(snap_size, &bounds);
+    AdjustBoundsForMainWindow(sticky_size, &bounds);
 
   if (bounds != window()->bounds()) {
     if (!did_move_or_resize_) {
@@ -357,6 +374,8 @@
   // out of a maximized window, it's already in the normal show state when this
   // is called, so it does not matter.
   if (wm::IsWindowNormal(window()) &&
+      (window()->type() != aura::client::WINDOW_TYPE_PANEL ||
+       !window()->GetProperty(kPanelAttachedKey)) &&
       (snap_type_ == SNAP_LEFT_EDGE || snap_type_ == SNAP_RIGHT_EDGE)) {
     if (!GetRestoreBoundsInScreen(window())) {
       gfx::Rect initial_bounds = ScreenAsh::ConvertRectToScreen(
@@ -641,7 +660,7 @@
 }
 
 void WorkspaceWindowResizer::AdjustBoundsForMainWindow(
-    int snap_size,
+    int sticky_size,
     gfx::Rect* bounds) {
   gfx::Point last_mouse_location_in_screen = last_mouse_location_;
   wm::ConvertPointToScreen(window()->parent(), &last_mouse_location_in_screen);
@@ -661,14 +680,14 @@
       bounds->set_y(work_area.y());
     }
 
-    if (snap_size > 0) {
-      SnapToWorkAreaEdges(work_area, snap_size, bounds);
+    if (sticky_size > 0) {
+      StickToWorkAreaOnMove(work_area, sticky_size, bounds);
       MagneticallySnapToOtherWindows(bounds);
     }
-  } else if (snap_size > 0) {
+  } else if (sticky_size > 0) {
     MagneticallySnapResizeToOtherWindows(bounds);
-    if (!magnetism_window_ && snap_size > 0)
-      SnapResizeToWorkAreaBounds(work_area, snap_size, bounds);
+    if (!magnetism_window_ && sticky_size > 0)
+      StickToWorkAreaOnResize(work_area, sticky_size, bounds);
   }
 
   if (attached_windows_.empty())
@@ -684,23 +703,22 @@
   }
 }
 
-void WorkspaceWindowResizer::SnapToWorkAreaEdges(
+void WorkspaceWindowResizer::StickToWorkAreaOnMove(
     const gfx::Rect& work_area,
-    int snap_size,
+    int sticky_size,
     gfx::Rect* bounds) const {
   const int left_edge = work_area.x();
   const int right_edge = work_area.right();
   const int top_edge = work_area.y();
   const int bottom_edge = work_area.bottom();
-  if (ShouldSnapToEdge(bounds->x() - left_edge, snap_size)) {
+  if (ShouldStickToEdge(bounds->x() - left_edge, sticky_size)) {
     bounds->set_x(left_edge);
-  } else if (ShouldSnapToEdge(right_edge - bounds->right(),
-                              snap_size)) {
+  } else if (ShouldStickToEdge(right_edge - bounds->right(), sticky_size)) {
     bounds->set_x(right_edge - bounds->width());
   }
-  if (ShouldSnapToEdge(bounds->y() - top_edge, snap_size)) {
+  if (ShouldStickToEdge(bounds->y() - top_edge, sticky_size)) {
     bounds->set_y(top_edge);
-  } else if (ShouldSnapToEdge(bottom_edge - bounds->bottom(), snap_size) &&
+  } else if (ShouldStickToEdge(bottom_edge - bounds->bottom(), sticky_size) &&
              bounds->height() < (bottom_edge - top_edge)) {
     // Only snap to the bottom if the window is smaller than the work area.
     // Doing otherwise can lead to window snapping in weird ways as it bounces
@@ -709,9 +727,9 @@
   }
 }
 
-void WorkspaceWindowResizer::SnapResizeToWorkAreaBounds(
+void WorkspaceWindowResizer::StickToWorkAreaOnResize(
     const gfx::Rect& work_area,
-    int snap_size,
+    int sticky_size,
     gfx::Rect* bounds) const {
   const uint32 edges = WindowComponentToMagneticEdge(details_.window_component);
   const int left_edge = work_area.x();
@@ -719,21 +737,21 @@
   const int top_edge = work_area.y();
   const int bottom_edge = work_area.bottom();
   if (edges & MAGNETISM_EDGE_TOP &&
-      ShouldSnapToEdge(bounds->y() - top_edge, snap_size)) {
+      ShouldStickToEdge(bounds->y() - top_edge, sticky_size)) {
     bounds->set_height(bounds->bottom() - top_edge);
     bounds->set_y(top_edge);
   }
   if (edges & MAGNETISM_EDGE_LEFT &&
-      ShouldSnapToEdge(bounds->x() - left_edge, snap_size)) {
+      ShouldStickToEdge(bounds->x() - left_edge, sticky_size)) {
     bounds->set_width(bounds->right() - left_edge);
     bounds->set_x(left_edge);
   }
   if (edges & MAGNETISM_EDGE_BOTTOM &&
-      ShouldSnapToEdge(bottom_edge - bounds->bottom(), snap_size)) {
+      ShouldStickToEdge(bottom_edge - bounds->bottom(), sticky_size)) {
     bounds->set_height(bottom_edge - bounds->y());
   }
   if (edges & MAGNETISM_EDGE_RIGHT &&
-      ShouldSnapToEdge(right_edge - bounds->right(), snap_size)) {
+      ShouldStickToEdge(right_edge - bounds->right(), sticky_size)) {
     bounds->set_width(right_edge - bounds->x());
   }
 }
@@ -770,7 +788,7 @@
     if (snap_type_ == SNAP_NONE)
       return;
   }
-  if (!snap_sizer_.get()) {
+  if (!snap_sizer_) {
     SnapSizer::Edge edge = (snap_type_ == SNAP_LEFT_EDGE) ?
         SnapSizer::LEFT_EDGE : SnapSizer::RIGHT_EDGE;
     snap_sizer_.reset(new SnapSizer(window(),
@@ -780,7 +798,7 @@
   } else {
     snap_sizer_->Update(location);
   }
-  if (!snap_phantom_window_controller_.get()) {
+  if (!snap_phantom_window_controller_) {
     snap_phantom_window_controller_.reset(
         new PhantomWindowController(window()));
   }
diff --git a/ash/wm/workspace/workspace_window_resizer.h b/ash/wm/workspace/workspace_window_resizer.h
index 4c71285..424e47d 100644
--- a/ash/wm/workspace/workspace_window_resizer.h
+++ b/ash/wm/workspace/workspace_window_resizer.h
@@ -134,16 +134,15 @@
   // snapping.
   void AdjustBoundsForMainWindow(int snap_size, gfx::Rect* bounds);
 
-  // Snaps the window bounds to the work area edges if necessary.
-  void SnapToWorkAreaEdges(
-      const gfx::Rect& work_area,
-      int snap_size,
-      gfx::Rect* bounds) const;
+  // Stick the window bounds to the work area during a move.
+  void StickToWorkAreaOnMove(const gfx::Rect& work_area,
+                             int sticky_size,
+                             gfx::Rect* bounds) const;
 
-  // Snaps the window bounds to the work area during a resize.
-  void SnapResizeToWorkAreaBounds(const gfx::Rect& work_area,
-                                  int snap_size,
-                                  gfx::Rect* bounds) const;
+  // Stick the window bounds to the work area during a resize.
+  void StickToWorkAreaOnResize(const gfx::Rect& work_area,
+                               int sticky_size,
+                               gfx::Rect* bounds) const;
 
   // Returns a coordinate along the primary axis. Used to share code for
   // left/right multi window resize and top/bottom resize.
diff --git a/ash/wm/workspace/workspace_window_resizer_unittest.cc b/ash/wm/workspace/workspace_window_resizer_unittest.cc
index a1d27e3..a0a8561 100644
--- a/ash/wm/workspace/workspace_window_resizer_unittest.cc
+++ b/ash/wm/workspace/workspace_window_resizer_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "ash/wm/workspace/workspace_window_resizer.h"
 
+#include "ash/ash_switches.h"
 #include "ash/display/display_controller.h"
 #include "ash/root_window_controller.h"
 #include "ash/screen_ash.h"
@@ -16,8 +17,9 @@
 #include "ash/wm/workspace/phantom_window_controller.h"
 #include "ash/wm/workspace/snap_sizer.h"
 #include "ash/wm/workspace_controller.h"
-#include "base/string_number_conversions.h"
+#include "base/command_line.h"
 #include "base/stringprintf.h"
+#include "base/strings/string_number_conversions.h"
 #include "ui/aura/client/aura_constants.h"
 #include "ui/aura/root_window.h"
 #include "ui/aura/test/test_window_delegate.h"
@@ -122,7 +124,7 @@
     const aura::Window::Windows& windows = parent->children();
     for (aura::Window::Windows::const_reverse_iterator i = windows.rbegin();
          i != windows.rend(); ++i) {
-      if (*i == window_.get() || *i == window2_.get() || *i == window3_.get()) {
+      if (*i == window_ || *i == window2_ || *i == window3_) {
         if (!result.empty())
           result += " ";
         result += base::IntToString((*i)->id());
@@ -162,6 +164,21 @@
   DISALLOW_COPY_AND_ASSIGN(WorkspaceWindowResizerTest);
 };
 
+class WorkspaceWindowResizerTestSticky : public WorkspaceWindowResizerTest {
+ public:
+  WorkspaceWindowResizerTestSticky() {}
+  virtual ~WorkspaceWindowResizerTestSticky() {}
+
+  virtual void SetUp() OVERRIDE {
+    CommandLine::ForCurrentProcess()->AppendSwitch(
+        ash::switches::kAshEnableStickyEdges);
+    WorkspaceWindowResizerTest::SetUp();
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(WorkspaceWindowResizerTestSticky);
+};
+
 }  // namespace
 
 // Assertions around attached window resize dragging from the right with 2
@@ -638,9 +655,8 @@
       Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 10, 0));
 
   // Positions the secondary display at the bottom the primary display.
-  ash::DisplayLayout display_layout(ash::DisplayLayout::BOTTOM, 0);
-  Shell::GetInstance()->display_controller()->SetDefaultDisplayLayout(
-      display_layout);
+  Shell::GetInstance()->display_controller()->SetLayoutForCurrentDisplays(
+      ash::DisplayLayout(ash::DisplayLayout::BOTTOM, 0));
 
   {
     window_->SetBounds(gfx::Rect(100, 200, 300, 400));
@@ -808,17 +824,17 @@
       window_.get(), gfx::Point(), HTCAPTION, empty_windows()));
   ASSERT_TRUE(resizer.get());
   // Move to an x-coordinate of 15, which should not snap.
-  resizer->Drag(CalculateDragPoint(*resizer, -81, 0), 0);
+  resizer->Drag(CalculateDragPoint(*resizer, 15 - 96, 0), 0);
   // An x-coordinate of 7 should snap.
-  resizer->Drag(CalculateDragPoint(*resizer, -89, 0), 0);
+  resizer->Drag(CalculateDragPoint(*resizer, 7 - 96, 0), 0);
   EXPECT_EQ("0,112 320x160", window_->bounds().ToString());
   // Move to -15, should still snap to 0.
-  resizer->Drag(CalculateDragPoint(*resizer, -111, 0), 0);
+  resizer->Drag(CalculateDragPoint(*resizer, -15 - 96, 0), 0);
   EXPECT_EQ("0,112 320x160", window_->bounds().ToString());
   // At -32 should move past snap points.
-  resizer->Drag(CalculateDragPoint(*resizer, -128, 0), 0);
+  resizer->Drag(CalculateDragPoint(*resizer, -32 - 96, 0), 0);
   EXPECT_EQ("-32,112 320x160", window_->bounds().ToString());
-  resizer->Drag(CalculateDragPoint(*resizer, -129, 0), 0);
+  resizer->Drag(CalculateDragPoint(*resizer, -33 - 96, 0), 0);
   EXPECT_EQ("-33,112 320x160", window_->bounds().ToString());
 
   // Right side should similarly snap.
@@ -910,6 +926,104 @@
   EXPECT_EQ(work_area.bottom() - 200, window_->bounds().height());
 }
 
+// Verifies sticking to edges works.
+TEST_F(WorkspaceWindowResizerTestSticky, StickToEdge) {
+  Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager()->
+      SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
+  window_->SetBounds(gfx::Rect(96, 112, 320, 160));
+  scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
+      window_.get(), gfx::Point(), HTCAPTION, empty_windows()));
+  ASSERT_TRUE(resizer.get());
+  // Move to an x-coordinate of 15, which should not stick.
+  resizer->Drag(CalculateDragPoint(*resizer, 15 - 96, 0), 0);
+  // Move to -15, should still stick to 0.
+  resizer->Drag(CalculateDragPoint(*resizer, -15 - 96, 0), 0);
+  EXPECT_EQ("0,112 320x160", window_->bounds().ToString());
+  // At -100 should move past edge.
+  resizer->Drag(CalculateDragPoint(*resizer, -100 - 96, 0), 0);
+  EXPECT_EQ("-100,112 320x160", window_->bounds().ToString());
+  resizer->Drag(CalculateDragPoint(*resizer, -101 - 96, 0), 0);
+  EXPECT_EQ("-101,112 320x160", window_->bounds().ToString());
+
+  // Right side should similarly stick.
+  resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 - 15, 0), 0);
+  EXPECT_EQ("465,112 320x160", window_->bounds().ToString());
+  resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 + 15, 0), 0);
+  EXPECT_EQ("480,112 320x160", window_->bounds().ToString());
+  resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 + 100, 0), 0);
+  EXPECT_EQ("580,112 320x160", window_->bounds().ToString());
+  resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 + 101, 0), 0);
+  EXPECT_EQ("581,112 320x160", window_->bounds().ToString());
+
+  // And the bottom should stick too.
+  resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 3 + 15), 0);
+  EXPECT_EQ("96,437 320x160", window_->bounds().ToString());
+  resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 2 + 100), 0);
+  EXPECT_EQ("96,538 320x160", window_->bounds().ToString());
+  resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 2 + 101), 0);
+  EXPECT_EQ("96,539 320x160", window_->bounds().ToString());
+
+  // No need to test dragging < 0 as we force that to 0.
+}
+
+// Verifies a resize sticks when dragging TOPLEFT.
+TEST_F(WorkspaceWindowResizerTestSticky, StickToWorkArea_TOPLEFT) {
+  window_->SetBounds(gfx::Rect(100, 200, 20, 30));
+  scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
+      window_.get(), gfx::Point(), HTTOPLEFT, empty_windows()));
+  ASSERT_TRUE(resizer.get());
+  resizer->Drag(CalculateDragPoint(*resizer, -15 - 100, -15 -200), 0);
+  EXPECT_EQ("0,0 120x230", window_->bounds().ToString());
+}
+
+// Verifies a resize sticks when dragging TOPRIGHT.
+TEST_F(WorkspaceWindowResizerTestSticky, StickToWorkArea_TOPRIGHT) {
+  window_->SetBounds(gfx::Rect(100, 200, 20, 30));
+  gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(
+                          window_.get()));
+  scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
+      window_.get(), gfx::Point(), HTTOPRIGHT, empty_windows()));
+  ASSERT_TRUE(resizer.get());
+  resizer->Drag(CalculateDragPoint(*resizer, work_area.right() - 100 + 20,
+                                   -200 - 15), 0);
+  EXPECT_EQ(100, window_->bounds().x());
+  EXPECT_EQ(work_area.y(), window_->bounds().y());
+  EXPECT_EQ(work_area.right() - 100, window_->bounds().width());
+  EXPECT_EQ(230, window_->bounds().height());
+}
+
+// Verifies a resize snap when dragging BOTTOMRIGHT.
+TEST_F(WorkspaceWindowResizerTestSticky, StickToWorkArea_BOTTOMRIGHT) {
+  window_->SetBounds(gfx::Rect(100, 200, 20, 30));
+  gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(
+                          window_.get()));
+  scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
+      window_.get(), gfx::Point(), HTBOTTOMRIGHT, empty_windows()));
+  ASSERT_TRUE(resizer.get());
+  resizer->Drag(CalculateDragPoint(*resizer, work_area.right() - 100 - 20 + 15,
+                                   work_area.bottom() - 200 - 30 + 15), 0);
+  EXPECT_EQ(100, window_->bounds().x());
+  EXPECT_EQ(200, window_->bounds().y());
+  EXPECT_EQ(work_area.right() - 100, window_->bounds().width());
+  EXPECT_EQ(work_area.bottom() - 200, window_->bounds().height());
+}
+
+// Verifies a resize snap when dragging BOTTOMLEFT.
+TEST_F(WorkspaceWindowResizerTestSticky, StickToWorkArea_BOTTOMLEFT) {
+  window_->SetBounds(gfx::Rect(100, 200, 20, 30));
+  gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(
+                          window_.get()));
+  scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
+      window_.get(), gfx::Point(), HTBOTTOMLEFT, empty_windows()));
+  ASSERT_TRUE(resizer.get());
+  resizer->Drag(CalculateDragPoint(*resizer, -15 - 100,
+                                   work_area.bottom() - 200 - 30 + 15), 0);
+  EXPECT_EQ(0, window_->bounds().x());
+  EXPECT_EQ(200, window_->bounds().y());
+  EXPECT_EQ(120, window_->bounds().width());
+  EXPECT_EQ(work_area.bottom() - 200, window_->bounds().height());
+}
+
 TEST_F(WorkspaceWindowResizerTest, CtrlDragResizeToExactPosition) {
   window_->SetBounds(gfx::Rect(96, 112, 320, 160));
   scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
diff --git a/ash/wm/workspace_controller.cc b/ash/wm/workspace_controller.cc
index c880663..2fc5062 100644
--- a/ash/wm/workspace_controller.cc
+++ b/ash/wm/workspace_controller.cc
@@ -4,6 +4,7 @@
 
 #include "ash/wm/workspace_controller.h"
 
+#include "ash/shell.h"
 #include "ash/wm/window_util.h"
 #include "ash/wm/workspace/workspace_manager.h"
 #include "ui/aura/client/activation_client.h"
@@ -58,5 +59,20 @@
   }
 }
 
+void WorkspaceController::OnAttemptToReactivateWindow(
+    aura::Window* request_active,
+    aura::Window* actual_active) {
+  if (ash::Shell::GetInstance()->IsSystemModalWindowOpen() &&
+      viewport_->Contains(request_active)) {
+    // While a system model dialog is showing requests to activate a window
+    // other than that of the modal dialog fail. Outside of this function we
+    // only switch the active workspace when activation changes. That prevents
+    // the active workspace from changing while a system modal dialog is
+    // showing. This code ensures the active workspace changes even though
+    // activation doesn't change away from the system model dialog.
+    workspace_manager_->SetActiveWorkspaceByWindow(request_active);
+  }
+}
+
 }  // namespace internal
 }  // namespace ash
diff --git a/ash/wm/workspace_controller.h b/ash/wm/workspace_controller.h
index 310c36e..3b27fee 100644
--- a/ash/wm/workspace_controller.h
+++ b/ash/wm/workspace_controller.h
@@ -51,6 +51,9 @@
   // aura::client::ActivationChangeObserver overrides:
   virtual void OnWindowActivated(aura::Window* gained_active,
                                  aura::Window* lost_active) OVERRIDE;
+  virtual void OnAttemptToReactivateWindow(
+      aura::Window* request_active,
+      aura::Window* actual_active) OVERRIDE;
 
  private:
   friend class WorkspaceControllerTestHelper;