diff --git a/DEPS b/DEPS
index 0a0b968..4d9810f 100644
--- a/DEPS
+++ b/DEPS
@@ -43,7 +43,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': '935b8785b9c5c7e29732c0a4830704e4be4d13f5',
+  'v8_revision': 'c6d4236d881aa80fb360d95a361672082a66a15e',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
diff --git a/android_webview/common/render_view_messages.h b/android_webview/common/render_view_messages.h
index e13c3a2..45796f1 100644
--- a/android_webview/common/render_view_messages.h
+++ b/android_webview/common/render_view_messages.h
@@ -81,7 +81,7 @@
 IPC_MESSAGE_ROUTED3(AwViewMsg_SmoothScroll,
                     int /* target_x */,
                     int /* target_y */,
-                    long /* duration_ms */);
+                    long /* duration_ms */)
 
 //-----------------------------------------------------------------------------
 // RenderView messages
diff --git a/base/win/registry.cc b/base/win/registry.cc
index 28e0461..ea96e67 100644
--- a/base/win/registry.cc
+++ b/base/win/registry.cc
@@ -364,7 +364,7 @@
   DWORD type = REG_MULTI_SZ;
   DWORD size = 0;
   LONG result = ReadValue(name, NULL, &size, &type);
-  if (FAILED(result) || size == 0)
+  if (result != ERROR_SUCCESS || size == 0)
     return result;
 
   if (type != REG_MULTI_SZ)
@@ -372,7 +372,7 @@
 
   std::vector<wchar_t> buffer(size / sizeof(wchar_t));
   result = ReadValue(name, &buffer[0], &size, NULL);
-  if (FAILED(result) || size == 0)
+  if (result != ERROR_SUCCESS || size == 0)
     return result;
 
   // Parse the double-null-terminated list of strings.
diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc
index a38c2552..d4d321c 100644
--- a/chrome/common/chrome_content_client.cc
+++ b/chrome/common/chrome_content_client.cc
@@ -330,7 +330,7 @@
 
   base::win::RegKey path_key(HKEY_LOCAL_MACHINE, kFlashRegistryRoot, KEY_READ);
   DWORD debug_value;
-  if (FAILED(path_key.ReadValueDW(kIsDebuggerValueName, &debug_value)))
+  if (path_key.ReadValueDW(kIsDebuggerValueName, &debug_value) != ERROR_SUCCESS)
     return false;
 
   return (debug_value == 1);
diff --git a/components/mus/ws/window_tree_apptest.cc b/components/mus/ws/window_tree_apptest.cc
index 3cc0ca0..0e5e0ad 100644
--- a/components/mus/ws/window_tree_apptest.cc
+++ b/components/mus/ws/window_tree_apptest.cc
@@ -30,7 +30,6 @@
 using mus::mojom::WindowTreeClient;
 
 namespace mus {
-
 namespace ws {
 
 namespace {
@@ -76,7 +75,7 @@
 // -----------------------------------------------------------------------------
 
 bool EmbedUrl(mojo::ApplicationImpl* app,
-              WindowTree* vm,
+              WindowTree* ws,
               const String& url,
               Id root_id) {
   bool result = false;
@@ -88,82 +87,82 @@
         app->ConnectToApplication(request.Pass());
     mojom::WindowTreeClientPtr client;
     connection->ConnectToService(&client);
-    vm->Embed(root_id, client.Pass(), mojom::WindowTree::ACCESS_POLICY_DEFAULT,
+    ws->Embed(root_id, client.Pass(), mojom::WindowTree::ACCESS_POLICY_DEFAULT,
               base::Bind(&EmbedCallbackImpl, &run_loop, &result));
   }
   run_loop.Run();
   return result;
 }
 
-bool Embed(WindowTree* vm, Id root_id, mojom::WindowTreeClientPtr client) {
+bool Embed(WindowTree* ws, Id root_id, mojom::WindowTreeClientPtr client) {
   bool result = false;
   base::RunLoop run_loop;
   {
-    vm->Embed(root_id, client.Pass(), mojom::WindowTree::ACCESS_POLICY_DEFAULT,
+    ws->Embed(root_id, client.Pass(), mojom::WindowTree::ACCESS_POLICY_DEFAULT,
               base::Bind(&EmbedCallbackImpl, &run_loop, &result));
   }
   run_loop.Run();
   return result;
 }
 
-ErrorCode NewWindowWithErrorCode(WindowTree* vm, Id window_id) {
+ErrorCode NewWindowWithErrorCode(WindowTree* ws, Id window_id) {
   ErrorCode result = ERROR_CODE_NONE;
   base::RunLoop run_loop;
-  vm->NewWindow(window_id,
+  ws->NewWindow(window_id,
                 base::Bind(&ErrorCodeResultCallback, &run_loop, &result));
   run_loop.Run();
   return result;
 }
 
-bool AddWindow(WindowTree* vm, Id parent, Id child) {
+bool AddWindow(WindowTree* ws, Id parent, Id child) {
   bool result = false;
   base::RunLoop run_loop;
-  vm->AddWindow(parent, child,
+  ws->AddWindow(parent, child,
                 base::Bind(&BoolResultCallback, &run_loop, &result));
   run_loop.Run();
   return result;
 }
 
-bool RemoveWindowFromParent(WindowTree* vm, Id window_id) {
+bool RemoveWindowFromParent(WindowTree* ws, Id window_id) {
   bool result = false;
   base::RunLoop run_loop;
-  vm->RemoveWindowFromParent(
+  ws->RemoveWindowFromParent(
       window_id, base::Bind(&BoolResultCallback, &run_loop, &result));
   run_loop.Run();
   return result;
 }
 
-bool ReorderWindow(WindowTree* vm,
+bool ReorderWindow(WindowTree* ws,
                    Id window_id,
                    Id relative_window_id,
                    mojom::OrderDirection direction) {
   bool result = false;
   base::RunLoop run_loop;
-  vm->ReorderWindow(window_id, relative_window_id, direction,
+  ws->ReorderWindow(window_id, relative_window_id, direction,
                     base::Bind(&BoolResultCallback, &run_loop, &result));
   run_loop.Run();
   return result;
 }
 
-void GetWindowTree(WindowTree* vm,
+void GetWindowTree(WindowTree* ws,
                    Id window_id,
                    std::vector<TestWindow>* windows) {
   base::RunLoop run_loop;
-  vm->GetWindowTree(window_id,
+  ws->GetWindowTree(window_id,
                     base::Bind(&WindowTreeResultCallback, &run_loop, windows));
   run_loop.Run();
 }
 
-bool DeleteWindow(WindowTree* vm, Id window_id) {
+bool DeleteWindow(WindowTree* ws, Id window_id) {
   base::RunLoop run_loop;
   bool result = false;
-  vm->DeleteWindow(window_id,
+  ws->DeleteWindow(window_id,
                    base::Bind(&BoolResultCallback, &run_loop, &result));
   run_loop.Run();
   return result;
 }
 
-bool SetWindowBounds(WindowTree* vm, Id window_id, int x, int y, int w, int h) {
+bool SetWindowBounds(WindowTree* ws, Id window_id, int x, int y, int w, int h) {
   base::RunLoop run_loop;
   bool result = false;
   RectPtr rect(mojo::Rect::New());
@@ -171,22 +170,22 @@
   rect->y = y;
   rect->width = w;
   rect->height = h;
-  vm->SetWindowBounds(window_id, rect.Pass(),
+  ws->SetWindowBounds(window_id, rect.Pass(),
                       base::Bind(&BoolResultCallback, &run_loop, &result));
   run_loop.Run();
   return result;
 }
 
-bool SetWindowVisibility(WindowTree* vm, Id window_id, bool visible) {
+bool SetWindowVisibility(WindowTree* ws, Id window_id, bool visible) {
   base::RunLoop run_loop;
   bool result = false;
-  vm->SetWindowVisibility(window_id, visible,
+  ws->SetWindowVisibility(window_id, visible,
                           base::Bind(&BoolResultCallback, &run_loop, &result));
   run_loop.Run();
   return result;
 }
 
-bool SetWindowProperty(WindowTree* vm,
+bool SetWindowProperty(WindowTree* ws,
                        Id window_id,
                        const std::string& name,
                        const std::vector<uint8_t>* data) {
@@ -195,7 +194,7 @@
   Array<uint8_t> mojo_data;
   if (data)
     mojo_data = Array<uint8_t>::From(*data);
-  vm->SetWindowProperty(window_id, name, mojo_data.Pass(),
+  ws->SetWindowProperty(window_id, name, mojo_data.Pass(),
                         base::Bind(&BoolResultCallback, &run_loop, &result));
   run_loop.Run();
   return result;
@@ -203,14 +202,14 @@
 
 // Utility functions -----------------------------------------------------------
 
-// Waits for all messages to be received by |vm|. This is done by attempting to
+// Waits for all messages to be received by |ws|. This is done by attempting to
 // create a bogus window. When we get the response we know all messages have
 // been
 // processed.
-bool WaitForAllMessages(WindowTree* vm) {
+bool WaitForAllMessages(WindowTree* ws) {
   ErrorCode result = ERROR_CODE_NONE;
   base::RunLoop run_loop;
-  vm->NewWindow(WindowIdToTransportId(InvalidWindowId()),
+  ws->NewWindow(WindowIdToTransportId(InvalidWindowId()),
                 base::Bind(&ErrorCodeResultCallback, &run_loop, &result));
   run_loop.Run();
   return result != ERROR_CODE_NONE;
@@ -440,19 +439,19 @@
 
  protected:
   // Returns the changes from the various connections.
-  std::vector<Change>* changes1() { return vm_client1_->tracker()->changes(); }
-  std::vector<Change>* changes2() { return vm_client2_->tracker()->changes(); }
-  std::vector<Change>* changes3() { return vm_client3_->tracker()->changes(); }
+  std::vector<Change>* changes1() { return ws_client1_->tracker()->changes(); }
+  std::vector<Change>* changes2() { return ws_client2_->tracker()->changes(); }
+  std::vector<Change>* changes3() { return ws_client3_->tracker()->changes(); }
 
-  // Various connections. |vm1()|, being the first connection, has special
+  // Various connections. |ws1()|, being the first connection, has special
   // permissions (it's treated as the window manager).
-  WindowTree* vm1() { return vm_client1_->tree(); }
-  WindowTree* vm2() { return vm_client2_->tree(); }
-  WindowTree* vm3() { return vm_client3_->tree(); }
+  WindowTree* ws1() { return ws_client1_->tree(); }
+  WindowTree* ws2() { return ws_client2_->tree(); }
+  WindowTree* ws3() { return ws_client3_->tree(); }
 
-  TestWindowTreeClientImpl* vm_client1() { return vm_client1_.get(); }
-  TestWindowTreeClientImpl* vm_client2() { return vm_client2_.get(); }
-  TestWindowTreeClientImpl* vm_client3() { return vm_client3_.get(); }
+  TestWindowTreeClientImpl* ws_client1() { return ws_client1_.get(); }
+  TestWindowTreeClientImpl* ws_client2() { return ws_client2_.get(); }
+  TestWindowTreeClientImpl* ws_client3() { return ws_client3_.get(); }
 
   Id root_window_id() const { return root_window_id_; }
 
@@ -460,18 +459,18 @@
   int connection_id_2() const { return connection_id_2_; }
 
   void EstablishSecondConnectionWithRoot(Id root_id) {
-    ASSERT_TRUE(vm_client2_.get() == nullptr);
-    vm_client2_ =
-        EstablishConnectionViaEmbed(vm1(), root_id, &connection_id_2_);
+    ASSERT_TRUE(ws_client2_.get() == nullptr);
+    ws_client2_ =
+        EstablishConnectionViaEmbed(ws1(), root_id, &connection_id_2_);
     ASSERT_GT(connection_id_2_, 0);
-    ASSERT_TRUE(vm_client2_.get() != nullptr);
-    vm_client2_->set_root_window(root_window_id_);
+    ASSERT_TRUE(ws_client2_.get() != nullptr);
+    ws_client2_->set_root_window(root_window_id_);
   }
 
   void EstablishSecondConnection(bool create_initial_window) {
     Id window_1_1 = 0;
     if (create_initial_window) {
-      window_1_1 = vm_client1()->NewWindow(1);
+      window_1_1 = ws_client1()->NewWindow(1);
       ASSERT_TRUE(window_1_1);
     }
     ASSERT_NO_FATAL_FAILURE(
@@ -484,10 +483,10 @@
   }
 
   void EstablishThirdConnection(WindowTree* owner, Id root_id) {
-    ASSERT_TRUE(vm_client3_.get() == nullptr);
-    vm_client3_ = EstablishConnectionViaEmbed(owner, root_id, nullptr);
-    ASSERT_TRUE(vm_client3_.get() != nullptr);
-    vm_client3_->set_root_window(root_window_id_);
+    ASSERT_TRUE(ws_client3_.get() == nullptr);
+    ws_client3_ = EstablishConnectionViaEmbed(owner, root_id, nullptr);
+    ASSERT_TRUE(ws_client3_.get() != nullptr);
+    ws_client3_->set_root_window(root_window_id_);
   }
 
   scoped_ptr<TestWindowTreeClientImpl> WaitForWindowTreeClient() {
@@ -542,15 +541,15 @@
     application_impl()->ConnectToService(request.Pass(), &factory);
 
     mojom::WindowTreeClientPtr tree_client_ptr;
-    vm_client1_.reset(new TestWindowTreeClientImpl(application_impl()));
-    vm_client1_->Bind(GetProxy(&tree_client_ptr));
+    ws_client1_.reset(new TestWindowTreeClientImpl(application_impl()));
+    ws_client1_->Bind(GetProxy(&tree_client_ptr));
 
     factory->CreateWindowTreeHost(GetProxy(&host_),
                                   mojom::WindowTreeHostClientPtr(),
                                   tree_client_ptr.Pass(), nullptr);
 
     // Next we should get an embed call on the "window manager" client.
-    vm_client1_->WaitForIncomingMethodCall();
+    ws_client1_->WaitForIncomingMethodCall();
 
     ASSERT_EQ(1u, changes1()->size());
     EXPECT_EQ(CHANGE_TYPE_EMBED, (*changes1())[0].type);
@@ -561,7 +560,7 @@
     connection_id_1_ = (*changes1())[0].connection_id;
     ASSERT_FALSE((*changes1())[0].windows.empty());
     root_window_id_ = (*changes1())[0].windows[0].window_id;
-    vm_client1_->set_root_window(root_window_id_);
+    ws_client1_->set_root_window(root_window_id_);
     changes1()->clear();
   }
 
@@ -571,9 +570,9 @@
     return true;
   }
 
-  scoped_ptr<TestWindowTreeClientImpl> vm_client1_;
-  scoped_ptr<TestWindowTreeClientImpl> vm_client2_;
-  scoped_ptr<TestWindowTreeClientImpl> vm_client3_;
+  scoped_ptr<TestWindowTreeClientImpl> ws_client1_;
+  scoped_ptr<TestWindowTreeClientImpl> ws_client2_;
+  scoped_ptr<TestWindowTreeClientImpl> ws_client3_;
 
   mojom::WindowTreeHostPtr host_;
 
@@ -597,13 +596,13 @@
 // Verifies when Embed() is invoked any child windows are removed.
 TEST_F(WindowTreeAppTest, WindowsRemovedWhenEmbedding) {
   // Two windows 1 and 2. 2 is parented to 1.
-  Id window_1_1 = vm_client1()->NewWindow(1);
+  Id window_1_1 = ws_client1()->NewWindow(1);
   ASSERT_TRUE(window_1_1);
-  ASSERT_TRUE(AddWindow(vm1(), root_window_id(), window_1_1));
+  ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_1));
 
-  Id window_1_2 = vm_client1()->NewWindow(2);
+  Id window_1_2 = ws_client1()->NewWindow(2);
   ASSERT_TRUE(window_1_2);
-  ASSERT_TRUE(AddWindow(vm1(), window_1_1, window_1_2));
+  ASSERT_TRUE(AddWindow(ws1(), window_1_1, window_1_2));
 
   ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
   ASSERT_EQ(1u, changes2()->size());
@@ -614,43 +613,43 @@
   // Embed() removed window 2.
   {
     std::vector<TestWindow> windows;
-    GetWindowTree(vm1(), window_1_2, &windows);
+    GetWindowTree(ws1(), window_1_2, &windows);
     EXPECT_EQ(WindowParentToString(window_1_2, kNullParentId),
               SingleWindowDescription(windows));
   }
 
-  // vm2 should not see window 2.
+  // ws2 should not see window 2.
   {
     std::vector<TestWindow> windows;
-    GetWindowTree(vm2(), window_1_1, &windows);
+    GetWindowTree(ws2(), window_1_1, &windows);
     EXPECT_EQ(WindowParentToString(window_1_1, kNullParentId),
               SingleWindowDescription(windows));
   }
   {
     std::vector<TestWindow> windows;
-    GetWindowTree(vm2(), window_1_2, &windows);
+    GetWindowTree(ws2(), window_1_2, &windows);
     EXPECT_TRUE(windows.empty());
   }
 
   // Windows 3 and 4 in connection 2.
-  Id window_2_3 = vm_client2()->NewWindow(3);
-  Id window_2_4 = vm_client2()->NewWindow(4);
+  Id window_2_3 = ws_client2()->NewWindow(3);
+  Id window_2_4 = ws_client2()->NewWindow(4);
   ASSERT_TRUE(window_2_3);
   ASSERT_TRUE(window_2_4);
-  ASSERT_TRUE(AddWindow(vm2(), window_2_3, window_2_4));
+  ASSERT_TRUE(AddWindow(ws2(), window_2_3, window_2_4));
 
   // Connection 3 rooted at 2.
-  ASSERT_NO_FATAL_FAILURE(EstablishThirdConnection(vm2(), window_2_3));
+  ASSERT_NO_FATAL_FAILURE(EstablishThirdConnection(ws2(), window_2_3));
 
   // Window 4 should no longer have a parent.
   {
     std::vector<TestWindow> windows;
-    GetWindowTree(vm2(), window_2_3, &windows);
+    GetWindowTree(ws2(), window_2_3, &windows);
     EXPECT_EQ(WindowParentToString(window_2_3, kNullParentId),
               SingleWindowDescription(windows));
 
     windows.clear();
-    GetWindowTree(vm2(), window_2_4, &windows);
+    GetWindowTree(ws2(), window_2_4, &windows);
     EXPECT_EQ(WindowParentToString(window_2_4, kNullParentId),
               SingleWindowDescription(windows));
   }
@@ -658,7 +657,7 @@
   // And window 4 should not be visible to connection 3.
   {
     std::vector<TestWindow> windows;
-    GetWindowTree(vm3(), window_2_3, &windows);
+    GetWindowTree(ws3(), window_2_3, &windows);
     EXPECT_EQ(WindowParentToString(window_2_3, kNullParentId),
               SingleWindowDescription(windows));
   }
@@ -670,21 +669,21 @@
   ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
 
   Id window_1_1 = BuildWindowId(connection_id_1(), 1);
-  Id window_2_2 = vm_client2()->NewWindow(2);
+  Id window_2_2 = ws_client2()->NewWindow(2);
   ASSERT_TRUE(window_2_2);
-  ASSERT_TRUE(AddWindow(vm2(), window_1_1, window_2_2));
+  ASSERT_TRUE(AddWindow(ws2(), window_1_1, window_2_2));
 
-  ASSERT_NO_FATAL_FAILURE(EstablishThirdConnection(vm2(), window_2_2));
+  ASSERT_NO_FATAL_FAILURE(EstablishThirdConnection(ws2(), window_2_2));
 
-  Id window_3_3 = vm_client3()->NewWindow(3);
+  Id window_3_3 = ws_client3()->NewWindow(3);
   ASSERT_TRUE(window_3_3);
-  ASSERT_TRUE(AddWindow(vm3(), window_2_2, window_3_3));
+  ASSERT_TRUE(AddWindow(ws3(), window_2_2, window_3_3));
 
   // Even though 3 is a child of 2 connection 2 can't see 3 as it's from a
   // different connection.
   {
     std::vector<TestWindow> windows;
-    GetWindowTree(vm2(), window_2_2, &windows);
+    GetWindowTree(ws2(), window_2_2, &windows);
     EXPECT_EQ(WindowParentToString(window_2_2, window_1_1),
               SingleWindowDescription(windows));
   }
@@ -692,14 +691,14 @@
   // Connection 2 shouldn't be able to get window 3 at all.
   {
     std::vector<TestWindow> windows;
-    GetWindowTree(vm2(), window_3_3, &windows);
+    GetWindowTree(ws2(), window_3_3, &windows);
     EXPECT_TRUE(windows.empty());
   }
 
   // Connection 1 should be able to see it all (its the root).
   {
     std::vector<TestWindow> windows;
-    GetWindowTree(vm1(), window_1_1, &windows);
+    GetWindowTree(ws1(), window_1_1, &windows);
     ASSERT_EQ(3u, windows.size());
     EXPECT_EQ(WindowParentToString(window_1_1, kNullParentId),
               windows[0].ToString());
@@ -715,80 +714,80 @@
   ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
 
   Id window_1_1 = BuildWindowId(connection_id_1(), 1);
-  Id window_2_2 = vm_client2()->NewWindow(2);
+  Id window_2_2 = ws_client2()->NewWindow(2);
   ASSERT_TRUE(window_2_2);
-  ASSERT_TRUE(AddWindow(vm2(), window_1_1, window_2_2));
+  ASSERT_TRUE(AddWindow(ws2(), window_1_1, window_2_2));
 
-  ASSERT_NO_FATAL_FAILURE(EstablishThirdConnection(vm2(), window_2_2));
+  ASSERT_NO_FATAL_FAILURE(EstablishThirdConnection(ws2(), window_2_2));
 
-  Id window_2_3 = vm_client2()->NewWindow(3);
+  Id window_2_3 = ws_client2()->NewWindow(3);
   ASSERT_TRUE(window_2_3);
   // Connection 2 shouldn't be able to add anything to the window anymore.
-  ASSERT_FALSE(AddWindow(vm2(), window_2_2, window_2_3));
+  ASSERT_FALSE(AddWindow(ws2(), window_2_2, window_2_3));
 
   // Create window 3 in connection 3 and add it to window 3.
-  Id window_3_3 = vm_client3()->NewWindow(3);
+  Id window_3_3 = ws_client3()->NewWindow(3);
   ASSERT_TRUE(window_3_3);
-  ASSERT_TRUE(AddWindow(vm3(), window_2_2, window_3_3));
+  ASSERT_TRUE(AddWindow(ws3(), window_2_2, window_3_3));
 
   // Connection 2 shouldn't be able to remove window 3.
-  ASSERT_FALSE(RemoveWindowFromParent(vm2(), window_3_3));
+  ASSERT_FALSE(RemoveWindowFromParent(ws2(), window_3_3));
 }
 
 // Verifies client gets a valid id.
 TEST_F(WindowTreeAppTest, NewWindow) {
-  Id window_1_1 = vm_client1()->NewWindow(1);
+  Id window_1_1 = ws_client1()->NewWindow(1);
   ASSERT_TRUE(window_1_1);
   EXPECT_TRUE(changes1()->empty());
 
   // Can't create a window with the same id.
   ASSERT_EQ(mojom::ERROR_CODE_VALUE_IN_USE,
-            NewWindowWithErrorCode(vm1(), window_1_1));
+            NewWindowWithErrorCode(ws1(), window_1_1));
   EXPECT_TRUE(changes1()->empty());
 
   // Can't create a window with a bogus connection id.
   EXPECT_EQ(
       mojom::ERROR_CODE_ILLEGAL_ARGUMENT,
-      NewWindowWithErrorCode(vm1(), BuildWindowId(connection_id_1() + 1, 1)));
+      NewWindowWithErrorCode(ws1(), BuildWindowId(connection_id_1() + 1, 1)));
   EXPECT_TRUE(changes1()->empty());
 }
 
 // Verifies AddWindow fails when window is already in position.
 TEST_F(WindowTreeAppTest, AddWindowWithNoChange) {
-  Id window_1_2 = vm_client1()->NewWindow(2);
-  Id window_1_3 = vm_client1()->NewWindow(3);
+  Id window_1_2 = ws_client1()->NewWindow(2);
+  Id window_1_3 = ws_client1()->NewWindow(3);
   ASSERT_TRUE(window_1_2);
   ASSERT_TRUE(window_1_3);
 
   ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
 
   // Make 3 a child of 2.
-  ASSERT_TRUE(AddWindow(vm1(), window_1_2, window_1_3));
+  ASSERT_TRUE(AddWindow(ws1(), window_1_2, window_1_3));
 
   // Try again, this should fail.
-  EXPECT_FALSE(AddWindow(vm1(), window_1_2, window_1_3));
+  EXPECT_FALSE(AddWindow(ws1(), window_1_2, window_1_3));
 }
 
 // Verifies AddWindow fails when window is already in position.
 TEST_F(WindowTreeAppTest, AddAncestorFails) {
-  Id window_1_2 = vm_client1()->NewWindow(2);
-  Id window_1_3 = vm_client1()->NewWindow(3);
+  Id window_1_2 = ws_client1()->NewWindow(2);
+  Id window_1_3 = ws_client1()->NewWindow(3);
   ASSERT_TRUE(window_1_2);
   ASSERT_TRUE(window_1_3);
 
   ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
 
   // Make 3 a child of 2.
-  ASSERT_TRUE(AddWindow(vm1(), window_1_2, window_1_3));
+  ASSERT_TRUE(AddWindow(ws1(), window_1_2, window_1_3));
 
   // Try to make 2 a child of 3, this should fail since 2 is an ancestor of 3.
-  EXPECT_FALSE(AddWindow(vm1(), window_1_3, window_1_2));
+  EXPECT_FALSE(AddWindow(ws1(), window_1_3, window_1_2));
 }
 
 // Verifies adding to root sends right notifications.
 TEST_F(WindowTreeAppTest, AddToRoot) {
-  Id window_1_21 = vm_client1()->NewWindow(21);
-  Id window_1_3 = vm_client1()->NewWindow(3);
+  Id window_1_21 = ws_client1()->NewWindow(21);
+  Id window_1_3 = ws_client1()->NewWindow(3);
   ASSERT_TRUE(window_1_21);
   ASSERT_TRUE(window_1_3);
 
@@ -797,41 +796,41 @@
   changes2()->clear();
 
   // Make 3 a child of 21.
-  ASSERT_TRUE(AddWindow(vm1(), window_1_21, window_1_3));
+  ASSERT_TRUE(AddWindow(ws1(), window_1_21, window_1_3));
 
   // Make 21 a child of 1.
-  ASSERT_TRUE(AddWindow(vm1(), window_1_1, window_1_21));
+  ASSERT_TRUE(AddWindow(ws1(), window_1_1, window_1_21));
 
   // Connection 2 should not be told anything (because the window is from a
   // different connection). Create a window to ensure we got a response from
   // the server.
-  ASSERT_TRUE(vm_client2()->NewWindow(100));
+  ASSERT_TRUE(ws_client2()->NewWindow(100));
   EXPECT_TRUE(changes2()->empty());
 }
 
 // Verifies HierarchyChanged is correctly sent for various adds/removes.
 TEST_F(WindowTreeAppTest, WindowHierarchyChangedWindows) {
   // 1,2->1,11.
-  Id window_1_2 = vm_client1()->NewWindow(2);
+  Id window_1_2 = ws_client1()->NewWindow(2);
   ASSERT_TRUE(window_1_2);
-  ASSERT_TRUE(SetWindowVisibility(vm1(), window_1_2, true));
-  Id window_1_11 = vm_client1()->NewWindow(11);
+  ASSERT_TRUE(SetWindowVisibility(ws1(), window_1_2, true));
+  Id window_1_11 = ws_client1()->NewWindow(11);
   ASSERT_TRUE(window_1_11);
-  ASSERT_TRUE(SetWindowVisibility(vm1(), window_1_11, true));
-  ASSERT_TRUE(AddWindow(vm1(), window_1_2, window_1_11));
+  ASSERT_TRUE(SetWindowVisibility(ws1(), window_1_11, true));
+  ASSERT_TRUE(AddWindow(ws1(), window_1_2, window_1_11));
 
   Id window_1_1 = BuildWindowId(connection_id_1(), 1);
   ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
-  ASSERT_TRUE(SetWindowVisibility(vm1(), window_1_1, true));
+  ASSERT_TRUE(SetWindowVisibility(ws1(), window_1_1, true));
 
-  ASSERT_TRUE(WaitForAllMessages(vm2()));
+  ASSERT_TRUE(WaitForAllMessages(ws2()));
   changes2()->clear();
 
   // 1,1->1,2->1,11
   {
     // Client 2 should not get anything (1,2 is from another connection).
-    ASSERT_TRUE(AddWindow(vm1(), window_1_1, window_1_2));
-    ASSERT_TRUE(WaitForAllMessages(vm2()));
+    ASSERT_TRUE(AddWindow(ws1(), window_1_1, window_1_2));
+    ASSERT_TRUE(WaitForAllMessages(ws2()));
     EXPECT_TRUE(changes2()->empty());
   }
 
@@ -839,8 +838,8 @@
   {
     // Client 2 is now connected to the root, so it should have gotten a drawn
     // notification.
-    ASSERT_TRUE(AddWindow(vm1(), root_window_id(), window_1_1));
-    vm_client2_->WaitForChangeCount(1u);
+    ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_1));
+    ws_client2_->WaitForChangeCount(1u);
     EXPECT_EQ(
         "DrawnStateChanged window=" + IdToString(window_1_1) + " drawn=true",
         SingleChangeToDescription(*changes2()));
@@ -851,29 +850,29 @@
     // Client 2 is no longer connected to the root, should get drawn state
     // changed.
     changes2()->clear();
-    ASSERT_TRUE(RemoveWindowFromParent(vm1(), window_1_1));
-    vm_client2_->WaitForChangeCount(1);
+    ASSERT_TRUE(RemoveWindowFromParent(ws1(), window_1_1));
+    ws_client2_->WaitForChangeCount(1);
     EXPECT_EQ(
         "DrawnStateChanged window=" + IdToString(window_1_1) + " drawn=false",
         SingleChangeToDescription(*changes2()));
   }
 
   // 1,1->1,2->1,11->1,111.
-  Id window_1_111 = vm_client1()->NewWindow(111);
+  Id window_1_111 = ws_client1()->NewWindow(111);
   ASSERT_TRUE(window_1_111);
-  ASSERT_TRUE(SetWindowVisibility(vm1(), window_1_111, true));
+  ASSERT_TRUE(SetWindowVisibility(ws1(), window_1_111, true));
   {
     changes2()->clear();
-    ASSERT_TRUE(AddWindow(vm1(), window_1_11, window_1_111));
-    ASSERT_TRUE(WaitForAllMessages(vm2()));
+    ASSERT_TRUE(AddWindow(ws1(), window_1_11, window_1_111));
+    ASSERT_TRUE(WaitForAllMessages(ws2()));
     EXPECT_TRUE(changes2()->empty());
   }
 
   // 0,1->1,1->1,2->1,11->1,111
   {
     changes2()->clear();
-    ASSERT_TRUE(AddWindow(vm1(), root_window_id(), window_1_1));
-    vm_client2_->WaitForChangeCount(1);
+    ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_1));
+    ws_client2_->WaitForChangeCount(1);
     EXPECT_EQ(
         "DrawnStateChanged window=" + IdToString(window_1_1) + " drawn=true",
         SingleChangeToDescription(*changes2()));
@@ -886,24 +885,24 @@
   ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
   Id window_1_1 = BuildWindowId(connection_id_1(), 1);
 
-  Id window_2_11 = vm_client2()->NewWindow(11);
-  Id window_2_2 = vm_client2()->NewWindow(2);
-  Id window_2_21 = vm_client2()->NewWindow(21);
+  Id window_2_11 = ws_client2()->NewWindow(11);
+  Id window_2_2 = ws_client2()->NewWindow(2);
+  Id window_2_21 = ws_client2()->NewWindow(21);
   ASSERT_TRUE(window_2_11);
   ASSERT_TRUE(window_2_2);
   ASSERT_TRUE(window_2_21);
 
   // Set up the hierarchy.
-  ASSERT_TRUE(AddWindow(vm1(), root_window_id(), window_1_1));
-  ASSERT_TRUE(AddWindow(vm2(), window_1_1, window_2_11));
-  ASSERT_TRUE(AddWindow(vm2(), window_2_2, window_2_21));
+  ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_1));
+  ASSERT_TRUE(AddWindow(ws2(), window_1_1, window_2_11));
+  ASSERT_TRUE(AddWindow(ws2(), window_2_2, window_2_21));
 
   // Remove 11, should result in a hierarchy change for the root.
   {
     changes1()->clear();
-    ASSERT_TRUE(RemoveWindowFromParent(vm2(), window_2_11));
+    ASSERT_TRUE(RemoveWindowFromParent(ws2(), window_2_11));
 
-    vm_client1_->WaitForChangeCount(1);
+    ws_client1_->WaitForChangeCount(1);
     EXPECT_EQ("HierarchyChanged window=" + IdToString(window_2_11) +
                   " new_parent=null old_parent=" + IdToString(window_1_1),
               SingleChangeToDescription(*changes1()));
@@ -912,8 +911,8 @@
   // Add 2 to 1.
   {
     changes1()->clear();
-    ASSERT_TRUE(AddWindow(vm2(), window_1_1, window_2_2));
-    vm_client1_->WaitForChangeCount(1);
+    ASSERT_TRUE(AddWindow(ws2(), window_1_1, window_2_2));
+    ws_client1_->WaitForChangeCount(1);
     EXPECT_EQ("HierarchyChanged window=" + IdToString(window_2_2) +
                   " new_parent=" + IdToString(window_1_1) + " old_parent=null",
               SingleChangeToDescription(*changes1()));
@@ -926,14 +925,14 @@
 TEST_F(WindowTreeAppTest, ReorderWindow) {
   ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
 
-  Id window_2_1 = vm_client2()->NewWindow(1);
-  Id window_2_2 = vm_client2()->NewWindow(2);
-  Id window_2_3 = vm_client2()->NewWindow(3);
-  Id window_1_4 = vm_client1()->NewWindow(4);  // Peer to 1,1
-  Id window_1_5 = vm_client1()->NewWindow(5);  // Peer to 1,1
-  Id window_2_6 = vm_client2()->NewWindow(6);  // Child of 1,2.
-  Id window_2_7 = vm_client2()->NewWindow(7);  // Unparented.
-  Id window_2_8 = vm_client2()->NewWindow(8);  // Unparented.
+  Id window_2_1 = ws_client2()->NewWindow(1);
+  Id window_2_2 = ws_client2()->NewWindow(2);
+  Id window_2_3 = ws_client2()->NewWindow(3);
+  Id window_1_4 = ws_client1()->NewWindow(4);  // Peer to 1,1
+  Id window_1_5 = ws_client1()->NewWindow(5);  // Peer to 1,1
+  Id window_2_6 = ws_client2()->NewWindow(6);  // Child of 1,2.
+  Id window_2_7 = ws_client2()->NewWindow(7);  // Unparented.
+  Id window_2_8 = ws_client2()->NewWindow(8);  // Unparented.
   ASSERT_TRUE(window_2_1);
   ASSERT_TRUE(window_2_2);
   ASSERT_TRUE(window_2_3);
@@ -943,19 +942,19 @@
   ASSERT_TRUE(window_2_7);
   ASSERT_TRUE(window_2_8);
 
-  ASSERT_TRUE(AddWindow(vm2(), window_2_1, window_2_2));
-  ASSERT_TRUE(AddWindow(vm2(), window_2_2, window_2_6));
-  ASSERT_TRUE(AddWindow(vm2(), window_2_1, window_2_3));
-  ASSERT_TRUE(AddWindow(vm1(), root_window_id(), window_1_4));
-  ASSERT_TRUE(AddWindow(vm1(), root_window_id(), window_1_5));
-  ASSERT_TRUE(AddWindow(vm1(), root_window_id(), window_2_1));
+  ASSERT_TRUE(AddWindow(ws2(), window_2_1, window_2_2));
+  ASSERT_TRUE(AddWindow(ws2(), window_2_2, window_2_6));
+  ASSERT_TRUE(AddWindow(ws2(), window_2_1, window_2_3));
+  ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_4));
+  ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_5));
+  ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_2_1));
 
   {
     changes1()->clear();
-    ASSERT_TRUE(ReorderWindow(vm2(), window_2_2, window_2_3,
+    ASSERT_TRUE(ReorderWindow(ws2(), window_2_2, window_2_3,
                               mojom::ORDER_DIRECTION_ABOVE));
 
-    vm_client1_->WaitForChangeCount(1);
+    ws_client1_->WaitForChangeCount(1);
     EXPECT_EQ("Reordered window=" + IdToString(window_2_2) + " relative=" +
                   IdToString(window_2_3) + " direction=above",
               SingleChangeToDescription(*changes1()));
@@ -963,34 +962,34 @@
 
   {
     changes1()->clear();
-    ASSERT_TRUE(ReorderWindow(vm2(), window_2_2, window_2_3,
+    ASSERT_TRUE(ReorderWindow(ws2(), window_2_2, window_2_3,
                               mojom::ORDER_DIRECTION_BELOW));
 
-    vm_client1_->WaitForChangeCount(1);
+    ws_client1_->WaitForChangeCount(1);
     EXPECT_EQ("Reordered window=" + IdToString(window_2_2) + " relative=" +
                   IdToString(window_2_3) + " direction=below",
               SingleChangeToDescription(*changes1()));
   }
 
   // view2 is already below view3.
-  EXPECT_FALSE(ReorderWindow(vm2(), window_2_2, window_2_3,
+  EXPECT_FALSE(ReorderWindow(ws2(), window_2_2, window_2_3,
                              mojom::ORDER_DIRECTION_BELOW));
 
   // view4 & 5 are unknown to connection2_.
-  EXPECT_FALSE(ReorderWindow(vm2(), window_1_4, window_1_5,
+  EXPECT_FALSE(ReorderWindow(ws2(), window_1_4, window_1_5,
                              mojom::ORDER_DIRECTION_ABOVE));
 
   // view6 & view3 have different parents.
-  EXPECT_FALSE(ReorderWindow(vm1(), window_2_3, window_2_6,
+  EXPECT_FALSE(ReorderWindow(ws1(), window_2_3, window_2_6,
                              mojom::ORDER_DIRECTION_ABOVE));
 
   // Non-existent window-ids
-  EXPECT_FALSE(ReorderWindow(vm1(), BuildWindowId(connection_id_1(), 27),
+  EXPECT_FALSE(ReorderWindow(ws1(), BuildWindowId(connection_id_1(), 27),
                              BuildWindowId(connection_id_1(), 28),
                              mojom::ORDER_DIRECTION_ABOVE));
 
   // view7 & view8 are un-parented.
-  EXPECT_FALSE(ReorderWindow(vm1(), window_2_7, window_2_8,
+  EXPECT_FALSE(ReorderWindow(ws1(), window_2_7, window_2_8,
                              mojom::ORDER_DIRECTION_ABOVE));
 }
 
@@ -998,14 +997,14 @@
 TEST_F(WindowTreeAppTest, DeleteWindow) {
   ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
   Id window_1_1 = BuildWindowId(connection_id_1(), 1);
-  Id window_2_2 = vm_client2()->NewWindow(2);
+  Id window_2_2 = ws_client2()->NewWindow(2);
   ASSERT_TRUE(window_2_2);
 
   // Make 2 a child of 1.
   {
     changes1()->clear();
-    ASSERT_TRUE(AddWindow(vm2(), window_1_1, window_2_2));
-    vm_client1_->WaitForChangeCount(1);
+    ASSERT_TRUE(AddWindow(ws2(), window_1_1, window_2_2));
+    ws_client1_->WaitForChangeCount(1);
     EXPECT_EQ("HierarchyChanged window=" + IdToString(window_2_2) +
                   " new_parent=" + IdToString(window_1_1) + " old_parent=null",
               SingleChangeToDescription(*changes1()));
@@ -1015,10 +1014,10 @@
   {
     changes1()->clear();
     changes2()->clear();
-    ASSERT_TRUE(DeleteWindow(vm2(), window_2_2));
+    ASSERT_TRUE(DeleteWindow(ws2(), window_2_2));
     EXPECT_TRUE(changes2()->empty());
 
-    vm_client1_->WaitForChangeCount(1);
+    ws_client1_->WaitForChangeCount(1);
     EXPECT_EQ("WindowDeleted window=" + IdToString(window_2_2),
               SingleChangeToDescription(*changes1()));
   }
@@ -1027,7 +1026,7 @@
 // Verifies DeleteWindow isn't allowed from a separate connection.
 TEST_F(WindowTreeAppTest, DeleteWindowFromAnotherConnectionDisallowed) {
   ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
-  EXPECT_FALSE(DeleteWindow(vm2(), BuildWindowId(connection_id_1(), 1)));
+  EXPECT_FALSE(DeleteWindow(ws2(), BuildWindowId(connection_id_1(), 1)));
 }
 
 // Verifies if a window was deleted and then reused that other clients are
@@ -1035,14 +1034,14 @@
 TEST_F(WindowTreeAppTest, ReuseDeletedWindowId) {
   ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
   Id window_1_1 = BuildWindowId(connection_id_1(), 1);
-  Id window_2_2 = vm_client2()->NewWindow(2);
+  Id window_2_2 = ws_client2()->NewWindow(2);
   ASSERT_TRUE(window_2_2);
 
   // Add 2 to 1.
   {
     changes1()->clear();
-    ASSERT_TRUE(AddWindow(vm2(), window_1_1, window_2_2));
-    vm_client1_->WaitForChangeCount(1);
+    ASSERT_TRUE(AddWindow(ws2(), window_1_1, window_2_2));
+    ws_client1_->WaitForChangeCount(1);
     EXPECT_EQ("HierarchyChanged window=" + IdToString(window_2_2) +
                   " new_parent=" + IdToString(window_1_1) + " old_parent=null",
               SingleChangeToDescription(*changes1()));
@@ -1053,21 +1052,21 @@
   // Delete 2.
   {
     changes1()->clear();
-    ASSERT_TRUE(DeleteWindow(vm2(), window_2_2));
+    ASSERT_TRUE(DeleteWindow(ws2(), window_2_2));
 
-    vm_client1_->WaitForChangeCount(1);
+    ws_client1_->WaitForChangeCount(1);
     EXPECT_EQ("WindowDeleted window=" + IdToString(window_2_2),
               SingleChangeToDescription(*changes1()));
   }
 
   // Create 2 again, and add it back to 1. Should get the same notification.
-  window_2_2 = vm_client2()->NewWindow(2);
+  window_2_2 = ws_client2()->NewWindow(2);
   ASSERT_TRUE(window_2_2);
   {
     changes1()->clear();
-    ASSERT_TRUE(AddWindow(vm2(), window_1_1, window_2_2));
+    ASSERT_TRUE(AddWindow(ws2(), window_1_1, window_2_2));
 
-    vm_client1_->WaitForChangeCount(1);
+    ws_client1_->WaitForChangeCount(1);
     EXPECT_EQ("HierarchyChanged window=" + IdToString(window_2_2) +
                   " new_parent=" + IdToString(window_1_1) + " old_parent=null",
               SingleChangeToDescription(*changes1()));
@@ -1082,23 +1081,23 @@
   Id window_1_1 = BuildWindowId(connection_id_1(), 1);
 
   // Create 11 in first connection and make it a child of 1.
-  Id window_1_11 = vm_client1()->NewWindow(11);
+  Id window_1_11 = ws_client1()->NewWindow(11);
   ASSERT_TRUE(window_1_11);
-  ASSERT_TRUE(AddWindow(vm1(), root_window_id(), window_1_1));
-  ASSERT_TRUE(AddWindow(vm1(), window_1_1, window_1_11));
+  ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_1));
+  ASSERT_TRUE(AddWindow(ws1(), window_1_1, window_1_11));
 
   // Create two windows in second connection, 2 and 3, both children of 1.
-  Id window_2_2 = vm_client2()->NewWindow(2);
-  Id window_2_3 = vm_client2()->NewWindow(3);
+  Id window_2_2 = ws_client2()->NewWindow(2);
+  Id window_2_3 = ws_client2()->NewWindow(3);
   ASSERT_TRUE(window_2_2);
   ASSERT_TRUE(window_2_3);
-  ASSERT_TRUE(AddWindow(vm2(), window_1_1, window_2_2));
-  ASSERT_TRUE(AddWindow(vm2(), window_1_1, window_2_3));
+  ASSERT_TRUE(AddWindow(ws2(), window_1_1, window_2_2));
+  ASSERT_TRUE(AddWindow(ws2(), window_1_1, window_2_3));
 
   // Verifies GetWindowTree() on the root. The root connection sees all.
   {
     std::vector<TestWindow> windows;
-    GetWindowTree(vm1(), root_window_id(), &windows);
+    GetWindowTree(ws1(), root_window_id(), &windows);
     ASSERT_EQ(5u, windows.size());
     EXPECT_EQ(WindowParentToString(root_window_id(), kNullParentId),
               windows[0].ToString());
@@ -1112,12 +1111,12 @@
               windows[4].ToString());
   }
 
-  // Verifies GetWindowTree() on the window 1,1 from vm2(). vm2() sees 1,1 as
+  // Verifies GetWindowTree() on the window 1,1 from ws2(). ws2() sees 1,1 as
   // 1,1
-  // is vm2()'s root and vm2() sees all the windows it created.
+  // is ws2()'s root and ws2() sees all the windows it created.
   {
     std::vector<TestWindow> windows;
-    GetWindowTree(vm2(), window_1_1, &windows);
+    GetWindowTree(ws2(), window_1_1, &windows);
     ASSERT_EQ(3u, windows.size());
     EXPECT_EQ(WindowParentToString(window_1_1, kNullParentId),
               windows[0].ToString());
@@ -1130,36 +1129,36 @@
   // Connection 2 shouldn't be able to get the root tree.
   {
     std::vector<TestWindow> windows;
-    GetWindowTree(vm2(), root_window_id(), &windows);
+    GetWindowTree(ws2(), root_window_id(), &windows);
     ASSERT_EQ(0u, windows.size());
   }
 }
 
 TEST_F(WindowTreeAppTest, SetWindowBounds) {
-  Id window_1_1 = vm_client1()->NewWindow(1);
+  Id window_1_1 = ws_client1()->NewWindow(1);
   ASSERT_TRUE(window_1_1);
-  ASSERT_TRUE(AddWindow(vm1(), root_window_id(), window_1_1));
+  ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_1));
 
   ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
 
   changes2()->clear();
-  ASSERT_TRUE(SetWindowBounds(vm1(), window_1_1, 0, 0, 100, 100));
+  ASSERT_TRUE(SetWindowBounds(ws1(), window_1_1, 0, 0, 100, 100));
 
-  vm_client2_->WaitForChangeCount(1);
+  ws_client2_->WaitForChangeCount(1);
   EXPECT_EQ("BoundsChanged window=" + IdToString(window_1_1) +
                 " old_bounds=0,0 0x0 new_bounds=0,0 100x100",
             SingleChangeToDescription(*changes2()));
 
   // Should not be possible to change the bounds of a window created by another
   // connection.
-  ASSERT_FALSE(SetWindowBounds(vm2(), window_1_1, 0, 0, 0, 0));
+  ASSERT_FALSE(SetWindowBounds(ws2(), window_1_1, 0, 0, 0, 0));
 }
 
 // Verify AddWindow fails when trying to manipulate windows in other roots.
 TEST_F(WindowTreeAppTest, CantMoveWindowsFromOtherRoot) {
   // Create 1 and 2 in the first connection.
-  Id window_1_1 = vm_client1()->NewWindow(1);
-  Id window_1_2 = vm_client1()->NewWindow(2);
+  Id window_1_1 = ws_client1()->NewWindow(1);
+  Id window_1_2 = ws_client1()->NewWindow(2);
   ASSERT_TRUE(window_1_1);
   ASSERT_TRUE(window_1_2);
 
@@ -1167,47 +1166,47 @@
 
   // Try to move 2 to be a child of 1 from connection 2. This should fail as 2
   // should not be able to access 1.
-  ASSERT_FALSE(AddWindow(vm2(), window_1_1, window_1_2));
+  ASSERT_FALSE(AddWindow(ws2(), window_1_1, window_1_2));
 
   // Try to reparent 1 to the root. A connection is not allowed to reparent its
   // roots.
-  ASSERT_FALSE(AddWindow(vm2(), root_window_id(), window_1_1));
+  ASSERT_FALSE(AddWindow(ws2(), root_window_id(), window_1_1));
 }
 
 // Verify RemoveWindowFromParent fails for windows that are descendants of the
 // roots.
 TEST_F(WindowTreeAppTest, CantRemoveWindowsInOtherRoots) {
   // Create 1 and 2 in the first connection and parent both to the root.
-  Id window_1_1 = vm_client1()->NewWindow(1);
-  Id window_1_2 = vm_client1()->NewWindow(2);
+  Id window_1_1 = ws_client1()->NewWindow(1);
+  Id window_1_2 = ws_client1()->NewWindow(2);
   ASSERT_TRUE(window_1_1);
   ASSERT_TRUE(window_1_2);
 
-  ASSERT_TRUE(AddWindow(vm1(), root_window_id(), window_1_1));
-  ASSERT_TRUE(AddWindow(vm1(), root_window_id(), window_1_2));
+  ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_1));
+  ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_2));
 
   // Establish the second connection and give it the root 1.
   ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
 
   // Connection 2 should not be able to remove window 2 or 1 from its parent.
-  ASSERT_FALSE(RemoveWindowFromParent(vm2(), window_1_2));
-  ASSERT_FALSE(RemoveWindowFromParent(vm2(), window_1_1));
+  ASSERT_FALSE(RemoveWindowFromParent(ws2(), window_1_2));
+  ASSERT_FALSE(RemoveWindowFromParent(ws2(), window_1_1));
 
   // Create windows 10 and 11 in 2.
-  Id window_2_10 = vm_client2()->NewWindow(10);
-  Id window_2_11 = vm_client2()->NewWindow(11);
+  Id window_2_10 = ws_client2()->NewWindow(10);
+  Id window_2_11 = ws_client2()->NewWindow(11);
   ASSERT_TRUE(window_2_10);
   ASSERT_TRUE(window_2_11);
 
   // Parent 11 to 10.
-  ASSERT_TRUE(AddWindow(vm2(), window_2_10, window_2_11));
+  ASSERT_TRUE(AddWindow(ws2(), window_2_10, window_2_11));
   // Remove 11 from 10.
-  ASSERT_TRUE(RemoveWindowFromParent(vm2(), window_2_11));
+  ASSERT_TRUE(RemoveWindowFromParent(ws2(), window_2_11));
 
   // Verify nothing was actually removed.
   {
     std::vector<TestWindow> windows;
-    GetWindowTree(vm1(), root_window_id(), &windows);
+    GetWindowTree(ws1(), root_window_id(), &windows);
     ASSERT_EQ(3u, windows.size());
     EXPECT_EQ(WindowParentToString(root_window_id(), kNullParentId),
               windows[0].ToString());
@@ -1221,28 +1220,28 @@
 // Verify GetWindowTree fails for windows that are not descendants of the roots.
 TEST_F(WindowTreeAppTest, CantGetWindowTreeOfOtherRoots) {
   // Create 1 and 2 in the first connection and parent both to the root.
-  Id window_1_1 = vm_client1()->NewWindow(1);
-  Id window_1_2 = vm_client1()->NewWindow(2);
+  Id window_1_1 = ws_client1()->NewWindow(1);
+  Id window_1_2 = ws_client1()->NewWindow(2);
   ASSERT_TRUE(window_1_1);
   ASSERT_TRUE(window_1_2);
 
-  ASSERT_TRUE(AddWindow(vm1(), root_window_id(), window_1_1));
-  ASSERT_TRUE(AddWindow(vm1(), root_window_id(), window_1_2));
+  ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_1));
+  ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_2));
 
   ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
 
   std::vector<TestWindow> windows;
 
   // Should get nothing for the root.
-  GetWindowTree(vm2(), root_window_id(), &windows);
+  GetWindowTree(ws2(), root_window_id(), &windows);
   ASSERT_TRUE(windows.empty());
 
   // Should get nothing for window 2.
-  GetWindowTree(vm2(), window_1_2, &windows);
+  GetWindowTree(ws2(), window_1_2, &windows);
   ASSERT_TRUE(windows.empty());
 
   // Should get window 1 if asked for.
-  GetWindowTree(vm2(), window_1_1, &windows);
+  GetWindowTree(ws2(), window_1_1, &windows);
   ASSERT_EQ(1u, windows.size());
   EXPECT_EQ(WindowParentToString(window_1_1, kNullParentId),
             windows[0].ToString());
@@ -1253,11 +1252,11 @@
   changes2()->clear();
 
   Id window_1_1 = BuildWindowId(connection_id_1(), 1);
-  ASSERT_NO_FATAL_FAILURE(EstablishThirdConnection(vm1(), window_1_1));
+  ASSERT_NO_FATAL_FAILURE(EstablishThirdConnection(ws1(), window_1_1));
 
   // Connection2 should have been told of the unembed and delete.
   {
-    vm_client2_->WaitForChangeCount(2);
+    ws_client2_->WaitForChangeCount(2);
     EXPECT_EQ("OnUnembed", ChangesToDescription1(*changes2())[0]);
     EXPECT_EQ("WindowDeleted window=" + IdToString(window_1_1),
               ChangesToDescription1(*changes2())[1]);
@@ -1266,7 +1265,7 @@
   // Connection2 has no root. Verify it can't see window 1,1 anymore.
   {
     std::vector<TestWindow> windows;
-    GetWindowTree(vm2(), window_1_1, &windows);
+    GetWindowTree(ws2(), window_1_1, &windows);
     EXPECT_TRUE(windows.empty());
   }
 }
@@ -1276,20 +1275,20 @@
   Id window_1_1 = BuildWindowId(connection_id_1(), 1);
   changes2()->clear();
 
-  ASSERT_NO_FATAL_FAILURE(EstablishThirdConnection(vm1(), window_1_1));
+  ASSERT_NO_FATAL_FAILURE(EstablishThirdConnection(ws1(), window_1_1));
 
   // Connection2 should have been told about the unembed and delete.
-  vm_client2_->WaitForChangeCount(2);
+  ws_client2_->WaitForChangeCount(2);
   changes2()->clear();
 
   // Create a window in the third connection and parent it to the root.
-  Id window_3_1 = vm_client3()->NewWindow(1);
+  Id window_3_1 = ws_client3()->NewWindow(1);
   ASSERT_TRUE(window_3_1);
-  ASSERT_TRUE(AddWindow(vm3(), window_1_1, window_3_1));
+  ASSERT_TRUE(AddWindow(ws3(), window_1_1, window_3_1));
 
   // Connection 1 should have been told about the add (it owns the window).
   {
-    vm_client1_->WaitForChangeCount(1);
+    ws_client1_->WaitForChangeCount(1);
     EXPECT_EQ("HierarchyChanged window=" + IdToString(window_3_1) +
                   " new_parent=" + IdToString(window_1_1) + " old_parent=null",
               SingleChangeToDescription(*changes1()));
@@ -1301,39 +1300,39 @@
 
     // We should get a new connection for the new embedding.
     scoped_ptr<TestWindowTreeClientImpl> connection4(
-        EstablishConnectionViaEmbed(vm1(), window_1_1, nullptr));
+        EstablishConnectionViaEmbed(ws1(), window_1_1, nullptr));
     ASSERT_TRUE(connection4.get());
     EXPECT_EQ("[" + WindowParentToString(window_1_1, kNullParentId) + "]",
               ChangeWindowDescription(*connection4->tracker()->changes()));
 
     // And 3 should get an unembed and delete.
-    vm_client3_->WaitForChangeCount(2);
+    ws_client3_->WaitForChangeCount(2);
     EXPECT_EQ("OnUnembed", ChangesToDescription1(*changes3())[0]);
     EXPECT_EQ("WindowDeleted window=" + IdToString(window_1_1),
               ChangesToDescription1(*changes3())[1]);
   }
 
-  // vm3() has no root. Verify it can't see window 1,1 anymore.
+  // ws3() has no root. Verify it can't see window 1,1 anymore.
   {
     std::vector<TestWindow> windows;
-    GetWindowTree(vm3(), window_1_1, &windows);
+    GetWindowTree(ws3(), window_1_1, &windows);
     EXPECT_TRUE(windows.empty());
   }
 
   // Verify 3,1 is no longer parented to 1,1. We have to do this from 1,1 as
-  // vm3() can no longer see 1,1.
+  // ws3() can no longer see 1,1.
   {
     std::vector<TestWindow> windows;
-    GetWindowTree(vm1(), window_1_1, &windows);
+    GetWindowTree(ws1(), window_1_1, &windows);
     ASSERT_EQ(1u, windows.size());
     EXPECT_EQ(WindowParentToString(window_1_1, kNullParentId),
               windows[0].ToString());
   }
 
-  // Verify vm3() can still see the window it created 3,1.
+  // Verify ws3() can still see the window it created 3,1.
   {
     std::vector<TestWindow> windows;
-    GetWindowTree(vm3(), window_3_1, &windows);
+    GetWindowTree(ws3(), window_3_1, &windows);
     ASSERT_EQ(1u, windows.size());
     EXPECT_EQ(WindowParentToString(window_3_1, kNullParentId),
               windows[0].ToString());
@@ -1343,15 +1342,15 @@
 // Assertions for SetWindowVisibility.
 TEST_F(WindowTreeAppTest, SetWindowVisibility) {
   // Create 1 and 2 in the first connection and parent both to the root.
-  Id window_1_1 = vm_client1()->NewWindow(1);
-  Id window_1_2 = vm_client1()->NewWindow(2);
+  Id window_1_1 = ws_client1()->NewWindow(1);
+  Id window_1_2 = ws_client1()->NewWindow(2);
   ASSERT_TRUE(window_1_1);
   ASSERT_TRUE(window_1_2);
 
-  ASSERT_TRUE(AddWindow(vm1(), root_window_id(), window_1_1));
+  ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_1));
   {
     std::vector<TestWindow> windows;
-    GetWindowTree(vm1(), root_window_id(), &windows);
+    GetWindowTree(ws1(), root_window_id(), &windows);
     ASSERT_EQ(2u, windows.size());
     EXPECT_EQ(WindowParentToString(root_window_id(), kNullParentId) +
                   " visible=true drawn=true",
@@ -1362,11 +1361,11 @@
   }
 
   // Show all the windows.
-  ASSERT_TRUE(SetWindowVisibility(vm1(), window_1_1, true));
-  ASSERT_TRUE(SetWindowVisibility(vm1(), window_1_2, true));
+  ASSERT_TRUE(SetWindowVisibility(ws1(), window_1_1, true));
+  ASSERT_TRUE(SetWindowVisibility(ws1(), window_1_2, true));
   {
     std::vector<TestWindow> windows;
-    GetWindowTree(vm1(), root_window_id(), &windows);
+    GetWindowTree(ws1(), root_window_id(), &windows);
     ASSERT_EQ(2u, windows.size());
     EXPECT_EQ(WindowParentToString(root_window_id(), kNullParentId) +
                   " visible=true drawn=true",
@@ -1377,10 +1376,10 @@
   }
 
   // Hide 1.
-  ASSERT_TRUE(SetWindowVisibility(vm1(), window_1_1, false));
+  ASSERT_TRUE(SetWindowVisibility(ws1(), window_1_1, false));
   {
     std::vector<TestWindow> windows;
-    GetWindowTree(vm1(), window_1_1, &windows);
+    GetWindowTree(ws1(), window_1_1, &windows);
     ASSERT_EQ(1u, windows.size());
     EXPECT_EQ(WindowParentToString(window_1_1, root_window_id()) +
                   " visible=false drawn=false",
@@ -1388,10 +1387,10 @@
   }
 
   // Attach 2 to 1.
-  ASSERT_TRUE(AddWindow(vm1(), window_1_1, window_1_2));
+  ASSERT_TRUE(AddWindow(ws1(), window_1_1, window_1_2));
   {
     std::vector<TestWindow> windows;
-    GetWindowTree(vm1(), window_1_1, &windows);
+    GetWindowTree(ws1(), window_1_1, &windows);
     ASSERT_EQ(2u, windows.size());
     EXPECT_EQ(WindowParentToString(window_1_1, root_window_id()) +
                   " visible=false drawn=false",
@@ -1402,10 +1401,10 @@
   }
 
   // Show 1.
-  ASSERT_TRUE(SetWindowVisibility(vm1(), window_1_1, true));
+  ASSERT_TRUE(SetWindowVisibility(ws1(), window_1_1, true));
   {
     std::vector<TestWindow> windows;
-    GetWindowTree(vm1(), window_1_1, &windows);
+    GetWindowTree(ws1(), window_1_1, &windows);
     ASSERT_EQ(2u, windows.size());
     EXPECT_EQ(WindowParentToString(window_1_1, root_window_id()) +
                   " visible=true drawn=true",
@@ -1419,30 +1418,30 @@
 // Assertions for SetWindowVisibility sending notifications.
 TEST_F(WindowTreeAppTest, SetWindowVisibilityNotifications) {
   // Create 1,1 and 1,2. 1,2 is made a child of 1,1 and 1,1 a child of the root.
-  Id window_1_1 = vm_client1()->NewWindow(1);
+  Id window_1_1 = ws_client1()->NewWindow(1);
   ASSERT_TRUE(window_1_1);
-  ASSERT_TRUE(SetWindowVisibility(vm1(), window_1_1, true));
-  Id window_1_2 = vm_client1()->NewWindow(2);
+  ASSERT_TRUE(SetWindowVisibility(ws1(), window_1_1, true));
+  Id window_1_2 = ws_client1()->NewWindow(2);
   ASSERT_TRUE(window_1_2);
-  ASSERT_TRUE(SetWindowVisibility(vm1(), window_1_2, true));
-  ASSERT_TRUE(AddWindow(vm1(), root_window_id(), window_1_1));
-  ASSERT_TRUE(AddWindow(vm1(), window_1_1, window_1_2));
+  ASSERT_TRUE(SetWindowVisibility(ws1(), window_1_2, true));
+  ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_1));
+  ASSERT_TRUE(AddWindow(ws1(), window_1_1, window_1_2));
 
   // Establish the second connection at 1,2.
   ASSERT_NO_FATAL_FAILURE(EstablishSecondConnectionWithRoot(window_1_2));
 
   // Add 2,3 as a child of 1,2.
-  Id window_2_3 = vm_client2()->NewWindow(3);
+  Id window_2_3 = ws_client2()->NewWindow(3);
   ASSERT_TRUE(window_2_3);
-  ASSERT_TRUE(SetWindowVisibility(vm2(), window_2_3, true));
-  ASSERT_TRUE(AddWindow(vm2(), window_1_2, window_2_3));
-  WaitForAllMessages(vm1());
+  ASSERT_TRUE(SetWindowVisibility(ws2(), window_2_3, true));
+  ASSERT_TRUE(AddWindow(ws2(), window_1_2, window_2_3));
+  WaitForAllMessages(ws1());
 
   changes2()->clear();
   // Hide 1,2 from connection 1. Connection 2 should see this.
-  ASSERT_TRUE(SetWindowVisibility(vm1(), window_1_2, false));
+  ASSERT_TRUE(SetWindowVisibility(ws1(), window_1_2, false));
   {
-    vm_client2_->WaitForChangeCount(1);
+    ws_client2_->WaitForChangeCount(1);
     EXPECT_EQ(
         "VisibilityChanged window=" + IdToString(window_1_2) + " visible=false",
         SingleChangeToDescription(*changes2()));
@@ -1450,9 +1449,9 @@
 
   changes1()->clear();
   // Show 1,2 from connection 2, connection 1 should be notified.
-  ASSERT_TRUE(SetWindowVisibility(vm2(), window_1_2, true));
+  ASSERT_TRUE(SetWindowVisibility(ws2(), window_1_2, true));
   {
-    vm_client1_->WaitForChangeCount(1);
+    ws_client1_->WaitForChangeCount(1);
     EXPECT_EQ(
         "VisibilityChanged window=" + IdToString(window_1_2) + " visible=true",
         SingleChangeToDescription(*changes1()));
@@ -1460,9 +1459,9 @@
 
   changes2()->clear();
   // Hide 1,1, connection 2 should be told the draw state changed.
-  ASSERT_TRUE(SetWindowVisibility(vm1(), window_1_1, false));
+  ASSERT_TRUE(SetWindowVisibility(ws1(), window_1_1, false));
   {
-    vm_client2_->WaitForChangeCount(1);
+    ws_client2_->WaitForChangeCount(1);
     EXPECT_EQ(
         "DrawnStateChanged window=" + IdToString(window_1_2) + " drawn=false",
         SingleChangeToDescription(*changes2()));
@@ -1470,9 +1469,9 @@
 
   changes2()->clear();
   // Show 1,1 from connection 1. Connection 2 should see this.
-  ASSERT_TRUE(SetWindowVisibility(vm1(), window_1_1, true));
+  ASSERT_TRUE(SetWindowVisibility(ws1(), window_1_1, true));
   {
-    vm_client2_->WaitForChangeCount(1);
+    ws_client2_->WaitForChangeCount(1);
     EXPECT_EQ(
         "DrawnStateChanged window=" + IdToString(window_1_2) + " drawn=true",
         SingleChangeToDescription(*changes2()));
@@ -1480,9 +1479,9 @@
 
   // Change visibility of 2,3, connection 1 should see this.
   changes1()->clear();
-  ASSERT_TRUE(SetWindowVisibility(vm2(), window_2_3, false));
+  ASSERT_TRUE(SetWindowVisibility(ws2(), window_2_3, false));
   {
-    vm_client1_->WaitForChangeCount(1);
+    ws_client1_->WaitForChangeCount(1);
     EXPECT_EQ(
         "VisibilityChanged window=" + IdToString(window_2_3) + " visible=false",
         SingleChangeToDescription(*changes1()));
@@ -1490,9 +1489,9 @@
 
   changes2()->clear();
   // Remove 1,1 from the root, connection 2 should see drawn state changed.
-  ASSERT_TRUE(RemoveWindowFromParent(vm1(), window_1_1));
+  ASSERT_TRUE(RemoveWindowFromParent(ws1(), window_1_1));
   {
-    vm_client2_->WaitForChangeCount(1);
+    ws_client2_->WaitForChangeCount(1);
     EXPECT_EQ(
         "DrawnStateChanged window=" + IdToString(window_1_2) + " drawn=false",
         SingleChangeToDescription(*changes2()));
@@ -1500,9 +1499,9 @@
 
   changes2()->clear();
   // Add 1,1 back to the root, connection 2 should see drawn state changed.
-  ASSERT_TRUE(AddWindow(vm1(), root_window_id(), window_1_1));
+  ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_1));
   {
-    vm_client2_->WaitForChangeCount(1);
+    ws_client2_->WaitForChangeCount(1);
     EXPECT_EQ(
         "DrawnStateChanged window=" + IdToString(window_1_2) + " drawn=true",
         SingleChangeToDescription(*changes2()));
@@ -1510,16 +1509,16 @@
 }
 
 TEST_F(WindowTreeAppTest, SetWindowProperty) {
-  Id window_1_1 = vm_client1()->NewWindow(1);
+  Id window_1_1 = ws_client1()->NewWindow(1);
   ASSERT_TRUE(window_1_1);
 
   ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
   changes2()->clear();
 
-  ASSERT_TRUE(AddWindow(vm1(), root_window_id(), window_1_1));
+  ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_1));
   {
     std::vector<TestWindow> windows;
-    GetWindowTree(vm1(), root_window_id(), &windows);
+    GetWindowTree(ws1(), root_window_id(), &windows);
     ASSERT_EQ(2u, windows.size());
     EXPECT_EQ(root_window_id(), windows[0].window_id);
     EXPECT_EQ(window_1_1, windows[1].window_id);
@@ -1529,9 +1528,9 @@
   // Set properties on 1.
   changes2()->clear();
   std::vector<uint8_t> one(1, '1');
-  ASSERT_TRUE(SetWindowProperty(vm1(), window_1_1, "one", &one));
+  ASSERT_TRUE(SetWindowProperty(ws1(), window_1_1, "one", &one));
   {
-    vm_client2_->WaitForChangeCount(1);
+    ws_client2_->WaitForChangeCount(1);
     EXPECT_EQ(
         "PropertyChanged window=" + IdToString(window_1_1) + " key=one value=1",
         SingleChangeToDescription(*changes2()));
@@ -1540,7 +1539,7 @@
   // Test that our properties exist in the window tree
   {
     std::vector<TestWindow> windows;
-    GetWindowTree(vm1(), window_1_1, &windows);
+    GetWindowTree(ws1(), window_1_1, &windows);
     ASSERT_EQ(1u, windows.size());
     ASSERT_EQ(1u, windows[0].properties.size());
     EXPECT_EQ(one, windows[0].properties["one"]);
@@ -1548,9 +1547,9 @@
 
   changes2()->clear();
   // Set back to null.
-  ASSERT_TRUE(SetWindowProperty(vm1(), window_1_1, "one", NULL));
+  ASSERT_TRUE(SetWindowProperty(ws1(), window_1_1, "one", NULL));
   {
-    vm_client2_->WaitForChangeCount(1);
+    ws_client2_->WaitForChangeCount(1);
     EXPECT_EQ("PropertyChanged window=" + IdToString(window_1_1) +
                   " key=one value=NULL",
               SingleChangeToDescription(*changes2()));
@@ -1561,24 +1560,24 @@
   // Create connection 2 and 3.
   ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
   Id window_1_1 = BuildWindowId(connection_id_1(), 1);
-  Id window_2_2 = vm_client2()->NewWindow(2);
+  Id window_2_2 = ws_client2()->NewWindow(2);
   ASSERT_TRUE(window_2_2);
-  ASSERT_TRUE(AddWindow(vm2(), window_1_1, window_2_2));
+  ASSERT_TRUE(AddWindow(ws2(), window_1_1, window_2_2));
   changes2()->clear();
-  ASSERT_NO_FATAL_FAILURE(EstablishThirdConnection(vm2(), window_2_2));
+  ASSERT_NO_FATAL_FAILURE(EstablishThirdConnection(ws2(), window_2_2));
 
   // Connection 1 should get a hierarchy change for window_2_2.
-  vm_client1_->WaitForChangeCount(1);
+  ws_client1_->WaitForChangeCount(1);
   changes1()->clear();
 
   // Close connection 3. Connection 2 (which had previously embedded 3) should
   // be notified of this.
-  vm_client3_.reset();
-  vm_client2_->WaitForChangeCount(1);
+  ws_client3_.reset();
+  ws_client2_->WaitForChangeCount(1);
   EXPECT_EQ("OnEmbeddedAppDisconnected window=" + IdToString(window_2_2),
             SingleChangeToDescription(*changes2()));
 
-  vm_client1_->WaitForChangeCount(1);
+  ws_client1_->WaitForChangeCount(1);
   EXPECT_EQ("OnEmbeddedAppDisconnected window=" + IdToString(window_2_2),
             SingleChangeToDescription(*changes1()));
 }
@@ -1589,20 +1588,20 @@
   // Create connection 2 and 3.
   ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
   Id window_1_1 = BuildWindowId(connection_id_1(), 1);
-  ASSERT_TRUE(AddWindow(vm1(), root_window_id(), window_1_1));
-  Id window_2_2 = vm_client2()->NewWindow(2);
-  Id window_2_3 = vm_client2()->NewWindow(3);
+  ASSERT_TRUE(AddWindow(ws1(), root_window_id(), window_1_1));
+  Id window_2_2 = ws_client2()->NewWindow(2);
+  Id window_2_3 = ws_client2()->NewWindow(3);
   ASSERT_TRUE(window_2_2);
   ASSERT_TRUE(window_2_3);
-  ASSERT_TRUE(AddWindow(vm2(), window_1_1, window_2_2));
-  ASSERT_TRUE(AddWindow(vm2(), window_2_2, window_2_3));
+  ASSERT_TRUE(AddWindow(ws2(), window_1_1, window_2_2));
+  ASSERT_TRUE(AddWindow(ws2(), window_2_2, window_2_3));
   changes2()->clear();
-  ASSERT_NO_FATAL_FAILURE(EstablishThirdConnection(vm2(), window_2_3));
+  ASSERT_NO_FATAL_FAILURE(EstablishThirdConnection(ws2(), window_2_3));
   changes3()->clear();
 
   // Close connection 2. Connection 3 should get a delete (for its root).
-  vm_client2_.reset();
-  vm_client3_->WaitForChangeCount(1);
+  ws_client2_.reset();
+  ws_client3_->WaitForChangeCount(1);
   EXPECT_EQ("WindowDeleted window=" + IdToString(window_2_3),
             SingleChangeToDescription(*changes3()));
 }
@@ -1612,26 +1611,26 @@
 TEST_F(WindowTreeAppTest, DontCleanMapOnDestroy) {
   ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
   Id window_1_1 = BuildWindowId(connection_id_1(), 1);
-  ASSERT_TRUE(vm_client2()->NewWindow(1));
+  ASSERT_TRUE(ws_client2()->NewWindow(1));
   changes1()->clear();
-  vm_client2_.reset();
-  vm_client1_->WaitForChangeCount(1);
+  ws_client2_.reset();
+  ws_client1_->WaitForChangeCount(1);
   EXPECT_EQ("OnEmbeddedAppDisconnected window=" + IdToString(window_1_1),
             SingleChangeToDescription(*changes1()));
   std::vector<TestWindow> windows;
-  GetWindowTree(vm1(), window_1_1, &windows);
+  GetWindowTree(ws1(), window_1_1, &windows);
   EXPECT_FALSE(windows.empty());
 }
 
 // Verifies Embed() works when supplying a WindowTreeClient.
 TEST_F(WindowTreeAppTest, EmbedSupplyingWindowTreeClient) {
-  ASSERT_TRUE(vm_client1()->NewWindow(1));
+  ASSERT_TRUE(ws_client1()->NewWindow(1));
 
   TestWindowTreeClientImpl client2(application_impl());
   mojom::WindowTreeClientPtr client2_ptr;
   mojo::Binding<WindowTreeClient> client2_binding(&client2, &client2_ptr);
   ASSERT_TRUE(
-      Embed(vm1(), BuildWindowId(connection_id_1(), 1), client2_ptr.Pass()));
+      Embed(ws1(), BuildWindowId(connection_id_1(), 1), client2_ptr.Pass()));
   client2.WaitForOnEmbed();
   EXPECT_EQ("OnEmbed",
             SingleChangeToDescription(*client2.tracker()->changes()));
@@ -1641,19 +1640,19 @@
   ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
 
   Id window_1_1 = BuildWindowId(connection_id_1(), 1);
-  Id window_2_2 = vm_client2()->NewWindow(2);
+  Id window_2_2 = ws_client2()->NewWindow(2);
   ASSERT_TRUE(window_2_2);
-  ASSERT_TRUE(AddWindow(vm2(), window_1_1, window_2_2));
-  ASSERT_NO_FATAL_FAILURE(EstablishThirdConnection(vm2(), window_2_2));
+  ASSERT_TRUE(AddWindow(ws2(), window_1_1, window_2_2));
+  ASSERT_NO_FATAL_FAILURE(EstablishThirdConnection(ws2(), window_2_2));
 
-  Id window_3_3 = vm_client3()->NewWindow(3);
+  Id window_3_3 = ws_client3()->NewWindow(3);
   ASSERT_TRUE(window_3_3);
-  ASSERT_TRUE(AddWindow(vm3(), window_2_2, window_3_3));
+  ASSERT_TRUE(AddWindow(ws3(), window_2_2, window_3_3));
 
   // 2 should not be able to embed in window_3_3 as window_3_3 was not created
   // by
   // 2.
-  EXPECT_FALSE(EmbedUrl(application_impl(), vm2(), application_impl()->url(),
+  EXPECT_FALSE(EmbedUrl(application_impl(), ws2(), application_impl()->url(),
                         window_3_3));
 }
 
@@ -1662,22 +1661,22 @@
   ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
 
   Id window_1_1 = BuildWindowId(connection_id_1(), 1);
-  Id window_2_2 = vm_client2()->NewWindow(2);
+  Id window_2_2 = ws_client2()->NewWindow(2);
   ASSERT_TRUE(window_2_2);
-  ASSERT_TRUE(AddWindow(vm2(), window_1_1, window_2_2));
+  ASSERT_TRUE(AddWindow(ws2(), window_1_1, window_2_2));
 
   changes2()->clear();
 
   // Establish a third connection in window_2_2.
-  ASSERT_NO_FATAL_FAILURE(EstablishThirdConnection(vm1(), window_2_2));
+  ASSERT_NO_FATAL_FAILURE(EstablishThirdConnection(ws1(), window_2_2));
 
-  WaitForAllMessages(vm2());
+  WaitForAllMessages(ws2());
   EXPECT_EQ(std::string(), SingleChangeToDescription(*changes2()));
 }
 
 TEST_F(WindowTreeAppTest, CantEmbedFromConnectionRoot) {
   // Shouldn't be able to embed into the root.
-  ASSERT_FALSE(EmbedUrl(application_impl(), vm1(), application_impl()->url(),
+  ASSERT_FALSE(EmbedUrl(application_impl(), ws1(), application_impl()->url(),
                         root_window_id()));
 
   // Even though the call above failed a WindowTreeClient was obtained. We need
@@ -1687,25 +1686,25 @@
 
   // Don't allow a connection to embed into its own root.
   ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
-  EXPECT_FALSE(EmbedUrl(application_impl(), vm2(), application_impl()->url(),
+  EXPECT_FALSE(EmbedUrl(application_impl(), ws2(), application_impl()->url(),
                         BuildWindowId(connection_id_1(), 1)));
 
   // Need to wait for a WindowTreeClient for same reason as above.
   WaitForWindowTreeClient();
 
-  Id window_1_2 = vm_client1()->NewWindow(2);
+  Id window_1_2 = ws_client1()->NewWindow(2);
   ASSERT_TRUE(window_1_2);
   ASSERT_TRUE(
-      AddWindow(vm1(), BuildWindowId(connection_id_1(), 1), window_1_2));
-  ASSERT_TRUE(vm_client3_.get() == nullptr);
-  vm_client3_ = EstablishConnectionViaEmbedWithPolicyBitmask(
-      vm1(), window_1_2, mojom::WindowTree::ACCESS_POLICY_EMBED_ROOT, nullptr);
-  ASSERT_TRUE(vm_client3_.get() != nullptr);
-  vm_client3_->set_root_window(root_window_id());
+      AddWindow(ws1(), BuildWindowId(connection_id_1(), 1), window_1_2));
+  ASSERT_TRUE(ws_client3_.get() == nullptr);
+  ws_client3_ = EstablishConnectionViaEmbedWithPolicyBitmask(
+      ws1(), window_1_2, mojom::WindowTree::ACCESS_POLICY_EMBED_ROOT, nullptr);
+  ASSERT_TRUE(ws_client3_.get() != nullptr);
+  ws_client3_->set_root_window(root_window_id());
 
-  // window_1_2 is vm3's root, so even though v3 is an embed root it should not
+  // window_1_2 is ws3's root, so even though v3 is an embed root it should not
   // be able to Embed into itself.
-  ASSERT_FALSE(EmbedUrl(application_impl(), vm3(), application_impl()->url(),
+  ASSERT_FALSE(EmbedUrl(application_impl(), ws3(), application_impl()->url(),
                         window_1_2));
 }
 
@@ -1720,5 +1719,4 @@
 // tests.
 
 }  // namespace ws
-
 }  // namespace mus
diff --git a/components/password_manager/core/browser/password_autofill_manager.cc b/components/password_manager/core/browser/password_autofill_manager.cc
index 3100bddf..6aa0418 100644
--- a/components/password_manager/core/browser/password_autofill_manager.cc
+++ b/components/password_manager/core/browser/password_autofill_manager.cc
@@ -258,8 +258,8 @@
 
 bool PasswordAutofillManager::RemoveSuggestion(const base::string16& value,
                                                int identifier) {
-  // http://crbug.com/329038
-  NOTIMPLEMENTED();
+  // Password suggestions cannot be deleted this way.
+  // See http://crbug.com/329038#c15
   return false;
 }
 
diff --git a/content/browser/service_worker/service_worker_version_unittest.cc b/content/browser/service_worker/service_worker_version_unittest.cc
index 0a6544ed..55a6d91 100644
--- a/content/browser/service_worker/service_worker_version_unittest.cc
+++ b/content/browser/service_worker/service_worker_version_unittest.cc
@@ -23,8 +23,8 @@
 
 #define IPC_MESSAGE_START TestMsgStart
 
-IPC_MESSAGE_CONTROL0(TestMsg_Message);
-IPC_MESSAGE_ROUTED1(TestMsg_MessageFromWorker, int);
+IPC_MESSAGE_CONTROL0(TestMsg_Message)
+IPC_MESSAGE_ROUTED1(TestMsg_MessageFromWorker, int)
 
 // ---------------------------------------------------------------------------
 
diff --git a/content/common/android/sync_compositor_messages.h b/content/common/android/sync_compositor_messages.h
index d48091a..4ea5b15 100644
--- a/content/common/android/sync_compositor_messages.h
+++ b/content/common/android/sync_compositor_messages.h
@@ -105,23 +105,23 @@
                            content::SyncCompositorCommonBrowserParams,
                            IPC::WebInputEventPointer,
                            content::SyncCompositorCommonRendererParams,
-                           content::InputEventAckState);
+                           content::InputEventAckState)
 
 IPC_SYNC_MESSAGE_ROUTED2_1(SyncCompositorMsg_BeginFrame,
                            content::SyncCompositorCommonBrowserParams,
                            cc::BeginFrameArgs,
-                           content::SyncCompositorCommonRendererParams);
+                           content::SyncCompositorCommonRendererParams)
 
 IPC_SYNC_MESSAGE_ROUTED2_1(SyncCompositorMsg_ComputeScroll,
                            content::SyncCompositorCommonBrowserParams,
                            base::TimeTicks,
-                           content::SyncCompositorCommonRendererParams);
+                           content::SyncCompositorCommonRendererParams)
 
 IPC_SYNC_MESSAGE_ROUTED2_2(SyncCompositorMsg_DemandDrawHw,
                            content::SyncCompositorCommonBrowserParams,
                            content::SyncCompositorDemandDrawHwParams,
                            content::SyncCompositorCommonRendererParams,
-                           cc::CompositorFrame);
+                           cc::CompositorFrame)
 
 IPC_MESSAGE_ROUTED1(SyncCompositorHostMsg_UpdateState,
-                    content::SyncCompositorCommonRendererParams);
+                    content::SyncCompositorCommonRendererParams)
diff --git a/content/common/media/media_player_messages_android.h b/content/common/media/media_player_messages_android.h
index 29c52699..909c273 100644
--- a/content/common/media/media_player_messages_android.h
+++ b/content/common/media/media_player_messages_android.h
@@ -209,7 +209,7 @@
 // Initialize a media player object.
 IPC_MESSAGE_ROUTED1(
     MediaPlayerHostMsg_Initialize,
-    MediaPlayerHostMsg_Initialize_Params);
+    MediaPlayerHostMsg_Initialize_Params)
 
 // Pause the player.
 IPC_MESSAGE_ROUTED2(MediaPlayerHostMsg_Pause,
@@ -251,7 +251,7 @@
 // Requests the player with |player_id| to use the CDM with |cdm_id|.
 IPC_MESSAGE_ROUTED2(MediaPlayerHostMsg_SetCdm,
                     int /* player_id */,
-                    int /* cdm_id */);
+                    int /* cdm_id */)
 
 // Sent after the renderer demuxer has seeked.
 IPC_MESSAGE_CONTROL2(MediaPlayerHostMsg_DemuxerSeekDone,
diff --git a/content/common/view_messages.h b/content/common/view_messages.h
index f4fb6a4..c1a3d36 100644
--- a/content/common/view_messages.h
+++ b/content/common/view_messages.h
@@ -891,7 +891,7 @@
 IPC_MESSAGE_CONTROL3(ViewMsg_SystemColorsChanged,
                      int /* AppleAquaColorVariant */,
                      std::string /* AppleHighlightedTextColor */,
-                     std::string /* AppleHighlightColor */);
+                     std::string /* AppleHighlightColor */)
 #endif
 
 #if defined(OS_ANDROID)
@@ -1399,7 +1399,7 @@
 IPC_MESSAGE_ROUTED0(ViewHostMsg_StartPluginIme)
 
 // Receives content of a web page as plain text.
-IPC_MESSAGE_ROUTED1(ViewMsg_GetRenderedTextCompleted, std::string);
+IPC_MESSAGE_ROUTED1(ViewMsg_GetRenderedTextCompleted, std::string)
 #endif
 
 // Adding a new message? Stick to the sort order above: first platform
diff --git a/third_party/WebKit/Source/core/animation/SVGAngleInterpolationType.cpp b/third_party/WebKit/Source/core/animation/SVGAngleInterpolationType.cpp
index aa3145a9..4fced35 100644
--- a/third_party/WebKit/Source/core/animation/SVGAngleInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/SVGAngleInterpolationType.cpp
@@ -23,11 +23,6 @@
     return InterpolationValue::create(*this, InterpolableNumber::create(toSVGAngle(svgValue).value()));
 }
 
-PassOwnPtr<InterpolationValue> SVGAngleInterpolationType::maybeConvertUnderlyingValue(const InterpolationEnvironment& environment) const
-{
-    return maybeConvertSVGValue(environment.svgBaseValue());
-}
-
 RefPtrWillBeRawPtr<SVGPropertyBase> SVGAngleInterpolationType::appliedSVGValue(const InterpolableValue& interpolableValue, const NonInterpolableValue*) const
 {
     double doubleValue = toInterpolableNumber(interpolableValue).value();
diff --git a/third_party/WebKit/Source/core/animation/SVGAngleInterpolationType.h b/third_party/WebKit/Source/core/animation/SVGAngleInterpolationType.h
index 176bf33..15e766ed 100644
--- a/third_party/WebKit/Source/core/animation/SVGAngleInterpolationType.h
+++ b/third_party/WebKit/Source/core/animation/SVGAngleInterpolationType.h
@@ -18,7 +18,6 @@
 private:
     PassOwnPtr<InterpolationValue> maybeConvertNeutral() const final;
     PassOwnPtr<InterpolationValue> maybeConvertSVGValue(const SVGPropertyBase& svgValue) const final;
-    PassOwnPtr<InterpolationValue> maybeConvertUnderlyingValue(const InterpolationEnvironment&) const final;
     RefPtrWillBeRawPtr<SVGPropertyBase> appliedSVGValue(const InterpolableValue&, const NonInterpolableValue*) const final;
 };
 
diff --git a/third_party/WebKit/Source/core/animation/SVGInterpolationType.cpp b/third_party/WebKit/Source/core/animation/SVGInterpolationType.cpp
index 82435d9..0b18d60 100644
--- a/third_party/WebKit/Source/core/animation/SVGInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/SVGInterpolationType.cpp
@@ -20,6 +20,11 @@
     return maybeConvertSVGValue(*svgValue);
 }
 
+PassOwnPtr<InterpolationValue> SVGInterpolationType::maybeConvertUnderlyingValue(const InterpolationEnvironment& environment) const
+{
+    return maybeConvertSVGValue(environment.svgBaseValue());
+}
+
 void SVGInterpolationType::apply(const InterpolableValue& interpolableValue, const NonInterpolableValue* nonInterpolableValue, InterpolationEnvironment& environment) const
 {
     SVGElement& targetElement = environment.svgElement();
diff --git a/third_party/WebKit/Source/core/animation/SVGInterpolationType.h b/third_party/WebKit/Source/core/animation/SVGInterpolationType.h
index e8b3b3b..5e4ef44 100644
--- a/third_party/WebKit/Source/core/animation/SVGInterpolationType.h
+++ b/third_party/WebKit/Source/core/animation/SVGInterpolationType.h
@@ -24,6 +24,7 @@
     virtual RefPtrWillBeRawPtr<SVGPropertyBase> appliedSVGValue(const InterpolableValue&, const NonInterpolableValue*) const = 0;
 
     PassOwnPtr<InterpolationValue> maybeConvertSingle(const PropertySpecificKeyframe&, const InterpolationEnvironment&, const UnderlyingValue&, ConversionCheckers&) const override;
+    PassOwnPtr<InterpolationValue> maybeConvertUnderlyingValue(const InterpolationEnvironment&) const override;
     void apply(const InterpolableValue&, const NonInterpolableValue*, InterpolationEnvironment&) const final;
 };
 
diff --git a/third_party/WebKit/Source/core/animation/SVGNumberInterpolationType.cpp b/third_party/WebKit/Source/core/animation/SVGNumberInterpolationType.cpp
index 86702f4..820077f 100644
--- a/third_party/WebKit/Source/core/animation/SVGNumberInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/SVGNumberInterpolationType.cpp
@@ -24,11 +24,6 @@
     return InterpolationValue::create(*this, InterpolableNumber::create(toSVGNumber(svgValue).value()));
 }
 
-PassOwnPtr<InterpolationValue> SVGNumberInterpolationType::maybeConvertUnderlyingValue(const InterpolationEnvironment& environment) const
-{
-    return maybeConvertSVGValue(environment.svgBaseValue());
-}
-
 RefPtrWillBeRawPtr<SVGPropertyBase> SVGNumberInterpolationType::appliedSVGValue(const InterpolableValue& interpolableValue, const NonInterpolableValue*) const
 {
     double value = toInterpolableNumber(interpolableValue).value();
diff --git a/third_party/WebKit/Source/core/animation/SVGNumberInterpolationType.h b/third_party/WebKit/Source/core/animation/SVGNumberInterpolationType.h
index 05aa0b8..e169aafa 100644
--- a/third_party/WebKit/Source/core/animation/SVGNumberInterpolationType.h
+++ b/third_party/WebKit/Source/core/animation/SVGNumberInterpolationType.h
@@ -20,7 +20,6 @@
 private:
     PassOwnPtr<InterpolationValue> maybeConvertNeutral() const final;
     PassOwnPtr<InterpolationValue> maybeConvertSVGValue(const SVGPropertyBase& svgValue) const final;
-    PassOwnPtr<InterpolationValue> maybeConvertUnderlyingValue(const InterpolationEnvironment&) const final;
     RefPtrWillBeRawPtr<SVGPropertyBase> appliedSVGValue(const InterpolableValue&, const NonInterpolableValue*) const final;
 
     bool m_isNonNegative;
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp
index 0e74191..756bf7d 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp
@@ -25,11 +25,15 @@
 #include "config.h"
 #include "platform/graphics/GraphicsLayer.h"
 
+#include "platform/RuntimeEnabledFeatures.h"
 #include "platform/scroll/ScrollableArea.h"
 #include "platform/transforms/Matrix3DTransformOperation.h"
 #include "platform/transforms/RotateTransformOperation.h"
 #include "platform/transforms/TranslateTransformOperation.h"
 #include "public/platform/Platform.h"
+#include "public/platform/WebCompositorAnimationPlayer.h"
+#include "public/platform/WebCompositorAnimationPlayerClient.h"
+#include "public/platform/WebCompositorAnimationTimeline.h"
 #include "public/platform/WebCompositorSupport.h"
 #include "public/platform/WebFloatAnimationCurve.h"
 #include "public/platform/WebGraphicsContext3D.h"
@@ -83,6 +87,8 @@
         m_layerTreeView.clear();
     }
 
+    WebLayerTreeView* layerTreeView() { return m_layerTreeView.get(); }
+
 protected:
     WebLayer* m_platformLayer;
     OwnPtr<GraphicsLayerForTesting> m_graphicsLayer;
@@ -94,6 +100,21 @@
     MockGraphicsLayerClient m_client;
 };
 
+class AnimationPlayerForTesting : public WebCompositorAnimationPlayerClient {
+public:
+    AnimationPlayerForTesting()
+    {
+        m_compositorPlayer = adoptPtr(Platform::current()->compositorSupport()->createAnimationPlayer());
+    }
+
+    WebCompositorAnimationPlayer* compositorPlayer() const override
+    {
+        return m_compositorPlayer.get();
+    }
+
+    OwnPtr<WebCompositorAnimationPlayer> m_compositorPlayer;
+};
+
 TEST_F(GraphicsLayerTest, updateLayerShouldFlattenTransformWithAnimations)
 {
     ASSERT_FALSE(m_platformLayer->hasActiveAnimation());
@@ -102,25 +123,63 @@
     curve->add(WebFloatKeyframe(0.0, 0.0));
     OwnPtr<WebCompositorAnimation> floatAnimation(adoptPtr(Platform::current()->compositorSupport()->createAnimation(*curve, WebCompositorAnimation::TargetPropertyOpacity)));
     int animationId = floatAnimation->id();
-    ASSERT_TRUE(m_platformLayer->addAnimation(floatAnimation.leakPtr()));
 
-    ASSERT_TRUE(m_platformLayer->hasActiveAnimation());
+    if (RuntimeEnabledFeatures::compositorAnimationTimelinesEnabled()) {
+        OwnPtr<WebCompositorAnimationTimeline> compositorTimeline = adoptPtr(Platform::current()->compositorSupport()->createAnimationTimeline());
+        AnimationPlayerForTesting player;
 
-    m_graphicsLayer->setShouldFlattenTransform(false);
+        layerTreeView()->attachCompositorAnimationTimeline(compositorTimeline.get());
+        compositorTimeline->playerAttached(player);
 
-    m_platformLayer = m_graphicsLayer->platformLayer();
-    ASSERT_TRUE(m_platformLayer);
+        player.compositorPlayer()->attachLayer(m_platformLayer);
+        ASSERT_TRUE(player.compositorPlayer()->isLayerAttached());
 
-    ASSERT_TRUE(m_platformLayer->hasActiveAnimation());
-    m_platformLayer->removeAnimation(animationId);
-    ASSERT_FALSE(m_platformLayer->hasActiveAnimation());
+        player.compositorPlayer()->addAnimation(floatAnimation.leakPtr());
 
-    m_graphicsLayer->setShouldFlattenTransform(true);
+        ASSERT_TRUE(m_platformLayer->hasActiveAnimation());
 
-    m_platformLayer = m_graphicsLayer->platformLayer();
-    ASSERT_TRUE(m_platformLayer);
+        m_graphicsLayer->setShouldFlattenTransform(false);
 
-    ASSERT_FALSE(m_platformLayer->hasActiveAnimation());
+        m_platformLayer = m_graphicsLayer->platformLayer();
+        ASSERT_TRUE(m_platformLayer);
+
+        ASSERT_TRUE(m_platformLayer->hasActiveAnimation());
+        player.compositorPlayer()->removeAnimation(animationId);
+        ASSERT_FALSE(m_platformLayer->hasActiveAnimation());
+
+        m_graphicsLayer->setShouldFlattenTransform(true);
+
+        m_platformLayer = m_graphicsLayer->platformLayer();
+        ASSERT_TRUE(m_platformLayer);
+
+        ASSERT_FALSE(m_platformLayer->hasActiveAnimation());
+
+        player.compositorPlayer()->detachLayer();
+        ASSERT_FALSE(player.compositorPlayer()->isLayerAttached());
+
+        compositorTimeline->playerDestroyed(player);
+        layerTreeView()->detachCompositorAnimationTimeline(compositorTimeline.get());
+    } else {
+        ASSERT_TRUE(m_platformLayer->addAnimation(floatAnimation.leakPtr()));
+
+        ASSERT_TRUE(m_platformLayer->hasActiveAnimation());
+
+        m_graphicsLayer->setShouldFlattenTransform(false);
+
+        m_platformLayer = m_graphicsLayer->platformLayer();
+        ASSERT_TRUE(m_platformLayer);
+
+        ASSERT_TRUE(m_platformLayer->hasActiveAnimation());
+        m_platformLayer->removeAnimation(animationId);
+        ASSERT_FALSE(m_platformLayer->hasActiveAnimation());
+
+        m_graphicsLayer->setShouldFlattenTransform(true);
+
+        m_platformLayer = m_graphicsLayer->platformLayer();
+        ASSERT_TRUE(m_platformLayer);
+
+        ASSERT_FALSE(m_platformLayer->hasActiveAnimation());
+    }
 }
 
 class FakeScrollableArea : public NoBaseWillBeGarbageCollectedFinalized<FakeScrollableArea>, public ScrollableArea {
diff --git a/third_party/brotli/README.chromium b/third_party/brotli/README.chromium
index c57d2f2..972cdb3 100644
--- a/third_party/brotli/README.chromium
+++ b/third_party/brotli/README.chromium
@@ -1,6 +1,6 @@
 Name: Brotli
 URL: https://github.com/google/brotli
-Version: 8e90bf4c5f6479353beb83af4118782621947765
+Version: c90ec29f54e9165df815b0f1311cfddb1be4afad
 License: Apache 2.0
 License File: LICENSE
 Security Critical: yes
diff --git a/third_party/brotli/dec/bit_reader.c b/third_party/brotli/dec/bit_reader.c
index 351cbc2..ddd014e 100644
--- a/third_party/brotli/dec/bit_reader.c
+++ b/third_party/brotli/dec/bit_reader.c
@@ -24,15 +24,9 @@
 extern "C" {
 #endif
 
-void BrotliInitBitReader(BrotliBitReader* const br, BrotliInput input) {
-  BROTLI_DCHECK(br != NULL);
-
-  br->input_ = input;
+void BrotliInitBitReader(BrotliBitReader* const br) {
   br->val_ = 0;
   br->bit_pos_ = sizeof(br->val_) << 3;
-  br->avail_in = 0;
-  br->eos_ = 0;
-  br->next_in = br->buf_;
 }
 
 int BrotliWarmupBitReader(BrotliBitReader* const br) {
@@ -43,12 +37,17 @@
   if (!BROTLI_ALIGNED_READ) {
     aligned_read_mask = 0;
   }
-  while (br->bit_pos_ == (sizeof(br->val_) << 3) ||
-      (((size_t)br->next_in) & aligned_read_mask) != 0) {
-    if (!br->avail_in) {
+  if (BrotliGetAvailableBits(br) == 0) {
+    if (!BrotliPullByte(br)) {
       return 0;
     }
-    BrotliPullByte(br);
+  }
+
+  while ((((size_t)br->next_in) & aligned_read_mask) != 0) {
+    if (!BrotliPullByte(br)) {
+      /* If we consumed all the input, we don't care about the alignment. */
+      return 1;
+    }
   }
   return 1;
 }
diff --git a/third_party/brotli/dec/bit_reader.h b/third_party/brotli/dec/bit_reader.h
index f25fd4a7..f390348 100644
--- a/third_party/brotli/dec/bit_reader.h
+++ b/third_party/brotli/dec/bit_reader.h
@@ -20,45 +20,57 @@
 
 #include <string.h>
 #include "./port.h"
-#include "./streams.h"
 #include "./types.h"
 
 #if defined(__cplusplus) || defined(c_plusplus)
 extern "C" {
 #endif
 
-#define BROTLI_READ_SIZE          1024
-/* 128 bytes, plus 8 bytes slack for valid 128-byte BrotliCheckInputAmount with
-   some bytes read in val_ of bit reader. */
-#define BROTLI_IMPLICIT_ZEROES    136
-#define BROTLI_IBUF_SIZE          (BROTLI_READ_SIZE + BROTLI_IMPLICIT_ZEROES)
-#define BROTLI_IBUF_MASK          (BROTLI_READ_SIZE - 1)
+#if (BROTLI_64_BITS)
+#define BROTLI_SHORT_FILL_BIT_WINDOW_READ 4
+typedef uint64_t reg_t;
+#else
+#define BROTLI_SHORT_FILL_BIT_WINDOW_READ 2
+typedef uint32_t reg_t;
+#endif
 
-/* Masking with this expression turns to a single "Unsigned Bit Field Extract"
-   UBFX instruction on ARM. */
+static const uint32_t kBitMask[33] = { 0x0000,
+    0x00000001, 0x00000003, 0x00000007, 0x0000000F,
+    0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
+    0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
+    0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF,
+    0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF,
+    0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF,
+    0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF,
+    0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF
+};
+
 static BROTLI_INLINE uint32_t BitMask(uint32_t n) {
+  if (IS_CONSTANT(n) || BROTLI_HAS_UBFX) {
+    /* Masking with this expression turns to a single
+       "Unsigned Bit Field Extract" UBFX instruction on ARM. */
     return ~((0xffffffffU) << n);
+  } else {
+    return kBitMask[n];
+  }
 }
 
 typedef struct {
-#if (BROTLI_64_BITS)
-  uint64_t    val_;          /* pre-fetched bits */
-#else
-  uint32_t    val_;          /* pre-fetched bits */
-#endif
+  reg_t       val_;          /* pre-fetched bits */
   uint32_t    bit_pos_;      /* current bit-reading position in val_ */
-  uint8_t*    next_in;       /* the byte we're reading from */
-  uint32_t    avail_in;
-  int         eos_;          /* input stream is finished */
-  BrotliInput input_;        /* input callback */
-
-  /* Input byte buffer, consist of a ringbuffer and a "slack" region where */
-  /* bytes from the start of the ringbuffer are copied. */
-  uint8_t buf_[BROTLI_IBUF_SIZE];
+  const uint8_t* next_in;    /* the byte we're reading from */
+  size_t      avail_in;
 } BrotliBitReader;
 
+typedef struct {
+  reg_t    val_;
+  uint32_t bit_pos_;
+  const uint8_t* next_in;
+  size_t   avail_in;
+} BrotliBitReaderState;
+
 /* Initializes the bitreader fields. */
-void BrotliInitBitReader(BrotliBitReader* const br, BrotliInput input);
+void BrotliInitBitReader(BrotliBitReader* const br);
 
 /* Ensures that accumulator is not empty. May consume one byte of input.
    Returns 0 if data is required but there is no input available.
@@ -66,66 +78,35 @@
    reading. */
 int BrotliWarmupBitReader(BrotliBitReader* const br);
 
-/* Pulls data from the input to the the read buffer.
+static BROTLI_INLINE void BrotliBitReaderSaveState(
+    BrotliBitReader* const from, BrotliBitReaderState* to) {
+  to->val_ = from->val_;
+  to->bit_pos_ = from->bit_pos_;
+  to->next_in = from->next_in;
+  to->avail_in = from->avail_in;
+}
 
-   Returns 0 if one of:
-    - the input callback returned an error, or
-    - there is no more input and the position is past the end of the stream.
-    - finish is false and less than BROTLI_READ_SIZE are available - a next call
-      when more data is available makes it continue including the partially read
-      data
+static BROTLI_INLINE void BrotliBitReaderRestoreState(
+    BrotliBitReader* const to, BrotliBitReaderState* from) {
+  to->val_ = from->val_;
+  to->bit_pos_ = from->bit_pos_;
+  to->next_in = from->next_in;
+  to->avail_in = from->avail_in;
+}
 
-   If finish is true and the end of the stream is reached,
-   BROTLI_IMPLICIT_ZEROES additional zero bytes are copied to the ringbuffer.
-*/
-static BROTLI_INLINE int BrotliReadInput(
-    BrotliBitReader* const br, int finish) {
-  if (PREDICT_FALSE(br->eos_)) {
-    return 0;
-  } else {
-    size_t i;
-    int bytes_read;
-    if (br->next_in != br->buf_) {
-      for (i = 0; i < br->avail_in; i++) {
-        br->buf_[i] = br->next_in[i];
-      }
-      br->next_in = br->buf_;
-    }
-    bytes_read = BrotliRead(br->input_, br->next_in + br->avail_in,
-        (size_t)(BROTLI_READ_SIZE - br->avail_in));
-    if (bytes_read < 0) {
-      return 0;
-    }
-    br->avail_in += (uint32_t)bytes_read;
-    if (br->avail_in < BROTLI_READ_SIZE) {
-      if (!finish) {
-        return 0;
-      }
-      br->eos_ = 1;
-      /* Store BROTLI_IMPLICIT_ZEROES bytes of zero after the stream end. */
-      memset(br->next_in + br->avail_in, 0, BROTLI_IMPLICIT_ZEROES);
-      br->avail_in += BROTLI_IMPLICIT_ZEROES;
-    }
-    return 1;
-  }
+static BROTLI_INLINE uint32_t BrotliGetAvailableBits(
+    const BrotliBitReader* br) {
+  return (BROTLI_64_BITS ? 64 : 32) - br->bit_pos_;
 }
 
 /* Returns amount of unread bytes the bit reader still has buffered from the
    BrotliInput, including whole bytes in br->val_. */
 static BROTLI_INLINE size_t BrotliGetRemainingBytes(BrotliBitReader* br) {
-  size_t result = br->avail_in + sizeof(br->val_) - (br->bit_pos_ >> 3);
-  if (!br->eos_) {
-    return result;
-  }
-  if (result <= BROTLI_IMPLICIT_ZEROES) {
-    return 0;
-  }
-  return result - BROTLI_IMPLICIT_ZEROES;
+  return br->avail_in + (BrotliGetAvailableBits(br) >> 3);
 }
 
 /* Checks if there is at least num bytes left in the input ringbuffer (excluding
-   the bits remaining in br->val_). The maximum value for num is
-   BROTLI_IMPLICIT_ZEROES bytes. */
+   the bits remaining in br->val_). */
 static BROTLI_INLINE int BrotliCheckInputAmount(
     BrotliBitReader* const br, size_t num) {
   return br->avail_in >= num;
@@ -160,6 +141,7 @@
   }
 }
 
+#if (BROTLI_64_BITS)
 static BROTLI_INLINE uint64_t BrotliLoad64LE(const uint8_t* in) {
   if (BROTLI_LITTLE_ENDIAN) {
     return *((const uint64_t*)in);
@@ -186,6 +168,7 @@
     return value;
   }
 }
+#endif
 
 /* Guarantees that there are at least n_bits + 1 bits in accumulator.
    Precondition: accumulator contains at least 1 bit.
@@ -215,8 +198,8 @@
       br->val_ >>= 32;
       br->bit_pos_ ^= 32;  /* here same as -= 32 because of the if condition */
       br->val_ |= ((uint64_t)BrotliLoad32LE(br->next_in)) << 32;
-      br->avail_in -= 4;
-      br->next_in += 4;
+      br->avail_in -= BROTLI_SHORT_FILL_BIT_WINDOW_READ;
+      br->next_in += BROTLI_SHORT_FILL_BIT_WINDOW_READ;
     }
   }
 #else
@@ -233,15 +216,24 @@
       br->val_ >>= 16;
       br->bit_pos_ ^= 16;  /* here same as -= 16 because of the if condition */
       br->val_ |= ((uint32_t)BrotliLoad16LE(br->next_in)) << 16;
-      br->avail_in -= 2;
-      br->next_in += 2;
+      br->avail_in -= BROTLI_SHORT_FILL_BIT_WINDOW_READ;
+      br->next_in += BROTLI_SHORT_FILL_BIT_WINDOW_READ;
     }
   }
 #endif
 }
 
+/* Mosltly like BrotliFillBitWindow, but guarantees only 16 bits and reads no
+   more than BROTLI_SHORT_FILL_BIT_WINDOW_READ bytes of input. */
+static BROTLI_INLINE void BrotliFillBitWindow16(BrotliBitReader* const br) {
+  BrotliFillBitWindow(br, 17);
+}
+
 /* Pulls one byte of input to accumulator. */
-static BROTLI_INLINE void BrotliPullByte(BrotliBitReader* const br) {
+static BROTLI_INLINE int BrotliPullByte(BrotliBitReader* const br) {
+  if (br->avail_in == 0) {
+    return 0;
+  }
   br->val_ >>= 8;
 #if (BROTLI_64_BITS)
     br->val_ |= ((uint64_t)*br->next_in) << 56;
@@ -251,39 +243,68 @@
   br->bit_pos_ -= 8;
   --br->avail_in;
   ++br->next_in;
+  return 1;
 }
 
-/* Like BrotliGetBits, but does not mask the result, it is only guaranteed
-that it has minimum n_bits. */
-static BROTLI_INLINE uint32_t BrotliGetBitsUnmasked(
-    BrotliBitReader* const br, uint32_t n_bits) {
-  BrotliFillBitWindow(br, n_bits);
-  return (uint32_t)(br->val_ >> br->bit_pos_);
+/* Returns currently available bits.
+   The number of valid bits could be calclulated by BrotliGetAvailableBits. */
+static BROTLI_INLINE reg_t BrotliGetBitsUnmasked(BrotliBitReader* const br) {
+  return br->val_ >> br->bit_pos_;
+}
+
+/* Like BrotliGetBits, but does not mask the result.
+   The result contains at least 16 valid bits. */
+static BROTLI_INLINE uint32_t BrotliGet16BitsUnmasked(
+    BrotliBitReader* const br) {
+  BrotliFillBitWindow(br, 16);
+  return (uint32_t)BrotliGetBitsUnmasked(br);
 }
 
 /* Returns the specified number of bits from br without advancing bit pos. */
 static BROTLI_INLINE uint32_t BrotliGetBits(
     BrotliBitReader* const br, uint32_t n_bits) {
   BrotliFillBitWindow(br, n_bits);
-  return (uint32_t)(br->val_ >> br->bit_pos_) & BitMask(n_bits);
+  return (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits);
+}
+
+/* Tries to peek the specified amount of bits. Returns 0, if there is not
+   enough input. */
+static BROTLI_INLINE int BrotliSafeGetBits(
+  BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
+  while (BrotliGetAvailableBits(br) < n_bits) {
+    if (!BrotliPullByte(br)) {
+      return 0;
+    }
+  }
+  *val = (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits);
+  return 1;
 }
 
 /* Advances the bit pos by n_bits. */
 static BROTLI_INLINE void BrotliDropBits(
-    BrotliBitReader* const br, int n_bits) {
-  br->bit_pos_ += (uint32_t)n_bits;
+    BrotliBitReader* const br, uint32_t n_bits) {
+  br->bit_pos_ += n_bits;
+}
+
+static BROTLI_INLINE void BrotliBitReaderUnload(BrotliBitReader* br) {
+  uint32_t unused_bytes = BrotliGetAvailableBits(br) >> 3;
+  uint32_t unused_bits = unused_bytes << 3;
+  br->avail_in += unused_bytes;
+  br->next_in -= unused_bytes;
+  br->val_ <<= unused_bits;
+  br->bit_pos_ += unused_bits;
 }
 
 /* Reads the specified number of bits from br and advances the bit pos.
    Precondition: accumulator MUST contain at least n_bits. */
 static BROTLI_INLINE void BrotliTakeBits(
   BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
-  *val = (uint32_t)(br->val_ >> br->bit_pos_) & BitMask(n_bits);
+  *val = (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits);
 #ifdef BROTLI_DECODE_DEBUG
   printf("[BrotliReadBits]  %d %d %d val: %6x\n",
          (int)br->avail_in, (int)br->bit_pos_, n_bits, (int)*val);
 #endif
-  br->bit_pos_ += n_bits;
+  BrotliDropBits(br, n_bits);
 }
 
 /* Reads the specified number of bits from br and advances the bit pos.
@@ -307,14 +328,13 @@
 }
 
 /* Tries to read the specified amount of bits. Returns 0, if there is not
-   enough input. */
+   enough input. n_bits MUST be positive. */
 static BROTLI_INLINE int BrotliSafeReadBits(
   BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
-  while (br->bit_pos_ + (uint32_t)n_bits > (sizeof(br->val_) << 3)) {
-    if (br->avail_in == 0) {
+  while (BrotliGetAvailableBits(br) < n_bits) {
+    if (!BrotliPullByte(br)) {
       return 0;
     }
-    BrotliPullByte(br);
   }
   BrotliTakeBits(br, n_bits, val);
   return 1;
@@ -323,7 +343,7 @@
 /* Advances the bit reader position to the next byte boundary and verifies
    that any skipped bits are set to zero. */
 static BROTLI_INLINE int BrotliJumpToByteBoundary(BrotliBitReader* br) {
-  uint32_t pad_bits_count = (64 - (int)br->bit_pos_) & 0x7;
+  uint32_t pad_bits_count = BrotliGetAvailableBits(br) & 0x7;
   uint32_t pad_bits = 0;
   if (pad_bits_count != 0) {
     BrotliTakeBits(br, pad_bits_count, &pad_bits);
@@ -335,12 +355,13 @@
    Precondition: bit reader is parked to a byte boundary.
    Returns -1 if operation is not feasible. */
 static BROTLI_INLINE int BrotliPeekByte(BrotliBitReader* br, size_t offset) {
-  size_t bytes_left = sizeof(br->val_) - (br->bit_pos_ >> 3);
-  if (br->bit_pos_ & 7) {
+  uint32_t available_bits = BrotliGetAvailableBits(br);
+  size_t bytes_left = available_bits >> 3;
+  if (available_bits & 7) {
     return -1;
   }
   if (offset < bytes_left) {
-    return (br->val_ >> (br->bit_pos_ + (unsigned)(offset << 3))) & 0xFF;
+    return (BrotliGetBitsUnmasked(br) >> (unsigned)(offset << 3)) & 0xFF;
   }
   offset -= bytes_left;
   if (offset < br->avail_in) {
@@ -354,30 +375,17 @@
    warmed up again after this. */
 static BROTLI_INLINE void BrotliCopyBytes(uint8_t* dest,
                                           BrotliBitReader* br, size_t num) {
-  while (br->bit_pos_ + 8 <= (BROTLI_64_BITS ? 64 : 32)
-      && num > 0) {
-    *dest = (uint8_t)(br->val_ >> br->bit_pos_);
-    br->bit_pos_ += 8;
+  while (BrotliGetAvailableBits(br) >= 8 && num > 0) {
+    *dest = (uint8_t)BrotliGetBitsUnmasked(br);
+    BrotliDropBits(br, 8);
     ++dest;
     --num;
   }
   memcpy(dest, br->next_in, num);
-  br->avail_in -= (uint32_t)num;
+  br->avail_in -= num;
   br->next_in += num;
 }
 
-/* Checks that bit reader hasn't read after the end of input.
-   Returns 0 if bit reader has used implicit zeroes after the end of input. */
-static BROTLI_INLINE int BrotliIsBitReaderOK(BrotliBitReader* br) {
-  size_t remaining_bytes =
-      br->avail_in + sizeof(br->val_) - (br->bit_pos_ >> 3);
-  return !br->eos_ || (remaining_bytes >= BROTLI_IMPLICIT_ZEROES);
-}
-
-#undef BROTLI_IMPLICIT_ZEROES
-#undef BROTLI_IBUF_SIZE
-#undef BROTLI_IBUF_MASK
-
 #if defined(__cplusplus) || defined(c_plusplus)
 }    /* extern "C" */
 #endif
diff --git a/third_party/brotli/dec/decode.c b/third_party/brotli/dec/decode.c
index eb91ce3..bd0d2132 100644
--- a/third_party/brotli/dec/decode.c
+++ b/third_party/brotli/dec/decode.c
@@ -46,8 +46,8 @@
 #define BROTLI_LOG(x)
 #endif
 
-static const uint8_t kDefaultCodeLength = 8;
-static const uint8_t kCodeLengthRepeatCode = 16;
+static const uint32_t kDefaultCodeLength = 8;
+static const uint32_t kCodeLengthRepeatCode = 16;
 static const uint32_t kNumLiteralCodes = 256;
 static const uint32_t kNumInsertAndCopyCodes = 704;
 static const uint32_t kNumBlockLengthCodes = 26;
@@ -274,27 +274,94 @@
   }
 }
 
-/* Decodes the next Huffman code from bit-stream. Reads 0 - 15 bits. */
-static BROTLI_INLINE uint32_t ReadSymbol(const HuffmanCode* table,
-                                         BrotliBitReader* br) {
-  /* Read the bits for two reads at once. */
-  uint32_t val = BrotliGetBitsUnmasked(br, 15);
-  table += val & HUFFMAN_TABLE_MASK;
+/* Decodes the Huffman code.
+   This method doesn't read data from the bit reader, BUT drops the amount of
+   bits that correspond to the decoded symbol.
+   bits MUST contain at least 15 (BROTLI_HUFFMAN_MAX_CODE_LENGTH) valid bits. */
+static BROTLI_INLINE uint32_t DecodeSymbol(uint32_t bits,
+                                           const HuffmanCode* table,
+                                           BrotliBitReader* br) {
+  table += bits & HUFFMAN_TABLE_MASK;
   if (table->bits > HUFFMAN_TABLE_BITS) {
     uint32_t nbits = table->bits - HUFFMAN_TABLE_BITS;
     BrotliDropBits(br, HUFFMAN_TABLE_BITS);
     table += table->value;
-    table += (val >> HUFFMAN_TABLE_BITS) & BitMask(nbits);
+    table += (bits >> HUFFMAN_TABLE_BITS) & BitMask(nbits);
   }
   BrotliDropBits(br, table->bits);
   return table->value;
 }
 
+/* Reads and decodes the next Huffman code from bit-stream.
+   This method peeks 16 bits of input and drops 0 - 15 of them. */
+static BROTLI_INLINE uint32_t ReadSymbol(const HuffmanCode* table,
+                                         BrotliBitReader* br) {
+  return DecodeSymbol(BrotliGet16BitsUnmasked(br), table, br);
+}
+
+/* Same as DecodeSymbol, but it is known that there is less than 15 bits of
+   input are currently available. */
+static BROTLI_NOINLINE int SafeDecodeSymbol(const HuffmanCode* table,
+                                            BrotliBitReader* br,
+                                            uint32_t* result) {
+  uint32_t val;
+  uint32_t available_bits = BrotliGetAvailableBits(br);
+  if (available_bits == 0) {
+    if (table->bits == 0) {
+      *result = table->value;
+      return 1;
+    }
+    return 0; /* No valid bits at all. */
+  }
+  val = (uint32_t)BrotliGetBitsUnmasked(br);
+  table += val & HUFFMAN_TABLE_MASK;
+  if (table->bits <= HUFFMAN_TABLE_BITS) {
+    if (table->bits <= available_bits) {
+      BrotliDropBits(br, table->bits);
+      *result = table->value;
+      return 1;
+    } else {
+      return 0; /* Not enough bits for the first level. */
+    }
+  }
+  if (available_bits <= HUFFMAN_TABLE_BITS) {
+    return 0; /* Not enough bits to move to the second level. */
+  }
+
+  /* Speculatively drop HUFFMAN_TABLE_BITS. */
+  val = (val & BitMask(table->bits)) >> HUFFMAN_TABLE_BITS;
+  available_bits -= HUFFMAN_TABLE_BITS;
+  table += table->value + val;
+  if (available_bits < table->bits) {
+    return 0; /* Not enough bits for the second level. */
+  }
+
+  BrotliDropBits(br, HUFFMAN_TABLE_BITS + table->bits);
+  *result = table->value;
+  return 1;
+}
+
+static BROTLI_INLINE int SafeReadSymbol(const HuffmanCode* table,
+                                        BrotliBitReader* br,
+                                        uint32_t* result) {
+  uint32_t val;
+  if (PREDICT_TRUE(BrotliSafeGetBits(br, 15, &val))) {
+    *result = DecodeSymbol(val, table, br);
+    return 1;
+  }
+  return SafeDecodeSymbol(table, br, result);
+}
+
+
 /* Makes a look-up in first level Huffman table. Peeks 8 bits. */
-static BROTLI_INLINE void PreloadSymbol(const HuffmanCode* table,
+static BROTLI_INLINE void PreloadSymbol(int safe,
+                                        const HuffmanCode* table,
                                         BrotliBitReader* br,
                                         uint32_t* bits,
                                         uint32_t* value) {
+  if (safe) {
+    return;
+  }
   table += BrotliGetBits(br, HUFFMAN_TABLE_BITS);
   *bits = table->bits;
   *value = table->value;
@@ -308,7 +375,7 @@
                                                   uint32_t* value) {
   uint32_t result = *value;
   if (PREDICT_FALSE(*bits > HUFFMAN_TABLE_BITS)) {
-    uint32_t val = BrotliGetBitsUnmasked(br, 15);
+    uint32_t val = BrotliGet16BitsUnmasked(br);
     const HuffmanCode* ext = table + (val & HUFFMAN_TABLE_MASK) + *value;
     uint32_t mask = BitMask((*bits - HUFFMAN_TABLE_BITS));
     BrotliDropBits(br, HUFFMAN_TABLE_BITS);
@@ -316,9 +383,9 @@
     BrotliDropBits(br, ext->bits);
     result = ext->value;
   } else {
-    BrotliDropBits(br, (int)*bits);
+    BrotliDropBits(br, *bits);
   }
-  PreloadSymbol(table, br, bits, value);
+  PreloadSymbol(0, table, br, bits, value);
   return result;
 }
 
@@ -331,6 +398,250 @@
   return result;
 }
 
+/* Reads (s->symbol + 1) symbols.
+   Totally 1..4 symbols are read, 1..10 bits each.
+   The list of symbols MUST NOT contain duplicates.
+ */
+static BrotliResult ReadSimpleHuffmanSymbols(uint32_t alphabet_size,
+                                             BrotliState* s) {
+  /* max_bits == 1..10; symbol == 0..3; 1..40 bits will be read. */
+  BrotliBitReader* br = &s->br;
+  uint32_t max_bits = Log2Floor(alphabet_size - 1);
+  uint32_t i = s->sub_loop_counter;
+  uint32_t num_symbols = s->symbol;
+  while (i <= num_symbols) {
+    uint32_t v;
+    if (PREDICT_FALSE(!BrotliSafeReadBits(br, max_bits, &v))) {
+      s->sub_loop_counter = i;
+      s->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_READ;
+      return BROTLI_RESULT_NEEDS_MORE_INPUT;
+    }
+    if (v >= alphabet_size) {
+      return BROTLI_FAILURE();
+    }
+    s->symbols_lists_array[i] = (uint16_t)v;
+    BROTLI_LOG_UINT(s->symbols_lists_array[i]);
+    ++i;
+  }
+
+  for (i = 0; i < num_symbols; ++i) {
+    uint32_t k = i + 1;
+    for (; k <= num_symbols; ++k) {
+      if (s->symbols_lists_array[i] == s->symbols_lists_array[k]) {
+        return BROTLI_FAILURE();
+      }
+    }
+  }
+
+  return BROTLI_RESULT_SUCCESS;
+}
+
+/* Process single decoded symbol code length:
+    A) reset the repeat variable
+    B) remember code length (if it is not 0)
+    C) extend corredponding index-chain
+    D) reduce the huffman space
+    E) update the histogram
+ */
+static BROTLI_INLINE void ProcessSingleCodeLength(uint32_t code_len,
+    uint32_t* symbol, uint32_t* repeat, uint32_t* space,
+    uint32_t* prev_code_len, uint16_t* symbol_lists,
+    uint16_t* code_length_histo, int* next_symbol) {
+  *repeat = 0;
+  if (code_len != 0) { /* code_len == 1..15 */
+    symbol_lists[next_symbol[code_len]] = (uint16_t)(*symbol);
+    next_symbol[code_len] = (int)(*symbol);
+    *prev_code_len = code_len;
+    *space -= 32768U >> code_len;
+    code_length_histo[code_len]++;
+  }
+  (*symbol)++;
+}
+
+/* Process repeated symbol code length.
+    A) Check if it is the extension of previous repeat sequence; if the decoded
+       value is not kCodeLengthRepeatCode, then it is a new symbol-skip
+    B) Update repeat variable
+    C) Check if operation is feasible (fits alphapet)
+    D) For each symbol do the same operations as in ProcessSingleCodeLength
+
+   PRECONDITION: code_len == kCodeLengthRepeatCode or kCodeLengthRepeatCode + 1
+ */
+static BROTLI_INLINE void ProcessRepeatedCodeLength(uint32_t code_len,
+    uint32_t repeat_delta, uint32_t alphabet_size, uint32_t* symbol,
+    uint32_t* repeat, uint32_t* space, uint32_t* prev_code_len,
+    uint32_t* repeat_code_len, uint16_t* symbol_lists,
+    uint16_t* code_length_histo, int* next_symbol) {
+  uint32_t old_repeat;
+  uint32_t new_len = 0;
+  if (code_len == kCodeLengthRepeatCode) {
+    new_len = *prev_code_len;
+  }
+  if (*repeat_code_len != new_len) {
+    *repeat = 0;
+    *repeat_code_len = new_len;
+  }
+  old_repeat = *repeat;
+  if (*repeat > 0) {
+    *repeat -= 2;
+    *repeat <<= code_len - 14U;
+  }
+  *repeat += repeat_delta + 3U;
+  repeat_delta = *repeat - old_repeat;
+  if (*symbol + repeat_delta > alphabet_size) {
+    (void)BROTLI_FAILURE();
+    *symbol = alphabet_size;
+    *space = 0xFFFFF;
+    return;
+  }
+  if (*repeat_code_len != 0) {
+    unsigned last = *symbol + repeat_delta;
+    int next = next_symbol[*repeat_code_len];
+    do {
+      symbol_lists[next] = (uint16_t)*symbol;
+      next = (int)*symbol;
+    } while (++(*symbol) != last);
+    next_symbol[*repeat_code_len] = next;
+    *space -= repeat_delta << (15 - *repeat_code_len);
+    code_length_histo[*repeat_code_len] = (uint16_t)
+        (code_length_histo[*repeat_code_len] + repeat_delta);
+  } else {
+    *symbol += repeat_delta;
+  }
+}
+
+/* Reads and decodes symbol codelengths. */
+static BrotliResult ReadSymbolCodeLengths(
+    uint32_t alphabet_size, BrotliState* s) {
+  BrotliBitReader* br = &s->br;
+  uint32_t symbol = s->symbol;
+  uint32_t repeat = s->repeat;
+  uint32_t space = s->space;
+  uint32_t prev_code_len = s->prev_code_len;
+  uint32_t repeat_code_len = s->repeat_code_len;
+  uint16_t* symbol_lists = s->symbol_lists;
+  uint16_t* code_length_histo = s->code_length_histo;
+  int* next_symbol = s->next_symbol;
+  if (!BrotliWarmupBitReader(br)) {
+    return BROTLI_RESULT_NEEDS_MORE_INPUT;
+  }
+  while (symbol < alphabet_size && space > 0) {
+    const HuffmanCode* p = s->table;
+    uint32_t code_len;
+    if (!BrotliCheckInputAmount(br, BROTLI_SHORT_FILL_BIT_WINDOW_READ)) {
+      s->symbol = symbol;
+      s->repeat = repeat;
+      s->prev_code_len = prev_code_len;
+      s->repeat_code_len = repeat_code_len;
+      s->space = space;
+      return BROTLI_RESULT_NEEDS_MORE_INPUT;
+    }
+    BrotliFillBitWindow16(br);
+    p += BrotliGetBitsUnmasked(br) &
+        BitMask(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH);
+    BrotliDropBits(br, p->bits); /* Use 1..5 bits */
+    code_len = p->value; /* code_len == 0..17 */
+    if (code_len < kCodeLengthRepeatCode) {
+      ProcessSingleCodeLength(code_len, &symbol, &repeat, &space,
+          &prev_code_len, symbol_lists, code_length_histo, next_symbol);
+    } else { /* code_len == 16..17, extra_bits == 2..3 */
+      uint32_t repeat_delta =
+          (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(code_len - 14U);
+      BrotliDropBits(br, code_len - 14U);
+      ProcessRepeatedCodeLength(code_len, repeat_delta, alphabet_size,
+          &symbol, &repeat, &space, &prev_code_len, &repeat_code_len,
+          symbol_lists, code_length_histo, next_symbol);
+    }
+  }
+  s->space = space;
+  return BROTLI_RESULT_SUCCESS;
+}
+
+static BrotliResult SafeReadSymbolCodeLengths(
+    uint32_t alphabet_size, BrotliState* s) {
+  BrotliBitReader* br = &s->br;
+  while (s->symbol < alphabet_size && s->space > 0) {
+    const HuffmanCode* p = s->table;
+    uint32_t code_len;
+    uint32_t bits = 0;
+    uint32_t available_bits = BrotliGetAvailableBits(br);
+    if (available_bits != 0) {
+      bits = (uint32_t)BrotliGetBitsUnmasked(br);
+    }
+    p += bits & BitMask(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH);
+    if (p->bits > available_bits) goto pullMoreInput;
+    code_len = p->value; /* code_len == 0..17 */
+    if (code_len < kCodeLengthRepeatCode) {
+      BrotliDropBits(br, p->bits);
+      ProcessSingleCodeLength(code_len, &s->symbol, &s->repeat, &s->space,
+          &s->prev_code_len, s->symbol_lists, s->code_length_histo,
+          s->next_symbol);
+    } else { /* code_len == 16..17, extra_bits == 2..3 */
+      uint32_t extra_bits = code_len - 14U;
+      uint32_t repeat_delta = (bits >> p->bits) & BitMask(extra_bits);
+      if (available_bits < p->bits + extra_bits) goto pullMoreInput;
+      BrotliDropBits(br, p->bits + extra_bits);
+      ProcessRepeatedCodeLength(code_len, repeat_delta, alphabet_size,
+          &s->symbol, &s->repeat, &s->space, &s->prev_code_len,
+          &s->repeat_code_len, s->symbol_lists, s->code_length_histo,
+          s->next_symbol);
+    }
+    continue;
+
+pullMoreInput:
+    if (!BrotliPullByte(br)) {
+      return BROTLI_RESULT_NEEDS_MORE_INPUT;
+    }
+  }
+  return BROTLI_RESULT_SUCCESS;
+}
+
+/* Reads and decodes 15..18 codes using static prefix code.
+   Each code is 2..4 bits long. In total 30..72 bits are used. */
+static BrotliResult ReadCodeLengthCodeLengths(BrotliState* s) {
+  BrotliBitReader* br = &s->br;
+  uint32_t num_codes = s->repeat;
+  unsigned space = s->space;
+  uint32_t i = s->sub_loop_counter;
+  for (; i < CODE_LENGTH_CODES; ++i) {
+    const uint8_t code_len_idx = kCodeLengthCodeOrder[i];
+    uint32_t ix;
+    uint32_t v;
+    if (PREDICT_FALSE(!BrotliSafeGetBits(br, 4, &ix))) {
+      uint32_t available_bits = BrotliGetAvailableBits(br);
+      if (available_bits != 0) {
+        ix = BrotliGetBitsUnmasked(br) & 0xF;
+      } else {
+        ix = 0;
+      }
+      if (kCodeLengthPrefixLength[ix] > available_bits) {
+        s->sub_loop_counter = i;
+        s->repeat = num_codes;
+        s->space = space;
+        s->substate_huffman = BROTLI_STATE_HUFFMAN_COMPLEX;
+        return BROTLI_RESULT_NEEDS_MORE_INPUT;
+      }
+    }
+    v = kCodeLengthPrefixValue[ix];
+    BrotliDropBits(br, kCodeLengthPrefixLength[ix]);
+    s->code_length_code_lengths[code_len_idx] = (uint8_t)v;
+    BROTLI_LOG_ARRAY_INDEX(s->code_length_code_lengths, code_len_idx);
+    if (v != 0) {
+      space = space - (32U >> v);
+      ++num_codes;
+      ++s->code_length_histo[v];
+      if (space - 1U >= 32U) {
+        /* space is 0 or wrapped around */
+        break;
+      }
+    }
+  }
+  if (!(num_codes == 1 || space == 0)) {
+    return BROTLI_FAILURE();
+  }
+  return BROTLI_RESULT_SUCCESS;
+}
+
 /* Decodes the Huffman tables.
    There are 2 scenarios:
     A) Huffman code contains only few symbols (1..4). Those symbols are read
@@ -348,84 +659,71 @@
                                     uint32_t* opt_table_size,
                                     BrotliState* s) {
   BrotliBitReader* br = &s->br;
-  uint32_t i;
   /* Unnecessary masking, but might be good for safety. */
   alphabet_size &= 0x3ff;
   /* State machine */
   switch (s->substate_huffman) {
     case BROTLI_STATE_HUFFMAN_NONE:
-      if (!BrotliCheckInputAmount(br, 32)) {
+      if (!BrotliSafeReadBits(br, 2, &s->sub_loop_counter)) {
         return BROTLI_RESULT_NEEDS_MORE_INPUT;
       }
-      i = BrotliReadBits(br, 2);
+      BROTLI_LOG_UINT(s->sub_loop_counter);
       /* The value is used as follows:
          1 for simple code;
          0 for no skipping, 2 skips 2 code lengths, 3 skips 3 code lengths */
-      BROTLI_LOG_UINT(i);
-      if (i == 1) {
-        /* Read symbols, codes & code lengths directly. */
-        uint32_t max_bits = Log2Floor(alphabet_size - 1);
-        uint32_t num_symbols = BrotliReadBits(br, 2);
-        for (i = 0; i < 4; ++i) {
-          s->symbols_lists_array[i] = 0;
-        }
-        i = 0;
-        /* max_bits == 0..10; symbol == 0..3; 0..40 bits will be read. */
-        do {
-          uint32_t v = BrotliReadBits(br, max_bits);
-          if (v >= alphabet_size) {
-            return BROTLI_FAILURE();
-          }
-          s->symbols_lists_array[i] = (uint16_t)v;
-          BROTLI_LOG_UINT(s->symbols_lists_array[i]);
-        } while (++i <= num_symbols);
-        for (i = 0; i < num_symbols; ++i) {
-          uint32_t k = i + 1;
-          for (; k <= num_symbols; ++k) {
-            if (s->symbols_lists_array[i] == s->symbols_lists_array[k]) {
-              return BROTLI_FAILURE();
-            }
-          }
-        }
-        if (num_symbols == 3) {
-          num_symbols += BrotliReadBits(br, 1);
-        }
-        BROTLI_LOG_UINT(num_symbols);
-        i = BrotliBuildSimpleHuffmanTable(
-            table, HUFFMAN_TABLE_BITS, s->symbols_lists_array, num_symbols);
-        if (opt_table_size) {
-          *opt_table_size = i;
-        }
-        s->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
-        return BROTLI_RESULT_SUCCESS;
-      } else {  /* Decode Huffman-coded code lengths. */
-        int8_t num_codes = 0;
-        unsigned space = 32;
+      if (s->sub_loop_counter != 1) {
+        s->space = 32;
+        s->repeat = 0; /* num_codes */
         memset(&s->code_length_histo[0], 0, sizeof(s->code_length_histo[0]) *
             (BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH + 1));
         memset(&s->code_length_code_lengths[0], 0,
-               sizeof(s->code_length_code_lengths));
-        /* 15..18 codes will be read, 2..4 bits each; 30..72 bits totally. */
-        for (; i < CODE_LENGTH_CODES; ++i) {
-          const uint8_t code_len_idx = kCodeLengthCodeOrder[i];
-          uint8_t ix = (uint8_t)BrotliGetBits(br, 4);
-          uint8_t v = kCodeLengthPrefixValue[ix];
-          BrotliDropBits(br, kCodeLengthPrefixLength[ix]);
-          s->code_length_code_lengths[code_len_idx] = v;
-          BROTLI_LOG_ARRAY_INDEX(s->code_length_code_lengths, code_len_idx);
-          if (v != 0) {
-            space = space - (32U >> v);
-            ++num_codes;
-            ++s->code_length_histo[v];
-            if (space - 1U >= 32U) {
-              /* space is 0 or wrapped around */
-              break;
-            }
-          }
+            sizeof(s->code_length_code_lengths));
+        s->substate_huffman = BROTLI_STATE_HUFFMAN_COMPLEX;
+        goto Complex;
+      }
+      /* No break, transit to the next state. */
+
+    case BROTLI_STATE_HUFFMAN_SIMPLE_SIZE:
+      /* Read symbols, codes & code lengths directly. */
+      if (!BrotliSafeReadBits(br, 2, &s->symbol)) { /* num_symbols */
+        s->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_SIZE;
+        return BROTLI_RESULT_NEEDS_MORE_INPUT;
+      }
+      s->sub_loop_counter = 0;
+      /* No break, transit to the next state. */
+    case BROTLI_STATE_HUFFMAN_SIMPLE_READ: {
+      BrotliResult result = ReadSimpleHuffmanSymbols(alphabet_size, s);
+      if (result != BROTLI_RESULT_SUCCESS) {
+        return result;
+      }
+      /* No break, transit to the next state. */
+    }
+    case BROTLI_STATE_HUFFMAN_SIMPLE_BUILD: {
+      uint32_t table_size;
+      if (s->symbol == 3) {
+        uint32_t bits;
+        if (!BrotliSafeReadBits(br, 1, &bits)) {
+          s->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_BUILD;
+          return BROTLI_RESULT_NEEDS_MORE_INPUT;
         }
-        if (!(num_codes == 1 || space == 0)) {
-          return BROTLI_FAILURE();
-        }
+        s->symbol += bits;
+      }
+      BROTLI_LOG_UINT(s->symbol);
+      table_size = BrotliBuildSimpleHuffmanTable(
+          table, HUFFMAN_TABLE_BITS, s->symbols_lists_array, s->symbol);
+      if (opt_table_size) {
+        *opt_table_size = table_size;
+      }
+      s->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
+      return BROTLI_RESULT_SUCCESS;
+    }
+
+Complex: /* Decode Huffman-coded code lengths. */
+    case BROTLI_STATE_HUFFMAN_COMPLEX: {
+      uint32_t i;
+      BrotliResult result = ReadCodeLengthCodeLengths(s);
+      if (result != BROTLI_RESULT_SUCCESS) {
+        return result;
       }
       BrotliBuildCodeLengthsHuffmanTable(s->table,
                                          s->code_length_code_lengths,
@@ -443,89 +741,25 @@
       s->space = 32768;
       s->substate_huffman = BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS;
       /* No break, transit to the next state. */
+    }
     case BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS: {
-      uint32_t symbol = s->symbol;
-      uint32_t repeat = s->repeat;
-      uint32_t space = s->space;
-      uint8_t prev_code_len = s->prev_code_len;
-      uint8_t repeat_code_len = s->repeat_code_len;
-      uint16_t* symbol_lists = s->symbol_lists;
-      uint16_t* code_length_histo = s->code_length_histo;
-      int* next_symbol = s->next_symbol;
-      while (symbol < alphabet_size && space > 0) {
-        const HuffmanCode* p = s->table;
-        uint8_t code_len;
-        if (!BrotliCheckInputAmount(br, 8)) {
-          s->symbol = symbol;
-          s->repeat = repeat;
-          s->prev_code_len = prev_code_len;
-          s->repeat_code_len = repeat_code_len;
-          s->space = space;
-          return BROTLI_RESULT_NEEDS_MORE_INPUT;
-        }
-        p += BrotliGetBits(br, BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH);
-        BrotliDropBits(br, p->bits); /* Use 1..5 bits */
-        code_len = (uint8_t)p->value; /* code_len == 0..17 */
-        if (code_len < kCodeLengthRepeatCode) {
-          repeat = 0;
-          if (code_len != 0) { /* code_len == 1..15 */
-            symbol_lists[next_symbol[code_len]] = (uint16_t)symbol;
-            next_symbol[code_len] = (int)symbol;
-            prev_code_len = code_len;
-            space -= 32768U >> code_len;
-            code_length_histo[code_len]++;
-          }
-          symbol++;
-        } else { /* code_len == 16..17, extra_bits == 2..3 */
-          uint32_t repeat_delta = BrotliReadBits(br, code_len - 14U);
-          uint32_t old_repeat;
-          uint8_t new_len = 0;
-          if (code_len == kCodeLengthRepeatCode) {
-            new_len = prev_code_len;
-          }
-          if (repeat_code_len != new_len) {
-            repeat = 0;
-            repeat_code_len = new_len;
-          }
-          old_repeat = repeat;
-          if (repeat > 0) {
-            repeat -= 2;
-            repeat <<= code_len - 14;
-          }
-          repeat += repeat_delta + 3;
-          repeat_delta = repeat - old_repeat; /* repeat_delta >= 3 */
-          /* So, for extra 2..3 bits we produce more than 2 symbols.
-             Consequently, at most 5 bits per symbol are used. */
-          if (symbol + repeat_delta > alphabet_size) {
-            return BROTLI_FAILURE();
-          }
-          if (repeat_code_len != 0) {
-            unsigned last = symbol + repeat_delta;
-            int next = next_symbol[repeat_code_len];
-            do {
-              symbol_lists[next] = (uint16_t)symbol;
-              next = (int)symbol;
-            } while (++symbol != last);
-            next_symbol[repeat_code_len] = next;
-            space -= repeat_delta << (15 - repeat_code_len);
-            code_length_histo[repeat_code_len] = (uint16_t)
-                (code_length_histo[repeat_code_len] + repeat_delta);
-          } else {
-            symbol += repeat_delta;
-          }
-        }
+      uint32_t table_size;
+      BrotliResult result = ReadSymbolCodeLengths(alphabet_size, s);
+      if (result == BROTLI_RESULT_NEEDS_MORE_INPUT) {
+        result = SafeReadSymbolCodeLengths(alphabet_size, s);
       }
-      if (space != 0) {
-        BROTLI_LOG(("[ReadHuffmanCode] space = %d\n", space));
+      if (result != BROTLI_RESULT_SUCCESS) {
+        return result;
+      }
+
+      if (s->space != 0) {
+        BROTLI_LOG(("[ReadHuffmanCode] space = %d\n", s->space));
         return BROTLI_FAILURE();
       }
-      {
-        uint32_t table_size = BrotliBuildHuffmanTable(
-            table, HUFFMAN_TABLE_BITS, symbol_lists,
-            s->code_length_histo);
-        if (opt_table_size) {
-          *opt_table_size = table_size;
-        }
+      table_size = BrotliBuildHuffmanTable(table, HUFFMAN_TABLE_BITS,
+          s->symbol_lists, s->code_length_histo);
+      if (opt_table_size) {
+        *opt_table_size = table_size;
       }
       s->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
       return BROTLI_RESULT_SUCCESS;
@@ -537,13 +771,41 @@
 }
 
 /* Decodes a block length by reading 3..39 bits. */
-static BROTLI_INLINE int ReadBlockLength(const HuffmanCode* table,
-                                         BrotliBitReader* br) {
+static BROTLI_INLINE uint32_t ReadBlockLength(const HuffmanCode* table,
+                                              BrotliBitReader* br) {
   uint32_t code;
   uint32_t nbits;
   code = ReadSymbol(table, br);
   nbits = kBlockLengthPrefixCode[code].nbits; /* nbits == 2..24 */
-  return kBlockLengthPrefixCode[code].offset + (int)BrotliReadBits(br, nbits);
+  return kBlockLengthPrefixCode[code].offset + BrotliReadBits(br, nbits);
+}
+
+/* WARNING: if state is not BROTLI_STATE_READ_BLOCK_LENGTH_NONE, then
+   reading can't be continued with ReadBlockLength. */
+static BROTLI_INLINE int SafeReadBlockLength(BrotliState* s,
+                                             uint32_t* result,
+                                             const HuffmanCode* table,
+                                             BrotliBitReader* br) {
+  uint32_t index;
+  if (s->substate_read_block_length == BROTLI_STATE_READ_BLOCK_LENGTH_NONE) {
+    if (!SafeReadSymbol(table, br, &index)) {
+      return 0;
+    }
+  } else {
+    index = s->block_length_index;
+  }
+  {
+    uint32_t bits;
+    uint32_t nbits = kBlockLengthPrefixCode[index].nbits; /* nbits == 2..24 */
+    if (!BrotliSafeReadBits(br, nbits, &bits)) {
+      s->block_length_index = index;
+      s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_SUFFIX;
+      return 0;
+    }
+    *result = kBlockLengthPrefixCode[index].offset + bits;
+    s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_NONE;
+    return 1;
+  }
 }
 
 /* Transform:
@@ -597,12 +859,6 @@
   state->mtf_upper_bound = upper_bound;
 }
 
-/* Expose function for testing. Will be removed by linker as unused. */
-void InverseMoveToFrontTransformForTesting(
-    uint8_t* v, uint32_t l, BrotliState* s) {
-  InverseMoveToFrontTransform(v, l, s);
-}
-
 
 /* Decodes a series of Huffman table using ReadHuffmanCode function. */
 static BrotliResult HuffmanTreeGroupDecode(HuffmanTreeGroup* group,
@@ -640,7 +896,6 @@
                                      BrotliState* s) {
   BrotliBitReader* br = &s->br;
   BrotliResult result = BROTLI_RESULT_SUCCESS;
-  int use_rle_for_zeros;
 
   switch((int)s->substate_context_map) {
     case BROTLI_STATE_CONTEXT_MAP_NONE:
@@ -662,41 +917,65 @@
       }
       s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_READ_PREFIX;
       /* No break, continue to next state. */
-    case BROTLI_STATE_CONTEXT_MAP_READ_PREFIX:
-      if (!BrotliWarmupBitReader(br) || !BrotliCheckInputAmount(br, 8)) {
+    case BROTLI_STATE_CONTEXT_MAP_READ_PREFIX: {
+      uint32_t bits;
+      /* In next stage ReadHuffmanCode uses at least 4 bits, so it is safe
+         to peek 4 bits ahead. */
+      if (!BrotliSafeGetBits(br, 5, &bits)) {
         return BROTLI_RESULT_NEEDS_MORE_INPUT;
       }
-      use_rle_for_zeros = (int)BrotliReadBits(br, 1);
-      if (use_rle_for_zeros) {
-        s->max_run_length_prefix = BrotliReadBits(br, 4) + 1;
+      if ((bits & 1) != 0) { /* Use RLE for zeroes. */
+        s->max_run_length_prefix = (bits >> 1) + 1;
+        BrotliDropBits(br, 5);
       } else {
         s->max_run_length_prefix = 0;
+        BrotliDropBits(br, 1);
       }
       BROTLI_LOG_UINT(s->max_run_length_prefix);
       s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_HUFFMAN;
       /* No break, continue to next state. */
+    }
     case BROTLI_STATE_CONTEXT_MAP_HUFFMAN:
       result = ReadHuffmanCode(*num_htrees + s->max_run_length_prefix,
                                s->context_map_table, NULL, s);
       if (result != BROTLI_RESULT_SUCCESS) return result;
+      s->code = 0xFFFF;
       s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_DECODE;
       /* No break, continue to next state. */
     case BROTLI_STATE_CONTEXT_MAP_DECODE: {
       uint32_t context_index = s->context_index;
       uint32_t max_run_length_prefix = s->max_run_length_prefix;
       uint8_t* context_map = *context_map_arg;
-      uint32_t code;
+      uint32_t code = s->code;
+      if (code != 0xFFFF) {
+        goto rleCode;
+      }
       while (context_index < context_map_size) {
-        if (!BrotliCheckInputAmount(br, 32)) {
+        if (!SafeReadSymbol(s->context_map_table, br, &code)) {
+          s->code = 0xFFFF;
           s->context_index = context_index;
           return BROTLI_RESULT_NEEDS_MORE_INPUT;
         }
-        code = ReadSymbol(s->context_map_table, br);
         BROTLI_LOG_UINT(code);
+
         if (code == 0) {
           context_map[context_index++] = 0;
-        } else if (code <= max_run_length_prefix) {
-          uint32_t reps = (1U << code) + BrotliReadBits(br, code);
+          continue;
+        }
+        if (code > max_run_length_prefix) {
+          context_map[context_index++] =
+              (uint8_t)(code - max_run_length_prefix);
+          continue;
+        }
+rleCode:
+        {
+          uint32_t reps;
+          if (!BrotliSafeReadBits(br, code, &reps)) {
+            s->code = code;
+            s->context_index = context_index;
+            return BROTLI_RESULT_NEEDS_MORE_INPUT;
+          }
+          reps += 1U << code;
           BROTLI_LOG_UINT(reps);
           if (context_index + reps > context_map_size) {
             return BROTLI_FAILURE();
@@ -704,13 +983,18 @@
           do {
             context_map[context_index++] = 0;
           } while (--reps);
-        } else {
-          context_map[context_index++] =
-              (uint8_t)(code - max_run_length_prefix);
         }
       }
-      if (BrotliReadBits(br, 1)) {
-        InverseMoveToFrontTransform(context_map, context_map_size, s);
+      /* No break, continue to next state. */
+    }
+    case BROTLI_STATE_CONTEXT_MAP_TRANSFORM: {
+      uint32_t bits;
+      if (!BrotliSafeReadBits(br, 1, &bits)) {
+        s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_TRANSFORM;
+        return BROTLI_RESULT_NEEDS_MORE_INPUT;
+      }
+      if (bits != 0) {
+        InverseMoveToFrontTransform(*context_map_arg, context_map_size, s);
       }
       s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_NONE;
       return BROTLI_RESULT_SUCCESS;
@@ -721,15 +1005,32 @@
 }
 
 /* Decodes a command or literal and updates block type ringbuffer.
-   Reads 0..15 bits. */
-static void DecodeBlockType(const uint32_t max_block_type,
-                            const HuffmanCode* trees,
-                            int tree_type,
-                            uint32_t* ringbuffers,
-                            BrotliBitReader* br) {
-  uint32_t* ringbuffer = ringbuffers + tree_type * 2;
-  uint32_t block_type = ReadSymbol(
-      &trees[tree_type * BROTLI_HUFFMAN_MAX_TABLE_SIZE], br);
+   Reads 3..54 bits. */
+static int BROTLI_INLINE DecodeBlockTypeAndLength(int safe,
+    BrotliState* s, int tree_type) {
+  uint32_t max_block_type = s->num_block_types[tree_type];
+  int tree_offset = tree_type * BROTLI_HUFFMAN_MAX_TABLE_SIZE;
+  const HuffmanCode* type_tree = &s->block_type_trees[tree_offset];
+  const HuffmanCode* len_tree = &s->block_len_trees[tree_offset];
+  BrotliBitReader* br = &s->br;
+  uint32_t* ringbuffer = &s->block_type_rb[tree_type * 2];
+  uint32_t block_type;
+
+  /* Read 0..15 + 3..39 bits */
+  if (!safe) {
+    block_type = ReadSymbol(type_tree, br);
+    s->block_length[tree_type] = ReadBlockLength(len_tree, br);
+  } else {
+    BrotliBitReaderState memento;
+    BrotliBitReaderSaveState(br, &memento);
+    if (!SafeReadSymbol(type_tree, br, &block_type)) return 0;
+    if (!SafeReadBlockLength(s, &s->block_length[tree_type], len_tree, br)) {
+      s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_NONE;
+      BrotliBitReaderRestoreState(br, &memento);
+      return 0;
+    }
+  }
+
   if (block_type == 1) {
     block_type = ringbuffer[1] + 1;
   } else if (block_type == 0) {
@@ -742,17 +1043,18 @@
   }
   ringbuffer[0] = ringbuffer[1];
   ringbuffer[1] = block_type;
+  return 1;
 }
 
 /* Decodes the block type and updates the state for literal context.
-   Reads 18..54 bits. */
-static void DecodeBlockTypeWithContext(BrotliState* s,
-                                       BrotliBitReader* br) {
+   Reads 3..54 bits. */
+static int BROTLI_INLINE DecodeLiteralBlockSwitchInternal(int safe,
+    BrotliState* s) {
   uint8_t context_mode;
   uint32_t context_offset;
-  DecodeBlockType(s->num_block_types[0], s->block_type_trees, 0,
-                  s->block_type_rb, br); /* Reads 0..15 bits. */
-  s->block_length[0] = ReadBlockLength(s->block_len_trees, br); /* 3..39 bits */
+  if (!DecodeBlockTypeAndLength(safe, s, 0)) {
+    return 0;
+  }
   context_offset = s->block_type_rb[1] << kLiteralContextBits;
   s->context_map_slice = s->context_map + context_offset;
   s->literal_htree_index = s->context_map_slice[0];
@@ -760,115 +1062,125 @@
   context_mode = s->context_modes[s->block_type_rb[1]];
   s->context_lookup1 = &kContextLookup[kContextLookupOffsets[context_mode]];
   s->context_lookup2 = &kContextLookup[kContextLookupOffsets[context_mode + 1]];
+  return 1;
 }
 
-BrotliResult WriteRingBuffer(BrotliOutput output,
-                             BrotliState* s) {
-  int num_written;
+static void BROTLI_NOINLINE DecodeLiteralBlockSwitch(BrotliState* s) {
+  DecodeLiteralBlockSwitchInternal(0, s);
+}
+
+static int BROTLI_NOINLINE SafeDecodeLiteralBlockSwitch(BrotliState* s) {
+  return DecodeLiteralBlockSwitchInternal(1, s);
+}
+
+/* Block switch for insert/copy length.
+   Reads 3..54 bits. */
+static int BROTLI_INLINE DecodeCommandBlockSwitchInternal(int safe,
+    BrotliState* s) {
+  if (!DecodeBlockTypeAndLength(safe, s, 1)) {
+    return 0;
+  }
+  s->htree_command = s->insert_copy_hgroup.htrees[s->block_type_rb[3]];
+  return 1;
+}
+
+static void BROTLI_NOINLINE DecodeCommandBlockSwitch(BrotliState* s) {
+  DecodeCommandBlockSwitchInternal(0, s);
+}
+static int BROTLI_NOINLINE SafeDecodeCommandBlockSwitch(BrotliState* s) {
+  return DecodeCommandBlockSwitchInternal(1, s);
+}
+
+/* Block switch for distance codes.
+   Reads 3..54 bits. */
+static int BROTLI_INLINE DecodeDistanceBlockSwitchInternal(int safe,
+    BrotliState* s) {
+  if (!DecodeBlockTypeAndLength(safe, s, 2)) {
+    return 0;
+  }
+  s->dist_context_map_slice =
+      s->dist_context_map + (s->block_type_rb[5] << kDistanceContextBits);
+  s->dist_htree_index = s->dist_context_map_slice[s->distance_context];
+  return 1;
+}
+
+static void BROTLI_NOINLINE DecodeDistanceBlockSwitch(BrotliState* s) {
+  DecodeDistanceBlockSwitchInternal(0, s);
+}
+
+static int BROTLI_NOINLINE SafeDecodeDistanceBlockSwitch(BrotliState* s) {
+  return DecodeDistanceBlockSwitchInternal(1, s);
+}
+
+static BrotliResult WriteRingBuffer(size_t* available_out, uint8_t** next_out,
+    size_t* total_out, BrotliState* s) {
+  size_t pos = (s->pos > s->ringbuffer_size) ?
+      (size_t)s->ringbuffer_size : (size_t)(s->pos);
+  uint8_t* start = s->ringbuffer
+      + (s->partial_pos_out & (size_t)s->ringbuffer_mask);
+  size_t partial_pos_rb =
+      (s->rb_roundtrips * (size_t)s->ringbuffer_size) + pos;
+  size_t to_write = (partial_pos_rb - s->partial_pos_out);
+  size_t num_written = *available_out;
+  if (num_written > to_write) {
+    num_written = to_write;
+  }
   if (s->meta_block_remaining_len < 0) {
     return BROTLI_FAILURE();
   }
-  num_written = BrotliWrite(
-      output, s->ringbuffer + s->partially_written,
-      (size_t)(s->to_write - s->partially_written));
-  BROTLI_LOG_UINT(s->partially_written);
-  BROTLI_LOG_UINT(s->to_write);
+  memcpy(*next_out, start, num_written);
+  *next_out += num_written;
+  *available_out -= num_written;
+  BROTLI_LOG_UINT(to_write);
   BROTLI_LOG_UINT(num_written);
-  if (num_written < 0) {
-    return BROTLI_FAILURE();
-  }
-  s->partially_written += num_written;
-  if (s->partially_written < s->to_write) {
+  s->partial_pos_out += (size_t)num_written;
+  *total_out = s->partial_pos_out;
+  if (num_written < to_write) {
     return BROTLI_RESULT_NEEDS_MORE_OUTPUT;
   }
   return BROTLI_RESULT_SUCCESS;
 }
 
-BrotliResult BROTLI_NOINLINE CopyUncompressedBlockToOutput(BrotliOutput output,
-                                                           int pos,
-                                                           BrotliState* s) {
-  BrotliResult result;
-  int num_read;
-  int nbytes;
+static BrotliResult BROTLI_NOINLINE CopyUncompressedBlockToOutput(
+    size_t* available_out, uint8_t** next_out, size_t* total_out,
+    BrotliState* s) {
   /* State machine */
   for (;;) {
-    switch ((int)s->substate_uncompressed) {
-      case BROTLI_STATE_UNCOMPRESSED_NONE:
-        nbytes = (int)BrotliGetRemainingBytes(&s->br);
-        /* For short lengths copy byte-by-byte */
-        if (s->meta_block_remaining_len < 8 ||
-            s->meta_block_remaining_len < nbytes) {
-          s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_SHORT;
-          break;
+    switch (s->substate_uncompressed) {
+      case BROTLI_STATE_UNCOMPRESSED_NONE: {
+        int nbytes = (int)BrotliGetRemainingBytes(&s->br);
+        if (nbytes > s->meta_block_remaining_len) {
+          nbytes = s->meta_block_remaining_len;
+        }
+        if (s->pos + nbytes > s->ringbuffer_size) {
+          nbytes = s->ringbuffer_size - s->pos;
         }
         /* Copy remaining bytes from s->br.buf_ to ringbuffer. */
-        BrotliCopyBytes(&s->ringbuffer[pos], &s->br, (size_t)nbytes);
-        pos += nbytes;
+        BrotliCopyBytes(&s->ringbuffer[s->pos], &s->br, (size_t)nbytes);
+        s->pos += nbytes;
         s->meta_block_remaining_len -= nbytes;
-        if (pos >= s->ringbuffer_size) {
-          s->to_write = s->ringbuffer_size;
-          s->partially_written = 0;
-          s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_WRITE;
-          break;
-        }
-        s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_COPY;
-        break;
-      case BROTLI_STATE_UNCOMPRESSED_SHORT:
-        if (!BrotliWarmupBitReader(&s->br)) {
+        if (s->pos < s->ringbuffer_size) {
+          if (s->meta_block_remaining_len == 0) {
+            return BROTLI_RESULT_SUCCESS;
+          }
           return BROTLI_RESULT_NEEDS_MORE_INPUT;
         }
-        while (s->meta_block_remaining_len > 0) {
-          if (!BrotliCheckInputAmount(&s->br, 8)) {
-            return BROTLI_RESULT_NEEDS_MORE_INPUT;
-          }
-          s->ringbuffer[pos++] = (uint8_t)BrotliReadBits(&s->br, 8);
-          s->meta_block_remaining_len--;
-        }
-        if (pos >= s->ringbuffer_size) {
-          s->to_write = s->ringbuffer_size;
-          s->partially_written = 0;
-          s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_WRITE;
-        } else {
-          s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_NONE;
-          return BROTLI_RESULT_SUCCESS;
-        }
-        /* No break, if state is updated, continue to next state */
-      case BROTLI_STATE_UNCOMPRESSED_WRITE:
-        result = WriteRingBuffer(output, s);
+        s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_WRITE;
+        /*s->partial_pos_rb += (size_t)s->ringbuffer_size;*/
+        /* No break, continue to next state */
+      }
+      case BROTLI_STATE_UNCOMPRESSED_WRITE: {
+        BrotliResult result = WriteRingBuffer(
+            available_out, next_out, total_out, s);
         if (result != BROTLI_RESULT_SUCCESS) {
           return result;
         }
-        pos &= s->ringbuffer_mask;
+        s->pos = 0;
+        s->rb_roundtrips++;
         s->max_distance = s->max_backward_distance;
-        /* If we wrote past the logical end of the ringbuffer, copy the tail
-           of the ringbuffer to its beginning and flush the ringbuffer to the
-           output. */
-        memcpy(s->ringbuffer, s->ringbuffer_end, (size_t)pos);
-        s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_COPY;
-        /* No break, continue to next state */
-      case BROTLI_STATE_UNCOMPRESSED_COPY:
-        /* Copy straight from the input onto the ringbuffer. The ringbuffer will
-           be flushed to the output at a later time. */
-        nbytes = s->meta_block_remaining_len;
-        if (pos + nbytes > s->ringbuffer_size) {
-          nbytes = s->ringbuffer_size - pos;
-        }
-        num_read = BrotliRead(s->br.input_, &s->ringbuffer[pos],
-                              (size_t)nbytes);
-        pos += num_read;
-        s->meta_block_remaining_len -= num_read;
-        if (num_read < nbytes) {
-          if (num_read < 0) return BROTLI_FAILURE();
-          return BROTLI_RESULT_NEEDS_MORE_INPUT;
-        }
-        if (pos == s->ringbuffer_size) {
-          s->to_write = s->ringbuffer_size;
-          s->partially_written = 0;
-          s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_WRITE;
-          break;
-        }
         s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_NONE;
-        return BROTLI_RESULT_SUCCESS;
+        break;
+      }
     }
   }
   return BROTLI_FAILURE();
@@ -877,36 +1189,27 @@
 int BrotliDecompressedSize(size_t encoded_size,
                            const uint8_t* encoded_buffer,
                            size_t* decoded_size) {
-  BrotliMemInput memin;
-  BrotliInput in = BrotliInitMemInput(encoded_buffer, encoded_size, &memin);
-  BrotliBitReader br;
   BrotliState s;
   int next_block_header;
-  size_t offset;
   BrotliStateInit(&s);
-  BrotliInitBitReader(&br, in);
-  if (!BrotliReadInput(&br, 1) || !BrotliWarmupBitReader(&br)) {
+  s.br.next_in = encoded_buffer;
+  s.br.avail_in = encoded_size;
+  if (!BrotliWarmupBitReader(&s.br)) {
     return 0;
   }
-  DecodeWindowBits(&br);
-  if (DecodeMetaBlockLength(&s, &br) != BROTLI_RESULT_SUCCESS) {
+  DecodeWindowBits(&s.br);
+  if (DecodeMetaBlockLength(&s, &s.br) != BROTLI_RESULT_SUCCESS) {
     return 0;
   }
   *decoded_size = (size_t)s.meta_block_remaining_len;
   if (s.is_last_metablock) {
     return 1;
   }
-  if (!s.is_uncompressed || !BrotliJumpToByteBoundary(&br)) {
+  if (!s.is_uncompressed || !BrotliJumpToByteBoundary(&s.br)) {
     return 0;
   }
-  next_block_header = BrotliPeekByte(&br, (size_t)s.meta_block_remaining_len);
-  if (next_block_header != -1) {
-    return (next_block_header & 3) == 3;
-  }
-  /* Currently bit reader can't peek outside of its buffer... */
-  offset = BROTLI_READ_SIZE - BrotliGetRemainingBytes(&br);
-  offset += (size_t)s.meta_block_remaining_len;
-  return (offset < encoded_size) && ((encoded_buffer[offset] & 3) == 3);
+  next_block_header = BrotliPeekByte(&s.br, (size_t)s.meta_block_remaining_len);
+  return (next_block_header != -1) && ((next_block_header & 3) == 3);
 }
 
 /* Allocates the smallest feasible ring buffer.
@@ -918,9 +1221,12 @@
    processed. When this method is called, metablock size and flags MUST be
    decoded.
 */
-int BROTLI_NOINLINE BrotliAllocateRingBuffer(BrotliState* s,
+static int BROTLI_NOINLINE BrotliAllocateRingBuffer(BrotliState* s,
     BrotliBitReader* br) {
-  static const int kRingBufferWriteAheadSlack = BROTLI_READ_SIZE;
+  /* We need the slack region for the following reasons:
+      - doing up to two 16-byte copies for fast backward copying
+      - inserting transformed dictionary word (5 prefix + 24 base + 8 suffix) */
+  static const int kRingBufferWriteAheadSlack = 42;
   int is_last = s->is_last_metablock;
   s->ringbuffer_size = 1 << s->window_bits;
 
@@ -950,8 +1256,7 @@
 
   s->ringbuffer_mask = s->ringbuffer_size - 1;
   s->ringbuffer = (uint8_t*)malloc((size_t)(s->ringbuffer_size +
-                                         kRingBufferWriteAheadSlack +
-                                         kBrotliMaxDictionaryWordLength));
+      kRingBufferWriteAheadSlack + kBrotliMaxDictionaryWordLength));
   if (s->ringbuffer == 0) {
     return 0;
   }
@@ -966,17 +1271,527 @@
   return 1;
 }
 
+/* Reads 1..256 2-bit context modes. */
+static BrotliResult ReadContextModes(BrotliState* s) {
+  BrotliBitReader* br = &s->br;
+  int i = s->loop_counter;
+
+  while (i < (int)s->num_block_types[0]) {
+    uint32_t bits;
+    if (!BrotliSafeReadBits(br, 2, &bits)) {
+      s->loop_counter = i;
+      return BROTLI_RESULT_NEEDS_MORE_INPUT;
+    }
+    s->context_modes[i] = (uint8_t)(bits << 1);
+    BROTLI_LOG_ARRAY_INDEX(s->context_modes, i);
+    i++;
+  }
+  return BROTLI_RESULT_SUCCESS;
+}
+
+static void BROTLI_INLINE TakeDistanceFromRingBuffer(BrotliState* s) {
+  if (s->distance_code == 0) {
+    --s->dist_rb_idx;
+    s->distance_code = s->dist_rb[s->dist_rb_idx & 3];
+  } else {
+    int distance_code = s->distance_code << 1;
+    /* kDistanceShortCodeIndexOffset has 2-bit values from LSB: */
+    /* 3, 2, 1, 0, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 */
+    const uint32_t kDistanceShortCodeIndexOffset = 0xaaafff1b;
+    /* kDistanceShortCodeValueOffset has 2-bit values from LSB: */
+    /*-0, 0,-0, 0,-1, 1,-2, 2,-3, 3,-1, 1,-2, 2,-3, 3 */
+    const uint32_t kDistanceShortCodeValueOffset = 0xfa5fa500;
+    int v = (s->dist_rb_idx +
+        (int)(kDistanceShortCodeIndexOffset >> distance_code)) & 0x3;
+    s->distance_code = s->dist_rb[v];
+    v = (int)(kDistanceShortCodeValueOffset >> distance_code) & 0x3;
+    if ((distance_code & 0x3) != 0) {
+      s->distance_code += v;
+    } else {
+      s->distance_code -= v;
+      if (s->distance_code <= 0) {
+        /* A huge distance will cause a BROTLI_FAILURE() soon. */
+        /* This is a little faster than failing here. */
+        s->distance_code = 0x0fffffff;
+      }
+    }
+  }
+}
+
+static BROTLI_INLINE int SafeReadBits(
+    BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
+  if (n_bits != 0) {
+    return BrotliSafeReadBits(br, n_bits, val);
+  } else {
+    *val = 0;
+    return 1;
+  }
+}
+
+/* Precondition: s->distance_code < 0 */
+static int BROTLI_INLINE ReadDistanceInternal(int safe,
+    BrotliState* s, BrotliBitReader* br) {
+  int distval;
+  BrotliBitReaderState memento;
+  HuffmanCode* distance_tree = s->distance_hgroup.htrees[s->dist_htree_index];
+  if (!safe) {
+    s->distance_code = (int)ReadSymbol(distance_tree, br);
+  } else {
+    uint32_t code;
+    BrotliBitReaderSaveState(br, &memento);
+    if (!SafeReadSymbol(distance_tree, br, &code)) {
+      return 0;
+    }
+    s->distance_code = (int)code;
+  }
+  /* Convert the distance code to the actual distance by possibly */
+  /* looking up past distances from the s->ringbuffer. */
+  if ((s->distance_code & ~0xf) == 0) {
+    TakeDistanceFromRingBuffer(s);
+    --s->block_length[2];
+    return 1;
+  }
+  distval = s->distance_code - (int)s->num_direct_distance_codes;
+  if (distval >= 0) {
+    uint32_t nbits;
+    int postfix;
+    int offset;
+    if (!safe && (s->distance_postfix_bits == 0)) {
+      nbits = ((uint32_t)distval >> 1) + 1;
+      offset = ((2 + (distval & 1)) << nbits) - 4;
+      s->distance_code = (int)s->num_direct_distance_codes +
+          offset + (int)BrotliReadBits(br, nbits);
+    } else {
+      /* This branch also works well when s->distance_postfix_bits == 0 */
+      uint32_t bits;
+      postfix = distval & s->distance_postfix_mask;
+      distval >>= s->distance_postfix_bits;
+      nbits = ((uint32_t)distval >> 1) + 1;
+      if (safe) {
+        if (!SafeReadBits(br, nbits, &bits)) {
+          s->distance_code = -1; /* Restore precondition. */
+          BrotliBitReaderRestoreState(br, &memento);
+          return 0;
+        }
+      } else {
+        bits = BrotliReadBits(br, nbits);
+      }
+      offset = ((2 + (distval & 1)) << nbits) - 4;
+      s->distance_code = (int)s->num_direct_distance_codes +
+          ((offset + (int)bits) << s->distance_postfix_bits) + postfix;
+    }
+  }
+  s->distance_code = s->distance_code - NUM_DISTANCE_SHORT_CODES + 1;
+  --s->block_length[2];
+  return 1;
+}
+
+static void BROTLI_INLINE ReadDistance(BrotliState* s, BrotliBitReader* br) {
+  ReadDistanceInternal(0, s, br);
+}
+
+static int BROTLI_INLINE SafeReadDistance(BrotliState* s, BrotliBitReader* br) {
+  return ReadDistanceInternal(1, s, br);
+}
+
+static int BROTLI_INLINE ReadCommandInternal(int safe,
+    BrotliState* s, BrotliBitReader* br, int* insert_length) {
+  uint32_t cmd_code;
+  uint32_t insert_len_extra = 0;
+  uint32_t copy_length;
+  CmdLutElement v;
+  BrotliBitReaderState memento;
+  if (!safe) {
+    cmd_code = ReadSymbol(s->htree_command, br);
+  } else {
+    BrotliBitReaderSaveState(br, &memento);
+    if (!SafeReadSymbol(s->htree_command, br, &cmd_code)) {
+      return 0;
+    }
+  }
+  v = kCmdLut[cmd_code];
+  s->distance_code = v.distance_code;
+  s->distance_context = v.context;
+  s->dist_htree_index = s->dist_context_map_slice[s->distance_context];
+  *insert_length = v.insert_len_offset;
+  if (!safe) {
+    if (PREDICT_FALSE(v.insert_len_extra_bits != 0)) {
+      insert_len_extra = BrotliReadBits(br, v.insert_len_extra_bits);
+    }
+    copy_length = BrotliReadBits(br, v.copy_len_extra_bits);
+  } else {
+    if (!SafeReadBits(br, v.insert_len_extra_bits, &insert_len_extra) ||
+        !SafeReadBits(br, v.copy_len_extra_bits, &copy_length)) {
+      BrotliBitReaderRestoreState(br, &memento);
+      return 0;
+    }
+  }
+  s->copy_length = (int)copy_length + v.copy_len_offset;
+  --s->block_length[1];
+  *insert_length += (int)insert_len_extra;
+  return 1;
+}
+
+static void BROTLI_INLINE ReadCommand(BrotliState* s, BrotliBitReader* br,
+    int* insert_length) {
+  ReadCommandInternal(0, s, br, insert_length);
+}
+
+static int BROTLI_INLINE SafeReadCommand(BrotliState* s, BrotliBitReader* br,
+    int* insert_length) {
+  return ReadCommandInternal(1, s, br, insert_length);
+}
+
+static BROTLI_INLINE int WarmupBitReader(int safe, BrotliBitReader* const br) {
+  if (safe) {
+    return 1;
+  }
+  return BrotliWarmupBitReader(br);
+}
+
+static BROTLI_INLINE int CheckInputAmount(int safe,
+    BrotliBitReader* const br, size_t num) {
+  if (safe) {
+    return 1;
+  }
+  return BrotliCheckInputAmount(br, num);
+}
+
+#define BROTLI_SAFE(METHOD) { \
+  if (safe) { \
+    if (! Safe ## METHOD ) { \
+      result = BROTLI_RESULT_NEEDS_MORE_INPUT; \
+      goto saveStateAndReturn; \
+    } \
+  } else { \
+    METHOD ; \
+  } \
+}
+
+static BROTLI_INLINE BrotliResult ProcessCommandsInternal(int safe,
+    BrotliState* s) {
+  int pos = s->pos;
+  int i = s->loop_counter;
+  BrotliResult result = BROTLI_RESULT_SUCCESS;
+  BrotliBitReader* br = &s->br;
+
+  if (!CheckInputAmount(safe, br, 28) || !WarmupBitReader(safe, br)) {
+    result = BROTLI_RESULT_NEEDS_MORE_INPUT;
+    goto saveStateAndReturn;
+  }
+
+  /* Jump into state machine. */
+  if (s->state == BROTLI_STATE_COMMAND_BEGIN) {
+    goto CommandBegin;
+  } else if (s->state == BROTLI_STATE_COMMAND_INNER) {
+    goto CommandInner;
+  } else if (s->state == BROTLI_STATE_COMMAND_POST_DECODE_LITERALS) {
+    goto CommandPostDecodeLiterals;
+  } else if (s->state == BROTLI_STATE_COMMAND_POST_WRAP_COPY) {
+    goto CommandPostWrapCopy;
+  } else {
+    return BROTLI_FAILURE();
+  }
+
+CommandBegin:
+  if (safe) {
+    s->state = BROTLI_STATE_COMMAND_BEGIN;
+  }
+  if (!CheckInputAmount(safe, br, 28)) { /* 156 bits + 7 bytes */
+    s->state = BROTLI_STATE_COMMAND_BEGIN;
+    result = BROTLI_RESULT_NEEDS_MORE_INPUT;
+    goto saveStateAndReturn;
+  }
+  if (PREDICT_FALSE(s->block_length[1] == 0)) {
+    BROTLI_SAFE(DecodeCommandBlockSwitch(s));
+    goto CommandBegin;
+  }
+  /* Read the insert/copy length in the command */
+  BROTLI_SAFE(ReadCommand(s, br, &i));
+  BROTLI_LOG_UINT(i);
+  BROTLI_LOG_UINT(s->copy_length);
+  BROTLI_LOG_UINT(s->distance_code);
+  if (i == 0) {
+    goto CommandPostDecodeLiterals;
+  }
+  s->meta_block_remaining_len -= i;
+
+CommandInner:
+  if (safe) {
+    s->state = BROTLI_STATE_COMMAND_INNER;
+  }
+  /* Read the literals in the command */
+  if (s->trivial_literal_context) {
+    uint32_t bits;
+    uint32_t value;
+    PreloadSymbol(safe, s->literal_htree, br, &bits, &value);
+    do {
+      if (!CheckInputAmount(safe, br, 28)) { /* 162 bits + 7 bytes */
+        s->state = BROTLI_STATE_COMMAND_INNER;
+        result = BROTLI_RESULT_NEEDS_MORE_INPUT;
+        goto saveStateAndReturn;
+      }
+      if (PREDICT_FALSE(s->block_length[0] == 0)) {
+        BROTLI_SAFE(DecodeLiteralBlockSwitch(s));
+        PreloadSymbol(safe, s->literal_htree, br, &bits, &value);
+      }
+      if (!safe) {
+        s->ringbuffer[pos] = (uint8_t)ReadPreloadedSymbol(
+            s->literal_htree, br, &bits, &value);
+      } else {
+        uint32_t literal;
+        if (!SafeReadSymbol(s->literal_htree, br, &literal)) {
+          result = BROTLI_RESULT_NEEDS_MORE_INPUT;
+          goto saveStateAndReturn;
+        }
+        s->ringbuffer[pos] = (uint8_t)literal;
+      }
+      --s->block_length[0];
+      BROTLI_LOG_UINT(s->literal_htree_index);
+      BROTLI_LOG_ARRAY_INDEX(s->ringbuffer, pos);
+      ++pos;
+      if (PREDICT_FALSE(pos == s->ringbuffer_size)) {
+        s->state = BROTLI_STATE_COMMAND_INNER_WRITE;
+        --i;
+        goto saveStateAndReturn;
+      }
+    } while (--i != 0);
+  } else {
+    uint8_t p1 = s->ringbuffer[(pos - 1) & s->ringbuffer_mask];
+    uint8_t p2 = s->ringbuffer[(pos - 2) & s->ringbuffer_mask];
+    do {
+      const HuffmanCode* hc;
+      uint8_t context;
+      if (!CheckInputAmount(safe, br, 28)) { /* 162 bits + 7 bytes */
+        s->state = BROTLI_STATE_COMMAND_INNER;
+        result = BROTLI_RESULT_NEEDS_MORE_INPUT;
+        goto saveStateAndReturn;
+      }
+      if (PREDICT_FALSE(s->block_length[0] == 0)) {
+        BROTLI_SAFE(DecodeLiteralBlockSwitch(s));
+      }
+      context = s->context_lookup1[p1] | s->context_lookup2[p2];
+      BROTLI_LOG_UINT(context);
+      hc = s->literal_hgroup.htrees[s->context_map_slice[context]];
+      p2 = p1;
+      if (!safe) {
+        p1 = (uint8_t)ReadSymbol(hc, br);
+      } else {
+        uint32_t literal;
+        if (!SafeReadSymbol(hc, br, &literal)) {
+          result = BROTLI_RESULT_NEEDS_MORE_INPUT;
+          goto saveStateAndReturn;
+        }
+        p1 = (uint8_t)literal;
+      }
+      s->ringbuffer[pos] = p1;
+      --s->block_length[0];
+      BROTLI_LOG_UINT(s->context_map_slice[context]);
+      BROTLI_LOG_ARRAY_INDEX(s->ringbuffer, pos & s->ringbuffer_mask);
+      ++pos;
+      if (PREDICT_FALSE(pos == s->ringbuffer_size)) {
+        s->state = BROTLI_STATE_COMMAND_INNER_WRITE;
+        --i;
+        goto saveStateAndReturn;
+      }
+    } while (--i != 0);
+  }
+  if (s->meta_block_remaining_len <= 0) {
+    s->state = BROTLI_STATE_METABLOCK_DONE;
+    goto saveStateAndReturn;
+  }
+
+CommandPostDecodeLiterals:
+  if (safe) {
+    s->state = BROTLI_STATE_COMMAND_POST_DECODE_LITERALS;
+  }
+  if (s->distance_code >= 0) {
+    --s->dist_rb_idx;
+    s->distance_code = s->dist_rb[s->dist_rb_idx & 3];
+    goto postReadDistance;  /* We already have the implicit distance */
+  }
+  /* Read distance code in the command, unless it was implicitly zero. */
+  if (PREDICT_FALSE(s->block_length[2] == 0)) {
+    BROTLI_SAFE(DecodeDistanceBlockSwitch(s));
+  }
+  BROTLI_SAFE(ReadDistance(s, br));
+postReadDistance:
+  BROTLI_LOG_UINT(s->distance_code);
+  if (s->max_distance != s->max_backward_distance) {
+    if (pos < s->max_backward_distance_minus_custom_dict_size) {
+      s->max_distance = pos + s->custom_dict_size;
+    } else {
+      s->max_distance = s->max_backward_distance;
+    }
+  }
+  i = s->copy_length;
+  /* Apply copy of LZ77 back-reference, or static dictionary reference if
+  the distance is larger than the max LZ77 distance */
+  if (s->distance_code > s->max_distance) {
+    if (i >= kBrotliMinDictionaryWordLength &&
+        i <= kBrotliMaxDictionaryWordLength) {
+      int offset = kBrotliDictionaryOffsetsByLength[i];
+      int word_id = s->distance_code - s->max_distance - 1;
+      uint32_t shift = kBrotliDictionarySizeBitsByLength[i];
+      int mask = (int)BitMask(shift);
+      int word_idx = word_id & mask;
+      int transform_idx = word_id >> shift;
+      offset += word_idx * i;
+      if (transform_idx < kNumTransforms) {
+        const uint8_t* word = &kBrotliDictionary[offset];
+        int len = i;
+        if (transform_idx == 0) {
+          memcpy(&s->ringbuffer[pos], word, (size_t)len);
+        } else {
+          len = TransformDictionaryWord(
+              &s->ringbuffer[pos], word, len, transform_idx);
+        }
+        pos += len;
+        s->meta_block_remaining_len -= len;
+        if (pos >= s->ringbuffer_size) {
+          /*s->partial_pos_rb += (size_t)s->ringbuffer_size;*/
+          s->state = BROTLI_STATE_COMMAND_POST_WRITE_1;
+          goto saveStateAndReturn;
+        }
+      } else {
+        BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d "
+               "len: %d bytes left: %d\n",
+            pos, s->distance_code, i,
+            s->meta_block_remaining_len));
+        return BROTLI_FAILURE();
+      }
+    } else {
+      BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d "
+             "len: %d bytes left: %d\n", pos, s->distance_code, i,
+             s->meta_block_remaining_len));
+      return BROTLI_FAILURE();
+    }
+  } else {
+    const uint8_t *ringbuffer_end_minus_copy_length =
+        s->ringbuffer_end - i;
+    uint8_t* copy_src = &s->ringbuffer[
+        (pos - s->distance_code) & s->ringbuffer_mask];
+    uint8_t* copy_dst = &s->ringbuffer[pos];
+    /* update the recent distances cache */
+    s->dist_rb[s->dist_rb_idx & 3] = s->distance_code;
+    ++s->dist_rb_idx;
+    s->meta_block_remaining_len -= i;
+    if (PREDICT_FALSE(s->meta_block_remaining_len < 0)) {
+      BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d "
+             "len: %d bytes left: %d\n", pos, s->distance_code, i,
+             s->meta_block_remaining_len));
+      return BROTLI_FAILURE();
+    }
+    /* There is 128+ bytes of slack in the ringbuffer allocation.
+       Also, we have 16 short codes, that make these 16 bytes irrelevant
+       in the ringbuffer. Let's copy over them as a first guess.
+     */
+    memmove16(copy_dst, copy_src);
+    /* Now check if the copy extends over the ringbuffer end,
+       or if the copy overlaps with itself, if yes, do wrap-copy. */
+    if (copy_src < copy_dst) {
+      if (copy_dst >= ringbuffer_end_minus_copy_length) {
+        goto CommandPostWrapCopy;
+      }
+      if (copy_src + i > copy_dst) {
+        goto postSelfintersecting;
+      }
+    } else {
+      if (copy_src >= ringbuffer_end_minus_copy_length) {
+        goto CommandPostWrapCopy;
+      }
+      if (copy_dst + i > copy_src) {
+        goto postSelfintersecting;
+      }
+    }
+    pos += i;
+    if (i > 16) {
+      if (i > 32) {
+        memcpy(copy_dst + 16, copy_src + 16, (size_t)(i - 16));
+      } else {
+        /* This branch covers about 45% cases.
+           Fixed size short copy allows more compiler optimizations. */
+        memmove16(copy_dst + 16, copy_src + 16);
+      }
+    }
+  }
+  if (s->meta_block_remaining_len <= 0) {
+    /* Next metablock, if any */
+    s->state = BROTLI_STATE_METABLOCK_DONE;
+    goto saveStateAndReturn;
+  } else {
+    goto CommandBegin;
+  }
+postSelfintersecting:
+  while (--i >= 0) {
+    s->ringbuffer[pos] =
+        s->ringbuffer[(pos - s->distance_code) & s->ringbuffer_mask];
+    ++pos;
+  }
+  if (s->meta_block_remaining_len <= 0) {
+    /* Next metablock, if any */
+    s->state = BROTLI_STATE_METABLOCK_DONE;
+    goto saveStateAndReturn;
+  } else {
+    goto CommandBegin;
+  }
+
+CommandPostWrapCopy:
+  s->state = BROTLI_STATE_COMMAND_POST_WRAP_COPY;
+  while (--i >= 0) {
+    s->ringbuffer[pos] =
+        s->ringbuffer[(pos - s->distance_code) & s->ringbuffer_mask];
+    ++pos;
+    if (pos == s->ringbuffer_size) {
+      /*s->partial_pos_rb += (size_t)s->ringbuffer_size;*/
+      s->state = BROTLI_STATE_COMMAND_POST_WRITE_2;
+      goto saveStateAndReturn;
+    }
+  }
+  if (s->meta_block_remaining_len <= 0) {
+    /* Next metablock, if any */
+    s->state = BROTLI_STATE_METABLOCK_DONE;
+    goto saveStateAndReturn;
+  } else {
+    goto CommandBegin;
+  }
+
+saveStateAndReturn:
+  s->pos = pos;
+  s->loop_counter = i;
+  return result;
+}
+
+#undef BROTLI_SAFE
+
+static BROTLI_NOINLINE BrotliResult ProcessCommands(BrotliState* s) {
+  return ProcessCommandsInternal(0, s);
+}
+
+static BROTLI_NOINLINE BrotliResult SafeProcessCommands(BrotliState* s) {
+  return ProcessCommandsInternal(1, s);
+}
+
 BrotliResult BrotliDecompressBuffer(size_t encoded_size,
                                     const uint8_t* encoded_buffer,
                                     size_t* decoded_size,
                                     uint8_t* decoded_buffer) {
-  BrotliMemInput memin;
-  BrotliInput in = BrotliInitMemInput(encoded_buffer, encoded_size, &memin);
-  BrotliMemOutput mout;
-  BrotliOutput out = BrotliInitMemOutput(decoded_buffer, *decoded_size, &mout);
-  BrotliResult success = BrotliDecompress(in, out);
-  *decoded_size = mout.pos;
-  return success;
+  BrotliState s;
+  BrotliResult result;
+  size_t total_out = 0;
+  size_t available_in = encoded_size;
+  const uint8_t* next_in = encoded_buffer;
+  size_t available_out = *decoded_size;
+  uint8_t* next_out = decoded_buffer;
+  BrotliStateInit(&s);
+  result = BrotliDecompressStream(&available_in, &next_in, &available_out,
+      &next_out, &total_out, &s);
+  *decoded_size = total_out;
+  BrotliStateCleanup(&s);
+  if (result != BROTLI_RESULT_SUCCESS) {
+    result = BROTLI_RESULT_ERROR;
+  }
+  return result;
 }
 
 BrotliResult BrotliDecompress(BrotliInput input, BrotliOutput output) {
@@ -999,61 +1814,184 @@
                                              uint8_t** next_out,
                                              size_t* total_out,
                                              BrotliState* s) {
-  BrotliMemInput memin;
-  BrotliInput in = BrotliInitMemInput(*next_in, *available_in, &memin);
-  BrotliMemOutput memout;
-  BrotliOutput out = BrotliInitMemOutput(*next_out, *available_out, &memout);
-  BrotliResult result = BrotliDecompressStreaming(in, out, finish, s);
-  /* The current implementation reads everything, so 0 bytes are available. */
-  *next_in += memin.pos;
-  *available_in -= memin.pos;
-  /* Update the output position to where we write next. */
-  *next_out += memout.pos;
-  *available_out -= memout.pos;
-  *total_out += memout.pos;
+  BrotliResult result = BrotliDecompressStream(available_in, next_in,
+      available_out, next_out, total_out, s);
+  if (finish && result == BROTLI_RESULT_NEEDS_MORE_INPUT) {
+    result = BROTLI_FAILURE();
+  }
   return result;
 }
 
 BrotliResult BrotliDecompressStreaming(BrotliInput input, BrotliOutput output,
                                        int finish, BrotliState* s) {
-  uint8_t context;
-  int pos = s->pos;
-  int i = s->loop_counter;
-  uint32_t j;
+  const size_t kBufferSize = 65536;
+  BrotliResult result;
+  uint8_t* input_buffer;
+  uint8_t* output_buffer;
+  size_t avail_in;
+  const uint8_t* next_in;
+  size_t total_out;
+
+  if (s->legacy_input_buffer == 0) {
+    s->legacy_input_buffer = (uint8_t*)malloc(kBufferSize);
+  }
+  if (s->legacy_output_buffer == 0) {
+    s->legacy_output_buffer = (uint8_t*)malloc(kBufferSize);
+  }
+  if (s->legacy_input_buffer == 0 || s->legacy_output_buffer == 0) {
+    return BROTLI_FAILURE();
+  }
+  input_buffer = s->legacy_input_buffer;
+  output_buffer = s->legacy_output_buffer;
+
+  /* Push remaining output. */
+  if (s->legacy_output_len > s->legacy_output_pos) {
+    size_t to_write = s->legacy_output_len - s->legacy_output_pos;
+    int num_written = BrotliWrite(
+        output, output_buffer + s->legacy_output_pos, to_write);
+    if (num_written < 0) {
+      return BROTLI_FAILURE();
+    }
+    s->legacy_output_pos += (size_t)num_written;
+    if ((size_t)num_written < to_write) {
+      return BROTLI_RESULT_NEEDS_MORE_OUTPUT;
+    }
+  }
+  s->legacy_output_pos = 0;
+
+  avail_in = s->legacy_input_len - s->legacy_input_pos;
+  next_in = input_buffer + s->legacy_input_pos;
+
+  while (1) {
+    size_t to_write;
+    int num_written;
+    size_t avail_out = kBufferSize;
+    uint8_t* next_out = output_buffer;
+    result = BrotliDecompressStream(&avail_in, &next_in,
+        &avail_out, &next_out, &total_out, s);
+    s->legacy_input_pos = (size_t)(next_out - input_buffer);
+    to_write = (size_t)(next_out - output_buffer);
+    num_written = BrotliWrite(output, output_buffer, to_write);
+    if (num_written < 0) {
+      return BROTLI_FAILURE();
+    }
+    if ((size_t)num_written < to_write) {
+      s->legacy_output_len = to_write;
+      s->legacy_output_pos = (size_t)num_written;
+      return BROTLI_RESULT_NEEDS_MORE_OUTPUT;
+    }
+    if (result == BROTLI_RESULT_NEEDS_MORE_INPUT) {
+      int num_read = BrotliRead(input, input_buffer, kBufferSize);
+      if (num_read < 0 || (num_read == 0 && finish)) {
+        return BROTLI_FAILURE();
+      }
+      if (num_read == 0) {
+        s->legacy_input_len = 0;
+        s->legacy_input_pos = 0;
+        return BROTLI_RESULT_NEEDS_MORE_INPUT;
+      }
+      avail_in = (size_t)num_read;
+      next_in = input_buffer;
+      s->legacy_input_len = avail_in;
+      s->legacy_input_pos = 0;
+    } else if (result != BROTLI_RESULT_NEEDS_MORE_OUTPUT) {
+      /* Success or failure. */
+      return result;
+    }
+  }
+}
+
+/* Invariant: input stream is never overconsumed:
+    * invalid input implies that the whole stream is invalid -> any amount of
+      input could be read and discarded
+    * when result is "needs more input", then at leat one more byte is REQUIRED
+      to complete decoding; all input data MUST be consumed by decoder, so
+      client could swap the input buffer
+    * when result is "needs more output" decoder MUST ensure that it doesn't
+      hold more than 7 bits in bit reader; this saves client from swapping input
+      buffer ahead of time
+    * when result is "success" decoder MUST return all unused data back to input
+      buffer; this is possible because the invariant is hold on enter
+*/
+BrotliResult BrotliDecompressStream(size_t* available_in,
+    const uint8_t** next_in, size_t* available_out, uint8_t** next_out,
+    size_t* total_out, BrotliState* s) {
   BrotliResult result = BROTLI_RESULT_SUCCESS;
   BrotliBitReader* br = &s->br;
-  int initial_remaining_len;
-  int bytes_copied;
-  uint8_t *copy_src;
-  uint8_t *copy_dst;
-  /* We need the slack region for the following reasons:
-       - doing up to two 16-byte copies for fast backward copying
-       - transforms
-       - flushing the input s->ringbuffer when decoding uncompressed blocks */
-  s->br.input_ = input;
+  if (s->buffer_length == 0) { /* Just connect bit reader to input stream. */
+    br->avail_in = *available_in;
+    br->next_in = *next_in;
+  } else {
+    /* At least one byte of input is required. More than one byte of input may
+       be required to complete the transaction -> reading more data must be
+       done in a loop -> do it in a main loop. */
+    result = BROTLI_RESULT_NEEDS_MORE_INPUT;
+    br->next_in = &s->buffer.u8[0];
+  }
   /* State machine */
   for (;;) {
-    if (result != BROTLI_RESULT_SUCCESS) {
+    if (result != BROTLI_RESULT_SUCCESS) { /* Error | needs more input/output */
       if (result == BROTLI_RESULT_NEEDS_MORE_INPUT) {
-        if (BrotliReadInput(br, finish)) {
-          result = BROTLI_RESULT_SUCCESS;
-          continue;
+        if (s->ringbuffer != 0) { /* Proactively push output. */
+          WriteRingBuffer(available_out, next_out, total_out, s);
         }
-        if (finish) {
-          BROTLI_LOG(("Unexpected end of input. State: %d\n", s->state));
-          result = BROTLI_FAILURE();
+        if (s->buffer_length != 0) { /* Used with internal buffer. */
+          if (br->avail_in == 0) { /* Successfully finished read transaction. */
+            /* Accamulator contains less than 8 bits, because internal buffer
+               is expanded byte-by-byte until it is enough to complete read. */
+            s->buffer_length = 0;
+            /* Switch to input stream and restart. */
+            result = BROTLI_RESULT_SUCCESS;
+            br->avail_in = *available_in;
+            br->next_in = *next_in;
+            continue;
+          } else if (*available_in != 0) {
+            /* Not enough data in buffer, but can take one more byte from
+               input stream. */
+            result = BROTLI_RESULT_SUCCESS;
+            s->buffer.u8[s->buffer_length] = **next_in;
+            s->buffer_length++;
+            br->avail_in = s->buffer_length;
+            (*next_in)++;
+            (*available_in)--;
+            /* Retry with more data in buffer. */
+            continue;
+          }
+          /* Can't finish reading and no more input.*/
+          break;
+        } else { /* Input stream doesn't contain enough input. */
+          /* Copy tail to internal buffer and return. */
+          *next_in = br->next_in;
+          *available_in = br->avail_in;
+          while (*available_in) {
+            s->buffer.u8[s->buffer_length] = **next_in;
+            s->buffer_length++;
+            (*next_in)++;
+            (*available_in)--;
+          }
+          break;
         }
+        /* Unreachable. */
       }
-      break;  /* Fail, or partial data. */
+
+      /* Fail or needs more output. */
+
+      if (s->buffer_length != 0) {
+        /* Just consumed the buffered input and produced some output. Otherwise
+           it would result in "needs more input". Reset internal buffer.*/
+        s->buffer_length = 0;
+      } else {
+        /* Using input stream in last iteration. When decoder switches to input
+           stream it has less than 8 bits in accamulator, so it is safe to
+           return unused accamulator bits there. */
+        BrotliBitReaderUnload(br);
+        *available_in = br->avail_in;
+        *next_in = br->next_in;
+      }
+      break;
     }
     switch (s->state) {
       case BROTLI_STATE_UNINITED:
-        pos = 0;
-        BrotliInitBitReader(br, input);
-
-        s->state = BROTLI_STATE_BITREADER_WARMUP;
-        /* No break, continue to next state */
-      case BROTLI_STATE_BITREADER_WARMUP:
         /* Prepare to the first read. */
         if (!BrotliWarmupBitReader(br)) {
           result = BROTLI_RESULT_NEEDS_MORE_INPUT;
@@ -1085,13 +2023,12 @@
         /* No break, continue to next state */
       case BROTLI_STATE_METABLOCK_BEGIN:
         BrotliStateMetablockBegin(s);
-        BROTLI_LOG_UINT(pos);
+        BROTLI_LOG_UINT(s->pos);
         s->state = BROTLI_STATE_METABLOCK_HEADER;
         /* No break, continue to next state */
       case BROTLI_STATE_METABLOCK_HEADER:
         result = DecodeMetaBlockLength(s, br); /* Reads 2 - 31 bits. */
         if (result != BROTLI_RESULT_SUCCESS) {
-          i = s->loop_counter; /* Has been updated in DecodeMetaBlockLength. */
           break;
         }
         BROTLI_LOG_UINT(s->is_last_metablock);
@@ -1122,20 +2059,20 @@
           s->state = BROTLI_STATE_UNCOMPRESSED;
           break;
         }
-        i = 0;
+        s->loop_counter = 0;
         s->state = BROTLI_STATE_HUFFMAN_CODE_0;
         break;
-      case BROTLI_STATE_UNCOMPRESSED:
-        initial_remaining_len = s->meta_block_remaining_len;
-        /* pos is given as argument since s->pos is only updated at the end. */
-        result = CopyUncompressedBlockToOutput(output, pos, s);
-        bytes_copied = initial_remaining_len - s->meta_block_remaining_len;
-        pos = (pos + bytes_copied) & s->ringbuffer_mask;
+      case BROTLI_STATE_UNCOMPRESSED: {
+        int bytes_copied = s->meta_block_remaining_len;
+        result = CopyUncompressedBlockToOutput(
+            available_out, next_out, total_out, s);
+        bytes_copied -= s->meta_block_remaining_len;
         if (result != BROTLI_RESULT_SUCCESS) {
           break;
         }
         s->state = BROTLI_STATE_METABLOCK_DONE;
         break;
+      }
       case BROTLI_STATE_METADATA:
         for (; s->meta_block_remaining_len > 0; --s->meta_block_remaining_len) {
           uint32_t bits;
@@ -1150,63 +2087,61 @@
         }
         break;
       case BROTLI_STATE_HUFFMAN_CODE_0:
-        if (i >= 3) {
-          s->state = BROTLI_STATE_CONTEXT_MODES;
+        if (s->loop_counter >= 3) {
+          s->state = BROTLI_STATE_METABLOCK_HEADER_2;
           break;
         }
         /* Reads 1..11 bits. */
-        result = DecodeVarLenUint8(s, br, &s->num_block_types[i]);
+        result = DecodeVarLenUint8(s, br, &s->num_block_types[s->loop_counter]);
         if (result != BROTLI_RESULT_SUCCESS) {
           break;
         }
-        s->num_block_types[i]++;
-        BROTLI_LOG_UINT(s->num_block_types[i]);
+        s->num_block_types[s->loop_counter]++;
+        BROTLI_LOG_UINT(s->num_block_types[s->loop_counter]);
+        if (s->num_block_types[s->loop_counter] < 2) {
+          s->loop_counter++;
+          break;
+        }
         s->state = BROTLI_STATE_HUFFMAN_CODE_1;
         /* No break, continue to next state */
-      case BROTLI_STATE_HUFFMAN_CODE_1:
-        if (!BrotliWarmupBitReader(br)) {
-          result = BROTLI_RESULT_NEEDS_MORE_INPUT;
-          break;
-        }
-        if (s->num_block_types[i] >= 2) {
-          result = ReadHuffmanCode(s->num_block_types[i] + 2,
-              &s->block_type_trees[i * BROTLI_HUFFMAN_MAX_TABLE_SIZE],
-              NULL, s);
-          if (result != BROTLI_RESULT_SUCCESS) break;
-          s->state = BROTLI_STATE_HUFFMAN_CODE_2;
-        } else {
-          i++;
-          s->state = BROTLI_STATE_HUFFMAN_CODE_0;
-          break;
-        }
+      case BROTLI_STATE_HUFFMAN_CODE_1: {
+        int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_TABLE_SIZE;
+        result = ReadHuffmanCode(s->num_block_types[s->loop_counter] + 2,
+            &s->block_type_trees[tree_offset], NULL, s);
+        if (result != BROTLI_RESULT_SUCCESS) break;
+        s->state = BROTLI_STATE_HUFFMAN_CODE_2;
         /* No break, continue to next state */
-      case BROTLI_STATE_HUFFMAN_CODE_2:
+      }
+      case BROTLI_STATE_HUFFMAN_CODE_2: {
+        int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_TABLE_SIZE;
         result = ReadHuffmanCode(kNumBlockLengthCodes,
-            &s->block_len_trees[i * BROTLI_HUFFMAN_MAX_TABLE_SIZE],
-            NULL, s);
+            &s->block_len_trees[tree_offset], NULL, s);
         if (result != BROTLI_RESULT_SUCCESS) break;
         s->state = BROTLI_STATE_HUFFMAN_CODE_3;
         /* No break, continue to next state */
-      case BROTLI_STATE_HUFFMAN_CODE_3:
-        if (!BrotliCheckInputAmount(br, 8)) {
+      }
+      case BROTLI_STATE_HUFFMAN_CODE_3: {
+        int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_TABLE_SIZE;
+        if (!SafeReadBlockLength(s, &s->block_length[s->loop_counter],
+            &s->block_len_trees[tree_offset], br)) {
           result = BROTLI_RESULT_NEEDS_MORE_INPUT;
           break;
         }
-        s->block_length[i] = ReadBlockLength( /* Reads 3..39 bits. */
-            &s->block_len_trees[i * BROTLI_HUFFMAN_MAX_TABLE_SIZE], br);
-        BROTLI_LOG_UINT(s->block_length[i]);
-        i++;
+        BROTLI_LOG_UINT(s->block_length[s->loop_counter]);
+        s->loop_counter++;
         s->state = BROTLI_STATE_HUFFMAN_CODE_0;
         break;
-      case BROTLI_STATE_CONTEXT_MODES:
-        /* We need up to 256 * 2 + 6 bits, this fits in 128 bytes. */
-        if (!BrotliCheckInputAmount(br, 128)) {
+      }
+      case BROTLI_STATE_METABLOCK_HEADER_2: {
+        uint32_t bits;
+        if (!BrotliSafeReadBits(br, 6, &bits)) {
           result = BROTLI_RESULT_NEEDS_MORE_INPUT;
           break;
         }
-        s->distance_postfix_bits = BrotliReadBits(br, 2);
+        s->distance_postfix_bits = bits & BitMask(2);
+        bits >>= 2;
         s->num_direct_distance_codes = NUM_DISTANCE_SHORT_CODES +
-            (BrotliReadBits(br, 4) << s->distance_postfix_bits);
+            (bits << s->distance_postfix_bits);
         BROTLI_LOG_UINT(s->num_direct_distance_codes);
         BROTLI_LOG_UINT(s->distance_postfix_bits);
         s->distance_postfix_mask = (int)BitMask(s->distance_postfix_bits);
@@ -1215,13 +2150,19 @@
           result = BROTLI_FAILURE();
           break;
         }
-        for (j = 0; j < s->num_block_types[0]; ++j) {
-          s->context_modes[j] = (uint8_t)(BrotliReadBits(br, 2) << 1);
-          BROTLI_LOG_ARRAY_INDEX(s->context_modes, j);
+        s->loop_counter = 0;
+        s->state = BROTLI_STATE_CONTEXT_MODES;
+        /* No break, continue to next state */
+      }
+      case BROTLI_STATE_CONTEXT_MODES:
+        result = ReadContextModes(s);
+        if (result != BROTLI_RESULT_SUCCESS) {
+          break;
         }
         s->state = BROTLI_STATE_CONTEXT_MAP_1;
         /* No break, continue to next state */
-      case BROTLI_STATE_CONTEXT_MAP_1:
+      case BROTLI_STATE_CONTEXT_MAP_1: {
+        uint32_t j;
         result = DecodeContextMap(s->num_block_types[0] << kLiteralContextBits,
                                   &s->num_literal_htrees, &s->context_map, s);
         if (result != BROTLI_RESULT_SUCCESS) {
@@ -1236,6 +2177,7 @@
         }
         s->state = BROTLI_STATE_CONTEXT_MAP_2;
         /* No break, continue to next state */
+      }
       case BROTLI_STATE_CONTEXT_MAP_2:
         {
           uint32_t num_distance_codes =
@@ -1259,13 +2201,13 @@
             return BROTLI_FAILURE();
           }
         }
-        i = 0;
+        s->loop_counter = 0;
         s->state = BROTLI_STATE_TREE_GROUP;
         /* No break, continue to next state */
       case BROTLI_STATE_TREE_GROUP:
         {
           HuffmanTreeGroup* hgroup = NULL;
-          switch (i) {
+          switch (s->loop_counter) {
             case 0:
               hgroup = &s->literal_hgroup;
               break;
@@ -1279,8 +2221,8 @@
           result = HuffmanTreeGroupDecode(hgroup, s);
         }
         if (result != BROTLI_RESULT_SUCCESS) break;
-        i++;
-        if (i >= 3) {
+        s->loop_counter++;
+        if (s->loop_counter >= 3) {
           uint8_t context_mode = s->context_modes[s->block_type_rb[1]];
           s->context_map_slice = s->context_map;
           s->dist_context_map_slice = s->dist_context_map;
@@ -1294,377 +2236,43 @@
         }
         break;
       case BROTLI_STATE_COMMAND_BEGIN:
-        if (s->meta_block_remaining_len <= 0) {
-          /* Next metablock, if any */
-          s->state = BROTLI_STATE_METABLOCK_DONE;
-          break;
-        }
- /* Decoding of Brotli commands is the inner loop, jumping with goto makes it
-    3% faster */
- CommandBegin:
-        if (!BrotliCheckInputAmount(br, 32)) {
-          s->state = BROTLI_STATE_COMMAND_BEGIN;
-          result = BROTLI_RESULT_NEEDS_MORE_INPUT;
-          break;
-        }
-          /* Read the insert/copy length in the command */
-        if (s->block_length[1] == 0) {
-          /* Block switch for insert/copy length. Reads 0..15 bits. */
-          DecodeBlockType(s->num_block_types[1],
-                          s->block_type_trees, 1,
-                          s->block_type_rb, br);
-          s->htree_command = s->insert_copy_hgroup.htrees[s->block_type_rb[3]];
-          s->block_length[1] = ReadBlockLength( /* Reads 3..39 bits. */
-              &s->block_len_trees[BROTLI_HUFFMAN_MAX_TABLE_SIZE], br);
-        }
-        {
-          uint32_t cmd_code = ReadSymbol(s->htree_command, br);
-          int insert_len_extra = 0;
-          CmdLutElement v;
-          --s->block_length[1];
-          v = kCmdLut[cmd_code];
-          s->distance_code = v.distance_code;
-          s->distance_context = v.context;
-          s->dist_htree_index = s->dist_context_map_slice[s->distance_context];
-          i = v.insert_len_offset;
-          if (PREDICT_FALSE(v.insert_len_extra_bits != 0)) {
-            insert_len_extra = (int)BrotliReadBits(br, v.insert_len_extra_bits);
-          }
-          s->copy_length = (int)BrotliReadBits(br, v.copy_len_extra_bits) +
-                           v.copy_len_offset;
-          i += insert_len_extra;
-        }
-        BROTLI_LOG_UINT(i);
-        BROTLI_LOG_UINT(s->copy_length);
-        BROTLI_LOG_UINT(s->distance_code);
-        if (i == 0) {
-          goto postDecodeLiterals;
-        }
-        s->meta_block_remaining_len -= i;
-        /* No break, go to next state */
       case BROTLI_STATE_COMMAND_INNER:
-        /* Read the literals in the command */
-        if (s->trivial_literal_context) {
-          uint32_t bits;
-          uint32_t value;
-          PreloadSymbol(s->literal_htree, br, &bits, &value);
-          do {
-            if (!BrotliCheckInputAmount(br, 64)) {
-              s->state = BROTLI_STATE_COMMAND_INNER;
-              result = BROTLI_RESULT_NEEDS_MORE_INPUT;
-              break;
-            }
-            if (PREDICT_FALSE(s->block_length[0] == 0)) {
-              /* Block switch for literals */
-              DecodeBlockTypeWithContext(s, br);
-              PreloadSymbol(s->literal_htree, br, &bits, &value);
-            }
-            s->ringbuffer[pos] =
-                (uint8_t)ReadPreloadedSymbol(s->literal_htree,
-                                             br, &bits, &value);
-            --s->block_length[0];
-            BROTLI_LOG_UINT(s->literal_htree_index);
-            BROTLI_LOG_ARRAY_INDEX(s->ringbuffer, pos);
-            ++pos;
-            if (PREDICT_FALSE(pos == s->ringbuffer_size)) {
-              s->to_write = s->ringbuffer_size;
-              s->partially_written = 0;
-              s->state = BROTLI_STATE_COMMAND_INNER_WRITE;
-              --i;
-              goto innerWrite;
-            }
-          } while (--i != 0);
-        } else {
-          uint8_t p1 = s->ringbuffer[(pos - 1) & s->ringbuffer_mask];
-          uint8_t p2 = s->ringbuffer[(pos - 2) & s->ringbuffer_mask];
-          do {
-            const HuffmanCode* hc;
-            if (!BrotliCheckInputAmount(br, 64)) {
-              s->state = BROTLI_STATE_COMMAND_INNER;
-              result = BROTLI_RESULT_NEEDS_MORE_INPUT;
-              break;
-            }
-            if (PREDICT_FALSE(s->block_length[0] == 0)) {
-              /* Block switch for literals */
-              DecodeBlockTypeWithContext(s, br);
-            }
-            context = s->context_lookup1[p1] | s->context_lookup2[p2];
-            BROTLI_LOG_UINT(context);
-            hc = s->literal_hgroup.htrees[s->context_map_slice[context]];
-            --s->block_length[0];
-            p2 = p1;
-            p1 = (uint8_t)ReadSymbol(hc, br);
-            s->ringbuffer[pos] = p1;
-            BROTLI_LOG_UINT(s->context_map_slice[context]);
-            BROTLI_LOG_ARRAY_INDEX(s->ringbuffer, pos & s->ringbuffer_mask);
-            ++pos;
-            if (PREDICT_FALSE(pos == s->ringbuffer_size)) {
-              s->to_write = s->ringbuffer_size;
-              s->partially_written = 0;
-              s->state = BROTLI_STATE_COMMAND_INNER_WRITE;
-              --i;
-              goto innerWrite;
-            }
-          } while (--i != 0);
-        }
-        if (result != BROTLI_RESULT_SUCCESS) break;
-        if (s->meta_block_remaining_len <= 0) {
-          s->state = BROTLI_STATE_METABLOCK_DONE;
-          break;
-        }
-postDecodeLiterals:
-        if (s->distance_code >= 0) {
-          --s->dist_rb_idx;
-          s->distance_code = s->dist_rb[s->dist_rb_idx & 3];
-          goto postReadDistance;  /* We already have the implicit distance */
-        }
-        /* Read distance code in the command, unless it was implicitly zero. */
-        BROTLI_DCHECK(s->distance_code < 0);
-        if (s->block_length[2] == 0) {
-          /* Block switch for distance codes */
-          uint32_t dist_context_offset;
-          DecodeBlockType(s->num_block_types[2],
-                          s->block_type_trees, 2,
-                          s->block_type_rb, br); /* Reads 0..15 bits. */
-          s->block_length[2] = ReadBlockLength( /* Reads 3..39 bits. */
-              &s->block_len_trees[2 * BROTLI_HUFFMAN_MAX_TABLE_SIZE], br);
-          dist_context_offset = s->block_type_rb[5] << kDistanceContextBits;
-          s->dist_context_map_slice =
-              s->dist_context_map + dist_context_offset;
-          s->dist_htree_index = s->dist_context_map_slice[s->distance_context];
-        }
-        --s->block_length[2];
-        s->distance_code = (int)ReadSymbol(
-            s->distance_hgroup.htrees[s->dist_htree_index], br);
-        /* Convert the distance code to the actual distance by possibly */
-        /* looking up past distances from the s->ringbuffer. */
-        if ((s->distance_code & ~0xf) == 0) {
-          if (s->distance_code == 0) {
-            --s->dist_rb_idx;
-            s->distance_code = s->dist_rb[s->dist_rb_idx & 3];
-          } else {
-            int distance_code = s->distance_code << 1;
-            /* kDistanceShortCodeIndexOffset has 2-bit values from LSB: */
-            /* 3, 2, 1, 0, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 */
-            const uint32_t kDistanceShortCodeIndexOffset = 0xaaafff1b;
-            /* kDistanceShortCodeValueOffset has 2-bit values from LSB: */
-            /* 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 1, 1, 2, 2, 3, 3 */
-            const uint32_t kDistanceShortCodeValueOffset = 0xfa5fa500;
-            int v = (s->dist_rb_idx +
-                (int)(kDistanceShortCodeIndexOffset >> distance_code)) & 0x3;
-            s->distance_code = s->dist_rb[v];
-            v = (int)(kDistanceShortCodeValueOffset >> distance_code) & 0x3;
-            if ((distance_code & 0x3) != 0) {
-              s->distance_code += v;
-            } else {
-              s->distance_code -= v;
-              if (s->distance_code <= 0) {
-                /* A huge distance will cause a BROTLI_FAILURE() soon. */
-                /* This is a little faster than failing here. */
-                s->distance_code = 0x0fffffff;
-              }
-            }
-          }
-        } else {
-          int distval = s->distance_code - (int)s->num_direct_distance_codes;
-          if (distval >= 0) {
-            uint32_t nbits;
-            int postfix;
-            int offset;
-            if (s->distance_postfix_bits == 0) {
-              nbits = ((uint32_t)distval >> 1) + 1;
-              offset = ((2 + (distval & 1)) << nbits) - 4;
-              s->distance_code = (int)s->num_direct_distance_codes +
-                  offset + (int)BrotliReadBits(br, nbits);
-            } else {
-              postfix = distval & s->distance_postfix_mask;
-              distval >>= s->distance_postfix_bits;
-              nbits = ((uint32_t)distval >> 1) + 1;
-              offset = ((2 + (distval & 1)) << nbits) - 4;
-              s->distance_code = (int)s->num_direct_distance_codes +
-                  ((offset + (int)BrotliReadBits(br, nbits)) <<
-                   s->distance_postfix_bits) + postfix;
-            }
-          }
-          s->distance_code = s->distance_code - NUM_DISTANCE_SHORT_CODES + 1;
-        }
-postReadDistance:
-        BROTLI_LOG_UINT(s->distance_code);
-        if (s->max_distance != s->max_backward_distance) {
-          if (pos < s->max_backward_distance_minus_custom_dict_size) {
-            s->max_distance = pos + s->custom_dict_size;
-          } else {
-            s->max_distance = s->max_backward_distance;
-          }
-        }
-        i = s->copy_length;
-        /* Apply copy of LZ77 back-reference, or static dictionary reference if
-        the distance is larger than the max LZ77 distance */
-        if (s->distance_code > s->max_distance) {
-          if (i >= kBrotliMinDictionaryWordLength &&
-              i <= kBrotliMaxDictionaryWordLength) {
-            int offset = kBrotliDictionaryOffsetsByLength[i];
-            int word_id = s->distance_code - s->max_distance - 1;
-            uint32_t shift = kBrotliDictionarySizeBitsByLength[i];
-            int mask = (int)BitMask(shift);
-            int word_idx = word_id & mask;
-            int transform_idx = word_id >> shift;
-            offset += word_idx * i;
-            if (transform_idx < kNumTransforms) {
-              const uint8_t* word = &kBrotliDictionary[offset];
-              int len = i;
-              if (transform_idx == 0) {
-                memcpy(&s->ringbuffer[pos], word, (size_t)len);
-              } else {
-                len = TransformDictionaryWord(
-                    &s->ringbuffer[pos], word, len, transform_idx);
-              }
-              pos += len;
-              s->meta_block_remaining_len -= len;
-              if (pos >= s->ringbuffer_size) {
-                s->to_write = s->ringbuffer_size;
-                s->partially_written = 0;
-                s->state = BROTLI_STATE_COMMAND_POST_WRITE_1;
-                break;
-              }
-            } else {
-              BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d "
-                     "len: %d bytes left: %d\n",
-                  pos, s->distance_code, i,
-                  s->meta_block_remaining_len));
-              result = BROTLI_FAILURE();
-              break;
-            }
-          } else {
-            BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d "
-                   "len: %d bytes left: %d\n", pos, s->distance_code, i,
-                   s->meta_block_remaining_len));
-            result = BROTLI_FAILURE();
-            break;
-          }
-        } else {
-          const uint8_t *ringbuffer_end_minus_copy_length =
-              s->ringbuffer_end - i;
-          copy_src = &s->ringbuffer[(pos - s->distance_code) &
-                                    s->ringbuffer_mask];
-          copy_dst = &s->ringbuffer[pos];
-          /* update the recent distances cache */
-          s->dist_rb[s->dist_rb_idx & 3] = s->distance_code;
-          ++s->dist_rb_idx;
-          s->meta_block_remaining_len -= i;
-          if (PREDICT_FALSE(s->meta_block_remaining_len < 0)) {
-            BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d "
-                   "len: %d bytes left: %d\n", pos, s->distance_code, i,
-                   s->meta_block_remaining_len));
-            result = BROTLI_FAILURE();
-            break;
-          }
-          /* There is 128+ bytes of slack in the ringbuffer allocation.
-             Also, we have 16 short codes, that make these 16 bytes irrelevant
-             in the ringbuffer. Let's copy over them as a first guess.
-           */
-          memmove16(copy_dst, copy_src);
-          /* Now check if the copy extends over the ringbuffer end,
-             or if the copy overlaps with itself, if yes, do wrap-copy. */
-          if (copy_src < copy_dst) {
-            if (copy_dst >= ringbuffer_end_minus_copy_length) {
-              goto postWrapCopy;
-            }
-            if (copy_src + i > copy_dst) {
-              goto postSelfintersecting;
-            }
-          } else {
-            if (copy_src >= ringbuffer_end_minus_copy_length) {
-              goto postWrapCopy;
-            }
-            if (copy_dst + i > copy_src) {
-              goto postSelfintersecting;
-            }
-          }
-          pos += i;
-          if (i > 16) {
-            if (i > 32) {
-              memcpy(copy_dst + 16, copy_src + 16, (size_t)(i - 16));
-            } else {
-              /* This branch covers about 45% cases.
-                 Fixed size short copy allows more compiler optimizations. */
-              memmove16(copy_dst + 16, copy_src + 16);
-            }
-          }
-        }
-        if (s->meta_block_remaining_len <= 0) {
-          /* Next metablock, if any */
-          s->state = BROTLI_STATE_METABLOCK_DONE;
-          break;
-        } else {
-          goto CommandBegin;
-        }
-      postSelfintersecting:
-        while (--i >= 0) {
-          s->ringbuffer[pos] =
-              s->ringbuffer[(pos - s->distance_code) & s->ringbuffer_mask];
-          ++pos;
-        }
-        if (s->meta_block_remaining_len <= 0) {
-          /* Next metablock, if any */
-          s->state = BROTLI_STATE_METABLOCK_DONE;
-          break;
-        } else {
-          goto CommandBegin;
-        }
-      postWrapCopy:
-        s->state = BROTLI_STATE_COMMAND_POST_WRAP_COPY;
-        /* No break, go to next state */
+      case BROTLI_STATE_COMMAND_POST_DECODE_LITERALS:
       case BROTLI_STATE_COMMAND_POST_WRAP_COPY:
-        while (--i >= 0) {
-          s->ringbuffer[pos] =
-              s->ringbuffer[(pos - s->distance_code) & s->ringbuffer_mask];
-          ++pos;
-          if (pos == s->ringbuffer_size) {
-            s->to_write = s->ringbuffer_size;
-            s->partially_written = 0;
-            s->state = BROTLI_STATE_COMMAND_POST_WRITE_2;
-            break;
-          }
-        }
-        if (s->state == BROTLI_STATE_COMMAND_POST_WRAP_COPY) {
-          if (s->meta_block_remaining_len <= 0) {
-            /* Next metablock, if any */
-            s->state = BROTLI_STATE_METABLOCK_DONE;
-            break;
-          } else {
-            goto CommandBegin;
-          }
+        result = ProcessCommands(s);
+        if (result == BROTLI_RESULT_NEEDS_MORE_INPUT) {
+          result = SafeProcessCommands(s);
         }
         break;
       case BROTLI_STATE_COMMAND_INNER_WRITE:
       case BROTLI_STATE_COMMAND_POST_WRITE_1:
       case BROTLI_STATE_COMMAND_POST_WRITE_2:
-innerWrite:
-        result = WriteRingBuffer(output, s);
+        result = WriteRingBuffer(available_out, next_out, total_out, s);
         if (result != BROTLI_RESULT_SUCCESS) {
           break;
         }
-        pos -= s->ringbuffer_size;
+        s->pos -= s->ringbuffer_size;
+        s->rb_roundtrips++;
         s->max_distance = s->max_backward_distance;
         if (s->state == BROTLI_STATE_COMMAND_POST_WRITE_1) {
-          memcpy(s->ringbuffer, s->ringbuffer_end, (size_t)pos);
+          memcpy(s->ringbuffer, s->ringbuffer_end, (size_t)s->pos);
           if (s->meta_block_remaining_len <= 0) {
             /* Next metablock, if any */
             s->state = BROTLI_STATE_METABLOCK_DONE;
-            break;
           } else {
-            goto CommandBegin;
+            s->state = BROTLI_STATE_COMMAND_BEGIN;
           }
+          break;
         } else if (s->state == BROTLI_STATE_COMMAND_POST_WRITE_2) {
           s->state = BROTLI_STATE_COMMAND_POST_WRAP_COPY;
         } else {  /* BROTLI_STATE_COMMAND_INNER_WRITE */
-          if (i == 0) {
+          if (s->loop_counter == 0) {
             if (s->meta_block_remaining_len <= 0) {
               s->state = BROTLI_STATE_METABLOCK_DONE;
-              break;
+            } else {
+              s->state = BROTLI_STATE_COMMAND_POST_DECODE_LITERALS;
             }
-            goto postDecodeLiterals;
+            break;
           }
           s->state = BROTLI_STATE_COMMAND_INNER;
         }
@@ -1675,30 +2283,26 @@
           s->state = BROTLI_STATE_METABLOCK_BEGIN;
           break;
         }
-        s->to_write = pos;
-        s->partially_written = 0;
+        if (!BrotliJumpToByteBoundary(br)) {
+          result = BROTLI_FAILURE();
+        }
+        if (s->buffer_length == 0) {
+          BrotliBitReaderUnload(br);
+          *available_in = br->avail_in;
+          *next_in = br->next_in;
+        }
         s->state = BROTLI_STATE_DONE;
         /* No break, continue to next state */
       case BROTLI_STATE_DONE:
         if (s->ringbuffer != 0) {
-          result = WriteRingBuffer(output, s);
+          result = WriteRingBuffer(available_out, next_out, total_out, s);
           if (result != BROTLI_RESULT_SUCCESS) {
             break;
           }
         }
-        if (!BrotliJumpToByteBoundary(br)) {
-          result = BROTLI_FAILURE();
-        }
-        if (!BrotliIsBitReaderOK(br)) {
-          /* The brotli input stream was too small, does not follow the spec.
-             NOTE: larger input is allowed, smaller not. */
-          result = BROTLI_FAILURE();
-        }
         return result;
     }
   }
-  s->pos = pos;
-  s->loop_counter = i;
   return result;
 }
 
diff --git a/third_party/brotli/dec/decode.h b/third_party/brotli/dec/decode.h
index cd3d124..78a156e 100644
--- a/third_party/brotli/dec/decode.h
+++ b/third_party/brotli/dec/decode.h
@@ -62,9 +62,6 @@
 
 /* Decompresses the data in encoded_buffer into decoded_buffer, and sets */
 /* *decoded_size to the decompressed length. */
-/* Returns 0 if there was either a bit stream error or memory allocation */
-/* error, and 1 otherwise. */
-/* If decoded size is zero, returns 1 and keeps decoded_buffer unchanged. */
 BrotliResult BrotliDecompressBuffer(size_t encoded_size,
                                     const uint8_t* encoded_buffer,
                                     size_t* decoded_size,
@@ -72,6 +69,7 @@
 
 /* Same as above, but uses the specified input and output callbacks instead */
 /* of reading from and writing to pre-allocated memory buffers. */
+/* DEPRECATED */
 BrotliResult BrotliDecompress(BrotliInput input, BrotliOutput output);
 
 /* Same as above, but supports the caller to call the decoder repeatedly with
@@ -99,6 +97,7 @@
    it returning a smaller value than the amount of bytes to write always results
    in an error.
 */
+/* DEPRECATED */
 BrotliResult BrotliDecompressStreaming(BrotliInput input, BrotliOutput output,
                                        int finish, BrotliState* s);
 
@@ -129,6 +128,7 @@
    *available_out yourself before a next call, e.g. to point to a new larger
    buffer.
 */
+/* DEPRECATED */
 BrotliResult BrotliDecompressBufferStreaming(size_t* available_in,
                                              const uint8_t** next_in,
                                              int finish,
@@ -137,6 +137,13 @@
                                              size_t* total_out,
                                              BrotliState* s);
 
+BrotliResult BrotliDecompressStream(size_t* available_in,
+                                    const uint8_t** next_in,
+                                    size_t* available_out,
+                                    uint8_t** next_out,
+                                    size_t* total_out,
+                                    BrotliState* s);
+
 /* Fills the new state with a dictionary for LZ77, warming up the ringbuffer,
    e.g. for custom static dictionaries for data formats.
    Not to be confused with the built-in transformable dictionary of Brotli.
@@ -151,10 +158,6 @@
     size_t size, const uint8_t* dict, BrotliState* s);
 
 
-/* Escalate internal functions visibility; for testing purposes only. */
-void InverseMoveToFrontTransformForTesting(
-    uint8_t* v, uint32_t l, BrotliState* s);
-
 #if defined(__cplusplus) || defined(c_plusplus)
 } /* extern "C" */
 #endif
diff --git a/third_party/brotli/dec/huffman.c b/third_party/brotli/dec/huffman.c
index d4ccbd9..0628c36 100644
--- a/third_party/brotli/dec/huffman.c
+++ b/third_party/brotli/dec/huffman.c
@@ -377,6 +377,7 @@
 
 void BrotliHuffmanTreeGroupRelease(HuffmanTreeGroup* group) {
   BROTLI_FREE(group->codes);
+  group->htrees = NULL;
 }
 
 #if defined(__cplusplus) || defined(c_plusplus)
diff --git a/third_party/brotli/dec/port.h b/third_party/brotli/dec/port.h
index bf33242b..f8fc4a8 100644
--- a/third_party/brotli/dec/port.h
+++ b/third_party/brotli/dec/port.h
@@ -19,8 +19,10 @@
     * BROTLI_BUILD_32_BIT disables 64-bit optimizations
     * BROTLI_BUILD_64_BIT forces to use 64-bit optimizations
     * BROTLI_BUILD_BIG_ENDIAN forces to use big-endian optimizations
-    * BROTLI_BUILD_LITTLE_ENDIAN forces to use little-endian optimizations
     * BROTLI_BUILD_ENDIAN_NEUTRAL disables endian-aware optimizations
+    * BROTLI_BUILD_LITTLE_ENDIAN forces to use little-endian optimizations
+    * BROTLI_BUILD_MODERN_COMPILER forces to use modern compilers built-ins,
+      features and attributes
     * BROTLI_BUILD_PORTABLE disables dangerous optimizations, like unaligned
       read and overlapping memcpy; this reduces decompression speed by 5%
     * BROTLI_DEBUG dumps file name and line number when decoder detects stream
@@ -46,6 +48,59 @@
 #define __has_feature(x) 0
 #endif
 
+#if defined(__sparc)
+#define BROTLI_TARGET_SPARC
+#endif
+
+#if defined(__arm__) || defined(__thumb__) || \
+    defined(_M_ARM) || defined(_M_ARMT)
+#define BROTLI_TARGET_ARM
+#if (defined(__ARM_ARCH) && (__ARM_ARCH >= 7)) || \
+    (defined(M_ARM) && (M_ARM >= 7))
+#define BROTLI_TARGET_ARMV7
+#endif  /* ARMv7 */
+#if defined(__aarch64__)
+#define BROTLI_TARGET_ARMV8
+#endif  /* ARMv8 */
+#endif  /* ARM */
+
+#if defined(__x86_64__) || defined(_M_X64)
+#define BROTLI_TARGET_X64
+#endif
+
+#if defined(__PPC64__)
+#define BROTLI_TARGET_POWERPC64
+#endif
+
+#if defined(__GNUC__) && defined(__GNUC_MINOR__)
+#define BROTLI_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
+#else
+#define BROTLI_GCC_VERSION 0
+#endif
+
+#if defined(__ICC)
+#define BROTLI_ICC_VERSION __ICC
+#else
+#define BROTLI_ICC_VERSION 0
+#endif
+
+#if defined(BROTLI_BUILD_MODERN_COMPILER)
+#define BROTLI_MODERN_COMPILER 1
+#elif (BROTLI_GCC_VERSION > 300) || (BROTLI_ICC_VERSION >= 1600)
+#define BROTLI_MODERN_COMPILER 1
+#else
+#define BROTLI_MODERN_COMPILER 0
+#endif
+
+/* SPARC and ARMv6 don't support unaligned read.
+   Choose portable build for them. */
+#if !defined(BROTLI_BUILD_PORTABLE)
+#if defined(BROTLI_TARGET_SPARC) || \
+    (defined(BROTLI_TARGET_ARM) && !defined(BROTLI_TARGET_ARMV7))
+#define BROTLI_BUILD_PORTABLE
+#endif  /* SPARK or ARMv6 */
+#endif  /* portable build */
+
 #ifdef BROTLI_BUILD_PORTABLE
 #define BROTLI_ALIGNED_READ 1
 #define BROTLI_SAFE_MEMMOVE 1
@@ -73,8 +128,7 @@
   }
 
 */
-#if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ > 95) || \
-    (defined(__llvm__) && __has_builtin(__builtin_expect))
+#if BROTLI_MODERN_COMPILER || __has_builtin(__builtin_expect)
 #define PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
 #define PREDICT_FALSE(x) (__builtin_expect(x, 0))
 #else
@@ -83,15 +137,13 @@
 #endif
 
 /* IS_CONSTANT macros returns true for compile-time constant expressions. */
-#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ > 0) || \
-    (defined(__llvm__) && __has_builtin(__builtin_constant_p))
+#if BROTLI_MODERN_COMPILER || __has_builtin(__builtin_constant_p)
 #define IS_CONSTANT(x) __builtin_constant_p(x)
 #else
 #define IS_CONSTANT(x) 0
 #endif
 
-#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ > 0) || \
-    (defined(__llvm__) && __has_attribute(always_inline))
+#if BROTLI_MODERN_COMPILER || __has_attribute(always_inline)
 #define ATTRIBUTE_ALWAYS_INLINE __attribute__ ((always_inline))
 #else
 #define ATTRIBUTE_ALWAYS_INLINE
@@ -118,8 +170,8 @@
 #define BROTLI_64_BITS 1
 #elif defined(BROTLI_BUILD_32_BIT)
 #define BROTLI_64_BITS 0
-#elif defined(__x86_64__) || defined(_M_X64) || defined(__aarch64__) || \
-     defined(__PPC64__)
+#elif defined(BROTLI_TARGET_X64) || defined(BROTLI_TARGET_ARMV8) || \
+    defined(BROTLI_TARGET_POWERPC64)
 #define BROTLI_64_BITS 1
 #else
 #define BROTLI_64_BITS 0
@@ -150,8 +202,7 @@
 #define BROTLI_LITTLE_ENDIAN 0
 #endif
 
-#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) || \
-    (defined(__llvm__) && __has_attribute(noinline))
+#if BROTLI_MODERN_COMPILER || __has_attribute(noinline)
 #define BROTLI_NOINLINE __attribute__ ((noinline))
 #else
 #define BROTLI_NOINLINE
@@ -169,8 +220,8 @@
   if ((N & 4) != 0) {X; X; X; X;} \
 }
 
-#if (__GNUC__ > 2) || defined(__llvm__)
-#if (defined(__ARM_ARCH) && (__ARM_ARCH >= 7))
+#if BROTLI_MODERN_COMPILER || defined(__llvm__)
+#if defined(BROTLI_TARGET_ARMV7)
 static BROTLI_INLINE unsigned BrotliRBit(unsigned input) {
   unsigned output;
   __asm__("rbit %0, %1\n" : "=r"(output) : "r"(input));
@@ -180,6 +231,12 @@
 #endif  /* armv7 */
 #endif  /* gcc || clang */
 
+#if defined(BROTLI_TARGET_ARM)
+#define BROTLI_HAS_UBFX 1
+#else
+#define BROTLI_HAS_UBFX 0
+#endif
+
 #define BROTLI_FREE(X) { \
   free(X); \
   X = NULL; \
diff --git a/third_party/brotli/dec/prefix.h b/third_party/brotli/dec/prefix.h
index 0d77f6e..91e43e92 100644
--- a/third_party/brotli/dec/prefix.h
+++ b/third_party/brotli/dec/prefix.h
@@ -23,7 +23,7 @@
 /* Represents the range of values belonging to a prefix code: */
 /* [offset, offset + 2^nbits) */
 struct PrefixCodeRange {
-  int16_t offset;
+  uint16_t offset;
   uint8_t nbits;
 };
 
diff --git a/third_party/brotli/dec/state.c b/third_party/brotli/dec/state.c
index d32dfd3..f4f239a 100644
--- a/third_party/brotli/dec/state.c
+++ b/third_party/brotli/dec/state.c
@@ -24,6 +24,7 @@
 #endif
 
 void BrotliStateInit(BrotliState* s) {
+  BrotliInitBitReader(&s->br);
   s->state = BROTLI_STATE_UNINITED;
   s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE;
   s->substate_tree_group = BROTLI_STATE_TREE_GROUP_NONE;
@@ -31,9 +32,13 @@
   s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_NONE;
   s->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
   s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_NONE;
+  s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_NONE;
 
+  s->buffer_length = 0;
   s->loop_counter = 0;
   s->pos = 0;
+  s->rb_roundtrips = 0;
+  s->partial_pos_out = 0;
 
   s->block_type_trees = NULL;
   s->block_len_trees = NULL;
@@ -45,6 +50,8 @@
   s->context_map_slice = NULL;
   s->dist_context_map_slice = NULL;
 
+  s->sub_loop_counter = 0;
+
   s->literal_hgroup.codes = NULL;
   s->literal_hgroup.htrees = NULL;
   s->insert_copy_hgroup.codes = NULL;
@@ -71,13 +78,20 @@
   s->symbol_lists = &s->symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1];
 
   s->mtf_upper_bound = 255;
+
+  s->legacy_input_buffer = 0;
+  s->legacy_output_buffer = 0;
+  s->legacy_input_len = 0;
+  s->legacy_output_len = 0;
+  s->legacy_input_pos = 0;
+  s->legacy_output_pos = 0;
 }
 
 void BrotliStateMetablockBegin(BrotliState* s) {
   s->meta_block_remaining_len = 0;
-  s->block_length[0] = 1 << 28;
-  s->block_length[1] = 1 << 28;
-  s->block_length[2] = 1 << 28;
+  s->block_length[0] = 1U << 28;
+  s->block_length[1] = 1U << 28;
+  s->block_length[2] = 1U << 28;
   s->num_block_types[0] = 1;
   s->num_block_types[1] = 1;
   s->num_block_types[2] = 1;
@@ -113,27 +127,27 @@
   BrotliHuffmanTreeGroupRelease(&s->literal_hgroup);
   BrotliHuffmanTreeGroupRelease(&s->insert_copy_hgroup);
   BrotliHuffmanTreeGroupRelease(&s->distance_hgroup);
-  s->literal_hgroup.codes = NULL;
-  s->literal_hgroup.htrees = NULL;
-  s->insert_copy_hgroup.codes = NULL;
-  s->insert_copy_hgroup.htrees = NULL;
-  s->distance_hgroup.codes = NULL;
-  s->distance_hgroup.htrees = NULL;
 }
 
 void BrotliStateCleanup(BrotliState* s) {
-  BROTLI_FREE(s->context_modes);
-  BROTLI_FREE(s->context_map);
-  BROTLI_FREE(s->dist_context_map);
-
-  BrotliHuffmanTreeGroupRelease(&s->literal_hgroup);
-  BrotliHuffmanTreeGroupRelease(&s->insert_copy_hgroup);
-  BrotliHuffmanTreeGroupRelease(&s->distance_hgroup);
+  BrotliStateCleanupAfterMetablock(s);
 
   BROTLI_FREE(s->ringbuffer);
   BROTLI_FREE(s->block_type_trees);
+  BROTLI_FREE(s->legacy_input_buffer);
+  BROTLI_FREE(s->legacy_output_buffer);
 }
 
+int BrotliStateIsStreamStart(const BrotliState* s) {
+  return (s->state == BROTLI_STATE_UNINITED &&
+      BrotliGetAvailableBits(&s->br) == 0);
+}
+
+int BrotliStateIsStreamEnd(const BrotliState* s) {
+  return s->state == BROTLI_STATE_DONE;
+}
+
+
 #if defined(__cplusplus) || defined(c_plusplus)
 } /* extern "C" */
 #endif
diff --git a/third_party/brotli/dec/state.h b/third_party/brotli/dec/state.h
index 241ee6cc..0d9329b 100644
--- a/third_party/brotli/dec/state.h
+++ b/third_party/brotli/dec/state.h
@@ -21,7 +21,6 @@
 #include <stdio.h>
 #include "./bit_reader.h"
 #include "./huffman.h"
-#include "./streams.h"
 #include "./types.h"
 
 #if defined(__cplusplus) || defined(c_plusplus)
@@ -30,19 +29,20 @@
 
 typedef enum {
   BROTLI_STATE_UNINITED,
-  BROTLI_STATE_BITREADER_WARMUP,
   BROTLI_STATE_METABLOCK_BEGIN,
   BROTLI_STATE_METABLOCK_HEADER,
+  BROTLI_STATE_METABLOCK_HEADER_2,
   BROTLI_STATE_CONTEXT_MODES,
   BROTLI_STATE_COMMAND_BEGIN,
   BROTLI_STATE_COMMAND_INNER,
+  BROTLI_STATE_COMMAND_POST_DECODE_LITERALS,
+  BROTLI_STATE_COMMAND_POST_WRAP_COPY,
   BROTLI_STATE_UNCOMPRESSED,
   BROTLI_STATE_METADATA,
   BROTLI_STATE_COMMAND_INNER_WRITE,
   BROTLI_STATE_METABLOCK_DONE,
   BROTLI_STATE_COMMAND_POST_WRITE_1,
   BROTLI_STATE_COMMAND_POST_WRITE_2,
-  BROTLI_STATE_COMMAND_POST_WRAP_COPY,
   BROTLI_STATE_HUFFMAN_CODE_0,
   BROTLI_STATE_HUFFMAN_CODE_1,
   BROTLI_STATE_HUFFMAN_CODE_2,
@@ -66,8 +66,6 @@
 
 typedef enum {
   BROTLI_STATE_UNCOMPRESSED_NONE,
-  BROTLI_STATE_UNCOMPRESSED_SHORT,
-  BROTLI_STATE_UNCOMPRESSED_COPY,
   BROTLI_STATE_UNCOMPRESSED_WRITE
 } BrotliRunningUncompressedState;
 
@@ -80,11 +78,16 @@
   BROTLI_STATE_CONTEXT_MAP_NONE,
   BROTLI_STATE_CONTEXT_MAP_READ_PREFIX,
   BROTLI_STATE_CONTEXT_MAP_HUFFMAN,
-  BROTLI_STATE_CONTEXT_MAP_DECODE
+  BROTLI_STATE_CONTEXT_MAP_DECODE,
+  BROTLI_STATE_CONTEXT_MAP_TRANSFORM
 } BrotliRunningContextMapState;
 
 typedef enum {
   BROTLI_STATE_HUFFMAN_NONE,
+  BROTLI_STATE_HUFFMAN_SIMPLE_SIZE,
+  BROTLI_STATE_HUFFMAN_SIMPLE_READ,
+  BROTLI_STATE_HUFFMAN_SIMPLE_BUILD,
+  BROTLI_STATE_HUFFMAN_COMPLEX,
   BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS
 } BrotliRunningHuffmanState;
 
@@ -94,10 +97,23 @@
   BROTLI_STATE_DECODE_UINT8_LONG
 } BrotliRunningDecodeUint8State;
 
-typedef struct {
+typedef enum {
+  BROTLI_STATE_READ_BLOCK_LENGTH_NONE,
+  BROTLI_STATE_READ_BLOCK_LENGTH_SUFFIX
+} BrotliRunningReadBlockLengthState;
+
+struct BrotliStateStruct {
   BrotliRunningState state;
-  /* This counter is reused for several disjoint loops. */
   BrotliBitReader br;
+
+  /* Temporary storage for remaining input. */
+  union {
+    uint64_t u64;
+    uint8_t u8[8];
+  } buffer;
+  uint32_t buffer_length;
+
+  /* This counter is reused for several disjoint loops. */
   int loop_counter;
   int pos;
   int max_backward_distance;
@@ -115,6 +131,8 @@
   uint8_t* context_map_slice;
   uint8_t* dist_context_map_slice;
 
+  uint32_t sub_loop_counter;
+
   /* This ring buffer holds a few past copy distances that will be used by */
   /* some special distance codes. */
   HuffmanTreeGroup literal_hgroup;
@@ -127,7 +145,8 @@
   int trivial_literal_context;
   int distance_context;
   int meta_block_remaining_len;
-  int block_length[3];
+  uint32_t block_length_index;
+  uint32_t block_length[3];
   uint32_t num_block_types[3];
   uint32_t block_type_rb[6];
   uint32_t distance_postfix_bits;
@@ -138,16 +157,16 @@
   HuffmanCode *literal_htree;
   uint8_t literal_htree_index;
   uint8_t dist_htree_index;
-  uint8_t repeat_code_len;
-  uint8_t prev_code_len;
+  uint32_t repeat_code_len;
+  uint32_t prev_code_len;
 
 
   int copy_length;
   int distance_code;
 
   /* For partial write operations */
-  int to_write;
-  int partially_written;
+  size_t rb_roundtrips;  /* How many times we went around the ringbuffer */
+  size_t partial_pos_out;  /* How much output to the user in total (<= rb) */
 
   /* For ReadHuffmanCode */
   uint32_t symbol;
@@ -173,6 +192,7 @@
   /* For DecodeContextMap */
   uint32_t context_index;
   uint32_t max_run_length_prefix;
+  uint32_t code;
   HuffmanCode context_map_table[BROTLI_HUFFMAN_MAX_TABLE_SIZE];
 
   /* For InverseMoveToFrontTransform */
@@ -191,6 +211,7 @@
   BrotliRunningUncompressedState substate_uncompressed;
   BrotliRunningHuffmanState substate_huffman;
   BrotliRunningDecodeUint8State substate_decode_uint8;
+  BrotliRunningReadBlockLengthState substate_read_block_length;
 
   uint8_t is_last_metablock;
   uint8_t is_uncompressed;
@@ -201,13 +222,32 @@
   uint32_t num_literal_htrees;
   uint8_t* context_map;
   uint8_t* context_modes;
-} BrotliState;
+
+  uint8_t* legacy_input_buffer;
+  uint8_t* legacy_output_buffer;
+  size_t legacy_input_len;
+  size_t legacy_output_len;
+  size_t legacy_input_pos;
+  size_t legacy_output_pos;
+};
+
+typedef struct BrotliStateStruct BrotliState;
 
 void BrotliStateInit(BrotliState* s);
 void BrotliStateCleanup(BrotliState* s);
 void BrotliStateMetablockBegin(BrotliState* s);
 void BrotliStateCleanupAfterMetablock(BrotliState* s);
 
+
+/* Returns 1, if s is in a state where we have not read any input bytes yet,
+   and 0 otherwise */
+int BrotliStateIsStreamStart(const BrotliState* s);
+
+/* Returns 1, if s is in a state where we reached the end of the input and
+   produced all of the output, and 0 otherwise. */
+int BrotliStateIsStreamEnd(const BrotliState* s);
+
+
 #if defined(__cplusplus) || defined(c_plusplus)
 } /* extern "C" */
 #endif
diff --git a/third_party/brotli/dec/streams.c b/third_party/brotli/dec/streams.c
index f7060a9..007c513 100644
--- a/third_party/brotli/dec/streams.c
+++ b/third_party/brotli/dec/streams.c
@@ -99,7 +99,7 @@
   return (int)count;
 }
 
-BrotliOutput BrotliNullOutput() {
+BrotliOutput BrotliNullOutput(void) {
   BrotliOutput out;
   out.cb_ = BrotliNullOutputFunction;
   out.data_ = NULL;
diff --git a/third_party/brotli/dec/streams.h b/third_party/brotli/dec/streams.h
index decfa7e..99eb125 100644
--- a/third_party/brotli/dec/streams.h
+++ b/third_party/brotli/dec/streams.h
@@ -95,7 +95,7 @@
 
 /* Output callback that does nothing, always consumes the whole input. */
 int BrotliNullOutputFunction(void* data, const uint8_t* buf, size_t count);
-BrotliOutput BrotliNullOutput();
+BrotliOutput BrotliNullOutput(void);
 
 #if defined(__cplusplus) || defined(c_plusplus)
 }    /* extern "C" */
diff --git a/third_party/brotli/dec/types.h b/third_party/brotli/dec/types.h
index e7e5ab1..8a9cc4a8 100644
--- a/third_party/brotli/dec/types.h
+++ b/third_party/brotli/dec/types.h
@@ -21,14 +21,14 @@
 #include <stddef.h>  /* for size_t */
 
 #if defined(_MSC_VER) && (_MSC_VER < 1600)
-typedef signed   char int8_t;
-typedef unsigned char uint8_t;
-typedef signed   short int16_t;
-typedef unsigned short uint16_t;
-typedef signed   int int32_t;
-typedef unsigned int uint32_t;
-typedef unsigned long long int uint64_t;
-typedef long long int int64_t;
+typedef __int8 int8_t;
+typedef unsigned __int8 uint8_t;
+typedef __int16 int16_t;
+typedef unsigned __int16 uint16_t;
+typedef __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+typedef unsigned __int64 uint64_t;
+typedef __int64 int64_t;
 #else
 #include <stdint.h>
 #endif  /* defined(_MSC_VER) && (_MSC_VER < 1600) */
diff --git a/ui/metro_viewer/metro_viewer_messages.h b/ui/metro_viewer/metro_viewer_messages.h
index ad7690c..068909f26 100644
--- a/ui/metro_viewer/metro_viewer_messages.h
+++ b/ui/metro_viewer/metro_viewer_messages.h
@@ -49,21 +49,21 @@
                      uint32,       /* virtual key */
                      uint32,       /* repeat count */
                      uint32,       /* scan code */
-                     uint32        /* key state */);
+                     uint32        /* key state */)
 // Informs the browser that a key was released.
 IPC_MESSAGE_CONTROL4(MetroViewerHostMsg_KeyUp,
                      uint32,       /* virtual key */
                      uint32,       /* repeat count */
                      uint32,       /* scan code */
-                     uint32        /* key state */);
+                     uint32        /* key state */)
 IPC_MESSAGE_CONTROL4(MetroViewerHostMsg_Character,
                      uint32,       /* virtual key */
                      uint32,       /* repeat count */
                      uint32,       /* scan code */
-                     uint32        /* key state */);
+                     uint32        /* key state */)
 // Informs the browser that the Metro window has been activated.
 IPC_MESSAGE_CONTROL1(MetroViewerHostMsg_WindowActivated,
-                     bool /* Whether the window should be repainted */);
+                     bool /* Whether the window should be repainted */)
 
 // Informs the browser that the user has completed an edge gesture.
 IPC_MESSAGE_CONTROL0(MetroViewerHostMsg_EdgeGesture)
@@ -109,19 +109,19 @@
 // Requests the viewer to activate desktop mode.
 IPC_MESSAGE_CONTROL2(MetroViewerHostMsg_ActivateDesktop,
                      base::FilePath /* shortcut */,
-                     bool           /* ash exit */);
+                     bool           /* ash exit */)
 
 // Request the viewer to close itself gracefully.
-IPC_MESSAGE_CONTROL0(MetroViewerHostMsg_MetroExit);
+IPC_MESSAGE_CONTROL0(MetroViewerHostMsg_MetroExit)
 
 // Requests the viewer to open a URL in desktop mode.
 IPC_MESSAGE_CONTROL2(MetroViewerHostMsg_OpenURLOnDesktop,
-                     base::FilePath,  /* shortcut */
-                     base::string16         /* url */);
+                     base::FilePath /* shortcut */,
+                     base::string16 /* url */)
 
 // Requests the viewer to change the pointer to a new cursor.
 IPC_MESSAGE_CONTROL1(MetroViewerHostMsg_SetCursor,
-                     int64         /* cursor */);
+                     int64         /* cursor */)
 
 // This structure contains the parameters sent to the viewer process to display
 // the file save dialog.