diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-api-utils.js b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-api-utils.js
deleted file mode 100644
index cf2376e..0000000
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-api-utils.js
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * @license
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-(function(window) {
-  'use strict';
-
-  const PRELOADED_PROTOCOL = 'preloaded:';
-
-  let _restAPI;
-
-  const getRestAPI = () => {
-    if (!_restAPI) {
-      _restAPI = document.createElement('gr-rest-api-interface');
-    }
-    return _restAPI;
-  };
-
-  function getPluginNameFromUrl(url) {
-    if (!(url instanceof URL)) {
-      try {
-        url = new URL(url);
-      } catch (e) {
-        console.warn(e);
-        return null;
-      }
-    }
-    if (url.protocol === PRELOADED_PROTOCOL) {
-      return url.pathname;
-    }
-    const base = Gerrit.BaseUrlBehavior.getBaseUrl();
-    const pathname = url.pathname.replace(base, '');
-    // Site theme is server from predefined path.
-    if (pathname === '/static/gerrit-theme.html') {
-      return 'gerrit-theme';
-    } else if (!pathname.startsWith('/plugins')) {
-      console.warn('Plugin not being loaded from /plugins base path:',
-          url.href, '— Unable to determine name.');
-      return null;
-    }
-    // Pathname should normally look like this:
-    // /plugins/PLUGINNAME/static/SCRIPTNAME.html
-    // Or, for app/samples:
-    // /plugins/PLUGINNAME.html
-    return pathname.split('/')[2].split('.')[0];
-  }
-
-  // TODO (viktard): deprecate in favor of GrPluginRestApi.
-  function send(method, url, opt_callback, opt_payload) {
-    return getRestAPI().send(method, url, opt_payload).then(response => {
-      if (response.status < 200 || response.status >= 300) {
-        return response.text().then(text => {
-          if (text) {
-            return Promise.reject(text);
-          } else {
-            return Promise.reject(response.status);
-          }
-        });
-      } else {
-        return getRestAPI().getResponseObject(response);
-      }
-    }).then(response => {
-      if (opt_callback) {
-        opt_callback(response);
-      }
-      return response;
-    });
-  }
-
-  function resetInternalState() {
-    _restAPI = null;
-  }
-
-  window._apiUtils = {
-    getPluginNameFromUrl,
-    send,
-    getRestAPI,
-
-    // TEST only methods
-    resetInternalState,
-  };
-})(window);
\ No newline at end of file
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-api-utils_test.html b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-api-utils_test.html
deleted file mode 100644
index c407aa8..0000000
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-api-utils_test.html
+++ /dev/null
@@ -1,78 +0,0 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<title>gr-api-interface</title>
-<script src="/test/common-test-setup.js"></script>
-<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/bower_components/web-component-tester/browser.js"></script>
-<link rel="import" href="../../../test/common-test-setup.html"/>
-<link rel="import" href="gr-js-api-interface.html">
-
-<script>void(0);</script>
-
-<script>
-
-  const PRELOADED_PROTOCOL = 'preloaded:';
-
-  suite('gr-api-utils tests', () => {
-    suite('test getPluginNameFromUrl', () => {
-      const {getPluginNameFromUrl} = window._apiUtils;
-
-      test('with empty string', () => {
-        assert.equal(getPluginNameFromUrl(''), null);
-      });
-
-      test('with invalid url', () => {
-        assert.equal(getPluginNameFromUrl('test'), null);
-      });
-
-      test('with random invalid url', () => {
-        assert.equal(getPluginNameFromUrl('http://example.com'), null);
-        assert.equal(
-            getPluginNameFromUrl('http://example.com/static/a.html'),
-            null
-        );
-      });
-
-      test('with valid urls', () => {
-        assert.equal(
-            getPluginNameFromUrl('http://example.com/plugins/a.html'),
-            'a'
-        );
-        assert.equal(
-            getPluginNameFromUrl('http://example.com/plugins/a/static/t.html'),
-            'a'
-        );
-      });
-
-      test('with preloaded urls', () => {
-        assert.equal(getPluginNameFromUrl(`${PRELOADED_PROTOCOL}a`), 'a');
-      });
-
-      test('with gerrit-theme override', () => {
-        assert.equal(
-            getPluginNameFromUrl('http://example.com/static/gerrit-theme.html'),
-            'gerrit-theme'
-        );
-      });
-    });
-  });
-</script>
\ No newline at end of file
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-gerrit.js b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-gerrit.js
deleted file mode 100644
index 8cdbcb7..0000000
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-gerrit.js
+++ /dev/null
@@ -1,280 +0,0 @@
-/**
- * @license
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-(function(window) {
-  'use strict';
-
-  /**
-   * Hash of loaded and installed plugins, name to Plugin object.
-   */
-  const _plugins = {};
-
-  /**
-   * Array of plugin URLs to be loaded, name to url.
-   */
-  let _pluginsPending = {};
-
-  let _pluginsInstalled = [];
-
-  let _pluginsPendingCount = -1;
-
-  const UNKNOWN_PLUGIN = 'unknown';
-  const PRELOADED_PROTOCOL = 'preloaded:';
-
-  const PLUGIN_LOADING_TIMEOUT_MS = 10000;
-
-  let _reporting;
-  const getReporting = () => {
-    if (!_reporting) {
-      _reporting = document.createElement('gr-reporting');
-    }
-    return _reporting;
-  };
-
-  // Import utils methods
-  const {
-      getPluginNameFromUrl,
-      send,
-      getRestAPI,
-      resetInternalState,
-  } = window._apiUtils;
-
-  const API_VERSION = '0.1';
-
-  window.Gerrit = window.Gerrit || {};
-  const Gerrit = window.Gerrit;
-
-  let _resolveAllPluginsLoaded = null;
-  let _allPluginsPromise = null;
-
-  Gerrit._endpoints = new GrPluginEndpoints();
-
-  // Provide reset plugins function to clear installed plugins between tests.
-  const app = document.querySelector('#app');
-  if (!app) {
-    // No gr-app found (running tests)
-    Gerrit._installPreloadedPlugins = installPreloadedPlugins;
-    Gerrit._flushPreinstalls = flushPreinstalls;
-    Gerrit._resetPlugins = () => {
-      _allPluginsPromise = null;
-      _pluginsInstalled = [];
-      _pluginsPending = {};
-      _pluginsPendingCount = -1;
-      _reporting = null;
-      _resolveAllPluginsLoaded = null;
-      resetInternalState();
-      Gerrit._endpoints = new GrPluginEndpoints();
-      for (const k of Object.keys(_plugins)) {
-        delete _plugins[k];
-      }
-    };
-  }
-
-  /**
-   * @deprecated Use plugin.styles().css(rulesStr) instead. Please, consult
-   * the documentation how to replace it accordingly.
-   */
-  Gerrit.css = function(rulesStr) {
-    console.warn('Gerrit.css(rulesStr) is deprecated!',
-        'Use plugin.styles().css(rulesStr)');
-    if (!Gerrit._customStyleSheet) {
-      const styleEl = document.createElement('style');
-      document.head.appendChild(styleEl);
-      Gerrit._customStyleSheet = styleEl.sheet;
-    }
-
-    const name = '__pg_js_api_class_' +
-        Gerrit._customStyleSheet.cssRules.length;
-    Gerrit._customStyleSheet.insertRule('.' + name + '{' + rulesStr + '}', 0);
-    return name;
-  };
-
-  Gerrit.install = function(callback, opt_version, opt_src) {
-    // HTML import polyfill adds __importElement pointing to the import tag.
-    const script = document.currentScript &&
-        (document.currentScript.__importElement || document.currentScript);
-
-    let src = opt_src || (script && script.src);
-    if (!src || src.startsWith('data:')) {
-      src = script && script.baseURI;
-    }
-    const name = getPluginNameFromUrl(src);
-
-    if (opt_version && opt_version !== API_VERSION) {
-      Gerrit._pluginInstallError(`Plugin ${name} install error: only version ` +
-          API_VERSION + ' is supported in PolyGerrit. ' + opt_version +
-          ' was given.');
-      return;
-    }
-
-    const existingPlugin = _plugins[name];
-    const plugin = existingPlugin || new Plugin(src);
-    try {
-      callback(plugin);
-      if (name) {
-        _plugins[name] = plugin;
-      }
-      if (!existingPlugin) {
-        Gerrit._pluginInstalled(src);
-      }
-    } catch (e) {
-      Gerrit._pluginInstallError(`${e.name}: ${e.message}`);
-    }
-  };
-
-  Gerrit.getLoggedIn = function() {
-    console.warn('Gerrit.getLoggedIn() is deprecated! ' +
-        'Use plugin.restApi().getLoggedIn()');
-    return document.createElement('gr-rest-api-interface').getLoggedIn();
-  };
-
-  Gerrit.get = function(url, callback) {
-    console.warn('.get() is deprecated! Use plugin.restApi().get()');
-    send('GET', url, callback);
-  };
-
-  Gerrit.post = function(url, payload, callback) {
-    console.warn('.post() is deprecated! Use plugin.restApi().post()');
-    send('POST', url, callback, payload);
-  };
-
-  Gerrit.put = function(url, payload, callback) {
-    console.warn('.put() is deprecated! Use plugin.restApi().put()');
-    send('PUT', url, callback, payload);
-  };
-
-  Gerrit.delete = function(url, opt_callback) {
-    console.warn('.delete() is deprecated! Use plugin.restApi().delete()');
-    return getRestAPI().send('DELETE', url).then(response => {
-      if (response.status !== 204) {
-        return response.text().then(text => {
-          if (text) {
-            return Promise.reject(text);
-          } else {
-            return Promise.reject(response.status);
-          }
-        });
-      }
-      if (opt_callback) {
-        opt_callback(response);
-      }
-      return response;
-    });
-  };
-
-  Gerrit.awaitPluginsLoaded = function() {
-    if (!_allPluginsPromise) {
-      if (Gerrit._arePluginsLoaded()) {
-        _allPluginsPromise = Promise.resolve();
-      } else {
-        let timeoutId;
-        _allPluginsPromise =
-          Promise.race([
-            new Promise(resolve => _resolveAllPluginsLoaded = resolve),
-            new Promise(resolve => timeoutId = setTimeout(
-                Gerrit._pluginLoadingTimeout, PLUGIN_LOADING_TIMEOUT_MS)),
-          ]).then(() => clearTimeout(timeoutId));
-      }
-    }
-    return _allPluginsPromise;
-  };
-
-  Gerrit._pluginLoadingTimeout = function() {
-    console.error(`Failed to load plugins: ${Object.keys(_pluginsPending)}`);
-    Gerrit._setPluginsPending([]);
-  };
-
-  Gerrit._setPluginsPending = function(plugins) {
-    _pluginsPending = plugins.reduce((o, url) => {
-      // TODO(viktard): Remove guard (@see Issue 8962)
-      o[getPluginNameFromUrl(url) || UNKNOWN_PLUGIN] = url;
-      return o;
-    }, {});
-    Gerrit._setPluginsCount(Object.keys(_pluginsPending).length);
-  };
-
-  Gerrit._setPluginsCount = function(count) {
-    _pluginsPendingCount = count;
-    if (Gerrit._arePluginsLoaded()) {
-      getReporting().pluginsLoaded(_pluginsInstalled);
-      if (_resolveAllPluginsLoaded) {
-        _resolveAllPluginsLoaded();
-      }
-    }
-  };
-
-  Gerrit._pluginInstallError = function(message) {
-    document.dispatchEvent(new CustomEvent('show-alert', {
-      detail: {
-        message: `Plugin install error: ${message}`,
-      },
-    }));
-    console.info(`Plugin install error: ${message}`);
-    Gerrit._setPluginsCount(_pluginsPendingCount - 1);
-  };
-
-  Gerrit._pluginInstalled = function(url) {
-    const name = getPluginNameFromUrl(url) || UNKNOWN_PLUGIN;
-    if (!_pluginsPending[name]) {
-      console.warn(`Unexpected plugin ${name} installed from ${url}.`);
-    } else {
-      delete _pluginsPending[name];
-      _pluginsInstalled.push(name);
-      Gerrit._setPluginsCount(_pluginsPendingCount - 1);
-      getReporting().pluginLoaded(name);
-      console.log(`Plugin ${name} installed.`);
-    }
-  };
-
-  Gerrit._arePluginsLoaded = function() {
-    return _pluginsPendingCount === 0;
-  };
-
-  Gerrit._getPluginScreenName = function(pluginName, screenName) {
-    return `${pluginName}-screen-${screenName}`;
-  };
-
-  Gerrit._isPluginPreloaded = function(url) {
-    const name = getPluginNameFromUrl(url);
-    if (name && Gerrit._preloadedPlugins) {
-      return name in Gerrit._preloadedPlugins;
-    } else {
-      return false;
-    }
-  };
-
-  function flushPreinstalls() {
-    if (window.Gerrit.flushPreinstalls) {
-      window.Gerrit.flushPreinstalls();
-    }
-  }
-
-  function installPreloadedPlugins() {
-    if (!Gerrit._preloadedPlugins) { return; }
-    for (const name in Gerrit._preloadedPlugins) {
-      if (!Gerrit._preloadedPlugins.hasOwnProperty(name)) { continue; }
-      const callback = Gerrit._preloadedPlugins[name];
-      Gerrit.install(callback, API_VERSION, PRELOADED_PROTOCOL + name);
-    }
-  }
-
-  flushPreinstalls();
-
-  // Preloaded plugins should be installed after Gerrit.install() is set,
-  // since plugin preloader substitutes Gerrit.install() temporarily.
-  installPreloadedPlugins();
-})(window);
\ No newline at end of file
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-gerrit_test.html b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-gerrit_test.html
deleted file mode 100644
index b3ec30f..0000000
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-gerrit_test.html
+++ /dev/null
@@ -1,188 +0,0 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<title>gr-api-interface</title>
-<script src="/test/common-test-setup.js"></script>
-<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/bower_components/web-component-tester/browser.js"></script>
-<link rel="import" href="../../../test/common-test-setup.html"/>
-<link rel="import" href="gr-js-api-interface.html">
-
-<script>void(0);</script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-js-api-interface></gr-js-api-interface>
-  </template>
-</test-fixture>
-
-<script>
-  suite('gr-gerrit tests', () => {
-    let element;
-    let plugin;
-    let sandbox;
-    let sendStub;
-
-    setup(() => {
-      sandbox = sinon.sandbox.create();
-      sendStub = sandbox.stub().returns(Promise.resolve({status: 200}));
-      stub('gr-rest-api-interface', {
-        getAccount() {
-          return Promise.resolve({name: 'Judy Hopps'});
-        },
-        send(...args) {
-          return sendStub(...args);
-        },
-      });
-      element = fixture('basic');
-      Gerrit.install(p => { plugin = p; }, '0.1',
-          'http://test.com/plugins/testplugin/static/test.js');
-      Gerrit._setPluginsPending([]);
-    });
-
-    teardown(() => {
-      sandbox.restore();
-      element._removeEventCallbacks();
-      plugin = null;
-    });
-
-    test('reuse plugin for install calls', () => {
-      let otherPlugin;
-      Gerrit.install(p => { otherPlugin = p; }, '0.1',
-          'http://test.com/plugins/testplugin/static/test.js');
-      assert.strictEqual(plugin, otherPlugin);
-    });
-
-    test('flushes preinstalls if provided', () => {
-      assert.doesNotThrow(() => {
-        Gerrit._flushPreinstalls();
-      });
-      window.Gerrit.flushPreinstalls = sandbox.stub();
-      Gerrit._flushPreinstalls();
-      assert.isTrue(window.Gerrit.flushPreinstalls.calledOnce);
-      delete window.Gerrit.flushPreinstalls;
-    });
-
-    test('versioning', () => {
-      const callback = sandbox.spy();
-      Gerrit.install(callback, '0.0pre-alpha');
-      assert(callback.notCalled);
-    });
-
-    test('_setPluginsCount', done => {
-      stub('gr-reporting', {
-        pluginsLoaded() {
-          done();
-        },
-      });
-      Gerrit._setPluginsCount(0);
-    });
-
-    test('_arePluginsLoaded', () => {
-      assert.isTrue(Gerrit._arePluginsLoaded());
-      Gerrit._setPluginsCount(1);
-      assert.isFalse(Gerrit._arePluginsLoaded());
-      Gerrit._setPluginsCount(0);
-      assert.isTrue(Gerrit._arePluginsLoaded());
-    });
-
-    test('_pluginInstalled', () => {
-      const pluginsLoadedStub = sandbox.stub();
-      stub('gr-reporting', {
-        pluginsLoaded: (...args) => pluginsLoadedStub(...args),
-      });
-      const plugins = [
-        'http://test.com/plugins/foo/static/test.js',
-        'http://test.com/plugins/bar/static/test.js',
-      ];
-      Gerrit._setPluginsPending(plugins);
-      Gerrit._pluginInstalled(plugins[0]);
-      Gerrit._pluginInstalled(plugins[1]);
-      assert.isTrue(pluginsLoadedStub.calledWithExactly(['foo', 'bar']));
-    });
-
-    test('install calls _pluginInstalled', () => {
-      sandbox.stub(Gerrit, '_pluginInstalled');
-      Gerrit.install(p => { plugin = p; }, '0.1',
-          'http://test.com/plugins/testplugin/static/test.js');
-
-      // testplugin has already been installed once (in setup).
-      assert.isFalse(Gerrit._pluginInstalled.called);
-
-      // testplugin2 plugin has not yet been installed.
-      Gerrit.install(p => { plugin = p; }, '0.1',
-          'http://test.com/plugins/testplugin2/static/test.js');
-      assert.isTrue(Gerrit._pluginInstalled.calledOnce);
-    });
-
-    test('plugin install errors mark plugins as loaded', () => {
-      Gerrit._setPluginsCount(1);
-      Gerrit.install(() => {}, '0.0pre-alpha');
-      return Gerrit.awaitPluginsLoaded();
-    });
-
-    test('multiple ui plugins per java plugin', () => {
-      const file1 = 'http://test.com/plugins/qaz/static/foo.nocache.js';
-      const file2 = 'http://test.com/plugins/qaz/static/bar.js';
-      Gerrit._setPluginsPending([file1, file2]);
-      Gerrit.install(() => {}, '0.1', file1);
-      Gerrit.install(() => {}, '0.1', file2);
-      return Gerrit.awaitPluginsLoaded();
-    });
-
-    test('plugin install errors shows toasts', () => {
-      const alertStub = sandbox.stub();
-      document.addEventListener('show-alert', alertStub);
-      Gerrit._setPluginsCount(1);
-      Gerrit.install(() => {}, '0.0pre-alpha');
-      return Gerrit.awaitPluginsLoaded().then(() => {
-        assert.isTrue(alertStub.calledOnce);
-      });
-    });
-
-    test('Gerrit._isPluginPreloaded', () => {
-      Gerrit._preloadedPlugins = {baz: ()=>{}};
-      assert.isFalse(Gerrit._isPluginPreloaded('plugins/foo/bar'));
-      assert.isFalse(Gerrit._isPluginPreloaded('http://a.com/42'));
-      assert.isTrue(Gerrit._isPluginPreloaded('preloaded:baz'));
-      Gerrit._preloadedPlugins = null;
-    });
-
-    test('preloaded plugins are installed', () => {
-      const installStub = sandbox.stub();
-      Gerrit._preloadedPlugins = {foo: installStub};
-      Gerrit._installPreloadedPlugins();
-      assert.isTrue(installStub.called);
-      const pluginApi = installStub.lastCall.args[0];
-      assert.strictEqual(pluginApi.getPluginName(), 'foo');
-    });
-
-    test('installing preloaded plugin', () => {
-      let plugin;
-      window.ASSETS_PATH = 'http://blips.com/chitz';
-      Gerrit.install(p => { plugin = p; }, '0.1', 'preloaded:foo');
-      assert.strictEqual(plugin.getPluginName(), 'foo');
-      assert.strictEqual(plugin.url('/some/thing.html'),
-          'http://blips.com/chitz/plugins/foo/some/thing.html');
-      delete window.ASSETS_PATH;
-    });
-  });
-</script>
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.html b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.html
index 7fa2250..e460660 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.html
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.html
@@ -31,7 +31,6 @@
 <link rel="import" href="../gr-rest-api-interface/gr-rest-api-interface.html">
 
 <dom-module id="gr-js-api-interface">
-  <script src="gr-api-utils.js"></script>
   <script src="gr-annotation-actions-context.js"></script>
   <script src="gr-annotation-actions-js-api.js"></script>
   <script src="gr-change-actions-js-api.js"></script>
@@ -41,5 +40,4 @@
   <script src="gr-plugin-action-context.js"></script>
   <script src="gr-plugin-rest-api.js"></script>
   <script src="gr-public-js-api.js"></script>
-  <script src="gr-gerrit.js"></script>
 </dom-module>
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface_test.html b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface_test.html
index 330310f..c7e4f09 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface_test.html
@@ -73,6 +73,23 @@
       plugin = null;
     });
 
+    test('reuse plugin for install calls', () => {
+      let otherPlugin;
+      Gerrit.install(p => { otherPlugin = p; }, '0.1',
+          'http://test.com/plugins/testplugin/static/test.js');
+      assert.strictEqual(plugin, otherPlugin);
+    });
+
+    test('flushes preinstalls if provided', () => {
+      assert.doesNotThrow(() => {
+        Gerrit._flushPreinstalls();
+      });
+      window.Gerrit.flushPreinstalls = sandbox.stub();
+      Gerrit._flushPreinstalls();
+      assert.isTrue(window.Gerrit.flushPreinstalls.calledOnce);
+      delete window.Gerrit.flushPreinstalls;
+    });
+
     test('url', () => {
       assert.equal(plugin.url(), 'http://test.com/plugins/testplugin/');
       assert.equal(plugin.url('/static/test.js'),
@@ -296,6 +313,12 @@
       element.handleEvent(element.EventType.HIGHLIGHTJS_LOADED, {hljs: testHljs});
     });
 
+    test('versioning', () => {
+      const callback = sandbox.spy();
+      Gerrit.install(callback, '0.0pre-alpha');
+      assert(callback.notCalled);
+    });
+
     test('getAccount', done => {
       plugin.restApi().getLoggedIn().then(loggedIn => {
         assert.isTrue(loggedIn);
@@ -303,6 +326,77 @@
       });
     });
 
+    test('_setPluginsCount', done => {
+      stub('gr-reporting', {
+        pluginsLoaded() {
+          done();
+        },
+      });
+      Gerrit._setPluginsCount(0);
+    });
+
+    test('_arePluginsLoaded', () => {
+      assert.isTrue(Gerrit._arePluginsLoaded());
+      Gerrit._setPluginsCount(1);
+      assert.isFalse(Gerrit._arePluginsLoaded());
+      Gerrit._setPluginsCount(0);
+      assert.isTrue(Gerrit._arePluginsLoaded());
+    });
+
+    test('_pluginInstalled', () => {
+      const pluginsLoadedStub = sandbox.stub();
+      stub('gr-reporting', {
+        pluginsLoaded: (...args) => pluginsLoadedStub(...args),
+      });
+      const plugins = [
+        'http://test.com/plugins/foo/static/test.js',
+        'http://test.com/plugins/bar/static/test.js',
+      ];
+      Gerrit._setPluginsPending(plugins);
+      Gerrit._pluginInstalled(plugins[0]);
+      Gerrit._pluginInstalled(plugins[1]);
+      assert.isTrue(pluginsLoadedStub.calledWithExactly(['foo', 'bar']));
+    });
+
+    test('install calls _pluginInstalled', () => {
+      sandbox.stub(Gerrit, '_pluginInstalled');
+      Gerrit.install(p => { plugin = p; }, '0.1',
+          'http://test.com/plugins/testplugin/static/test.js');
+
+      // testplugin has already been installed once (in setup).
+      assert.isFalse(Gerrit._pluginInstalled.called);
+
+      // testplugin2 plugin has not yet been installed.
+      Gerrit.install(p => { plugin = p; }, '0.1',
+          'http://test.com/plugins/testplugin2/static/test.js');
+      assert.isTrue(Gerrit._pluginInstalled.calledOnce);
+    });
+
+    test('plugin install errors mark plugins as loaded', () => {
+      Gerrit._setPluginsCount(1);
+      Gerrit.install(() => {}, '0.0pre-alpha');
+      return Gerrit.awaitPluginsLoaded();
+    });
+
+    test('multiple ui plugins per java plugin', () => {
+      const file1 = 'http://test.com/plugins/qaz/static/foo.nocache.js';
+      const file2 = 'http://test.com/plugins/qaz/static/bar.js';
+      Gerrit._setPluginsPending([file1, file2]);
+      Gerrit.install(() => {}, '0.1', file1);
+      Gerrit.install(() => {}, '0.1', file2);
+      return Gerrit.awaitPluginsLoaded();
+    });
+
+    test('plugin install errors shows toasts', () => {
+      const alertStub = sandbox.stub();
+      document.addEventListener('show-alert', alertStub);
+      Gerrit._setPluginsCount(1);
+      Gerrit.install(() => {}, '0.0pre-alpha');
+      return Gerrit.awaitPluginsLoaded().then(() => {
+        assert.isTrue(alertStub.calledOnce);
+      });
+    });
+
     test('attributeHelper', () => {
       assert.isOk(plugin.attributeHelper());
     });
@@ -328,6 +422,33 @@
           element.EventType.ADMIN_MENU_LINKS);
     });
 
+    test('Gerrit._isPluginPreloaded', () => {
+      Gerrit._preloadedPlugins = {baz: ()=>{}};
+      assert.isFalse(Gerrit._isPluginPreloaded('plugins/foo/bar'));
+      assert.isFalse(Gerrit._isPluginPreloaded('http://a.com/42'));
+      assert.isTrue(Gerrit._isPluginPreloaded('preloaded:baz'));
+      Gerrit._preloadedPlugins = null;
+    });
+
+    test('preloaded plugins are installed', () => {
+      const installStub = sandbox.stub();
+      Gerrit._preloadedPlugins = {foo: installStub};
+      Gerrit._installPreloadedPlugins();
+      assert.isTrue(installStub.called);
+      const pluginApi = installStub.lastCall.args[0];
+      assert.strictEqual(pluginApi.getPluginName(), 'foo');
+    });
+
+    test('installing preloaded plugin', () => {
+      let plugin;
+      window.ASSETS_PATH = 'http://blips.com/chitz';
+      Gerrit.install(p => { plugin = p; }, '0.1', 'preloaded:foo');
+      assert.strictEqual(plugin.getPluginName(), 'foo');
+      assert.strictEqual(plugin.url('/some/thing.html'),
+          'http://blips.com/chitz/plugins/foo/some/thing.html');
+      delete window.ASSETS_PATH;
+    });
+
     suite('test plugin with base url', () => {
       let baseUrlPlugin;
 
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-public-js-api.js b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-public-js-api.js
index d44acea..3b7b80d 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-public-js-api.js
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-public-js-api.js
@@ -17,18 +17,71 @@
 (function(window) {
   'use strict';
 
+  /**
+   * Hash of loaded and installed plugins, name to Plugin object.
+   */
+  const _plugins = {};
+
+  /**
+   * Array of plugin URLs to be loaded, name to url.
+   */
+  let _pluginsPending = {};
+
+  let _pluginsInstalled = [];
+
+  let _pluginsPendingCount = -1;
+
   const PRELOADED_PROTOCOL = 'preloaded:';
 
+  const UNKNOWN_PLUGIN = 'unknown';
+
   const PANEL_ENDPOINTS_MAPPING = {
     CHANGE_SCREEN_BELOW_COMMIT_INFO_BLOCK: 'change-view-integration',
     CHANGE_SCREEN_BELOW_CHANGE_INFO_BLOCK: 'change-metadata-item',
   };
 
-  // Import utils methods
-  const {
-      getPluginNameFromUrl,
-      send,
-  } = window._apiUtils;
+  const PLUGIN_LOADING_TIMEOUT_MS = 10000;
+
+  let _restAPI;
+
+  const getRestAPI = () => {
+    if (!_restAPI) {
+      _restAPI = document.createElement('gr-rest-api-interface');
+    }
+    return _restAPI;
+  };
+
+  let _reporting;
+  const getReporting = () => {
+    if (!_reporting) {
+      _reporting = document.createElement('gr-reporting');
+    }
+    return _reporting;
+  };
+
+  // TODO (viktard): deprecate in favor of GrPluginRestApi.
+  function send(method, url, opt_callback, opt_payload) {
+    return getRestAPI().send(method, url, opt_payload).then(response => {
+      if (response.status < 200 || response.status >= 300) {
+        return response.text().then(text => {
+          if (text) {
+            return Promise.reject(text);
+          } else {
+            return Promise.reject(response.status);
+          }
+        });
+      } else {
+        return getRestAPI().getResponseObject(response);
+      }
+    }).then(response => {
+      if (opt_callback) {
+        opt_callback(response);
+      }
+      return response;
+    });
+  }
+
+  const API_VERSION = '0.1';
 
   /**
    * Plugin-provided custom components can affect content in extension
@@ -46,6 +99,50 @@
     STYLE: 'style',
   };
 
+  function flushPreinstalls() {
+    if (window.Gerrit.flushPreinstalls) {
+      window.Gerrit.flushPreinstalls();
+    }
+  }
+
+  function installPreloadedPlugins() {
+    if (!Gerrit._preloadedPlugins) { return; }
+    for (const name in Gerrit._preloadedPlugins) {
+      if (!Gerrit._preloadedPlugins.hasOwnProperty(name)) { continue; }
+      const callback = Gerrit._preloadedPlugins[name];
+      Gerrit.install(callback, API_VERSION, PRELOADED_PROTOCOL + name);
+    }
+  }
+
+  function getPluginNameFromUrl(url) {
+    if (!(url instanceof URL)) {
+      try {
+        url = new URL(url);
+      } catch (e) {
+        console.warn(e);
+        return null;
+      }
+    }
+    if (url.protocol === PRELOADED_PROTOCOL) {
+      return url.pathname;
+    }
+    const base = Gerrit.BaseUrlBehavior.getBaseUrl();
+    const pathname = url.pathname.replace(base, '');
+    // Site theme is server from predefined path.
+    if (pathname === '/static/gerrit-theme.html') {
+      return 'gerrit-theme';
+    } else if (!pathname.startsWith('/plugins')) {
+      console.warn('Plugin not being loaded from /plugins base path:',
+          url.href, '— Unable to determine name.');
+      return;
+    }
+    // Pathname should normally look like this:
+    // /plugins/PLUGINNAME/static/SCRIPTNAME.html
+    // Or, for app/samples:
+    // /plugins/PLUGINNAME.html
+    return pathname.split('/')[2].split('.')[0];
+  }
+
   function Plugin(opt_url) {
     this._domHooks = new GrDomHooksManager(this);
 
@@ -378,5 +475,211 @@
     },
   };
 
-  window.Plugin = Plugin;
+  flushPreinstalls();
+
+  window.Gerrit = window.Gerrit || {};
+  const Gerrit = window.Gerrit;
+
+  let _resolveAllPluginsLoaded = null;
+  let _allPluginsPromise = null;
+
+  Gerrit._endpoints = new GrPluginEndpoints();
+
+  // Provide reset plugins function to clear installed plugins between tests.
+  const app = document.querySelector('#app');
+  if (!app) {
+    // No gr-app found (running tests)
+    Gerrit._installPreloadedPlugins = installPreloadedPlugins;
+    Gerrit._flushPreinstalls = flushPreinstalls;
+    Gerrit._resetPlugins = () => {
+      _allPluginsPromise = null;
+      _pluginsInstalled = [];
+      _pluginsPending = {};
+      _pluginsPendingCount = -1;
+      _reporting = null;
+      _resolveAllPluginsLoaded = null;
+      _restAPI = null;
+      Gerrit._endpoints = new GrPluginEndpoints();
+      for (const k of Object.keys(_plugins)) {
+        delete _plugins[k];
+      }
+    };
+  }
+
+  /**
+   * @deprecated Use plugin.styles().css(rulesStr) instead. Please, consult
+   * the documentation how to replace it accordingly.
+   */
+  Gerrit.css = function(rulesStr) {
+    console.warn('Gerrit.css(rulesStr) is deprecated!',
+        'Use plugin.styles().css(rulesStr)');
+    if (!Gerrit._customStyleSheet) {
+      const styleEl = document.createElement('style');
+      document.head.appendChild(styleEl);
+      Gerrit._customStyleSheet = styleEl.sheet;
+    }
+
+    const name = '__pg_js_api_class_' +
+        Gerrit._customStyleSheet.cssRules.length;
+    Gerrit._customStyleSheet.insertRule('.' + name + '{' + rulesStr + '}', 0);
+    return name;
+  };
+
+  Gerrit.install = function(callback, opt_version, opt_src) {
+    // HTML import polyfill adds __importElement pointing to the import tag.
+    const script = document.currentScript &&
+        (document.currentScript.__importElement || document.currentScript);
+
+    let src = opt_src || (script && script.src);
+    if (!src || src.startsWith('data:')) {
+      src = script && script.baseURI;
+    }
+    const name = getPluginNameFromUrl(src);
+
+    if (opt_version && opt_version !== API_VERSION) {
+      Gerrit._pluginInstallError(`Plugin ${name} install error: only version ` +
+          API_VERSION + ' is supported in PolyGerrit. ' + opt_version +
+          ' was given.');
+      return;
+    }
+
+    const existingPlugin = _plugins[name];
+    const plugin = existingPlugin || new Plugin(src);
+    try {
+      callback(plugin);
+      if (name) {
+        _plugins[name] = plugin;
+      }
+      if (!existingPlugin) {
+        Gerrit._pluginInstalled(src);
+      }
+    } catch (e) {
+      Gerrit._pluginInstallError(`${e.name}: ${e.message}`);
+    }
+  };
+
+  Gerrit.getLoggedIn = function() {
+    console.warn('Gerrit.getLoggedIn() is deprecated! ' +
+        'Use plugin.restApi().getLoggedIn()');
+    return document.createElement('gr-rest-api-interface').getLoggedIn();
+  };
+
+  Gerrit.get = function(url, callback) {
+    console.warn('.get() is deprecated! Use plugin.restApi().get()');
+    send('GET', url, callback);
+  };
+
+  Gerrit.post = function(url, payload, callback) {
+    console.warn('.post() is deprecated! Use plugin.restApi().post()');
+    send('POST', url, callback, payload);
+  };
+
+  Gerrit.put = function(url, payload, callback) {
+    console.warn('.put() is deprecated! Use plugin.restApi().put()');
+    send('PUT', url, callback, payload);
+  };
+
+  Gerrit.delete = function(url, opt_callback) {
+    console.warn('.delete() is deprecated! Use plugin.restApi().delete()');
+    return getRestAPI().send('DELETE', url).then(response => {
+      if (response.status !== 204) {
+        return response.text().then(text => {
+          if (text) {
+            return Promise.reject(text);
+          } else {
+            return Promise.reject(response.status);
+          }
+        });
+      }
+      if (opt_callback) {
+        opt_callback(response);
+      }
+      return response;
+    });
+  };
+
+  Gerrit.awaitPluginsLoaded = function() {
+    if (!_allPluginsPromise) {
+      if (Gerrit._arePluginsLoaded()) {
+        _allPluginsPromise = Promise.resolve();
+      } else {
+        let timeoutId;
+        _allPluginsPromise =
+          Promise.race([
+            new Promise(resolve => _resolveAllPluginsLoaded = resolve),
+            new Promise(resolve => timeoutId = setTimeout(
+                Gerrit._pluginLoadingTimeout, PLUGIN_LOADING_TIMEOUT_MS)),
+          ]).then(() => clearTimeout(timeoutId));
+      }
+    }
+    return _allPluginsPromise;
+  };
+
+  Gerrit._pluginLoadingTimeout = function() {
+    console.error(`Failed to load plugins: ${Object.keys(_pluginsPending)}`);
+    Gerrit._setPluginsPending([]);
+  };
+
+  Gerrit._setPluginsPending = function(plugins) {
+    _pluginsPending = plugins.reduce((o, url) => {
+      // TODO(viktard): Remove guard (@see Issue 8962)
+      o[getPluginNameFromUrl(url) || UNKNOWN_PLUGIN] = url;
+      return o;
+    }, {});
+    Gerrit._setPluginsCount(Object.keys(_pluginsPending).length);
+  };
+
+  Gerrit._setPluginsCount = function(count) {
+    _pluginsPendingCount = count;
+    if (Gerrit._arePluginsLoaded()) {
+      getReporting().pluginsLoaded(_pluginsInstalled);
+      if (_resolveAllPluginsLoaded) {
+        _resolveAllPluginsLoaded();
+      }
+    }
+  };
+
+  Gerrit._pluginInstallError = function(message) {
+    document.dispatchEvent(new CustomEvent('show-alert', {
+      detail: {
+        message: `Plugin install error: ${message}`,
+      },
+    }));
+    console.info(`Plugin install error: ${message}`);
+    Gerrit._setPluginsCount(_pluginsPendingCount - 1);
+  };
+
+  Gerrit._pluginInstalled = function(url) {
+    const name = getPluginNameFromUrl(url) || UNKNOWN_PLUGIN;
+    if (!_pluginsPending[name]) {
+      console.warn(`Unexpected plugin ${name} installed from ${url}.`);
+    } else {
+      delete _pluginsPending[name];
+      _pluginsInstalled.push(name);
+      Gerrit._setPluginsCount(_pluginsPendingCount - 1);
+      getReporting().pluginLoaded(name);
+      console.log(`Plugin ${name} installed.`);
+    }
+  };
+
+  Gerrit._arePluginsLoaded = function() {
+    return _pluginsPendingCount === 0;
+  };
+
+  Gerrit._getPluginScreenName = function(pluginName, screenName) {
+    return `${pluginName}-screen-${screenName}`;
+  };
+
+  Gerrit._isPluginPreloaded = function(url) {
+    const name = getPluginNameFromUrl(url);
+    if (name && Gerrit._preloadedPlugins) {
+      return name in Gerrit._preloadedPlugins;
+    } else {
+      return false;
+    }
+  };
+
+  // Preloaded plugins should be installed after Gerrit.install() is set,
+  // since plugin preloader substitutes Gerrit.install() temporarily.
+  installPreloadedPlugins();
 })(window);
diff --git a/polygerrit-ui/app/test/index.html b/polygerrit-ui/app/test/index.html
index a0e85ef..10d5aff 100644
--- a/polygerrit-ui/app/test/index.html
+++ b/polygerrit-ui/app/test/index.html
@@ -188,9 +188,7 @@
     'shared/gr-js-api-interface/gr-annotation-actions-js-api_test.html',
     'shared/gr-js-api-interface/gr-change-actions-js-api_test.html',
     'shared/gr-js-api-interface/gr-change-reply-js-api_test.html',
-    'shared/gr-js-api-interface/gr-api-utils_test.html',
     'shared/gr-js-api-interface/gr-js-api-interface_test.html',
-    'shared/gr-js-api-interface/gr-gerrit_test.html',
     // TODO: uncomment file & fix tests. The file was missed in this list for a long time.
     // 'shared/gr-js-api-interface/gr-plugin-action-context_test.html',
     'shared/gr-js-api-interface/gr-plugin-endpoints_test.html',
