Remove GWT-based UI

GWT-based UIs are not supported anymore with Gerrit 3.0. Thus it was not
possible to use the plugin with newer Gerrit versions.

This change removes all components used to create the UI and thus the
dependency to GWT. The aim is to reimplement a new UI using PolyGerrit
in a later change.

Change-Id: I672a4e80f0fcf50ff7156bfae4b800a32b6ec398
diff --git a/BUILD b/BUILD
index f4c8d63..06e79d5 100644
--- a/BUILD
+++ b/BUILD
@@ -3,11 +3,9 @@
 gerrit_plugin(
     name = "serviceuser",
     srcs = glob(["src/main/java/**/*.java"]),
-    gwt_module = "com.googlesource.gerrit.plugins.serviceuser.CreateServiceUserForm",
     manifest_entries = [
         "Gerrit-PluginName: serviceuser",
         "Gerrit-Module: com.googlesource.gerrit.plugins.serviceuser.Module",
-        "Gerrit-HttpModule: com.googlesource.gerrit.plugins.serviceuser.HttpModule",
         "Gerrit-SshModule: com.googlesource.gerrit.plugins.serviceuser.SshModule",
     ],
     resources = glob(["src/main/**/*"]),
diff --git a/WORKSPACE b/WORKSPACE
index b88e14d..5404b46 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -24,10 +24,3 @@
 
 # Load release Plugin API
 gerrit_api()
-
-load(
-    "@com_googlesource_gerrit_bazlets//:gerrit_gwt.bzl",
-    "gerrit_gwt",
-)
-
-gerrit_gwt()
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/CreateServiceUserForm.gwt.xml b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/CreateServiceUserForm.gwt.xml
deleted file mode 100644
index 9d921cb..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/CreateServiceUserForm.gwt.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright (C) 2013 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.
--->
-<module rename-to="serviceuser">
-  <!-- Inherit the core Web Toolkit stuff.                        -->
-  <inherits name="com.google.gwt.user.User"/>
-  <!-- Other module inherits                                      -->
-  <inherits name="com.google.gerrit.Plugin"/>
-  <inherits name="com.google.gwt.http.HTTP"/>
-  <inherits name="com.google.gwt.json.JSON"/>
-  <inherits name='com.google.gwtexpui.clippy.Clippy'/>
-  <inherits name='com.google.gwtexpui.globalkey.GlobalKey'/>
-  <!-- Using GWT built-in themes adds a number of static          -->
-  <!-- resources to the plugin. No theme inherits lines were      -->
-  <!-- added in order to make this plugin as simple as possible   -->
-  <!-- Specify the app entry point class.                         -->
-  <entry-point class="com.googlesource.gerrit.plugins.serviceuser.client.ServiceUserPlugin"/>
-  <stylesheet src="serviceuser.css"/>
-</module>
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/GetConfig.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/GetConfig.java
index 28d7be3..dfcd92d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/GetConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/GetConfig.java
@@ -14,7 +14,6 @@
 
 package com.googlesource.gerrit.plugins.serviceuser;
 
-import com.google.common.base.Strings;
 import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.extensions.common.GroupInfo;
 import com.google.gerrit.extensions.restapi.RestReadView;
@@ -63,8 +62,6 @@
   public ConfigInfo apply(ConfigResource rsrc) throws OrmException, PermissionBackendException {
     PluginConfig cfg = cfgFactory.getFromGerritConfig(pluginName);
     ConfigInfo info = new ConfigInfo();
-    info.info = Strings.emptyToNull(cfg.getString("infoMessage"));
-    info.onSuccess = Strings.emptyToNull(cfg.getString("onSuccessMessage"));
     info.allowEmail = toBoolean(cfg.getBoolean("allowEmail", false));
     info.allowHttpPassword = toBoolean(cfg.getBoolean("allowHttpPassword", false));
     info.allowOwner = toBoolean(cfg.getBoolean("allowOwner", false));
@@ -96,8 +93,6 @@
   }
 
   public class ConfigInfo {
-    public String info;
-    public String onSuccess;
     public Boolean allowEmail;
     public Boolean allowHttpPassword;
     public Boolean allowOwner;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/HttpModule.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/HttpModule.java
deleted file mode 100644
index 80d86e2..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/HttpModule.java
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (C) 2013 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.
-
-package com.googlesource.gerrit.plugins.serviceuser;
-
-import com.google.gerrit.extensions.registration.DynamicSet;
-import com.google.gerrit.extensions.webui.GwtPlugin;
-import com.google.gerrit.extensions.webui.WebUiPlugin;
-import com.google.inject.servlet.ServletModule;
-
-class HttpModule extends ServletModule {
-
-  @Override
-  protected void configureServlets() {
-    DynamicSet.bind(binder(), WebUiPlugin.class).toInstance(new GwtPlugin("serviceuser"));
-  }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/Module.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/Module.java
index 9ceba80..ca6f8f0 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/Module.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/Module.java
@@ -36,7 +36,6 @@
     bind(CapabilityDefinition.class)
         .annotatedWith(Exports.named(CreateServiceUserCapability.ID))
         .to(CreateServiceUserCapability.class);
-    DynamicSet.bind(binder(), TopMenu.class).to(ServiceUserMenu.class);
     DynamicSet.bind(binder(), GitReferenceUpdatedListener.class).to(RefUpdateListener.class);
     DynamicSet.bind(binder(), CommitValidationListener.class).to(ValidateServiceUserCommits.class);
     install(new FactoryModuleBuilder().build(CreateServiceUserNotes.Factory.class));
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/PutConfig.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/PutConfig.java
index 09a559e..8b45918 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/PutConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/PutConfig.java
@@ -40,8 +40,6 @@
 @Singleton
 class PutConfig implements RestModifyView<ConfigResource, Input> {
   public static class Input {
-    public String info;
-    public String onSuccess;
     public Boolean allowEmail;
     public Boolean allowHttpPassword;
     public Boolean allowOwner;
@@ -73,12 +71,6 @@
       throws IOException, ConfigInvalidException, UnprocessableEntityException {
     FileBasedConfig cfg = new FileBasedConfig(sitePaths.gerrit_config.toFile(), FS.DETECTED);
     cfg.load();
-    if (input.info != null) {
-      cfg.setString("plugin", pluginName, "infoMessage", Strings.emptyToNull(input.info));
-    }
-    if (input.onSuccess != null) {
-      cfg.setString("plugin", pluginName, "onSuccessMessage", Strings.emptyToNull(input.onSuccess));
-    }
     if (input.allowEmail != null) {
       setBoolean(cfg, "allowEmail", input.allowEmail);
     }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ServiceUserMenu.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ServiceUserMenu.java
deleted file mode 100644
index df2cf8c..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ServiceUserMenu.java
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (C) 2013 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.
-
-package com.googlesource.gerrit.plugins.serviceuser;
-
-import static com.google.gerrit.server.permissions.GlobalPermission.ADMINISTRATE_SERVER;
-
-import com.google.common.collect.Lists;
-import com.google.gerrit.extensions.annotations.PluginName;
-import com.google.gerrit.extensions.api.access.PluginPermission;
-import com.google.gerrit.extensions.client.MenuItem;
-import com.google.gerrit.extensions.restapi.AuthException;
-import com.google.gerrit.extensions.restapi.RestApiException;
-import com.google.gerrit.extensions.webui.TopMenu;
-import com.google.gerrit.server.CurrentUser;
-import com.google.gerrit.server.IdentifiedUser;
-import com.google.gerrit.server.config.ConfigResource;
-import com.google.gerrit.server.permissions.PermissionBackend;
-import com.google.gerrit.server.permissions.PermissionBackendException;
-import com.google.gwtorm.server.OrmException;
-import com.google.inject.Inject;
-import com.google.inject.Provider;
-import java.io.IOException;
-import java.util.List;
-import org.eclipse.jgit.errors.ConfigInvalidException;
-
-class ServiceUserMenu implements TopMenu {
-  private final String pluginName;
-  private final Provider<CurrentUser> userProvider;
-  private final List<MenuEntry> menuEntries;
-  private final Provider<ListServiceUsers> listServiceUsers;
-  private final PermissionBackend permissionBackend;
-
-  @Inject
-  ServiceUserMenu(
-      @PluginName String pluginName,
-      Provider<CurrentUser> userProvider,
-      Provider<ListServiceUsers> listServiceUsers,
-      PermissionBackend permissionBackend)
-      throws IOException, PermissionBackendException, ConfigInvalidException, RestApiException {
-    this.pluginName = pluginName;
-    this.userProvider = userProvider;
-    this.listServiceUsers = listServiceUsers;
-    menuEntries = Lists.newArrayList();
-    this.permissionBackend = permissionBackend;
-
-    List<MenuItem> peopleItems = Lists.newArrayListWithExpectedSize(2);
-    if (canCreateServiceUser()) {
-      peopleItems.add(new MenuItem("Create Service User", "#/x/" + pluginName + "/create", ""));
-    }
-    if (canCreateServiceUser() || hasServiceUser()) {
-      peopleItems.add(new MenuItem("List Service Users", "#/x/" + pluginName + "/list", ""));
-    }
-    if (!peopleItems.isEmpty()) {
-      menuEntries.add(new MenuEntry("People", peopleItems));
-    }
-  }
-
-  private boolean canCreateServiceUser() {
-    if (userProvider.get().isIdentifiedUser()) {
-      IdentifiedUser user = userProvider.get().asIdentifiedUser();
-      return permissionBackend
-              .user(user)
-              .testOrFalse(new PluginPermission(pluginName, CreateServiceUserCapability.ID))
-          || permissionBackend.user(user).testOrFalse(ADMINISTRATE_SERVER);
-    }
-    return false;
-  }
-
-  private boolean hasServiceUser()
-      throws PermissionBackendException, IOException, ConfigInvalidException, RestApiException {
-    try {
-      return !listServiceUsers.get().apply(new ConfigResource()).isEmpty();
-    } catch (AuthException | OrmException e) {
-      return false;
-    }
-  }
-
-  @Override
-  public List<MenuEntry> getEntries() {
-    return menuEntries;
-  }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/AccountCapabilities.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/AccountCapabilities.java
deleted file mode 100644
index a6f7f84..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/AccountCapabilities.java
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (C) 2014 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.
-
-package com.googlesource.gerrit.plugins.serviceuser.client;
-
-import com.google.gerrit.plugin.client.rpc.RestApi;
-import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-
-/** Capabilities the caller has from {@code /accounts/self/capabilities}. */
-public class AccountCapabilities extends JavaScriptObject {
-  public static void all(AsyncCallback<AccountCapabilities> cb, String... filter) {
-    new RestApi("/accounts/self/capabilities").addParameter("q", filter).get(cb);
-  }
-
-  protected AccountCapabilities() {}
-
-  public final native boolean canPerform(String name) /*-{ return this[name] ? true : false; }-*/;
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/AccountInfo.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/AccountInfo.java
deleted file mode 100644
index ffc1953..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/AccountInfo.java
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (C) 2014 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.
-
-package com.googlesource.gerrit.plugins.serviceuser.client;
-
-import com.google.gwt.core.client.JavaScriptObject;
-
-public class AccountInfo extends JavaScriptObject {
-  public final native int _account_id() /*-{ return this._account_id || 0; }-*/;
-
-  public final native String name() /*-{ return this.name; }-*/;
-
-  public final native String username() /*-{ return this.username; }-*/;
-
-  public final native String email() /*-{ return this.email; }-*/;
-
-  protected AccountInfo() {}
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/ConfigInfo.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/ConfigInfo.java
deleted file mode 100644
index 6291319..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/ConfigInfo.java
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright (C) 2014 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.
-
-package com.googlesource.gerrit.plugins.serviceuser.client;
-
-import com.google.gerrit.client.rpc.NativeMap;
-import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.core.client.JsArrayString;
-import java.util.List;
-
-public class ConfigInfo extends JavaScriptObject {
-  final native String getInfoMessage() /*-{ return this.info }-*/;
-
-  final native String getOnSuccessMessage() /*-{ return this.on_success }-*/;
-
-  final native boolean getAllowEmail() /*-{ return this.allow_email ? true : false; }-*/;
-
-  final native boolean
-      getAllowHttpPassword() /*-{ return this.allow_http_password ? true : false; }-*/;
-
-  final native boolean getAllowOwner() /*-{ return this.allow_owner ? true : false; }-*/;
-
-  final native boolean getCreateNotes() /*-{ return this.create_notes ? true : false; }-*/;
-
-  final native boolean
-      getCreateNotesAsync() /*-{ return this.create_notes_async ? true : false; }-*/;
-
-  final native JsArrayString getBlockedNames() /*-{ return this.blocked_names; }-*/;
-
-  final native NativeMap<GroupInfo> getGroups() /*-{ return this.groups; }-*/;
-
-  final native void setInfoMessage(String s) /*-{ this.info = s; }-*/;
-
-  final native void setOnSuccessMessage(String s) /*-{ this.on_success = s; }-*/;
-
-  final native void setAllowEmail(boolean s) /*-{ this.allow_email = s; }-*/;
-
-  final native void setAllowHttpPassword(boolean s) /*-{ this.allow_http_password = s; }-*/;
-
-  final native void setAllowOwner(boolean s) /*-{ this.allow_owner = s; }-*/;
-
-  final native void setCreateNotes(boolean s) /*-{ this.create_notes = s; }-*/;
-
-  final native void setCreateNotesAsync(boolean s) /*-{ this.create_notes_async = s; }-*/;
-
-  final void setBlockedNames(List<String> blockedNames) {
-    initBlockedNames();
-    for (String n : blockedNames) {
-      addBlockedName(n);
-    }
-  }
-
-  final native void initBlockedNames() /*-{ this.blocked_names = []; }-*/;
-
-  final native void addBlockedName(String n) /*-{ this.blocked_names.push(n); }-*/;
-
-  final void setGroups(List<String> groups) {
-    initGroups();
-    for (String g : groups) {
-      addGroup(g);
-    }
-  }
-
-  final native void initGroups() /*-{ this.groups = []; }-*/;
-
-  final native void addGroup(String g) /*-{ this.groups.push(g); }-*/;
-
-  static ConfigInfo create() {
-    ConfigInfo g = (ConfigInfo) createObject();
-    return g;
-  }
-
-  protected ConfigInfo() {}
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/CreateServiceUserScreen.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/CreateServiceUserScreen.java
deleted file mode 100644
index c57eb5f..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/CreateServiceUserScreen.java
+++ /dev/null
@@ -1,259 +0,0 @@
-// Copyright (C) 2013 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.
-
-package com.googlesource.gerrit.plugins.serviceuser.client;
-
-import com.google.gerrit.plugin.client.Plugin;
-import com.google.gerrit.plugin.client.rpc.RestApi;
-import com.google.gerrit.plugin.client.screen.Screen;
-import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.core.client.Scheduler;
-import com.google.gwt.core.client.Scheduler.ScheduledCommand;
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.event.dom.client.ClickHandler;
-import com.google.gwt.event.dom.client.KeyPressEvent;
-import com.google.gwt.event.dom.client.KeyPressHandler;
-import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.google.gwt.user.client.ui.Button;
-import com.google.gwt.user.client.ui.DialogBox;
-import com.google.gwt.user.client.ui.HTML;
-import com.google.gwt.user.client.ui.HorizontalPanel;
-import com.google.gwt.user.client.ui.Label;
-import com.google.gwt.user.client.ui.Panel;
-import com.google.gwt.user.client.ui.TextArea;
-import com.google.gwt.user.client.ui.TextBox;
-import com.google.gwt.user.client.ui.VerticalPanel;
-
-public class CreateServiceUserScreen extends VerticalPanel {
-  static class Factory implements Screen.EntryPoint {
-    @Override
-    public void onLoad(Screen screen) {
-      screen.setPageTitle("Create Service User");
-      screen.show(new CreateServiceUserScreen());
-    }
-  }
-
-  private TextBox usernameTxt;
-  private TextBox emailTxt;
-  private TextArea sshKeyTxt;
-  private String onSuccessMessage;
-
-  CreateServiceUserScreen() {
-    setStyleName("serviceuser-panel");
-
-    Panel usernamePanel = new VerticalPanel();
-    usernamePanel.add(new Label("Username:"));
-    usernameTxt =
-        new TextBox() {
-          @Override
-          public void onBrowserEvent(Event event) {
-            super.onBrowserEvent(event);
-            if (event.getTypeInt() == Event.ONPASTE) {
-              Scheduler.get()
-                  .scheduleDeferred(
-                      new ScheduledCommand() {
-                        @Override
-                        public void execute() {
-                          if (getValue().trim().length() != 0) {
-                            setEnabled(true);
-                          }
-                        }
-                      });
-            }
-          }
-        };
-    usernameTxt.addKeyPressHandler(
-        new KeyPressHandler() {
-          @Override
-          public void onKeyPress(final KeyPressEvent event) {
-            event.stopPropagation();
-          }
-        });
-    usernameTxt.sinkEvents(Event.ONPASTE);
-    usernameTxt.setVisibleLength(40);
-    usernamePanel.add(usernameTxt);
-    add(usernamePanel);
-
-    Panel sshKeyPanel = new VerticalPanel();
-    sshKeyPanel.add(new Label("Public SSH Key:"));
-    sshKeyPanel.add(new SshKeyHelpPanel());
-    sshKeyTxt = new TextArea();
-    sshKeyTxt.addKeyPressHandler(
-        new KeyPressHandler() {
-          @Override
-          public void onKeyPress(final KeyPressEvent event) {
-            event.stopPropagation();
-          }
-        });
-    sshKeyTxt.setVisibleLines(12);
-    sshKeyTxt.setCharacterWidth(80);
-    sshKeyTxt.getElement().setPropertyBoolean("spellcheck", false);
-    sshKeyPanel.add(sshKeyTxt);
-    add(sshKeyPanel);
-
-    HorizontalPanel buttons = new HorizontalPanel();
-    add(buttons);
-
-    final Button createButton = new Button("Create");
-    createButton.addStyleName("serviceuser-createButton");
-    createButton.addClickHandler(
-        new ClickHandler() {
-          @Override
-          public void onClick(final ClickEvent event) {
-            doCreate();
-          }
-        });
-    buttons.add(createButton);
-    createButton.setEnabled(false);
-    new OnEditEnabler(createButton, usernameTxt);
-
-    usernameTxt.setFocus(true);
-    createButton.setEnabled(false);
-
-    new RestApi("config")
-        .id("server")
-        .view(Plugin.get().getPluginName(), "config")
-        .get(
-            new AsyncCallback<ConfigInfo>() {
-              @Override
-              public void onSuccess(ConfigInfo info) {
-                onSuccessMessage = info.getOnSuccessMessage();
-
-                String infoMessage = info.getInfoMessage();
-                if (infoMessage != null && !"".equals(infoMessage)) {
-                  insert(new HTML(infoMessage), 0);
-                }
-
-                if (info.getAllowEmail()) {
-                  Panel emailPanel = new VerticalPanel();
-                  emailPanel.add(new Label("Email:"));
-                  emailTxt =
-                      new TextBox() {
-                        @Override
-                        public void onBrowserEvent(Event event) {
-                          super.onBrowserEvent(event);
-                          if (event.getTypeInt() == Event.ONPASTE) {
-                            Scheduler.get()
-                                .scheduleDeferred(
-                                    new ScheduledCommand() {
-                                      @Override
-                                      public void execute() {
-                                        if (getValue().trim().length() != 0) {
-                                          setEnabled(true);
-                                        }
-                                      }
-                                    });
-                          }
-                        }
-                      };
-                  emailTxt.addKeyPressHandler(
-                      new KeyPressHandler() {
-                        @Override
-                        public void onKeyPress(final KeyPressEvent event) {
-                          event.stopPropagation();
-                        }
-                      });
-                  emailTxt.sinkEvents(Event.ONPASTE);
-                  emailTxt.setVisibleLength(40);
-                  emailPanel.add(emailTxt);
-                  insert(emailPanel, 2);
-                }
-              }
-
-              @Override
-              public void onFailure(Throwable caught) {
-                // never invoked
-              }
-            });
-  }
-
-  private void doCreate() {
-    final String username = usernameTxt.getValue().trim();
-    String sshKey = sshKeyTxt.getText();
-    if (sshKey != null) {
-      sshKey = sshKey.trim();
-    }
-
-    ServiceUserInput in = ServiceUserInput.create();
-    in.ssh_key(sshKey);
-    if (emailTxt != null) {
-      in.email(emailTxt.getValue().trim());
-    }
-    new RestApi("config")
-        .id("server")
-        .view("serviceuser", "serviceusers")
-        .id(username)
-        .post(
-            in,
-            new AsyncCallback<JavaScriptObject>() {
-
-              @Override
-              public void onSuccess(JavaScriptObject result) {
-                clearForm();
-                Plugin.get().go("/x/" + Plugin.get().getName() + "/user/" + username);
-
-                final DialogBox successDialog = new DialogBox();
-                successDialog.setText("Service User Created");
-                successDialog.setAnimationEnabled(true);
-
-                Panel p = new VerticalPanel();
-                p.setStyleName("serviceuser-panel");
-                p.add(new Label("The service user '" + username + "' was created."));
-                Button okButton = new Button("OK");
-                okButton.addClickHandler(
-                    new ClickHandler() {
-                      @Override
-                      public void onClick(ClickEvent event) {
-                        successDialog.hide();
-                      }
-                    });
-
-                if (onSuccessMessage != null && !"".equals(onSuccessMessage)) {
-                  p.add(new HTML(onSuccessMessage));
-                }
-
-                p.add(okButton);
-                successDialog.add(p);
-
-                successDialog.center();
-                successDialog.show();
-              }
-
-              @Override
-              public void onFailure(Throwable caught) {}
-            });
-  }
-
-  private void clearForm() {
-    usernameTxt.setValue("");
-    if (emailTxt != null) {
-      emailTxt.setValue("");
-    }
-    sshKeyTxt.setValue("");
-  }
-
-  private static class ServiceUserInput extends JavaScriptObject {
-    final native void ssh_key(String s) /*-{ this.ssh_key = s; }-*/;
-
-    final native void email(String e) /*-{ this.email = e; }-*/;
-
-    static ServiceUserInput create() {
-      ServiceUserInput g = (ServiceUserInput) createObject();
-      return g;
-    }
-
-    protected ServiceUserInput() {}
-  }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/EditableValue.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/EditableValue.java
deleted file mode 100644
index 0ab741f..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/EditableValue.java
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright (C) 2014 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.
-
-package com.googlesource.gerrit.plugins.serviceuser.client;
-
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.event.dom.client.ClickHandler;
-import com.google.gwt.event.dom.client.KeyCodes;
-import com.google.gwt.event.dom.client.KeyPressEvent;
-import com.google.gwt.event.dom.client.KeyPressHandler;
-import com.google.gwt.user.client.ui.Anchor;
-import com.google.gwt.user.client.ui.Button;
-import com.google.gwt.user.client.ui.FlowPanel;
-import com.google.gwt.user.client.ui.Image;
-import com.google.gwt.user.client.ui.InlineLabel;
-import com.google.gwt.user.client.ui.Label;
-import com.google.gwt.user.client.ui.Widget;
-import com.google.gwtexpui.globalkey.client.NpTextBox;
-
-public abstract class EditableValue extends FlowPanel {
-  private final Widget labelWidget;
-  private final Image edit;
-  private final NpTextBox input;
-  private final Button save;
-  private final Button cancel;
-  private Image warning;
-
-  EditableValue(String serviceUser, String value) {
-    this(serviceUser, value, null);
-  }
-
-  EditableValue(final String serviceUser, String value, String href) {
-    if (href != null) {
-      labelWidget = new Anchor(value, href);
-    } else {
-      labelWidget = new InlineLabel(value);
-    }
-    edit = new Image(ServiceUserPlugin.RESOURCES.edit());
-    edit.addStyleName("serviceuser-editButton");
-    edit.setTitle("Edit");
-
-    input = new NpTextBox();
-    input.setVisibleLength(25);
-    input.setValue(value);
-    input.setVisible(false);
-    save = new Button();
-    save.setText("Save");
-    save.setVisible(false);
-    save.setEnabled(false);
-    cancel = new Button();
-    cancel.setText("Cancel");
-    cancel.setVisible(false);
-
-    OnEditEnabler e = new OnEditEnabler(save);
-    e.listenTo(input);
-
-    edit.addClickHandler(
-        new ClickHandler() {
-          @Override
-          public void onClick(ClickEvent event) {
-            labelWidget.setVisible(false);
-            edit.setVisible(false);
-            input.setVisible(true);
-            input.setFocus(true);
-            save.setVisible(true);
-            if (warning != null) {
-              warning.setVisible(true);
-            }
-            cancel.setVisible(true);
-          }
-        });
-    save.addClickHandler(
-        new ClickHandler() {
-          @Override
-          public void onClick(ClickEvent event) {
-            save.setEnabled(false);
-            save(serviceUser, input.getValue().trim());
-          }
-        });
-    input.addKeyPressHandler(
-        new KeyPressHandler() {
-          @Override
-          public void onKeyPress(KeyPressEvent event) {
-            if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) {
-              save.setEnabled(false);
-              save(serviceUser, input.getValue().trim());
-            } else if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ESCAPE) {
-              cancel();
-            }
-          }
-        });
-    cancel.addClickHandler(
-        new ClickHandler() {
-          @Override
-          public void onClick(ClickEvent event) {
-            cancel();
-          }
-        });
-
-    add(labelWidget);
-    add(edit);
-    add(input);
-    add(save);
-    add(cancel);
-  }
-
-  private void cancel() {
-    labelWidget.setVisible(true);
-    edit.setVisible(true);
-    input.setVisible(false);
-    if (labelWidget instanceof Label) {
-      input.setValue(((Label) labelWidget).getText());
-    } else {
-      input.setValue(((Anchor) labelWidget).getText());
-    }
-    save.setVisible(false);
-    save.setEnabled(false);
-    if (warning != null) {
-      warning.setVisible(false);
-    }
-    cancel.setVisible(false);
-  }
-
-  public void setWarning(String msg) {
-    if (warning == null) {
-      warning = new Image(ServiceUserPlugin.RESOURCES.warning());
-      insert(warning, getWidgetIndex(save));
-      warning.setVisible(save.isVisible());
-    }
-    warning.setTitle(msg);
-  }
-
-  protected void updateValue(String newValue) {
-    if (labelWidget instanceof Label) {
-      ((Label) labelWidget).setText(newValue);
-    } else {
-      ((Anchor) labelWidget).setText(newValue);
-    }
-    labelWidget.setVisible(true);
-    edit.setVisible(true);
-    input.setVisible(false);
-    input.setValue(newValue);
-    save.setVisible(false);
-    if (warning != null) {
-      warning.setVisible(false);
-    }
-    save.setEnabled(false);
-    cancel.setVisible(false);
-  }
-
-  protected void updateHref(String newHref) {
-    if (labelWidget instanceof Anchor) {
-      ((Anchor) labelWidget).setHref(newHref);
-    }
-  }
-
-  protected abstract void save(String serviceUser, final String newValue);
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/GroupInfo.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/GroupInfo.java
deleted file mode 100644
index b398092..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/GroupInfo.java
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (C) 2014 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.
-
-package com.googlesource.gerrit.plugins.serviceuser.client;
-
-import com.google.gwt.core.client.JavaScriptObject;
-
-public class GroupInfo extends JavaScriptObject {
-  public final native String name() /*-{ return this.name; }-*/;
-
-  public final native String url() /*-{ return this.url; }-*/;
-
-  protected GroupInfo() {}
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/HttpPasswordInput.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/HttpPasswordInput.java
deleted file mode 100644
index 5549597..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/HttpPasswordInput.java
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (C) 2015 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.
-
-package com.googlesource.gerrit.plugins.serviceuser.client;
-
-import com.google.gwt.core.client.JavaScriptObject;
-
-public class HttpPasswordInput extends JavaScriptObject {
-  final native void generate(boolean g) /*-{ if (g) this.generate = g; }-*/;
-
-  public static HttpPasswordInput create() {
-    return createObject().cast();
-  }
-
-  protected HttpPasswordInput() {}
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/OnEditEnabler.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/OnEditEnabler.java
deleted file mode 100644
index 815962c..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/OnEditEnabler.java
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright (C) 2010 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.
-
-package com.googlesource.gerrit.plugins.serviceuser.client;
-
-import com.google.gwt.core.client.Scheduler;
-import com.google.gwt.core.client.Scheduler.ScheduledCommand;
-import com.google.gwt.event.dom.client.ChangeEvent;
-import com.google.gwt.event.dom.client.ChangeHandler;
-import com.google.gwt.event.dom.client.FocusEvent;
-import com.google.gwt.event.dom.client.FocusHandler;
-import com.google.gwt.event.dom.client.KeyDownEvent;
-import com.google.gwt.event.dom.client.KeyDownHandler;
-import com.google.gwt.event.dom.client.KeyPressEvent;
-import com.google.gwt.event.dom.client.KeyPressHandler;
-import com.google.gwt.event.dom.client.MouseUpEvent;
-import com.google.gwt.event.dom.client.MouseUpHandler;
-import com.google.gwt.event.logical.shared.ValueChangeEvent;
-import com.google.gwt.event.logical.shared.ValueChangeHandler;
-import com.google.gwt.event.shared.GwtEvent;
-import com.google.gwt.user.client.ui.CheckBox;
-import com.google.gwt.user.client.ui.FocusWidget;
-import com.google.gwt.user.client.ui.ListBox;
-import com.google.gwt.user.client.ui.TextBoxBase;
-import com.google.gwt.user.client.ui.ValueBoxBase;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Enables a FocusWidget (e.g. a Button) if an edit is detected from any registered input widget.
- */
-public class OnEditEnabler
-    implements KeyPressHandler,
-        KeyDownHandler,
-        MouseUpHandler,
-        ChangeHandler,
-        ValueChangeHandler<Object> {
-
-  private final FocusWidget widget;
-  private Map<TextBoxBase, String> strings = new HashMap<>();
-  private String originalValue;
-
-  // The first parameter to the constructors must be the FocusWidget to enable,
-  // subsequent parameters are widgets to listenTo.
-
-  public OnEditEnabler(final FocusWidget w, final TextBoxBase tb) {
-    this(w);
-    originalValue = tb.getValue().trim();
-    listenTo(tb);
-  }
-
-  public OnEditEnabler(final FocusWidget w, final ListBox lb) {
-    this(w);
-    listenTo(lb);
-  }
-
-  public OnEditEnabler(final FocusWidget w, final CheckBox cb) {
-    this(w);
-    listenTo(cb);
-  }
-
-  public OnEditEnabler(final FocusWidget w) {
-    widget = w;
-  }
-
-  // Register input widgets to be listened to
-
-  public void listenTo(final TextBoxBase tb) {
-    strings.put(tb, tb.getText().trim());
-    tb.addKeyPressHandler(this);
-
-    // Is there another way to capture middle button X11 pastes in browsers
-    // which do not yet support ONPASTE events (Firefox)?
-    tb.addMouseUpHandler(this);
-
-    // Resetting the "original text" on focus ensures that we are
-    // up to date with non-user updates of the text (calls to
-    // setText()...) and also up to date with user changes which
-    // occured after enabling "widget".
-    tb.addFocusHandler(
-        new FocusHandler() {
-          @Override
-          public void onFocus(FocusEvent event) {
-            strings.put(tb, tb.getText().trim());
-          }
-        });
-
-    // CTRL-V Pastes in Chrome seem only detectable via BrowserEvents or
-    // KeyDownEvents, the latter is better.
-    tb.addKeyDownHandler(this);
-  }
-
-  public void listenTo(final ListBox lb) {
-    lb.addChangeHandler(this);
-  }
-
-  @SuppressWarnings({"unchecked", "rawtypes"})
-  public void listenTo(final CheckBox cb) {
-    cb.addValueChangeHandler((ValueChangeHandler) this);
-  }
-
-  // Handlers
-
-  @Override
-  public void onKeyPress(final KeyPressEvent e) {
-    on(e);
-  }
-
-  @Override
-  public void onKeyDown(final KeyDownEvent e) {
-    on(e);
-  }
-
-  @Override
-  public void onMouseUp(final MouseUpEvent e) {
-    on(e);
-  }
-
-  @Override
-  public void onChange(final ChangeEvent e) {
-    on(e);
-  }
-
-  @SuppressWarnings("rawtypes")
-  @Override
-  public void onValueChange(final ValueChangeEvent e) {
-    on(e);
-  }
-
-  private void on(final GwtEvent<?> e) {
-    if (widget.isEnabled()
-        || !(e.getSource() instanceof FocusWidget)
-        || !((FocusWidget) e.getSource()).isEnabled()) {
-      if (e.getSource() instanceof ValueBoxBase) {
-        final TextBoxBase box = ((TextBoxBase) e.getSource());
-        Scheduler.get()
-            .scheduleDeferred(
-                new ScheduledCommand() {
-                  @Override
-                  public void execute() {
-                    if (box.getValue().trim().equals(originalValue)) {
-                      widget.setEnabled(false);
-                    }
-                  }
-                });
-      }
-      return;
-    }
-
-    if (e.getSource() instanceof TextBoxBase) {
-      onTextBoxBase((TextBoxBase) e.getSource());
-    } else {
-      // For many widgets, we can assume that a change is an edit. If
-      // a widget does not work that way, it should be special cased
-      // above.
-      widget.setEnabled(true);
-    }
-  }
-
-  private void onTextBoxBase(final TextBoxBase tb) {
-    // The text appears to not get updated until the handlers complete.
-    Scheduler.get()
-        .scheduleDeferred(
-            new ScheduledCommand() {
-              @Override
-              public void execute() {
-                String orig = strings.get(tb);
-                if (orig == null) {
-                  orig = "";
-                }
-                if (!orig.equals(tb.getText().trim())) {
-                  widget.setEnabled(true);
-                }
-              }
-            });
-  }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/ServiceUserInfo.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/ServiceUserInfo.java
index 96c543d..47723f1 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/ServiceUserInfo.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/ServiceUserInfo.java
@@ -14,34 +14,28 @@
 
 package com.googlesource.gerrit.plugins.serviceuser.client;
 
-import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gerrit.extensions.common.AccountInfo;
+import com.google.gerrit.extensions.common.GroupInfo;
 
-public class ServiceUserInfo extends JavaScriptObject {
+public class ServiceUserInfo {
   public final String getDisplayName() {
-    if (created_by().username() != null) {
-      return created_by().username();
+    if (created_by.username != null) {
+      return created_by.username;
     }
-    if (created_by()._account_id() != -1) {
-      return Integer.toString(created_by()._account_id());
+    if (created_by._accountId != -1) {
+      return Integer.toString(created_by._accountId);
     }
     return "N/A";
   }
 
-  public final native int _account_id() /*-{ return this._account_id || 0; }-*/;
-
-  public final native String name() /*-{ return this.name; }-*/;
-
-  public final native String username() /*-{ return this.username; }-*/;
-
-  public final native String email() /*-{ return this.email; }-*/;
-
-  public final native AccountInfo created_by() /*-{ return this.created_by; }-*/;
-
-  public final native String created_at() /*-{ return this.created_at; }-*/;
-
-  public final native boolean active() /*-{ return this.inactive ? false : true; }-*/;
-
-  public final native GroupInfo owner() /*-{ return this.owner; }-*/;
+  public int _account_id;
+  public String name;
+  public String username;
+  public String email;
+  public AccountInfo created_by;
+  public String created_at;
+  public boolean active;
+  public GroupInfo owner;
 
   protected ServiceUserInfo() {}
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/ServiceUserListScreen.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/ServiceUserListScreen.java
deleted file mode 100644
index 5c30bea..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/ServiceUserListScreen.java
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright (C) 2014 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.
-
-package com.googlesource.gerrit.plugins.serviceuser.client;
-
-import com.google.gerrit.client.rpc.NativeMap;
-import com.google.gerrit.plugin.client.Plugin;
-import com.google.gerrit.plugin.client.rpc.RestApi;
-import com.google.gerrit.plugin.client.screen.Screen;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.google.gwt.user.client.ui.Anchor;
-import com.google.gwt.user.client.ui.FlexTable;
-import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
-import com.google.gwt.user.client.ui.InlineHyperlink;
-import com.google.gwt.user.client.ui.VerticalPanel;
-
-public class ServiceUserListScreen extends VerticalPanel {
-  static class Factory implements Screen.EntryPoint {
-    @Override
-    public void onLoad(Screen screen) {
-      screen.setPageTitle("Service Users");
-      screen.show(new ServiceUserListScreen());
-    }
-  }
-
-  ServiceUserListScreen() {
-    setStyleName("serviceuser-panel");
-
-    new RestApi("config")
-        .id("server")
-        .view(Plugin.get().getPluginName(), "serviceusers")
-        .get(
-            NativeMap.copyKeysIntoChildren(
-                "username",
-                new AsyncCallback<NativeMap<ServiceUserInfo>>() {
-                  @Override
-                  public void onSuccess(NativeMap<ServiceUserInfo> info) {
-                    display(info);
-                  }
-
-                  @Override
-                  public void onFailure(Throwable caught) {
-                    // never invoked
-                  }
-                }));
-  }
-
-  private void display(NativeMap<ServiceUserInfo> info) {
-    int columns = 7;
-    FlexTable t = new FlexTable();
-    t.setStyleName("serviceuser-serviceUserTable");
-    FlexCellFormatter fmt = t.getFlexCellFormatter();
-    for (int c = 0; c < columns; c++) {
-      fmt.addStyleName(0, c, "dataHeader");
-      fmt.addStyleName(0, c, "topMostCell");
-    }
-    fmt.addStyleName(0, 0, "leftMostCell");
-
-    t.setText(0, 0, "Username");
-    t.setText(0, 1, "Full Name");
-    t.setText(0, 2, "Email");
-    t.setText(0, 3, "Owner");
-    t.setText(0, 4, "Created By");
-    t.setText(0, 5, "Created At");
-    t.setText(0, 6, "Account State");
-
-    int row = 1;
-    for (String username : info.keySet()) {
-      ServiceUserInfo a = info.get(username);
-
-      for (int c = 0; c < columns; c++) {
-        fmt.addStyleName(row, c, "dataCell");
-        fmt.addStyleName(row, 0, "leftMostCell");
-      }
-
-      t.setWidget(
-          row,
-          0,
-          new InlineHyperlink(username, "/x/" + Plugin.get().getName() + "/user/" + username));
-      t.setText(row, 1, a.name());
-      t.setText(row, 2, a.email());
-
-      if (a.owner() != null) {
-        if (a.owner().url() != null) {
-          t.setWidget(row, 3, new Anchor(a.owner().name(), a.owner().url()));
-        } else {
-          t.setText(row, 3, a.owner().name());
-        }
-      }
-
-      t.setText(row, 4, a.getDisplayName());
-      t.setText(row, 5, a.created_at());
-      t.setText(row, 6, !a.active() ? "Inactive" : "");
-      row++;
-    }
-
-    add(t);
-  }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/ServiceUserPlugin.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/ServiceUserPlugin.java
deleted file mode 100644
index 393963d..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/ServiceUserPlugin.java
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (C) 2014 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.
-
-package com.googlesource.gerrit.plugins.serviceuser.client;
-
-import com.google.gerrit.client.Resources;
-import com.google.gerrit.plugin.client.Plugin;
-import com.google.gerrit.plugin.client.PluginEntryPoint;
-import com.google.gwt.core.client.GWT;
-
-public class ServiceUserPlugin extends PluginEntryPoint {
-  public static final Resources RESOURCES = GWT.create(Resources.class);
-
-  @Override
-  public void onPluginLoad() {
-    Plugin.get().screen("create", new CreateServiceUserScreen.Factory());
-    Plugin.get().screen("settings", new ServiceUserSettingsScreen.Factory());
-    Plugin.get().screen("list", new ServiceUserListScreen.Factory());
-    Plugin.get().screenRegex("user/(.*)", new ServiceUserScreen.Factory());
-  }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/ServiceUserScreen.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/ServiceUserScreen.java
deleted file mode 100644
index 78cb65e..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/ServiceUserScreen.java
+++ /dev/null
@@ -1,371 +0,0 @@
-// Copyright (C) 2014 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.
-
-package com.googlesource.gerrit.plugins.serviceuser.client;
-
-import com.google.gerrit.client.rpc.NativeString;
-import com.google.gerrit.plugin.client.Plugin;
-import com.google.gerrit.plugin.client.rpc.NoContent;
-import com.google.gerrit.plugin.client.rpc.RestApi;
-import com.google.gerrit.plugin.client.screen.Screen;
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.event.dom.client.ClickHandler;
-import com.google.gwt.event.logical.shared.ValueChangeEvent;
-import com.google.gwt.event.logical.shared.ValueChangeHandler;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.google.gwt.user.client.ui.Anchor;
-import com.google.gwt.user.client.ui.FlexTable;
-import com.google.gwt.user.client.ui.HorizontalPanel;
-import com.google.gwt.user.client.ui.Image;
-import com.google.gwt.user.client.ui.Label;
-import com.google.gwt.user.client.ui.ToggleButton;
-import com.google.gwt.user.client.ui.VerticalPanel;
-import com.google.gwt.user.client.ui.Widget;
-import com.google.gwtexpui.clippy.client.CopyableLabel;
-
-public class ServiceUserScreen extends VerticalPanel {
-  static class Factory implements Screen.EntryPoint {
-    @Override
-    public void onLoad(Screen screen) {
-      screen.setPageTitle("Service User " + screen.getToken(1));
-      screen.show(new ServiceUserScreen(screen.getToken(1)));
-    }
-  }
-
-  ServiceUserScreen(final String serviceUser) {
-    setStyleName("serviceuser-panel");
-
-    new RestApi("config")
-        .id("server")
-        .view(Plugin.get().getPluginName(), "serviceusers")
-        .id(serviceUser)
-        .get(
-            new AsyncCallback<ServiceUserInfo>() {
-              @Override
-              public void onSuccess(final ServiceUserInfo serviceUserInfo) {
-                new RestApi("config")
-                    .id("server")
-                    .view(Plugin.get().getPluginName(), "config")
-                    .get(
-                        new AsyncCallback<ConfigInfo>() {
-                          @Override
-                          public void onSuccess(final ConfigInfo configInfo) {
-                            AccountCapabilities.all(
-                                new AsyncCallback<AccountCapabilities>() {
-                                  @Override
-                                  public void onSuccess(AccountCapabilities ac) {
-                                    boolean isAdmin = ac.canPerform("administrateServer");
-                                    display(
-                                        serviceUserInfo,
-                                        configInfo.getAllowEmail() || isAdmin,
-                                        configInfo.getAllowOwner() || isAdmin,
-                                        configInfo.getAllowHttpPassword() || isAdmin);
-                                  }
-
-                                  @Override
-                                  public void onFailure(Throwable caught) {
-                                    // never invoked
-                                  }
-                                },
-                                "administrateServer");
-                          }
-
-                          @Override
-                          public void onFailure(Throwable caught) {
-                            // never invoked
-                          }
-                        });
-              }
-
-              @Override
-              public void onFailure(Throwable caught) {
-                // never invoked
-              }
-            });
-  }
-
-  private void display(
-      ServiceUserInfo info, boolean allowEmail, boolean allowOwner, boolean allowHttpPassword) {
-    MyTable t = new MyTable();
-    t.setStyleName("serviceuser-serviceUserInfoTable");
-    t.addRow("Account State", createActiveToggle(info));
-    t.addRow("Username", info.username());
-    t.addRow(
-        "Full Name",
-        new EditableValue(info.username(), info.name()) {
-          @Override
-          protected void save(String serviceUser, final String newValue) {
-            new RestApi("config")
-                .id("server")
-                .view(Plugin.get().getPluginName(), "serviceusers")
-                .id(serviceUser)
-                .view("name")
-                .put(
-                    newValue,
-                    new AsyncCallback<NativeString>() {
-                      @Override
-                      public void onSuccess(NativeString result) {
-                        updateValue(newValue);
-                      }
-
-                      @Override
-                      public void onFailure(Throwable caught) {
-                        // never invoked
-                      }
-                    });
-          }
-        });
-    if (allowEmail) {
-      t.addRow(
-          "Email Address",
-          new EditableValue(info.username(), info.email()) {
-            @Override
-            protected void save(String serviceUser, final String newValue) {
-              new RestApi("config")
-                  .id("server")
-                  .view(Plugin.get().getPluginName(), "serviceusers")
-                  .id(serviceUser)
-                  .view("email")
-                  .put(
-                      newValue,
-                      new AsyncCallback<NativeString>() {
-                        @Override
-                        public void onSuccess(NativeString result) {
-                          updateValue(newValue);
-                        }
-
-                        @Override
-                        public void onFailure(Throwable caught) {
-                          // never invoked
-                        }
-                      });
-            }
-          });
-    } else {
-      t.addRow("Email Address", info.email());
-    }
-    t.addRow("HTTP Password", createHttpPasswordWidget(info.username(), allowHttpPassword));
-    t.addRow("Owner Group", createOwnerWidget(info, allowOwner));
-    t.addRow("Created By", info.getDisplayName());
-    t.addRow("Created At", info.created_at());
-    add(t);
-
-    add(new SshPanel(info.username()));
-  }
-
-  private ToggleButton createActiveToggle(final ServiceUserInfo info) {
-    final ToggleButton activeToggle = new ToggleButton();
-    activeToggle.setStyleName("serviceuser-toggleButton");
-    activeToggle.setVisible(false);
-    activeToggle.setValue(true);
-    activeToggle.setText("Active");
-    activeToggle.setValue(false);
-    activeToggle.setText("Inactive");
-    activeToggle.setValue(info.active());
-    activeToggle.setVisible(true);
-
-    activeToggle.addValueChangeHandler(
-        new ValueChangeHandler<Boolean>() {
-          @Override
-          public void onValueChange(ValueChangeEvent<Boolean> event) {
-            if (event.getValue()) {
-              new RestApi("config")
-                  .id("server")
-                  .view(Plugin.get().getPluginName(), "serviceusers")
-                  .id(info.username())
-                  .view("active")
-                  .put(
-                      new AsyncCallback<NoContent>() {
-                        @Override
-                        public void onSuccess(NoContent result) {}
-
-                        @Override
-                        public void onFailure(Throwable caught) {
-                          // never invoked
-                        }
-                      });
-            } else {
-              new RestApi("config")
-                  .id("server")
-                  .view(Plugin.get().getPluginName(), "serviceusers")
-                  .id(info.username())
-                  .view("active")
-                  .delete(
-                      new AsyncCallback<NoContent>() {
-                        @Override
-                        public void onSuccess(NoContent result) {}
-
-                        @Override
-                        public void onFailure(Throwable caught) {
-                          // never invoked
-                        }
-                      });
-            }
-          }
-        });
-
-    return activeToggle;
-  }
-
-  private Widget createHttpPasswordWidget(final String serviceUser, boolean allowHttpPassword) {
-    if (allowHttpPassword) {
-      HorizontalPanel p = new HorizontalPanel();
-      final CopyableLabel label = new CopyableLabel("");
-      label.setVisible(false);
-      p.add(label);
-
-      // The redNot icon is only used as temporary measure until gerrit core
-      // provides a better icon that symbolizes "clear".
-      final Image delete = new Image(ServiceUserPlugin.RESOURCES.redNot());
-      delete.addStyleName("serviceuser-deleteButton");
-      delete.setTitle("Clear HTTP password");
-      delete.addClickHandler(
-          new ClickHandler() {
-            @Override
-            public void onClick(ClickEvent event) {
-              new RestApi("config")
-                  .id("server")
-                  .view(Plugin.get().getPluginName(), "serviceusers")
-                  .id(serviceUser)
-                  .view("password.http")
-                  .delete(
-                      new AsyncCallback<NoContent>() {
-                        @Override
-                        public void onSuccess(NoContent noContent) {
-                          label.setText("");
-                          label.setVisible(false);
-                          delete.setVisible(false);
-                        }
-
-                        @Override
-                        public void onFailure(Throwable caught) {
-                          // never invoked
-                        }
-                      });
-            }
-          });
-      delete.setVisible(true);
-      p.add(delete);
-
-      Image generate = new Image(ServiceUserPlugin.RESOURCES.gear());
-      generate.addStyleName("serviceuser-generateButton");
-      generate.setTitle("Generate new HTTP password");
-      generate.addClickHandler(
-          new ClickHandler() {
-            @Override
-            public void onClick(ClickEvent event) {
-              HttpPasswordInput in = HttpPasswordInput.create();
-              in.generate(true);
-              new RestApi("config")
-                  .id("server")
-                  .view(Plugin.get().getPluginName(), "serviceusers")
-                  .id(serviceUser)
-                  .view("password.http")
-                  .put(
-                      in,
-                      new AsyncCallback<NativeString>() {
-                        @Override
-                        public void onSuccess(NativeString newPassword) {
-                          label.setText(newPassword.asString());
-                          label.setVisible(true);
-                          delete.setVisible(true);
-                        }
-
-                        @Override
-                        public void onFailure(Throwable caught) {
-                          // never invoked
-                        }
-                      });
-            }
-          });
-      p.add(generate);
-      return p;
-    }
-    return new CopyableLabel("");
-  }
-
-  private Widget createOwnerWidget(ServiceUserInfo info, boolean allowOwner) {
-    if (allowOwner) {
-      EditableValue ownerWidget =
-          new EditableValue(
-              info.username(),
-              info.owner() != null ? info.owner().name() : "",
-              info.owner() != null ? info.owner().url() : null) {
-            @Override
-            protected void save(String serviceUser, final String newValue) {
-              new RestApi("config")
-                  .id("server")
-                  .view(Plugin.get().getPluginName(), "serviceusers")
-                  .id(serviceUser)
-                  .view("owner")
-                  .put(
-                      newValue,
-                      new AsyncCallback<GroupInfo>() {
-                        @Override
-                        public void onSuccess(GroupInfo result) {
-                          updateValue(result != null ? result.name() : "");
-                          updateHref(result != null ? result.url() : "");
-                          Plugin.get().refresh();
-                        }
-
-                        @Override
-                        public void onFailure(Throwable caught) {
-                          // never invoked
-                        }
-                      });
-            }
-          };
-      StringBuilder ownerWarning = new StringBuilder();
-      ownerWarning.append("If ");
-      ownerWarning.append(
-          info.owner() != null ? "the owner group is changed" : "an owner group is set");
-      ownerWarning.append(" only members of the ");
-      ownerWarning.append(info.owner() != null ? "new " : "");
-      ownerWarning.append("owner group can see and administrate" + " the service user.");
-      if (info.owner() != null) {
-        ownerWarning.append(
-            " If the owner group is removed only the"
-                + " creator of the service user can see and administrate"
-                + " the service user.");
-      } else {
-        ownerWarning.append(
-            " The creator of the service user can no"
-                + " longer see and administrate the service user if she/he"
-                + " is not member of the owner group.");
-      }
-      ownerWidget.setWarning(ownerWarning.toString());
-      return ownerWidget;
-    }
-    if (info.owner() != null && info.owner().url() != null) {
-      return new Anchor(info.owner().name(), info.owner().url());
-    }
-    return new Label(info.owner() != null ? info.owner().name() : "");
-  }
-
-  private static class MyTable extends FlexTable {
-    private static int row = 0;
-
-    private void addRow(String label, String value) {
-      setWidget(row, 0, new Label(label + ":"));
-      setWidget(row, 1, new Label(value));
-      row++;
-    }
-
-    private void addRow(String label, Widget w) {
-      setWidget(row, 0, new Label(label + ":"));
-      setWidget(row, 1, w);
-      row++;
-    }
-  }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/ServiceUserSettingsScreen.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/ServiceUserSettingsScreen.java
deleted file mode 100644
index 1755cda..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/ServiceUserSettingsScreen.java
+++ /dev/null
@@ -1,268 +0,0 @@
-// Copyright (C) 2014 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.
-
-package com.googlesource.gerrit.plugins.serviceuser.client;
-
-import com.google.gerrit.plugin.client.Plugin;
-import com.google.gerrit.plugin.client.rpc.RestApi;
-import com.google.gerrit.plugin.client.screen.Screen;
-import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.event.dom.client.ClickHandler;
-import com.google.gwt.event.dom.client.KeyPressEvent;
-import com.google.gwt.event.dom.client.KeyPressHandler;
-import com.google.gwt.event.logical.shared.ValueChangeEvent;
-import com.google.gwt.event.logical.shared.ValueChangeHandler;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.google.gwt.user.client.ui.Button;
-import com.google.gwt.user.client.ui.CheckBox;
-import com.google.gwt.user.client.ui.HorizontalPanel;
-import com.google.gwt.user.client.ui.Image;
-import com.google.gwt.user.client.ui.Label;
-import com.google.gwt.user.client.ui.Panel;
-import com.google.gwt.user.client.ui.TextArea;
-import com.google.gwt.user.client.ui.VerticalPanel;
-
-public class ServiceUserSettingsScreen extends VerticalPanel {
-  static class Factory implements Screen.EntryPoint {
-    @Override
-    public void onLoad(Screen screen) {
-      screen.setPageTitle("Service User Administration");
-      screen.show(new ServiceUserSettingsScreen());
-    }
-  }
-
-  private TextArea infoMsgTxt;
-  private TextArea onSuccessMsgTxt;
-  private CheckBox allowEmailCheckBox;
-  private CheckBox allowHttpPasswordCheckBox;
-  private CheckBox allowOwnerCheckBox;
-  private CheckBox createNotesCheckBox;
-  private CheckBox createNotesAsyncCheckBox;
-  private StringListPanel blockedUsernamesPanel;
-  private StringListPanel groupsPanel;
-  private Button saveButton;
-
-  ServiceUserSettingsScreen() {
-    setStyleName("serviceuser-panel");
-
-    new RestApi("config")
-        .id("server")
-        .view(Plugin.get().getPluginName(), "config")
-        .get(
-            new AsyncCallback<ConfigInfo>() {
-              @Override
-              public void onSuccess(ConfigInfo info) {
-                display(info);
-              }
-
-              @Override
-              public void onFailure(Throwable caught) {
-                // never invoked
-              }
-            });
-  }
-
-  private void display(ConfigInfo info) {
-    Panel infoMsgPanel = new VerticalPanel();
-    Panel infoMsgTitelPanel = new HorizontalPanel();
-    infoMsgTitelPanel.add(new Label("Info Message"));
-    Image infoMsgInfo = new Image(ServiceUserPlugin.RESOURCES.info());
-    infoMsgInfo.setTitle(
-        "HTML formatted message that should be"
-            + " displayed on the service user creation screen.");
-    infoMsgTitelPanel.add(infoMsgInfo);
-    infoMsgTitelPanel.add(new Label(":"));
-    infoMsgPanel.add(infoMsgTitelPanel);
-    infoMsgTxt = new TextArea();
-    infoMsgTxt.setValue(info.getInfoMessage());
-    infoMsgTxt.addKeyPressHandler(
-        new KeyPressHandler() {
-          @Override
-          public void onKeyPress(final KeyPressEvent event) {
-            event.stopPropagation();
-          }
-        });
-    infoMsgTxt.setVisibleLines(12);
-    infoMsgTxt.setCharacterWidth(80);
-    infoMsgTxt.getElement().setPropertyBoolean("spellcheck", false);
-    infoMsgPanel.add(infoMsgTxt);
-    add(infoMsgPanel);
-
-    Panel onSuccessMsgPanel = new VerticalPanel();
-    Panel onSuccessMsgTitelPanel = new HorizontalPanel();
-    onSuccessMsgTitelPanel.add(new Label("On Success Message"));
-    Image onSuccessMsgInfo = new Image(ServiceUserPlugin.RESOURCES.info());
-    onSuccessMsgInfo.setTitle(
-        "HTML formatted message that should be"
-            + " displayed after a service user was successfully created.");
-    onSuccessMsgTitelPanel.add(onSuccessMsgInfo);
-    onSuccessMsgTitelPanel.add(new Label(":"));
-    onSuccessMsgPanel.add(onSuccessMsgTitelPanel);
-    onSuccessMsgTxt = new TextArea();
-    onSuccessMsgTxt.setValue(info.getOnSuccessMessage());
-    onSuccessMsgTxt.addKeyPressHandler(
-        new KeyPressHandler() {
-          @Override
-          public void onKeyPress(final KeyPressEvent event) {
-            event.stopPropagation();
-          }
-        });
-    onSuccessMsgTxt.setVisibleLines(12);
-    onSuccessMsgTxt.setCharacterWidth(80);
-    onSuccessMsgTxt.getElement().setPropertyBoolean("spellcheck", false);
-    onSuccessMsgPanel.add(onSuccessMsgTxt);
-    add(onSuccessMsgPanel);
-
-    Panel allowEmailPanel = new HorizontalPanel();
-    allowEmailCheckBox = new CheckBox("Allow Email Address");
-    allowEmailCheckBox.setValue(info.getAllowEmail());
-    allowEmailPanel.add(allowEmailCheckBox);
-    Image allowEmailInfo = new Image(ServiceUserPlugin.RESOURCES.info());
-    allowEmailInfo.setTitle(
-        "Whether it is allowed to provide an email address "
-            + "for a service user. E.g. having an email address allows a service user "
-            + "to push commits and tags.");
-    allowEmailPanel.add(allowEmailInfo);
-    add(allowEmailPanel);
-
-    Panel allowHttpPasswordPanel = new HorizontalPanel();
-    allowHttpPasswordCheckBox = new CheckBox("Allow HTTP password");
-    allowHttpPasswordCheckBox.setValue(info.getAllowHttpPassword());
-    allowHttpPasswordPanel.add(allowHttpPasswordCheckBox);
-    Image allowHttpPasswordInfo = new Image(ServiceUserPlugin.RESOURCES.info());
-    allowHttpPasswordInfo.setTitle(
-        "Whether it is allowed to generate an HTTP password "
-            + "for a service user. E.g. having an HTTP password allows a service user "
-            + "to use the Gerrit REST API.");
-    allowHttpPasswordPanel.add(allowHttpPasswordInfo);
-    add(allowHttpPasswordPanel);
-
-    Panel allowOwnerPanel = new HorizontalPanel();
-    allowOwnerCheckBox = new CheckBox("Allow Owner Group");
-    allowOwnerCheckBox.setValue(info.getAllowOwner());
-    allowOwnerPanel.add(allowOwnerCheckBox);
-    Image allowOwnerInfo = new Image(ServiceUserPlugin.RESOURCES.info());
-    allowOwnerInfo.setTitle("Whether it is allowed to set an owner group " + "for a service user.");
-    allowOwnerPanel.add(allowOwnerInfo);
-    add(allowOwnerPanel);
-
-    Panel createNotesPanel = new HorizontalPanel();
-    createNotesCheckBox = new CheckBox("Create Git Notes");
-    createNotesCheckBox.setValue(info.getCreateNotes());
-    createNotesPanel.add(createNotesCheckBox);
-    Image createNotesInfo = new Image(ServiceUserPlugin.RESOURCES.info());
-    createNotesInfo.setTitle(
-        "Whether commits of a service user should be "
-            + "annotated by a Git note that contains information about the current "
-            + "owners of the service user. This allows to find a real person that "
-            + "is responsible for this commit. To get such a Git note for each commit "
-            + "of a service user the 'Forge Committer' access right must be blocked "
-            + "for service users.");
-    createNotesPanel.add(createNotesInfo);
-    add(createNotesPanel);
-
-    Panel createNotesAsyncPanel = new HorizontalPanel();
-    createNotesAsyncCheckBox = new CheckBox("Create Git Notes Asynchronously");
-    createNotesAsyncCheckBox.setValue(info.getCreateNotesAsync());
-    createNotesAsyncCheckBox.setEnabled(info.getCreateNotes());
-    createNotesAsyncPanel.add(createNotesAsyncCheckBox);
-    Image createNotesAsyncInfo = new Image(ServiceUserPlugin.RESOURCES.info());
-    createNotesAsyncInfo.setTitle(
-        "Whether the Git notes on commits that are "
-            + "pushed by a service user should be created asynchronously.");
-    createNotesAsyncPanel.add(createNotesAsyncInfo);
-    add(createNotesAsyncPanel);
-
-    createNotesCheckBox.addValueChangeHandler(
-        new ValueChangeHandler<Boolean>() {
-          @Override
-          public void onValueChange(ValueChangeEvent<Boolean> event) {
-            createNotesAsyncCheckBox.setEnabled(event.getValue());
-          }
-        });
-
-    saveButton = new Button("Save");
-    saveButton.addStyleName("serviceuser-saveButton");
-    saveButton.addClickHandler(
-        new ClickHandler() {
-          @Override
-          public void onClick(final ClickEvent event) {
-            doSave();
-          }
-        });
-
-    blockedUsernamesPanel =
-        new StringListPanel("Blocked Usernames", "Username", info.getBlockedNames(), saveButton);
-    blockedUsernamesPanel.setInfo(
-        "List of usernames which are "
-            + "forbidden to be used as name for a service user. "
-            + "The blocked usernames are case insensitive.");
-    add(blockedUsernamesPanel);
-
-    groupsPanel =
-        new StringListPanel("Groups", "Group Name", info.getGroups().keySet(), saveButton);
-    groupsPanel.setInfo(
-        "Names of groups to which newly created " + "service users should be added automatically.");
-    add(groupsPanel);
-
-    HorizontalPanel buttons = new HorizontalPanel();
-    add(buttons);
-
-    buttons.add(saveButton);
-    saveButton.setEnabled(false);
-    OnEditEnabler onEditEnabler = new OnEditEnabler(saveButton, infoMsgTxt);
-    onEditEnabler.listenTo(onSuccessMsgTxt);
-    onEditEnabler.listenTo(allowEmailCheckBox);
-    onEditEnabler.listenTo(allowHttpPasswordCheckBox);
-    onEditEnabler.listenTo(allowOwnerCheckBox);
-    onEditEnabler.listenTo(createNotesCheckBox);
-    onEditEnabler.listenTo(createNotesAsyncCheckBox);
-
-    infoMsgTxt.setFocus(true);
-    saveButton.setEnabled(false);
-  }
-
-  private void doSave() {
-    ConfigInfo in = ConfigInfo.create();
-    in.setInfoMessage(infoMsgTxt.getValue());
-    in.setOnSuccessMessage(onSuccessMsgTxt.getValue());
-    in.setAllowEmail(allowEmailCheckBox.getValue());
-    in.setAllowHttpPassword(allowHttpPasswordCheckBox.getValue());
-    in.setAllowOwner(allowOwnerCheckBox.getValue());
-    in.setCreateNotes(createNotesCheckBox.getValue());
-    if (createNotesAsyncCheckBox.isEnabled()) {
-      in.setCreateNotesAsync(createNotesAsyncCheckBox.getValue());
-    }
-    in.setBlockedNames(blockedUsernamesPanel.getValues());
-    in.setGroups(groupsPanel.getValues());
-    new RestApi("config")
-        .id("server")
-        .view(Plugin.get().getPluginName(), "config")
-        .put(
-            in,
-            new AsyncCallback<JavaScriptObject>() {
-
-              @Override
-              public void onSuccess(JavaScriptObject result) {
-                saveButton.setEnabled(false);
-              }
-
-              @Override
-              public void onFailure(Throwable caught) {
-                // never invoked
-              }
-            });
-  }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/SshKeyHelpPanel.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/SshKeyHelpPanel.java
deleted file mode 100644
index 9845b23..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/SshKeyHelpPanel.java
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (C) 2014 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.
-
-package com.googlesource.gerrit.plugins.serviceuser.client;
-
-import com.google.gwt.user.client.ui.DisclosurePanel;
-import com.google.gwt.user.client.ui.FlowPanel;
-import com.google.gwt.user.client.ui.HTML;
-
-public class SshKeyHelpPanel extends FlowPanel {
-
-  SshKeyHelpPanel() {
-    DisclosurePanel dp = new DisclosurePanel("How to generate an SSH Key");
-    StringBuilder b = new StringBuilder();
-    b.append("<ol>")
-        .append("<li>From the Terminal or Git Bash, run <em>ssh-keygen</em></li>")
-        .append("<li>")
-        .append(
-            "Enter a path for the key, e.g. <em>id_rsa</em>. If you are generating the key<br />")
-        .append("on your local system take care to not overwrite your own SSH key.")
-        .append("</li>")
-        .append("<li>")
-        .append("Enter a passphrase only if the service where you intend to use this<br />")
-        .append("service user is able to deal with passphrases, otherwise leave it blank.<br />")
-        .append("Remember this passphrase, as you will need it to unlock the key.")
-        .append("</li>")
-        .append("<li>")
-        .append(
-            "Open <em>id_rsa.pub</em> and copy &amp; paste the contents into the box below.<br />")
-        .append("Note that <em>id_rsa.pub</em> is your public key and can be shared,<br />")
-        .append("while <em>id_rsa</em> is your private key and should be kept secret.")
-        .append("</li>")
-        .append("</ol>");
-    dp.add(new HTML(b.toString()));
-    add(dp);
-  }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/SshKeyInfo.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/SshKeyInfo.java
deleted file mode 100644
index 52a7044..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/SshKeyInfo.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (C) 2014 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.
-
-package com.googlesource.gerrit.plugins.serviceuser.client;
-
-import com.google.gwt.core.client.JavaScriptObject;
-
-public class SshKeyInfo extends JavaScriptObject {
-  public final native int seq() /*-{ return this.seq || 0; }-*/;
-
-  public final native String sshPublicKey() /*-{ return this.ssh_public_key; }-*/;
-
-  public final native String encodedKey() /*-{ return this.encoded_key; }-*/;
-
-  public final native String algorithm() /*-{ return this.algorithm; }-*/;
-
-  public final native String comment() /*-{ return this.comment; }-*/;
-
-  public final native boolean isValid() /*-{ return this['valid'] ? true : false; }-*/;
-
-  protected SshKeyInfo() {}
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/SshPanel.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/SshPanel.java
deleted file mode 100644
index 10acc65..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/SshPanel.java
+++ /dev/null
@@ -1,382 +0,0 @@
-// Copyright (C) 2014 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.
-
-package com.googlesource.gerrit.plugins.serviceuser.client;
-
-import com.google.gerrit.client.rpc.Natives;
-import com.google.gerrit.plugin.client.Plugin;
-import com.google.gerrit.plugin.client.rpc.NoContent;
-import com.google.gerrit.plugin.client.rpc.RestApi;
-import com.google.gwt.core.client.JsArray;
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.event.dom.client.ClickHandler;
-import com.google.gwt.event.logical.shared.ValueChangeEvent;
-import com.google.gwt.event.logical.shared.ValueChangeHandler;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.google.gwt.user.client.ui.Button;
-import com.google.gwt.user.client.ui.CheckBox;
-import com.google.gwt.user.client.ui.Composite;
-import com.google.gwt.user.client.ui.FlexTable;
-import com.google.gwt.user.client.ui.FlowPanel;
-import com.google.gwt.user.client.ui.HasHorizontalAlignment;
-import com.google.gwt.user.client.ui.HorizontalPanel;
-import com.google.gwt.user.client.ui.Label;
-import com.google.gwt.user.client.ui.Panel;
-import com.google.gwt.user.client.ui.VerticalPanel;
-import com.google.gwtexpui.clippy.client.CopyableLabel;
-import com.google.gwtexpui.globalkey.client.NpTextArea;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-
-class SshPanel extends Composite {
-  private final String serviceUser;
-
-  private SshKeyTable keys;
-
-  private Button showAddKeyBlock;
-  private Panel addKeyBlock;
-  private Button closeAddKeyBlock;
-  private Button clearNew;
-  private Button addNew;
-  private NpTextArea addTxt;
-  private Button deleteKey;
-
-  private Panel serverKeys;
-
-  private int loadCount;
-
-  SshPanel(String serviceUser) {
-    this.serviceUser = serviceUser;
-
-    FlowPanel body = new FlowPanel();
-
-    showAddKeyBlock = new Button("Add Key ...");
-    showAddKeyBlock.addClickHandler(
-        new ClickHandler() {
-          @Override
-          public void onClick(final ClickEvent event) {
-            showAddKeyBlock(true);
-          }
-        });
-
-    keys = new SshKeyTable();
-    body.add(keys);
-    {
-      final FlowPanel fp = new FlowPanel();
-      deleteKey = new Button("Delete");
-      deleteKey.setEnabled(false);
-      deleteKey.addClickHandler(
-          new ClickHandler() {
-            @Override
-            public void onClick(final ClickEvent event) {
-              keys.deleteChecked();
-            }
-          });
-      fp.add(deleteKey);
-      fp.add(showAddKeyBlock);
-      body.add(fp);
-    }
-
-    addKeyBlock = new VerticalPanel();
-    addKeyBlock.setVisible(false);
-    addKeyBlock.setStyleName("serviceuser-addSshKeyPanel");
-    addKeyBlock.add(new Label("Add SSH Public Key"));
-    addKeyBlock.add(new SshKeyHelpPanel());
-
-    addTxt = new NpTextArea();
-    addTxt.setVisibleLines(12);
-    addTxt.setCharacterWidth(80);
-    addTxt.setSpellCheck(false);
-    addKeyBlock.add(addTxt);
-
-    final HorizontalPanel buttons = new HorizontalPanel();
-    addKeyBlock.add(buttons);
-
-    clearNew = new Button("Clear");
-    clearNew.addClickHandler(
-        new ClickHandler() {
-          @Override
-          public void onClick(final ClickEvent event) {
-            addTxt.setText("");
-            addTxt.setFocus(true);
-          }
-        });
-    buttons.add(clearNew);
-
-    addNew = new Button("Add");
-    addNew.addClickHandler(
-        new ClickHandler() {
-          @Override
-          public void onClick(final ClickEvent event) {
-            doAddNew();
-          }
-        });
-    buttons.add(addNew);
-
-    closeAddKeyBlock = new Button("Close");
-    closeAddKeyBlock.addClickHandler(
-        new ClickHandler() {
-          @Override
-          public void onClick(final ClickEvent event) {
-            showAddKeyBlock(false);
-          }
-        });
-    buttons.add(closeAddKeyBlock);
-    buttons.setCellWidth(closeAddKeyBlock, "100%");
-    buttons.setCellHorizontalAlignment(closeAddKeyBlock, HasHorizontalAlignment.ALIGN_RIGHT);
-
-    body.add(addKeyBlock);
-
-    serverKeys = new FlowPanel();
-    body.add(serverKeys);
-
-    initWidget(body);
-  }
-
-  void setKeyTableVisible(final boolean on) {
-    keys.setVisible(on);
-    deleteKey.setVisible(on);
-    closeAddKeyBlock.setVisible(on);
-  }
-
-  void doAddNew() {
-    final String txt = addTxt.getText();
-    if (txt != null && txt.length() > 0) {
-      new RestApi("config")
-          .id("server")
-          .view(Plugin.get().getPluginName(), "serviceusers")
-          .id(serviceUser)
-          .view("sshkeys")
-          .post(
-              txt,
-              new AsyncCallback<SshKeyInfo>() {
-                @Override
-                public void onSuccess(SshKeyInfo k) {
-                  addTxt.setText("");
-                  keys.addOneKey(k);
-                  if (!keys.isVisible()) {
-                    showAddKeyBlock(false);
-                    setKeyTableVisible(true);
-                    keys.updateDeleteButton();
-                  }
-                }
-
-                @Override
-                public void onFailure(final Throwable caught) {
-                  // never invoked
-                }
-              });
-    }
-  }
-
-  @Override
-  protected void onLoad() {
-    super.onLoad();
-    refreshSshKeys();
-  }
-
-  private void refreshSshKeys() {
-    new RestApi("config")
-        .id("server")
-        .view(Plugin.get().getPluginName(), "serviceusers")
-        .id(serviceUser)
-        .view("sshkeys")
-        .get(
-            new AsyncCallback<JsArray<SshKeyInfo>>() {
-              @Override
-              public void onSuccess(JsArray<SshKeyInfo> result) {
-                keys.display(Natives.asList(result));
-                if (result.length() == 0 && keys.isVisible()) {
-                  showAddKeyBlock(true);
-                }
-                if (++loadCount == 2) {
-                  display();
-                }
-              }
-
-              @Override
-              public void onFailure(Throwable caught) {
-                // never invoked
-              }
-            });
-  }
-
-  void display() {}
-
-  private void showAddKeyBlock(boolean show) {
-    showAddKeyBlock.setVisible(!show);
-    addKeyBlock.setVisible(show);
-  }
-
-  private class SshKeyTable extends FlexTable {
-    private final Map<Integer, SshKeyInfo> sshKeyInfos;
-    private ValueChangeHandler<Boolean> updateDeleteHandler;
-
-    SshKeyTable() {
-      this.sshKeyInfos = new HashMap<>();
-      setStyleName("serviceuser-sshKeyTable");
-      setWidth("");
-      setText(0, 2, "Status");
-      setText(0, 3, "Algorithm");
-      setText(0, 4, "Key");
-      setText(0, 5, "Comment");
-
-      FlexCellFormatter fmt = getFlexCellFormatter();
-      fmt.addStyleName(0, 1, "iconHeader");
-      fmt.addStyleName(0, 2, "dataHeader");
-      fmt.addStyleName(0, 3, "dataHeader");
-      fmt.addStyleName(0, 4, "dataHeader");
-      fmt.addStyleName(0, 5, "dataHeader");
-
-      fmt.addStyleName(0, 1, "topMostCell");
-      fmt.addStyleName(0, 2, "topMostCell");
-      fmt.addStyleName(0, 3, "topMostCell");
-      fmt.addStyleName(0, 4, "topMostCell");
-      fmt.addStyleName(0, 5, "topMostCell");
-
-      updateDeleteHandler =
-          new ValueChangeHandler<Boolean>() {
-            @Override
-            public void onValueChange(ValueChangeEvent<Boolean> event) {
-              updateDeleteButton();
-            }
-          };
-    }
-
-    void deleteChecked() {
-      final HashSet<Integer> sequenceNumbers = new HashSet<>();
-      for (int row = 1; row < getRowCount(); row++) {
-        SshKeyInfo k = getRowItem(row);
-        if (k != null && ((CheckBox) getWidget(row, 1)).getValue()) {
-          sequenceNumbers.add(k.seq());
-        }
-      }
-      if (sequenceNumbers.isEmpty()) {
-        updateDeleteButton();
-      } else {
-        for (int seq : sequenceNumbers) {
-          new RestApi("config")
-              .id("server")
-              .view(Plugin.get().getPluginName(), "serviceusers")
-              .id(serviceUser)
-              .view("sshkeys")
-              .id(seq)
-              .delete(
-                  new AsyncCallback<NoContent>() {
-                    @Override
-                    public void onSuccess(NoContent result) {
-                      for (int row = 1; row < getRowCount(); ) {
-                        SshKeyInfo k = getRowItem(row);
-                        if (k != null && sequenceNumbers.contains(k.seq())) {
-                          removeRow(row);
-                        } else {
-                          row++;
-                        }
-                      }
-                      if (getRowCount() == 1) {
-                        display(Collections.<SshKeyInfo>emptyList());
-                      } else {
-                        updateDeleteButton();
-                      }
-                    }
-
-                    @Override
-                    public void onFailure(Throwable caught) {
-                      // never invoked
-                    }
-                  });
-        }
-      }
-    }
-
-    void display(List<SshKeyInfo> result) {
-      if (result.isEmpty()) {
-        setKeyTableVisible(false);
-        showAddKeyBlock(true);
-      } else {
-        while (1 < getRowCount()) removeRow(getRowCount() - 1);
-        for (SshKeyInfo k : result) {
-          addOneKey(k);
-        }
-        setKeyTableVisible(true);
-        deleteKey.setEnabled(false);
-      }
-    }
-
-    void addOneKey(SshKeyInfo k) {
-      FlexCellFormatter fmt = getFlexCellFormatter();
-      int row = getRowCount();
-      insertRow(row);
-      getCellFormatter().addStyleName(row, 0, "iconCell");
-      getCellFormatter().addStyleName(row, 0, "leftMostCell");
-
-      CheckBox sel = new CheckBox();
-      sel.addValueChangeHandler(updateDeleteHandler);
-
-      setWidget(row, 1, sel);
-      if (k.isValid()) {
-        setText(row, 2, "");
-        fmt.removeStyleName(row, 2, "serviceuser-sshKeyPanelInvalid");
-      } else {
-        setText(row, 2, "Invalid Key");
-        fmt.addStyleName(row, 2, "serviceuser-sshKeyPanelInvalid");
-      }
-      setText(row, 3, k.algorithm());
-
-      CopyableLabel keyLabel = new CopyableLabel(k.sshPublicKey());
-      keyLabel.setPreviewText(elide(k.encodedKey(), 40));
-      setWidget(row, 4, keyLabel);
-
-      setText(row, 5, k.comment());
-
-      fmt.addStyleName(row, 1, "iconCell");
-      fmt.addStyleName(row, 4, "serviceuser-sshKeyPanelEncodedKey");
-      for (int c = 2; c <= 5; c++) {
-        fmt.addStyleName(row, c, "dataCell");
-      }
-
-      setRowItem(row, k);
-    }
-
-    void updateDeleteButton() {
-      boolean on = false;
-      for (int row = 1; row < getRowCount(); row++) {
-        CheckBox sel = (CheckBox) getWidget(row, 1);
-        if (sel.getValue()) {
-          on = true;
-          break;
-        }
-      }
-      deleteKey.setEnabled(on);
-    }
-
-    private SshKeyInfo getRowItem(int row) {
-      return sshKeyInfos.get(row);
-    }
-
-    private void setRowItem(int row, SshKeyInfo sshKeyInfo) {
-      sshKeyInfos.put(row, sshKeyInfo);
-    }
-  }
-
-  static String elide(String s, int len) {
-    if (s == null || s.length() < len || len <= 10) {
-      return s;
-    }
-    return s.substring(0, len - 10) + "..." + s.substring(s.length() - 10);
-  }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/StringListPanel.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/StringListPanel.java
deleted file mode 100644
index c2fff99..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/client/StringListPanel.java
+++ /dev/null
@@ -1,202 +0,0 @@
-// Copyright (C) 2014 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.
-
-package com.googlesource.gerrit.plugins.serviceuser.client;
-
-import com.google.gerrit.client.rpc.Natives;
-import com.google.gwt.core.client.JsArrayString;
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.event.dom.client.ClickHandler;
-import com.google.gwt.event.dom.client.KeyCodes;
-import com.google.gwt.event.dom.client.KeyPressEvent;
-import com.google.gwt.event.dom.client.KeyPressHandler;
-import com.google.gwt.event.logical.shared.ValueChangeEvent;
-import com.google.gwt.event.logical.shared.ValueChangeHandler;
-import com.google.gwt.user.client.ui.Button;
-import com.google.gwt.user.client.ui.CheckBox;
-import com.google.gwt.user.client.ui.FlexTable;
-import com.google.gwt.user.client.ui.FlowPanel;
-import com.google.gwt.user.client.ui.FocusWidget;
-import com.google.gwt.user.client.ui.HorizontalPanel;
-import com.google.gwt.user.client.ui.Image;
-import com.google.gwt.user.client.ui.Label;
-import com.google.gwtexpui.globalkey.client.NpTextBox;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-public class StringListPanel extends FlowPanel {
-  private final NpTextBox input;
-  private final StringListTable t;
-  private final Button deleteButton;
-  private final HorizontalPanel titlePanel;
-  private Image info;
-
-  StringListPanel(String title, String fieldName, JsArrayString values, final FocusWidget w) {
-    this(title, fieldName, Natives.asList(values), w);
-  }
-
-  StringListPanel(String title, String fieldName, Collection<String> values, final FocusWidget w) {
-    titlePanel = new HorizontalPanel();
-    Label titleLabel = new Label(title);
-    titleLabel.setStyleName("serviceuser-smallHeading");
-    titlePanel.add(titleLabel);
-    add(titlePanel);
-    input = new NpTextBox();
-    input.addKeyPressHandler(
-        new KeyPressHandler() {
-          @Override
-          public void onKeyPress(KeyPressEvent event) {
-            if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) {
-              w.setEnabled(true);
-              add();
-            }
-          }
-        });
-    HorizontalPanel p = new HorizontalPanel();
-    p.add(input);
-    Button addButton = new Button("Add");
-    addButton.setEnabled(false);
-    new OnEditEnabler(addButton, input);
-    addButton.addClickHandler(
-        new ClickHandler() {
-          @Override
-          public void onClick(ClickEvent event) {
-            w.setEnabled(true);
-            add();
-          }
-        });
-    p.add(addButton);
-    add(p);
-
-    t = new StringListTable(fieldName);
-    add(t);
-
-    deleteButton = new Button("Delete");
-    deleteButton.setEnabled(false);
-    add(deleteButton);
-    deleteButton.addClickHandler(
-        new ClickHandler() {
-          @Override
-          public void onClick(ClickEvent event) {
-            w.setEnabled(true);
-            t.deleteChecked();
-          }
-        });
-
-    t.display(values);
-  }
-
-  void setInfo(String msg) {
-    if (info == null) {
-      info = new Image(ServiceUserPlugin.RESOURCES.info());
-      titlePanel.add(info);
-    }
-    info.setTitle(msg);
-  }
-
-  List<String> getValues() {
-    return t.getValues();
-  }
-
-  private void add() {
-    String v = input.getValue().trim();
-    if (!v.isEmpty()) {
-      input.setValue("");
-      t.insert(v);
-    }
-  }
-
-  private class StringListTable extends FlexTable {
-    StringListTable(String name) {
-      setStyleName("serviceuser-stringListTable");
-      FlexCellFormatter fmt = getFlexCellFormatter();
-      fmt.addStyleName(0, 0, "iconHeader");
-      fmt.addStyleName(0, 0, "topMostCell");
-      fmt.addStyleName(0, 0, "leftMostCell");
-      fmt.addStyleName(0, 1, "dataHeader");
-      fmt.addStyleName(0, 1, "topMostCell");
-
-      setText(0, 1, name);
-    }
-
-    void display(Collection<String> values) {
-      int row = 1;
-      for (String v : values) {
-        populate(row, v);
-        row++;
-      }
-    }
-
-    List<String> getValues() {
-      List<String> values = new ArrayList<>();
-      for (int row = 1; row < getRowCount(); row++) {
-        values.add(getText(row, 1));
-      }
-      return values;
-    }
-
-    private void populate(int row, String value) {
-      FlexCellFormatter fmt = getFlexCellFormatter();
-      fmt.addStyleName(row, 0, "leftMostCell");
-      fmt.addStyleName(row, 0, "iconCell");
-      fmt.addStyleName(row, 1, "dataCell");
-
-      CheckBox checkBox = new CheckBox();
-      checkBox.addValueChangeHandler(
-          new ValueChangeHandler<Boolean>() {
-            @Override
-            public void onValueChange(ValueChangeEvent<Boolean> event) {
-              enableDelete();
-            }
-          });
-      setWidget(row, 0, checkBox);
-      setText(row, 1, value);
-    }
-
-    void insert(String v) {
-      int insertPos = getRowCount();
-      for (int row = 1; row < getRowCount(); row++) {
-        int compareResult = v.compareTo(getText(row, 1));
-        if (compareResult < 0) {
-          insertPos = row;
-          break;
-        } else if (compareResult == 0) {
-          return;
-        }
-      }
-      insertRow(insertPos);
-      populate(insertPos, v);
-    }
-
-    void enableDelete() {
-      for (int row = 1; row < getRowCount(); row++) {
-        if (((CheckBox) getWidget(row, 0)).getValue()) {
-          deleteButton.setEnabled(true);
-          return;
-        }
-      }
-      deleteButton.setEnabled(false);
-    }
-
-    void deleteChecked() {
-      deleteButton.setEnabled(false);
-      for (int row = 1; row < getRowCount(); row++) {
-        if (((CheckBox) getWidget(row, 0)).getValue()) {
-          removeRow(row--);
-        }
-      }
-    }
-  }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/public/serviceuser.css b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/public/serviceuser.css
deleted file mode 100644
index c996fa0..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/public/serviceuser.css
+++ /dev/null
@@ -1,141 +0,0 @@
-.serviceuser-panel {
-  border-spacing: 0px 5px;
-}
-
-.serviceuser-createButton, .serviceuser-saveButton {
-  margin-left: 10px !important;
-}
-
-.serviceuser-serviceUserTable,
-.serviceuser-sshKeyTable,
-.serviceuser-stringListTable {
-  border-collapse: separate;
-  border-spacing: 0;
-}
-
-.serviceuser-serviceUserTable .leftMostCell,
-.serviceuser-sshKeyTable .leftMostCell,
-.serviceuser-stringListTable .leftMostCell {
-  border-left: 1px solid #EEE;
-}
-
-.serviceuser-serviceUserTable .topMostCell,
-.serviceuser-sshKeyTable .topMostCell,
-.serviceuser-stringListTable .topMostCell {
-  border-top: 1px solid #EEE;
-}
-
-.serviceuser-serviceUserTable .dataHeader,
-.serviceuser-sshKeyTable .dataHeader,
-.serviceuser-stringListTable .dataHeader {
-  border: 1px solid #FFF;
-  padding: 2px 6px 1px;
-  background-color: #EEE;
-  font-style: italic;
-  white-space: nowrap;
-  color: textColor;
-}
-
-.serviceuser-sshKeyTable .iconHeader,
-.serviceuser-stringListTable .iconHeader {
-  border-top: 1px solid #FFF;
-  border-bottom: 1px solid #FFF;
-  background-color: #EEE;
-}
-
-.serviceuser-serviceUserTable .dataCell,
-.serviceuser-sshKeyTable .dataCell,
-.serviceuser-stringListTable .dataCell {
-  padding-left: 5px;
-  padding-right: 5px;
-  border-right: 1px solid #EEE;
-  border-bottom: 1px solid #EEE;
-  vertical-align: middle;
-  height: 20px;
-}
-
-.serviceuser-sshKeyTable .iconCell,
-.serviceuser-stringListTable .iconCell {
-  width: 1px;
-  padding: 0px;
-  vertical-align: middle;
-  border-bottom: 1px solid #EEE;
-}
-
-.serviceuser-sshKeyPanelEncodedKey {
-  white-space: nowrap;
-  text-overflow: ellipsis;
-  overflow: hidden;
-  font-family: mono-font;
-  font-size: small;
-}
-
-.serviceuser-sshKeyPanelInvalid {
-  white-space: nowrap;
-  color: red;
-  font-weight: bold;
-}
-
-.serviceuser-addSshKeyPanel {
-  margin-top: 10px;
-  background-color: #EEE;
-  padding: 5px 5px 5px 5px;
-}
-
-.serviceuser-serviceUserInfoTable {
-  margin-bottom: 10px;
-}
-
-.serviceuser-editButton,
-.serviceuser-deleteButton,
-.serviceuser-generateButton {
-  float: right;
-  cursor: pointer;
-  margin-left: 2px;
-}
-
-.serviceuser-toggleButton {
-  position: relative;
-  height: 19px;
-  width: 140px;
-  background: #FFF;
-  color: #000;
-  text-shadow: none;
-  border: 1px solid #EEE !important;
-}
-.serviceuser-toggleButton .html-face {
-  position: absolute;
-  top: 0;
-  width: 68px;
-  height: 17px;
-  line-height: 17px;
-  text-align: center;
-  border-width: 1px;
-}
-
-.serviceuser-toggleButton-up,
-.serviceuser-toggleButton-up-hovering,
-.serviceuser-toggleButton-up-disabled,
-.serviceuser-toggleButton-down,
-.serviceuser-toggleButton-down-hovering,
-.serviceuser-toggleButton-down-disabled {
-  padding: 0;
-  border: 0;
-}
-.serviceuser-toggleButton-up .html-face,
-.serviceuser-toggleButton-up-hovering .html-face {
-  left: 0;
-  background: #FCB;
-  border-style: outset;
-}
-.serviceuser-toggleButton-down .html-face,
-.serviceuser-toggleButton-down-hovering .html-face {
-  right: 0;
-  background: #BFC;
-  border-style: inset;
-}
-
-.serviceuser-smallHeading {
-  margin-top: 5px;
-  font-weight: bold;
-}
diff --git a/src/main/resources/Documentation/about.md b/src/main/resources/Documentation/about.md
index e5ad4c7..17a4e29 100644
--- a/src/main/resources/Documentation/about.md
+++ b/src/main/resources/Documentation/about.md
@@ -6,8 +6,8 @@
 in Jenkins. A service user is not able to login into the Gerrit WebUI
 and it cannot push commits or tags.
 
-This plugin supports the creation of service users via [SSH](cmd-create.md),
-[REST](rest-api-config.md) and in the [WebUI](#webui).
+This plugin supports the creation of service users via [SSH](cmd-create.md) and
+[REST](rest-api-config.md).
 
 To create a service user a user must be a member of a group that is
 granted the 'Create Service User' capability (provided by this plugin)
@@ -20,12 +20,6 @@
 For each created service user the plugin stores some
 [properties](#properties).
 
-<a id="webui"></a>
-Create Service User in WebUI
-----------------------------
-In the `People` top menu there is a menu item `Create Service User`
-that opens a dialog for creating a service user.
-
 <a id="properties"></a>
 Service User Properties
 -----------------------
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
index 1380b73..0793bb6 100644
--- a/src/main/resources/Documentation/config.md
+++ b/src/main/resources/Documentation/config.md
@@ -22,16 +22,6 @@
 	should be automatically added. Multiple groups can be specified by
 	having multiple `plugin.@PLUGIN@.group` entries.
 
-<a id="infoMessage">
-`plugin.@PLUGIN@.infoMessage`
-:	HTML formatted message that should be displayed on the service user
-	creation screen.
-
-<a id="onSuccessMessage">
-`plugin.@PLUGIN@.onSuccessMessage`
-:	HTML formatted message that should be displayed after a service
-	user was successfully created.
-
 <a id="allowEmail">
 `plugin.@PLUGIN@.allowEmail`
 :	Whether it is allowed for service user owners to set email
diff --git a/src/main/resources/Documentation/rest-api-config.md b/src/main/resources/Documentation/rest-api-config.md
index 302be07..8497fcd 100644
--- a/src/main/resources/Documentation/rest-api-config.md
+++ b/src/main/resources/Documentation/rest-api-config.md
@@ -704,10 +704,6 @@
 The `ConfigInfo` entity contains the configuration of the @PLUGIN@
 plugin.
 
-* _info_: HTML formatted message that should be displayed on the
-  service user creation screen.
-* _on\_success_: HTML formatted message that should be displayed after
-  a service user was successfully created.
 * _allow\_email_: Whether it is allowed to provide an email address for
   a service user (not set if `false`).
 * _allow\_http\_password_: Whether it is allowed to generate an HTTP
@@ -731,10 +727,6 @@
 The `ConfigInput` entity contains updates for the configuration of the
 @PLUGIN@ plugin.
 
-* _info_: HTML formatted message that should be displayed on the
-  service user creation screen.
-* _on\_success_: HTML formatted message that should be displayed after
-  a service user was successfully created.
 * _allow\_email_: Whether it is allowed to provide an email address for
   a service user (not set if `false`).
 * _allow\_http\_password_: Whether it is allowed to generate an HTTP
diff --git a/tools/bzl/plugin.bzl b/tools/bzl/plugin.bzl
index 9568c84..89a1643 100644
--- a/tools/bzl/plugin.bzl
+++ b/tools/bzl/plugin.bzl
@@ -1,10 +1,8 @@
 load(
     "@com_googlesource_gerrit_bazlets//:gerrit_plugin.bzl",
     _gerrit_plugin = "gerrit_plugin",
-    _gwt_plugin_deps = "GWT_PLUGIN_DEPS",
     _plugin_deps = "PLUGIN_DEPS",
 )
 
 gerrit_plugin = _gerrit_plugin
-GWT_PLUGIN_DEPS = _gwt_plugin_deps
 PLUGIN_DEPS = _plugin_deps
diff --git a/tools/eclipse/BUILD b/tools/eclipse/BUILD
index 9b694c1..a38b222 100644
--- a/tools/eclipse/BUILD
+++ b/tools/eclipse/BUILD
@@ -1,16 +1,10 @@
 load("//tools/bzl:classpath.bzl", "classpath_collector")
-load(
-    "//tools/bzl:plugin.bzl",
-    "GWT_PLUGIN_DEPS",
-    "PLUGIN_DEPS",
-)
+load("//tools/bzl:plugin.bzl", "PLUGIN_DEPS")
 
 classpath_collector(
     name = "main_classpath_collect",
     testonly = 1,
-    deps = PLUGIN_DEPS + GWT_PLUGIN_DEPS + [
-        "//external:gwt-dev",
-        "//external:gwt-user",
+    deps = PLUGIN_DEPS + [
         "//:serviceuser__plugin",
     ],
 )